From ea9da1c79eb9a28176550d0b8ba9166e6e5f42b8 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Fri, 2 Dec 2011 11:55:44 -0800 Subject: UAS: Re-add workqueue items if submission fails. If the original submission (or allocation) of the URBs for a SCSI command fails, the UAS driver sticks the command structure in a workqueue and schedules uas_do_work() to run. That function removes the entire queue before walking across it and attempting to resubmit. Unfortunately, if the second submission fails, we will leak memory (because an allocated URB was not submitted) and possibly leave the SCSI command partially enqueued on some of the stream rings. Fix this by checking whether the second submission failed and re-queueing the command to the UAS workqueue and scheduling it. Signed-off-by: Sarah Sharp Cc: Matthew Wilcox Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/storage/uas.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 1d10d5b8204..4bbaf6e150e 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -125,29 +125,38 @@ struct uas_cmd_info { /* I hate forward declarations, but I actually have a loop */ static int uas_submit_urbs(struct scsi_cmnd *cmnd, struct uas_dev_info *devinfo, gfp_t gfp); +static void uas_do_work(struct work_struct *work); +static DECLARE_WORK(uas_work, uas_do_work); static DEFINE_SPINLOCK(uas_work_lock); static LIST_HEAD(uas_work_list); static void uas_do_work(struct work_struct *work) { struct uas_cmd_info *cmdinfo; + struct uas_cmd_info *temp; struct list_head list; + int err; spin_lock_irq(&uas_work_lock); list_replace_init(&uas_work_list, &list); spin_unlock_irq(&uas_work_lock); - list_for_each_entry(cmdinfo, &list, list) { + list_for_each_entry_safe(cmdinfo, temp, &list, list) { struct scsi_pointer *scp = (void *)cmdinfo; struct scsi_cmnd *cmnd = container_of(scp, struct scsi_cmnd, SCp); - uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_NOIO); + err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_NOIO); + if (err) { + list_del(&cmdinfo->list); + spin_lock_irq(&uas_work_lock); + list_add_tail(&cmdinfo->list, &uas_work_list); + spin_unlock_irq(&uas_work_lock); + schedule_work(&uas_work); + } } } -static DECLARE_WORK(uas_work, uas_do_work); - static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd) { struct sense_iu *sense_iu = urb->transfer_buffer; -- cgit v1.2.3-70-g09d2 From 9eb445410db99e5f5f660e97a2165a0567bd909e Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Fri, 2 Dec 2011 11:55:46 -0800 Subject: UAS: Use unique tags on non-streams devices. UAS can work with either USB 3.0 devices that support bulk streams, or USB 2.0 devices that do not support bulk streams. When we're working with a non-streams device, we need to be able to uniquely identify a SCSI command with a tag in the IU. Devices will barf and abort all queued commands if they find a duplicate tag. uas_queuecommand_lck() sets cmdinfo->stream to zero if the device doesn't support streams, which is later passed into uas_alloc_cmd_urb() as the variable stream. This means the UAS driver was setting the tag in all commands to zero for non-stream devices. So the UAS driver won't currently work with USB 2.0 devices. Use the SCSI command tag instead of the stream ID for the command IU tag. We have to add one to the SCSI command tag because SCSI tags are zero-based, but stream IDs are one-based, and the command tag must match the stream ID that we're queueing the data IUs for. Untagged SCSI commands use stream ID 1. Signed-off-by: Sarah Sharp Cc: Matthew Wilcox Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/storage/uas.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 4bbaf6e150e..28d9b190938 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -343,7 +343,10 @@ static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp, goto free; iu->iu_id = IU_ID_COMMAND; - iu->tag = cpu_to_be16(stream_id); + if (blk_rq_tagged(cmnd->request)) + iu->tag = cpu_to_be16(cmnd->request->tag + 1); + else + iu->tag = cpu_to_be16(1); iu->prio_attr = UAS_SIMPLE_TAG; iu->len = len; int_to_scsilun(sdev->lun, &iu->lun); -- cgit v1.2.3-70-g09d2 From 96c1eb9873caffc507a1951c36b43fdcf3ddeff3 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Fri, 2 Dec 2011 11:55:48 -0800 Subject: UAS: Free status URB when we can't find the SCSI tag. In the UAS status URB completion handler, we need to free the URB, no matter what happens. Fix a bug where we would leak the URB (and its buffer) if we couldn't find a SCSI command that is associated with this status phase. Signed-off-by: Sarah Sharp Cc: Matthew Wilcox Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/storage/uas.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 28d9b190938..9dd4aaee85c 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -246,8 +246,10 @@ static void uas_stat_cmplt(struct urb *urb) cmnd = sdev->current_cmnd; else cmnd = scsi_find_tag(sdev, tag); - if (!cmnd) + if (!cmnd) { + usb_free_urb(urb); return; + } switch (iu->iu_id) { case IU_ID_STATUS: -- cgit v1.2.3-70-g09d2 From dae51546b6564b06cbae4191d4f2dee7136be3c1 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 19 Dec 2011 17:06:08 +0100 Subject: usb/uas: use unique tags for all LUNs I observed that on a device with multiple LUNs UAS was re-using the same tag number for requests which were issued at the same time to both LUNs. This patch uses scsi_init_shared_tag_map() to use unique tags for all LUNs. With this patch I haven't seen the same tag number during the init sequence anymore. Tag 1 is used for devices which do not adverise command queueing. This patch initilizes the queue before adding the scsi host like the other two user in tree. Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/storage/uas.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 9dd4aaee85c..6974f4bed2f 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -684,6 +684,17 @@ static void uas_configure_endpoints(struct uas_dev_info *devinfo) } } +static void uas_free_streams(struct uas_dev_info *devinfo) +{ + struct usb_device *udev = devinfo->udev; + struct usb_host_endpoint *eps[3]; + + eps[0] = usb_pipe_endpoint(udev, devinfo->status_pipe); + eps[1] = usb_pipe_endpoint(udev, devinfo->data_in_pipe); + eps[2] = usb_pipe_endpoint(udev, devinfo->data_out_pipe); + usb_free_streams(devinfo->intf, eps, 3, GFP_KERNEL); +} + /* * XXX: What I'd like to do here is register a SCSI host for each USB host in * the system. Follow usb-storage's design of registering a SCSI host for @@ -713,18 +724,26 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id) shost->max_id = 1; shost->sg_tablesize = udev->bus->sg_tablesize; - result = scsi_add_host(shost, &intf->dev); - if (result) - goto free; - shost->hostdata[0] = (unsigned long)devinfo; - devinfo->intf = intf; devinfo->udev = udev; uas_configure_endpoints(devinfo); + result = scsi_init_shared_tag_map(shost, devinfo->qdepth - 1); + if (result) + goto free; + + result = scsi_add_host(shost, &intf->dev); + if (result) + goto deconfig_eps; + + shost->hostdata[0] = (unsigned long)devinfo; + scsi_scan_host(shost); usb_set_intfdata(intf, shost); return result; + +deconfig_eps: + uas_free_streams(devinfo); free: kfree(devinfo); if (shost) @@ -746,18 +765,11 @@ static int uas_post_reset(struct usb_interface *intf) static void uas_disconnect(struct usb_interface *intf) { - struct usb_device *udev = interface_to_usbdev(intf); - struct usb_host_endpoint *eps[3]; struct Scsi_Host *shost = usb_get_intfdata(intf); struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; scsi_remove_host(shost); - - eps[0] = usb_pipe_endpoint(udev, devinfo->status_pipe); - eps[1] = usb_pipe_endpoint(udev, devinfo->data_in_pipe); - eps[2] = usb_pipe_endpoint(udev, devinfo->data_out_pipe); - usb_free_streams(intf, eps, 3, GFP_KERNEL); - + uas_free_streams(devinfo); kfree(devinfo); } -- cgit v1.2.3-70-g09d2 From 22188f4a933c6e86ac67f52028895c795896492e Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 19 Dec 2011 20:22:39 +0100 Subject: usb/uas: use scsi_host_find_tag() to find command from a tag In "usb/uas: use unique tags for all LUNs" we make sure to create unique tags across all LUNs. This patch uses scsi_host_find_tag() to obtain the correct command which is associated with the tag. The following changes are required: - don't use sdev->current_cmnd anymore Since we can have devices which don't support command queueing we must ensure that we can tell the two commands apart. Even if a device supports comand queuing we send the INQUIRY command "untagged" for LUN1 while we can send a tagged command to LUN0 at the same time. devinfo->cmnd is used for stashing the one "untagged" command. - tag number is altered. If stream support is used then the tag number must match the stream number. Therefore we can't use tag 0 and must start at tag 1. In case we have untagged commands (at least the first command) we must be able to distinguish between command tag 0 (which becomes 1) and untagged command (which becomes curently also 1). The following tag numbers are used: 0: never 1: for untagged commands (devinfo->cmnd) 2+: tagged commands. Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/storage/uas.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 6974f4bed2f..e2386e8c767 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -98,6 +98,7 @@ struct uas_dev_info { unsigned cmd_pipe, status_pipe, data_in_pipe, data_out_pipe; unsigned use_streams:1; unsigned uas_sense_old:1; + struct scsi_cmnd *cmnd; }; enum { @@ -178,8 +179,6 @@ static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd) } cmnd->result = sense_iu->status; - if (sdev->current_cmnd) - sdev->current_cmnd = NULL; cmnd->scsi_done(cmnd); usb_free_urb(urb); } @@ -205,8 +204,6 @@ static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd) } cmnd->result = sense_iu->status; - if (sdev->current_cmnd) - sdev->current_cmnd = NULL; cmnd->scsi_done(cmnd); usb_free_urb(urb); } @@ -230,8 +227,8 @@ static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd, static void uas_stat_cmplt(struct urb *urb) { struct iu *iu = urb->transfer_buffer; - struct scsi_device *sdev = urb->context; - struct uas_dev_info *devinfo = sdev->hostdata; + struct Scsi_Host *shost = urb->context; + struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; struct scsi_cmnd *cmnd; u16 tag; @@ -242,10 +239,10 @@ static void uas_stat_cmplt(struct urb *urb) } tag = be16_to_cpup(&iu->tag) - 1; - if (sdev->current_cmnd) - cmnd = sdev->current_cmnd; + if (tag == 0) + cmnd = devinfo->cmnd; else - cmnd = scsi_find_tag(sdev, tag); + cmnd = scsi_host_find_tag(shost, tag - 1); if (!cmnd) { usb_free_urb(urb); return; @@ -253,6 +250,9 @@ static void uas_stat_cmplt(struct urb *urb) switch (iu->iu_id) { case IU_ID_STATUS: + if (devinfo->cmnd == cmnd) + devinfo->cmnd = NULL; + if (urb->actual_length < 16) devinfo->uas_sense_old = 1; if (devinfo->uas_sense_old) @@ -314,7 +314,7 @@ static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp, goto free; usb_fill_bulk_urb(urb, udev, devinfo->status_pipe, iu, sizeof(*iu), - uas_stat_cmplt, cmnd->device); + uas_stat_cmplt, cmnd->device->host); urb->stream_id = stream_id; urb->transfer_flags |= URB_FREE_BUFFER; out: @@ -346,7 +346,7 @@ static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp, iu->iu_id = IU_ID_COMMAND; if (blk_rq_tagged(cmnd->request)) - iu->tag = cpu_to_be16(cmnd->request->tag + 1); + iu->tag = cpu_to_be16(cmnd->request->tag + 2); else iu->tag = cpu_to_be16(1); iu->prio_attr = UAS_SIMPLE_TAG; @@ -458,13 +458,13 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer)); - if (!cmdinfo->status_urb && sdev->current_cmnd) + if (devinfo->cmnd) return SCSI_MLQUEUE_DEVICE_BUSY; if (blk_rq_tagged(cmnd->request)) { - cmdinfo->stream = cmnd->request->tag + 1; + cmdinfo->stream = cmnd->request->tag + 2; } else { - sdev->current_cmnd = cmnd; + devinfo->cmnd = cmnd; cmdinfo->stream = 1; } @@ -565,7 +565,7 @@ static int uas_slave_configure(struct scsi_device *sdev) { struct uas_dev_info *devinfo = sdev->hostdata; scsi_set_tag_type(sdev, MSG_ORDERED_TAG); - scsi_activate_tcq(sdev, devinfo->qdepth - 1); + scsi_activate_tcq(sdev, devinfo->qdepth - 2); return 0; } @@ -633,6 +633,7 @@ static void uas_configure_endpoints(struct uas_dev_info *devinfo) unsigned i, n_endpoints = intf->cur_altsetting->desc.bNumEndpoints; devinfo->uas_sense_old = 0; + devinfo->cmnd = NULL; for (i = 0; i < n_endpoints; i++) { unsigned char *extra = endpoint[i].extra; @@ -728,7 +729,7 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id) devinfo->udev = udev; uas_configure_endpoints(devinfo); - result = scsi_init_shared_tag_map(shost, devinfo->qdepth - 1); + result = scsi_init_shared_tag_map(shost, devinfo->qdepth - 2); if (result) goto free; -- cgit v1.2.3-70-g09d2 From ceb3f91fd53c9fbd7b292fc2754ba4efffeeeedb Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 20 Dec 2011 14:50:26 +0100 Subject: usb/uas: one only one status URB/host on stream-less connection The status/sense URB is allocated on per-command basis. A read/write looks the following way on a stream-less connection: - send cmd tag X, queue status - receive status, oh it is a read for tag X. queue status & read - receive read - receive status, oh I'm done for tag X. Cool call complete and free status urb. This block repeats itself 1:1 for further commands and looks great so far. Lets take a look now what happens if we do allow multiple commands: - send cmd tag X, queue statusX (belongs to the command with the X tag) - send cmd tag Y, queue statusY (belongs to the command with the Y tag) - receive statusX, oh it is a read for tag X. queue statusX & a read - receive read - receive statusY, oh I'm done for tag X. Cool call complete and free statusY. - receive statusX, oh it is a read for tag Y. queue statusY & before we queue the read the the following message can be observed: |sd 0:0:0:0: [sda] sense urb submission failure followed by a second attempt with the same result. In order to address this problem we will use only one status URB for each scsi host in case we don't have stream support (as suggested by Matthew). This URB is requeued until the device removed. Nothing changes on stream based endpoints. Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/storage/uas.c | 70 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index e2386e8c767..036e9690095 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -99,6 +99,7 @@ struct uas_dev_info { unsigned use_streams:1; unsigned uas_sense_old:1; struct scsi_cmnd *cmnd; + struct urb *status_urb; /* used only if stream support is available */ }; enum { @@ -117,6 +118,7 @@ struct uas_cmd_info { unsigned int state; unsigned int stream; struct urb *cmd_urb; + /* status_urb is used only if stream support isn't available */ struct urb *status_urb; struct urb *data_in_urb; struct urb *data_out_urb; @@ -180,7 +182,6 @@ static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd) cmnd->result = sense_iu->status; cmnd->scsi_done(cmnd); - usb_free_urb(urb); } static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd) @@ -205,7 +206,6 @@ static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd) cmnd->result = sense_iu->status; cmnd->scsi_done(cmnd); - usb_free_urb(urb); } static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd, @@ -214,7 +214,7 @@ static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd, struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; int err; - cmdinfo->state = direction | SUBMIT_STATUS_URB; + cmdinfo->state = direction; err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC); if (err) { spin_lock(&uas_work_lock); @@ -231,10 +231,12 @@ static void uas_stat_cmplt(struct urb *urb) struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; struct scsi_cmnd *cmnd; u16 tag; + int ret; if (urb->status) { dev_err(&urb->dev->dev, "URB BAD STATUS %d\n", urb->status); - usb_free_urb(urb); + if (devinfo->use_streams) + usb_free_urb(urb); return; } @@ -244,7 +246,13 @@ static void uas_stat_cmplt(struct urb *urb) else cmnd = scsi_host_find_tag(shost, tag - 1); if (!cmnd) { - usb_free_urb(urb); + if (devinfo->use_streams) { + usb_free_urb(urb); + return; + } + ret = usb_submit_urb(urb, GFP_ATOMIC); + if (ret) + dev_err(&urb->dev->dev, "failed submit status urb\n"); return; } @@ -270,6 +278,15 @@ static void uas_stat_cmplt(struct urb *urb) scmd_printk(KERN_ERR, cmnd, "Bogus IU (%d) received on status pipe\n", iu->iu_id); } + + if (devinfo->use_streams) { + usb_free_urb(urb); + return; + } + + ret = usb_submit_urb(urb, GFP_ATOMIC); + if (ret) + dev_err(&urb->dev->dev, "failed submit status urb\n"); } static void uas_data_cmplt(struct urb *urb) @@ -300,7 +317,7 @@ static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp, } static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp, - struct scsi_cmnd *cmnd, u16 stream_id) + struct Scsi_Host *shost, u16 stream_id) { struct usb_device *udev = devinfo->udev; struct urb *urb = usb_alloc_urb(0, gfp); @@ -314,7 +331,7 @@ static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp, goto free; usb_fill_bulk_urb(urb, udev, devinfo->status_pipe, iu, sizeof(*iu), - uas_stat_cmplt, cmnd->device->host); + uas_stat_cmplt, shost); urb->stream_id = stream_id; urb->transfer_flags |= URB_FREE_BUFFER; out: @@ -376,8 +393,8 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; if (cmdinfo->state & ALLOC_STATUS_URB) { - cmdinfo->status_urb = uas_alloc_sense_urb(devinfo, gfp, cmnd, - cmdinfo->stream); + cmdinfo->status_urb = uas_alloc_sense_urb(devinfo, gfp, + cmnd->device->host, cmdinfo->stream); if (!cmdinfo->status_urb) return SCSI_MLQUEUE_DEVICE_BUSY; cmdinfo->state &= ~ALLOC_STATUS_URB; @@ -486,7 +503,8 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, } if (!devinfo->use_streams) { - cmdinfo->state &= ~(SUBMIT_DATA_IN_URB | SUBMIT_DATA_OUT_URB); + cmdinfo->state &= ~(SUBMIT_DATA_IN_URB | SUBMIT_DATA_OUT_URB | + ALLOC_STATUS_URB | SUBMIT_STATUS_URB); cmdinfo->stream = 0; } @@ -685,6 +703,29 @@ static void uas_configure_endpoints(struct uas_dev_info *devinfo) } } +static int uas_alloc_status_urb(struct uas_dev_info *devinfo, + struct Scsi_Host *shost) +{ + if (devinfo->use_streams) { + devinfo->status_urb = NULL; + return 0; + } + + devinfo->status_urb = uas_alloc_sense_urb(devinfo, GFP_KERNEL, + shost, 0); + if (!devinfo->status_urb) + goto err_s_urb; + + if (usb_submit_urb(devinfo->status_urb, GFP_KERNEL)) + goto err_submit_urb; + + return 0; +err_submit_urb: + usb_free_urb(devinfo->status_urb); +err_s_urb: + return -ENOMEM; +} + static void uas_free_streams(struct uas_dev_info *devinfo) { struct usb_device *udev = devinfo->udev; @@ -739,10 +780,17 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id) shost->hostdata[0] = (unsigned long)devinfo; + result = uas_alloc_status_urb(devinfo, shost); + if (result) + goto err_alloc_status; + scsi_scan_host(shost); usb_set_intfdata(intf, shost); return result; +err_alloc_status: + scsi_remove_host(shost); + shost = NULL; deconfig_eps: uas_free_streams(devinfo); free: @@ -770,6 +818,8 @@ static void uas_disconnect(struct usb_interface *intf) struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; scsi_remove_host(shost); + usb_kill_urb(devinfo->status_urb); + usb_free_urb(devinfo->status_urb); uas_free_streams(devinfo); kfree(devinfo); } -- cgit v1.2.3-70-g09d2 From 5e13fd354a39d637df9b25edcb2964edf4a7c534 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Tue, 13 Dec 2011 17:19:57 +0530 Subject: ath6kl: Use cfg80211_roamed_bss() to report roaming event This is to avoid the scenario where the bss entry of the AP got expired when reporting roaming event to current AP. As the bss entry for the current bss is available in driver, pass this bss to cfg80211. This fixes WARNING: at net/wireless/sme.c:586. This patch depends on the following patch in cfg80211 "cfg80211: Fix race in bss timeout". Reported-by: Kalle Valo Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 37 +++++++++++++++--------------- 1 file changed, 18 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 6c59a217b1a..85c24dd0156 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -605,11 +605,13 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, return 0; } -static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif, - enum network_type nw_type, - const u8 *bssid, - struct ieee80211_channel *chan, - const u8 *beacon_ie, size_t beacon_ie_len) +static struct cfg80211_bss * +ath6kl_add_bss_if_needed(struct ath6kl_vif *vif, + enum network_type nw_type, + const u8 *bssid, + struct ieee80211_channel *chan, + const u8 *beacon_ie, + size_t beacon_ie_len) { struct ath6kl *ar = vif->ar; struct cfg80211_bss *bss; @@ -638,7 +640,7 @@ static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif, */ ie = kmalloc(2 + vif->ssid_len + beacon_ie_len, GFP_KERNEL); if (ie == NULL) - return -ENOMEM; + return NULL; ie[0] = WLAN_EID_SSID; ie[1] = vif->ssid_len; memcpy(ie + 2, vif->ssid, vif->ssid_len); @@ -652,15 +654,9 @@ static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif, "cfg80211\n", bssid); kfree(ie); } else - ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss " - "entry\n"); - - if (bss == NULL) - return -ENOMEM; + ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss\n"); - cfg80211_put_bss(bss); - - return 0; + return bss; } void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, @@ -672,6 +668,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, { struct ieee80211_channel *chan; struct ath6kl *ar = vif->ar; + struct cfg80211_bss *bss; /* capinfo + listen interval */ u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16); @@ -712,8 +709,9 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, chan = ieee80211_get_channel(ar->wiphy, (int) channel); - if (ath6kl_add_bss_if_needed(vif, nw_type, bssid, chan, assoc_info, - beacon_ie_len) < 0) { + bss = ath6kl_add_bss_if_needed(vif, nw_type, bssid, chan, + assoc_info, beacon_ie_len); + if (!bss) { ath6kl_err("could not add cfg80211 bss entry\n"); return; } @@ -722,6 +720,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n", nw_type & ADHOC_CREATOR ? "creator" : "joiner"); cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL); + cfg80211_put_bss(bss); return; } @@ -732,11 +731,11 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, assoc_req_ie, assoc_req_len, assoc_resp_ie, assoc_resp_len, WLAN_STATUS_SUCCESS, GFP_KERNEL); + cfg80211_put_bss(bss); } else if (vif->sme_state == SME_CONNECTED) { /* inform roam event to cfg80211 */ - cfg80211_roamed(vif->ndev, chan, bssid, - assoc_req_ie, assoc_req_len, - assoc_resp_ie, assoc_resp_len, GFP_KERNEL); + cfg80211_roamed_bss(vif->ndev, bss, assoc_req_ie, assoc_req_len, + assoc_resp_ie, assoc_resp_len, GFP_KERNEL); } } -- cgit v1.2.3-70-g09d2 From 6e786cb1e514dc87647beccaa96bd8a255d97a0c Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 15 Dec 2011 14:16:00 +0200 Subject: ath6kl: Fix connect command to clear previously used IEs Empty IE buffer means that the new association is not supposed to include extra IEs. Make sure any previously configured (Re)Association Request frame IEs get cleared in such a case. This is based on a patch from Shuibing. Cc: Dai Shuibing Signed-off-by: Jouni Malinen Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 85c24dd0156..1a06a04c510 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -461,13 +461,13 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, } } - if (sme->ie && (sme->ie_len > 0)) { - status = ath6kl_set_assoc_req_ies(vif, sme->ie, sme->ie_len); - if (status) { - up(&ar->sem); - return status; - } - } else + status = ath6kl_set_assoc_req_ies(vif, sme->ie, sme->ie_len); + if (status) { + up(&ar->sem); + return status; + } + + if (sme->ie == NULL || sme->ie_len == 0) ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG; if (test_bit(CONNECTED, &vif->flags) && -- cgit v1.2.3-70-g09d2 From ca1d16a08fc2c26b693e65ad92fa37a4c778e60d Mon Sep 17 00:00:00 2001 From: Raja Mani Date: Fri, 16 Dec 2011 14:24:23 +0530 Subject: ath6kl: Avoid taking struct as argument in ath6kl_wmi_set_ip_cmd In this way, caller is free to pass only the value of IP addr to configure. In addition to this, * 'ips' variable data type in struct wmi_set_ip_cmd is changed from __le32 to __be32 in order to match network byte order. * ipv4_is_multicast() is used to validate multicast ip addr. * New argument if_idx is added to supply correct vif index to ath6kl_wmi_cmd_send(). This will be used in the next patch. Signed-off-by: Raja Mani Signed-off-by: Thirumalai Pachamuthu Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/wmi.c | 12 +++++++----- drivers/net/wireless/ath/ath6kl/wmi.h | 5 +++-- 2 files changed, 10 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index f6f2aa27fc2..1e31c38abb4 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -2479,15 +2479,16 @@ int ath6kl_wmi_delete_pstream_cmd(struct wmi *wmi, u8 if_idx, u8 traffic_class, return ret; } -int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd) +int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, u8 if_idx, + __be32 ips0, __be32 ips1) { struct sk_buff *skb; struct wmi_set_ip_cmd *cmd; int ret; /* Multicast address are not valid */ - if ((*((u8 *) &ip_cmd->ips[0]) >= 0xE0) || - (*((u8 *) &ip_cmd->ips[1]) >= 0xE0)) + if (ipv4_is_multicast(ips0) || + ipv4_is_multicast(ips1)) return -EINVAL; skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_set_ip_cmd)); @@ -2495,9 +2496,10 @@ int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd) return -ENOMEM; cmd = (struct wmi_set_ip_cmd *) skb->data; - memcpy(cmd, ip_cmd, sizeof(struct wmi_set_ip_cmd)); + cmd->ips[0] = ips0; + cmd->ips[1] = ips1; - ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_IP_CMDID, + ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_IP_CMDID, NO_SYNC_WMIFLAG); return ret; } diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index 42ac311eda4..96e3cc10cab 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -1903,7 +1903,7 @@ struct wow_filter { struct wmi_set_ip_cmd { /* IP in network byte order */ - __le32 ips[MAX_IP_ADDRS]; + __be32 ips[MAX_IP_ADDRS]; } __packed; enum ath6kl_wow_filters { @@ -2417,7 +2417,8 @@ int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len); s32 ath6kl_wmi_get_rate(s8 rate_index); -int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd); +int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, u8 if_idx, + __be32 ips0, __be32 ips1); int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx, enum ath6kl_host_mode host_mode); int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx, -- cgit v1.2.3-70-g09d2 From c08631c6e43e7ce91bca6b2d3466bb22a85fe724 Mon Sep 17 00:00:00 2001 From: Raja Mani Date: Fri, 16 Dec 2011 14:24:24 +0530 Subject: ath6kl: Send own IP addr to the firmware during WOW suspend Firmware ARP module requires own IP addr in order to respond to the outside world when the target is in WOW suspend state. At present, firmware ARP module has capability to hold 2 IP addr. So, WOW mode will be disabled if the total IP addr configured in net_dev for our device is greater than firmware limit (MAX_IP_ADDRS) which is 2 at this moment. Signed-off-by: Raja Mani Signed-off-by: Thirumalai Pachamuthu Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 33 +++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 1a06a04c510..45b0d974e4f 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -15,6 +15,7 @@ */ #include +#include #include "core.h" #include "cfg80211.h" @@ -1729,11 +1730,14 @@ static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) { + struct in_device *in_dev; + struct in_ifaddr *ifa; struct ath6kl_vif *vif; int ret, pos, left; u32 filter = 0; u16 i; - u8 mask[WOW_MASK_SIZE]; + u8 mask[WOW_MASK_SIZE], index = 0; + __be32 ips[MAX_IP_ADDRS]; vif = ath6kl_vif_first(ar); if (!vif) @@ -1780,6 +1784,33 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) return ret; } + /* Setup own IP addr for ARP agent. */ + in_dev = __in_dev_get_rtnl(vif->ndev); + if (!in_dev) + goto skip_arp; + + ifa = in_dev->ifa_list; + memset(&ips, 0, sizeof(ips)); + + /* Configure IP addr only if IP address count < MAX_IP_ADDRS */ + while (index < MAX_IP_ADDRS && ifa) { + ips[index] = ifa->ifa_local; + ifa = ifa->ifa_next; + index++; + } + + if (ifa) { + ath6kl_err("total IP addr count is exceeding fw limit\n"); + return -EINVAL; + } + + ret = ath6kl_wmi_set_ip_cmd(ar->wmi, vif->fw_vif_idx, ips[0], ips[1]); + if (ret) { + ath6kl_err("fail to setup ip for arp agent\n"); + return ret; + } + +skip_arp: if (wow->disconnect) filter |= WOW_FILTER_OPTION_NWK_DISASSOC; -- cgit v1.2.3-70-g09d2 From c0038972b1253ad7f3ab7cc35ed57a830f5c8568 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Fri, 16 Dec 2011 20:53:31 +0200 Subject: ath6kl: handle firmware names more dynamically Currently ath6kl has just hardcoded paths to each firmware file. Change this more dynamic by separating the the directory and file name from each other. That way it's easier to dynamically create full paths to firmware and code looks better. And now it's possible to remove a function needed by devicetree code. While at it add a structure inside struct ath6kl_hw to contain all firmware names. I deliberately omitted board file support as those will be handled later. This is needed for firmware API 3. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/core.h | 45 +++++++++------- drivers/net/wireless/ath/ath6kl/init.c | 95 ++++++++++++++++++---------------- drivers/net/wireless/ath/ath6kl/sdio.c | 16 +++--- drivers/net/wireless/ath/ath6kl/usb.c | 5 +- 4 files changed, 87 insertions(+), 74 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index c863a28f2e0..26795771256 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -97,45 +97,46 @@ struct ath6kl_fw_ie { u8 data[0]; }; +#define ATH6KL_FW_API2_FILE "fw-2.bin" + /* AR6003 1.0 definitions */ #define AR6003_HW_1_0_VERSION 0x300002ba /* AR6003 2.0 definitions */ #define AR6003_HW_2_0_VERSION 0x30000384 #define AR6003_HW_2_0_PATCH_DOWNLOAD_ADDRESS 0x57e910 -#define AR6003_HW_2_0_OTP_FILE "ath6k/AR6003/hw2.0/otp.bin.z77" -#define AR6003_HW_2_0_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athwlan.bin.z77" -#define AR6003_HW_2_0_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athtcmd_ram.bin" -#define AR6003_HW_2_0_PATCH_FILE "ath6k/AR6003/hw2.0/data.patch.bin" -#define AR6003_HW_2_0_FIRMWARE_2_FILE "ath6k/AR6003/hw2.0/fw-2.bin" +#define AR6003_HW_2_0_FW_DIR "ath6k/AR6003/hw2.0" +#define AR6003_HW_2_0_OTP_FILE "otp.bin.z77" +#define AR6003_HW_2_0_FIRMWARE_FILE "athwlan.bin.z77" +#define AR6003_HW_2_0_TCMD_FIRMWARE_FILE "athtcmd_ram.bin" +#define AR6003_HW_2_0_PATCH_FILE "data.patch.bin" #define AR6003_HW_2_0_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.bin" #define AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE \ "ath6k/AR6003/hw2.0/bdata.SD31.bin" /* AR6003 3.0 definitions */ #define AR6003_HW_2_1_1_VERSION 0x30000582 -#define AR6003_HW_2_1_1_OTP_FILE "ath6k/AR6003/hw2.1.1/otp.bin" -#define AR6003_HW_2_1_1_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/athwlan.bin" -#define AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE \ - "ath6k/AR6003/hw2.1.1/athtcmd_ram.bin" -#define AR6003_HW_2_1_1_PATCH_FILE "ath6k/AR6003/hw2.1.1/data.patch.bin" -#define AR6003_HW_2_1_1_FIRMWARE_2_FILE "ath6k/AR6003/hw2.1.1/fw-2.bin" +#define AR6003_HW_2_1_1_FW_DIR "ath6k/AR6003/hw2.1.1" +#define AR6003_HW_2_1_1_OTP_FILE "otp.bin" +#define AR6003_HW_2_1_1_FIRMWARE_FILE "athwlan.bin" +#define AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE "athtcmd_ram.bin" +#define AR6003_HW_2_1_1_PATCH_FILE "data.patch.bin" #define AR6003_HW_2_1_1_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.bin" #define AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE \ "ath6k/AR6003/hw2.1.1/bdata.SD31.bin" /* AR6004 1.0 definitions */ #define AR6004_HW_1_0_VERSION 0x30000623 -#define AR6004_HW_1_0_FIRMWARE_2_FILE "ath6k/AR6004/hw1.0/fw-2.bin" -#define AR6004_HW_1_0_FIRMWARE_FILE "ath6k/AR6004/hw1.0/fw.ram.bin" +#define AR6004_HW_1_0_FW_DIR "ath6k/AR6004/hw1.0" +#define AR6004_HW_1_0_FIRMWARE_FILE "fw.ram.bin" #define AR6004_HW_1_0_BOARD_DATA_FILE "ath6k/AR6004/hw1.0/bdata.bin" #define AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE \ "ath6k/AR6004/hw1.0/bdata.DB132.bin" /* AR6004 1.1 definitions */ #define AR6004_HW_1_1_VERSION 0x30000001 -#define AR6004_HW_1_1_FIRMWARE_2_FILE "ath6k/AR6004/hw1.1/fw-2.bin" -#define AR6004_HW_1_1_FIRMWARE_FILE "ath6k/AR6004/hw1.1/fw.ram.bin" +#define AR6004_HW_1_1_FW_DIR "ath6k/AR6004/hw1.1" +#define AR6004_HW_1_1_FIRMWARE_FILE "fw.ram.bin" #define AR6004_HW_1_1_BOARD_DATA_FILE "ath6k/AR6004/hw1.1/bdata.bin" #define AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE \ "ath6k/AR6004/hw1.1/bdata.DB132.bin" @@ -575,11 +576,15 @@ struct ath6kl { u32 refclk_hz; u32 uarttx_pin; - const char *fw_otp; - const char *fw; - const char *fw_tcmd; - const char *fw_patch; - const char *fw_api2; + struct ath6kl_hw_fw { + const char *dir; + const char *otp; + const char *fw; + const char *tcmd; + const char *patch; + const char *api2; + } fw; + const char *fw_board; const char *fw_default_board; } hw; diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 368ecbd172a..7b802e99851 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -47,11 +47,15 @@ static const struct ath6kl_hw hw_list[] = { /* hw2.0 needs override address hardcoded */ .app_start_override_addr = 0x944C00, - .fw_otp = AR6003_HW_2_0_OTP_FILE, - .fw = AR6003_HW_2_0_FIRMWARE_FILE, - .fw_tcmd = AR6003_HW_2_0_TCMD_FIRMWARE_FILE, - .fw_patch = AR6003_HW_2_0_PATCH_FILE, - .fw_api2 = AR6003_HW_2_0_FIRMWARE_2_FILE, + .fw = { + .dir = AR6003_HW_2_0_FW_DIR, + .otp = AR6003_HW_2_0_OTP_FILE, + .fw = AR6003_HW_2_0_FIRMWARE_FILE, + .tcmd = AR6003_HW_2_0_TCMD_FIRMWARE_FILE, + .patch = AR6003_HW_2_0_PATCH_FILE, + .api2 = ATH6KL_FW_API2_FILE, + }, + .fw_board = AR6003_HW_2_0_BOARD_DATA_FILE, .fw_default_board = AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE, }, @@ -65,11 +69,15 @@ static const struct ath6kl_hw hw_list[] = { .refclk_hz = 26000000, .uarttx_pin = 8, - .fw_otp = AR6003_HW_2_1_1_OTP_FILE, - .fw = AR6003_HW_2_1_1_FIRMWARE_FILE, - .fw_tcmd = AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE, - .fw_patch = AR6003_HW_2_1_1_PATCH_FILE, - .fw_api2 = AR6003_HW_2_1_1_FIRMWARE_2_FILE, + .fw = { + .dir = AR6003_HW_2_1_1_FW_DIR, + .otp = AR6003_HW_2_1_1_OTP_FILE, + .fw = AR6003_HW_2_1_1_FIRMWARE_FILE, + .tcmd = AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE, + .patch = AR6003_HW_2_1_1_PATCH_FILE, + .api2 = ATH6KL_FW_API2_FILE, + }, + .fw_board = AR6003_HW_2_1_1_BOARD_DATA_FILE, .fw_default_board = AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE, }, @@ -84,8 +92,12 @@ static const struct ath6kl_hw hw_list[] = { .refclk_hz = 26000000, .uarttx_pin = 11, - .fw = AR6004_HW_1_0_FIRMWARE_FILE, - .fw_api2 = AR6004_HW_1_0_FIRMWARE_2_FILE, + .fw = { + .dir = AR6004_HW_1_0_FW_DIR, + .fw = AR6004_HW_1_0_FIRMWARE_FILE, + .api2 = ATH6KL_FW_API2_FILE, + }, + .fw_board = AR6004_HW_1_0_BOARD_DATA_FILE, .fw_default_board = AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE, }, @@ -100,8 +112,12 @@ static const struct ath6kl_hw hw_list[] = { .refclk_hz = 40000000, .uarttx_pin = 11, - .fw = AR6004_HW_1_1_FIRMWARE_FILE, - .fw_api2 = AR6004_HW_1_1_FIRMWARE_2_FILE, + .fw = { + .dir = AR6004_HW_1_1_FW_DIR, + .fw = AR6004_HW_1_1_FIRMWARE_FILE, + .api2 = ATH6KL_FW_API2_FILE, + }, + .fw_board = AR6004_HW_1_1_BOARD_DATA_FILE, .fw_default_board = AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE, }, @@ -626,21 +642,6 @@ static int ath6kl_get_fw(struct ath6kl *ar, const char *filename, } #ifdef CONFIG_OF -static const char *get_target_ver_dir(const struct ath6kl *ar) -{ - switch (ar->version.target_ver) { - case AR6003_HW_1_0_VERSION: - return "ath6k/AR6003/hw1.0"; - case AR6003_HW_2_0_VERSION: - return "ath6k/AR6003/hw2.0"; - case AR6003_HW_2_1_1_VERSION: - return "ath6k/AR6003/hw2.1.1"; - } - ath6kl_warn("%s: unsupported target version 0x%x.\n", __func__, - ar->version.target_ver); - return NULL; -} - /* * Check the device tree for a board-id and use it to construct * the pathname to the firmware file. Used (for now) to find a @@ -663,7 +664,7 @@ static bool check_device_tree(struct ath6kl *ar) continue; } snprintf(board_filename, sizeof(board_filename), - "%s/bdata.%s.bin", get_target_ver_dir(ar), board_id); + "%s/bdata.%s.bin", ar->hw.fw.dir, board_id); ret = ath6kl_get_fw(ar, board_filename, &ar->fw_board, &ar->fw_board_len); @@ -730,19 +731,20 @@ static int ath6kl_fetch_board_file(struct ath6kl *ar) static int ath6kl_fetch_otp_file(struct ath6kl *ar) { - const char *filename; + char filename[100]; int ret; if (ar->fw_otp != NULL) return 0; - if (ar->hw.fw_otp == NULL) { + if (ar->hw.fw.otp == NULL) { ath6kl_dbg(ATH6KL_DBG_BOOT, "no OTP file configured for this hw\n"); return 0; } - filename = ar->hw.fw_otp; + snprintf(filename, sizeof(filename), "%s/%s", + ar->hw.fw.dir, ar->hw.fw.otp); ret = ath6kl_get_fw(ar, filename, &ar->fw_otp, &ar->fw_otp_len); @@ -757,29 +759,32 @@ static int ath6kl_fetch_otp_file(struct ath6kl *ar) static int ath6kl_fetch_fw_file(struct ath6kl *ar) { - const char *filename; + char filename[100]; int ret; if (ar->fw != NULL) return 0; if (testmode) { - if (ar->hw.fw_tcmd == NULL) { + if (ar->hw.fw.tcmd == NULL) { ath6kl_warn("testmode not supported\n"); return -EOPNOTSUPP; } - filename = ar->hw.fw_tcmd; + snprintf(filename, sizeof(filename), "%s/%s", + ar->hw.fw.dir, ar->hw.fw.tcmd); set_bit(TESTMODE, &ar->flag); goto get_fw; } - if (WARN_ON(ar->hw.fw == NULL)) + /* FIXME: remove WARN_ON() as we won't support FW API 1 for long */ + if (WARN_ON(ar->hw.fw.fw == NULL)) return -EINVAL; - filename = ar->hw.fw; + snprintf(filename, sizeof(filename), "%s/%s", + ar->hw.fw.dir, ar->hw.fw.fw); get_fw: ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len); @@ -794,16 +799,17 @@ get_fw: static int ath6kl_fetch_patch_file(struct ath6kl *ar) { - const char *filename; + char filename[100]; int ret; if (ar->fw_patch != NULL) return 0; - if (ar->hw.fw_patch == NULL) + if (ar->hw.fw.patch == NULL) return 0; - filename = ar->hw.fw_patch; + snprintf(filename, sizeof(filename), "%s/%s", + ar->hw.fw.dir, ar->hw.fw.patch); ret = ath6kl_get_fw(ar, filename, &ar->fw_patch, &ar->fw_patch_len); @@ -840,15 +846,16 @@ static int ath6kl_fetch_fw_api2(struct ath6kl *ar) size_t magic_len, len, ie_len; const struct firmware *fw; struct ath6kl_fw_ie *hdr; - const char *filename; + char filename[100]; const u8 *data; int ret, ie_id, i, index, bit; __le32 *val; - if (ar->hw.fw_api2 == NULL) + if (ar->hw.fw.api2 == NULL) return -EOPNOTSUPP; - filename = ar->hw.fw_api2; + snprintf(filename, sizeof(filename), "%s/%s", + ar->hw.fw.dir, ar->hw.fw.api2); ret = request_firmware(&fw, filename, ar->dev); if (ret) diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index 15c3f56caf4..278a9f30795 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -1362,19 +1362,19 @@ MODULE_AUTHOR("Atheros Communications, Inc."); MODULE_DESCRIPTION("Driver support for Atheros AR600x SDIO devices"); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_FIRMWARE(AR6003_HW_2_0_OTP_FILE); -MODULE_FIRMWARE(AR6003_HW_2_0_FIRMWARE_FILE); -MODULE_FIRMWARE(AR6003_HW_2_0_PATCH_FILE); +MODULE_FIRMWARE(AR6003_HW_2_0_FW_DIR "/" AR6003_HW_2_0_OTP_FILE); +MODULE_FIRMWARE(AR6003_HW_2_0_FW_DIR "/" AR6003_HW_2_0_FIRMWARE_FILE); +MODULE_FIRMWARE(AR6003_HW_2_0_FW_DIR "/" AR6003_HW_2_0_PATCH_FILE); MODULE_FIRMWARE(AR6003_HW_2_0_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE); -MODULE_FIRMWARE(AR6003_HW_2_1_1_OTP_FILE); -MODULE_FIRMWARE(AR6003_HW_2_1_1_FIRMWARE_FILE); -MODULE_FIRMWARE(AR6003_HW_2_1_1_PATCH_FILE); +MODULE_FIRMWARE(AR6003_HW_2_1_1_FW_DIR "/" AR6003_HW_2_1_1_OTP_FILE); +MODULE_FIRMWARE(AR6003_HW_2_1_1_FW_DIR "/" AR6003_HW_2_1_1_FIRMWARE_FILE); +MODULE_FIRMWARE(AR6003_HW_2_1_1_FW_DIR "/" AR6003_HW_2_1_1_PATCH_FILE); MODULE_FIRMWARE(AR6003_HW_2_1_1_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE); -MODULE_FIRMWARE(AR6004_HW_1_0_FIRMWARE_FILE); +MODULE_FIRMWARE(AR6004_HW_1_0_FW_DIR "/" AR6004_HW_1_0_FIRMWARE_FILE); MODULE_FIRMWARE(AR6004_HW_1_0_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE); -MODULE_FIRMWARE(AR6004_HW_1_1_FIRMWARE_FILE); +MODULE_FIRMWARE(AR6004_HW_1_1_FW_DIR "/" AR6004_HW_1_1_FIRMWARE_FILE); MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE); diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c index e3cf397fcaf..bb341796dc8 100644 --- a/drivers/net/wireless/ath/ath6kl/usb.c +++ b/drivers/net/wireless/ath/ath6kl/usb.c @@ -423,9 +423,10 @@ module_exit(ath6kl_usb_exit); MODULE_AUTHOR("Atheros Communications, Inc."); MODULE_DESCRIPTION("Driver support for Atheros AR600x USB devices"); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_FIRMWARE(AR6004_HW_1_0_FIRMWARE_FILE); + +MODULE_FIRMWARE(AR6004_HW_1_0_FW_DIR "/" AR6004_HW_1_0_FIRMWARE_FILE); MODULE_FIRMWARE(AR6004_HW_1_0_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE); -MODULE_FIRMWARE(AR6004_HW_1_1_FIRMWARE_FILE); +MODULE_FIRMWARE(AR6004_HW_1_1_FW_DIR "/" AR6004_HW_1_1_FIRMWARE_FILE); MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE); -- cgit v1.2.3-70-g09d2 From 65a8b4cc511b68712799e91137324f2abece7d3e Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Fri, 16 Dec 2011 20:53:41 +0200 Subject: ath6kl: add support for FW API 3 As firmware starting from 3.2.0.12 has some API changes and doesn't work with older versions of ath6kl we need to bump up the API version. This way we don't break anything. Also store which version of API is used and print that during boot: ath6kl: ar6003 hw 2.1.1 sdio fw 3.2.0.13 api 3 Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/core.h | 3 ++- drivers/net/wireless/ath/ath6kl/init.c | 32 +++++++++++++++++--------------- 2 files changed, 19 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 26795771256..c095fafa278 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -98,6 +98,7 @@ struct ath6kl_fw_ie { }; #define ATH6KL_FW_API2_FILE "fw-2.bin" +#define ATH6KL_FW_API3_FILE "fw-3.bin" /* AR6003 1.0 definitions */ #define AR6003_HW_1_0_VERSION 0x300002ba @@ -582,7 +583,6 @@ struct ath6kl { const char *fw; const char *tcmd; const char *patch; - const char *api2; } fw; const char *fw_board; @@ -608,6 +608,7 @@ struct ath6kl { u8 *fw_patch; size_t fw_patch_len; + unsigned int fw_api; unsigned long fw_capabilities[ATH6KL_CAPABILITY_LEN]; struct workqueue_struct *ath6kl_wq; diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 7b802e99851..57e0312c4cb 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -53,7 +53,6 @@ static const struct ath6kl_hw hw_list[] = { .fw = AR6003_HW_2_0_FIRMWARE_FILE, .tcmd = AR6003_HW_2_0_TCMD_FIRMWARE_FILE, .patch = AR6003_HW_2_0_PATCH_FILE, - .api2 = ATH6KL_FW_API2_FILE, }, .fw_board = AR6003_HW_2_0_BOARD_DATA_FILE, @@ -75,7 +74,6 @@ static const struct ath6kl_hw hw_list[] = { .fw = AR6003_HW_2_1_1_FIRMWARE_FILE, .tcmd = AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE, .patch = AR6003_HW_2_1_1_PATCH_FILE, - .api2 = ATH6KL_FW_API2_FILE, }, .fw_board = AR6003_HW_2_1_1_BOARD_DATA_FILE, @@ -95,7 +93,6 @@ static const struct ath6kl_hw hw_list[] = { .fw = { .dir = AR6004_HW_1_0_FW_DIR, .fw = AR6004_HW_1_0_FIRMWARE_FILE, - .api2 = ATH6KL_FW_API2_FILE, }, .fw_board = AR6004_HW_1_0_BOARD_DATA_FILE, @@ -115,7 +112,6 @@ static const struct ath6kl_hw hw_list[] = { .fw = { .dir = AR6004_HW_1_1_FW_DIR, .fw = AR6004_HW_1_1_FIRMWARE_FILE, - .api2 = ATH6KL_FW_API2_FILE, }, .fw_board = AR6004_HW_1_1_BOARD_DATA_FILE, @@ -841,7 +837,7 @@ static int ath6kl_fetch_fw_api1(struct ath6kl *ar) return 0; } -static int ath6kl_fetch_fw_api2(struct ath6kl *ar) +static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name) { size_t magic_len, len, ie_len; const struct firmware *fw; @@ -851,11 +847,7 @@ static int ath6kl_fetch_fw_api2(struct ath6kl *ar) int ret, ie_id, i, index, bit; __le32 *val; - if (ar->hw.fw.api2 == NULL) - return -EOPNOTSUPP; - - snprintf(filename, sizeof(filename), "%s/%s", - ar->hw.fw.dir, ar->hw.fw.api2); + snprintf(filename, sizeof(filename), "%s/%s", ar->hw.fw.dir, name); ret = request_firmware(&fw, filename, ar->dev); if (ret) @@ -1025,17 +1017,26 @@ static int ath6kl_fetch_firmwares(struct ath6kl *ar) if (ret) return ret; - ret = ath6kl_fetch_fw_api2(ar); + ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API3_FILE); if (ret == 0) { - ath6kl_dbg(ATH6KL_DBG_BOOT, "using fw api 2\n"); - return 0; + ar->fw_api = 3; + goto out; + } + + ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API2_FILE); + if (ret == 0) { + ar->fw_api = 2; + goto out; } ret = ath6kl_fetch_fw_api1(ar); if (ret) return ret; - ath6kl_dbg(ATH6KL_DBG_BOOT, "using fw api 1\n"); + ar->fw_api = 1; + +out: + ath6kl_dbg(ATH6KL_DBG_BOOT, "using fw api %d\n", ar->fw_api); return 0; } @@ -1488,10 +1489,11 @@ int ath6kl_init_hw_start(struct ath6kl *ar) if (test_and_clear_bit(FIRST_BOOT, &ar->flag)) { - ath6kl_info("%s %s fw %s%s\n", + ath6kl_info("%s %s fw %s api %d%s\n", ar->hw.name, ath6kl_init_get_hif_name(ar->hif_type), ar->wiphy->fw_version, + ar->fw_api, test_bit(TESTMODE, &ar->flag) ? " testmode" : ""); } -- cgit v1.2.3-70-g09d2 From e68f67509d92114c55938898643600c23f88b4c1 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Thu, 22 Dec 2011 12:15:27 +0530 Subject: ath6kl: Fix panic when setting a channel cfg80211 could pass a NULL net_device to the driver via the set_channel() callback, when it receives a request to set the device's channel. Not handling this case properly results in this panic: BUG: unable to handle kernel NULL pointer dereference at 0000000000000cb0 IP: [] ath6kl_cfg80211_ready+0x9/0x70 [ath6kl_sdio] Call Trace: [] ath6kl_set_channel+0x27/0x90 [ath6kl_sdio] [] cfg80211_set_freq+0xff/0x1d0 [cfg80211] [] ? nl80211_set_wiphy+0x85/0x660 [cfg80211] [] __nl80211_set_channel.isra.39+0x118/0x140 [cfg80211] [] nl80211_set_wiphy+0x303/0x660 [cfg80211] [] ? rtnl_lock+0x17/0x20 [] ? nl80211_pre_doit+0xb5/0x150 [cfg80211] [] genl_rcv_msg+0x1d5/0x250 [] ? genl_rcv+0x40/0x40 [] netlink_rcv_skb+0xa9/0xd0 [] genl_rcv+0x25/0x40 [] ? might_fault+0x40/0x90 [] netlink_unicast+0x2d9/0x320 [] netlink_sendmsg+0x2c6/0x320 [] ? sock_update_classid+0xb0/0x110 [] sock_sendmsg+0x10e/0x130 [] ? mem_cgroup_update_page_stat+0x193/0x250 [] ? might_fault+0x40/0x90 [] ? might_fault+0x40/0x90 [] ? might_fault+0x89/0x90 [] ? might_fault+0x40/0x90 [] ? verify_iovec+0x56/0xd0 [] __sys_sendmsg+0x396/0x3b0 [] ? up_read+0x23/0x40 [] ? do_page_fault+0x208/0x4e0 [] ? vfsmount_lock_local_unlock+0x21/0x60 [] ? mntput_no_expire+0x30/0xe0 [] ? mntput+0x1f/0x30 [] sys_sendmsg+0x49/0x90 [] system_call_fastpath+0x16/0x1b Signed-off-by: Sujith Manoharan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 45b0d974e4f..d6806be5895 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -2044,7 +2044,18 @@ static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type) { - struct ath6kl_vif *vif = netdev_priv(dev); + struct ath6kl_vif *vif; + + /* + * 'dev' could be NULL if a channel change is required for the hardware + * device itself, instead of a particular VIF. + * + * FIXME: To be handled properly when monitor mode is supported. + */ + if (!dev) + return -EBUSY; + + vif = netdev_priv(dev); if (!ath6kl_cfg80211_ready(vif)) return -EIO; -- cgit v1.2.3-70-g09d2 From 33e5308d8a0fb857a57c38def36ccf7b14ebf1c1 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 27 Dec 2011 11:02:56 +0200 Subject: ath6kl: Add del_station cfg80211_ops hostapd/wpa_supplicant AP mode uses this operation to flush the station entries. Implement this in ath6kl to avoid unnecessary warnings from NL80211_CMD_DEL_STATION failing. Signed-off-by: Jouni Malinen Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index d6806be5895..f74762ed619 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -2300,6 +2300,19 @@ static int ath6kl_del_beacon(struct wiphy *wiphy, struct net_device *dev) return 0; } +static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + +static int ath6kl_del_station(struct wiphy *wiphy, struct net_device *dev, + u8 *mac) +{ + struct ath6kl *ar = ath6kl_priv(dev); + struct ath6kl_vif *vif = netdev_priv(dev); + const u8 *addr = mac ? mac : bcast_addr; + + return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx, WMI_AP_DEAUTH, + addr, WLAN_REASON_PREV_AUTH_NOT_VALID); +} + static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev, u8 *mac, struct station_parameters *params) { @@ -2603,6 +2616,7 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = { .add_beacon = ath6kl_add_beacon, .set_beacon = ath6kl_set_beacon, .del_beacon = ath6kl_del_beacon, + .del_station = ath6kl_del_station, .change_station = ath6kl_change_station, .remain_on_channel = ath6kl_remain_on_channel, .cancel_remain_on_channel = ath6kl_cancel_remain_on_channel, -- cgit v1.2.3-70-g09d2 From ba1f6fe393c329230d2589ea508cbf90ff3cc9ce Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 27 Dec 2011 11:03:53 +0200 Subject: ath6kl: Advertise TX/RX support for frames in AP mode This is needed to fix current hostapd/wpa_supplicant AP operations for frame registration. P2P GO mode already advertised these, but AP mode was forgotten and could not be used after the hostapd/wpa_supplicant frame registration changes. Signed-off-by: Jouni Malinen Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index f74762ed619..c756425abf7 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -2572,6 +2572,12 @@ ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = { .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) }, + [NL80211_IFTYPE_AP] = { + .tx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_RESP >> 4), + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) + }, [NL80211_IFTYPE_P2P_CLIENT] = { .tx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_RESP >> 4), -- cgit v1.2.3-70-g09d2 From bc48ad31c5814feb4ff8faca9a8d422279593cb1 Mon Sep 17 00:00:00 2001 From: Rishi Panjwani Date: Tue, 27 Dec 2011 14:28:00 -0800 Subject: ath6kl: Support for TCP checksum offload to firmware The change enables offloading TCP checksum calculation to firmware. There are still some issues with the checksum offload so better to disable it by default until the issues are resolved. To enable TCP checksum offload for tx and rx paths, use the ethtool as follows: ethtool -K tx on ethtool -K rx on To disable TCP checksum offload, for tx and rx paths, use the ethtool as follows: ethtool -K tx off ethtool -K rx off kvalo: indentation changes Signed-off-by: Rishi Panjwani Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/init.c | 2 ++ drivers/net/wireless/ath/ath6kl/main.c | 33 +++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath6kl/txrx.c | 38 ++++++++++++++++++++++++++++++---- drivers/net/wireless/ath/ath6kl/wmi.h | 3 +++ 4 files changed, 72 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 57e0312c4cb..e74279372ef 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -1686,6 +1686,8 @@ int ath6kl_core_init(struct ath6kl *ar) set_bit(FIRST_BOOT, &ar->flag); + ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM; + ret = ath6kl_init_hw_start(ar); if (ret) { ath6kl_err("Failed to start hardware: %d\n", ret); diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index eea3c747653..f3d0184a5ce 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -1020,11 +1020,44 @@ static struct net_device_stats *ath6kl_get_stats(struct net_device *dev) return &vif->net_stats; } +static int ath6kl_set_features(struct net_device *dev, u32 features) +{ + struct ath6kl_vif *vif = netdev_priv(dev); + struct ath6kl *ar = vif->ar; + int err = 0; + + if ((features & NETIF_F_RXCSUM) && + (ar->rx_meta_ver != WMI_META_VERSION_2)) { + ar->rx_meta_ver = WMI_META_VERSION_2; + err = ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi, + vif->fw_vif_idx, + ar->rx_meta_ver, 0, 0); + if (err) { + dev->features = features & ~NETIF_F_RXCSUM; + return err; + } + } else if (!(features & NETIF_F_RXCSUM) && + (ar->rx_meta_ver == WMI_META_VERSION_2)) { + ar->rx_meta_ver = 0; + err = ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi, + vif->fw_vif_idx, + ar->rx_meta_ver, 0, 0); + if (err) { + dev->features = features | NETIF_F_RXCSUM; + return err; + } + + } + + return err; +} + static struct net_device_ops ath6kl_netdev_ops = { .ndo_open = ath6kl_open, .ndo_stop = ath6kl_close, .ndo_start_xmit = ath6kl_data_tx, .ndo_get_stats = ath6kl_get_stats, + .ndo_set_features = ath6kl_set_features, }; void init_netdev(struct net_device *dev) diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index 506a3031a88..78bd57306f7 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -244,6 +244,10 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) u8 ac = 99 ; /* initialize to unmapped ac */ bool chk_adhoc_ps_mapping = false, more_data = false; int ret; + struct wmi_tx_meta_v2 meta_v2; + void *meta; + u8 csum_start = 0, csum_dest = 0, csum = skb->ip_summed; + u8 meta_ver = 0; ath6kl_dbg(ATH6KL_DBG_WLAN_TX, "%s: skb=0x%p, data=0x%p, len=0x%x\n", __func__, @@ -265,6 +269,14 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) } if (test_bit(WMI_ENABLED, &ar->flag)) { + if ((dev->features & NETIF_F_IP_CSUM) && + (csum == CHECKSUM_PARTIAL)) { + csum_start = skb->csum_start - + (skb_network_header(skb) - skb->head) + + sizeof(struct ath6kl_llc_snap_hdr); + csum_dest = skb->csum_offset + csum_start; + } + if (skb_headroom(skb) < dev->needed_headroom) { struct sk_buff *tmp_skb = skb; @@ -281,10 +293,28 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) goto fail_tx; } - if (ath6kl_wmi_data_hdr_add(ar->wmi, skb, DATA_MSGTYPE, - more_data, 0, 0, NULL, - vif->fw_vif_idx)) { - ath6kl_err("wmi_data_hdr_add failed\n"); + if ((dev->features & NETIF_F_IP_CSUM) && + (csum == CHECKSUM_PARTIAL)) { + meta_v2.csum_start = csum_start; + meta_v2.csum_dest = csum_dest; + + /* instruct target to calculate checksum */ + meta_v2.csum_flags = WMI_META_V2_FLAG_CSUM_OFFLOAD; + meta_ver = WMI_META_VERSION_2; + meta = &meta_v2; + } else { + meta_ver = 0; + meta = NULL; + } + + ret = ath6kl_wmi_data_hdr_add(ar->wmi, skb, + DATA_MSGTYPE, more_data, 0, + meta_ver, + meta, vif->fw_vif_idx); + + if (ret) { + ath6kl_warn("failed to add wmi data header:%d\n" + , ret); goto fail_tx; } diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index 96e3cc10cab..9f8425b97db 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -257,6 +257,9 @@ static inline u8 wmi_data_hdr_get_if_idx(struct wmi_data_hdr *dhdr) #define WMI_META_VERSION_1 0x01 #define WMI_META_VERSION_2 0x02 +/* Flag to signal to FW to calculate TCP checksum */ +#define WMI_META_V2_FLAG_CSUM_OFFLOAD 0x01 + struct wmi_tx_meta_v1 { /* packet ID to identify the tx request */ u8 pkt_id; -- cgit v1.2.3-70-g09d2 From 351de2835d6429548feb8cca9a17497ec3474f41 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Thu, 29 Dec 2011 16:05:37 +0530 Subject: ath6kl: Remove few unnecessary spin_locks around set_bit() Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/txrx.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index 78bd57306f7..fcea82479cd 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -479,9 +479,7 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target, * WMI queue with too many commands the only exception to * this is during testing using endpointping. */ - spin_lock_bh(&ar->lock); set_bit(WMI_CTRL_EP_FULL, &ar->flag); - spin_unlock_bh(&ar->lock); ath6kl_err("wmi ctrl ep is full\n"); return action; } @@ -509,9 +507,7 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target, action != HTC_SEND_FULL_DROP) { spin_unlock_bh(&ar->list_lock); - spin_lock_bh(&vif->if_lock); set_bit(NETQ_STOPPED, &vif->flags); - spin_unlock_bh(&vif->if_lock); netif_stop_queue(vif->ndev); return action; -- cgit v1.2.3-70-g09d2 From a10e2f2f6db8f86eaca1cf3d00269463da4d6434 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Thu, 29 Dec 2011 16:05:38 +0530 Subject: ath6kl: Add a module parameter to enable uart debug To enable firmware debug messages through uart interface, modprobe ath6kl_sdio uart_debug=1. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/init.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index e74279372ef..a481b6a1715 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -28,10 +28,12 @@ unsigned int debug_mask; static unsigned int testmode; static bool suspend_cutpower; +static unsigned int uart_debug; module_param(debug_mask, uint, 0644); module_param(testmode, uint, 0644); module_param(suspend_cutpower, bool, 0444); +module_param(uart_debug, uint, 0644); static const struct ath6kl_hw hw_list[] = { { @@ -464,6 +466,13 @@ int ath6kl_configure_target(struct ath6kl *ar) u8 fw_iftype, fw_mode = 0, fw_submode = 0; int i, status; + param = uart_debug; + if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar, + HI_ITEM(hi_serial_enable)), (u8 *)¶m, 4)) { + ath6kl_err("bmi_write_memory for uart debug failed\n"); + return -EIO; + } + /* * Note: Even though the firmware interface type is * chosen as BSS_STA for all three interfaces, can -- cgit v1.2.3-70-g09d2 From 792ecb33080f4e315695e0fe21cf3a3c2a514dd0 Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Thu, 29 Dec 2011 16:18:39 +0530 Subject: ath6kl: Remove redundant key_index check. Less-than-zero comparison of an unsigned value is never true. kvalo: remove WMI_MIN_KEY_INDEX altogether, it's useless Signed-off-by: Vivek Natarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 11 +++++------ drivers/net/wireless/ath/ath6kl/main.c | 2 +- drivers/net/wireless/ath/ath6kl/wmi.h | 1 - 3 files changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index c756425abf7..2a166cc7cc3 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -524,8 +524,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, (vif->prwise_crypto == WEP_CRYPT)) { struct ath6kl_key *key = NULL; - if (sme->key_idx < WMI_MIN_KEY_INDEX || - sme->key_idx > WMI_MAX_KEY_INDEX) { + if (sme->key_idx > WMI_MAX_KEY_INDEX) { ath6kl_err("key index %d out of bounds\n", sme->key_idx); up(&ar->sem); @@ -997,7 +996,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, params->key); } - if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) { + if (key_index > WMI_MAX_KEY_INDEX) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: key index %d out of bounds\n", __func__, key_index); @@ -1115,7 +1114,7 @@ static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, if (!ath6kl_cfg80211_ready(vif)) return -EIO; - if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) { + if (key_index > WMI_MAX_KEY_INDEX) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: key index %d out of bounds\n", __func__, key_index); @@ -1148,7 +1147,7 @@ static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, if (!ath6kl_cfg80211_ready(vif)) return -EIO; - if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) { + if (key_index > WMI_MAX_KEY_INDEX) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: key index %d out of bounds\n", __func__, key_index); @@ -1184,7 +1183,7 @@ static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy, if (!ath6kl_cfg80211_ready(vif)) return -EIO; - if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) { + if (key_index > WMI_MAX_KEY_INDEX) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: key index %d out of bounds\n", __func__, key_index); diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index f3d0184a5ce..f74986d6209 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -363,7 +363,7 @@ static void ath6kl_install_static_wep_keys(struct ath6kl_vif *vif) u8 index; u8 keyusage; - for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) { + for (index = 0; index <= WMI_MAX_KEY_INDEX; index++) { if (vif->wep_key_list[index].key_len) { keyusage = GROUP_USAGE; if (index == vif->def_txkey_index) diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index 9f8425b97db..2b435994b01 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -649,7 +649,6 @@ enum auth_mode { WPA2_AUTH_CCKM = 0x40, }; -#define WMI_MIN_KEY_INDEX 0 #define WMI_MAX_KEY_INDEX 3 #define WMI_MAX_KEY_LEN 32 -- cgit v1.2.3-70-g09d2 From 4f34dacea117029dbad1f0f50d68207b97546d1e Mon Sep 17 00:00:00 2001 From: Thomas Pedersen Date: Fri, 30 Dec 2011 01:57:00 -0800 Subject: ath6kl: send TCMD response through testmode events ath6kl no longer knows what it is transmitting through cfg80211_testmode, and simply passes opaque buffers between userspace and the firmware. Leave the CONT_RX enum for backwards compatibility. kvalo: change ATH6KL_TM_CMD_RX_REPORT to return -EOPNOTSUPP Signed-off-by: Thomas Pedersen Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/testmode.c | 102 +++++------------------------ drivers/net/wireless/ath/ath6kl/testmode.h | 6 +- drivers/net/wireless/ath/ath6kl/wmi.c | 6 +- 3 files changed, 23 insertions(+), 91 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/testmode.c b/drivers/net/wireless/ath/ath6kl/testmode.c index 381eb66a605..f0cd61d6188 100644 --- a/drivers/net/wireless/ath/ath6kl/testmode.c +++ b/drivers/net/wireless/ath/ath6kl/testmode.c @@ -15,6 +15,7 @@ */ #include "testmode.h" +#include "debug.h" #include @@ -30,7 +31,7 @@ enum ath6kl_tm_attr { enum ath6kl_tm_cmd { ATH6KL_TM_CMD_TCMD = 0, - ATH6KL_TM_CMD_RX_REPORT = 1, + ATH6KL_TM_CMD_RX_REPORT = 1, /* not used anymore */ }; #define ATH6KL_TM_DATA_MAX_LEN 5000 @@ -41,84 +42,33 @@ static const struct nla_policy ath6kl_tm_policy[ATH6KL_TM_ATTR_MAX + 1] = { .len = ATH6KL_TM_DATA_MAX_LEN }, }; -void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf, size_t buf_len) +void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf, size_t buf_len) { - if (down_interruptible(&ar->sem)) - return; - - kfree(ar->tm.rx_report); - - ar->tm.rx_report = kmemdup(buf, buf_len, GFP_KERNEL); - ar->tm.rx_report_len = buf_len; - - up(&ar->sem); - - wake_up(&ar->event_wq); -} - -static int ath6kl_tm_rx_report(struct ath6kl *ar, void *buf, size_t buf_len, - struct sk_buff *skb) -{ - int ret = 0; - long left; - - if (down_interruptible(&ar->sem)) - return -ERESTARTSYS; - - if (!test_bit(WMI_READY, &ar->flag)) { - ret = -EIO; - goto out; - } - - if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) { - ret = -EBUSY; - goto out; - } - - if (ath6kl_wmi_test_cmd(ar->wmi, buf, buf_len) < 0) { - up(&ar->sem); - return -EIO; - } - - left = wait_event_interruptible_timeout(ar->event_wq, - ar->tm.rx_report != NULL, - WMI_TIMEOUT); + struct sk_buff *skb; - if (left == 0) { - ret = -ETIMEDOUT; - goto out; - } else if (left < 0) { - ret = left; - goto out; - } + if (!buf || buf_len == 0) + return; - if (ar->tm.rx_report == NULL || ar->tm.rx_report_len == 0) { - ret = -EINVAL; - goto out; + skb = cfg80211_testmode_alloc_event_skb(ar->wiphy, buf_len, GFP_KERNEL); + if (!skb) { + ath6kl_warn("failed to allocate testmode rx skb!\n"); + return; } - - NLA_PUT(skb, ATH6KL_TM_ATTR_DATA, ar->tm.rx_report_len, - ar->tm.rx_report); - - kfree(ar->tm.rx_report); - ar->tm.rx_report = NULL; - -out: - up(&ar->sem); - - return ret; + NLA_PUT_U32(skb, ATH6KL_TM_ATTR_CMD, ATH6KL_TM_CMD_TCMD); + NLA_PUT(skb, ATH6KL_TM_ATTR_DATA, buf_len, buf); + cfg80211_testmode_event(skb, GFP_KERNEL); + return; nla_put_failure: - ret = -ENOBUFS; - goto out; + kfree_skb(skb); + ath6kl_warn("nla_put failed on testmode rx skb!\n"); } int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len) { struct ath6kl *ar = wiphy_priv(wiphy); struct nlattr *tb[ATH6KL_TM_ATTR_MAX + 1]; - int err, buf_len, reply_len; - struct sk_buff *skb; + int err, buf_len; void *buf; err = nla_parse(tb, ATH6KL_TM_ATTR_MAX, data, len, @@ -143,24 +93,6 @@ int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len) break; case ATH6KL_TM_CMD_RX_REPORT: - if (!tb[ATH6KL_TM_ATTR_DATA]) - return -EINVAL; - - buf = nla_data(tb[ATH6KL_TM_ATTR_DATA]); - buf_len = nla_len(tb[ATH6KL_TM_ATTR_DATA]); - - reply_len = nla_total_size(ATH6KL_TM_DATA_MAX_LEN); - skb = cfg80211_testmode_alloc_reply_skb(wiphy, reply_len); - if (!skb) - return -ENOMEM; - - err = ath6kl_tm_rx_report(ar, buf, buf_len, skb); - if (err < 0) { - kfree_skb(skb); - return err; - } - - return cfg80211_testmode_reply(skb); default: return -EOPNOTSUPP; } diff --git a/drivers/net/wireless/ath/ath6kl/testmode.h b/drivers/net/wireless/ath/ath6kl/testmode.h index 43dffcc11fb..7fd47a62d07 100644 --- a/drivers/net/wireless/ath/ath6kl/testmode.h +++ b/drivers/net/wireless/ath/ath6kl/testmode.h @@ -18,13 +18,13 @@ #ifdef CONFIG_NL80211_TESTMODE -void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf, size_t buf_len); +void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf, size_t buf_len); int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len); #else -static inline void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf, - size_t buf_len) +static inline void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf, + size_t buf_len) { } diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 1e31c38abb4..c6ca660d270 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -1145,9 +1145,9 @@ static int ath6kl_wmi_bitrate_reply_rx(struct wmi *wmi, u8 *datap, int len) return 0; } -static int ath6kl_wmi_tcmd_test_report_rx(struct wmi *wmi, u8 *datap, int len) +static int ath6kl_wmi_test_rx(struct wmi *wmi, u8 *datap, int len) { - ath6kl_tm_rx_report_event(wmi->parent_dev, datap, len); + ath6kl_tm_rx_event(wmi->parent_dev, datap, len); return 0; } @@ -3402,7 +3402,7 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) break; case WMI_TEST_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TEST_EVENTID\n"); - ret = ath6kl_wmi_tcmd_test_report_rx(wmi, datap, len); + ret = ath6kl_wmi_test_rx(wmi, datap, len); break; case WMI_GET_FIXRATES_CMDID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_FIXRATES_CMDID\n"); -- cgit v1.2.3-70-g09d2 From cd42f4a3b2b1c4cbd997363dc57821953d73fd87 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Thu, 15 Dec 2011 10:48:12 -0800 Subject: HWPOISON: Clean up memory_failure() vs. __memory_failure() There is only one caller of memory_failure(), all other users call __memory_failure() and pass in the flags argument explicitly. The lone user of memory_failure() will soon need to pass flags too. Add flags argument to the callsite in mce.c. Delete the old memory_failure() function, and then rename __memory_failure() without the leading "__". Provide clearer message when action optional memory errors are ignored. Acked-by: Borislav Petkov Signed-off-by: Tony Luck --- arch/x86/kernel/cpu/mcheck/mce.c | 12 +++++++---- drivers/base/memory.c | 2 +- include/linux/mm.h | 3 +-- mm/hwpoison-inject.c | 4 ++-- mm/madvise.c | 2 +- mm/memory-failure.c | 46 ++++++++++++++++++---------------------- 6 files changed, 34 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 2af127d4c3d..1a08ce5f345 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -1046,11 +1046,15 @@ out: } EXPORT_SYMBOL_GPL(do_machine_check); -/* dummy to break dependency. actual code is in mm/memory-failure.c */ -void __attribute__((weak)) memory_failure(unsigned long pfn, int vector) +#ifndef CONFIG_MEMORY_FAILURE +int memory_failure(unsigned long pfn, int vector, int flags) { - printk(KERN_ERR "Action optional memory failure at %lx ignored\n", pfn); + printk(KERN_ERR "Uncorrected memory error in page 0x%lx ignored\n" + "Rebuild kernel with CONFIG_MEMORY_FAILURE=y for smarter handling\n", pfn); + + return 0; } +#endif /* * Called after mce notification in process context. This code @@ -1068,7 +1072,7 @@ void mce_notify_process(void) unsigned long pfn; mce_notify_irq(); while (mce_ring_get(&pfn)) - memory_failure(pfn, MCE_VECTOR); + memory_failure(pfn, MCE_VECTOR, 0); } static void mce_process_work(struct work_struct *dummy) diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 8272d92d22c..9a924440053 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -474,7 +474,7 @@ store_hard_offline_page(struct class *class, if (strict_strtoull(buf, 0, &pfn) < 0) return -EINVAL; pfn >>= PAGE_SHIFT; - ret = __memory_failure(pfn, 0, 0); + ret = memory_failure(pfn, 0, 0); return ret ? ret : count; } diff --git a/include/linux/mm.h b/include/linux/mm.h index 4baadd18f4a..bcc52347472 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1607,8 +1607,7 @@ void vmemmap_populate_print_last(void); enum mf_flags { MF_COUNT_INCREASED = 1 << 0, }; -extern void memory_failure(unsigned long pfn, int trapno); -extern int __memory_failure(unsigned long pfn, int trapno, int flags); +extern int memory_failure(unsigned long pfn, int trapno, int flags); extern void memory_failure_queue(unsigned long pfn, int trapno, int flags); extern int unpoison_memory(unsigned long pfn); extern int sysctl_memory_failure_early_kill; diff --git a/mm/hwpoison-inject.c b/mm/hwpoison-inject.c index c7fc7fd00e3..cc448bb983b 100644 --- a/mm/hwpoison-inject.c +++ b/mm/hwpoison-inject.c @@ -45,7 +45,7 @@ static int hwpoison_inject(void *data, u64 val) * do a racy check with elevated page count, to make sure PG_hwpoison * will only be set for the targeted owner (or on a free page). * We temporarily take page lock for try_get_mem_cgroup_from_page(). - * __memory_failure() will redo the check reliably inside page lock. + * memory_failure() will redo the check reliably inside page lock. */ lock_page(hpage); err = hwpoison_filter(hpage); @@ -55,7 +55,7 @@ static int hwpoison_inject(void *data, u64 val) inject: printk(KERN_INFO "Injecting memory failure at pfn %lx\n", pfn); - return __memory_failure(pfn, 18, MF_COUNT_INCREASED); + return memory_failure(pfn, 18, MF_COUNT_INCREASED); } static int hwpoison_unpoison(void *data, u64 val) diff --git a/mm/madvise.c b/mm/madvise.c index 74bf193eff0..f5ab745672b 100644 --- a/mm/madvise.c +++ b/mm/madvise.c @@ -251,7 +251,7 @@ static int madvise_hwpoison(int bhv, unsigned long start, unsigned long end) printk(KERN_INFO "Injecting memory failure for page %lx at %lx\n", page_to_pfn(p), start); /* Ignore return value for now */ - __memory_failure(page_to_pfn(p), 0, MF_COUNT_INCREASED); + memory_failure(page_to_pfn(p), 0, MF_COUNT_INCREASED); } return ret; } diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 06d3479513a..ab259bb0adc 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -984,7 +984,25 @@ static void clear_page_hwpoison_huge_page(struct page *hpage) ClearPageHWPoison(hpage + i); } -int __memory_failure(unsigned long pfn, int trapno, int flags) +/** + * memory_failure - Handle memory failure of a page. + * @pfn: Page Number of the corrupted page + * @trapno: Trap number reported in the signal to user space. + * @flags: fine tune action taken + * + * This function is called by the low level machine check code + * of an architecture when it detects hardware memory corruption + * of a page. It tries its best to recover, which includes + * dropping pages, killing processes etc. + * + * The function is primarily of use for corruptions that + * happen outside the current execution context (e.g. when + * detected by a background scrubber) + * + * Must run in process context (e.g. a work queue) with interrupts + * enabled and no spinlocks hold. + */ +int memory_failure(unsigned long pfn, int trapno, int flags) { struct page_state *ps; struct page *p; @@ -1156,29 +1174,7 @@ out: unlock_page(hpage); return res; } -EXPORT_SYMBOL_GPL(__memory_failure); - -/** - * memory_failure - Handle memory failure of a page. - * @pfn: Page Number of the corrupted page - * @trapno: Trap number reported in the signal to user space. - * - * This function is called by the low level machine check code - * of an architecture when it detects hardware memory corruption - * of a page. It tries its best to recover, which includes - * dropping pages, killing processes etc. - * - * The function is primarily of use for corruptions that - * happen outside the current execution context (e.g. when - * detected by a background scrubber) - * - * Must run in process context (e.g. a work queue) with interrupts - * enabled and no spinlocks hold. - */ -void memory_failure(unsigned long pfn, int trapno) -{ - __memory_failure(pfn, trapno, 0); -} +EXPORT_SYMBOL_GPL(memory_failure); #define MEMORY_FAILURE_FIFO_ORDER 4 #define MEMORY_FAILURE_FIFO_SIZE (1 << MEMORY_FAILURE_FIFO_ORDER) @@ -1251,7 +1247,7 @@ static void memory_failure_work_func(struct work_struct *work) spin_unlock_irqrestore(&mf_cpu->lock, proc_flags); if (!gotten) break; - __memory_failure(entry.pfn, entry.trapno, entry.flags); + memory_failure(entry.pfn, entry.trapno, entry.flags); } } -- cgit v1.2.3-70-g09d2 From 9c636baf8518d0f986004b40669b75506459beac Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 5 Jan 2012 17:19:45 +0000 Subject: sfc: Fix some formatting errors reported by checkpatch Fix the following errors and warnings: ERROR: trailing whitespace ERROR: spaces required around that '=' (ctx:VxV) WARNING: please, no space before tabs Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/bitfield.h | 18 +++++++++--------- drivers/net/ethernet/sfc/efx.c | 16 ++++++++-------- drivers/net/ethernet/sfc/ethtool.c | 4 ++-- drivers/net/ethernet/sfc/falcon_xmac.c | 2 +- drivers/net/ethernet/sfc/mcdi_mac.c | 2 +- drivers/net/ethernet/sfc/mcdi_phy.c | 2 +- drivers/net/ethernet/sfc/mdio_10g.c | 2 +- drivers/net/ethernet/sfc/nic.c | 2 +- drivers/net/ethernet/sfc/qt202x_phy.c | 6 +++--- drivers/net/ethernet/sfc/selftest.c | 2 +- drivers/net/ethernet/sfc/spi.h | 2 +- drivers/net/ethernet/sfc/tenxpress.c | 2 +- 12 files changed, 30 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/bitfield.h b/drivers/net/ethernet/sfc/bitfield.h index 098ac2ad757..a2a9f40b90c 100644 --- a/drivers/net/ethernet/sfc/bitfield.h +++ b/drivers/net/ethernet/sfc/bitfield.h @@ -448,40 +448,40 @@ typedef union efx_oword { EFX_INSERT32(min, max, low, high, EFX_MASK32(high + 1 - low)) #define EFX_SET_OWORD64(oword, low, high, value) do { \ - (oword).u64[0] = (((oword).u64[0] \ + (oword).u64[0] = (((oword).u64[0] \ & ~EFX_INPLACE_MASK64(0, 63, low, high)) \ | EFX_INSERT64(0, 63, low, high, value)); \ - (oword).u64[1] = (((oword).u64[1] \ + (oword).u64[1] = (((oword).u64[1] \ & ~EFX_INPLACE_MASK64(64, 127, low, high)) \ | EFX_INSERT64(64, 127, low, high, value)); \ } while (0) #define EFX_SET_QWORD64(qword, low, high, value) do { \ - (qword).u64[0] = (((qword).u64[0] \ + (qword).u64[0] = (((qword).u64[0] \ & ~EFX_INPLACE_MASK64(0, 63, low, high)) \ | EFX_INSERT64(0, 63, low, high, value)); \ } while (0) #define EFX_SET_OWORD32(oword, low, high, value) do { \ - (oword).u32[0] = (((oword).u32[0] \ + (oword).u32[0] = (((oword).u32[0] \ & ~EFX_INPLACE_MASK32(0, 31, low, high)) \ | EFX_INSERT32(0, 31, low, high, value)); \ - (oword).u32[1] = (((oword).u32[1] \ + (oword).u32[1] = (((oword).u32[1] \ & ~EFX_INPLACE_MASK32(32, 63, low, high)) \ | EFX_INSERT32(32, 63, low, high, value)); \ - (oword).u32[2] = (((oword).u32[2] \ + (oword).u32[2] = (((oword).u32[2] \ & ~EFX_INPLACE_MASK32(64, 95, low, high)) \ | EFX_INSERT32(64, 95, low, high, value)); \ - (oword).u32[3] = (((oword).u32[3] \ + (oword).u32[3] = (((oword).u32[3] \ & ~EFX_INPLACE_MASK32(96, 127, low, high)) \ | EFX_INSERT32(96, 127, low, high, value)); \ } while (0) #define EFX_SET_QWORD32(qword, low, high, value) do { \ - (qword).u32[0] = (((qword).u32[0] \ + (qword).u32[0] = (((qword).u32[0] \ & ~EFX_INPLACE_MASK32(0, 31, low, high)) \ | EFX_INSERT32(0, 31, low, high, value)); \ - (qword).u32[1] = (((qword).u32[1] \ + (qword).u32[1] = (((qword).u32[1] \ & ~EFX_INPLACE_MASK32(32, 63, low, high)) \ | EFX_INSERT32(32, 63, low, high, value)); \ } while (0) diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index e43702f33b6..11cc585c36a 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -44,9 +44,9 @@ const char *efx_loopback_mode_names[] = { [LOOPBACK_GMAC] = "GMAC", [LOOPBACK_XGMII] = "XGMII", [LOOPBACK_XGXS] = "XGXS", - [LOOPBACK_XAUI] = "XAUI", - [LOOPBACK_GMII] = "GMII", - [LOOPBACK_SGMII] = "SGMII", + [LOOPBACK_XAUI] = "XAUI", + [LOOPBACK_GMII] = "GMII", + [LOOPBACK_SGMII] = "SGMII", [LOOPBACK_XGBR] = "XGBR", [LOOPBACK_XFI] = "XFI", [LOOPBACK_XAUI_FAR] = "XAUI_FAR", @@ -55,17 +55,17 @@ const char *efx_loopback_mode_names[] = { [LOOPBACK_XFI_FAR] = "XFI_FAR", [LOOPBACK_GPHY] = "GPHY", [LOOPBACK_PHYXS] = "PHYXS", - [LOOPBACK_PCS] = "PCS", - [LOOPBACK_PMAPMD] = "PMA/PMD", + [LOOPBACK_PCS] = "PCS", + [LOOPBACK_PMAPMD] = "PMA/PMD", [LOOPBACK_XPORT] = "XPORT", [LOOPBACK_XGMII_WS] = "XGMII_WS", - [LOOPBACK_XAUI_WS] = "XAUI_WS", + [LOOPBACK_XAUI_WS] = "XAUI_WS", [LOOPBACK_XAUI_WS_FAR] = "XAUI_WS_FAR", [LOOPBACK_XAUI_WS_NEAR] = "XAUI_WS_NEAR", - [LOOPBACK_GMII_WS] = "GMII_WS", + [LOOPBACK_GMII_WS] = "GMII_WS", [LOOPBACK_XFI_WS] = "XFI_WS", [LOOPBACK_XFI_WS_FAR] = "XFI_WS_FAR", - [LOOPBACK_PHYXS_WS] = "PHYXS_WS", + [LOOPBACK_PHYXS_WS] = "PHYXS_WS", }; const unsigned int efx_reset_type_max = RESET_TYPE_MAX; diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index 29b2ebfef19..c090de4e66c 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c @@ -68,11 +68,11 @@ static u64 efx_get_atomic_stat(void *field) } #define EFX_ETHTOOL_ULONG_MAC_STAT(field) \ - EFX_ETHTOOL_STAT(field, mac_stats, field, \ + EFX_ETHTOOL_STAT(field, mac_stats, field, \ unsigned long, efx_get_ulong_stat) #define EFX_ETHTOOL_U64_MAC_STAT(field) \ - EFX_ETHTOOL_STAT(field, mac_stats, field, \ + EFX_ETHTOOL_STAT(field, mac_stats, field, \ u64, efx_get_u64_stat) #define EFX_ETHTOOL_UINT_NIC_STAT(name) \ diff --git a/drivers/net/ethernet/sfc/falcon_xmac.c b/drivers/net/ethernet/sfc/falcon_xmac.c index 9516452c079..57434593f07 100644 --- a/drivers/net/ethernet/sfc/falcon_xmac.c +++ b/drivers/net/ethernet/sfc/falcon_xmac.c @@ -139,7 +139,7 @@ static bool falcon_xmac_link_ok(struct efx_nic *efx) return (efx->loopback_mode == LOOPBACK_XGMII || falcon_xgxs_link_ok(efx)) && (!(efx->mdio.mmds & (1 << MDIO_MMD_PHYXS)) || - LOOPBACK_INTERNAL(efx) || + LOOPBACK_INTERNAL(efx) || efx_mdio_phyxgxs_lane_sync(efx)); } diff --git a/drivers/net/ethernet/sfc/mcdi_mac.c b/drivers/net/ethernet/sfc/mcdi_mac.c index 50c20777a56..aa4052c500f 100644 --- a/drivers/net/ethernet/sfc/mcdi_mac.c +++ b/drivers/net/ethernet/sfc/mcdi_mac.c @@ -141,5 +141,5 @@ static bool efx_mcdi_mac_check_fault(struct efx_nic *efx) const struct efx_mac_operations efx_mcdi_mac_operations = { .reconfigure = efx_mcdi_mac_reconfigure, .update_stats = efx_port_dummy_op_void, - .check_fault = efx_mcdi_mac_check_fault, + .check_fault = efx_mcdi_mac_check_fault, }; diff --git a/drivers/net/ethernet/sfc/mcdi_phy.c b/drivers/net/ethernet/sfc/mcdi_phy.c index 6c63ab0710a..3077bf1e7df 100644 --- a/drivers/net/ethernet/sfc/mcdi_phy.c +++ b/drivers/net/ethernet/sfc/mcdi_phy.c @@ -741,7 +741,7 @@ static const char *efx_mcdi_phy_test_name(struct efx_nic *efx, const struct efx_phy_operations efx_mcdi_phy_ops = { .probe = efx_mcdi_phy_probe, - .init = efx_port_dummy_op_int, + .init = efx_port_dummy_op_int, .reconfigure = efx_mcdi_phy_reconfigure, .poll = efx_mcdi_phy_poll, .fini = efx_port_dummy_op_void, diff --git a/drivers/net/ethernet/sfc/mdio_10g.c b/drivers/net/ethernet/sfc/mdio_10g.c index 7ab385c8136..9acfd6696ff 100644 --- a/drivers/net/ethernet/sfc/mdio_10g.c +++ b/drivers/net/ethernet/sfc/mdio_10g.c @@ -228,7 +228,7 @@ void efx_mdio_set_mmds_lpower(struct efx_nic *efx, /** * efx_mdio_set_settings - Set (some of) the PHY settings over MDIO. * @efx: Efx NIC - * @ecmd: New settings + * @ecmd: New settings */ int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) { diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c index 3edfbaf5f02..b1df2f39c8f 100644 --- a/drivers/net/ethernet/sfc/nic.c +++ b/drivers/net/ethernet/sfc/nic.c @@ -1837,7 +1837,7 @@ struct efx_nic_reg_table { REGISTER_REVISION_ ## min_rev, REGISTER_REVISION_ ## max_rev, \ step, rows \ } -#define REGISTER_TABLE(name, min_rev, max_rev) \ +#define REGISTER_TABLE(name, min_rev, max_rev) \ REGISTER_TABLE_DIMENSIONS( \ name, FR_ ## min_rev ## max_rev ## _ ## name, \ min_rev, max_rev, \ diff --git a/drivers/net/ethernet/sfc/qt202x_phy.c b/drivers/net/ethernet/sfc/qt202x_phy.c index 7ad97e39740..8a7caf88ffb 100644 --- a/drivers/net/ethernet/sfc/qt202x_phy.c +++ b/drivers/net/ethernet/sfc/qt202x_phy.c @@ -47,7 +47,7 @@ #define PMA_PMD_FTX_STATIC_LBN 13 #define PMA_PMD_VEND1_REG 0xc001 #define PMA_PMD_VEND1_LBTXD_LBN 15 -#define PCS_VEND1_REG 0xc000 +#define PCS_VEND1_REG 0xc000 #define PCS_VEND1_LBTXD_LBN 5 void falcon_qt202x_set_led(struct efx_nic *p, int led, int mode) @@ -453,9 +453,9 @@ const struct efx_phy_operations falcon_qt202x_phy_ops = { .probe = qt202x_phy_probe, .init = qt202x_phy_init, .reconfigure = qt202x_phy_reconfigure, - .poll = qt202x_phy_poll, + .poll = qt202x_phy_poll, .fini = efx_port_dummy_op_void, - .remove = qt202x_phy_remove, + .remove = qt202x_phy_remove, .get_settings = qt202x_phy_get_settings, .set_settings = efx_mdio_set_settings, .test_alive = efx_mdio_test_alive, diff --git a/drivers/net/ethernet/sfc/selftest.c b/drivers/net/ethernet/sfc/selftest.c index 52edd24fcde..fc62fe2f766 100644 --- a/drivers/net/ethernet/sfc/selftest.c +++ b/drivers/net/ethernet/sfc/selftest.c @@ -445,7 +445,7 @@ static int efx_end_loopback(struct efx_tx_queue *tx_queue, /* Count the number of tx completions, and decrement the refcnt. Any * skbs not already completed will be free'd when the queue is flushed */ - for (i=0; i < state->packet_count; i++) { + for (i = 0; i < state->packet_count; i++) { skb = state->skbs[i]; if (skb && !skb_shared(skb)) ++tx_done; diff --git a/drivers/net/ethernet/sfc/spi.h b/drivers/net/ethernet/sfc/spi.h index 71f2e3ebe1c..5431a1bbff5 100644 --- a/drivers/net/ethernet/sfc/spi.h +++ b/drivers/net/ethernet/sfc/spi.h @@ -68,7 +68,7 @@ static inline bool efx_spi_present(const struct efx_spi_device *spi) int falcon_spi_cmd(struct efx_nic *efx, const struct efx_spi_device *spi, unsigned int command, - int address, const void* in, void *out, size_t len); + int address, const void *in, void *out, size_t len); int falcon_spi_wait_write(struct efx_nic *efx, const struct efx_spi_device *spi); int falcon_spi_read(struct efx_nic *efx, diff --git a/drivers/net/ethernet/sfc/tenxpress.c b/drivers/net/ethernet/sfc/tenxpress.c index 7b0fd89e7b8..d37cb501712 100644 --- a/drivers/net/ethernet/sfc/tenxpress.c +++ b/drivers/net/ethernet/sfc/tenxpress.c @@ -121,7 +121,7 @@ #define GPHY_XCONTROL_REG 49152 #define GPHY_ISOLATE_LBN 10 #define GPHY_ISOLATE_WIDTH 1 -#define GPHY_DUPLEX_LBN 8 +#define GPHY_DUPLEX_LBN 8 #define GPHY_DUPLEX_WIDTH 1 #define GPHY_LOOPBACK_NEAR_LBN 14 #define GPHY_LOOPBACK_NEAR_WIDTH 1 -- cgit v1.2.3-70-g09d2 From e9e01846c7e18a3b5682b54e50f1005949737bd9 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 5 Jan 2012 18:50:29 +0000 Subject: sfc: Avoid assignment in an if-statement, reported by checkpatch Fix the following error: ERROR: do not use assignment in if condition Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 11cc585c36a..0539a8d88a2 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -1069,9 +1069,11 @@ static int efx_init_io(struct efx_nic *efx) * masks event though they reject 46 bit masks. */ while (dma_mask > 0x7fffffffUL) { - if (pci_dma_supported(pci_dev, dma_mask) && - ((rc = pci_set_dma_mask(pci_dev, dma_mask)) == 0)) - break; + if (pci_dma_supported(pci_dev, dma_mask)) { + rc = pci_set_dma_mask(pci_dev, dma_mask); + if (rc == 0) + break; + } dma_mask >>= 1; } if (rc) { -- cgit v1.2.3-70-g09d2 From 0beaca2ca0b3c12dabab046f1541b09179ec449c Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 5 Jan 2012 18:54:04 +0000 Subject: sfc: Remove parentheses around return expressions, reported by checkpatch Fix the following error: ERROR: return is not a function, parentheses are not required Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/rx.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index aca34986176..3572c34a79f 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -98,8 +98,8 @@ static inline unsigned int efx_rx_buf_offset(struct efx_nic *efx, /* Offset is always within one page, so we don't need to consider * the page order. */ - return (((__force unsigned long) buf->dma_addr & (PAGE_SIZE - 1)) + - efx->type->rx_buffer_hash_size); + return ((__force unsigned long) buf->dma_addr & (PAGE_SIZE - 1)) + + efx->type->rx_buffer_hash_size; } static inline unsigned int efx_rx_buf_size(struct efx_nic *efx) { @@ -111,8 +111,7 @@ static u8 *efx_rx_buf_eh(struct efx_nic *efx, struct efx_rx_buffer *buf) if (buf->is_page) return page_address(buf->u.page) + efx_rx_buf_offset(efx, buf); else - return ((u8 *)buf->u.skb->data + - efx->type->rx_buffer_hash_size); + return (u8 *)buf->u.skb->data + efx->type->rx_buffer_hash_size; } static inline u32 efx_rx_buf_hash(const u8 *eh) @@ -122,10 +121,10 @@ static inline u32 efx_rx_buf_hash(const u8 *eh) return __le32_to_cpup((const __le32 *)(eh - 4)); #else const u8 *data = eh - 4; - return ((u32)data[0] | - (u32)data[1] << 8 | - (u32)data[2] << 16 | - (u32)data[3] << 24); + return (u32)data[0] | + (u32)data[1] << 8 | + (u32)data[2] << 16 | + (u32)data[3] << 24; #endif } -- cgit v1.2.3-70-g09d2 From 3f3c4ee735ff0957a53b9dccae66c8e5ead25b17 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Tue, 3 Jan 2012 14:41:59 +0530 Subject: ath6kl: Add a function in wmi to send WMI_MCAST_FILTER_CMDID This will be used to disable/enable multicast receive. Signed-off-by: Vasanthakumar Thiagarajan --- drivers/net/wireless/ath/ath6kl/wmi.c | 17 +++++++++++++++++ drivers/net/wireless/ath/ath6kl/wmi.h | 5 +++++ 2 files changed, 22 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index c6ca660d270..d3eec0761ea 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -2855,6 +2855,23 @@ int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len) return ret; } +int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on) +{ + struct sk_buff *skb; + struct wmi_mcast_filter_cmd *cmd; + int ret; + + skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_mcast_filter_cmd *) skb->data; + cmd->mcast_all_enable = mc_all_on; + + ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_MCAST_FILTER_CMDID, + NO_SYNC_WMIFLAG); + return ret; +} s32 ath6kl_wmi_get_rate(s8 rate_index) { diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index 2b435994b01..dc704571155 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -1239,6 +1239,10 @@ enum target_event_report_config { NO_DISCONN_EVT_IN_RECONN }; +struct wmi_mcast_filter_cmd { + u8 mcast_all_enable; +} __packed; + /* Command Replies */ /* WMI_GET_CHANNEL_LIST_CMDID reply */ @@ -2434,6 +2438,7 @@ int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi); int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid); int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode); +int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on); /* AP mode */ int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, u8 if_idx, -- cgit v1.2.3-70-g09d2 From f914edd38920369d8926261f9ab72da6756c3e0c Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Tue, 3 Jan 2012 14:42:00 +0530 Subject: ath6kl: Add a function in wmi.c to add/delete a multicast filter Signed-off-by: Vasanthakumar Thiagarajan --- drivers/net/wireless/ath/ath6kl/wmi.c | 28 ++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath6kl/wmi.h | 7 +++++++ 2 files changed, 35 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index d3eec0761ea..08fbd9a9be4 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -2873,6 +2873,34 @@ int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on) return ret; } +int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, + u8 *filter, bool add_filter) +{ + struct sk_buff *skb; + struct wmi_mcast_filter_add_del_cmd *cmd; + int ret; + + if ((filter[0] != 0x33 || filter[1] != 0x33) && + (filter[0] != 0x01 || filter[1] != 0x00 || + filter[2] != 0x5e || filter[3] > 0x7f)) { + ath6kl_warn("invalid multicast filter address\n"); + return -EINVAL; + } + + skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_mcast_filter_add_del_cmd *) skb->data; + memcpy(cmd->mcast_mac, filter, ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE); + ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, + add_filter ? WMI_SET_MCAST_FILTER_CMDID : + WMI_DEL_MCAST_FILTER_CMDID, + NO_SYNC_WMIFLAG); + + return ret; +} + s32 ath6kl_wmi_get_rate(s8 rate_index) { if (rate_index == RATE_AUTO) diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index dc704571155..eae0e4e065c 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -1243,6 +1243,11 @@ struct wmi_mcast_filter_cmd { u8 mcast_all_enable; } __packed; +#define ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE 6 +struct wmi_mcast_filter_add_del_cmd { + u8 mcast_mac[ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE]; +} __packed; + /* Command Replies */ /* WMI_GET_CHANNEL_LIST_CMDID reply */ @@ -2439,6 +2444,8 @@ int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi); int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid); int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode); int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on); +int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, + u8 *filter, bool add_filter); /* AP mode */ int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, u8 if_idx, -- cgit v1.2.3-70-g09d2 From 80abaf9b4c920cab044e185ed4327f801c1ff99d Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Tue, 3 Jan 2012 14:42:01 +0530 Subject: ath6kl: Implement ndo_set_rx_mode() There are maximum of seven multicast filter are supported by hw. When the requested number of filters exceeds the maximum supported one, multicast filtering is completely disabled, the requested filters will be configured in firmware and the only multicast frames that host is interested in will be passed to host for further processing otherwise. Signed-off-by: Vasanthakumar Thiagarajan --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 8 +++ drivers/net/wireless/ath/ath6kl/core.h | 9 +++ drivers/net/wireless/ath/ath6kl/main.c | 110 +++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 2a166cc7cc3..14f180eac48 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -2818,12 +2818,15 @@ static int ath6kl_init_if_data(struct ath6kl_vif *vif) set_bit(WMM_ENABLED, &vif->flags); spin_lock_init(&vif->if_lock); + INIT_LIST_HEAD(&vif->mc_filter); + return 0; } void ath6kl_deinit_if_data(struct ath6kl_vif *vif) { struct ath6kl *ar = vif->ar; + struct ath6kl_mc_filter *mc_filter, *tmp; aggr_module_destroy(vif->aggr_cntxt); @@ -2832,6 +2835,11 @@ void ath6kl_deinit_if_data(struct ath6kl_vif *vif) if (vif->nw_type == ADHOC_NETWORK) ar->ibss_if_active = false; + list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) { + list_del(&mc_filter->list); + kfree(mc_filter); + } + unregister_netdevice(vif->ndev); ar->num_vif--; diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index c095fafa278..793c6a58f0f 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -410,6 +410,13 @@ enum ath6kl_hif_type { ATH6KL_HIF_TYPE_USB, }; +/* Max number of filters that hw supports */ +#define ATH6K_MAX_MC_FILTERS_PER_LIST 7 +struct ath6kl_mc_filter { + struct list_head list; + char hw_addr[ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE]; +}; + /* * Driver's maximum limit, note that some firmwares support only one vif * and the runtime (current) limit must be checked from ar->vif_max. @@ -473,6 +480,8 @@ struct ath6kl_vif { u8 assoc_bss_dtim_period; struct net_device_stats net_stats; struct target_stats target_stats; + + struct list_head mc_filter; }; #define WOW_LIST_ID 0 diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index f74986d6209..cffbc62ee79 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -1052,12 +1052,122 @@ static int ath6kl_set_features(struct net_device *dev, u32 features) return err; } +static void ath6kl_set_multicast_list(struct net_device *ndev) +{ + struct ath6kl_vif *vif = netdev_priv(ndev); + bool mc_all_on = false, mc_all_off = false; + int mc_count = netdev_mc_count(ndev); + struct netdev_hw_addr *ha; + bool found; + struct ath6kl_mc_filter *mc_filter, *tmp; + struct list_head mc_filter_new; + int ret; + + if (!test_bit(WMI_READY, &vif->ar->flag) || + !test_bit(WLAN_ENABLED, &vif->flags)) + return; + + mc_all_on = !!(ndev->flags & IFF_PROMISC) || + !!(ndev->flags & IFF_ALLMULTI) || + !!(mc_count > ATH6K_MAX_MC_FILTERS_PER_LIST); + + mc_all_off = !(ndev->flags & IFF_MULTICAST) || mc_count == 0; + + if (mc_all_on || mc_all_off) { + /* Enable/disable all multicast */ + ath6kl_dbg(ATH6KL_DBG_TRC, "%s multicast filter\n", + mc_all_on ? "enabling" : "disabling"); + ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx, + mc_all_on); + if (ret) + ath6kl_warn("Failed to %s multicast receive\n", + mc_all_on ? "enable" : "disable"); + return; + } + + list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) { + found = false; + netdev_for_each_mc_addr(ha, ndev) { + if (memcmp(ha->addr, mc_filter->hw_addr, + ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) { + found = true; + break; + } + } + + if (!found) { + /* + * Delete the filter which was previously set + * but not in the new request. + */ + ath6kl_dbg(ATH6KL_DBG_TRC, + "Removing %pM from multicast filter\n", + mc_filter->hw_addr); + ret = ath6kl_wmi_add_del_mcast_filter_cmd(vif->ar->wmi, + vif->fw_vif_idx, mc_filter->hw_addr, + false); + if (ret) { + ath6kl_warn("Failed to remove multicast filter:%pM\n", + mc_filter->hw_addr); + return; + } + + list_del(&mc_filter->list); + kfree(mc_filter); + } + } + + INIT_LIST_HEAD(&mc_filter_new); + + netdev_for_each_mc_addr(ha, ndev) { + found = false; + list_for_each_entry(mc_filter, &vif->mc_filter, list) { + if (memcmp(ha->addr, mc_filter->hw_addr, + ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) { + found = true; + break; + } + } + + if (!found) { + mc_filter = kzalloc(sizeof(struct ath6kl_mc_filter), + GFP_ATOMIC); + if (!mc_filter) { + WARN_ON(1); + goto out; + } + + memcpy(mc_filter->hw_addr, ha->addr, + ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE); + /* Set the multicast filter */ + ath6kl_dbg(ATH6KL_DBG_TRC, + "Adding %pM to multicast filter list\n", + mc_filter->hw_addr); + ret = ath6kl_wmi_add_del_mcast_filter_cmd(vif->ar->wmi, + vif->fw_vif_idx, mc_filter->hw_addr, + true); + if (ret) { + ath6kl_warn("Failed to add multicast filter :%pM\n", + mc_filter->hw_addr); + kfree(mc_filter); + goto out; + } + + list_add_tail(&mc_filter->list, &mc_filter_new); + } + } + +out: + list_splice_tail(&mc_filter_new, &vif->mc_filter); +} + static struct net_device_ops ath6kl_netdev_ops = { .ndo_open = ath6kl_open, .ndo_stop = ath6kl_close, .ndo_start_xmit = ath6kl_data_tx, .ndo_get_stats = ath6kl_get_stats, .ndo_set_features = ath6kl_set_features, + .ndo_set_rx_mode = ath6kl_set_multicast_list, }; void init_netdev(struct net_device *dev) -- cgit v1.2.3-70-g09d2 From 3d6aba260bcd5a5f9d47056cac2e313ce986ad12 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Tue, 3 Jan 2012 15:19:02 +0530 Subject: ath6kl: Remove deadcode in main.c In ath6kl_reset_device(), since control can never reach switch..case when the target_type is neither TARGET_TYPE_AR6003 nor TARGET_TYPE_AR6004, remove the default option of switch statement. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/main.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index cffbc62ee79..d764768f8f7 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -347,9 +347,6 @@ void ath6kl_reset_device(struct ath6kl *ar, u32 target_type, case TARGET_TYPE_AR6004: address = AR6004_RESET_CONTROL_ADDRESS; break; - default: - address = AR6003_RESET_CONTROL_ADDRESS; - break; } status = ath6kl_diag_write32(ar, address, data); -- cgit v1.2.3-70-g09d2 From 982767b8c94482b4b7f694e2ab2074c95fbf3e0e Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Tue, 3 Jan 2012 15:28:53 +0530 Subject: ath6kl: Change ielen in ath6kl_add_new_sta() from u8 to size_t Otherwise if (ielen <= ATH6KL_MAX_IE) is dead code. It looks safe to change the type of ielen from u8 to size_t instead of removing this if check, this ielen can have the length of more than one ies in future. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index d764768f8f7..325d316f40e 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -53,7 +53,7 @@ struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid) } static void ath6kl_add_new_sta(struct ath6kl *ar, u8 *mac, u16 aid, u8 *wpaie, - u8 ielen, u8 keymgmt, u8 ucipher, u8 auth) + size_t ielen, u8 keymgmt, u8 ucipher, u8 auth) { struct ath6kl_sta *sta; u8 free_slot; -- cgit v1.2.3-70-g09d2 From 9d82682d45ef7407474e0ae043a587cb33a7fa26 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Wed, 4 Jan 2012 15:57:19 +0530 Subject: ath6kl: Use a mutex_lock to avoid race in diabling and handling irq Currently this race is handled but in a messy way an atomic variable is being checked in a loop which sleeps upto ms in every iteration. Remove this logic and use a mutex to make sure irq is not disabled when irq handling is in progress. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/sdio.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index 278a9f30795..8b36904ec3e 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -49,11 +49,13 @@ struct ath6kl_sdio { /* scatter request list head */ struct list_head scat_req; + /* Avoids disabling irq while the interrupts being handled */ + struct mutex mtx_irq; + spinlock_t scat_lock; bool scatter_enabled; bool is_disabled; - atomic_t irq_handling; const struct sdio_device_id *id; struct work_struct wr_async_work; struct list_head wr_asyncq; @@ -460,8 +462,7 @@ static void ath6kl_sdio_irq_handler(struct sdio_func *func) ath6kl_dbg(ATH6KL_DBG_SDIO, "irq\n"); ar_sdio = sdio_get_drvdata(func); - atomic_set(&ar_sdio->irq_handling, 1); - + mutex_lock(&ar_sdio->mtx_irq); /* * Release the host during interrups so we can pick it back up when * we process commands. @@ -470,7 +471,7 @@ static void ath6kl_sdio_irq_handler(struct sdio_func *func) status = ath6kl_hif_intr_bh_handler(ar_sdio->ar); sdio_claim_host(ar_sdio->func); - atomic_set(&ar_sdio->irq_handling, 0); + mutex_unlock(&ar_sdio->mtx_irq); WARN_ON(status && status != -ECANCELED); } @@ -578,17 +579,14 @@ static void ath6kl_sdio_irq_disable(struct ath6kl *ar) sdio_claim_host(ar_sdio->func); - /* Mask our function IRQ */ - while (atomic_read(&ar_sdio->irq_handling)) { - sdio_release_host(ar_sdio->func); - schedule_timeout(HZ / 10); - sdio_claim_host(ar_sdio->func); - } + mutex_lock(&ar_sdio->mtx_irq); ret = sdio_release_irq(ar_sdio->func); if (ret) ath6kl_err("Failed to release sdio irq: %d\n", ret); + mutex_unlock(&ar_sdio->mtx_irq); + sdio_release_host(ar_sdio->func); } @@ -1253,6 +1251,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func, spin_lock_init(&ar_sdio->scat_lock); spin_lock_init(&ar_sdio->wr_async_lock); mutex_init(&ar_sdio->dma_buffer_mutex); + mutex_init(&ar_sdio->mtx_irq); INIT_LIST_HEAD(&ar_sdio->scat_req); INIT_LIST_HEAD(&ar_sdio->bus_req_freeq); -- cgit v1.2.3-70-g09d2 From 4269a930548966014dd4186a15c8e023ca4abc29 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 5 Jan 2012 10:39:48 -0800 Subject: ath6kl: make net_device_ops const Signed-off-by: Stephen Hemminger Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index 325d316f40e..8742eaa7818 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -1158,7 +1158,7 @@ out: list_splice_tail(&mc_filter_new, &vif->mc_filter); } -static struct net_device_ops ath6kl_netdev_ops = { +static const struct net_device_ops ath6kl_netdev_ops = { .ndo_open = ath6kl_open, .ndo_stop = ath6kl_close, .ndo_start_xmit = ath6kl_data_tx, -- cgit v1.2.3-70-g09d2 From 18e83e4cd144e30fb38bf1f714914182c6c8bced Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 5 Jan 2012 19:05:20 +0000 Subject: sfc: Const-qualify static data as appropriate, partly prompted by checkpatch Fix the following warnings: WARNING: struct dev_pm_ops should normally be const WARNING: static const char * array should probably be static const char * const Similarly const-qualify struct i2c_board_info, struct i2c_algo_bit_data, struct efx_ethtool_stat, struct efx_mtd_ops and struct siena_nvram_type_info. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 6 +++--- drivers/net/ethernet/sfc/ethtool.c | 4 ++-- drivers/net/ethernet/sfc/falcon.c | 2 +- drivers/net/ethernet/sfc/falcon_boards.c | 12 ++++++------ drivers/net/ethernet/sfc/mcdi.c | 4 ++-- drivers/net/ethernet/sfc/mtd.c | 8 ++++---- drivers/net/ethernet/sfc/net_driver.h | 4 ++-- drivers/net/ethernet/sfc/selftest.c | 2 +- drivers/net/ethernet/sfc/txc43128_phy.c | 2 +- 9 files changed, 22 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 0539a8d88a2..9ca5dcdf5a8 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -38,7 +38,7 @@ /* Loopback mode names (see LOOPBACK_MODE()) */ const unsigned int efx_loopback_mode_max = LOOPBACK_MAX; -const char *efx_loopback_mode_names[] = { +const char *const efx_loopback_mode_names[] = { [LOOPBACK_NONE] = "NONE", [LOOPBACK_DATA] = "DATAPATH", [LOOPBACK_GMAC] = "GMAC", @@ -69,7 +69,7 @@ const char *efx_loopback_mode_names[] = { }; const unsigned int efx_reset_type_max = RESET_TYPE_MAX; -const char *efx_reset_type_names[] = { +const char *const efx_reset_type_names[] = { [RESET_TYPE_INVISIBLE] = "INVISIBLE", [RESET_TYPE_ALL] = "ALL", [RESET_TYPE_WORLD] = "WORLD", @@ -2660,7 +2660,7 @@ static int efx_pm_suspend(struct device *dev) return rc; } -static struct dev_pm_ops efx_pm_ops = { +static const struct dev_pm_ops efx_pm_ops = { .suspend = efx_pm_suspend, .resume = efx_pm_resume, .freeze = efx_pm_freeze, diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index c090de4e66c..52c9ee4c8aa 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c @@ -91,7 +91,7 @@ static u64 efx_get_atomic_stat(void *field) EFX_ETHTOOL_STAT(tx_##field, tx_queue, field, \ unsigned int, efx_get_uint_stat) -static struct efx_ethtool_stat efx_ethtool_stats[] = { +static const struct efx_ethtool_stat efx_ethtool_stats[] = { EFX_ETHTOOL_U64_MAC_STAT(tx_bytes), EFX_ETHTOOL_U64_MAC_STAT(tx_good_bytes), EFX_ETHTOOL_U64_MAC_STAT(tx_bad_bytes), @@ -486,7 +486,7 @@ static void efx_ethtool_get_stats(struct net_device *net_dev, { struct efx_nic *efx = netdev_priv(net_dev); struct efx_mac_stats *mac_stats = &efx->mac_stats; - struct efx_ethtool_stat *stat; + const struct efx_ethtool_stat *stat; struct efx_channel *channel; struct efx_tx_queue *tx_queue; struct rtnl_link_stats64 temp; diff --git a/drivers/net/ethernet/sfc/falcon.c b/drivers/net/ethernet/sfc/falcon.c index 8ae1ebd3539..5c7548959dd 100644 --- a/drivers/net/ethernet/sfc/falcon.c +++ b/drivers/net/ethernet/sfc/falcon.c @@ -89,7 +89,7 @@ static int falcon_getscl(void *data) return EFX_OWORD_FIELD(reg, FRF_AB_GPIO0_IN); } -static struct i2c_algo_bit_data falcon_i2c_bit_operations = { +static const struct i2c_algo_bit_data falcon_i2c_bit_operations = { .setsda = falcon_setsda, .setscl = falcon_setscl, .getsda = falcon_getsda, diff --git a/drivers/net/ethernet/sfc/falcon_boards.c b/drivers/net/ethernet/sfc/falcon_boards.c index 6cc16b8cc6f..2084cc6ede5 100644 --- a/drivers/net/ethernet/sfc/falcon_boards.c +++ b/drivers/net/ethernet/sfc/falcon_boards.c @@ -87,7 +87,7 @@ static const u8 falcon_lm87_common_regs[] = { 0 }; -static int efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info, +static int efx_init_lm87(struct efx_nic *efx, const struct i2c_board_info *info, const u8 *reg_values) { struct falcon_board *board = falcon_board(efx); @@ -179,7 +179,7 @@ static int efx_check_lm87(struct efx_nic *efx, unsigned mask) #else /* !CONFIG_SENSORS_LM87 */ static inline int -efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info, +efx_init_lm87(struct efx_nic *efx, const struct i2c_board_info *info, const u8 *reg_values) { return 0; @@ -442,7 +442,7 @@ static int sfe4001_check_hw(struct efx_nic *efx) return (status < 0) ? -EIO : -ERANGE; } -static struct i2c_board_info sfe4001_hwmon_info = { +static const struct i2c_board_info sfe4001_hwmon_info = { I2C_BOARD_INFO("max6647", 0x4e), }; @@ -522,7 +522,7 @@ static const u8 sfe4002_lm87_regs[] = { 0 }; -static struct i2c_board_info sfe4002_hwmon_info = { +static const struct i2c_board_info sfe4002_hwmon_info = { I2C_BOARD_INFO("lm87", 0x2e), .platform_data = &sfe4002_lm87_channel, }; @@ -591,7 +591,7 @@ static const u8 sfn4112f_lm87_regs[] = { 0 }; -static struct i2c_board_info sfn4112f_hwmon_info = { +static const struct i2c_board_info sfn4112f_hwmon_info = { I2C_BOARD_INFO("lm87", 0x2e), .platform_data = &sfn4112f_lm87_channel, }; @@ -653,7 +653,7 @@ static const u8 sfe4003_lm87_regs[] = { 0 }; -static struct i2c_board_info sfe4003_hwmon_info = { +static const struct i2c_board_info sfe4003_hwmon_info = { I2C_BOARD_INFO("lm87", 0x2e), .platform_data = &sfe4003_lm87_channel, }; diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index 81a42539746..b1de400ca24 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c @@ -502,7 +502,7 @@ static void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev) efx_link_status_changed(efx); } -static const char *sensor_names[] = { +static const char *const sensor_names[] = { [MC_CMD_SENSOR_CONTROLLER_TEMP] = "Controller temp. sensor", [MC_CMD_SENSOR_PHY_COMMON_TEMP] = "PHY shared temp. sensor", [MC_CMD_SENSOR_CONTROLLER_COOLING] = "Controller cooling", @@ -518,7 +518,7 @@ static const char *sensor_names[] = { [MC_CMD_SENSOR_IN_12V0] = "12V supply sensor" }; -static const char *sensor_status_names[] = { +static const char *const sensor_status_names[] = { [MC_CMD_SENSOR_STATE_OK] = "OK", [MC_CMD_SENSOR_STATE_WARNING] = "Warning", [MC_CMD_SENSOR_STATE_FATAL] = "Fatal", diff --git a/drivers/net/ethernet/sfc/mtd.c b/drivers/net/ethernet/sfc/mtd.c index bc9dcd6b30d..13f61fba731 100644 --- a/drivers/net/ethernet/sfc/mtd.c +++ b/drivers/net/ethernet/sfc/mtd.c @@ -382,7 +382,7 @@ static int falcon_mtd_sync(struct mtd_info *mtd) return rc; } -static struct efx_mtd_ops falcon_mtd_ops = { +static const struct efx_mtd_ops falcon_mtd_ops = { .read = falcon_mtd_read, .erase = falcon_mtd_erase, .write = falcon_mtd_write, @@ -560,7 +560,7 @@ static int siena_mtd_sync(struct mtd_info *mtd) return rc; } -static struct efx_mtd_ops siena_mtd_ops = { +static const struct efx_mtd_ops siena_mtd_ops = { .read = siena_mtd_read, .erase = siena_mtd_erase, .write = siena_mtd_write, @@ -572,7 +572,7 @@ struct siena_nvram_type_info { const char *name; }; -static struct siena_nvram_type_info siena_nvram_types[] = { +static const struct siena_nvram_type_info siena_nvram_types[] = { [MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO] = { 0, "sfc_dummy_phy" }, [MC_CMD_NVRAM_TYPE_MC_FW] = { 0, "sfc_mcfw" }, [MC_CMD_NVRAM_TYPE_MC_FW_BACKUP] = { 0, "sfc_mcfw_backup" }, @@ -593,7 +593,7 @@ static int siena_mtd_probe_partition(struct efx_nic *efx, unsigned int type) { struct efx_mtd_partition *part = &efx_mtd->part[part_id]; - struct siena_nvram_type_info *info; + const struct siena_nvram_type_info *info; size_t size, erase_size; bool protected; int rc; diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index c49502bab6a..9353ce80175 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -395,12 +395,12 @@ enum efx_led_mode { #define STRING_TABLE_LOOKUP(val, member) \ ((val) < member ## _max) ? member ## _names[val] : "(invalid)" -extern const char *efx_loopback_mode_names[]; +extern const char *const efx_loopback_mode_names[]; extern const unsigned int efx_loopback_mode_max; #define LOOPBACK_MODE(efx) \ STRING_TABLE_LOOKUP((efx)->loopback_mode, efx_loopback_mode) -extern const char *efx_reset_type_names[]; +extern const char *const efx_reset_type_names[]; extern const unsigned int efx_reset_type_max; #define RESET_TYPE(type) \ STRING_TABLE_LOOKUP(type, efx_reset_type) diff --git a/drivers/net/ethernet/sfc/selftest.c b/drivers/net/ethernet/sfc/selftest.c index fc62fe2f766..17ff9b39995 100644 --- a/drivers/net/ethernet/sfc/selftest.c +++ b/drivers/net/ethernet/sfc/selftest.c @@ -50,7 +50,7 @@ static const char payload_msg[] = /* Interrupt mode names */ static const unsigned int efx_interrupt_mode_max = EFX_INT_MODE_MAX; -static const char *efx_interrupt_mode_names[] = { +static const char *const efx_interrupt_mode_names[] = { [EFX_INT_MODE_MSIX] = "MSI-X", [EFX_INT_MODE_MSI] = "MSI", [EFX_INT_MODE_LEGACY] = "legacy", diff --git a/drivers/net/ethernet/sfc/txc43128_phy.c b/drivers/net/ethernet/sfc/txc43128_phy.c index 7c21b334a75..29bb3f9941c 100644 --- a/drivers/net/ethernet/sfc/txc43128_phy.c +++ b/drivers/net/ethernet/sfc/txc43128_phy.c @@ -512,7 +512,7 @@ static bool txc43128_phy_poll(struct efx_nic *efx) return efx->link_state.up != was_up; } -static const char *txc43128_test_names[] = { +static const char *const txc43128_test_names[] = { "bist" }; -- cgit v1.2.3-70-g09d2 From 783b6bb66d4289826b3d022ad7b8ac3666951bb6 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 5 Jan 2012 19:09:24 +0000 Subject: sfc: Remove unnecessary inclusion of , prompted by checkpatch Fix the warning: WARNING: Use #include instead of There is no need for selftest.c to include the file at all. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/selftest.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/selftest.c b/drivers/net/ethernet/sfc/selftest.c index 17ff9b39995..5226d9857f3 100644 --- a/drivers/net/ethernet/sfc/selftest.c +++ b/drivers/net/ethernet/sfc/selftest.c @@ -19,7 +19,6 @@ #include #include #include -#include #include "net_driver.h" #include "efx.h" #include "nic.h" -- cgit v1.2.3-70-g09d2 From 05a9320f7e64b69cbf612a69b7358546519ffc30 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 20 Dec 2011 00:44:06 +0000 Subject: sfc: Update MCDI (firmware interface) definitions Some commands and constants have been renamed; adjust the code accordingly. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/mcdi.c | 15 +- drivers/net/ethernet/sfc/mcdi_mac.c | 16 +- drivers/net/ethernet/sfc/mcdi_pcol.h | 3542 ++++++++++++++++++++-------------- drivers/net/ethernet/sfc/mcdi_phy.c | 34 +- drivers/net/ethernet/sfc/mtd.c | 3 +- 5 files changed, 2119 insertions(+), 1491 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index b1de400ca24..7c405d16692 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c @@ -604,7 +604,7 @@ void efx_mcdi_process_event(struct efx_channel *channel, void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len) { - u8 outbuf[ALIGN(MC_CMD_GET_VERSION_V1_OUT_LEN, 4)]; + u8 outbuf[ALIGN(MC_CMD_GET_VERSION_OUT_LEN, 4)]; size_t outlength; const __le16 *ver_words; int rc; @@ -616,7 +616,7 @@ void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len) if (rc) goto fail; - if (outlength < MC_CMD_GET_VERSION_V1_OUT_LEN) { + if (outlength < MC_CMD_GET_VERSION_OUT_LEN) { rc = -EIO; goto fail; } @@ -665,7 +665,7 @@ fail: int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address, u16 *fw_subtype_list) { - uint8_t outbuf[MC_CMD_GET_BOARD_CFG_OUT_LEN]; + uint8_t outbuf[MC_CMD_GET_BOARD_CFG_OUT_LENMIN]; size_t outlen; int port_num = efx_port_num(efx); int offset; @@ -678,7 +678,7 @@ int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address, if (rc) goto fail; - if (outlen < MC_CMD_GET_BOARD_CFG_OUT_LEN) { + if (outlen < MC_CMD_GET_BOARD_CFG_OUT_LENMIN) { rc = -EIO; goto fail; } @@ -691,7 +691,8 @@ int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address, if (fw_subtype_list) memcpy(fw_subtype_list, outbuf + MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_OFST, - MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN); + MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MINNUM * + sizeof(fw_subtype_list[0])); return 0; @@ -779,7 +780,7 @@ int efx_mcdi_nvram_info(struct efx_nic *efx, unsigned int type, *size_out = MCDI_DWORD(outbuf, NVRAM_INFO_OUT_SIZE); *erase_size_out = MCDI_DWORD(outbuf, NVRAM_INFO_OUT_ERASESIZE); *protected_out = !!(MCDI_DWORD(outbuf, NVRAM_INFO_OUT_FLAGS) & - (1 << MC_CMD_NVRAM_PROTECTED_LBN)); + (1 << MC_CMD_NVRAM_INFO_OUT_PROTECTED_LBN)); return 0; fail: @@ -1060,7 +1061,7 @@ void efx_mcdi_set_id_led(struct efx_nic *efx, enum efx_led_mode mode) int efx_mcdi_reset_port(struct efx_nic *efx) { - int rc = efx_mcdi_rpc(efx, MC_CMD_PORT_RESET, NULL, 0, NULL, 0, NULL); + int rc = efx_mcdi_rpc(efx, MC_CMD_ENTITY_RESET, NULL, 0, NULL, 0, NULL); if (rc) netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); diff --git a/drivers/net/ethernet/sfc/mcdi_mac.c b/drivers/net/ethernet/sfc/mcdi_mac.c index aa4052c500f..85fe24f8639 100644 --- a/drivers/net/ethernet/sfc/mcdi_mac.c +++ b/drivers/net/ethernet/sfc/mcdi_mac.c @@ -84,7 +84,7 @@ int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr, u32 addr_hi; u32 addr_lo; - BUILD_BUG_ON(MC_CMD_MAC_STATS_OUT_LEN != 0); + BUILD_BUG_ON(MC_CMD_MAC_STATS_OUT_DMA_LEN != 0); addr_lo = ((u64)dma_addr) >> 0; addr_hi = ((u64)dma_addr) >> 32; @@ -93,13 +93,13 @@ int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr, MCDI_SET_DWORD(inbuf, MAC_STATS_IN_DMA_ADDR_HI, addr_hi); cmd_ptr = (efx_dword_t *)MCDI_PTR(inbuf, MAC_STATS_IN_CMD); EFX_POPULATE_DWORD_7(*cmd_ptr, - MC_CMD_MAC_STATS_CMD_DMA, !!enable, - MC_CMD_MAC_STATS_CMD_CLEAR, clear, - MC_CMD_MAC_STATS_CMD_PERIODIC_CHANGE, 1, - MC_CMD_MAC_STATS_CMD_PERIODIC_ENABLE, !!enable, - MC_CMD_MAC_STATS_CMD_PERIODIC_CLEAR, 0, - MC_CMD_MAC_STATS_CMD_PERIODIC_NOEVENT, 1, - MC_CMD_MAC_STATS_CMD_PERIOD_MS, period); + MC_CMD_MAC_STATS_IN_DMA, !!enable, + MC_CMD_MAC_STATS_IN_CLEAR, clear, + MC_CMD_MAC_STATS_IN_PERIODIC_CHANGE, 1, + MC_CMD_MAC_STATS_IN_PERIODIC_ENABLE, !!enable, + MC_CMD_MAC_STATS_IN_PERIODIC_CLEAR, 0, + MC_CMD_MAC_STATS_IN_PERIODIC_NOEVENT, 1, + MC_CMD_MAC_STATS_IN_PERIOD_MS, period); MCDI_SET_DWORD(inbuf, MAC_STATS_IN_DMA_LEN, dma_len); rc = efx_mcdi_rpc(efx, MC_CMD_MAC_STATS, inbuf, sizeof(inbuf), diff --git a/drivers/net/ethernet/sfc/mcdi_pcol.h b/drivers/net/ethernet/sfc/mcdi_pcol.h index 41fe06fa060..0310b9f08c9 100644 --- a/drivers/net/ethernet/sfc/mcdi_pcol.h +++ b/drivers/net/ethernet/sfc/mcdi_pcol.h @@ -22,6 +22,18 @@ /* The Scheduler has started. */ #define MC_FW_STATE_SCHED (8) +/* Siena MC shared memmory offsets */ +/* The 'doorbell' addresses are hard-wired to alert the MC when written */ +#define MC_SMEM_P0_DOORBELL_OFST 0x000 +#define MC_SMEM_P1_DOORBELL_OFST 0x004 +/* The rest of these are firmware-defined */ +#define MC_SMEM_P0_PDU_OFST 0x008 +#define MC_SMEM_P1_PDU_OFST 0x108 +#define MC_SMEM_PDU_LEN 0x100 +#define MC_SMEM_P0_PTP_TIME_OFST 0x7f0 +#define MC_SMEM_P0_STATUS_OFST 0x7f8 +#define MC_SMEM_P1_STATUS_OFST 0x7fc + /* Values to be written to the per-port status dword in shared * memory on reboot and assert */ #define MC_STATUS_DWORD_REBOOT (0xb007b007) @@ -34,6 +46,8 @@ */ #define MCDI_PCOL_VERSION 1 +/* Unused commands: 0x23, 0x27, 0x30, 0x31 */ + /** * MCDI version 1 * @@ -131,53 +145,6 @@ */ #define FSE_AZ_EV_CODE_MCDI_EVRESPONSE 0xc -#define MCDI_EVENT_DATA_LBN 0 -#define MCDI_EVENT_DATA_WIDTH 32 -#define MCDI_EVENT_CONT_LBN 32 -#define MCDI_EVENT_CONT_WIDTH 1 -#define MCDI_EVENT_LEVEL_LBN 33 -#define MCDI_EVENT_LEVEL_WIDTH 3 -#define MCDI_EVENT_LEVEL_INFO (0) -#define MCDI_EVENT_LEVEL_WARN (1) -#define MCDI_EVENT_LEVEL_ERR (2) -#define MCDI_EVENT_LEVEL_FATAL (3) -#define MCDI_EVENT_SRC_LBN 36 -#define MCDI_EVENT_SRC_WIDTH 8 -#define MCDI_EVENT_CODE_LBN 44 -#define MCDI_EVENT_CODE_WIDTH 8 -#define MCDI_EVENT_CODE_BADSSERT (1) -#define MCDI_EVENT_CODE_PMNOTICE (2) -#define MCDI_EVENT_CODE_CMDDONE (3) -#define MCDI_EVENT_CMDDONE_SEQ_LBN 0 -#define MCDI_EVENT_CMDDONE_SEQ_WIDTH 8 -#define MCDI_EVENT_CMDDONE_DATALEN_LBN 8 -#define MCDI_EVENT_CMDDONE_DATALEN_WIDTH 8 -#define MCDI_EVENT_CMDDONE_ERRNO_LBN 16 -#define MCDI_EVENT_CMDDONE_ERRNO_WIDTH 8 -#define MCDI_EVENT_CODE_LINKCHANGE (4) -#define MCDI_EVENT_LINKCHANGE_LP_CAP_LBN 0 -#define MCDI_EVENT_LINKCHANGE_LP_CAP_WIDTH 16 -#define MCDI_EVENT_LINKCHANGE_SPEED_LBN 16 -#define MCDI_EVENT_LINKCHANGE_SPEED_WIDTH 4 -#define MCDI_EVENT_LINKCHANGE_SPEED_100M 1 -#define MCDI_EVENT_LINKCHANGE_SPEED_1G 2 -#define MCDI_EVENT_LINKCHANGE_SPEED_10G 3 -#define MCDI_EVENT_LINKCHANGE_FCNTL_LBN 20 -#define MCDI_EVENT_LINKCHANGE_FCNTL_WIDTH 4 -#define MCDI_EVENT_LINKCHANGE_LINK_FLAGS_LBN 24 -#define MCDI_EVENT_LINKCHANGE_LINK_FLAGS_WIDTH 8 -#define MCDI_EVENT_CODE_SENSOREVT (5) -#define MCDI_EVENT_SENSOREVT_MONITOR_LBN 0 -#define MCDI_EVENT_SENSOREVT_MONITOR_WIDTH 8 -#define MCDI_EVENT_SENSOREVT_STATE_LBN 8 -#define MCDI_EVENT_SENSOREVT_STATE_WIDTH 8 -#define MCDI_EVENT_SENSOREVT_VALUE_LBN 16 -#define MCDI_EVENT_SENSOREVT_VALUE_WIDTH 16 -#define MCDI_EVENT_CODE_SCHEDERR (6) -#define MCDI_EVENT_CODE_REBOOT (7) -#define MCDI_EVENT_CODE_MAC_STATS_DMA (8) -#define MCDI_EVENT_MAC_STATS_DMA_GENERATION_LBN 0 -#define MCDI_EVENT_MAC_STATS_DMA_GENERATION_WIDTH 32 /* Non-existent command target */ #define MC_CMD_ERR_ENOENT 2 @@ -198,121 +165,24 @@ #define MC_CMD_ERR_CODE_OFST 0 +/* We define 8 "escape" commands to allow + for command number space extension */ + +#define MC_CMD_CMD_SPACE_ESCAPE_0 0x78 +#define MC_CMD_CMD_SPACE_ESCAPE_1 0x79 +#define MC_CMD_CMD_SPACE_ESCAPE_2 0x7A +#define MC_CMD_CMD_SPACE_ESCAPE_3 0x7B +#define MC_CMD_CMD_SPACE_ESCAPE_4 0x7C +#define MC_CMD_CMD_SPACE_ESCAPE_5 0x7D +#define MC_CMD_CMD_SPACE_ESCAPE_6 0x7E +#define MC_CMD_CMD_SPACE_ESCAPE_7 0x7F + +/* Vectors in the boot ROM */ +/* Point to the copycode entry point. */ +#define MC_BOOTROM_COPYCODE_VEC (0x7f4) +/* Points to the recovery mode entry point. */ +#define MC_BOOTROM_NOFLASH_VEC (0x7f8) -/* MC_CMD_READ32: (debug, variadic out) - * Read multiple 32byte words from MC memory - */ -#define MC_CMD_READ32 0x01 -#define MC_CMD_READ32_IN_LEN 8 -#define MC_CMD_READ32_IN_ADDR_OFST 0 -#define MC_CMD_READ32_IN_NUMWORDS_OFST 4 -#define MC_CMD_READ32_OUT_LEN(_numwords) \ - (4 * (_numwords)) -#define MC_CMD_READ32_OUT_BUFFER_OFST 0 - -/* MC_CMD_WRITE32: (debug, variadic in) - * Write multiple 32byte words to MC memory - */ -#define MC_CMD_WRITE32 0x02 -#define MC_CMD_WRITE32_IN_LEN(_numwords) (((_numwords) * 4) + 4) -#define MC_CMD_WRITE32_IN_ADDR_OFST 0 -#define MC_CMD_WRITE32_IN_BUFFER_OFST 4 -#define MC_CMD_WRITE32_OUT_LEN 0 - -/* MC_CMD_COPYCODE: (debug) - * Copy MC code between two locations and jump - */ -#define MC_CMD_COPYCODE 0x03 -#define MC_CMD_COPYCODE_IN_LEN 16 -#define MC_CMD_COPYCODE_IN_SRC_ADDR_OFST 0 -#define MC_CMD_COPYCODE_IN_DEST_ADDR_OFST 4 -#define MC_CMD_COPYCODE_IN_NUMWORDS_OFST 8 -#define MC_CMD_COPYCODE_IN_JUMP_OFST 12 -/* Control should return to the caller rather than jumping */ -#define MC_CMD_COPYCODE_JUMP_NONE 1 -#define MC_CMD_COPYCODE_OUT_LEN 0 - -/* MC_CMD_SET_FUNC: (debug) - * Select function for function-specific commands. - */ -#define MC_CMD_SET_FUNC 0x04 -#define MC_CMD_SET_FUNC_IN_LEN 4 -#define MC_CMD_SET_FUNC_IN_FUNC_OFST 0 -#define MC_CMD_SET_FUNC_OUT_LEN 0 - -/* MC_CMD_GET_BOOT_STATUS: - * Get the instruction address from which the MC booted. - */ -#define MC_CMD_GET_BOOT_STATUS 0x05 -#define MC_CMD_GET_BOOT_STATUS_IN_LEN 0 -#define MC_CMD_GET_BOOT_STATUS_OUT_LEN 8 -#define MC_CMD_GET_BOOT_STATUS_OUT_BOOT_OFFSET_OFST 0 -#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_OFST 4 -/* Reboot caused by watchdog */ -#define MC_CMD_GET_BOOT_STATUS_FLAGS_WATCHDOG_LBN (0) -#define MC_CMD_GET_BOOT_STATUS_FLAGS_WATCHDOG_WIDTH (1) -/* MC booted from primary flash partition */ -#define MC_CMD_GET_BOOT_STATUS_FLAGS_PRIMARY_LBN (1) -#define MC_CMD_GET_BOOT_STATUS_FLAGS_PRIMARY_WIDTH (1) -/* MC booted from backup flash partition */ -#define MC_CMD_GET_BOOT_STATUS_FLAGS_BACKUP_LBN (2) -#define MC_CMD_GET_BOOT_STATUS_FLAGS_BACKUP_WIDTH (1) - -/* MC_CMD_GET_ASSERTS: (debug, variadic out) - * Get (and optionally clear) the current assertion status. - * - * Only OUT.GLOBAL_FLAGS is guaranteed to exist in the completion - * payload. The other fields will only be present if - * OUT.GLOBAL_FLAGS != NO_FAILS - */ -#define MC_CMD_GET_ASSERTS 0x06 -#define MC_CMD_GET_ASSERTS_IN_LEN 4 -#define MC_CMD_GET_ASSERTS_IN_CLEAR_OFST 0 -#define MC_CMD_GET_ASSERTS_OUT_LEN 140 -/* Assertion status flag */ -#define MC_CMD_GET_ASSERTS_OUT_GLOBAL_FLAGS_OFST 0 -/*! No assertions have failed. */ -#define MC_CMD_GET_ASSERTS_FLAGS_NO_FAILS 1 -/*! A system-level assertion has failed. */ -#define MC_CMD_GET_ASSERTS_FLAGS_SYS_FAIL 2 -/*! A thread-level assertion has failed. */ -#define MC_CMD_GET_ASSERTS_FLAGS_THR_FAIL 3 -/*! The system was reset by the watchdog. */ -#define MC_CMD_GET_ASSERTS_FLAGS_WDOG_FIRED 4 -/* Failing PC value */ -#define MC_CMD_GET_ASSERTS_OUT_SAVED_PC_OFFS_OFST 4 -/* Saved GP regs */ -#define MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_OFST 8 -#define MC_CMD_GET_ASSERTS_OUT_GP_REGS_LEN 124 -/* Failing thread address */ -#define MC_CMD_GET_ASSERTS_OUT_THREAD_OFFS_OFST 132 - -/* MC_CMD_LOG_CTRL: - * Determine the output stream for various events and messages - */ -#define MC_CMD_LOG_CTRL 0x07 -#define MC_CMD_LOG_CTRL_IN_LEN 8 -#define MC_CMD_LOG_CTRL_IN_LOG_DEST_OFST 0 -#define MC_CMD_LOG_CTRL_IN_LOG_DEST_UART (1) -#define MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ (2) -#define MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ_OFST 4 -#define MC_CMD_LOG_CTRL_OUT_LEN 0 - -/* MC_CMD_GET_VERSION: - * Get version information about the MC firmware - */ -#define MC_CMD_GET_VERSION 0x08 -#define MC_CMD_GET_VERSION_IN_LEN 0 -#define MC_CMD_GET_VERSION_V0_OUT_LEN 4 -#define MC_CMD_GET_VERSION_V1_OUT_LEN 32 -#define MC_CMD_GET_VERSION_OUT_FIRMWARE_OFST 0 -/* Reserved version number to indicate "any" version. */ -#define MC_CMD_GET_VERSION_OUT_FIRMWARE_ANY 0xffffffff -/* The version response of a boot ROM awaiting rescue */ -#define MC_CMD_GET_VERSION_OUT_FIRMWARE_BOOTROM 0xb0070000 -#define MC_CMD_GET_VERSION_V1_OUT_PCOL_OFST 4 -/* 128bit mask of functions supported by the current firmware */ -#define MC_CMD_GET_VERSION_V1_OUT_SUPPORTED_FUNCS_OFST 8 /* The command set exported by the boot ROM (MCDI v0) */ #define MC_CMD_GET_VERSION_V0_SUPPORTED_FUNCS { \ (1 << MC_CMD_READ32) | \ @@ -320,1456 +190,2214 @@ (1 << MC_CMD_COPYCODE) | \ (1 << MC_CMD_GET_VERSION), \ 0, 0, 0 } -#define MC_CMD_GET_VERSION_OUT_VERSION_OFST 24 -/* Vectors in the boot ROM */ -/* Point to the copycode entry point. */ -#define MC_BOOTROM_COPYCODE_VEC (0x7f4) -/* Points to the recovery mode entry point. */ -#define MC_BOOTROM_NOFLASH_VEC (0x7f8) +#define MC_CMD_SENSOR_INFO_OUT_OFFSET_OFST(_x) \ + (MC_CMD_SENSOR_ENTRY_OFST + (_x)) + +#define MC_CMD_DBI_WRITE_IN_ADDRESS_OFST(n) \ + (MC_CMD_DBI_WRITE_IN_DBIWROP_OFST + \ + MC_CMD_DBIWROP_TYPEDEF_ADDRESS_OFST + \ + (n) * MC_CMD_DBIWROP_TYPEDEF_LEN) + +#define MC_CMD_DBI_WRITE_IN_BYTE_MASK_OFST(n) \ + (MC_CMD_DBI_WRITE_IN_DBIWROP_OFST + \ + MC_CMD_DBIWROP_TYPEDEF_BYTE_MASK_OFST + \ + (n) * MC_CMD_DBIWROP_TYPEDEF_LEN) + +#define MC_CMD_DBI_WRITE_IN_VALUE_OFST(n) \ + (MC_CMD_DBI_WRITE_IN_DBIWROP_OFST + \ + MC_CMD_DBIWROP_TYPEDEF_VALUE_OFST + \ + (n) * MC_CMD_DBIWROP_TYPEDEF_LEN) + + +/* MCDI_EVENT structuredef */ +#define MCDI_EVENT_LEN 8 +#define MCDI_EVENT_CONT_LBN 32 +#define MCDI_EVENT_CONT_WIDTH 1 +#define MCDI_EVENT_LEVEL_LBN 33 +#define MCDI_EVENT_LEVEL_WIDTH 3 +#define MCDI_EVENT_LEVEL_INFO 0x0 /* enum */ +#define MCDI_EVENT_LEVEL_WARN 0x1 /* enum */ +#define MCDI_EVENT_LEVEL_ERR 0x2 /* enum */ +#define MCDI_EVENT_LEVEL_FATAL 0x3 /* enum */ +#define MCDI_EVENT_DATA_OFST 0 +#define MCDI_EVENT_CMDDONE_SEQ_LBN 0 +#define MCDI_EVENT_CMDDONE_SEQ_WIDTH 8 +#define MCDI_EVENT_CMDDONE_DATALEN_LBN 8 +#define MCDI_EVENT_CMDDONE_DATALEN_WIDTH 8 +#define MCDI_EVENT_CMDDONE_ERRNO_LBN 16 +#define MCDI_EVENT_CMDDONE_ERRNO_WIDTH 8 +#define MCDI_EVENT_LINKCHANGE_LP_CAP_LBN 0 +#define MCDI_EVENT_LINKCHANGE_LP_CAP_WIDTH 16 +#define MCDI_EVENT_LINKCHANGE_SPEED_LBN 16 +#define MCDI_EVENT_LINKCHANGE_SPEED_WIDTH 4 +#define MCDI_EVENT_LINKCHANGE_SPEED_100M 0x1 /* enum */ +#define MCDI_EVENT_LINKCHANGE_SPEED_1G 0x2 /* enum */ +#define MCDI_EVENT_LINKCHANGE_SPEED_10G 0x3 /* enum */ +#define MCDI_EVENT_LINKCHANGE_FCNTL_LBN 20 +#define MCDI_EVENT_LINKCHANGE_FCNTL_WIDTH 4 +#define MCDI_EVENT_LINKCHANGE_LINK_FLAGS_LBN 24 +#define MCDI_EVENT_LINKCHANGE_LINK_FLAGS_WIDTH 8 +#define MCDI_EVENT_SENSOREVT_MONITOR_LBN 0 +#define MCDI_EVENT_SENSOREVT_MONITOR_WIDTH 8 +#define MCDI_EVENT_SENSOREVT_STATE_LBN 8 +#define MCDI_EVENT_SENSOREVT_STATE_WIDTH 8 +#define MCDI_EVENT_SENSOREVT_VALUE_LBN 16 +#define MCDI_EVENT_SENSOREVT_VALUE_WIDTH 16 +#define MCDI_EVENT_FWALERT_DATA_LBN 8 +#define MCDI_EVENT_FWALERT_DATA_WIDTH 24 +#define MCDI_EVENT_FWALERT_REASON_LBN 0 +#define MCDI_EVENT_FWALERT_REASON_WIDTH 8 +#define MCDI_EVENT_FWALERT_REASON_SRAM_ACCESS 0x1 /* enum */ +#define MCDI_EVENT_FLR_VF_LBN 0 +#define MCDI_EVENT_FLR_VF_WIDTH 8 +#define MCDI_EVENT_TX_ERR_TXQ_LBN 0 +#define MCDI_EVENT_TX_ERR_TXQ_WIDTH 12 +#define MCDI_EVENT_TX_ERR_TYPE_LBN 12 +#define MCDI_EVENT_TX_ERR_TYPE_WIDTH 4 +#define MCDI_EVENT_TX_ERR_DL_FAIL 0x1 /* enum */ +#define MCDI_EVENT_TX_ERR_NO_EOP 0x2 /* enum */ +#define MCDI_EVENT_TX_ERR_2BIG 0x3 /* enum */ +#define MCDI_EVENT_TX_ERR_INFO_LBN 16 +#define MCDI_EVENT_TX_ERR_INFO_WIDTH 16 +#define MCDI_EVENT_TX_FLUSH_TXQ_LBN 0 +#define MCDI_EVENT_TX_FLUSH_TXQ_WIDTH 12 +#define MCDI_EVENT_PTP_ERR_TYPE_LBN 0 +#define MCDI_EVENT_PTP_ERR_TYPE_WIDTH 8 +#define MCDI_EVENT_PTP_ERR_PLL_LOST 0x1 /* enum */ +#define MCDI_EVENT_PTP_ERR_FILTER 0x2 /* enum */ +#define MCDI_EVENT_PTP_ERR_FIFO 0x3 /* enum */ +#define MCDI_EVENT_PTP_ERR_QUEUE 0x4 /* enum */ +#define MCDI_EVENT_DATA_LBN 0 +#define MCDI_EVENT_DATA_WIDTH 32 +#define MCDI_EVENT_SRC_LBN 36 +#define MCDI_EVENT_SRC_WIDTH 8 +#define MCDI_EVENT_EV_CODE_LBN 60 +#define MCDI_EVENT_EV_CODE_WIDTH 4 +#define MCDI_EVENT_CODE_LBN 44 +#define MCDI_EVENT_CODE_WIDTH 8 +#define MCDI_EVENT_CODE_BADSSERT 0x1 /* enum */ +#define MCDI_EVENT_CODE_PMNOTICE 0x2 /* enum */ +#define MCDI_EVENT_CODE_CMDDONE 0x3 /* enum */ +#define MCDI_EVENT_CODE_LINKCHANGE 0x4 /* enum */ +#define MCDI_EVENT_CODE_SENSOREVT 0x5 /* enum */ +#define MCDI_EVENT_CODE_SCHEDERR 0x6 /* enum */ +#define MCDI_EVENT_CODE_REBOOT 0x7 /* enum */ +#define MCDI_EVENT_CODE_MAC_STATS_DMA 0x8 /* enum */ +#define MCDI_EVENT_CODE_FWALERT 0x9 /* enum */ +#define MCDI_EVENT_CODE_FLR 0xa /* enum */ +#define MCDI_EVENT_CODE_TX_ERR 0xb /* enum */ +#define MCDI_EVENT_CODE_TX_FLUSH 0xc /* enum */ +#define MCDI_EVENT_CODE_PTP_RX 0xd /* enum */ +#define MCDI_EVENT_CODE_PTP_FAULT 0xe /* enum */ +#define MCDI_EVENT_CMDDONE_DATA_OFST 0 +#define MCDI_EVENT_CMDDONE_DATA_LBN 0 +#define MCDI_EVENT_CMDDONE_DATA_WIDTH 32 +#define MCDI_EVENT_LINKCHANGE_DATA_OFST 0 +#define MCDI_EVENT_LINKCHANGE_DATA_LBN 0 +#define MCDI_EVENT_LINKCHANGE_DATA_WIDTH 32 +#define MCDI_EVENT_SENSOREVT_DATA_OFST 0 +#define MCDI_EVENT_SENSOREVT_DATA_LBN 0 +#define MCDI_EVENT_SENSOREVT_DATA_WIDTH 32 +#define MCDI_EVENT_MAC_STATS_DMA_GENERATION_OFST 0 +#define MCDI_EVENT_MAC_STATS_DMA_GENERATION_LBN 0 +#define MCDI_EVENT_MAC_STATS_DMA_GENERATION_WIDTH 32 +#define MCDI_EVENT_TX_ERR_DATA_OFST 0 +#define MCDI_EVENT_TX_ERR_DATA_LBN 0 +#define MCDI_EVENT_TX_ERR_DATA_WIDTH 32 +#define MCDI_EVENT_PTP_SECONDS_OFST 0 +#define MCDI_EVENT_PTP_SECONDS_LBN 0 +#define MCDI_EVENT_PTP_SECONDS_WIDTH 32 +#define MCDI_EVENT_PTP_NANOSECONDS_OFST 0 +#define MCDI_EVENT_PTP_NANOSECONDS_LBN 0 +#define MCDI_EVENT_PTP_NANOSECONDS_WIDTH 32 +#define MCDI_EVENT_PTP_UUID_OFST 0 +#define MCDI_EVENT_PTP_UUID_LBN 0 +#define MCDI_EVENT_PTP_UUID_WIDTH 32 + + +/***********************************/ +/* MC_CMD_READ32 + * Read multiple 32byte words from MC memory. + */ +#define MC_CMD_READ32 0x1 + +/* MC_CMD_READ32_IN msgrequest */ +#define MC_CMD_READ32_IN_LEN 8 +#define MC_CMD_READ32_IN_ADDR_OFST 0 +#define MC_CMD_READ32_IN_NUMWORDS_OFST 4 + +/* MC_CMD_READ32_OUT msgresponse */ +#define MC_CMD_READ32_OUT_LENMIN 4 +#define MC_CMD_READ32_OUT_LENMAX 252 +#define MC_CMD_READ32_OUT_LEN(num) (0+4*(num)) +#define MC_CMD_READ32_OUT_BUFFER_OFST 0 +#define MC_CMD_READ32_OUT_BUFFER_LEN 4 +#define MC_CMD_READ32_OUT_BUFFER_MINNUM 1 +#define MC_CMD_READ32_OUT_BUFFER_MAXNUM 63 + + +/***********************************/ +/* MC_CMD_WRITE32 + * Write multiple 32byte words to MC memory. + */ +#define MC_CMD_WRITE32 0x2 + +/* MC_CMD_WRITE32_IN msgrequest */ +#define MC_CMD_WRITE32_IN_LENMIN 8 +#define MC_CMD_WRITE32_IN_LENMAX 252 +#define MC_CMD_WRITE32_IN_LEN(num) (4+4*(num)) +#define MC_CMD_WRITE32_IN_ADDR_OFST 0 +#define MC_CMD_WRITE32_IN_BUFFER_OFST 4 +#define MC_CMD_WRITE32_IN_BUFFER_LEN 4 +#define MC_CMD_WRITE32_IN_BUFFER_MINNUM 1 +#define MC_CMD_WRITE32_IN_BUFFER_MAXNUM 62 + +/* MC_CMD_WRITE32_OUT msgresponse */ +#define MC_CMD_WRITE32_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_COPYCODE + * Copy MC code between two locations and jump. + */ +#define MC_CMD_COPYCODE 0x3 + +/* MC_CMD_COPYCODE_IN msgrequest */ +#define MC_CMD_COPYCODE_IN_LEN 16 +#define MC_CMD_COPYCODE_IN_SRC_ADDR_OFST 0 +#define MC_CMD_COPYCODE_IN_DEST_ADDR_OFST 4 +#define MC_CMD_COPYCODE_IN_NUMWORDS_OFST 8 +#define MC_CMD_COPYCODE_IN_JUMP_OFST 12 +#define MC_CMD_COPYCODE_JUMP_NONE 0x1 /* enum */ + +/* MC_CMD_COPYCODE_OUT msgresponse */ +#define MC_CMD_COPYCODE_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_SET_FUNC + */ +#define MC_CMD_SET_FUNC 0x4 + +/* MC_CMD_SET_FUNC_IN msgrequest */ +#define MC_CMD_SET_FUNC_IN_LEN 4 +#define MC_CMD_SET_FUNC_IN_FUNC_OFST 0 + +/* MC_CMD_SET_FUNC_OUT msgresponse */ +#define MC_CMD_SET_FUNC_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_GET_BOOT_STATUS + */ +#define MC_CMD_GET_BOOT_STATUS 0x5 + +/* MC_CMD_GET_BOOT_STATUS_IN msgrequest */ +#define MC_CMD_GET_BOOT_STATUS_IN_LEN 0 + +/* MC_CMD_GET_BOOT_STATUS_OUT msgresponse */ +#define MC_CMD_GET_BOOT_STATUS_OUT_LEN 8 +#define MC_CMD_GET_BOOT_STATUS_OUT_BOOT_OFFSET_OFST 0 +#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_OFST 4 +#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_WATCHDOG_LBN 0 +#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_WATCHDOG_WIDTH 1 +#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_PRIMARY_LBN 1 +#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_PRIMARY_WIDTH 1 +#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_BACKUP_LBN 2 +#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_BACKUP_WIDTH 1 -/* Test execution limits */ -#define MC_TESTEXEC_VARIANT_COUNT 16 -#define MC_TESTEXEC_RESULT_COUNT 7 -/* MC_CMD_SET_TESTVARS: (debug, variadic in) - * Write variant words for test. - * - * The user supplies a bitmap of the variants they wish to set. - * They must ensure that IN.LEN >= 4 + 4 * ffs(BITMAP) - */ -#define MC_CMD_SET_TESTVARS 0x09 -#define MC_CMD_SET_TESTVARS_IN_LEN(_numwords) \ - (4 + 4*(_numwords)) -#define MC_CMD_SET_TESTVARS_IN_ARGS_BITMAP_OFST 0 -/* Up to MC_TESTEXEC_VARIANT_COUNT of 32byte words start here */ -#define MC_CMD_SET_TESTVARS_IN_ARGS_BUFFER_OFST 4 -#define MC_CMD_SET_TESTVARS_OUT_LEN 0 - -/* MC_CMD_GET_TESTRCS: (debug, variadic out) - * Return result words from test. - */ -#define MC_CMD_GET_TESTRCS 0x0a -#define MC_CMD_GET_TESTRCS_IN_LEN 4 -#define MC_CMD_GET_TESTRCS_IN_NUMWORDS_OFST 0 -#define MC_CMD_GET_TESTRCS_OUT_LEN(_numwords) \ - (4 * (_numwords)) -#define MC_CMD_GET_TESTRCS_OUT_BUFFER_OFST 0 - -/* MC_CMD_RUN_TEST: (debug) - * Run the test exported by this firmware image - */ -#define MC_CMD_RUN_TEST 0x0b -#define MC_CMD_RUN_TEST_IN_LEN 0 -#define MC_CMD_RUN_TEST_OUT_LEN 0 - -/* MC_CMD_CSR_READ32: (debug, variadic out) - * Read 32bit words from the indirect memory map - */ -#define MC_CMD_CSR_READ32 0x0c -#define MC_CMD_CSR_READ32_IN_LEN 12 -#define MC_CMD_CSR_READ32_IN_ADDR_OFST 0 -#define MC_CMD_CSR_READ32_IN_STEP_OFST 4 -#define MC_CMD_CSR_READ32_IN_NUMWORDS_OFST 8 -#define MC_CMD_CSR_READ32_OUT_LEN(_numwords) \ - (((_numwords) * 4) + 4) -/* IN.NUMWORDS of 32bit words start here */ -#define MC_CMD_CSR_READ32_OUT_BUFFER_OFST 0 -#define MC_CMD_CSR_READ32_OUT_IREG_STATUS_OFST(_numwords) \ - ((_numwords) * 4) - -/* MC_CMD_CSR_WRITE32: (debug, variadic in) - * Write 32bit dwords to the indirect memory map - */ -#define MC_CMD_CSR_WRITE32 0x0d -#define MC_CMD_CSR_WRITE32_IN_LEN(_numwords) \ - (((_numwords) * 4) + 8) -#define MC_CMD_CSR_WRITE32_IN_ADDR_OFST 0 -#define MC_CMD_CSR_WRITE32_IN_STEP_OFST 4 -/* Multiple 32bit words of data to write start here */ -#define MC_CMD_CSR_WRITE32_IN_BUFFER_OFST 8 -#define MC_CMD_CSR_WRITE32_OUT_LEN 4 -#define MC_CMD_CSR_WRITE32_OUT_STATUS_OFST 0 - -/* MC_CMD_JTAG_WORK: (debug, fpga only) - * Process JTAG work buffer for RBF acceleration. - * - * Host: bit count, (up to) 32 words of data to clock out to JTAG - * (bits 1,0=TMS,TDO for first bit; bits 3,2=TMS,TDO for second bit, etc.) - * MC: bit count, (up to) 32 words of data clocked in from JTAG - * (bit 0=TDI for first bit, bit 1=TDI for second bit, etc.; [31:16] unused) +/***********************************/ +/* MC_CMD_GET_ASSERTS + * Get and clear any assertion status. */ -#define MC_CMD_JTAG_WORK 0x0e +#define MC_CMD_GET_ASSERTS 0x6 -/* MC_CMD_STACKINFO: (debug, variadic out) - * Get stack information - * - * Host: nothing - * MC: (thread ptr, stack size, free space) for each thread in system - */ -#define MC_CMD_STACKINFO 0x0f +/* MC_CMD_GET_ASSERTS_IN msgrequest */ +#define MC_CMD_GET_ASSERTS_IN_LEN 4 +#define MC_CMD_GET_ASSERTS_IN_CLEAR_OFST 0 + +/* MC_CMD_GET_ASSERTS_OUT msgresponse */ +#define MC_CMD_GET_ASSERTS_OUT_LEN 140 +#define MC_CMD_GET_ASSERTS_OUT_GLOBAL_FLAGS_OFST 0 +#define MC_CMD_GET_ASSERTS_FLAGS_NO_FAILS 0x1 /* enum */ +#define MC_CMD_GET_ASSERTS_FLAGS_SYS_FAIL 0x2 /* enum */ +#define MC_CMD_GET_ASSERTS_FLAGS_THR_FAIL 0x3 /* enum */ +#define MC_CMD_GET_ASSERTS_FLAGS_WDOG_FIRED 0x4 /* enum */ +#define MC_CMD_GET_ASSERTS_OUT_SAVED_PC_OFFS_OFST 4 +#define MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_OFST 8 +#define MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_LEN 4 +#define MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_NUM 31 +#define MC_CMD_GET_ASSERTS_OUT_THREAD_OFFS_OFST 132 +#define MC_CMD_GET_ASSERTS_OUT_RESERVED_OFST 136 -/* MC_CMD_MDIO_READ: - * MDIO register read + +/***********************************/ +/* MC_CMD_LOG_CTRL + * Configure the output stream for various events and messages. + */ +#define MC_CMD_LOG_CTRL 0x7 + +/* MC_CMD_LOG_CTRL_IN msgrequest */ +#define MC_CMD_LOG_CTRL_IN_LEN 8 +#define MC_CMD_LOG_CTRL_IN_LOG_DEST_OFST 0 +#define MC_CMD_LOG_CTRL_IN_LOG_DEST_UART 0x1 /* enum */ +#define MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ 0x2 /* enum */ +#define MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ_OFST 4 + +/* MC_CMD_LOG_CTRL_OUT msgresponse */ +#define MC_CMD_LOG_CTRL_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_GET_VERSION + * Get version information about the MC firmware. + */ +#define MC_CMD_GET_VERSION 0x8 + +/* MC_CMD_GET_VERSION_IN msgrequest */ +#define MC_CMD_GET_VERSION_IN_LEN 0 + +/* MC_CMD_GET_VERSION_V0_OUT msgresponse */ +#define MC_CMD_GET_VERSION_V0_OUT_LEN 4 +#define MC_CMD_GET_VERSION_OUT_FIRMWARE_OFST 0 +#define MC_CMD_GET_VERSION_OUT_FIRMWARE_ANY 0xffffffff /* enum */ +#define MC_CMD_GET_VERSION_OUT_FIRMWARE_BOOTROM 0xb0070000 /* enum */ + +/* MC_CMD_GET_VERSION_OUT msgresponse */ +#define MC_CMD_GET_VERSION_OUT_LEN 32 +/* MC_CMD_GET_VERSION_OUT_FIRMWARE_OFST 0 */ +/* Enum values, see field(s): */ +/* MC_CMD_GET_VERSION_V0_OUT/MC_CMD_GET_VERSION_OUT_FIRMWARE */ +#define MC_CMD_GET_VERSION_OUT_PCOL_OFST 4 +#define MC_CMD_GET_VERSION_OUT_SUPPORTED_FUNCS_OFST 8 +#define MC_CMD_GET_VERSION_OUT_SUPPORTED_FUNCS_LEN 16 +#define MC_CMD_GET_VERSION_OUT_VERSION_OFST 24 +#define MC_CMD_GET_VERSION_OUT_VERSION_LEN 8 +#define MC_CMD_GET_VERSION_OUT_VERSION_LO_OFST 24 +#define MC_CMD_GET_VERSION_OUT_VERSION_HI_OFST 28 + + +/***********************************/ +/* MC_CMD_GET_FPGAREG + * Read multiple bytes from PTP FPGA. + */ +#define MC_CMD_GET_FPGAREG 0x9 + +/* MC_CMD_GET_FPGAREG_IN msgrequest */ +#define MC_CMD_GET_FPGAREG_IN_LEN 8 +#define MC_CMD_GET_FPGAREG_IN_ADDR_OFST 0 +#define MC_CMD_GET_FPGAREG_IN_NUMBYTES_OFST 4 + +/* MC_CMD_GET_FPGAREG_OUT msgresponse */ +#define MC_CMD_GET_FPGAREG_OUT_LENMIN 1 +#define MC_CMD_GET_FPGAREG_OUT_LENMAX 255 +#define MC_CMD_GET_FPGAREG_OUT_LEN(num) (0+1*(num)) +#define MC_CMD_GET_FPGAREG_OUT_BUFFER_OFST 0 +#define MC_CMD_GET_FPGAREG_OUT_BUFFER_LEN 1 +#define MC_CMD_GET_FPGAREG_OUT_BUFFER_MINNUM 1 +#define MC_CMD_GET_FPGAREG_OUT_BUFFER_MAXNUM 255 + + +/***********************************/ +/* MC_CMD_PUT_FPGAREG + * Write multiple bytes to PTP FPGA. + */ +#define MC_CMD_PUT_FPGAREG 0xa + +/* MC_CMD_PUT_FPGAREG_IN msgrequest */ +#define MC_CMD_PUT_FPGAREG_IN_LENMIN 5 +#define MC_CMD_PUT_FPGAREG_IN_LENMAX 255 +#define MC_CMD_PUT_FPGAREG_IN_LEN(num) (4+1*(num)) +#define MC_CMD_PUT_FPGAREG_IN_ADDR_OFST 0 +#define MC_CMD_PUT_FPGAREG_IN_BUFFER_OFST 4 +#define MC_CMD_PUT_FPGAREG_IN_BUFFER_LEN 1 +#define MC_CMD_PUT_FPGAREG_IN_BUFFER_MINNUM 1 +#define MC_CMD_PUT_FPGAREG_IN_BUFFER_MAXNUM 251 + +/* MC_CMD_PUT_FPGAREG_OUT msgresponse */ +#define MC_CMD_PUT_FPGAREG_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_PTP + * Perform PTP operation + */ +#define MC_CMD_PTP 0xb + +/* MC_CMD_PTP_IN msgrequest */ +#define MC_CMD_PTP_IN_LEN 1 +#define MC_CMD_PTP_IN_OP_OFST 0 +#define MC_CMD_PTP_IN_OP_LEN 1 +#define MC_CMD_PTP_OP_ENABLE 0x1 /* enum */ +#define MC_CMD_PTP_OP_DISABLE 0x2 /* enum */ +#define MC_CMD_PTP_OP_TRANSMIT 0x3 /* enum */ +#define MC_CMD_PTP_OP_READ_NIC_TIME 0x4 /* enum */ +#define MC_CMD_PTP_OP_STATUS 0x5 /* enum */ +#define MC_CMD_PTP_OP_ADJUST 0x6 /* enum */ +#define MC_CMD_PTP_OP_SYNCHRONIZE 0x7 /* enum */ +#define MC_CMD_PTP_OP_MANFTEST_BASIC 0x8 /* enum */ +#define MC_CMD_PTP_OP_MANFTEST_PACKET 0x9 /* enum */ +#define MC_CMD_PTP_OP_RESET_STATS 0xa /* enum */ +#define MC_CMD_PTP_OP_DEBUG 0xb /* enum */ +#define MC_CMD_PTP_OP_MAX 0xc /* enum */ + +/* MC_CMD_PTP_IN_ENABLE msgrequest */ +#define MC_CMD_PTP_IN_ENABLE_LEN 16 +#define MC_CMD_PTP_IN_CMD_OFST 0 +#define MC_CMD_PTP_IN_PERIPH_ID_OFST 4 +#define MC_CMD_PTP_IN_ENABLE_QUEUE_OFST 8 +#define MC_CMD_PTP_IN_ENABLE_MODE_OFST 12 +#define MC_CMD_PTP_MODE_V1 0x0 /* enum */ +#define MC_CMD_PTP_MODE_V1_VLAN 0x1 /* enum */ +#define MC_CMD_PTP_MODE_V2 0x2 /* enum */ +#define MC_CMD_PTP_MODE_V2_VLAN 0x3 /* enum */ + +/* MC_CMD_PTP_IN_DISABLE msgrequest */ +#define MC_CMD_PTP_IN_DISABLE_LEN 8 +/* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ + +/* MC_CMD_PTP_IN_TRANSMIT msgrequest */ +#define MC_CMD_PTP_IN_TRANSMIT_LENMIN 13 +#define MC_CMD_PTP_IN_TRANSMIT_LENMAX 255 +#define MC_CMD_PTP_IN_TRANSMIT_LEN(num) (12+1*(num)) +/* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +#define MC_CMD_PTP_IN_TRANSMIT_LENGTH_OFST 8 +#define MC_CMD_PTP_IN_TRANSMIT_PACKET_OFST 12 +#define MC_CMD_PTP_IN_TRANSMIT_PACKET_LEN 1 +#define MC_CMD_PTP_IN_TRANSMIT_PACKET_MINNUM 1 +#define MC_CMD_PTP_IN_TRANSMIT_PACKET_MAXNUM 243 + +/* MC_CMD_PTP_IN_READ_NIC_TIME msgrequest */ +#define MC_CMD_PTP_IN_READ_NIC_TIME_LEN 8 +/* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ + +/* MC_CMD_PTP_IN_STATUS msgrequest */ +#define MC_CMD_PTP_IN_STATUS_LEN 8 +/* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ + +/* MC_CMD_PTP_IN_ADJUST msgrequest */ +#define MC_CMD_PTP_IN_ADJUST_LEN 24 +/* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +#define MC_CMD_PTP_IN_ADJUST_FREQ_OFST 8 +#define MC_CMD_PTP_IN_ADJUST_FREQ_LEN 8 +#define MC_CMD_PTP_IN_ADJUST_FREQ_LO_OFST 8 +#define MC_CMD_PTP_IN_ADJUST_FREQ_HI_OFST 12 +#define MC_CMD_PTP_IN_ADJUST_BITS 0x28 /* enum */ +#define MC_CMD_PTP_IN_ADJUST_SECONDS_OFST 16 +#define MC_CMD_PTP_IN_ADJUST_NANOSECONDS_OFST 20 + +/* MC_CMD_PTP_IN_SYNCHRONIZE msgrequest */ +#define MC_CMD_PTP_IN_SYNCHRONIZE_LEN 20 +/* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +#define MC_CMD_PTP_IN_SYNCHRONIZE_NUMTIMESETS_OFST 8 +#define MC_CMD_PTP_IN_SYNCHRONIZE_START_ADDR_OFST 12 +#define MC_CMD_PTP_IN_SYNCHRONIZE_START_ADDR_LEN 8 +#define MC_CMD_PTP_IN_SYNCHRONIZE_START_ADDR_LO_OFST 12 +#define MC_CMD_PTP_IN_SYNCHRONIZE_START_ADDR_HI_OFST 16 + +/* MC_CMD_PTP_IN_MANFTEST_BASIC msgrequest */ +#define MC_CMD_PTP_IN_MANFTEST_BASIC_LEN 8 +/* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ + +/* MC_CMD_PTP_IN_MANFTEST_PACKET msgrequest */ +#define MC_CMD_PTP_IN_MANFTEST_PACKET_LEN 12 +/* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +#define MC_CMD_PTP_IN_MANFTEST_PACKET_TEST_ENABLE_OFST 8 + +/* MC_CMD_PTP_IN_RESET_STATS msgrequest */ +#define MC_CMD_PTP_IN_RESET_STATS_LEN 8 +/* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ + +/* MC_CMD_PTP_IN_DEBUG msgrequest */ +#define MC_CMD_PTP_IN_DEBUG_LEN 12 +/* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +#define MC_CMD_PTP_IN_DEBUG_DEBUG_PARAM_OFST 8 + +/* MC_CMD_PTP_OUT msgresponse */ +#define MC_CMD_PTP_OUT_LEN 0 + +/* MC_CMD_PTP_OUT_TRANSMIT msgresponse */ +#define MC_CMD_PTP_OUT_TRANSMIT_LEN 8 +#define MC_CMD_PTP_OUT_TRANSMIT_SECONDS_OFST 0 +#define MC_CMD_PTP_OUT_TRANSMIT_NANOSECONDS_OFST 4 + +/* MC_CMD_PTP_OUT_READ_NIC_TIME msgresponse */ +#define MC_CMD_PTP_OUT_READ_NIC_TIME_LEN 8 +#define MC_CMD_PTP_OUT_READ_NIC_TIME_SECONDS_OFST 0 +#define MC_CMD_PTP_OUT_READ_NIC_TIME_NANOSECONDS_OFST 4 + +/* MC_CMD_PTP_OUT_STATUS msgresponse */ +#define MC_CMD_PTP_OUT_STATUS_LEN 64 +#define MC_CMD_PTP_OUT_STATUS_CLOCK_FREQ_OFST 0 +#define MC_CMD_PTP_OUT_STATUS_STATS_TX_OFST 4 +#define MC_CMD_PTP_OUT_STATUS_STATS_RX_OFST 8 +#define MC_CMD_PTP_OUT_STATUS_STATS_TS_OFST 12 +#define MC_CMD_PTP_OUT_STATUS_STATS_FM_OFST 16 +#define MC_CMD_PTP_OUT_STATUS_STATS_NFM_OFST 20 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFLOW_OFST 24 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_BAD_OFST 28 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_MIN_OFST 32 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_MAX_OFST 36 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_LAST_OFST 40 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_MEAN_OFST 44 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_MIN_OFST 48 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_MAX_OFST 52 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_LAST_OFST 56 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_MEAN_OFST 60 + +/* MC_CMD_PTP_OUT_SYNCHRONIZE msgresponse */ +#define MC_CMD_PTP_OUT_SYNCHRONIZE_LENMIN 20 +#define MC_CMD_PTP_OUT_SYNCHRONIZE_LENMAX 240 +#define MC_CMD_PTP_OUT_SYNCHRONIZE_LEN(num) (0+20*(num)) +#define MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_OFST 0 +#define MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_LEN 20 +#define MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_MINNUM 1 +#define MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_MAXNUM 12 +#define MC_CMD_PTP_OUT_SYNCHRONIZE_HOSTSTART_OFST 0 +#define MC_CMD_PTP_OUT_SYNCHRONIZE_SECONDS_OFST 4 +#define MC_CMD_PTP_OUT_SYNCHRONIZE_NANOSECONDS_OFST 8 +#define MC_CMD_PTP_OUT_SYNCHRONIZE_HOSTEND_OFST 12 +#define MC_CMD_PTP_OUT_SYNCHRONIZE_WAITNS_OFST 16 + +/* MC_CMD_PTP_OUT_MANFTEST_BASIC msgresponse */ +#define MC_CMD_PTP_OUT_MANFTEST_BASIC_LEN 8 +#define MC_CMD_PTP_OUT_MANFTEST_BASIC_TEST_RESULT_OFST 0 +#define MC_CMD_PTP_MANF_SUCCESS 0x0 /* enum */ +#define MC_CMD_PTP_MANF_FPGA_LOAD 0x1 /* enum */ +#define MC_CMD_PTP_MANF_FPGA_VERSION 0x2 /* enum */ +#define MC_CMD_PTP_MANF_FPGA_REGISTERS 0x3 /* enum */ +#define MC_CMD_PTP_MANF_OSCILLATOR 0x4 /* enum */ +#define MC_CMD_PTP_MANF_TIMESTAMPS 0x5 /* enum */ +#define MC_CMD_PTP_MANF_PACKET_COUNT 0x6 /* enum */ +#define MC_CMD_PTP_MANF_FILTER_COUNT 0x7 /* enum */ +#define MC_CMD_PTP_MANF_PACKET_ENOUGH 0x8 /* enum */ +#define MC_CMD_PTP_MANF_GPIO_TRIGGER 0x9 /* enum */ +#define MC_CMD_PTP_OUT_MANFTEST_BASIC_TEST_EXTOSC_OFST 4 + +/* MC_CMD_PTP_OUT_MANFTEST_PACKET msgresponse */ +#define MC_CMD_PTP_OUT_MANFTEST_PACKET_LEN 12 +#define MC_CMD_PTP_OUT_MANFTEST_PACKET_TEST_RESULT_OFST 0 +#define MC_CMD_PTP_OUT_MANFTEST_PACKET_TEST_FPGACOUNT_OFST 4 +#define MC_CMD_PTP_OUT_MANFTEST_PACKET_TEST_FILTERCOUNT_OFST 8 + + +/***********************************/ +/* MC_CMD_CSR_READ32 + * Read 32bit words from the indirect memory map. + */ +#define MC_CMD_CSR_READ32 0xc + +/* MC_CMD_CSR_READ32_IN msgrequest */ +#define MC_CMD_CSR_READ32_IN_LEN 12 +#define MC_CMD_CSR_READ32_IN_ADDR_OFST 0 +#define MC_CMD_CSR_READ32_IN_STEP_OFST 4 +#define MC_CMD_CSR_READ32_IN_NUMWORDS_OFST 8 + +/* MC_CMD_CSR_READ32_OUT msgresponse */ +#define MC_CMD_CSR_READ32_OUT_LENMIN 4 +#define MC_CMD_CSR_READ32_OUT_LENMAX 252 +#define MC_CMD_CSR_READ32_OUT_LEN(num) (0+4*(num)) +#define MC_CMD_CSR_READ32_OUT_BUFFER_OFST 0 +#define MC_CMD_CSR_READ32_OUT_BUFFER_LEN 4 +#define MC_CMD_CSR_READ32_OUT_BUFFER_MINNUM 1 +#define MC_CMD_CSR_READ32_OUT_BUFFER_MAXNUM 63 + + +/***********************************/ +/* MC_CMD_CSR_WRITE32 + * Write 32bit dwords to the indirect memory map. + */ +#define MC_CMD_CSR_WRITE32 0xd + +/* MC_CMD_CSR_WRITE32_IN msgrequest */ +#define MC_CMD_CSR_WRITE32_IN_LENMIN 12 +#define MC_CMD_CSR_WRITE32_IN_LENMAX 252 +#define MC_CMD_CSR_WRITE32_IN_LEN(num) (8+4*(num)) +#define MC_CMD_CSR_WRITE32_IN_ADDR_OFST 0 +#define MC_CMD_CSR_WRITE32_IN_STEP_OFST 4 +#define MC_CMD_CSR_WRITE32_IN_BUFFER_OFST 8 +#define MC_CMD_CSR_WRITE32_IN_BUFFER_LEN 4 +#define MC_CMD_CSR_WRITE32_IN_BUFFER_MINNUM 1 +#define MC_CMD_CSR_WRITE32_IN_BUFFER_MAXNUM 61 + +/* MC_CMD_CSR_WRITE32_OUT msgresponse */ +#define MC_CMD_CSR_WRITE32_OUT_LEN 4 +#define MC_CMD_CSR_WRITE32_OUT_STATUS_OFST 0 + + +/***********************************/ +/* MC_CMD_STACKINFO + * Get stack information. + */ +#define MC_CMD_STACKINFO 0xf + +/* MC_CMD_STACKINFO_IN msgrequest */ +#define MC_CMD_STACKINFO_IN_LEN 0 + +/* MC_CMD_STACKINFO_OUT msgresponse */ +#define MC_CMD_STACKINFO_OUT_LENMIN 12 +#define MC_CMD_STACKINFO_OUT_LENMAX 252 +#define MC_CMD_STACKINFO_OUT_LEN(num) (0+12*(num)) +#define MC_CMD_STACKINFO_OUT_THREAD_INFO_OFST 0 +#define MC_CMD_STACKINFO_OUT_THREAD_INFO_LEN 12 +#define MC_CMD_STACKINFO_OUT_THREAD_INFO_MINNUM 1 +#define MC_CMD_STACKINFO_OUT_THREAD_INFO_MAXNUM 21 + + +/***********************************/ +/* MC_CMD_MDIO_READ + * MDIO register read. */ #define MC_CMD_MDIO_READ 0x10 -#define MC_CMD_MDIO_READ_IN_LEN 16 -#define MC_CMD_MDIO_READ_IN_BUS_OFST 0 -#define MC_CMD_MDIO_READ_IN_PRTAD_OFST 4 -#define MC_CMD_MDIO_READ_IN_DEVAD_OFST 8 -#define MC_CMD_MDIO_READ_IN_ADDR_OFST 12 -#define MC_CMD_MDIO_READ_OUT_LEN 8 -#define MC_CMD_MDIO_READ_OUT_VALUE_OFST 0 -#define MC_CMD_MDIO_READ_OUT_STATUS_OFST 4 - -/* MC_CMD_MDIO_WRITE: - * MDIO register write - */ -#define MC_CMD_MDIO_WRITE 0x11 -#define MC_CMD_MDIO_WRITE_IN_LEN 20 -#define MC_CMD_MDIO_WRITE_IN_BUS_OFST 0 -#define MC_CMD_MDIO_WRITE_IN_PRTAD_OFST 4 -#define MC_CMD_MDIO_WRITE_IN_DEVAD_OFST 8 -#define MC_CMD_MDIO_WRITE_IN_ADDR_OFST 12 -#define MC_CMD_MDIO_WRITE_IN_VALUE_OFST 16 -#define MC_CMD_MDIO_WRITE_OUT_LEN 4 -#define MC_CMD_MDIO_WRITE_OUT_STATUS_OFST 0 -/* By default all the MCDI MDIO operations perform clause45 mode. - * If you want to use clause22 then set DEVAD = MC_CMD_MDIO_CLAUSE22. - */ -#define MC_CMD_MDIO_CLAUSE22 32 +/* MC_CMD_MDIO_READ_IN msgrequest */ +#define MC_CMD_MDIO_READ_IN_LEN 16 +#define MC_CMD_MDIO_READ_IN_BUS_OFST 0 +#define MC_CMD_MDIO_BUS_INTERNAL 0x0 /* enum */ +#define MC_CMD_MDIO_BUS_EXTERNAL 0x1 /* enum */ +#define MC_CMD_MDIO_READ_IN_PRTAD_OFST 4 +#define MC_CMD_MDIO_READ_IN_DEVAD_OFST 8 +#define MC_CMD_MDIO_CLAUSE22 0x20 /* enum */ +#define MC_CMD_MDIO_READ_IN_ADDR_OFST 12 -/* There are two MDIO buses: one for the internal PHY, and one for external - * devices. - */ -#define MC_CMD_MDIO_BUS_INTERNAL 0 -#define MC_CMD_MDIO_BUS_EXTERNAL 1 +/* MC_CMD_MDIO_READ_OUT msgresponse */ +#define MC_CMD_MDIO_READ_OUT_LEN 8 +#define MC_CMD_MDIO_READ_OUT_VALUE_OFST 0 +#define MC_CMD_MDIO_READ_OUT_STATUS_OFST 4 +#define MC_CMD_MDIO_STATUS_GOOD 0x8 /* enum */ -/* The MDIO commands return the raw status bits from the MDIO block. A "good" - * transaction should have the DONE bit set and all other bits clear. + +/***********************************/ +/* MC_CMD_MDIO_WRITE + * MDIO register write. */ -#define MC_CMD_MDIO_STATUS_GOOD 0x08 +#define MC_CMD_MDIO_WRITE 0x11 +/* MC_CMD_MDIO_WRITE_IN msgrequest */ +#define MC_CMD_MDIO_WRITE_IN_LEN 20 +#define MC_CMD_MDIO_WRITE_IN_BUS_OFST 0 +/* MC_CMD_MDIO_BUS_INTERNAL 0x0 */ +/* MC_CMD_MDIO_BUS_EXTERNAL 0x1 */ +#define MC_CMD_MDIO_WRITE_IN_PRTAD_OFST 4 +#define MC_CMD_MDIO_WRITE_IN_DEVAD_OFST 8 +/* MC_CMD_MDIO_CLAUSE22 0x20 */ +#define MC_CMD_MDIO_WRITE_IN_ADDR_OFST 12 +#define MC_CMD_MDIO_WRITE_IN_VALUE_OFST 16 -/* MC_CMD_DBI_WRITE: (debug) - * Write DBI register(s) - * - * Host: address, byte-enables (and VF selection, and cs2 flag), - * value [,address ...] - * MC: nothing +/* MC_CMD_MDIO_WRITE_OUT msgresponse */ +#define MC_CMD_MDIO_WRITE_OUT_LEN 4 +#define MC_CMD_MDIO_WRITE_OUT_STATUS_OFST 0 +/* MC_CMD_MDIO_STATUS_GOOD 0x8 */ + + +/***********************************/ +/* MC_CMD_DBI_WRITE + * Write DBI register(s). */ #define MC_CMD_DBI_WRITE 0x12 -#define MC_CMD_DBI_WRITE_IN_LEN(_numwords) \ - (12 * (_numwords)) -#define MC_CMD_DBI_WRITE_IN_ADDRESS_OFST(_word) \ - (((_word) * 12) + 0) -#define MC_CMD_DBI_WRITE_IN_BYTE_MASK_OFST(_word) \ - (((_word) * 12) + 4) -#define MC_CMD_DBI_WRITE_IN_VALUE_OFST(_word) \ - (((_word) * 12) + 8) -#define MC_CMD_DBI_WRITE_OUT_LEN 0 - -/* MC_CMD_DBI_READ: (debug) - * Read DBI register(s) - * - * Host: address, [,address ...] - * MC: value [,value ...] - * (note: this does not support reading from VFs, but is retained for backwards - * compatibility; see MC_CMD_DBI_READX below) - */ -#define MC_CMD_DBI_READ 0x13 -#define MC_CMD_DBI_READ_IN_LEN(_numwords) \ - (4 * (_numwords)) -#define MC_CMD_DBI_READ_OUT_LEN(_numwords) \ - (4 * (_numwords)) - -/* MC_CMD_PORT_READ32: (debug) + +/* MC_CMD_DBI_WRITE_IN msgrequest */ +#define MC_CMD_DBI_WRITE_IN_LENMIN 12 +#define MC_CMD_DBI_WRITE_IN_LENMAX 252 +#define MC_CMD_DBI_WRITE_IN_LEN(num) (0+12*(num)) +#define MC_CMD_DBI_WRITE_IN_DBIWROP_OFST 0 +#define MC_CMD_DBI_WRITE_IN_DBIWROP_LEN 12 +#define MC_CMD_DBI_WRITE_IN_DBIWROP_MINNUM 1 +#define MC_CMD_DBI_WRITE_IN_DBIWROP_MAXNUM 21 + +/* MC_CMD_DBI_WRITE_OUT msgresponse */ +#define MC_CMD_DBI_WRITE_OUT_LEN 0 + +/* MC_CMD_DBIWROP_TYPEDEF structuredef */ +#define MC_CMD_DBIWROP_TYPEDEF_LEN 12 +#define MC_CMD_DBIWROP_TYPEDEF_ADDRESS_OFST 0 +#define MC_CMD_DBIWROP_TYPEDEF_ADDRESS_LBN 0 +#define MC_CMD_DBIWROP_TYPEDEF_ADDRESS_WIDTH 32 +#define MC_CMD_DBIWROP_TYPEDEF_BYTE_MASK_OFST 4 +#define MC_CMD_DBIWROP_TYPEDEF_BYTE_MASK_LBN 32 +#define MC_CMD_DBIWROP_TYPEDEF_BYTE_MASK_WIDTH 32 +#define MC_CMD_DBIWROP_TYPEDEF_VALUE_OFST 8 +#define MC_CMD_DBIWROP_TYPEDEF_VALUE_LBN 64 +#define MC_CMD_DBIWROP_TYPEDEF_VALUE_WIDTH 32 + + +/***********************************/ +/* MC_CMD_PORT_READ32 * Read a 32-bit register from the indirect port register map. - * - * The port to access is implied by the Shared memory channel used. */ #define MC_CMD_PORT_READ32 0x14 -#define MC_CMD_PORT_READ32_IN_LEN 4 -#define MC_CMD_PORT_READ32_IN_ADDR_OFST 0 -#define MC_CMD_PORT_READ32_OUT_LEN 8 -#define MC_CMD_PORT_READ32_OUT_VALUE_OFST 0 -#define MC_CMD_PORT_READ32_OUT_STATUS_OFST 4 -/* MC_CMD_PORT_WRITE32: (debug) +/* MC_CMD_PORT_READ32_IN msgrequest */ +#define MC_CMD_PORT_READ32_IN_LEN 4 +#define MC_CMD_PORT_READ32_IN_ADDR_OFST 0 + +/* MC_CMD_PORT_READ32_OUT msgresponse */ +#define MC_CMD_PORT_READ32_OUT_LEN 8 +#define MC_CMD_PORT_READ32_OUT_VALUE_OFST 0 +#define MC_CMD_PORT_READ32_OUT_STATUS_OFST 4 + + +/***********************************/ +/* MC_CMD_PORT_WRITE32 * Write a 32-bit register to the indirect port register map. - * - * The port to access is implied by the Shared memory channel used. */ #define MC_CMD_PORT_WRITE32 0x15 -#define MC_CMD_PORT_WRITE32_IN_LEN 8 -#define MC_CMD_PORT_WRITE32_IN_ADDR_OFST 0 -#define MC_CMD_PORT_WRITE32_IN_VALUE_OFST 4 -#define MC_CMD_PORT_WRITE32_OUT_LEN 4 -#define MC_CMD_PORT_WRITE32_OUT_STATUS_OFST 0 - -/* MC_CMD_PORT_READ128: (debug) - * Read a 128-bit register from indirect port register map - * - * The port to access is implied by the Shared memory channel used. + +/* MC_CMD_PORT_WRITE32_IN msgrequest */ +#define MC_CMD_PORT_WRITE32_IN_LEN 8 +#define MC_CMD_PORT_WRITE32_IN_ADDR_OFST 0 +#define MC_CMD_PORT_WRITE32_IN_VALUE_OFST 4 + +/* MC_CMD_PORT_WRITE32_OUT msgresponse */ +#define MC_CMD_PORT_WRITE32_OUT_LEN 4 +#define MC_CMD_PORT_WRITE32_OUT_STATUS_OFST 0 + + +/***********************************/ +/* MC_CMD_PORT_READ128 + * Read a 128-bit register from the indirect port register map. */ #define MC_CMD_PORT_READ128 0x16 -#define MC_CMD_PORT_READ128_IN_LEN 4 -#define MC_CMD_PORT_READ128_IN_ADDR_OFST 0 -#define MC_CMD_PORT_READ128_OUT_LEN 20 -#define MC_CMD_PORT_READ128_OUT_VALUE_OFST 0 -#define MC_CMD_PORT_READ128_OUT_STATUS_OFST 16 - -/* MC_CMD_PORT_WRITE128: (debug) - * Write a 128-bit register to indirect port register map. - * - * The port to access is implied by the Shared memory channel used. + +/* MC_CMD_PORT_READ128_IN msgrequest */ +#define MC_CMD_PORT_READ128_IN_LEN 4 +#define MC_CMD_PORT_READ128_IN_ADDR_OFST 0 + +/* MC_CMD_PORT_READ128_OUT msgresponse */ +#define MC_CMD_PORT_READ128_OUT_LEN 20 +#define MC_CMD_PORT_READ128_OUT_VALUE_OFST 0 +#define MC_CMD_PORT_READ128_OUT_VALUE_LEN 16 +#define MC_CMD_PORT_READ128_OUT_STATUS_OFST 16 + + +/***********************************/ +/* MC_CMD_PORT_WRITE128 + * Write a 128-bit register to the indirect port register map. */ #define MC_CMD_PORT_WRITE128 0x17 -#define MC_CMD_PORT_WRITE128_IN_LEN 20 -#define MC_CMD_PORT_WRITE128_IN_ADDR_OFST 0 -#define MC_CMD_PORT_WRITE128_IN_VALUE_OFST 4 -#define MC_CMD_PORT_WRITE128_OUT_LEN 4 -#define MC_CMD_PORT_WRITE128_OUT_STATUS_OFST 0 - -/* MC_CMD_GET_BOARD_CFG: - * Returns the MC firmware configuration structure - * - * The FW_SUBTYPE_LIST contains a 16-bit value for each of the 12 types of - * NVRAM area. The values are defined in the firmware/mc/platform/.c file - * for a specific board type, but otherwise have no meaning to the MC; they - * are used by the driver to manage selection of appropriate firmware updates. + +/* MC_CMD_PORT_WRITE128_IN msgrequest */ +#define MC_CMD_PORT_WRITE128_IN_LEN 20 +#define MC_CMD_PORT_WRITE128_IN_ADDR_OFST 0 +#define MC_CMD_PORT_WRITE128_IN_VALUE_OFST 4 +#define MC_CMD_PORT_WRITE128_IN_VALUE_LEN 16 + +/* MC_CMD_PORT_WRITE128_OUT msgresponse */ +#define MC_CMD_PORT_WRITE128_OUT_LEN 4 +#define MC_CMD_PORT_WRITE128_OUT_STATUS_OFST 0 + + +/***********************************/ +/* MC_CMD_GET_BOARD_CFG + * Returns the MC firmware configuration structure. */ #define MC_CMD_GET_BOARD_CFG 0x18 -#define MC_CMD_GET_BOARD_CFG_IN_LEN 0 -#define MC_CMD_GET_BOARD_CFG_OUT_LEN 96 -#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_TYPE_OFST 0 -#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_NAME_OFST 4 -#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_NAME_LEN 32 -#define MC_CMD_GET_BOARD_CFG_OUT_CAPABILITIES_PORT0_OFST 36 -#define MC_CMD_GET_BOARD_CFG_OUT_CAPABILITIES_PORT1_OFST 40 -#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_OFST 44 -#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_LEN 6 -#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1_OFST 50 -#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1_LEN 6 -#define MC_CMD_GET_BOARD_CFG_OUT_MAC_COUNT_PORT0_OFST 56 -#define MC_CMD_GET_BOARD_CFG_OUT_MAC_COUNT_PORT1_OFST 60 -#define MC_CMD_GET_BOARD_CFG_OUT_MAC_STRIDE_PORT0_OFST 64 -#define MC_CMD_GET_BOARD_CFG_OUT_MAC_STRIDE_PORT1_OFST 68 -#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_OFST 72 -#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN 24 - -/* MC_CMD_DBI_READX: (debug) - * Read DBI register(s) -- extended functionality - * - * Host: vf selection, address, [,vf selection ...] - * MC: value [,value ...] + +/* MC_CMD_GET_BOARD_CFG_IN msgrequest */ +#define MC_CMD_GET_BOARD_CFG_IN_LEN 0 + +/* MC_CMD_GET_BOARD_CFG_OUT msgresponse */ +#define MC_CMD_GET_BOARD_CFG_OUT_LENMIN 96 +#define MC_CMD_GET_BOARD_CFG_OUT_LENMAX 136 +#define MC_CMD_GET_BOARD_CFG_OUT_LEN(num) (72+2*(num)) +#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_TYPE_OFST 0 +#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_NAME_OFST 4 +#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_NAME_LEN 32 +#define MC_CMD_GET_BOARD_CFG_OUT_CAPABILITIES_PORT0_OFST 36 +#define MC_CMD_CAPABILITIES_SMALL_BUF_TBL_LBN 0x0 /* enum */ +#define MC_CMD_CAPABILITIES_SMALL_BUF_TBL_WIDTH 0x1 /* enum */ +#define MC_CMD_CAPABILITIES_TURBO_LBN 0x1 /* enum */ +#define MC_CMD_CAPABILITIES_TURBO_WIDTH 0x1 /* enum */ +#define MC_CMD_CAPABILITIES_TURBO_ACTIVE_LBN 0x2 /* enum */ +#define MC_CMD_CAPABILITIES_TURBO_ACTIVE_WIDTH 0x1 /* enum */ +#define MC_CMD_CAPABILITIES_PTP_LBN 0x3 /* enum */ +#define MC_CMD_CAPABILITIES_PTP_WIDTH 0x1 /* enum */ +#define MC_CMD_GET_BOARD_CFG_OUT_CAPABILITIES_PORT1_OFST 40 +/* Enum values, see field(s): */ +/* CAPABILITIES_PORT0 */ +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_OFST 44 +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_LEN 6 +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1_OFST 50 +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1_LEN 6 +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_COUNT_PORT0_OFST 56 +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_COUNT_PORT1_OFST 60 +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_STRIDE_PORT0_OFST 64 +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_STRIDE_PORT1_OFST 68 +#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_OFST 72 +#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN 2 +#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MINNUM 12 +#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MAXNUM 32 + + +/***********************************/ +/* MC_CMD_DBI_READX + * Read DBI register(s). */ #define MC_CMD_DBI_READX 0x19 -#define MC_CMD_DBI_READX_IN_LEN(_numwords) \ - (8*(_numwords)) -#define MC_CMD_DBI_READX_OUT_LEN(_numwords) \ - (4*(_numwords)) -/* MC_CMD_SET_RAND_SEED: - * Set the 16byte seed for the MC pseudo-random generator +/* MC_CMD_DBI_READX_IN msgrequest */ +#define MC_CMD_DBI_READX_IN_LENMIN 8 +#define MC_CMD_DBI_READX_IN_LENMAX 248 +#define MC_CMD_DBI_READX_IN_LEN(num) (0+8*(num)) +#define MC_CMD_DBI_READX_IN_DBIRDOP_OFST 0 +#define MC_CMD_DBI_READX_IN_DBIRDOP_LEN 8 +#define MC_CMD_DBI_READX_IN_DBIRDOP_LO_OFST 0 +#define MC_CMD_DBI_READX_IN_DBIRDOP_HI_OFST 4 +#define MC_CMD_DBI_READX_IN_DBIRDOP_MINNUM 1 +#define MC_CMD_DBI_READX_IN_DBIRDOP_MAXNUM 31 + +/* MC_CMD_DBI_READX_OUT msgresponse */ +#define MC_CMD_DBI_READX_OUT_LENMIN 4 +#define MC_CMD_DBI_READX_OUT_LENMAX 252 +#define MC_CMD_DBI_READX_OUT_LEN(num) (0+4*(num)) +#define MC_CMD_DBI_READX_OUT_VALUE_OFST 0 +#define MC_CMD_DBI_READX_OUT_VALUE_LEN 4 +#define MC_CMD_DBI_READX_OUT_VALUE_MINNUM 1 +#define MC_CMD_DBI_READX_OUT_VALUE_MAXNUM 63 + + +/***********************************/ +/* MC_CMD_SET_RAND_SEED + * Set the 16byte seed for the MC pseudo-random generator. */ #define MC_CMD_SET_RAND_SEED 0x1a -#define MC_CMD_SET_RAND_SEED_IN_LEN 16 -#define MC_CMD_SET_RAND_SEED_IN_SEED_OFST 0 -#define MC_CMD_SET_RAND_SEED_OUT_LEN 0 -/* MC_CMD_LTSSM_HIST: (debug) - * Retrieve the history of the LTSSM, if the build supports it. - * - * Host: nothing - * MC: variable number of LTSSM values, as bytes - * The history is read-to-clear. +/* MC_CMD_SET_RAND_SEED_IN msgrequest */ +#define MC_CMD_SET_RAND_SEED_IN_LEN 16 +#define MC_CMD_SET_RAND_SEED_IN_SEED_OFST 0 +#define MC_CMD_SET_RAND_SEED_IN_SEED_LEN 16 + +/* MC_CMD_SET_RAND_SEED_OUT msgresponse */ +#define MC_CMD_SET_RAND_SEED_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_LTSSM_HIST + * Retrieve the history of the PCIE LTSSM. */ #define MC_CMD_LTSSM_HIST 0x1b -/* MC_CMD_DRV_ATTACH: - * Inform MCPU that this port is managed on the host (i.e. driver active) +/* MC_CMD_LTSSM_HIST_IN msgrequest */ +#define MC_CMD_LTSSM_HIST_IN_LEN 0 + +/* MC_CMD_LTSSM_HIST_OUT msgresponse */ +#define MC_CMD_LTSSM_HIST_OUT_LENMIN 0 +#define MC_CMD_LTSSM_HIST_OUT_LENMAX 252 +#define MC_CMD_LTSSM_HIST_OUT_LEN(num) (0+4*(num)) +#define MC_CMD_LTSSM_HIST_OUT_DATA_OFST 0 +#define MC_CMD_LTSSM_HIST_OUT_DATA_LEN 4 +#define MC_CMD_LTSSM_HIST_OUT_DATA_MINNUM 0 +#define MC_CMD_LTSSM_HIST_OUT_DATA_MAXNUM 63 + + +/***********************************/ +/* MC_CMD_DRV_ATTACH + * Inform MCPU that this port is managed on the host. */ #define MC_CMD_DRV_ATTACH 0x1c -#define MC_CMD_DRV_ATTACH_IN_LEN 8 -#define MC_CMD_DRV_ATTACH_IN_NEW_STATE_OFST 0 -#define MC_CMD_DRV_ATTACH_IN_UPDATE_OFST 4 -#define MC_CMD_DRV_ATTACH_OUT_LEN 4 -#define MC_CMD_DRV_ATTACH_OUT_OLD_STATE_OFST 0 -/* MC_CMD_NCSI_PROD: (debug) - * Trigger an NC-SI event (and possibly an AEN in response) +/* MC_CMD_DRV_ATTACH_IN msgrequest */ +#define MC_CMD_DRV_ATTACH_IN_LEN 8 +#define MC_CMD_DRV_ATTACH_IN_NEW_STATE_OFST 0 +#define MC_CMD_DRV_ATTACH_IN_UPDATE_OFST 4 + +/* MC_CMD_DRV_ATTACH_OUT msgresponse */ +#define MC_CMD_DRV_ATTACH_OUT_LEN 4 +#define MC_CMD_DRV_ATTACH_OUT_OLD_STATE_OFST 0 + + +/***********************************/ +/* MC_CMD_NCSI_PROD + * Trigger an NC-SI event. */ #define MC_CMD_NCSI_PROD 0x1d -#define MC_CMD_NCSI_PROD_IN_LEN 4 -#define MC_CMD_NCSI_PROD_IN_EVENTS_OFST 0 -#define MC_CMD_NCSI_PROD_LINKCHANGE_LBN 0 -#define MC_CMD_NCSI_PROD_LINKCHANGE_WIDTH 1 -#define MC_CMD_NCSI_PROD_RESET_LBN 1 -#define MC_CMD_NCSI_PROD_RESET_WIDTH 1 -#define MC_CMD_NCSI_PROD_DRVATTACH_LBN 2 -#define MC_CMD_NCSI_PROD_DRVATTACH_WIDTH 1 -#define MC_CMD_NCSI_PROD_OUT_LEN 0 - -/* Enumeration */ -#define MC_CMD_NCSI_PROD_LINKCHANGE 0 -#define MC_CMD_NCSI_PROD_RESET 1 -#define MC_CMD_NCSI_PROD_DRVATTACH 2 - -/* MC_CMD_DEVEL: (debug) - * Reserved for development - */ -#define MC_CMD_DEVEL 0x1e - -/* MC_CMD_SHMUART: (debug) + +/* MC_CMD_NCSI_PROD_IN msgrequest */ +#define MC_CMD_NCSI_PROD_IN_LEN 4 +#define MC_CMD_NCSI_PROD_IN_EVENTS_OFST 0 +#define MC_CMD_NCSI_PROD_LINKCHANGE 0x0 /* enum */ +#define MC_CMD_NCSI_PROD_RESET 0x1 /* enum */ +#define MC_CMD_NCSI_PROD_DRVATTACH 0x2 /* enum */ +#define MC_CMD_NCSI_PROD_IN_LINKCHANGE_LBN 0 +#define MC_CMD_NCSI_PROD_IN_LINKCHANGE_WIDTH 1 +#define MC_CMD_NCSI_PROD_IN_RESET_LBN 1 +#define MC_CMD_NCSI_PROD_IN_RESET_WIDTH 1 +#define MC_CMD_NCSI_PROD_IN_DRVATTACH_LBN 2 +#define MC_CMD_NCSI_PROD_IN_DRVATTACH_WIDTH 1 + +/* MC_CMD_NCSI_PROD_OUT msgresponse */ +#define MC_CMD_NCSI_PROD_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_SHMUART * Route UART output to circular buffer in shared memory instead. */ #define MC_CMD_SHMUART 0x1f -#define MC_CMD_SHMUART_IN_FLAG_OFST 0 -#define MC_CMD_SHMUART_IN_LEN 4 -#define MC_CMD_SHMUART_OUT_LEN 0 -/* MC_CMD_PORT_RESET: - * Generic per-port reset. There is no equivalent for per-board reset. - * - * Locks required: None - * Return code: 0, ETIME - */ -#define MC_CMD_PORT_RESET 0x20 -#define MC_CMD_PORT_RESET_IN_LEN 0 -#define MC_CMD_PORT_RESET_OUT_LEN 0 - -/* MC_CMD_RESOURCE_LOCK: - * Generic resource lock/unlock interface. - * - * Locks required: None - * Return code: 0, - * EBUSY (if trylock is contended by other port), - * EDEADLK (if trylock is already acquired by this port) - * EINVAL (if unlock doesn't own the lock) - */ -#define MC_CMD_RESOURCE_LOCK 0x21 -#define MC_CMD_RESOURCE_LOCK_IN_LEN 8 -#define MC_CMD_RESOURCE_LOCK_IN_ACTION_OFST 0 -#define MC_CMD_RESOURCE_LOCK_ACTION_TRYLOCK 1 -#define MC_CMD_RESOURCE_LOCK_ACTION_UNLOCK 0 -#define MC_CMD_RESOURCE_LOCK_IN_RESOURCE_OFST 4 -#define MC_CMD_RESOURCE_LOCK_I2C 2 -#define MC_CMD_RESOURCE_LOCK_PHY 3 -#define MC_CMD_RESOURCE_LOCK_OUT_LEN 0 - -/* MC_CMD_SPI_COMMAND: (variadic in, variadic out) - * Read/Write to/from the SPI device. - * - * Locks required: SPI_LOCK - * Return code: 0, ETIME, EINVAL, EACCES (if SPI_LOCK is not held) - */ -#define MC_CMD_SPI_COMMAND 0x22 -#define MC_CMD_SPI_COMMAND_IN_LEN(_write_bytes) (12 + (_write_bytes)) -#define MC_CMD_SPI_COMMAND_IN_ARGS_OFST 0 -#define MC_CMD_SPI_COMMAND_IN_ARGS_ADDRESS_OFST 0 -#define MC_CMD_SPI_COMMAND_IN_ARGS_READ_BYTES_OFST 4 -#define MC_CMD_SPI_COMMAND_IN_ARGS_CHIP_SELECT_OFST 8 -/* Data to write here */ -#define MC_CMD_SPI_COMMAND_IN_WRITE_BUFFER_OFST 12 -#define MC_CMD_SPI_COMMAND_OUT_LEN(_read_bytes) (_read_bytes) -/* Data read here */ -#define MC_CMD_SPI_COMMAND_OUT_READ_BUFFER_OFST 0 - -/* MC_CMD_I2C_READ_WRITE: (variadic in, variadic out) - * Read/Write to/from the I2C bus. - * - * Locks required: I2C_LOCK - * Return code: 0, ETIME, EINVAL, EACCES (if I2C_LOCK is not held) - */ -#define MC_CMD_I2C_RW 0x23 -#define MC_CMD_I2C_RW_IN_LEN(_write_bytes) (8 + (_write_bytes)) -#define MC_CMD_I2C_RW_IN_ARGS_OFST 0 -#define MC_CMD_I2C_RW_IN_ARGS_ADDR_OFST 0 -#define MC_CMD_I2C_RW_IN_ARGS_READ_BYTES_OFST 4 -/* Data to write here */ -#define MC_CMD_I2C_RW_IN_WRITE_BUFFER_OFSET 8 -#define MC_CMD_I2C_RW_OUT_LEN(_read_bytes) (_read_bytes) -/* Data read here */ -#define MC_CMD_I2C_RW_OUT_READ_BUFFER_OFST 0 - -/* Generic phy capability bitmask */ -#define MC_CMD_PHY_CAP_10HDX_LBN 1 -#define MC_CMD_PHY_CAP_10HDX_WIDTH 1 -#define MC_CMD_PHY_CAP_10FDX_LBN 2 -#define MC_CMD_PHY_CAP_10FDX_WIDTH 1 -#define MC_CMD_PHY_CAP_100HDX_LBN 3 -#define MC_CMD_PHY_CAP_100HDX_WIDTH 1 -#define MC_CMD_PHY_CAP_100FDX_LBN 4 -#define MC_CMD_PHY_CAP_100FDX_WIDTH 1 -#define MC_CMD_PHY_CAP_1000HDX_LBN 5 -#define MC_CMD_PHY_CAP_1000HDX_WIDTH 1 -#define MC_CMD_PHY_CAP_1000FDX_LBN 6 -#define MC_CMD_PHY_CAP_1000FDX_WIDTH 1 -#define MC_CMD_PHY_CAP_10000FDX_LBN 7 -#define MC_CMD_PHY_CAP_10000FDX_WIDTH 1 -#define MC_CMD_PHY_CAP_PAUSE_LBN 8 -#define MC_CMD_PHY_CAP_PAUSE_WIDTH 1 -#define MC_CMD_PHY_CAP_ASYM_LBN 9 -#define MC_CMD_PHY_CAP_ASYM_WIDTH 1 -#define MC_CMD_PHY_CAP_AN_LBN 10 -#define MC_CMD_PHY_CAP_AN_WIDTH 1 - -/* Generic loopback enumeration */ -#define MC_CMD_LOOPBACK_NONE 0 -#define MC_CMD_LOOPBACK_DATA 1 -#define MC_CMD_LOOPBACK_GMAC 2 -#define MC_CMD_LOOPBACK_XGMII 3 -#define MC_CMD_LOOPBACK_XGXS 4 -#define MC_CMD_LOOPBACK_XAUI 5 -#define MC_CMD_LOOPBACK_GMII 6 -#define MC_CMD_LOOPBACK_SGMII 7 -#define MC_CMD_LOOPBACK_XGBR 8 -#define MC_CMD_LOOPBACK_XFI 9 -#define MC_CMD_LOOPBACK_XAUI_FAR 10 -#define MC_CMD_LOOPBACK_GMII_FAR 11 -#define MC_CMD_LOOPBACK_SGMII_FAR 12 -#define MC_CMD_LOOPBACK_XFI_FAR 13 -#define MC_CMD_LOOPBACK_GPHY 14 -#define MC_CMD_LOOPBACK_PHYXS 15 -#define MC_CMD_LOOPBACK_PCS 16 -#define MC_CMD_LOOPBACK_PMAPMD 17 -#define MC_CMD_LOOPBACK_XPORT 18 -#define MC_CMD_LOOPBACK_XGMII_WS 19 -#define MC_CMD_LOOPBACK_XAUI_WS 20 -#define MC_CMD_LOOPBACK_XAUI_WS_FAR 21 -#define MC_CMD_LOOPBACK_XAUI_WS_NEAR 22 -#define MC_CMD_LOOPBACK_GMII_WS 23 -#define MC_CMD_LOOPBACK_XFI_WS 24 -#define MC_CMD_LOOPBACK_XFI_WS_FAR 25 -#define MC_CMD_LOOPBACK_PHYXS_WS 26 - -/* Generic PHY statistics enumeration */ -#define MC_CMD_OUI 0 -#define MC_CMD_PMA_PMD_LINK_UP 1 -#define MC_CMD_PMA_PMD_RX_FAULT 2 -#define MC_CMD_PMA_PMD_TX_FAULT 3 -#define MC_CMD_PMA_PMD_SIGNAL 4 -#define MC_CMD_PMA_PMD_SNR_A 5 -#define MC_CMD_PMA_PMD_SNR_B 6 -#define MC_CMD_PMA_PMD_SNR_C 7 -#define MC_CMD_PMA_PMD_SNR_D 8 -#define MC_CMD_PCS_LINK_UP 9 -#define MC_CMD_PCS_RX_FAULT 10 -#define MC_CMD_PCS_TX_FAULT 11 -#define MC_CMD_PCS_BER 12 -#define MC_CMD_PCS_BLOCK_ERRORS 13 -#define MC_CMD_PHYXS_LINK_UP 14 -#define MC_CMD_PHYXS_RX_FAULT 15 -#define MC_CMD_PHYXS_TX_FAULT 16 -#define MC_CMD_PHYXS_ALIGN 17 -#define MC_CMD_PHYXS_SYNC 18 -#define MC_CMD_AN_LINK_UP 19 -#define MC_CMD_AN_COMPLETE 20 -#define MC_CMD_AN_10GBT_STATUS 21 -#define MC_CMD_CL22_LINK_UP 22 -#define MC_CMD_PHY_NSTATS 23 - -/* MC_CMD_GET_PHY_CFG: - * Report PHY configuration. This guarantees to succeed even if the PHY is in - * a "zombie" state. - * - * Locks required: None - * Return code: 0 +/* MC_CMD_SHMUART_IN msgrequest */ +#define MC_CMD_SHMUART_IN_LEN 4 +#define MC_CMD_SHMUART_IN_FLAG_OFST 0 + +/* MC_CMD_SHMUART_OUT msgresponse */ +#define MC_CMD_SHMUART_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_ENTITY_RESET + * Generic per-port reset. + */ +#define MC_CMD_ENTITY_RESET 0x20 + +/* MC_CMD_ENTITY_RESET_IN msgrequest */ +#define MC_CMD_ENTITY_RESET_IN_LEN 4 +#define MC_CMD_ENTITY_RESET_IN_FLAG_OFST 0 +#define MC_CMD_ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET_LBN 0 +#define MC_CMD_ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET_WIDTH 1 + +/* MC_CMD_ENTITY_RESET_OUT msgresponse */ +#define MC_CMD_ENTITY_RESET_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_PCIE_CREDITS + * Read instantaneous and minimum flow control thresholds. + */ +#define MC_CMD_PCIE_CREDITS 0x21 + +/* MC_CMD_PCIE_CREDITS_IN msgrequest */ +#define MC_CMD_PCIE_CREDITS_IN_LEN 8 +#define MC_CMD_PCIE_CREDITS_IN_POLL_PERIOD_OFST 0 +#define MC_CMD_PCIE_CREDITS_IN_WIPE_OFST 4 + +/* MC_CMD_PCIE_CREDITS_OUT msgresponse */ +#define MC_CMD_PCIE_CREDITS_OUT_LEN 16 +#define MC_CMD_PCIE_CREDITS_OUT_CURRENT_P_HDR_OFST 0 +#define MC_CMD_PCIE_CREDITS_OUT_CURRENT_P_HDR_LEN 2 +#define MC_CMD_PCIE_CREDITS_OUT_CURRENT_P_DATA_OFST 2 +#define MC_CMD_PCIE_CREDITS_OUT_CURRENT_P_DATA_LEN 2 +#define MC_CMD_PCIE_CREDITS_OUT_CURRENT_NP_HDR_OFST 4 +#define MC_CMD_PCIE_CREDITS_OUT_CURRENT_NP_HDR_LEN 2 +#define MC_CMD_PCIE_CREDITS_OUT_CURRENT_NP_DATA_OFST 6 +#define MC_CMD_PCIE_CREDITS_OUT_CURRENT_NP_DATA_LEN 2 +#define MC_CMD_PCIE_CREDITS_OUT_MINIMUM_P_HDR_OFST 8 +#define MC_CMD_PCIE_CREDITS_OUT_MINIMUM_P_HDR_LEN 2 +#define MC_CMD_PCIE_CREDITS_OUT_MINIMUM_P_DATA_OFST 10 +#define MC_CMD_PCIE_CREDITS_OUT_MINIMUM_P_DATA_LEN 2 +#define MC_CMD_PCIE_CREDITS_OUT_MINIMUM_NP_HDR_OFST 12 +#define MC_CMD_PCIE_CREDITS_OUT_MINIMUM_NP_HDR_LEN 2 +#define MC_CMD_PCIE_CREDITS_OUT_MINIMUM_NP_DATA_OFST 14 +#define MC_CMD_PCIE_CREDITS_OUT_MINIMUM_NP_DATA_LEN 2 + + +/***********************************/ +/* MC_CMD_RXD_MONITOR + * Get histogram of RX queue fill level. + */ +#define MC_CMD_RXD_MONITOR 0x22 + +/* MC_CMD_RXD_MONITOR_IN msgrequest */ +#define MC_CMD_RXD_MONITOR_IN_LEN 12 +#define MC_CMD_RXD_MONITOR_IN_QID_OFST 0 +#define MC_CMD_RXD_MONITOR_IN_POLL_PERIOD_OFST 4 +#define MC_CMD_RXD_MONITOR_IN_WIPE_OFST 8 + +/* MC_CMD_RXD_MONITOR_OUT msgresponse */ +#define MC_CMD_RXD_MONITOR_OUT_LEN 80 +#define MC_CMD_RXD_MONITOR_OUT_QID_OFST 0 +#define MC_CMD_RXD_MONITOR_OUT_RING_FILL_OFST 4 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_FILL_OFST 8 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_1_OFST 12 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_2_OFST 16 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_4_OFST 20 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_8_OFST 24 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_16_OFST 28 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_32_OFST 32 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_64_OFST 36 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_128_OFST 40 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_256_OFST 44 +#define MC_CMD_RXD_MONITOR_OUT_RING_GE_256_OFST 48 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_1_OFST 52 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_2_OFST 56 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_4_OFST 60 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_8_OFST 64 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_16_OFST 68 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_32_OFST 72 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_GE_32_OFST 76 + + +/***********************************/ +/* MC_CMD_PUTS + * puts(3) implementation over MCDI + */ +#define MC_CMD_PUTS 0x23 + +/* MC_CMD_PUTS_IN msgrequest */ +#define MC_CMD_PUTS_IN_LENMIN 13 +#define MC_CMD_PUTS_IN_LENMAX 255 +#define MC_CMD_PUTS_IN_LEN(num) (12+1*(num)) +#define MC_CMD_PUTS_IN_DEST_OFST 0 +#define MC_CMD_PUTS_IN_UART_LBN 0 +#define MC_CMD_PUTS_IN_UART_WIDTH 1 +#define MC_CMD_PUTS_IN_PORT_LBN 1 +#define MC_CMD_PUTS_IN_PORT_WIDTH 1 +#define MC_CMD_PUTS_IN_DHOST_OFST 4 +#define MC_CMD_PUTS_IN_DHOST_LEN 6 +#define MC_CMD_PUTS_IN_STRING_OFST 12 +#define MC_CMD_PUTS_IN_STRING_LEN 1 +#define MC_CMD_PUTS_IN_STRING_MINNUM 1 +#define MC_CMD_PUTS_IN_STRING_MAXNUM 243 + +/* MC_CMD_PUTS_OUT msgresponse */ +#define MC_CMD_PUTS_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_GET_PHY_CFG + * Report PHY configuration. */ #define MC_CMD_GET_PHY_CFG 0x24 -#define MC_CMD_GET_PHY_CFG_IN_LEN 0 -#define MC_CMD_GET_PHY_CFG_OUT_LEN 72 - -#define MC_CMD_GET_PHY_CFG_OUT_FLAGS_OFST 0 -#define MC_CMD_GET_PHY_CFG_PRESENT_LBN 0 -#define MC_CMD_GET_PHY_CFG_PRESENT_WIDTH 1 -#define MC_CMD_GET_PHY_CFG_BIST_CABLE_SHORT_LBN 1 -#define MC_CMD_GET_PHY_CFG_BIST_CABLE_SHORT_WIDTH 1 -#define MC_CMD_GET_PHY_CFG_BIST_CABLE_LONG_LBN 2 -#define MC_CMD_GET_PHY_CFG_BIST_CABLE_LONG_WIDTH 1 -#define MC_CMD_GET_PHY_CFG_LOWPOWER_LBN 3 -#define MC_CMD_GET_PHY_CFG_LOWPOWER_WIDTH 1 -#define MC_CMD_GET_PHY_CFG_POWEROFF_LBN 4 -#define MC_CMD_GET_PHY_CFG_POWEROFF_WIDTH 1 -#define MC_CMD_GET_PHY_CFG_TXDIS_LBN 5 -#define MC_CMD_GET_PHY_CFG_TXDIS_WIDTH 1 -#define MC_CMD_GET_PHY_CFG_BIST_LBN 6 -#define MC_CMD_GET_PHY_CFG_BIST_WIDTH 1 -#define MC_CMD_GET_PHY_CFG_OUT_TYPE_OFST 4 -/* Bitmask of supported capabilities */ -#define MC_CMD_GET_PHY_CFG_OUT_SUPPORTED_CAP_OFST 8 -#define MC_CMD_GET_PHY_CFG_OUT_CHANNEL_OFST 12 -#define MC_CMD_GET_PHY_CFG_OUT_PRT_OFST 16 -/* PHY statistics bitmap */ -#define MC_CMD_GET_PHY_CFG_OUT_STATS_MASK_OFST 20 -/* PHY type/name string */ -#define MC_CMD_GET_PHY_CFG_OUT_NAME_OFST 24 -#define MC_CMD_GET_PHY_CFG_OUT_NAME_LEN 20 -#define MC_CMD_GET_PHY_CFG_OUT_MEDIA_TYPE_OFST 44 -#define MC_CMD_MEDIA_XAUI 1 -#define MC_CMD_MEDIA_CX4 2 -#define MC_CMD_MEDIA_KX4 3 -#define MC_CMD_MEDIA_XFP 4 -#define MC_CMD_MEDIA_SFP_PLUS 5 -#define MC_CMD_MEDIA_BASE_T 6 -/* MDIO "MMDS" supported */ -#define MC_CMD_GET_PHY_CFG_OUT_MMD_MASK_OFST 48 -/* Native clause 22 */ -#define MC_CMD_MMD_CLAUSE22 0 -#define MC_CMD_MMD_CLAUSE45_PMAPMD 1 -#define MC_CMD_MMD_CLAUSE45_WIS 2 -#define MC_CMD_MMD_CLAUSE45_PCS 3 -#define MC_CMD_MMD_CLAUSE45_PHYXS 4 -#define MC_CMD_MMD_CLAUSE45_DTEXS 5 -#define MC_CMD_MMD_CLAUSE45_TC 6 -#define MC_CMD_MMD_CLAUSE45_AN 7 -/* Clause22 proxied over clause45 by PHY */ -#define MC_CMD_MMD_CLAUSE45_C22EXT 29 -#define MC_CMD_MMD_CLAUSE45_VEND1 30 -#define MC_CMD_MMD_CLAUSE45_VEND2 31 -/* PHY stepping version */ -#define MC_CMD_GET_PHY_CFG_OUT_REVISION_OFST 52 -#define MC_CMD_GET_PHY_CFG_OUT_REVISION_LEN 20 - -/* MC_CMD_START_BIST: +/* MC_CMD_GET_PHY_CFG_IN msgrequest */ +#define MC_CMD_GET_PHY_CFG_IN_LEN 0 + +/* MC_CMD_GET_PHY_CFG_OUT msgresponse */ +#define MC_CMD_GET_PHY_CFG_OUT_LEN 72 +#define MC_CMD_GET_PHY_CFG_OUT_FLAGS_OFST 0 +#define MC_CMD_GET_PHY_CFG_OUT_PRESENT_LBN 0 +#define MC_CMD_GET_PHY_CFG_OUT_PRESENT_WIDTH 1 +#define MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_LBN 1 +#define MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_WIDTH 1 +#define MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN 2 +#define MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_WIDTH 1 +#define MC_CMD_GET_PHY_CFG_OUT_LOWPOWER_LBN 3 +#define MC_CMD_GET_PHY_CFG_OUT_LOWPOWER_WIDTH 1 +#define MC_CMD_GET_PHY_CFG_OUT_POWEROFF_LBN 4 +#define MC_CMD_GET_PHY_CFG_OUT_POWEROFF_WIDTH 1 +#define MC_CMD_GET_PHY_CFG_OUT_TXDIS_LBN 5 +#define MC_CMD_GET_PHY_CFG_OUT_TXDIS_WIDTH 1 +#define MC_CMD_GET_PHY_CFG_OUT_BIST_LBN 6 +#define MC_CMD_GET_PHY_CFG_OUT_BIST_WIDTH 1 +#define MC_CMD_GET_PHY_CFG_OUT_TYPE_OFST 4 +#define MC_CMD_GET_PHY_CFG_OUT_SUPPORTED_CAP_OFST 8 +#define MC_CMD_PHY_CAP_10HDX_LBN 1 +#define MC_CMD_PHY_CAP_10HDX_WIDTH 1 +#define MC_CMD_PHY_CAP_10FDX_LBN 2 +#define MC_CMD_PHY_CAP_10FDX_WIDTH 1 +#define MC_CMD_PHY_CAP_100HDX_LBN 3 +#define MC_CMD_PHY_CAP_100HDX_WIDTH 1 +#define MC_CMD_PHY_CAP_100FDX_LBN 4 +#define MC_CMD_PHY_CAP_100FDX_WIDTH 1 +#define MC_CMD_PHY_CAP_1000HDX_LBN 5 +#define MC_CMD_PHY_CAP_1000HDX_WIDTH 1 +#define MC_CMD_PHY_CAP_1000FDX_LBN 6 +#define MC_CMD_PHY_CAP_1000FDX_WIDTH 1 +#define MC_CMD_PHY_CAP_10000FDX_LBN 7 +#define MC_CMD_PHY_CAP_10000FDX_WIDTH 1 +#define MC_CMD_PHY_CAP_PAUSE_LBN 8 +#define MC_CMD_PHY_CAP_PAUSE_WIDTH 1 +#define MC_CMD_PHY_CAP_ASYM_LBN 9 +#define MC_CMD_PHY_CAP_ASYM_WIDTH 1 +#define MC_CMD_PHY_CAP_AN_LBN 10 +#define MC_CMD_PHY_CAP_AN_WIDTH 1 +#define MC_CMD_GET_PHY_CFG_OUT_CHANNEL_OFST 12 +#define MC_CMD_GET_PHY_CFG_OUT_PRT_OFST 16 +#define MC_CMD_GET_PHY_CFG_OUT_STATS_MASK_OFST 20 +#define MC_CMD_GET_PHY_CFG_OUT_NAME_OFST 24 +#define MC_CMD_GET_PHY_CFG_OUT_NAME_LEN 20 +#define MC_CMD_GET_PHY_CFG_OUT_MEDIA_TYPE_OFST 44 +#define MC_CMD_MEDIA_XAUI 0x1 /* enum */ +#define MC_CMD_MEDIA_CX4 0x2 /* enum */ +#define MC_CMD_MEDIA_KX4 0x3 /* enum */ +#define MC_CMD_MEDIA_XFP 0x4 /* enum */ +#define MC_CMD_MEDIA_SFP_PLUS 0x5 /* enum */ +#define MC_CMD_MEDIA_BASE_T 0x6 /* enum */ +#define MC_CMD_GET_PHY_CFG_OUT_MMD_MASK_OFST 48 +#define MC_CMD_MMD_CLAUSE22 0x0 /* enum */ +#define MC_CMD_MMD_CLAUSE45_PMAPMD 0x1 /* enum */ +#define MC_CMD_MMD_CLAUSE45_WIS 0x2 /* enum */ +#define MC_CMD_MMD_CLAUSE45_PCS 0x3 /* enum */ +#define MC_CMD_MMD_CLAUSE45_PHYXS 0x4 /* enum */ +#define MC_CMD_MMD_CLAUSE45_DTEXS 0x5 /* enum */ +#define MC_CMD_MMD_CLAUSE45_TC 0x6 /* enum */ +#define MC_CMD_MMD_CLAUSE45_AN 0x7 /* enum */ +#define MC_CMD_MMD_CLAUSE45_C22EXT 0x1d /* enum */ +#define MC_CMD_MMD_CLAUSE45_VEND1 0x1e /* enum */ +#define MC_CMD_MMD_CLAUSE45_VEND2 0x1f /* enum */ +#define MC_CMD_GET_PHY_CFG_OUT_REVISION_OFST 52 +#define MC_CMD_GET_PHY_CFG_OUT_REVISION_LEN 20 + + +/***********************************/ +/* MC_CMD_START_BIST * Start a BIST test on the PHY. - * - * Locks required: PHY_LOCK if doing a PHY BIST - * Return code: 0, EINVAL, EACCES (if PHY_LOCK is not held) */ #define MC_CMD_START_BIST 0x25 -#define MC_CMD_START_BIST_IN_LEN 4 -#define MC_CMD_START_BIST_IN_TYPE_OFST 0 -#define MC_CMD_START_BIST_OUT_LEN 0 - -/* Run the PHY's short cable BIST */ -#define MC_CMD_PHY_BIST_CABLE_SHORT 1 -/* Run the PHY's long cable BIST */ -#define MC_CMD_PHY_BIST_CABLE_LONG 2 -/* Run BIST on the currently selected BPX Serdes (XAUI or XFI) */ -#define MC_CMD_BPX_SERDES_BIST 3 -/* Run the MC loopback tests */ -#define MC_CMD_MC_LOOPBACK_BIST 4 -/* Run the PHY's standard BIST */ -#define MC_CMD_PHY_BIST 5 - -/* MC_CMD_POLL_PHY_BIST: (variadic output) - * Poll for BIST completion - * - * Returns a single status code, and optionally some PHY specific - * bist output. The driver should only consume the BIST output - * after validating OUTLEN and PHY_CFG.PHY_TYPE. - * - * If a driver can't successfully parse the BIST output, it should - * still respect the pass/Fail in OUT.RESULT - * - * Locks required: PHY_LOCK if doing a PHY BIST - * Return code: 0, EACCES (if PHY_LOCK is not held) + +/* MC_CMD_START_BIST_IN msgrequest */ +#define MC_CMD_START_BIST_IN_LEN 4 +#define MC_CMD_START_BIST_IN_TYPE_OFST 0 +#define MC_CMD_PHY_BIST_CABLE_SHORT 0x1 /* enum */ +#define MC_CMD_PHY_BIST_CABLE_LONG 0x2 /* enum */ +#define MC_CMD_BPX_SERDES_BIST 0x3 /* enum */ +#define MC_CMD_MC_LOOPBACK_BIST 0x4 /* enum */ +#define MC_CMD_PHY_BIST 0x5 /* enum */ + +/* MC_CMD_START_BIST_OUT msgresponse */ +#define MC_CMD_START_BIST_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_POLL_BIST + * Poll for BIST completion. */ #define MC_CMD_POLL_BIST 0x26 -#define MC_CMD_POLL_BIST_IN_LEN 0 -#define MC_CMD_POLL_BIST_OUT_LEN UNKNOWN -#define MC_CMD_POLL_BIST_OUT_SFT9001_LEN 36 -#define MC_CMD_POLL_BIST_OUT_MRSFP_LEN 8 -#define MC_CMD_POLL_BIST_OUT_RESULT_OFST 0 -#define MC_CMD_POLL_BIST_RUNNING 1 -#define MC_CMD_POLL_BIST_PASSED 2 -#define MC_CMD_POLL_BIST_FAILED 3 -#define MC_CMD_POLL_BIST_TIMEOUT 4 -/* Generic: */ -#define MC_CMD_POLL_BIST_OUT_PRIVATE_OFST 4 -/* SFT9001-specific: */ -#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_A_OFST 4 -#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_B_OFST 8 -#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_C_OFST 12 -#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_D_OFST 16 -#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_A_OFST 20 -#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_B_OFST 24 -#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_C_OFST 28 -#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_D_OFST 32 -#define MC_CMD_POLL_BIST_SFT9001_PAIR_OK 1 -#define MC_CMD_POLL_BIST_SFT9001_PAIR_OPEN 2 -#define MC_CMD_POLL_BIST_SFT9001_INTRA_PAIR_SHORT 3 -#define MC_CMD_POLL_BIST_SFT9001_INTER_PAIR_SHORT 4 -#define MC_CMD_POLL_BIST_SFT9001_PAIR_BUSY 9 -/* mrsfp "PHY" driver: */ -#define MC_CMD_POLL_BIST_OUT_MRSFP_TEST_OFST 4 -#define MC_CMD_POLL_BIST_MRSFP_TEST_COMPLETE 0 -#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_WRITE 1 -#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_NO_ACCESS_IO_EXP 2 -#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_NO_ACCESS_MODULE 3 -#define MC_CMD_POLL_BIST_MRSFP_TEST_IO_EXP_I2C_CONFIGURE 4 -#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_I2C_NO_CROSSTALK 5 -#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_PRESENCE 6 -#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_ID_I2C_ACCESS 7 -#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_ID_SANE_VALUE 8 - -/* MC_CMD_PHY_SPI: (variadic in, variadic out) - * Read/Write/Erase the PHY SPI device - * - * Locks required: PHY_LOCK - * Return code: 0, ETIME, EINVAL, EACCES (if PHY_LOCK is not held) - */ -#define MC_CMD_PHY_SPI 0x27 -#define MC_CMD_PHY_SPI_IN_LEN(_write_bytes) (12 + (_write_bytes)) -#define MC_CMD_PHY_SPI_IN_ARGS_OFST 0 -#define MC_CMD_PHY_SPI_IN_ARGS_ADDR_OFST 0 -#define MC_CMD_PHY_SPI_IN_ARGS_READ_BYTES_OFST 4 -#define MC_CMD_PHY_SPI_IN_ARGS_ERASE_ALL_OFST 8 -/* Data to write here */ -#define MC_CMD_PHY_SPI_IN_WRITE_BUFFER_OFSET 12 -#define MC_CMD_PHY_SPI_OUT_LEN(_read_bytes) (_read_bytes) -/* Data read here */ -#define MC_CMD_PHY_SPI_OUT_READ_BUFFER_OFST 0 - - -/* MC_CMD_GET_LOOPBACK_MODES: - * Returns a bitmask of loopback modes evailable at each speed. - * - * Locks required: None - * Return code: 0 + +/* MC_CMD_POLL_BIST_IN msgrequest */ +#define MC_CMD_POLL_BIST_IN_LEN 0 + +/* MC_CMD_POLL_BIST_OUT msgresponse */ +#define MC_CMD_POLL_BIST_OUT_LEN 8 +#define MC_CMD_POLL_BIST_OUT_RESULT_OFST 0 +#define MC_CMD_POLL_BIST_RUNNING 0x1 /* enum */ +#define MC_CMD_POLL_BIST_PASSED 0x2 /* enum */ +#define MC_CMD_POLL_BIST_FAILED 0x3 /* enum */ +#define MC_CMD_POLL_BIST_TIMEOUT 0x4 /* enum */ +#define MC_CMD_POLL_BIST_OUT_PRIVATE_OFST 4 + +/* MC_CMD_POLL_BIST_OUT_SFT9001 msgresponse */ +#define MC_CMD_POLL_BIST_OUT_SFT9001_LEN 36 +/* MC_CMD_POLL_BIST_OUT_RESULT_OFST 0 */ +/* Enum values, see field(s): */ +/* MC_CMD_POLL_BIST_OUT/MC_CMD_POLL_BIST_OUT_RESULT */ +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_A_OFST 4 +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_B_OFST 8 +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_C_OFST 12 +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_D_OFST 16 +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_A_OFST 20 +#define MC_CMD_POLL_BIST_SFT9001_PAIR_OK 0x1 /* enum */ +#define MC_CMD_POLL_BIST_SFT9001_PAIR_OPEN 0x2 /* enum */ +#define MC_CMD_POLL_BIST_SFT9001_INTRA_PAIR_SHORT 0x3 /* enum */ +#define MC_CMD_POLL_BIST_SFT9001_INTER_PAIR_SHORT 0x4 /* enum */ +#define MC_CMD_POLL_BIST_SFT9001_PAIR_BUSY 0x9 /* enum */ +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_B_OFST 24 +/* Enum values, see field(s): */ +/* CABLE_STATUS_A */ +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_C_OFST 28 +/* Enum values, see field(s): */ +/* CABLE_STATUS_A */ +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_D_OFST 32 +/* Enum values, see field(s): */ +/* CABLE_STATUS_A */ + +/* MC_CMD_POLL_BIST_OUT_MRSFP msgresponse */ +#define MC_CMD_POLL_BIST_OUT_MRSFP_LEN 8 +/* MC_CMD_POLL_BIST_OUT_RESULT_OFST 0 */ +/* Enum values, see field(s): */ +/* MC_CMD_POLL_BIST_OUT/MC_CMD_POLL_BIST_OUT_RESULT */ +#define MC_CMD_POLL_BIST_OUT_MRSFP_TEST_OFST 4 +#define MC_CMD_POLL_BIST_MRSFP_TEST_COMPLETE 0x0 /* enum */ +#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_WRITE 0x1 /* enum */ +#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_NO_ACCESS_IO_EXP 0x2 /* enum */ +#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_NO_ACCESS_MODULE 0x3 /* enum */ +#define MC_CMD_POLL_BIST_MRSFP_TEST_IO_EXP_I2C_CONFIGURE 0x4 /* enum */ +#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_I2C_NO_CROSSTALK 0x5 /* enum */ +#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_PRESENCE 0x6 /* enum */ +#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_ID_I2C_ACCESS 0x7 /* enum */ +#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_ID_SANE_VALUE 0x8 /* enum */ + + +/***********************************/ +/* MC_CMD_FLUSH_RX_QUEUES + * Flush receive queue(s). + */ +#define MC_CMD_FLUSH_RX_QUEUES 0x27 + +/* MC_CMD_FLUSH_RX_QUEUES_IN msgrequest */ +#define MC_CMD_FLUSH_RX_QUEUES_IN_LENMIN 4 +#define MC_CMD_FLUSH_RX_QUEUES_IN_LENMAX 252 +#define MC_CMD_FLUSH_RX_QUEUES_IN_LEN(num) (0+4*(num)) +#define MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_OFST 0 +#define MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_LEN 4 +#define MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_MINNUM 1 +#define MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_MAXNUM 63 + +/* MC_CMD_FLUSH_RX_QUEUES_OUT msgresponse */ +#define MC_CMD_FLUSH_RX_QUEUES_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_GET_LOOPBACK_MODES + * Get port's loopback modes. */ #define MC_CMD_GET_LOOPBACK_MODES 0x28 -#define MC_CMD_GET_LOOPBACK_MODES_IN_LEN 0 -#define MC_CMD_GET_LOOPBACK_MODES_OUT_LEN 32 -#define MC_CMD_GET_LOOPBACK_MODES_100M_OFST 0 -#define MC_CMD_GET_LOOPBACK_MODES_1G_OFST 8 -#define MC_CMD_GET_LOOPBACK_MODES_10G_OFST 16 -#define MC_CMD_GET_LOOPBACK_MODES_SUGGESTED_OFST 24 - -/* Flow control enumeration */ -#define MC_CMD_FCNTL_OFF 0 -#define MC_CMD_FCNTL_RESPOND 1 -#define MC_CMD_FCNTL_BIDIR 2 -/* Auto - Use what the link has autonegotiated - * - The driver should modify the advertised capabilities via SET_LINK.CAP - * to control the negotiated flow control mode. - * - Can only be set if the PHY supports PAUSE+ASYM capabilities - * - Never returned by GET_LINK as the value programmed into the MAC - */ -#define MC_CMD_FCNTL_AUTO 3 - -/* Generic mac fault bitmask */ -#define MC_CMD_MAC_FAULT_XGMII_LOCAL_LBN 0 -#define MC_CMD_MAC_FAULT_XGMII_LOCAL_WIDTH 1 -#define MC_CMD_MAC_FAULT_XGMII_REMOTE_LBN 1 -#define MC_CMD_MAC_FAULT_XGMII_REMOTE_WIDTH 1 -#define MC_CMD_MAC_FAULT_SGMII_REMOTE_LBN 2 -#define MC_CMD_MAC_FAULT_SGMII_REMOTE_WIDTH 1 - -/* MC_CMD_GET_LINK: - * Read the unified MAC/PHY link state - * - * Locks required: None - * Return code: 0, ETIME + +/* MC_CMD_GET_LOOPBACK_MODES_IN msgrequest */ +#define MC_CMD_GET_LOOPBACK_MODES_IN_LEN 0 + +/* MC_CMD_GET_LOOPBACK_MODES_OUT msgresponse */ +#define MC_CMD_GET_LOOPBACK_MODES_OUT_LEN 32 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_100M_OFST 0 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_100M_LEN 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_100M_LO_OFST 0 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_100M_HI_OFST 4 +#define MC_CMD_LOOPBACK_NONE 0x0 /* enum */ +#define MC_CMD_LOOPBACK_DATA 0x1 /* enum */ +#define MC_CMD_LOOPBACK_GMAC 0x2 /* enum */ +#define MC_CMD_LOOPBACK_XGMII 0x3 /* enum */ +#define MC_CMD_LOOPBACK_XGXS 0x4 /* enum */ +#define MC_CMD_LOOPBACK_XAUI 0x5 /* enum */ +#define MC_CMD_LOOPBACK_GMII 0x6 /* enum */ +#define MC_CMD_LOOPBACK_SGMII 0x7 /* enum */ +#define MC_CMD_LOOPBACK_XGBR 0x8 /* enum */ +#define MC_CMD_LOOPBACK_XFI 0x9 /* enum */ +#define MC_CMD_LOOPBACK_XAUI_FAR 0xa /* enum */ +#define MC_CMD_LOOPBACK_GMII_FAR 0xb /* enum */ +#define MC_CMD_LOOPBACK_SGMII_FAR 0xc /* enum */ +#define MC_CMD_LOOPBACK_XFI_FAR 0xd /* enum */ +#define MC_CMD_LOOPBACK_GPHY 0xe /* enum */ +#define MC_CMD_LOOPBACK_PHYXS 0xf /* enum */ +#define MC_CMD_LOOPBACK_PCS 0x10 /* enum */ +#define MC_CMD_LOOPBACK_PMAPMD 0x11 /* enum */ +#define MC_CMD_LOOPBACK_XPORT 0x12 /* enum */ +#define MC_CMD_LOOPBACK_XGMII_WS 0x13 /* enum */ +#define MC_CMD_LOOPBACK_XAUI_WS 0x14 /* enum */ +#define MC_CMD_LOOPBACK_XAUI_WS_FAR 0x15 /* enum */ +#define MC_CMD_LOOPBACK_XAUI_WS_NEAR 0x16 /* enum */ +#define MC_CMD_LOOPBACK_GMII_WS 0x17 /* enum */ +#define MC_CMD_LOOPBACK_XFI_WS 0x18 /* enum */ +#define MC_CMD_LOOPBACK_XFI_WS_FAR 0x19 /* enum */ +#define MC_CMD_LOOPBACK_PHYXS_WS 0x1a /* enum */ +#define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_OFST 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_LEN 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_LO_OFST 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_HI_OFST 12 +/* Enum values, see field(s): */ +/* 100M */ +#define MC_CMD_GET_LOOPBACK_MODES_OUT_10G_OFST 16 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_10G_LEN 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_10G_LO_OFST 16 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_10G_HI_OFST 20 +/* Enum values, see field(s): */ +/* 100M */ +#define MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST 24 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LO_OFST 24 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_HI_OFST 28 +/* Enum values, see field(s): */ +/* 100M */ + + +/***********************************/ +/* MC_CMD_GET_LINK + * Read the unified MAC/PHY link state. */ #define MC_CMD_GET_LINK 0x29 -#define MC_CMD_GET_LINK_IN_LEN 0 -#define MC_CMD_GET_LINK_OUT_LEN 28 -/* near-side and link-partner advertised capabilities */ -#define MC_CMD_GET_LINK_OUT_CAP_OFST 0 -#define MC_CMD_GET_LINK_OUT_LP_CAP_OFST 4 -/* Autonegotiated speed in mbit/s. The link may still be down - * even if this reads non-zero */ -#define MC_CMD_GET_LINK_OUT_LINK_SPEED_OFST 8 -#define MC_CMD_GET_LINK_OUT_LOOPBACK_MODE_OFST 12 -#define MC_CMD_GET_LINK_OUT_FLAGS_OFST 16 -/* Whether we have overall link up */ -#define MC_CMD_GET_LINK_LINK_UP_LBN 0 -#define MC_CMD_GET_LINK_LINK_UP_WIDTH 1 -#define MC_CMD_GET_LINK_FULL_DUPLEX_LBN 1 -#define MC_CMD_GET_LINK_FULL_DUPLEX_WIDTH 1 -/* Whether we have link at the layers provided by the BPX */ -#define MC_CMD_GET_LINK_BPX_LINK_LBN 2 -#define MC_CMD_GET_LINK_BPX_LINK_WIDTH 1 -/* Whether the PHY has external link */ -#define MC_CMD_GET_LINK_PHY_LINK_LBN 3 -#define MC_CMD_GET_LINK_PHY_LINK_WIDTH 1 -#define MC_CMD_GET_LINK_OUT_FCNTL_OFST 20 -#define MC_CMD_GET_LINK_OUT_MAC_FAULT_OFST 24 - -/* MC_CMD_SET_LINK: - * Write the unified MAC/PHY link configuration - * - * A loopback speed of "0" is supported, and means - * (choose any available speed) - * - * Locks required: None - * Return code: 0, EINVAL, ETIME + +/* MC_CMD_GET_LINK_IN msgrequest */ +#define MC_CMD_GET_LINK_IN_LEN 0 + +/* MC_CMD_GET_LINK_OUT msgresponse */ +#define MC_CMD_GET_LINK_OUT_LEN 28 +#define MC_CMD_GET_LINK_OUT_CAP_OFST 0 +#define MC_CMD_GET_LINK_OUT_LP_CAP_OFST 4 +#define MC_CMD_GET_LINK_OUT_LINK_SPEED_OFST 8 +#define MC_CMD_GET_LINK_OUT_LOOPBACK_MODE_OFST 12 +/* Enum values, see field(s): */ +/* MC_CMD_GET_LOOPBACK_MODES/MC_CMD_GET_LOOPBACK_MODES_OUT/100M */ +#define MC_CMD_GET_LINK_OUT_FLAGS_OFST 16 +#define MC_CMD_GET_LINK_OUT_LINK_UP_LBN 0 +#define MC_CMD_GET_LINK_OUT_LINK_UP_WIDTH 1 +#define MC_CMD_GET_LINK_OUT_FULL_DUPLEX_LBN 1 +#define MC_CMD_GET_LINK_OUT_FULL_DUPLEX_WIDTH 1 +#define MC_CMD_GET_LINK_OUT_BPX_LINK_LBN 2 +#define MC_CMD_GET_LINK_OUT_BPX_LINK_WIDTH 1 +#define MC_CMD_GET_LINK_OUT_PHY_LINK_LBN 3 +#define MC_CMD_GET_LINK_OUT_PHY_LINK_WIDTH 1 +#define MC_CMD_GET_LINK_OUT_FCNTL_OFST 20 +#define MC_CMD_FCNTL_OFF 0x0 /* enum */ +#define MC_CMD_FCNTL_RESPOND 0x1 /* enum */ +#define MC_CMD_FCNTL_BIDIR 0x2 /* enum */ +#define MC_CMD_GET_LINK_OUT_MAC_FAULT_OFST 24 +#define MC_CMD_MAC_FAULT_XGMII_LOCAL_LBN 0 +#define MC_CMD_MAC_FAULT_XGMII_LOCAL_WIDTH 1 +#define MC_CMD_MAC_FAULT_XGMII_REMOTE_LBN 1 +#define MC_CMD_MAC_FAULT_XGMII_REMOTE_WIDTH 1 +#define MC_CMD_MAC_FAULT_SGMII_REMOTE_LBN 2 +#define MC_CMD_MAC_FAULT_SGMII_REMOTE_WIDTH 1 +#define MC_CMD_MAC_FAULT_PENDING_RECONFIG_LBN 3 +#define MC_CMD_MAC_FAULT_PENDING_RECONFIG_WIDTH 1 + + +/***********************************/ +/* MC_CMD_SET_LINK + * Write the unified MAC/PHY link configuration. */ #define MC_CMD_SET_LINK 0x2a -#define MC_CMD_SET_LINK_IN_LEN 16 -#define MC_CMD_SET_LINK_IN_CAP_OFST 0 -#define MC_CMD_SET_LINK_IN_FLAGS_OFST 4 -#define MC_CMD_SET_LINK_LOWPOWER_LBN 0 -#define MC_CMD_SET_LINK_LOWPOWER_WIDTH 1 -#define MC_CMD_SET_LINK_POWEROFF_LBN 1 -#define MC_CMD_SET_LINK_POWEROFF_WIDTH 1 -#define MC_CMD_SET_LINK_TXDIS_LBN 2 -#define MC_CMD_SET_LINK_TXDIS_WIDTH 1 -#define MC_CMD_SET_LINK_IN_LOOPBACK_MODE_OFST 8 -#define MC_CMD_SET_LINK_IN_LOOPBACK_SPEED_OFST 12 -#define MC_CMD_SET_LINK_OUT_LEN 0 - -/* MC_CMD_SET_ID_LED: - * Set indentification LED state - * - * Locks required: None - * Return code: 0, EINVAL + +/* MC_CMD_SET_LINK_IN msgrequest */ +#define MC_CMD_SET_LINK_IN_LEN 16 +#define MC_CMD_SET_LINK_IN_CAP_OFST 0 +#define MC_CMD_SET_LINK_IN_FLAGS_OFST 4 +#define MC_CMD_SET_LINK_IN_LOWPOWER_LBN 0 +#define MC_CMD_SET_LINK_IN_LOWPOWER_WIDTH 1 +#define MC_CMD_SET_LINK_IN_POWEROFF_LBN 1 +#define MC_CMD_SET_LINK_IN_POWEROFF_WIDTH 1 +#define MC_CMD_SET_LINK_IN_TXDIS_LBN 2 +#define MC_CMD_SET_LINK_IN_TXDIS_WIDTH 1 +#define MC_CMD_SET_LINK_IN_LOOPBACK_MODE_OFST 8 +/* Enum values, see field(s): */ +/* MC_CMD_GET_LOOPBACK_MODES/MC_CMD_GET_LOOPBACK_MODES_OUT/100M */ +#define MC_CMD_SET_LINK_IN_LOOPBACK_SPEED_OFST 12 + +/* MC_CMD_SET_LINK_OUT msgresponse */ +#define MC_CMD_SET_LINK_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_SET_ID_LED + * Set indentification LED state. */ #define MC_CMD_SET_ID_LED 0x2b -#define MC_CMD_SET_ID_LED_IN_LEN 4 -#define MC_CMD_SET_ID_LED_IN_STATE_OFST 0 -#define MC_CMD_LED_OFF 0 -#define MC_CMD_LED_ON 1 -#define MC_CMD_LED_DEFAULT 2 -#define MC_CMD_SET_ID_LED_OUT_LEN 0 - -/* MC_CMD_SET_MAC: - * Set MAC configuration - * - * The MTU is the MTU programmed directly into the XMAC/GMAC - * (inclusive of EtherII, VLAN, bug16011 padding) - * - * Locks required: None - * Return code: 0, EINVAL + +/* MC_CMD_SET_ID_LED_IN msgrequest */ +#define MC_CMD_SET_ID_LED_IN_LEN 4 +#define MC_CMD_SET_ID_LED_IN_STATE_OFST 0 +#define MC_CMD_LED_OFF 0x0 /* enum */ +#define MC_CMD_LED_ON 0x1 /* enum */ +#define MC_CMD_LED_DEFAULT 0x2 /* enum */ + +/* MC_CMD_SET_ID_LED_OUT msgresponse */ +#define MC_CMD_SET_ID_LED_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_SET_MAC + * Set MAC configuration. */ #define MC_CMD_SET_MAC 0x2c -#define MC_CMD_SET_MAC_IN_LEN 24 -#define MC_CMD_SET_MAC_IN_MTU_OFST 0 -#define MC_CMD_SET_MAC_IN_DRAIN_OFST 4 -#define MC_CMD_SET_MAC_IN_ADDR_OFST 8 -#define MC_CMD_SET_MAC_IN_REJECT_OFST 16 -#define MC_CMD_SET_MAC_IN_REJECT_UNCST_LBN 0 -#define MC_CMD_SET_MAC_IN_REJECT_UNCST_WIDTH 1 -#define MC_CMD_SET_MAC_IN_REJECT_BRDCST_LBN 1 -#define MC_CMD_SET_MAC_IN_REJECT_BRDCST_WIDTH 1 -#define MC_CMD_SET_MAC_IN_FCNTL_OFST 20 -#define MC_CMD_SET_MAC_OUT_LEN 0 - -/* MC_CMD_PHY_STATS: - * Get generic PHY statistics - * - * This call returns the statistics for a generic PHY in a sparse - * array (indexed by the enumerate). Each value is represented by - * a 32bit number. - * - * If the DMA_ADDR is 0, then no DMA is performed, and the statistics - * may be read directly out of shared memory. If DMA_ADDR != 0, then - * the statistics are dmad to that (page-aligned location) - * - * Locks required: None - * Returns: 0, ETIME - * Response methods: shared memory, event + +/* MC_CMD_SET_MAC_IN msgrequest */ +#define MC_CMD_SET_MAC_IN_LEN 24 +#define MC_CMD_SET_MAC_IN_MTU_OFST 0 +#define MC_CMD_SET_MAC_IN_DRAIN_OFST 4 +#define MC_CMD_SET_MAC_IN_ADDR_OFST 8 +#define MC_CMD_SET_MAC_IN_ADDR_LEN 8 +#define MC_CMD_SET_MAC_IN_ADDR_LO_OFST 8 +#define MC_CMD_SET_MAC_IN_ADDR_HI_OFST 12 +#define MC_CMD_SET_MAC_IN_REJECT_OFST 16 +#define MC_CMD_SET_MAC_IN_REJECT_UNCST_LBN 0 +#define MC_CMD_SET_MAC_IN_REJECT_UNCST_WIDTH 1 +#define MC_CMD_SET_MAC_IN_REJECT_BRDCST_LBN 1 +#define MC_CMD_SET_MAC_IN_REJECT_BRDCST_WIDTH 1 +#define MC_CMD_SET_MAC_IN_FCNTL_OFST 20 +/* MC_CMD_FCNTL_OFF 0x0 */ +/* MC_CMD_FCNTL_RESPOND 0x1 */ +/* MC_CMD_FCNTL_BIDIR 0x2 */ +#define MC_CMD_FCNTL_AUTO 0x3 /* enum */ + +/* MC_CMD_SET_MAC_OUT msgresponse */ +#define MC_CMD_SET_MAC_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_PHY_STATS + * Get generic PHY statistics. */ #define MC_CMD_PHY_STATS 0x2d -#define MC_CMD_PHY_STATS_IN_LEN 8 -#define MC_CMD_PHY_STATS_IN_DMA_ADDR_LO_OFST 0 -#define MC_CMD_PHY_STATS_IN_DMA_ADDR_HI_OFST 4 -#define MC_CMD_PHY_STATS_OUT_DMA_LEN 0 -#define MC_CMD_PHY_STATS_OUT_NO_DMA_LEN (MC_CMD_PHY_NSTATS * 4) - -/* Unified MAC statistics enumeration */ -#define MC_CMD_MAC_GENERATION_START 0 -#define MC_CMD_MAC_TX_PKTS 1 -#define MC_CMD_MAC_TX_PAUSE_PKTS 2 -#define MC_CMD_MAC_TX_CONTROL_PKTS 3 -#define MC_CMD_MAC_TX_UNICAST_PKTS 4 -#define MC_CMD_MAC_TX_MULTICAST_PKTS 5 -#define MC_CMD_MAC_TX_BROADCAST_PKTS 6 -#define MC_CMD_MAC_TX_BYTES 7 -#define MC_CMD_MAC_TX_BAD_BYTES 8 -#define MC_CMD_MAC_TX_LT64_PKTS 9 -#define MC_CMD_MAC_TX_64_PKTS 10 -#define MC_CMD_MAC_TX_65_TO_127_PKTS 11 -#define MC_CMD_MAC_TX_128_TO_255_PKTS 12 -#define MC_CMD_MAC_TX_256_TO_511_PKTS 13 -#define MC_CMD_MAC_TX_512_TO_1023_PKTS 14 -#define MC_CMD_MAC_TX_1024_TO_15XX_PKTS 15 -#define MC_CMD_MAC_TX_15XX_TO_JUMBO_PKTS 16 -#define MC_CMD_MAC_TX_GTJUMBO_PKTS 17 -#define MC_CMD_MAC_TX_BAD_FCS_PKTS 18 -#define MC_CMD_MAC_TX_SINGLE_COLLISION_PKTS 19 -#define MC_CMD_MAC_TX_MULTIPLE_COLLISION_PKTS 20 -#define MC_CMD_MAC_TX_EXCESSIVE_COLLISION_PKTS 21 -#define MC_CMD_MAC_TX_LATE_COLLISION_PKTS 22 -#define MC_CMD_MAC_TX_DEFERRED_PKTS 23 -#define MC_CMD_MAC_TX_EXCESSIVE_DEFERRED_PKTS 24 -#define MC_CMD_MAC_TX_NON_TCPUDP_PKTS 25 -#define MC_CMD_MAC_TX_MAC_SRC_ERR_PKTS 26 -#define MC_CMD_MAC_TX_IP_SRC_ERR_PKTS 27 -#define MC_CMD_MAC_RX_PKTS 28 -#define MC_CMD_MAC_RX_PAUSE_PKTS 29 -#define MC_CMD_MAC_RX_GOOD_PKTS 30 -#define MC_CMD_MAC_RX_CONTROL_PKTS 31 -#define MC_CMD_MAC_RX_UNICAST_PKTS 32 -#define MC_CMD_MAC_RX_MULTICAST_PKTS 33 -#define MC_CMD_MAC_RX_BROADCAST_PKTS 34 -#define MC_CMD_MAC_RX_BYTES 35 -#define MC_CMD_MAC_RX_BAD_BYTES 36 -#define MC_CMD_MAC_RX_64_PKTS 37 -#define MC_CMD_MAC_RX_65_TO_127_PKTS 38 -#define MC_CMD_MAC_RX_128_TO_255_PKTS 39 -#define MC_CMD_MAC_RX_256_TO_511_PKTS 40 -#define MC_CMD_MAC_RX_512_TO_1023_PKTS 41 -#define MC_CMD_MAC_RX_1024_TO_15XX_PKTS 42 -#define MC_CMD_MAC_RX_15XX_TO_JUMBO_PKTS 43 -#define MC_CMD_MAC_RX_GTJUMBO_PKTS 44 -#define MC_CMD_MAC_RX_UNDERSIZE_PKTS 45 -#define MC_CMD_MAC_RX_BAD_FCS_PKTS 46 -#define MC_CMD_MAC_RX_OVERFLOW_PKTS 47 -#define MC_CMD_MAC_RX_FALSE_CARRIER_PKTS 48 -#define MC_CMD_MAC_RX_SYMBOL_ERROR_PKTS 49 -#define MC_CMD_MAC_RX_ALIGN_ERROR_PKTS 50 -#define MC_CMD_MAC_RX_LENGTH_ERROR_PKTS 51 -#define MC_CMD_MAC_RX_INTERNAL_ERROR_PKTS 52 -#define MC_CMD_MAC_RX_JABBER_PKTS 53 -#define MC_CMD_MAC_RX_NODESC_DROPS 54 -#define MC_CMD_MAC_RX_LANES01_CHAR_ERR 55 -#define MC_CMD_MAC_RX_LANES23_CHAR_ERR 56 -#define MC_CMD_MAC_RX_LANES01_DISP_ERR 57 -#define MC_CMD_MAC_RX_LANES23_DISP_ERR 58 -#define MC_CMD_MAC_RX_MATCH_FAULT 59 -#define MC_CMD_GMAC_DMABUF_START 64 -#define MC_CMD_GMAC_DMABUF_END 95 -/* Insert new members here. */ -#define MC_CMD_MAC_GENERATION_END 96 -#define MC_CMD_MAC_NSTATS (MC_CMD_MAC_GENERATION_END+1) - -/* MC_CMD_MAC_STATS: - * Get unified GMAC/XMAC statistics - * - * This call returns unified statistics maintained by the MC as it - * switches between the GMAC and XMAC. The MC will write out all - * supported stats. The driver should zero initialise the buffer to - * guarantee consistent results. - * - * Locks required: None - * Returns: 0 - * Response methods: shared memory, event - */ -#define MC_CMD_MAC_STATS 0x2e -#define MC_CMD_MAC_STATS_IN_LEN 16 -#define MC_CMD_MAC_STATS_IN_DMA_ADDR_LO_OFST 0 -#define MC_CMD_MAC_STATS_IN_DMA_ADDR_HI_OFST 4 -#define MC_CMD_MAC_STATS_IN_CMD_OFST 8 -#define MC_CMD_MAC_STATS_CMD_DMA_LBN 0 -#define MC_CMD_MAC_STATS_CMD_DMA_WIDTH 1 -#define MC_CMD_MAC_STATS_CMD_CLEAR_LBN 1 -#define MC_CMD_MAC_STATS_CMD_CLEAR_WIDTH 1 -#define MC_CMD_MAC_STATS_CMD_PERIODIC_CHANGE_LBN 2 -#define MC_CMD_MAC_STATS_CMD_PERIODIC_CHANGE_WIDTH 1 -/* Remaining PERIOD* fields only relevant when PERIODIC_CHANGE is set */ -#define MC_CMD_MAC_STATS_CMD_PERIODIC_ENABLE_LBN 3 -#define MC_CMD_MAC_STATS_CMD_PERIODIC_ENABLE_WIDTH 1 -#define MC_CMD_MAC_STATS_CMD_PERIODIC_CLEAR_LBN 4 -#define MC_CMD_MAC_STATS_CMD_PERIODIC_CLEAR_WIDTH 1 -#define MC_CMD_MAC_STATS_CMD_PERIODIC_NOEVENT_LBN 5 -#define MC_CMD_MAC_STATS_CMD_PERIODIC_NOEVENT_WIDTH 1 -#define MC_CMD_MAC_STATS_CMD_PERIOD_MS_LBN 16 -#define MC_CMD_MAC_STATS_CMD_PERIOD_MS_WIDTH 16 -#define MC_CMD_MAC_STATS_IN_DMA_LEN_OFST 12 - -#define MC_CMD_MAC_STATS_OUT_LEN 0 - -/* Callisto flags */ -#define MC_CMD_SFT9001_ROBUST_LBN 0 -#define MC_CMD_SFT9001_ROBUST_WIDTH 1 -#define MC_CMD_SFT9001_SHORT_REACH_LBN 1 -#define MC_CMD_SFT9001_SHORT_REACH_WIDTH 1 - -/* MC_CMD_SFT9001_GET: - * Read current callisto specific setting - * - * Locks required: None - * Returns: 0, ETIME - */ -#define MC_CMD_SFT9001_GET 0x30 -#define MC_CMD_SFT9001_GET_IN_LEN 0 -#define MC_CMD_SFT9001_GET_OUT_LEN 4 -#define MC_CMD_SFT9001_GET_OUT_FLAGS_OFST 0 -/* MC_CMD_SFT9001_SET: - * Write current callisto specific setting - * - * Locks required: None - * Returns: 0, ETIME, EINVAL +/* MC_CMD_PHY_STATS_IN msgrequest */ +#define MC_CMD_PHY_STATS_IN_LEN 8 +#define MC_CMD_PHY_STATS_IN_DMA_ADDR_OFST 0 +#define MC_CMD_PHY_STATS_IN_DMA_ADDR_LEN 8 +#define MC_CMD_PHY_STATS_IN_DMA_ADDR_LO_OFST 0 +#define MC_CMD_PHY_STATS_IN_DMA_ADDR_HI_OFST 4 + +/* MC_CMD_PHY_STATS_OUT_DMA msgresponse */ +#define MC_CMD_PHY_STATS_OUT_DMA_LEN 0 + +/* MC_CMD_PHY_STATS_OUT_NO_DMA msgresponse */ +#define MC_CMD_PHY_STATS_OUT_NO_DMA_LEN (((MC_CMD_PHY_NSTATS*32))>>3) +#define MC_CMD_PHY_STATS_OUT_NO_DMA_STATISTICS_OFST 0 +#define MC_CMD_PHY_STATS_OUT_NO_DMA_STATISTICS_LEN 4 +#define MC_CMD_PHY_STATS_OUT_NO_DMA_STATISTICS_NUM MC_CMD_PHY_NSTATS +#define MC_CMD_OUI 0x0 /* enum */ +#define MC_CMD_PMA_PMD_LINK_UP 0x1 /* enum */ +#define MC_CMD_PMA_PMD_RX_FAULT 0x2 /* enum */ +#define MC_CMD_PMA_PMD_TX_FAULT 0x3 /* enum */ +#define MC_CMD_PMA_PMD_SIGNAL 0x4 /* enum */ +#define MC_CMD_PMA_PMD_SNR_A 0x5 /* enum */ +#define MC_CMD_PMA_PMD_SNR_B 0x6 /* enum */ +#define MC_CMD_PMA_PMD_SNR_C 0x7 /* enum */ +#define MC_CMD_PMA_PMD_SNR_D 0x8 /* enum */ +#define MC_CMD_PCS_LINK_UP 0x9 /* enum */ +#define MC_CMD_PCS_RX_FAULT 0xa /* enum */ +#define MC_CMD_PCS_TX_FAULT 0xb /* enum */ +#define MC_CMD_PCS_BER 0xc /* enum */ +#define MC_CMD_PCS_BLOCK_ERRORS 0xd /* enum */ +#define MC_CMD_PHYXS_LINK_UP 0xe /* enum */ +#define MC_CMD_PHYXS_RX_FAULT 0xf /* enum */ +#define MC_CMD_PHYXS_TX_FAULT 0x10 /* enum */ +#define MC_CMD_PHYXS_ALIGN 0x11 /* enum */ +#define MC_CMD_PHYXS_SYNC 0x12 /* enum */ +#define MC_CMD_AN_LINK_UP 0x13 /* enum */ +#define MC_CMD_AN_COMPLETE 0x14 /* enum */ +#define MC_CMD_AN_10GBT_STATUS 0x15 /* enum */ +#define MC_CMD_CL22_LINK_UP 0x16 /* enum */ +#define MC_CMD_PHY_NSTATS 0x17 /* enum */ + + +/***********************************/ +/* MC_CMD_MAC_STATS + * Get generic MAC statistics. */ -#define MC_CMD_SFT9001_SET 0x31 -#define MC_CMD_SFT9001_SET_IN_LEN 4 -#define MC_CMD_SFT9001_SET_IN_FLAGS_OFST 0 -#define MC_CMD_SFT9001_SET_OUT_LEN 0 - +#define MC_CMD_MAC_STATS 0x2e -/* MC_CMD_WOL_FILTER_SET: - * Set a WoL filter - * - * Locks required: None - * Returns: 0, EBUSY, EINVAL, ENOSYS +/* MC_CMD_MAC_STATS_IN msgrequest */ +#define MC_CMD_MAC_STATS_IN_LEN 16 +#define MC_CMD_MAC_STATS_IN_DMA_ADDR_OFST 0 +#define MC_CMD_MAC_STATS_IN_DMA_ADDR_LEN 8 +#define MC_CMD_MAC_STATS_IN_DMA_ADDR_LO_OFST 0 +#define MC_CMD_MAC_STATS_IN_DMA_ADDR_HI_OFST 4 +#define MC_CMD_MAC_STATS_IN_CMD_OFST 8 +#define MC_CMD_MAC_STATS_IN_DMA_LBN 0 +#define MC_CMD_MAC_STATS_IN_DMA_WIDTH 1 +#define MC_CMD_MAC_STATS_IN_CLEAR_LBN 1 +#define MC_CMD_MAC_STATS_IN_CLEAR_WIDTH 1 +#define MC_CMD_MAC_STATS_IN_PERIODIC_CHANGE_LBN 2 +#define MC_CMD_MAC_STATS_IN_PERIODIC_CHANGE_WIDTH 1 +#define MC_CMD_MAC_STATS_IN_PERIODIC_ENABLE_LBN 3 +#define MC_CMD_MAC_STATS_IN_PERIODIC_ENABLE_WIDTH 1 +#define MC_CMD_MAC_STATS_IN_PERIODIC_CLEAR_LBN 4 +#define MC_CMD_MAC_STATS_IN_PERIODIC_CLEAR_WIDTH 1 +#define MC_CMD_MAC_STATS_IN_PERIODIC_NOEVENT_LBN 5 +#define MC_CMD_MAC_STATS_IN_PERIODIC_NOEVENT_WIDTH 1 +#define MC_CMD_MAC_STATS_IN_PERIOD_MS_LBN 16 +#define MC_CMD_MAC_STATS_IN_PERIOD_MS_WIDTH 16 +#define MC_CMD_MAC_STATS_IN_DMA_LEN_OFST 12 + +/* MC_CMD_MAC_STATS_OUT_DMA msgresponse */ +#define MC_CMD_MAC_STATS_OUT_DMA_LEN 0 + +/* MC_CMD_MAC_STATS_OUT_NO_DMA msgresponse */ +#define MC_CMD_MAC_STATS_OUT_NO_DMA_LEN (((MC_CMD_MAC_NSTATS*64))>>3) +#define MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_OFST 0 +#define MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_LEN 8 +#define MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_LO_OFST 0 +#define MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_HI_OFST 4 +#define MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_NUM MC_CMD_MAC_NSTATS +#define MC_CMD_MAC_GENERATION_START 0x0 /* enum */ +#define MC_CMD_MAC_TX_PKTS 0x1 /* enum */ +#define MC_CMD_MAC_TX_PAUSE_PKTS 0x2 /* enum */ +#define MC_CMD_MAC_TX_CONTROL_PKTS 0x3 /* enum */ +#define MC_CMD_MAC_TX_UNICAST_PKTS 0x4 /* enum */ +#define MC_CMD_MAC_TX_MULTICAST_PKTS 0x5 /* enum */ +#define MC_CMD_MAC_TX_BROADCAST_PKTS 0x6 /* enum */ +#define MC_CMD_MAC_TX_BYTES 0x7 /* enum */ +#define MC_CMD_MAC_TX_BAD_BYTES 0x8 /* enum */ +#define MC_CMD_MAC_TX_LT64_PKTS 0x9 /* enum */ +#define MC_CMD_MAC_TX_64_PKTS 0xa /* enum */ +#define MC_CMD_MAC_TX_65_TO_127_PKTS 0xb /* enum */ +#define MC_CMD_MAC_TX_128_TO_255_PKTS 0xc /* enum */ +#define MC_CMD_MAC_TX_256_TO_511_PKTS 0xd /* enum */ +#define MC_CMD_MAC_TX_512_TO_1023_PKTS 0xe /* enum */ +#define MC_CMD_MAC_TX_1024_TO_15XX_PKTS 0xf /* enum */ +#define MC_CMD_MAC_TX_15XX_TO_JUMBO_PKTS 0x10 /* enum */ +#define MC_CMD_MAC_TX_GTJUMBO_PKTS 0x11 /* enum */ +#define MC_CMD_MAC_TX_BAD_FCS_PKTS 0x12 /* enum */ +#define MC_CMD_MAC_TX_SINGLE_COLLISION_PKTS 0x13 /* enum */ +#define MC_CMD_MAC_TX_MULTIPLE_COLLISION_PKTS 0x14 /* enum */ +#define MC_CMD_MAC_TX_EXCESSIVE_COLLISION_PKTS 0x15 /* enum */ +#define MC_CMD_MAC_TX_LATE_COLLISION_PKTS 0x16 /* enum */ +#define MC_CMD_MAC_TX_DEFERRED_PKTS 0x17 /* enum */ +#define MC_CMD_MAC_TX_EXCESSIVE_DEFERRED_PKTS 0x18 /* enum */ +#define MC_CMD_MAC_TX_NON_TCPUDP_PKTS 0x19 /* enum */ +#define MC_CMD_MAC_TX_MAC_SRC_ERR_PKTS 0x1a /* enum */ +#define MC_CMD_MAC_TX_IP_SRC_ERR_PKTS 0x1b /* enum */ +#define MC_CMD_MAC_RX_PKTS 0x1c /* enum */ +#define MC_CMD_MAC_RX_PAUSE_PKTS 0x1d /* enum */ +#define MC_CMD_MAC_RX_GOOD_PKTS 0x1e /* enum */ +#define MC_CMD_MAC_RX_CONTROL_PKTS 0x1f /* enum */ +#define MC_CMD_MAC_RX_UNICAST_PKTS 0x20 /* enum */ +#define MC_CMD_MAC_RX_MULTICAST_PKTS 0x21 /* enum */ +#define MC_CMD_MAC_RX_BROADCAST_PKTS 0x22 /* enum */ +#define MC_CMD_MAC_RX_BYTES 0x23 /* enum */ +#define MC_CMD_MAC_RX_BAD_BYTES 0x24 /* enum */ +#define MC_CMD_MAC_RX_64_PKTS 0x25 /* enum */ +#define MC_CMD_MAC_RX_65_TO_127_PKTS 0x26 /* enum */ +#define MC_CMD_MAC_RX_128_TO_255_PKTS 0x27 /* enum */ +#define MC_CMD_MAC_RX_256_TO_511_PKTS 0x28 /* enum */ +#define MC_CMD_MAC_RX_512_TO_1023_PKTS 0x29 /* enum */ +#define MC_CMD_MAC_RX_1024_TO_15XX_PKTS 0x2a /* enum */ +#define MC_CMD_MAC_RX_15XX_TO_JUMBO_PKTS 0x2b /* enum */ +#define MC_CMD_MAC_RX_GTJUMBO_PKTS 0x2c /* enum */ +#define MC_CMD_MAC_RX_UNDERSIZE_PKTS 0x2d /* enum */ +#define MC_CMD_MAC_RX_BAD_FCS_PKTS 0x2e /* enum */ +#define MC_CMD_MAC_RX_OVERFLOW_PKTS 0x2f /* enum */ +#define MC_CMD_MAC_RX_FALSE_CARRIER_PKTS 0x30 /* enum */ +#define MC_CMD_MAC_RX_SYMBOL_ERROR_PKTS 0x31 /* enum */ +#define MC_CMD_MAC_RX_ALIGN_ERROR_PKTS 0x32 /* enum */ +#define MC_CMD_MAC_RX_LENGTH_ERROR_PKTS 0x33 /* enum */ +#define MC_CMD_MAC_RX_INTERNAL_ERROR_PKTS 0x34 /* enum */ +#define MC_CMD_MAC_RX_JABBER_PKTS 0x35 /* enum */ +#define MC_CMD_MAC_RX_NODESC_DROPS 0x36 /* enum */ +#define MC_CMD_MAC_RX_LANES01_CHAR_ERR 0x37 /* enum */ +#define MC_CMD_MAC_RX_LANES23_CHAR_ERR 0x38 /* enum */ +#define MC_CMD_MAC_RX_LANES01_DISP_ERR 0x39 /* enum */ +#define MC_CMD_MAC_RX_LANES23_DISP_ERR 0x3a /* enum */ +#define MC_CMD_MAC_RX_MATCH_FAULT 0x3b /* enum */ +#define MC_CMD_GMAC_DMABUF_START 0x40 /* enum */ +#define MC_CMD_GMAC_DMABUF_END 0x5f /* enum */ +#define MC_CMD_MAC_GENERATION_END 0x60 /* enum */ +#define MC_CMD_MAC_NSTATS 0x61 /* enum */ + + +/***********************************/ +/* MC_CMD_SRIOV + * to be documented + */ +#define MC_CMD_SRIOV 0x30 + +/* MC_CMD_SRIOV_IN msgrequest */ +#define MC_CMD_SRIOV_IN_LEN 12 +#define MC_CMD_SRIOV_IN_ENABLE_OFST 0 +#define MC_CMD_SRIOV_IN_VI_BASE_OFST 4 +#define MC_CMD_SRIOV_IN_VF_COUNT_OFST 8 + +/* MC_CMD_SRIOV_OUT msgresponse */ +#define MC_CMD_SRIOV_OUT_LEN 8 +#define MC_CMD_SRIOV_OUT_VI_SCALE_OFST 0 +#define MC_CMD_SRIOV_OUT_VF_TOTAL_OFST 4 + +/* MC_CMD_MEMCPY_RECORD_TYPEDEF structuredef */ +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_LEN 32 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_NUM_RECORDS_OFST 0 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_NUM_RECORDS_LBN 0 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_NUM_RECORDS_WIDTH 32 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_RID_OFST 4 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_RID_LBN 32 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_RID_WIDTH 32 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_ADDR_OFST 8 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_ADDR_LEN 8 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_ADDR_LO_OFST 8 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_ADDR_HI_OFST 12 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_ADDR_LBN 64 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_ADDR_WIDTH 64 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_RID_OFST 16 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_RID_INLINE 0x100 /* enum */ +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_RID_LBN 128 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_RID_WIDTH 32 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_ADDR_OFST 20 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_ADDR_LEN 8 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_ADDR_LO_OFST 20 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_ADDR_HI_OFST 24 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_ADDR_LBN 160 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_ADDR_WIDTH 64 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_LENGTH_OFST 28 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_LENGTH_LBN 224 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_LENGTH_WIDTH 32 + + +/***********************************/ +/* MC_CMD_MEMCPY + * Perform memory copy operation. + */ +#define MC_CMD_MEMCPY 0x31 + +/* MC_CMD_MEMCPY_IN msgrequest */ +#define MC_CMD_MEMCPY_IN_LENMIN 32 +#define MC_CMD_MEMCPY_IN_LENMAX 224 +#define MC_CMD_MEMCPY_IN_LEN(num) (0+32*(num)) +#define MC_CMD_MEMCPY_IN_RECORD_OFST 0 +#define MC_CMD_MEMCPY_IN_RECORD_LEN 32 +#define MC_CMD_MEMCPY_IN_RECORD_MINNUM 1 +#define MC_CMD_MEMCPY_IN_RECORD_MAXNUM 7 + +/* MC_CMD_MEMCPY_OUT msgresponse */ +#define MC_CMD_MEMCPY_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_WOL_FILTER_SET + * Set a WoL filter. */ #define MC_CMD_WOL_FILTER_SET 0x32 -#define MC_CMD_WOL_FILTER_SET_IN_LEN 192 /* 190 rounded up to a word */ -#define MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 -#define MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 - -/* There is a union at offset 8, following defines overlap due to - * this */ -#define MC_CMD_WOL_FILTER_SET_IN_DATA_OFST 8 - -#define MC_CMD_WOL_FILTER_SET_IN_MAGIC_MAC_OFST \ - MC_CMD_WOL_FILTER_SET_IN_DATA_OFST - -#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_SRC_IP_OFST \ - MC_CMD_WOL_FILTER_SET_IN_DATA_OFST -#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_DST_IP_OFST \ - (MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 4) -#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_SRC_PORT_OFST \ - (MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 8) -#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_DST_PORT_OFST \ - (MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 10) - -#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_SRC_IP_OFST \ - MC_CMD_WOL_FILTER_SET_IN_DATA_OFST -#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_DST_IP_OFST \ - (MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 16) -#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_SRC_PORT_OFST \ - (MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 32) -#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_DST_PORT_OFST \ - (MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 34) - -#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_MASK_OFST \ - MC_CMD_WOL_FILTER_SET_IN_DATA_OFST -#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_OFST \ - (MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 48) -#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LEN_OFST \ - (MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 176) -#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LAYER3_OFST \ - (MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 177) -#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LAYER4_OFST \ - (MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 178) - -#define MC_CMD_WOL_FILTER_SET_IN_LINK_MASK_OFST \ - MC_CMD_WOL_FILTER_SET_IN_DATA_OFST -#define MC_CMD_WOL_FILTER_SET_IN_LINK_UP_LBN 0 -#define MC_CMD_WOL_FILTER_SET_IN_LINK_UP_WIDTH 1 -#define MC_CMD_WOL_FILTER_SET_IN_LINK_DOWN_LBN 1 -#define MC_CMD_WOL_FILTER_SET_IN_LINK_DOWN_WIDTH 1 - -#define MC_CMD_WOL_FILTER_SET_OUT_LEN 4 -#define MC_CMD_WOL_FILTER_SET_OUT_FILTER_ID_OFST 0 - -/* WOL Filter types enumeration */ -#define MC_CMD_WOL_TYPE_MAGIC 0x0 - /* unused 0x1 */ -#define MC_CMD_WOL_TYPE_WIN_MAGIC 0x2 -#define MC_CMD_WOL_TYPE_IPV4_SYN 0x3 -#define MC_CMD_WOL_TYPE_IPV6_SYN 0x4 -#define MC_CMD_WOL_TYPE_BITMAP 0x5 -#define MC_CMD_WOL_TYPE_LINK 0x6 -#define MC_CMD_WOL_TYPE_MAX 0x7 - -#define MC_CMD_FILTER_MODE_SIMPLE 0x0 -#define MC_CMD_FILTER_MODE_STRUCTURED 0xffffffff - -/* MC_CMD_WOL_FILTER_REMOVE: - * Remove a WoL filter - * - * Locks required: None - * Returns: 0, EINVAL, ENOSYS + +/* MC_CMD_WOL_FILTER_SET_IN msgrequest */ +#define MC_CMD_WOL_FILTER_SET_IN_LEN 192 +#define MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 +#define MC_CMD_FILTER_MODE_SIMPLE 0x0 /* enum */ +#define MC_CMD_FILTER_MODE_STRUCTURED 0xffffffff /* enum */ +#define MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 +#define MC_CMD_WOL_TYPE_MAGIC 0x0 /* enum */ +#define MC_CMD_WOL_TYPE_WIN_MAGIC 0x2 /* enum */ +#define MC_CMD_WOL_TYPE_IPV4_SYN 0x3 /* enum */ +#define MC_CMD_WOL_TYPE_IPV6_SYN 0x4 /* enum */ +#define MC_CMD_WOL_TYPE_BITMAP 0x5 /* enum */ +#define MC_CMD_WOL_TYPE_LINK 0x6 /* enum */ +#define MC_CMD_WOL_TYPE_MAX 0x7 /* enum */ +#define MC_CMD_WOL_FILTER_SET_IN_DATA_OFST 8 +#define MC_CMD_WOL_FILTER_SET_IN_DATA_LEN 4 +#define MC_CMD_WOL_FILTER_SET_IN_DATA_NUM 46 + +/* MC_CMD_WOL_FILTER_SET_IN_MAGIC msgrequest */ +#define MC_CMD_WOL_FILTER_SET_IN_MAGIC_LEN 16 +/* MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 */ +/* MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 */ +#define MC_CMD_WOL_FILTER_SET_IN_MAGIC_MAC_OFST 8 +#define MC_CMD_WOL_FILTER_SET_IN_MAGIC_MAC_LEN 8 +#define MC_CMD_WOL_FILTER_SET_IN_MAGIC_MAC_LO_OFST 8 +#define MC_CMD_WOL_FILTER_SET_IN_MAGIC_MAC_HI_OFST 12 + +/* MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN msgrequest */ +#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_LEN 20 +/* MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 */ +/* MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 */ +#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_SRC_IP_OFST 8 +#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_DST_IP_OFST 12 +#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_SRC_PORT_OFST 16 +#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_SRC_PORT_LEN 2 +#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_DST_PORT_OFST 18 +#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_DST_PORT_LEN 2 + +/* MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN msgrequest */ +#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_LEN 44 +/* MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 */ +/* MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 */ +#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_SRC_IP_OFST 8 +#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_SRC_IP_LEN 16 +#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_DST_IP_OFST 24 +#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_DST_IP_LEN 16 +#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_SRC_PORT_OFST 40 +#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_SRC_PORT_LEN 2 +#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_DST_PORT_OFST 42 +#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_DST_PORT_LEN 2 + +/* MC_CMD_WOL_FILTER_SET_IN_BITMAP msgrequest */ +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LEN 187 +/* MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 */ +/* MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 */ +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_MASK_OFST 8 +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_MASK_LEN 48 +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_BITMAP_OFST 56 +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_BITMAP_LEN 128 +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LEN_OFST 184 +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LEN_LEN 1 +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LAYER3_OFST 185 +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LAYER3_LEN 1 +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LAYER4_OFST 186 +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LAYER4_LEN 1 + +/* MC_CMD_WOL_FILTER_SET_IN_LINK msgrequest */ +#define MC_CMD_WOL_FILTER_SET_IN_LINK_LEN 12 +/* MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 */ +/* MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 */ +#define MC_CMD_WOL_FILTER_SET_IN_LINK_MASK_OFST 8 +#define MC_CMD_WOL_FILTER_SET_IN_LINK_UP_LBN 0 +#define MC_CMD_WOL_FILTER_SET_IN_LINK_UP_WIDTH 1 +#define MC_CMD_WOL_FILTER_SET_IN_LINK_DOWN_LBN 1 +#define MC_CMD_WOL_FILTER_SET_IN_LINK_DOWN_WIDTH 1 + +/* MC_CMD_WOL_FILTER_SET_OUT msgresponse */ +#define MC_CMD_WOL_FILTER_SET_OUT_LEN 4 +#define MC_CMD_WOL_FILTER_SET_OUT_FILTER_ID_OFST 0 + + +/***********************************/ +/* MC_CMD_WOL_FILTER_REMOVE + * Remove a WoL filter. */ #define MC_CMD_WOL_FILTER_REMOVE 0x33 -#define MC_CMD_WOL_FILTER_REMOVE_IN_LEN 4 -#define MC_CMD_WOL_FILTER_REMOVE_IN_FILTER_ID_OFST 0 -#define MC_CMD_WOL_FILTER_REMOVE_OUT_LEN 0 +/* MC_CMD_WOL_FILTER_REMOVE_IN msgrequest */ +#define MC_CMD_WOL_FILTER_REMOVE_IN_LEN 4 +#define MC_CMD_WOL_FILTER_REMOVE_IN_FILTER_ID_OFST 0 -/* MC_CMD_WOL_FILTER_RESET: - * Reset (i.e. remove all) WoL filters - * - * Locks required: None - * Returns: 0, ENOSYS +/* MC_CMD_WOL_FILTER_REMOVE_OUT msgresponse */ +#define MC_CMD_WOL_FILTER_REMOVE_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_WOL_FILTER_RESET + * Reset (i.e. remove all) WoL filters. */ #define MC_CMD_WOL_FILTER_RESET 0x34 -#define MC_CMD_WOL_FILTER_RESET_IN_LEN 0 -#define MC_CMD_WOL_FILTER_RESET_OUT_LEN 0 -/* MC_CMD_SET_MCAST_HASH: - * Set the MCASH hash value without otherwise - * reconfiguring the MAC +/* MC_CMD_WOL_FILTER_RESET_IN msgrequest */ +#define MC_CMD_WOL_FILTER_RESET_IN_LEN 4 +#define MC_CMD_WOL_FILTER_RESET_IN_MASK_OFST 0 +#define MC_CMD_WOL_FILTER_RESET_IN_WAKE_FILTERS 0x1 /* enum */ +#define MC_CMD_WOL_FILTER_RESET_IN_LIGHTSOUT_OFFLOADS 0x2 /* enum */ + +/* MC_CMD_WOL_FILTER_RESET_OUT msgresponse */ +#define MC_CMD_WOL_FILTER_RESET_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_SET_MCAST_HASH + * Set the MCASH hash value. */ #define MC_CMD_SET_MCAST_HASH 0x35 -#define MC_CMD_SET_MCAST_HASH_IN_LEN 32 -#define MC_CMD_SET_MCAST_HASH_IN_HASH0_OFST 0 -#define MC_CMD_SET_MCAST_HASH_IN_HASH1_OFST 16 -#define MC_CMD_SET_MCAST_HASH_OUT_LEN 0 -/* MC_CMD_NVRAM_TYPES: - * Return bitfield indicating available types of virtual NVRAM partitions - * - * Locks required: none - * Returns: 0 +/* MC_CMD_SET_MCAST_HASH_IN msgrequest */ +#define MC_CMD_SET_MCAST_HASH_IN_LEN 32 +#define MC_CMD_SET_MCAST_HASH_IN_HASH0_OFST 0 +#define MC_CMD_SET_MCAST_HASH_IN_HASH0_LEN 16 +#define MC_CMD_SET_MCAST_HASH_IN_HASH1_OFST 16 +#define MC_CMD_SET_MCAST_HASH_IN_HASH1_LEN 16 + +/* MC_CMD_SET_MCAST_HASH_OUT msgresponse */ +#define MC_CMD_SET_MCAST_HASH_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_NVRAM_TYPES + * Get virtual NVRAM partitions information. */ #define MC_CMD_NVRAM_TYPES 0x36 -#define MC_CMD_NVRAM_TYPES_IN_LEN 0 -#define MC_CMD_NVRAM_TYPES_OUT_LEN 4 -#define MC_CMD_NVRAM_TYPES_OUT_TYPES_OFST 0 - -/* Supported NVRAM types */ -#define MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO 0 -#define MC_CMD_NVRAM_TYPE_MC_FW 1 -#define MC_CMD_NVRAM_TYPE_MC_FW_BACKUP 2 -#define MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT0 3 -#define MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT1 4 -#define MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT0 5 -#define MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT1 6 -#define MC_CMD_NVRAM_TYPE_EXP_ROM 7 -#define MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT0 8 -#define MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT1 9 -#define MC_CMD_NVRAM_TYPE_PHY_PORT0 10 -#define MC_CMD_NVRAM_TYPE_PHY_PORT1 11 -#define MC_CMD_NVRAM_TYPE_LOG 12 - -/* MC_CMD_NVRAM_INFO: - * Read info about a virtual NVRAM partition - * - * Locks required: none - * Returns: 0, EINVAL (bad type) + +/* MC_CMD_NVRAM_TYPES_IN msgrequest */ +#define MC_CMD_NVRAM_TYPES_IN_LEN 0 + +/* MC_CMD_NVRAM_TYPES_OUT msgresponse */ +#define MC_CMD_NVRAM_TYPES_OUT_LEN 4 +#define MC_CMD_NVRAM_TYPES_OUT_TYPES_OFST 0 +#define MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO 0x0 /* enum */ +#define MC_CMD_NVRAM_TYPE_MC_FW 0x1 /* enum */ +#define MC_CMD_NVRAM_TYPE_MC_FW_BACKUP 0x2 /* enum */ +#define MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT0 0x3 /* enum */ +#define MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT1 0x4 /* enum */ +#define MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT0 0x5 /* enum */ +#define MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT1 0x6 /* enum */ +#define MC_CMD_NVRAM_TYPE_EXP_ROM 0x7 /* enum */ +#define MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT0 0x8 /* enum */ +#define MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT1 0x9 /* enum */ +#define MC_CMD_NVRAM_TYPE_PHY_PORT0 0xa /* enum */ +#define MC_CMD_NVRAM_TYPE_PHY_PORT1 0xb /* enum */ +#define MC_CMD_NVRAM_TYPE_LOG 0xc /* enum */ +#define MC_CMD_NVRAM_TYPE_FPGA 0xd /* enum */ + + +/***********************************/ +/* MC_CMD_NVRAM_INFO + * Read info about a virtual NVRAM partition. */ #define MC_CMD_NVRAM_INFO 0x37 -#define MC_CMD_NVRAM_INFO_IN_LEN 4 -#define MC_CMD_NVRAM_INFO_IN_TYPE_OFST 0 -#define MC_CMD_NVRAM_INFO_OUT_LEN 24 -#define MC_CMD_NVRAM_INFO_OUT_TYPE_OFST 0 -#define MC_CMD_NVRAM_INFO_OUT_SIZE_OFST 4 -#define MC_CMD_NVRAM_INFO_OUT_ERASESIZE_OFST 8 -#define MC_CMD_NVRAM_INFO_OUT_FLAGS_OFST 12 -#define MC_CMD_NVRAM_PROTECTED_LBN 0 -#define MC_CMD_NVRAM_PROTECTED_WIDTH 1 -#define MC_CMD_NVRAM_INFO_OUT_PHYSDEV_OFST 16 -#define MC_CMD_NVRAM_INFO_OUT_PHYSADDR_OFST 20 - -/* MC_CMD_NVRAM_UPDATE_START: - * Start a group of update operations on a virtual NVRAM partition - * - * Locks required: PHY_LOCK if type==*PHY* - * Returns: 0, EINVAL (bad type), EACCES (if PHY_LOCK required and not held) + +/* MC_CMD_NVRAM_INFO_IN msgrequest */ +#define MC_CMD_NVRAM_INFO_IN_LEN 4 +#define MC_CMD_NVRAM_INFO_IN_TYPE_OFST 0 +/* Enum values, see field(s): */ +/* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ + +/* MC_CMD_NVRAM_INFO_OUT msgresponse */ +#define MC_CMD_NVRAM_INFO_OUT_LEN 24 +#define MC_CMD_NVRAM_INFO_OUT_TYPE_OFST 0 +/* Enum values, see field(s): */ +/* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ +#define MC_CMD_NVRAM_INFO_OUT_SIZE_OFST 4 +#define MC_CMD_NVRAM_INFO_OUT_ERASESIZE_OFST 8 +#define MC_CMD_NVRAM_INFO_OUT_FLAGS_OFST 12 +#define MC_CMD_NVRAM_INFO_OUT_PROTECTED_LBN 0 +#define MC_CMD_NVRAM_INFO_OUT_PROTECTED_WIDTH 1 +#define MC_CMD_NVRAM_INFO_OUT_PHYSDEV_OFST 16 +#define MC_CMD_NVRAM_INFO_OUT_PHYSADDR_OFST 20 + + +/***********************************/ +/* MC_CMD_NVRAM_UPDATE_START + * Start a group of update operations on a virtual NVRAM partition. */ #define MC_CMD_NVRAM_UPDATE_START 0x38 -#define MC_CMD_NVRAM_UPDATE_START_IN_LEN 4 -#define MC_CMD_NVRAM_UPDATE_START_IN_TYPE_OFST 0 -#define MC_CMD_NVRAM_UPDATE_START_OUT_LEN 0 -/* MC_CMD_NVRAM_READ: - * Read data from a virtual NVRAM partition - * - * Locks required: PHY_LOCK if type==*PHY* - * Returns: 0, EINVAL (bad type/offset/length), EACCES (if PHY_LOCK required and not held) +/* MC_CMD_NVRAM_UPDATE_START_IN msgrequest */ +#define MC_CMD_NVRAM_UPDATE_START_IN_LEN 4 +#define MC_CMD_NVRAM_UPDATE_START_IN_TYPE_OFST 0 +/* Enum values, see field(s): */ +/* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ + +/* MC_CMD_NVRAM_UPDATE_START_OUT msgresponse */ +#define MC_CMD_NVRAM_UPDATE_START_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_NVRAM_READ + * Read data from a virtual NVRAM partition. */ #define MC_CMD_NVRAM_READ 0x39 -#define MC_CMD_NVRAM_READ_IN_LEN 12 -#define MC_CMD_NVRAM_READ_IN_TYPE_OFST 0 -#define MC_CMD_NVRAM_READ_IN_OFFSET_OFST 4 -#define MC_CMD_NVRAM_READ_IN_LENGTH_OFST 8 -#define MC_CMD_NVRAM_READ_OUT_LEN(_read_bytes) (_read_bytes) -#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_OFST 0 - -/* MC_CMD_NVRAM_WRITE: - * Write data to a virtual NVRAM partition - * - * Locks required: PHY_LOCK if type==*PHY* - * Returns: 0, EINVAL (bad type/offset/length), EACCES (if PHY_LOCK required and not held) + +/* MC_CMD_NVRAM_READ_IN msgrequest */ +#define MC_CMD_NVRAM_READ_IN_LEN 12 +#define MC_CMD_NVRAM_READ_IN_TYPE_OFST 0 +/* Enum values, see field(s): */ +/* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ +#define MC_CMD_NVRAM_READ_IN_OFFSET_OFST 4 +#define MC_CMD_NVRAM_READ_IN_LENGTH_OFST 8 + +/* MC_CMD_NVRAM_READ_OUT msgresponse */ +#define MC_CMD_NVRAM_READ_OUT_LENMIN 1 +#define MC_CMD_NVRAM_READ_OUT_LENMAX 255 +#define MC_CMD_NVRAM_READ_OUT_LEN(num) (0+1*(num)) +#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_OFST 0 +#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_LEN 1 +#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_MINNUM 1 +#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_MAXNUM 255 + + +/***********************************/ +/* MC_CMD_NVRAM_WRITE + * Write data to a virtual NVRAM partition. */ #define MC_CMD_NVRAM_WRITE 0x3a -#define MC_CMD_NVRAM_WRITE_IN_TYPE_OFST 0 -#define MC_CMD_NVRAM_WRITE_IN_OFFSET_OFST 4 -#define MC_CMD_NVRAM_WRITE_IN_LENGTH_OFST 8 -#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_OFST 12 -#define MC_CMD_NVRAM_WRITE_IN_LEN(_write_bytes) (12 + _write_bytes) -#define MC_CMD_NVRAM_WRITE_OUT_LEN 0 - -/* MC_CMD_NVRAM_ERASE: - * Erase sector(s) from a virtual NVRAM partition - * - * Locks required: PHY_LOCK if type==*PHY* - * Returns: 0, EINVAL (bad type/offset/length), EACCES (if PHY_LOCK required and not held) + +/* MC_CMD_NVRAM_WRITE_IN msgrequest */ +#define MC_CMD_NVRAM_WRITE_IN_LENMIN 13 +#define MC_CMD_NVRAM_WRITE_IN_LENMAX 255 +#define MC_CMD_NVRAM_WRITE_IN_LEN(num) (12+1*(num)) +#define MC_CMD_NVRAM_WRITE_IN_TYPE_OFST 0 +/* Enum values, see field(s): */ +/* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ +#define MC_CMD_NVRAM_WRITE_IN_OFFSET_OFST 4 +#define MC_CMD_NVRAM_WRITE_IN_LENGTH_OFST 8 +#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_OFST 12 +#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_LEN 1 +#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_MINNUM 1 +#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_MAXNUM 243 + +/* MC_CMD_NVRAM_WRITE_OUT msgresponse */ +#define MC_CMD_NVRAM_WRITE_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_NVRAM_ERASE + * Erase sector(s) from a virtual NVRAM partition. */ #define MC_CMD_NVRAM_ERASE 0x3b -#define MC_CMD_NVRAM_ERASE_IN_LEN 12 -#define MC_CMD_NVRAM_ERASE_IN_TYPE_OFST 0 -#define MC_CMD_NVRAM_ERASE_IN_OFFSET_OFST 4 -#define MC_CMD_NVRAM_ERASE_IN_LENGTH_OFST 8 -#define MC_CMD_NVRAM_ERASE_OUT_LEN 0 - -/* MC_CMD_NVRAM_UPDATE_FINISH: - * Finish a group of update operations on a virtual NVRAM partition - * - * Locks required: PHY_LOCK if type==*PHY* - * Returns: 0, EINVAL (bad type/offset/length), EACCES (if PHY_LOCK required and not held) + +/* MC_CMD_NVRAM_ERASE_IN msgrequest */ +#define MC_CMD_NVRAM_ERASE_IN_LEN 12 +#define MC_CMD_NVRAM_ERASE_IN_TYPE_OFST 0 +/* Enum values, see field(s): */ +/* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ +#define MC_CMD_NVRAM_ERASE_IN_OFFSET_OFST 4 +#define MC_CMD_NVRAM_ERASE_IN_LENGTH_OFST 8 + +/* MC_CMD_NVRAM_ERASE_OUT msgresponse */ +#define MC_CMD_NVRAM_ERASE_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_NVRAM_UPDATE_FINISH + * Finish a group of update operations on a virtual NVRAM partition. */ #define MC_CMD_NVRAM_UPDATE_FINISH 0x3c -#define MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN 8 -#define MC_CMD_NVRAM_UPDATE_FINISH_IN_TYPE_OFST 0 -#define MC_CMD_NVRAM_UPDATE_FINISH_IN_REBOOT_OFST 4 -#define MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN 0 -/* MC_CMD_REBOOT: +/* MC_CMD_NVRAM_UPDATE_FINISH_IN msgrequest */ +#define MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN 8 +#define MC_CMD_NVRAM_UPDATE_FINISH_IN_TYPE_OFST 0 +/* Enum values, see field(s): */ +/* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ +#define MC_CMD_NVRAM_UPDATE_FINISH_IN_REBOOT_OFST 4 + +/* MC_CMD_NVRAM_UPDATE_FINISH_OUT msgresponse */ +#define MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_REBOOT * Reboot the MC. - * - * The AFTER_ASSERTION flag is intended to be used when the driver notices - * an assertion failure (at which point it is expected to perform a complete - * tear down and reinitialise), to allow both ports to reset the MC once - * in an atomic fashion. - * - * Production mc firmwares are generally compiled with REBOOT_ON_ASSERT=1, - * which means that they will automatically reboot out of the assertion - * handler, so this is in practise an optional operation. It is still - * recommended that drivers execute this to support custom firmwares - * with REBOOT_ON_ASSERT=0. - * - * Locks required: NONE - * Returns: Nothing. You get back a response with ERR=1, DATALEN=0 */ #define MC_CMD_REBOOT 0x3d -#define MC_CMD_REBOOT_IN_LEN 4 -#define MC_CMD_REBOOT_IN_FLAGS_OFST 0 -#define MC_CMD_REBOOT_FLAGS_AFTER_ASSERTION 1 -#define MC_CMD_REBOOT_OUT_LEN 0 -/* MC_CMD_SCHEDINFO: - * Request scheduler info. from the MC. - * - * Locks required: NONE - * Returns: An array of (timeslice,maximum overrun), one for each thread, - * in ascending order of thread address.s +/* MC_CMD_REBOOT_IN msgrequest */ +#define MC_CMD_REBOOT_IN_LEN 4 +#define MC_CMD_REBOOT_IN_FLAGS_OFST 0 +#define MC_CMD_REBOOT_FLAGS_AFTER_ASSERTION 0x1 /* enum */ + +/* MC_CMD_REBOOT_OUT msgresponse */ +#define MC_CMD_REBOOT_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_SCHEDINFO + * Request scheduler info. */ #define MC_CMD_SCHEDINFO 0x3e -#define MC_CMD_SCHEDINFO_IN_LEN 0 +/* MC_CMD_SCHEDINFO_IN msgrequest */ +#define MC_CMD_SCHEDINFO_IN_LEN 0 -/* MC_CMD_SET_REBOOT_MODE: (debug) - * Set the mode for the next MC reboot. - * - * Locks required: NONE - * - * Sets the reboot mode to the specified value. Returns the old mode. +/* MC_CMD_SCHEDINFO_OUT msgresponse */ +#define MC_CMD_SCHEDINFO_OUT_LENMIN 4 +#define MC_CMD_SCHEDINFO_OUT_LENMAX 252 +#define MC_CMD_SCHEDINFO_OUT_LEN(num) (0+4*(num)) +#define MC_CMD_SCHEDINFO_OUT_DATA_OFST 0 +#define MC_CMD_SCHEDINFO_OUT_DATA_LEN 4 +#define MC_CMD_SCHEDINFO_OUT_DATA_MINNUM 1 +#define MC_CMD_SCHEDINFO_OUT_DATA_MAXNUM 63 + + +/***********************************/ +/* MC_CMD_REBOOT_MODE */ #define MC_CMD_REBOOT_MODE 0x3f -#define MC_CMD_REBOOT_MODE_IN_LEN 4 -#define MC_CMD_REBOOT_MODE_IN_VALUE_OFST 0 -#define MC_CMD_REBOOT_MODE_OUT_LEN 4 -#define MC_CMD_REBOOT_MODE_OUT_VALUE_OFST 0 -#define MC_CMD_REBOOT_MODE_NORMAL 0 -#define MC_CMD_REBOOT_MODE_SNAPPER 3 - -/* MC_CMD_DEBUG_LOG: - * Null request/response command (debug) - * - sequence number is always zero - * - only supported on the UART interface - * (the same set of bytes is delivered as an - * event over PCI) - */ -#define MC_CMD_DEBUG_LOG 0x40 -#define MC_CMD_DEBUG_LOG_IN_LEN 0 -#define MC_CMD_DEBUG_LOG_OUT_LEN 0 - -/* Generic sensor enumeration. Note that a dual port NIC - * will EITHER expose PHY_COMMON_TEMP OR PHY0_TEMP and - * PHY1_TEMP depending on whether there is a single sensor - * in the vicinity of the two port, or one per port. - */ -#define MC_CMD_SENSOR_CONTROLLER_TEMP 0 /* degC */ -#define MC_CMD_SENSOR_PHY_COMMON_TEMP 1 /* degC */ -#define MC_CMD_SENSOR_CONTROLLER_COOLING 2 /* bool */ -#define MC_CMD_SENSOR_PHY0_TEMP 3 /* degC */ -#define MC_CMD_SENSOR_PHY0_COOLING 4 /* bool */ -#define MC_CMD_SENSOR_PHY1_TEMP 5 /* degC */ -#define MC_CMD_SENSOR_PHY1_COOLING 6 /* bool */ -#define MC_CMD_SENSOR_IN_1V0 7 /* mV */ -#define MC_CMD_SENSOR_IN_1V2 8 /* mV */ -#define MC_CMD_SENSOR_IN_1V8 9 /* mV */ -#define MC_CMD_SENSOR_IN_2V5 10 /* mV */ -#define MC_CMD_SENSOR_IN_3V3 11 /* mV */ -#define MC_CMD_SENSOR_IN_12V0 12 /* mV */ - - -/* Sensor state */ -#define MC_CMD_SENSOR_STATE_OK 0 -#define MC_CMD_SENSOR_STATE_WARNING 1 -#define MC_CMD_SENSOR_STATE_FATAL 2 -#define MC_CMD_SENSOR_STATE_BROKEN 3 - -/* MC_CMD_SENSOR_INFO: + +/* MC_CMD_REBOOT_MODE_IN msgrequest */ +#define MC_CMD_REBOOT_MODE_IN_LEN 4 +#define MC_CMD_REBOOT_MODE_IN_VALUE_OFST 0 +#define MC_CMD_REBOOT_MODE_NORMAL 0x0 /* enum */ +#define MC_CMD_REBOOT_MODE_SNAPPER 0x3 /* enum */ + +/* MC_CMD_REBOOT_MODE_OUT msgresponse */ +#define MC_CMD_REBOOT_MODE_OUT_LEN 4 +#define MC_CMD_REBOOT_MODE_OUT_VALUE_OFST 0 + + +/***********************************/ +/* MC_CMD_SENSOR_INFO * Returns information about every available sensor. - * - * Each sensor has a single (16bit) value, and a corresponding state. - * The mapping between value and sensor is nominally determined by the - * MC, but in practise is implemented as zero (BROKEN), one (TEMPERATURE), - * or two (VOLTAGE) ranges per sensor per state. - * - * This call returns a mask (32bit) of the sensors that are supported - * by this platform, then an array (indexed by MC_CMD_SENSOR) of byte - * offsets to the per-sensor arrays. Each sensor array has four 16bit - * numbers, min1, max1, min2, max2. - * - * Locks required: None - * Returns: 0 */ #define MC_CMD_SENSOR_INFO 0x41 -#define MC_CMD_SENSOR_INFO_IN_LEN 0 -#define MC_CMD_SENSOR_INFO_OUT_MASK_OFST 0 -#define MC_CMD_SENSOR_INFO_OUT_OFFSET_OFST(_x) \ - (4 + (_x)) -#define MC_CMD_SENSOR_INFO_OUT_MIN1_OFST(_ofst) \ - ((_ofst) + 0) -#define MC_CMD_SENSOR_INFO_OUT_MAX1_OFST(_ofst) \ - ((_ofst) + 2) -#define MC_CMD_SENSOR_INFO_OUT_MIN2_OFST(_ofst) \ - ((_ofst) + 4) -#define MC_CMD_SENSOR_INFO_OUT_MAX2_OFST(_ofst) \ - ((_ofst) + 6) +/* MC_CMD_SENSOR_INFO_IN msgrequest */ +#define MC_CMD_SENSOR_INFO_IN_LEN 0 + +/* MC_CMD_SENSOR_INFO_OUT msgresponse */ +#define MC_CMD_SENSOR_INFO_OUT_LENMIN 12 +#define MC_CMD_SENSOR_INFO_OUT_LENMAX 252 +#define MC_CMD_SENSOR_INFO_OUT_LEN(num) (4+8*(num)) +#define MC_CMD_SENSOR_INFO_OUT_MASK_OFST 0 +#define MC_CMD_SENSOR_CONTROLLER_TEMP 0x0 /* enum */ +#define MC_CMD_SENSOR_PHY_COMMON_TEMP 0x1 /* enum */ +#define MC_CMD_SENSOR_CONTROLLER_COOLING 0x2 /* enum */ +#define MC_CMD_SENSOR_PHY0_TEMP 0x3 /* enum */ +#define MC_CMD_SENSOR_PHY0_COOLING 0x4 /* enum */ +#define MC_CMD_SENSOR_PHY1_TEMP 0x5 /* enum */ +#define MC_CMD_SENSOR_PHY1_COOLING 0x6 /* enum */ +#define MC_CMD_SENSOR_IN_1V0 0x7 /* enum */ +#define MC_CMD_SENSOR_IN_1V2 0x8 /* enum */ +#define MC_CMD_SENSOR_IN_1V8 0x9 /* enum */ +#define MC_CMD_SENSOR_IN_2V5 0xa /* enum */ +#define MC_CMD_SENSOR_IN_3V3 0xb /* enum */ +#define MC_CMD_SENSOR_IN_12V0 0xc /* enum */ +#define MC_CMD_SENSOR_IN_1V2A 0xd /* enum */ +#define MC_CMD_SENSOR_IN_VREF 0xe /* enum */ +#define MC_CMD_SENSOR_ENTRY_OFST 4 +#define MC_CMD_SENSOR_ENTRY_LEN 8 +#define MC_CMD_SENSOR_ENTRY_LO_OFST 4 +#define MC_CMD_SENSOR_ENTRY_HI_OFST 8 +#define MC_CMD_SENSOR_ENTRY_MINNUM 1 +#define MC_CMD_SENSOR_ENTRY_MAXNUM 31 + +/* MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF structuredef */ +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_LEN 8 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN1_OFST 0 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN1_LEN 2 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN1_LBN 0 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN1_WIDTH 16 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX1_OFST 2 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX1_LEN 2 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX1_LBN 16 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX1_WIDTH 16 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN2_OFST 4 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN2_LEN 2 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN2_LBN 32 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN2_WIDTH 16 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX2_OFST 6 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX2_LEN 2 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX2_LBN 48 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX2_WIDTH 16 + + +/***********************************/ /* MC_CMD_READ_SENSORS - * Returns the current reading from each sensor - * - * Returns a sparse array of sensor readings (indexed by the sensor - * type) into host memory. Each array element is a dword. - * - * The MC will send a SENSOREVT event every time any sensor changes state. The - * driver is responsible for ensuring that it doesn't miss any events. The board - * will function normally if all sensors are in STATE_OK or state_WARNING. - * Otherwise the board should not be expected to function. + * Returns the current reading from each sensor. */ #define MC_CMD_READ_SENSORS 0x42 -#define MC_CMD_READ_SENSORS_IN_LEN 8 -#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_LO_OFST 0 -#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_HI_OFST 4 -#define MC_CMD_READ_SENSORS_OUT_LEN 0 -/* Sensor reading fields */ -#define MC_CMD_READ_SENSOR_VALUE_LBN 0 -#define MC_CMD_READ_SENSOR_VALUE_WIDTH 16 -#define MC_CMD_READ_SENSOR_STATE_LBN 16 -#define MC_CMD_READ_SENSOR_STATE_WIDTH 8 - - -/* MC_CMD_GET_PHY_STATE: - * Report current state of PHY. A "zombie" PHY is a PHY that has failed to - * boot (e.g. due to missing or corrupted firmware). - * - * Locks required: None - * Return code: 0 +/* MC_CMD_READ_SENSORS_IN msgrequest */ +#define MC_CMD_READ_SENSORS_IN_LEN 8 +#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_OFST 0 +#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_LEN 8 +#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_LO_OFST 0 +#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_HI_OFST 4 + +/* MC_CMD_READ_SENSORS_OUT msgresponse */ +#define MC_CMD_READ_SENSORS_OUT_LEN 0 + +/* MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF structuredef */ +#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_LEN 3 +#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE_OFST 0 +#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE_LEN 2 +#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE_LBN 0 +#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE_WIDTH 16 +#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_OFST 2 +#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_LEN 1 +#define MC_CMD_SENSOR_STATE_OK 0x0 /* enum */ +#define MC_CMD_SENSOR_STATE_WARNING 0x1 /* enum */ +#define MC_CMD_SENSOR_STATE_FATAL 0x2 /* enum */ +#define MC_CMD_SENSOR_STATE_BROKEN 0x3 /* enum */ +#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_LBN 16 +#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_WIDTH 8 + + +/***********************************/ +/* MC_CMD_GET_PHY_STATE + * Report current state of PHY. */ #define MC_CMD_GET_PHY_STATE 0x43 -#define MC_CMD_GET_PHY_STATE_IN_LEN 0 -#define MC_CMD_GET_PHY_STATE_OUT_LEN 4 -#define MC_CMD_GET_PHY_STATE_STATE_OFST 0 -/* PHY state enumeration: */ -#define MC_CMD_PHY_STATE_OK 1 -#define MC_CMD_PHY_STATE_ZOMBIE 2 +/* MC_CMD_GET_PHY_STATE_IN msgrequest */ +#define MC_CMD_GET_PHY_STATE_IN_LEN 0 +/* MC_CMD_GET_PHY_STATE_OUT msgresponse */ +#define MC_CMD_GET_PHY_STATE_OUT_LEN 4 +#define MC_CMD_GET_PHY_STATE_OUT_STATE_OFST 0 +#define MC_CMD_PHY_STATE_OK 0x1 /* enum */ +#define MC_CMD_PHY_STATE_ZOMBIE 0x2 /* enum */ -/* 802.1Qbb control. 8 Tx queues that map to priorities 0 - 7. Use all 1s to - * disable 802.Qbb for a given priority. */ + +/***********************************/ +/* MC_CMD_SETUP_8021QBB + * 802.1Qbb control. + */ #define MC_CMD_SETUP_8021QBB 0x44 -#define MC_CMD_SETUP_8021QBB_IN_LEN 32 -#define MC_CMD_SETUP_8021QBB_OUT_LEN 0 -#define MC_CMD_SETUP_8021QBB_IN_TXQS_OFFST 0 +/* MC_CMD_SETUP_8021QBB_IN msgrequest */ +#define MC_CMD_SETUP_8021QBB_IN_LEN 32 +#define MC_CMD_SETUP_8021QBB_IN_TXQS_OFST 0 +#define MC_CMD_SETUP_8021QBB_IN_TXQS_LEN 32 -/* MC_CMD_WOL_FILTER_GET: - * Retrieve ID of any WoL filters - * - * Locks required: None - * Returns: 0, ENOSYS - */ -#define MC_CMD_WOL_FILTER_GET 0x45 -#define MC_CMD_WOL_FILTER_GET_IN_LEN 0 -#define MC_CMD_WOL_FILTER_GET_OUT_LEN 4 -#define MC_CMD_WOL_FILTER_GET_OUT_FILTER_ID_OFST 0 +/* MC_CMD_SETUP_8021QBB_OUT msgresponse */ +#define MC_CMD_SETUP_8021QBB_OUT_LEN 0 -/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD: - * Offload a protocol to NIC for lights-out state - * - * Locks required: None - * Returns: 0, ENOSYS +/***********************************/ +/* MC_CMD_WOL_FILTER_GET + * Retrieve ID of any WoL filters. */ -#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD 0x46 +#define MC_CMD_WOL_FILTER_GET 0x45 -#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_LEN 16 -#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0 +/* MC_CMD_WOL_FILTER_GET_IN msgrequest */ +#define MC_CMD_WOL_FILTER_GET_IN_LEN 0 -/* There is a union at offset 4, following defines overlap due to - * this */ -#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_OFST 4 -#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARPMAC_OFST 4 -#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARPIP_OFST 10 -#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NSMAC_OFST 4 -#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NSSNIPV6_OFST 10 -#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NSIPV6_OFST 26 +/* MC_CMD_WOL_FILTER_GET_OUT msgresponse */ +#define MC_CMD_WOL_FILTER_GET_OUT_LEN 4 +#define MC_CMD_WOL_FILTER_GET_OUT_FILTER_ID_OFST 0 -#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN 4 -#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_FILTER_ID_OFST 0 +/***********************************/ +/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD + * Add a protocol offload to NIC for lights-out state. + */ +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD 0x46 -/* MC_CMD_REMOVE_LIGHTSOUT_PROTOCOL_OFFLOAD: - * Offload a protocol to NIC for lights-out state - * - * Locks required: None - * Returns: 0, ENOSYS +/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN msgrequest */ +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_LENMIN 8 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_LENMAX 252 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_LEN(num) (4+4*(num)) +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0 +#define MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_ARP 0x1 /* enum */ +#define MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS 0x2 /* enum */ +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_OFST 4 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_LEN 4 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_MINNUM 1 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_MAXNUM 62 + +/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP msgrequest */ +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_LEN 14 +/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0 */ +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_MAC_OFST 4 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_MAC_LEN 6 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_IP_OFST 10 + +/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS msgrequest */ +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_LEN 42 +/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0 */ +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_MAC_OFST 4 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_MAC_LEN 6 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_SNIPV6_OFST 10 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_SNIPV6_LEN 16 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_IPV6_OFST 26 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_IPV6_LEN 16 + +/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT msgresponse */ +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN 4 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_FILTER_ID_OFST 0 + + +/***********************************/ +/* MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD + * Remove a protocol offload from NIC for lights-out state. */ #define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD 0x47 -#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN 8 -#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT_LEN 0 -#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0 -#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_FILTER_ID_OFST 4 +/* MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN msgrequest */ +#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN 8 +#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0 +#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_FILTER_ID_OFST 4 -/* Lights-out offload protocols enumeration */ -#define MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_ARP 0x1 -#define MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS 0x2 +/* MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT msgresponse */ +#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT_LEN 0 -/* MC_CMD_MAC_RESET_RESTORE: - * Restore MAC after block reset - * - * Locks required: None - * Returns: 0 +/***********************************/ +/* MC_CMD_MAC_RESET_RESTORE + * Restore MAC after block reset. */ - #define MC_CMD_MAC_RESET_RESTORE 0x48 -#define MC_CMD_MAC_RESET_RESTORE_IN_LEN 0 -#define MC_CMD_MAC_RESET_RESTORE_OUT_LEN 0 +/* MC_CMD_MAC_RESET_RESTORE_IN msgrequest */ +#define MC_CMD_MAC_RESET_RESTORE_IN_LEN 0 + +/* MC_CMD_MAC_RESET_RESTORE_OUT msgresponse */ +#define MC_CMD_MAC_RESET_RESTORE_OUT_LEN 0 -/* MC_CMD_TEST_ASSERT: - * Deliberately trigger an assert-detonation in the firmware for testing - * purposes (i.e. to allow tests that the driver copes gracefully). - * - * Locks required: None - * Returns: 0 - */ +/***********************************/ +/* MC_CMD_TESTASSERT + */ #define MC_CMD_TESTASSERT 0x49 -#define MC_CMD_TESTASSERT_IN_LEN 0 -#define MC_CMD_TESTASSERT_OUT_LEN 0 -/* MC_CMD_WORKAROUND 0x4a - * - * Enable/Disable a given workaround. The mcfw will return EINVAL if it - * doesn't understand the given workaround number - which should not - * be treated as a hard error by client code. - * - * This op does not imply any semantics about each workaround, that's between - * the driver and the mcfw on a per-workaround basis. - * - * Locks required: None - * Returns: 0, EINVAL +/* MC_CMD_TESTASSERT_IN msgrequest */ +#define MC_CMD_TESTASSERT_IN_LEN 0 + +/* MC_CMD_TESTASSERT_OUT msgresponse */ +#define MC_CMD_TESTASSERT_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_WORKAROUND + * Enable/Disable a given workaround. */ #define MC_CMD_WORKAROUND 0x4a -#define MC_CMD_WORKAROUND_IN_LEN 8 -#define MC_CMD_WORKAROUND_IN_TYPE_OFST 0 -#define MC_CMD_WORKAROUND_BUG17230 1 -#define MC_CMD_WORKAROUND_IN_ENABLED_OFST 4 -#define MC_CMD_WORKAROUND_OUT_LEN 0 - -/* MC_CMD_GET_PHY_MEDIA_INFO: - * Read media-specific data from PHY (e.g. SFP/SFP+ module ID information for - * SFP+ PHYs). - * - * The "media type" can be found via GET_PHY_CFG (GET_PHY_CFG_OUT_MEDIA_TYPE); - * the valid "page number" input values, and the output data, are interpreted - * on a per-type basis. - * - * For SFP+: PAGE=0 or 1 returns a 128-byte block read from module I2C address - * 0xA0 offset 0 or 0x80. - * Anything else: currently undefined. - * - * Locks required: None - * Return code: 0 + +/* MC_CMD_WORKAROUND_IN msgrequest */ +#define MC_CMD_WORKAROUND_IN_LEN 8 +#define MC_CMD_WORKAROUND_IN_TYPE_OFST 0 +#define MC_CMD_WORKAROUND_BUG17230 0x1 /* enum */ +#define MC_CMD_WORKAROUND_IN_ENABLED_OFST 4 + +/* MC_CMD_WORKAROUND_OUT msgresponse */ +#define MC_CMD_WORKAROUND_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_GET_PHY_MEDIA_INFO + * Read media-specific data from PHY. */ #define MC_CMD_GET_PHY_MEDIA_INFO 0x4b -#define MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN 4 -#define MC_CMD_GET_PHY_MEDIA_INFO_IN_PAGE_OFST 0 -#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LEN(_num_bytes) (4 + (_num_bytes)) -#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATALEN_OFST 0 -#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_OFST 4 - -/* MC_CMD_NVRAM_TEST: - * Test a particular NVRAM partition for valid contents (where "valid" - * depends on the type of partition). - * - * Locks required: None - * Return code: 0 + +/* MC_CMD_GET_PHY_MEDIA_INFO_IN msgrequest */ +#define MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN 4 +#define MC_CMD_GET_PHY_MEDIA_INFO_IN_PAGE_OFST 0 + +/* MC_CMD_GET_PHY_MEDIA_INFO_OUT msgresponse */ +#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMIN 5 +#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMAX 255 +#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LEN(num) (4+1*(num)) +#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATALEN_OFST 0 +#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_OFST 4 +#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_LEN 1 +#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_MINNUM 1 +#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_MAXNUM 251 + + +/***********************************/ +/* MC_CMD_NVRAM_TEST + * Test a particular NVRAM partition. */ #define MC_CMD_NVRAM_TEST 0x4c -#define MC_CMD_NVRAM_TEST_IN_LEN 4 -#define MC_CMD_NVRAM_TEST_IN_TYPE_OFST 0 -#define MC_CMD_NVRAM_TEST_OUT_LEN 4 -#define MC_CMD_NVRAM_TEST_OUT_RESULT_OFST 0 -#define MC_CMD_NVRAM_TEST_PASS 0 -#define MC_CMD_NVRAM_TEST_FAIL 1 -#define MC_CMD_NVRAM_TEST_NOTSUPP 2 - -/* MC_CMD_MRSFP_TWEAK: (debug) - * Read status and/or set parameters for the "mrsfp" driver in mr_rusty builds. - * I2C I/O expander bits are always read; if equaliser parameters are supplied, - * they are configured first. - * - * Locks required: None - * Return code: 0, EINVAL + +/* MC_CMD_NVRAM_TEST_IN msgrequest */ +#define MC_CMD_NVRAM_TEST_IN_LEN 4 +#define MC_CMD_NVRAM_TEST_IN_TYPE_OFST 0 +/* Enum values, see field(s): */ +/* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ + +/* MC_CMD_NVRAM_TEST_OUT msgresponse */ +#define MC_CMD_NVRAM_TEST_OUT_LEN 4 +#define MC_CMD_NVRAM_TEST_OUT_RESULT_OFST 0 +#define MC_CMD_NVRAM_TEST_PASS 0x0 /* enum */ +#define MC_CMD_NVRAM_TEST_FAIL 0x1 /* enum */ +#define MC_CMD_NVRAM_TEST_NOTSUPP 0x2 /* enum */ + + +/***********************************/ +/* MC_CMD_MRSFP_TWEAK + * Read status and/or set parameters for the 'mrsfp' driver. */ #define MC_CMD_MRSFP_TWEAK 0x4d -#define MC_CMD_MRSFP_TWEAK_IN_LEN_READ_ONLY 0 -#define MC_CMD_MRSFP_TWEAK_IN_LEN_EQ_CONFIG 16 -#define MC_CMD_MRSFP_TWEAK_IN_TXEQ_LEVEL_OFST 0 /* 0-6 low->high de-emph. */ -#define MC_CMD_MRSFP_TWEAK_IN_TXEQ_DT_CFG_OFST 4 /* 0-8 low->high ref.V */ -#define MC_CMD_MRSFP_TWEAK_IN_RXEQ_BOOST_OFST 8 /* 0-8 low->high boost */ -#define MC_CMD_MRSFP_TWEAK_IN_RXEQ_DT_CFG_OFST 12 /* 0-8 low->high ref.V */ -#define MC_CMD_MRSFP_TWEAK_OUT_LEN 12 -#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_INPUTS_OFST 0 /* input bits */ -#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_OUTPUTS_OFST 4 /* output bits */ -#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_OFST 8 /* dirs: 0=out, 1=in */ - -/* MC_CMD_TEST_HACK: (debug (unsurprisingly)) - * Change bits of network port state for test purposes in ways that would never be - * useful in normal operation and so need a special command to change. */ -#define MC_CMD_TEST_HACK 0x2f -#define MC_CMD_TEST_HACK_IN_LEN 8 -#define MC_CMD_TEST_HACK_IN_TXPAD_OFST 0 -#define MC_CMD_TEST_HACK_IN_TXPAD_AUTO 0 /* Let the MC manage things */ -#define MC_CMD_TEST_HACK_IN_TXPAD_ON 1 /* Force on */ -#define MC_CMD_TEST_HACK_IN_TXPAD_OFF 2 /* Force on */ -#define MC_CMD_TEST_HACK_IN_IPG_OFST 4 /* Takes a value in bits */ -#define MC_CMD_TEST_HACK_IN_IPG_AUTO 0 /* The MC picks the value */ -#define MC_CMD_TEST_HACK_OUT_LEN 0 - -/* MC_CMD_SENSOR_SET_LIMS: (debug) (mostly) adjust the sensor limits. This - * is a warranty-voiding operation. - * - * IN: sensor identifier (one of the enumeration starting with MC_CMD_SENSOR_CONTROLLER_TEMP - * followed by 4 32-bit values: min(warning) max(warning), min(fatal), max(fatal). Which - * of these limits are meaningful and what their interpretation is is sensor-specific. - * - * OUT: nothing - * - * Returns: ENOENT if the sensor specified does not exist, EINVAL if the limits are - * out of range. + +/* MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG msgrequest */ +#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_LEN 16 +#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_TXEQ_LEVEL_OFST 0 +#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_TXEQ_DT_CFG_OFST 4 +#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_RXEQ_BOOST_OFST 8 +#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_RXEQ_DT_CFG_OFST 12 + +/* MC_CMD_MRSFP_TWEAK_IN_READ_ONLY msgrequest */ +#define MC_CMD_MRSFP_TWEAK_IN_READ_ONLY_LEN 0 + +/* MC_CMD_MRSFP_TWEAK_OUT msgresponse */ +#define MC_CMD_MRSFP_TWEAK_OUT_LEN 12 +#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_INPUTS_OFST 0 +#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_OUTPUTS_OFST 4 +#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_OFST 8 +#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_OUT 0x0 /* enum */ +#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_IN 0x1 /* enum */ + + +/***********************************/ +/* MC_CMD_SENSOR_SET_LIMS + * Adjusts the sensor limits. */ #define MC_CMD_SENSOR_SET_LIMS 0x4e -#define MC_CMD_SENSOR_SET_LIMS_IN_LEN 20 -#define MC_CMD_SENSOR_SET_LIMS_IN_SENSOR_OFST 0 -#define MC_CMD_SENSOR_SET_LIMS_IN_LOW0_OFST 4 -#define MC_CMD_SENSOR_SET_LIMS_IN_HI0_OFST 8 -#define MC_CMD_SENSOR_SET_LIMS_IN_LOW1_OFST 12 -#define MC_CMD_SENSOR_SET_LIMS_IN_HI1_OFST 16 - -/* Do NOT add new commands beyond 0x4f as part of 3.0 : 0x50 - 0x7f will be - * used for post-3.0 extensions. If you run out of space, look for gaps or - * commands that are unused in the existing range. */ + +/* MC_CMD_SENSOR_SET_LIMS_IN msgrequest */ +#define MC_CMD_SENSOR_SET_LIMS_IN_LEN 20 +#define MC_CMD_SENSOR_SET_LIMS_IN_SENSOR_OFST 0 +/* Enum values, see field(s): */ +/* MC_CMD_SENSOR_INFO/MC_CMD_SENSOR_INFO_OUT/MASK */ +#define MC_CMD_SENSOR_SET_LIMS_IN_LOW0_OFST 4 +#define MC_CMD_SENSOR_SET_LIMS_IN_HI0_OFST 8 +#define MC_CMD_SENSOR_SET_LIMS_IN_LOW1_OFST 12 +#define MC_CMD_SENSOR_SET_LIMS_IN_HI1_OFST 16 + +/* MC_CMD_SENSOR_SET_LIMS_OUT msgresponse */ +#define MC_CMD_SENSOR_SET_LIMS_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_GET_RESOURCE_LIMITS + */ +#define MC_CMD_GET_RESOURCE_LIMITS 0x4f + +/* MC_CMD_GET_RESOURCE_LIMITS_IN msgrequest */ +#define MC_CMD_GET_RESOURCE_LIMITS_IN_LEN 0 + +/* MC_CMD_GET_RESOURCE_LIMITS_OUT msgresponse */ +#define MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN 16 +#define MC_CMD_GET_RESOURCE_LIMITS_OUT_BUFTBL_OFST 0 +#define MC_CMD_GET_RESOURCE_LIMITS_OUT_EVQ_OFST 4 +#define MC_CMD_GET_RESOURCE_LIMITS_OUT_RXQ_OFST 8 +#define MC_CMD_GET_RESOURCE_LIMITS_OUT_TXQ_OFST 12 + +/* MC_CMD_RESOURCE_SPECIFIER enum */ +#define MC_CMD_RESOURCE_INSTANCE_ANY 0xffffffff /* enum */ +#define MC_CMD_RESOURCE_INSTANCE_NONE 0xfffffffe /* enum */ + #endif /* MCDI_PCOL_H */ diff --git a/drivers/net/ethernet/sfc/mcdi_phy.c b/drivers/net/ethernet/sfc/mcdi_phy.c index 3077bf1e7df..7bcad899a93 100644 --- a/drivers/net/ethernet/sfc/mcdi_phy.c +++ b/drivers/net/ethernet/sfc/mcdi_phy.c @@ -116,7 +116,7 @@ static int efx_mcdi_loopback_modes(struct efx_nic *efx, u64 *loopback_modes) goto fail; } - *loopback_modes = MCDI_QWORD(outbuf, GET_LOOPBACK_MODES_SUGGESTED); + *loopback_modes = MCDI_QWORD(outbuf, GET_LOOPBACK_MODES_OUT_SUGGESTED); return 0; @@ -264,22 +264,22 @@ static u32 efx_get_mcdi_phy_flags(struct efx_nic *efx) /* TODO: Advertise the capabilities supported by this PHY */ supported = 0; - if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_TXDIS_LBN)) + if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_TXDIS_LBN)) supported |= PHY_MODE_TX_DISABLED; - if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_LOWPOWER_LBN)) + if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_LOWPOWER_LBN)) supported |= PHY_MODE_LOW_POWER; - if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_POWEROFF_LBN)) + if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_POWEROFF_LBN)) supported |= PHY_MODE_OFF; mode = efx->phy_mode & supported; flags = 0; if (mode & PHY_MODE_TX_DISABLED) - flags |= (1 << MC_CMD_SET_LINK_TXDIS_LBN); + flags |= (1 << MC_CMD_SET_LINK_IN_TXDIS_LBN); if (mode & PHY_MODE_LOW_POWER) - flags |= (1 << MC_CMD_SET_LINK_LOWPOWER_LBN); + flags |= (1 << MC_CMD_SET_LINK_IN_LOWPOWER_LBN); if (mode & PHY_MODE_OFF) - flags |= (1 << MC_CMD_SET_LINK_POWEROFF_LBN); + flags |= (1 << MC_CMD_SET_LINK_IN_POWEROFF_LBN); return flags; } @@ -436,8 +436,8 @@ void efx_mcdi_phy_decode_link(struct efx_nic *efx, break; } - link_state->up = !!(flags & (1 << MC_CMD_GET_LINK_LINK_UP_LBN)); - link_state->fd = !!(flags & (1 << MC_CMD_GET_LINK_FULL_DUPLEX_LBN)); + link_state->up = !!(flags & (1 << MC_CMD_GET_LINK_OUT_LINK_UP_LBN)); + link_state->fd = !!(flags & (1 << MC_CMD_GET_LINK_OUT_FULL_DUPLEX_LBN)); link_state->speed = speed; } @@ -592,7 +592,7 @@ static int efx_mcdi_phy_test_alive(struct efx_nic *efx) if (outlen < MC_CMD_GET_PHY_STATE_OUT_LEN) return -EIO; - if (MCDI_DWORD(outbuf, GET_PHY_STATE_STATE) != MC_CMD_PHY_STATE_OK) + if (MCDI_DWORD(outbuf, GET_PHY_STATE_OUT_STATE) != MC_CMD_PHY_STATE_OK) return -EINVAL; return 0; @@ -680,7 +680,7 @@ static int efx_mcdi_phy_run_tests(struct efx_nic *efx, int *results, u32 mode; int rc; - if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_BIST_LBN)) { + if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_LBN)) { rc = efx_mcdi_bist(efx, MC_CMD_PHY_BIST, results); if (rc < 0) return rc; @@ -691,15 +691,15 @@ static int efx_mcdi_phy_run_tests(struct efx_nic *efx, int *results, /* If we support both LONG and SHORT, then run each in response to * break or not. Otherwise, run the one we support */ mode = 0; - if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_BIST_CABLE_SHORT_LBN)) { + if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_LBN)) { if ((flags & ETH_TEST_FL_OFFLINE) && (phy_cfg->flags & - (1 << MC_CMD_GET_PHY_CFG_BIST_CABLE_LONG_LBN))) + (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN))) mode = MC_CMD_PHY_BIST_CABLE_LONG; else mode = MC_CMD_PHY_BIST_CABLE_SHORT; } else if (phy_cfg->flags & - (1 << MC_CMD_GET_PHY_CFG_BIST_CABLE_LONG_LBN)) + (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN)) mode = MC_CMD_PHY_BIST_CABLE_LONG; if (mode != 0) { @@ -717,14 +717,14 @@ static const char *efx_mcdi_phy_test_name(struct efx_nic *efx, { struct efx_mcdi_phy_data *phy_cfg = efx->phy_data; - if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_BIST_LBN)) { + if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_LBN)) { if (index == 0) return "bist"; --index; } - if (phy_cfg->flags & ((1 << MC_CMD_GET_PHY_CFG_BIST_CABLE_SHORT_LBN) | - (1 << MC_CMD_GET_PHY_CFG_BIST_CABLE_LONG_LBN))) { + if (phy_cfg->flags & ((1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_LBN) | + (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN))) { if (index == 0) return "cable"; --index; diff --git a/drivers/net/ethernet/sfc/mtd.c b/drivers/net/ethernet/sfc/mtd.c index 13f61fba731..7f61cd3812d 100644 --- a/drivers/net/ethernet/sfc/mtd.c +++ b/drivers/net/ethernet/sfc/mtd.c @@ -627,8 +627,7 @@ static int siena_mtd_get_fw_subtypes(struct efx_nic *efx, struct efx_mtd *efx_mtd) { struct efx_mtd_partition *part; - uint16_t fw_subtype_list[MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN / - sizeof(uint16_t)]; + uint16_t fw_subtype_list[MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MINNUM]; int rc; rc = efx_mcdi_get_board_cfg(efx, NULL, fw_subtype_list); -- cgit v1.2.3-70-g09d2 From fa142b9da3393fd92b398b6bdecf3f21914e309b Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 20 Dec 2011 01:15:30 +0000 Subject: sfc: Rename efx_wanted_channels() to efx_wanted_parallelism() This function returns the degree of parallelism wanted, which is not necessarily the total number of channels we want to create. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 9ca5dcdf5a8..5fcc42f7d86 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -1146,9 +1146,7 @@ static void efx_fini_io(struct efx_nic *efx) pci_disable_device(efx->pci_dev); } -/* Get number of channels wanted. Each channel will have its own IRQ, - * 1 RX queue and/or 2 TX queues. */ -static int efx_wanted_channels(void) +static int efx_wanted_parallelism(void) { cpumask_var_t core_mask; int count; @@ -1211,7 +1209,7 @@ static int efx_probe_interrupts(struct efx_nic *efx) struct msix_entry xentries[EFX_MAX_CHANNELS]; int n_channels; - n_channels = efx_wanted_channels(); + n_channels = efx_wanted_parallelism(); if (separate_tx_channels) n_channels *= 2; n_channels = min(n_channels, max_channels); -- cgit v1.2.3-70-g09d2 From cdb08f8fd8642a6d661c920f565e85cf87a0c9be Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 20 Dec 2011 01:08:05 +0000 Subject: sfc: Set default parallelism to per-core by default The previous default of per-package can be more CPU-efficient, but users generally seem to prefer per-core. It should also allow accelerated RFS to direct packets more precisely, if IRQ affinity is properly spread out. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 5fcc42f7d86..d7301d2e81a 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -162,7 +162,7 @@ static unsigned int interrupt_mode; * interrupt handling. * * Cards without MSI-X will only target one CPU via legacy or MSI interrupt. - * The default (0) means to assign an interrupt to each package (level II cache) + * The default (0) means to assign an interrupt to each core. */ static unsigned int rss_cpus; module_param(rss_cpus, uint, 0444); @@ -1148,14 +1148,14 @@ static void efx_fini_io(struct efx_nic *efx) static int efx_wanted_parallelism(void) { - cpumask_var_t core_mask; + cpumask_var_t thread_mask; int count; int cpu; if (rss_cpus) return rss_cpus; - if (unlikely(!zalloc_cpumask_var(&core_mask, GFP_KERNEL))) { + if (unlikely(!zalloc_cpumask_var(&thread_mask, GFP_KERNEL))) { printk(KERN_WARNING "sfc: RSS disabled due to allocation failure\n"); return 1; @@ -1163,14 +1163,14 @@ static int efx_wanted_parallelism(void) count = 0; for_each_online_cpu(cpu) { - if (!cpumask_test_cpu(cpu, core_mask)) { + if (!cpumask_test_cpu(cpu, thread_mask)) { ++count; - cpumask_or(core_mask, core_mask, - topology_core_cpumask(cpu)); + cpumask_or(thread_mask, thread_mask, + topology_thread_cpumask(cpu)); } } - free_cpumask_var(core_mask); + free_cpumask_var(thread_mask); return count; } -- cgit v1.2.3-70-g09d2 From 866dc88607aa07f297eec7b504be58ca17d91a26 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 10 Jan 2012 09:53:23 +0530 Subject: ath6kl: Fix SDIO error path sdio_release_host() would be called twice if sdio_set_block_size() fails for some reason, which would result in the following warning. WARNING: at /home/sujith/dev/wireless-testing/drivers/mmc/core/core.c:828 mmc_release_host+0x42/0x50 [mmc_core]() Call Trace: [] warn_slowpath_common+0x7f/0xc0 [] warn_slowpath_null+0x1a/0x20 [] mmc_release_host+0x42/0x50 [mmc_core] [] sdio_release_host+0x1e/0x30 [mmc_core] [] ath6kl_sdio_config+0xc7/0x110 [ath6kl_sdio] [] ath6kl_sdio_probe+0x21c/0x320 [ath6kl_sdio] [] ? mmc_release_host+0x2a/0x50 [mmc_core] [] sdio_bus_probe+0xfa/0x130 [mmc_core] [] driver_probe_device+0x7e/0x1b0 [] __driver_attach+0xab/0xb0 [] ? driver_probe_device+0x1b0/0x1b0 [] ? driver_probe_device+0x1b0/0x1b0 [] bus_for_each_dev+0x64/0xa0 [] driver_attach+0x1e/0x20 [] bus_add_driver+0x1b0/0x280 [] ? 0xffffffffa0064fff [] driver_register+0x76/0x140 [] ? 0xffffffffa0064fff [] sdio_register_driver+0x21/0x30 [mmc_core] [] ath6kl_sdio_init+0x12/0x35 [ath6kl_sdio] [] do_one_initcall+0x42/0x180 [] sys_init_module+0x8f/0x200 [] system_call_fastpath+0x16/0x1b Signed-off-by: Sujith Manoharan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/sdio.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index 8b36904ec3e..50b19d3aefa 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -770,7 +770,6 @@ static int ath6kl_sdio_config(struct ath6kl *ar) if (ret) { ath6kl_err("Set sdio block size %d failed: %d)\n", HIF_MBOX_BLOCK_SIZE, ret); - sdio_release_host(func); goto out; } -- cgit v1.2.3-70-g09d2 From 4a8ce2fd055f8c117fb6fa6da39af8f62cbffe4b Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 10 Jan 2012 09:53:38 +0530 Subject: ath6kl: Remove redundant pointer check 'params' is already used earlier and there is no point in checking for a NULL condition again. Signed-off-by: Sujith Manoharan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 31 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 14f180eac48..9b26bbaf124 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -983,6 +983,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, struct ath6kl *ar = ath6kl_priv(ndev); struct ath6kl_vif *vif = netdev_priv(ndev); struct ath6kl_key *key = NULL; + int seq_len; u8 key_usage; u8 key_type; @@ -1011,23 +1012,21 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, else key_usage = GROUP_USAGE; - if (params) { - int seq_len = params->seq_len; - if (params->cipher == WLAN_CIPHER_SUITE_SMS4 && - seq_len > ATH6KL_KEY_SEQ_LEN) { - /* Only first half of the WPI PN is configured */ - seq_len = ATH6KL_KEY_SEQ_LEN; - } - if (params->key_len > WLAN_MAX_KEY_LEN || - seq_len > sizeof(key->seq)) - return -EINVAL; - - key->key_len = params->key_len; - memcpy(key->key, params->key, key->key_len); - key->seq_len = seq_len; - memcpy(key->seq, params->seq, key->seq_len); - key->cipher = params->cipher; + seq_len = params->seq_len; + if (params->cipher == WLAN_CIPHER_SUITE_SMS4 && + seq_len > ATH6KL_KEY_SEQ_LEN) { + /* Only first half of the WPI PN is configured */ + seq_len = ATH6KL_KEY_SEQ_LEN; } + if (params->key_len > WLAN_MAX_KEY_LEN || + seq_len > sizeof(key->seq)) + return -EINVAL; + + key->key_len = params->key_len; + memcpy(key->key, params->key, key->key_len); + key->seq_len = seq_len; + memcpy(key->seq, params->seq, key->seq_len); + key->cipher = params->cipher; switch (key->cipher) { case WLAN_CIPHER_SUITE_WEP40: -- cgit v1.2.3-70-g09d2 From cbec267a5143f70ece4069d18889a442bcb3365b Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 10 Jan 2012 09:53:53 +0530 Subject: ath6kl: Initialize a variable properly This prevents 'comp_pktq' from being used in an incorrect manner. Signed-off-by: Sujith Manoharan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/htc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c index b01702258fa..2d721903640 100644 --- a/drivers/net/wireless/ath/ath6kl/htc.c +++ b/drivers/net/wireless/ath/ath6kl/htc.c @@ -2062,6 +2062,7 @@ int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target, enum htc_endpoint_id id; int n_fetched = 0; + INIT_LIST_HEAD(&comp_pktq); *num_pkts = 0; /* -- cgit v1.2.3-70-g09d2 From 8232736dabd2a0310f76944fa7af0542fe3ded4f Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 10 Jan 2012 09:54:10 +0530 Subject: ath6kl: Fix listen interval handling This patch addresses a few problems with the commit: "ath6kl: Implement support for listen interval from userspace" * The debugfs file required for reading/writing the listen interval wasn't created. Fix this. * The interface index was being hardcoded to zero. Fix this. * Two separate parameters, "listen_interval_time and listen_interval_beacons" were being used. This fails to work as expected because the FW assigns higher precedence to "listen_interval_beacons" and "listen_interval_time" ends up being never used at all. To handle this, fix the host driver to exclusively use listen interval based on units of beacon intervals. To set the listen interval, a user would now do something like this: echo "10" > /sys/kernel/debug/ieee80211/*/ath6kl/listen_interval kvalo: fix two checkpatch warnings Signed-off-by: Sujith Manoharan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 3 +- drivers/net/wireless/ath/ath6kl/core.h | 3 +- drivers/net/wireless/ath/ath6kl/debug.c | 44 ++++++++++++------------------ drivers/net/wireless/ath/ath6kl/main.c | 7 +++-- 4 files changed, 24 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 9b26bbaf124..1a98c9256c6 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -2725,8 +2725,7 @@ struct ath6kl *ath6kl_core_alloc(struct device *dev) clear_bit(SKIP_SCAN, &ar->flag); clear_bit(DESTROY_IN_PROGRESS, &ar->flag); - ar->listen_intvl_t = A_DEFAULT_LISTEN_INTERVAL; - ar->listen_intvl_b = 0; + ar->listen_intvl_b = A_DEFAULT_LISTEN_INTERVAL; ar->tx_pwr = 0; ar->intra_bss = 1; diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 793c6a58f0f..f4da5e19a36 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -55,7 +55,7 @@ #define MAX_DEFAULT_SEND_QUEUE_DEPTH (MAX_DEF_COOKIE_NUM / WMM_NUM_AC) #define DISCON_TIMER_INTVAL 10000 /* in msec */ -#define A_DEFAULT_LISTEN_INTERVAL 100 +#define A_DEFAULT_LISTEN_INTERVAL 1 /* beacon intervals */ #define A_MAX_WOW_LISTEN_INTERVAL 1000 /* includes also the null byte */ @@ -534,7 +534,6 @@ struct ath6kl { spinlock_t lock; struct semaphore sem; u16 listen_intvl_b; - u16 listen_intvl_t; u8 lrssi_roam_threshold; struct ath6kl_version version; u32 target_type; diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c index eb808b46f94..fa7243b4144 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.c +++ b/drivers/net/wireless/ath/ath6kl/debug.c @@ -1505,57 +1505,46 @@ static const struct file_operations fops_bgscan_int = { }; static ssize_t ath6kl_listen_int_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) + const char __user *user_buf, + size_t count, loff_t *ppos) { struct ath6kl *ar = file->private_data; - u16 listen_int_t, listen_int_b; + struct ath6kl_vif *vif; + u16 listen_interval; char buf[32]; - char *sptr, *token; ssize_t len; + vif = ath6kl_vif_first(ar); + if (!vif) + return -EIO; + len = min(count, sizeof(buf) - 1); if (copy_from_user(buf, user_buf, len)) return -EFAULT; buf[len] = '\0'; - sptr = buf; - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - - if (kstrtou16(token, 0, &listen_int_t)) - return -EINVAL; - - if (kstrtou16(sptr, 0, &listen_int_b)) - return -EINVAL; - - if ((listen_int_t < 15) || (listen_int_t > 5000)) + if (kstrtou16(buf, 0, &listen_interval)) return -EINVAL; - if ((listen_int_b < 1) || (listen_int_b > 50)) + if ((listen_interval < 1) || (listen_interval > 50)) return -EINVAL; - ar->listen_intvl_t = listen_int_t; - ar->listen_intvl_b = listen_int_b; - - ath6kl_wmi_listeninterval_cmd(ar->wmi, 0, ar->listen_intvl_t, + ar->listen_intvl_b = listen_interval; + ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, 0, ar->listen_intvl_b); return count; } static ssize_t ath6kl_listen_int_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) + char __user *user_buf, + size_t count, loff_t *ppos) { struct ath6kl *ar = file->private_data; char buf[32]; int len; - len = scnprintf(buf, sizeof(buf), "%u %u\n", ar->listen_intvl_t, - ar->listen_intvl_b); + len = scnprintf(buf, sizeof(buf), "%u\n", ar->listen_intvl_b); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -1710,6 +1699,9 @@ int ath6kl_debug_init(struct ath6kl *ar) debugfs_create_file("bgscan_interval", S_IWUSR, ar->debugfs_phy, ar, &fops_bgscan_int); + debugfs_create_file("listen_interval", S_IRUSR | S_IWUSR, + ar->debugfs_phy, ar, &fops_listen_int); + debugfs_create_file("power_params", S_IWUSR, ar->debugfs_phy, ar, &fops_power_params); diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index 8742eaa7818..4c26572214c 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -584,10 +584,11 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid, memcpy(vif->bssid, bssid, sizeof(vif->bssid)); vif->bss_ch = channel; - if ((vif->nw_type == INFRA_NETWORK)) + if ((vif->nw_type == INFRA_NETWORK)) { + ar->listen_intvl_b = listen_int; ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, - ar->listen_intvl_t, - ar->listen_intvl_b); + 0, ar->listen_intvl_b); + } netif_wake_queue(vif->ndev); -- cgit v1.2.3-70-g09d2 From a96d627abaac899e8bfaf18fd0578b228c9c752f Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 4 Jan 2012 14:23:56 -0500 Subject: pci: Introduce __pci_reset_function_locked to be used when holding device_lock. The use case of this is when a driver wants to call FLR when a device is attached to it using the SysFS "bind" or "unbind" functionality. The call chain when a user does "bind" looks as so: echo "0000:01.07.0" > /sys/bus/pci/drivers/XXXX/bind and ends up calling: driver_bind: device_lock(dev); <=== TAKES LOCK XXXX_probe: .. pci_enable_device() ...__pci_reset_function(), which calls pci_dev_reset(dev, 0): if (!0) { device_lock(dev) <==== DEADLOCK The __pci_reset_function_locked function allows the the drivers 'probe' function to call the "pci_reset_function" while still holding the driver mutex lock. Signed-off-by: Konrad Rzeszutek Wilk --- drivers/pci/pci.c | 25 +++++++++++++++++++++++++ include/linux/pci.h | 1 + 2 files changed, 26 insertions(+) (limited to 'drivers') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 97fff785e97..192be5dbde5 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3162,6 +3162,31 @@ int __pci_reset_function(struct pci_dev *dev) } EXPORT_SYMBOL_GPL(__pci_reset_function); +/** + * __pci_reset_function_locked - reset a PCI device function while holding + * the @dev mutex lock. + * @dev: PCI device to reset + * + * Some devices allow an individual function to be reset without affecting + * other functions in the same device. The PCI device must be responsive + * to PCI config space in order to use this function. + * + * The device function is presumed to be unused and the caller is holding + * the device mutex lock when this function is called. + * Resetting the device will make the contents of PCI configuration space + * random, so any caller of this must be prepared to reinitialise the + * device including MSI, bus mastering, BARs, decoding IO and memory spaces, + * etc. + * + * Returns 0 if the device function was successfully reset or negative if the + * device doesn't support resetting a single function. + */ +int __pci_reset_function_locked(struct pci_dev *dev) +{ + return pci_dev_reset(dev, 1); +} +EXPORT_SYMBOL_GPL(__pci_reset_function_locked); + /** * pci_probe_reset_function - check whether the device can be safely reset * @dev: PCI device to reset diff --git a/include/linux/pci.h b/include/linux/pci.h index a16b1df3def..65c2d8a32b2 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -817,6 +817,7 @@ int pcie_set_readrq(struct pci_dev *dev, int rq); int pcie_get_mps(struct pci_dev *dev); int pcie_set_mps(struct pci_dev *dev, int mps); int __pci_reset_function(struct pci_dev *dev); +int __pci_reset_function_locked(struct pci_dev *dev); int pci_reset_function(struct pci_dev *dev); void pci_update_resource(struct pci_dev *dev, int resno); int __must_check pci_assign_resource(struct pci_dev *dev, int i); -- cgit v1.2.3-70-g09d2 From cd9db80e5257682a7f7ab245a2459648b3c8d268 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 4 Jan 2012 14:30:58 -0500 Subject: xen/pciback: Support pci_reset_function, aka FLR or D3 support. We use the __pci_reset_function_locked to perform the action. Also on attaching ("bind") and detaching ("unbind") we save and restore the configuration states. When the device is disconnected from a guest we use the "pci_reset_function" to also reset the device before being passed to another guest. Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/xen-pciback/pci_stub.c | 41 +++++++++++++++++++++++++++++++++++--- drivers/xen/xen-pciback/pciback.h | 1 + 2 files changed, 39 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index 7944a17f5cb..6f63b9d954f 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c @@ -85,19 +85,34 @@ static struct pcistub_device *pcistub_device_alloc(struct pci_dev *dev) static void pcistub_device_release(struct kref *kref) { struct pcistub_device *psdev; + struct xen_pcibk_dev_data *dev_data; psdev = container_of(kref, struct pcistub_device, kref); + dev_data = pci_get_drvdata(psdev->dev); dev_dbg(&psdev->dev->dev, "pcistub_device_release\n"); xen_unregister_device_domain_owner(psdev->dev); - /* Clean-up the device */ + /* Call the reset function which does not take lock as this + * is called from "unbind" which takes a device_lock mutex. + */ + __pci_reset_function_locked(psdev->dev); + if (pci_load_and_free_saved_state(psdev->dev, + &dev_data->pci_saved_state)) { + dev_dbg(&psdev->dev->dev, "Could not reload PCI state\n"); + } else + pci_restore_state(psdev->dev); + + /* Disable the device */ xen_pcibk_reset_device(psdev->dev); + + kfree(dev_data); + pci_set_drvdata(psdev->dev, NULL); + + /* Clean-up the device */ xen_pcibk_config_free_dyn_fields(psdev->dev); xen_pcibk_config_free_dev(psdev->dev); - kfree(pci_get_drvdata(psdev->dev)); - pci_set_drvdata(psdev->dev, NULL); psdev->dev->dev_flags &= ~PCI_DEV_FLAGS_ASSIGNED; pci_dev_put(psdev->dev); @@ -231,7 +246,17 @@ void pcistub_put_pci_dev(struct pci_dev *dev) /* Cleanup our device * (so it's ready for the next domain) */ + + /* This is OK - we are running from workqueue context + * and want to inhibit the user from fiddling with 'reset' + */ + pci_reset_function(dev); + pci_restore_state(psdev->dev); + + /* This disables the device. */ xen_pcibk_reset_device(found_psdev->dev); + + /* And cleanup up our emulated fields. */ xen_pcibk_config_free_dyn_fields(found_psdev->dev); xen_pcibk_config_reset_dev(found_psdev->dev); @@ -328,6 +353,16 @@ static int __devinit pcistub_init_device(struct pci_dev *dev) if (err) goto config_release; + dev_dbg(&dev->dev, "reseting (FLR, D3, etc) the device\n"); + __pci_reset_function_locked(dev); + + /* We need the device active to save the state. */ + dev_dbg(&dev->dev, "save state of device\n"); + pci_save_state(dev); + dev_data->pci_saved_state = pci_store_saved_state(dev); + if (!dev_data->pci_saved_state) + dev_err(&dev->dev, "Could not store PCI conf saved state!\n"); + /* Now disable the device (this also ensures some private device * data is setup before we export) */ diff --git a/drivers/xen/xen-pciback/pciback.h b/drivers/xen/xen-pciback/pciback.h index e9b4011c5f9..a7def010eba 100644 --- a/drivers/xen/xen-pciback/pciback.h +++ b/drivers/xen/xen-pciback/pciback.h @@ -41,6 +41,7 @@ struct xen_pcibk_device { struct xen_pcibk_dev_data { struct list_head config_fields; + struct pci_saved_state *pci_saved_state; unsigned int permissive:1; unsigned int warned_on_write:1; unsigned int enable_intx:1; -- cgit v1.2.3-70-g09d2 From f1df57d02a0f83e764b4dc9187f58665d70f190e Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Fri, 13 Jan 2012 16:38:37 +1100 Subject: crypto: driver for Tegra AES hardware driver supports ecb/cbc/ofb/ansi_x9.31rng modes, 128, 192 and 256-bit key sizes Signed-off-by: Varun Wadekar Signed-off-by: Herbert Xu --- drivers/crypto/Kconfig | 11 + drivers/crypto/Makefile | 1 + drivers/crypto/tegra-aes.c | 1096 ++++++++++++++++++++++++++++++++++++++++++++ drivers/crypto/tegra-aes.h | 103 +++++ 4 files changed, 1211 insertions(+) create mode 100644 drivers/crypto/tegra-aes.c create mode 100644 drivers/crypto/tegra-aes.h (limited to 'drivers') diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 6d16b4b0d7a..e707979767f 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -293,4 +293,15 @@ config CRYPTO_DEV_S5P Select this to offload Samsung S5PV210 or S5PC110 from AES algorithms execution. +config CRYPTO_DEV_TEGRA_AES + tristate "Support for TEGRA AES hw engine" + depends on ARCH_TEGRA + select CRYPTO_AES + help + TEGRA processors have AES module accelerator. Select this if you + want to use the TEGRA module for AES algorithms. + + To compile this driver as a module, choose M here: the module + will be called tegra-aes. + endif # CRYPTO_HW diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index 53ea5015531..f3e64eadd7a 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -13,3 +13,4 @@ obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o obj-$(CONFIG_CRYPTO_DEV_PICOXCELL) += picoxcell_crypto.o obj-$(CONFIG_CRYPTO_DEV_S5P) += s5p-sss.o +obj-$(CONFIG_CRYPTO_DEV_TEGRA_AES) += tegra-aes.o diff --git a/drivers/crypto/tegra-aes.c b/drivers/crypto/tegra-aes.c new file mode 100644 index 00000000000..422a9766c7c --- /dev/null +++ b/drivers/crypto/tegra-aes.c @@ -0,0 +1,1096 @@ +/* + * drivers/crypto/tegra-aes.c + * + * Driver for NVIDIA Tegra AES hardware engine residing inside the + * Bit Stream Engine for Video (BSEV) hardware block. + * + * The programming sequence for this engine is with the help + * of commands which travel via a command queue residing between the + * CPU and the BSEV block. The BSEV engine has an internal RAM (VRAM) + * where the final input plaintext, keys and the IV have to be copied + * before starting the encrypt/decrypt operation. + * + * Copyright (c) 2010, NVIDIA 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., + * 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 "tegra-aes.h" + +#define FLAGS_MODE_MASK 0x00FF +#define FLAGS_ENCRYPT BIT(0) +#define FLAGS_CBC BIT(1) +#define FLAGS_GIV BIT(2) +#define FLAGS_RNG BIT(3) +#define FLAGS_OFB BIT(4) +#define FLAGS_NEW_KEY BIT(5) +#define FLAGS_NEW_IV BIT(6) +#define FLAGS_INIT BIT(7) +#define FLAGS_FAST BIT(8) +#define FLAGS_BUSY 9 + +/* + * Defines AES engine Max process bytes size in one go, which takes 1 msec. + * AES engine spends about 176 cycles/16-bytes or 11 cycles/byte + * The duration CPU can use the BSE to 1 msec, then the number of available + * cycles of AVP/BSE is 216K. In this duration, AES can process 216/11 ~= 19KB + * Based on this AES_HW_DMA_BUFFER_SIZE_BYTES is configured to 16KB. + */ +#define AES_HW_DMA_BUFFER_SIZE_BYTES 0x4000 + +/* + * The key table length is 64 bytes + * (This includes first upto 32 bytes key + 16 bytes original initial vector + * and 16 bytes updated initial vector) + */ +#define AES_HW_KEY_TABLE_LENGTH_BYTES 64 + +/* + * The memory being used is divides as follows: + * 1. Key - 32 bytes + * 2. Original IV - 16 bytes + * 3. Updated IV - 16 bytes + * 4. Key schedule - 256 bytes + * + * 1+2+3 constitute the hw key table. + */ +#define AES_HW_IV_SIZE 16 +#define AES_HW_KEYSCHEDULE_LEN 256 +#define AES_IVKEY_SIZE (AES_HW_KEY_TABLE_LENGTH_BYTES + AES_HW_KEYSCHEDULE_LEN) + +/* Define commands required for AES operation */ +enum { + CMD_BLKSTARTENGINE = 0x0E, + CMD_DMASETUP = 0x10, + CMD_DMACOMPLETE = 0x11, + CMD_SETTABLE = 0x15, + CMD_MEMDMAVD = 0x22, +}; + +/* Define sub-commands */ +enum { + SUBCMD_VRAM_SEL = 0x1, + SUBCMD_CRYPTO_TABLE_SEL = 0x3, + SUBCMD_KEY_TABLE_SEL = 0x8, +}; + +/* memdma_vd command */ +#define MEMDMA_DIR_DTOVRAM 0 /* sdram -> vram */ +#define MEMDMA_DIR_VTODRAM 1 /* vram -> sdram */ +#define MEMDMA_DIR_SHIFT 25 +#define MEMDMA_NUM_WORDS_SHIFT 12 + +/* command queue bit shifts */ +enum { + CMDQ_KEYTABLEADDR_SHIFT = 0, + CMDQ_KEYTABLEID_SHIFT = 17, + CMDQ_VRAMSEL_SHIFT = 23, + CMDQ_TABLESEL_SHIFT = 24, + CMDQ_OPCODE_SHIFT = 26, +}; + +/* + * The secure key slot contains a unique secure key generated + * and loaded by the bootloader. This slot is marked as non-accessible + * to the kernel. + */ +#define SSK_SLOT_NUM 4 + +#define AES_NR_KEYSLOTS 8 +#define TEGRA_AES_QUEUE_LENGTH 50 +#define DEFAULT_RNG_BLK_SZ 16 + +/* The command queue depth */ +#define AES_HW_MAX_ICQ_LENGTH 5 + +struct tegra_aes_slot { + struct list_head node; + int slot_num; +}; + +static struct tegra_aes_slot ssk = { + .slot_num = SSK_SLOT_NUM, +}; + +struct tegra_aes_reqctx { + unsigned long mode; +}; + +struct tegra_aes_dev { + struct device *dev; + void __iomem *io_base; + dma_addr_t ivkey_phys_base; + void __iomem *ivkey_base; + struct clk *aes_clk; + struct tegra_aes_ctx *ctx; + int irq; + unsigned long flags; + struct completion op_complete; + u32 *buf_in; + dma_addr_t dma_buf_in; + u32 *buf_out; + dma_addr_t dma_buf_out; + u8 *iv; + u8 dt[DEFAULT_RNG_BLK_SZ]; + int ivlen; + u64 ctr; + spinlock_t lock; + struct crypto_queue queue; + struct tegra_aes_slot *slots; + struct ablkcipher_request *req; + size_t total; + struct scatterlist *in_sg; + size_t in_offset; + struct scatterlist *out_sg; + size_t out_offset; +}; + +static struct tegra_aes_dev *aes_dev; + +struct tegra_aes_ctx { + struct tegra_aes_dev *dd; + unsigned long flags; + struct tegra_aes_slot *slot; + u8 key[AES_MAX_KEY_SIZE]; + size_t keylen; +}; + +static struct tegra_aes_ctx rng_ctx = { + .flags = FLAGS_NEW_KEY, + .keylen = AES_KEYSIZE_128, +}; + +/* keep registered devices data here */ +static struct list_head dev_list; +static DEFINE_SPINLOCK(list_lock); +static DEFINE_MUTEX(aes_lock); + +static void aes_workqueue_handler(struct work_struct *work); +static DECLARE_WORK(aes_work, aes_workqueue_handler); +static struct workqueue_struct *aes_wq; + +extern unsigned long long tegra_chip_uid(void); + +static inline u32 aes_readl(struct tegra_aes_dev *dd, u32 offset) +{ + return readl(dd->io_base + offset); +} + +static inline void aes_writel(struct tegra_aes_dev *dd, u32 val, u32 offset) +{ + writel(val, dd->io_base + offset); +} + +static int aes_start_crypt(struct tegra_aes_dev *dd, u32 in_addr, u32 out_addr, + int nblocks, int mode, bool upd_iv) +{ + u32 cmdq[AES_HW_MAX_ICQ_LENGTH]; + int i, eng_busy, icq_empty, ret; + u32 value; + + /* reset all the interrupt bits */ + aes_writel(dd, 0xFFFFFFFF, TEGRA_AES_INTR_STATUS); + + /* enable error, dma xfer complete interrupts */ + aes_writel(dd, 0x33, TEGRA_AES_INT_ENB); + + cmdq[0] = CMD_DMASETUP << CMDQ_OPCODE_SHIFT; + cmdq[1] = in_addr; + cmdq[2] = CMD_BLKSTARTENGINE << CMDQ_OPCODE_SHIFT | (nblocks-1); + cmdq[3] = CMD_DMACOMPLETE << CMDQ_OPCODE_SHIFT; + + value = aes_readl(dd, TEGRA_AES_CMDQUE_CONTROL); + /* access SDRAM through AHB */ + value &= ~TEGRA_AES_CMDQ_CTRL_SRC_STM_SEL_FIELD; + value &= ~TEGRA_AES_CMDQ_CTRL_DST_STM_SEL_FIELD; + value |= TEGRA_AES_CMDQ_CTRL_SRC_STM_SEL_FIELD | + TEGRA_AES_CMDQ_CTRL_DST_STM_SEL_FIELD | + TEGRA_AES_CMDQ_CTRL_ICMDQEN_FIELD; + aes_writel(dd, value, TEGRA_AES_CMDQUE_CONTROL); + dev_dbg(dd->dev, "cmd_q_ctrl=0x%x", value); + + value = (0x1 << TEGRA_AES_SECURE_INPUT_ALG_SEL_SHIFT) | + ((dd->ctx->keylen * 8) << + TEGRA_AES_SECURE_INPUT_KEY_LEN_SHIFT) | + ((u32)upd_iv << TEGRA_AES_SECURE_IV_SELECT_SHIFT); + + if (mode & FLAGS_CBC) { + value |= ((((mode & FLAGS_ENCRYPT) ? 2 : 3) + << TEGRA_AES_SECURE_XOR_POS_SHIFT) | + (((mode & FLAGS_ENCRYPT) ? 2 : 3) + << TEGRA_AES_SECURE_VCTRAM_SEL_SHIFT) | + ((mode & FLAGS_ENCRYPT) ? 1 : 0) + << TEGRA_AES_SECURE_CORE_SEL_SHIFT); + } else if (mode & FLAGS_OFB) { + value |= ((TEGRA_AES_SECURE_XOR_POS_FIELD) | + (2 << TEGRA_AES_SECURE_INPUT_SEL_SHIFT) | + (TEGRA_AES_SECURE_CORE_SEL_FIELD)); + } else if (mode & FLAGS_RNG) { + value |= (((mode & FLAGS_ENCRYPT) ? 1 : 0) + << TEGRA_AES_SECURE_CORE_SEL_SHIFT | + TEGRA_AES_SECURE_RNG_ENB_FIELD); + } else { + value |= (((mode & FLAGS_ENCRYPT) ? 1 : 0) + << TEGRA_AES_SECURE_CORE_SEL_SHIFT); + } + + dev_dbg(dd->dev, "secure_in_sel=0x%x", value); + aes_writel(dd, value, TEGRA_AES_SECURE_INPUT_SELECT); + + aes_writel(dd, out_addr, TEGRA_AES_SECURE_DEST_ADDR); + INIT_COMPLETION(dd->op_complete); + + for (i = 0; i < AES_HW_MAX_ICQ_LENGTH - 1; i++) { + do { + value = aes_readl(dd, TEGRA_AES_INTR_STATUS); + eng_busy = value & TEGRA_AES_ENGINE_BUSY_FIELD; + icq_empty = value & TEGRA_AES_ICQ_EMPTY_FIELD; + } while (eng_busy & (!icq_empty)); + aes_writel(dd, cmdq[i], TEGRA_AES_ICMDQUE_WR); + } + + ret = wait_for_completion_timeout(&dd->op_complete, + msecs_to_jiffies(150)); + if (ret == 0) { + dev_err(dd->dev, "timed out (0x%x)\n", + aes_readl(dd, TEGRA_AES_INTR_STATUS)); + return -ETIMEDOUT; + } + + aes_writel(dd, cmdq[AES_HW_MAX_ICQ_LENGTH - 1], TEGRA_AES_ICMDQUE_WR); + return 0; +} + +static void aes_release_key_slot(struct tegra_aes_slot *slot) +{ + if (slot->slot_num == SSK_SLOT_NUM) + return; + + spin_lock(&list_lock); + list_add_tail(&slot->node, &dev_list); + slot = NULL; + spin_unlock(&list_lock); +} + +static struct tegra_aes_slot *aes_find_key_slot(void) +{ + struct tegra_aes_slot *slot = NULL; + struct list_head *new_head; + int empty; + + spin_lock(&list_lock); + empty = list_empty(&dev_list); + if (!empty) { + slot = list_entry(&dev_list, struct tegra_aes_slot, node); + new_head = dev_list.next; + list_del(&dev_list); + dev_list.next = new_head->next; + dev_list.prev = NULL; + } + spin_unlock(&list_lock); + + return slot; +} + +static int aes_set_key(struct tegra_aes_dev *dd) +{ + u32 value, cmdq[2]; + struct tegra_aes_ctx *ctx = dd->ctx; + int eng_busy, icq_empty, dma_busy; + bool use_ssk = false; + + /* use ssk? */ + if (!dd->ctx->slot) { + dev_dbg(dd->dev, "using ssk"); + dd->ctx->slot = &ssk; + use_ssk = true; + } + + /* enable key schedule generation in hardware */ + value = aes_readl(dd, TEGRA_AES_SECURE_CONFIG_EXT); + value &= ~TEGRA_AES_SECURE_KEY_SCH_DIS_FIELD; + aes_writel(dd, value, TEGRA_AES_SECURE_CONFIG_EXT); + + /* select the key slot */ + value = aes_readl(dd, TEGRA_AES_SECURE_CONFIG); + value &= ~TEGRA_AES_SECURE_KEY_INDEX_FIELD; + value |= (ctx->slot->slot_num << TEGRA_AES_SECURE_KEY_INDEX_SHIFT); + aes_writel(dd, value, TEGRA_AES_SECURE_CONFIG); + + if (use_ssk) + return 0; + + /* copy the key table from sdram to vram */ + cmdq[0] = CMD_MEMDMAVD << CMDQ_OPCODE_SHIFT | + MEMDMA_DIR_DTOVRAM << MEMDMA_DIR_SHIFT | + AES_HW_KEY_TABLE_LENGTH_BYTES / sizeof(u32) << + MEMDMA_NUM_WORDS_SHIFT; + cmdq[1] = (u32)dd->ivkey_phys_base; + + aes_writel(dd, cmdq[0], TEGRA_AES_ICMDQUE_WR); + aes_writel(dd, cmdq[1], TEGRA_AES_ICMDQUE_WR); + + do { + value = aes_readl(dd, TEGRA_AES_INTR_STATUS); + eng_busy = value & TEGRA_AES_ENGINE_BUSY_FIELD; + icq_empty = value & TEGRA_AES_ICQ_EMPTY_FIELD; + dma_busy = value & TEGRA_AES_DMA_BUSY_FIELD; + } while (eng_busy & (!icq_empty) & dma_busy); + + /* settable command to get key into internal registers */ + value = CMD_SETTABLE << CMDQ_OPCODE_SHIFT | + SUBCMD_CRYPTO_TABLE_SEL << CMDQ_TABLESEL_SHIFT | + SUBCMD_VRAM_SEL << CMDQ_VRAMSEL_SHIFT | + (SUBCMD_KEY_TABLE_SEL | ctx->slot->slot_num) << + CMDQ_KEYTABLEID_SHIFT; + aes_writel(dd, value, TEGRA_AES_ICMDQUE_WR); + + do { + value = aes_readl(dd, TEGRA_AES_INTR_STATUS); + eng_busy = value & TEGRA_AES_ENGINE_BUSY_FIELD; + icq_empty = value & TEGRA_AES_ICQ_EMPTY_FIELD; + } while (eng_busy & (!icq_empty)); + + return 0; +} + +static int tegra_aes_handle_req(struct tegra_aes_dev *dd) +{ + struct crypto_async_request *async_req, *backlog; + struct crypto_ablkcipher *tfm; + struct tegra_aes_ctx *ctx; + struct tegra_aes_reqctx *rctx; + struct ablkcipher_request *req; + unsigned long flags; + int dma_max = AES_HW_DMA_BUFFER_SIZE_BYTES; + int ret = 0, nblocks, total; + int count = 0; + dma_addr_t addr_in, addr_out; + struct scatterlist *in_sg, *out_sg; + + if (!dd) + return -EINVAL; + + spin_lock_irqsave(&dd->lock, flags); + backlog = crypto_get_backlog(&dd->queue); + async_req = crypto_dequeue_request(&dd->queue); + if (!async_req) + clear_bit(FLAGS_BUSY, &dd->flags); + spin_unlock_irqrestore(&dd->lock, flags); + + if (!async_req) + return -ENODATA; + + if (backlog) + backlog->complete(backlog, -EINPROGRESS); + + req = ablkcipher_request_cast(async_req); + + dev_dbg(dd->dev, "%s: get new req\n", __func__); + + if (!req->src || !req->dst) + return -EINVAL; + + /* take mutex to access the aes hw */ + mutex_lock(&aes_lock); + + /* assign new request to device */ + dd->req = req; + dd->total = req->nbytes; + dd->in_offset = 0; + dd->in_sg = req->src; + dd->out_offset = 0; + dd->out_sg = req->dst; + + in_sg = dd->in_sg; + out_sg = dd->out_sg; + + total = dd->total; + + tfm = crypto_ablkcipher_reqtfm(req); + rctx = ablkcipher_request_ctx(req); + ctx = crypto_ablkcipher_ctx(tfm); + rctx->mode &= FLAGS_MODE_MASK; + dd->flags = (dd->flags & ~FLAGS_MODE_MASK) | rctx->mode; + + dd->iv = (u8 *)req->info; + dd->ivlen = crypto_ablkcipher_ivsize(tfm); + + /* assign new context to device */ + ctx->dd = dd; + dd->ctx = ctx; + + if (ctx->flags & FLAGS_NEW_KEY) { + /* copy the key */ + memcpy(dd->ivkey_base, ctx->key, ctx->keylen); + memset(dd->ivkey_base + ctx->keylen, 0, AES_HW_KEY_TABLE_LENGTH_BYTES - ctx->keylen); + aes_set_key(dd); + ctx->flags &= ~FLAGS_NEW_KEY; + } + + if (((dd->flags & FLAGS_CBC) || (dd->flags & FLAGS_OFB)) && dd->iv) { + /* set iv to the aes hw slot + * Hw generates updated iv only after iv is set in slot. + * So key and iv is passed asynchronously. + */ + memcpy(dd->buf_in, dd->iv, dd->ivlen); + + ret = aes_start_crypt(dd, (u32)dd->dma_buf_in, + dd->dma_buf_out, 1, FLAGS_CBC, false); + if (ret < 0) { + dev_err(dd->dev, "aes_start_crypt fail(%d)\n", ret); + goto out; + } + } + + while (total) { + dev_dbg(dd->dev, "remain: %d\n", total); + ret = dma_map_sg(dd->dev, in_sg, 1, DMA_TO_DEVICE); + if (!ret) { + dev_err(dd->dev, "dma_map_sg() error\n"); + goto out; + } + + ret = dma_map_sg(dd->dev, out_sg, 1, DMA_FROM_DEVICE); + if (!ret) { + dev_err(dd->dev, "dma_map_sg() error\n"); + dma_unmap_sg(dd->dev, dd->in_sg, + 1, DMA_TO_DEVICE); + goto out; + } + + addr_in = sg_dma_address(in_sg); + addr_out = sg_dma_address(out_sg); + dd->flags |= FLAGS_FAST; + count = min_t(int, sg_dma_len(in_sg), dma_max); + WARN_ON(sg_dma_len(in_sg) != sg_dma_len(out_sg)); + nblocks = DIV_ROUND_UP(count, AES_BLOCK_SIZE); + + ret = aes_start_crypt(dd, addr_in, addr_out, nblocks, + dd->flags, true); + + dma_unmap_sg(dd->dev, out_sg, 1, DMA_FROM_DEVICE); + dma_unmap_sg(dd->dev, in_sg, 1, DMA_TO_DEVICE); + + if (ret < 0) { + dev_err(dd->dev, "aes_start_crypt fail(%d)\n", ret); + goto out; + } + dd->flags &= ~FLAGS_FAST; + + dev_dbg(dd->dev, "out: copied %d\n", count); + total -= count; + in_sg = sg_next(in_sg); + out_sg = sg_next(out_sg); + WARN_ON(((total != 0) && (!in_sg || !out_sg))); + } + +out: + mutex_unlock(&aes_lock); + + dd->total = total; + + if (dd->req->base.complete) + dd->req->base.complete(&dd->req->base, ret); + + dev_dbg(dd->dev, "%s: exit\n", __func__); + return ret; +} + +static int tegra_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key, + unsigned int keylen) +{ + struct tegra_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm); + struct tegra_aes_dev *dd = aes_dev; + struct tegra_aes_slot *key_slot; + + if ((keylen != AES_KEYSIZE_128) && (keylen != AES_KEYSIZE_192) && + (keylen != AES_KEYSIZE_256)) { + dev_err(dd->dev, "unsupported key size\n"); + crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; + } + + dev_dbg(dd->dev, "keylen: %d\n", keylen); + + ctx->dd = dd; + + if (key) { + if (!ctx->slot) { + key_slot = aes_find_key_slot(); + if (!key_slot) { + dev_err(dd->dev, "no empty slot\n"); + return -ENOMEM; + } + + ctx->slot = key_slot; + } + + memcpy(ctx->key, key, keylen); + ctx->keylen = keylen; + } + + ctx->flags |= FLAGS_NEW_KEY; + dev_dbg(dd->dev, "done\n"); + return 0; +} + +static void aes_workqueue_handler(struct work_struct *work) +{ + struct tegra_aes_dev *dd = aes_dev; + int ret; + + ret = clk_enable(dd->aes_clk); + if (ret) + BUG_ON("clock enable failed"); + + /* empty the crypto queue and then return */ + do { + ret = tegra_aes_handle_req(dd); + } while (!ret); + + clk_disable(dd->aes_clk); +} + +static irqreturn_t aes_irq(int irq, void *dev_id) +{ + struct tegra_aes_dev *dd = (struct tegra_aes_dev *)dev_id; + u32 value = aes_readl(dd, TEGRA_AES_INTR_STATUS); + int busy = test_bit(FLAGS_BUSY, &dd->flags); + + if (!busy) { + dev_dbg(dd->dev, "spurious interrupt\n"); + return IRQ_NONE; + } + + dev_dbg(dd->dev, "irq_stat: 0x%x\n", value); + if (value & TEGRA_AES_INT_ERROR_MASK) + aes_writel(dd, TEGRA_AES_INT_ERROR_MASK, TEGRA_AES_INTR_STATUS); + + if (!(value & TEGRA_AES_ENGINE_BUSY_FIELD)) + complete(&dd->op_complete); + else + return IRQ_NONE; + + return IRQ_HANDLED; +} + +static int tegra_aes_crypt(struct ablkcipher_request *req, unsigned long mode) +{ + struct tegra_aes_reqctx *rctx = ablkcipher_request_ctx(req); + struct tegra_aes_dev *dd = aes_dev; + unsigned long flags; + int err = 0; + int busy; + + dev_dbg(dd->dev, "nbytes: %d, enc: %d, cbc: %d, ofb: %d\n", + req->nbytes, !!(mode & FLAGS_ENCRYPT), + !!(mode & FLAGS_CBC), !!(mode & FLAGS_OFB)); + + rctx->mode = mode; + + spin_lock_irqsave(&dd->lock, flags); + err = ablkcipher_enqueue_request(&dd->queue, req); + busy = test_and_set_bit(FLAGS_BUSY, &dd->flags); + spin_unlock_irqrestore(&dd->lock, flags); + + if (!busy) + queue_work(aes_wq, &aes_work); + + return err; +} + +static int tegra_aes_ecb_encrypt(struct ablkcipher_request *req) +{ + return tegra_aes_crypt(req, FLAGS_ENCRYPT); +} + +static int tegra_aes_ecb_decrypt(struct ablkcipher_request *req) +{ + return tegra_aes_crypt(req, 0); +} + +static int tegra_aes_cbc_encrypt(struct ablkcipher_request *req) +{ + return tegra_aes_crypt(req, FLAGS_ENCRYPT | FLAGS_CBC); +} + +static int tegra_aes_cbc_decrypt(struct ablkcipher_request *req) +{ + return tegra_aes_crypt(req, FLAGS_CBC); +} + +static int tegra_aes_ofb_encrypt(struct ablkcipher_request *req) +{ + return tegra_aes_crypt(req, FLAGS_ENCRYPT | FLAGS_OFB); +} + +static int tegra_aes_ofb_decrypt(struct ablkcipher_request *req) +{ + return tegra_aes_crypt(req, FLAGS_OFB); +} + +static int tegra_aes_get_random(struct crypto_rng *tfm, u8 *rdata, + unsigned int dlen) +{ + struct tegra_aes_dev *dd = aes_dev; + struct tegra_aes_ctx *ctx = &rng_ctx; + int ret, i; + u8 *dest = rdata, *dt = dd->dt; + + /* take mutex to access the aes hw */ + mutex_lock(&aes_lock); + + ret = clk_enable(dd->aes_clk); + if (ret) + return ret; + + ctx->dd = dd; + dd->ctx = ctx; + dd->flags = FLAGS_ENCRYPT | FLAGS_RNG; + + memcpy(dd->buf_in, dt, DEFAULT_RNG_BLK_SZ); + + ret = aes_start_crypt(dd, (u32)dd->dma_buf_in, + (u32)dd->dma_buf_out, 1, dd->flags, true); + if (ret < 0) { + dev_err(dd->dev, "aes_start_crypt fail(%d)\n", ret); + dlen = ret; + goto out; + } + memcpy(dest, dd->buf_out, dlen); + + /* update the DT */ + for (i = DEFAULT_RNG_BLK_SZ - 1; i >= 0; i--) { + dt[i] += 1; + if (dt[i] != 0) + break; + } + +out: + clk_disable(dd->aes_clk); + mutex_unlock(&aes_lock); + + dev_dbg(dd->dev, "%s: done\n", __func__); + return dlen; +} + +static int tegra_aes_rng_reset(struct crypto_rng *tfm, u8 *seed, + unsigned int slen) +{ + struct tegra_aes_dev *dd = aes_dev; + struct tegra_aes_ctx *ctx = &rng_ctx; + struct tegra_aes_slot *key_slot; + struct timespec ts; + int ret = 0; + u64 nsec, tmp[2]; + u8 *dt; + + if (!ctx || !dd) { + dev_err(dd->dev, "ctx=0x%x, dd=0x%x\n", + (unsigned int)ctx, (unsigned int)dd); + return -EINVAL; + } + + if (slen < (DEFAULT_RNG_BLK_SZ + AES_KEYSIZE_128)) { + dev_err(dd->dev, "seed size invalid"); + return -ENOMEM; + } + + /* take mutex to access the aes hw */ + mutex_lock(&aes_lock); + + if (!ctx->slot) { + key_slot = aes_find_key_slot(); + if (!key_slot) { + dev_err(dd->dev, "no empty slot\n"); + mutex_unlock(&aes_lock); + return -ENOMEM; + } + ctx->slot = key_slot; + } + + ctx->dd = dd; + dd->ctx = ctx; + dd->ctr = 0; + + ctx->keylen = AES_KEYSIZE_128; + ctx->flags |= FLAGS_NEW_KEY; + + /* copy the key to the key slot */ + memcpy(dd->ivkey_base, seed + DEFAULT_RNG_BLK_SZ, AES_KEYSIZE_128); + memset(dd->ivkey_base + AES_KEYSIZE_128, 0, AES_HW_KEY_TABLE_LENGTH_BYTES - AES_KEYSIZE_128); + + dd->iv = seed; + dd->ivlen = slen; + + dd->flags = FLAGS_ENCRYPT | FLAGS_RNG; + + ret = clk_enable(dd->aes_clk); + if (ret) + return ret; + + aes_set_key(dd); + + /* set seed to the aes hw slot */ + memcpy(dd->buf_in, dd->iv, DEFAULT_RNG_BLK_SZ); + ret = aes_start_crypt(dd, (u32)dd->dma_buf_in, + dd->dma_buf_out, 1, FLAGS_CBC, false); + if (ret < 0) { + dev_err(dd->dev, "aes_start_crypt fail(%d)\n", ret); + goto out; + } + + if (dd->ivlen >= (2 * DEFAULT_RNG_BLK_SZ + AES_KEYSIZE_128)) { + dt = dd->iv + DEFAULT_RNG_BLK_SZ + AES_KEYSIZE_128; + } else { + getnstimeofday(&ts); + nsec = timespec_to_ns(&ts); + do_div(nsec, 1000); + nsec ^= dd->ctr << 56; + dd->ctr++; + tmp[0] = nsec; + tmp[1] = tegra_chip_uid(); + dt = (u8 *)tmp; + } + memcpy(dd->dt, dt, DEFAULT_RNG_BLK_SZ); + +out: + clk_disable(dd->aes_clk); + mutex_unlock(&aes_lock); + + dev_dbg(dd->dev, "%s: done\n", __func__); + return ret; +} + +static int tegra_aes_cra_init(struct crypto_tfm *tfm) +{ + tfm->crt_ablkcipher.reqsize = sizeof(struct tegra_aes_reqctx); + + return 0; +} + +void tegra_aes_cra_exit(struct crypto_tfm *tfm) +{ + struct tegra_aes_ctx *ctx = + crypto_ablkcipher_ctx((struct crypto_ablkcipher *)tfm); + + if (ctx && ctx->slot) + aes_release_key_slot(ctx->slot); +} + +static struct crypto_alg algs[] = { + { + .cra_name = "ecb(aes)", + .cra_driver_name = "ecb-aes-tegra", + .cra_priority = 300, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_alignmask = 3, + .cra_type = &crypto_ablkcipher_type, + .cra_u.ablkcipher = { + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .setkey = tegra_aes_setkey, + .encrypt = tegra_aes_ecb_encrypt, + .decrypt = tegra_aes_ecb_decrypt, + }, + }, { + .cra_name = "cbc(aes)", + .cra_driver_name = "cbc-aes-tegra", + .cra_priority = 300, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_alignmask = 3, + .cra_type = &crypto_ablkcipher_type, + .cra_u.ablkcipher = { + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .ivsize = AES_MIN_KEY_SIZE, + .setkey = tegra_aes_setkey, + .encrypt = tegra_aes_cbc_encrypt, + .decrypt = tegra_aes_cbc_decrypt, + } + }, { + .cra_name = "ofb(aes)", + .cra_driver_name = "ofb-aes-tegra", + .cra_priority = 300, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_alignmask = 3, + .cra_type = &crypto_ablkcipher_type, + .cra_u.ablkcipher = { + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .ivsize = AES_MIN_KEY_SIZE, + .setkey = tegra_aes_setkey, + .encrypt = tegra_aes_ofb_encrypt, + .decrypt = tegra_aes_ofb_decrypt, + } + }, { + .cra_name = "ansi_cprng", + .cra_driver_name = "rng-aes-tegra", + .cra_flags = CRYPTO_ALG_TYPE_RNG, + .cra_ctxsize = sizeof(struct tegra_aes_ctx), + .cra_type = &crypto_rng_type, + .cra_u.rng = { + .rng_make_random = tegra_aes_get_random, + .rng_reset = tegra_aes_rng_reset, + .seedsize = AES_KEYSIZE_128 + (2 * DEFAULT_RNG_BLK_SZ), + } + } +}; + +static int tegra_aes_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct tegra_aes_dev *dd; + struct resource *res; + int err = -ENOMEM, i = 0, j; + + dd = devm_kzalloc(dev, sizeof(struct tegra_aes_dev), GFP_KERNEL); + if (dd == NULL) { + dev_err(dev, "unable to alloc data struct.\n"); + return err; + } + + dd->dev = dev; + platform_set_drvdata(pdev, dd); + + dd->slots = devm_kzalloc(dev, sizeof(struct tegra_aes_slot) * + AES_NR_KEYSLOTS, GFP_KERNEL); + if (dd->slots == NULL) { + dev_err(dev, "unable to alloc slot struct.\n"); + goto out; + } + + spin_lock_init(&dd->lock); + crypto_init_queue(&dd->queue, TEGRA_AES_QUEUE_LENGTH); + + /* Get the module base address */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "invalid resource type: base\n"); + err = -ENODEV; + goto out; + } + + if (!devm_request_mem_region(&pdev->dev, res->start, + resource_size(res), + dev_name(&pdev->dev))) { + dev_err(&pdev->dev, "Couldn't request MEM resource\n"); + return -ENODEV; + } + + dd->io_base = devm_ioremap(dev, res->start, resource_size(res)); + if (!dd->io_base) { + dev_err(dev, "can't ioremap register space\n"); + err = -ENOMEM; + goto out; + } + + /* Initialize the vde clock */ + dd->aes_clk = clk_get(dev, "vde"); + if (IS_ERR(dd->aes_clk)) { + dev_err(dev, "iclock intialization failed.\n"); + err = -ENODEV; + goto out; + } + + err = clk_set_rate(dd->aes_clk, ULONG_MAX); + if (err) { + dev_err(dd->dev, "iclk set_rate fail(%d)\n", err); + goto out; + } + + /* + * the foll contiguous memory is allocated as follows - + * - hardware key table + * - key schedule + */ + dd->ivkey_base = dma_alloc_coherent(dev, AES_HW_KEY_TABLE_LENGTH_BYTES, + &dd->ivkey_phys_base, + GFP_KERNEL); + if (!dd->ivkey_base) { + dev_err(dev, "can not allocate iv/key buffer\n"); + err = -ENOMEM; + goto out; + } + + dd->buf_in = dma_alloc_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES, + &dd->dma_buf_in, GFP_KERNEL); + if (!dd->buf_in) { + dev_err(dev, "can not allocate dma-in buffer\n"); + err = -ENOMEM; + goto out; + } + + dd->buf_out = dma_alloc_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES, + &dd->dma_buf_out, GFP_KERNEL); + if (!dd->buf_out) { + dev_err(dev, "can not allocate dma-out buffer\n"); + err = -ENOMEM; + goto out; + } + + init_completion(&dd->op_complete); + aes_wq = alloc_workqueue("tegra_aes_wq", WQ_HIGHPRI | WQ_UNBOUND, 1); + if (!aes_wq) { + dev_err(dev, "alloc_workqueue failed\n"); + goto out; + } + + /* get the irq */ + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res) { + dev_err(dev, "invalid resource type: base\n"); + err = -ENODEV; + goto out; + } + dd->irq = res->start; + + err = devm_request_irq(dev, dd->irq, aes_irq, IRQF_TRIGGER_HIGH | + IRQF_SHARED, "tegra-aes", dd); + if (err) { + dev_err(dev, "request_irq failed\n"); + goto out; + } + + mutex_init(&aes_lock); + INIT_LIST_HEAD(&dev_list); + + spin_lock_init(&list_lock); + spin_lock(&list_lock); + for (i = 0; i < AES_NR_KEYSLOTS; i++) { + if (i == SSK_SLOT_NUM) + continue; + dd->slots[i].slot_num = i; + INIT_LIST_HEAD(&dd->slots[i].node); + list_add_tail(&dd->slots[i].node, &dev_list); + } + spin_unlock(&list_lock); + + aes_dev = dd; + for (i = 0; i < ARRAY_SIZE(algs); i++) { + INIT_LIST_HEAD(&algs[i].cra_list); + + algs[i].cra_priority = 300; + algs[i].cra_ctxsize = sizeof(struct tegra_aes_ctx); + algs[i].cra_module = THIS_MODULE; + algs[i].cra_init = tegra_aes_cra_init; + algs[i].cra_exit = tegra_aes_cra_exit; + + err = crypto_register_alg(&algs[i]); + if (err) + goto out; + } + + dev_info(dev, "registered"); + return 0; + +out: + for (j = 0; j < i; j++) + crypto_unregister_alg(&algs[j]); + if (dd->ivkey_base) + dma_free_coherent(dev, AES_HW_KEY_TABLE_LENGTH_BYTES, + dd->ivkey_base, dd->ivkey_phys_base); + if (dd->buf_in) + dma_free_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES, + dd->buf_in, dd->dma_buf_in); + if (dd->buf_out) + dma_free_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES, + dd->buf_out, dd->dma_buf_out); + if (IS_ERR(dd->aes_clk)) + clk_put(dd->aes_clk); + if (aes_wq) + destroy_workqueue(aes_wq); + spin_lock(&list_lock); + list_del(&dev_list); + spin_unlock(&list_lock); + + aes_dev = NULL; + + dev_err(dev, "%s: initialization failed.\n", __func__); + return err; +} + +static int __devexit tegra_aes_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct tegra_aes_dev *dd = platform_get_drvdata(pdev); + int i; + + for (i = 0; i < ARRAY_SIZE(algs); i++) + crypto_unregister_alg(&algs[i]); + + cancel_work_sync(&aes_work); + destroy_workqueue(aes_wq); + spin_lock(&list_lock); + list_del(&dev_list); + spin_unlock(&list_lock); + + dma_free_coherent(dev, AES_HW_KEY_TABLE_LENGTH_BYTES, + dd->ivkey_base, dd->ivkey_phys_base); + dma_free_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES, + dd->buf_in, dd->dma_buf_in); + dma_free_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES, + dd->buf_out, dd->dma_buf_out); + clk_put(dd->aes_clk); + aes_dev = NULL; + + return 0; +} + +static struct of_device_id tegra_aes_of_match[] __devinitdata = { + { .compatible = "nvidia,tegra20-aes", }, + { .compatible = "nvidia,tegra30-aes", }, + { }, +}; + +static struct platform_driver tegra_aes_driver = { + .probe = tegra_aes_probe, + .remove = __devexit_p(tegra_aes_remove), + .driver = { + .name = "tegra-aes", + .owner = THIS_MODULE, + .of_match_table = tegra_aes_of_match, + }, +}; + +module_platform_driver(tegra_aes_driver); + +MODULE_DESCRIPTION("Tegra AES/OFB/CPRNG hw acceleration support."); +MODULE_AUTHOR("NVIDIA Corporation"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/crypto/tegra-aes.h b/drivers/crypto/tegra-aes.h new file mode 100644 index 00000000000..6006333a893 --- /dev/null +++ b/drivers/crypto/tegra-aes.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2010, NVIDIA 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __CRYPTODEV_TEGRA_AES_H +#define __CRYPTODEV_TEGRA_AES_H + +#define TEGRA_AES_ICMDQUE_WR 0x1000 +#define TEGRA_AES_CMDQUE_CONTROL 0x1008 +#define TEGRA_AES_INTR_STATUS 0x1018 +#define TEGRA_AES_INT_ENB 0x1040 +#define TEGRA_AES_CONFIG 0x1044 +#define TEGRA_AES_IRAM_ACCESS_CFG 0x10A0 +#define TEGRA_AES_SECURE_DEST_ADDR 0x1100 +#define TEGRA_AES_SECURE_INPUT_SELECT 0x1104 +#define TEGRA_AES_SECURE_CONFIG 0x1108 +#define TEGRA_AES_SECURE_CONFIG_EXT 0x110C +#define TEGRA_AES_SECURE_SECURITY 0x1110 +#define TEGRA_AES_SECURE_HASH_RESULT0 0x1120 +#define TEGRA_AES_SECURE_HASH_RESULT1 0x1124 +#define TEGRA_AES_SECURE_HASH_RESULT2 0x1128 +#define TEGRA_AES_SECURE_HASH_RESULT3 0x112C +#define TEGRA_AES_SECURE_SEC_SEL0 0x1140 +#define TEGRA_AES_SECURE_SEC_SEL1 0x1144 +#define TEGRA_AES_SECURE_SEC_SEL2 0x1148 +#define TEGRA_AES_SECURE_SEC_SEL3 0x114C +#define TEGRA_AES_SECURE_SEC_SEL4 0x1150 +#define TEGRA_AES_SECURE_SEC_SEL5 0x1154 +#define TEGRA_AES_SECURE_SEC_SEL6 0x1158 +#define TEGRA_AES_SECURE_SEC_SEL7 0x115C + +/* interrupt status reg masks and shifts */ +#define TEGRA_AES_ENGINE_BUSY_FIELD BIT(0) +#define TEGRA_AES_ICQ_EMPTY_FIELD BIT(3) +#define TEGRA_AES_DMA_BUSY_FIELD BIT(23) + +/* secure select reg masks and shifts */ +#define TEGRA_AES_SECURE_SEL0_KEYREAD_ENB0_FIELD BIT(0) + +/* secure config ext masks and shifts */ +#define TEGRA_AES_SECURE_KEY_SCH_DIS_FIELD BIT(15) + +/* secure config masks and shifts */ +#define TEGRA_AES_SECURE_KEY_INDEX_SHIFT 20 +#define TEGRA_AES_SECURE_KEY_INDEX_FIELD (0x1F << TEGRA_AES_SECURE_KEY_INDEX_SHIFT) +#define TEGRA_AES_SECURE_BLOCK_CNT_SHIFT 0 +#define TEGRA_AES_SECURE_BLOCK_CNT_FIELD (0xFFFFF << TEGRA_AES_SECURE_BLOCK_CNT_SHIFT) + +/* stream interface select masks and shifts */ +#define TEGRA_AES_CMDQ_CTRL_UCMDQEN_FIELD BIT(0) +#define TEGRA_AES_CMDQ_CTRL_ICMDQEN_FIELD BIT(1) +#define TEGRA_AES_CMDQ_CTRL_SRC_STM_SEL_FIELD BIT(4) +#define TEGRA_AES_CMDQ_CTRL_DST_STM_SEL_FIELD BIT(5) + +/* config register masks and shifts */ +#define TEGRA_AES_CONFIG_ENDIAN_ENB_FIELD BIT(10) +#define TEGRA_AES_CONFIG_MODE_SEL_SHIFT 0 +#define TEGRA_AES_CONFIG_MODE_SEL_FIELD (0x1F << TEGRA_AES_CONFIG_MODE_SEL_SHIFT) + +/* extended config */ +#define TEGRA_AES_SECURE_OFFSET_CNT_SHIFT 24 +#define TEGRA_AES_SECURE_OFFSET_CNT_FIELD (0xFF << TEGRA_AES_SECURE_OFFSET_CNT_SHIFT) +#define TEGRA_AES_SECURE_KEYSCHED_GEN_FIELD BIT(15) + +/* init vector select */ +#define TEGRA_AES_SECURE_IV_SELECT_SHIFT 10 +#define TEGRA_AES_SECURE_IV_SELECT_FIELD BIT(10) + +/* secure engine input */ +#define TEGRA_AES_SECURE_INPUT_ALG_SEL_SHIFT 28 +#define TEGRA_AES_SECURE_INPUT_ALG_SEL_FIELD (0xF << TEGRA_AES_SECURE_INPUT_ALG_SEL_SHIFT) +#define TEGRA_AES_SECURE_INPUT_KEY_LEN_SHIFT 16 +#define TEGRA_AES_SECURE_INPUT_KEY_LEN_FIELD (0xFFF << TEGRA_AES_SECURE_INPUT_KEY_LEN_SHIFT) +#define TEGRA_AES_SECURE_RNG_ENB_FIELD BIT(11) +#define TEGRA_AES_SECURE_CORE_SEL_SHIFT 9 +#define TEGRA_AES_SECURE_CORE_SEL_FIELD BIT(9) +#define TEGRA_AES_SECURE_VCTRAM_SEL_SHIFT 7 +#define TEGRA_AES_SECURE_VCTRAM_SEL_FIELD (0x3 << TEGRA_AES_SECURE_VCTRAM_SEL_SHIFT) +#define TEGRA_AES_SECURE_INPUT_SEL_SHIFT 5 +#define TEGRA_AES_SECURE_INPUT_SEL_FIELD (0x3 << TEGRA_AES_SECURE_INPUT_SEL_SHIFT) +#define TEGRA_AES_SECURE_XOR_POS_SHIFT 3 +#define TEGRA_AES_SECURE_XOR_POS_FIELD (0x3 << TEGRA_AES_SECURE_XOR_POS_SHIFT) +#define TEGRA_AES_SECURE_HASH_ENB_FIELD BIT(2) +#define TEGRA_AES_SECURE_ON_THE_FLY_FIELD BIT(0) + +/* interrupt error mask */ +#define TEGRA_AES_INT_ERROR_MASK 0xFFF000 + +#endif -- cgit v1.2.3-70-g09d2 From d0b03c5fe469ed0f3d7d94372c8bf77c64fcfce8 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 27 Dec 2011 15:01:30 +0100 Subject: hwrng: tx4939 - use devm_request_and_ioremap Reimplement a call to devm_request_mem_region followed by a call to ioremap or ioremap_nocache by a call to devm_request_and_ioremap. The semantic patch that makes this transformation is as follows: (http://coccinelle.lip6.fr/) // @nm@ expression myname; identifier i; @@ struct platform_driver i = { .driver = { .name = myname } }; @@ expression dev,res,size; expression nm.myname; @@ -if (!devm_request_mem_region(dev, res->start, size, - \(res->name\|dev_name(dev)\|myname\))) { - ... - return ...; -} ... when != res->start ( -devm_ioremap(dev,res->start,size) +devm_request_and_ioremap(dev,res) | -devm_ioremap_nocache(dev,res->start,size) +devm_request_and_ioremap(dev,res) ) ... when any when != res->start // Signed-off-by: Julia Lawall Signed-off-by: Herbert Xu --- drivers/char/hw_random/tx4939-rng.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/char/hw_random/tx4939-rng.c b/drivers/char/hw_random/tx4939-rng.c index 0bc0cb70210..de473ef3882 100644 --- a/drivers/char/hw_random/tx4939-rng.c +++ b/drivers/char/hw_random/tx4939-rng.c @@ -115,10 +115,7 @@ static int __init tx4939_rng_probe(struct platform_device *dev) rngdev = devm_kzalloc(&dev->dev, sizeof(*rngdev), GFP_KERNEL); if (!rngdev) return -ENOMEM; - if (!devm_request_mem_region(&dev->dev, r->start, resource_size(r), - dev_name(&dev->dev))) - return -EBUSY; - rngdev->base = devm_ioremap(&dev->dev, r->start, resource_size(r)); + rngdev->base = devm_request_and_ioremap(&dev->dev, r); if (!rngdev->base) return -EBUSY; -- cgit v1.2.3-70-g09d2 From d912bb7677f46d78a3cde8a4afd45a3fca4b34e9 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Tue, 1 Nov 2011 13:39:56 +0100 Subject: crypto: Add CRYPTO_ALG_KERN_DRIVER_ONLY flag The added CRYPTO_ALG_KERN_DRIVER_ONLY indicates whether a cipher is only available via a kernel driver. If the cipher implementation might be available by using an instruction set or by porting the kernel code, then it must not be set. Signed-off-by: Nikos Mavrogiannopoulos Signed-off-by: Herbert Xu --- drivers/crypto/caam/caamalg.c | 3 ++- drivers/crypto/geode-aes.c | 6 +++-- drivers/crypto/hifn_795x.c | 3 ++- drivers/crypto/ixp4xx_crypto.c | 2 ++ drivers/crypto/mv_cesa.c | 12 ++++++---- drivers/crypto/n2_core.c | 7 ++++-- drivers/crypto/omap-aes.c | 8 +++++-- drivers/crypto/omap-sham.c | 4 ++++ drivers/crypto/picoxcell_crypto.c | 46 +++++++++++++++++++++++++++++---------- drivers/crypto/s5p-sss.c | 6 +++-- drivers/crypto/talitos.c | 1 + include/linux/crypto.h | 5 +++++ 12 files changed, 78 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index e73cf2e8110..e9acadbb1d3 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -2205,7 +2205,8 @@ static struct caam_crypto_alg *caam_alg_alloc(struct device *ctrldev, alg->cra_blocksize = template->blocksize; alg->cra_alignmask = 0; alg->cra_ctxsize = sizeof(struct caam_ctx); - alg->cra_flags = CRYPTO_ALG_ASYNC | template->type; + alg->cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY | + template->type; switch (template->type) { case CRYPTO_ALG_TYPE_ABLKCIPHER: alg->cra_type = &crypto_ablkcipher_type; diff --git a/drivers/crypto/geode-aes.c b/drivers/crypto/geode-aes.c index 219d09cbb0d..f3e36c86b6c 100644 --- a/drivers/crypto/geode-aes.c +++ b/drivers/crypto/geode-aes.c @@ -393,7 +393,8 @@ static struct crypto_alg geode_cbc_alg = { .cra_driver_name = "cbc-aes-geode", .cra_priority = 400, .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | - CRYPTO_ALG_NEED_FALLBACK, + CRYPTO_ALG_KERN_DRIVER_ONLY | + CRYPTO_ALG_NEED_FALLBACK, .cra_init = fallback_init_blk, .cra_exit = fallback_exit_blk, .cra_blocksize = AES_MIN_BLOCK_SIZE, @@ -479,7 +480,8 @@ static struct crypto_alg geode_ecb_alg = { .cra_driver_name = "ecb-aes-geode", .cra_priority = 400, .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | - CRYPTO_ALG_NEED_FALLBACK, + CRYPTO_ALG_KERN_DRIVER_ONLY | + CRYPTO_ALG_NEED_FALLBACK, .cra_init = fallback_init_blk, .cra_exit = fallback_exit_blk, .cra_blocksize = AES_MIN_BLOCK_SIZE, diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index fe765f49de5..6bd9d176820 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c @@ -2494,7 +2494,8 @@ static int hifn_alg_alloc(struct hifn_device *dev, struct hifn_alg_template *t) t->drv_name, dev->name); alg->alg.cra_priority = 300; - alg->alg.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC; + alg->alg.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC; alg->alg.cra_blocksize = t->bsize; alg->alg.cra_ctxsize = sizeof(struct hifn_context); alg->alg.cra_alignmask = 0; diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c index 4c20c5bf605..a82c11af9f4 100644 --- a/drivers/crypto/ixp4xx_crypto.c +++ b/drivers/crypto/ixp4xx_crypto.c @@ -1449,6 +1449,7 @@ static int __init ixp_module_init(void) /* block ciphers */ cra->cra_type = &crypto_ablkcipher_type; cra->cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC; if (!cra->cra_ablkcipher.setkey) cra->cra_ablkcipher.setkey = ablk_setkey; @@ -1461,6 +1462,7 @@ static int __init ixp_module_init(void) /* authenc */ cra->cra_type = &crypto_aead_type; cra->cra_flags = CRYPTO_ALG_TYPE_AEAD | + CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC; cra->cra_aead.setkey = aead_setkey; cra->cra_aead.setauthsize = aead_setauthsize; diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c index 597235a2f8f..8ad2883505a 100644 --- a/drivers/crypto/mv_cesa.c +++ b/drivers/crypto/mv_cesa.c @@ -898,7 +898,8 @@ struct crypto_alg mv_aes_alg_ecb = { .cra_name = "ecb(aes)", .cra_driver_name = "mv-ecb-aes", .cra_priority = 300, - .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC, .cra_blocksize = 16, .cra_ctxsize = sizeof(struct mv_ctx), .cra_alignmask = 0, @@ -920,7 +921,8 @@ struct crypto_alg mv_aes_alg_cbc = { .cra_name = "cbc(aes)", .cra_driver_name = "mv-cbc-aes", .cra_priority = 300, - .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct mv_ctx), .cra_alignmask = 0, @@ -952,7 +954,8 @@ struct ahash_alg mv_sha1_alg = { .cra_driver_name = "mv-sha1", .cra_priority = 300, .cra_flags = - CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, + CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY | + CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = SHA1_BLOCK_SIZE, .cra_ctxsize = sizeof(struct mv_tfm_hash_ctx), .cra_init = mv_cra_hash_sha1_init, @@ -976,7 +979,8 @@ struct ahash_alg mv_hmac_sha1_alg = { .cra_driver_name = "mv-hmac-sha1", .cra_priority = 300, .cra_flags = - CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, + CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY | + CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = SHA1_BLOCK_SIZE, .cra_ctxsize = sizeof(struct mv_tfm_hash_ctx), .cra_init = mv_cra_hash_hmac_sha1_init, diff --git a/drivers/crypto/n2_core.c b/drivers/crypto/n2_core.c index 8944dabc0e3..67b97c5fd85 100644 --- a/drivers/crypto/n2_core.c +++ b/drivers/crypto/n2_core.c @@ -1402,7 +1402,8 @@ static int __devinit __n2_register_one_cipher(const struct n2_cipher_tmpl *tmpl) snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", tmpl->name); snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s-n2", tmpl->drv_name); alg->cra_priority = N2_CRA_PRIORITY; - alg->cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC; + alg->cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC; alg->cra_blocksize = tmpl->block_size; p->enc_type = tmpl->enc_type; alg->cra_ctxsize = sizeof(struct n2_cipher_context); @@ -1493,7 +1494,9 @@ static int __devinit __n2_register_one_ahash(const struct n2_hash_tmpl *tmpl) snprintf(base->cra_name, CRYPTO_MAX_ALG_NAME, "%s", tmpl->name); snprintf(base->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s-n2", tmpl->name); base->cra_priority = N2_CRA_PRIORITY; - base->cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_NEED_FALLBACK; + base->cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_KERN_DRIVER_ONLY | + CRYPTO_ALG_NEED_FALLBACK; base->cra_blocksize = tmpl->block_size; base->cra_ctxsize = sizeof(struct n2_hash_ctx); base->cra_module = THIS_MODULE; diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c index 5b970d9e995..63e57b57a12 100644 --- a/drivers/crypto/omap-aes.c +++ b/drivers/crypto/omap-aes.c @@ -756,7 +756,9 @@ static struct crypto_alg algs[] = { .cra_name = "ecb(aes)", .cra_driver_name = "ecb-aes-omap", .cra_priority = 100, - .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY | + CRYPTO_ALG_ASYNC, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct omap_aes_ctx), .cra_alignmask = 0, @@ -776,7 +778,9 @@ static struct crypto_alg algs[] = { .cra_name = "cbc(aes)", .cra_driver_name = "cbc-aes-omap", .cra_priority = 100, - .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY | + CRYPTO_ALG_ASYNC, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct omap_aes_ctx), .cra_alignmask = 0, diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c index 6399a8f1938..a3fd6fc504b 100644 --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c @@ -953,6 +953,7 @@ static struct ahash_alg algs[] = { .cra_driver_name = "omap-sha1", .cra_priority = 100, .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = SHA1_BLOCK_SIZE, @@ -975,6 +976,7 @@ static struct ahash_alg algs[] = { .cra_driver_name = "omap-md5", .cra_priority = 100, .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = SHA1_BLOCK_SIZE, @@ -998,6 +1000,7 @@ static struct ahash_alg algs[] = { .cra_driver_name = "omap-hmac-sha1", .cra_priority = 100, .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = SHA1_BLOCK_SIZE, @@ -1022,6 +1025,7 @@ static struct ahash_alg algs[] = { .cra_driver_name = "omap-hmac-md5", .cra_priority = 100, .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = SHA1_BLOCK_SIZE, diff --git a/drivers/crypto/picoxcell_crypto.c b/drivers/crypto/picoxcell_crypto.c index 58480d00932..410a03c01ca 100644 --- a/drivers/crypto/picoxcell_crypto.c +++ b/drivers/crypto/picoxcell_crypto.c @@ -1322,6 +1322,7 @@ static struct spacc_alg ipsec_engine_algs[] = { .cra_driver_name = "cbc-aes-picoxcell", .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = AES_BLOCK_SIZE, @@ -1349,6 +1350,7 @@ static struct spacc_alg ipsec_engine_algs[] = { .cra_driver_name = "ecb-aes-picoxcell", .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct spacc_ablk_ctx), @@ -1373,7 +1375,9 @@ static struct spacc_alg ipsec_engine_algs[] = { .cra_name = "cbc(des)", .cra_driver_name = "cbc-des-picoxcell", .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_blocksize = DES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct spacc_ablk_ctx), .cra_type = &crypto_ablkcipher_type, @@ -1398,7 +1402,9 @@ static struct spacc_alg ipsec_engine_algs[] = { .cra_name = "ecb(des)", .cra_driver_name = "ecb-des-picoxcell", .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_blocksize = DES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct spacc_ablk_ctx), .cra_type = &crypto_ablkcipher_type, @@ -1422,7 +1428,9 @@ static struct spacc_alg ipsec_engine_algs[] = { .cra_name = "cbc(des3_ede)", .cra_driver_name = "cbc-des3-ede-picoxcell", .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_blocksize = DES3_EDE_BLOCK_SIZE, .cra_ctxsize = sizeof(struct spacc_ablk_ctx), .cra_type = &crypto_ablkcipher_type, @@ -1447,7 +1455,9 @@ static struct spacc_alg ipsec_engine_algs[] = { .cra_name = "ecb(des3_ede)", .cra_driver_name = "ecb-des3-ede-picoxcell", .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_blocksize = DES3_EDE_BLOCK_SIZE, .cra_ctxsize = sizeof(struct spacc_ablk_ctx), .cra_type = &crypto_ablkcipher_type, @@ -1472,7 +1482,9 @@ static struct spacc_alg ipsec_engine_algs[] = { .cra_name = "authenc(hmac(sha1),cbc(aes))", .cra_driver_name = "authenc-hmac-sha1-cbc-aes-picoxcell", .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_AEAD | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct spacc_aead_ctx), .cra_type = &crypto_aead_type, @@ -1500,7 +1512,9 @@ static struct spacc_alg ipsec_engine_algs[] = { .cra_name = "authenc(hmac(sha256),cbc(aes))", .cra_driver_name = "authenc-hmac-sha256-cbc-aes-picoxcell", .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_AEAD | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct spacc_aead_ctx), .cra_type = &crypto_aead_type, @@ -1527,7 +1541,9 @@ static struct spacc_alg ipsec_engine_algs[] = { .cra_name = "authenc(hmac(md5),cbc(aes))", .cra_driver_name = "authenc-hmac-md5-cbc-aes-picoxcell", .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_AEAD | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct spacc_aead_ctx), .cra_type = &crypto_aead_type, @@ -1554,7 +1570,9 @@ static struct spacc_alg ipsec_engine_algs[] = { .cra_name = "authenc(hmac(sha1),cbc(des3_ede))", .cra_driver_name = "authenc-hmac-sha1-cbc-3des-picoxcell", .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_AEAD | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_blocksize = DES3_EDE_BLOCK_SIZE, .cra_ctxsize = sizeof(struct spacc_aead_ctx), .cra_type = &crypto_aead_type, @@ -1582,7 +1600,9 @@ static struct spacc_alg ipsec_engine_algs[] = { .cra_name = "authenc(hmac(sha256),cbc(des3_ede))", .cra_driver_name = "authenc-hmac-sha256-cbc-3des-picoxcell", .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_AEAD | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_blocksize = DES3_EDE_BLOCK_SIZE, .cra_ctxsize = sizeof(struct spacc_aead_ctx), .cra_type = &crypto_aead_type, @@ -1609,7 +1629,9 @@ static struct spacc_alg ipsec_engine_algs[] = { .cra_name = "authenc(hmac(md5),cbc(des3_ede))", .cra_driver_name = "authenc-hmac-md5-cbc-3des-picoxcell", .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_AEAD | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_blocksize = DES3_EDE_BLOCK_SIZE, .cra_ctxsize = sizeof(struct spacc_aead_ctx), .cra_type = &crypto_aead_type, @@ -1639,7 +1661,9 @@ static struct spacc_alg l2_engine_algs[] = { .cra_name = "f8(kasumi)", .cra_driver_name = "f8-kasumi-picoxcell", .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_GIVCIPHER | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_GIVCIPHER | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_blocksize = 8, .cra_ctxsize = sizeof(struct spacc_ablk_ctx), .cra_type = &crypto_ablkcipher_type, diff --git a/drivers/crypto/s5p-sss.c b/drivers/crypto/s5p-sss.c index 3376bca200f..bc986f80608 100644 --- a/drivers/crypto/s5p-sss.c +++ b/drivers/crypto/s5p-sss.c @@ -518,7 +518,8 @@ static struct crypto_alg algs[] = { .cra_driver_name = "ecb-aes-s5p", .cra_priority = 100, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | - CRYPTO_ALG_ASYNC, + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct s5p_aes_ctx), .cra_alignmask = 0x0f, @@ -538,7 +539,8 @@ static struct crypto_alg algs[] = { .cra_driver_name = "cbc-aes-s5p", .cra_priority = 100, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | - CRYPTO_ALG_ASYNC, + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct s5p_aes_ctx), .cra_alignmask = 0x0f, diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 2d8c7890168..dc641c79652 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -2648,6 +2648,7 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev, alg->cra_priority = TALITOS_CRA_PRIORITY; alg->cra_alignmask = 0; alg->cra_ctxsize = sizeof(struct talitos_ctx); + alg->cra_flags |= CRYPTO_ALG_KERN_DRIVER_ONLY; t_alg->dev = dev; diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 8a94217b298..a8fa6541b86 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -75,6 +75,11 @@ */ #define CRYPTO_ALG_INSTANCE 0x00000800 +/* Set this bit if the algorithm provided is hardware accelerated but + * not available to userspace via instruction set or so. + */ +#define CRYPTO_ALG_KERN_DRIVER_ONLY 0x00001000 + /* * Transform masks and values (for crt_flags). */ -- cgit v1.2.3-70-g09d2 From e7a2577a410a066ae409f805618f7e84748a537d Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 9 Jan 2012 10:40:49 +0100 Subject: crypto: ixp4xx - convert GFP_KERNEL to GFP_ATOMIC The function is called with locks held and thus should not use GFP_KERNEL. The semantic patch that makes this report is available in scripts/coccinelle/locks/call_kern.cocci. More information about semantic patching is available at http://coccinelle.lip6.fr/ Signed-off-by: Julia Lawall Signed-off-by: Herbert Xu --- drivers/crypto/ixp4xx_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c index a82c11af9f4..0053d7ebb5c 100644 --- a/drivers/crypto/ixp4xx_crypto.c +++ b/drivers/crypto/ixp4xx_crypto.c @@ -265,7 +265,7 @@ static int setup_crypt_desc(void) BUILD_BUG_ON(sizeof(struct crypt_ctl) != 64); crypt_virt = dma_alloc_coherent(dev, NPE_QLEN * sizeof(struct crypt_ctl), - &crypt_phys, GFP_KERNEL); + &crypt_phys, GFP_ATOMIC); if (!crypt_virt) return -ENOMEM; memset(crypt_virt, 0, NPE_QLEN * sizeof(struct crypt_ctl)); -- cgit v1.2.3-70-g09d2 From e863f9ccc7658883be7b42eb63851aef9da7630c Mon Sep 17 00:00:00 2001 From: Hemant Agrawal Date: Mon, 9 Jan 2012 18:26:44 -0600 Subject: crypto: caam - add sha224 and sha384 variants to existing AEAD algorithms Signed-off-by: Hemant Agrawal Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/caamalg.c | 115 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) (limited to 'drivers') diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index e9acadbb1d3..4cd2d84a2a1 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -1843,6 +1843,25 @@ static struct caam_alg_template driver_algs[] = { .class2_alg_type = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC_PRECOMP, .alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC, }, + { + .name = "authenc(hmac(sha224),cbc(aes))", + .driver_name = "authenc-hmac-sha224-cbc-aes-caam", + .blocksize = AES_BLOCK_SIZE, + .template_aead = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, + .decrypt = aead_decrypt, + .givencrypt = aead_givencrypt, + .geniv = "", + .ivsize = AES_BLOCK_SIZE, + .maxauthsize = SHA224_DIGEST_SIZE, + }, + .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, + .class2_alg_type = OP_ALG_ALGSEL_SHA224 | + OP_ALG_AAI_HMAC_PRECOMP, + .alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC, + }, { .name = "authenc(hmac(sha256),cbc(aes))", .driver_name = "authenc-hmac-sha256-cbc-aes-caam", @@ -1863,6 +1882,26 @@ static struct caam_alg_template driver_algs[] = { OP_ALG_AAI_HMAC_PRECOMP, .alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC, }, + { + .name = "authenc(hmac(sha384),cbc(aes))", + .driver_name = "authenc-hmac-sha384-cbc-aes-caam", + .blocksize = AES_BLOCK_SIZE, + .template_aead = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, + .decrypt = aead_decrypt, + .givencrypt = aead_givencrypt, + .geniv = "", + .ivsize = AES_BLOCK_SIZE, + .maxauthsize = SHA384_DIGEST_SIZE, + }, + .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, + .class2_alg_type = OP_ALG_ALGSEL_SHA384 | + OP_ALG_AAI_HMAC_PRECOMP, + .alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC, + }, + { .name = "authenc(hmac(sha512),cbc(aes))", .driver_name = "authenc-hmac-sha512-cbc-aes-caam", @@ -1921,6 +1960,25 @@ static struct caam_alg_template driver_algs[] = { .class2_alg_type = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC_PRECOMP, .alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC, }, + { + .name = "authenc(hmac(sha224),cbc(des3_ede))", + .driver_name = "authenc-hmac-sha224-cbc-des3_ede-caam", + .blocksize = DES3_EDE_BLOCK_SIZE, + .template_aead = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, + .decrypt = aead_decrypt, + .givencrypt = aead_givencrypt, + .geniv = "", + .ivsize = DES3_EDE_BLOCK_SIZE, + .maxauthsize = SHA224_DIGEST_SIZE, + }, + .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, + .class2_alg_type = OP_ALG_ALGSEL_SHA224 | + OP_ALG_AAI_HMAC_PRECOMP, + .alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC, + }, { .name = "authenc(hmac(sha256),cbc(des3_ede))", .driver_name = "authenc-hmac-sha256-cbc-des3_ede-caam", @@ -1941,6 +1999,25 @@ static struct caam_alg_template driver_algs[] = { OP_ALG_AAI_HMAC_PRECOMP, .alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC, }, + { + .name = "authenc(hmac(sha384),cbc(des3_ede))", + .driver_name = "authenc-hmac-sha384-cbc-des3_ede-caam", + .blocksize = DES3_EDE_BLOCK_SIZE, + .template_aead = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, + .decrypt = aead_decrypt, + .givencrypt = aead_givencrypt, + .geniv = "", + .ivsize = DES3_EDE_BLOCK_SIZE, + .maxauthsize = SHA384_DIGEST_SIZE, + }, + .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, + .class2_alg_type = OP_ALG_ALGSEL_SHA384 | + OP_ALG_AAI_HMAC_PRECOMP, + .alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC, + }, { .name = "authenc(hmac(sha512),cbc(des3_ede))", .driver_name = "authenc-hmac-sha512-cbc-des3_ede-caam", @@ -1999,6 +2076,25 @@ static struct caam_alg_template driver_algs[] = { .class2_alg_type = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC_PRECOMP, .alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC, }, + { + .name = "authenc(hmac(sha224),cbc(des))", + .driver_name = "authenc-hmac-sha224-cbc-des-caam", + .blocksize = DES_BLOCK_SIZE, + .template_aead = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, + .decrypt = aead_decrypt, + .givencrypt = aead_givencrypt, + .geniv = "", + .ivsize = DES_BLOCK_SIZE, + .maxauthsize = SHA224_DIGEST_SIZE, + }, + .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, + .class2_alg_type = OP_ALG_ALGSEL_SHA224 | + OP_ALG_AAI_HMAC_PRECOMP, + .alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC, + }, { .name = "authenc(hmac(sha256),cbc(des))", .driver_name = "authenc-hmac-sha256-cbc-des-caam", @@ -2019,6 +2115,25 @@ static struct caam_alg_template driver_algs[] = { OP_ALG_AAI_HMAC_PRECOMP, .alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC, }, + { + .name = "authenc(hmac(sha384),cbc(des))", + .driver_name = "authenc-hmac-sha384-cbc-des-caam", + .blocksize = DES_BLOCK_SIZE, + .template_aead = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, + .decrypt = aead_decrypt, + .givencrypt = aead_givencrypt, + .geniv = "", + .ivsize = DES_BLOCK_SIZE, + .maxauthsize = SHA384_DIGEST_SIZE, + }, + .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, + .class2_alg_type = OP_ALG_ALGSEL_SHA384 | + OP_ALG_AAI_HMAC_PRECOMP, + .alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC, + }, { .name = "authenc(hmac(sha512),cbc(des))", .driver_name = "authenc-hmac-sha512-cbc-des-caam", -- cgit v1.2.3-70-g09d2 From 0113529f37bcd17399403c68736b8ba59c7397b7 Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Mon, 9 Jan 2012 18:26:49 -0600 Subject: crypto: caam - be less noisy on startup sha224 and 384 support extends caam noise to 21 lines. Do the same as commit 5b859b6 "crypto: talitos - be less noisy on startup", but for caam, and display: caam ffe300000.crypto: fsl,sec-v4.0 algorithms registered in /proc/crypto Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/caamalg.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index 4cd2d84a2a1..534a36469d5 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -2401,12 +2401,12 @@ static int __init caam_algapi_init(void) 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); - dev_info(ctrldev, "%s\n", - t_alg->crypto_alg.cra_driver_name); - } } + if (!list_empty(&priv->alg_list)) + dev_info(ctrldev, "%s algorithms registered in /proc/crypto\n", + (char *)of_get_property(dev_node, "compatible", NULL)); return err; } -- cgit v1.2.3-70-g09d2 From c1762a3fe196483981f91b926f5f6ee18af757f2 Mon Sep 17 00:00:00 2001 From: Thirumalai Pachamuthu Date: Thu, 12 Jan 2012 18:21:39 +0530 Subject: ath6kl: Add support for uAPSD * A new APSD power save queue is added in the station structure. * When a station has APSD capability and goes to power save, the frame designated to the station will be buffered in APSD queue. * When the host receives a frame which the firmware marked as trigger, host delivers the buffered frame from the APSD power save queue. Number of frames to deliver is decided by MAX SP length. * When a station moves from sleep to awake state, all frames buffered in APSD power save queue are sent to the firmware. * When a station is disconnected, all frames bufferes in APSD power save queue are dropped. * When the host queues the first frame to the APSD queue or removes the last frame from the APSD queue, it is indicated to the firmware using WMI_AP_APSD_BUFFERED_TRAFFIC_CMD. kvalo: fix buggy handling of sks queues, made it more obvious the user priority when wmm is disabled, remove unneed else block and combined some variable declarations Signed-off-by: Thirumalai Pachamuthu Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 6 + drivers/net/wireless/ath/ath6kl/core.h | 10 +- drivers/net/wireless/ath/ath6kl/main.c | 9 +- drivers/net/wireless/ath/ath6kl/txrx.c | 249 ++++++++++++++++++++++++----- drivers/net/wireless/ath/ath6kl/wmi.c | 62 ++++++- drivers/net/wireless/ath/ath6kl/wmi.h | 41 ++++- 6 files changed, 324 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 1a98c9256c6..a13ecec0070 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -2253,6 +2253,11 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev, p.dot11_auth_mode = vif->dot11_auth_mode; p.ch = cpu_to_le16(vif->next_chan); + /* Enable uAPSD support by default */ + res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true); + if (res < 0) + return res; + if (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) { p.nw_subtype = SUBTYPE_P2PGO; } else { @@ -2740,6 +2745,7 @@ struct ath6kl *ath6kl_core_alloc(struct device *dev) for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) { spin_lock_init(&ar->sta_list[ctr].psq_lock); skb_queue_head_init(&ar->sta_list[ctr].psq); + skb_queue_head_init(&ar->sta_list[ctr].apsdq); } skb_queue_head_init(&ar->mcastpsq); diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index f4da5e19a36..ba3953918e4 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -44,6 +44,10 @@ #define ATH6KL_MAX_ENDPOINTS 4 #define MAX_NODE_NUM 15 +#define ATH6KL_APSD_ALL_FRAME 0xFFFF +#define ATH6KL_APSD_NUM_OF_AC 0x4 +#define ATH6KL_APSD_FRAME_MASK 0xF + /* Extra bytes for htc header alignment */ #define ATH6KL_HTC_ALIGN_BYTES 3 @@ -146,6 +150,8 @@ struct ath6kl_fw_ie { #define STA_PS_AWAKE BIT(0) #define STA_PS_SLEEP BIT(1) #define STA_PS_POLLED BIT(2) +#define STA_PS_APSD_TRIGGER BIT(3) +#define STA_PS_APSD_EOSP BIT(4) /* HTC TX packet tagging definitions */ #define ATH6KL_CONTROL_PKT_TAG HTC_TX_PACKET_TAG_USER_DEFINED @@ -282,6 +288,8 @@ struct ath6kl_sta { u8 wpa_ie[ATH6KL_MAX_IE]; struct sk_buff_head psq; spinlock_t psq_lock; + u8 apsd_info; + struct sk_buff_head apsdq; }; struct ath6kl_version { @@ -714,7 +722,7 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel); void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr, u8 keymgmt, u8 ucipher, u8 auth, - u8 assoc_req_len, u8 *assoc_info); + u8 assoc_req_len, u8 *assoc_info, u8 apsd_info); void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid, u8 assoc_resp_len, u8 *assoc_info, u16 prot_reason_status); diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index 4c26572214c..53f97db4a7a 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -53,7 +53,8 @@ struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid) } static void ath6kl_add_new_sta(struct ath6kl *ar, u8 *mac, u16 aid, u8 *wpaie, - size_t ielen, u8 keymgmt, u8 ucipher, u8 auth) + size_t ielen, u8 keymgmt, u8 ucipher, u8 auth, + u8 apsd_info) { struct ath6kl_sta *sta; u8 free_slot; @@ -68,6 +69,7 @@ static void ath6kl_add_new_sta(struct ath6kl *ar, u8 *mac, u16 aid, u8 *wpaie, sta->keymgmt = keymgmt; sta->ucipher = ucipher; sta->auth = auth; + sta->apsd_info = apsd_info; ar->sta_list_index = ar->sta_list_index | (1 << free_slot); ar->ap_stats.sta[free_slot].aid = cpu_to_le32(aid); @@ -80,6 +82,7 @@ static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i) /* empty the queued pkts in the PS queue if any */ spin_lock_bh(&sta->psq_lock); skb_queue_purge(&sta->psq); + skb_queue_purge(&sta->apsdq); spin_unlock_bh(&sta->psq_lock); memset(&ar->ap_stats.sta[sta->aid - 1], 0, @@ -425,7 +428,7 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel) void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr, u8 keymgmt, u8 ucipher, u8 auth, - u8 assoc_req_len, u8 *assoc_info) + u8 assoc_req_len, u8 *assoc_info, u8 apsd_info) { struct ath6kl *ar = vif->ar; u8 *ies = NULL, *wpa_ie = NULL, *pos; @@ -483,7 +486,7 @@ void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr, ath6kl_add_new_sta(ar, mac_addr, aid, wpa_ie, wpa_ie ? 2 + wpa_ie[1] : 0, - keymgmt, ucipher, auth); + keymgmt, ucipher, auth, apsd_info); /* send event to application */ memset(&sinfo, 0, sizeof(sinfo)); diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index fcea82479cd..91bbc1ffa49 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -77,12 +77,120 @@ static u8 ath6kl_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, return ar->node_map[ep_map].ep_id; } +static bool ath6kl_process_uapsdq(struct ath6kl_sta *conn, + struct ath6kl_vif *vif, + struct sk_buff *skb, + u32 *flags) +{ + struct ath6kl *ar = vif->ar; + bool is_apsdq_empty = false; + struct ethhdr *datap = (struct ethhdr *) skb->data; + u8 up, traffic_class, *ip_hdr; + u16 ether_type; + struct ath6kl_llc_snap_hdr *llc_hdr; + + if (conn->sta_flags & STA_PS_APSD_TRIGGER) { + /* + * This tx is because of a uAPSD trigger, determine + * more and EOSP bit. Set EOSP if queue is empty + * or sufficient frames are delivered for this trigger. + */ + spin_lock_bh(&conn->psq_lock); + if (!skb_queue_empty(&conn->apsdq)) + *flags |= WMI_DATA_HDR_FLAGS_MORE; + else if (conn->sta_flags & STA_PS_APSD_EOSP) + *flags |= WMI_DATA_HDR_FLAGS_EOSP; + *flags |= WMI_DATA_HDR_FLAGS_UAPSD; + spin_unlock_bh(&conn->psq_lock); + return false; + } else if (!conn->apsd_info) + return false; + + if (test_bit(WMM_ENABLED, &vif->flags)) { + ether_type = be16_to_cpu(datap->h_proto); + if (is_ethertype(ether_type)) { + /* packet is in DIX format */ + ip_hdr = (u8 *)(datap + 1); + } else { + /* packet is in 802.3 format */ + llc_hdr = (struct ath6kl_llc_snap_hdr *) + (datap + 1); + ether_type = be16_to_cpu(llc_hdr->eth_type); + ip_hdr = (u8 *)(llc_hdr + 1); + } + + if (ether_type == IP_ETHERTYPE) + up = ath6kl_wmi_determine_user_priority( + ip_hdr, 0); + } else { + up = 0; + } + + traffic_class = ath6kl_wmi_get_traffic_class(up); + + if ((conn->apsd_info & (1 << traffic_class)) == 0) + return false; + + /* Queue the frames if the STA is sleeping */ + spin_lock_bh(&conn->psq_lock); + is_apsdq_empty = skb_queue_empty(&conn->apsdq); + skb_queue_tail(&conn->apsdq, skb); + spin_unlock_bh(&conn->psq_lock); + + /* + * If this is the first pkt getting queued + * for this STA, update the PVB for this STA + */ + if (is_apsdq_empty) { + ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi, + vif->fw_vif_idx, + conn->aid, 1, 0); + } + *flags |= WMI_DATA_HDR_FLAGS_UAPSD; + + return true; +} + +static bool ath6kl_process_psq(struct ath6kl_sta *conn, + struct ath6kl_vif *vif, + struct sk_buff *skb, + u32 *flags) +{ + bool is_psq_empty = false; + struct ath6kl *ar = vif->ar; + + if (conn->sta_flags & STA_PS_POLLED) { + spin_lock_bh(&conn->psq_lock); + if (!skb_queue_empty(&conn->psq)) + *flags |= WMI_DATA_HDR_FLAGS_MORE; + spin_unlock_bh(&conn->psq_lock); + return false; + } + + /* Queue the frames if the STA is sleeping */ + spin_lock_bh(&conn->psq_lock); + is_psq_empty = skb_queue_empty(&conn->psq); + skb_queue_tail(&conn->psq, skb); + spin_unlock_bh(&conn->psq_lock); + + /* + * If this is the first pkt getting queued + * for this STA, update the PVB for this + * STA. + */ + if (is_psq_empty) + ath6kl_wmi_set_pvb_cmd(ar->wmi, + vif->fw_vif_idx, + conn->aid, 1); + return true; +} + static bool ath6kl_powersave_ap(struct ath6kl_vif *vif, struct sk_buff *skb, - bool *more_data) + u32 *flags) { struct ethhdr *datap = (struct ethhdr *) skb->data; struct ath6kl_sta *conn = NULL; - bool ps_queued = false, is_psq_empty = false; + bool ps_queued = false; struct ath6kl *ar = vif->ar; if (is_multicast_ether_addr(datap->h_dest)) { @@ -128,7 +236,7 @@ static bool ath6kl_powersave_ap(struct ath6kl_vif *vif, struct sk_buff *skb, */ spin_lock_bh(&ar->mcastpsq_lock); if (!skb_queue_empty(&ar->mcastpsq)) - *more_data = true; + *flags |= WMI_DATA_HDR_FLAGS_MORE; spin_unlock_bh(&ar->mcastpsq_lock); } } @@ -142,37 +250,13 @@ static bool ath6kl_powersave_ap(struct ath6kl_vif *vif, struct sk_buff *skb, } if (conn->sta_flags & STA_PS_SLEEP) { - if (!(conn->sta_flags & STA_PS_POLLED)) { - /* Queue the frames if the STA is sleeping */ - spin_lock_bh(&conn->psq_lock); - is_psq_empty = skb_queue_empty(&conn->psq); - skb_queue_tail(&conn->psq, skb); - spin_unlock_bh(&conn->psq_lock); - - /* - * If this is the first pkt getting queued - * for this STA, update the PVB for this - * STA. - */ - if (is_psq_empty) - ath6kl_wmi_set_pvb_cmd(ar->wmi, - vif->fw_vif_idx, - conn->aid, 1); - - ps_queued = true; - } else { - /* - * This tx is because of a PsPoll. - * Determine if MoreData bit has to be set. - */ - spin_lock_bh(&conn->psq_lock); - if (!skb_queue_empty(&conn->psq)) - *more_data = true; - spin_unlock_bh(&conn->psq_lock); - } + ps_queued = ath6kl_process_uapsdq(conn, + vif, skb, flags); + if (!(*flags & WMI_DATA_HDR_FLAGS_UAPSD)) + ps_queued = ath6kl_process_psq(conn, + vif, skb, flags); } } - return ps_queued; } @@ -242,12 +326,13 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) u32 map_no = 0; u16 htc_tag = ATH6KL_DATA_PKT_TAG; u8 ac = 99 ; /* initialize to unmapped ac */ - bool chk_adhoc_ps_mapping = false, more_data = false; + bool chk_adhoc_ps_mapping = false; int ret; struct wmi_tx_meta_v2 meta_v2; void *meta; u8 csum_start = 0, csum_dest = 0, csum = skb->ip_summed; u8 meta_ver = 0; + u32 flags = 0; ath6kl_dbg(ATH6KL_DBG_WLAN_TX, "%s: skb=0x%p, data=0x%p, len=0x%x\n", __func__, @@ -264,7 +349,7 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) /* AP mode Power saving processing */ if (vif->nw_type == AP_NETWORK) { - if (ath6kl_powersave_ap(vif, skb, &more_data)) + if (ath6kl_powersave_ap(vif, skb, &flags)) return 0; } @@ -308,7 +393,7 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) } ret = ath6kl_wmi_data_hdr_add(ar->wmi, skb, - DATA_MSGTYPE, more_data, 0, + DATA_MSGTYPE, flags, 0, meta_ver, meta, vif->fw_vif_idx); @@ -1093,6 +1178,76 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, return is_queued; } +static void ath6kl_uapsd_trigger_frame_rx(struct ath6kl_vif *vif, + struct ath6kl_sta *conn) +{ + struct ath6kl *ar = vif->ar; + bool is_apsdq_empty, is_apsdq_empty_at_start; + u32 num_frames_to_deliver, flags; + struct sk_buff *skb = NULL; + + /* + * If the APSD q for this STA is not empty, dequeue and + * send a pkt from the head of the q. Also update the + * More data bit in the WMI_DATA_HDR if there are + * more pkts for this STA in the APSD q. + * If there are no more pkts for this STA, + * update the APSD bitmap for this STA. + */ + + num_frames_to_deliver = (conn->apsd_info >> ATH6KL_APSD_NUM_OF_AC) & + ATH6KL_APSD_FRAME_MASK; + /* + * Number of frames to send in a service period is + * indicated by the station + * in the QOS_INFO of the association request + * If it is zero, send all frames + */ + if (!num_frames_to_deliver) + num_frames_to_deliver = ATH6KL_APSD_ALL_FRAME; + + spin_lock_bh(&conn->psq_lock); + is_apsdq_empty = skb_queue_empty(&conn->apsdq); + spin_unlock_bh(&conn->psq_lock); + is_apsdq_empty_at_start = is_apsdq_empty; + + while ((!is_apsdq_empty) && (num_frames_to_deliver)) { + + spin_lock_bh(&conn->psq_lock); + skb = skb_dequeue(&conn->apsdq); + is_apsdq_empty = skb_queue_empty(&conn->apsdq); + spin_unlock_bh(&conn->psq_lock); + + /* + * Set the STA flag to Trigger delivery, + * so that the frame will go out + */ + conn->sta_flags |= STA_PS_APSD_TRIGGER; + num_frames_to_deliver--; + + /* Last frame in the service period, set EOSP or queue empty */ + if ((is_apsdq_empty) || (!num_frames_to_deliver)) + conn->sta_flags |= STA_PS_APSD_EOSP; + + ath6kl_data_tx(skb, vif->ndev); + conn->sta_flags &= ~(STA_PS_APSD_TRIGGER); + conn->sta_flags &= ~(STA_PS_APSD_EOSP); + } + + if (is_apsdq_empty) { + if (is_apsdq_empty_at_start) + flags = WMI_AP_APSD_NO_DELIVERY_FRAMES; + else + flags = 0; + + ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi, + vif->fw_vif_idx, + conn->aid, 0, flags); + } + + return; +} + void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) { struct ath6kl *ar = target->dev->ar; @@ -1104,6 +1259,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) int status = packet->status; enum htc_endpoint_id ept = packet->endpoint; bool is_amsdu, prev_ps, ps_state = false; + bool trig_state = false; struct ath6kl_sta *conn = NULL; struct sk_buff *skb1 = NULL; struct ethhdr *datap = NULL; @@ -1197,6 +1353,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) WMI_DATA_HDR_PS_MASK); offset = sizeof(struct wmi_data_hdr); + trig_state = !!(le16_to_cpu(dhdr->info3) & WMI_DATA_HDR_TRIG); switch (meta_type) { case 0: @@ -1235,18 +1392,36 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) else conn->sta_flags &= ~STA_PS_SLEEP; + /* Accept trigger only when the station is in sleep */ + if ((conn->sta_flags & STA_PS_SLEEP) && trig_state) + ath6kl_uapsd_trigger_frame_rx(vif, conn); + if (prev_ps ^ !!(conn->sta_flags & STA_PS_SLEEP)) { if (!(conn->sta_flags & STA_PS_SLEEP)) { struct sk_buff *skbuff = NULL; + bool is_apsdq_empty; spin_lock_bh(&conn->psq_lock); - while ((skbuff = skb_dequeue(&conn->psq)) - != NULL) { + while ((skbuff = skb_dequeue(&conn->psq))) { + spin_unlock_bh(&conn->psq_lock); + ath6kl_data_tx(skbuff, vif->ndev); + spin_lock_bh(&conn->psq_lock); + } + + is_apsdq_empty = skb_queue_empty(&conn->apsdq); + while ((skbuff = skb_dequeue(&conn->apsdq))) { spin_unlock_bh(&conn->psq_lock); ath6kl_data_tx(skbuff, vif->ndev); spin_lock_bh(&conn->psq_lock); } spin_unlock_bh(&conn->psq_lock); + + if (!is_apsdq_empty) + ath6kl_wmi_set_apsd_bfrd_traf( + ar->wmi, + vif->fw_vif_idx, + conn->aid, 0, 0); + /* Clear the PVB for this STA */ ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx, conn->aid, 0); diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 08fbd9a9be4..c2420f886ed 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -180,7 +180,7 @@ static int ath6kl_wmi_meta_add(struct wmi *wmi, struct sk_buff *skb, } int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb, - u8 msg_type, bool more_data, + u8 msg_type, u32 flags, enum wmi_data_hdr_data_type data_type, u8 meta_ver, void *tx_meta_info, u8 if_idx) { @@ -204,17 +204,19 @@ int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb, data_hdr->info = msg_type << WMI_DATA_HDR_MSG_TYPE_SHIFT; data_hdr->info |= data_type << WMI_DATA_HDR_DATA_TYPE_SHIFT; - if (more_data) - data_hdr->info |= - WMI_DATA_HDR_MORE_MASK << WMI_DATA_HDR_MORE_SHIFT; + if (flags & WMI_DATA_HDR_FLAGS_MORE) + data_hdr->info |= WMI_DATA_HDR_MORE; - data_hdr->info2 = cpu_to_le16(meta_ver << WMI_DATA_HDR_META_SHIFT); - data_hdr->info3 = cpu_to_le16(if_idx & WMI_DATA_HDR_IF_IDX_MASK); + if (flags & WMI_DATA_HDR_FLAGS_EOSP) + data_hdr->info3 |= cpu_to_le16(WMI_DATA_HDR_EOSP); + + data_hdr->info2 |= cpu_to_le16(meta_ver << WMI_DATA_HDR_META_SHIFT); + data_hdr->info3 |= cpu_to_le16(if_idx & WMI_DATA_HDR_IF_IDX_MASK); return 0; } -static u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri) +u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri) { struct iphdr *ip_hdr = (struct iphdr *) pkt; u8 ip_pri; @@ -236,6 +238,11 @@ static u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri) return ip_pri; } +u8 ath6kl_wmi_get_traffic_class(u8 user_priority) +{ + return up_to_ac[user_priority & 0x7]; +} + int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, u8 if_idx, struct sk_buff *skb, u32 layer2_priority, bool wmm_enabled, @@ -786,12 +793,14 @@ static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len, ev->u.ap_sta.keymgmt, le16_to_cpu(ev->u.ap_sta.cipher), ev->u.ap_sta.apsd_info); + ath6kl_connect_ap_mode_sta( vif, ev->u.ap_sta.aid, ev->u.ap_sta.mac_addr, ev->u.ap_sta.keymgmt, le16_to_cpu(ev->u.ap_sta.cipher), ev->u.ap_sta.auth, ev->assoc_req_len, - ev->assoc_info + ev->beacon_ie_len); + ev->assoc_info + ev->beacon_ie_len, + ev->u.ap_sta.apsd_info); } return 0; } @@ -2993,6 +3002,43 @@ int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 if_idx, u8 cmd, const u8 *mac, NO_SYNC_WMIFLAG); } +/* This command will be used to enable/disable AP uAPSD feature */ +int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable) +{ + struct wmi_ap_set_apsd_cmd *cmd; + struct sk_buff *skb; + + skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_ap_set_apsd_cmd *)skb->data; + cmd->enable = enable; + + return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_AP_SET_APSD_CMDID, + NO_SYNC_WMIFLAG); +} + +int ath6kl_wmi_set_apsd_bfrd_traf(struct wmi *wmi, u8 if_idx, + u16 aid, u16 bitmap, u32 flags) +{ + struct wmi_ap_apsd_buffered_traffic_cmd *cmd; + struct sk_buff *skb; + + skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_ap_apsd_buffered_traffic_cmd *)skb->data; + cmd->aid = cpu_to_le16(aid); + cmd->bitmap = cpu_to_le16(bitmap); + cmd->flags = cpu_to_le32(flags); + + return ath6kl_wmi_cmd_send(wmi, if_idx, skb, + WMI_AP_APSD_BUFFERED_TRAFFIC_CMDID, + NO_SYNC_WMIFLAG); +} + static int ath6kl_wmi_pspoll_event_rx(struct wmi *wmi, u8 *datap, int len, struct ath6kl_vif *vif) { diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index eae0e4e065c..48e9d2641d6 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -149,8 +149,7 @@ enum wmi_msg_type { #define WMI_DATA_HDR_PS_MASK 0x1 #define WMI_DATA_HDR_PS_SHIFT 5 -#define WMI_DATA_HDR_MORE_MASK 0x1 -#define WMI_DATA_HDR_MORE_SHIFT 5 +#define WMI_DATA_HDR_MORE 0x20 enum wmi_data_hdr_data_type { WMI_DATA_HDR_DATA_TYPE_802_3 = 0, @@ -160,6 +159,13 @@ enum wmi_data_hdr_data_type { WMI_DATA_HDR_DATA_TYPE_ACL, }; +/* Bitmap of data header flags */ +enum wmi_data_hdr_flags { + WMI_DATA_HDR_FLAGS_MORE = 0x1, + WMI_DATA_HDR_FLAGS_EOSP = 0x2, + WMI_DATA_HDR_FLAGS_UAPSD = 0x4, +}; + #define WMI_DATA_HDR_DATA_TYPE_MASK 0x3 #define WMI_DATA_HDR_DATA_TYPE_SHIFT 6 @@ -173,8 +179,12 @@ enum wmi_data_hdr_data_type { #define WMI_DATA_HDR_META_MASK 0x7 #define WMI_DATA_HDR_META_SHIFT 13 +/* Macros for operating on WMI_DATA_HDR (info3) field */ #define WMI_DATA_HDR_IF_IDX_MASK 0xF +#define WMI_DATA_HDR_TRIG 0x10 +#define WMI_DATA_HDR_EOSP 0x10 + struct wmi_data_hdr { s8 rssi; @@ -203,7 +213,8 @@ struct wmi_data_hdr { /* * usage of info3, 16-bit: * b3:b0 - Interface index - * b15:b4 - Reserved + * b4 - uAPSD trigger in rx & EOSP in tx + * b15:b5 - Reserved */ __le16 info3; } __packed; @@ -2116,6 +2127,19 @@ struct wmi_rx_frame_format_cmd { } __packed; /* AP mode events */ +struct wmi_ap_set_apsd_cmd { + u8 enable; +} __packed; + +enum wmi_ap_apsd_buffered_traffic_flags { + WMI_AP_APSD_NO_DELIVERY_FRAMES = 0x1, +}; + +struct wmi_ap_apsd_buffered_traffic_cmd { + __le16 aid; + __le16 bitmap; + __le32 flags; +} __packed; /* WMI_PS_POLL_EVENT */ struct wmi_pspoll_event { @@ -2332,7 +2356,7 @@ enum htc_endpoint_id ath6kl_wmi_get_control_ep(struct wmi *wmi); void ath6kl_wmi_set_control_ep(struct wmi *wmi, enum htc_endpoint_id ep_id); int ath6kl_wmi_dix_2_dot3(struct wmi *wmi, struct sk_buff *skb); int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb, - u8 msg_type, bool more_data, + u8 msg_type, u32 flags, enum wmi_data_hdr_data_type data_type, u8 meta_ver, void *tx_meta_info, u8 if_idx); @@ -2446,7 +2470,16 @@ int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode); int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on); int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, u8 *filter, bool add_filter); +/* AP mode uAPSD */ +int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable); + +int ath6kl_wmi_set_apsd_bfrd_traf(struct wmi *wmi, + u8 if_idx, u16 aid, + u16 bitmap, u32 flags); + +u8 ath6kl_wmi_get_traffic_class(u8 user_priority); +u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri); /* AP mode */ int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, u8 if_idx, struct wmi_connect_cmd *p); -- cgit v1.2.3-70-g09d2 From e80ec84d9352419a7c0482edfbf1b96eaa4c8b95 Mon Sep 17 00:00:00 2001 From: Raja Mani Date: Thu, 12 Jan 2012 15:01:48 +0530 Subject: ath6kl: Remove useless initialization in ath6kl_read_fwlogs() ath6kl_read_fwlogs() assigns the value zero to the variable 'ret' at the time of declaration. Later, return value of ath6kl_diag_read32() repalces the init value. Hence removing useless zero assignment. Signed-off-by: Raja Mani Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index 53f97db4a7a..0a6d6e2be6e 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -255,7 +255,7 @@ int ath6kl_read_fwlogs(struct ath6kl *ar) struct ath6kl_dbglog_hdr debug_hdr; struct ath6kl_dbglog_buf debug_buf; u32 address, length, dropped, firstbuf, debug_hdr_addr; - int ret = 0, loop; + int ret, loop; u8 *buf; buf = kmalloc(ATH6KL_FWLOG_PAYLOAD_SIZE, GFP_KERNEL); -- cgit v1.2.3-70-g09d2 From 210762268466634ddbfaddb48fdf5181ce4b5f2d Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 27 Aug 2011 18:53:03 +0200 Subject: firewire: move fw_device reference counting from drivers to core fw_unit device drivers invariably need to talk to the fw_unit's parent (an fw_device) and grandparent (an fw_card). firewire-core already maintains an fw_card reference for the entire lifetime of an fw_device. Likewise, let firewire-core maintain an fw_device reference for the entire lifetime of an fw_unit so that fw_unit drivers don't have to. Signed-off-by: Stefan Richter --- drivers/firewire/core-device.c | 2 ++ drivers/firewire/core.h | 13 +++++++++++++ include/linux/firewire.h | 12 ------------ sound/firewire/isight.c | 4 +--- sound/firewire/speakers.c | 4 ---- 5 files changed, 16 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index f3b890da1e8..4c6c7d8cdaf 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c @@ -641,6 +641,7 @@ static void fw_unit_release(struct device *dev) { struct fw_unit *unit = fw_unit(dev); + fw_device_put(fw_parent_device(unit)); kfree(unit); } @@ -692,6 +693,7 @@ static void create_units(struct fw_device *device) if (device_register(&unit->device) < 0) goto skip_unit; + fw_device_get(device); continue; skip_unit: diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h index b45be576752..b5b34952cf1 100644 --- a/drivers/firewire/core.h +++ b/drivers/firewire/core.h @@ -1,6 +1,7 @@ #ifndef _FIREWIRE_CORE_H #define _FIREWIRE_CORE_H +#include #include #include #include @@ -141,6 +142,18 @@ extern struct rw_semaphore fw_device_rwsem; extern struct idr fw_device_idr; extern int fw_cdev_major; +static inline struct fw_device *fw_device_get(struct fw_device *device) +{ + get_device(&device->device); + + return device; +} + +static inline void fw_device_put(struct fw_device *device) +{ + put_device(&device->device); +} + struct fw_device *fw_device_get_by_devt(dev_t devt); int fw_device_set_broadcast_channel(struct device *dev, void *gen); void fw_node_event(struct fw_card *card, struct fw_node *node, int event); diff --git a/include/linux/firewire.h b/include/linux/firewire.h index 84ccf8e04fa..6f1d7385e05 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h @@ -203,18 +203,6 @@ static inline int fw_device_is_shutdown(struct fw_device *device) return atomic_read(&device->state) == FW_DEVICE_SHUTDOWN; } -static inline struct fw_device *fw_device_get(struct fw_device *device) -{ - get_device(&device->device); - - return device; -} - -static inline void fw_device_put(struct fw_device *device) -{ - put_device(&device->device); -} - int fw_device_enable_phys_dma(struct fw_device *device); /* diff --git a/sound/firewire/isight.c b/sound/firewire/isight.c index 440030818db..412b65f740d 100644 --- a/sound/firewire/isight.c +++ b/sound/firewire/isight.c @@ -612,7 +612,6 @@ static void isight_card_free(struct snd_card *card) fw_iso_resources_destroy(&isight->resources); fw_unit_put(isight->unit); - fw_device_put(isight->device); mutex_destroy(&isight->mutex); } @@ -645,7 +644,7 @@ static int isight_probe(struct device *unit_dev) isight->card = card; mutex_init(&isight->mutex); isight->unit = fw_unit_get(unit); - isight->device = fw_device_get(fw_dev); + isight->device = fw_dev; isight->audio_base = get_unit_base(unit); if (!isight->audio_base) { dev_err(&unit->device, "audio unit base not found\n"); @@ -682,7 +681,6 @@ static int isight_probe(struct device *unit_dev) err_unit: fw_unit_put(isight->unit); - fw_device_put(isight->device); mutex_destroy(&isight->mutex); error: snd_card_free(card); diff --git a/sound/firewire/speakers.c b/sound/firewire/speakers.c index 3fc257da180..18b9b5607f3 100644 --- a/sound/firewire/speakers.c +++ b/sound/firewire/speakers.c @@ -656,12 +656,10 @@ static u32 fwspk_read_firmware_version(struct fw_unit *unit) static void fwspk_card_free(struct snd_card *card) { struct fwspk *fwspk = card->private_data; - struct fw_device *dev = fw_parent_device(fwspk->unit); amdtp_out_stream_destroy(&fwspk->stream); cmp_connection_destroy(&fwspk->connection); fw_unit_put(fwspk->unit); - fw_device_put(dev); mutex_destroy(&fwspk->mutex); } @@ -718,7 +716,6 @@ static int __devinit fwspk_probe(struct device *unit_dev) fwspk = card->private_data; fwspk->card = card; mutex_init(&fwspk->mutex); - fw_device_get(fw_dev); fwspk->unit = fw_unit_get(unit); fwspk->device_info = fwspk_detect(fw_dev); if (!fwspk->device_info) { @@ -767,7 +764,6 @@ err_connection: cmp_connection_destroy(&fwspk->connection); err_unit: fw_unit_put(fwspk->unit); - fw_device_put(fw_dev); mutex_destroy(&fwspk->mutex); error: snd_card_free(card); -- cgit v1.2.3-70-g09d2 From 64d2172019dcfe46508593c561c9906de95df567 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Tue, 20 Dec 2011 21:32:46 +0100 Subject: firewire: ohci: use dev_printk API All messages are uniformly prefixed by driver name and device name now. Signed-off-by: Stefan Richter --- drivers/firewire/ohci.c | 185 +++++++++++++++++++++++++++--------------------- 1 file changed, 106 insertions(+), 79 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 6628feaa762..68b3c1b635f 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -345,7 +345,7 @@ MODULE_PARM_DESC(debug, "Verbose logging (default = 0" ", busReset events = " __stringify(OHCI_PARAM_DEBUG_BUSRESETS) ", or a combination, or all = -1)"); -static void log_irqs(u32 evt) +static void log_irqs(struct fw_ohci *ohci, u32 evt) { if (likely(!(param_debug & (OHCI_PARAM_DEBUG_IRQS | OHCI_PARAM_DEBUG_BUSRESETS)))) @@ -355,7 +355,8 @@ static void log_irqs(u32 evt) !(evt & OHCI1394_busReset)) return; - fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt, + dev_notice(ohci->card.device, + "IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt, evt & OHCI1394_selfIDComplete ? " selfID" : "", evt & OHCI1394_RQPkt ? " AR_req" : "", evt & OHCI1394_RSPkt ? " AR_resp" : "", @@ -394,24 +395,29 @@ static char _p(u32 *s, int shift) return port[*s >> shift & 3]; } -static void log_selfids(int node_id, int generation, int self_id_count, u32 *s) +static void log_selfids(struct fw_ohci *ohci, int generation, int self_id_count) { + u32 *s; + if (likely(!(param_debug & OHCI_PARAM_DEBUG_SELFIDS))) return; - fw_notify("%d selfIDs, generation %d, local node ID %04x\n", - self_id_count, generation, node_id); + dev_notice(ohci->card.device, + "%d selfIDs, generation %d, local node ID %04x\n", + self_id_count, generation, ohci->node_id); - for (; self_id_count--; ++s) + for (s = ohci->self_id_buffer; self_id_count--; ++s) if ((*s & 1 << 23) == 0) - fw_notify("selfID 0: %08x, phy %d [%c%c%c] " + dev_notice(ohci->card.device, + "selfID 0: %08x, phy %d [%c%c%c] " "%s gc=%d %s %s%s%s\n", *s, *s >> 24 & 63, _p(s, 6), _p(s, 4), _p(s, 2), speed[*s >> 14 & 3], *s >> 16 & 63, power[*s >> 8 & 7], *s >> 22 & 1 ? "L" : "", *s >> 11 & 1 ? "c" : "", *s & 2 ? "i" : ""); else - fw_notify("selfID n: %08x, phy %d [%c%c%c%c%c%c%c%c]\n", + dev_notice(ohci->card.device, + "selfID n: %08x, phy %d [%c%c%c%c%c%c%c%c]\n", *s, *s >> 24 & 63, _p(s, 16), _p(s, 14), _p(s, 12), _p(s, 10), _p(s, 8), _p(s, 6), _p(s, 4), _p(s, 2)); @@ -447,7 +453,8 @@ static const char *tcodes[] = { [0xe] = "link internal", [0xf] = "-reserved-", }; -static void log_ar_at_event(char dir, int speed, u32 *header, int evt) +static void log_ar_at_event(struct fw_ohci *ohci, + char dir, int speed, u32 *header, int evt) { int tcode = header[0] >> 4 & 0xf; char specific[12]; @@ -459,8 +466,9 @@ static void log_ar_at_event(char dir, int speed, u32 *header, int evt) evt = 0x1f; if (evt == OHCI1394_evt_bus_reset) { - fw_notify("A%c evt_bus_reset, generation %d\n", - dir, (header[2] >> 16) & 0xff); + dev_notice(ohci->card.device, + "A%c evt_bus_reset, generation %d\n", + dir, (header[2] >> 16) & 0xff); return; } @@ -479,36 +487,41 @@ static void log_ar_at_event(char dir, int speed, u32 *header, int evt) switch (tcode) { case 0xa: - fw_notify("A%c %s, %s\n", dir, evts[evt], tcodes[tcode]); + dev_notice(ohci->card.device, + "A%c %s, %s\n", + dir, evts[evt], tcodes[tcode]); break; case 0xe: - fw_notify("A%c %s, PHY %08x %08x\n", - dir, evts[evt], header[1], header[2]); + dev_notice(ohci->card.device, + "A%c %s, PHY %08x %08x\n", + dir, evts[evt], header[1], header[2]); break; case 0x0: case 0x1: case 0x4: case 0x5: case 0x9: - fw_notify("A%c spd %x tl %02x, " - "%04x -> %04x, %s, " - "%s, %04x%08x%s\n", - dir, speed, header[0] >> 10 & 0x3f, - header[1] >> 16, header[0] >> 16, evts[evt], - tcodes[tcode], header[1] & 0xffff, header[2], specific); + dev_notice(ohci->card.device, + "A%c spd %x tl %02x, " + "%04x -> %04x, %s, " + "%s, %04x%08x%s\n", + dir, speed, header[0] >> 10 & 0x3f, + header[1] >> 16, header[0] >> 16, evts[evt], + tcodes[tcode], header[1] & 0xffff, header[2], specific); break; default: - fw_notify("A%c spd %x tl %02x, " - "%04x -> %04x, %s, " - "%s%s\n", - dir, speed, header[0] >> 10 & 0x3f, - header[1] >> 16, header[0] >> 16, evts[evt], - tcodes[tcode], specific); + dev_notice(ohci->card.device, + "A%c spd %x tl %02x, " + "%04x -> %04x, %s, " + "%s%s\n", + dir, speed, header[0] >> 10 & 0x3f, + header[1] >> 16, header[0] >> 16, evts[evt], + tcodes[tcode], specific); } } #else #define param_debug 0 -static inline void log_irqs(u32 evt) {} -static inline void log_selfids(int node_id, int generation, int self_id_count, u32 *s) {} -static inline void log_ar_at_event(char dir, int speed, u32 *header, int evt) {} +static inline void log_irqs(struct fw_ohci *ohci, u32 evt) {} +static inline void log_selfids(struct fw_ohci *ohci, int generation, int self_id_count) {} +static inline void log_ar_at_event(struct fw_ohci *ohci, char dir, int speed, u32 *header, int evt) {} #endif /* CONFIG_FIREWIRE_OHCI_DEBUG */ @@ -555,7 +568,7 @@ static int read_phy_reg(struct fw_ohci *ohci, int addr) if (i >= 3) msleep(1); } - fw_error("failed to read phy reg\n"); + dev_err(ohci->card.device, "failed to read phy reg\n"); return -EBUSY; } @@ -577,7 +590,7 @@ static int write_phy_reg(const struct fw_ohci *ohci, int addr, u32 val) if (i >= 3) msleep(1); } - fw_error("failed to write phy reg\n"); + dev_err(ohci->card.device, "failed to write phy reg\n"); return -EBUSY; } @@ -676,11 +689,14 @@ static void ar_context_release(struct ar_context *ctx) static void ar_context_abort(struct ar_context *ctx, const char *error_msg) { - if (reg_read(ctx->ohci, CONTROL_CLEAR(ctx->regs)) & CONTEXT_RUN) { - reg_write(ctx->ohci, CONTROL_CLEAR(ctx->regs), CONTEXT_RUN); - flush_writes(ctx->ohci); + struct fw_ohci *ohci = ctx->ohci; - fw_error("AR error: %s; DMA stopped\n", error_msg); + if (reg_read(ohci, CONTROL_CLEAR(ctx->regs)) & CONTEXT_RUN) { + reg_write(ohci, CONTROL_CLEAR(ctx->regs), CONTEXT_RUN); + flush_writes(ohci); + + dev_err(ohci->card.device, "AR error: %s; DMA stopped\n", + error_msg); } /* FIXME: restart? */ } @@ -850,7 +866,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) p.timestamp = status & 0xffff; p.generation = ohci->request_generation; - log_ar_at_event('R', p.speed, p.header, evt); + log_ar_at_event(ohci, 'R', p.speed, p.header, evt); /* * Several controllers, notably from NEC and VIA, forget to @@ -1222,21 +1238,22 @@ static void context_append(struct context *ctx, static void context_stop(struct context *ctx) { + struct fw_ohci *ohci = ctx->ohci; u32 reg; int i; - reg_write(ctx->ohci, CONTROL_CLEAR(ctx->regs), CONTEXT_RUN); + reg_write(ohci, CONTROL_CLEAR(ctx->regs), CONTEXT_RUN); ctx->running = false; for (i = 0; i < 1000; i++) { - reg = reg_read(ctx->ohci, CONTROL_SET(ctx->regs)); + reg = reg_read(ohci, CONTROL_SET(ctx->regs)); if ((reg & CONTEXT_ACTIVE) == 0) return; if (i) udelay(10); } - fw_error("Error: DMA context still active (0x%08x)\n", reg); + dev_err(ohci->card.device, "DMA context still active (0x%08x)\n", reg); } struct driver_data { @@ -1416,7 +1433,7 @@ static int handle_at_packet(struct context *context, evt = le16_to_cpu(last->transfer_status) & 0x1f; packet->timestamp = le16_to_cpu(last->res_count); - log_ar_at_event('T', packet->speed, packet->header, evt); + log_ar_at_event(ohci, 'T', packet->speed, packet->header, evt); switch (evt) { case OHCI1394_evt_timeout: @@ -1545,7 +1562,7 @@ static void handle_local_lock(struct fw_ohci *ohci, goto out; } - fw_error("swap not done (CSR lock timeout)\n"); + dev_err(ohci->card.device, "swap not done (CSR lock timeout)\n"); fw_fill_response(&response, packet->header, RCODE_BUSY, NULL, 0); out: @@ -1621,11 +1638,13 @@ static void detect_dead_context(struct fw_ohci *ohci, ctl = reg_read(ohci, CONTROL_SET(regs)); if (ctl & CONTEXT_DEAD) { #ifdef CONFIG_FIREWIRE_OHCI_DEBUG - fw_error("DMA context %s has stopped, error code: %s\n", - name, evts[ctl & 0x1f]); + dev_err(ohci->card.device, + "DMA context %s has stopped, error code: %s\n", + name, evts[ctl & 0x1f]); #else - fw_error("DMA context %s has stopped, error code: %#x\n", - name, ctl & 0x1f); + dev_err(ohci->card.device, + "DMA context %s has stopped, error code: %#x\n", + name, ctl & 0x1f); #endif } } @@ -1777,7 +1796,8 @@ static int find_and_insert_self_id(struct fw_ohci *ohci, int self_id_count) reg = reg_read(ohci, OHCI1394_NodeID); if (!(reg & OHCI1394_NodeID_idValid)) { - fw_notify("node ID not valid, new bus reset in progress\n"); + dev_notice(ohci->card.device, + "node ID not valid, new bus reset in progress\n"); return -EBUSY; } self_id |= ((reg & 0x3f) << 24); /* phy ID */ @@ -1823,11 +1843,12 @@ static void bus_reset_work(struct work_struct *work) reg = reg_read(ohci, OHCI1394_NodeID); if (!(reg & OHCI1394_NodeID_idValid)) { - fw_notify("node ID not valid, new bus reset in progress\n"); + dev_notice(ohci->card.device, + "node ID not valid, new bus reset in progress\n"); return; } if ((reg & OHCI1394_NodeID_nodeNumber) == 63) { - fw_notify("malconfigured bus\n"); + dev_notice(ohci->card.device, "malconfigured bus\n"); return; } ohci->node_id = reg & (OHCI1394_NodeID_busNumber | @@ -1841,7 +1862,7 @@ static void bus_reset_work(struct work_struct *work) reg = reg_read(ohci, OHCI1394_SelfIDCount); if (reg & OHCI1394_SelfIDCount_selfIDError) { - fw_notify("inconsistent self IDs\n"); + dev_notice(ohci->card.device, "inconsistent self IDs\n"); return; } /* @@ -1853,7 +1874,7 @@ static void bus_reset_work(struct work_struct *work) self_id_count = (reg >> 3) & 0xff; if (self_id_count > 252) { - fw_notify("inconsistent self IDs\n"); + dev_notice(ohci->card.device, "inconsistent self IDs\n"); return; } @@ -1871,11 +1892,13 @@ static void bus_reset_work(struct work_struct *work) */ if (cond_le32_to_cpu(ohci->self_id_cpu[i]) == 0xffff008f) { - fw_notify("ignoring spurious self IDs\n"); + dev_notice(ohci->card.device, + "ignoring spurious self IDs\n"); self_id_count = j; break; } else { - fw_notify("inconsistent self IDs\n"); + dev_notice(ohci->card.device, + "inconsistent self IDs\n"); return; } } @@ -1886,13 +1909,14 @@ static void bus_reset_work(struct work_struct *work) if (ohci->quirks & QUIRK_TI_SLLZ059) { self_id_count = find_and_insert_self_id(ohci, self_id_count); if (self_id_count < 0) { - fw_notify("could not construct local self ID\n"); + dev_notice(ohci->card.device, + "could not construct local self ID\n"); return; } } if (self_id_count == 0) { - fw_notify("inconsistent self IDs\n"); + dev_notice(ohci->card.device, "inconsistent self IDs\n"); return; } rmb(); @@ -1913,8 +1937,8 @@ static void bus_reset_work(struct work_struct *work) new_generation = (reg_read(ohci, OHCI1394_SelfIDCount) >> 16) & 0xff; if (new_generation != generation) { - fw_notify("recursive bus reset detected, " - "discarding self ids\n"); + dev_notice(ohci->card.device, + "new bus reset, discarding self ids\n"); return; } @@ -1985,8 +2009,7 @@ static void bus_reset_work(struct work_struct *work) dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, free_rom, free_rom_bus); - log_selfids(ohci->node_id, generation, - self_id_count, ohci->self_id_buffer); + log_selfids(ohci, generation, self_id_count); fw_core_handle_bus_reset(&ohci->card, ohci->node_id, generation, self_id_count, ohci->self_id_buffer, @@ -2011,7 +2034,7 @@ static irqreturn_t irq_handler(int irq, void *data) */ reg_write(ohci, OHCI1394_IntEventClear, event & ~(OHCI1394_busReset | OHCI1394_postedWriteErr)); - log_irqs(event); + log_irqs(ohci, event); if (event & OHCI1394_selfIDComplete) queue_work(fw_workqueue, &ohci->bus_reset_work); @@ -2053,8 +2076,8 @@ static irqreturn_t irq_handler(int irq, void *data) } if (unlikely(event & OHCI1394_regAccessFail)) - fw_error("Register access failure - " - "please notify linux1394-devel@lists.sf.net\n"); + dev_err(ohci->card.device, + "register access failure - please notify linux1394-devel@lists.sf.net\n"); if (unlikely(event & OHCI1394_postedWriteErr)) { reg_read(ohci, OHCI1394_PostedWriteAddressHi); @@ -2062,12 +2085,13 @@ static irqreturn_t irq_handler(int irq, void *data) reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_postedWriteErr); if (printk_ratelimit()) - fw_error("PCI posted write error\n"); + dev_err(ohci->card.device, "PCI posted write error\n"); } if (unlikely(event & OHCI1394_cycleTooLong)) { if (printk_ratelimit()) - fw_notify("isochronous cycle too long\n"); + dev_notice(ohci->card.device, + "isochronous cycle too long\n"); reg_write(ohci, OHCI1394_LinkControlSet, OHCI1394_LinkControl_cycleMaster); } @@ -2080,7 +2104,8 @@ static irqreturn_t irq_handler(int irq, void *data) * them at least two cycles later. (FIXME?) */ if (printk_ratelimit()) - fw_notify("isochronous cycle inconsistent\n"); + dev_notice(ohci->card.device, + "isochronous cycle inconsistent\n"); } if (unlikely(event & OHCI1394_unrecoverableError)) @@ -2207,7 +2232,7 @@ static int ohci_enable(struct fw_card *card, int i, ret; if (software_reset(ohci)) { - fw_error("Failed to reset ohci card.\n"); + dev_err(card->device, "failed to reset ohci card\n"); return -EBUSY; } @@ -2231,7 +2256,7 @@ static int ohci_enable(struct fw_card *card, } if (!lps) { - fw_error("Failed to set Link Power Status\n"); + dev_err(card->device, "failed to set Link Power Status\n"); return -EIO; } @@ -2240,7 +2265,7 @@ static int ohci_enable(struct fw_card *card, if (ret < 0) return ret; if (ret) - fw_notify("local TSB41BA3D phy\n"); + dev_notice(card->device, "local TSB41BA3D phy\n"); else ohci->quirks &= ~QUIRK_TI_SLLZ059; } @@ -2340,7 +2365,8 @@ static int ohci_enable(struct fw_card *card, if (request_irq(dev->irq, irq_handler, pci_dev_msi_enabled(dev) ? 0 : IRQF_SHARED, ohci_driver_name, ohci)) { - fw_error("Failed to allocate interrupt %d.\n", dev->irq); + dev_err(card->device, "failed to allocate interrupt %d\n", + dev->irq); pci_disable_msi(dev); if (config_rom) { @@ -2505,7 +2531,7 @@ static int ohci_cancel_packet(struct fw_card *card, struct fw_packet *packet) dma_unmap_single(ohci->card.device, packet->payload_bus, packet->payload_length, DMA_TO_DEVICE); - log_ar_at_event('T', packet->speed, packet->header, 0x20); + log_ar_at_event(ohci, 'T', packet->speed, packet->header, 0x20); driver_data->packet = NULL; packet->ack = RCODE_CANCELLED; packet->callback(packet, &ohci->card, packet->ack); @@ -3459,7 +3485,7 @@ static int __devinit pci_probe(struct pci_dev *dev, err = pci_enable_device(dev); if (err) { - fw_error("Failed to enable OHCI hardware\n"); + dev_err(&dev->dev, "failed to enable OHCI hardware\n"); goto fail_free; } @@ -3474,13 +3500,13 @@ static int __devinit pci_probe(struct pci_dev *dev, err = pci_request_region(dev, 0, ohci_driver_name); if (err) { - fw_error("MMIO resource unavailable\n"); + dev_err(&dev->dev, "MMIO resource unavailable\n"); goto fail_disable; } ohci->registers = pci_iomap(dev, 0, OHCI1394_REGISTER_SIZE); if (ohci->registers == NULL) { - fw_error("Failed to remap registers\n"); + dev_err(&dev->dev, "failed to remap registers\n"); err = -ENXIO; goto fail_iomem; } @@ -3569,9 +3595,10 @@ static int __devinit pci_probe(struct pci_dev *dev, goto fail_contexts; version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; - fw_notify("Added fw-ohci device %s, OHCI v%x.%x, " + dev_notice(&dev->dev, + "added OHCI v%x.%x device as card %d, " "%d IR + %d IT contexts, quirks 0x%x\n", - dev_name(&dev->dev), version >> 16, version & 0xff, + version >> 16, version & 0xff, ohci->card.index, ohci->n_ir, ohci->n_it, ohci->quirks); return 0; @@ -3600,7 +3627,7 @@ static int __devinit pci_probe(struct pci_dev *dev, pmac_ohci_off(dev); fail: if (err == -ENOMEM) - fw_error("Out of memory\n"); + dev_err(&dev->dev, "out of memory\n"); return err; } @@ -3644,7 +3671,7 @@ static void pci_remove(struct pci_dev *dev) kfree(ohci); pmac_ohci_off(dev); - fw_notify("Removed fw-ohci device.\n"); + dev_notice(&dev->dev, "removed fw-ohci device\n"); } #ifdef CONFIG_PM @@ -3658,12 +3685,12 @@ static int pci_suspend(struct pci_dev *dev, pm_message_t state) pci_disable_msi(dev); err = pci_save_state(dev); if (err) { - fw_error("pci_save_state failed\n"); + dev_err(&dev->dev, "pci_save_state failed\n"); return err; } err = pci_set_power_state(dev, pci_choose_state(dev, state)); if (err) - fw_error("pci_set_power_state failed with %d\n", err); + dev_err(&dev->dev, "pci_set_power_state failed with %d\n", err); pmac_ohci_off(dev); return 0; @@ -3679,7 +3706,7 @@ static int pci_resume(struct pci_dev *dev) pci_restore_state(dev); err = pci_enable_device(dev); if (err) { - fw_error("pci_enable_device failed\n"); + dev_err(&dev->dev, "pci_enable_device failed\n"); return err; } -- cgit v1.2.3-70-g09d2 From eba9ebaaa26d60e07bc0aea585c13bc1d5a728c1 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Tue, 20 Dec 2011 21:34:12 +0100 Subject: firewire: sbp2: use dev_printk API All messages are uniformly prefixed by driver name and device name now. Signed-off-by: Stefan Richter --- drivers/firewire/sbp2.c | 93 +++++++++++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index 68375bc3aef..32b3296a1c5 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c @@ -165,7 +165,6 @@ static void sbp2_queue_work(struct sbp2_logical_unit *lu, unsigned long delay) */ struct sbp2_target { struct fw_unit *unit; - const char *bus_id; struct list_head lu_list; u64 management_agent_address; @@ -181,11 +180,21 @@ struct sbp2_target { int blocked; /* ditto */ }; -static struct fw_device *target_device(struct sbp2_target *tgt) +static struct fw_device *target_parent_device(struct sbp2_target *tgt) { return fw_parent_device(tgt->unit); } +static const struct device *tgt_dev(const struct sbp2_target *tgt) +{ + return &tgt->unit->device; +} + +static const struct device *lu_dev(const struct sbp2_logical_unit *lu) +{ + return &lu->tgt->unit->device; +} + /* Impossible login_id, to detect logout attempt before successful login */ #define INVALID_LOGIN_ID 0x10000 @@ -430,7 +439,8 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request, memcpy(status.data, payload + 8, length - 8); if (STATUS_GET_SOURCE(status) == 2 || STATUS_GET_SOURCE(status) == 3) { - fw_notify("non-orb related status write, not handled\n"); + dev_notice(lu_dev(lu), + "non-ORB related status write, not handled\n"); fw_send_response(card, request, RCODE_COMPLETE); return; } @@ -451,7 +461,7 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request, orb->callback(orb, &status); kref_put(&orb->kref, free_orb); /* orb callback reference */ } else { - fw_error("status write for unknown orb\n"); + dev_err(lu_dev(lu), "status write for unknown ORB\n"); } fw_send_response(card, request, RCODE_COMPLETE); @@ -492,7 +502,7 @@ static void complete_transaction(struct fw_card *card, int rcode, static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu, int node_id, int generation, u64 offset) { - struct fw_device *device = target_device(lu->tgt); + struct fw_device *device = target_parent_device(lu->tgt); struct sbp2_pointer orb_pointer; unsigned long flags; @@ -513,7 +523,7 @@ static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu, static int sbp2_cancel_orbs(struct sbp2_logical_unit *lu) { - struct fw_device *device = target_device(lu->tgt); + struct fw_device *device = target_parent_device(lu->tgt); struct sbp2_orb *orb, *next; struct list_head list; unsigned long flags; @@ -552,7 +562,7 @@ static int sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, int generation, int function, int lun_or_login_id, void *response) { - struct fw_device *device = target_device(lu->tgt); + struct fw_device *device = target_parent_device(lu->tgt); struct sbp2_management_orb *orb; unsigned int timeout; int retval = -ENOMEM; @@ -612,20 +622,20 @@ static int sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, retval = -EIO; if (sbp2_cancel_orbs(lu) == 0) { - fw_error("%s: orb reply timed out, rcode=0x%02x\n", - lu->tgt->bus_id, orb->base.rcode); + dev_err(lu_dev(lu), "ORB reply timed out, rcode 0x%02x\n", + orb->base.rcode); goto out; } if (orb->base.rcode != RCODE_COMPLETE) { - fw_error("%s: management write failed, rcode 0x%02x\n", - lu->tgt->bus_id, orb->base.rcode); + dev_err(lu_dev(lu), "management write failed, rcode 0x%02x\n", + orb->base.rcode); goto out; } if (STATUS_GET_RESPONSE(orb->status) != 0 || STATUS_GET_SBP_STATUS(orb->status) != 0) { - fw_error("%s: error status: %d:%d\n", lu->tgt->bus_id, + dev_err(lu_dev(lu), "error status: %d:%d\n", STATUS_GET_RESPONSE(orb->status), STATUS_GET_SBP_STATUS(orb->status)); goto out; @@ -648,7 +658,7 @@ static int sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, static void sbp2_agent_reset(struct sbp2_logical_unit *lu) { - struct fw_device *device = target_device(lu->tgt); + struct fw_device *device = target_parent_device(lu->tgt); __be32 d = 0; fw_run_transaction(device->card, TCODE_WRITE_QUADLET_REQUEST, @@ -665,7 +675,7 @@ static void complete_agent_reset_write_no_wait(struct fw_card *card, static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu) { - struct fw_device *device = target_device(lu->tgt); + struct fw_device *device = target_parent_device(lu->tgt); struct fw_transaction *t; static __be32 d; @@ -704,7 +714,7 @@ static inline void sbp2_allow_block(struct sbp2_logical_unit *lu) static void sbp2_conditionally_block(struct sbp2_logical_unit *lu) { struct sbp2_target *tgt = lu->tgt; - struct fw_card *card = target_device(tgt)->card; + struct fw_card *card = target_parent_device(tgt)->card; struct Scsi_Host *shost = container_of((void *)tgt, struct Scsi_Host, hostdata[0]); unsigned long flags; @@ -728,7 +738,7 @@ static void sbp2_conditionally_block(struct sbp2_logical_unit *lu) static void sbp2_conditionally_unblock(struct sbp2_logical_unit *lu) { struct sbp2_target *tgt = lu->tgt; - struct fw_card *card = target_device(tgt)->card; + struct fw_card *card = target_parent_device(tgt)->card; struct Scsi_Host *shost = container_of((void *)tgt, struct Scsi_Host, hostdata[0]); unsigned long flags; @@ -753,7 +763,7 @@ static void sbp2_conditionally_unblock(struct sbp2_logical_unit *lu) */ static void sbp2_unblock(struct sbp2_target *tgt) { - struct fw_card *card = target_device(tgt)->card; + struct fw_card *card = target_parent_device(tgt)->card; struct Scsi_Host *shost = container_of((void *)tgt, struct Scsi_Host, hostdata[0]); unsigned long flags; @@ -794,7 +804,7 @@ static int sbp2_lun2int(u16 lun) */ static void sbp2_set_busy_timeout(struct sbp2_logical_unit *lu) { - struct fw_device *device = target_device(lu->tgt); + struct fw_device *device = target_parent_device(lu->tgt); __be32 d = cpu_to_be32(SBP2_CYCLE_LIMIT | SBP2_RETRY_LIMIT); fw_run_transaction(device->card, TCODE_WRITE_QUADLET_REQUEST, @@ -809,7 +819,7 @@ static void sbp2_login(struct work_struct *work) struct sbp2_logical_unit *lu = container_of(work, struct sbp2_logical_unit, work.work); struct sbp2_target *tgt = lu->tgt; - struct fw_device *device = target_device(tgt); + struct fw_device *device = target_parent_device(tgt); struct Scsi_Host *shost; struct scsi_device *sdev; struct sbp2_login_response response; @@ -833,8 +843,8 @@ static void sbp2_login(struct work_struct *work) if (lu->retries++ < 5) { sbp2_queue_work(lu, DIV_ROUND_UP(HZ, 5)); } else { - fw_error("%s: failed to login to LUN %04x\n", - tgt->bus_id, lu->lun); + dev_err(tgt_dev(tgt), "failed to login to LUN %04x\n", + lu->lun); /* Let any waiting I/O fail from now on. */ sbp2_unblock(lu->tgt); } @@ -851,8 +861,8 @@ static void sbp2_login(struct work_struct *work) << 32) | be32_to_cpu(response.command_block_agent.low); lu->login_id = be32_to_cpu(response.misc) & 0xffff; - fw_notify("%s: logged in to LUN %04x (%d retries)\n", - tgt->bus_id, lu->lun, lu->retries); + dev_notice(tgt_dev(tgt), "logged in to LUN %04x (%d retries)\n", + lu->lun, lu->retries); /* set appropriate retry limit(s) in BUSY_TIMEOUT register */ sbp2_set_busy_timeout(lu); @@ -919,7 +929,7 @@ static void sbp2_reconnect(struct work_struct *work) struct sbp2_logical_unit *lu = container_of(work, struct sbp2_logical_unit, work.work); struct sbp2_target *tgt = lu->tgt; - struct fw_device *device = target_device(tgt); + struct fw_device *device = target_parent_device(tgt); int generation, node_id, local_node_id; if (fw_device_is_shutdown(device)) @@ -943,7 +953,7 @@ static void sbp2_reconnect(struct work_struct *work) smp_rmb(); /* get current card generation */ if (generation == device->card->generation || lu->retries++ >= 5) { - fw_error("%s: failed to reconnect\n", tgt->bus_id); + dev_err(tgt_dev(tgt), "failed to reconnect\n"); lu->retries = 0; PREPARE_DELAYED_WORK(&lu->work, sbp2_login); } @@ -957,8 +967,8 @@ static void sbp2_reconnect(struct work_struct *work) smp_wmb(); /* node IDs must not be older than generation */ lu->generation = generation; - fw_notify("%s: reconnected to LUN %04x (%d retries)\n", - tgt->bus_id, lu->lun, lu->retries); + dev_notice(tgt_dev(tgt), "reconnected to LUN %04x (%d retries)\n", + lu->lun, lu->retries); sbp2_agent_reset(lu); sbp2_cancel_orbs(lu); @@ -1068,8 +1078,8 @@ static void sbp2_clamp_management_orb_timeout(struct sbp2_target *tgt) unsigned int timeout = tgt->mgt_orb_timeout; if (timeout > 40000) - fw_notify("%s: %ds mgt_ORB_timeout limited to 40s\n", - tgt->bus_id, timeout / 1000); + dev_notice(tgt_dev(tgt), "%ds mgt_ORB_timeout limited to 40s\n", + timeout / 1000); tgt->mgt_orb_timeout = clamp_val(timeout, 5000, 40000); } @@ -1081,9 +1091,9 @@ static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model, unsigned int w = sbp2_param_workarounds; if (w) - fw_notify("Please notify linux1394-devel@lists.sourceforge.net " - "if you need the workarounds parameter for %s\n", - tgt->bus_id); + dev_notice(tgt_dev(tgt), + "Please notify linux1394-devel@lists.sf.net " + "if you need the workarounds parameter\n"); if (w & SBP2_WORKAROUND_OVERRIDE) goto out; @@ -1103,9 +1113,9 @@ static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model, } out: if (w) - fw_notify("Workarounds for %s: 0x%x " - "(firmware_revision 0x%06x, model_id 0x%06x)\n", - tgt->bus_id, w, firmware_revision, model); + dev_notice(tgt_dev(tgt), "workarounds 0x%x " + "(firmware_revision 0x%06x, model_id 0x%06x)\n", + w, firmware_revision, model); tgt->workarounds = w; } @@ -1133,7 +1143,6 @@ static int sbp2_probe(struct device *dev) dev_set_drvdata(&unit->device, tgt); tgt->unit = unit; INIT_LIST_HEAD(&tgt->lu_list); - tgt->bus_id = dev_name(&unit->device); tgt->guid = (u64)device->config_rom[3] << 32 | device->config_rom[4]; if (fw_device_enable_phys_dma(device) < 0) @@ -1239,7 +1248,7 @@ static int sbp2_remove(struct device *dev) kfree(lu); } scsi_remove_host(shost); - fw_notify("released %s, target %d:0:0\n", tgt->bus_id, shost->host_no); + dev_notice(dev, "released target %d:0:0\n", shost->host_no); scsi_host_put(shost); return 0; @@ -1325,7 +1334,7 @@ static void complete_command_orb(struct sbp2_orb *base_orb, { struct sbp2_command_orb *orb = container_of(base_orb, struct sbp2_command_orb, base); - struct fw_device *device = target_device(orb->lu->tgt); + struct fw_device *device = target_parent_device(orb->lu->tgt); int result; if (status != NULL) { @@ -1433,7 +1442,7 @@ static int sbp2_scsi_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmd) { struct sbp2_logical_unit *lu = cmd->device->hostdata; - struct fw_device *device = target_device(lu->tgt); + struct fw_device *device = target_parent_device(lu->tgt); struct sbp2_command_orb *orb; int generation, retval = SCSI_MLQUEUE_HOST_BUSY; @@ -1442,7 +1451,7 @@ static int sbp2_scsi_queuecommand(struct Scsi_Host *shost, * transfer direction not handled. */ if (cmd->sc_data_direction == DMA_BIDIRECTIONAL) { - fw_error("Can't handle DMA_BIDIRECTIONAL, rejecting command\n"); + dev_err(lu_dev(lu), "cannot handle bidirectional command\n"); cmd->result = DID_ERROR << 16; cmd->scsi_done(cmd); return 0; @@ -1450,7 +1459,7 @@ static int sbp2_scsi_queuecommand(struct Scsi_Host *shost, orb = kzalloc(sizeof(*orb), GFP_ATOMIC); if (orb == NULL) { - fw_notify("failed to alloc orb\n"); + dev_notice(lu_dev(lu), "failed to alloc ORB\n"); return SCSI_MLQUEUE_HOST_BUSY; } @@ -1550,7 +1559,7 @@ static int sbp2_scsi_abort(struct scsi_cmnd *cmd) { struct sbp2_logical_unit *lu = cmd->device->hostdata; - fw_notify("%s: sbp2_scsi_abort\n", lu->tgt->bus_id); + dev_notice(lu_dev(lu), "sbp2_scsi_abort\n"); sbp2_agent_reset(lu); sbp2_cancel_orbs(lu); -- cgit v1.2.3-70-g09d2 From 0b8ecdda1943a05c8e7896f0b5f1addf39269927 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 13 Sep 2011 14:11:09 -0400 Subject: drm/i915: Silence _DSM errors <@ajax> mjg59: how concerned should i be about [drm:intel_dsm_pci_probe] *ERROR* failed to get supported _DSM functions ? <@mjg59> ajax: Entirely unconcerned Signed-off-by: Adam Jackson Acked-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_acpi.c b/drivers/gpu/drm/i915/intel_acpi.c index cb912106d1a..bae3edf956a 100644 --- a/drivers/gpu/drm/i915/intel_acpi.c +++ b/drivers/gpu/drm/i915/intel_acpi.c @@ -208,7 +208,7 @@ static bool intel_dsm_pci_probe(struct pci_dev *pdev) ret = intel_dsm(dhandle, INTEL_DSM_FN_SUPPORTED_FUNCTIONS, 0); if (ret < 0) { - DRM_ERROR("failed to get supported _DSM functions\n"); + DRM_DEBUG_KMS("failed to get supported _DSM functions\n"); return false; } -- cgit v1.2.3-70-g09d2 From cec2f356d59d9e070413e5966a3c5a1af136d948 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Tue, 10 Jan 2012 15:09:36 -0800 Subject: drm/i915: Only look for matching clocks for LVDS downclock This patch enforces that the downclock clock source is the same as the preferred clock source for LVDS. This fixes a bug where the driver chooses a downclock clock source with a different P than the preferred mode clock source. This happened even if the preferred clock source implemented an acceptable rate for the downclock. The result of this bug is that downclock is disabled. Signed-off-by: Sean Paul Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 74 ++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 29743dee54c..15f2b52ea70 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -75,7 +75,7 @@ struct intel_limit { intel_range_t dot, vco, n, m, m1, m2, p, p1; intel_p2_t p2; bool (* find_pll)(const intel_limit_t *, struct drm_crtc *, - int, int, intel_clock_t *); + int, int, intel_clock_t *, intel_clock_t *); }; /* FDI */ @@ -83,17 +83,21 @@ struct intel_limit { static bool intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *best_clock); + int target, int refclk, intel_clock_t *match_clock, + intel_clock_t *best_clock); static bool intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *best_clock); + int target, int refclk, intel_clock_t *match_clock, + intel_clock_t *best_clock); static bool intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *best_clock); + int target, int refclk, intel_clock_t *match_clock, + intel_clock_t *best_clock); static bool intel_find_pll_ironlake_dp(const intel_limit_t *, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *best_clock); + int target, int refclk, intel_clock_t *match_clock, + intel_clock_t *best_clock); static inline u32 /* units of 100MHz */ intel_fdi_link_freq(struct drm_device *dev) @@ -515,7 +519,8 @@ static bool intel_PLL_is_valid(struct drm_device *dev, static bool intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *best_clock) + int target, int refclk, intel_clock_t *match_clock, + intel_clock_t *best_clock) { struct drm_device *dev = crtc->dev; @@ -562,6 +567,9 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, if (!intel_PLL_is_valid(dev, limit, &clock)) continue; + if (match_clock && + clock.p != match_clock->p) + continue; this_err = abs(clock.dot - target); if (this_err < err) { @@ -578,7 +586,8 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, static bool intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *best_clock) + int target, int refclk, intel_clock_t *match_clock, + intel_clock_t *best_clock) { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -625,6 +634,9 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, if (!intel_PLL_is_valid(dev, limit, &clock)) continue; + if (match_clock && + clock.p != match_clock->p) + continue; this_err = abs(clock.dot - target); if (this_err < err_most) { @@ -642,7 +654,8 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, static bool intel_find_pll_ironlake_dp(const intel_limit_t *limit, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *best_clock) + int target, int refclk, intel_clock_t *match_clock, + intel_clock_t *best_clock) { struct drm_device *dev = crtc->dev; intel_clock_t clock; @@ -668,7 +681,8 @@ intel_find_pll_ironlake_dp(const intel_limit_t *limit, struct drm_crtc *crtc, /* DisplayPort has only two frequencies, 162MHz and 270MHz */ static bool intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *best_clock) + int target, int refclk, intel_clock_t *match_clock, + intel_clock_t *best_clock) { intel_clock_t clock; if (target < 200000) { @@ -5038,7 +5052,8 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. */ limit = intel_limit(crtc, refclk); - ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, &clock); + ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, NULL, + &clock); if (!ok) { DRM_ERROR("Couldn't find PLL settings for mode!\n"); return -EINVAL; @@ -5048,21 +5063,17 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, intel_crtc_update_cursor(crtc, true); if (is_lvds && dev_priv->lvds_downclock_avail) { + /* + * Ensure we match the reduced clock's P to the target clock. + * If the clocks don't match, we can't switch the display clock + * by using the FP0/FP1. In such case we will disable the LVDS + * downclock feature. + */ has_reduced_clock = limit->find_pll(limit, crtc, dev_priv->lvds_downclock, refclk, + &clock, &reduced_clock); - if (has_reduced_clock && (clock.p != reduced_clock.p)) { - /* - * If the different P is found, it means that we can't - * switch the display clock by using the FP0/FP1. - * In such case we will disable the LVDS downclock - * feature. - */ - DRM_DEBUG_KMS("Different P is found for " - "LVDS clock/downclock\n"); - has_reduced_clock = 0; - } } /* SDVO TV has fixed PLL values depend on its clock range, this mirrors vbios setting. */ @@ -5583,7 +5594,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. */ limit = intel_limit(crtc, refclk); - ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, &clock); + ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, NULL, + &clock); if (!ok) { DRM_ERROR("Couldn't find PLL settings for mode!\n"); return -EINVAL; @@ -5593,21 +5605,17 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, intel_crtc_update_cursor(crtc, true); if (is_lvds && dev_priv->lvds_downclock_avail) { + /* + * Ensure we match the reduced clock's P to the target clock. + * If the clocks don't match, we can't switch the display clock + * by using the FP0/FP1. In such case we will disable the LVDS + * downclock feature. + */ has_reduced_clock = limit->find_pll(limit, crtc, dev_priv->lvds_downclock, refclk, + &clock, &reduced_clock); - if (has_reduced_clock && (clock.p != reduced_clock.p)) { - /* - * If the different P is found, it means that we can't - * switch the display clock by using the FP0/FP1. - * In such case we will disable the LVDS downclock - * feature. - */ - DRM_DEBUG_KMS("Different P is found for " - "LVDS clock/downclock\n"); - has_reduced_clock = 0; - } } /* SDVO TV has fixed PLL values depend on its clock range, this mirrors vbios setting. */ -- cgit v1.2.3-70-g09d2 From 5a117db77e47e3946d1aaa7ce8deafafd9d76746 Mon Sep 17 00:00:00 2001 From: Eugeni Dodonov Date: Thu, 5 Jan 2012 09:34:29 -0200 Subject: drm/i915: there is no pipe CxSR on ironlake After checking the specs and discussing with Jesse, turns out CxSR is not available on Ironlake and gen5, and its advertisement on the device description is misleading. Acked-by: Jesse Barnes Signed-off-by: Eugeni Dodonov Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 8f7187915b0..057c2722594 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -198,7 +198,7 @@ static const struct intel_device_info intel_pineview_info = { static const struct intel_device_info intel_ironlake_d_info = { .gen = 5, - .need_gfx_hws = 1, .has_pipe_cxsr = 1, .has_hotplug = 1, + .need_gfx_hws = 1, .has_hotplug = 1, .has_bsd_ring = 1, }; -- cgit v1.2.3-70-g09d2 From 6b2d590540d219064a53638f485b75203131dfce Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Wed, 4 Jan 2012 14:04:33 -0800 Subject: agp/intel: Add pci id for hostbridge from has/qemu This is needed to run the simulator. Cc: Jesse Barnes Signed-off-by: Ben Widawsky [danvet: added a comment in case people wonder what it's for.] Signed-off-by: Daniel Vetter --- drivers/char/agp/intel-agp.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index b427711be4b..962e75dc478 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -850,6 +850,7 @@ static struct pci_device_id agp_intel_pci_table[] = { .subvendor = PCI_ANY_ID, \ .subdevice = PCI_ANY_ID, \ } + ID(PCI_DEVICE_ID_INTEL_82441), /* for HAS2 support */ ID(PCI_DEVICE_ID_INTEL_82443LX_0), ID(PCI_DEVICE_ID_INTEL_82443BX_0), ID(PCI_DEVICE_ID_INTEL_82443GX_0), -- cgit v1.2.3-70-g09d2 From c65d77d83ccffc60f8729b2e7806cac2564ee1b1 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 15 Dec 2011 12:30:36 -0800 Subject: drm/i915: split 9xx refclk & sdvo tv code out Makes the mode set routine a little cleaner and easier to extend. Signed-off-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 74 ++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 15f2b52ea70..b050a778516 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4982,6 +4982,48 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, return display_bpc != bpc; } +static int i9xx_get_refclk(struct drm_crtc *crtc, int num_connectors) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + int refclk; + + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && + intel_panel_use_ssc(dev_priv) && num_connectors < 2) { + refclk = dev_priv->lvds_ssc_freq * 1000; + DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", + refclk / 1000); + } else if (!IS_GEN2(dev)) { + refclk = 96000; + } else { + refclk = 48000; + } + + return refclk; +} + +static void i9xx_adjust_sdvo_tv_clock(struct drm_display_mode *adjusted_mode, + intel_clock_t *clock) +{ + /* SDVO TV has fixed PLL values depend on its clock range, + this mirrors vbios setting. */ + if (adjusted_mode->clock >= 100000 + && adjusted_mode->clock < 140500) { + clock->p1 = 2; + clock->p2 = 10; + clock->n = 3; + clock->m1 = 16; + clock->m2 = 8; + } else if (adjusted_mode->clock >= 140500 + && adjusted_mode->clock <= 200000) { + clock->p1 = 1; + clock->p2 = 10; + clock->n = 6; + clock->m1 = 12; + clock->m2 = 8; + } +} + static int i9xx_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode, @@ -5036,15 +5078,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, num_connectors++; } - if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) { - refclk = dev_priv->lvds_ssc_freq * 1000; - DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", - refclk / 1000); - } else if (!IS_GEN2(dev)) { - refclk = 96000; - } else { - refclk = 48000; - } + refclk = i9xx_get_refclk(crtc, num_connectors); /* * Returns a set of divisors for the desired target clock with the given @@ -5075,25 +5109,9 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, &clock, &reduced_clock); } - /* SDVO TV has fixed PLL values depend on its clock range, - this mirrors vbios setting. */ - if (is_sdvo && is_tv) { - if (adjusted_mode->clock >= 100000 - && adjusted_mode->clock < 140500) { - clock.p1 = 2; - clock.p2 = 10; - clock.n = 3; - clock.m1 = 16; - clock.m2 = 8; - } else if (adjusted_mode->clock >= 140500 - && adjusted_mode->clock <= 200000) { - clock.p1 = 1; - clock.p2 = 10; - clock.n = 6; - clock.m1 = 12; - clock.m2 = 8; - } - } + + if (is_sdvo && is_tv) + i9xx_adjust_sdvo_tv_clock(adjusted_mode, &clock); if (IS_PINEVIEW(dev)) { fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; -- cgit v1.2.3-70-g09d2 From a7516a05311d0e2deb8ce8ae8b8c12a513ca8ca2 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 15 Dec 2011 12:30:37 -0800 Subject: drm/i915: split out pll divider code This cleans up the mode set path a little further, making it easier to extend for future platforms. Signed-off-by: Jesse Barnes [danvet: shut up stupid gcc warning about potential use of un-initlized fp2] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 62 +++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b050a778516..f3e706c2bd3 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5024,6 +5024,40 @@ static void i9xx_adjust_sdvo_tv_clock(struct drm_display_mode *adjusted_mode, } } +static void i9xx_update_pll_dividers(struct drm_crtc *crtc, + intel_clock_t *clock, + intel_clock_t *reduced_clock) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int pipe = intel_crtc->pipe; + u32 fp, fp2 = 0; + + if (IS_PINEVIEW(dev)) { + fp = (1 << clock->n) << 16 | clock->m1 << 8 | clock->m2; + if (reduced_clock) + fp2 = (1 << reduced_clock->n) << 16 | + reduced_clock->m1 << 8 | reduced_clock->m2; + } else { + fp = clock->n << 16 | clock->m1 << 8 | clock->m2; + if (reduced_clock) + fp2 = reduced_clock->n << 16 | reduced_clock->m1 << 8 | + reduced_clock->m2; + } + + I915_WRITE(FP0(pipe), fp); + + intel_crtc->lowfreq_avail = false; + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && + reduced_clock && i915_powersave) { + I915_WRITE(FP1(pipe), fp2); + intel_crtc->lowfreq_avail = true; + } else { + I915_WRITE(FP1(pipe), fp); + } +} + static int i9xx_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode, @@ -5037,7 +5071,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, int plane = intel_crtc->plane; int refclk, num_connectors = 0; intel_clock_t clock, reduced_clock; - u32 dpll, fp = 0, fp2 = 0, dspcntr, pipeconf; + u32 dpll, dspcntr, pipeconf; bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false; bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; struct drm_mode_config *mode_config = &dev->mode_config; @@ -5113,17 +5147,8 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, if (is_sdvo && is_tv) i9xx_adjust_sdvo_tv_clock(adjusted_mode, &clock); - if (IS_PINEVIEW(dev)) { - fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; - if (has_reduced_clock) - fp2 = (1 << reduced_clock.n) << 16 | - reduced_clock.m1 << 8 | reduced_clock.m2; - } else { - fp = clock.n << 16 | clock.m1 << 8 | clock.m2; - if (has_reduced_clock) - fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 | - reduced_clock.m2; - } + i9xx_update_pll_dividers(crtc, &clock, has_reduced_clock ? + &reduced_clock : NULL); dpll = DPLL_VGA_MODE_DIS; @@ -5233,7 +5258,6 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); drm_mode_debug_printmodeline(mode); - I915_WRITE(FP0(pipe), fp); I915_WRITE(DPLL(pipe), dpll & ~DPLL_VCO_ENABLE); POSTING_READ(DPLL(pipe)); @@ -5320,17 +5344,11 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, I915_WRITE(DPLL(pipe), dpll); } - intel_crtc->lowfreq_avail = false; - if (is_lvds && has_reduced_clock && i915_powersave) { - I915_WRITE(FP1(pipe), fp2); - intel_crtc->lowfreq_avail = true; - if (HAS_PIPE_CXSR(dev)) { + if (HAS_PIPE_CXSR(dev)) { + if (intel_crtc->lowfreq_avail) { DRM_DEBUG_KMS("enabling CxSR downclocking\n"); pipeconf |= PIPECONF_CXSR_DOWNCLOCK; - } - } else { - I915_WRITE(FP1(pipe), fp); - if (HAS_PIPE_CXSR(dev)) { + } else { DRM_DEBUG_KMS("disabling CxSR downclocking\n"); pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK; } -- cgit v1.2.3-70-g09d2 From f3953dcb98bad1c3badf451bcf41bf83ae2ce542 Mon Sep 17 00:00:00 2001 From: Eugeni Dodonov Date: Mon, 28 Nov 2011 16:15:17 -0200 Subject: drm/i915: fix typo in function name Fix function name in comments, a left-over from when i965_reset was renamed to i915_reset. Signed-off-by: Eugeni Dodonov Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 057c2722594..7578c08110f 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -603,7 +603,7 @@ static int gen6_do_reset(struct drm_device *dev, u8 flags) } /** - * i965_reset - reset chip after a hang + * i915_reset - reset chip after a hang * @dev: drm device to reset * @flags: reset domains * -- cgit v1.2.3-70-g09d2 From 931872fceabacf2d4f8b6fbd51611c167e83164c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 16 Jan 2012 23:01:13 +0000 Subject: drm/i915: Check that plane/pipe is disabled before removing the fb Staring at an error state such as: PGTBL_ER: 0x00000400 Display B: Invalid tiling fence[0] = 05001001 valid, x-tiled, pitch: 512, start: 0x05000000, size: 1048576 Pinned [2]: 00000000 131072 0001 0001 00000000 P uncached 00020000 4096000 0041 0000 00000000 P uncached (name: 1) Plane [1]: CNTR: c0000000 # enabled | gamma STRIDE: 00001400 SIZE: 03ff04ff POS: 00000000 ADDR: 05000000 Suggests that we did not clear the DSPBCNTR prior to unpinning the framebuffer and reusing the GTT space. Impossible! Unless our DPMS bookkeeping ran afoul again... In the meantime add an assertion that the plane is decoupled from the framebuffer prior to release. Signed-off-by: Chris Wilson Acked-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f3e706c2bd3..5fa1476cbfc 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -944,19 +944,24 @@ void assert_pipe(struct drm_i915_private *dev_priv, pipe_name(pipe), state_string(state), state_string(cur_state)); } -static void assert_plane_enabled(struct drm_i915_private *dev_priv, - enum plane plane) +static void assert_plane(struct drm_i915_private *dev_priv, + enum plane plane, bool state) { int reg; u32 val; + bool cur_state; reg = DSPCNTR(plane); val = I915_READ(reg); - WARN(!(val & DISPLAY_PLANE_ENABLE), - "plane %c assertion failure, should be active but is disabled\n", - plane_name(plane)); + cur_state = !!(val & DISPLAY_PLANE_ENABLE); + WARN(cur_state != state, + "plane %c assertion failure (expected %s, current %s)\n", + plane_name(plane), state_string(state), state_string(cur_state)); } +#define assert_plane_enabled(d, p) assert_plane(d, p, true) +#define assert_plane_disabled(d, p) assert_plane(d, p, false) + static void assert_planes_disabled(struct drm_i915_private *dev_priv, enum pipe pipe) { @@ -3335,6 +3340,8 @@ static void intel_crtc_disable(struct drm_crtc *crtc) struct drm_device *dev = crtc->dev; crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); + assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane); + assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe); if (crtc->fb) { mutex_lock(&dev->struct_mutex); -- cgit v1.2.3-70-g09d2 From 2aded1b6bb83cabe3ee5763e5c3834e36bf4a61f Mon Sep 17 00:00:00 2001 From: Simon Que Date: Thu, 10 Nov 2011 17:50:26 -0800 Subject: drivers: i915: Fix BLC PWM register setup There is an error in i915_read_blc_pwm_ctl, where the register values are not being copied correctly. BLC_PWM_CTL and BLC_PWM_CTL2 are getting mixed up. This patch fixes that so that saveBLC_PWM_CTL2 and not saveBLC_PWM_CTL is copied to the BLC_PWM_CTL2 register. Signed-off-by: Simon Que Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_panel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 04d79fd1dc9..c935cdaa215 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -141,8 +141,8 @@ static u32 i915_read_blc_pwm_ctl(struct drm_i915_private *dev_priv) dev_priv->saveBLC_PWM_CTL2 = val; } else if (val == 0) { I915_WRITE(BLC_PWM_PCH_CTL2, - dev_priv->saveBLC_PWM_CTL); - val = dev_priv->saveBLC_PWM_CTL; + dev_priv->saveBLC_PWM_CTL2); + val = dev_priv->saveBLC_PWM_CTL2; } } else { val = I915_READ(BLC_PWM_CTL); -- cgit v1.2.3-70-g09d2 From 28c057945ef5d164925db4fccc64207ee58c8681 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 7 Oct 2011 14:38:42 -0400 Subject: drm/i915: Implement plane-disabled assertion for PCH too Signed-off-by: Adam Jackson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5fa1476cbfc..d775f954c1b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -970,8 +970,14 @@ static void assert_planes_disabled(struct drm_i915_private *dev_priv, int cur_pipe; /* Planes are fixed to pipes on ILK+ */ - if (HAS_PCH_SPLIT(dev_priv->dev)) + if (HAS_PCH_SPLIT(dev_priv->dev)) { + reg = DSPCNTR(pipe); + val = I915_READ(reg); + WARN((val & DISPLAY_PLANE_ENABLE), + "plane %c assertion failure, should be disabled but not\n", + plane_name(pipe)); return; + } /* Need to check both planes against the pipe */ for (i = 0; i < 2; i++) { -- cgit v1.2.3-70-g09d2 From 23c99e775d14f01ba45a5affd2fb51af4328359c Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 7 Oct 2011 14:38:43 -0400 Subject: drm/i915: Fix assert_pch_hdmi_disabled to mention HDMI (not DP) Signed-off-by: Adam Jackson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d775f954c1b..3e21f3cb787 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1096,7 +1096,7 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv, { u32 val = I915_READ(reg); WARN(hdmi_pipe_enabled(dev_priv, val, pipe), - "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n", + "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n", reg, pipe_name(pipe)); } -- cgit v1.2.3-70-g09d2 From 1f182b27d50ae9f5efeb28be5b65302c8a81e711 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 7 Oct 2011 14:38:46 -0400 Subject: drm/i915: Remove a comment about PCH from the non-PCH path Signed-off-by: Adam Jackson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3e21f3cb787..ebe71eda954 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5235,8 +5235,6 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, /* Set up the display plane register */ dspcntr = DISPPLANE_GAMMA_ENABLE; - /* Ironlake's plane is forced to pipe, bit 24 is to - enable color space conversion */ if (pipe == 0) dspcntr &= ~DISPPLANE_SEL_PIPE_MASK; else -- cgit v1.2.3-70-g09d2 From 6919132e7a307b1f181d7655b3ef64cc7581a5ef Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 26 Jul 2011 15:39:44 -0400 Subject: drm/i915/dp: Tweak auxch clock divider for PCH Matches the advice in the Sandybridge documentation. Signed-off-by: Adam Jackson Acked-by: Jesse Barnes 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 db3b461ad41..add871911a6 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -378,7 +378,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, else aux_clock_divider = 225; /* eDP input clock at 450Mhz */ } else if (HAS_PCH_SPLIT(dev)) - aux_clock_divider = 62; /* IRL input clock fixed at 125Mhz */ + aux_clock_divider = 63; /* IRL input clock fixed at 125Mhz */ else aux_clock_divider = intel_hrawclk(dev) / 2; -- cgit v1.2.3-70-g09d2 From 092945e11c5b84f66dd08f0b87fb729715d377bc Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 26 Jul 2011 15:39:45 -0400 Subject: drm/i915/dp: Use auxch precharge value of 5 everywhere The default in the Sandybridge docs is 5, as on Ironlake, and I have no reason to believe 3 would work any better. Signed-off-by: Adam Jackson Acked-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index add871911a6..2f476638579 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -362,7 +362,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, int recv_bytes; uint32_t status; uint32_t aux_clock_divider; - int try, precharge; + int try, precharge = 5; intel_dp_check_edp(intel_dp); /* The clock divider is based off the hrawclk, @@ -382,11 +382,6 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, else aux_clock_divider = intel_hrawclk(dev) / 2; - if (IS_GEN6(dev)) - precharge = 3; - else - precharge = 5; - /* Try to wait for any previous AUX channel activity */ for (try = 0; try < 3; try++) { status = I915_READ(ch_ctl); -- cgit v1.2.3-70-g09d2 From d7e96feab83d29e27d14c60f1fa7c716ef7880cd Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 26 Jul 2011 15:39:46 -0400 Subject: drm/i915/dp: Check for AUXCH error before checking for success This is paranoid, but I am entirely willing to believe the hardware could come up with a condition where I get a status with both the 'done' and 'receive error' bits set. Signed-off-by: Adam Jackson Acked-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 2f476638579..8f1148c0410 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -426,6 +426,10 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, DP_AUX_CH_CTL_DONE | DP_AUX_CH_CTL_TIME_OUT_ERROR | DP_AUX_CH_CTL_RECEIVE_ERROR); + + if (status & (DP_AUX_CH_CTL_TIME_OUT_ERROR | + DP_AUX_CH_CTL_RECEIVE_ERROR)) + continue; if (status & DP_AUX_CH_CTL_DONE) break; } -- cgit v1.2.3-70-g09d2 From 493dea2876df144ec57a6a9efbe55db43c7a729e Mon Sep 17 00:00:00 2001 From: Thomas Meyer Date: Tue, 29 Nov 2011 22:08:00 +0100 Subject: drm/i915: Use kcalloc instead of kzalloc to allocate array The advantage of kcalloc is, that will prevent integer overflows which could result from the multiplication of number of elements and size and it is also a bit nicer to read. The semantic patch that makes this change is available in https://lkml.org/lkml/2011/11/25/107 Signed-off-by: Thomas Meyer Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_bios.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 63880e2e5cf..50656339d92 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -572,7 +572,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv, DRM_DEBUG_KMS("no child dev is parsed from VBT\n"); return; } - dev_priv->child_dev = kzalloc(sizeof(*p_child) * count, GFP_KERNEL); + dev_priv->child_dev = kcalloc(count, sizeof(*p_child), GFP_KERNEL); if (!dev_priv->child_dev) { DRM_DEBUG_KMS("No memory space for child device\n"); return; -- cgit v1.2.3-70-g09d2 From b2c606fe1defd1fb79612b48b528b2568c97def7 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 17 Jan 2012 12:50:12 +0100 Subject: drm/i915: kill i915_mem.c Some decent history digging indicates that this was to be used for the GLX_MESA_allocate_memory extension but never actually implemented for any released i915 userspace code. So just rip it out. v2: Fixup the Makefile. Acked-by: Dave Airlie Cc: Keith Whitwell Reviewed-by: Eric Anholt Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/drm_ioctl.c | 2 + drivers/gpu/drm/i915/Makefile | 2 +- drivers/gpu/drm/i915/i915_dma.c | 14 +- drivers/gpu/drm/i915/i915_drv.h | 13 -- drivers/gpu/drm/i915/i915_mem.c | 387 ---------------------------------------- 5 files changed, 7 insertions(+), 411 deletions(-) delete mode 100644 drivers/gpu/drm/i915/i915_mem.c (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 956fd38d7c9..2300ab1a2a7 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -37,6 +37,7 @@ #include "drm_core.h" #include "linux/pci.h" +#include "linux/export.h" /** * Get the bus id. @@ -346,3 +347,4 @@ int drm_noop(struct drm_device *dev, void *data, DRM_DEBUG("\n"); return 0; } +EXPORT_SYMBOL(drm_noop); diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 808b255d7fc..ce7fc77678b 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -3,7 +3,7 @@ # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. ccflags-y := -Iinclude/drm -i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ +i915-y := i915_drv.o i915_dma.o i915_irq.o \ i915_debugfs.o \ i915_suspend.o \ i915_gem.o \ diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 5f4d5893e98..2484c8ff0b8 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -2246,18 +2246,12 @@ void i915_driver_lastclose(struct drm_device * dev) i915_gem_lastclose(dev); - if (dev_priv->agp_heap) - i915_mem_takedown(&(dev_priv->agp_heap)); - i915_dma_cleanup(dev); } void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) { - drm_i915_private_t *dev_priv = dev->dev_private; i915_gem_release(dev, file_priv); - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - i915_mem_release(dev, file_priv, dev_priv->agp_heap); } void i915_driver_postclose(struct drm_device *dev, struct drm_file *file) @@ -2276,11 +2270,11 @@ struct drm_ioctl_desc i915_ioctls[] = { DRM_IOCTL_DEF_DRV(I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH), DRM_IOCTL_DEF_DRV(I915_GETPARAM, i915_getparam, DRM_AUTH), DRM_IOCTL_DEF_DRV(I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(I915_ALLOC, i915_mem_alloc, DRM_AUTH), - DRM_IOCTL_DEF_DRV(I915_FREE, i915_mem_free, DRM_AUTH), - DRM_IOCTL_DEF_DRV(I915_INIT_HEAP, i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(I915_ALLOC, drm_noop, DRM_AUTH), + DRM_IOCTL_DEF_DRV(I915_FREE, drm_noop, DRM_AUTH), + DRM_IOCTL_DEF_DRV(I915_INIT_HEAP, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF_DRV(I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH), - DRM_IOCTL_DEF_DRV(I915_DESTROY_HEAP, i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(I915_DESTROY_HEAP, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF_DRV(I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF_DRV(I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH), DRM_IOCTL_DEF_DRV(I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 602bc80baab..3cb88c3e056 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -329,7 +329,6 @@ typedef struct drm_i915_private { int tex_lru_log_granularity; int allow_batchbuffer; - struct mem_block *agp_heap; unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; int vblank_pipe; int num_pipe; @@ -1075,18 +1074,6 @@ extern void i915_destroy_error_state(struct drm_device *dev); #endif -/* i915_mem.c */ -extern int i915_mem_alloc(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int i915_mem_free(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int i915_mem_init_heap(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int i915_mem_destroy_heap(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern void i915_mem_takedown(struct mem_block **heap); -extern void i915_mem_release(struct drm_device * dev, - struct drm_file *file_priv, struct mem_block *heap); /* i915_gem.c */ int i915_gem_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); diff --git a/drivers/gpu/drm/i915/i915_mem.c b/drivers/gpu/drm/i915/i915_mem.c deleted file mode 100644 index cc8f6d49cf2..00000000000 --- a/drivers/gpu/drm/i915/i915_mem.c +++ /dev/null @@ -1,387 +0,0 @@ -/* i915_mem.c -- Simple agp/fb memory manager for i915 -*- linux-c -*- - */ -/* - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "drm.h" -#include "i915_drm.h" -#include "i915_drv.h" - -/* This memory manager is integrated into the global/local lru - * mechanisms used by the clients. Specifically, it operates by - * setting the 'in_use' fields of the global LRU to indicate whether - * this region is privately allocated to a client. - * - * This does require the client to actually respect that field. - * - * Currently no effort is made to allocate 'private' memory in any - * clever way - the LRU information isn't used to determine which - * block to allocate, and the ring is drained prior to allocations -- - * in other words allocation is expensive. - */ -static void mark_block(struct drm_device * dev, struct mem_block *p, int in_use) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; - drm_i915_sarea_t *sarea_priv = master_priv->sarea_priv; - struct drm_tex_region *list; - unsigned shift, nr; - unsigned start; - unsigned end; - unsigned i; - int age; - - shift = dev_priv->tex_lru_log_granularity; - nr = I915_NR_TEX_REGIONS; - - start = p->start >> shift; - end = (p->start + p->size - 1) >> shift; - - age = ++sarea_priv->texAge; - list = sarea_priv->texList; - - /* Mark the regions with the new flag and update their age. Move - * them to head of list to preserve LRU semantics. - */ - for (i = start; i <= end; i++) { - list[i].in_use = in_use; - list[i].age = age; - - /* remove_from_list(i) - */ - list[(unsigned)list[i].next].prev = list[i].prev; - list[(unsigned)list[i].prev].next = list[i].next; - - /* insert_at_head(list, i) - */ - list[i].prev = nr; - list[i].next = list[nr].next; - list[(unsigned)list[nr].next].prev = i; - list[nr].next = i; - } -} - -/* Very simple allocator for agp memory, working on a static range - * already mapped into each client's address space. - */ - -static struct mem_block *split_block(struct mem_block *p, int start, int size, - struct drm_file *file_priv) -{ - /* Maybe cut off the start of an existing block */ - if (start > p->start) { - struct mem_block *newblock = kmalloc(sizeof(*newblock), - GFP_KERNEL); - if (!newblock) - goto out; - newblock->start = start; - newblock->size = p->size - (start - p->start); - newblock->file_priv = NULL; - newblock->next = p->next; - newblock->prev = p; - p->next->prev = newblock; - p->next = newblock; - p->size -= newblock->size; - p = newblock; - } - - /* Maybe cut off the end of an existing block */ - if (size < p->size) { - struct mem_block *newblock = kmalloc(sizeof(*newblock), - GFP_KERNEL); - if (!newblock) - goto out; - newblock->start = start + size; - newblock->size = p->size - size; - newblock->file_priv = NULL; - newblock->next = p->next; - newblock->prev = p; - p->next->prev = newblock; - p->next = newblock; - p->size = size; - } - - out: - /* Our block is in the middle */ - p->file_priv = file_priv; - return p; -} - -static struct mem_block *alloc_block(struct mem_block *heap, int size, - int align2, struct drm_file *file_priv) -{ - struct mem_block *p; - int mask = (1 << align2) - 1; - - for (p = heap->next; p != heap; p = p->next) { - int start = (p->start + mask) & ~mask; - if (p->file_priv == NULL && start + size <= p->start + p->size) - return split_block(p, start, size, file_priv); - } - - return NULL; -} - -static struct mem_block *find_block(struct mem_block *heap, int start) -{ - struct mem_block *p; - - for (p = heap->next; p != heap; p = p->next) - if (p->start == start) - return p; - - return NULL; -} - -static void free_block(struct mem_block *p) -{ - p->file_priv = NULL; - - /* Assumes a single contiguous range. Needs a special file_priv in - * 'heap' to stop it being subsumed. - */ - if (p->next->file_priv == NULL) { - struct mem_block *q = p->next; - p->size += q->size; - p->next = q->next; - p->next->prev = p; - kfree(q); - } - - if (p->prev->file_priv == NULL) { - struct mem_block *q = p->prev; - q->size += p->size; - q->next = p->next; - q->next->prev = q; - kfree(p); - } -} - -/* Initialize. How to check for an uninitialized heap? - */ -static int init_heap(struct mem_block **heap, int start, int size) -{ - struct mem_block *blocks = kmalloc(sizeof(*blocks), GFP_KERNEL); - - if (!blocks) - return -ENOMEM; - - *heap = kmalloc(sizeof(**heap), GFP_KERNEL); - if (!*heap) { - kfree(blocks); - return -ENOMEM; - } - - blocks->start = start; - blocks->size = size; - blocks->file_priv = NULL; - blocks->next = blocks->prev = *heap; - - memset(*heap, 0, sizeof(**heap)); - (*heap)->file_priv = (struct drm_file *) -1; - (*heap)->next = (*heap)->prev = blocks; - return 0; -} - -/* Free all blocks associated with the releasing file. - */ -void i915_mem_release(struct drm_device * dev, struct drm_file *file_priv, - struct mem_block *heap) -{ - struct mem_block *p; - - if (!heap || !heap->next) - return; - - for (p = heap->next; p != heap; p = p->next) { - if (p->file_priv == file_priv) { - p->file_priv = NULL; - mark_block(dev, p, 0); - } - } - - /* Assumes a single contiguous range. Needs a special file_priv in - * 'heap' to stop it being subsumed. - */ - for (p = heap->next; p != heap; p = p->next) { - while (p->file_priv == NULL && p->next->file_priv == NULL) { - struct mem_block *q = p->next; - p->size += q->size; - p->next = q->next; - p->next->prev = p; - kfree(q); - } - } -} - -/* Shutdown. - */ -void i915_mem_takedown(struct mem_block **heap) -{ - struct mem_block *p; - - if (!*heap) - return; - - for (p = (*heap)->next; p != *heap;) { - struct mem_block *q = p; - p = p->next; - kfree(q); - } - - kfree(*heap); - *heap = NULL; -} - -static struct mem_block **get_heap(drm_i915_private_t * dev_priv, int region) -{ - switch (region) { - case I915_MEM_REGION_AGP: - return &dev_priv->agp_heap; - default: - return NULL; - } -} - -/* IOCTL HANDLERS */ - -int i915_mem_alloc(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_mem_alloc_t *alloc = data; - struct mem_block *block, **heap; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - heap = get_heap(dev_priv, alloc->region); - if (!heap || !*heap) - return -EFAULT; - - /* Make things easier on ourselves: all allocations at least - * 4k aligned. - */ - if (alloc->alignment < 12) - alloc->alignment = 12; - - block = alloc_block(*heap, alloc->size, alloc->alignment, file_priv); - - if (!block) - return -ENOMEM; - - mark_block(dev, block, 1); - - if (DRM_COPY_TO_USER(alloc->region_offset, &block->start, - sizeof(int))) { - DRM_ERROR("copy_to_user\n"); - return -EFAULT; - } - - return 0; -} - -int i915_mem_free(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_mem_free_t *memfree = data; - struct mem_block *block, **heap; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - heap = get_heap(dev_priv, memfree->region); - if (!heap || !*heap) - return -EFAULT; - - block = find_block(*heap, memfree->region_offset); - if (!block) - return -EFAULT; - - if (block->file_priv != file_priv) - return -EPERM; - - mark_block(dev, block, 0); - free_block(block); - return 0; -} - -int i915_mem_init_heap(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_mem_init_heap_t *initheap = data; - struct mem_block **heap; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - heap = get_heap(dev_priv, initheap->region); - if (!heap) - return -EFAULT; - - if (*heap) { - DRM_ERROR("heap already initialized?"); - return -EFAULT; - } - - return init_heap(heap, initheap->start, initheap->size); -} - -int i915_mem_destroy_heap(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_mem_destroy_heap_t *destroyheap = data; - struct mem_block **heap; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - heap = get_heap(dev_priv, destroyheap->region); - if (!heap) { - DRM_ERROR("get_heap failed"); - return -EFAULT; - } - - if (!*heap) { - DRM_ERROR("heap not initialized?"); - return -EFAULT; - } - - i915_mem_takedown(heap); - return 0; -} -- cgit v1.2.3-70-g09d2 From 3d29b842e58fbca2c13a9f458fddbaa535c6e578 Mon Sep 17 00:00:00 2001 From: Eugeni Dodonov Date: Tue, 17 Jan 2012 14:43:53 -0200 Subject: drm/i915: add a LLC feature flag in device description LLC is not SNB/IVB-specific, so we should check for it in a more generic way. Reviewed-by: Chris Wilson Reviewed-by: Eric Anholt Reviewed-by: Kenneth Graunke Signed-off-by: Eugeni Dodonov Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 1 + drivers/gpu/drm/i915/i915_dma.c | 3 +++ drivers/gpu/drm/i915/i915_drv.c | 4 ++++ drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_gem.c | 4 ++-- include/drm/i915_drm.h | 1 + 6 files changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 11807989f91..6c3be86274e 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -83,6 +83,7 @@ static int i915_capabilities(struct seq_file *m, void *data) B(supports_tv); B(has_bsd_ring); B(has_blt_ring); + B(has_llc); #undef B return 0; diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 2484c8ff0b8..8122738db91 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -784,6 +784,9 @@ static int i915_getparam(struct drm_device *dev, void *data, case I915_PARAM_HAS_GEN7_SOL_RESET: value = 1; break; + case I915_PARAM_HAS_LLC: + value = HAS_LLC(dev); + break; default: DRM_DEBUG_DRIVER("Unknown parameter %d\n", param->param); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 7578c08110f..1658cfd85aa 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -214,6 +214,7 @@ static const struct intel_device_info intel_sandybridge_d_info = { .need_gfx_hws = 1, .has_hotplug = 1, .has_bsd_ring = 1, .has_blt_ring = 1, + .has_llc = 1, }; static const struct intel_device_info intel_sandybridge_m_info = { @@ -222,6 +223,7 @@ static const struct intel_device_info intel_sandybridge_m_info = { .has_fbc = 1, .has_bsd_ring = 1, .has_blt_ring = 1, + .has_llc = 1, }; static const struct intel_device_info intel_ivybridge_d_info = { @@ -229,6 +231,7 @@ static const struct intel_device_info intel_ivybridge_d_info = { .need_gfx_hws = 1, .has_hotplug = 1, .has_bsd_ring = 1, .has_blt_ring = 1, + .has_llc = 1, }; static const struct intel_device_info intel_ivybridge_m_info = { @@ -237,6 +240,7 @@ static const struct intel_device_info intel_ivybridge_m_info = { .has_fbc = 0, /* FBC is not enabled on Ivybridge mobile yet */ .has_bsd_ring = 1, .has_blt_ring = 1, + .has_llc = 1, }; static const struct pci_device_id pciidlist[] = { /* aka */ diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 3cb88c3e056..f02a5f525f0 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -255,6 +255,7 @@ struct intel_device_info { u8 supports_tv:1; u8 has_bsd_ring:1; u8 has_blt_ring:1; + u8 has_llc:1; }; enum no_fbc_reason { @@ -969,6 +970,7 @@ struct drm_i915_file_private { #define HAS_BSD(dev) (INTEL_INFO(dev)->has_bsd_ring) #define HAS_BLT(dev) (INTEL_INFO(dev)->has_blt_ring) +#define HAS_LLC(dev) (INTEL_INFO(dev)->has_llc) #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) #define HAS_OVERLAY(dev) (INTEL_INFO(dev)->has_overlay) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e55badb2d86..eb98a7f55cf 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3619,8 +3619,8 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, obj->base.write_domain = I915_GEM_DOMAIN_CPU; obj->base.read_domains = I915_GEM_DOMAIN_CPU; - if (IS_GEN6(dev) || IS_GEN7(dev)) { - /* On Gen6, we can have the GPU use the LLC (the CPU + if (HAS_LLC(dev)) { + /* On some devices, we can have the GPU use the LLC (the CPU * cache) for about a 10% performance improvement * compared to uncached. Graphics requests other than * display scanout are coherent with the CPU in diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index 924f6a454fe..da929bb5b78 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h @@ -296,6 +296,7 @@ typedef struct drm_i915_irq_wait { #define I915_PARAM_HAS_EXEC_CONSTANTS 14 #define I915_PARAM_HAS_RELAXED_DELTA 15 #define I915_PARAM_HAS_GEN7_SOL_RESET 16 +#define I915_PARAM_HAS_LLC 17 typedef struct drm_i915_getparam { int param; -- cgit v1.2.3-70-g09d2 From d6f802612af55cc1b3699d119a04dfa2fc8812a0 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 17 Jan 2012 15:05:19 +0200 Subject: ath6kl: use netdev_features_t Commit c8f44affb7 ("net: introduce and use netdev_features_t for device features sets") added netdev_features_t to ndo_set_features. Change ath6kl to use the new type. This fixes a warning: ath6kl/main.c:1170: warning: initialization from incompatible pointer type Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index 0a6d6e2be6e..3a3b2cc9940 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -1021,7 +1021,8 @@ static struct net_device_stats *ath6kl_get_stats(struct net_device *dev) return &vif->net_stats; } -static int ath6kl_set_features(struct net_device *dev, u32 features) +static int ath6kl_set_features(struct net_device *dev, + netdev_features_t features) { struct ath6kl_vif *vif = netdev_priv(dev); struct ath6kl *ar = vif->ar; -- cgit v1.2.3-70-g09d2 From 3462735dadb90efd5bed9d2b81222ed7da1390a0 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 17 Jan 2012 15:05:32 +0200 Subject: ath6kl: remove -D__CHECK_ENDIAN__ from Makefile As drivers/net/wireless/ath/Makefile contains the flag to enable endian checks there's no need to have it in ath6kl makefile anymore. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/Makefile | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile index 70706930355..e24b6179915 100644 --- a/drivers/net/wireless/ath/ath6kl/Makefile +++ b/drivers/net/wireless/ath/ath6kl/Makefile @@ -33,5 +33,3 @@ ath6kl-y += txrx.o ath6kl-y += wmi.o ath6kl-y += sdio.o ath6kl-$(CONFIG_NL80211_TESTMODE) += testmode.o - -ccflags-y += -D__CHECK_ENDIAN__ -- cgit v1.2.3-70-g09d2 From e572602884c4f979cbba4fed413af24797fd01d9 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 17 Jan 2012 15:05:46 +0200 Subject: ath6kl: fix uninitialized warning in ath6kl_process_uapsdq() Before I commited patch c1762a3fe ("ath6kl: Add support for uAPSD") I did a minor change how up variable is initialised in ath6kl_process_uapsdq(). But I was sloppy and caused this compiler warning: txrx.c:88:5: warning: 'up' may be used uninitialized in this function Revert my change to fix the warning. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/txrx.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index 91bbc1ffa49..dd633714260 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -85,7 +85,7 @@ static bool ath6kl_process_uapsdq(struct ath6kl_sta *conn, struct ath6kl *ar = vif->ar; bool is_apsdq_empty = false; struct ethhdr *datap = (struct ethhdr *) skb->data; - u8 up, traffic_class, *ip_hdr; + u8 up = 0, traffic_class, *ip_hdr; u16 ether_type; struct ath6kl_llc_snap_hdr *llc_hdr; @@ -122,8 +122,6 @@ static bool ath6kl_process_uapsdq(struct ath6kl_sta *conn, if (ether_type == IP_ETHERTYPE) up = ath6kl_wmi_determine_user_priority( ip_hdr, 0); - } else { - up = 0; } traffic_class = ath6kl_wmi_get_traffic_class(up); -- cgit v1.2.3-70-g09d2 From cd23c1c9b8a2de64477a795ab5a9cd5278397f24 Mon Sep 17 00:00:00 2001 From: Alex Yang Date: Tue, 17 Jan 2012 15:32:29 +0200 Subject: ath6kl: add testmode 2 for 6003 ART Add testmode 2 for 6003 ART. When you insmod ath6kl_sdio.ko testmode=2, ath6kl will load ART firmware utf.bin and testscript nullTestFlow.bin. These files should be put in the firmware folder. kvalo: add "ath6kl:" to the title, word wrap the commit log and remove extra line in the code Signed-off-by: Alex Yang Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/core.h | 8 +++ drivers/net/wireless/ath/ath6kl/init.c | 108 +++++++++++++++++++++++++++++++-- 2 files changed, 110 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index ba3953918e4..f53594f2e53 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -125,6 +125,8 @@ struct ath6kl_fw_ie { #define AR6003_HW_2_1_1_OTP_FILE "otp.bin" #define AR6003_HW_2_1_1_FIRMWARE_FILE "athwlan.bin" #define AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE "athtcmd_ram.bin" +#define AR6003_HW_2_1_1_UTF_FIRMWARE_FILE "utf.bin" +#define AR6003_HW_2_1_1_TESTSCRIPT_FILE "nullTestFlow.bin" #define AR6003_HW_2_1_1_PATCH_FILE "data.patch.bin" #define AR6003_HW_2_1_1_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.bin" #define AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE \ @@ -592,6 +594,7 @@ struct ath6kl { u32 board_addr; u32 refclk_hz; u32 uarttx_pin; + u32 testscript_addr; struct ath6kl_hw_fw { const char *dir; @@ -599,6 +602,8 @@ struct ath6kl { const char *fw; const char *tcmd; const char *patch; + const char *utf; + const char *testscript; } fw; const char *fw_board; @@ -624,6 +629,9 @@ struct ath6kl { u8 *fw_patch; size_t fw_patch_len; + u8 *fw_testscript; + size_t fw_testscript_len; + unsigned int fw_api; unsigned long fw_capabilities[ATH6KL_CAPABILITY_LEN]; diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index e5969c14630..b88f41dc3df 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -69,6 +69,7 @@ static const struct ath6kl_hw hw_list[] = { .reserved_ram_size = 512, .refclk_hz = 26000000, .uarttx_pin = 8, + .testscript_addr = 0x57ef74, .fw = { .dir = AR6003_HW_2_1_1_FW_DIR, @@ -76,6 +77,8 @@ static const struct ath6kl_hw hw_list[] = { .fw = AR6003_HW_2_1_1_FIRMWARE_FILE, .tcmd = AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE, .patch = AR6003_HW_2_1_1_PATCH_FILE, + .utf = AR6003_HW_2_1_1_UTF_FIRMWARE_FILE, + .testscript = AR6003_HW_2_1_1_TESTSCRIPT_FILE, }, .fw_board = AR6003_HW_2_1_1_BOARD_DATA_FILE, @@ -620,6 +623,7 @@ void ath6kl_core_cleanup(struct ath6kl *ar) kfree(ar->fw_otp); kfree(ar->fw); kfree(ar->fw_patch); + kfree(ar->fw_testscript); ath6kl_deinit_ieee80211_hw(ar); } @@ -771,14 +775,25 @@ static int ath6kl_fetch_fw_file(struct ath6kl *ar) return 0; if (testmode) { - if (ar->hw.fw.tcmd == NULL) { - ath6kl_warn("testmode not supported\n"); - return -EOPNOTSUPP; - } + ath6kl_dbg(ATH6KL_DBG_BOOT, "testmode %d\n", + testmode); + if (testmode == 2) { + if (ar->hw.fw.utf == NULL) { + ath6kl_warn("testmode 2 not supported\n"); + return -EOPNOTSUPP; + } - snprintf(filename, sizeof(filename), "%s/%s", - ar->hw.fw.dir, ar->hw.fw.tcmd); + snprintf(filename, sizeof(filename), "%s/%s", + ar->hw.fw.dir, ar->hw.fw.utf); + } else { + if (ar->hw.fw.tcmd == NULL) { + ath6kl_warn("testmode 1 not supported\n"); + return -EOPNOTSUPP; + } + snprintf(filename, sizeof(filename), "%s/%s", + ar->hw.fw.dir, ar->hw.fw.tcmd); + } set_bit(TESTMODE, &ar->flag); goto get_fw; @@ -827,6 +842,34 @@ static int ath6kl_fetch_patch_file(struct ath6kl *ar) return 0; } +static int ath6kl_fetch_testscript_file(struct ath6kl *ar) +{ + char filename[100]; + int ret; + + if (testmode != 2) + return 0; + + if (ar->fw_testscript != NULL) + return 0; + + if (ar->hw.fw.testscript == NULL) + return 0; + + snprintf(filename, sizeof(filename), "%s/%s", + ar->hw.fw.dir, ar->hw.fw.testscript); + + ret = ath6kl_get_fw(ar, filename, &ar->fw_testscript, + &ar->fw_testscript_len); + if (ret) { + ath6kl_err("Failed to get testscript file %s: %d\n", + filename, ret); + return ret; + } + + return 0; +} + static int ath6kl_fetch_fw_api1(struct ath6kl *ar) { int ret; @@ -843,6 +886,10 @@ static int ath6kl_fetch_fw_api1(struct ath6kl *ar) if (ret) return ret; + ret = ath6kl_fetch_testscript_file(ar); + if (ret) + return ret; + return 0; } @@ -1266,6 +1313,50 @@ static int ath6kl_upload_patch(struct ath6kl *ar) return 0; } +static int ath6kl_upload_testscript(struct ath6kl *ar) +{ + u32 address, param; + int ret; + + if (testmode != 2) + return 0; + + if (ar->fw_testscript == NULL) + return 0; + + address = ar->hw.testscript_addr; + + ath6kl_dbg(ATH6KL_DBG_BOOT, "writing testscript to 0x%x (%zd B)\n", + address, ar->fw_testscript_len); + + ret = ath6kl_bmi_write(ar, address, ar->fw_testscript, + ar->fw_testscript_len); + if (ret) { + ath6kl_err("Failed to write testscript file: %d\n", ret); + return ret; + } + + param = address; + ath6kl_bmi_write(ar, + ath6kl_get_hi_item_addr(ar, + HI_ITEM(hi_ota_testscript)), + (unsigned char *) ¶m, 4); + + param = 4096; + ath6kl_bmi_write(ar, + ath6kl_get_hi_item_addr(ar, + HI_ITEM(hi_end_ram_reserve_sz)), + (unsigned char *) ¶m, 4); + + param = 1; + ath6kl_bmi_write(ar, + ath6kl_get_hi_item_addr(ar, + HI_ITEM(hi_test_apps_related)), + (unsigned char *) ¶m, 4); + + return 0; +} + static int ath6kl_init_upload(struct ath6kl *ar) { u32 param, options, sleep, address; @@ -1374,6 +1465,11 @@ static int ath6kl_init_upload(struct ath6kl *ar) if (status) return status; + /* Download the test script */ + status = ath6kl_upload_testscript(ar); + if (status) + return status; + /* Restore system sleep */ address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS; status = ath6kl_bmi_reg_write(ar, address, sleep); -- cgit v1.2.3-70-g09d2 From c25889e8a6fdfc54618b192a80c94419ddb7949d Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 17 Jan 2012 20:08:27 +0200 Subject: ath6kl: rename vif init and cleanup functions ath6kl_cfg80211_vif_init/cleanup() follow more closely the style used elsewhere in ath6kl. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 9 ++++----- drivers/net/wireless/ath/ath6kl/cfg80211.h | 2 ++ drivers/net/wireless/ath/ath6kl/core.h | 1 - drivers/net/wireless/ath/ath6kl/init.c | 5 +++-- 4 files changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index a13ecec0070..7e92dc9799a 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -1401,7 +1401,7 @@ static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy, ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag)); - ath6kl_deinit_if_data(vif); + ath6kl_cfg80211_vif_cleanup(vif); return 0; } @@ -2806,7 +2806,7 @@ int ath6kl_register_ieee80211_hw(struct ath6kl *ar) return 0; } -static int ath6kl_init_if_data(struct ath6kl_vif *vif) +static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif) { vif->aggr_cntxt = aggr_init(vif->ndev); if (!vif->aggr_cntxt) { @@ -2827,7 +2827,7 @@ static int ath6kl_init_if_data(struct ath6kl_vif *vif) return 0; } -void ath6kl_deinit_if_data(struct ath6kl_vif *vif) +void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif) { struct ath6kl *ar = vif->ar; struct ath6kl_mc_filter *mc_filter, *tmp; @@ -2880,8 +2880,7 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, ath6kl_init_control_info(vif); - /* TODO: Pass interface specific pointer instead of ar */ - if (ath6kl_init_if_data(vif)) + if (ath6kl_cfg80211_vif_init(vif)) goto err; if (register_netdevice(ndev)) diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h index 81f20a57231..aa961694cf9 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.h +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h @@ -53,6 +53,8 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar, int ath6kl_cfg80211_resume(struct ath6kl *ar); +void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif); + void ath6kl_cfg80211_stop(struct ath6kl_vif *vif); void ath6kl_cfg80211_stop_all(struct ath6kl *ar); diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index f53594f2e53..bdeb254c259 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -753,7 +753,6 @@ void ath6kl_wakeup_event(void *dev); void ath6kl_reset_device(struct ath6kl *ar, u32 target_type, bool wait_fot_compltn, bool cold_reset); void ath6kl_init_control_info(struct ath6kl_vif *vif); -void ath6kl_deinit_if_data(struct ath6kl_vif *vif); void ath6kl_core_free(struct ath6kl *ar); struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar); void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready); diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index b88f41dc3df..3cc4e0842ad 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -1811,7 +1811,7 @@ err_rxbuf_cleanup: ath6kl_htc_flush_rx_buf(ar->htc_target); ath6kl_cleanup_amsdu_rxbufs(ar); rtnl_lock(); - ath6kl_deinit_if_data(netdev_priv(ndev)); + ath6kl_cfg80211_vif_cleanup(netdev_priv(ndev)); rtnl_unlock(); wiphy_unregister(ar->wiphy); err_debug_init: @@ -1832,6 +1832,7 @@ err_wq: return ret; } +/* FIXME: move this to cfg80211.c and rename to ath6kl_cfg80211_vif_stop() */ void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready) { static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; @@ -1877,7 +1878,7 @@ void ath6kl_stop_txrx(struct ath6kl *ar) spin_unlock_bh(&ar->list_lock); ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag)); rtnl_lock(); - ath6kl_deinit_if_data(vif); + ath6kl_cfg80211_vif_cleanup(vif); rtnl_unlock(); spin_lock_bh(&ar->list_lock); } -- cgit v1.2.3-70-g09d2 From 46d33a21cfa531f4271c3f0b7b87a295f30f9e6a Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 17 Jan 2012 20:08:40 +0200 Subject: ath6kl: unify cfg80211 init/cleanup functions Group them together and change the naming to follow the common style in ath6kl. No functional changes. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 109 +++++++++++++++-------------- drivers/net/wireless/ath/ath6kl/cfg80211.h | 6 +- drivers/net/wireless/ath/ath6kl/init.c | 4 +- 3 files changed, 62 insertions(+), 57 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 7e92dc9799a..44fdd39e170 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -2755,57 +2755,6 @@ struct ath6kl *ath6kl_core_alloc(struct device *dev) return ar; } -int ath6kl_register_ieee80211_hw(struct ath6kl *ar) -{ - struct wiphy *wiphy = ar->wiphy; - int ret; - - wiphy->mgmt_stypes = ath6kl_mgmt_stypes; - - wiphy->max_remain_on_channel_duration = 5000; - - /* set device pointer for wiphy */ - set_wiphy_dev(wiphy, ar->dev); - - wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC) | - BIT(NL80211_IFTYPE_AP); - if (ar->p2p) { - wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) | - BIT(NL80211_IFTYPE_P2P_CLIENT); - } - - /* max num of ssids that can be probed during scanning */ - wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX; - wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */ - wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz; - wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz; - wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; - - wiphy->cipher_suites = cipher_suites; - wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); - - wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | - WIPHY_WOWLAN_DISCONNECT | - WIPHY_WOWLAN_GTK_REKEY_FAILURE | - WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | - WIPHY_WOWLAN_EAP_IDENTITY_REQ | - WIPHY_WOWLAN_4WAY_HANDSHAKE; - wiphy->wowlan.n_patterns = WOW_MAX_FILTERS_PER_LIST; - wiphy->wowlan.pattern_min_len = 1; - wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE; - - wiphy->max_sched_scan_ssids = 10; - - ret = wiphy_register(wiphy); - if (ret < 0) { - ath6kl_err("couldn't register wiphy device\n"); - return ret; - } - - return 0; -} - static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif) { vif->aggr_cntxt = aggr_init(vif->ndev); @@ -2907,8 +2856,64 @@ err: return NULL; } -void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar) +int ath6kl_cfg80211_init(struct ath6kl *ar) +{ + struct wiphy *wiphy = ar->wiphy; + int ret; + + wiphy->mgmt_stypes = ath6kl_mgmt_stypes; + + wiphy->max_remain_on_channel_duration = 5000; + + /* set device pointer for wiphy */ + set_wiphy_dev(wiphy, ar->dev); + + wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC) | + BIT(NL80211_IFTYPE_AP); + if (ar->p2p) { + wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) | + BIT(NL80211_IFTYPE_P2P_CLIENT); + } + + /* max num of ssids that can be probed during scanning */ + wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX; + wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */ + wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz; + wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz; + wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; + + wiphy->cipher_suites = cipher_suites; + wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); + + wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | + WIPHY_WOWLAN_DISCONNECT | + WIPHY_WOWLAN_GTK_REKEY_FAILURE | + WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | + WIPHY_WOWLAN_EAP_IDENTITY_REQ | + WIPHY_WOWLAN_4WAY_HANDSHAKE; + wiphy->wowlan.n_patterns = WOW_MAX_FILTERS_PER_LIST; + wiphy->wowlan.pattern_min_len = 1; + wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE; + + wiphy->max_sched_scan_ssids = 10; + + ret = wiphy_register(wiphy); + if (ret < 0) { + ath6kl_err("couldn't register wiphy device\n"); + return ret; + } + + return 0; +} + +void ath6kl_cfg80211_cleanup(struct ath6kl *ar) { wiphy_unregister(ar->wiphy); + + /* + * FIXME: should be removed as we remove wiphy in + * ath6kl_core_free(). Most likely this causes a use after free. + */ wiphy_free(ar->wiphy); } diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h index aa961694cf9..08d97691039 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.h +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h @@ -27,10 +27,7 @@ enum ath6kl_cfg_suspend_mode { struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, enum nl80211_iftype type, u8 fw_vif_idx, u8 nw_type); -int ath6kl_register_ieee80211_hw(struct ath6kl *ar); struct ath6kl *ath6kl_core_alloc(struct device *dev); -void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar); - void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted); void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, @@ -58,4 +55,7 @@ void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif); void ath6kl_cfg80211_stop(struct ath6kl_vif *vif); void ath6kl_cfg80211_stop_all(struct ath6kl *ar); +int ath6kl_cfg80211_init(struct ath6kl *ar); +void ath6kl_cfg80211_cleanup(struct ath6kl *ar); + #endif /* ATH6KL_CFG80211_H */ diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 3cc4e0842ad..7e56a6aa70b 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -625,7 +625,7 @@ void ath6kl_core_cleanup(struct ath6kl *ar) kfree(ar->fw_patch); kfree(ar->fw_testscript); - ath6kl_deinit_ieee80211_hw(ar); + ath6kl_cfg80211_cleanup(ar); } /* firmware upload */ @@ -1722,7 +1722,7 @@ int ath6kl_core_init(struct ath6kl *ar) ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi); - ret = ath6kl_register_ieee80211_hw(ar); + ret = ath6kl_cfg80211_init(ar); if (ret) goto err_node_cleanup; -- cgit v1.2.3-70-g09d2 From f29af97853599e9537191c4f33f8ac87f3f503a9 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 17 Jan 2012 20:08:56 +0200 Subject: ath6kl: add ATH6KL_CONF_UART_DEBUG Add ATH6KL_CONF_UART_DEBUG which is set whenever uart_debug module parameter is enabled. This way we can keep the uart_debug parameter static when core.c file is introduced. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/core.h | 1 + drivers/net/wireless/ath/ath6kl/init.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index bdeb254c259..78c0402e2d3 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -197,6 +197,7 @@ struct ath6kl_fw_ie { #define ATH6KL_CONF_ENABLE_11N BIT(2) #define ATH6KL_CONF_ENABLE_TX_BURST BIT(3) #define ATH6KL_CONF_SUSPEND_CUTPOWER BIT(4) +#define ATH6KL_CONF_UART_DEBUG BIT(5) enum wlan_low_pwr_state { WLAN_POWER_STATE_ON, diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 7e56a6aa70b..2804921d5d8 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -469,7 +469,7 @@ int ath6kl_configure_target(struct ath6kl *ar) u8 fw_iftype, fw_mode = 0, fw_submode = 0; int i, status; - param = uart_debug; + param = !!(ar->conf_flags & ATH6KL_CONF_UART_DEBUG); if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_serial_enable)), (u8 *)¶m, 4)) { ath6kl_err("bmi_write_memory for uart debug failed\n"); @@ -1775,6 +1775,9 @@ int ath6kl_core_init(struct ath6kl *ar) if (suspend_cutpower) ar->conf_flags |= ATH6KL_CONF_SUSPEND_CUTPOWER; + if (uart_debug) + ar->conf_flags |= ATH6KL_CONF_UART_DEBUG; + ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM | WIPHY_FLAG_HAVE_AP_SME | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | -- cgit v1.2.3-70-g09d2 From 45eaa78f757b3b3992ca02c753764665e9fba0a4 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 17 Jan 2012 20:09:05 +0200 Subject: ath6kl: create core.c Currently core functions are spread between various files, group all the functions into file and rename the functions to follow the style used elsewhere in the driver. This will make it easier to a separate core module. Also fix a bug where wiphy is freed too early. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/Makefile | 1 + drivers/net/wireless/ath/ath6kl/cfg80211.c | 94 +++------- drivers/net/wireless/ath/ath6kl/cfg80211.h | 4 +- drivers/net/wireless/ath/ath6kl/common.h | 3 - drivers/net/wireless/ath/ath6kl/core.c | 292 +++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath6kl/core.h | 9 +- drivers/net/wireless/ath/ath6kl/init.c | 213 +-------------------- drivers/net/wireless/ath/ath6kl/sdio.c | 4 +- 8 files changed, 332 insertions(+), 288 deletions(-) create mode 100644 drivers/net/wireless/ath/ath6kl/core.c (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile index e24b6179915..854694b26a4 100644 --- a/drivers/net/wireless/ath/ath6kl/Makefile +++ b/drivers/net/wireless/ath/ath6kl/Makefile @@ -31,5 +31,6 @@ ath6kl-y += init.o ath6kl-y += main.o ath6kl-y += txrx.o ath6kl-y += wmi.o +ath6kl-y += core.o ath6kl-y += sdio.o ath6kl-$(CONFIG_NL80211_TESTMODE) += testmode.o diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 44fdd39e170..7ff9806de50 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -23,10 +23,6 @@ #include "hif-ops.h" #include "testmode.h" -static unsigned int ath6kl_p2p; - -module_param(ath6kl_p2p, uint, 0644); - #define RATETAB_ENT(_rate, _rateid, _flags) { \ .bitrate = (_rate), \ .flags = (_flags), \ @@ -2693,68 +2689,6 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar) ath6kl_cfg80211_stop(vif); } -struct ath6kl *ath6kl_core_alloc(struct device *dev) -{ - struct ath6kl *ar; - struct wiphy *wiphy; - u8 ctr; - - /* create a new wiphy for use with cfg80211 */ - wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl)); - - if (!wiphy) { - ath6kl_err("couldn't allocate wiphy device\n"); - return NULL; - } - - ar = wiphy_priv(wiphy); - ar->p2p = !!ath6kl_p2p; - ar->wiphy = wiphy; - ar->dev = dev; - - ar->vif_max = 1; - - ar->max_norm_iface = 1; - - spin_lock_init(&ar->lock); - spin_lock_init(&ar->mcastpsq_lock); - spin_lock_init(&ar->list_lock); - - init_waitqueue_head(&ar->event_wq); - sema_init(&ar->sem, 1); - - INIT_LIST_HEAD(&ar->amsdu_rx_buffer_queue); - INIT_LIST_HEAD(&ar->vif_list); - - clear_bit(WMI_ENABLED, &ar->flag); - clear_bit(SKIP_SCAN, &ar->flag); - clear_bit(DESTROY_IN_PROGRESS, &ar->flag); - - ar->listen_intvl_b = A_DEFAULT_LISTEN_INTERVAL; - ar->tx_pwr = 0; - - ar->intra_bss = 1; - ar->lrssi_roam_threshold = DEF_LRSSI_ROAM_THRESHOLD; - - ar->state = ATH6KL_STATE_OFF; - - memset((u8 *)ar->sta_list, 0, - AP_MAX_NUM_STA * sizeof(struct ath6kl_sta)); - - /* Init the PS queues */ - for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) { - spin_lock_init(&ar->sta_list[ctr].psq_lock); - skb_queue_head_init(&ar->sta_list[ctr].psq); - skb_queue_head_init(&ar->sta_list[ctr].apsdq); - } - - skb_queue_head_init(&ar->mcastpsq); - - memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3); - - return ar; -} - static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif) { vif->aggr_cntxt = aggr_init(vif->ndev); @@ -2910,10 +2844,30 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) void ath6kl_cfg80211_cleanup(struct ath6kl *ar) { wiphy_unregister(ar->wiphy); +} - /* - * FIXME: should be removed as we remove wiphy in - * ath6kl_core_free(). Most likely this causes a use after free. - */ +struct ath6kl *ath6kl_cfg80211_create(void) +{ + struct ath6kl *ar; + struct wiphy *wiphy; + + /* create a new wiphy for use with cfg80211 */ + wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl)); + + if (!wiphy) { + ath6kl_err("couldn't allocate wiphy device\n"); + return NULL; + } + + ar = wiphy_priv(wiphy); + ar->wiphy = wiphy; + + return ar; +} + +/* Note: ar variable must not be accessed after calling this! */ +void ath6kl_cfg80211_destroy(struct ath6kl *ar) +{ wiphy_free(ar->wiphy); } + diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h index 08d97691039..3c693b7c0ef 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.h +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h @@ -27,7 +27,6 @@ enum ath6kl_cfg_suspend_mode { struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, enum nl80211_iftype type, u8 fw_vif_idx, u8 nw_type); -struct ath6kl *ath6kl_core_alloc(struct device *dev); void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted); void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, @@ -58,4 +57,7 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar); int ath6kl_cfg80211_init(struct ath6kl *ar); void ath6kl_cfg80211_cleanup(struct ath6kl *ar); +struct ath6kl *ath6kl_cfg80211_create(void); +void ath6kl_cfg80211_destroy(struct ath6kl *ar); + #endif /* ATH6KL_CFG80211_H */ diff --git a/drivers/net/wireless/ath/ath6kl/common.h b/drivers/net/wireless/ath/ath6kl/common.h index bfd6597763d..f89f1e180da 100644 --- a/drivers/net/wireless/ath/ath6kl/common.h +++ b/drivers/net/wireless/ath/ath6kl/common.h @@ -79,8 +79,5 @@ struct ath6kl; enum htc_credit_dist_reason; struct ath6kl_htc_credit_info; -struct ath6kl *ath6kl_core_alloc(struct device *sdev); -int ath6kl_core_init(struct ath6kl *ar); -void ath6kl_core_cleanup(struct ath6kl *ar); struct sk_buff *ath6kl_buf_alloc(int size); #endif /* COMMON_H */ diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c new file mode 100644 index 00000000000..40fad5ec936 --- /dev/null +++ b/drivers/net/wireless/ath/ath6kl/core.c @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2004-2011 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "core.h" + +#include + +#include "debug.h" +#include "hif-ops.h" +#include "cfg80211.h" + +unsigned int debug_mask; +static bool suspend_cutpower; +static unsigned int uart_debug; +static unsigned int ath6kl_p2p; + +module_param(debug_mask, uint, 0644); +module_param(suspend_cutpower, bool, 0444); +module_param(uart_debug, uint, 0644); +module_param(ath6kl_p2p, uint, 0644); + +int ath6kl_core_init(struct ath6kl *ar) +{ + struct ath6kl_bmi_target_info targ_info; + struct net_device *ndev; + int ret = 0, i; + + ar->ath6kl_wq = create_singlethread_workqueue("ath6kl"); + if (!ar->ath6kl_wq) + return -ENOMEM; + + ret = ath6kl_bmi_init(ar); + if (ret) + goto err_wq; + + /* + * Turn on power to get hardware (target) version and leave power + * on delibrately as we will boot the hardware anyway within few + * seconds. + */ + ret = ath6kl_hif_power_on(ar); + if (ret) + goto err_bmi_cleanup; + + ret = ath6kl_bmi_get_target_info(ar, &targ_info); + if (ret) + goto err_power_off; + + ar->version.target_ver = le32_to_cpu(targ_info.version); + ar->target_type = le32_to_cpu(targ_info.type); + ar->wiphy->hw_version = le32_to_cpu(targ_info.version); + + ret = ath6kl_init_hw_params(ar); + if (ret) + goto err_power_off; + + ar->htc_target = ath6kl_htc_create(ar); + + if (!ar->htc_target) { + ret = -ENOMEM; + goto err_power_off; + } + + ret = ath6kl_init_fetch_firmwares(ar); + if (ret) + goto err_htc_cleanup; + + /* FIXME: we should free all firmwares in the error cases below */ + + /* Indicate that WMI is enabled (although not ready yet) */ + set_bit(WMI_ENABLED, &ar->flag); + ar->wmi = ath6kl_wmi_init(ar); + if (!ar->wmi) { + ath6kl_err("failed to initialize wmi\n"); + ret = -EIO; + goto err_htc_cleanup; + } + + ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi); + + ret = ath6kl_cfg80211_init(ar); + if (ret) + goto err_node_cleanup; + + ret = ath6kl_debug_init(ar); + if (ret) { + wiphy_unregister(ar->wiphy); + goto err_node_cleanup; + } + + for (i = 0; i < ar->vif_max; i++) + ar->avail_idx_map |= BIT(i); + + rtnl_lock(); + + /* Add an initial station interface */ + ndev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0, + INFRA_NETWORK); + + rtnl_unlock(); + + if (!ndev) { + ath6kl_err("Failed to instantiate a network device\n"); + ret = -ENOMEM; + wiphy_unregister(ar->wiphy); + goto err_debug_init; + } + + + ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n", + __func__, ndev->name, ndev, ar); + + /* setup access class priority mappings */ + ar->ac_stream_pri_map[WMM_AC_BK] = 0; /* lowest */ + ar->ac_stream_pri_map[WMM_AC_BE] = 1; + ar->ac_stream_pri_map[WMM_AC_VI] = 2; + ar->ac_stream_pri_map[WMM_AC_VO] = 3; /* highest */ + + /* give our connected endpoints some buffers */ + ath6kl_rx_refill(ar->htc_target, ar->ctrl_ep); + ath6kl_rx_refill(ar->htc_target, ar->ac2ep_map[WMM_AC_BE]); + + /* allocate some buffers that handle larger AMSDU frames */ + ath6kl_refill_amsdu_rxbufs(ar, ATH6KL_MAX_AMSDU_RX_BUFFERS); + + ath6kl_cookie_init(ar); + + ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER | + ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST; + + if (suspend_cutpower) + ar->conf_flags |= ATH6KL_CONF_SUSPEND_CUTPOWER; + + if (uart_debug) + ar->conf_flags |= ATH6KL_CONF_UART_DEBUG; + + ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM | + WIPHY_FLAG_HAVE_AP_SME | + WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | + WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; + + if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities)) + ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; + + ar->wiphy->probe_resp_offload = + NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | + NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | + NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P | + NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U; + + set_bit(FIRST_BOOT, &ar->flag); + + ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM; + + ret = ath6kl_init_hw_start(ar); + if (ret) { + ath6kl_err("Failed to start hardware: %d\n", ret); + goto err_rxbuf_cleanup; + } + + /* + * Set mac address which is received in ready event + * FIXME: Move to ath6kl_interface_add() + */ + memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN); + + return ret; + +err_rxbuf_cleanup: + ath6kl_htc_flush_rx_buf(ar->htc_target); + ath6kl_cleanup_amsdu_rxbufs(ar); + rtnl_lock(); + ath6kl_cfg80211_vif_cleanup(netdev_priv(ndev)); + rtnl_unlock(); + wiphy_unregister(ar->wiphy); +err_debug_init: + ath6kl_debug_cleanup(ar); +err_node_cleanup: + ath6kl_wmi_shutdown(ar->wmi); + clear_bit(WMI_ENABLED, &ar->flag); + ar->wmi = NULL; +err_htc_cleanup: + ath6kl_htc_cleanup(ar->htc_target); +err_power_off: + ath6kl_hif_power_off(ar); +err_bmi_cleanup: + ath6kl_bmi_cleanup(ar); +err_wq: + destroy_workqueue(ar->ath6kl_wq); + + return ret; +} + +struct ath6kl *ath6kl_core_create(struct device *dev) +{ + struct ath6kl *ar; + u8 ctr; + + ar = ath6kl_cfg80211_create(); + if (!ar) + return NULL; + + ar->p2p = !!ath6kl_p2p; + ar->dev = dev; + + ar->vif_max = 1; + + ar->max_norm_iface = 1; + + spin_lock_init(&ar->lock); + spin_lock_init(&ar->mcastpsq_lock); + spin_lock_init(&ar->list_lock); + + init_waitqueue_head(&ar->event_wq); + sema_init(&ar->sem, 1); + + INIT_LIST_HEAD(&ar->amsdu_rx_buffer_queue); + INIT_LIST_HEAD(&ar->vif_list); + + clear_bit(WMI_ENABLED, &ar->flag); + clear_bit(SKIP_SCAN, &ar->flag); + clear_bit(DESTROY_IN_PROGRESS, &ar->flag); + + ar->listen_intvl_b = A_DEFAULT_LISTEN_INTERVAL; + ar->tx_pwr = 0; + + ar->intra_bss = 1; + ar->lrssi_roam_threshold = DEF_LRSSI_ROAM_THRESHOLD; + + ar->state = ATH6KL_STATE_OFF; + + memset((u8 *)ar->sta_list, 0, + AP_MAX_NUM_STA * sizeof(struct ath6kl_sta)); + + /* Init the PS queues */ + for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) { + spin_lock_init(&ar->sta_list[ctr].psq_lock); + skb_queue_head_init(&ar->sta_list[ctr].psq); + skb_queue_head_init(&ar->sta_list[ctr].apsdq); + } + + skb_queue_head_init(&ar->mcastpsq); + + memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3); + + return ar; +} + +void ath6kl_core_cleanup(struct ath6kl *ar) +{ + ath6kl_hif_power_off(ar); + + destroy_workqueue(ar->ath6kl_wq); + + if (ar->htc_target) + ath6kl_htc_cleanup(ar->htc_target); + + ath6kl_cookie_cleanup(ar); + + ath6kl_cleanup_amsdu_rxbufs(ar); + + ath6kl_bmi_cleanup(ar); + + ath6kl_debug_cleanup(ar); + + kfree(ar->fw_board); + kfree(ar->fw_otp); + kfree(ar->fw); + kfree(ar->fw_patch); + kfree(ar->fw_testscript); + + ath6kl_cfg80211_cleanup(ar); +} + +void ath6kl_core_destroy(struct ath6kl *ar) +{ + ath6kl_cfg80211_destroy(ar); +} + diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 78c0402e2d3..67b22e4bbcc 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -754,11 +754,18 @@ void ath6kl_wakeup_event(void *dev); void ath6kl_reset_device(struct ath6kl *ar, u32 target_type, bool wait_fot_compltn, bool cold_reset); void ath6kl_init_control_info(struct ath6kl_vif *vif); -void ath6kl_core_free(struct ath6kl *ar); struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar); void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready); int ath6kl_init_hw_start(struct ath6kl *ar); int ath6kl_init_hw_stop(struct ath6kl *ar); +int ath6kl_init_fetch_firmwares(struct ath6kl *ar); +int ath6kl_init_hw_params(struct ath6kl *ar); + void ath6kl_check_wow_status(struct ath6kl *ar); +struct ath6kl *ath6kl_core_create(struct device *dev); +int ath6kl_core_init(struct ath6kl *ar); +void ath6kl_core_cleanup(struct ath6kl *ar); +void ath6kl_core_destroy(struct ath6kl *ar); + #endif /* CORE_H */ diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 2804921d5d8..b8252ced096 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -25,15 +25,9 @@ #include "debug.h" #include "hif-ops.h" -unsigned int debug_mask; static unsigned int testmode; -static bool suspend_cutpower; -static unsigned int uart_debug; -module_param(debug_mask, uint, 0644); module_param(testmode, uint, 0644); -module_param(suspend_cutpower, bool, 0444); -module_param(uart_debug, uint, 0644); static const struct ath6kl_hw hw_list[] = { { @@ -597,37 +591,6 @@ int ath6kl_configure_target(struct ath6kl *ar) return 0; } -void ath6kl_core_free(struct ath6kl *ar) -{ - wiphy_free(ar->wiphy); -} - -void ath6kl_core_cleanup(struct ath6kl *ar) -{ - ath6kl_hif_power_off(ar); - - destroy_workqueue(ar->ath6kl_wq); - - if (ar->htc_target) - ath6kl_htc_cleanup(ar->htc_target); - - ath6kl_cookie_cleanup(ar); - - ath6kl_cleanup_amsdu_rxbufs(ar); - - ath6kl_bmi_cleanup(ar); - - ath6kl_debug_cleanup(ar); - - kfree(ar->fw_board); - kfree(ar->fw_otp); - kfree(ar->fw); - kfree(ar->fw_patch); - kfree(ar->fw_testscript); - - ath6kl_cfg80211_cleanup(ar); -} - /* firmware upload */ static int ath6kl_get_fw(struct ath6kl *ar, const char *filename, u8 **fw, size_t *fw_len) @@ -1065,7 +1028,7 @@ out: return ret; } -static int ath6kl_fetch_firmwares(struct ath6kl *ar) +int ath6kl_init_fetch_firmwares(struct ath6kl *ar) { int ret; @@ -1485,7 +1448,7 @@ static int ath6kl_init_upload(struct ath6kl *ar) return status; } -static int ath6kl_init_hw_params(struct ath6kl *ar) +int ath6kl_init_hw_params(struct ath6kl *ar) { const struct ath6kl_hw *hw; int i; @@ -1663,178 +1626,6 @@ int ath6kl_init_hw_stop(struct ath6kl *ar) return 0; } -int ath6kl_core_init(struct ath6kl *ar) -{ - struct ath6kl_bmi_target_info targ_info; - struct net_device *ndev; - int ret = 0, i; - - ar->ath6kl_wq = create_singlethread_workqueue("ath6kl"); - if (!ar->ath6kl_wq) - return -ENOMEM; - - ret = ath6kl_bmi_init(ar); - if (ret) - goto err_wq; - - /* - * Turn on power to get hardware (target) version and leave power - * on delibrately as we will boot the hardware anyway within few - * seconds. - */ - ret = ath6kl_hif_power_on(ar); - if (ret) - goto err_bmi_cleanup; - - ret = ath6kl_bmi_get_target_info(ar, &targ_info); - if (ret) - goto err_power_off; - - ar->version.target_ver = le32_to_cpu(targ_info.version); - ar->target_type = le32_to_cpu(targ_info.type); - ar->wiphy->hw_version = le32_to_cpu(targ_info.version); - - ret = ath6kl_init_hw_params(ar); - if (ret) - goto err_power_off; - - ar->htc_target = ath6kl_htc_create(ar); - - if (!ar->htc_target) { - ret = -ENOMEM; - goto err_power_off; - } - - ret = ath6kl_fetch_firmwares(ar); - if (ret) - goto err_htc_cleanup; - - /* FIXME: we should free all firmwares in the error cases below */ - - /* Indicate that WMI is enabled (although not ready yet) */ - set_bit(WMI_ENABLED, &ar->flag); - ar->wmi = ath6kl_wmi_init(ar); - if (!ar->wmi) { - ath6kl_err("failed to initialize wmi\n"); - ret = -EIO; - goto err_htc_cleanup; - } - - ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi); - - ret = ath6kl_cfg80211_init(ar); - if (ret) - goto err_node_cleanup; - - ret = ath6kl_debug_init(ar); - if (ret) { - wiphy_unregister(ar->wiphy); - goto err_node_cleanup; - } - - for (i = 0; i < ar->vif_max; i++) - ar->avail_idx_map |= BIT(i); - - rtnl_lock(); - - /* Add an initial station interface */ - ndev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0, - INFRA_NETWORK); - - rtnl_unlock(); - - if (!ndev) { - ath6kl_err("Failed to instantiate a network device\n"); - ret = -ENOMEM; - wiphy_unregister(ar->wiphy); - goto err_debug_init; - } - - - ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n", - __func__, ndev->name, ndev, ar); - - /* setup access class priority mappings */ - ar->ac_stream_pri_map[WMM_AC_BK] = 0; /* lowest */ - ar->ac_stream_pri_map[WMM_AC_BE] = 1; - ar->ac_stream_pri_map[WMM_AC_VI] = 2; - ar->ac_stream_pri_map[WMM_AC_VO] = 3; /* highest */ - - /* give our connected endpoints some buffers */ - ath6kl_rx_refill(ar->htc_target, ar->ctrl_ep); - ath6kl_rx_refill(ar->htc_target, ar->ac2ep_map[WMM_AC_BE]); - - /* allocate some buffers that handle larger AMSDU frames */ - ath6kl_refill_amsdu_rxbufs(ar, ATH6KL_MAX_AMSDU_RX_BUFFERS); - - ath6kl_cookie_init(ar); - - ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER | - ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST; - - if (suspend_cutpower) - ar->conf_flags |= ATH6KL_CONF_SUSPEND_CUTPOWER; - - if (uart_debug) - ar->conf_flags |= ATH6KL_CONF_UART_DEBUG; - - ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM | - WIPHY_FLAG_HAVE_AP_SME | - WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | - WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; - - if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities)) - ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; - - ar->wiphy->probe_resp_offload = - NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | - NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | - NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P | - NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U; - - set_bit(FIRST_BOOT, &ar->flag); - - ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM; - - ret = ath6kl_init_hw_start(ar); - if (ret) { - ath6kl_err("Failed to start hardware: %d\n", ret); - goto err_rxbuf_cleanup; - } - - /* - * Set mac address which is received in ready event - * FIXME: Move to ath6kl_interface_add() - */ - memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN); - - return ret; - -err_rxbuf_cleanup: - ath6kl_htc_flush_rx_buf(ar->htc_target); - ath6kl_cleanup_amsdu_rxbufs(ar); - rtnl_lock(); - ath6kl_cfg80211_vif_cleanup(netdev_priv(ndev)); - rtnl_unlock(); - wiphy_unregister(ar->wiphy); -err_debug_init: - ath6kl_debug_cleanup(ar); -err_node_cleanup: - ath6kl_wmi_shutdown(ar->wmi); - clear_bit(WMI_ENABLED, &ar->flag); - ar->wmi = NULL; -err_htc_cleanup: - ath6kl_htc_cleanup(ar->htc_target); -err_power_off: - ath6kl_hif_power_off(ar); -err_bmi_cleanup: - ath6kl_bmi_cleanup(ar); -err_wq: - destroy_workqueue(ar->ath6kl_wq); - - return ret; -} - /* FIXME: move this to cfg80211.c and rename to ath6kl_cfg80211_vif_stop() */ void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready) { diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index 662b47dc71e..bef32ecea79 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -1261,7 +1261,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func, for (count = 0; count < BUS_REQUEST_MAX_NUM; count++) ath6kl_sdio_free_bus_req(ar_sdio, &ar_sdio->bus_req[count]); - ar = ath6kl_core_alloc(&ar_sdio->func->dev); + ar = ath6kl_core_create(&ar_sdio->func->dev); if (!ar) { ath6kl_err("Failed to alloc ath6kl core\n"); ret = -ENOMEM; @@ -1291,7 +1291,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func, return ret; err_core_alloc: - ath6kl_core_free(ar_sdio->ar); + ath6kl_core_destroy(ar_sdio->ar); err_dma: kfree(ar_sdio->dma_buffer); err_hif: -- cgit v1.2.3-70-g09d2 From 5afa5aa79680ee107fef1195c80f5f67c54b6691 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 17 Jan 2012 20:09:19 +0200 Subject: ath6kl: get rid of AR_DBG_LVL_CHECK() We don't need it as debug calls already have a log level and compiler should be smart enough to optimise away the code when ath6kl debug code is not enabled. Also it makes it easier to abstract core code to ath6kl_core.ko. In ath6kl_dump_registers() I had to change the debug level from ANY to IRQ as I removed the AR_DBG_LVL_CHECK() check before calling the function. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/debug.c | 35 +++++++++++++++------------------ drivers/net/wireless/ath/ath6kl/debug.h | 2 -- drivers/net/wireless/ath/ath6kl/hif.c | 5 ++--- drivers/net/wireless/ath/ath6kl/wmi.c | 3 --- 4 files changed, 18 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c index fa7243b4144..bd2f1fae72a 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.c +++ b/drivers/net/wireless/ath/ath6kl/debug.c @@ -82,31 +82,31 @@ void ath6kl_dump_registers(struct ath6kl_device *dev, struct ath6kl_irq_enable_reg *irq_enable_reg) { - ath6kl_dbg(ATH6KL_DBG_ANY, ("<------- Register Table -------->\n")); + ath6kl_dbg(ATH6KL_DBG_IRQ, ("<------- Register Table -------->\n")); if (irq_proc_reg != NULL) { - ath6kl_dbg(ATH6KL_DBG_ANY, + ath6kl_dbg(ATH6KL_DBG_IRQ, "Host Int status: 0x%x\n", irq_proc_reg->host_int_status); - ath6kl_dbg(ATH6KL_DBG_ANY, + ath6kl_dbg(ATH6KL_DBG_IRQ, "CPU Int status: 0x%x\n", irq_proc_reg->cpu_int_status); - ath6kl_dbg(ATH6KL_DBG_ANY, + ath6kl_dbg(ATH6KL_DBG_IRQ, "Error Int status: 0x%x\n", irq_proc_reg->error_int_status); - ath6kl_dbg(ATH6KL_DBG_ANY, + ath6kl_dbg(ATH6KL_DBG_IRQ, "Counter Int status: 0x%x\n", irq_proc_reg->counter_int_status); - ath6kl_dbg(ATH6KL_DBG_ANY, + ath6kl_dbg(ATH6KL_DBG_IRQ, "Mbox Frame: 0x%x\n", irq_proc_reg->mbox_frame); - ath6kl_dbg(ATH6KL_DBG_ANY, + ath6kl_dbg(ATH6KL_DBG_IRQ, "Rx Lookahead Valid: 0x%x\n", irq_proc_reg->rx_lkahd_valid); - ath6kl_dbg(ATH6KL_DBG_ANY, + ath6kl_dbg(ATH6KL_DBG_IRQ, "Rx Lookahead 0: 0x%x\n", irq_proc_reg->rx_lkahd[0]); - ath6kl_dbg(ATH6KL_DBG_ANY, + ath6kl_dbg(ATH6KL_DBG_IRQ, "Rx Lookahead 1: 0x%x\n", irq_proc_reg->rx_lkahd[1]); @@ -115,16 +115,16 @@ void ath6kl_dump_registers(struct ath6kl_device *dev, * If the target supports GMBOX hardware, dump some * additional state. */ - ath6kl_dbg(ATH6KL_DBG_ANY, + ath6kl_dbg(ATH6KL_DBG_IRQ, "GMBOX Host Int status 2: 0x%x\n", irq_proc_reg->host_int_status2); - ath6kl_dbg(ATH6KL_DBG_ANY, + ath6kl_dbg(ATH6KL_DBG_IRQ, "GMBOX RX Avail: 0x%x\n", irq_proc_reg->gmbox_rx_avail); - ath6kl_dbg(ATH6KL_DBG_ANY, + ath6kl_dbg(ATH6KL_DBG_IRQ, "GMBOX lookahead alias 0: 0x%x\n", irq_proc_reg->rx_gmbox_lkahd_alias[0]); - ath6kl_dbg(ATH6KL_DBG_ANY, + ath6kl_dbg(ATH6KL_DBG_IRQ, "GMBOX lookahead alias 1: 0x%x\n", irq_proc_reg->rx_gmbox_lkahd_alias[1]); } @@ -132,13 +132,13 @@ void ath6kl_dump_registers(struct ath6kl_device *dev, } if (irq_enable_reg != NULL) { - ath6kl_dbg(ATH6KL_DBG_ANY, + ath6kl_dbg(ATH6KL_DBG_IRQ, "Int status Enable: 0x%x\n", irq_enable_reg->int_status_en); - ath6kl_dbg(ATH6KL_DBG_ANY, "Counter Int status Enable: 0x%x\n", + ath6kl_dbg(ATH6KL_DBG_IRQ, "Counter Int status Enable: 0x%x\n", irq_enable_reg->cntr_int_status_en); } - ath6kl_dbg(ATH6KL_DBG_ANY, "<------------------------------->\n"); + ath6kl_dbg(ATH6KL_DBG_IRQ, "<------------------------------->\n"); } static void dump_cred_dist(struct htc_endpoint_credit_dist *ep_dist) @@ -175,9 +175,6 @@ void dump_cred_dist_stats(struct htc_target *target) { struct htc_endpoint_credit_dist *ep_list; - if (!AR_DBG_LVL_CHECK(ATH6KL_DBG_CREDIT)) - return; - list_for_each_entry(ep_list, &target->cred_dist_list, list) dump_cred_dist(ep_list); diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h index 9853c9c125c..9dc39754a35 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.h +++ b/drivers/net/wireless/ath/ath6kl/debug.h @@ -55,8 +55,6 @@ int ath6kl_printk(const char *level, const char *fmt, ...); #define ath6kl_warn(fmt, ...) \ ath6kl_printk(KERN_WARNING, fmt, ##__VA_ARGS__) -#define AR_DBG_LVL_CHECK(mask) (debug_mask & mask) - enum ath6kl_war { ATH6KL_WAR_INVALID_RATE, }; diff --git a/drivers/net/wireless/ath/ath6kl/hif.c b/drivers/net/wireless/ath/ath6kl/hif.c index e57da35e59f..711886860b5 100644 --- a/drivers/net/wireless/ath/ath6kl/hif.c +++ b/drivers/net/wireless/ath/ath6kl/hif.c @@ -429,9 +429,8 @@ static int proc_pending_irqs(struct ath6kl_device *dev, bool *done) if (status) goto out; - if (AR_DBG_LVL_CHECK(ATH6KL_DBG_IRQ)) - ath6kl_dump_registers(dev, &dev->irq_proc_reg, - &dev->irq_en_reg); + ath6kl_dump_registers(dev, &dev->irq_proc_reg, + &dev->irq_en_reg); /* Update only those registers that are enabled */ host_int_status = dev->irq_proc_reg.host_int_status & diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index c2420f886ed..5d678bf372d 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -426,9 +426,6 @@ static int ath6kl_wmi_tx_complete_event_rx(u8 *datap, int len) ath6kl_dbg(ATH6KL_DBG_WMI, "comp: %d %d %d\n", evt->num_msg, evt->msg_len, evt->msg_type); - if (!AR_DBG_LVL_CHECK(ATH6KL_DBG_WMI)) - return 0; - for (index = 0; index < evt->num_msg; index++) { size = sizeof(struct wmi_tx_complete_event) + (index * sizeof(struct tx_complete_msg_v1)); -- cgit v1.2.3-70-g09d2 From 3b1b7d0985fdb26403678e49938a668ef7f772ea Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 17 Jan 2012 20:09:27 +0200 Subject: ath6kl: convert ath6kl_dbg() and ath6kl_dbg_dump() into functions That way it's possible to not export debug_mask outside the upcoming ath6kl_core.ko and that makes it easier to ath6kl_core.ko in the following patch. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/debug.c | 30 ++++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath6kl/debug.h | 25 ++++--------------------- 2 files changed, 34 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c index bd2f1fae72a..4ba6560f0bf 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.c +++ b/drivers/net/wireless/ath/ath6kl/debug.c @@ -57,6 +57,36 @@ int ath6kl_printk(const char *level, const char *fmt, ...) #ifdef CONFIG_ATH6KL_DEBUG +void ath6kl_dbg(enum ATH6K_DEBUG_MASK mask, const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + + if (!(debug_mask & mask)) + return; + + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + ath6kl_printk(KERN_DEBUG, "%pV", &vaf); + + va_end(args); +} + +void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask, + const char *msg, const char *prefix, + const void *buf, size_t len) +{ + if (debug_mask & mask) { + if (msg) + ath6kl_dbg(mask, "%s\n", msg); + + print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len); + } +} + #define REG_OUTPUT_LEN_PER_LINE 25 #define REGTYPE_STR_LEN 100 diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h index 9dc39754a35..872a8ce5d8f 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.h +++ b/drivers/net/wireless/ath/ath6kl/debug.h @@ -60,28 +60,11 @@ enum ath6kl_war { }; #ifdef CONFIG_ATH6KL_DEBUG -#define ath6kl_dbg(mask, fmt, ...) \ - ({ \ - int rtn; \ - if (debug_mask & mask) \ - rtn = ath6kl_printk(KERN_DEBUG, fmt, ##__VA_ARGS__); \ - else \ - rtn = 0; \ - \ - rtn; \ - }) -static inline void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask, - const char *msg, const char *prefix, - const void *buf, size_t len) -{ - if (debug_mask & mask) { - if (msg) - ath6kl_dbg(mask, "%s\n", msg); - - print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len); - } -} +void ath6kl_dbg(enum ATH6K_DEBUG_MASK mask, const char *fmt, ...); +void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask, + const char *msg, const char *prefix, + const void *buf, size_t len); void ath6kl_dump_registers(struct ath6kl_device *dev, struct ath6kl_irq_proc_registers *irq_proc_reg, -- cgit v1.2.3-70-g09d2 From d6a434d60e064a5f2bef1c13ca5ed84bfa6b8b4f Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 17 Jan 2012 20:09:36 +0200 Subject: ath6kl: create ath6kl_core.ko Now ath6kl is ready for splitting core code to ath6kl_core.ko module. This also makes it possible to link both sdio and usb code to kernel at the same time, which earlier failed miserably. Reported-by: Stephen Rothwell Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/Makefile | 28 +++++++++++++++------------- drivers/net/wireless/ath/ath6kl/cfg80211.c | 3 +++ drivers/net/wireless/ath/ath6kl/core.c | 9 +++++++++ drivers/net/wireless/ath/ath6kl/debug.c | 3 +++ drivers/net/wireless/ath/ath6kl/hif.c | 5 +++++ drivers/net/wireless/ath/ath6kl/init.c | 3 +++ 6 files changed, 38 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile index 854694b26a4..cbdc31c603f 100644 --- a/drivers/net/wireless/ath/ath6kl/Makefile +++ b/drivers/net/wireless/ath/ath6kl/Makefile @@ -21,16 +21,18 @@ # Author(s): ="Atheros" #------------------------------------------------------------------------------ -obj-$(CONFIG_ATH6KL) := ath6kl.o -ath6kl-y += debug.o -ath6kl-y += hif.o -ath6kl-y += htc.o -ath6kl-y += bmi.o -ath6kl-y += cfg80211.o -ath6kl-y += init.o -ath6kl-y += main.o -ath6kl-y += txrx.o -ath6kl-y += wmi.o -ath6kl-y += core.o -ath6kl-y += sdio.o -ath6kl-$(CONFIG_NL80211_TESTMODE) += testmode.o +obj-$(CONFIG_ATH6KL) += ath6kl_core.o +ath6kl_core-y += debug.o +ath6kl_core-y += hif.o +ath6kl_core-y += htc.o +ath6kl_core-y += bmi.o +ath6kl_core-y += cfg80211.o +ath6kl_core-y += init.o +ath6kl_core-y += main.o +ath6kl_core-y += txrx.o +ath6kl_core-y += wmi.o +ath6kl_core-y += core.o +ath6kl_core-$(CONFIG_NL80211_TESTMODE) += testmode.o + +obj-$(CONFIG_ATH6KL_SDIO) += ath6kl_sdio.o +ath6kl_sdio-y += sdio.o diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 7ff9806de50..594d246da8e 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -16,6 +16,7 @@ #include #include +#include #include "core.h" #include "cfg80211.h" @@ -1935,6 +1936,7 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar, return 0; } +EXPORT_SYMBOL(ath6kl_cfg80211_suspend); int ath6kl_cfg80211_resume(struct ath6kl *ar) { @@ -1986,6 +1988,7 @@ int ath6kl_cfg80211_resume(struct ath6kl *ar) return 0; } +EXPORT_SYMBOL(ath6kl_cfg80211_resume); #ifdef CONFIG_PM diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c index 40fad5ec936..d764afec395 100644 --- a/drivers/net/wireless/ath/ath6kl/core.c +++ b/drivers/net/wireless/ath/ath6kl/core.c @@ -16,7 +16,9 @@ #include "core.h" +#include #include +#include #include "debug.h" #include "hif-ops.h" @@ -203,6 +205,7 @@ err_wq: return ret; } +EXPORT_SYMBOL(ath6kl_core_init); struct ath6kl *ath6kl_core_create(struct device *dev) { @@ -258,6 +261,7 @@ struct ath6kl *ath6kl_core_create(struct device *dev) return ar; } +EXPORT_SYMBOL(ath6kl_core_create); void ath6kl_core_cleanup(struct ath6kl *ar) { @@ -284,9 +288,14 @@ void ath6kl_core_cleanup(struct ath6kl *ar) ath6kl_cfg80211_cleanup(ar); } +EXPORT_SYMBOL(ath6kl_core_cleanup); void ath6kl_core_destroy(struct ath6kl *ar) { ath6kl_cfg80211_destroy(ar); } +EXPORT_SYMBOL(ath6kl_core_destroy); +MODULE_AUTHOR("Qualcomm Atheros"); +MODULE_DESCRIPTION("Core module for AR600x SDIO and USB devices."); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c index 4ba6560f0bf..6b546dc6672 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.c +++ b/drivers/net/wireless/ath/ath6kl/debug.c @@ -54,6 +54,7 @@ int ath6kl_printk(const char *level, const char *fmt, ...) return rtn; } +EXPORT_SYMBOL(ath6kl_printk); #ifdef CONFIG_ATH6KL_DEBUG @@ -74,6 +75,7 @@ void ath6kl_dbg(enum ATH6K_DEBUG_MASK mask, const char *fmt, ...) va_end(args); } +EXPORT_SYMBOL(ath6kl_dbg); void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask, const char *msg, const char *prefix, @@ -86,6 +88,7 @@ void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask, print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len); } } +EXPORT_SYMBOL(ath6kl_dbg_dump); #define REG_OUTPUT_LEN_PER_LINE 25 #define REGTYPE_STR_LEN 100 diff --git a/drivers/net/wireless/ath/ath6kl/hif.c b/drivers/net/wireless/ath/ath6kl/hif.c index 711886860b5..d912da6ab0d 100644 --- a/drivers/net/wireless/ath/ath6kl/hif.c +++ b/drivers/net/wireless/ath/ath6kl/hif.c @@ -15,6 +15,8 @@ */ #include "hif.h" +#include + #include "core.h" #include "target.h" #include "hif-ops.h" @@ -59,6 +61,8 @@ int ath6kl_hif_rw_comp_handler(void *context, int status) return 0; } +EXPORT_SYMBOL(ath6kl_hif_rw_comp_handler); + #define REG_DUMP_COUNT_AR6003 60 #define REGISTER_DUMP_LEN_MAX 60 @@ -560,6 +564,7 @@ int ath6kl_hif_intr_bh_handler(struct ath6kl *ar) return status; } +EXPORT_SYMBOL(ath6kl_hif_intr_bh_handler); static int ath6kl_hif_enable_intrs(struct ath6kl_device *dev) { diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index b8252ced096..167dc41af2d 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -17,8 +17,10 @@ #include #include +#include #include #include + #include "core.h" #include "cfg80211.h" #include "target.h" @@ -1707,3 +1709,4 @@ void ath6kl_stop_txrx(struct ath6kl *ar) clear_bit(WLAN_ENABLED, &ar->flag); } +EXPORT_SYMBOL(ath6kl_stop_txrx); -- cgit v1.2.3-70-g09d2 From 241b128b6b69ad41fc6f12cba45a3c3e64bce673 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 17 Jan 2012 20:09:45 +0200 Subject: ath6kl: add back beginnings of USB support John Linville had to revert the part of USB support which was already in ath6kl due to build problems in commit cb00ec382b ("ath6kl: revert USB support"). Now that I fixed the build problems properly by adding ath6kl_core.ko kernel module it's possible to add back the (incomplete) USB support. This patch is a revert of John's patch and adds back the USB code which as already in ath6kl, only difference being minor changes in Makefile and adapting usb.c to new core function names. Note that USB support in ath6kl is not complete yet. This code only makes it possible to boot firmware but as HTC layer does not yet support USB it's not possible to send any WMI commands nor data packets to the firmware. That will be added soon. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/Kconfig | 25 +- drivers/net/wireless/ath/ath6kl/Makefile | 3 + drivers/net/wireless/ath/ath6kl/bmi.c | 10 +- drivers/net/wireless/ath/ath6kl/debug.h | 1 + drivers/net/wireless/ath/ath6kl/hif.c | 5 + drivers/net/wireless/ath/ath6kl/htc.c | 10 +- drivers/net/wireless/ath/ath6kl/sdio.c | 2 +- drivers/net/wireless/ath/ath6kl/usb.c | 431 +++++++++++++++++++++++++++++++ 8 files changed, 479 insertions(+), 8 deletions(-) create mode 100644 drivers/net/wireless/ath/ath6kl/usb.c (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/Kconfig b/drivers/net/wireless/ath/ath6kl/Kconfig index 3d5f8be20ea..d755a5e7ed2 100644 --- a/drivers/net/wireless/ath/ath6kl/Kconfig +++ b/drivers/net/wireless/ath/ath6kl/Kconfig @@ -1,12 +1,29 @@ config ATH6KL - tristate "Atheros ath6kl support" + tristate "Atheros mobile chipsets support" + +config ATH6KL_SDIO + tristate "Atheros ath6kl SDIO support" + depends on ATH6KL depends on MMC depends on CFG80211 ---help--- This module adds support for wireless adapters based on - Atheros AR6003 chipset running over SDIO. If you choose to - build it as a module, it will be called ath6kl. Pls note - that AR6002 and AR6001 are not supported by this driver. + Atheros AR6003 and AR6004 chipsets running over SDIO. If you + choose to build it as a module, it will be called ath6kl_sdio. + Please note that AR6002 and AR6001 are not supported by this + driver. + +config ATH6KL_USB + tristate "Atheros ath6kl USB support" + depends on ATH6KL + depends on USB + depends on CFG80211 + depends on EXPERIMENTAL + ---help--- + This module adds support for wireless adapters based on + Atheros AR6004 chipset running over USB. This is still under + implementation and it isn't functional. If you choose to + build it as a module, it will be called ath6kl_usb. config ATH6KL_DEBUG bool "Atheros ath6kl debugging" diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile index cbdc31c603f..9ba42fa0496 100644 --- a/drivers/net/wireless/ath/ath6kl/Makefile +++ b/drivers/net/wireless/ath/ath6kl/Makefile @@ -36,3 +36,6 @@ ath6kl_core-$(CONFIG_NL80211_TESTMODE) += testmode.o obj-$(CONFIG_ATH6KL_SDIO) += ath6kl_sdio.o ath6kl_sdio-y += sdio.o + +obj-$(CONFIG_ATH6KL_USB) += ath6kl_usb.o +ath6kl_usb-y += usb.o diff --git a/drivers/net/wireless/ath/ath6kl/bmi.c b/drivers/net/wireless/ath/ath6kl/bmi.c index bce3575c310..aef00d5a143 100644 --- a/drivers/net/wireless/ath/ath6kl/bmi.c +++ b/drivers/net/wireless/ath/ath6kl/bmi.c @@ -57,8 +57,14 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar, return ret; } - ret = ath6kl_hif_bmi_read(ar, (u8 *)&targ_info->version, - sizeof(targ_info->version)); + if (ar->hif_type == ATH6KL_HIF_TYPE_USB) { + ret = ath6kl_hif_bmi_read(ar, (u8 *)targ_info, + sizeof(*targ_info)); + } else { + ret = ath6kl_hif_bmi_read(ar, (u8 *)&targ_info->version, + sizeof(targ_info->version)); + } + if (ret) { ath6kl_err("Unable to recv target info: %d\n", ret); return ret; diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h index 872a8ce5d8f..c4be6e50996 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.h +++ b/drivers/net/wireless/ath/ath6kl/debug.h @@ -41,6 +41,7 @@ enum ATH6K_DEBUG_MASK { ATH6KL_DBG_BOOT = BIT(18), /* driver init and fw boot */ ATH6KL_DBG_WMI_DUMP = BIT(19), ATH6KL_DBG_SUSPEND = BIT(20), + ATH6KL_DBG_USB = BIT(21), ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */ }; diff --git a/drivers/net/wireless/ath/ath6kl/hif.c b/drivers/net/wireless/ath/ath6kl/hif.c index d912da6ab0d..e911737ab34 100644 --- a/drivers/net/wireless/ath/ath6kl/hif.c +++ b/drivers/net/wireless/ath/ath6kl/hif.c @@ -693,6 +693,11 @@ int ath6kl_hif_setup(struct ath6kl_device *dev) ath6kl_dbg(ATH6KL_DBG_HIF, "hif block size %d mbox addr 0x%x\n", dev->htc_cnxt->block_sz, dev->ar->mbox_info.htc_addr); + /* usb doesn't support enabling interrupts */ + /* FIXME: remove check once USB support is implemented */ + if (dev->ar->hif_type == ATH6KL_HIF_TYPE_USB) + return 0; + status = ath6kl_hif_disable_intrs(dev); fail_setup: diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c index 073ddff3134..2d721903640 100644 --- a/drivers/net/wireless/ath/ath6kl/htc.c +++ b/drivers/net/wireless/ath/ath6kl/htc.c @@ -2544,6 +2544,12 @@ int ath6kl_htc_wait_target(struct htc_target *target) struct htc_service_connect_resp resp; int status; + /* FIXME: remove once USB support is implemented */ + if (target->dev->ar->hif_type == ATH6KL_HIF_TYPE_USB) { + ath6kl_err("HTC doesn't support USB yet. Patience!\n"); + return -EOPNOTSUPP; + } + /* we should be getting 1 control message that the target is ready */ packet = htc_wait_for_ctrl_msg(target); @@ -2773,7 +2779,9 @@ void ath6kl_htc_cleanup(struct htc_target *target) { struct htc_packet *packet, *tmp_packet; - ath6kl_hif_cleanup_scatter(target->dev->ar); + /* FIXME: remove check once USB support is implemented */ + if (target->dev->ar->hif_type != ATH6KL_HIF_TYPE_USB) + ath6kl_hif_cleanup_scatter(target->dev->ar); list_for_each_entry_safe(packet, tmp_packet, &target->free_ctrl_txbuf, list) { diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index bef32ecea79..7bb61077c40 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -1330,7 +1330,7 @@ static const struct sdio_device_id ath6kl_sdio_devices[] = { MODULE_DEVICE_TABLE(sdio, ath6kl_sdio_devices); static struct sdio_driver ath6kl_sdio_driver = { - .name = "ath6kl", + .name = "ath6kl_sdio", .id_table = ath6kl_sdio_devices, .probe = ath6kl_sdio_probe, .remove = ath6kl_sdio_remove, diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c new file mode 100644 index 00000000000..c72567c6d33 --- /dev/null +++ b/drivers/net/wireless/ath/ath6kl/usb.c @@ -0,0 +1,431 @@ +/* + * Copyright (c) 2007-2011 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include "debug.h" +#include "core.h" + +/* usb device object */ +struct ath6kl_usb { + struct usb_device *udev; + struct usb_interface *interface; + u8 *diag_cmd_buffer; + u8 *diag_resp_buffer; + struct ath6kl *ar; +}; + +/* diagnostic command defnitions */ +#define ATH6KL_USB_CONTROL_REQ_SEND_BMI_CMD 1 +#define ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP 2 +#define ATH6KL_USB_CONTROL_REQ_DIAG_CMD 3 +#define ATH6KL_USB_CONTROL_REQ_DIAG_RESP 4 + +#define ATH6KL_USB_CTRL_DIAG_CC_READ 0 +#define ATH6KL_USB_CTRL_DIAG_CC_WRITE 1 + +struct ath6kl_usb_ctrl_diag_cmd_write { + __le32 cmd; + __le32 address; + __le32 value; + __le32 _pad[1]; +} __packed; + +struct ath6kl_usb_ctrl_diag_cmd_read { + __le32 cmd; + __le32 address; +} __packed; + +struct ath6kl_usb_ctrl_diag_resp_read { + __le32 value; +} __packed; + +#define ATH6KL_USB_MAX_DIAG_CMD (sizeof(struct ath6kl_usb_ctrl_diag_cmd_write)) +#define ATH6KL_USB_MAX_DIAG_RESP (sizeof(struct ath6kl_usb_ctrl_diag_resp_read)) + +static void ath6kl_usb_destroy(struct ath6kl_usb *ar_usb) +{ + usb_set_intfdata(ar_usb->interface, NULL); + + kfree(ar_usb->diag_cmd_buffer); + kfree(ar_usb->diag_resp_buffer); + + kfree(ar_usb); +} + +static struct ath6kl_usb *ath6kl_usb_create(struct usb_interface *interface) +{ + struct ath6kl_usb *ar_usb = NULL; + struct usb_device *dev = interface_to_usbdev(interface); + int status = 0; + + ar_usb = kzalloc(sizeof(struct ath6kl_usb), GFP_KERNEL); + if (ar_usb == NULL) + goto fail_ath6kl_usb_create; + + memset(ar_usb, 0, sizeof(struct ath6kl_usb)); + usb_set_intfdata(interface, ar_usb); + ar_usb->udev = dev; + ar_usb->interface = interface; + + ar_usb->diag_cmd_buffer = kzalloc(ATH6KL_USB_MAX_DIAG_CMD, GFP_KERNEL); + if (ar_usb->diag_cmd_buffer == NULL) { + status = -ENOMEM; + goto fail_ath6kl_usb_create; + } + + ar_usb->diag_resp_buffer = kzalloc(ATH6KL_USB_MAX_DIAG_RESP, + GFP_KERNEL); + if (ar_usb->diag_resp_buffer == NULL) { + status = -ENOMEM; + goto fail_ath6kl_usb_create; + } + +fail_ath6kl_usb_create: + if (status != 0) { + ath6kl_usb_destroy(ar_usb); + ar_usb = NULL; + } + return ar_usb; +} + +static void ath6kl_usb_device_detached(struct usb_interface *interface) +{ + struct ath6kl_usb *ar_usb; + + ar_usb = usb_get_intfdata(interface); + if (ar_usb == NULL) + return; + + ath6kl_stop_txrx(ar_usb->ar); + + ath6kl_core_cleanup(ar_usb->ar); + + ath6kl_usb_destroy(ar_usb); +} + +static int ath6kl_usb_submit_ctrl_out(struct ath6kl_usb *ar_usb, + u8 req, u16 value, u16 index, void *data, + u32 size) +{ + u8 *buf = NULL; + int ret; + + if (size > 0) { + buf = kmalloc(size, GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + + memcpy(buf, data, size); + } + + /* note: if successful returns number of bytes transfered */ + ret = usb_control_msg(ar_usb->udev, + usb_sndctrlpipe(ar_usb->udev, 0), + req, + USB_DIR_OUT | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, value, index, buf, + size, 1000); + + if (ret < 0) { + ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n", + __func__, ret); + } + + kfree(buf); + + return 0; +} + +static int ath6kl_usb_submit_ctrl_in(struct ath6kl_usb *ar_usb, + u8 req, u16 value, u16 index, void *data, + u32 size) +{ + u8 *buf = NULL; + int ret; + + if (size > 0) { + buf = kmalloc(size, GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + } + + /* note: if successful returns number of bytes transfered */ + ret = usb_control_msg(ar_usb->udev, + usb_rcvctrlpipe(ar_usb->udev, 0), + req, + USB_DIR_IN | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, value, index, buf, + size, 2 * HZ); + + if (ret < 0) { + ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n", + __func__, ret); + } + + memcpy((u8 *) data, buf, size); + + kfree(buf); + + return 0; +} + +static int ath6kl_usb_ctrl_msg_exchange(struct ath6kl_usb *ar_usb, + u8 req_val, u8 *req_buf, u32 req_len, + u8 resp_val, u8 *resp_buf, u32 *resp_len) +{ + int ret; + + /* send command */ + ret = ath6kl_usb_submit_ctrl_out(ar_usb, req_val, 0, 0, + req_buf, req_len); + + if (ret != 0) + return ret; + + if (resp_buf == NULL) { + /* no expected response */ + return ret; + } + + /* get response */ + ret = ath6kl_usb_submit_ctrl_in(ar_usb, resp_val, 0, 0, + resp_buf, *resp_len); + + return ret; +} + +static int ath6kl_usb_diag_read32(struct ath6kl *ar, u32 address, u32 *data) +{ + struct ath6kl_usb *ar_usb = ar->hif_priv; + struct ath6kl_usb_ctrl_diag_resp_read *resp; + struct ath6kl_usb_ctrl_diag_cmd_read *cmd; + u32 resp_len; + int ret; + + cmd = (struct ath6kl_usb_ctrl_diag_cmd_read *) ar_usb->diag_cmd_buffer; + + memset(cmd, 0, sizeof(*cmd)); + cmd->cmd = ATH6KL_USB_CTRL_DIAG_CC_READ; + cmd->address = cpu_to_le32(address); + resp_len = sizeof(*resp); + + ret = ath6kl_usb_ctrl_msg_exchange(ar_usb, + ATH6KL_USB_CONTROL_REQ_DIAG_CMD, + (u8 *) cmd, + sizeof(struct ath6kl_usb_ctrl_diag_cmd_write), + ATH6KL_USB_CONTROL_REQ_DIAG_RESP, + ar_usb->diag_resp_buffer, &resp_len); + + if (ret) + return ret; + + resp = (struct ath6kl_usb_ctrl_diag_resp_read *) + ar_usb->diag_resp_buffer; + + *data = le32_to_cpu(resp->value); + + return ret; +} + +static int ath6kl_usb_diag_write32(struct ath6kl *ar, u32 address, __le32 data) +{ + struct ath6kl_usb *ar_usb = ar->hif_priv; + struct ath6kl_usb_ctrl_diag_cmd_write *cmd; + + cmd = (struct ath6kl_usb_ctrl_diag_cmd_write *) ar_usb->diag_cmd_buffer; + + memset(cmd, 0, sizeof(struct ath6kl_usb_ctrl_diag_cmd_write)); + cmd->cmd = cpu_to_le32(ATH6KL_USB_CTRL_DIAG_CC_WRITE); + cmd->address = cpu_to_le32(address); + cmd->value = data; + + return ath6kl_usb_ctrl_msg_exchange(ar_usb, + ATH6KL_USB_CONTROL_REQ_DIAG_CMD, + (u8 *) cmd, + sizeof(*cmd), + 0, NULL, NULL); + +} + +static int ath6kl_usb_bmi_read(struct ath6kl *ar, u8 *buf, u32 len) +{ + struct ath6kl_usb *ar_usb = ar->hif_priv; + int ret; + + /* get response */ + ret = ath6kl_usb_submit_ctrl_in(ar_usb, + ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP, + 0, 0, buf, len); + if (ret != 0) { + ath6kl_err("Unable to read the bmi data from the device: %d\n", + ret); + return ret; + } + + return 0; +} + +static int ath6kl_usb_bmi_write(struct ath6kl *ar, u8 *buf, u32 len) +{ + struct ath6kl_usb *ar_usb = ar->hif_priv; + int ret; + + /* send command */ + ret = ath6kl_usb_submit_ctrl_out(ar_usb, + ATH6KL_USB_CONTROL_REQ_SEND_BMI_CMD, + 0, 0, buf, len); + if (ret != 0) { + ath6kl_err("unable to send the bmi data to the device: %d\n", + ret); + return ret; + } + + return 0; +} + +static int ath6kl_usb_power_on(struct ath6kl *ar) +{ + return 0; +} + +static int ath6kl_usb_power_off(struct ath6kl *ar) +{ + return 0; +} + +static const struct ath6kl_hif_ops ath6kl_usb_ops = { + .diag_read32 = ath6kl_usb_diag_read32, + .diag_write32 = ath6kl_usb_diag_write32, + .bmi_read = ath6kl_usb_bmi_read, + .bmi_write = ath6kl_usb_bmi_write, + .power_on = ath6kl_usb_power_on, + .power_off = ath6kl_usb_power_off, +}; + +/* ath6kl usb driver registered functions */ +static int ath6kl_usb_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct usb_device *dev = interface_to_usbdev(interface); + struct ath6kl *ar; + struct ath6kl_usb *ar_usb = NULL; + int vendor_id, product_id; + int ret = 0; + + usb_get_dev(dev); + + vendor_id = le16_to_cpu(dev->descriptor.idVendor); + product_id = le16_to_cpu(dev->descriptor.idProduct); + + ath6kl_dbg(ATH6KL_DBG_USB, "vendor_id = %04x\n", vendor_id); + ath6kl_dbg(ATH6KL_DBG_USB, "product_id = %04x\n", product_id); + + if (interface->cur_altsetting) + ath6kl_dbg(ATH6KL_DBG_USB, "USB Interface %d\n", + interface->cur_altsetting->desc.bInterfaceNumber); + + + if (dev->speed == USB_SPEED_HIGH) + ath6kl_dbg(ATH6KL_DBG_USB, "USB 2.0 Host\n"); + else + ath6kl_dbg(ATH6KL_DBG_USB, "USB 1.1 Host\n"); + + ar_usb = ath6kl_usb_create(interface); + + if (ar_usb == NULL) { + ret = -ENOMEM; + goto err_usb_put; + } + + ar = ath6kl_core_create(&ar_usb->udev->dev); + if (ar == NULL) { + ath6kl_err("Failed to alloc ath6kl core\n"); + ret = -ENOMEM; + goto err_usb_destroy; + } + + ar->hif_priv = ar_usb; + ar->hif_type = ATH6KL_HIF_TYPE_USB; + ar->hif_ops = &ath6kl_usb_ops; + ar->mbox_info.block_size = 16; + ar->bmi.max_data_size = 252; + + ar_usb->ar = ar; + + ret = ath6kl_core_init(ar); + if (ret) { + ath6kl_err("Failed to init ath6kl core: %d\n", ret); + goto err_core_free; + } + + return ret; + +err_core_free: + ath6kl_core_destroy(ar); +err_usb_destroy: + ath6kl_usb_destroy(ar_usb); +err_usb_put: + usb_put_dev(dev); + + return ret; +} + +static void ath6kl_usb_remove(struct usb_interface *interface) +{ + usb_put_dev(interface_to_usbdev(interface)); + ath6kl_usb_device_detached(interface); +} + +/* table of devices that work with this driver */ +static struct usb_device_id ath6kl_usb_ids[] = { + {USB_DEVICE(0x0cf3, 0x9374)}, + { /* Terminating entry */ }, +}; + +MODULE_DEVICE_TABLE(usb, ath6kl_usb_ids); + +static struct usb_driver ath6kl_usb_driver = { + .name = "ath6kl_usb", + .probe = ath6kl_usb_probe, + .disconnect = ath6kl_usb_remove, + .id_table = ath6kl_usb_ids, +}; + +static int ath6kl_usb_init(void) +{ + usb_register(&ath6kl_usb_driver); + return 0; +} + +static void ath6kl_usb_exit(void) +{ + usb_deregister(&ath6kl_usb_driver); +} + +module_init(ath6kl_usb_init); +module_exit(ath6kl_usb_exit); + +MODULE_AUTHOR("Atheros Communications, Inc."); +MODULE_DESCRIPTION("Driver support for Atheros AR600x USB devices"); +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_FIRMWARE(AR6004_HW_1_0_FIRMWARE_FILE); +MODULE_FIRMWARE(AR6004_HW_1_0_BOARD_DATA_FILE); +MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE); +MODULE_FIRMWARE(AR6004_HW_1_1_FIRMWARE_FILE); +MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE); +MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE); -- cgit v1.2.3-70-g09d2 From 859dd55d91d977090efbba15c7dfc82e7ed774ef Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 16:52:00 +0100 Subject: ARM: 7215/1: mmc: mmci: Increase max_segs from 16 to 128 A significant increase (10-20%) in performance throughput for USB mass storage is the reason for incrementing the value. By some reason the USB driver allocates buffers which requires a scattergather list to contain a lot more than 16 elements to get optimal performance. This change sets the maximum elements to 128. Tests with large reads and large writes (100 MiB) show that the throughput increase is significant for write (10% for this test) but not for read. Tests are run on a Linux host with ext4 FS on the gadget mass storage device. The sg-len still exceeds 16 for the read tests but the performance gain is low or nothing. Tested-by: Linus Walleij Signed-off-by: Per Forlin Signed-off-by: Ulf Hansson Signed-off-by: Russell King --- drivers/mmc/host/mmci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 79e4143ab9d..49f153e6ef7 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -160,7 +160,7 @@ (MCI_RXFIFOHALFFULLMASK | MCI_RXDATAAVLBLMASK | \ MCI_TXFIFOHALFEMPTYMASK) -#define NR_SG 16 +#define NR_SG 128 struct clk; struct variant_data; -- cgit v1.2.3-70-g09d2 From 5074d25dc97ac2d93fca7852563b7e204f03464a Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 16:53:17 +0100 Subject: ARM: 7216/1: mmc: mmci: Do not release spinlock in request_end The patch "mmc: core: move ->request() call from atomic context", is the reason to why this change is possible. This simplifies the error handling code execution path quite a lot and potentially also fixes some error handling hang problems. Tested-by: Linus Walleij Signed-off-by: Ulf Hansson Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 0d955ffaf44..0e04138b175 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -166,14 +166,8 @@ mmci_request_end(struct mmci_host *host, struct mmc_request *mrq) host->mrq = NULL; host->cmd = NULL; - /* - * Need to drop the host lock here; mmc_request_done may call - * back into the driver... - */ - spin_unlock(&host->lock); pm_runtime_put(mmc_dev(host->mmc)); mmc_request_done(host->mmc, mrq); - spin_lock(&host->lock); } static void mmci_set_mask1(struct mmci_host *host, unsigned int mask) -- cgit v1.2.3-70-g09d2 From 7d72a1d48af95211677ea83157945a8ef76b0751 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 16:54:55 +0100 Subject: ARM: 7217/1: mmc: mmci: Put power register deviations in variant data Use variant data to store hardware controller deviations concerning power registers to improve readability of the code. Signed-off-by: Sebastian Rasmussen Tested-by: Linus Walleij Signed-off-by: Ulf Hansson Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 0e04138b175..7cc89beee87 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -53,6 +53,7 @@ static unsigned int fmax = 515633; * @sdio: variant supports SDIO * @st_clkdiv: true if using a ST-specific clock divider algorithm * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register + * @pwrreg_powerup: power up value for MMCIPOWER register */ struct variant_data { unsigned int clkreg; @@ -63,18 +64,21 @@ struct variant_data { bool sdio; bool st_clkdiv; bool blksz_datactrl16; + u32 pwrreg_powerup; }; static struct variant_data variant_arm = { .fifosize = 16 * 4, .fifohalfsize = 8 * 4, .datalength_bits = 16, + .pwrreg_powerup = MCI_PWR_UP, }; static struct variant_data variant_arm_extended_fifo = { .fifosize = 128 * 4, .fifohalfsize = 64 * 4, .datalength_bits = 16, + .pwrreg_powerup = MCI_PWR_UP, }; static struct variant_data variant_u300 = { @@ -83,6 +87,7 @@ static struct variant_data variant_u300 = { .clkreg_enable = MCI_ST_U300_HWFCEN, .datalength_bits = 16, .sdio = true, + .pwrreg_powerup = MCI_PWR_ON, }; static struct variant_data variant_ux500 = { @@ -93,6 +98,7 @@ static struct variant_data variant_ux500 = { .datalength_bits = 24, .sdio = true, .st_clkdiv = true, + .pwrreg_powerup = MCI_PWR_ON, }; static struct variant_data variant_ux500v2 = { @@ -104,6 +110,7 @@ static struct variant_data variant_ux500v2 = { .sdio = true, .st_clkdiv = true, .blksz_datactrl16 = true, + .pwrreg_powerup = MCI_PWR_ON, }; /* @@ -1009,6 +1016,7 @@ static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq) static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { struct mmci_host *host = mmc_priv(mmc); + struct variant_data *variant = host->variant; u32 pwr = 0; unsigned long flags; int ret; @@ -1035,11 +1043,15 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (host->plat->vdd_handler) pwr |= host->plat->vdd_handler(mmc_dev(mmc), ios->vdd, ios->power_mode); - /* The ST version does not have this, fall through to POWER_ON */ - if (host->hw_designer != AMBA_VENDOR_ST) { - pwr |= MCI_PWR_UP; - break; - } + + /* + * The ST Micro variant doesn't have the PL180s MCI_PWR_UP + * and instead uses MCI_PWR_ON so apply whatever value is + * configured in the variant data. + */ + pwr |= variant->pwrreg_powerup; + + break; case MMC_POWER_ON: pwr |= MCI_PWR_ON; break; -- cgit v1.2.3-70-g09d2 From 4d1a3a0dc551cfa7304ca46e014231500f3b81a6 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 16:57:07 +0100 Subject: ARM: 7218/1: mmc: mmci: Provide option to configure bus signal direction The ST Micro variant supports bus signal direction indication. A new member in the variant struct is added for this. Moreover the actual signal direction configuration is board specific, thus the amba mmci platform data is extended with a new member to be able provide mmci with these specific board configurations. This patch is based upon a patch from Sebastian Rasmussen. Tested-by: Linus Walleij Signed-off-by: Sebastian Rasmussen Signed-off-by: Ulf Hansson Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 21 +++++++++++++++++++++ drivers/mmc/host/mmci.h | 10 ---------- include/linux/amba/mmci.h | 16 ++++++++++++++++ 3 files changed, 37 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 7cc89beee87..eb11ce61941 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -54,6 +54,7 @@ static unsigned int fmax = 515633; * @st_clkdiv: true if using a ST-specific clock divider algorithm * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register * @pwrreg_powerup: power up value for MMCIPOWER register + * @signal_direction: input/out direction of bus signals can be indicated */ struct variant_data { unsigned int clkreg; @@ -65,6 +66,7 @@ struct variant_data { bool st_clkdiv; bool blksz_datactrl16; u32 pwrreg_powerup; + bool signal_direction; }; static struct variant_data variant_arm = { @@ -88,6 +90,7 @@ static struct variant_data variant_u300 = { .datalength_bits = 16, .sdio = true, .pwrreg_powerup = MCI_PWR_ON, + .signal_direction = true, }; static struct variant_data variant_ux500 = { @@ -99,6 +102,7 @@ static struct variant_data variant_ux500 = { .sdio = true, .st_clkdiv = true, .pwrreg_powerup = MCI_PWR_ON, + .signal_direction = true, }; static struct variant_data variant_ux500v2 = { @@ -111,6 +115,7 @@ static struct variant_data variant_ux500v2 = { .st_clkdiv = true, .blksz_datactrl16 = true, .pwrreg_powerup = MCI_PWR_ON, + .signal_direction = true, }; /* @@ -1057,6 +1062,22 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) break; } + if (variant->signal_direction && ios->power_mode != MMC_POWER_OFF) { + /* + * The ST Micro variant has some additional bits + * indicating signal direction for the signals in + * the SD/MMC bus and feedback-clock usage. + */ + pwr |= host->plat->sigdir; + + if (ios->bus_width == MMC_BUS_WIDTH_4) + pwr &= ~MCI_ST_DATA74DIREN; + else if (ios->bus_width == MMC_BUS_WIDTH_1) + pwr &= (~MCI_ST_DATA74DIREN & + ~MCI_ST_DATA31DIREN & + ~MCI_ST_DATA2DIREN); + } + if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) { if (host->hw_designer != AMBA_VENDOR_ST) pwr |= MCI_ROD; diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 49f153e6ef7..89eb2e3556d 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -13,16 +13,6 @@ #define MCI_PWR_ON 0x03 #define MCI_OD (1 << 6) #define MCI_ROD (1 << 7) -/* - * The ST Micro version does not have ROD and reuse the voltage registers - * for direction settings - */ -#define MCI_ST_DATA2DIREN (1 << 2) -#define MCI_ST_CMDDIREN (1 << 3) -#define MCI_ST_DATA0DIREN (1 << 4) -#define MCI_ST_DATA31DIREN (1 << 5) -#define MCI_ST_FBCLKEN (1 << 7) -#define MCI_ST_DATA74DIREN (1 << 8) #define MMCICLOCK 0x004 #define MCI_CLK_ENABLE (1 << 8) diff --git a/include/linux/amba/mmci.h b/include/linux/amba/mmci.h index 0101e9c17fa..b51bf5fa85f 100644 --- a/include/linux/amba/mmci.h +++ b/include/linux/amba/mmci.h @@ -6,6 +6,19 @@ #include + +/* + * These defines is places here due to access is needed from machine + * configuration files. The ST Micro version does not have ROD and + * reuse the voltage registers for direction settings. + */ +#define MCI_ST_DATA2DIREN (1 << 2) +#define MCI_ST_CMDDIREN (1 << 3) +#define MCI_ST_DATA0DIREN (1 << 4) +#define MCI_ST_DATA31DIREN (1 << 5) +#define MCI_ST_FBCLKEN (1 << 7) +#define MCI_ST_DATA74DIREN (1 << 8) + /* Just some dummy forwarding */ struct dma_chan; @@ -31,6 +44,8 @@ struct dma_chan; * @capabilities: the capabilities of the block as implemented in * this platform, signify anything MMC_CAP_* from mmc/host.h * @capabilities2: more capabilities, MMC_CAP2_* from mmc/host.h + * @sigdir: a bit field indicating for what bits in the MMC bus the host + * should enable signal direction indication. * @dma_filter: function used to select an appropriate RX and TX * DMA channel to be used for DMA, if and only if you're deploying the * generic DMA engine @@ -54,6 +69,7 @@ struct mmci_platform_data { bool cd_invert; unsigned long capabilities; unsigned long capabilities2; + u32 sigdir; bool (*dma_filter)(struct dma_chan *chan, void *filter_param); void *dma_rx_param; void *dma_tx_param; -- cgit v1.2.3-70-g09d2 From bc521818e28042bb6018d91c353d24fb01ccb162 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 16:57:55 +0100 Subject: ARM: 7219/1: mmc: mmci: Change vdd_handler to a generic ios_handler The purpose of the vdd_handler does not make sense. We remove it and use a generic approach instead. A new ios_handler is added, the purpose of which e.g. can be to control GPIO pins to a levelshifter. Previously the vdd_handler was also used for making additional changes to the power register bits. This option is superfluous and is therefore removed. Adaptaptions from the old vdd_handler to the new ios_handler is done for mach-ux500 board, which was the only one using the vdd_handler. This patch is based upon a patch from Sebastian Rasmussen. Tested-by: Linus Walleij Signed-off-by: Sebastian Rasmussen Signed-off-by: Ulf Hansson Signed-off-by: Russell King --- arch/arm/mach-ux500/board-mop500-sdi.c | 21 ++++++++------------- drivers/mmc/host/mmci.c | 8 ++++---- include/linux/amba/mmci.h | 6 +++--- 3 files changed, 15 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c index 23be34b3bb6..4049bd7f061 100644 --- a/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/arch/arm/mach-ux500/board-mop500-sdi.c @@ -31,21 +31,13 @@ * SDI 0 (MicroSD slot) */ -/* MMCIPOWER bits */ -#define MCI_DATA2DIREN (1 << 2) -#define MCI_CMDDIREN (1 << 3) -#define MCI_DATA0DIREN (1 << 4) -#define MCI_DATA31DIREN (1 << 5) -#define MCI_FBCLKEN (1 << 7) - /* GPIO pins used by the sdi0 level shifter */ static int sdi0_en = -1; static int sdi0_vsel = -1; -static u32 mop500_sdi0_vdd_handler(struct device *dev, unsigned int vdd, - unsigned char power_mode) +static int mop500_sdi0_ios_handler(struct device *dev, struct mmc_ios *ios) { - switch (power_mode) { + switch (ios->power_mode) { case MMC_POWER_UP: case MMC_POWER_ON: /* @@ -65,8 +57,7 @@ static u32 mop500_sdi0_vdd_handler(struct device *dev, unsigned int vdd, break; } - return MCI_FBCLKEN | MCI_CMDDIREN | MCI_DATA0DIREN | - MCI_DATA2DIREN | MCI_DATA31DIREN; + return 0; } #ifdef CONFIG_STE_DMA40 @@ -90,13 +81,17 @@ static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = { #endif static struct mmci_platform_data mop500_sdi0_data = { - .vdd_handler = mop500_sdi0_vdd_handler, + .ios_handler = mop500_sdi0_ios_handler, .ocr_mask = MMC_VDD_29_30, .f_max = 50000000, .capabilities = MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED, .gpio_wp = -1, + .sigdir = MCI_ST_FBCLKEN | + MCI_ST_CMDDIREN | + MCI_ST_DATA0DIREN | + MCI_ST_DATA2DIREN, #ifdef CONFIG_STE_DMA40 .dma_filter = stedma40_filter, .dma_rx_param = &mop500_sdi0_dma_cfg_rx, diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index eb11ce61941..0af1507d15c 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1026,6 +1026,10 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) unsigned long flags; int ret; + if (host->plat->ios_handler && + host->plat->ios_handler(mmc_dev(mmc), ios)) + dev_err(mmc_dev(mmc), "platform ios_handler failed\n"); + switch (ios->power_mode) { case MMC_POWER_OFF: if (host->vcc) @@ -1045,10 +1049,6 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) return; } } - if (host->plat->vdd_handler) - pwr |= host->plat->vdd_handler(mmc_dev(mmc), ios->vdd, - ios->power_mode); - /* * The ST Micro variant doesn't have the PL180s MCI_PWR_UP * and instead uses MCI_PWR_ON so apply whatever value is diff --git a/include/linux/amba/mmci.h b/include/linux/amba/mmci.h index b51bf5fa85f..32a89cf5ec4 100644 --- a/include/linux/amba/mmci.h +++ b/include/linux/amba/mmci.h @@ -31,7 +31,8 @@ struct dma_chan; * @ocr_mask: available voltages on the 4 pins from the block, this * is ignored if a regulator is used, see the MMC_VDD_* masks in * mmc/host.h - * @vdd_handler: a callback function to translate a MMC_VDD_* + * @ios_handler: a callback function to act on specfic ios changes, + * used for example to control a levelshifter * mask into a value to be binary (or set some other custom bits * in MMCIPWR) or:ed and written into the MMCIPWR register of the * block. May also control external power based on the power_mode. @@ -61,8 +62,7 @@ struct dma_chan; struct mmci_platform_data { unsigned int f_max; unsigned int ocr_mask; - u32 (*vdd_handler)(struct device *, unsigned int vdd, - unsigned char power_mode); + int (*ios_handler)(struct device *, struct mmc_ios *); unsigned int (*status)(struct device *); int gpio_wp; int gpio_cd; -- cgit v1.2.3-70-g09d2 From 48fa700388bec2ba79e9c8cc087f39c800a6fff5 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 16:59:34 +0100 Subject: ARM: 7221/1: mmc: mmci: Change from using legacy suspend This patch switch from using the legacy suspend/resume to the new way of registering PM callbacks. No functional change is done. Tested-by: Linus Walleij Signed-off-by: Ulf Hansson Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 0af1507d15c..544995b3cb9 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1456,10 +1456,11 @@ static int __devexit mmci_remove(struct amba_device *dev) return 0; } -#ifdef CONFIG_PM -static int mmci_suspend(struct amba_device *dev, pm_message_t state) +#ifdef CONFIG_SUSPEND +static int mmci_suspend(struct device *dev) { - struct mmc_host *mmc = amba_get_drvdata(dev); + struct amba_device *adev = to_amba_device(dev); + struct mmc_host *mmc = amba_get_drvdata(adev); int ret = 0; if (mmc) { @@ -1473,9 +1474,10 @@ static int mmci_suspend(struct amba_device *dev, pm_message_t state) return ret; } -static int mmci_resume(struct amba_device *dev) +static int mmci_resume(struct device *dev) { - struct mmc_host *mmc = amba_get_drvdata(dev); + struct amba_device *adev = to_amba_device(dev); + struct mmc_host *mmc = amba_get_drvdata(adev); int ret = 0; if (mmc) { @@ -1488,11 +1490,12 @@ static int mmci_resume(struct amba_device *dev) return ret; } -#else -#define mmci_suspend NULL -#define mmci_resume NULL #endif +static const struct dev_pm_ops mmci_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(mmci_suspend, mmci_resume) +}; + static struct amba_id mmci_ids[] = { { .id = 0x00041180, @@ -1538,11 +1541,10 @@ MODULE_DEVICE_TABLE(amba, mmci_ids); static struct amba_driver mmci_driver = { .drv = { .name = DRIVER_NAME, + .pm = &mmci_dev_pm_ops, }, .probe = mmci_probe, .remove = __devexit_p(mmci_remove), - .suspend = mmci_suspend, - .resume = mmci_resume, .id_table = mmci_ids, }; -- cgit v1.2.3-70-g09d2 From 2cd976c46472e34460349ed43a217e34f90bad55 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 17:01:11 +0100 Subject: ARM: 7223/1: mmc: mmci: Fixup use of runtime PM and use autosuspend Added use of runtime PM autosuspend feature, with a fixed timeout of 50 ms. This will prevent adding a latency, although very minor, for _every_ request. Moreover the runtime_get_sync is now also used in set_ios and suspend since the runtime resourses are needed here as well. Tested-by: Linus Walleij Signed-off-by: Ulf Hansson Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 544995b3cb9..6a21fc0bf3d 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -178,8 +178,10 @@ mmci_request_end(struct mmci_host *host, struct mmc_request *mrq) host->mrq = NULL; host->cmd = NULL; - pm_runtime_put(mmc_dev(host->mmc)); mmc_request_done(host->mmc, mrq); + + pm_runtime_mark_last_busy(mmc_dev(host->mmc)); + pm_runtime_put_autosuspend(mmc_dev(host->mmc)); } static void mmci_set_mask1(struct mmci_host *host, unsigned int mask) @@ -1026,6 +1028,8 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) unsigned long flags; int ret; + pm_runtime_get_sync(mmc_dev(mmc)); + if (host->plat->ios_handler && host->plat->ios_handler(mmc_dev(mmc), ios)) dev_err(mmc_dev(mmc), "platform ios_handler failed\n"); @@ -1046,7 +1050,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) * power should be rare so we print an error * and return here. */ - return; + goto out; } } /* @@ -1100,6 +1104,10 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) } spin_unlock_irqrestore(&host->lock, flags); + + out: + pm_runtime_mark_last_busy(mmc_dev(mmc)); + pm_runtime_put_autosuspend(mmc_dev(mmc)); } static int mmci_get_ro(struct mmc_host *mmc) @@ -1372,6 +1380,8 @@ static int __devinit mmci_probe(struct amba_device *dev, mmci_dma_setup(host); + pm_runtime_set_autosuspend_delay(&dev->dev, 50); + pm_runtime_use_autosuspend(&dev->dev); pm_runtime_put(&dev->dev); mmc_add_host(mmc); @@ -1467,8 +1477,10 @@ static int mmci_suspend(struct device *dev) struct mmci_host *host = mmc_priv(mmc); ret = mmc_suspend_host(mmc); - if (ret == 0) + if (ret == 0) { + pm_runtime_get_sync(dev); writel(0, host->base + MMCIMASK0); + } } return ret; @@ -1484,6 +1496,7 @@ static int mmci_resume(struct device *dev) struct mmci_host *host = mmc_priv(mmc); writel(MCI_IRQENABLE, host->base + MMCIMASK0); + pm_runtime_put(dev); ret = mmc_resume_host(mmc); } -- cgit v1.2.3-70-g09d2 From 7258db7efe7d9c5eb80151554faa1fa7411d6e3e Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 17:05:28 +0100 Subject: ARM: 7227/1: mmc: mmci: Prepare for SDIO before setting up DMA job Move the SDIO preparation to be done before the DMA job is setup. This makes it possible to do DMA for SDIO transfers as well as the earlier supported pio mode. Signed-off-by: Ulf Hansson Signed-off-by: Stefan Nilsson XK Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 6a21fc0bf3d..b09ccb7223e 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -615,6 +615,11 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) if (data->flags & MMC_DATA_READ) datactrl |= MCI_DPSM_DIRECTION; + /* The ST Micro variants has a special bit to enable SDIO */ + if (variant->sdio && host->mmc->card) + if (mmc_card_sdio(host->mmc->card)) + datactrl |= MCI_ST_DPSM_SDIOEN; + /* * Attempt to use DMA operation mode, if this * should fail, fall back to PIO mode @@ -643,11 +648,6 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) irqmask = MCI_TXFIFOHALFEMPTYMASK; } - /* The ST Micro variants has a special bit to enable SDIO */ - if (variant->sdio && host->mmc->card) - if (mmc_card_sdio(host->mmc->card)) - datactrl |= MCI_ST_DPSM_SDIOEN; - writel(datactrl, base + MMCIDATACTRL); writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0); mmci_set_mask1(host, irqmask); -- cgit v1.2.3-70-g09d2 From 393e5e24165d0bef60489ecd0baef085e9af2e5a Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 17:08:04 +0100 Subject: ARM: 7230/1: mmc: mmci: Fix PIO read for small SDIO packets Corrects a bug in MMCI host driver which silently causes small reads (< 4 bytes as only used in SDIO) from PL-18X to fail. Signed-off-by: Stefan Nilsson XK Signed-off-by: Ulf Hansson Signed-off-by: Fredrik Soderstedt Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index b09ccb7223e..1f8832699cd 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -794,7 +794,24 @@ static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int rema if (count <= 0) break; - readsl(base + MMCIFIFO, ptr, count >> 2); + /* + * SDIO especially may want to send something that is + * not divisible by 4 (as opposed to card sectors + * etc). Therefore make sure to always read the last bytes + * while only doing full 32-bit reads towards the FIFO. + */ + if (unlikely(count & 0x3)) { + if (count < 4) { + unsigned char buf[4]; + readsl(base + MMCIFIFO, buf, 1); + memcpy(ptr, buf, count); + } else { + readsl(base + MMCIFIFO, ptr, count >> 2); + count &= ~0x3; + } + } else { + readsl(base + MMCIFIFO, ptr, count >> 2); + } ptr += count; remain -= count; -- cgit v1.2.3-70-g09d2 From f0c28b0075cad861f4b93c526c6446169d136466 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 14 Jan 2012 16:56:43 +0800 Subject: devfreq: exynos4_bus: Use dev_get_drvdata at appropriate places Signed-off-by: Axel Lin Signed-off-by: MyungJoo Ham --- drivers/devfreq/exynos4_bus.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/devfreq/exynos4_bus.c b/drivers/devfreq/exynos4_bus.c index 6460577d670..489ccfa93a9 100644 --- a/drivers/devfreq/exynos4_bus.c +++ b/drivers/devfreq/exynos4_bus.c @@ -622,9 +622,7 @@ static int exynos4_bus_setvolt(struct busfreq_data *data, struct opp *opp, static int exynos4_bus_target(struct device *dev, unsigned long *_freq) { int err = 0; - struct platform_device *pdev = container_of(dev, struct platform_device, - dev); - struct busfreq_data *data = platform_get_drvdata(pdev); + struct busfreq_data *data = dev_get_drvdata(dev); struct opp *opp = devfreq_recommended_opp(dev, _freq); unsigned long old_freq = opp_get_freq(data->curr_opp); unsigned long freq = opp_get_freq(opp); @@ -689,9 +687,7 @@ static int exynos4_get_busier_dmc(struct busfreq_data *data) static int exynos4_bus_get_dev_status(struct device *dev, struct devfreq_dev_status *stat) { - struct platform_device *pdev = container_of(dev, struct platform_device, - dev); - struct busfreq_data *data = platform_get_drvdata(pdev); + struct busfreq_data *data = dev_get_drvdata(dev); int busier_dmc; int cycles_x2 = 2; /* 2 x cycles */ void __iomem *addr; @@ -739,9 +735,7 @@ static int exynos4_bus_get_dev_status(struct device *dev, static void exynos4_bus_exit(struct device *dev) { - struct platform_device *pdev = container_of(dev, struct platform_device, - dev); - struct busfreq_data *data = platform_get_drvdata(pdev); + struct busfreq_data *data = dev_get_drvdata(dev); devfreq_unregister_opp_notifier(dev, data->devfreq); } @@ -1087,9 +1081,7 @@ static __devexit int exynos4_busfreq_remove(struct platform_device *pdev) static int exynos4_busfreq_resume(struct device *dev) { - struct platform_device *pdev = container_of(dev, struct platform_device, - dev); - struct busfreq_data *data = platform_get_drvdata(pdev); + struct busfreq_data *data = dev_get_drvdata(dev); busfreq_mon_reset(data); return 0; -- cgit v1.2.3-70-g09d2 From e0d44e8ab06885a5bb980f3d6d4cf64ad430d406 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 16 Jan 2012 14:53:08 +0800 Subject: devfreq: Remove MODULE_ALIAS for exynos4 busfreq driver This driver can only be built-in, it does not make sense to add modalias for it (in addition to being incorrect, the platform modalias needs to be prefixed with "platform:"). Signed-off-by: Axel Lin Signed-off-by: MyungJoo Ham --- drivers/devfreq/exynos4_bus.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/devfreq/exynos4_bus.c b/drivers/devfreq/exynos4_bus.c index 489ccfa93a9..590d6865e38 100644 --- a/drivers/devfreq/exynos4_bus.c +++ b/drivers/devfreq/exynos4_bus.c @@ -1124,4 +1124,3 @@ module_exit(exynos4_busfreq_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("EXYNOS4 busfreq driver with devfreq framework"); MODULE_AUTHOR("MyungJoo Ham "); -MODULE_ALIAS("exynos4-busfreq"); -- cgit v1.2.3-70-g09d2 From 6530b9dea1b7f33eaf79ba625e3a99f2455f3eb1 Mon Sep 17 00:00:00 2001 From: MyungJoo Ham Date: Fri, 9 Dec 2011 16:42:19 +0900 Subject: PM / devfreq: add min/max_freq limit requested by users. The frequency requested to devfreq device driver from devfreq governors is restricted by min_freq and max_freq input. Signed-off-by: MyungJoo Ham Signed-off-by: Kyungmin Park --- drivers/devfreq/devfreq.c | 70 +++++++++++++++++++++++++++++++ drivers/devfreq/governor_performance.c | 5 ++- drivers/devfreq/governor_powersave.c | 2 +- drivers/devfreq/governor_simpleondemand.c | 12 ++++-- drivers/devfreq/governor_userspace.c | 15 +++++-- include/linux/devfreq.h | 5 +++ 6 files changed, 101 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index c189b82f5ec..a129a7b6bfd 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -501,12 +501,82 @@ static ssize_t show_central_polling(struct device *dev, !to_devfreq(dev)->governor->no_central_polling); } +static ssize_t store_min_freq(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct devfreq *df = to_devfreq(dev); + unsigned long value; + int ret; + unsigned long max; + + ret = sscanf(buf, "%lu", &value); + if (ret != 1) + goto out; + + mutex_lock(&df->lock); + max = df->max_freq; + if (value && max && value > max) { + ret = -EINVAL; + goto unlock; + } + + df->min_freq = value; + update_devfreq(df); + ret = count; +unlock: + mutex_unlock(&df->lock); +out: + return ret; +} + +static ssize_t show_min_freq(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "%lu\n", to_devfreq(dev)->min_freq); +} + +static ssize_t store_max_freq(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct devfreq *df = to_devfreq(dev); + unsigned long value; + int ret; + unsigned long min; + + ret = sscanf(buf, "%lu", &value); + if (ret != 1) + goto out; + + mutex_lock(&df->lock); + min = df->min_freq; + if (value && min && value < min) { + ret = -EINVAL; + goto unlock; + } + + df->max_freq = value; + update_devfreq(df); + ret = count; +unlock: + mutex_unlock(&df->lock); +out: + return ret; +} + +static ssize_t show_max_freq(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "%lu\n", to_devfreq(dev)->max_freq); +} + static struct device_attribute devfreq_attrs[] = { __ATTR(governor, S_IRUGO, show_governor, NULL), __ATTR(cur_freq, S_IRUGO, show_freq, NULL), __ATTR(central_polling, S_IRUGO, show_central_polling, NULL), __ATTR(polling_interval, S_IRUGO | S_IWUSR, show_polling_interval, store_polling_interval), + __ATTR(min_freq, S_IRUGO | S_IWUSR, show_min_freq, store_min_freq), + __ATTR(max_freq, S_IRUGO | S_IWUSR, show_max_freq, store_max_freq), { }, }; diff --git a/drivers/devfreq/governor_performance.c b/drivers/devfreq/governor_performance.c index c0596b29176..574a06b1b1d 100644 --- a/drivers/devfreq/governor_performance.c +++ b/drivers/devfreq/governor_performance.c @@ -18,7 +18,10 @@ static int devfreq_performance_func(struct devfreq *df, * target callback should be able to get floor value as * said in devfreq.h */ - *freq = UINT_MAX; + if (!df->max_freq) + *freq = UINT_MAX; + else + *freq = df->max_freq; return 0; } diff --git a/drivers/devfreq/governor_powersave.c b/drivers/devfreq/governor_powersave.c index 2483a85a266..d742d4a82d6 100644 --- a/drivers/devfreq/governor_powersave.c +++ b/drivers/devfreq/governor_powersave.c @@ -18,7 +18,7 @@ static int devfreq_powersave_func(struct devfreq *df, * target callback should be able to get ceiling value as * said in devfreq.h */ - *freq = 0; + *freq = df->min_freq; return 0; } diff --git a/drivers/devfreq/governor_simpleondemand.c b/drivers/devfreq/governor_simpleondemand.c index efad8dcf902..a2e3eae7901 100644 --- a/drivers/devfreq/governor_simpleondemand.c +++ b/drivers/devfreq/governor_simpleondemand.c @@ -25,6 +25,7 @@ static int devfreq_simple_ondemand_func(struct devfreq *df, unsigned int dfso_upthreshold = DFSO_UPTHRESHOLD; unsigned int dfso_downdifferential = DFSO_DOWNDIFFERENCTIAL; struct devfreq_simple_ondemand_data *data = df->data; + unsigned long max = (df->max_freq) ? df->max_freq : UINT_MAX; if (err) return err; @@ -41,7 +42,7 @@ static int devfreq_simple_ondemand_func(struct devfreq *df, /* Assume MAX if it is going to be divided by zero */ if (stat.total_time == 0) { - *freq = UINT_MAX; + *freq = max; return 0; } @@ -54,13 +55,13 @@ static int devfreq_simple_ondemand_func(struct devfreq *df, /* Set MAX if it's busy enough */ if (stat.busy_time * 100 > stat.total_time * dfso_upthreshold) { - *freq = UINT_MAX; + *freq = max; return 0; } /* Set MAX if we do not know the initial frequency */ if (stat.current_frequency == 0) { - *freq = UINT_MAX; + *freq = max; return 0; } @@ -79,6 +80,11 @@ static int devfreq_simple_ondemand_func(struct devfreq *df, b = div_u64(b, (dfso_upthreshold - dfso_downdifferential / 2)); *freq = (unsigned long) b; + if (df->min_freq && *freq < df->min_freq) + *freq = df->min_freq; + if (df->max_freq && *freq > df->max_freq) + *freq = df->max_freq; + return 0; } diff --git a/drivers/devfreq/governor_userspace.c b/drivers/devfreq/governor_userspace.c index 4f8b563da78..0681246fc89 100644 --- a/drivers/devfreq/governor_userspace.c +++ b/drivers/devfreq/governor_userspace.c @@ -25,10 +25,19 @@ static int devfreq_userspace_func(struct devfreq *df, unsigned long *freq) { struct userspace_data *data = df->data; - if (!data->valid) + if (data->valid) { + unsigned long adjusted_freq = data->user_frequency; + + if (df->max_freq && adjusted_freq > df->max_freq) + adjusted_freq = df->max_freq; + + if (df->min_freq && adjusted_freq < df->min_freq) + adjusted_freq = df->min_freq; + + *freq = adjusted_freq; + } else { *freq = df->previous_freq; /* No user freq specified yet */ - else - *freq = data->user_frequency; + } return 0; } diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index f7eb7d06df7..5862475d05f 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -124,6 +124,8 @@ struct devfreq_governor { * touch this. * @being_removed a flag to mark that this object is being removed in * order to prevent trying to remove the object multiple times. + * @min_freq Limit minimum frequency requested by user (0: none) + * @max_freq Limit maximum frequency requested by user (0: none) * * This structure stores the devfreq information for a give device. * @@ -149,6 +151,9 @@ struct devfreq { void *data; /* private data for governors */ bool being_removed; + + unsigned long min_freq; + unsigned long max_freq; }; #if defined(CONFIG_PM_DEVFREQ) -- cgit v1.2.3-70-g09d2 From f4a0391dfa91155bd961673b31eb42d9d45c799d Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 5 Jan 2012 12:49:54 -0200 Subject: ima: fix Kconfig dependencies Fix the following build warning: warning: (IMA) selects TCG_TPM which has unmet direct dependencies (HAS_IOMEM && EXPERIMENTAL) Suggested-by: Rajiv Andrade Signed-off-by: Fabio Estevam Signed-off-by: Rajiv Andrade Cc: Signed-off-by: Mimi Zohar --- drivers/char/tpm/Kconfig | 1 - security/integrity/ima/Kconfig | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig index 7fc75e47e6d..a048199ce86 100644 --- a/drivers/char/tpm/Kconfig +++ b/drivers/char/tpm/Kconfig @@ -5,7 +5,6 @@ menuconfig TCG_TPM tristate "TPM Hardware Support" depends on HAS_IOMEM - depends on EXPERIMENTAL select SECURITYFS ---help--- If you have a TPM security chip in your system, which diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig index 4f554f20dc9..063298a797e 100644 --- a/security/integrity/ima/Kconfig +++ b/security/integrity/ima/Kconfig @@ -9,7 +9,7 @@ config IMA select CRYPTO_HMAC select CRYPTO_MD5 select CRYPTO_SHA1 - select TCG_TPM if !S390 && !UML + select TCG_TPM if HAS_IOMEM && !UML select TCG_TIS if TCG_TPM help The Trusted Computing Group(TCG) runtime Integrity -- cgit v1.2.3-70-g09d2 From 6219929f5f82708309b3054ec7db6cb6e3ee47d5 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Mon, 9 Jan 2012 20:27:41 +0530 Subject: regulator: TPS62360: Add tps62360 regulator driver The regulator module consists of 1 DCDC. The output voltage is configurable and is meant for supply power to the core voltage of Soc. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 10 + drivers/regulator/Makefile | 1 + drivers/regulator/tps62360-regulator.c | 472 +++++++++++++++++++++++++++++++++ include/linux/regulator/tps62360.h | 57 ++++ 4 files changed, 540 insertions(+) create mode 100644 drivers/regulator/tps62360-regulator.c create mode 100644 include/linux/regulator/tps62360.h (limited to 'drivers') diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 7a61b17ddd0..b9ad3d8e03c 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -328,6 +328,16 @@ config REGULATOR_TPS65910 help This driver supports TPS65910 voltage regulator chips. +config REGULATOR_TPS62360 + tristate "TI TPS62360 Power Regulator" + depends on I2C + select REGMAP_I2C + help + This driver supports TPS62360 voltage regulator chip. This + regulator is meant for processor core supply. This chip is + high-frequency synchronous step down dc-dc converter optimized + for battery-powered portable applications. + config REGULATOR_AAT2870 tristate "AnalogicTech AAT2870 Regulators" depends on MFD_AAT2870_CORE diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 503bac87715..1668b2e667c 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -47,6 +47,7 @@ obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o +obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG diff --git a/drivers/regulator/tps62360-regulator.c b/drivers/regulator/tps62360-regulator.c new file mode 100644 index 00000000000..f778ef06769 --- /dev/null +++ b/drivers/regulator/tps62360-regulator.c @@ -0,0 +1,472 @@ +/* + * tps62360.c -- TI tps62360 + * + * Driver for processor core supply tps62360 and tps62361B + * + * Copyright (c) 2012, NVIDIA Corporation. + * + * Author: Laxman Dewangan + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, + * whether express or implied; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307, USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Register definitions */ +#define REG_VSET0 0 +#define REG_VSET1 1 +#define REG_VSET2 2 +#define REG_VSET3 3 +#define REG_CONTROL 4 +#define REG_TEMP 5 +#define REG_RAMPCTRL 6 +#define REG_CHIPID 8 + +enum chips {TPS62360, TPS62361}; + +#define TPS62360_BASE_VOLTAGE 770 +#define TPS62360_N_VOLTAGES 64 + +#define TPS62361_BASE_VOLTAGE 500 +#define TPS62361_N_VOLTAGES 128 + +/* tps 62360 chip information */ +struct tps62360_chip { + const char *name; + struct device *dev; + struct regulator_desc desc; + struct i2c_client *client; + struct regulator_dev *rdev; + struct regmap *regmap; + int chip_id; + int vsel0_gpio; + int vsel1_gpio; + int voltage_base; + u8 voltage_reg_mask; + bool en_internal_pulldn; + bool en_force_pwm; + bool en_discharge; + bool valid_gpios; + int lru_index[4]; + int curr_vset_vsel[4]; + int curr_vset_id; +}; + +/* + * find_voltage_set_register: Find new voltage configuration register + * (VSET) id. + * The finding of the new VSET register will be based on the LRU mechanism. + * Each VSET register will have different voltage configured . This + * Function will look if any of the VSET register have requested voltage set + * or not. + * - If it is already there then it will make that register as most + * recently used and return as found so that caller need not to set + * the VSET register but need to set the proper gpios to select this + * VSET register. + * - If requested voltage is not found then it will use the least + * recently mechanism to get new VSET register for new configuration + * and will return not_found so that caller need to set new VSET + * register and then gpios (both). + */ +static bool find_voltage_set_register(struct tps62360_chip *tps, + int req_vsel, int *vset_reg_id) +{ + int i; + bool found = false; + int new_vset_reg = tps->lru_index[3]; + int found_index = 3; + for (i = 0; i < 4; ++i) { + if (tps->curr_vset_vsel[tps->lru_index[i]] == req_vsel) { + new_vset_reg = tps->lru_index[i]; + found_index = i; + found = true; + goto update_lru_index; + } + } + +update_lru_index: + for (i = found_index; i > 0; i--) + tps->lru_index[i] = tps->lru_index[i - 1]; + + tps->lru_index[0] = new_vset_reg; + *vset_reg_id = new_vset_reg; + return found; +} + +static int tps62360_dcdc_get_voltage(struct regulator_dev *dev) +{ + struct tps62360_chip *tps = rdev_get_drvdata(dev); + int vsel; + unsigned int data; + int ret; + + ret = regmap_read(tps->regmap, REG_VSET0 + tps->curr_vset_id, &data); + if (ret < 0) { + dev_err(tps->dev, "%s: Error in reading register %d\n", + __func__, REG_VSET0 + tps->curr_vset_id); + return ret; + } + vsel = (int)data & tps->voltage_reg_mask; + return (tps->voltage_base + vsel * 10) * 1000; +} + +static int tps62360_dcdc_set_voltage(struct regulator_dev *dev, + int min_uV, int max_uV, unsigned *selector) +{ + struct tps62360_chip *tps = rdev_get_drvdata(dev); + int vsel; + int ret; + bool found = false; + int new_vset_id = tps->curr_vset_id; + + if (max_uV < min_uV) + return -EINVAL; + + if (min_uV > + ((tps->voltage_base + (tps->desc.n_voltages - 1) * 10) * 1000)) + return -EINVAL; + + if (max_uV < tps->voltage_base * 1000) + return -EINVAL; + + vsel = DIV_ROUND_UP(min_uV - (tps->voltage_base * 1000), 10000); + if (selector) + *selector = (vsel & tps->voltage_reg_mask); + + /* + * If gpios are available to select the VSET register then least + * recently used register for new configuration. + */ + if (tps->valid_gpios) + found = find_voltage_set_register(tps, vsel, &new_vset_id); + + if (!found) { + ret = regmap_update_bits(tps->regmap, REG_VSET0 + new_vset_id, + tps->voltage_reg_mask, vsel); + if (ret < 0) { + dev_err(tps->dev, "%s: Error in updating register %d\n", + __func__, REG_VSET0 + new_vset_id); + return ret; + } + tps->curr_vset_id = new_vset_id; + tps->curr_vset_vsel[new_vset_id] = vsel; + } + + /* Select proper VSET register vio gpios */ + if (tps->valid_gpios) { + gpio_set_value_cansleep(tps->vsel0_gpio, + new_vset_id & 0x1); + gpio_set_value_cansleep(tps->vsel1_gpio, + (new_vset_id >> 1) & 0x1); + } + return 0; +} + +static int tps62360_dcdc_list_voltage(struct regulator_dev *dev, + unsigned selector) +{ + struct tps62360_chip *tps = rdev_get_drvdata(dev); + + if ((selector < 0) || (selector >= tps->desc.n_voltages)) + return -EINVAL; + return (tps->voltage_base + selector * 10) * 1000; +} + +static struct regulator_ops tps62360_dcdc_ops = { + .get_voltage = tps62360_dcdc_get_voltage, + .set_voltage = tps62360_dcdc_set_voltage, + .list_voltage = tps62360_dcdc_list_voltage, +}; + +static int tps62360_init_force_pwm(struct tps62360_chip *tps, + struct tps62360_regulator_platform_data *pdata, + int vset_id) +{ + unsigned int data; + int ret; + ret = regmap_read(tps->regmap, REG_VSET0 + vset_id, &data); + if (ret < 0) { + dev_err(tps->dev, "%s() fails in writing reg %d\n", + __func__, REG_VSET0 + vset_id); + return ret; + } + tps->curr_vset_vsel[vset_id] = data & tps->voltage_reg_mask; + if (pdata->en_force_pwm) + data |= BIT(7); + else + data &= ~BIT(7); + ret = regmap_write(tps->regmap, REG_VSET0 + vset_id, data); + if (ret < 0) + dev_err(tps->dev, "%s() fails in writing reg %d\n", + __func__, REG_VSET0 + vset_id); + return ret; +} + +static int tps62360_init_dcdc(struct tps62360_chip *tps, + struct tps62360_regulator_platform_data *pdata) +{ + int ret; + int i; + + /* Initailize internal pull up/down control */ + if (tps->en_internal_pulldn) + ret = regmap_write(tps->regmap, REG_CONTROL, 0xE0); + else + ret = regmap_write(tps->regmap, REG_CONTROL, 0x0); + if (ret < 0) { + dev_err(tps->dev, "%s() fails in writing reg %d\n", + __func__, REG_CONTROL); + return ret; + } + + /* Initailize force PWM mode */ + if (tps->valid_gpios) { + for (i = 0; i < 4; ++i) { + ret = tps62360_init_force_pwm(tps, pdata, i); + if (ret < 0) + return ret; + } + } else { + ret = tps62360_init_force_pwm(tps, pdata, tps->curr_vset_id); + if (ret < 0) + return ret; + } + + /* Reset output discharge path to reduce power consumption */ + ret = regmap_update_bits(tps->regmap, REG_RAMPCTRL, BIT(2), 0); + if (ret < 0) + dev_err(tps->dev, "%s() fails in updating reg %d\n", + __func__, REG_RAMPCTRL); + return ret; +} + +static const struct regmap_config tps62360_regmap_config = { + .reg_bits = 8, + .val_bits = 8, +}; + +static int __devinit tps62360_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct tps62360_regulator_platform_data *pdata; + struct regulator_dev *rdev; + struct tps62360_chip *tps; + int ret; + int i; + + pdata = client->dev.platform_data; + if (!pdata) { + dev_err(&client->dev, "%s() Err: Platform data not found\n", + __func__); + return -EIO; + } + + tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); + if (!tps) { + dev_err(&client->dev, "%s() Err: Memory allocation fails\n", + __func__); + return -ENOMEM; + } + + tps->en_force_pwm = pdata->en_force_pwm; + tps->en_discharge = pdata->en_discharge; + tps->en_internal_pulldn = pdata->en_internal_pulldn; + tps->vsel0_gpio = pdata->vsel0_gpio; + tps->vsel1_gpio = pdata->vsel1_gpio; + tps->client = client; + tps->dev = &client->dev; + tps->name = id->name; + tps->voltage_base = (id->driver_data == TPS62360) ? + TPS62360_BASE_VOLTAGE : TPS62361_BASE_VOLTAGE; + tps->voltage_reg_mask = (id->driver_data == TPS62360) ? 0x3F : 0x7F; + + tps->desc.name = id->name; + tps->desc.id = 0; + tps->desc.n_voltages = (id->driver_data == TPS62360) ? + TPS62360_N_VOLTAGES : TPS62361_N_VOLTAGES; + tps->desc.ops = &tps62360_dcdc_ops; + tps->desc.type = REGULATOR_VOLTAGE; + tps->desc.owner = THIS_MODULE; + tps->regmap = regmap_init_i2c(client, &tps62360_regmap_config); + if (IS_ERR(tps->regmap)) { + ret = PTR_ERR(tps->regmap); + dev_err(&client->dev, "%s() Err: Failed to allocate register" + "map: %d\n", __func__, ret); + return ret; + } + i2c_set_clientdata(client, tps); + + tps->curr_vset_id = (pdata->vsel1_def_state & 1) * 2 + + (pdata->vsel0_def_state & 1); + tps->lru_index[0] = tps->curr_vset_id; + tps->valid_gpios = false; + + if (gpio_is_valid(tps->vsel0_gpio) && gpio_is_valid(tps->vsel1_gpio)) { + ret = gpio_request(tps->vsel0_gpio, "tps62360-vsel0"); + if (ret) { + dev_err(&client->dev, + "Err: Could not obtain vsel0 GPIO %d: %d\n", + tps->vsel0_gpio, ret); + goto err_gpio0; + } + ret = gpio_direction_output(tps->vsel0_gpio, + pdata->vsel0_def_state); + if (ret) { + dev_err(&client->dev, "Err: Could not set direction of" + "vsel0 GPIO %d: %d\n", tps->vsel0_gpio, ret); + gpio_free(tps->vsel0_gpio); + goto err_gpio0; + } + + ret = gpio_request(tps->vsel1_gpio, "tps62360-vsel1"); + if (ret) { + dev_err(&client->dev, + "Err: Could not obtain vsel1 GPIO %d: %d\n", + tps->vsel1_gpio, ret); + goto err_gpio1; + } + ret = gpio_direction_output(tps->vsel1_gpio, + pdata->vsel1_def_state); + if (ret) { + dev_err(&client->dev, "Err: Could not set direction of" + "vsel1 GPIO %d: %d\n", tps->vsel1_gpio, ret); + gpio_free(tps->vsel1_gpio); + goto err_gpio1; + } + tps->valid_gpios = true; + + /* + * Initialize the lru index with vset_reg id + * The index 0 will be most recently used and + * set with the tps->curr_vset_id */ + for (i = 0; i < 4; ++i) + tps->lru_index[i] = i; + tps->lru_index[0] = tps->curr_vset_id; + tps->lru_index[tps->curr_vset_id] = 0; + } + + ret = tps62360_init_dcdc(tps, pdata); + if (ret < 0) { + dev_err(tps->dev, "%s() Err: Init fails with = %d\n", + __func__, ret); + goto err_init; + } + + /* Register the regulators */ + rdev = regulator_register(&tps->desc, &client->dev, + &pdata->reg_init_data, tps, NULL); + if (IS_ERR(rdev)) { + dev_err(tps->dev, "%s() Err: Failed to register %s\n", + __func__, id->name); + ret = PTR_ERR(rdev); + goto err_init; + } + + tps->rdev = rdev; + return 0; + +err_init: + if (gpio_is_valid(tps->vsel1_gpio)) + gpio_free(tps->vsel1_gpio); +err_gpio1: + if (gpio_is_valid(tps->vsel0_gpio)) + gpio_free(tps->vsel0_gpio); +err_gpio0: + regmap_exit(tps->regmap); + return ret; +} + +/** + * tps62360_remove - tps62360 driver i2c remove handler + * @client: i2c driver client device structure + * + * Unregister TPS driver as an i2c client device driver + */ +static int __devexit tps62360_remove(struct i2c_client *client) +{ + struct tps62360_chip *tps = i2c_get_clientdata(client); + + if (gpio_is_valid(tps->vsel1_gpio)) + gpio_free(tps->vsel1_gpio); + + if (gpio_is_valid(tps->vsel0_gpio)) + gpio_free(tps->vsel0_gpio); + + regulator_unregister(tps->rdev); + regmap_exit(tps->regmap); + return 0; +} + +static void tps62360_shutdown(struct i2c_client *client) +{ + struct tps62360_chip *tps = i2c_get_clientdata(client); + int st; + + if (!tps->en_discharge) + return; + + /* Configure the output discharge path */ + st = regmap_update_bits(tps->regmap, REG_RAMPCTRL, BIT(2), BIT(2)); + if (st < 0) + dev_err(tps->dev, "%s() fails in updating reg %d\n", + __func__, REG_RAMPCTRL); +} + +static const struct i2c_device_id tps62360_id[] = { + {.name = "tps62360", .driver_data = TPS62360}, + {.name = "tps62361", .driver_data = TPS62361}, + {}, +}; + +MODULE_DEVICE_TABLE(i2c, tps62360_id); + +static struct i2c_driver tps62360_i2c_driver = { + .driver = { + .name = "tps62360", + .owner = THIS_MODULE, + }, + .probe = tps62360_probe, + .remove = __devexit_p(tps62360_remove), + .shutdown = tps62360_shutdown, + .id_table = tps62360_id, +}; + +static int __init tps62360_init(void) +{ + return i2c_add_driver(&tps62360_i2c_driver); +} +subsys_initcall(tps62360_init); + +static void __exit tps62360_cleanup(void) +{ + i2c_del_driver(&tps62360_i2c_driver); +} +module_exit(tps62360_cleanup); + +MODULE_AUTHOR("Laxman Dewangan "); +MODULE_DESCRIPTION("TPS62360 voltage regulator driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/regulator/tps62360.h b/include/linux/regulator/tps62360.h new file mode 100644 index 00000000000..6a5c1b2c751 --- /dev/null +++ b/include/linux/regulator/tps62360.h @@ -0,0 +1,57 @@ +/* + * tps62360.h -- TI tps62360 + * + * Interface for regulator driver for TI TPS62360 Processor core supply + * + * Copyright (C) 2012 NVIDIA Corporation + + * Author: Laxman Dewangan + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef __LINUX_REGULATOR_TPS62360_H +#define __LINUX_REGULATOR_TPS62360_H + +#include + +/* + * struct tps62360_regulator_platform_data - tps62360 regulator platform data. + * + * @reg_init_data: The regulator init data. + * @en_force_pwm: Enable force pwm or not. + * @en_discharge: Enable discharge the output capacitor via internal + * register. + * @en_internal_pulldn: internal pull down enable or not. + * @vsel0_gpio: Gpio number for vsel0. It should be -1 if this is tied with + * fixed logic. + * @vsel1_gpio: Gpio number for vsel1. It should be -1 if this is tied with + * fixed logic. + * @vsel0_def_state: Default state of vsel0. 1 if it is high else 0. + * @vsel1_def_state: Default state of vsel1. 1 if it is high else 0. + */ +struct tps62360_regulator_platform_data { + struct regulator_init_data reg_init_data; + bool en_force_pwm; + bool en_discharge; + bool en_internal_pulldn; + int vsel0_gpio; + int vsel1_gpio; + int vsel0_def_state; + int vsel1_def_state; +}; + +#endif /* __LINUX_REGULATOR_TPS62360_H */ -- cgit v1.2.3-70-g09d2 From 9767ec7fe8d9bf00e764f1d0ca0176988255be11 Mon Sep 17 00:00:00 2001 From: Sangbeom Kim Date: Mon, 9 Jan 2012 19:10:25 +0900 Subject: regulator: Add S5M8767A regulator driver S5M8767A is a cost-effective PMIC which is designed for mobile applications. It includes high efficient 9 Buck converters, 28 LDOs. Especially, S5M8767A is optimized for Multi-core SOCs. And during DVFS operation, S5M8767A output stable voltage. This patch implement regulator driver for S5M8767A. Signed-off-by: Sangbeom Kim Signed-off-by: Mark Brown --- drivers/regulator/s5m8767.c | 834 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 834 insertions(+) create mode 100644 drivers/regulator/s5m8767.c (limited to 'drivers') diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c new file mode 100644 index 00000000000..b3d356f5e27 --- /dev/null +++ b/drivers/regulator/s5m8767.c @@ -0,0 +1,834 @@ +/* + * s5m8767.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd + * http://www.samsung.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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct s5m8767_info { + struct device *dev; + struct s5m87xx_dev *iodev; + int num_regulators; + struct regulator_dev **rdev; + + int ramp_delay; + bool buck2_ramp; + bool buck3_ramp; + bool buck4_ramp; + + bool buck2_gpiodvs; + bool buck3_gpiodvs; + bool buck4_gpiodvs; + u8 buck2_vol[8]; + u8 buck3_vol[8]; + u8 buck4_vol[8]; + int buck_gpios[3]; + int buck_gpioindex; +}; + +struct s5m_voltage_desc { + int max; + int min; + int step; +}; + +static const struct s5m_voltage_desc buck_voltage_val1 = { + .max = 2225000, + .min = 650000, + .step = 6250, +}; + +static const struct s5m_voltage_desc buck_voltage_val2 = { + .max = 1600000, + .min = 600000, + .step = 6250, +}; + +static const struct s5m_voltage_desc buck_voltage_val3 = { + .max = 3000000, + .min = 750000, + .step = 12500, +}; + +static const struct s5m_voltage_desc ldo_voltage_val1 = { + .max = 3950000, + .min = 800000, + .step = 50000, +}; + +static const struct s5m_voltage_desc ldo_voltage_val2 = { + .max = 2375000, + .min = 800000, + .step = 25000, +}; + +static const struct s5m_voltage_desc *reg_voltage_map[] = { + [S5M8767_LDO1] = &ldo_voltage_val2, + [S5M8767_LDO2] = &ldo_voltage_val2, + [S5M8767_LDO3] = &ldo_voltage_val1, + [S5M8767_LDO4] = &ldo_voltage_val1, + [S5M8767_LDO5] = &ldo_voltage_val1, + [S5M8767_LDO6] = &ldo_voltage_val2, + [S5M8767_LDO7] = &ldo_voltage_val2, + [S5M8767_LDO8] = &ldo_voltage_val2, + [S5M8767_LDO9] = &ldo_voltage_val1, + [S5M8767_LDO10] = &ldo_voltage_val1, + [S5M8767_LDO11] = &ldo_voltage_val1, + [S5M8767_LDO12] = &ldo_voltage_val1, + [S5M8767_LDO13] = &ldo_voltage_val1, + [S5M8767_LDO14] = &ldo_voltage_val1, + [S5M8767_LDO15] = &ldo_voltage_val2, + [S5M8767_LDO16] = &ldo_voltage_val1, + [S5M8767_LDO17] = &ldo_voltage_val1, + [S5M8767_LDO18] = &ldo_voltage_val1, + [S5M8767_LDO19] = &ldo_voltage_val1, + [S5M8767_LDO20] = &ldo_voltage_val1, + [S5M8767_LDO21] = &ldo_voltage_val1, + [S5M8767_LDO22] = &ldo_voltage_val1, + [S5M8767_LDO23] = &ldo_voltage_val1, + [S5M8767_LDO24] = &ldo_voltage_val1, + [S5M8767_LDO25] = &ldo_voltage_val1, + [S5M8767_LDO26] = &ldo_voltage_val1, + [S5M8767_LDO27] = &ldo_voltage_val1, + [S5M8767_LDO28] = &ldo_voltage_val1, + [S5M8767_BUCK1] = &buck_voltage_val1, + [S5M8767_BUCK2] = &buck_voltage_val2, + [S5M8767_BUCK3] = &buck_voltage_val2, + [S5M8767_BUCK4] = &buck_voltage_val2, + [S5M8767_BUCK5] = &buck_voltage_val1, + [S5M8767_BUCK6] = &buck_voltage_val1, + [S5M8767_BUCK7] = NULL, + [S5M8767_BUCK8] = NULL, + [S5M8767_BUCK9] = &buck_voltage_val3, +}; + +static inline int s5m8767_get_reg_id(struct regulator_dev *rdev) +{ + return rdev_get_id(rdev); +} + +static int s5m8767_list_voltage(struct regulator_dev *rdev, + unsigned int selector) +{ + const struct s5m_voltage_desc *desc; + int reg_id = s5m8767_get_reg_id(rdev); + int val; + + if (reg_id >= ARRAY_SIZE(reg_voltage_map) || reg_id < 0) + return -EINVAL; + + desc = reg_voltage_map[reg_id]; + if (desc == NULL) + return -EINVAL; + + val = desc->min + desc->step * selector; + if (val > desc->max) + return -EINVAL; + + return val; +} + +static int s5m8767_get_register(struct regulator_dev *rdev, int *reg) +{ + int reg_id = s5m8767_get_reg_id(rdev); + + switch (reg_id) { + case S5M8767_LDO1 ... S5M8767_LDO2: + *reg = S5M8767_REG_LDO1CTRL + (reg_id - S5M8767_LDO1); + break; + case S5M8767_LDO3 ... S5M8767_LDO28: + *reg = S5M8767_REG_LDO3CTRL + (reg_id - S5M8767_LDO3); + break; + case S5M8767_BUCK1: + *reg = S5M8767_REG_BUCK1CTRL1; + break; + case S5M8767_BUCK2 ... S5M8767_BUCK4: + *reg = S5M8767_REG_BUCK2CTRL + (reg_id - S5M8767_BUCK2) * 9; + break; + case S5M8767_BUCK5: + *reg = S5M8767_REG_BUCK5CTRL1; + break; + case S5M8767_BUCK6 ... S5M8767_BUCK9: + *reg = S5M8767_REG_BUCK6CTRL1 + (reg_id - S5M8767_BUCK6) * 2; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int s5m8767_reg_is_enabled(struct regulator_dev *rdev) +{ + struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); + int ret, reg; + int mask = 0xc0, pattern = 0xc0; + u8 val; + + ret = s5m8767_get_register(rdev, ®); + if (ret == -EINVAL) + return 1; + else if (ret) + return ret; + + ret = s5m_reg_read(s5m8767->iodev, reg, &val); + if (ret) + return ret; + + return (val & mask) == pattern; +} + +static int s5m8767_reg_enable(struct regulator_dev *rdev) +{ + struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); + int ret, reg; + int mask = 0xc0, pattern = 0xc0; + + ret = s5m8767_get_register(rdev, ®); + if (ret) + return ret; + + return s5m_reg_update(s5m8767->iodev, reg, pattern, mask); +} + +static int s5m8767_reg_disable(struct regulator_dev *rdev) +{ + struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); + int ret, reg; + int mask = 0xc0, pattern = 0xc0; + + ret = s5m8767_get_register(rdev, ®); + if (ret) + return ret; + + return s5m_reg_update(s5m8767->iodev, reg, ~pattern, mask); +} + +static int s5m8767_get_voltage_register(struct regulator_dev *rdev, int *_reg) +{ + int reg_id = s5m8767_get_reg_id(rdev); + int reg; + + switch (reg_id) { + case S5M8767_LDO1 ... S5M8767_LDO2: + reg = S5M8767_REG_LDO1CTRL + (reg_id - S5M8767_LDO1); + break; + case S5M8767_LDO3 ... S5M8767_LDO28: + reg = S5M8767_REG_LDO3CTRL + (reg_id - S5M8767_LDO3); + break; + case S5M8767_BUCK1: + reg = S5M8767_REG_BUCK1CTRL2; + break; + case S5M8767_BUCK2: + reg = S5M8767_REG_BUCK2DVS1; + break; + case S5M8767_BUCK3: + reg = S5M8767_REG_BUCK3DVS1; + break; + case S5M8767_BUCK4: + reg = S5M8767_REG_BUCK4DVS1; + break; + case S5M8767_BUCK5: + reg = S5M8767_REG_BUCK5CTRL2; + break; + case S5M8767_BUCK6 ... S5M8767_BUCK9: + reg = S5M8767_REG_BUCK6CTRL2 + (reg_id - S5M8767_BUCK6) * 2; + break; + default: + return -EINVAL; + } + + *_reg = reg; + + return 0; +} + +static int s5m8767_get_voltage_sel(struct regulator_dev *rdev) +{ + struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); + int reg, mask = 0xff, ret; + int reg_id = s5m8767_get_reg_id(rdev); + u8 val; + + ret = s5m8767_get_voltage_register(rdev, ®); + if (ret) + return ret; + + switch (reg_id) { + case S5M8767_LDO1 ... S5M8767_LDO28: + mask = 0x3f; + break; + case S5M8767_BUCK2: + if (s5m8767->buck2_gpiodvs) + reg += s5m8767->buck_gpioindex; + break; + case S5M8767_BUCK3: + if (s5m8767->buck3_gpiodvs) + reg += s5m8767->buck_gpioindex; + break; + case S5M8767_BUCK4: + if (s5m8767->buck4_gpiodvs) + reg += s5m8767->buck_gpioindex; + break; + } + + ret = s5m_reg_read(s5m8767->iodev, reg, &val); + if (ret) + return ret; + + val &= mask; + + return val; +} + +static inline int s5m8767_convert_voltage( + const struct s5m_voltage_desc *desc, + int min_vol, int max_vol) +{ + int out_vol = 0; + + if (desc == NULL) + return -EINVAL; + + if (max_vol < desc->min || min_vol > desc->max) + return -EINVAL; + + out_vol = (min_vol - desc->min) / desc->step; + + if (desc->min + desc->step * out_vol > max_vol) + return -EINVAL; + + return out_vol; +} + +static int s5m8767_set_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, unsigned *selector) +{ + struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); + int min_vol = min_uV, max_vol = max_uV; + const struct s5m_voltage_desc *desc; + int reg_id = s5m8767_get_reg_id(rdev); + int reg, mask, ret; + int i; + u8 val; + + switch (reg_id) { + case S5M8767_LDO1 ... S5M8767_LDO28: + mask = 0x3f; + break; + case S5M8767_BUCK1 ... S5M8767_BUCK6: + mask = 0xff; + break; + case S5M8767_BUCK7 ... S5M8767_BUCK8: + return -EINVAL; + case S5M8767_BUCK9: + mask = 0xff; + break; + default: + return -EINVAL; + } + + desc = reg_voltage_map[reg_id]; + + i = s5m8767_convert_voltage(desc, min_vol, max_vol); + if (i < 0) + return i; + + ret = s5m8767_get_voltage_register(rdev, ®); + if (ret) + return ret; + + s5m_reg_read(s5m8767->iodev, reg, &val); + val = val & mask; + + ret = s5m_reg_write(s5m8767->iodev, reg, val); + *selector = i; + + return ret; +} + +static inline void s5m8767_set_high(struct s5m8767_info *s5m8767) +{ + int temp_index = s5m8767->buck_gpioindex; + + gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1); + gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1); + gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1); +} + +static inline void s5m8767_set_low(struct s5m8767_info *s5m8767) +{ + int temp_index = s5m8767->buck_gpioindex; + + gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1); + gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1); + gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1); +} + +static int s5m8767_set_voltage_buck(struct regulator_dev *rdev, + int min_uV, int max_uV, unsigned *selector) +{ + struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); + int reg_id = s5m8767_get_reg_id(rdev); + const struct s5m_voltage_desc *desc; + int new_val, old_val, i = 0; + int min_vol = min_uV, max_vol = max_uV; + + if (reg_id < S5M8767_BUCK1 || reg_id > S5M8767_BUCK6) + return -EINVAL; + + switch (reg_id) { + case S5M8767_BUCK1: + return s5m8767_set_voltage(rdev, min_uV, max_uV, selector); + case S5M8767_BUCK2 ... S5M8767_BUCK4: + break; + case S5M8767_BUCK5 ... S5M8767_BUCK6: + return s5m8767_set_voltage(rdev, min_uV, max_uV, selector); + case S5M8767_BUCK9: + return s5m8767_set_voltage(rdev, min_uV, max_uV, selector); + } + + desc = reg_voltage_map[reg_id]; + new_val = s5m8767_convert_voltage(desc, min_vol, max_vol); + if (new_val < 0) + return new_val; + + switch (reg_id) { + case S5M8767_BUCK2: + if (s5m8767->buck2_gpiodvs) { + while (s5m8767->buck2_vol[i] != new_val) + i++; + } else + return s5m8767_set_voltage(rdev, min_uV, + max_uV, selector); + break; + case S5M8767_BUCK3: + if (s5m8767->buck3_gpiodvs) { + while (s5m8767->buck3_vol[i] != new_val) + i++; + } else + return s5m8767_set_voltage(rdev, min_uV, + max_uV, selector); + break; + case S5M8767_BUCK4: + if (s5m8767->buck3_gpiodvs) { + while (s5m8767->buck4_vol[i] != new_val) + i++; + } else + return s5m8767_set_voltage(rdev, min_uV, + max_uV, selector); + break; + } + + old_val = s5m8767->buck_gpioindex; + s5m8767->buck_gpioindex = i; + + if (i > old_val) + s5m8767_set_high(s5m8767); + else + s5m8767_set_low(s5m8767); + + *selector = new_val; + return 0; +} + +static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev, + unsigned int old_sel, + unsigned int new_sel) +{ + struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); + const struct s5m_voltage_desc *desc; + int reg_id = s5m8767_get_reg_id(rdev); + int mask; + int new_val, old_val; + + switch (reg_id) { + case S5M8767_LDO1 ... S5M8767_LDO28: + mask = 0x3f; + break; + case S5M8767_BUCK1 ... S5M8767_BUCK6: + mask = 0xff; + break; + case S5M8767_BUCK7 ... S5M8767_BUCK8: + return -EINVAL; + case S5M8767_BUCK9: + mask = 0xff; + break; + default: + return -EINVAL; + } + desc = reg_voltage_map[reg_id]; + + new_val = s5m8767_convert_voltage(desc, new_sel, new_sel); + if (new_val < 0) + return new_val; + + old_val = s5m8767_convert_voltage(desc, old_sel, old_sel); + if (old_val < 0) + return old_val; + + if (old_sel < new_sel) + return DIV_ROUND_UP(desc->step * (new_val - old_val), + s5m8767->ramp_delay); + else + return 0; +} + +static struct regulator_ops s5m8767_ldo_ops = { + .list_voltage = s5m8767_list_voltage, + .is_enabled = s5m8767_reg_is_enabled, + .enable = s5m8767_reg_enable, + .disable = s5m8767_reg_disable, + .get_voltage_sel = s5m8767_get_voltage_sel, + .set_voltage = s5m8767_set_voltage, + .set_voltage_time_sel = s5m8767_set_voltage_time_sel, +}; + +static struct regulator_ops s5m8767_buck_ops = { + .list_voltage = s5m8767_list_voltage, + .is_enabled = s5m8767_reg_is_enabled, + .enable = s5m8767_reg_enable, + .disable = s5m8767_reg_disable, + .get_voltage_sel = s5m8767_get_voltage_sel, + .set_voltage = s5m8767_set_voltage_buck, + .set_voltage_time_sel = s5m8767_set_voltage_time_sel, +}; + +#define regulator_desc_ldo(num) { \ + .name = "LDO"#num, \ + .id = S5M8767_LDO##num, \ + .ops = &s5m8767_ldo_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ +} +#define regulator_desc_buck(num) { \ + .name = "BUCK"#num, \ + .id = S5M8767_BUCK##num, \ + .ops = &s5m8767_buck_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ +} + +static struct regulator_desc regulators[] = { + regulator_desc_ldo(1), + regulator_desc_ldo(2), + regulator_desc_ldo(3), + regulator_desc_ldo(4), + regulator_desc_ldo(5), + regulator_desc_ldo(6), + regulator_desc_ldo(7), + regulator_desc_ldo(8), + regulator_desc_ldo(9), + regulator_desc_ldo(10), + regulator_desc_ldo(11), + regulator_desc_ldo(12), + regulator_desc_ldo(13), + regulator_desc_ldo(14), + regulator_desc_ldo(15), + regulator_desc_ldo(16), + regulator_desc_ldo(17), + regulator_desc_ldo(18), + regulator_desc_ldo(19), + regulator_desc_ldo(20), + regulator_desc_ldo(21), + regulator_desc_ldo(22), + regulator_desc_ldo(23), + regulator_desc_ldo(24), + regulator_desc_ldo(25), + regulator_desc_ldo(26), + regulator_desc_ldo(27), + regulator_desc_ldo(28), + regulator_desc_buck(1), + regulator_desc_buck(2), + regulator_desc_buck(3), + regulator_desc_buck(4), + regulator_desc_buck(5), + regulator_desc_buck(6), + regulator_desc_buck(7), + regulator_desc_buck(8), + regulator_desc_buck(9), +}; + +static __devinit int s5m8767_pmic_probe(struct platform_device *pdev) +{ + struct s5m87xx_dev *iodev = dev_get_drvdata(pdev->dev.parent); + struct s5m_platform_data *pdata = dev_get_platdata(iodev->dev); + struct regulator_dev **rdev; + struct s5m8767_info *s5m8767; + struct i2c_client *i2c; + int i, ret, size, reg; + + if (!pdata) { + dev_err(pdev->dev.parent, "Platform data not supplied\n"); + return -ENODEV; + } + + s5m8767 = devm_kzalloc(&pdev->dev, sizeof(struct s5m8767_info), + GFP_KERNEL); + if (!s5m8767) + return -ENOMEM; + + size = sizeof(struct regulator_dev *) * (S5M8767_REG_MAX - 2); + s5m8767->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); + if (!s5m8767->rdev) + return -ENOMEM; + + rdev = s5m8767->rdev; + s5m8767->dev = &pdev->dev; + s5m8767->iodev = iodev; + s5m8767->num_regulators = S5M8767_REG_MAX - 2; + platform_set_drvdata(pdev, s5m8767); + i2c = s5m8767->iodev->i2c; + + s5m8767->buck_gpioindex = pdata->buck_default_idx; + s5m8767->buck2_gpiodvs = pdata->buck2_gpiodvs; + s5m8767->buck3_gpiodvs = pdata->buck3_gpiodvs; + s5m8767->buck4_gpiodvs = pdata->buck4_gpiodvs; + s5m8767->buck_gpios[0] = pdata->buck_gpios[0]; + s5m8767->buck_gpios[1] = pdata->buck_gpios[1]; + s5m8767->buck_gpios[2] = pdata->buck_gpios[2]; + s5m8767->ramp_delay = pdata->buck_ramp_delay; + s5m8767->buck2_ramp = pdata->buck2_ramp_enable; + s5m8767->buck3_ramp = pdata->buck3_ramp_enable; + s5m8767->buck4_ramp = pdata->buck4_ramp_enable; + + for (i = 0; i < 8; i++) { + if (s5m8767->buck2_gpiodvs) { + s5m8767->buck2_vol[i] = + s5m8767_convert_voltage( + &buck_voltage_val2, + pdata->buck2_voltage[i], + pdata->buck2_voltage[i] + + buck_voltage_val2.step); + } + + if (s5m8767->buck3_gpiodvs) { + s5m8767->buck3_vol[i] = + s5m8767_convert_voltage( + &buck_voltage_val2, + pdata->buck3_voltage[i], + pdata->buck3_voltage[i] + + buck_voltage_val2.step); + } + + if (s5m8767->buck4_gpiodvs) { + s5m8767->buck4_vol[i] = + s5m8767_convert_voltage( + &buck_voltage_val2, + pdata->buck4_voltage[i], + pdata->buck4_voltage[i] + + buck_voltage_val2.step); + } + } + + if (pdata->buck2_gpiodvs || pdata->buck3_gpiodvs || + pdata->buck4_gpiodvs) { + if (gpio_is_valid(pdata->buck_gpios[0]) && + gpio_is_valid(pdata->buck_gpios[1]) && + gpio_is_valid(pdata->buck_gpios[2])) { + ret = gpio_request(pdata->buck_gpios[0], + "S5M8767 SET1"); + if (ret == -EBUSY) + dev_warn(&pdev->dev, "Duplicated gpio request for SET1\n"); + + ret = gpio_request(pdata->buck_gpios[1], + "S5M8767 SET2"); + if (ret == -EBUSY) + dev_warn(&pdev->dev, "Duplicated gpio request for SET2\n"); + + ret = gpio_request(pdata->buck_gpios[2], + "S5M8767 SET3"); + if (ret == -EBUSY) + dev_warn(&pdev->dev, "Duplicated gpio request for SET3\n"); + /* SET1 GPIO */ + gpio_direction_output(pdata->buck_gpios[0], + (s5m8767->buck_gpioindex >> 2) & 0x1); + /* SET2 GPIO */ + gpio_direction_output(pdata->buck_gpios[1], + (s5m8767->buck_gpioindex >> 1) & 0x1); + /* SET3 GPIO */ + gpio_direction_output(pdata->buck_gpios[2], + (s5m8767->buck_gpioindex >> 0) & 0x1); + ret = 0; + } else { + dev_err(&pdev->dev, "GPIO NOT VALID\n"); + ret = -EINVAL; + return ret; + } + } + + if (pdata->buck2_gpiodvs) { + if (pdata->buck3_gpiodvs || pdata->buck4_gpiodvs) { + dev_err(&pdev->dev, "S5M8767 GPIO DVS NOT VALID\n"); + ret = -EINVAL; + return ret; + } + } + + if (pdata->buck3_gpiodvs) { + if (pdata->buck2_gpiodvs || pdata->buck4_gpiodvs) { + dev_err(&pdev->dev, "S5M8767 GPIO DVS NOT VALID\n"); + ret = -EINVAL; + return ret; + } + } + + if (pdata->buck4_gpiodvs) { + if (pdata->buck2_gpiodvs || pdata->buck3_gpiodvs) { + dev_err(&pdev->dev, "S5M8767 GPIO DVS NOT VALID\n"); + ret = -EINVAL; + return ret; + } + } + + s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK2CTRL, + (pdata->buck2_gpiodvs) ? (1 << 1) : (0 << 1), 1 << 1); + s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK3CTRL, + (pdata->buck3_gpiodvs) ? (1 << 1) : (0 << 1), 1 << 1); + s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK4CTRL, + (pdata->buck4_gpiodvs) ? (1 << 1) : (0 << 1), 1 << 1); + + /* Initialize GPIO DVS registers */ + for (i = 0; i < 8; i++) { + if (s5m8767->buck2_gpiodvs) { + s5m_reg_write(s5m8767->iodev, S5M8767_REG_BUCK2DVS1 + i, + s5m8767->buck2_vol[i]); + } + + if (s5m8767->buck3_gpiodvs) { + s5m_reg_write(s5m8767->iodev, S5M8767_REG_BUCK3DVS1 + i, + s5m8767->buck3_vol[i]); + } + + if (s5m8767->buck4_gpiodvs) { + s5m_reg_write(s5m8767->iodev, S5M8767_REG_BUCK4DVS1 + i, + s5m8767->buck4_vol[i]); + } + } + s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK2CTRL, 0x78, 0xff); + s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK3CTRL, 0x58, 0xff); + s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK4CTRL, 0x78, 0xff); + + if (s5m8767->buck2_ramp) + s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x08, 0x08); + + if (s5m8767->buck3_ramp) + s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x04, 0x04); + + if (s5m8767->buck4_ramp) + s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x02, 0x02); + + if (s5m8767->buck2_ramp || s5m8767->buck3_ramp + || s5m8767->buck4_ramp) { + switch (s5m8767->ramp_delay) { + case 15: + s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, + 0xc0, 0xf0); + case 25: + s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, + 0xd0, 0xf0); + case 50: + s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, + 0xe0, 0xf0); + case 100: + s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, + 0xf0, 0xf0); + default: + s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, + 0x90, 0xf0); + } + } + + for (i = 0; i < pdata->num_regulators; i++) { + const struct s5m_voltage_desc *desc; + int id = pdata->regulators[i].id; + + desc = reg_voltage_map[id]; + if (desc) + regulators[id].n_voltages = + (desc->max - desc->min) / desc->step + 1; + + rdev[i] = regulator_register(®ulators[id], s5m8767->dev, + pdata->regulators[i].initdata, s5m8767); + if (IS_ERR(rdev[i])) { + ret = PTR_ERR(rdev[i]); + dev_err(s5m8767->dev, "regulator init failed for %d\n", + id); + rdev[i] = NULL; + goto err; + } + } + + return 0; +err: + for (i = 0; i < s5m8767->num_regulators; i++) + if (rdev[i]) + regulator_unregister(rdev[i]); + + return ret; +} + +static int __devexit s5m8767_pmic_remove(struct platform_device *pdev) +{ + struct s5m8767_info *s5m8767 = platform_get_drvdata(pdev); + struct regulator_dev **rdev = s5m8767->rdev; + int i; + + for (i = 0; i < s5m8767->num_regulators; i++) + if (rdev[i]) + regulator_unregister(rdev[i]); + + return 0; +} + +static const struct platform_device_id s5m8767_pmic_id[] = { + { "s5m8767-pmic", 0}, + { }, +}; +MODULE_DEVICE_TABLE(platform, s5m8767_pmic_id); + +static struct platform_driver s5m8767_pmic_driver = { + .driver = { + .name = "s5m8767-pmic", + .owner = THIS_MODULE, + }, + .probe = s5m8767_pmic_probe, + .remove = __devexit_p(s5m8767_pmic_remove), + .id_table = s5m8767_pmic_id, +}; + +static int __init s5m8767_pmic_init(void) +{ + return platform_driver_register(&s5m8767_pmic_driver); +} +subsys_initcall(s5m8767_pmic_init); + +static void __exit s5m8767_pmic_exit(void) +{ + platform_driver_unregister(&s5m8767_pmic_driver); +} +module_exit(s5m8767_pmic_exit); + +/* Module information */ +MODULE_AUTHOR("Sangbeom Kim "); +MODULE_DESCRIPTION("SAMSUNG S5M8767 Regulator Driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:s5m8767-pmic"); -- cgit v1.2.3-70-g09d2 From 047ec220a49f96ab0f8bd0bc574368e2cae8f1f7 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 12 Jan 2012 14:57:09 +0800 Subject: regulator: s5m8767: Add missing breaks Signed-off-by: Axel Lin Acked-by: Sangbeom Kim Signed-off-by: Mark Brown --- drivers/regulator/s5m8767.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index b3d356f5e27..40610126ab2 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -742,15 +742,19 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev) case 15: s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0xc0, 0xf0); + break; case 25: s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0xd0, 0xf0); + break; case 50: s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0xe0, 0xf0); + break; case 100: s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0xf0, 0xf0); + break; default: s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x90, 0xf0); -- cgit v1.2.3-70-g09d2 From c835e1c00eda6f8f6c6bce49b2d89208f3a184dc Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 12 Jan 2012 14:58:25 +0800 Subject: regulator: s5m8767: Remove redundant MODULE_ALIAS The MODULE_DEVICE_TABLE will setup the modalias, thus adding a MODULE_ALIAS for an entry already in s5m8767_pmic_id is redundant. Signed-off-by: Axel Lin Acked-by: Sangbeom Kim Signed-off-by: Mark Brown --- drivers/regulator/s5m8767.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index 40610126ab2..caf0117b471 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -835,4 +835,3 @@ module_exit(s5m8767_pmic_exit); MODULE_AUTHOR("Sangbeom Kim "); MODULE_DESCRIPTION("SAMSUNG S5M8767 Regulator Driver"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:s5m8767-pmic"); -- cgit v1.2.3-70-g09d2 From 38e968380b27d6c0f4b68bdd6e3161f8a7effe38 Mon Sep 17 00:00:00 2001 From: Bengt Jonsson Date: Fri, 13 Jan 2012 16:30:31 +0100 Subject: regulators/db8500: split off shared dbx500 code As we progress with DB5500 and future voltage domain regulators based on very similar hardware as found in the DB8500 PRCMU, it makes sense to split off the generic parts and introduce some generic debug code for the DBx500 regulators. This patch accoplish a basic abstraction of the DBx500 voltage domain regulators. Signed-off-by: Bengt Jonsson Signed-off-by: Linus Walleij Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 4 + drivers/regulator/Makefile | 1 + drivers/regulator/db8500-prcmu.c | 118 ++++++------------- drivers/regulator/dbx500-prcmu.c | 241 +++++++++++++++++++++++++++++++++++++++ drivers/regulator/dbx500-prcmu.h | 63 ++++++++++ 5 files changed, 341 insertions(+), 86 deletions(-) create mode 100644 drivers/regulator/dbx500-prcmu.c create mode 100644 drivers/regulator/dbx500-prcmu.h (limited to 'drivers') diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index b9ad3d8e03c..c7e49b140be 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -299,9 +299,13 @@ config REGULATOR_AB8500 This driver supports the regulators found on the ST-Ericsson mixed signal AB8500 PMIC +config REGULATOR_DBX500_PRCMU + bool + config REGULATOR_DB8500_PRCMU bool "ST-Ericsson DB8500 Voltage Domain Regulators" depends on MFD_DB8500_PRCMU + select REGULATOR_DBX500_PRCMU help This driver supports the voltage domain regulators controlled by the DB8500 PRCMU diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 1668b2e667c..bf595135248 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -45,6 +45,7 @@ obj-$(CONFIG_REGULATOR_TPS65912) += tps65912-regulator.o obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o +obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o diff --git a/drivers/regulator/db8500-prcmu.c b/drivers/regulator/db8500-prcmu.c index 515443fcd26..4bd25e75efa 100644 --- a/drivers/regulator/db8500-prcmu.c +++ b/drivers/regulator/db8500-prcmu.c @@ -18,74 +18,11 @@ #include #include #include - -/* - * power state reference count - */ -static int power_state_active_cnt; /* will initialize to zero */ -static DEFINE_SPINLOCK(power_state_active_lock); - -static void power_state_active_enable(void) -{ - unsigned long flags; - - spin_lock_irqsave(&power_state_active_lock, flags); - power_state_active_cnt++; - spin_unlock_irqrestore(&power_state_active_lock, flags); -} - -static int power_state_active_disable(void) -{ - int ret = 0; - unsigned long flags; - - spin_lock_irqsave(&power_state_active_lock, flags); - if (power_state_active_cnt <= 0) { - pr_err("power state: unbalanced enable/disable calls\n"); - ret = -EINVAL; - goto out; - } - - power_state_active_cnt--; -out: - spin_unlock_irqrestore(&power_state_active_lock, flags); - return ret; -} - -/* - * Exported interface for CPUIdle only. This function is called when interrupts - * are turned off. Hence, no locking. - */ -int power_state_active_is_enabled(void) -{ - return (power_state_active_cnt > 0); -} - -/** - * struct db8500_regulator_info - db8500 regulator information - * @dev: device pointer - * @desc: regulator description - * @rdev: regulator device pointer - * @is_enabled: status of the regulator - * @epod_id: id for EPOD (power domain) - * @is_ramret: RAM retention switch for EPOD (power domain) - * @operating_point: operating point (only for vape, to be removed) - * - */ -struct db8500_regulator_info { - struct device *dev; - struct regulator_desc desc; - struct regulator_dev *rdev; - bool is_enabled; - u16 epod_id; - bool is_ramret; - bool exclude_from_power_state; - unsigned int operating_point; -}; +#include "dbx500-prcmu.h" static int db8500_regulator_enable(struct regulator_dev *rdev) { - struct db8500_regulator_info *info = rdev_get_drvdata(rdev); + struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); if (info == NULL) return -EINVAL; @@ -93,16 +30,18 @@ static int db8500_regulator_enable(struct regulator_dev *rdev) dev_vdbg(rdev_get_dev(rdev), "regulator-%s-enable\n", info->desc.name); - info->is_enabled = true; - if (!info->exclude_from_power_state) - power_state_active_enable(); + if (!info->is_enabled) { + info->is_enabled = true; + if (!info->exclude_from_power_state) + power_state_active_enable(); + } return 0; } static int db8500_regulator_disable(struct regulator_dev *rdev) { - struct db8500_regulator_info *info = rdev_get_drvdata(rdev); + struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); int ret = 0; if (info == NULL) @@ -111,16 +50,18 @@ static int db8500_regulator_disable(struct regulator_dev *rdev) dev_vdbg(rdev_get_dev(rdev), "regulator-%s-disable\n", info->desc.name); - info->is_enabled = false; - if (!info->exclude_from_power_state) - ret = power_state_active_disable(); + if (info->is_enabled) { + info->is_enabled = false; + if (!info->exclude_from_power_state) + ret = power_state_active_disable(); + } return ret; } static int db8500_regulator_is_enabled(struct regulator_dev *rdev) { - struct db8500_regulator_info *info = rdev_get_drvdata(rdev); + struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); if (info == NULL) return -EINVAL; @@ -197,7 +138,7 @@ static int disable_epod(u16 epod_id, bool ramret) */ static int db8500_regulator_switch_enable(struct regulator_dev *rdev) { - struct db8500_regulator_info *info = rdev_get_drvdata(rdev); + struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); int ret; if (info == NULL) @@ -221,7 +162,7 @@ out: static int db8500_regulator_switch_disable(struct regulator_dev *rdev) { - struct db8500_regulator_info *info = rdev_get_drvdata(rdev); + struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); int ret; if (info == NULL) @@ -245,7 +186,7 @@ out: static int db8500_regulator_switch_is_enabled(struct regulator_dev *rdev) { - struct db8500_regulator_info *info = rdev_get_drvdata(rdev); + struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); if (info == NULL) return -EINVAL; @@ -266,8 +207,8 @@ static struct regulator_ops db8500_regulator_switch_ops = { /* * Regulator information */ -static struct db8500_regulator_info -db8500_regulator_info[DB8500_NUM_REGULATORS] = { +static struct dbx500_regulator_info +dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_VAPE] = { .desc = { .name = "db8500-vape", @@ -476,12 +417,12 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev) int i, err; /* register all regulators */ - for (i = 0; i < ARRAY_SIZE(db8500_regulator_info); i++) { - struct db8500_regulator_info *info; + for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) { + struct dbx500_regulator_info *info; struct regulator_init_data *init_data = &db8500_init_data[i]; /* assign per-regulator data */ - info = &db8500_regulator_info[i]; + info = &dbx500_regulator_info[i]; info->dev = &pdev->dev; /* register with the regulator framework */ @@ -494,7 +435,7 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev) /* if failing, unregister all earlier regulators */ while (--i >= 0) { - info = &db8500_regulator_info[i]; + info = &dbx500_regulator_info[i]; regulator_unregister(info->rdev); } return err; @@ -503,17 +444,22 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev) dev_dbg(rdev_get_dev(info->rdev), "regulator-%s-probed\n", info->desc.name); } + err = ux500_regulator_debug_init(pdev, + dbx500_regulator_info, + ARRAY_SIZE(dbx500_regulator_info)); - return 0; + return err; } static int __exit db8500_regulator_remove(struct platform_device *pdev) { int i; - for (i = 0; i < ARRAY_SIZE(db8500_regulator_info); i++) { - struct db8500_regulator_info *info; - info = &db8500_regulator_info[i]; + ux500_regulator_debug_exit(); + + for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) { + struct dbx500_regulator_info *info; + info = &dbx500_regulator_info[i]; dev_vdbg(rdev_get_dev(info->rdev), "regulator-%s-remove\n", info->desc.name); diff --git a/drivers/regulator/dbx500-prcmu.c b/drivers/regulator/dbx500-prcmu.c new file mode 100644 index 00000000000..f2e5ecdc586 --- /dev/null +++ b/drivers/regulator/dbx500-prcmu.c @@ -0,0 +1,241 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License Terms: GNU General Public License v2 + * Authors: Sundar Iyer for ST-Ericsson + * Bengt Jonsson for ST-Ericsson + * + * UX500 common part of Power domain regulators + */ + +#include +#include +#include +#include +#include +#include + +#include "dbx500-prcmu.h" + +/* + * power state reference count + */ +static int power_state_active_cnt; /* will initialize to zero */ +static DEFINE_SPINLOCK(power_state_active_lock); + +int power_state_active_get(void) +{ + unsigned long flags; + int cnt; + + spin_lock_irqsave(&power_state_active_lock, flags); + cnt = power_state_active_cnt; + spin_unlock_irqrestore(&power_state_active_lock, flags); + + return cnt; +} + +void power_state_active_enable(void) +{ + unsigned long flags; + + spin_lock_irqsave(&power_state_active_lock, flags); + power_state_active_cnt++; + spin_unlock_irqrestore(&power_state_active_lock, flags); +} + +int power_state_active_disable(void) +{ + int ret = 0; + unsigned long flags; + + spin_lock_irqsave(&power_state_active_lock, flags); + if (power_state_active_cnt <= 0) { + pr_err("power state: unbalanced enable/disable calls\n"); + ret = -EINVAL; + goto out; + } + + power_state_active_cnt--; +out: + spin_unlock_irqrestore(&power_state_active_lock, flags); + return ret; +} + +#ifdef CONFIG_REGULATOR_DEBUG + +static struct ux500_regulator_debug { + struct dentry *dir; + struct dentry *status_file; + struct dentry *power_state_cnt_file; + struct dbx500_regulator_info *regulator_array; + int num_regulators; + u8 *state_before_suspend; + u8 *state_after_suspend; +} rdebug; + +void ux500_regulator_suspend_debug(void) +{ + int i; + for (i = 0; i < rdebug.num_regulators; i++) + rdebug.state_before_suspend[i] = + rdebug.regulator_array[i].is_enabled; +} + +void ux500_regulator_resume_debug(void) +{ + int i; + for (i = 0; i < rdebug.num_regulators; i++) + rdebug.state_after_suspend[i] = + rdebug.regulator_array[i].is_enabled; +} + +static int ux500_regulator_power_state_cnt_print(struct seq_file *s, void *p) +{ + struct device *dev = s->private; + int err; + + /* print power state count */ + err = seq_printf(s, "ux500-regulator power state count: %i\n", + power_state_active_get()); + if (err < 0) + dev_err(dev, "seq_printf overflow\n"); + + return 0; +} + +static int ux500_regulator_power_state_cnt_open(struct inode *inode, + struct file *file) +{ + return single_open(file, ux500_regulator_power_state_cnt_print, + inode->i_private); +} + +static const struct file_operations ux500_regulator_power_state_cnt_fops = { + .open = ux500_regulator_power_state_cnt_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static int ux500_regulator_status_print(struct seq_file *s, void *p) +{ + struct device *dev = s->private; + int err; + int i; + + /* print dump header */ + err = seq_printf(s, "ux500-regulator status:\n"); + if (err < 0) + dev_err(dev, "seq_printf overflow\n"); + + err = seq_printf(s, "%31s : %8s : %8s\n", "current", + "before", "after"); + if (err < 0) + dev_err(dev, "seq_printf overflow\n"); + + for (i = 0; i < rdebug.num_regulators; i++) { + struct dbx500_regulator_info *info; + /* Access per-regulator data */ + info = &rdebug.regulator_array[i]; + + /* print status */ + err = seq_printf(s, "%20s : %8s : %8s : %8s\n", info->desc.name, + info->is_enabled ? "enabled" : "disabled", + rdebug.state_before_suspend[i] ? "enabled" : "disabled", + rdebug.state_after_suspend[i] ? "enabled" : "disabled"); + if (err < 0) + dev_err(dev, "seq_printf overflow\n"); + } + + return 0; +} + +static int ux500_regulator_status_open(struct inode *inode, struct file *file) +{ + return single_open(file, ux500_regulator_status_print, + inode->i_private); +} + +static const struct file_operations ux500_regulator_status_fops = { + .open = ux500_regulator_status_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +int __attribute__((weak)) dbx500_regulator_testcase( + struct dbx500_regulator_info *regulator_info, + int num_regulators) +{ + return 0; +} + +int __devinit +ux500_regulator_debug_init(struct platform_device *pdev, + struct dbx500_regulator_info *regulator_info, + int num_regulators) +{ + /* create directory */ + rdebug.dir = debugfs_create_dir("ux500-regulator", NULL); + if (!rdebug.dir) + goto exit_no_debugfs; + + /* create "status" file */ + rdebug.status_file = debugfs_create_file("status", + S_IRUGO, rdebug.dir, &pdev->dev, + &ux500_regulator_status_fops); + if (!rdebug.status_file) + goto exit_destroy_dir; + + /* create "power-state-count" file */ + rdebug.power_state_cnt_file = debugfs_create_file("power-state-count", + S_IRUGO, rdebug.dir, &pdev->dev, + &ux500_regulator_power_state_cnt_fops); + if (!rdebug.power_state_cnt_file) + goto exit_destroy_status; + + rdebug.regulator_array = regulator_info; + rdebug.num_regulators = num_regulators; + + rdebug.state_before_suspend = kzalloc(num_regulators, GFP_KERNEL); + if (!rdebug.state_before_suspend) { + dev_err(&pdev->dev, + "could not allocate memory for saving state\n"); + goto exit_destroy_power_state; + } + + rdebug.state_after_suspend = kzalloc(num_regulators, GFP_KERNEL); + if (!rdebug.state_after_suspend) { + dev_err(&pdev->dev, + "could not allocate memory for saving state\n"); + goto exit_free; + } + + dbx500_regulator_testcase(regulator_info, num_regulators); + return 0; + +exit_free: + kfree(rdebug.state_before_suspend); +exit_destroy_power_state: + debugfs_remove(rdebug.power_state_cnt_file); +exit_destroy_status: + debugfs_remove(rdebug.status_file); +exit_destroy_dir: + debugfs_remove(rdebug.dir); +exit_no_debugfs: + dev_err(&pdev->dev, "failed to create debugfs entries.\n"); + return -ENOMEM; +} + +int __devexit ux500_regulator_debug_exit(void) +{ + debugfs_remove_recursive(rdebug.dir); + kfree(rdebug.state_after_suspend); + kfree(rdebug.state_before_suspend); + + return 0; +} +#endif diff --git a/drivers/regulator/dbx500-prcmu.h b/drivers/regulator/dbx500-prcmu.h new file mode 100644 index 00000000000..e763883a44f --- /dev/null +++ b/drivers/regulator/dbx500-prcmu.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Bengt Jonsson for ST-Ericsson, + * Jonas Aaberg for ST-Ericsson + * + * License Terms: GNU General Public License v2 + * + */ + +#ifndef DBX500_REGULATOR_H +#define DBX500_REGULATOR_H + +#include + +/** + * struct dbx500_regulator_info - dbx500 regulator information + * @dev: device pointer + * @desc: regulator description + * @rdev: regulator device pointer + * @is_enabled: status of the regulator + * @epod_id: id for EPOD (power domain) + * @is_ramret: RAM retention switch for EPOD (power domain) + * @operating_point: operating point (only for vape, to be removed) + * + */ +struct dbx500_regulator_info { + struct device *dev; + struct regulator_desc desc; + struct regulator_dev *rdev; + bool is_enabled; + u16 epod_id; + bool is_ramret; + bool exclude_from_power_state; + unsigned int operating_point; +}; + +void power_state_active_enable(void); +int power_state_active_disable(void); + + +#ifdef CONFIG_REGULATOR_DEBUG +int ux500_regulator_debug_init(struct platform_device *pdev, + struct dbx500_regulator_info *regulator_info, + int num_regulators); + +int ux500_regulator_debug_exit(void); +#else + +static inline int ux500_regulator_debug_init(struct platform_device *pdev, + struct dbx500_regulator_info *regulator_info, + int num_regulators) +{ + return 0; +} + +static inline int ux500_regulator_debug_exit(void) +{ + return 0; +} + +#endif +#endif -- cgit v1.2.3-70-g09d2 From 62aa492582cd6ce9f5e797ac3197239e63de1df9 Mon Sep 17 00:00:00 2001 From: Sangbeom Kim Date: Fri, 13 Jan 2012 10:13:13 +0900 Subject: regulator: Add S5M8767 configuration This patch add Samsung S5M8767A pmic configuration. Signed-off-by: Sangbeom Kim Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 8 ++++++++ drivers/regulator/Makefile | 2 ++ 2 files changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index c7e49b140be..4792d661f0b 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -136,6 +136,14 @@ config REGULATOR_MAX8998 via I2C bus. The provided regulator is suitable for S3C6410 and S5PC1XX chips to control VCC_CORE and VCC_USIM voltages. +config REGULATOR_S5M8767 + tristate "Samsung S5M8767A voltage regulator" + depends on MFD_S5M_CORE + help + This driver supports a Samsung S5M8767A voltage output regulator + via I2C bus. S5M8767A have 9 Bucks and 28 LDOs output and + supports DVS mode with 8bits of output voltage control. + config REGULATOR_TWL4030 bool "TI TWL4030/TWL5030/TWL6030/TPS659x0 PMIC" depends on TWL4030_CORE diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index bf595135248..66be54a3e68 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -50,5 +50,7 @@ obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o +obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o + ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG -- cgit v1.2.3-70-g09d2 From a493077f1883a627d6ba2659b0a82888e58d31dd Mon Sep 17 00:00:00 2001 From: AnilKumar Ch Date: Wed, 11 Jan 2012 16:11:49 +0530 Subject: regulator: tps65217: Add tps65217 regulator driver This patch adds tps65217 PMIC as a regulator The regulator module consists of 3 DCDCs and 4 LDOs. The output voltages are configurable and are meant to supply power to the main processor and other components Signed-off-by: AnilKumar Ch Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 9 + drivers/regulator/Makefile | 1 + drivers/regulator/tps65217-regulator.c | 493 +++++++++++++++++++++++++++++++++ 3 files changed, 503 insertions(+) create mode 100644 drivers/regulator/tps65217-regulator.c (limited to 'drivers') diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 4792d661f0b..376824b865a 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -275,6 +275,15 @@ config REGULATOR_TPS6507X three step-down converters and two general-purpose LDO voltage regulators. It supports TI's software based Class-2 SmartReflex implementation. +config REGULATOR_TPS65217 + tristate "TI TPS65217 Power regulators" + depends on MFD_TPS65217 + help + This driver supports TPS65217 voltage regulator chips. TPS65217 + provides three step-down converters and four general-purpose LDO + voltage regulators. It supports software based voltage control + for different voltage domains + config REGULATOR_TPS65912 tristate "TI TPS65912 Power regulator" depends on (MFD_TPS65912_I2C || MFD_TPS65912_SPI) diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 66be54a3e68..4cbf8c55f8a 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o +obj-$(CONFIG_REGULATOR_TPS65217) += tps65217-regulator.o obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o obj-$(CONFIG_REGULATOR_TPS65912) += tps65912-regulator.o obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c new file mode 100644 index 00000000000..66655668f96 --- /dev/null +++ b/drivers/regulator/tps65217-regulator.c @@ -0,0 +1,493 @@ +/* + * tps65217-regulator.c + * + * Regulator driver for TPS65217 PMIC + * + * Copyright (C) 2011 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 version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define TPS65217_REGULATOR(_name, _id, _ops, _n) \ + { \ + .name = _name, \ + .id = _id, \ + .ops = &_ops, \ + .n_voltages = _n, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + } \ + +#define TPS65217_INFO(_nm, _min, _max, _f1, _f2, _t, _n, _em, _vr, _vm) \ + { \ + .name = _nm, \ + .min_uV = _min, \ + .max_uV = _max, \ + .vsel_to_uv = _f1, \ + .uv_to_vsel = _f2, \ + .table = _t, \ + .table_len = _n, \ + .enable_mask = _em, \ + .set_vout_reg = _vr, \ + .set_vout_mask = _vm, \ + } + +static const int LDO1_VSEL_table[] = { + 1000000, 1100000, 1200000, 1250000, + 1300000, 1350000, 1400000, 1500000, + 1600000, 1800000, 2500000, 2750000, + 2800000, 3000000, 3100000, 3300000, +}; + +static int tps65217_vsel_to_uv1(unsigned int vsel) +{ + int uV = 0; + + if (vsel > 63) + return -EINVAL; + + if (vsel <= 24) + uV = vsel * 25000 + 900000; + else if (vsel <= 52) + uV = (vsel - 24) * 50000 + 1500000; + else if (vsel < 56) + uV = (vsel - 52) * 100000 + 2900000; + else + uV = 3300000; + + return uV; +} + +static int tps65217_uv_to_vsel1(int uV, unsigned int *vsel) +{ + if ((uV < 0) && (uV > 3300000)) + return -EINVAL; + + if (uV <= 1500000) + *vsel = (uV - 875001) / 25000; + else if (uV <= 2900000) + *vsel = 24 + (uV - 1450001) / 50000; + else if (uV < 3300000) + *vsel = 52 + (uV - 2800001) / 100000; + else + *vsel = 56; + + return 0; +} + +static int tps65217_vsel_to_uv2(unsigned int vsel) +{ + int uV = 0; + + if (vsel > 31) + return -EINVAL; + + if (vsel <= 8) + uV = vsel * 50000 + 1500000; + else if (vsel <= 13) + uV = (vsel - 8) * 100000 + 1900000; + else + uV = (vsel - 13) * 50000 + 2400000; + + return uV; +} + +static int tps65217_uv_to_vsel2(int uV, unsigned int *vsel) +{ + if ((uV < 0) && (uV > 3300000)) + return -EINVAL; + + if (uV <= 1900000) + *vsel = (uV - 1450001) / 50000; + else if (uV <= 2400000) + *vsel = 8 + (uV - 1800001) / 100000; + else + *vsel = 13 + (uV - 2350001) / 50000; + + return 0; +} + +static struct tps_info tps65217_pmic_regs[] = { + TPS65217_INFO("DCDC1", 900000, 1800000, tps65217_vsel_to_uv1, + tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_DC1_EN, + TPS65217_REG_DEFDCDC1, TPS65217_DEFDCDCX_DCDC_MASK), + TPS65217_INFO("DCDC2", 900000, 3300000, tps65217_vsel_to_uv1, + tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_DC2_EN, + TPS65217_REG_DEFDCDC2, TPS65217_DEFDCDCX_DCDC_MASK), + TPS65217_INFO("DCDC3", 900000, 1500000, tps65217_vsel_to_uv1, + tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_DC3_EN, + TPS65217_REG_DEFDCDC3, TPS65217_DEFDCDCX_DCDC_MASK), + TPS65217_INFO("LDO1", 1000000, 3300000, NULL, NULL, LDO1_VSEL_table, + 16, TPS65217_ENABLE_LDO1_EN, TPS65217_REG_DEFLDO1, + TPS65217_DEFLDO1_LDO1_MASK), + TPS65217_INFO("LDO2", 900000, 3300000, tps65217_vsel_to_uv1, + tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_LDO2_EN, + TPS65217_REG_DEFLDO2, TPS65217_DEFLDO2_LDO2_MASK), + TPS65217_INFO("LDO3", 1800000, 3300000, tps65217_vsel_to_uv2, + tps65217_uv_to_vsel2, NULL, 32, + TPS65217_ENABLE_LS1_EN | TPS65217_DEFLDO3_LDO3_EN, + TPS65217_REG_DEFLS1, TPS65217_DEFLDO3_LDO3_MASK), + TPS65217_INFO("LDO4", 1800000, 3300000, tps65217_vsel_to_uv2, + tps65217_uv_to_vsel2, NULL, 32, + TPS65217_ENABLE_LS2_EN | TPS65217_DEFLDO4_LDO4_EN, + TPS65217_REG_DEFLS2, TPS65217_DEFLDO4_LDO4_MASK), +}; + +static int tps65217_pmic_dcdc_is_enabled(struct regulator_dev *dev) +{ + int ret; + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int data, dcdc = rdev_get_id(dev); + + if (dcdc < TPS65217_DCDC_1 || dcdc > TPS65217_DCDC_3) + return -EINVAL; + + ret = tps65217_reg_read(tps, TPS65217_REG_ENABLE, &data); + if (ret) + return ret; + + return (data & tps->info[dcdc]->enable_mask) ? 1 : 0; +} + +static int tps65217_pmic_ldo_is_enabled(struct regulator_dev *dev) +{ + int ret; + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int data, ldo = rdev_get_id(dev); + + if (ldo < TPS65217_LDO_1 || ldo > TPS65217_LDO_4) + return -EINVAL; + + ret = tps65217_reg_read(tps, TPS65217_REG_ENABLE, &data); + if (ret) + return ret; + + return (data & tps->info[ldo]->enable_mask) ? 1 : 0; +} + +static int tps65217_pmic_dcdc_enable(struct regulator_dev *dev) +{ + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int dcdc = rdev_get_id(dev); + + if (dcdc < TPS65217_DCDC_1 || dcdc > TPS65217_DCDC_3) + return -EINVAL; + + /* Enable the regulator and password protection is level 1 */ + return tps65217_set_bits(tps, TPS65217_REG_ENABLE, + tps->info[dcdc]->enable_mask, + tps->info[dcdc]->enable_mask, + TPS65217_PROTECT_L1); +} + +static int tps65217_pmic_dcdc_disable(struct regulator_dev *dev) +{ + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int dcdc = rdev_get_id(dev); + + if (dcdc < TPS65217_DCDC_1 || dcdc > TPS65217_DCDC_3) + return -EINVAL; + + /* Disable the regulator and password protection is level 1 */ + return tps65217_clear_bits(tps, TPS65217_REG_ENABLE, + tps->info[dcdc]->enable_mask, TPS65217_PROTECT_L1); +} + +static int tps65217_pmic_ldo_enable(struct regulator_dev *dev) +{ + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int ldo = rdev_get_id(dev); + + if (ldo < TPS65217_LDO_1 || ldo > TPS65217_LDO_4) + return -EINVAL; + + /* Enable the regulator and password protection is level 1 */ + return tps65217_set_bits(tps, TPS65217_REG_ENABLE, + tps->info[ldo]->enable_mask, + tps->info[ldo]->enable_mask, + TPS65217_PROTECT_L1); +} + +static int tps65217_pmic_ldo_disable(struct regulator_dev *dev) +{ + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int ldo = rdev_get_id(dev); + + if (ldo < TPS65217_LDO_1 || ldo > TPS65217_LDO_4) + return -EINVAL; + + /* Disable the regulator and password protection is level 1 */ + return tps65217_clear_bits(tps, TPS65217_REG_ENABLE, + tps->info[ldo]->enable_mask, TPS65217_PROTECT_L1); +} + +static int tps65217_pmic_dcdc_get_voltage_sel(struct regulator_dev *dev) +{ + int ret; + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int selector, dcdc = rdev_get_id(dev); + + if (dcdc < TPS65217_DCDC_1 || dcdc > TPS65217_DCDC_3) + return -EINVAL; + + ret = tps65217_reg_read(tps, tps->info[dcdc]->set_vout_reg, &selector); + if (ret) + return ret; + + selector &= tps->info[dcdc]->set_vout_mask; + + return selector; +} + +static int tps65217_pmic_dcdc_set_voltage(struct regulator_dev *dev, + int min_uV, int max_uV, unsigned *selector) +{ + int ret; + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int dcdc = rdev_get_id(dev); + + if (dcdc < TPS65217_DCDC_1 || dcdc > TPS65217_DCDC_3) + return -EINVAL; + + if (min_uV < tps->info[dcdc]->min_uV + || min_uV > tps->info[dcdc]->max_uV) + return -EINVAL; + + if (max_uV < tps->info[dcdc]->min_uV + || max_uV > tps->info[dcdc]->max_uV) + return -EINVAL; + + ret = tps->info[dcdc]->uv_to_vsel(min_uV, selector); + if (ret) + return ret; + + /* Set the voltage based on vsel value and write protect level is 2 */ + ret = tps65217_set_bits(tps, tps->info[dcdc]->set_vout_reg, + tps->info[dcdc]->set_vout_mask, + *selector, TPS65217_PROTECT_L2); + if (ret) + return ret; + + /* Set GO bit to initiate voltage transistion */ + return tps65217_set_bits(tps, TPS65217_REG_DEFSLEW, + TPS65217_DEFSLEW_GO, TPS65217_DEFSLEW_GO, + TPS65217_PROTECT_L2); +} + +static int tps65217_pmic_ldo_get_voltage_sel(struct regulator_dev *dev) +{ + int ret; + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int selector, ldo = rdev_get_id(dev); + + if (ldo < TPS65217_LDO_1 || ldo > TPS65217_LDO_4) + return -EINVAL; + + ret = tps65217_reg_read(tps, tps->info[ldo]->set_vout_reg, &selector); + if (ret) + return ret; + + selector &= tps->info[ldo]->set_vout_mask; + + return selector; +} + +static int tps65217_pmic_ldo_set_voltage_sel(struct regulator_dev *dev, + unsigned selector) +{ + struct tps65217 *tps = rdev_get_drvdata(dev); + int ldo = rdev_get_id(dev); + + if (ldo != TPS65217_LDO_1) + return -EINVAL; + + if (selector >= tps->info[ldo]->table_len) + return -EINVAL; + + /* Set the voltage based on vsel value and write protect level is 2 */ + return tps65217_set_bits(tps, tps->info[ldo]->set_vout_reg, + tps->info[ldo]->set_vout_mask, + selector, TPS65217_PROTECT_L2); +} + +static int tps65217_pmic_ldo_set_voltage(struct regulator_dev *dev, + int min_uV, int max_uV, unsigned *selector) +{ + int ret; + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int ldo = rdev_get_id(dev); + + if (ldo < TPS65217_LDO_2 || ldo > TPS65217_LDO_4) + return -EINVAL; + + if (min_uV < tps->info[ldo]->min_uV + || min_uV > tps->info[ldo]->max_uV) + return -EINVAL; + + if (max_uV < tps->info[ldo]->min_uV + || max_uV > tps->info[ldo]->max_uV) + return -EINVAL; + + ret = tps->info[ldo]->uv_to_vsel(min_uV, selector); + if (ret) + return ret; + + /* Set the voltage based on vsel value and write protect level is 2 */ + return tps65217_set_bits(tps, tps->info[ldo]->set_vout_reg, + tps->info[ldo]->set_vout_mask, + *selector, TPS65217_PROTECT_L2); +} + +static int tps65217_pmic_dcdc_list_voltage(struct regulator_dev *dev, + unsigned selector) +{ + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int dcdc = rdev_get_id(dev); + + if (dcdc < TPS65217_DCDC_1 || dcdc > TPS65217_DCDC_3) + return -EINVAL; + + if (selector >= tps->info[dcdc]->table_len) + return -EINVAL; + + return tps->info[dcdc]->vsel_to_uv(selector); +} + +static int tps65217_pmic_ldo_list_voltage(struct regulator_dev *dev, + unsigned selector) +{ + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int ldo = rdev_get_id(dev); + + if (ldo < TPS65217_LDO_1 || ldo > TPS65217_LDO_4) + return -EINVAL; + + if (selector >= tps->info[ldo]->table_len) + return -EINVAL; + + if (tps->info[ldo]->table) + return tps->info[ldo]->table[selector]; + + return tps->info[ldo]->vsel_to_uv(selector); +} + +/* Operations permitted on DCDCx */ +static struct regulator_ops tps65217_pmic_dcdc_ops = { + .is_enabled = tps65217_pmic_dcdc_is_enabled, + .enable = tps65217_pmic_dcdc_enable, + .disable = tps65217_pmic_dcdc_disable, + .get_voltage_sel = tps65217_pmic_dcdc_get_voltage_sel, + .set_voltage = tps65217_pmic_dcdc_set_voltage, + .list_voltage = tps65217_pmic_dcdc_list_voltage, +}; + +/* Operations permitted on LDO1 */ +static struct regulator_ops tps65217_pmic_ldo1_ops = { + .is_enabled = tps65217_pmic_ldo_is_enabled, + .enable = tps65217_pmic_ldo_enable, + .disable = tps65217_pmic_ldo_disable, + .get_voltage_sel = tps65217_pmic_ldo_get_voltage_sel, + .set_voltage_sel = tps65217_pmic_ldo_set_voltage_sel, + .list_voltage = tps65217_pmic_ldo_list_voltage, +}; + +/* Operations permitted on LDO2, LDO3 and LDO4 */ +static struct regulator_ops tps65217_pmic_ldo234_ops = { + .is_enabled = tps65217_pmic_ldo_is_enabled, + .enable = tps65217_pmic_ldo_enable, + .disable = tps65217_pmic_ldo_disable, + .get_voltage_sel = tps65217_pmic_ldo_get_voltage_sel, + .set_voltage = tps65217_pmic_ldo_set_voltage, + .list_voltage = tps65217_pmic_ldo_list_voltage, +}; + +static struct regulator_desc regulators[] = { + TPS65217_REGULATOR("DCDC1", TPS65217_DCDC_1, + tps65217_pmic_dcdc_ops, 64), + TPS65217_REGULATOR("DCDC2",TPS65217_DCDC_2, + tps65217_pmic_dcdc_ops, 64), + TPS65217_REGULATOR("DCDC3", TPS65217_DCDC_3, + tps65217_pmic_dcdc_ops, 64), + TPS65217_REGULATOR("LDO1", TPS65217_LDO_1, + tps65217_pmic_ldo1_ops, 16), + TPS65217_REGULATOR("LDO2", TPS65217_LDO_2, + tps65217_pmic_ldo234_ops, 64), + TPS65217_REGULATOR("LDO3", TPS65217_LDO_3, + tps65217_pmic_ldo234_ops, 32), + TPS65217_REGULATOR("LDO4", TPS65217_LDO_4, + tps65217_pmic_ldo234_ops, 32), +}; + +static int __devinit tps65217_regulator_probe(struct platform_device *pdev) +{ + struct regulator_dev *rdev; + struct tps65217 *tps; + struct tps_info *info = &tps65217_pmic_regs[pdev->id]; + + /* Already set by core driver */ + tps = dev_to_tps65217(pdev->dev.parent); + tps->info[pdev->id] = info; + + rdev = regulator_register(®ulators[pdev->id], &pdev->dev, + pdev->dev.platform_data, tps); + if (IS_ERR(rdev)) + return PTR_ERR(rdev); + + platform_set_drvdata(pdev, rdev); + + return 0; +} + +static int __devexit tps65217_regulator_remove(struct platform_device *pdev) +{ + struct regulator_dev *rdev = platform_get_drvdata(pdev); + + platform_set_drvdata(pdev, NULL); + regulator_unregister(rdev); + + return 0; +} + +static struct platform_driver tps65217_regulator_driver = { + .driver = { + .name = "tps65217-pmic", + }, + .probe = tps65217_regulator_probe, + .remove = __devexit_p(tps65217_regulator_remove), +}; + +static int __init tps65217_regulator_init(void) +{ + return platform_driver_register(&tps65217_regulator_driver); +} +subsys_initcall(tps65217_regulator_init); + +static void __exit tps65217_regulator_exit(void) +{ + platform_driver_unregister(&tps65217_regulator_driver); +} +module_exit(tps65217_regulator_exit); + + +MODULE_AUTHOR("AnilKumar Ch "); +MODULE_DESCRIPTION("TPS65217 voltage regulator driver"); +MODULE_ALIAS("platform:tps65217-pmic"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-70-g09d2 From b683d980d8cd91f95a00c9be95ea5116a7db7537 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 15 Jan 2012 20:25:22 +0800 Subject: regulator: Update tps65217-regulator for DT changes Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/tps65217-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index 66655668f96..28a10eaeda1 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c @@ -447,7 +447,7 @@ static int __devinit tps65217_regulator_probe(struct platform_device *pdev) tps->info[pdev->id] = info; rdev = regulator_register(®ulators[pdev->id], &pdev->dev, - pdev->dev.platform_data, tps); + pdev->dev.platform_data, tps, NULL); if (IS_ERR(rdev)) return PTR_ERR(rdev); -- cgit v1.2.3-70-g09d2 From 0ce6987345a739fc3b2ac5da9c727c3b0133bb9c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 17 Jan 2012 11:25:45 +0000 Subject: regulator: Update s5m8767 for device tree API changes 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 caf0117b471..a5b9d83913f 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -771,7 +771,7 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev) (desc->max - desc->min) / desc->step + 1; rdev[i] = regulator_register(®ulators[id], s5m8767->dev, - pdata->regulators[i].initdata, s5m8767); + pdata->regulators[i].initdata, s5m8767, NULL); if (IS_ERR(rdev[i])) { ret = PTR_ERR(rdev[i]); dev_err(s5m8767->dev, "regulator init failed for %d\n", -- cgit v1.2.3-70-g09d2 From c2f8efd7641b1b10b73ffa6f216a45209a5705dd Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Wed, 18 Jan 2012 20:46:56 +0530 Subject: regulator: tps65910: Add regulator info for RTC rail Adding missing regulator info for VRTC rail for device tps65911. The regulator voltage rail index start from VRTC which is defined as 0. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/tps65910-regulator.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 5c15ba01e9c..67424185b36 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -174,6 +174,9 @@ static struct tps_info tps65910_regs[] = { }; static struct tps_info tps65911_regs[] = { + { + .name = "VRTC", + }, { .name = "VIO", .min_uV = 1500000, -- cgit v1.2.3-70-g09d2 From 070b9079226d4f3e3e7c9f4eb81f2e02e7d99572 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 16 Jan 2012 19:39:58 -0800 Subject: regulator: Add devm_regulator_get() Add a resource managed regulator_get() to simplify regulator usage in drivers. This allows driver authors to "get and forget" about their regulators by automatically calling regulator_put() when the driver is detached. [Fixed up a couple of coding style issues -- broonie] Signed-off-by: Stephen Boyd Signed-off-by: Mark Brown --- Documentation/driver-model/devres.txt | 3 +++ drivers/regulator/core.c | 34 ++++++++++++++++++++++++++++++++++ include/linux/regulator/consumer.h | 9 +++++++++ 3 files changed, 46 insertions(+) (limited to 'drivers') diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index 10c64c8a13d..016fd2b06a5 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt @@ -267,3 +267,6 @@ IOMAP pcim_iounmap() pcim_iomap_table() : array of mapped addresses indexed by BAR pcim_iomap_regions() : do request_region() and iomap() on multiple BARs + +REGULATOR + devm_regulator_get() diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index ca86f39a0fd..214640db084 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1320,6 +1320,40 @@ struct regulator *regulator_get(struct device *dev, const char *id) } EXPORT_SYMBOL_GPL(regulator_get); +static void devm_regulator_release(struct device *dev, void *res) +{ + regulator_put(*(struct regulator **)res); +} + +/** + * devm_regulator_get - Resource managed regulator_get() + * @dev: device for regulator "consumer" + * @id: Supply name or regulator ID. + * + * Managed regulator_get(). Regulators returned from this function are + * automatically regulator_put() on driver detach. See regulator_get() for more + * information. + */ +struct regulator *devm_regulator_get(struct device *dev, const char *id) +{ + struct regulator **ptr, *regulator; + + ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return ERR_PTR(-ENOMEM); + + regulator = regulator_get(dev, id); + if (!IS_ERR(regulator)) { + *ptr = regulator; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return regulator; +} +EXPORT_SYMBOL_GPL(devm_regulator_get); + /** * regulator_get_exclusive - obtain exclusive access to a regulator. * @dev: device for regulator "consumer" diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index f2698a0edfc..bcfe1065876 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -132,6 +132,8 @@ struct regulator_bulk_data { /* regulator get and put */ struct regulator *__must_check regulator_get(struct device *dev, const char *id); +struct regulator *__must_check devm_regulator_get(struct device *dev, + const char *id); struct regulator *__must_check regulator_get_exclusive(struct device *dev, const char *id); void regulator_put(struct regulator *regulator); @@ -200,6 +202,13 @@ static inline struct regulator *__must_check regulator_get(struct device *dev, */ return NULL; } + +static inline struct regulator *__must_check +devm_regulator_get(struct device *dev, const char *id) +{ + return NULL; +} + static inline void regulator_put(struct regulator *regulator) { } -- cgit v1.2.3-70-g09d2 From 51ced5e288b4381705df173fb05f561dea35bfac Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Wed, 18 Jan 2012 20:47:16 +0530 Subject: regulator: tps65910: Initialize n_voltages for rails. Initializing the number of voltages supported by different rails of pmic device tps65911. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/tps65910-regulator.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 67424185b36..3ac5f91a4f7 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -188,56 +188,67 @@ static struct tps_info tps65911_regs[] = { .name = "VDD1", .min_uV = 600000, .max_uV = 4500000, + .table_len = 73, }, { .name = "VDD2", .min_uV = 600000, .max_uV = 4500000, + .table_len = 73, }, { .name = "VDDCTRL", .min_uV = 600000, .max_uV = 1400000, + .table_len = 65, }, { .name = "LDO1", .min_uV = 1000000, .max_uV = 3300000, + .table_len = 47, }, { .name = "LDO2", .min_uV = 1000000, .max_uV = 3300000, + .table_len = 47, }, { .name = "LDO3", .min_uV = 1000000, .max_uV = 3300000, + .table_len = 24, }, { .name = "LDO4", .min_uV = 1000000, .max_uV = 3300000, + .table_len = 47, }, { .name = "LDO5", .min_uV = 1000000, .max_uV = 3300000, + .table_len = 24, }, { .name = "LDO6", .min_uV = 1000000, .max_uV = 3300000, + .table_len = 24, }, { .name = "LDO7", .min_uV = 1000000, .max_uV = 3300000, + .table_len = 24, }, { .name = "LDO8", .min_uV = 1000000, .max_uV = 3300000, + .table_len = 24, }, }; -- cgit v1.2.3-70-g09d2 From 7d38a3cb9b9f6a6d31b1d19e4f07a7c0b71407d5 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Fri, 20 Jan 2012 16:36:22 +0530 Subject: regulator: tps65910: use appropriate variable names. Renaming the variables "table" to "voltage_table" and "table_len" to "n_voltages" of regulator information to have more meaningful. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/tps65910-regulator.c | 82 +++++++++++++++++----------------- 1 file changed, 41 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 3ac5f91a4f7..1d13cf997af 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -83,8 +83,8 @@ struct tps_info { const char *name; unsigned min_uV; unsigned max_uV; - u8 table_len; - const u16 *table; + u8 n_voltages; + const u16 *voltage_table; }; static struct tps_info tps65910_regs[] = { @@ -95,8 +95,8 @@ static struct tps_info tps65910_regs[] = { .name = "VIO", .min_uV = 1500000, .max_uV = 3300000, - .table_len = ARRAY_SIZE(VIO_VSEL_table), - .table = VIO_VSEL_table, + .n_voltages = ARRAY_SIZE(VIO_VSEL_table), + .voltage_table = VIO_VSEL_table, }, { .name = "VDD1", @@ -112,64 +112,64 @@ static struct tps_info tps65910_regs[] = { .name = "VDD3", .min_uV = 5000000, .max_uV = 5000000, - .table_len = ARRAY_SIZE(VDD3_VSEL_table), - .table = VDD3_VSEL_table, + .n_voltages = ARRAY_SIZE(VDD3_VSEL_table), + .voltage_table = VDD3_VSEL_table, }, { .name = "VDIG1", .min_uV = 1200000, .max_uV = 2700000, - .table_len = ARRAY_SIZE(VDIG1_VSEL_table), - .table = VDIG1_VSEL_table, + .n_voltages = ARRAY_SIZE(VDIG1_VSEL_table), + .voltage_table = VDIG1_VSEL_table, }, { .name = "VDIG2", .min_uV = 1000000, .max_uV = 1800000, - .table_len = ARRAY_SIZE(VDIG2_VSEL_table), - .table = VDIG2_VSEL_table, + .n_voltages = ARRAY_SIZE(VDIG2_VSEL_table), + .voltage_table = VDIG2_VSEL_table, }, { .name = "VPLL", .min_uV = 1000000, .max_uV = 2500000, - .table_len = ARRAY_SIZE(VPLL_VSEL_table), - .table = VPLL_VSEL_table, + .n_voltages = ARRAY_SIZE(VPLL_VSEL_table), + .voltage_table = VPLL_VSEL_table, }, { .name = "VDAC", .min_uV = 1800000, .max_uV = 2850000, - .table_len = ARRAY_SIZE(VDAC_VSEL_table), - .table = VDAC_VSEL_table, + .n_voltages = ARRAY_SIZE(VDAC_VSEL_table), + .voltage_table = VDAC_VSEL_table, }, { .name = "VAUX1", .min_uV = 1800000, .max_uV = 2850000, - .table_len = ARRAY_SIZE(VAUX1_VSEL_table), - .table = VAUX1_VSEL_table, + .n_voltages = ARRAY_SIZE(VAUX1_VSEL_table), + .voltage_table = VAUX1_VSEL_table, }, { .name = "VAUX2", .min_uV = 1800000, .max_uV = 3300000, - .table_len = ARRAY_SIZE(VAUX2_VSEL_table), - .table = VAUX2_VSEL_table, + .n_voltages = ARRAY_SIZE(VAUX2_VSEL_table), + .voltage_table = VAUX2_VSEL_table, }, { .name = "VAUX33", .min_uV = 1800000, .max_uV = 3300000, - .table_len = ARRAY_SIZE(VAUX33_VSEL_table), - .table = VAUX33_VSEL_table, + .n_voltages = ARRAY_SIZE(VAUX33_VSEL_table), + .voltage_table = VAUX33_VSEL_table, }, { .name = "VMMC", .min_uV = 1800000, .max_uV = 3300000, - .table_len = ARRAY_SIZE(VMMC_VSEL_table), - .table = VMMC_VSEL_table, + .n_voltages = ARRAY_SIZE(VMMC_VSEL_table), + .voltage_table = VMMC_VSEL_table, }, }; @@ -181,74 +181,74 @@ static struct tps_info tps65911_regs[] = { .name = "VIO", .min_uV = 1500000, .max_uV = 3300000, - .table_len = ARRAY_SIZE(VIO_VSEL_table), - .table = VIO_VSEL_table, + .n_voltages = ARRAY_SIZE(VIO_VSEL_table), + .voltage_table = VIO_VSEL_table, }, { .name = "VDD1", .min_uV = 600000, .max_uV = 4500000, - .table_len = 73, + .n_voltages = 73, }, { .name = "VDD2", .min_uV = 600000, .max_uV = 4500000, - .table_len = 73, + .n_voltages = 73, }, { .name = "VDDCTRL", .min_uV = 600000, .max_uV = 1400000, - .table_len = 65, + .n_voltages = 65, }, { .name = "LDO1", .min_uV = 1000000, .max_uV = 3300000, - .table_len = 47, + .n_voltages = 47, }, { .name = "LDO2", .min_uV = 1000000, .max_uV = 3300000, - .table_len = 47, + .n_voltages = 47, }, { .name = "LDO3", .min_uV = 1000000, .max_uV = 3300000, - .table_len = 24, + .n_voltages = 24, }, { .name = "LDO4", .min_uV = 1000000, .max_uV = 3300000, - .table_len = 47, + .n_voltages = 47, }, { .name = "LDO5", .min_uV = 1000000, .max_uV = 3300000, - .table_len = 24, + .n_voltages = 24, }, { .name = "LDO6", .min_uV = 1000000, .max_uV = 3300000, - .table_len = 24, + .n_voltages = 24, }, { .name = "LDO7", .min_uV = 1000000, .max_uV = 3300000, - .table_len = 24, + .n_voltages = 24, }, { .name = "LDO8", .min_uV = 1000000, .max_uV = 3300000, - .table_len = 24, + .n_voltages = 24, }, }; @@ -586,7 +586,7 @@ static int tps65910_get_voltage(struct regulator_dev *dev) return -EINVAL; } - voltage = pmic->info[id]->table[value] * 1000; + voltage = pmic->info[id]->voltage_table[value] * 1000; return voltage; } @@ -636,7 +636,7 @@ static int tps65911_get_voltage(struct regulator_dev *dev) step_mv = 100; break; case TPS65910_REG_VIO: - return pmic->info[id]->table[value] * 1000; + return pmic->info[id]->voltage_table[value] * 1000; break; default: return -EINVAL; @@ -770,10 +770,10 @@ static int tps65910_list_voltage(struct regulator_dev *dev, if (id < TPS65910_REG_VIO || id > TPS65910_REG_VMMC) return -EINVAL; - if (selector >= pmic->info[id]->table_len) + if (selector >= pmic->info[id]->n_voltages) return -EINVAL; else - voltage = pmic->info[id]->table[selector] * 1000; + voltage = pmic->info[id]->voltage_table[selector] * 1000; return voltage; } @@ -809,7 +809,7 @@ static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector) step_mv = 100; break; case TPS65910_REG_VIO: - return pmic->info[id]->table[selector] * 1000; + return pmic->info[id]->voltage_table[selector] * 1000; default: return -EINVAL; } @@ -940,7 +940,7 @@ static __devinit int tps65910_probe(struct platform_device *pdev) pmic->desc[i].name = info->name; pmic->desc[i].id = i; - pmic->desc[i].n_voltages = info->table_len; + pmic->desc[i].n_voltages = info->n_voltages; if (i == TPS65910_REG_VDD1 || i == TPS65910_REG_VDD2) { pmic->desc[i].ops = &tps65910_ops_dcdc; -- cgit v1.2.3-70-g09d2 From 82159ba8e6ef8c38e3e0452d90b4ff8da9e4b2c1 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 18 Jan 2012 10:52:25 +0000 Subject: regmap: Add support for padding between register and address Some devices, especially those with high speed control interfaces, require padding between the register and the data. Support this in the regmap API by providing a pad_bits configuration parameter. Only devices with integer byte counts are supported. Signed-off-by: Mark Brown --- drivers/base/regmap/internal.h | 1 + drivers/base/regmap/regmap.c | 32 +++++++++++++++++++++----------- include/linux/regmap.h | 2 ++ 3 files changed, 24 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index 1a02b7537c8..e33f1be2b29 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h @@ -22,6 +22,7 @@ struct regcache_ops; struct regmap_format { size_t buf_size; size_t reg_bytes; + size_t pad_bytes; size_t val_bytes; void (*format_write)(struct regmap *map, unsigned int reg, unsigned int val); diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index be10a4ff660..e9c2ac0174c 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -160,7 +160,9 @@ struct regmap *regmap_init(struct device *dev, mutex_init(&map->lock); map->format.buf_size = (config->reg_bits + config->val_bits) / 8; map->format.reg_bytes = config->reg_bits / 8; + map->format.pad_bytes = config->pad_bits / 8; map->format.val_bytes = config->val_bits / 8; + map->format.buf_size += map->format.pad_bytes; map->dev = dev; map->bus = bus; map->max_register = config->max_register; @@ -235,7 +237,7 @@ struct regmap *regmap_init(struct device *dev, !(map->format.format_reg && map->format.format_val)) goto err_map; - map->work_buf = kmalloc(map->format.buf_size, GFP_KERNEL); + map->work_buf = kzalloc(map->format.buf_size, GFP_KERNEL); if (map->work_buf == NULL) { ret = -ENOMEM; goto err_map; @@ -329,23 +331,28 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, * send the work_buf directly, otherwise try to do a gather * write. */ - if (val == map->work_buf + map->format.reg_bytes) + if (val == (map->work_buf + map->format.pad_bytes + + map->format.reg_bytes)) ret = map->bus->write(map->dev, map->work_buf, - map->format.reg_bytes + val_len); + map->format.reg_bytes + + map->format.pad_bytes + + val_len); else if (map->bus->gather_write) ret = map->bus->gather_write(map->dev, map->work_buf, - map->format.reg_bytes, + map->format.reg_bytes + + map->format.pad_bytes, val, val_len); /* If that didn't work fall back on linearising by hand. */ if (ret == -ENOTSUPP) { - len = map->format.reg_bytes + val_len; - buf = kmalloc(len, GFP_KERNEL); + len = map->format.reg_bytes + map->format.pad_bytes + val_len; + buf = kzalloc(len, GFP_KERNEL); if (!buf) return -ENOMEM; memcpy(buf, map->work_buf, map->format.reg_bytes); - memcpy(buf + map->format.reg_bytes, val, val_len); + memcpy(buf + map->format.reg_bytes + map->format.pad_bytes, + val, val_len); ret = map->bus->write(map->dev, buf, len); kfree(buf); @@ -387,10 +394,12 @@ int _regmap_write(struct regmap *map, unsigned int reg, return ret; } else { - map->format.format_val(map->work_buf + map->format.reg_bytes, - val); + map->format.format_val(map->work_buf + map->format.reg_bytes + + map->format.pad_bytes, val); return _regmap_raw_write(map, reg, - map->work_buf + map->format.reg_bytes, + map->work_buf + + map->format.reg_bytes + + map->format.pad_bytes, map->format.val_bytes); } } @@ -473,7 +482,8 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, trace_regmap_hw_read_start(map->dev, reg, val_len / map->format.val_bytes); - ret = map->bus->read(map->dev, map->work_buf, map->format.reg_bytes, + ret = map->bus->read(map->dev, map->work_buf, + map->format.reg_bytes + map->format.pad_bytes, val, val_len); trace_regmap_hw_read_done(map->dev, reg, diff --git a/include/linux/regmap.h b/include/linux/regmap.h index eb93921cdd3..a6ed6e6e27a 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -44,6 +44,7 @@ struct reg_default { * Configuration for the register map of a device. * * @reg_bits: Number of bits in a register address, mandatory. + * @pad_bits: Number of bits of padding between register and value. * @val_bits: Number of bits in a register value, mandatory. * * @writeable_reg: Optional callback returning true if the register @@ -74,6 +75,7 @@ struct reg_default { */ struct regmap_config { int reg_bits; + int pad_bits; int val_bits; bool (*writeable_reg)(struct device *dev, unsigned int reg); -- cgit v1.2.3-70-g09d2 From c2573128ad1ff36a7e231799c102be2413a2f756 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 10 Nov 2011 10:57:32 +0000 Subject: spi/s3c64xx: Log error interrupts Although the hardware supports interrupts we're not currently using them at all since for small transfers the overhead is greater than that for busy waiting and for large transfers we have interrupts from the DMA. This means that if the hardware reports an error (especially one which might not stall transfer) we might miss it. Take a first pass at dealing with such errors by enabling the interrupt if we can and logging the errors if they happen. Ideally we'd report the error via the affected transfer but since we're in master mode it's very difficult to trigger errors at present and this code is much simpler. Signed-off-by: Mark Brown Acked-by: Linus Walleij --- drivers/spi/spi-s3c64xx.c | 57 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 019a7163572..d56066bcbb9 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -153,6 +154,7 @@ struct s3c64xx_spi_dma_data { * @tx_dmach: Controller's DMA channel for Tx. * @sfr_start: BUS address of SPI controller regs. * @regs: Pointer to ioremap'ed controller registers. + * @irq: interrupt * @xfer_completion: To indicate completion of xfer task. * @cur_mode: Stores the active configuration of the controller. * @cur_bpw: Stores the active bits per word settings. @@ -930,6 +932,33 @@ setup_exit: return err; } +static irqreturn_t s3c64xx_spi_irq(int irq, void *data) +{ + struct s3c64xx_spi_driver_data *sdd = data; + struct spi_master *spi = sdd->master; + unsigned int val; + + val = readl(sdd->regs + S3C64XX_SPI_PENDING_CLR); + + val &= S3C64XX_SPI_PND_RX_OVERRUN_CLR | + S3C64XX_SPI_PND_RX_UNDERRUN_CLR | + S3C64XX_SPI_PND_TX_OVERRUN_CLR | + S3C64XX_SPI_PND_TX_UNDERRUN_CLR; + + writel(val, sdd->regs + S3C64XX_SPI_PENDING_CLR); + + if (val & S3C64XX_SPI_PND_RX_OVERRUN_CLR) + dev_err(&spi->dev, "RX overrun\n"); + if (val & S3C64XX_SPI_PND_RX_UNDERRUN_CLR) + dev_err(&spi->dev, "RX underrun\n"); + if (val & S3C64XX_SPI_PND_TX_OVERRUN_CLR) + dev_err(&spi->dev, "TX overrun\n"); + if (val & S3C64XX_SPI_PND_TX_UNDERRUN_CLR) + dev_err(&spi->dev, "TX underrun\n"); + + return IRQ_HANDLED; +} + static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel) { struct s3c64xx_spi_info *sci = sdd->cntrlr_info; @@ -970,7 +999,8 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev) struct s3c64xx_spi_driver_data *sdd; struct s3c64xx_spi_info *sci; struct spi_master *master; - int ret; + int ret, irq; + char clk_name[16]; if (pdev->id < 0) { dev_err(&pdev->dev, @@ -1010,6 +1040,12 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev) return -ENXIO; } + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_warn(&pdev->dev, "Failed to get IRQ: %d\n", irq); + return irq; + } + master = spi_alloc_master(&pdev->dev, sizeof(struct s3c64xx_spi_driver_data)); if (master == NULL) { @@ -1104,10 +1140,21 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev) INIT_WORK(&sdd->work, s3c64xx_spi_work); INIT_LIST_HEAD(&sdd->queue); + ret = request_irq(irq, s3c64xx_spi_irq, 0, "spi-s3c64xx", sdd); + if (ret != 0) { + dev_err(&pdev->dev, "Failed to request IRQ %d: %d\n", + irq, ret); + goto err8; + } + + writel(S3C64XX_SPI_INT_RX_OVERRUN_EN | S3C64XX_SPI_INT_RX_UNDERRUN_EN | + S3C64XX_SPI_INT_TX_OVERRUN_EN | S3C64XX_SPI_INT_TX_UNDERRUN_EN, + sdd->regs + S3C64XX_SPI_INT_EN); + if (spi_register_master(master)) { dev_err(&pdev->dev, "cannot register SPI master\n"); ret = -EBUSY; - goto err8; + goto err9; } dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d " @@ -1119,6 +1166,8 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev) return 0; +err9: + free_irq(irq, sdd); err8: destroy_workqueue(sdd->workqueue); err7: @@ -1157,6 +1206,10 @@ static int s3c64xx_spi_remove(struct platform_device *pdev) spi_unregister_master(master); + writel(0, sdd->regs + S3C64XX_SPI_INT_EN); + + free_irq(platform_get_irq(pdev, 0), sdd); + destroy_workqueue(sdd->workqueue); clk_disable(sdd->src_clk); -- cgit v1.2.3-70-g09d2 From e25d0bf917e8f3b6b5bafdc2fe666ca81eb9099d Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 4 Dec 2011 00:36:18 +0000 Subject: spi/s3c64xx: Convert to dev_pm_ops In preparation for the addition of runtime PM ops. Signed-off-by: Mark Brown --- drivers/spi/spi-s3c64xx.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index d56066bcbb9..56dbdf15cba 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -1231,9 +1231,9 @@ static int s3c64xx_spi_remove(struct platform_device *pdev) } #ifdef CONFIG_PM -static int s3c64xx_spi_suspend(struct platform_device *pdev, pm_message_t state) +static int s3c64xx_spi_suspend(struct device *dev) { - struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); + struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); unsigned long flags; @@ -1253,9 +1253,10 @@ static int s3c64xx_spi_suspend(struct platform_device *pdev, pm_message_t state) return 0; } -static int s3c64xx_spi_resume(struct platform_device *pdev) +static int s3c64xx_spi_resume(struct device *dev) { - struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); + struct platform_device *pdev = to_platform_device(dev); + struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); struct s3c64xx_spi_info *sci = sdd->cntrlr_info; unsigned long flags; @@ -1274,19 +1275,19 @@ static int s3c64xx_spi_resume(struct platform_device *pdev) return 0; } -#else -#define s3c64xx_spi_suspend NULL -#define s3c64xx_spi_resume NULL #endif /* CONFIG_PM */ +static const struct dev_pm_ops s3c64xx_spi_pm = { + SET_SYSTEM_SLEEP_PM_OPS(s3c64xx_spi_suspend, s3c64xx_spi_resume) +}; + static struct platform_driver s3c64xx_spi_driver = { .driver = { .name = "s3c64xx-spi", .owner = THIS_MODULE, + .pm = &s3c64xx_spi_pm, }, .remove = s3c64xx_spi_remove, - .suspend = s3c64xx_spi_suspend, - .resume = s3c64xx_spi_resume, }; MODULE_ALIAS("platform:s3c64xx-spi"); -- cgit v1.2.3-70-g09d2 From b97b662174162b44944abd0fa9faea50006ba711 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 4 Dec 2011 00:58:06 +0000 Subject: spi/s3c64xx: Implement runtime PM support Enable and disable the clocks to the SPI controller using runtime PM. This serves the dual purpose of reducing power consumption a little and letting the core know when the device is idle. Signed-off-by: Mark Brown Acked-by: Linus Walleij Acked-by: Heiko Stuebner --- drivers/spi/spi-s3c64xx.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'drivers') diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 56dbdf15cba..b0b843b321b 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -782,6 +783,8 @@ static void s3c64xx_spi_work(struct work_struct *work) while (!acquire_dma(sdd)) msleep(10); + pm_runtime_get_sync(&sdd->pdev->dev); + spin_lock_irqsave(&sdd->lock, flags); while (!list_empty(&sdd->queue) @@ -810,6 +813,8 @@ static void s3c64xx_spi_work(struct work_struct *work) /* Free DMA channels */ sdd->ops->release(sdd->rx_dma.ch, &s3c64xx_spi_dma_client); sdd->ops->release(sdd->tx_dma.ch, &s3c64xx_spi_dma_client); + + pm_runtime_put(&sdd->pdev->dev); } static int s3c64xx_spi_transfer(struct spi_device *spi, @@ -892,6 +897,8 @@ static int s3c64xx_spi_setup(struct spi_device *spi) goto setup_exit; } + pm_runtime_get_sync(&sdd->pdev->dev); + /* Check if we can provide the requested rate */ if (!sci->clk_from_cmu) { u32 psr, speed; @@ -924,6 +931,8 @@ static int s3c64xx_spi_setup(struct spi_device *spi) err = -EINVAL; } + pm_runtime_put(&sdd->pdev->dev); + setup_exit: /* setup() returns with device de-selected */ @@ -1164,6 +1173,8 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev) mem_res->end, mem_res->start, sdd->rx_dma.dmach, sdd->tx_dma.dmach); + pm_runtime_enable(&pdev->dev); + return 0; err9: @@ -1197,6 +1208,8 @@ static int s3c64xx_spi_remove(struct platform_device *pdev) struct resource *mem_res; unsigned long flags; + pm_runtime_disable(&pdev->dev); + spin_lock_irqsave(&sdd->lock, flags); sdd->state |= SUSPND; spin_unlock_irqrestore(&sdd->lock, flags); @@ -1277,8 +1290,34 @@ static int s3c64xx_spi_resume(struct device *dev) } #endif /* CONFIG_PM */ +#ifdef CONFIG_PM_RUNTIME +static int s3c64xx_spi_runtime_suspend(struct device *dev) +{ + struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); + struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); + + clk_disable(sdd->clk); + clk_disable(sdd->src_clk); + + return 0; +} + +static int s3c64xx_spi_runtime_resume(struct device *dev) +{ + struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); + struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); + + clk_enable(sdd->src_clk); + clk_enable(sdd->clk); + + return 0; +} +#endif /* CONFIG_PM_RUNTIME */ + static const struct dev_pm_ops s3c64xx_spi_pm = { SET_SYSTEM_SLEEP_PM_OPS(s3c64xx_spi_suspend, s3c64xx_spi_resume) + SET_RUNTIME_PM_OPS(s3c64xx_spi_runtime_suspend, + s3c64xx_spi_runtime_resume, NULL) }; static struct platform_driver s3c64xx_spi_driver = { -- cgit v1.2.3-70-g09d2 From 71d676345698b275955b2584803ae550972249e5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 21 Jul 2011 17:46:41 -0300 Subject: [media] dvb: Add a new driver for az6007 Import the az6007 driver from Terratec H7 source, as-is. It won't compile or run, so latter patches are needed in order to fix it. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 627 +++++++++++++++++++++++++++++++++++++ drivers/media/dvb/dvb-usb/az6007.h | 18 ++ 2 files changed, 645 insertions(+) create mode 100644 drivers/media/dvb/dvb-usb/az6007.c create mode 100644 drivers/media/dvb/dvb-usb/az6007.h (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c new file mode 100644 index 00000000000..cd5dd4cecd0 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -0,0 +1,627 @@ +/* DVB USB compliant Linux driver for the AzureWave 6017 USB2.0 DVB-S + * receiver. + * see Documentation/dvb/README.dvb-usb for more information + */ + +#include "az6007.h" +#include "drxk.h" +#include "mt2063.h" +#include "dvb_ca_en50221.h" + +/* debug */ +int dvb_usb_az6007_debug; +module_param_named(debug,dvb_usb_az6007_debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS); + + +static int az6007_type =0; +module_param(az6007_type, int, 0644); +MODULE_PARM_DESC(az6007_type, "select delivery mode (0=DVB-T, 1=DVB-T"); + +//module_param_named(type, 6007_type, int, 0644); +//MODULE_PARM_DESC(type, "select delivery mode (0=DVB-T, 1=DVB-C)"); + +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + + +struct az6007_device_state { + struct dvb_ca_en50221 ca; + struct mutex ca_mutex; + u8 power_state; +}; + +struct drxk3913_config az6007_drxk3913_config_DVBT = { + .demod_address = 0x52, + .min_delay_ms = 100, + .standard = MTTUNEA_DVBT, + .set_tuner = mt2063_setTune, + .tuner_getlocked = mt2063_lockStatus, + .tuner_MT2063_Open = tuner_MT2063_Open, + .tuner_MT2063_SoftwareShutdown = tuner_MT2063_SoftwareShutdown, + .tuner_MT2063_ClearPowerMaskBits = tuner_MT2063_ClearPowerMaskBits, +}; + +struct drxk3913_config az6007_drxk3913_config_DVBC = { + .demod_address = 0x52, + .min_delay_ms = 100, + .standard = MTTUNEA_DVBC, + .set_tuner = mt2063_setTune, + .tuner_getlocked = mt2063_lockStatus, + .tuner_MT2063_Open = tuner_MT2063_Open, + .tuner_MT2063_SoftwareShutdown = tuner_MT2063_SoftwareShutdown, + .tuner_MT2063_ClearPowerMaskBits = tuner_MT2063_ClearPowerMaskBits, +}; + +struct mt2063_config az6007_mt2063_config = { + .tuner_address = 0xc0, + .refclock = 36125000, +}; + +/* check for mutex FIXME */ +int az6007_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen) +{ + int ret = -1; + + ret = usb_control_msg(d->udev, + usb_rcvctrlpipe(d->udev,0), + req, + USB_TYPE_VENDOR | USB_DIR_IN, + value,index,b,blen, + 5000); + + if (ret < 0) { + warn("usb in operation failed. (%d)", ret); + ret = -EIO; + } else + ret = 0; + + + deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index); + debug_dump(b,blen,deb_xfer); + + return ret; +} + +static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, + u16 index, u8 *b, int blen) +{ + int ret; + +#if 0 + int i=0, cyc=0, rem=0; + cyc = blen/64; + rem = blen%64; +#endif + + deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index); + debug_dump(b,blen,deb_xfer); + + +#if 0 + if (blen>64) + { + for (i=0; iudev, + usb_sndctrlpipe(d->udev,0), + req, + USB_TYPE_VENDOR | USB_DIR_OUT, + value,index+i*64,b+i*64,64, + 5000)) != 64) { + warn("usb out operation failed. (%d)",ret); + return -EIO; + } + } + + if (rem>0) + { + if ((ret = usb_control_msg(d->udev, + usb_sndctrlpipe(d->udev,0), + req, + USB_TYPE_VENDOR | USB_DIR_OUT, + value,index+cyc*64,b+cyc*64,rem, + 5000)) != rem) { + warn("usb out operation failed. (%d)",ret); + return -EIO; + } + } + } + else +#endif + { + if ((ret = usb_control_msg(d->udev, + usb_sndctrlpipe(d->udev,0), + req, + USB_TYPE_VENDOR | USB_DIR_OUT, + value,index,b,blen, + 5000)) != blen) { + warn("usb out operation failed. (%d)",ret); + return -EIO; + } + } + + return 0; +} + +static int az6007_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) +{ + return 0; +} + +/* keys for the enclosed remote control */ +static struct dvb_usb_rc_key az6007_rc_keys[] = { + { 0x00, 0x01, KEY_1 }, + { 0x00, 0x02, KEY_2 }, +}; + +/* remote control stuff (does not work with my box) */ +static int az6007_rc_query(struct dvb_usb_device *d, u32 *event, int *state) +{ + return 0; +#if 0 + u8 key[10]; + int i; + +/* remove the following return to enabled remote querying */ + + + az6007_usb_in_op(d,READ_REMOTE_REQ,0,0,key,10); + + deb_rc("remote query key: %x %d\n",key[1],key[1]); + + if (key[1] == 0x44) { + *state = REMOTE_NO_KEY_PRESSED; + return 0; + } + + for (i = 0; i < ARRAY_SIZE(az6007_rc_keys); i++) + if (az6007_rc_keys[i].custom == key[1]) { + *state = REMOTE_KEY_PRESSED; + *event = az6007_rc_keys[i].event; + break; + } + return 0; +#endif +} + +/* +int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) +{ + u8 v = onoff; + return az6007_usb_out_op(d,0xBC,v,3,NULL,1); +} +*/ + +static int az6007_read_mac_addr(struct dvb_usb_device *d,u8 mac[6]) +{ + az6007_usb_in_op(d, 0xb7, 6, 0, &mac[0], 6); + return 0; +} + +static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) +{ + int ret; + u8 req; + u16 value; + u16 index; + int blen; + + info("az6007_frontend_poweron adap=%p adap->dev=%p\n", adap, adap->dev); + + req = 0xBC; + value = 1;//power on + index = 3; + blen =0; + + if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) + { + err("az6007_frontend_poweron failed!!!"); + return -EIO; + } + + msleep_interruptible(200); + + req = 0xBC; + value = 0;//power on + index = 3; + blen =0; + + if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) + { + err("az6007_frontend_poweron failed!!!"); + return -EIO; + } + + msleep_interruptible(200); + + req = 0xBC; + value = 1;//power on + index = 3; + blen =0; + + if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) + { + err("az6007_frontend_poweron failed!!!"); + return -EIO; + } + info("az6007_frontend_poweron\n"); + return 0; +} + +static int az6007_frontend_reset(struct dvb_usb_adapter *adap) +{ + int ret; + u8 req; + u16 value; + u16 index; + int blen; + + info("az6007_frontend_reset adap=%p adap->dev=%p\n", adap, adap->dev); + + //reset demodulator + req = 0xC0; + value = 1;//high + index = 3; + blen =0; + if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) + { + err("az6007_frontend_reset failed 1 !!!"); + return -EIO; + } + + req = 0xC0; + value = 0;//low + index = 3; + blen =0; + msleep_interruptible(200); + if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) + { + err("az6007_frontend_reset failed 2 !!!"); + return -EIO; + } + msleep_interruptible(200); + req = 0xC0; + value = 1;//high + index = 3; + blen =0; + + if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) + { + err("az6007_frontend_reset failed 3 !!!"); + return -EIO; + } + + msleep_interruptible(200); + + info("reset az6007 frontend\n"); + + return 0; +} + +static int az6007_led_on_off(struct usb_interface *intf, int onoff) +{ + int ret = -1; + u8 req; + u16 value; + u16 index; + int blen; + //TS through + req = 0xBC; + value = onoff; + index = 0; + blen =0; + + ret = usb_control_msg(interface_to_usbdev(intf), + usb_rcvctrlpipe(interface_to_usbdev(intf),0), + req, + USB_TYPE_VENDOR | USB_DIR_OUT, + value,index,NULL,blen, + 2000); + + if (ret < 0) { + warn("usb in operation failed. (%d)", ret); + ret = -EIO; + } else + ret = 0; + + + deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index); + + return ret; +} + +static int az6007_frontend_tsbypass(struct dvb_usb_adapter *adap,int onoff) +{ + int ret; + u8 req; + u16 value; + u16 index; + int blen; + //TS through + req = 0xC7; + value = onoff; + index = 0; + blen =0; + + if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) + return -EIO; + return 0; +} + +static int az6007_frontend_attach(struct dvb_usb_adapter *adap) +{ + az6007_frontend_poweron(adap); + az6007_frontend_reset(adap); + + info("az6007_frontend_attach\n"); + + if (az6007_type == 0) + { + info("az6007_drxk3913_config_DVBT\n"); + adap->fe = drxk3913_attach(&az6007_drxk3913_config_DVBT, &adap->dev->i2c_adap); + } + else + { + info("az6007_drxk3913_config_DVBC\n"); + adap->fe = drxk3913_attach(&az6007_drxk3913_config_DVBC, &adap->dev->i2c_adap); + } + if (adap->fe) { + if (mt2063_attach(adap->fe, &az6007_mt2063_config, &adap->dev->i2c_adap)) { + info("found STB6100 DVB-C/DVB-T frontend @0x%02x\n",az6007_mt2063_config.tuner_address); + + //vp6027_ci_init(adap); + } else { + adap->fe = NULL; + } + } + else + { + adap->fe = NULL; + err("no front-end attached\n"); + } + //az6007_frontend_tsbypass(adap,0); + + return 0; +} + +static struct dvb_usb_device_properties az6007_properties; + +static void +az6007_usb_disconnect(struct usb_interface *intf) +{ + dvb_usb_device_exit (intf); +} + +/* I2C */ +static int az6007_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num) +{ + struct dvb_usb_device *d = i2c_get_adapdata(adap); + int j=0,len=0; + int ret=0; + u16 index; + u16 value; + int length; + u8 req; + u8 data[512]; + + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + return -EAGAIN; + if (num > 2) + warn("more than 2 i2c messages at a time is not handled yet. TODO."); + + + if (msg[0].addr == 0xc0) //MT2063 + { + if (msg[0].flags != I2C_M_RD) //write + { + //printk("Tuner Tuner Write DevAddr=%02x RegAddr=%d\n", msg[0].addr, msg[0].buf[0]); + req = 0xBD; + index = msg[0].buf[0]; + value = msg[0].addr | (1<<8); + length = msg[0].len - 1; + len = msg[0].len - 1; + //printk("Tuner Tuner WriteDATA len=%d ", len); + for(j=0;ji2c_mutex); + return ret; +} + + +static u32 az6007_i2c_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C; +} + +static struct i2c_algorithm az6007_i2c_algo = { + .master_xfer = az6007_i2c_xfer, + .functionality = az6007_i2c_func, +#ifdef NEED_ALGO_CONTROL + .algo_control = dummy_algo_control, +#endif +}; + +int az6007_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, + struct dvb_usb_device_description **desc, int *cold) +{ + u8 b[16]; + s16 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev,0), + 0xb7, USB_TYPE_VENDOR | USB_DIR_IN, 6, 0, b, 6, USB_CTRL_GET_TIMEOUT); + + info("FW GET_VERSION length: %d\n",ret); + + *cold = ret <= 0; + + info("cold: %d\n", *cold); + return 0; +} + +static int az6007_usb_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + az6007_led_on_off(intf, 0); + + return dvb_usb_device_init(intf, &az6007_properties, + THIS_MODULE, NULL, adapter_nr); +} + +static struct usb_device_id az6007_usb_table [] = { + { USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_6007) }, + { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7) }, + { 0 }, +}; + +MODULE_DEVICE_TABLE(usb, az6007_usb_table); + +static struct dvb_usb_device_properties az6007_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + .usb_ctrl = CYPRESS_FX2, + //.download_firmware = az6007_download_firmware, + .firmware = "dvb-usb-az6007-03.fw", + .no_reconnect = 1, + + .size_of_priv = sizeof(struct az6007_device_state), + .identify_state = az6007_identify_state, + .num_adapters = 1, + .adapter = { + { + //.caps = DVB_USB_ADAP_RECEIVES_204_BYTE_TS, + + .streaming_ctrl = az6007_streaming_ctrl, + .frontend_attach = az6007_frontend_attach, + + /* parameter for the MPEG2-data transfer */ + .stream = { + .type = USB_BULK, + .count = 10, + .endpoint = 0x02, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + .size_of_priv = 0,//sizeof(struct az6007_state), + } + }, + //.power_ctrl = az6007_power_ctrl, + .read_mac_address = az6007_read_mac_addr, + + .rc_key_map = az6007_rc_keys, + .rc_key_map_size = ARRAY_SIZE(az6007_rc_keys), + .rc_interval = 400, + .rc_query = az6007_rc_query, + .i2c_algo = &az6007_i2c_algo, + + .num_device_descs = 2, + .devices = { + { .name = "AzureWave DTV StarBox DVB-T/C USB2.0 (az6007)", + .cold_ids = { &az6007_usb_table[0], NULL }, + .warm_ids = { NULL }, + }, + { .name = "TerraTec DTV StarBox DVB-T/C USB2.0 (az6007)", + .cold_ids = { &az6007_usb_table[1], NULL }, + .warm_ids = { NULL }, + }, + { NULL }, + } +}; + +/* usb specific object needed to register this driver with the usb subsystem */ +static struct usb_driver az6007_usb_driver = { + .name = "dvb_usb_az6007", + .probe = az6007_usb_probe, + .disconnect = dvb_usb_device_exit, + //.disconnect = az6007_usb_disconnect, + .id_table = az6007_usb_table, +}; + +/* module stuff */ +static int __init az6007_usb_module_init(void) +{ + int result; + info("henry :: az6007 usb module init"); + if ((result = usb_register(&az6007_usb_driver))) { + err("usb_register failed. (%d)",result); + return result; + } + + return 0; +} + +static void __exit az6007_usb_module_exit(void) +{ + /* deregister this driver from the USB subsystem */ + info("henry :: az6007 usb module exit"); + usb_deregister(&az6007_usb_driver); +} + +module_init(az6007_usb_module_init); +module_exit(az6007_usb_module_exit); + +MODULE_AUTHOR("Henry Wang "); +MODULE_DESCRIPTION("Driver for AzureWave 6007 DVB-C/T USB2.0 and clones"); +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/az6007.h b/drivers/media/dvb/dvb-usb/az6007.h new file mode 100644 index 00000000000..aefa5b506ee --- /dev/null +++ b/drivers/media/dvb/dvb-usb/az6007.h @@ -0,0 +1,18 @@ +#ifndef _DVB_USB_AZ6007_H_ +#define _DVB_USB_AZ6007_H_ + +#define DVB_USB_LOG_PREFIX "az6007" +#include "dvb-usb.h" + + +extern int dvb_usb_az6007_debug; +#define deb_info(args...) dprintk(dvb_usb_az6007_debug,0x01,args) +#define deb_xfer(args...) dprintk(dvb_usb_az6007_debug,0x02,args) +#define deb_rc(args...) dprintk(dvb_usb_az6007_debug,0x04,args) +#define deb_fe(args...) dprintk(dvb_usb_az6007_debug,0x08,args) + + +extern int vp702x_usb_out_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec); +extern int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen); + +#endif -- cgit v1.2.3-70-g09d2 From 6da347065062d28de035c01b298c6aebab2723fb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 21 Jul 2011 18:31:14 -0300 Subject: [media] az6007: Fix compilation troubles at az6007 Some changes are needed, in order to make az6007 compile with the upstream tree. Most of the changes are due to the upstream drxk module. Even allowing its compilation, the driver is not working yet. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/mt2063.c | 2 +- drivers/media/dvb/dvb-usb/az6007.c | 174 +++++++++++++++++++++-------------- 2 files changed, 104 insertions(+), 72 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/tuners/mt2063.c b/drivers/media/common/tuners/mt2063.c index c89af3cd5eb..7bbf25da3ef 100644 --- a/drivers/media/common/tuners/mt2063.c +++ b/drivers/media/common/tuners/mt2063.c @@ -350,7 +350,7 @@ static int MT2063_Sleep(struct dvb_frontend *fe) /* * ToDo: Add code here to implement a OS blocking */ - msleep(10); + msleep(100); return 0; } diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index cd5dd4cecd0..5873759f5db 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -8,6 +8,10 @@ #include "mt2063.h" #include "dvb_ca_en50221.h" +/* HACK: Should be moved to the right place */ +#define USB_PID_AZUREWAVE_6007 0xccd +#define USB_PID_TERRATEC_H7 0x10b4 + /* debug */ int dvb_usb_az6007_debug; module_param_named(debug,dvb_usb_az6007_debug, int, 0644); @@ -28,30 +32,39 @@ struct az6007_device_state { struct dvb_ca_en50221 ca; struct mutex ca_mutex; u8 power_state; -}; -struct drxk3913_config az6007_drxk3913_config_DVBT = { - .demod_address = 0x52, - .min_delay_ms = 100, - .standard = MTTUNEA_DVBT, - .set_tuner = mt2063_setTune, - .tuner_getlocked = mt2063_lockStatus, - .tuner_MT2063_Open = tuner_MT2063_Open, - .tuner_MT2063_SoftwareShutdown = tuner_MT2063_SoftwareShutdown, - .tuner_MT2063_ClearPowerMaskBits = tuner_MT2063_ClearPowerMaskBits, + /* Due to DRX-K - probably need changes */ + int (*gate_ctrl)(struct dvb_frontend *, int); + struct semaphore pll_mutex; + bool dont_attach_fe1; }; -struct drxk3913_config az6007_drxk3913_config_DVBC = { - .demod_address = 0x52, - .min_delay_ms = 100, - .standard = MTTUNEA_DVBC, - .set_tuner = mt2063_setTune, - .tuner_getlocked = mt2063_lockStatus, - .tuner_MT2063_Open = tuner_MT2063_Open, - .tuner_MT2063_SoftwareShutdown = tuner_MT2063_SoftwareShutdown, - .tuner_MT2063_ClearPowerMaskBits = tuner_MT2063_ClearPowerMaskBits, +struct drxk_config terratec_h7_drxk = { + .adr = 0x29, + .single_master = 1, + .no_i2c_bridge = 1, + .microcode_name = "dvb-usb-terratec-h5-drxk.fw", }; +static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) +{ + struct dvb_usb_adapter *adap = fe->sec_priv; + struct az6007_device_state *st = adap->priv; + int status; + + if (!adap || !st) + return -EINVAL; + + if (enable) { + down(&st->pll_mutex); + status = st->gate_ctrl(fe, 1); + } else { + status = st->gate_ctrl(fe, 0); + up(&st->pll_mutex); + } + return status; +} + struct mt2063_config az6007_mt2063_config = { .tuner_address = 0xc0, .refclock = 36125000, @@ -87,7 +100,7 @@ static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, { int ret; -#if 0 +#if 0 int i=0, cyc=0, rem=0; cyc = blen/64; rem = blen%64; @@ -96,7 +109,7 @@ static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index); debug_dump(b,blen,deb_xfer); - + #if 0 if (blen>64) { @@ -110,7 +123,7 @@ static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, 5000)) != 64) { warn("usb out operation failed. (%d)",ret); return -EIO; - } + } } if (rem>0) @@ -127,7 +140,7 @@ static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, } } else -#endif +#endif { if ((ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev,0), @@ -139,7 +152,7 @@ static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, return -EIO; } } - + return 0; } @@ -149,9 +162,9 @@ static int az6007_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) } /* keys for the enclosed remote control */ -static struct dvb_usb_rc_key az6007_rc_keys[] = { - { 0x00, 0x01, KEY_1 }, - { 0x00, 0x02, KEY_2 }, +struct rc_map_table rc_map_az6007_table[] = { + { 0x0001, KEY_1 }, + { 0x0002, KEY_2 }, }; /* remote control stuff (does not work with my box) */ @@ -163,7 +176,7 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 *event, int *state) int i; /* remove the following return to enabled remote querying */ - + az6007_usb_in_op(d,READ_REMOTE_REQ,0,0,key,10); @@ -257,7 +270,7 @@ static int az6007_frontend_reset(struct dvb_usb_adapter *adap) int blen; info("az6007_frontend_reset adap=%p adap->dev=%p\n", adap, adap->dev); - + //reset demodulator req = 0xC0; value = 1;//high @@ -268,7 +281,7 @@ static int az6007_frontend_reset(struct dvb_usb_adapter *adap) err("az6007_frontend_reset failed 1 !!!"); return -EIO; } - + req = 0xC0; value = 0;//low index = 3; @@ -290,11 +303,11 @@ static int az6007_frontend_reset(struct dvb_usb_adapter *adap) err("az6007_frontend_reset failed 3 !!!"); return -EIO; } - + msleep_interruptible(200); - + info("reset az6007 frontend\n"); - + return 0; } @@ -350,38 +363,55 @@ static int az6007_frontend_tsbypass(struct dvb_usb_adapter *adap,int onoff) static int az6007_frontend_attach(struct dvb_usb_adapter *adap) { + struct az6007_device_state *st = adap->priv; + + int result; + az6007_frontend_poweron(adap); az6007_frontend_reset(adap); info("az6007_frontend_attach\n"); - if (az6007_type == 0) - { - info("az6007_drxk3913_config_DVBT\n"); - adap->fe = drxk3913_attach(&az6007_drxk3913_config_DVBT, &adap->dev->i2c_adap); + adap->fe = dvb_attach(drxk_attach, &terratec_h7_drxk, + &adap->dev->i2c_adap, &adap->fe2); + if (!adap->fe) { + result = -EINVAL; + goto out_free; } - else - { - info("az6007_drxk3913_config_DVBC\n"); - adap->fe = drxk3913_attach(&az6007_drxk3913_config_DVBC, &adap->dev->i2c_adap); - } - if (adap->fe) { - if (mt2063_attach(adap->fe, &az6007_mt2063_config, &adap->dev->i2c_adap)) { - info("found STB6100 DVB-C/DVB-T frontend @0x%02x\n",az6007_mt2063_config.tuner_address); - - //vp6027_ci_init(adap); - } else { - adap->fe = NULL; - } - } - else - { - adap->fe = NULL; - err("no front-end attached\n"); + + /* FIXME: do we need a pll semaphore? */ + adap->fe->sec_priv = adap; + sema_init(&st->pll_mutex, 1); + st->gate_ctrl = adap->fe->ops.i2c_gate_ctrl; + adap->fe->ops.i2c_gate_ctrl = drxk_gate_ctrl; + adap->fe2->id = 1; + + /* Attach mt2063 to DVB-C frontend */ + if (adap->fe->ops.i2c_gate_ctrl) + adap->fe->ops.i2c_gate_ctrl(adap->fe, 1); + if (!dvb_attach(mt2063_attach, adap->fe, &az6007_mt2063_config, + &adap->dev->i2c_adap)) { + result = -EINVAL; + + goto out_free; } - //az6007_frontend_tsbypass(adap,0); - + if (adap->fe->ops.i2c_gate_ctrl) + adap->fe->ops.i2c_gate_ctrl(adap->fe, 0); + + /* Hack - needed due to drxk */ + adap->fe2->tuner_priv = adap->fe->tuner_priv; + memcpy(&adap->fe2->ops.tuner_ops, + &adap->fe->ops.tuner_ops, + sizeof(adap->fe->ops.tuner_ops)); return 0; + +out_free: + if (adap->fe) + dvb_frontend_detach(adap->fe); + adap->fe = NULL; + adap->fe2 = NULL; + + return result; } static struct dvb_usb_device_properties az6007_properties; @@ -403,7 +433,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num int length; u8 req; u8 data[512]; - + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) return -EAGAIN; if (num > 2) @@ -442,7 +472,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num //printk("Tuner Tuner ReadDATA len=%d ", len); for (j=0; j Date: Fri, 22 Jul 2011 10:31:25 -0300 Subject: [media] az6007: Fix it to allow loading it without crash Add some fixes to allow frontend attachment. The patch is not complete yet, as just the frontend 0 is initialized. So, more changes will be needed, including some changes at dvb-usb core. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 190 +++++++++++++++++++------------------ 1 file changed, 98 insertions(+), 92 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 5873759f5db..6a21f928550 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -49,12 +49,20 @@ struct drxk_config terratec_h7_drxk = { static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) { struct dvb_usb_adapter *adap = fe->sec_priv; - struct az6007_device_state *st = adap->priv; + struct az6007_device_state *st; int status; - if (!adap || !st) + info("%s", __func__); + + if (!adap) + return -EINVAL; + + st = adap->priv; + + if (!st) return -EINVAL; + if (enable) { down(&st->pll_mutex); status = st->gate_ctrl(fe, 1); @@ -66,7 +74,7 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) } struct mt2063_config az6007_mt2063_config = { - .tuner_address = 0xc0, + .tuner_address = 0x60, .refclock = 36125000, }; @@ -84,10 +92,8 @@ int az6007_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 if (ret < 0) { warn("usb in operation failed. (%d)", ret); - ret = -EIO; - } else - ret = 0; - + return -EIO; + } deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index); debug_dump(b,blen,deb_xfer); @@ -219,7 +225,7 @@ static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) u16 index; int blen; - info("az6007_frontend_poweron adap=%p adap->dev=%p\n", adap, adap->dev); + info("az6007_frontend_poweron adap=%p adap->dev=%p", adap, adap->dev); req = 0xBC; value = 1;//power on @@ -257,7 +263,8 @@ static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) err("az6007_frontend_poweron failed!!!"); return -EIO; } - info("az6007_frontend_poweron\n"); + info("az6007_frontend_poweron: OK"); + return 0; } @@ -269,7 +276,7 @@ static int az6007_frontend_reset(struct dvb_usb_adapter *adap) u16 index; int blen; - info("az6007_frontend_reset adap=%p adap->dev=%p\n", adap, adap->dev); + info("az6007_frontend_reset adap=%p adap->dev=%p", adap, adap->dev); //reset demodulator req = 0xC0; @@ -306,7 +313,7 @@ static int az6007_frontend_reset(struct dvb_usb_adapter *adap) msleep_interruptible(200); - info("reset az6007 frontend\n"); + info("reset az6007 frontend"); return 0; } @@ -367,10 +374,12 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) int result; + BUG_ON(!st); + az6007_frontend_poweron(adap); az6007_frontend_reset(adap); - info("az6007_frontend_attach\n"); + info("az6007_frontend_attach: drxk"); adap->fe = dvb_attach(drxk_attach, &terratec_h7_drxk, &adap->dev->i2c_adap, &adap->fe2); @@ -379,6 +388,8 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) goto out_free; } + info("Setting hacks"); + /* FIXME: do we need a pll semaphore? */ adap->fe->sec_priv = adap; sema_init(&st->pll_mutex, 1); @@ -386,6 +397,7 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) adap->fe->ops.i2c_gate_ctrl = drxk_gate_ctrl; adap->fe2->id = 1; + info("az6007_frontend_attach: mt2063"); /* Attach mt2063 to DVB-C frontend */ if (adap->fe->ops.i2c_gate_ctrl) adap->fe->ops.i2c_gate_ctrl(adap->fe, 1); @@ -423,100 +435,95 @@ az6007_usb_disconnect(struct usb_interface *intf) } /* I2C */ -static int az6007_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num) +static int az6007_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msgs[],int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); - int j=0,len=0; - int ret=0; + int i, j, len; + int ret = 0; u16 index; u16 value; int length; - u8 req; + u8 req, addr; u8 data[512]; if (mutex_lock_interruptible(&d->i2c_mutex) < 0) return -EAGAIN; - if (num > 2) - warn("more than 2 i2c messages at a time is not handled yet. TODO."); - - if (msg[0].addr == 0xc0) //MT2063 - { - if (msg[0].flags != I2C_M_RD) //write - { - //printk("Tuner Tuner Write DevAddr=%02x RegAddr=%d\n", msg[0].addr, msg[0].buf[0]); - req = 0xBD; - index = msg[0].buf[0]; - value = msg[0].addr | (1<<8); - length = msg[0].len - 1; - len = msg[0].len - 1; - //printk("Tuner Tuner WriteDATA len=%d ", len); - for(j=0;j= len) { + for (j = 0; j < len; j++) { + msgs[i + 1].buf[j] = data[j + 5]; + printk("0x%02x ", msgs[i + 1].buf[j]); + } + } else + ret = -EIO; + i++; + } else if (!(msgs[i].flags & I2C_M_RD)) { + /* write bytes */ +// printk("az6007 I2C xfer write addr=0x%x len=%d: ", +// addr, msgs[i].len); + req = 0xbd; + index = msgs[i].buf[0]; + value = addr | (1 << 8); + length = msgs[i].len - 1; + len = msgs[i].len - 1; +// printk("(0x%02x) ", msgs[i].buf[0]); + for (j = 0; j < len; j++) { - data[j] = msg[0].buf[j+1]; - //printk("data[%d]=%02x ", j, data[j]); + data[j] = msgs[i].buf[j + 1]; +// printk("0x%02x ", data[j]); } - //printk("\n"); ret = az6007_usb_out_op(d,req,value,index,data,length); - } - else //read - { - //printk("Demodulator Read DevAddr=%02x RegAddr=%02x\n", msg[0].addr, msg[0].buf[0]); - req = 0xB9; - index = 0; - value = msg[0].addr + (0 << 8); - length = msg[0].len + 6; + } else { + /* read bytes */ +// printk("az6007 I2C xfer read addr=0x%x len=%d: ", +// addr, msgs[i].len); + req = 0xb9; + index = msgs[i].buf[0]; + value = addr; + length = msgs[i].len + 6; + len = msgs[i].len; ret = az6007_usb_in_op(d,req,value,index,data,length); - len = msg[0].len; - //printk("Demodulator ReadDATA len=%d ", len); - for (j=0; ji2c_mutex); - return ret; + + if (ret < 0) { + info("%s ERROR: %i\n", __func__, ret); + return ret; + } + return num; } @@ -540,11 +547,11 @@ int az6007_identify_state(struct usb_device *udev, struct dvb_usb_device_propert s16 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev,0), 0xb7, USB_TYPE_VENDOR | USB_DIR_IN, 6, 0, b, 6, USB_CTRL_GET_TIMEOUT); - info("FW GET_VERSION length: %d\n",ret); + info("FW GET_VERSION length: %d",ret); *cold = ret <= 0; - info("cold: %d\n", *cold); + info("cold: %d", *cold); return 0; } @@ -572,7 +579,6 @@ static struct dvb_usb_device_properties az6007_properties = { .firmware = "dvb-usb-az6007-03.fw", .no_reconnect = 1, - .size_of_priv = sizeof(struct az6007_device_state), .identify_state = az6007_identify_state, .num_adapters = 1, .adapter = { @@ -593,7 +599,7 @@ static struct dvb_usb_device_properties az6007_properties = { } } }, - .size_of_priv = 0,//sizeof(struct az6007_state), + .size_of_priv = sizeof(struct az6007_device_state), } }, //.power_ctrl = az6007_power_ctrl, @@ -634,7 +640,7 @@ static struct usb_driver az6007_usb_driver = { static int __init az6007_usb_module_init(void) { int result; - info("henry :: az6007 usb module init"); + info("az6007 usb module init"); if ((result = usb_register(&az6007_usb_driver))) { err("usb_register failed. (%d)",result); return result; @@ -646,7 +652,7 @@ static int __init az6007_usb_module_init(void) static void __exit az6007_usb_module_exit(void) { /* deregister this driver from the USB subsystem */ - info("henry :: az6007 usb module exit"); + info("az6007 usb module exit"); usb_deregister(&az6007_usb_driver); } -- cgit v1.2.3-70-g09d2 From d20a7f7277785e6f7fbe02eb469f7a99a9f058a4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 23 Jul 2011 09:51:12 -0300 Subject: [media] az6007: Fix the I2C code in order to handle mt2063 mt2063 uses a one-byte transfer. This requires a special handling inside the i2c code. Fix it to properly accept i2c reads. This is needed to make the mt2063 to be detected. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 47 ++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 6a21f928550..56126d41a60 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -42,7 +42,7 @@ struct az6007_device_state { struct drxk_config terratec_h7_drxk = { .adr = 0x29, .single_master = 1, - .no_i2c_bridge = 1, + .no_i2c_bridge = 0, .microcode_name = "dvb-usb-terratec-h5-drxk.fw", }; @@ -451,7 +451,6 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msgs[],int nu for (i = 0; i < num; i++) { addr = msgs[i].addr << 1; - if (((i + 1) < num) && (msgs[i].len == 1) && (!msgs[i].flags & I2C_M_RD) @@ -462,44 +461,55 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msgs[],int nu * the first xfer has just 1 byte length. * Need to join both into one operation */ - printk("az6007 I2C xfer write+read addr=0x%x len=%d/%d: ", - addr, msgs[i].len, msgs[i + 1].len); + if (dvb_usb_az6007_debug & 2) + printk(KERN_DEBUG + "az6007 I2C xfer write+read addr=0x%x len=%d/%d: ", + addr, msgs[i].len, msgs[i + 1].len); req = 0xb9; - index = 0; - value = addr; - for (j = 0; j < msgs[i].len; j++) - data[j] = msgs[i].buf[j]; + index = msgs[i].buf[0]; + value = addr | (1 << 8); length = 6 + msgs[i + 1].len; len = msgs[i + 1].len; ret = az6007_usb_in_op(d,req,value,index,data,length); if (ret >= len) { for (j = 0; j < len; j++) { msgs[i + 1].buf[j] = data[j + 5]; - printk("0x%02x ", msgs[i + 1].buf[j]); + if (dvb_usb_az6007_debug & 2) + printk(KERN_CONT + "0x%02x ", + msgs[i + 1].buf[j]); } } else ret = -EIO; i++; } else if (!(msgs[i].flags & I2C_M_RD)) { /* write bytes */ -// printk("az6007 I2C xfer write addr=0x%x len=%d: ", -// addr, msgs[i].len); + if (dvb_usb_az6007_debug & 2) + printk(KERN_DEBUG + "az6007 I2C xfer write addr=0x%x len=%d: ", + addr, msgs[i].len); req = 0xbd; index = msgs[i].buf[0]; value = addr | (1 << 8); length = msgs[i].len - 1; len = msgs[i].len - 1; -// printk("(0x%02x) ", msgs[i].buf[0]); + if (dvb_usb_az6007_debug & 2) + printk(KERN_CONT + "(0x%02x) ", msgs[i].buf[0]); for (j = 0; j < len; j++) { data[j] = msgs[i].buf[j + 1]; -// printk("0x%02x ", data[j]); + if (dvb_usb_az6007_debug & 2) + printk(KERN_CONT + "0x%02x ", data[j]); } ret = az6007_usb_out_op(d,req,value,index,data,length); } else { /* read bytes */ -// printk("az6007 I2C xfer read addr=0x%x len=%d: ", -// addr, msgs[i].len); + if (dvb_usb_az6007_debug & 2) + printk(KERN_DEBUG + "az6007 I2C xfer read addr=0x%x len=%d: ", + addr, msgs[i].len); req = 0xb9; index = msgs[i].buf[0]; value = addr; @@ -509,10 +519,13 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msgs[],int nu for (j = 0; j < len; j++) { msgs[i].buf[j] = data[j + 5]; -// printk("0x%02x ", data[j + 5]); + if (dvb_usb_az6007_debug & 2) + printk(KERN_CONT + "0x%02x ", data[j + 5]); } } -// printk("\n"); + if (dvb_usb_az6007_debug & 2) + printk(KERN_CONT "\n"); if (ret < 0) goto err; } -- cgit v1.2.3-70-g09d2 From 2212501ffad7fee1c2fcf9d6d55a24b489da18ad Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 23 Jul 2011 09:58:38 -0300 Subject: [media] az6007: Comment the gate_ctl mutex The mutex is there to protect the I2C gate. However, for some reason, it is being called twice: [ 2103.542796] usbcore: registered new interface driver dvb_usb_az6007 [ 2103.772392] az6007: drxk_gate_ctrl: enable [ 2103.793900] az6007: drxk_gate_ctrl: enable For now, let's just comment, to allow the driver to run. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 56126d41a60..ed376b8292c 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -52,7 +52,7 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) struct az6007_device_state *st; int status; - info("%s", __func__); + info("%s: %s", __func__, enable? "enable" : "disable" ); if (!adap) return -EINVAL; @@ -64,10 +64,14 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) if (enable) { +#if 0 down(&st->pll_mutex); +#endif status = st->gate_ctrl(fe, 1); } else { +#if 0 status = st->gate_ctrl(fe, 0); +#endif up(&st->pll_mutex); } return status; -- cgit v1.2.3-70-g09d2 From 357535800d98174ceddc6ad1f3092f1dce0ea04c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 23 Jul 2011 10:12:12 -0300 Subject: [media] az6007: Remove some dead code that doesn't seem to be needed Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 79 ++++++++------------------------------ 1 file changed, 16 insertions(+), 63 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index ed376b8292c..1fc174b86a7 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -17,17 +17,8 @@ int dvb_usb_az6007_debug; module_param_named(debug,dvb_usb_az6007_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS); - -static int az6007_type =0; -module_param(az6007_type, int, 0644); -MODULE_PARM_DESC(az6007_type, "select delivery mode (0=DVB-T, 1=DVB-T"); - -//module_param_named(type, 6007_type, int, 0644); -//MODULE_PARM_DESC(type, "select delivery mode (0=DVB-T, 1=DVB-C)"); - DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - struct az6007_device_state { struct dvb_ca_en50221 ca; struct mutex ca_mutex; @@ -110,57 +101,22 @@ static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, { int ret; -#if 0 - int i=0, cyc=0, rem=0; - cyc = blen/64; - rem = blen%64; -#endif - deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index); debug_dump(b,blen,deb_xfer); - -#if 0 - if (blen>64) - { - for (i=0; iudev, - usb_sndctrlpipe(d->udev,0), - req, - USB_TYPE_VENDOR | USB_DIR_OUT, - value,index+i*64,b+i*64,64, - 5000)) != 64) { - warn("usb out operation failed. (%d)",ret); - return -EIO; - } - } - - if (rem>0) - { - if ((ret = usb_control_msg(d->udev, - usb_sndctrlpipe(d->udev,0), - req, - USB_TYPE_VENDOR | USB_DIR_OUT, - value,index+cyc*64,b+cyc*64,rem, - 5000)) != rem) { - warn("usb out operation failed. (%d)",ret); - return -EIO; - } - } + if (blen > 64) { + printk(KERN_ERR "az6007: doesn't suport I2C transactions longer than 64 bytes\n"); + return -EOPNOTSUPP; } - else -#endif - { - if ((ret = usb_control_msg(d->udev, - usb_sndctrlpipe(d->udev,0), - req, - USB_TYPE_VENDOR | USB_DIR_OUT, - value,index,b,blen, - 5000)) != blen) { - warn("usb out operation failed. (%d)",ret); - return -EIO; - } + + if ((ret = usb_control_msg(d->udev, + usb_sndctrlpipe(d->udev,0), + req, + USB_TYPE_VENDOR | USB_DIR_OUT, + value,index,b,blen, + 5000)) != blen) { + warn("usb out operation failed. (%d)",ret); + return -EIO; } return 0; @@ -232,7 +188,7 @@ static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) info("az6007_frontend_poweron adap=%p adap->dev=%p", adap, adap->dev); req = 0xBC; - value = 1;//power on + value = 1; /* power on */ index = 3; blen =0; @@ -245,7 +201,7 @@ static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) msleep_interruptible(200); req = 0xBC; - value = 0;//power on + value = 0; /* power off */ index = 3; blen =0; @@ -258,7 +214,7 @@ static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) msleep_interruptible(200); req = 0xBC; - value = 1;//power on + value = 1; /* power on */ index = 3; blen =0; @@ -552,9 +508,6 @@ static u32 az6007_i2c_func(struct i2c_adapter *adapter) static struct i2c_algorithm az6007_i2c_algo = { .master_xfer = az6007_i2c_xfer, .functionality = az6007_i2c_func, -#ifdef NEED_ALGO_CONTROL - .algo_control = dummy_algo_control, -#endif }; int az6007_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, @@ -678,5 +631,5 @@ module_exit(az6007_usb_module_exit); MODULE_AUTHOR("Henry Wang "); MODULE_DESCRIPTION("Driver for AzureWave 6007 DVB-C/T USB2.0 and clones"); -MODULE_VERSION("1.0"); +MODULE_VERSION("1.1"); MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From 93b32126f94333afd012daf5b48b594b86ae8128 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 23 Jul 2011 10:40:08 -0300 Subject: [media] az6007: CodingStyle cleanup make checkpatch.pl happy Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 239 +++++++++++++++++++------------------ 1 file changed, 120 insertions(+), 119 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 1fc174b86a7..a709cec16b0 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -14,23 +14,24 @@ /* debug */ int dvb_usb_az6007_debug; -module_param_named(debug,dvb_usb_az6007_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS); +module_param_named(debug, dvb_usb_az6007_debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." + DVB_USB_DEBUG_STATUS); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); struct az6007_device_state { - struct dvb_ca_en50221 ca; - struct mutex ca_mutex; - u8 power_state; + struct dvb_ca_en50221 ca; + struct mutex ca_mutex; + u8 power_state; /* Due to DRX-K - probably need changes */ - int (*gate_ctrl)(struct dvb_frontend *, int); - struct semaphore pll_mutex; + int (*gate_ctrl) (struct dvb_frontend *, int); + struct semaphore pll_mutex; bool dont_attach_fe1; }; -struct drxk_config terratec_h7_drxk = { +static struct drxk_config terratec_h7_drxk = { .adr = 0x29, .single_master = 1, .no_i2c_bridge = 0, @@ -43,7 +44,7 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) struct az6007_device_state *st; int status; - info("%s: %s", __func__, enable? "enable" : "disable" ); + info("%s: %s", __func__, enable ? "enable" : "disable"); if (!adap) return -EINVAL; @@ -53,7 +54,6 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) if (!st) return -EINVAL; - if (enable) { #if 0 down(&st->pll_mutex); @@ -68,30 +68,31 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) return status; } -struct mt2063_config az6007_mt2063_config = { +static struct mt2063_config az6007_mt2063_config = { .tuner_address = 0x60, .refclock = 36125000, }; /* check for mutex FIXME */ -int az6007_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen) +static int az6007_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, + u16 index, u8 *b, int blen) { int ret = -1; - ret = usb_control_msg(d->udev, - usb_rcvctrlpipe(d->udev,0), - req, - USB_TYPE_VENDOR | USB_DIR_IN, - value,index,b,blen, - 5000); + ret = usb_control_msg(d->udev, + usb_rcvctrlpipe(d->udev, 0), + req, + USB_TYPE_VENDOR | USB_DIR_IN, + value, index, b, blen, 5000); if (ret < 0) { warn("usb in operation failed. (%d)", ret); return -EIO; } - deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index); - debug_dump(b,blen,deb_xfer); + deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, + index); + debug_dump(b, blen, deb_xfer); return ret; } @@ -101,21 +102,23 @@ static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, { int ret; - deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index); - debug_dump(b,blen,deb_xfer); + deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, + index); + debug_dump(b, blen, deb_xfer); if (blen > 64) { - printk(KERN_ERR "az6007: doesn't suport I2C transactions longer than 64 bytes\n"); + printk(KERN_ERR + "az6007: doesn't suport I2C transactions longer than 64 bytes\n"); return -EOPNOTSUPP; } - if ((ret = usb_control_msg(d->udev, - usb_sndctrlpipe(d->udev,0), - req, - USB_TYPE_VENDOR | USB_DIR_OUT, - value,index,b,blen, - 5000)) != blen) { - warn("usb out operation failed. (%d)",ret); + ret = usb_control_msg(d->udev, + usb_sndctrlpipe(d->udev, 0), + req, + USB_TYPE_VENDOR | USB_DIR_OUT, + value, index, b, blen, 5000); + if (ret != blen) { + warn("usb out operation failed. (%d)", ret); return -EIO; } @@ -128,25 +131,24 @@ static int az6007_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) } /* keys for the enclosed remote control */ -struct rc_map_table rc_map_az6007_table[] = { - { 0x0001, KEY_1 }, - { 0x0002, KEY_2 }, +static struct rc_map_table rc_map_az6007_table[] = { + {0x0001, KEY_1}, + {0x0002, KEY_2}, }; /* remote control stuff (does not work with my box) */ -static int az6007_rc_query(struct dvb_usb_device *d, u32 *event, int *state) +static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) { return 0; #if 0 u8 key[10]; int i; -/* remove the following return to enabled remote querying */ - + /* remove the following return to enabled remote querying */ - az6007_usb_in_op(d,READ_REMOTE_REQ,0,0,key,10); + az6007_usb_in_op(d, READ_REMOTE_REQ, 0, 0, key, 10); - deb_rc("remote query key: %x %d\n",key[1],key[1]); + deb_rc("remote query key: %x %d\n", key[1], key[1]); if (key[1] == 0x44) { *state = REMOTE_NO_KEY_PRESSED; @@ -171,7 +173,7 @@ int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) } */ -static int az6007_read_mac_addr(struct dvb_usb_device *d,u8 mac[6]) +static int az6007_read_mac_addr(struct dvb_usb_device *d, u8 mac[6]) { az6007_usb_in_op(d, 0xb7, 6, 0, &mac[0], 6); return 0; @@ -190,12 +192,12 @@ static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) req = 0xBC; value = 1; /* power on */ index = 3; - blen =0; + blen = 0; - if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) - { + ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); + if (ret != 0) { err("az6007_frontend_poweron failed!!!"); - return -EIO; + return -EIO; } msleep_interruptible(200); @@ -203,12 +205,12 @@ static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) req = 0xBC; value = 0; /* power off */ index = 3; - blen =0; + blen = 0; - if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) - { + ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); + if (ret != 0) { err("az6007_frontend_poweron failed!!!"); - return -EIO; + return -EIO; } msleep_interruptible(200); @@ -216,12 +218,12 @@ static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) req = 0xBC; value = 1; /* power on */ index = 3; - blen =0; + blen = 0; - if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) - { + ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); + if (ret != 0) { err("az6007_frontend_poweron failed!!!"); - return -EIO; + return -EIO; } info("az6007_frontend_poweron: OK"); @@ -238,37 +240,37 @@ static int az6007_frontend_reset(struct dvb_usb_adapter *adap) info("az6007_frontend_reset adap=%p adap->dev=%p", adap, adap->dev); - //reset demodulator + /* reset demodulator */ req = 0xC0; - value = 1;//high + value = 1; /* high */ index = 3; - blen =0; - if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) - { + blen = 0; + ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); + if (ret != 0) { err("az6007_frontend_reset failed 1 !!!"); - return -EIO; + return -EIO; } req = 0xC0; - value = 0;//low + value = 0; /* low */ index = 3; - blen =0; + blen = 0; msleep_interruptible(200); - if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) - { + ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); + if (ret != 0) { err("az6007_frontend_reset failed 2 !!!"); - return -EIO; + return -EIO; } msleep_interruptible(200); req = 0xC0; - value = 1;//high + value = 1; /* high */ index = 3; - blen =0; + blen = 0; - if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) - { + ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); + if (ret != 0) { err("az6007_frontend_reset failed 3 !!!"); - return -EIO; + return -EIO; } msleep_interruptible(200); @@ -285,18 +287,17 @@ static int az6007_led_on_off(struct usb_interface *intf, int onoff) u16 value; u16 index; int blen; - //TS through + /* TS through */ req = 0xBC; value = onoff; index = 0; - blen =0; + blen = 0; ret = usb_control_msg(interface_to_usbdev(intf), - usb_rcvctrlpipe(interface_to_usbdev(intf),0), - req, - USB_TYPE_VENDOR | USB_DIR_OUT, - value,index,NULL,blen, - 2000); + usb_rcvctrlpipe(interface_to_usbdev(intf), 0), + req, + USB_TYPE_VENDOR | USB_DIR_OUT, + value, index, NULL, blen, 2000); if (ret < 0) { warn("usb in operation failed. (%d)", ret); @@ -304,27 +305,28 @@ static int az6007_led_on_off(struct usb_interface *intf, int onoff) } else ret = 0; - - deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index); + deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, + index); return ret; } -static int az6007_frontend_tsbypass(struct dvb_usb_adapter *adap,int onoff) +static int az6007_frontend_tsbypass(struct dvb_usb_adapter *adap, int onoff) { int ret; u8 req; u16 value; u16 index; int blen; - //TS through + /* TS through */ req = 0xC7; value = onoff; index = 0; - blen =0; + blen = 0; - if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) - return -EIO; + ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); + if (ret != 0) + return -EIO; return 0; } @@ -373,8 +375,7 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) /* Hack - needed due to drxk */ adap->fe2->tuner_priv = adap->fe->tuner_priv; memcpy(&adap->fe2->ops.tuner_ops, - &adap->fe->ops.tuner_ops, - sizeof(adap->fe->ops.tuner_ops)); + &adap->fe->ops.tuner_ops, sizeof(adap->fe->ops.tuner_ops)); return 0; out_free: @@ -388,14 +389,14 @@ out_free: static struct dvb_usb_device_properties az6007_properties; -static void -az6007_usb_disconnect(struct usb_interface *intf) +static void az6007_usb_disconnect(struct usb_interface *intf) { - dvb_usb_device_exit (intf); + dvb_usb_device_exit(intf); } /* I2C */ -static int az6007_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msgs[],int num) +static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], + int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); int i, j, len; @@ -430,7 +431,8 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msgs[],int nu value = addr | (1 << 8); length = 6 + msgs[i + 1].len; len = msgs[i + 1].len; - ret = az6007_usb_in_op(d,req,value,index,data,length); + ret = az6007_usb_in_op(d, req, value, index, data, + length); if (ret >= len) { for (j = 0; j < len; j++) { msgs[i + 1].buf[j] = data[j + 5]; @@ -454,16 +456,14 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msgs[],int nu length = msgs[i].len - 1; len = msgs[i].len - 1; if (dvb_usb_az6007_debug & 2) - printk(KERN_CONT - "(0x%02x) ", msgs[i].buf[0]); - for (j = 0; j < len; j++) - { + printk(KERN_CONT "(0x%02x) ", msgs[i].buf[0]); + for (j = 0; j < len; j++) { data[j] = msgs[i].buf[j + 1]; if (dvb_usb_az6007_debug & 2) - printk(KERN_CONT - "0x%02x ", data[j]); + printk(KERN_CONT "0x%02x ", data[j]); } - ret = az6007_usb_out_op(d,req,value,index,data,length); + ret = az6007_usb_out_op(d, req, value, index, data, + length); } else { /* read bytes */ if (dvb_usb_az6007_debug & 2) @@ -475,9 +475,9 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msgs[],int nu value = addr; length = msgs[i].len + 6; len = msgs[i].len; - ret = az6007_usb_in_op(d,req,value,index,data,length); - for (j = 0; j < len; j++) - { + ret = az6007_usb_in_op(d, req, value, index, data, + length); + for (j = 0; j < len; j++) { msgs[i].buf[j] = data[j + 5]; if (dvb_usb_az6007_debug & 2) printk(KERN_CONT @@ -499,25 +499,26 @@ err: return num; } - static u32 az6007_i2c_func(struct i2c_adapter *adapter) { return I2C_FUNC_I2C; } static struct i2c_algorithm az6007_i2c_algo = { - .master_xfer = az6007_i2c_xfer, + .master_xfer = az6007_i2c_xfer, .functionality = az6007_i2c_func, }; -int az6007_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, - struct dvb_usb_device_description **desc, int *cold) +int az6007_identify_state(struct usb_device *udev, + struct dvb_usb_device_properties *props, + struct dvb_usb_device_description **desc, int *cold) { u8 b[16]; - s16 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev,0), - 0xb7, USB_TYPE_VENDOR | USB_DIR_IN, 6, 0, b, 6, USB_CTRL_GET_TIMEOUT); + s16 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + 0xb7, USB_TYPE_VENDOR | USB_DIR_IN, 6, 0, b, + 6, USB_CTRL_GET_TIMEOUT); - info("FW GET_VERSION length: %d",ret); + info("FW GET_VERSION length: %d", ret); *cold = ret <= 0; @@ -526,7 +527,7 @@ int az6007_identify_state(struct usb_device *udev, struct dvb_usb_device_propert } static int az6007_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id) + const struct usb_device_id *id) { az6007_led_on_off(intf, 0); @@ -534,10 +535,10 @@ static int az6007_usb_probe(struct usb_interface *intf, THIS_MODULE, NULL, adapter_nr); } -static struct usb_device_id az6007_usb_table [] = { - { USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_6007) }, - { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7) }, - { 0 }, +static struct usb_device_id az6007_usb_table[] = { + {USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_6007)}, + {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7)}, + {0}, }; MODULE_DEVICE_TABLE(usb, az6007_usb_table); @@ -545,7 +546,6 @@ MODULE_DEVICE_TABLE(usb, az6007_usb_table); static struct dvb_usb_device_properties az6007_properties = { .caps = DVB_USB_IS_AN_I2C_ADAPTER, .usb_ctrl = CYPRESS_FX2, - //.download_firmware = az6007_download_firmware, .firmware = "dvb-usb-az6007-03.fw", .no_reconnect = 1, @@ -553,8 +553,7 @@ static struct dvb_usb_device_properties az6007_properties = { .num_adapters = 1, .adapter = { { - //.caps = DVB_USB_ADAP_RECEIVES_204_BYTE_TS, - + /* .caps = DVB_USB_ADAP_RECEIVES_204_BYTE_TS, */ .streaming_ctrl = az6007_streaming_ctrl, .frontend_attach = az6007_frontend_attach, @@ -572,7 +571,7 @@ static struct dvb_usb_device_properties az6007_properties = { .size_of_priv = sizeof(struct az6007_device_state), } }, - //.power_ctrl = az6007_power_ctrl, + /* .power_ctrl = az6007_power_ctrl, */ .read_mac_address = az6007_read_mac_addr, .rc.legacy = { @@ -600,10 +599,10 @@ static struct dvb_usb_device_properties az6007_properties = { /* usb specific object needed to register this driver with the usb subsystem */ static struct usb_driver az6007_usb_driver = { .name = "dvb_usb_az6007", - .probe = az6007_usb_probe, + .probe = az6007_usb_probe, .disconnect = dvb_usb_device_exit, - //.disconnect = az6007_usb_disconnect, - .id_table = az6007_usb_table, + /* .disconnect = az6007_usb_disconnect, */ + .id_table = az6007_usb_table, }; /* module stuff */ @@ -611,8 +610,10 @@ static int __init az6007_usb_module_init(void) { int result; info("az6007 usb module init"); - if ((result = usb_register(&az6007_usb_driver))) { - err("usb_register failed. (%d)",result); + + result = usb_register(&az6007_usb_driver); + if (result) { + err("usb_register failed. (%d)", result); return result; } -- cgit v1.2.3-70-g09d2 From 70fa444d81b4fea992c2899467d5c4939a35100c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 23 Jul 2011 10:55:10 -0300 Subject: [media] az6007: Get rid of az6007.h The header file serves for no purpose and exports some things that should be static. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 11 +++++++++-- drivers/media/dvb/dvb-usb/az6007.h | 18 ------------------ 2 files changed, 9 insertions(+), 20 deletions(-) delete mode 100644 drivers/media/dvb/dvb-usb/az6007.h (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index a709cec16b0..1791cb08862 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -3,13 +3,15 @@ * see Documentation/dvb/README.dvb-usb for more information */ -#include "az6007.h" #include "drxk.h" #include "mt2063.h" #include "dvb_ca_en50221.h" +#include "dvb-usb.h" + +#define DVB_USB_LOG_PREFIX "az6007" /* HACK: Should be moved to the right place */ -#define USB_PID_AZUREWAVE_6007 0xccd +#define USB_PID_AZUREWAVE_6007 0x0ccd #define USB_PID_TERRATEC_H7 0x10b4 /* debug */ @@ -18,6 +20,11 @@ module_param_named(debug, dvb_usb_az6007_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS); +#define deb_info(args...) dprintk(dvb_usb_az6007_debug, 0x01, args) +#define deb_xfer(args...) dprintk(dvb_usb_az6007_debug, 0x02, args) +#define deb_rc(args...) dprintk(dvb_usb_az6007_debug, 0x04, args) +#define deb_fe(args...) dprintk(dvb_usb_az6007_debug, 0x08, args) + DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); struct az6007_device_state { diff --git a/drivers/media/dvb/dvb-usb/az6007.h b/drivers/media/dvb/dvb-usb/az6007.h deleted file mode 100644 index aefa5b506ee..00000000000 --- a/drivers/media/dvb/dvb-usb/az6007.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _DVB_USB_AZ6007_H_ -#define _DVB_USB_AZ6007_H_ - -#define DVB_USB_LOG_PREFIX "az6007" -#include "dvb-usb.h" - - -extern int dvb_usb_az6007_debug; -#define deb_info(args...) dprintk(dvb_usb_az6007_debug,0x01,args) -#define deb_xfer(args...) dprintk(dvb_usb_az6007_debug,0x02,args) -#define deb_rc(args...) dprintk(dvb_usb_az6007_debug,0x04,args) -#define deb_fe(args...) dprintk(dvb_usb_az6007_debug,0x08,args) - - -extern int vp702x_usb_out_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec); -extern int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen); - -#endif -- cgit v1.2.3-70-g09d2 From 25c1646670fb4220c6c3ca91e1423c6aa76b3f87 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 23 Jul 2011 10:59:25 -0300 Subject: [media] az6007: Replace the comments at the beginning of the driver The comments there is wrong. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 1791cb08862..f946b1b65b1 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -1,6 +1,23 @@ -/* DVB USB compliant Linux driver for the AzureWave 6017 USB2.0 DVB-S - * receiver. - * see Documentation/dvb/README.dvb-usb for more information +/* + * Driver for AzureWave 6007 DVB-C/T USB2.0 and clones + * + * Copyright (c) Henry Wang + * + * This driver was made publicly available by Terratec, at: + * http://linux.terratec.de/files/TERRATEC_H7/20110323_TERRATEC_H7_Linux.tar.gz + * The original driver's license is GPL, as declared with MODULE_LICENSE() + * + * Driver modifiyed by Mauro Carvalho Chehab in order + * to work with upstream drxk driver, and to fix some bugs. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation under version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #include "drxk.h" -- cgit v1.2.3-70-g09d2 From 067fb88c9d423d67dbf432010b3bfc5336a2bbed Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 23 Jul 2011 11:10:10 -0300 Subject: [media] az6007: move device PID's to the proper place Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 4 ---- drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 2 ++ 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index f946b1b65b1..780a480fb70 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -27,10 +27,6 @@ #define DVB_USB_LOG_PREFIX "az6007" -/* HACK: Should be moved to the right place */ -#define USB_PID_AZUREWAVE_6007 0x0ccd -#define USB_PID_TERRATEC_H7 0x10b4 - /* debug */ int dvb_usb_az6007_debug; module_param_named(debug, dvb_usb_az6007_debug, int, 0644); diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index d390ddaa5a5..b3e7be4718a 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -80,6 +80,7 @@ #define USB_PID_ANSONIC_DVBT_USB 0x6000 #define USB_PID_ANYSEE 0x861f #define USB_PID_AZUREWAVE_AD_TU700 0x3237 +#define USB_PID_AZUREWAVE_6007 0x0ccd #define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001 #define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002 #define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800 @@ -226,6 +227,7 @@ #define USB_PID_TERRATEC_CINERGY_T_EXPRESS 0x0062 #define USB_PID_TERRATEC_CINERGY_T_XXS 0x0078 #define USB_PID_TERRATEC_CINERGY_T_XXS_2 0x00ab +#define USB_PID_TERRATEC_H7 0x10b4 #define USB_PID_TERRATEC_T3 0x10a0 #define USB_PID_TERRATEC_T5 0x10a1 #define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e -- cgit v1.2.3-70-g09d2 From f2ba9e5dda2afd4615dbd3c48afe64fe2ce70d4e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 23 Jul 2011 11:54:40 -0300 Subject: [media] az6007: make driver less verbose Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 780a480fb70..bb597c67cc9 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -62,9 +62,9 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) { struct dvb_usb_adapter *adap = fe->sec_priv; struct az6007_device_state *st; - int status; + int status = 0; - info("%s: %s", __func__, enable ? "enable" : "disable"); + deb_info("%s: %s\n", __func__, enable ? "enable" : "disable"); if (!adap) return -EINVAL; @@ -127,8 +127,7 @@ static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, debug_dump(b, blen, deb_xfer); if (blen > 64) { - printk(KERN_ERR - "az6007: doesn't suport I2C transactions longer than 64 bytes\n"); + err("az6007: doesn't suport I2C transactions longer than 64 bytes\n"); return -EOPNOTSUPP; } @@ -138,7 +137,7 @@ static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, USB_TYPE_VENDOR | USB_DIR_OUT, value, index, b, blen, 5000); if (ret != blen) { - warn("usb out operation failed. (%d)", ret); + err("usb out operation failed. (%d)", ret); return -EIO; } @@ -207,7 +206,8 @@ static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) u16 index; int blen; - info("az6007_frontend_poweron adap=%p adap->dev=%p", adap, adap->dev); + deb_info("az6007_frontend_poweron adap=%p adap->dev=%p\n", + adap, adap->dev); req = 0xBC; value = 1; /* power on */ @@ -245,7 +245,7 @@ static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) err("az6007_frontend_poweron failed!!!"); return -EIO; } - info("az6007_frontend_poweron: OK"); + deb_info("az6007_frontend_poweron: OK\n"); return 0; } @@ -258,7 +258,7 @@ static int az6007_frontend_reset(struct dvb_usb_adapter *adap) u16 index; int blen; - info("az6007_frontend_reset adap=%p adap->dev=%p", adap, adap->dev); + deb_info("az6007_frontend_reset adap=%p adap->dev=%p\n", adap, adap->dev); /* reset demodulator */ req = 0xC0; @@ -295,7 +295,7 @@ static int az6007_frontend_reset(struct dvb_usb_adapter *adap) msleep_interruptible(200); - info("reset az6007 frontend"); + deb_info("reset az6007 frontend\n"); return 0; } @@ -361,8 +361,7 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) az6007_frontend_poweron(adap); az6007_frontend_reset(adap); - info("az6007_frontend_attach: drxk"); - + info("az6007: attaching demod drxk"); adap->fe = dvb_attach(drxk_attach, &terratec_h7_drxk, &adap->dev->i2c_adap, &adap->fe2); if (!adap->fe) { @@ -370,7 +369,7 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) goto out_free; } - info("Setting hacks"); + deb_info("Setting hacks\n"); /* FIXME: do we need a pll semaphore? */ adap->fe->sec_priv = adap; @@ -379,7 +378,7 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) adap->fe->ops.i2c_gate_ctrl = drxk_gate_ctrl; adap->fe2->id = 1; - info("az6007_frontend_attach: mt2063"); + info("az6007: attaching tuner mt2063"); /* Attach mt2063 to DVB-C frontend */ if (adap->fe->ops.i2c_gate_ctrl) adap->fe->ops.i2c_gate_ctrl(adap->fe, 1); @@ -513,7 +512,7 @@ err: mutex_unlock(&d->i2c_mutex); if (ret < 0) { - info("%s ERROR: %i\n", __func__, ret); + info("%s ERROR: %i", __func__, ret); return ret; } return num; @@ -538,11 +537,11 @@ int az6007_identify_state(struct usb_device *udev, 0xb7, USB_TYPE_VENDOR | USB_DIR_IN, 6, 0, b, 6, USB_CTRL_GET_TIMEOUT); - info("FW GET_VERSION length: %d", ret); + deb_info("FW GET_VERSION length: %d\n", ret); *cold = ret <= 0; - info("cold: %d", *cold); + deb_info("cold: %d\n", *cold); return 0; } @@ -629,7 +628,7 @@ static struct usb_driver az6007_usb_driver = { static int __init az6007_usb_module_init(void) { int result; - info("az6007 usb module init"); + deb_info("az6007 usb module init\n"); result = usb_register(&az6007_usb_driver); if (result) { @@ -643,7 +642,7 @@ static int __init az6007_usb_module_init(void) static void __exit az6007_usb_module_exit(void) { /* deregister this driver from the USB subsystem */ - info("az6007 usb module exit"); + deb_info("az6007 usb module exit\n"); usb_deregister(&az6007_usb_driver); } -- cgit v1.2.3-70-g09d2 From da989e0bc7f2b3db3fea417c0bae3c20c6455995 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 24 Jul 2011 09:25:39 -0300 Subject: [media] drxk: Don't assume a default firmware name Move the ngene/ddbridge firmware into their drivers. There are two reasons for that: 1) The firmware used there didn't work for a few devices I tested here (Terratec H5, H6 and H7); 2) At least Terratec H7 doesn't seem to require a firmware for it to work. After this change, if firmware is not specified, the driver will use a rom-based firmware (this seems to be the case for Terratec H7, although I need to better check the USB dumps to be sure about that). In any case, the firmware seems to be optional, as the DRX-K driver don't return the firmware load error. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ddbridge/ddbridge-core.c | 1 + drivers/media/dvb/dvb-usb/az6007.c | 8 +++++--- drivers/media/dvb/frontends/drxk_hard.c | 4 +--- drivers/media/dvb/ngene/ngene-cards.c | 1 + 4 files changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/ddbridge/ddbridge-core.c b/drivers/media/dvb/ddbridge/ddbridge-core.c index 2f31648bba9..243dbb37bd5 100644 --- a/drivers/media/dvb/ddbridge/ddbridge-core.c +++ b/drivers/media/dvb/ddbridge/ddbridge-core.c @@ -578,6 +578,7 @@ static int demod_attach_drxk(struct ddb_input *input) struct drxk_config config; memset(&config, 0, sizeof(config)); + config.microcode_name = "drxk_a3.mc"; config.adr = 0x29 + (input->nr & 1); fe = input->fe = dvb_attach(drxk_attach, &config, i2c); diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index bb597c67cc9..523972f9ef5 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -55,7 +55,8 @@ static struct drxk_config terratec_h7_drxk = { .adr = 0x29, .single_master = 1, .no_i2c_bridge = 0, - .microcode_name = "dvb-usb-terratec-h5-drxk.fw", + .max_size = 64, +// .microcode_name = "dvb-usb-terratec-h5-drxk.fw", }; static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) @@ -127,7 +128,8 @@ static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, debug_dump(b, blen, deb_xfer); if (blen > 64) { - err("az6007: doesn't suport I2C transactions longer than 64 bytes\n"); + err("az6007: tried to write %d bytes, but I2C max size is 64 bytes\n", + blen); return -EOPNOTSUPP; } @@ -395,6 +397,7 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) adap->fe2->tuner_priv = adap->fe->tuner_priv; memcpy(&adap->fe2->ops.tuner_ops, &adap->fe->ops.tuner_ops, sizeof(adap->fe->ops.tuner_ops)); + return 0; out_free: @@ -572,7 +575,6 @@ static struct dvb_usb_device_properties az6007_properties = { .num_adapters = 1, .adapter = { { - /* .caps = DVB_USB_ADAP_RECEIVES_204_BYTE_TS, */ .streaming_ctrl = az6007_streaming_ctrl, .frontend_attach = az6007_frontend_attach, diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c index 6980ed7b878..4b99255f7ba 100644 --- a/drivers/media/dvb/frontends/drxk_hard.c +++ b/drivers/media/dvb/frontends/drxk_hard.c @@ -6070,9 +6070,7 @@ static int init_drxk(struct drxk_state *state) if (status < 0) goto error; - if (!state->microcode_name) - load_microcode(state, "drxk_a3.mc"); - else + if (state->microcode_name) load_microcode(state, state->microcode_name); /* disable token-ring bus through OFDM block for possible ucode upload */ diff --git a/drivers/media/dvb/ngene/ngene-cards.c b/drivers/media/dvb/ngene/ngene-cards.c index 8418c02bcef..7539a5d7102 100644 --- a/drivers/media/dvb/ngene/ngene-cards.c +++ b/drivers/media/dvb/ngene/ngene-cards.c @@ -216,6 +216,7 @@ static int demod_attach_drxk(struct ngene_channel *chan, struct drxk_config config; memset(&config, 0, sizeof(config)); + config.microcode_name = "drxk_a3.mc"; config.adr = 0x29 + (chan->number ^ 2); chan->fe = dvb_attach(drxk_attach, &config, i2c); -- cgit v1.2.3-70-g09d2 From c108a5a0ef1fc20f7ae36318dd154f40dcf1d345 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 25 Jul 2011 10:38:20 -0300 Subject: [media] az6007: need to define drivers name before including dvb-usb.h Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 523972f9ef5..87dff933289 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -23,9 +23,9 @@ #include "drxk.h" #include "mt2063.h" #include "dvb_ca_en50221.h" -#include "dvb-usb.h" #define DVB_USB_LOG_PREFIX "az6007" +#include "dvb-usb.h" /* debug */ int dvb_usb_az6007_debug; -- cgit v1.2.3-70-g09d2 From 81091144ebdb7bdc6197559cd3547d8be7e4e18e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 25 Jul 2011 11:07:20 -0300 Subject: [media] az6007: Fix some init sequences and use the right firmwares Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 105 +++++++++++++++---------------------- 1 file changed, 43 insertions(+), 62 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 87dff933289..03e318d2d4b 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -56,7 +56,8 @@ static struct drxk_config terratec_h7_drxk = { .single_master = 1, .no_i2c_bridge = 0, .max_size = 64, -// .microcode_name = "dvb-usb-terratec-h5-drxk.fw", + .microcode_name = "dvb-usb-terratec-h7-drxk.fw", + .parallel_ts = 1, }; static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) @@ -200,53 +201,31 @@ static int az6007_read_mac_addr(struct dvb_usb_device *d, u8 mac[6]) return 0; } +#define AZ6007_POWER 0xbc +#define FX2_SCON1 0xc0 +#define AZ6007_TS_THROUGH 0xc7 + static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) { - int ret; - u8 req; - u16 value; - u16 index; - int blen; + struct dvb_usb_device *d = adap->dev; deb_info("az6007_frontend_poweron adap=%p adap->dev=%p\n", adap, adap->dev); - req = 0xBC; - value = 1; /* power on */ - index = 3; - blen = 0; - - ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); - if (ret != 0) { - err("az6007_frontend_poweron failed!!!"); - return -EIO; - } - - msleep_interruptible(200); - - req = 0xBC; - value = 0; /* power off */ - index = 3; - blen = 0; - - ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); - if (ret != 0) { - err("az6007_frontend_poweron failed!!!"); - return -EIO; - } - - msleep_interruptible(200); - - req = 0xBC; - value = 1; /* power on */ - index = 3; - blen = 0; + az6007_usb_out_op(d, AZ6007_POWER /* 0xbc */, 0, 2, NULL, 0); + msleep(150); + az6007_usb_out_op(d, AZ6007_POWER /* 0xbc */, 1, 4, NULL, 0); + msleep(100); + az6007_usb_out_op(d, AZ6007_POWER /* 0xbc */, 1, 3, NULL, 0); + msleep(100); + az6007_usb_out_op(d, AZ6007_POWER /* 0xbc */, 1, 4, NULL, 0); + msleep(100); + az6007_usb_out_op(d, FX2_SCON1 /* 0xc0 */, 0, 3, NULL, 0); + msleep (10); + az6007_usb_out_op(d, FX2_SCON1 /* 0xc0 */, 1, 3, NULL, 0); + msleep (10); + az6007_usb_out_op(d, AZ6007_POWER /* 0xbc */, 0, 0, NULL, 0); - ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); - if (ret != 0) { - err("az6007_frontend_poweron failed!!!"); - return -EIO; - } deb_info("az6007_frontend_poweron: OK\n"); return 0; @@ -333,25 +312,6 @@ static int az6007_led_on_off(struct usb_interface *intf, int onoff) return ret; } -static int az6007_frontend_tsbypass(struct dvb_usb_adapter *adap, int onoff) -{ - int ret; - u8 req; - u16 value; - u16 index; - int blen; - /* TS through */ - req = 0xC7; - value = onoff; - index = 0; - blen = 0; - - ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); - if (ret != 0) - return -EIO; - return 0; -} - static int az6007_frontend_attach(struct dvb_usb_adapter *adap) { struct az6007_device_state *st = adap->priv; @@ -409,6 +369,27 @@ out_free: return result; } +int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) +{ + if (!onoff) + return 0; + + + info("Sending poweron sequence"); + + az6007_usb_out_op(d, AZ6007_TS_THROUGH /* 0xc7 */, 0, 0, NULL, 0); + +#if 0 + // Seems to be a poweroff sequence + az6007_usb_out_op(d, 0xbc, 1, 3, NULL, 0); + az6007_usb_out_op(d, 0xbc, 1, 4, NULL, 0); + az6007_usb_out_op(d, 0xc0, 0, 3, NULL, 0); + az6007_usb_out_op(d, 0xc0, 1, 3, NULL, 0); + az6007_usb_out_op(d, 0xbc, 0, 1, NULL, 0); +#endif + return 0; +} + static struct dvb_usb_device_properties az6007_properties; static void az6007_usb_disconnect(struct usb_interface *intf) @@ -568,7 +549,7 @@ MODULE_DEVICE_TABLE(usb, az6007_usb_table); static struct dvb_usb_device_properties az6007_properties = { .caps = DVB_USB_IS_AN_I2C_ADAPTER, .usb_ctrl = CYPRESS_FX2, - .firmware = "dvb-usb-az6007-03.fw", + .firmware = "dvb-usb-terratec-h7-az6007.fw", .no_reconnect = 1, .identify_state = az6007_identify_state, @@ -592,7 +573,7 @@ static struct dvb_usb_device_properties az6007_properties = { .size_of_priv = sizeof(struct az6007_device_state), } }, - /* .power_ctrl = az6007_power_ctrl, */ + .power_ctrl = az6007_power_ctrl, .read_mac_address = az6007_read_mac_addr, .rc.legacy = { -- cgit v1.2.3-70-g09d2 From 3af2f4f15a61b55469a8512d186221eaf7652eec Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 25 Jul 2011 11:17:41 -0300 Subject: [media] az6007: Change the az6007 read/write routine parameter Use usb_device for those routines, as it allows using them on all places. While there, rename to better express the meaning. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 56 +++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 03e318d2d4b..f098e47102e 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -96,13 +96,13 @@ static struct mt2063_config az6007_mt2063_config = { }; /* check for mutex FIXME */ -static int az6007_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, +static int az6007_read(struct usb_device *udev, u8 req, u16 value, u16 index, u8 *b, int blen) { int ret = -1; - ret = usb_control_msg(d->udev, - usb_rcvctrlpipe(d->udev, 0), + ret = usb_control_msg(udev, + usb_rcvctrlpipe(udev, 0), req, USB_TYPE_VENDOR | USB_DIR_IN, value, index, b, blen, 5000); @@ -119,7 +119,7 @@ static int az6007_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, return ret; } -static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, +static int az6007_write(struct usb_device *udev, u8 req, u16 value, u16 index, u8 *b, int blen) { int ret; @@ -134,8 +134,8 @@ static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, return -EOPNOTSUPP; } - ret = usb_control_msg(d->udev, - usb_sndctrlpipe(d->udev, 0), + ret = usb_control_msg(udev, + usb_sndctrlpipe(udev, 0), req, USB_TYPE_VENDOR | USB_DIR_OUT, value, index, b, blen, 5000); @@ -168,7 +168,7 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) /* remove the following return to enabled remote querying */ - az6007_usb_in_op(d, READ_REMOTE_REQ, 0, 0, key, 10); + az6007_read(d->udev, READ_REMOTE_REQ, 0, 0, key, 10); deb_rc("remote query key: %x %d\n", key[1], key[1]); @@ -191,13 +191,13 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) { u8 v = onoff; - return az6007_usb_out_op(d,0xBC,v,3,NULL,1); + return az6007_write(d->udev,0xBC,v,3,NULL,1); } */ static int az6007_read_mac_addr(struct dvb_usb_device *d, u8 mac[6]) { - az6007_usb_in_op(d, 0xb7, 6, 0, &mac[0], 6); + az6007_read(d->udev, 0xb7, 6, 0, &mac[0], 6); return 0; } @@ -212,19 +212,19 @@ static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) deb_info("az6007_frontend_poweron adap=%p adap->dev=%p\n", adap, adap->dev); - az6007_usb_out_op(d, AZ6007_POWER /* 0xbc */, 0, 2, NULL, 0); + az6007_write(d->udev, AZ6007_POWER /* 0xbc */, 0, 2, NULL, 0); msleep(150); - az6007_usb_out_op(d, AZ6007_POWER /* 0xbc */, 1, 4, NULL, 0); + az6007_write(d->udev, AZ6007_POWER /* 0xbc */, 1, 4, NULL, 0); msleep(100); - az6007_usb_out_op(d, AZ6007_POWER /* 0xbc */, 1, 3, NULL, 0); + az6007_write(d->udev, AZ6007_POWER /* 0xbc */, 1, 3, NULL, 0); msleep(100); - az6007_usb_out_op(d, AZ6007_POWER /* 0xbc */, 1, 4, NULL, 0); + az6007_write(d->udev, AZ6007_POWER /* 0xbc */, 1, 4, NULL, 0); msleep(100); - az6007_usb_out_op(d, FX2_SCON1 /* 0xc0 */, 0, 3, NULL, 0); + az6007_write(d->udev, FX2_SCON1 /* 0xc0 */, 0, 3, NULL, 0); msleep (10); - az6007_usb_out_op(d, FX2_SCON1 /* 0xc0 */, 1, 3, NULL, 0); + az6007_write(d->udev, FX2_SCON1 /* 0xc0 */, 1, 3, NULL, 0); msleep (10); - az6007_usb_out_op(d, AZ6007_POWER /* 0xbc */, 0, 0, NULL, 0); + az6007_write(d->udev, AZ6007_POWER /* 0xbc */, 0, 0, NULL, 0); deb_info("az6007_frontend_poweron: OK\n"); @@ -246,7 +246,7 @@ static int az6007_frontend_reset(struct dvb_usb_adapter *adap) value = 1; /* high */ index = 3; blen = 0; - ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); + ret = az6007_write(adap->dev->udev, req, value, index, NULL, blen); if (ret != 0) { err("az6007_frontend_reset failed 1 !!!"); return -EIO; @@ -257,7 +257,7 @@ static int az6007_frontend_reset(struct dvb_usb_adapter *adap) index = 3; blen = 0; msleep_interruptible(200); - ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); + ret = az6007_write(adap->dev->udev, req, value, index, NULL, blen); if (ret != 0) { err("az6007_frontend_reset failed 2 !!!"); return -EIO; @@ -268,7 +268,7 @@ static int az6007_frontend_reset(struct dvb_usb_adapter *adap) index = 3; blen = 0; - ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); + ret = az6007_write(adap->dev->udev, req, value, index, NULL, blen); if (ret != 0) { err("az6007_frontend_reset failed 3 !!!"); return -EIO; @@ -377,15 +377,15 @@ int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) info("Sending poweron sequence"); - az6007_usb_out_op(d, AZ6007_TS_THROUGH /* 0xc7 */, 0, 0, NULL, 0); + az6007_write(d->udev, AZ6007_TS_THROUGH /* 0xc7 */, 0, 0, NULL, 0); #if 0 // Seems to be a poweroff sequence - az6007_usb_out_op(d, 0xbc, 1, 3, NULL, 0); - az6007_usb_out_op(d, 0xbc, 1, 4, NULL, 0); - az6007_usb_out_op(d, 0xc0, 0, 3, NULL, 0); - az6007_usb_out_op(d, 0xc0, 1, 3, NULL, 0); - az6007_usb_out_op(d, 0xbc, 0, 1, NULL, 0); + az6007_write(d->udev, 0xbc, 1, 3, NULL, 0); + az6007_write(d->udev, 0xbc, 1, 4, NULL, 0); + az6007_write(d->udev, 0xc0, 0, 3, NULL, 0); + az6007_write(d->udev, 0xc0, 1, 3, NULL, 0); + az6007_write(d->udev, 0xbc, 0, 1, NULL, 0); #endif return 0; } @@ -434,7 +434,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], value = addr | (1 << 8); length = 6 + msgs[i + 1].len; len = msgs[i + 1].len; - ret = az6007_usb_in_op(d, req, value, index, data, + ret = az6007_read(d->udev, req, value, index, data, length); if (ret >= len) { for (j = 0; j < len; j++) { @@ -465,7 +465,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], if (dvb_usb_az6007_debug & 2) printk(KERN_CONT "0x%02x ", data[j]); } - ret = az6007_usb_out_op(d, req, value, index, data, + ret = az6007_write(d->udev, req, value, index, data, length); } else { /* read bytes */ @@ -478,7 +478,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], value = addr; length = msgs[i].len + 6; len = msgs[i].len; - ret = az6007_usb_in_op(d, req, value, index, data, + ret = az6007_read(d->udev, req, value, index, data, length); for (j = 0; j < len; j++) { msgs[i].buf[j] = data[j + 5]; -- cgit v1.2.3-70-g09d2 From 3aecf2c5a9881024dc7742568146e2f9a10f19a6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 25 Jul 2011 12:45:16 -0300 Subject: [media] az6007: Simplify the read/write logic This patch introduces no functional changes. It basically defines a macro for each different req found at the driver, and cleans the code to use them, making easier to understand the code. With regards to the IR handling code, although the original code doesn't define what's the request, it is clear, from the USB logs, that 0xc5 is for IR polling. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 185 +++++++++++++++++-------------------- 1 file changed, 87 insertions(+), 98 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index f098e47102e..8add81ade08 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -40,6 +40,17 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); +/* Known requests (Cypress FX2 firmware + az6007 "private" ones*/ + +#define FX2_OED 0xb5 +#define AZ6007_READ_DATA 0xb7 +#define AZ6007_I2C_RD 0xb9 +#define AZ6007_POWER 0xbc +#define AZ6007_I2C_WR 0xbd +#define FX2_SCON1 0xc0 +#define AZ6007_TS_THROUGH 0xc7 +#define AZ6007_READ_IR 0xc5 + struct az6007_device_state { struct dvb_ca_en50221 ca; struct mutex ca_mutex; @@ -168,7 +179,7 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) /* remove the following return to enabled remote querying */ - az6007_read(d->udev, READ_REMOTE_REQ, 0, 0, key, 10); + az6007_read(d->udev, AZ6007_READ_IR, 0, 0, key, 10); deb_rc("remote query key: %x %d\n", key[1], key[1]); @@ -187,127 +198,104 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) #endif } -/* +#if 0 int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) { u8 v = onoff; - return az6007_write(d->udev,0xBC,v,3,NULL,1); + return az6007_write(d->udev, AZ6007_POWER, v , 3, NULL, 1); } -*/ +#endif static int az6007_read_mac_addr(struct dvb_usb_device *d, u8 mac[6]) { - az6007_read(d->udev, 0xb7, 6, 0, &mac[0], 6); - return 0; -} + int ret; + ret = az6007_read(d->udev, AZ6007_READ_DATA, 6, 0, mac, 6); -#define AZ6007_POWER 0xbc -#define FX2_SCON1 0xc0 -#define AZ6007_TS_THROUGH 0xc7 + if (ret > 0) + deb_info("%s: mac is %02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, mac[0], mac[1], mac[2], + mac[3], mac[4], mac[5]); + + return ret; +} static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) { - struct dvb_usb_device *d = adap->dev; + int ret; + struct usb_device *udev = adap->dev->udev; - deb_info("az6007_frontend_poweron adap=%p adap->dev=%p\n", - adap, adap->dev); + deb_info("%s: adap=%p adap->dev=%p\n", __func__, adap, adap->dev); - az6007_write(d->udev, AZ6007_POWER /* 0xbc */, 0, 2, NULL, 0); + ret = az6007_write(udev, AZ6007_POWER, 0, 2, NULL, 0); + if (ret < 0) + goto error; msleep(150); - az6007_write(d->udev, AZ6007_POWER /* 0xbc */, 1, 4, NULL, 0); + ret = az6007_write(udev, AZ6007_POWER, 1, 4, NULL, 0); + if (ret < 0) + goto error; msleep(100); - az6007_write(d->udev, AZ6007_POWER /* 0xbc */, 1, 3, NULL, 0); + ret = az6007_write(udev, AZ6007_POWER, 1, 3, NULL, 0); + if (ret < 0) + goto error; msleep(100); - az6007_write(d->udev, AZ6007_POWER /* 0xbc */, 1, 4, NULL, 0); + ret = az6007_write(udev, AZ6007_POWER, 1, 4, NULL, 0); + if (ret < 0) + goto error; msleep(100); - az6007_write(d->udev, FX2_SCON1 /* 0xc0 */, 0, 3, NULL, 0); + ret = az6007_write(udev, FX2_SCON1, 0, 3, NULL, 0); + if (ret < 0) + goto error; msleep (10); - az6007_write(d->udev, FX2_SCON1 /* 0xc0 */, 1, 3, NULL, 0); + ret = az6007_write(udev, FX2_SCON1, 1, 3, NULL, 0); + if (ret < 0) + goto error; msleep (10); - az6007_write(d->udev, AZ6007_POWER /* 0xbc */, 0, 0, NULL, 0); + ret = az6007_write(udev, AZ6007_POWER, 0, 0, NULL, 0); - deb_info("az6007_frontend_poweron: OK\n"); +error: + if (ret < 0) + err("%s failed with error %d", __func__, ret); - return 0; + return ret; } static int az6007_frontend_reset(struct dvb_usb_adapter *adap) { + struct usb_device *udev = adap->dev->udev; int ret; - u8 req; - u16 value; - u16 index; - int blen; deb_info("az6007_frontend_reset adap=%p adap->dev=%p\n", adap, adap->dev); /* reset demodulator */ - req = 0xC0; - value = 1; /* high */ - index = 3; - blen = 0; - ret = az6007_write(adap->dev->udev, req, value, index, NULL, blen); - if (ret != 0) { - err("az6007_frontend_reset failed 1 !!!"); - return -EIO; - } + ret = az6007_write(udev, FX2_SCON1, 1, 3, NULL, 0); + if (ret < 0) + goto error; + msleep(200); + ret = az6007_write(udev, FX2_SCON1, 0, 3, NULL, 0); + if (ret < 0) + goto error; + msleep(200); + ret = az6007_write(udev, FX2_SCON1, 1, 3, NULL, 0); + if (ret < 0) + goto error; + msleep(200); + +error: + if (ret < 0) + err("%s failed with error %d", __func__, ret); - req = 0xC0; - value = 0; /* low */ - index = 3; - blen = 0; - msleep_interruptible(200); - ret = az6007_write(adap->dev->udev, req, value, index, NULL, blen); - if (ret != 0) { - err("az6007_frontend_reset failed 2 !!!"); - return -EIO; - } - msleep_interruptible(200); - req = 0xC0; - value = 1; /* high */ - index = 3; - blen = 0; - - ret = az6007_write(adap->dev->udev, req, value, index, NULL, blen); - if (ret != 0) { - err("az6007_frontend_reset failed 3 !!!"); - return -EIO; - } - - msleep_interruptible(200); - - deb_info("reset az6007 frontend\n"); - - return 0; + return ret; } static int az6007_led_on_off(struct usb_interface *intf, int onoff) { - int ret = -1; - u8 req; - u16 value; - u16 index; - int blen; - /* TS through */ - req = 0xBC; - value = onoff; - index = 0; - blen = 0; - - ret = usb_control_msg(interface_to_usbdev(intf), - usb_rcvctrlpipe(interface_to_usbdev(intf), 0), - req, - USB_TYPE_VENDOR | USB_DIR_OUT, - value, index, NULL, blen, 2000); - - if (ret < 0) { - warn("usb in operation failed. (%d)", ret); - ret = -EIO; - } else - ret = 0; + struct usb_device *udev = interface_to_usbdev(intf); + int ret; - deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, - index); + /* TS through */ + ret = az6007_write(udev, AZ6007_POWER, onoff, 0, NULL, 0); + if (ret < 0) + err("%s failed with error %d", __func__, ret); return ret; } @@ -377,7 +365,7 @@ int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) info("Sending poweron sequence"); - az6007_write(d->udev, AZ6007_TS_THROUGH /* 0xc7 */, 0, 0, NULL, 0); + az6007_write(d->udev, AZ6007_TS_THROUGH, 0, 0, NULL, 0); #if 0 // Seems to be a poweroff sequence @@ -429,7 +417,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], printk(KERN_DEBUG "az6007 I2C xfer write+read addr=0x%x len=%d/%d: ", addr, msgs[i].len, msgs[i + 1].len); - req = 0xb9; + req = AZ6007_I2C_RD; index = msgs[i].buf[0]; value = addr | (1 << 8); length = 6 + msgs[i + 1].len; @@ -453,7 +441,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], printk(KERN_DEBUG "az6007 I2C xfer write addr=0x%x len=%d: ", addr, msgs[i].len); - req = 0xbd; + req = AZ6007_I2C_WR; index = msgs[i].buf[0]; value = addr | (1 << 8); length = msgs[i].len - 1; @@ -473,7 +461,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], printk(KERN_DEBUG "az6007 I2C xfer read addr=0x%x len=%d: ", addr, msgs[i].len); - req = 0xb9; + req = AZ6007_I2C_RD; index = msgs[i].buf[0]; value = addr; length = msgs[i].len + 6; @@ -516,16 +504,17 @@ int az6007_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, struct dvb_usb_device_description **desc, int *cold) { - u8 b[16]; - s16 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - 0xb7, USB_TYPE_VENDOR | USB_DIR_IN, 6, 0, b, - 6, USB_CTRL_GET_TIMEOUT); - - deb_info("FW GET_VERSION length: %d\n", ret); + int ret; + u8 mac[6]; - *cold = ret <= 0; + /* Try to read the mac address */ + ret = az6007_read(udev, AZ6007_READ_DATA, 6, 0, mac, 6); + if (ret == 6) + *cold = 0; + else + *cold = 1; - deb_info("cold: %d\n", *cold); + deb_info("Device is on %s state\n", *cold? "warm" : "cold"); return 0; } -- cgit v1.2.3-70-g09d2 From ba02473eaaaa9e579a4bdbe9f15a5ad777764580 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 25 Jul 2011 12:49:46 -0300 Subject: [media] az6007: Simplify the code by removing an uneeded function Everything to reset the demod is already at az6007_frontend_poweron(). Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 29 ----------------------------- 1 file changed, 29 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 8add81ade08..912ba67bc39 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -259,34 +259,6 @@ error: return ret; } -static int az6007_frontend_reset(struct dvb_usb_adapter *adap) -{ - struct usb_device *udev = adap->dev->udev; - int ret; - - deb_info("az6007_frontend_reset adap=%p adap->dev=%p\n", adap, adap->dev); - - /* reset demodulator */ - ret = az6007_write(udev, FX2_SCON1, 1, 3, NULL, 0); - if (ret < 0) - goto error; - msleep(200); - ret = az6007_write(udev, FX2_SCON1, 0, 3, NULL, 0); - if (ret < 0) - goto error; - msleep(200); - ret = az6007_write(udev, FX2_SCON1, 1, 3, NULL, 0); - if (ret < 0) - goto error; - msleep(200); - -error: - if (ret < 0) - err("%s failed with error %d", __func__, ret); - - return ret; -} - static int az6007_led_on_off(struct usb_interface *intf, int onoff) { struct usb_device *udev = interface_to_usbdev(intf); @@ -309,7 +281,6 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) BUG_ON(!st); az6007_frontend_poweron(adap); - az6007_frontend_reset(adap); info("az6007: attaching demod drxk"); adap->fe = dvb_attach(drxk_attach, &terratec_h7_drxk, -- cgit v1.2.3-70-g09d2 From 2d5161b7714ae75ac62cd58bf4c5c11ca6c2da59 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 29 Jul 2011 11:31:13 -0300 Subject: [media] az6007: Fix IR receive code The code still needs to be commented, as there's a mutex missing at the az6007_read() call. A mutex there is needed, in order to prevent RC (or CI) calls while other operations are in progress. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 912ba67bc39..c9743ee2ba7 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -49,7 +49,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); #define AZ6007_I2C_WR 0xbd #define FX2_SCON1 0xc0 #define AZ6007_TS_THROUGH 0xc7 -#define AZ6007_READ_IR 0xc5 +#define AZ6007_READ_IR 0xb4 struct az6007_device_state { struct dvb_ca_en50221 ca; @@ -172,30 +172,45 @@ static struct rc_map_table rc_map_az6007_table[] = { /* remote control stuff (does not work with my box) */ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) { - return 0; -#if 0 + struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table; u8 key[10]; int i; - /* remove the following return to enabled remote querying */ + /* + * FIXME: remove the following return to enabled remote querying + * The driver likely needs proper locking to avoid troubles between + * this call and other concurrent calls. + */ + return 0; az6007_read(d->udev, AZ6007_READ_IR, 0, 0, key, 10); - deb_rc("remote query key: %x %d\n", key[1], key[1]); - if (key[1] == 0x44) { *state = REMOTE_NO_KEY_PRESSED; return 0; } - for (i = 0; i < ARRAY_SIZE(az6007_rc_keys); i++) - if (az6007_rc_keys[i].custom == key[1]) { + /* + * FIXME: need to make something useful with the keycodes and to + * convert it to the non-legacy mode. Yet, it is producing some + * debug info already, like: + * 88 04 eb 02 fd ff 00 82 63 82 (terratec IR) + * 88 04 eb 03 fc 00 00 82 63 82 (terratec IR) + * 88 80 7e 0d f2 ff 00 82 63 82 (another NEC-extended based IR) + * I suspect that the IR data is at bytes 1 to 4, and byte 5 is parity + */ + deb_rc("remote query key: %x %d\n", key[1], key[1]); + print_hex_dump_bytes("Remote: ", DUMP_PREFIX_NONE, key, 10); + + for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) { + if (rc5_custom(&keymap[i]) == key[1]) { + *event = keymap[i].keycode; *state = REMOTE_KEY_PRESSED; - *event = az6007_rc_keys[i].event; - break; + + return 0; } + } return 0; -#endif } #if 0 -- cgit v1.2.3-70-g09d2 From 9b01f3d498a9f39de1824609c08edbd137b774b6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 29 Jul 2011 11:40:40 -0300 Subject: [media] az6007: improve the error messages for az6007 read/write calls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index c9743ee2ba7..c9b6f807790 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -110,16 +110,15 @@ static struct mt2063_config az6007_mt2063_config = { static int az6007_read(struct usb_device *udev, u8 req, u16 value, u16 index, u8 *b, int blen) { - int ret = -1; + int ret; ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), req, USB_TYPE_VENDOR | USB_DIR_IN, value, index, b, blen, 5000); - if (ret < 0) { - warn("usb in operation failed. (%d)", ret); + warn("usb read operation failed. (%d)", ret); return -EIO; } @@ -151,7 +150,7 @@ static int az6007_write(struct usb_device *udev, u8 req, u16 value, USB_TYPE_VENDOR | USB_DIR_OUT, value, index, b, blen, 5000); if (ret != blen) { - err("usb out operation failed. (%d)", ret); + err("usb write operation failed. (%d)", ret); return -EIO; } -- cgit v1.2.3-70-g09d2 From 1c9a284fbd3d25dc1a1a1da32be1eaff021c4029 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 31 Jul 2011 10:11:32 -0300 Subject: [media] az6007: Use the new MFE support at dvb-usb Use the newly dvb-usb MFE support added by changeset 9bd9e3bd2c57530dfe3057dd0aa9bdb37824925d. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 74 +++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index c9b6f807790..b667854bdbf 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -59,7 +59,7 @@ struct az6007_device_state { /* Due to DRX-K - probably need changes */ int (*gate_ctrl) (struct dvb_frontend *, int); struct semaphore pll_mutex; - bool dont_attach_fe1; + bool tuner_attached; }; static struct drxk_config terratec_h7_drxk = { @@ -290,56 +290,56 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) { struct az6007_device_state *st = adap->priv; - int result; + /* FIXME: dvb-usb will call this function twice! */ + if (adap->fe[0]) + return 0; BUG_ON(!st); az6007_frontend_poweron(adap); - info("az6007: attaching demod drxk"); - adap->fe = dvb_attach(drxk_attach, &terratec_h7_drxk, - &adap->dev->i2c_adap, &adap->fe2); - if (!adap->fe) { - result = -EINVAL; - goto out_free; - } - - deb_info("Setting hacks\n"); + info("attaching demod drxk"); + adap->fe[0] = dvb_attach(drxk_attach, &terratec_h7_drxk, + &adap->dev->i2c_adap, &adap->fe[1]); + if (!adap->fe[0]) + return -EINVAL; + adap->fe[0]->sec_priv = adap; /* FIXME: do we need a pll semaphore? */ - adap->fe->sec_priv = adap; sema_init(&st->pll_mutex, 1); - st->gate_ctrl = adap->fe->ops.i2c_gate_ctrl; - adap->fe->ops.i2c_gate_ctrl = drxk_gate_ctrl; - adap->fe2->id = 1; + st->gate_ctrl = adap->fe[0]->ops.i2c_gate_ctrl; + adap->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl; + adap->dont_attach_fe[1] = true; + + return 0; +} + +static int az6007_tuner_attach(struct dvb_usb_adapter *adap) +{ + struct az6007_device_state *st = adap->priv; + + if (st->tuner_attached) + return 0; + + st->tuner_attached = true; - info("az6007: attaching tuner mt2063"); + info("attaching tuner mt2063"); /* Attach mt2063 to DVB-C frontend */ - if (adap->fe->ops.i2c_gate_ctrl) - adap->fe->ops.i2c_gate_ctrl(adap->fe, 1); - if (!dvb_attach(mt2063_attach, adap->fe, &az6007_mt2063_config, - &adap->dev->i2c_adap)) { - result = -EINVAL; + if (adap->fe[0]->ops.i2c_gate_ctrl) + adap->fe[0]->ops.i2c_gate_ctrl(adap->fe[0], 1); + if (!dvb_attach(mt2063_attach, adap->fe[0], &az6007_mt2063_config, + &adap->dev->i2c_adap)) + return -EINVAL; - goto out_free; - } - if (adap->fe->ops.i2c_gate_ctrl) - adap->fe->ops.i2c_gate_ctrl(adap->fe, 0); + if (adap->fe[0]->ops.i2c_gate_ctrl) + adap->fe[0]->ops.i2c_gate_ctrl(adap->fe[0], 0); /* Hack - needed due to drxk */ - adap->fe2->tuner_priv = adap->fe->tuner_priv; - memcpy(&adap->fe2->ops.tuner_ops, - &adap->fe->ops.tuner_ops, sizeof(adap->fe->ops.tuner_ops)); + adap->fe[1]->tuner_priv = adap->fe[0]->tuner_priv; + memcpy(&adap->fe[1]->ops.tuner_ops, + &adap->fe[0]->ops.tuner_ops, sizeof(adap->fe[0]->ops.tuner_ops)); return 0; - -out_free: - if (adap->fe) - dvb_frontend_detach(adap->fe); - adap->fe = NULL; - adap->fe2 = NULL; - - return result; } int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) @@ -530,7 +530,9 @@ static struct dvb_usb_device_properties az6007_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 2, .streaming_ctrl = az6007_streaming_ctrl, + .tuner_attach = az6007_tuner_attach, .frontend_attach = az6007_frontend_attach, /* parameter for the MPEG2-data transfer */ -- cgit v1.2.3-70-g09d2 From 781dacc82ac8105e19dd62e76b8d4278e680af81 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 16 Jan 2012 18:57:51 -0300 Subject: [media] az6007: Change it to use the MFE solution adopted at dvb-usb This driver were written to use a previous solution for MFE at dvb-usb. Due to the internal API changes, change the binding to work with the new way. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 42 +++++++++++++++----------------------- 1 file changed, 17 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index b667854bdbf..92ded30b2cc 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -66,7 +66,7 @@ static struct drxk_config terratec_h7_drxk = { .adr = 0x29, .single_master = 1, .no_i2c_bridge = 0, - .max_size = 64, + .chunk_size = 64, .microcode_name = "dvb-usb-terratec-h7-drxk.fw", .parallel_ts = 1, }; @@ -290,26 +290,21 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) { struct az6007_device_state *st = adap->priv; - /* FIXME: dvb-usb will call this function twice! */ - if (adap->fe[0]) - return 0; - BUG_ON(!st); az6007_frontend_poweron(adap); info("attaching demod drxk"); - adap->fe[0] = dvb_attach(drxk_attach, &terratec_h7_drxk, - &adap->dev->i2c_adap, &adap->fe[1]); - if (!adap->fe[0]) + adap->fe_adap[0].fe = dvb_attach(drxk_attach, &terratec_h7_drxk, + &adap->dev->i2c_adap); + if (!adap->fe_adap[0].fe) return -EINVAL; - adap->fe[0]->sec_priv = adap; + adap->fe_adap[0].fe->sec_priv = adap; /* FIXME: do we need a pll semaphore? */ sema_init(&st->pll_mutex, 1); - st->gate_ctrl = adap->fe[0]->ops.i2c_gate_ctrl; - adap->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl; - adap->dont_attach_fe[1] = true; + st->gate_ctrl = adap->fe_adap[0].fe->ops.i2c_gate_ctrl; + adap->fe_adap[0].fe->ops.i2c_gate_ctrl = drxk_gate_ctrl; return 0; } @@ -325,19 +320,15 @@ static int az6007_tuner_attach(struct dvb_usb_adapter *adap) info("attaching tuner mt2063"); /* Attach mt2063 to DVB-C frontend */ - if (adap->fe[0]->ops.i2c_gate_ctrl) - adap->fe[0]->ops.i2c_gate_ctrl(adap->fe[0], 1); - if (!dvb_attach(mt2063_attach, adap->fe[0], &az6007_mt2063_config, + if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl) + adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 1); + if (!dvb_attach(mt2063_attach, adap->fe_adap[0].fe, + &az6007_mt2063_config, &adap->dev->i2c_adap)) return -EINVAL; - if (adap->fe[0]->ops.i2c_gate_ctrl) - adap->fe[0]->ops.i2c_gate_ctrl(adap->fe[0], 0); - - /* Hack - needed due to drxk */ - adap->fe[1]->tuner_priv = adap->fe[0]->tuner_priv; - memcpy(&adap->fe[1]->ops.tuner_ops, - &adap->fe[0]->ops.tuner_ops, sizeof(adap->fe[0]->ops.tuner_ops)); + if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl) + adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 0); return 0; } @@ -530,7 +521,8 @@ static struct dvb_usb_device_properties az6007_properties = { .num_adapters = 1, .adapter = { { - .num_frontends = 2, + .num_frontends = 1, + .fe = {{ .streaming_ctrl = az6007_streaming_ctrl, .tuner_attach = az6007_tuner_attach, .frontend_attach = az6007_frontend_attach, @@ -547,8 +539,8 @@ static struct dvb_usb_device_properties az6007_properties = { } }, .size_of_priv = sizeof(struct az6007_device_state), - } - }, + }} + } }, .power_ctrl = az6007_power_ctrl, .read_mac_address = az6007_read_mac_addr, -- cgit v1.2.3-70-g09d2 From 978c26c3672a15fd545da2e927467b5b6bd67acb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 16 Jan 2012 20:37:13 -0300 Subject: [media] az6007: Use a per device private struct Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 92ded30b2cc..342f9292c17 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -82,7 +82,7 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) if (!adap) return -EINVAL; - st = adap->priv; + st = adap->dev->priv; if (!st) return -EINVAL; @@ -288,7 +288,7 @@ static int az6007_led_on_off(struct usb_interface *intf, int onoff) static int az6007_frontend_attach(struct dvb_usb_adapter *adap) { - struct az6007_device_state *st = adap->priv; + struct az6007_device_state *st = adap->dev->priv; BUG_ON(!st); @@ -311,7 +311,7 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) static int az6007_tuner_attach(struct dvb_usb_adapter *adap) { - struct az6007_device_state *st = adap->priv; + struct az6007_device_state *st = adap->dev->priv; if (st->tuner_attached) return 0; @@ -516,8 +516,8 @@ static struct dvb_usb_device_properties az6007_properties = { .usb_ctrl = CYPRESS_FX2, .firmware = "dvb-usb-terratec-h7-az6007.fw", .no_reconnect = 1, - - .identify_state = az6007_identify_state, + .size_of_priv = sizeof(struct az6007_device_state), + .identify_state = az6007_identify_state, .num_adapters = 1, .adapter = { { @@ -538,7 +538,6 @@ static struct dvb_usb_device_properties az6007_properties = { } } }, - .size_of_priv = sizeof(struct az6007_device_state), }} } }, .power_ctrl = az6007_power_ctrl, -- cgit v1.2.3-70-g09d2 From 67f04617377ecd4ee1547fd9ab3a97af38d572d0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 20 Jan 2012 18:30:58 -0300 Subject: [media] drxk: Allow setting it on dynamic_clock mode This is used on az6007. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/drxk.h | 17 ++++++++++------- drivers/media/dvb/frontends/drxk_hard.c | 14 +++++++++----- 2 files changed, 19 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/frontends/drxk.h b/drivers/media/dvb/frontends/drxk.h index 020981844a8..6b0fd2c5dcd 100644 --- a/drivers/media/dvb/frontends/drxk.h +++ b/drivers/media/dvb/frontends/drxk.h @@ -7,15 +7,17 @@ /** * struct drxk_config - Configure the initial parameters for DRX-K * - * adr: I2C Address of the DRX-K - * parallel_ts: true means that the device uses parallel TS, + * @adr: I2C Address of the DRX-K + * @parallel_ts: True means that the device uses parallel TS, * Serial otherwise. - * single_master: Device is on the single master mode - * no_i2c_bridge: Don't switch the I2C bridge to talk with tuner - * antenna_gpio: GPIO bit used to control the antenna - * antenna_dvbt: GPIO bit for changing antenna to DVB-C. A value of 1 + * @dynamic_clk: True means that the clock will be dynamically + * adjusted. Static clock otherwise. + * @single_master: Device is on the single master mode + * @no_i2c_bridge: Don't switch the I2C bridge to talk with tuner + * @antenna_gpio: GPIO bit used to control the antenna + * @antenna_dvbt: GPIO bit for changing antenna to DVB-C. A value of 1 * means that 1=DVBC, 0 = DVBT. Zero means the opposite. - * microcode_name: Name of the firmware file with the microcode + * @microcode_name: Name of the firmware file with the microcode * * On the *_gpio vars, bit 0 is UIO-1, bit 1 is UIO-2 and bit 2 is * UIO-3. @@ -25,6 +27,7 @@ struct drxk_config { bool single_master; bool no_i2c_bridge; bool parallel_ts; + bool dynamic_clk; bool antenna_dvbt; u16 antenna_gpio; diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c index 4b99255f7ba..65703968d8a 100644 --- a/drivers/media/dvb/frontends/drxk_hard.c +++ b/drivers/media/dvb/frontends/drxk_hard.c @@ -650,9 +650,6 @@ static int init_state(struct drxk_state *state) u32 ulQual83 = DEFAULT_MER_83; u32 ulQual93 = DEFAULT_MER_93; - u32 ulDVBTStaticTSClock = 1; - u32 ulDVBCStaticTSClock = 1; - u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT; u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT; @@ -815,8 +812,7 @@ static int init_state(struct drxk_state *state) state->m_invertSTR = false; /* If TRUE; invert STR signals */ state->m_invertVAL = false; /* If TRUE; invert VAL signals */ state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */ - state->m_DVBTStaticCLK = (ulDVBTStaticTSClock != 0); - state->m_DVBCStaticCLK = (ulDVBCStaticTSClock != 0); + /* If TRUE; static MPEG clockrate will be used; otherwise clockrate will adapt to the bitrate of the TS */ @@ -6390,6 +6386,14 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config, state->antenna_dvbt = config->antenna_dvbt; state->m_ChunkSize = config->chunk_size; + if (config->dynamic_clk) { + state->m_DVBTStaticCLK = 0; + state->m_DVBCStaticCLK = 0; + } else { + state->m_DVBTStaticCLK = 1; + state->m_DVBCStaticCLK = 1; + } + if (config->parallel_ts) state->m_enableParallel = true; else -- cgit v1.2.3-70-g09d2 From 6e5caf8493fabbb1c6aec1cb98adb9667182a1c6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 20 Jan 2012 18:36:26 -0300 Subject: [media] az6007: Use DRX-K dynamic clock mode Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 342f9292c17..00a0bf1c795 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -64,11 +64,12 @@ struct az6007_device_state { static struct drxk_config terratec_h7_drxk = { .adr = 0x29, - .single_master = 1, - .no_i2c_bridge = 0, + .parallel_ts = true, + .dynamic_clk = true, + .single_master = true, + .no_i2c_bridge = false, .chunk_size = 64, - .microcode_name = "dvb-usb-terratec-h7-drxk.fw", - .parallel_ts = 1, + .microcode_name = "dvb-usb-terratec-h7-az6007.fw", }; static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) -- cgit v1.2.3-70-g09d2 From 6fb65a66a227013ba1825efcf47e3c5df1a39131 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 20 Jan 2012 19:13:07 -0300 Subject: [media] drxk: add support for Mpeg output clock drive strength config Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 3 +-- drivers/media/dvb/frontends/drxk.h | 4 +++- drivers/media/dvb/frontends/drxk_hard.c | 12 ++++++------ 3 files changed, 10 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 00a0bf1c795..bf8d20151b0 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -69,6 +69,7 @@ static struct drxk_config terratec_h7_drxk = { .single_master = true, .no_i2c_bridge = false, .chunk_size = 64, + .mpeg_out_clk_strength = 0x02, .microcode_name = "dvb-usb-terratec-h7-az6007.fw", }; @@ -278,12 +279,10 @@ static int az6007_led_on_off(struct usb_interface *intf, int onoff) { struct usb_device *udev = interface_to_usbdev(intf); int ret; - /* TS through */ ret = az6007_write(udev, AZ6007_POWER, onoff, 0, NULL, 0); if (ret < 0) err("%s failed with error %d", __func__, ret); - return ret; } diff --git a/drivers/media/dvb/frontends/drxk.h b/drivers/media/dvb/frontends/drxk.h index 6b0fd2c5dcd..ca921c77f71 100644 --- a/drivers/media/dvb/frontends/drxk.h +++ b/drivers/media/dvb/frontends/drxk.h @@ -17,6 +17,7 @@ * @antenna_gpio: GPIO bit used to control the antenna * @antenna_dvbt: GPIO bit for changing antenna to DVB-C. A value of 1 * means that 1=DVBC, 0 = DVBT. Zero means the opposite. + * @mpeg_out_clk_strength: DRXK Mpeg output clock drive strength. * @microcode_name: Name of the firmware file with the microcode * * On the *_gpio vars, bit 0 is UIO-1, bit 1 is UIO-2 and bit 2 is @@ -32,7 +33,8 @@ struct drxk_config { bool antenna_dvbt; u16 antenna_gpio; - int chunk_size; + u8 mpeg_out_clk_strength; + int chunk_size; const char *microcode_name; }; diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c index 65703968d8a..d25b0d20038 100644 --- a/drivers/media/dvb/frontends/drxk_hard.c +++ b/drivers/media/dvb/frontends/drxk_hard.c @@ -91,10 +91,6 @@ bool IsA1WithRomCode(struct drxk_state *state) #define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03) #endif -#ifndef DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH -#define DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH (0x06) -#endif - #define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700 #define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500 @@ -659,7 +655,6 @@ static int init_state(struct drxk_state *state) u32 ulGPIOCfg = 0x0113; u32 ulInvertTSClock = 0; u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH; - u32 ulTSClockkStrength = DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH; u32 ulDVBTBitrate = 50000000; u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8; @@ -820,7 +815,6 @@ static int init_state(struct drxk_state *state) state->m_DVBCBitrate = ulDVBCBitrate; state->m_TSDataStrength = (ulTSDataStrength & 0x07); - state->m_TSClockkStrength = (ulTSClockkStrength & 0x07); /* Maximum bitrate in b/s in case static clockrate is selected */ state->m_mpegTsStaticBitrate = 19392658; @@ -6394,6 +6388,12 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config, state->m_DVBCStaticCLK = 1; } + + if (config->mpeg_out_clk_strength) + state->m_TSClockkStrength = config->mpeg_out_clk_strength & 0x07; + else + state->m_TSClockkStrength = 0x06; + if (config->parallel_ts) state->m_enableParallel = true; else -- cgit v1.2.3-70-g09d2 From d585681374ed23a707b572a1199d510e518d7522 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 21 Jan 2012 07:57:06 -0300 Subject: [media] drxk: Allow enabling MERR/MVAL cfg Those two settings are different when used with az6007. Add a config option to enable it. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 1 + drivers/media/dvb/frontends/drxk.h | 2 ++ drivers/media/dvb/frontends/drxk_hard.c | 11 +++++++++-- drivers/media/dvb/frontends/drxk_hard.h | 1 + 4 files changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index bf8d20151b0..81fdc90be44 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -67,6 +67,7 @@ static struct drxk_config terratec_h7_drxk = { .parallel_ts = true, .dynamic_clk = true, .single_master = true, + .enable_merr_cfg = true, .no_i2c_bridge = false, .chunk_size = 64, .mpeg_out_clk_strength = 0x02, diff --git a/drivers/media/dvb/frontends/drxk.h b/drivers/media/dvb/frontends/drxk.h index ca921c77f71..9d64e4fea06 100644 --- a/drivers/media/dvb/frontends/drxk.h +++ b/drivers/media/dvb/frontends/drxk.h @@ -12,6 +12,7 @@ * Serial otherwise. * @dynamic_clk: True means that the clock will be dynamically * adjusted. Static clock otherwise. + * @enable_merr_cfg: Enable SIO_PDR_PERR_CFG/SIO_PDR_MVAL_CFG. * @single_master: Device is on the single master mode * @no_i2c_bridge: Don't switch the I2C bridge to talk with tuner * @antenna_gpio: GPIO bit used to control the antenna @@ -29,6 +30,7 @@ struct drxk_config { bool no_i2c_bridge; bool parallel_ts; bool dynamic_clk; + bool enable_merr_cfg; bool antenna_dvbt; u16 antenna_gpio; diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c index d25b0d20038..5fa192731fc 100644 --- a/drivers/media/dvb/frontends/drxk_hard.c +++ b/drivers/media/dvb/frontends/drxk_hard.c @@ -1179,6 +1179,7 @@ static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable) int status = -1; u16 sioPdrMclkCfg = 0; u16 sioPdrMdxCfg = 0; + u16 err_cfg = 0; dprintk(1, ": mpeg %s, %s mode\n", mpegEnable ? "enable" : "disable", @@ -1244,12 +1245,17 @@ static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable) status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg); if (status < 0) goto error; - status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000); /* Disable */ + + if (state->enable_merr_cfg) + err_cfg = sioPdrMdxCfg; + + status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg); if (status < 0) goto error; - status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000); /* Disable */ + status = write16(state, SIO_PDR_MVAL_CFG__A, err_cfg); if (status < 0) goto error; + if (state->m_enableParallel == true) { /* paralel -> enable MD1 to MD7 */ status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg); @@ -6379,6 +6385,7 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config, state->antenna_gpio = config->antenna_gpio; state->antenna_dvbt = config->antenna_dvbt; state->m_ChunkSize = config->chunk_size; + state->enable_merr_cfg = config->enable_merr_cfg; if (config->dynamic_clk) { state->m_DVBTStaticCLK = 0; diff --git a/drivers/media/dvb/frontends/drxk_hard.h b/drivers/media/dvb/frontends/drxk_hard.h index 3a58b73eb9b..4bbf841de83 100644 --- a/drivers/media/dvb/frontends/drxk_hard.h +++ b/drivers/media/dvb/frontends/drxk_hard.h @@ -332,6 +332,7 @@ struct drxk_state { u16 UIO_mask; /* Bits used by UIO */ + bool enable_merr_cfg; bool single_master; bool no_i2c_bridge; bool antenna_dvbt; -- cgit v1.2.3-70-g09d2 From b19280cf2bee7df489f9488bda45220f8518e39f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 20 Jan 2012 18:37:01 -0300 Subject: [media] az6007: code cleanups and fixes Several changes were needed to make az6007 to work, producing the same commands as the original driver. This patch does that. While here, be less verbose when debug is not enabled. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 148 +++++++++++++++++++++---------------- 1 file changed, 83 insertions(+), 65 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 81fdc90be44..f0e4c013bb5 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -54,12 +54,16 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); struct az6007_device_state { struct dvb_ca_en50221 ca; struct mutex ca_mutex; - u8 power_state; + unsigned warm : 1; /* Due to DRX-K - probably need changes */ int (*gate_ctrl) (struct dvb_frontend *, int); struct semaphore pll_mutex; bool tuner_attached; + + unsigned char data[4096]; + + struct usb_data_stream *stream; }; static struct drxk_config terratec_h7_drxk = { @@ -71,7 +75,7 @@ static struct drxk_config terratec_h7_drxk = { .no_i2c_bridge = false, .chunk_size = 64, .mpeg_out_clk_strength = 0x02, - .microcode_name = "dvb-usb-terratec-h7-az6007.fw", + .microcode_name = "dvb-usb-terratec-h7-drxk.fw", }; static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) @@ -162,7 +166,9 @@ static int az6007_write(struct usb_device *udev, u8 req, u16 value, static int az6007_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) { - return 0; + deb_info("%s: %s", __func__, onoff ? "enable" : "disable"); + + return az6007_write(adap->dev->udev, 0xbc, onoff, 0, NULL, 0); } /* keys for the enclosed remote control */ @@ -236,46 +242,6 @@ static int az6007_read_mac_addr(struct dvb_usb_device *d, u8 mac[6]) return ret; } -static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) -{ - int ret; - struct usb_device *udev = adap->dev->udev; - - deb_info("%s: adap=%p adap->dev=%p\n", __func__, adap, adap->dev); - - ret = az6007_write(udev, AZ6007_POWER, 0, 2, NULL, 0); - if (ret < 0) - goto error; - msleep(150); - ret = az6007_write(udev, AZ6007_POWER, 1, 4, NULL, 0); - if (ret < 0) - goto error; - msleep(100); - ret = az6007_write(udev, AZ6007_POWER, 1, 3, NULL, 0); - if (ret < 0) - goto error; - msleep(100); - ret = az6007_write(udev, AZ6007_POWER, 1, 4, NULL, 0); - if (ret < 0) - goto error; - msleep(100); - ret = az6007_write(udev, FX2_SCON1, 0, 3, NULL, 0); - if (ret < 0) - goto error; - msleep (10); - ret = az6007_write(udev, FX2_SCON1, 1, 3, NULL, 0); - if (ret < 0) - goto error; - msleep (10); - ret = az6007_write(udev, AZ6007_POWER, 0, 0, NULL, 0); - -error: - if (ret < 0) - err("%s failed with error %d", __func__, ret); - - return ret; -} - static int az6007_led_on_off(struct usb_interface *intf, int onoff) { struct usb_device *udev = interface_to_usbdev(intf); @@ -293,9 +259,8 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) BUG_ON(!st); - az6007_frontend_poweron(adap); + deb_info("attaching demod drxk"); - info("attaching demod drxk"); adap->fe_adap[0].fe = dvb_attach(drxk_attach, &terratec_h7_drxk, &adap->dev->i2c_adap); if (!adap->fe_adap[0].fe) @@ -319,11 +284,11 @@ static int az6007_tuner_attach(struct dvb_usb_adapter *adap) st->tuner_attached = true; - info("attaching tuner mt2063"); + deb_info("attaching tuner mt2063"); /* Attach mt2063 to DVB-C frontend */ if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl) adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 1); - if (!dvb_attach(mt2063_attach, adap->fe_adap[0].fe, + if (!dvb_attach(mt2063_attach, adap->fe_adap[0].fe, &az6007_mt2063_config, &adap->dev->i2c_adap)) return -EINVAL; @@ -336,22 +301,69 @@ static int az6007_tuner_attach(struct dvb_usb_adapter *adap) int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) { - if (!onoff) - return 0; + struct az6007_device_state *st = d->priv; + struct usb_device *udev = d->udev; + int ret; + + deb_info("%s()\n", __func__); + + if (!st->warm) { + u8 data[6]; + + az6007_read(udev, FX2_OED, 1, 0, data, 1); /* {0x01} */ + az6007_read(udev, AZ6007_READ_DATA, 0, 8160, data, 1); /* {0x20} */ + az6007_read(udev, AZ6007_READ_DATA, 0, 0, data, 5); /* {0x00, 0x00, 0x00, 0x00, 0x0a} */ + az6007_read(udev, AZ6007_READ_DATA, 0, 4080, data, 6); /* {0x00, 0x08, 0x00, 0x0c, 0x22, 0x38} */ + + ret = az6007_write(udev, AZ6007_POWER, 0, 2, NULL, 0); + if (ret < 0) + return ret; + msleep(60); + ret = az6007_write(udev, AZ6007_POWER, 1, 4, NULL, 0); + if (ret < 0) + return ret; + msleep(100); + ret = az6007_write(udev, AZ6007_POWER, 1, 3, NULL, 0); + if (ret < 0) + return ret; + msleep(20); + ret = az6007_write(udev, AZ6007_POWER, 1, 4, NULL, 0); + if (ret < 0) + return ret; + + msleep(400); + ret = az6007_write(udev, FX2_SCON1, 0, 3, NULL, 0); + if (ret < 0) + return ret; + msleep (150); + ret = az6007_write(udev, FX2_SCON1, 1, 3, NULL, 0); + if (ret < 0) + return ret; + msleep (430); + ret = az6007_write(udev, AZ6007_POWER, 0, 0, NULL, 0); + if (ret < 0) + return ret; + st->warm = true; - info("Sending poweron sequence"); + return 0; + } - az6007_write(d->udev, AZ6007_TS_THROUGH, 0, 0, NULL, 0); + if (!onoff) + return 0; + + az6007_write(udev, AZ6007_POWER, 0, 0, NULL, 0); + az6007_write(udev, AZ6007_TS_THROUGH, 0, 0, NULL, 0); #if 0 // Seems to be a poweroff sequence - az6007_write(d->udev, 0xbc, 1, 3, NULL, 0); - az6007_write(d->udev, 0xbc, 1, 4, NULL, 0); - az6007_write(d->udev, 0xc0, 0, 3, NULL, 0); - az6007_write(d->udev, 0xc0, 1, 3, NULL, 0); - az6007_write(d->udev, 0xbc, 0, 1, NULL, 0); + az6007_write(udev, 0xbc, 1, 3, NULL, 0); + az6007_write(udev, 0xbc, 1, 4, NULL, 0); + az6007_write(udev, 0xc0, 0, 3, NULL, 0); + az6007_write(udev, 0xc0, 1, 3, NULL, 0); + az6007_write(udev, 0xbc, 0, 1, NULL, 0); #endif + return 0; } @@ -367,13 +379,13 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); + struct az6007_device_state *st = d->priv; int i, j, len; int ret = 0; u16 index; u16 value; int length; u8 req, addr; - u8 data[512]; if (mutex_lock_interruptible(&d->i2c_mutex) < 0) return -EAGAIN; @@ -399,11 +411,11 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], value = addr | (1 << 8); length = 6 + msgs[i + 1].len; len = msgs[i + 1].len; - ret = az6007_read(d->udev, req, value, index, data, + ret = az6007_read(d->udev, req, value, index, st->data, length); if (ret >= len) { for (j = 0; j < len; j++) { - msgs[i + 1].buf[j] = data[j + 5]; + msgs[i + 1].buf[j] = st->data[j + 5]; if (dvb_usb_az6007_debug & 2) printk(KERN_CONT "0x%02x ", @@ -426,11 +438,11 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], if (dvb_usb_az6007_debug & 2) printk(KERN_CONT "(0x%02x) ", msgs[i].buf[0]); for (j = 0; j < len; j++) { - data[j] = msgs[i].buf[j + 1]; + st->data[j] = msgs[i].buf[j + 1]; if (dvb_usb_az6007_debug & 2) - printk(KERN_CONT "0x%02x ", data[j]); + printk(KERN_CONT "0x%02x ", st->data[j]); } - ret = az6007_write(d->udev, req, value, index, data, + ret = az6007_write(d->udev, req, value, index, st->data, length); } else { /* read bytes */ @@ -443,13 +455,13 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], value = addr; length = msgs[i].len + 6; len = msgs[i].len; - ret = az6007_read(d->udev, req, value, index, data, + ret = az6007_read(d->udev, req, value, index, st->data, length); for (j = 0; j < len; j++) { - msgs[i].buf[j] = data[j + 5]; + msgs[i].buf[j] = st->data[j + 5]; if (dvb_usb_az6007_debug & 2) printk(KERN_CONT - "0x%02x ", data[j + 5]); + "0x%02x ", st->data[j + 5]); } } if (dvb_usb_az6007_debug & 2) @@ -491,6 +503,12 @@ int az6007_identify_state(struct usb_device *udev, else *cold = 1; + if (*cold) { + az6007_write(udev, 0x09, 1, 0, NULL, 0); + az6007_write(udev, 0x00, 0, 0, NULL, 0); + az6007_write(udev, 0x00, 0, 0, NULL, 0); + } + deb_info("Device is on %s state\n", *cold? "warm" : "cold"); return 0; } -- cgit v1.2.3-70-g09d2 From 04e3ece7153054e2694a882f6ffa54941574049c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 21 Jan 2012 10:35:12 -0300 Subject: [media] az6007: Driver cleanup Remove commented test code, remove unused poweroff stuff, and fix the copyright data. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 56 +++++++++----------------------------- 1 file changed, 13 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index f0e4c013bb5..534d3267c86 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -7,8 +7,9 @@ * http://linux.terratec.de/files/TERRATEC_H7/20110323_TERRATEC_H7_Linux.tar.gz * The original driver's license is GPL, as declared with MODULE_LICENSE() * - * Driver modifiyed by Mauro Carvalho Chehab in order - * to work with upstream drxk driver, and to fix some bugs. + * Copyright (c) 2010-2011 Mauro Carvalho Chehab + * Driver modified by in order to work with upstream drxk driver, and + * tons of bugs got fixed. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -58,7 +59,6 @@ struct az6007_device_state { /* Due to DRX-K - probably need changes */ int (*gate_ctrl) (struct dvb_frontend *, int); - struct semaphore pll_mutex; bool tuner_attached; unsigned char data[4096]; @@ -94,17 +94,11 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) if (!st) return -EINVAL; - if (enable) { -#if 0 - down(&st->pll_mutex); -#endif + if (enable) status = st->gate_ctrl(fe, 1); - } else { -#if 0 + else status = st->gate_ctrl(fe, 0); -#endif - up(&st->pll_mutex); - } + return status; } @@ -221,14 +215,6 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) return 0; } -#if 0 -int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) -{ - u8 v = onoff; - return az6007_write(d->udev, AZ6007_POWER, v , 3, NULL, 1); -} -#endif - static int az6007_read_mac_addr(struct dvb_usb_device *d, u8 mac[6]) { int ret; @@ -246,6 +232,7 @@ static int az6007_led_on_off(struct usb_interface *intf, int onoff) { struct usb_device *udev = interface_to_usbdev(intf); int ret; + /* TS through */ ret = az6007_write(udev, AZ6007_POWER, onoff, 0, NULL, 0); if (ret < 0) @@ -257,8 +244,6 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) { struct az6007_device_state *st = adap->dev->priv; - BUG_ON(!st); - deb_info("attaching demod drxk"); adap->fe_adap[0].fe = dvb_attach(drxk_attach, &terratec_h7_drxk, @@ -267,8 +252,6 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) return -EINVAL; adap->fe_adap[0].fe->sec_priv = adap; - /* FIXME: do we need a pll semaphore? */ - sema_init(&st->pll_mutex, 1); st->gate_ctrl = adap->fe_adap[0].fe->ops.i2c_gate_ctrl; adap->fe_adap[0].fe->ops.i2c_gate_ctrl = drxk_gate_ctrl; @@ -282,9 +265,8 @@ static int az6007_tuner_attach(struct dvb_usb_adapter *adap) if (st->tuner_attached) return 0; - st->tuner_attached = true; - deb_info("attaching tuner mt2063"); + /* Attach mt2063 to DVB-C frontend */ if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl) adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 1); @@ -296,6 +278,8 @@ static int az6007_tuner_attach(struct dvb_usb_adapter *adap) if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl) adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 0); + st->tuner_attached = true; + return 0; } @@ -355,25 +339,9 @@ int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) az6007_write(udev, AZ6007_POWER, 0, 0, NULL, 0); az6007_write(udev, AZ6007_TS_THROUGH, 0, 0, NULL, 0); -#if 0 - // Seems to be a poweroff sequence - az6007_write(udev, 0xbc, 1, 3, NULL, 0); - az6007_write(udev, 0xbc, 1, 4, NULL, 0); - az6007_write(udev, 0xc0, 0, 3, NULL, 0); - az6007_write(udev, 0xc0, 1, 3, NULL, 0); - az6007_write(udev, 0xbc, 0, 1, NULL, 0); -#endif - return 0; } -static struct dvb_usb_device_properties az6007_properties; - -static void az6007_usb_disconnect(struct usb_interface *intf) -{ - dvb_usb_device_exit(intf); -} - /* I2C */ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) @@ -513,6 +481,8 @@ int az6007_identify_state(struct usb_device *udev, return 0; } +static struct dvb_usb_device_properties az6007_properties; + static int az6007_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { @@ -589,7 +559,6 @@ static struct usb_driver az6007_usb_driver = { .name = "dvb_usb_az6007", .probe = az6007_usb_probe, .disconnect = dvb_usb_device_exit, - /* .disconnect = az6007_usb_disconnect, */ .id_table = az6007_usb_table, }; @@ -619,6 +588,7 @@ module_init(az6007_usb_module_init); module_exit(az6007_usb_module_exit); MODULE_AUTHOR("Henry Wang "); +MODULE_AUTHOR("Mauro Carvalho Chehab "); MODULE_DESCRIPTION("Driver for AzureWave 6007 DVB-C/T USB2.0 and clones"); MODULE_VERSION("1.1"); MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From a2c35d346d9e9555db930f9035d0e628bf7f3393 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 21 Jan 2012 11:19:16 -0300 Subject: [media] az6007: Protect read/write calls with a mutex This will avoid interference with CI and IR I/O operations. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 122 +++++++++++++++++++------------------ 1 file changed, 62 insertions(+), 60 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 534d3267c86..6177332a7a0 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -53,17 +53,11 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); #define AZ6007_READ_IR 0xb4 struct az6007_device_state { - struct dvb_ca_en50221 ca; - struct mutex ca_mutex; - unsigned warm : 1; - - /* Due to DRX-K - probably need changes */ + struct mutex mutex; + struct dvb_ca_en50221 ca; + unsigned warm:1; int (*gate_ctrl) (struct dvb_frontend *, int); - bool tuner_attached; - unsigned char data[4096]; - - struct usb_data_stream *stream; }; static struct drxk_config terratec_h7_drxk = { @@ -107,8 +101,7 @@ static struct mt2063_config az6007_mt2063_config = { .refclock = 36125000, }; -/* check for mutex FIXME */ -static int az6007_read(struct usb_device *udev, u8 req, u16 value, +static int __az6007_read(struct usb_device *udev, u8 req, u16 value, u16 index, u8 *b, int blen) { int ret; @@ -130,7 +123,23 @@ static int az6007_read(struct usb_device *udev, u8 req, u16 value, return ret; } -static int az6007_write(struct usb_device *udev, u8 req, u16 value, +static int az6007_read(struct dvb_usb_device *d, u8 req, u16 value, + u16 index, u8 *b, int blen) +{ + struct az6007_device_state *st = d->priv; + int ret; + + if (mutex_lock_interruptible(&st->mutex) < 0) + return -EAGAIN; + + ret = __az6007_read(d->udev, req, value, index, b, blen); + + mutex_unlock(&st->mutex); + + return ret; +} + +static int __az6007_write(struct usb_device *udev, u8 req, u16 value, u16 index, u8 *b, int blen) { int ret; @@ -158,11 +167,29 @@ static int az6007_write(struct usb_device *udev, u8 req, u16 value, return 0; } +static int az6007_write(struct dvb_usb_device *d, u8 req, u16 value, + u16 index, u8 *b, int blen) +{ + struct az6007_device_state *st = d->priv; + int ret; + + if (mutex_lock_interruptible(&st->mutex) < 0) + return -EAGAIN; + + ret = __az6007_write(d->udev, req, value, index, b, blen); + + mutex_unlock(&st->mutex); + + return ret; +} + static int az6007_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) { + struct dvb_usb_device *d = adap->dev; + deb_info("%s: %s", __func__, onoff ? "enable" : "disable"); - return az6007_write(adap->dev->udev, 0xbc, onoff, 0, NULL, 0); + return az6007_write(d, 0xbc, onoff, 0, NULL, 0); } /* keys for the enclosed remote control */ @@ -185,7 +212,7 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) */ return 0; - az6007_read(d->udev, AZ6007_READ_IR, 0, 0, key, 10); + az6007_read(d, AZ6007_READ_IR, 0, 0, key, 10); if (key[1] == 0x44) { *state = REMOTE_NO_KEY_PRESSED; @@ -218,7 +245,7 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) static int az6007_read_mac_addr(struct dvb_usb_device *d, u8 mac[6]) { int ret; - ret = az6007_read(d->udev, AZ6007_READ_DATA, 6, 0, mac, 6); + ret = az6007_read(d, AZ6007_READ_DATA, 6, 0, mac, 6); if (ret > 0) deb_info("%s: mac is %02x:%02x:%02x:%02x:%02x:%02x\n", @@ -228,18 +255,6 @@ static int az6007_read_mac_addr(struct dvb_usb_device *d, u8 mac[6]) return ret; } -static int az6007_led_on_off(struct usb_interface *intf, int onoff) -{ - struct usb_device *udev = interface_to_usbdev(intf); - int ret; - - /* TS through */ - ret = az6007_write(udev, AZ6007_POWER, onoff, 0, NULL, 0); - if (ret < 0) - err("%s failed with error %d", __func__, ret); - return ret; -} - static int az6007_frontend_attach(struct dvb_usb_adapter *adap) { struct az6007_device_state *st = adap->dev->priv; @@ -260,11 +275,6 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) static int az6007_tuner_attach(struct dvb_usb_adapter *adap) { - struct az6007_device_state *st = adap->dev->priv; - - if (st->tuner_attached) - return 0; - deb_info("attaching tuner mt2063"); /* Attach mt2063 to DVB-C frontend */ @@ -278,53 +288,45 @@ static int az6007_tuner_attach(struct dvb_usb_adapter *adap) if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl) adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 0); - st->tuner_attached = true; - return 0; } int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) { struct az6007_device_state *st = d->priv; - struct usb_device *udev = d->udev; int ret; deb_info("%s()\n", __func__); if (!st->warm) { - u8 data[6]; + mutex_init(&st->mutex); - az6007_read(udev, FX2_OED, 1, 0, data, 1); /* {0x01} */ - az6007_read(udev, AZ6007_READ_DATA, 0, 8160, data, 1); /* {0x20} */ - az6007_read(udev, AZ6007_READ_DATA, 0, 0, data, 5); /* {0x00, 0x00, 0x00, 0x00, 0x0a} */ - az6007_read(udev, AZ6007_READ_DATA, 0, 4080, data, 6); /* {0x00, 0x08, 0x00, 0x0c, 0x22, 0x38} */ - - ret = az6007_write(udev, AZ6007_POWER, 0, 2, NULL, 0); + ret = az6007_write(d, AZ6007_POWER, 0, 2, NULL, 0); if (ret < 0) return ret; msleep(60); - ret = az6007_write(udev, AZ6007_POWER, 1, 4, NULL, 0); + ret = az6007_write(d, AZ6007_POWER, 1, 4, NULL, 0); if (ret < 0) return ret; msleep(100); - ret = az6007_write(udev, AZ6007_POWER, 1, 3, NULL, 0); + ret = az6007_write(d, AZ6007_POWER, 1, 3, NULL, 0); if (ret < 0) return ret; msleep(20); - ret = az6007_write(udev, AZ6007_POWER, 1, 4, NULL, 0); + ret = az6007_write(d, AZ6007_POWER, 1, 4, NULL, 0); if (ret < 0) return ret; msleep(400); - ret = az6007_write(udev, FX2_SCON1, 0, 3, NULL, 0); + ret = az6007_write(d, FX2_SCON1, 0, 3, NULL, 0); if (ret < 0) return ret; msleep (150); - ret = az6007_write(udev, FX2_SCON1, 1, 3, NULL, 0); + ret = az6007_write(d, FX2_SCON1, 1, 3, NULL, 0); if (ret < 0) return ret; msleep (430); - ret = az6007_write(udev, AZ6007_POWER, 0, 0, NULL, 0); + ret = az6007_write(d, AZ6007_POWER, 0, 0, NULL, 0); if (ret < 0) return ret; @@ -336,8 +338,8 @@ int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) if (!onoff) return 0; - az6007_write(udev, AZ6007_POWER, 0, 0, NULL, 0); - az6007_write(udev, AZ6007_TS_THROUGH, 0, 0, NULL, 0); + az6007_write(d, AZ6007_POWER, 0, 0, NULL, 0); + az6007_write(d, AZ6007_TS_THROUGH, 0, 0, NULL, 0); return 0; } @@ -355,7 +357,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int length; u8 req, addr; - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + if (mutex_lock_interruptible(&st->mutex) < 0) return -EAGAIN; for (i = 0; i < num; i++) { @@ -379,7 +381,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], value = addr | (1 << 8); length = 6 + msgs[i + 1].len; len = msgs[i + 1].len; - ret = az6007_read(d->udev, req, value, index, st->data, + ret = __az6007_read(d->udev, req, value, index, st->data, length); if (ret >= len) { for (j = 0; j < len; j++) { @@ -410,7 +412,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], if (dvb_usb_az6007_debug & 2) printk(KERN_CONT "0x%02x ", st->data[j]); } - ret = az6007_write(d->udev, req, value, index, st->data, + ret = __az6007_write(d->udev, req, value, index, st->data, length); } else { /* read bytes */ @@ -423,7 +425,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], value = addr; length = msgs[i].len + 6; len = msgs[i].len; - ret = az6007_read(d->udev, req, value, index, st->data, + ret = __az6007_read(d->udev, req, value, index, st->data, length); for (j = 0; j < len; j++) { msgs[i].buf[j] = st->data[j + 5]; @@ -438,7 +440,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], goto err; } err: - mutex_unlock(&d->i2c_mutex); + mutex_unlock(&st->mutex); if (ret < 0) { info("%s ERROR: %i", __func__, ret); @@ -465,16 +467,16 @@ int az6007_identify_state(struct usb_device *udev, u8 mac[6]; /* Try to read the mac address */ - ret = az6007_read(udev, AZ6007_READ_DATA, 6, 0, mac, 6); + ret = __az6007_read(udev, AZ6007_READ_DATA, 6, 0, mac, 6); if (ret == 6) *cold = 0; else *cold = 1; if (*cold) { - az6007_write(udev, 0x09, 1, 0, NULL, 0); - az6007_write(udev, 0x00, 0, 0, NULL, 0); - az6007_write(udev, 0x00, 0, 0, NULL, 0); + __az6007_write(udev, 0x09, 1, 0, NULL, 0); + __az6007_write(udev, 0x00, 0, 0, NULL, 0); + __az6007_write(udev, 0x00, 0, 0, NULL, 0); } deb_info("Device is on %s state\n", *cold? "warm" : "cold"); @@ -486,7 +488,7 @@ static struct dvb_usb_device_properties az6007_properties; static int az6007_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { - az6007_led_on_off(intf, 0); + struct usb_device *udev = interface_to_usbdev(intf); return dvb_usb_device_init(intf, &az6007_properties, THIS_MODULE, NULL, adapter_nr); -- cgit v1.2.3-70-g09d2 From 711e1398d3131fd83aee0a35d450c6e1a809bfb2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 21 Jan 2012 11:53:18 -0300 Subject: [media] az6007: Be sure to use kmalloc'ed buffer for transfers USB data transfers may not work if the buffer is allocated at the stack. Be sure to use kmalloc on all places where a buffer is needed. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 6177332a7a0..142ef7b0c02 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -201,8 +201,8 @@ static struct rc_map_table rc_map_az6007_table[] = { /* remote control stuff (does not work with my box) */ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) { + struct az6007_device_state *st = d->priv; struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table; - u8 key[10]; int i; /* @@ -212,9 +212,9 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) */ return 0; - az6007_read(d, AZ6007_READ_IR, 0, 0, key, 10); + az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10); - if (key[1] == 0x44) { + if (st->data[1] == 0x44) { *state = REMOTE_NO_KEY_PRESSED; return 0; } @@ -228,11 +228,11 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) * 88 80 7e 0d f2 ff 00 82 63 82 (another NEC-extended based IR) * I suspect that the IR data is at bytes 1 to 4, and byte 5 is parity */ - deb_rc("remote query key: %x %d\n", key[1], key[1]); - print_hex_dump_bytes("Remote: ", DUMP_PREFIX_NONE, key, 10); + deb_rc("remote query key: %x %d\n", st->data[1], st->data[1]); + print_hex_dump_bytes("Remote: ", DUMP_PREFIX_NONE, st->data, 10); for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) { - if (rc5_custom(&keymap[i]) == key[1]) { + if (rc5_custom(&keymap[i]) == st->data[1]) { *event = keymap[i].keycode; *state = REMOTE_KEY_PRESSED; @@ -244,8 +244,11 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) static int az6007_read_mac_addr(struct dvb_usb_device *d, u8 mac[6]) { + struct az6007_device_state *st = d->priv; int ret; - ret = az6007_read(d, AZ6007_READ_DATA, 6, 0, mac, 6); + + ret = az6007_read(d, AZ6007_READ_DATA, 6, 0, st->data, 6); + memcpy(mac, st->data, sizeof(mac)); if (ret > 0) deb_info("%s: mac is %02x:%02x:%02x:%02x:%02x:%02x\n", @@ -464,7 +467,11 @@ int az6007_identify_state(struct usb_device *udev, struct dvb_usb_device_description **desc, int *cold) { int ret; - u8 mac[6]; + u8 *mac; + + mac = kmalloc(6, GFP_ATOMIC); + if (!mac) + return -ENOMEM; /* Try to read the mac address */ ret = __az6007_read(udev, AZ6007_READ_DATA, 6, 0, mac, 6); @@ -473,6 +480,8 @@ int az6007_identify_state(struct usb_device *udev, else *cold = 1; + kfree(mac); + if (*cold) { __az6007_write(udev, 0x09, 1, 0, NULL, 0); __az6007_write(udev, 0x00, 0, 0, NULL, 0); @@ -488,8 +497,6 @@ static struct dvb_usb_device_properties az6007_properties; static int az6007_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { - struct usb_device *udev = interface_to_usbdev(intf); - return dvb_usb_device_init(intf, &az6007_properties, THIS_MODULE, NULL, adapter_nr); } -- cgit v1.2.3-70-g09d2 From 9165144033944a4c650a9914888bf6b6f7328c7a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 21 Jan 2012 12:14:13 -0300 Subject: [media] az6007: Fix IR handling Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 142ef7b0c02..a8aedb87ae6 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -204,13 +204,7 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) struct az6007_device_state *st = d->priv; struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table; int i; - - /* - * FIXME: remove the following return to enabled remote querying - * The driver likely needs proper locking to avoid troubles between - * this call and other concurrent calls. - */ - return 0; + unsigned code = 0; az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10); @@ -219,20 +213,21 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) return 0; } - /* - * FIXME: need to make something useful with the keycodes and to - * convert it to the non-legacy mode. Yet, it is producing some - * debug info already, like: - * 88 04 eb 02 fd ff 00 82 63 82 (terratec IR) - * 88 04 eb 03 fc 00 00 82 63 82 (terratec IR) - * 88 80 7e 0d f2 ff 00 82 63 82 (another NEC-extended based IR) - * I suspect that the IR data is at bytes 1 to 4, and byte 5 is parity - */ - deb_rc("remote query key: %x %d\n", st->data[1], st->data[1]); + if ((st->data[1] ^ st->data[2]) == 0xff) + code = st->data[1]; + else + code = st->data[1] << 8 | st->data[2]; + + if ((st->data[3] ^ st->data[4]) == 0xff) + code = code << 8 | st->data[3]; + else + code = code << 16 | st->data[3] << 8| st->data[4]; + + printk("remote query key: %04x\n", code); print_hex_dump_bytes("Remote: ", DUMP_PREFIX_NONE, st->data, 10); for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) { - if (rc5_custom(&keymap[i]) == st->data[1]) { + if (rc5_custom(&keymap[i]) == code) { *event = keymap[i].keycode; *state = REMOTE_KEY_PRESSED; -- cgit v1.2.3-70-g09d2 From d3d076aaa7d8a028ae4617f57c14727b473f848d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 21 Jan 2012 12:20:30 -0300 Subject: [media] az6007: Convert IR to use the rc_core logic Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index a8aedb87ae6..2288916a2a4 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -192,26 +192,16 @@ static int az6007_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) return az6007_write(d, 0xbc, onoff, 0, NULL, 0); } -/* keys for the enclosed remote control */ -static struct rc_map_table rc_map_az6007_table[] = { - {0x0001, KEY_1}, - {0x0002, KEY_2}, -}; - /* remote control stuff (does not work with my box) */ -static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) +static int az6007_rc_query(struct dvb_usb_device *d) { struct az6007_device_state *st = d->priv; - struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table; - int i; unsigned code = 0; az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10); - if (st->data[1] == 0x44) { - *state = REMOTE_NO_KEY_PRESSED; + if (st->data[1] == 0x44) return 0; - } if ((st->data[1] ^ st->data[2]) == 0xff) code = st->data[1]; @@ -224,16 +214,9 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) code = code << 16 | st->data[3] << 8| st->data[4]; printk("remote query key: %04x\n", code); - print_hex_dump_bytes("Remote: ", DUMP_PREFIX_NONE, st->data, 10); - for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) { - if (rc5_custom(&keymap[i]) == code) { - *event = keymap[i].keycode; - *state = REMOTE_KEY_PRESSED; + rc_keydown(d->rc_dev, code, st->data[5]); - return 0; - } - } return 0; } @@ -536,11 +519,12 @@ static struct dvb_usb_device_properties az6007_properties = { .power_ctrl = az6007_power_ctrl, .read_mac_address = az6007_read_mac_addr, - .rc.legacy = { - .rc_map_table = rc_map_az6007_table, - .rc_map_size = ARRAY_SIZE(rc_map_az6007_table), + .rc.core = { .rc_interval = 400, + .rc_codes = RC_MAP_DIB0700_NEC_TABLE, + .module_name = "az6007", .rc_query = az6007_rc_query, + .allowed_protos = RC_TYPE_NEC, }, .i2c_algo = &az6007_i2c_algo, -- cgit v1.2.3-70-g09d2 From 083995477d45ae087d3c4f99cf8ae95b9de84019 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 21 Jan 2012 12:41:21 -0300 Subject: [media] az6007: Use the right keycode for Terratec H7 Instead of using a fake keycode, just for testing, use the right one, for Terratec H7. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 2 +- .../media/rc/keymaps/rc-nec-terratec-cinergy-xs.c | 52 ++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 2288916a2a4..14733b84e8b 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -521,7 +521,7 @@ static struct dvb_usb_device_properties az6007_properties = { .rc.core = { .rc_interval = 400, - .rc_codes = RC_MAP_DIB0700_NEC_TABLE, + .rc_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS, .module_name = "az6007", .rc_query = az6007_rc_query, .allowed_protos = RC_TYPE_NEC, diff --git a/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c index f3b86c8db67..8d4dae2e2ec 100644 --- a/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c +++ b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c @@ -18,6 +18,8 @@ */ static struct rc_map_table nec_terratec_cinergy_xs[] = { + + /* Terratec Grey IR, with most keys in orange */ { 0x1441, KEY_HOME}, { 0x1401, KEY_POWER2}, @@ -78,6 +80,56 @@ static struct rc_map_table nec_terratec_cinergy_xs[] = { { 0x144e, KEY_REWIND}, { 0x144f, KEY_FASTFORWARD}, { 0x145c, KEY_NEXT}, + + /* Terratec Black IR, with most keys in black */ + { 0x04eb01, KEY_POWER2}, + + { 0x04eb02, KEY_1}, + { 0x04eb03, KEY_2}, + { 0x04eb04, KEY_3}, + { 0x04eb05, KEY_4}, + { 0x04eb06, KEY_5}, + { 0x04eb07, KEY_6}, + { 0x04eb08, KEY_7}, + { 0x04eb09, KEY_8}, + { 0x04eb0a, KEY_9}, + { 0x04eb0c, KEY_0}, + + { 0x04eb0b, KEY_TEXT}, /* TXT */ + { 0x04eb0d, KEY_REFRESH}, /* Refresh */ + + { 0x04eb0e, KEY_HOME}, + { 0x04eb0f, KEY_EPG}, + + { 0x04eb10, KEY_UP}, + { 0x04eb11, KEY_LEFT}, + { 0x04eb12, KEY_OK}, + { 0x04eb13, KEY_RIGHT}, + { 0x04eb14, KEY_DOWN}, + + { 0x04eb15, KEY_BACKSPACE}, + { 0x04eb16, KEY_INFO}, + + { 0x04eb17, KEY_RED}, + { 0x04eb18, KEY_GREEN}, + { 0x04eb19, KEY_YELLOW}, + { 0x04eb1a, KEY_BLUE}, + + { 0x04eb1c, KEY_VOLUMEUP}, + { 0x04eb1e, KEY_VOLUMEDOWN}, + + { 0x04eb1d, KEY_MUTE}, + + { 0x04eb1b, KEY_CHANNELUP}, + { 0x04eb1f, KEY_CHANNELDOWN}, + + { 0x04eb40, KEY_RECORD}, + { 0x04eb4c, KEY_PLAY}, + { 0x04eb58, KEY_PAUSE}, + + { 0x04eb54, KEY_REWIND}, + { 0x04eb48, KEY_STOP}, + { 0x04eb5c, KEY_NEXT}, }; static struct rc_map_list nec_terratec_cinergy_xs_map = { -- cgit v1.2.3-70-g09d2 From 44744f9b982049da0f89c560d91bd2549aedf0a0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 21 Jul 2011 18:33:26 -0300 Subject: [media] az6007: Enable the driver at the building system Add the corresponding entries to allow building this driver. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/Kconfig | 8 ++++++++ drivers/media/dvb/dvb-usb/Makefile | 4 +++- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 9f203c6767a..e894bad6538 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -361,6 +361,14 @@ config DVB_USB_EC168 help Say Y here to support the E3C EC168 DVB-T USB2.0 receiver. +config DVB_USB_AZ6007 + tristate "AzureWave 6007 and clones DVB-T/C USB2.0 support" + depends on DVB_USB + select DVB_DRXK if !DVB_FE_CUSTOMISE + select MEDIA_TUNER_MT2063 if !DVB_FE_CUSTOMISE + help + Say Y here to support theAfatech AF9005 based DVB-T/DVB-C receivers. + config DVB_USB_AZ6027 tristate "Azurewave DVB-S/S2 USB2.0 AZ6027 support" depends on DVB_USB diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile index 26c8b9e5705..d9549cb2769 100644 --- a/drivers/media/dvb/dvb-usb/Makefile +++ b/drivers/media/dvb/dvb-usb/Makefile @@ -54,7 +54,6 @@ obj-$(CONFIG_DVB_USB_DIB0700) += dvb-usb-dib0700.o dvb-usb-opera-objs = opera1.o obj-$(CONFIG_DVB_USB_OPERA1) += dvb-usb-opera.o - dvb-usb-af9005-objs = af9005.o af9005-fe.o obj-$(CONFIG_DVB_USB_AF9005) += dvb-usb-af9005.o @@ -88,6 +87,9 @@ obj-$(CONFIG_DVB_USB_FRIIO) += dvb-usb-friio.o dvb-usb-ec168-objs = ec168.o obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o +dvb-usb-az6007-objs = az6007.o +obj-$(CONFIG_DVB_USB_AZ6007) += dvb-usb-az6007.o + dvb-usb-az6027-objs = az6027.o obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o -- cgit v1.2.3-70-g09d2 From 9e5e3097a3febbf317abc6d1b07bc6c33b20c279 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 21 Jan 2012 13:52:39 -0200 Subject: [media] az6007: CodingStyle fixes Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 14733b84e8b..02efd94dc72 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -211,9 +211,7 @@ static int az6007_rc_query(struct dvb_usb_device *d) if ((st->data[3] ^ st->data[4]) == 0xff) code = code << 8 | st->data[3]; else - code = code << 16 | st->data[3] << 8| st->data[4]; - - printk("remote query key: %04x\n", code); + code = code << 16 | st->data[3] << 8 | st->data[4]; rc_keydown(d->rc_dev, code, st->data[5]); @@ -302,11 +300,11 @@ int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) ret = az6007_write(d, FX2_SCON1, 0, 3, NULL, 0); if (ret < 0) return ret; - msleep (150); + msleep(150); ret = az6007_write(d, FX2_SCON1, 1, 3, NULL, 0); if (ret < 0) return ret; - msleep (430); + msleep(430); ret = az6007_write(d, AZ6007_POWER, 0, 0, NULL, 0); if (ret < 0) return ret; @@ -362,8 +360,8 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], value = addr | (1 << 8); length = 6 + msgs[i + 1].len; len = msgs[i + 1].len; - ret = __az6007_read(d->udev, req, value, index, st->data, - length); + ret = __az6007_read(d->udev, req, value, index, + st->data, length); if (ret >= len) { for (j = 0; j < len; j++) { msgs[i + 1].buf[j] = st->data[j + 5]; @@ -391,10 +389,11 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], for (j = 0; j < len; j++) { st->data[j] = msgs[i].buf[j + 1]; if (dvb_usb_az6007_debug & 2) - printk(KERN_CONT "0x%02x ", st->data[j]); + printk(KERN_CONT "0x%02x ", + st->data[j]); } - ret = __az6007_write(d->udev, req, value, index, st->data, - length); + ret = __az6007_write(d->udev, req, value, index, + st->data, length); } else { /* read bytes */ if (dvb_usb_az6007_debug & 2) @@ -406,8 +405,8 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], value = addr; length = msgs[i].len + 6; len = msgs[i].len; - ret = __az6007_read(d->udev, req, value, index, st->data, - length); + ret = __az6007_read(d->udev, req, value, index, + st->data, length); for (j = 0; j < len; j++) { msgs[i].buf[j] = st->data[j + 5]; if (dvb_usb_az6007_debug & 2) @@ -466,7 +465,7 @@ int az6007_identify_state(struct usb_device *udev, __az6007_write(udev, 0x00, 0, 0, NULL, 0); } - deb_info("Device is on %s state\n", *cold? "warm" : "cold"); + deb_info("Device is on %s state\n", *cold ? "warm" : "cold"); return 0; } @@ -514,7 +513,7 @@ static struct dvb_usb_device_properties az6007_properties = { } } }, - }} + } } } }, .power_ctrl = az6007_power_ctrl, .read_mac_address = az6007_read_mac_addr, -- cgit v1.2.3-70-g09d2 From c6a32fcbbbc25d7d4e7178aa984e5ef186ee9589 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 20 Jan 2012 10:43:44 +0100 Subject: drm/i915: clarify gen2 pageflip cmd I've reviewed gen2 pageflip code to hunt down multiple prepare pageflip issues. The only thing I've found is a slight but functionally meaningless confusion about the length of the mi cmd. Fix it up and add a comment about what this dword should be (according to docs at least). Reviewed-by: Eric Anholt Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ebe71eda954..4247a7b1823 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7288,7 +7288,7 @@ static int intel_gen2_queue_flip(struct drm_device *dev, MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); OUT_RING(fb->pitches[0]); OUT_RING(obj->gtt_offset + offset); - OUT_RING(MI_NOOP); + OUT_RING(0); /* aux display base address, unused */ ADVANCE_LP_RING(); out: return ret; -- cgit v1.2.3-70-g09d2 From 47842649ef43ba4b81ac2486df8caa0934e01195 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 16 Jan 2012 11:57:54 -0800 Subject: drm/i915: properly mask and or watermark values for sprites Now that we're using the sprite WM fields, we need to take care not to clobber them in the main update_wm functions. While we're at it, make sure we mask out the old sprite wm value before or'ing in the new one when the sprite wm is updated. Signed-off-by: Jesse Barnes Reviewed-by: Keith Packard Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 24 +++++++++++++++++------- 1 file changed, 17 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 4247a7b1823..ec31350337d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4548,6 +4548,7 @@ void sandybridge_update_wm(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ + u32 val; int fbc_wm, plane_wm, cursor_wm; unsigned int enabled; @@ -4556,8 +4557,10 @@ void sandybridge_update_wm(struct drm_device *dev) &sandybridge_display_wm_info, latency, &sandybridge_cursor_wm_info, latency, &plane_wm, &cursor_wm)) { - I915_WRITE(WM0_PIPEA_ILK, - (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); + val = I915_READ(WM0_PIPEA_ILK); + val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); + I915_WRITE(WM0_PIPEA_ILK, val | + ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm)); DRM_DEBUG_KMS("FIFO watermarks For pipe A -" " plane %d, " "cursor: %d\n", plane_wm, cursor_wm); @@ -4568,8 +4571,10 @@ void sandybridge_update_wm(struct drm_device *dev) &sandybridge_display_wm_info, latency, &sandybridge_cursor_wm_info, latency, &plane_wm, &cursor_wm)) { - I915_WRITE(WM0_PIPEB_ILK, - (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); + val = I915_READ(WM0_PIPEB_ILK); + val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); + I915_WRITE(WM0_PIPEB_ILK, val | + ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm)); DRM_DEBUG_KMS("FIFO watermarks For pipe B -" " plane %d, cursor: %d\n", plane_wm, cursor_wm); @@ -4582,8 +4587,10 @@ void sandybridge_update_wm(struct drm_device *dev) &sandybridge_display_wm_info, latency, &sandybridge_cursor_wm_info, latency, &plane_wm, &cursor_wm)) { - I915_WRITE(WM0_PIPEC_IVB, - (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); + val = I915_READ(WM0_PIPEC_IVB); + val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); + I915_WRITE(WM0_PIPEC_IVB, val | + ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm)); DRM_DEBUG_KMS("FIFO watermarks For pipe C -" " plane %d, cursor: %d\n", plane_wm, cursor_wm); @@ -4727,6 +4734,7 @@ static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe, { struct drm_i915_private *dev_priv = dev->dev_private; int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ + u32 val; int sprite_wm, reg; int ret; @@ -4753,7 +4761,9 @@ static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe, return; } - I915_WRITE(reg, I915_READ(reg) | (sprite_wm << WM0_PIPE_SPRITE_SHIFT)); + val = I915_READ(reg); + val &= ~WM0_PIPE_SPRITE_MASK; + I915_WRITE(reg, val | (sprite_wm << WM0_PIPE_SPRITE_SHIFT)); DRM_DEBUG_KMS("sprite watermarks For pipe %d - %d\n", pipe, sprite_wm); -- cgit v1.2.3-70-g09d2 From aca258482ed7c600b5aeed03aa8727d94d8dd07e Mon Sep 17 00:00:00 2001 From: Eugeni Dodonov Date: Tue, 17 Jan 2012 15:25:45 -0200 Subject: drm/i915: print out which pixel format we do not support Otherwise, we are left with pretty bogus message saying that the pixel format is not supported while leaving the details to the telepatic powers. v2: use DRM_DEBUG_KMS instead of DRM_ERROR Signed-off-by: Eugeni Dodonov Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ec31350337d..cfd3a87807f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7890,7 +7890,8 @@ int intel_framebuffer_init(struct drm_device *dev, case DRM_FORMAT_VYUY: break; default: - DRM_ERROR("unsupported pixel format\n"); + DRM_DEBUG_KMS("unsupported pixel format %u\n", + mode_cmd->pixel_format); return -EINVAL; } -- cgit v1.2.3-70-g09d2 From d5ad34f7cb8b23ab165cabef69577a2a20d53195 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 20 Jan 2012 20:09:18 +0000 Subject: regulator: Implement devm_regulator_free() Allow consumers to free regulators allocated using devm_regulator_get() if they need to. This will not normally be required. Signed-off-by: Mark Brown --- drivers/regulator/core.c | 28 ++++++++++++++++++++++++++++ include/linux/regulator/consumer.h | 1 + 2 files changed, 29 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 214640db084..88bcb111ca6 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1421,6 +1421,34 @@ void regulator_put(struct regulator *regulator) } EXPORT_SYMBOL_GPL(regulator_put); +static int devm_regulator_match(struct device *dev, void *res, void *data) +{ + struct regulator **r = res; + if (!r || !*r) { + WARN_ON(!r || !*r); + return 0; + } + return *r == data; +} + +/** + * devm_regulator_put - Resource managed regulator_put() + * @regulator: regulator to free + * + * Deallocate a regulator allocated with devm_regulator_get(). Normally + * this function will not need to be called and the resource management + * code will ensure that the resource is freed. + */ +void devm_regulator_put(struct regulator *regulator) +{ + int rc; + + rc = devres_destroy(regulator->dev, devm_regulator_release, + devm_regulator_match, regulator); + WARN_ON(rc); +} +EXPORT_SYMBOL_GPL(devm_regulator_put); + static int _regulator_can_change_status(struct regulator_dev *rdev) { if (!rdev->constraints) diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index bcfe1065876..60c2f996d89 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -137,6 +137,7 @@ struct regulator *__must_check devm_regulator_get(struct device *dev, struct regulator *__must_check regulator_get_exclusive(struct device *dev, const char *id); void regulator_put(struct regulator *regulator); +void devm_regulator_free(struct regulator *regulator); /* regulator output control and status */ int regulator_enable(struct regulator *regulator); -- cgit v1.2.3-70-g09d2 From e6e740304aa2a49ef09497e6c0bb906ed7987f6b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 20 Jan 2012 20:10:08 +0000 Subject: regulator: Provide devm_regulator_bulk_get() Allow drivers to benefit from both the bulk APIs and managed resources simultaneously. Signed-off-by: Mark Brown --- drivers/regulator/core.c | 46 ++++++++++++++++++++++++++++++++++++++ include/linux/regulator/consumer.h | 2 ++ 2 files changed, 48 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 88bcb111ca6..1432c22926b 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2463,6 +2463,52 @@ err: } EXPORT_SYMBOL_GPL(regulator_bulk_get); +/** + * devm_regulator_bulk_get - managed get multiple regulator consumers + * + * @dev: Device to supply + * @num_consumers: Number of consumers to register + * @consumers: Configuration of consumers; clients are stored here. + * + * @return 0 on success, an errno on failure. + * + * This helper function allows drivers to get several regulator + * consumers in one operation with management, the regulators will + * automatically be freed when the device is unbound. If any of the + * regulators cannot be acquired then any regulators that were + * allocated will be freed before returning to the caller. + */ +int devm_regulator_bulk_get(struct device *dev, int num_consumers, + struct regulator_bulk_data *consumers) +{ + int i; + int ret; + + for (i = 0; i < num_consumers; i++) + consumers[i].consumer = NULL; + + for (i = 0; i < num_consumers; i++) { + consumers[i].consumer = devm_regulator_get(dev, + consumers[i].supply); + if (IS_ERR(consumers[i].consumer)) { + ret = PTR_ERR(consumers[i].consumer); + dev_err(dev, "Failed to get supply '%s': %d\n", + consumers[i].supply, ret); + consumers[i].consumer = NULL; + goto err; + } + } + + return 0; + +err: + for (i = 0; i < num_consumers && consumers[i].consumer; i++) + devm_regulator_put(consumers[i].consumer); + + return ret; +} +EXPORT_SYMBOL_GPL(devm_regulator_bulk_get); + static void regulator_bulk_enable_async(void *data, async_cookie_t cookie) { struct regulator_bulk_data *bulk = data; diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index 60c2f996d89..35c42834ba3 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -148,6 +148,8 @@ int regulator_disable_deferred(struct regulator *regulator, int ms); int regulator_bulk_get(struct device *dev, int num_consumers, struct regulator_bulk_data *consumers); +int devm_regulator_bulk_get(struct device *dev, int num_consumers, + struct regulator_bulk_data *consumers); int regulator_bulk_enable(int num_consumers, struct regulator_bulk_data *consumers); int regulator_bulk_disable(int num_consumers, -- cgit v1.2.3-70-g09d2 From db3dbd093a7cbb201f169ace35f6cdff562e5a77 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 22 Jan 2012 23:27:29 -0800 Subject: Input: nomadik-ske-keypad - do not assign driver's probe() method Because we are using platform_device_probe() to register the driver we do not need to assign driver's probe method. We also can mark ske_keypad_probe(), together with ske_keypad_chip_init(), as __init instead of __devinit. Acked-by: Linus Walleij Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/nomadik-ske-keypad.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/input/keyboard/nomadik-ske-keypad.c b/drivers/input/keyboard/nomadik-ske-keypad.c index 5a71e55c9c5..a804f7b815b 100644 --- a/drivers/input/keyboard/nomadik-ske-keypad.c +++ b/drivers/input/keyboard/nomadik-ske-keypad.c @@ -88,7 +88,7 @@ static void ske_keypad_set_bits(struct ske_keypad *keypad, u16 addr, * * Enable Multi key press detection, auto scan mode */ -static int __devinit ske_keypad_chip_init(struct ske_keypad *keypad) +static int __init ske_keypad_chip_init(struct ske_keypad *keypad) { u32 value; int timeout = 50; @@ -198,7 +198,7 @@ static irqreturn_t ske_keypad_irq(int irq, void *dev_id) return IRQ_HANDLED; } -static int __devinit ske_keypad_probe(struct platform_device *pdev) +static int __init ske_keypad_probe(struct platform_device *pdev) { const struct ske_keypad_platform_data *plat = pdev->dev.platform_data; struct ske_keypad *keypad; @@ -387,7 +387,6 @@ static struct platform_driver ske_keypad_driver = { .pm = &ske_keypad_dev_pm_ops, #endif }, - .probe = ske_keypad_probe, .remove = __devexit_p(ske_keypad_remove), }; module_platform_driver(ske_keypad_driver); -- cgit v1.2.3-70-g09d2 From 89f0f170fbec6290637c3172cb08ddf31f211ef0 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 22 Jan 2012 23:27:54 -0800 Subject: Input: nomadik-ske-keypad - convert to using SIMPLE_DEV_PM_OPS Also proper guard for system suspend/resume methods is CONFIG_PM_SLEEP, not CONFIG_PM. Acked-by: Linus Walleij Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/nomadik-ske-keypad.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/input/keyboard/nomadik-ske-keypad.c b/drivers/input/keyboard/nomadik-ske-keypad.c index a804f7b815b..91c2fcb8ca4 100644 --- a/drivers/input/keyboard/nomadik-ske-keypad.c +++ b/drivers/input/keyboard/nomadik-ske-keypad.c @@ -344,7 +344,7 @@ static int __devexit ske_keypad_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int ske_keypad_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); @@ -372,20 +372,16 @@ static int ske_keypad_resume(struct device *dev) return 0; } - -static const struct dev_pm_ops ske_keypad_dev_pm_ops = { - .suspend = ske_keypad_suspend, - .resume = ske_keypad_resume, -}; #endif +static SIMPLE_DEV_PM_OPS(ske_keypad_dev_pm_ops, + ske_keypad_suspend, ske_keypad_resume); + static struct platform_driver ske_keypad_driver = { .driver = { .name = "nmk-ske-keypad", .owner = THIS_MODULE, -#ifdef CONFIG_PM .pm = &ske_keypad_dev_pm_ops, -#endif }, .remove = __devexit_p(ske_keypad_remove), }; -- cgit v1.2.3-70-g09d2 From 3e8040b0a93cadeead148938188212ac7422a6bc Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 22 Jan 2012 23:27:54 -0800 Subject: Input: at32psif - convert to dev_pm_ops Convert driver to use dev_pm_ops instead of legacy PM infrastructure. Also make 'open' a bool since it is really a boolean. Signed-off-by: Dmitry Torokhov --- drivers/input/serio/at32psif.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/input/serio/at32psif.c b/drivers/input/serio/at32psif.c index 421a7442e46..d0d861fb5b8 100644 --- a/drivers/input/serio/at32psif.c +++ b/drivers/input/serio/at32psif.c @@ -98,9 +98,9 @@ struct psif { struct serio *io; void __iomem *regs; unsigned int irq; - unsigned int open; /* Prevent concurrent writes to PSIF THR. */ spinlock_t lock; + bool open; }; static irqreturn_t psif_interrupt(int irq, void *_ptr) @@ -164,7 +164,7 @@ static int psif_open(struct serio *io) psif_writel(psif, CR, PSIF_BIT(CR_TXEN) | PSIF_BIT(CR_RXEN)); psif_writel(psif, IER, PSIF_BIT(RXRDY)); - psif->open = 1; + psif->open = true; out: return retval; } @@ -173,7 +173,7 @@ static void psif_close(struct serio *io) { struct psif *psif = io->port_data; - psif->open = 0; + psif->open = false; psif_writel(psif, IDR, ~0UL); psif_writel(psif, CR, PSIF_BIT(CR_TXDIS) | PSIF_BIT(CR_RXDIS)); @@ -319,9 +319,10 @@ static int __exit psif_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM -static int psif_suspend(struct platform_device *pdev, pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int psif_suspend(struct device *dev) { + struct platform_device *pdev = to_platform_device(dev); struct psif *psif = platform_get_drvdata(pdev); if (psif->open) { @@ -332,8 +333,9 @@ static int psif_suspend(struct platform_device *pdev, pm_message_t state) return 0; } -static int psif_resume(struct platform_device *pdev) +static int psif_resume(struct device *dev) { + struct platform_device *pdev = to_platform_device(dev); struct psif *psif = platform_get_drvdata(pdev); if (psif->open) { @@ -344,19 +346,17 @@ static int psif_resume(struct platform_device *pdev) return 0; } -#else -#define psif_suspend NULL -#define psif_resume NULL #endif +static SIMPLE_DEV_PM_OPS(psif_pm_ops, psif_suspend, psif_resume); + static struct platform_driver psif_driver = { .remove = __exit_p(psif_remove), .driver = { .name = "atmel_psif", .owner = THIS_MODULE, + .pm = &psif_pm_ops, }, - .suspend = psif_suspend, - .resume = psif_resume, }; module_platform_driver(psif_driver); -- cgit v1.2.3-70-g09d2 From 409e15442fc7f7ae9d025f3ea3fdf3c60070314f Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 22 Jan 2012 23:27:54 -0800 Subject: Input: q40kbd - convert driver to the split model Convert the driver to standard spilt model arch-specific code registers platform device to which driver code can bind later. Also request IRQ immediately upon binding to the device instead of doing this when serio port is being opened. Acked-by: Geert Uytterhoeven Signed-off-by: Dmitry Torokhov --- arch/m68k/q40/config.c | 13 ++++ drivers/input/serio/q40kbd.c | 139 ++++++++++++++++++++++++------------------- 2 files changed, 92 insertions(+), 60 deletions(-) (limited to 'drivers') diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c index ad10fecec2f..be936480b96 100644 --- a/arch/m68k/q40/config.c +++ b/arch/m68k/q40/config.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -329,3 +330,15 @@ static int q40_set_rtc_pll(struct rtc_pll_info *pll) } else return -EINVAL; } + +static __init int q40_add_kbd_device(void) +{ + struct platform_device *pdev; + + pdev = platform_device_register_simple("q40kbd", -1, NULL, 0); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + + return 0; +} +arch_initcall(q40_add_kbd_device); diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c index 5eb84b3b67f..0c0df7f7380 100644 --- a/drivers/input/serio/q40kbd.c +++ b/drivers/input/serio/q40kbd.c @@ -44,26 +44,31 @@ #include #include +#define DRV_NAME "q40kbd" + MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("Q40 PS/2 keyboard controller driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:" DRV_NAME); -static DEFINE_SPINLOCK(q40kbd_lock); -static struct serio *q40kbd_port; -static struct platform_device *q40kbd_device; +struct q40kbd { + struct serio *port; + spinlock_t lock; +}; static irqreturn_t q40kbd_interrupt(int irq, void *dev_id) { + struct q40kbd *q40kbd = dev_id; unsigned long flags; - spin_lock_irqsave(&q40kbd_lock, flags); + spin_lock_irqsave(&q40kbd->lock, flags); if (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG)) - serio_interrupt(q40kbd_port, master_inb(KEYCODE_REG), 0); + serio_interrupt(q40kbd->port, master_inb(KEYCODE_REG), 0); master_outb(-1, KEYBOARD_UNLOCK_REG); - spin_unlock_irqrestore(&q40kbd_lock, flags); + spin_unlock_irqrestore(&q40kbd->lock, flags); return IRQ_HANDLED; } @@ -72,17 +77,23 @@ static irqreturn_t q40kbd_interrupt(int irq, void *dev_id) * q40kbd_flush() flushes all data that may be in the keyboard buffers */ -static void q40kbd_flush(void) +static void q40kbd_flush(struct q40kbd *q40kbd) { int maxread = 100; unsigned long flags; - spin_lock_irqsave(&q40kbd_lock, flags); + spin_lock_irqsave(&q40kbd->lock, flags); while (maxread-- && (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG))) master_inb(KEYCODE_REG); - spin_unlock_irqrestore(&q40kbd_lock, flags); + spin_unlock_irqrestore(&q40kbd->lock, flags); +} + +static void q40kbd_stop(void) +{ + master_outb(0, KEY_IRQ_ENABLE_REG); + master_outb(-1, KEYBOARD_UNLOCK_REG); } /* @@ -92,12 +103,9 @@ static void q40kbd_flush(void) static int q40kbd_open(struct serio *port) { - q40kbd_flush(); + struct q40kbd *q40kbd = port->port_data; - if (request_irq(Q40_IRQ_KEYBOARD, q40kbd_interrupt, 0, "q40kbd", NULL)) { - printk(KERN_ERR "q40kbd.c: Can't get irq %d.\n", Q40_IRQ_KEYBOARD); - return -EBUSY; - } + q40kbd_flush(q40kbd); /* off we go */ master_outb(-1, KEYBOARD_UNLOCK_REG); @@ -108,36 +116,72 @@ static int q40kbd_open(struct serio *port) static void q40kbd_close(struct serio *port) { - master_outb(0, KEY_IRQ_ENABLE_REG); - master_outb(-1, KEYBOARD_UNLOCK_REG); - free_irq(Q40_IRQ_KEYBOARD, NULL); + struct q40kbd *q40kbd = port->port_data; - q40kbd_flush(); + q40kbd_stop(); + q40kbd_flush(q40kbd); } -static int __devinit q40kbd_probe(struct platform_device *dev) +static int __devinit q40kbd_probe(struct platform_device *pdev) { - q40kbd_port = kzalloc(sizeof(struct serio), GFP_KERNEL); - if (!q40kbd_port) - return -ENOMEM; - - q40kbd_port->id.type = SERIO_8042; - q40kbd_port->open = q40kbd_open; - q40kbd_port->close = q40kbd_close; - q40kbd_port->dev.parent = &dev->dev; - strlcpy(q40kbd_port->name, "Q40 Kbd Port", sizeof(q40kbd_port->name)); - strlcpy(q40kbd_port->phys, "Q40", sizeof(q40kbd_port->phys)); - - serio_register_port(q40kbd_port); + struct q40kbd *q40kbd; + struct serio *port; + int error; + + q40kbd = kzalloc(sizeof(struct q40kbd), GFP_KERNEL); + port = kzalloc(sizeof(struct serio), GFP_KERNEL); + if (!q40kbd || !port) { + error = -ENOMEM; + goto err_free_mem; + } + + q40kbd->port = port; + spin_lock_init(&q40kbd->lock); + + port->id.type = SERIO_8042; + port->open = q40kbd_open; + port->close = q40kbd_close; + port->port_data = q40kbd; + port->dev.parent = &pdev->dev; + strlcpy(port->name, "Q40 Kbd Port", sizeof(port->name)); + strlcpy(port->phys, "Q40", sizeof(port->phys)); + + q40kbd_stop(); + + error = request_irq(Q40_IRQ_KEYBOARD, q40kbd_interrupt, 0, + DRV_NAME, q40kbd); + if (error) { + dev_err(&pdev->dev, "Can't get irq %d.\n", Q40_IRQ_KEYBOARD); + goto err_free_mem; + } + + serio_register_port(q40kbd->port); + + platform_set_drvdata(pdev, q40kbd); printk(KERN_INFO "serio: Q40 kbd registered\n"); return 0; + +err_free_mem: + kfree(port); + kfree(q40kbd); + return error; } -static int __devexit q40kbd_remove(struct platform_device *dev) +static int __devexit q40kbd_remove(struct platform_device *pdev) { - serio_unregister_port(q40kbd_port); - + struct q40kbd *q40kbd = platform_get_drvdata(pdev); + + /* + * q40kbd_close() will be called as part of unregistering + * and will ensure that IRQ is turned off, so it is safe + * to unregister port first and free IRQ later. + */ + serio_unregister_port(q40kbd->port); + free_irq(Q40_IRQ_KEYBOARD, q40kbd); + kfree(q40kbd); + + platform_set_drvdata(pdev, NULL); return 0; } @@ -146,41 +190,16 @@ static struct platform_driver q40kbd_driver = { .name = "q40kbd", .owner = THIS_MODULE, }, - .probe = q40kbd_probe, .remove = __devexit_p(q40kbd_remove), }; static int __init q40kbd_init(void) { - int error; - - if (!MACH_IS_Q40) - return -ENODEV; - - error = platform_driver_register(&q40kbd_driver); - if (error) - return error; - - q40kbd_device = platform_device_alloc("q40kbd", -1); - if (!q40kbd_device) - goto err_unregister_driver; - - error = platform_device_add(q40kbd_device); - if (error) - goto err_free_device; - - return 0; - - err_free_device: - platform_device_put(q40kbd_device); - err_unregister_driver: - platform_driver_unregister(&q40kbd_driver); - return error; + return platform_driver_probe(&q40kbd_driver, q40kbd_probe); } static void __exit q40kbd_exit(void) { - platform_device_unregister(q40kbd_device); platform_driver_unregister(&q40kbd_driver); } -- cgit v1.2.3-70-g09d2 From 69898e512a4c27017aec43796bef8fe1dd1ec661 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 22 Jan 2012 23:27:54 -0800 Subject: Input: samsung-keypad - don't synchronise with runtime PM put We don't actually care if the device has been runtime suspended immediately so we can just drop the reference without waiting for any state change to be implemented. This may allow us to avoid some suspend/resume cycles and is a bit more friendly to the rest of the system. Signed-off-by: Mark Brown Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/samsung-keypad.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c index b746fce2d12..395b3af9f73 100644 --- a/drivers/input/keyboard/samsung-keypad.c +++ b/drivers/input/keyboard/samsung-keypad.c @@ -178,7 +178,7 @@ static irqreturn_t samsung_keypad_irq(int irq, void *dev_id) } while (key_down && !keypad->stopped); - pm_runtime_put_sync(&keypad->pdev->dev); + pm_runtime_put(&keypad->pdev->dev); return IRQ_HANDLED; } @@ -202,7 +202,7 @@ static void samsung_keypad_start(struct samsung_keypad *keypad) /* KEYIFCOL reg clear. */ writel(0, keypad->base + SAMSUNG_KEYIFCOL); - pm_runtime_put_sync(&keypad->pdev->dev); + pm_runtime_put(&keypad->pdev->dev); } static void samsung_keypad_stop(struct samsung_keypad *keypad) @@ -232,7 +232,7 @@ static void samsung_keypad_stop(struct samsung_keypad *keypad) */ enable_irq(keypad->irq); - pm_runtime_put_sync(&keypad->pdev->dev); + pm_runtime_put(&keypad->pdev->dev); } static int samsung_keypad_open(struct input_dev *input_dev) -- cgit v1.2.3-70-g09d2 From b6834b02e476ff0e99b6814665839e37affa31f0 Mon Sep 17 00:00:00 2001 From: Rakesh Iyer Date: Sun, 22 Jan 2012 23:27:54 -0800 Subject: Input: tegra-kbc - enable key interrupt for wakeup Enable keypress interrupt to support wakeup from low power state. Signed-off-by: Rakesh Iyer Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/tegra-kbc.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers') diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index a136e2e832b..b307a46ecef 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c @@ -48,6 +48,7 @@ #define KBC_FIFO_TH_CNT_SHIFT(cnt) (cnt << 14) #define KBC_DEBOUNCE_CNT_SHIFT(cnt) (cnt << 4) #define KBC_CONTROL_FIFO_CNT_INT_EN (1 << 3) +#define KBC_CONTROL_KEYPRESS_INT_EN (1 << 1) #define KBC_CONTROL_KBC_EN (1 << 0) /* KBC Interrupt Register */ @@ -356,6 +357,18 @@ static void tegra_kbc_set_fifo_interrupt(struct tegra_kbc *kbc, bool enable) writel(val, kbc->mmio + KBC_CONTROL_0); } +static void tegra_kbc_set_keypress_interrupt(struct tegra_kbc *kbc, bool enable) +{ + u32 val; + + val = readl(kbc->mmio + KBC_CONTROL_0); + if (enable) + val |= KBC_CONTROL_KEYPRESS_INT_EN; + else + val &= ~KBC_CONTROL_KEYPRESS_INT_EN; + writel(val, kbc->mmio + KBC_CONTROL_0); +} + static void tegra_kbc_keypress_timer(unsigned long data) { struct tegra_kbc *kbc = (struct tegra_kbc *)data; @@ -831,6 +844,8 @@ static int tegra_kbc_suspend(struct device *dev) msleep(30); kbc->keypress_caused_wake = false; + /* Enable keypress interrupt before going into suspend. */ + tegra_kbc_set_keypress_interrupt(kbc, true); enable_irq(kbc->irq); enable_irq_wake(kbc->irq); } else { @@ -852,6 +867,8 @@ static int tegra_kbc_resume(struct device *dev) if (device_may_wakeup(&pdev->dev)) { disable_irq_wake(kbc->irq); tegra_kbc_setup_wakekeys(kbc, false); + /* We will use fifo interrupts for key detection. */ + tegra_kbc_set_keypress_interrupt(kbc, false); /* Restore the resident time of continuous polling mode. */ writel(kbc->cp_to_wkup_dly, kbc->mmio + KBC_TO_CNT_0); -- cgit v1.2.3-70-g09d2 From 22f0d90a34827812413bb3fbeda6a2a79bb58423 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 21 Jan 2012 12:01:14 +0000 Subject: regmap: Support register patch sets Device manufacturers frequently provide register sequences, usually not fully documented, to be run at startup in order to provide better defaults for devices (for example, improving performance in the light of silicon evaluation). Support such updates by allowing drivers to register update sets with the core. These updates will be written to the device immediately and will also be rewritten when the cache is synced. The assumption is that the reason for resyncing the cache will always be that the device has been powered off. If this turns out to not be the case then a separate operation can be provided. Currently the implementation only allows a single set of updates to be specified for a device, this could be extended in future. Signed-off-by: Mark Brown --- drivers/base/regmap/internal.h | 3 +++ drivers/base/regmap/regcache.c | 11 ++++++++ drivers/base/regmap/regmap.c | 58 ++++++++++++++++++++++++++++++++++++++++++ include/linux/regmap.h | 3 +++ 4 files changed, 75 insertions(+) (limited to 'drivers') diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index 1a02b7537c8..d141b80479b 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h @@ -75,6 +75,9 @@ struct regmap { const void *reg_defaults_raw; void *cache; bool cache_dirty; + + struct reg_default *patch; + int patch_regs; }; struct regcache_ops { diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 1ead66186b7..ce2034c10ff 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -268,6 +268,17 @@ int regcache_sync(struct regmap *map) map->cache_ops->name); name = map->cache_ops->name; trace_regcache_sync(map->dev, name, "start"); + + /* Apply any patch first */ + for (i = 0; i < map->patch_regs; i++) { + ret = _regmap_write(map, map->patch[i].reg, map->patch[i].def); + if (ret != 0) { + dev_err(map->dev, "Failed to write %x = %x: %d\n", + map->patch[i].reg, map->patch[i].def, ret); + goto out; + } + } + if (!map->cache_dirty) goto out; if (map->cache_ops->sync) { diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index be10a4ff660..28e89fd7c28 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -669,6 +669,64 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg, } EXPORT_SYMBOL_GPL(regmap_update_bits_check); +/** + * regmap_register_patch: Register and apply register updates to be applied + * on device initialistion + * + * @map: Register map to apply updates to. + * @regs: Values to update. + * @num_regs: Number of entries in regs. + * + * Register a set of register updates to be applied to the device + * whenever the device registers are synchronised with the cache and + * apply them immediately. Typically this is used to apply + * corrections to be applied to the device defaults on startup, such + * as the updates some vendors provide to undocumented registers. + */ +int regmap_register_patch(struct regmap *map, const struct reg_default *regs, + int num_regs) +{ + int i, ret; + bool bypass; + + /* If needed the implementation can be extended to support this */ + if (map->patch) + return -EBUSY; + + mutex_lock(&map->lock); + + bypass = map->cache_bypass; + + map->cache_bypass = true; + + /* Write out first; it's useful to apply even if we fail later. */ + for (i = 0; i < num_regs; i++) { + ret = _regmap_write(map, regs[i].reg, regs[i].def); + if (ret != 0) { + dev_err(map->dev, "Failed to write %x = %x: %d\n", + regs[i].reg, regs[i].def, ret); + goto out; + } + } + + map->patch = kcalloc(sizeof(struct reg_default), num_regs, GFP_KERNEL); + if (map->patch != NULL) { + memcpy(map->patch, regs, + num_regs * sizeof(struct reg_default)); + map->patch_regs = num_regs; + } else { + ret = -ENOMEM; + } + +out: + map->cache_bypass = bypass; + + mutex_unlock(&map->lock); + + return ret; +} +EXPORT_SYMBOL_GPL(regmap_register_patch); + static int __init regmap_initcall(void) { regmap_debugfs_initcall(); diff --git a/include/linux/regmap.h b/include/linux/regmap.h index eb93921cdd3..860739a8a6d 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -149,6 +149,9 @@ void regcache_cache_only(struct regmap *map, bool enable); void regcache_cache_bypass(struct regmap *map, bool enable); void regcache_mark_dirty(struct regmap *map); +int regmap_register_patch(struct regmap *map, const struct reg_default *regs, + int num_regs); + /** * Description of an IRQ for the generic regmap irq_chip. * -- cgit v1.2.3-70-g09d2 From aa104b2fea3ced2a562c480448a2f346c3ab61f4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 23 Jan 2012 13:15:22 -0200 Subject: [media] cinergyT2-fe: Fix bandwdith settings Changeset 7830bbaff9f mangled the bandwidth field for CinergyT2. Properly fill it. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/cinergyT2-fe.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/cinergyT2-fe.c b/drivers/media/dvb/dvb-usb/cinergyT2-fe.c index 8a57ed8272d..1efc028a76c 100644 --- a/drivers/media/dvb/dvb-usb/cinergyT2-fe.c +++ b/drivers/media/dvb/dvb-usb/cinergyT2-fe.c @@ -276,14 +276,15 @@ static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe) param.flags = 0; switch (fep->bandwidth_hz) { + default: case 8000000: - param.bandwidth = 0; + param.bandwidth = 8; break; case 7000000: - param.bandwidth = 1; + param.bandwidth = 7; break; case 6000000: - param.bandwidth = 2; + param.bandwidth = 6; break; } -- cgit v1.2.3-70-g09d2 From 93596ef7db3e9bcc9306c3e93cf28ce1048858b6 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 8 Nov 2011 05:47:08 -0300 Subject: [media] omap_vout: fix section mismatch Fix the following warning by using platform_driver_probe() instead of platform_driver_register(): WARNING: drivers/media/video/omap/omap-vout.o(.data+0x24): Section mismatch in reference from the variable omap_vout_driver to the function .init.text:omap_vout_probe() The variable omap_vout_driver references the function __init omap_vout_probe() Signed-off-by: Tomi Valkeinen Acked-by: Vaibhav Hiremath Tested-by: Vaibhav Hiremath Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/omap/omap_vout.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 1fb7d5bd5ec..88cf9d95263 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -2268,13 +2268,12 @@ static struct platform_driver omap_vout_driver = { .driver = { .name = VOUT_NAME, }, - .probe = omap_vout_probe, .remove = omap_vout_remove, }; static int __init omap_vout_init(void) { - if (platform_driver_register(&omap_vout_driver) != 0) { + if (platform_driver_probe(&omap_vout_driver, omap_vout_probe) != 0) { printk(KERN_ERR VOUT_NAME ":Could not register Video driver\n"); return -EINVAL; } -- cgit v1.2.3-70-g09d2 From 583aa3a9b5ca846a84f7dd87bdc4b75dca07b011 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 11 Jan 2012 06:45:05 -0300 Subject: [media] V4L2: Add per-device-node capabilities If V4L2_CAP_DEVICE_CAPS is set, then the new device_caps field is filled with the capabilities of the opened device node. The capabilities field traditionally contains the capabilities of the physical device, being a superset of all capabilities available at the several device nodes. E.g., if you open /dev/video0, then if it contains VBI caps then that means that there is a corresponding vbi node as well. And the capabilities field of both the video and vbi nodes should contain identical caps. However, it would be very useful to also have a capabilities field that contains just the caps for the currently open device, hence the new CAP bit and field. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/media/v4l/compat.xml | 4 +++ Documentation/DocBook/media/v4l/v4l2.xml | 9 +++++- .../DocBook/media/v4l/vidioc-querycap.xml | 36 ++++++++++++++++++++-- drivers/media/video/cx231xx/cx231xx-417.c | 1 - drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 1 - drivers/media/video/v4l2-ioctl.c | 6 ++-- include/linux/videodev2.h | 29 +++++++++++------ 7 files changed, 69 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/Documentation/DocBook/media/v4l/compat.xml b/Documentation/DocBook/media/v4l/compat.xml index c736380b464..c93298ff327 100644 --- a/Documentation/DocBook/media/v4l/compat.xml +++ b/Documentation/DocBook/media/v4l/compat.xml @@ -2393,6 +2393,10 @@ details. to the User controls class. + + Added the device_caps field to struct v4l2_capabilities and added the new + V4L2_CAP_DEVICE_CAPS capability. + diff --git a/Documentation/DocBook/media/v4l/v4l2.xml b/Documentation/DocBook/media/v4l/v4l2.xml index e97c512861b..dce3fef15bc 100644 --- a/Documentation/DocBook/media/v4l/v4l2.xml +++ b/Documentation/DocBook/media/v4l/v4l2.xml @@ -127,6 +127,13 @@ structs, ioctls) must be noted in more detail in the history chapter (compat.xml), along with the possible impact on existing drivers and applications. --> + + 3.3 + 2012-01-11 + hv + Added device_caps field to struct v4l2_capabilities. + + 3.2 2011-08-26 @@ -417,7 +424,7 @@ and discussions on the V4L mailing list. Video for Linux Two API Specification - Revision 3.2 + Revision 3.3 &sub-common; diff --git a/Documentation/DocBook/media/v4l/vidioc-querycap.xml b/Documentation/DocBook/media/v4l/vidioc-querycap.xml index e3664d6f2de..4643505cd4c 100644 --- a/Documentation/DocBook/media/v4l/vidioc-querycap.xml +++ b/Documentation/DocBook/media/v4l/vidioc-querycap.xml @@ -124,12 +124,35 @@ printf ("Version: %u.%u.%u\n", __u32 capabilities - Device capabilities, see . + Available capabilities of the physical device as a whole, see . The same physical device can export + multiple devices in /dev (e.g. /dev/videoX, /dev/vbiY and /dev/radioZ). + The capabilities field should contain a union + of all capabilities available around the several V4L2 devices exported + to userspace. + For all those devices the capabilities field + returns the same set of capabilities. This allows applications to open + just one of the devices (typically the video device) and discover whether + video, vbi and/or radio are also supported. + __u32 - reserved[4] + device_caps + Device capabilities of the opened device, see . Should contain the available capabilities + of that specific device node. So, for example, device_caps + of a radio device will only contain radio related capabilities and + no video or vbi capabilities. This field is only set if the capabilities + field contains the V4L2_CAP_DEVICE_CAPS capability. + Only the capabilities field can have the + V4L2_CAP_DEVICE_CAPS capability, device_caps + will never set V4L2_CAP_DEVICE_CAPS. + + + + __u32 + reserved[3] Reserved for future extensions. Drivers must set this array to zero. @@ -276,6 +299,13 @@ linkend="async">asynchronous I/O methods. The device supports the streaming I/O method. + + V4L2_CAP_DEVICE_CAPS + 0x80000000 + The driver fills the device_caps + field. This capability can only appear in the capabilities + field and never in the device_caps field. + diff --git a/drivers/media/video/cx231xx/cx231xx-417.c b/drivers/media/video/cx231xx/cx231xx-417.c index f8f0e59cd58..d4327dab5a3 100644 --- a/drivers/media/video/cx231xx/cx231xx-417.c +++ b/drivers/media/video/cx231xx/cx231xx-417.c @@ -1686,7 +1686,6 @@ static struct v4l2_capability pvr_capability = { .capabilities = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO | V4L2_CAP_STREAMING | V4L2_CAP_READWRITE), - .reserved = {0, 0, 0, 0} }; static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index 6d666174dbb..e1111d968a3 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c @@ -96,7 +96,6 @@ static struct v4l2_capability pvr_capability ={ .capabilities = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO | V4L2_CAP_READWRITE), - .reserved = {0,0,0,0} }; static struct v4l2_fmtdesc pvr_fmtdesc [] = { diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index 3f623859a33..d0d7281e01e 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c @@ -540,10 +540,12 @@ static long __video_do_ioctl(struct file *file, if (!ret) dbgarg(cmd, "driver=%s, card=%s, bus=%s, " "version=0x%08x, " - "capabilities=0x%08x\n", + "capabilities=0x%08x, " + "device_caps=0x%08x\n", cap->driver, cap->card, cap->bus_info, cap->version, - cap->capabilities); + cap->capabilities, + cap->device_caps); break; } diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 5e11f8a1f86..0db05033c2e 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -235,16 +235,25 @@ struct v4l2_fract { __u32 denominator; }; -/* - * D R I V E R C A P A B I L I T I E S - */ +/** + * struct v4l2_capability - Describes V4L2 device caps returned by VIDIOC_QUERYCAP + * + * @driver: name of the driver module (e.g. "bttv") + * @card: name of the card (e.g. "Hauppauge WinTV") + * @bus_info: name of the bus (e.g. "PCI:" + pci_name(pci_dev) ) + * @version: KERNEL_VERSION + * @capabilities: capabilities of the physical device as a whole + * @device_caps: capabilities accessed via this particular device (node) + * @reserved: reserved fields for future extensions + */ struct v4l2_capability { - __u8 driver[16]; /* i.e. "bttv" */ - __u8 card[32]; /* i.e. "Hauppauge WinTV" */ - __u8 bus_info[32]; /* "PCI:" + pci_name(pci_dev) */ - __u32 version; /* should use KERNEL_VERSION() */ - __u32 capabilities; /* Device capabilities */ - __u32 reserved[4]; + __u8 driver[16]; + __u8 card[32]; + __u8 bus_info[32]; + __u32 version; + __u32 capabilities; + __u32 device_caps; + __u32 reserved[3]; }; /* Values for 'capabilities' field */ @@ -274,6 +283,8 @@ struct v4l2_capability { #define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */ #define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */ +#define V4L2_CAP_DEVICE_CAPS 0x80000000 /* sets device capabilities field */ + /* * V I D E O I M A G E F O R M A T */ -- cgit v1.2.3-70-g09d2 From a8187c42fbe594754eadd37cf16d3ad7c704869d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 7 Nov 2011 06:53:06 -0300 Subject: [media] vivi: set device_caps Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/vivi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 7d754fbcccb..84ea88dc10a 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c @@ -819,8 +819,9 @@ static int vidioc_querycap(struct file *file, void *priv, strcpy(cap->driver, "vivi"); strcpy(cap->card, "vivi"); strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | \ - V4L2_CAP_READWRITE; + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | + V4L2_CAP_READWRITE | V4L2_CAP_DEVICE_CAPS; + cap->device_caps = cap->capabilities; return 0; } -- cgit v1.2.3-70-g09d2 From d0c8b2d400279f7d4d530ede8c7cb66f75810007 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 7 Nov 2011 07:25:10 -0300 Subject: [media] ivtv: setup per-device caps Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-driver.h | 1 + drivers/media/video/ivtv/ivtv-ioctl.c | 7 +++++-- drivers/media/video/ivtv/ivtv-streams.c | 14 ++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index 06f3d78389b..20845d65d34 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h @@ -331,6 +331,7 @@ struct ivtv_stream { struct ivtv *itv; /* for ease of use */ const char *name; /* name of the stream */ int type; /* stream type */ + u32 caps; /* V4L2 capabilities */ struct v4l2_fh *fh; /* pointer to the streaming filehandle */ spinlock_t qlock; /* locks access to the queues */ diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index c4bc4814309..b0630773e50 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -754,12 +754,15 @@ static int ivtv_s_register(struct file *file, void *fh, struct v4l2_dbg_register static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap) { - struct ivtv *itv = fh2id(fh)->itv; + struct ivtv_open_id *id = fh2id(file->private_data); + struct ivtv *itv = id->itv; + struct ivtv_stream *s = &itv->streams[id->type]; strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver)); strlcpy(vcap->card, itv->card_name, sizeof(vcap->card)); snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev)); - vcap->capabilities = itv->v4l2_cap; /* capabilities */ + vcap->capabilities = itv->v4l2_cap | V4L2_CAP_DEVICE_CAPS; + vcap->device_caps = s->caps; return 0; } diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index c6e28b4ebbe..e5039f4f7f0 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c @@ -78,60 +78,73 @@ static struct { int num_offset; int dma, pio; enum v4l2_buf_type buf_type; + u32 v4l2_caps; const struct v4l2_file_operations *fops; } ivtv_stream_info[] = { { /* IVTV_ENC_STREAM_TYPE_MPG */ "encoder MPG", VFL_TYPE_GRABBER, 0, PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | + V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, &ivtv_v4l2_enc_fops }, { /* IVTV_ENC_STREAM_TYPE_YUV */ "encoder YUV", VFL_TYPE_GRABBER, IVTV_V4L2_ENC_YUV_OFFSET, PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | + V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, &ivtv_v4l2_enc_fops }, { /* IVTV_ENC_STREAM_TYPE_VBI */ "encoder VBI", VFL_TYPE_VBI, 0, PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VBI_CAPTURE, + V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE | V4L2_CAP_TUNER | + V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, &ivtv_v4l2_enc_fops }, { /* IVTV_ENC_STREAM_TYPE_PCM */ "encoder PCM", VFL_TYPE_GRABBER, IVTV_V4L2_ENC_PCM_OFFSET, PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_PRIVATE, + V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, &ivtv_v4l2_enc_fops }, { /* IVTV_ENC_STREAM_TYPE_RAD */ "encoder radio", VFL_TYPE_RADIO, 0, PCI_DMA_NONE, 1, V4L2_BUF_TYPE_PRIVATE, + V4L2_CAP_RADIO | V4L2_CAP_TUNER, &ivtv_v4l2_enc_fops }, { /* IVTV_DEC_STREAM_TYPE_MPG */ "decoder MPG", VFL_TYPE_GRABBER, IVTV_V4L2_DEC_MPG_OFFSET, PCI_DMA_TODEVICE, 0, V4L2_BUF_TYPE_VIDEO_OUTPUT, + V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, &ivtv_v4l2_dec_fops }, { /* IVTV_DEC_STREAM_TYPE_VBI */ "decoder VBI", VFL_TYPE_VBI, IVTV_V4L2_DEC_VBI_OFFSET, PCI_DMA_NONE, 1, V4L2_BUF_TYPE_VBI_CAPTURE, + V4L2_CAP_SLICED_VBI_CAPTURE | V4L2_CAP_READWRITE, &ivtv_v4l2_enc_fops }, { /* IVTV_DEC_STREAM_TYPE_VOUT */ "decoder VOUT", VFL_TYPE_VBI, IVTV_V4L2_DEC_VOUT_OFFSET, PCI_DMA_NONE, 1, V4L2_BUF_TYPE_VBI_OUTPUT, + V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, &ivtv_v4l2_dec_fops }, { /* IVTV_DEC_STREAM_TYPE_YUV */ "decoder YUV", VFL_TYPE_GRABBER, IVTV_V4L2_DEC_YUV_OFFSET, PCI_DMA_TODEVICE, 0, V4L2_BUF_TYPE_VIDEO_OUTPUT, + V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, &ivtv_v4l2_dec_fops } }; @@ -149,6 +162,7 @@ static void ivtv_stream_init(struct ivtv *itv, int type) s->itv = itv; s->type = type; s->name = ivtv_stream_info[type].name; + s->caps = ivtv_stream_info[type].v4l2_caps; if (ivtv_stream_info[type].pio) s->dma = PCI_DMA_NONE; -- cgit v1.2.3-70-g09d2 From a8ea0218625699a5c635655a17b565bab5888ea1 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Fri, 20 Jan 2012 19:07:18 -0300 Subject: [media] it913x v1.23 use it913x_config.chip_ver to select firmware As recommended by Jason at ITE, the chip version should select firmware. However, to continue to support IT9137 firmware with different configuration the driver will use udev->descriptor.idVendor to select the difference between IT9135 and IT9137. Signed-off-by: Malcolm Priestley Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/it913x.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/it913x.c b/drivers/media/dvb/dvb-usb/it913x.c index 9f01cd7a6e3..50d578c7b8c 100644 --- a/drivers/media/dvb/dvb-usb/it913x.c +++ b/drivers/media/dvb/dvb-usb/it913x.c @@ -388,19 +388,12 @@ static int ite_firmware_select(struct usb_device *udev, { int sw; /* auto switch */ - if (le16_to_cpu(udev->descriptor.idProduct) == - USB_PID_ITETECH_IT9135) - sw = IT9135_V1_FW; - else if (le16_to_cpu(udev->descriptor.idProduct) == - USB_PID_ITETECH_IT9135_9005) + if (le16_to_cpu(udev->descriptor.idVendor) == USB_VID_KWORLD_2) + sw = IT9137_FW; + else if (it913x_config.chip_ver == 1) sw = IT9135_V1_FW; - else if (le16_to_cpu(udev->descriptor.idProduct) == - USB_PID_ITETECH_IT9135_9006) { + else sw = IT9135_V2_FW; - if (it913x_config.tuner_id_0 == 0) - it913x_config.tuner_id_0 = IT9135_60; - } else - sw = IT9137_FW; /* force switch */ if (dvb_usb_it913x_firmware != IT9135_AUTO) @@ -416,6 +409,8 @@ static int ite_firmware_select(struct usb_device *udev, it913x_config.firmware_ver = 1; it913x_config.adc_x2 = 1; props->firmware = fw_it9135_v2; + if (it913x_config.tuner_id_0 == 0) + it913x_config.tuner_id_0 = IT9135_60; break; case IT9137_FW: default: @@ -823,5 +818,5 @@ module_usb_driver(it913x_driver); MODULE_AUTHOR("Malcolm Priestley "); MODULE_DESCRIPTION("it913x USB 2 Driver"); -MODULE_VERSION("1.22"); +MODULE_VERSION("1.23"); MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From 91c6cc9b5c216bd067f9af2cc64fcbe190755865 Mon Sep 17 00:00:00 2001 From: Dan Magenheimer Date: Thu, 12 Jan 2012 14:03:25 -0500 Subject: mm: zcache/tmem/cleancache: s/flush/invalidate/ Complete the renaming from "flush" to "invalidate" across both tmem frontends (cleancache and frontswap) and both tmem backends (Xen and zcache), as required by akpm. This change is completely cosmetic. [v10: no change] [v9: akpm@linux-foundation.org: change "flush" to "invalidate", part 3] Signed-off-by: Dan Magenheimer Cc: Kamezawa Hiroyuki Cc: Jan Beulich Acked-by: Seth Jennings Cc: Jeremy Fitzhardinge Cc: Hugh Dickins Cc: Johannes Weiner Cc: Nitin Gupta Cc: Matthew Wilcox Cc: Chris Mason Cc: Rik Riel Cc: Andrew Morton [v11: Remove the frontswap part] Signed-off-by: Konrad Rzeszutek Wilk --- drivers/staging/zcache/zcache-main.c | 10 +++++----- drivers/xen/tmem.c | 10 +++++----- include/linux/cleancache.h | 11 +++-------- mm/cleancache.c | 7 ++++--- 4 files changed, 17 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index 56c1f9c80dc..49c8791462f 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c @@ -1758,9 +1758,9 @@ static int zcache_cleancache_init_shared_fs(char *uuid, size_t pagesize) static struct cleancache_ops zcache_cleancache_ops = { .put_page = zcache_cleancache_put_page, .get_page = zcache_cleancache_get_page, - .flush_page = zcache_cleancache_flush_page, - .flush_inode = zcache_cleancache_flush_inode, - .flush_fs = zcache_cleancache_flush_fs, + .invalidate_page = zcache_cleancache_flush_page, + .invalidate_inode = zcache_cleancache_flush_inode, + .invalidate_fs = zcache_cleancache_flush_fs, .init_shared_fs = zcache_cleancache_init_shared_fs, .init_fs = zcache_cleancache_init_fs }; @@ -1868,8 +1868,8 @@ static void zcache_frontswap_init(unsigned ignored) static struct frontswap_ops zcache_frontswap_ops = { .put_page = zcache_frontswap_put_page, .get_page = zcache_frontswap_get_page, - .flush_page = zcache_frontswap_flush_page, - .flush_area = zcache_frontswap_flush_area, + .invalidate_page = zcache_frontswap_flush_page, + .invalidate_area = zcache_frontswap_flush_area, .init = zcache_frontswap_init }; diff --git a/drivers/xen/tmem.c b/drivers/xen/tmem.c index d369965e8f8..17d9e37beba 100644 --- a/drivers/xen/tmem.c +++ b/drivers/xen/tmem.c @@ -242,9 +242,9 @@ __setup("nocleancache", no_cleancache); static struct cleancache_ops tmem_cleancache_ops = { .put_page = tmem_cleancache_put_page, .get_page = tmem_cleancache_get_page, - .flush_page = tmem_cleancache_flush_page, - .flush_inode = tmem_cleancache_flush_inode, - .flush_fs = tmem_cleancache_flush_fs, + .invalidate_page = tmem_cleancache_flush_page, + .invalidate_inode = tmem_cleancache_flush_inode, + .invalidate_fs = tmem_cleancache_flush_fs, .init_shared_fs = tmem_cleancache_init_shared_fs, .init_fs = tmem_cleancache_init_fs }; @@ -369,8 +369,8 @@ __setup("nofrontswap", no_frontswap); static struct frontswap_ops tmem_frontswap_ops = { .put_page = tmem_frontswap_put_page, .get_page = tmem_frontswap_get_page, - .flush_page = tmem_frontswap_flush_page, - .flush_area = tmem_frontswap_flush_area, + .invalidate_page = tmem_frontswap_flush_page, + .invalidate_area = tmem_frontswap_flush_area, .init = tmem_frontswap_init }; #endif diff --git a/include/linux/cleancache.h b/include/linux/cleancache.h index 66fb63b243a..42e55deee75 100644 --- a/include/linux/cleancache.h +++ b/include/linux/cleancache.h @@ -28,14 +28,9 @@ struct cleancache_ops { pgoff_t, struct page *); void (*put_page)(int, struct cleancache_filekey, pgoff_t, struct page *); - /* - * NOTE: per akpm, flush_page, flush_inode and flush_fs will be - * renamed to invalidate_* in a later commit in which all - * dependencies (i.e Xen, zcache) will be renamed simultaneously - */ - void (*flush_page)(int, struct cleancache_filekey, pgoff_t); - void (*flush_inode)(int, struct cleancache_filekey); - void (*flush_fs)(int); + void (*invalidate_page)(int, struct cleancache_filekey, pgoff_t); + void (*invalidate_inode)(int, struct cleancache_filekey); + void (*invalidate_fs)(int); }; extern struct cleancache_ops diff --git a/mm/cleancache.c b/mm/cleancache.c index 237c6e0feea..b9c198bc698 100644 --- a/mm/cleancache.c +++ b/mm/cleancache.c @@ -161,7 +161,8 @@ void __cleancache_invalidate_page(struct address_space *mapping, if (pool_id >= 0) { VM_BUG_ON(!PageLocked(page)); if (cleancache_get_key(mapping->host, &key) >= 0) { - (*cleancache_ops.flush_page)(pool_id, key, page->index); + (*cleancache_ops.invalidate_page)(pool_id, + key, page->index); cleancache_flushes++; } } @@ -179,7 +180,7 @@ void __cleancache_invalidate_inode(struct address_space *mapping) struct cleancache_filekey key = { .u.key = { 0 } }; if (pool_id >= 0 && cleancache_get_key(mapping->host, &key) >= 0) - (*cleancache_ops.flush_inode)(pool_id, key); + (*cleancache_ops.invalidate_inode)(pool_id, key); } EXPORT_SYMBOL(__cleancache_invalidate_inode); @@ -193,7 +194,7 @@ void __cleancache_invalidate_fs(struct super_block *sb) if (sb->cleancache_poolid >= 0) { int old_poolid = sb->cleancache_poolid; sb->cleancache_poolid = -1; - (*cleancache_ops.flush_fs)(old_poolid); + (*cleancache_ops.invalidate_fs)(old_poolid); } } EXPORT_SYMBOL(__cleancache_invalidate_fs); -- cgit v1.2.3-70-g09d2 From c688419141ad6134d7973fcf182e3719e98d7491 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 9 Jan 2012 13:14:56 +0100 Subject: usb: gadget: dummy_hcd: initialize max_streams early While playing with uasp I noticed that it does not work with dummy_hcd. The problem is that uasp requires a stream capable endpoint which it is requesting at bind time like every other gadget. dummy_hcd however initializes the max_stream value after connect once it knows if it runs at SS or not. I don't think that it is might be wrong to initialize the stream capability even at HS speed. The gadget may not use this descriptor at HS speed so it should not cause any damage. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/dummy_hcd.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index db815c2da7e..5a21bf5c765 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -800,17 +800,10 @@ static int dummy_set_selfpowered (struct usb_gadget *_gadget, int value) static void dummy_udc_udpate_ep0(struct dummy *dum) { - u32 i; - - if (dum->gadget.speed == USB_SPEED_SUPER) { - for (i = 0; i < DUMMY_ENDPOINTS; i++) - dum->ep[i].ep.max_streams = 0x10; + if (dum->gadget.speed == USB_SPEED_SUPER) dum->ep[0].ep.maxpacket = 9; - } else { - for (i = 0; i < DUMMY_ENDPOINTS; i++) - dum->ep[i].ep.max_streams = 0; + else dum->ep[0].ep.maxpacket = 64; - } } static int dummy_pullup (struct usb_gadget *_gadget, int value) @@ -954,6 +947,7 @@ static void init_dummy_udc_hw(struct dummy *dum) ep->halted = ep->wedged = ep->already_seen = ep->setup_stage = 0; ep->ep.maxpacket = ~0; + ep->ep.max_streams = 16; ep->last_io = jiffies; ep->gadget = &dum->gadget; ep->desc = NULL; -- cgit v1.2.3-70-g09d2 From a04ce20d9f5e9484ed3879e1290bd05933cbbe2a Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 9 Jan 2012 13:14:57 +0100 Subject: usb: gadget: dummy_hcd: move the transfer part into its own function This patch moves the part of the code which does the bare transfer into its function. It is a preparion for the implementation of sg support. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/dummy_hcd.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 5a21bf5c765..61e893ac254 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -1133,6 +1133,23 @@ static int dummy_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) return rc; } +static int dummy_perform_transfer(struct urb *urb, struct dummy_request *req, + u32 len) +{ + void *ubuf, *rbuf; + int to_host; + + to_host = usb_pipein(urb->pipe); + rbuf = req->req.buf + req->req.actual; + ubuf = urb->transfer_buffer + urb->actual_length; + + if (to_host) + memcpy(ubuf, rbuf, len); + else + memcpy(rbuf, ubuf, len); + return len; +} + /* transfer up to a frame's worth; caller must own lock */ static int transfer(struct dummy *dum, struct urb *urb, struct dummy_ep *ep, int limit, @@ -1164,8 +1181,6 @@ top: if (unlikely (len == 0)) is_short = 1; else { - char *ubuf, *rbuf; - /* not enough bandwidth left? */ if (limit < ep->ep.maxpacket && limit < len) break; @@ -1180,13 +1195,8 @@ top: } is_short = (len % ep->ep.maxpacket) != 0; - /* else transfer packet(s) */ - ubuf = urb->transfer_buffer + urb->actual_length; - rbuf = req->req.buf + req->req.actual; - if (to_host) - memcpy (ubuf, rbuf, len); - else - memcpy (rbuf, ubuf, len); + len = dummy_perform_transfer(urb, req, len); + ep->last_io = jiffies; limit -= len; -- cgit v1.2.3-70-g09d2 From 14fce33a960afbcf91ef97135903092c33f6d076 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 9 Jan 2012 19:30:50 +0100 Subject: usb: gadget: dummy_hcd: add sg support This patch adds sg support to dummy_hcd. It seems that uas is not able to work with a hcd which does not support sg only based transfers. Signed-off-by: Sebastian Andrzej Siewior Acked-by: Alan Stern Signed-off-by: Felipe Balbi --- drivers/usb/gadget/dummy_hcd.c | 80 +++++++++++++++++++++++++++++++++++------- 1 file changed, 67 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 61e893ac254..4973778b778 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -147,6 +148,8 @@ static const char *const ep_name [] = { struct urbp { struct urb *urb; struct list_head urbp_list; + struct sg_mapping_iter miter; + u32 miter_started; }; @@ -1077,13 +1080,11 @@ static int dummy_urb_enqueue ( unsigned long flags; int rc; - if (!urb->transfer_buffer && urb->transfer_buffer_length) - return -EINVAL; - urbp = kmalloc (sizeof *urbp, mem_flags); if (!urbp) return -ENOMEM; urbp->urb = urb; + urbp->miter_started = 0; dum_hcd = hcd_to_dummy_hcd(hcd); spin_lock_irqsave(&dum_hcd->dum->lock, flags); @@ -1137,17 +1138,66 @@ static int dummy_perform_transfer(struct urb *urb, struct dummy_request *req, u32 len) { void *ubuf, *rbuf; + struct urbp *urbp = urb->hcpriv; int to_host; + struct sg_mapping_iter *miter = &urbp->miter; + u32 trans = 0; + u32 this_sg; + bool next_sg; to_host = usb_pipein(urb->pipe); rbuf = req->req.buf + req->req.actual; - ubuf = urb->transfer_buffer + urb->actual_length; - if (to_host) - memcpy(ubuf, rbuf, len); - else - memcpy(rbuf, ubuf, len); - return len; + if (!urb->num_sgs) { + ubuf = urb->transfer_buffer + urb->actual_length; + if (to_host) + memcpy(ubuf, rbuf, len); + else + memcpy(rbuf, ubuf, len); + return len; + } + + if (!urbp->miter_started) { + u32 flags = SG_MITER_ATOMIC; + + if (to_host) + flags |= SG_MITER_TO_SG; + else + flags |= SG_MITER_FROM_SG; + + sg_miter_start(miter, urb->sg, urb->num_sgs, flags); + urbp->miter_started = 1; + } + next_sg = sg_miter_next(miter); + if (next_sg == false) { + WARN_ON_ONCE(1); + return -EINVAL; + } + do { + ubuf = miter->addr; + this_sg = min_t(u32, len, miter->length); + miter->consumed = this_sg; + trans += this_sg; + + if (to_host) + memcpy(ubuf, rbuf, this_sg); + else + memcpy(rbuf, ubuf, this_sg); + len -= this_sg; + + if (!len) + break; + next_sg = sg_miter_next(miter); + if (next_sg == false) { + WARN_ON_ONCE(1); + return -EINVAL; + } + + rbuf += this_sg; + } while (1); + + sg_miter_stop(miter); + return trans; } /* transfer up to a frame's worth; caller must own lock */ @@ -1198,10 +1248,13 @@ top: len = dummy_perform_transfer(urb, req, len); ep->last_io = jiffies; - - limit -= len; - urb->actual_length += len; - req->req.actual += len; + if (len < 0) { + req->req.status = len; + } else { + limit -= len; + urb->actual_length += len; + req->req.actual += len; + } } /* short packets terminate, maybe with overflow/underflow. @@ -2212,6 +2265,7 @@ static int dummy_h_get_frame (struct usb_hcd *hcd) static int dummy_setup(struct usb_hcd *hcd) { + hcd->self.sg_tablesize = ~0; if (usb_hcd_is_primary_hcd(hcd)) { the_controller.hs_hcd = hcd_to_dummy_hcd(hcd); the_controller.hs_hcd->dum = &the_controller; -- cgit v1.2.3-70-g09d2 From d262127c330b852ce4b210a0b1b06e69d4d87704 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 9 Jan 2012 13:14:59 +0100 Subject: usb: gadget: dummy_hcd: rename dummy_udc_udpate_ep0() to dummy_udc_update_ep0() This renames a function so "update" is spelled properly. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/dummy_hcd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 4973778b778..a40dc6a4c9e 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -801,7 +801,7 @@ static int dummy_set_selfpowered (struct usb_gadget *_gadget, int value) return 0; } -static void dummy_udc_udpate_ep0(struct dummy *dum) +static void dummy_udc_update_ep0(struct dummy *dum) { if (dum->gadget.speed == USB_SPEED_SUPER) dum->ep[0].ep.maxpacket = 9; @@ -825,7 +825,7 @@ static int dummy_pullup (struct usb_gadget *_gadget, int value) dum->driver->max_speed); else dum->gadget.speed = USB_SPEED_FULL; - dummy_udc_udpate_ep0(dum); + dummy_udc_update_ep0(dum); if (dum->gadget.speed < dum->driver->max_speed) dev_dbg(udc_dev(dum), "This device can perform faster" -- cgit v1.2.3-70-g09d2 From d81f3e4f5792acab5929ef99aad6ca5e21a31a0e Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 9 Jan 2012 13:15:00 +0100 Subject: usb: gadget: dummy_hcd: make alloc/free streams static There is no reason why dummy_alloc_streams() and dummy_free_streams() are global. Make them static instead. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/dummy_hcd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index a40dc6a4c9e..626473238b3 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -2286,7 +2286,7 @@ static int dummy_setup(struct usb_hcd *hcd) } /* Change a group of bulk endpoints to support multiple stream IDs */ -int dummy_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev, +static int dummy_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint **eps, unsigned int num_eps, unsigned int num_streams, gfp_t mem_flags) { @@ -2298,7 +2298,7 @@ int dummy_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev, } /* Reverts a group of bulk endpoints back to not using stream IDs. */ -int dummy_free_streams(struct usb_hcd *hcd, struct usb_device *udev, +static int dummy_free_streams(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint **eps, unsigned int num_eps, gfp_t mem_flags) { -- cgit v1.2.3-70-g09d2 From 10800f2ca1a78e24cf92dc5e16a68a9b78f91bbe Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 4 Jan 2012 10:20:09 +0300 Subject: usb: gadget: mv_udc: remove unneeded NULL check We've dereferenced req already, and we checked for bogus parameters at the start of the function. Signed-off-by: Dan Carpenter Signed-off-by: Felipe Balbi --- drivers/usb/gadget/mv_udc_core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index f97e737d26f..8dd398b99e2 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -771,8 +771,7 @@ mv_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) udc->ep0_state = DATA_STATE_XMIT; /* irq handler advances the queue */ - if (req != NULL) - list_add_tail(&req->queue, &ep->queue); + list_add_tail(&req->queue, &ep->queue); spin_unlock_irqrestore(&udc->lock, flags); return 0; -- cgit v1.2.3-70-g09d2 From 53069af3fa8ba2849cd4785160690873995d4f39 Mon Sep 17 00:00:00 2001 From: "Shimoda, Yoshihiro" Date: Thu, 5 Jan 2012 15:37:18 +0900 Subject: usb: renesas_usbhs: add IRQ resource decoding for IRQF_SHARED In case of the SH7757, the irq number of USB module and SUDMAC are the same. So, we have to set the IRQF_SHARED in such a case. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/common.c | 11 ++++++----- drivers/usb/renesas_usbhs/common.h | 1 + drivers/usb/renesas_usbhs/mod.c | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index e9a5b1d2615..a165490bae4 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -413,8 +413,7 @@ static int usbhs_probe(struct platform_device *pdev) struct renesas_usbhs_platform_info *info = pdev->dev.platform_data; struct renesas_usbhs_driver_callback *dfunc; struct usbhs_priv *priv; - struct resource *res; - unsigned int irq; + struct resource *res, *irq_res; int ret; /* check platform information */ @@ -426,8 +425,8 @@ static int usbhs_probe(struct platform_device *pdev) /* platform data */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - irq = platform_get_irq(pdev, 0); - if (!res || (int)irq <= 0) { + irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res || !irq_res) { dev_err(&pdev->dev, "Not enough Renesas USB platform resources.\n"); return -ENODEV; } @@ -476,7 +475,9 @@ static int usbhs_probe(struct platform_device *pdev) /* * priv settings */ - priv->irq = irq; + priv->irq = irq_res->start; + if (irq_res->flags & IORESOURCE_IRQ_SHAREABLE) + priv->irqflags = IRQF_SHARED; priv->pdev = pdev; INIT_DELAYED_WORK(&priv->notify_hotplug_work, usbhsc_notify_hotplug); spin_lock_init(usbhs_priv_to_lock(priv)); diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h index d79b3e27db9..3f3ccd35875 100644 --- a/drivers/usb/renesas_usbhs/common.h +++ b/drivers/usb/renesas_usbhs/common.h @@ -242,6 +242,7 @@ struct usbhs_priv { void __iomem *base; unsigned int irq; + unsigned long irqflags; struct renesas_usbhs_platform_callback pfunc; struct renesas_usbhs_driver_param dparam; diff --git a/drivers/usb/renesas_usbhs/mod.c b/drivers/usb/renesas_usbhs/mod.c index 1b97fb12694..0871e816df4 100644 --- a/drivers/usb/renesas_usbhs/mod.c +++ b/drivers/usb/renesas_usbhs/mod.c @@ -152,7 +152,7 @@ int usbhs_mod_probe(struct usbhs_priv *priv) /* irq settings */ ret = request_irq(priv->irq, usbhs_interrupt, - 0, dev_name(dev), priv); + priv->irqflags, dev_name(dev), priv); if (ret) { dev_err(dev, "irq request err\n"); goto mod_init_gadget_err; -- cgit v1.2.3-70-g09d2 From 5ea4399457f730b4614d0632ceefd3e8f53fb1e6 Mon Sep 17 00:00:00 2001 From: "Shimoda, Yoshihiro" Date: Thu, 5 Jan 2012 15:37:22 +0900 Subject: usb: renesas_usbhs: add support for SUDMAC The SUDMAC uses 8-bit width only. So, when the driver uses SUDMAC, we have to clear the MBW_32. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/fifo.c | 6 +++++- include/linux/usb/renesas_usbhs.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 72339bd6fca..03a9cc529c8 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c @@ -23,6 +23,7 @@ #define usbhsf_get_cfifo(p) (&((p)->fifo_info.cfifo)) #define usbhsf_get_d0fifo(p) (&((p)->fifo_info.d0fifo)) #define usbhsf_get_d1fifo(p) (&((p)->fifo_info.d1fifo)) +#define usbhsf_is_cfifo(p, f) (usbhsf_get_cfifo(p) == f) #define usbhsf_fifo_is_busy(f) ((f)->pipe) /* see usbhs_pipe_select_fifo */ @@ -305,7 +306,10 @@ static int usbhsf_fifo_select(struct usbhs_pipe *pipe, } /* "base" will be used below */ - usbhs_write(priv, fifo->sel, base | MBW_32); + if (usbhs_get_dparam(priv, has_sudmac) && !usbhsf_is_cfifo(priv, fifo)) + usbhs_write(priv, fifo->sel, base); + else + usbhs_write(priv, fifo->sel, base | MBW_32); /* check ISEL and CURPIPE value */ while (timeout--) { diff --git a/include/linux/usb/renesas_usbhs.h b/include/linux/usb/renesas_usbhs.h index 0d3f9887925..547e59cc00e 100644 --- a/include/linux/usb/renesas_usbhs.h +++ b/include/linux/usb/renesas_usbhs.h @@ -149,6 +149,7 @@ struct renesas_usbhs_driver_param { * option: */ u32 has_otg:1; /* for controlling PWEN/EXTLP */ + u32 has_sudmac:1; /* for SUDMAC */ }; /* -- cgit v1.2.3-70-g09d2 From 2d4172c938745cfa51c4a91406efb584549c1024 Mon Sep 17 00:00:00 2001 From: Heiko Stübner Date: Sun, 8 Jan 2012 21:57:55 +0100 Subject: usb: s3c-hsudc: Use helper functions instead of generic container_of The helper functions were definied but never used until now. Signed-off-by: Heiko Stuebner Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsudc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index df8661d266c..41b3a583c1a 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c @@ -759,7 +759,7 @@ static int s3c_hsudc_ep_enable(struct usb_ep *_ep, unsigned long flags; u32 ecr = 0; - hsep = container_of(_ep, struct s3c_hsudc_ep, ep); + hsep = our_ep(_ep); if (!_ep || !desc || hsep->desc || _ep->name == ep0name || desc->bDescriptorType != USB_DT_ENDPOINT || hsep->bEndpointAddress != desc->bEndpointAddress @@ -853,7 +853,7 @@ static void s3c_hsudc_free_request(struct usb_ep *ep, struct usb_request *_req) { struct s3c_hsudc_req *hsreq; - hsreq = container_of(_req, struct s3c_hsudc_req, req); + hsreq = our_req(_req); WARN_ON(!list_empty(&hsreq->queue)); kfree(hsreq); } @@ -876,12 +876,12 @@ static int s3c_hsudc_queue(struct usb_ep *_ep, struct usb_request *_req, u32 offset; u32 csr; - hsreq = container_of(_req, struct s3c_hsudc_req, req); + hsreq = our_req(_req); if ((!_req || !_req->complete || !_req->buf || !list_empty(&hsreq->queue))) return -EINVAL; - hsep = container_of(_ep, struct s3c_hsudc_ep, ep); + hsep = our_ep(_ep); hsudc = hsep->dev; if (!hsudc->driver || hsudc->gadget.speed == USB_SPEED_UNKNOWN) return -ESHUTDOWN; @@ -935,7 +935,7 @@ static int s3c_hsudc_dequeue(struct usb_ep *_ep, struct usb_request *_req) struct s3c_hsudc_req *hsreq; unsigned long flags; - hsep = container_of(_ep, struct s3c_hsudc_ep, ep); + hsep = our_ep(_ep); if (!_ep || hsep->ep.name == ep0name) return -EINVAL; -- cgit v1.2.3-70-g09d2 From 294f78ec493e69b55bcba566d4fe264d041aba8d Mon Sep 17 00:00:00 2001 From: Heiko Stübner Date: Sun, 8 Jan 2012 21:58:28 +0100 Subject: usb: s3c-hsudc: add basic runtime_pm calls This will enable the system to check for activity of the usb gadget and also in a later patch to control the usbphy power-domain. When handling the power domain there, it will be possible to remove another reference to architecture code. Signed-off-by: Heiko Stuebner Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsudc.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index 41b3a583c1a..5e8729374fb 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c @@ -30,6 +30,7 @@ #include #include #include +#include #include @@ -1178,6 +1179,9 @@ static int s3c_hsudc_start(struct usb_gadget *gadget, dev_info(hsudc->dev, "bound driver %s\n", driver->driver.name); s3c_hsudc_reconfig(hsudc); + + pm_runtime_get_sync(hsudc->dev); + s3c_hsudc_init_phy(); if (hsudc->pd->gpio_init) hsudc->pd->gpio_init(); @@ -1208,6 +1212,9 @@ static int s3c_hsudc_stop(struct usb_gadget *gadget, hsudc->gadget.dev.driver = NULL; hsudc->gadget.speed = USB_SPEED_UNKNOWN; s3c_hsudc_uninit_phy(); + + pm_runtime_put(hsudc->dev); + if (hsudc->pd->gpio_uninit) hsudc->pd->gpio_uninit(); s3c_hsudc_stop_activity(hsudc); @@ -1362,6 +1369,8 @@ static int __devinit s3c_hsudc_probe(struct platform_device *pdev) if (ret) goto err_add_udc; + pm_runtime_enable(dev); + return 0; err_add_udc: device_unregister(&hsudc->gadget.dev); -- cgit v1.2.3-70-g09d2 From c50a3bff0edb0acd49d8033a12ea4668e09a31ad Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Thu, 12 Jan 2012 11:27:05 +0900 Subject: usb: gadget: pch_udc: Fix disconnect issue ISSUE: When the driver notifies a gadget of a disconnect event, a system rarely freezes. CAUSE: When the driver calls dev->driver->disconnect(), it is not calling spin_unlock(). Signed-off-by: Tomoya MORINAGA Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pch_udc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index a3fcaae4bc2..6a44c921d13 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c @@ -2335,8 +2335,11 @@ static void pch_udc_svc_ur_interrupt(struct pch_udc_dev *dev) /* Complete request queue */ empty_req_queue(ep); } - if (dev->driver && dev->driver->disconnect) + if (dev->driver && dev->driver->disconnect) { + spin_unlock(&dev->lock); dev->driver->disconnect(&dev->gadget); + spin_lock(&dev->lock); + } } /** -- cgit v1.2.3-70-g09d2 From c802672cd36cd063bfd54d54c8c34825ab5b2357 Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Thu, 12 Jan 2012 11:27:06 +0900 Subject: usb: gadget: pch_udc: Fix wrong return value ISSUE: If the return value of pch_udc_pcd_init() is False, the return value of this function is unsettled. Since pch_udc_pcd_init() always returns 0, there is not actually the issue. CAUSE: If pch_udc_pcd_init() is True, the variable, retval, is not set for an appropriate value. Signed-off-by: Tomoya MORINAGA Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pch_udc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index 6a44c921d13..96606b6cff4 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c @@ -2915,8 +2915,10 @@ static int pch_udc_probe(struct pci_dev *pdev, } pch_udc = dev; /* initialize the hardware */ - if (pch_udc_pcd_init(dev)) + if (pch_udc_pcd_init(dev)) { + retval = -ENODEV; goto finished; + } if (request_irq(pdev->irq, pch_udc_isr, IRQF_SHARED, KBUILD_MODNAME, dev)) { dev_err(&pdev->dev, "%s: request_irq(%d) fail\n", __func__, -- cgit v1.2.3-70-g09d2 From 84566abba058b2aae8d603dfa90b5a3778a6714f Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Thu, 12 Jan 2012 11:27:07 +0900 Subject: usb: gadget: pch_udc: Fix USB suspend issue ISSUE: After USB Suspend, a system rarely freezes. CAUSE: When USB Suspend occurred, the driver is not notifying a gadget of the event. Signed-off-by: Tomoya MORINAGA Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pch_udc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index 96606b6cff4..842ca6349a9 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c @@ -2475,8 +2475,15 @@ static void pch_udc_dev_isr(struct pch_udc_dev *dev, u32 dev_intr) if (dev_intr & UDC_DEVINT_SC) pch_udc_svc_cfg_interrupt(dev); /* USB Suspend interrupt */ - if (dev_intr & UDC_DEVINT_US) + if (dev_intr & UDC_DEVINT_US) { + if (dev->driver + && dev->driver->suspend) { + spin_unlock(&dev->lock); + dev->driver->suspend(&dev->gadget); + spin_lock(&dev->lock); + } dev_dbg(&dev->pdev->dev, "USB_SUSPEND\n"); + } /* Clear the SOF interrupt, if enabled */ if (dev_intr & UDC_DEVINT_SOF) dev_dbg(&dev->pdev->dev, "SOF\n"); -- cgit v1.2.3-70-g09d2 From 1c575d2d2e3ff2a7cb3c2e2165064199cfd8ad32 Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Thu, 12 Jan 2012 11:27:08 +0900 Subject: usb: gadget: pch_udc: Fix usb/gadget/pch_udc: Fix ether gadget connect/disconnect issue ISSUE: After a USB cable is connect/disconnected, the system rarely freezes. CAUSE: Since the USB device controller cannot know to disconnect the USB cable, when it is used without detecting VBUS by GPIO, the UDC driver does not notify to USB Gadget. Since USB Gadget cannot know to disconnect, a false setting occurred when the USB cable is connected/disconnect repeatedly. Signed-off-by: Tomoya MORINAGA Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pch_udc.c | 70 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index 842ca6349a9..c2f19752c07 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c @@ -311,6 +311,7 @@ struct pch_udc_ep { * @registered: driver regsitered with system * @suspended: driver in suspended state * @connected: gadget driver associated + * @vbus_session: required vbus_session state * @set_cfg_not_acked: pending acknowledgement 4 setup * @waiting_zlp_ack: pending acknowledgement 4 ZLP * @data_requests: DMA pool for data requests @@ -337,6 +338,7 @@ struct pch_udc_dev { registered:1, suspended:1, connected:1, + vbus_session:1, set_cfg_not_acked:1, waiting_zlp_ack:1; struct pci_pool *data_requests; @@ -553,6 +555,31 @@ static void pch_udc_clear_disconnect(struct pch_udc_dev *dev) pch_udc_bit_clr(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_RES); } +/** + * pch_udc_reconnect() - This API initializes usb device controller, + * and clear the disconnect status. + * @dev: Reference to pch_udc_regs structure + */ +static void pch_udc_init(struct pch_udc_dev *dev); +static void pch_udc_reconnect(struct pch_udc_dev *dev) +{ + pch_udc_init(dev); + + /* enable device interrupts */ + /* pch_udc_enable_interrupts() */ + pch_udc_bit_clr(dev, UDC_DEVIRQMSK_ADDR, + UDC_DEVINT_UR | UDC_DEVINT_US | + UDC_DEVINT_ENUM | + UDC_DEVINT_SI | UDC_DEVINT_SC); + + /* Clear the disconnect */ + pch_udc_bit_set(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_RES); + pch_udc_bit_clr(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_SD); + mdelay(1); + /* Resume USB signalling */ + pch_udc_bit_clr(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_RES); +} + /** * pch_udc_vbus_session() - set or clearr the disconnect status. * @dev: Reference to pch_udc_regs structure @@ -563,10 +590,18 @@ static void pch_udc_clear_disconnect(struct pch_udc_dev *dev) static inline void pch_udc_vbus_session(struct pch_udc_dev *dev, int is_active) { - if (is_active) - pch_udc_clear_disconnect(dev); - else + if (is_active) { + pch_udc_reconnect(dev); + dev->vbus_session = 1; + } else { + if (dev->driver && dev->driver->disconnect) { + spin_unlock(&dev->lock); + dev->driver->disconnect(&dev->gadget); + spin_lock(&dev->lock); + } pch_udc_set_disconnect(dev); + dev->vbus_session = 0; + } } /** @@ -1126,7 +1161,17 @@ static int pch_udc_pcd_pullup(struct usb_gadget *gadget, int is_on) if (!gadget) return -EINVAL; dev = container_of(gadget, struct pch_udc_dev, gadget); - pch_udc_vbus_session(dev, is_on); + if (is_on) { + pch_udc_reconnect(dev); + } else { + if (dev->driver && dev->driver->disconnect) { + spin_unlock(&dev->lock); + dev->driver->disconnect(&dev->gadget); + spin_lock(&dev->lock); + } + pch_udc_set_disconnect(dev); + } + return 0; } @@ -2482,6 +2527,15 @@ static void pch_udc_dev_isr(struct pch_udc_dev *dev, u32 dev_intr) dev->driver->suspend(&dev->gadget); spin_lock(&dev->lock); } + + if (dev->vbus_session == 0) { + if (dev->driver && dev->driver->disconnect) { + spin_unlock(&dev->lock); + dev->driver->disconnect(&dev->gadget); + spin_lock(&dev->lock); + } + pch_udc_reconnect(dev); + } dev_dbg(&dev->pdev->dev, "USB_SUSPEND\n"); } /* Clear the SOF interrupt, if enabled */ @@ -2509,6 +2563,14 @@ static irqreturn_t pch_udc_isr(int irq, void *pdev) dev_intr = pch_udc_read_device_interrupts(dev); ep_intr = pch_udc_read_ep_interrupts(dev); + /* For a hot plug, this find that the controller is hung up. */ + if (dev_intr == ep_intr) + if (dev_intr == pch_udc_readl(dev, UDC_DEVCFG_ADDR)) { + dev_dbg(&dev->pdev->dev, "UDC: Hung up\n"); + /* The controller is reset */ + pch_udc_writel(dev, UDC_SRST, UDC_SRST_ADDR); + return IRQ_HANDLED; + } if (dev_intr) /* Clear device interrupts */ pch_udc_write_device_interrupts(dev, dev_intr); -- cgit v1.2.3-70-g09d2 From 833310402c54ad9b676b465fc53ad276b13d36be Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Thu, 12 Jan 2012 11:27:09 +0900 Subject: usb: gadget: pch_udc: Reduce redundant interrupt ISSUE: USB Suspend interrupts occur frequently. CAUSE: When it is called pch_udc_reconnect() in USB Suspend, it repeats reset and Suspend. SOLUTION: pch_udc_reconnect() does not enable all interrupts. When an enumeration event occurred the driver enables all interrupts. Signed-off-by: Tomoya MORINAGA Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pch_udc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index c2f19752c07..4da98141e05 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c @@ -568,9 +568,7 @@ static void pch_udc_reconnect(struct pch_udc_dev *dev) /* enable device interrupts */ /* pch_udc_enable_interrupts() */ pch_udc_bit_clr(dev, UDC_DEVIRQMSK_ADDR, - UDC_DEVINT_UR | UDC_DEVINT_US | - UDC_DEVINT_ENUM | - UDC_DEVINT_SI | UDC_DEVINT_SC); + UDC_DEVINT_UR | UDC_DEVINT_ENUM); /* Clear the disconnect */ pch_udc_bit_set(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_RES); @@ -2419,6 +2417,11 @@ static void pch_udc_svc_enum_interrupt(struct pch_udc_dev *dev) pch_udc_set_dma(dev, DMA_DIR_TX); pch_udc_set_dma(dev, DMA_DIR_RX); pch_udc_ep_set_rrdy(&(dev->ep[UDC_EP0OUT_IDX])); + + /* enable device interrupts */ + pch_udc_enable_interrupts(dev, UDC_DEVINT_UR | UDC_DEVINT_US | + UDC_DEVINT_ES | UDC_DEVINT_ENUM | + UDC_DEVINT_SI | UDC_DEVINT_SC); } /** -- cgit v1.2.3-70-g09d2 From 9645f7d3dab346a9d442dca1688740551b8c55f2 Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Thu, 12 Jan 2012 11:27:10 +0900 Subject: usb: gadget: pch_udc: Add debug message ISSUE: Adding debugging messages. CAUSE: The debugging messages are added to make sure of that major interrupt events are occurring. Signed-off-by: Tomoya MORINAGA Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pch_udc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index 4da98141e05..82416aae816 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c @@ -2511,11 +2511,15 @@ static void pch_udc_svc_cfg_interrupt(struct pch_udc_dev *dev) static void pch_udc_dev_isr(struct pch_udc_dev *dev, u32 dev_intr) { /* USB Reset Interrupt */ - if (dev_intr & UDC_DEVINT_UR) + if (dev_intr & UDC_DEVINT_UR) { pch_udc_svc_ur_interrupt(dev); + dev_dbg(&dev->pdev->dev, "USB_RESET\n"); + } /* Enumeration Done Interrupt */ - if (dev_intr & UDC_DEVINT_ENUM) + if (dev_intr & UDC_DEVINT_ENUM) { pch_udc_svc_enum_interrupt(dev); + dev_dbg(&dev->pdev->dev, "USB_ENUM\n"); + } /* Set Interface Interrupt */ if (dev_intr & UDC_DEVINT_SI) pch_udc_svc_intf_interrupt(dev); -- cgit v1.2.3-70-g09d2 From a54c979fed31b4230b2e63132f7167206e4e5d69 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Fri, 13 Jan 2012 21:51:47 +0100 Subject: usb: gadget: dummy_hcd: complete stream support dummy_hcd provides (alloc|free)_stream() callbacks but there are not doing anything. The transfer side also lacks matching of streams. This patch changes this and implements stream allocation / de-allocation support and proper urb <=> req matching. The UDC side exposes a limit of 16 streams. DWC3, the only USB3 UDC has no limitations in this regard except that it _needs_ to know that streams will be used at the ep_enable time. At the host side, there is no real limit either: XHCI can allocate any number of streams as long as it does not run out of memory. The UAS gadget currently requests 16 streams and the UAS host side fallbacks from the requested 256 down to 16 which is fine. From the UASP point of view (the only specified user), the number of used streams does not really matter. The only limitation is that the host may not use a higher stream than the gadget requested and can deal with. The dummy stream support has been modelled after current UAS + XHCI + DWC3 + UASP usage which helps me testing: - the device announces that each ep supports 16 streams (even it could more than that). - the device side looks into Companion descriptor at ep_enable time and enables them according to it. - the host side tries to enable the requested number of streams but the upper limit is the Comanion descriptor. None (zero streams) is an error condition, less is okay. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/dummy_hcd.c | 197 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 181 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 626473238b3..e57989ccc0e 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -88,6 +88,7 @@ struct dummy_ep { unsigned wedged : 1; unsigned already_seen : 1; unsigned setup_stage : 1; + unsigned stream_en:1; }; struct dummy_request { @@ -169,6 +170,8 @@ struct dummy_hcd { struct usb_device *udev; struct list_head urbp_list; + u32 stream_en_ep; + u8 num_stream[30 / 2]; unsigned active:1; unsigned old_active:1; @@ -514,8 +517,16 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) _ep->maxpacket = max; ep->desc = desc; + if (usb_ss_max_streams(_ep->comp_desc)) { + if (!usb_endpoint_xfer_bulk(desc)) { + dev_err(udc_dev(dum), "Can't enable stream support on " + "non-bulk ep %s\n", _ep->name); + return -EINVAL; + } + ep->stream_en = 1; + } - dev_dbg (udc_dev(dum), "enabled %s (ep%d%s-%s) maxpacket %d\n", + dev_dbg(udc_dev(dum), "enabled %s (ep%d%s-%s) maxpacket %d stream %s\n", _ep->name, desc->bEndpointAddress & 0x0f, (desc->bEndpointAddress & USB_DIR_IN) ? "in" : "out", @@ -534,7 +545,7 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) val = "ctrl"; break; }; val; }), - max); + max, ep->stream_en ? "enabled" : "disabled"); /* at this point real hardware should be NAKing transfers * to that endpoint, until a buffer is queued to it. @@ -559,6 +570,7 @@ static int dummy_disable (struct usb_ep *_ep) spin_lock_irqsave (&dum->lock, flags); ep->desc = NULL; + ep->stream_en = 0; retval = 0; nuke (dum, ep); spin_unlock_irqrestore (&dum->lock, flags); @@ -1058,6 +1070,16 @@ static struct platform_driver dummy_udc_driver = { /*-------------------------------------------------------------------------*/ +static unsigned int dummy_get_ep_idx(const struct usb_endpoint_descriptor *desc) +{ + unsigned int index; + + index = usb_endpoint_num(desc) << 1; + if (usb_endpoint_dir_in(desc)) + index |= 1; + return index; +} + /* MASTER/HOST SIDE DRIVER * * this uses the hcd framework to hook up to host side drivers. @@ -1070,6 +1092,81 @@ static struct platform_driver dummy_udc_driver = { * usb 2.0 rules. */ +static int dummy_ep_stream_en(struct dummy_hcd *dum_hcd, struct urb *urb) +{ + const struct usb_endpoint_descriptor *desc = &urb->ep->desc; + u32 index; + + if (!usb_endpoint_xfer_bulk(desc)) + return 0; + + index = dummy_get_ep_idx(desc); + return (1 << index) & dum_hcd->stream_en_ep; +} + +/* + * The max stream number is saved as a nibble so for the 30 possible endpoints + * we only 15 bytes of memory. Therefore we are limited to max 16 streams (0 + * means we use only 1 stream). The maximum according to the spec is 16bit so + * if the 16 stream limit is about to go, the array size should be incremented + * to 30 elements of type u16. + */ +static int get_max_streams_for_pipe(struct dummy_hcd *dum_hcd, + unsigned int pipe) +{ + int max_streams; + + max_streams = dum_hcd->num_stream[usb_pipeendpoint(pipe)]; + if (usb_pipeout(pipe)) + max_streams >>= 4; + else + max_streams &= 0xf; + max_streams++; + return max_streams; +} + +static void set_max_streams_for_pipe(struct dummy_hcd *dum_hcd, + unsigned int pipe, unsigned int streams) +{ + int max_streams; + + streams--; + max_streams = dum_hcd->num_stream[usb_pipeendpoint(pipe)]; + if (usb_pipeout(pipe)) { + streams <<= 4; + max_streams &= 0xf; + } else { + max_streams &= 0xf0; + } + max_streams |= streams; + dum_hcd->num_stream[usb_pipeendpoint(pipe)] = max_streams; +} + +static int dummy_validate_stream(struct dummy_hcd *dum_hcd, struct urb *urb) +{ + unsigned int max_streams; + int enabled; + + enabled = dummy_ep_stream_en(dum_hcd, urb); + if (!urb->stream_id) { + if (enabled) + return -EINVAL; + return 0; + } + if (!enabled) + return -EINVAL; + + max_streams = get_max_streams_for_pipe(dum_hcd, + usb_pipeendpoint(urb->pipe)); + if (urb->stream_id > max_streams) { + dev_err(dummy_dev(dum_hcd), "Stream id %d is out of range.\n", + urb->stream_id); + BUG(); + return -EINVAL; + } + return 0; +} + static int dummy_urb_enqueue ( struct usb_hcd *hcd, struct urb *urb, @@ -1088,6 +1185,13 @@ static int dummy_urb_enqueue ( dum_hcd = hcd_to_dummy_hcd(hcd); spin_lock_irqsave(&dum_hcd->dum->lock, flags); + + rc = dummy_validate_stream(dum_hcd, urb); + if (rc) { + kfree(urbp); + goto done; + } + rc = usb_hcd_link_urb_to_ep(hcd, urb); if (rc) { kfree(urbp); @@ -1201,10 +1305,10 @@ static int dummy_perform_transfer(struct urb *urb, struct dummy_request *req, } /* transfer up to a frame's worth; caller must own lock */ -static int -transfer(struct dummy *dum, struct urb *urb, struct dummy_ep *ep, int limit, - int *status) +static int transfer(struct dummy_hcd *dum_hcd, struct urb *urb, + struct dummy_ep *ep, int limit, int *status) { + struct dummy *dum = dum_hcd->dum; struct dummy_request *req; top: @@ -1214,6 +1318,11 @@ top: int is_short, to_host; int rescan = 0; + if (dummy_ep_stream_en(dum_hcd, urb)) { + if ((urb->stream_id != req->req.stream_id)) + continue; + } + /* 1..N packets of ep->ep.maxpacket each ... the last one * may be short (including zero length). * @@ -1744,7 +1853,7 @@ restart: default: treat_control_like_bulk: ep->last_io = jiffies; - total = transfer(dum, urb, ep, limit, &status); + total = transfer(dum_hcd, urb, ep, limit, &status); break; } @@ -2201,6 +2310,7 @@ static int dummy_start_ss(struct dummy_hcd *dum_hcd) dum_hcd->timer.function = dummy_timer; dum_hcd->timer.data = (unsigned long)dum_hcd; dum_hcd->rh_state = DUMMY_RH_RUNNING; + dum_hcd->stream_en_ep = 0; INIT_LIST_HEAD(&dum_hcd->urbp_list); dummy_hcd_to_hcd(dum_hcd)->power_budget = POWER_BUDGET; dummy_hcd_to_hcd(dum_hcd)->state = HC_STATE_RUNNING; @@ -2290,11 +2400,46 @@ static int dummy_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint **eps, unsigned int num_eps, unsigned int num_streams, gfp_t mem_flags) { - if (hcd->speed != HCD_USB3) - dev_dbg(dummy_dev(hcd_to_dummy_hcd(hcd)), - "%s() - ERROR! Not supported for USB2.0 roothub\n", - __func__); - return 0; + struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); + unsigned long flags; + int max_stream; + int ret_streams = num_streams; + unsigned int index; + unsigned int i; + + if (!num_eps) + return -EINVAL; + + spin_lock_irqsave(&dum_hcd->dum->lock, flags); + for (i = 0; i < num_eps; i++) { + index = dummy_get_ep_idx(&eps[i]->desc); + if ((1 << index) & dum_hcd->stream_en_ep) { + ret_streams = -EINVAL; + goto out; + } + max_stream = usb_ss_max_streams(&eps[i]->ss_ep_comp); + if (!max_stream) { + ret_streams = -EINVAL; + goto out; + } + if (max_stream < ret_streams) { + dev_dbg(dummy_dev(dum_hcd), "Ep 0x%x only supports %u " + "stream IDs.\n", + eps[i]->desc.bEndpointAddress, + max_stream); + ret_streams = max_stream; + } + } + + for (i = 0; i < num_eps; i++) { + index = dummy_get_ep_idx(&eps[i]->desc); + dum_hcd->stream_en_ep |= 1 << index; + set_max_streams_for_pipe(dum_hcd, + usb_endpoint_num(&eps[i]->desc), ret_streams); + } +out: + spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); + return ret_streams; } /* Reverts a group of bulk endpoints back to not using stream IDs. */ @@ -2302,11 +2447,31 @@ static int dummy_free_streams(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint **eps, unsigned int num_eps, gfp_t mem_flags) { - if (hcd->speed != HCD_USB3) - dev_dbg(dummy_dev(hcd_to_dummy_hcd(hcd)), - "%s() - ERROR! Not supported for USB2.0 roothub\n", - __func__); - return 0; + struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); + unsigned long flags; + int ret; + unsigned int index; + unsigned int i; + + spin_lock_irqsave(&dum_hcd->dum->lock, flags); + for (i = 0; i < num_eps; i++) { + index = dummy_get_ep_idx(&eps[i]->desc); + if (!((1 << index) & dum_hcd->stream_en_ep)) { + ret = -EINVAL; + goto out; + } + } + + for (i = 0; i < num_eps; i++) { + index = dummy_get_ep_idx(&eps[i]->desc); + dum_hcd->stream_en_ep &= ~(1 << index); + set_max_streams_for_pipe(dum_hcd, + usb_endpoint_num(&eps[i]->desc), 0); + } + ret = 0; +out: + spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); + return ret; } static struct hc_driver dummy_hcd = { -- cgit v1.2.3-70-g09d2 From 59f08e6d2015a16fb4856f910ef0660d13a0c767 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 12 Jan 2012 12:53:14 +0100 Subject: usb: dummy_hcd: use usb_endpoint_type() This patch makes use of usb_endpoint_type() instead of the open coding. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/dummy_hcd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index e57989ccc0e..fd4d86a5714 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -447,7 +447,7 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) * especially for "ep9out" style fixed function ones.) */ retval = -EINVAL; - switch (desc->bmAttributes & 0x03) { + switch (usb_endpoint_type(desc)) { case USB_ENDPOINT_XFER_BULK: if (strstr (ep->ep.name, "-iso") || strstr (ep->ep.name, "-int")) { @@ -531,7 +531,7 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) desc->bEndpointAddress & 0x0f, (desc->bEndpointAddress & USB_DIR_IN) ? "in" : "out", ({ char *val; - switch (desc->bmAttributes & 0x03) { + switch (usb_endpoint_type(desc)) { case USB_ENDPOINT_XFER_BULK: val = "bulk"; break; @@ -1439,7 +1439,7 @@ static int periodic_bytes (struct dummy *dum, struct dummy_ep *ep) limit += limit * tmp; } if (dum->gadget.speed == USB_SPEED_SUPER) { - switch (ep->desc->bmAttributes & 0x03) { + switch (usb_endpoint_type(ep->desc)) { case USB_ENDPOINT_XFER_ISOC: /* Sec. 4.4.8.2 USB3.0 Spec */ limit = 3 * 16 * 1024 * 8; -- cgit v1.2.3-70-g09d2 From 18f2cbaa2b9617eed20789ce40878920a8ea6beb Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 12 Jan 2012 12:53:15 +0100 Subject: usb: gadget: dummy_hcd: clean up checkpatch This patch converts checkpatch output of |./scripts/checkpatch.pl drivers/usb/gadget/dummy_hcd.c -file from |total: 22 errors, 174 warnings, 2642 lines checked to |total: 0 errors, 0 warnings, 2632 lines checked Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/dummy_hcd.c | 432 ++++++++++++++++++++--------------------- 1 file changed, 211 insertions(+), 221 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index fd4d86a5714..67573e5f2a1 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -42,25 +42,24 @@ #include #include -#include +#include #include #include #include - #define DRIVER_DESC "USB Host+Gadget Emulator" #define DRIVER_VERSION "02 May 2005" #define POWER_BUDGET 500 /* in mA; use 8 for low-power port testing */ -static const char driver_name [] = "dummy_hcd"; -static const char driver_desc [] = "USB Host+Gadget Emulator"; +static const char driver_name[] = "dummy_hcd"; +static const char driver_desc[] = "USB Host+Gadget Emulator"; -static const char gadget_name [] = "dummy_udc"; +static const char gadget_name[] = "dummy_udc"; -MODULE_DESCRIPTION (DRIVER_DESC); -MODULE_AUTHOR ("David Brownell"); -MODULE_LICENSE ("GPL"); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("David Brownell"); +MODULE_LICENSE("GPL"); struct dummy_hcd_module_parameters { bool is_super_speed; @@ -84,10 +83,10 @@ struct dummy_ep { struct usb_gadget *gadget; const struct usb_endpoint_descriptor *desc; struct usb_ep ep; - unsigned halted : 1; - unsigned wedged : 1; - unsigned already_seen : 1; - unsigned setup_stage : 1; + unsigned halted:1; + unsigned wedged:1; + unsigned already_seen:1; + unsigned setup_stage:1; unsigned stream_en:1; }; @@ -96,15 +95,15 @@ struct dummy_request { struct usb_request req; }; -static inline struct dummy_ep *usb_ep_to_dummy_ep (struct usb_ep *_ep) +static inline struct dummy_ep *usb_ep_to_dummy_ep(struct usb_ep *_ep) { - return container_of (_ep, struct dummy_ep, ep); + return container_of(_ep, struct dummy_ep, ep); } static inline struct dummy_request *usb_request_to_dummy_request (struct usb_request *_req) { - return container_of (_req, struct dummy_request, req); + return container_of(_req, struct dummy_request, req); } /*-------------------------------------------------------------------------*/ @@ -123,9 +122,9 @@ static inline struct dummy_request *usb_request_to_dummy_request * configurations, illegal or unsupported packet lengths, and so on. */ -static const char ep0name [] = "ep0"; +static const char ep0name[] = "ep0"; -static const char *const ep_name [] = { +static const char *const ep_name[] = { ep0name, /* everyone has ep0 */ /* act like a net2280: high speed, six configurable endpoints */ @@ -184,12 +183,12 @@ struct dummy { /* * SLAVE/GADGET side support */ - struct dummy_ep ep [DUMMY_ENDPOINTS]; + struct dummy_ep ep[DUMMY_ENDPOINTS]; int address; struct usb_gadget gadget; struct usb_gadget_driver *driver; struct dummy_request fifo_req; - u8 fifo_buf [FIFO_SIZE]; + u8 fifo_buf[FIFO_SIZE]; u16 devstatus; unsigned udc_suspended:1; unsigned pullup:1; @@ -216,14 +215,14 @@ static inline struct device *dummy_dev(struct dummy_hcd *dum) return dummy_hcd_to_hcd(dum)->self.controller; } -static inline struct device *udc_dev (struct dummy *dum) +static inline struct device *udc_dev(struct dummy *dum) { return dum->gadget.dev.parent; } -static inline struct dummy *ep_to_dummy (struct dummy_ep *ep) +static inline struct dummy *ep_to_dummy(struct dummy_ep *ep) { - return container_of (ep->gadget, struct dummy, gadget); + return container_of(ep->gadget, struct dummy, gadget); } static inline struct dummy_hcd *gadget_to_dummy_hcd(struct usb_gadget *gadget) @@ -235,9 +234,9 @@ static inline struct dummy_hcd *gadget_to_dummy_hcd(struct usb_gadget *gadget) return dum->hs_hcd; } -static inline struct dummy *gadget_dev_to_dummy (struct device *dev) +static inline struct dummy *gadget_dev_to_dummy(struct device *dev) { - return container_of (dev, struct dummy, gadget.dev); + return container_of(dev, struct dummy, gadget.dev); } static struct dummy the_controller; @@ -247,24 +246,23 @@ static struct dummy the_controller; /* SLAVE/GADGET SIDE UTILITY ROUTINES */ /* called with spinlock held */ -static void nuke (struct dummy *dum, struct dummy_ep *ep) +static void nuke(struct dummy *dum, struct dummy_ep *ep) { - while (!list_empty (&ep->queue)) { + while (!list_empty(&ep->queue)) { struct dummy_request *req; - req = list_entry (ep->queue.next, struct dummy_request, queue); - list_del_init (&req->queue); + req = list_entry(ep->queue.next, struct dummy_request, queue); + list_del_init(&req->queue); req->req.status = -ESHUTDOWN; - spin_unlock (&dum->lock); - req->req.complete (&ep->ep, &req->req); - spin_lock (&dum->lock); + spin_unlock(&dum->lock); + req->req.complete(&ep->ep, &req->req); + spin_lock(&dum->lock); } } /* caller must hold lock */ -static void -stop_activity (struct dummy *dum) +static void stop_activity(struct dummy *dum) { struct dummy_ep *ep; @@ -274,8 +272,8 @@ stop_activity (struct dummy *dum) /* The timer is left running so that outstanding URBs can fail */ /* nuke any pending requests first, so driver i/o is quiesced */ - list_for_each_entry (ep, &dum->gadget.ep_list, ep.ep_list) - nuke (dum, ep); + list_for_each_entry(ep, &dum->gadget.ep_list, ep.ep_list) + nuke(dum, ep); /* driver now does any non-usb quiescing necessary */ } @@ -410,8 +408,8 @@ static void set_link_state(struct dummy_hcd *dum_hcd) #define is_enabled(dum) \ (dum->port_status & USB_PORT_STAT_ENABLE) -static int -dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) +static int dummy_enable(struct usb_ep *_ep, + const struct usb_endpoint_descriptor *desc) { struct dummy *dum; struct dummy_hcd *dum_hcd; @@ -419,11 +417,11 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) unsigned max; int retval; - ep = usb_ep_to_dummy_ep (_ep); + ep = usb_ep_to_dummy_ep(_ep); if (!_ep || !desc || ep->desc || _ep->name == ep0name || desc->bDescriptorType != USB_DT_ENDPOINT) return -EINVAL; - dum = ep_to_dummy (ep); + dum = ep_to_dummy(ep); if (!dum->driver) return -ESHUTDOWN; @@ -449,8 +447,8 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) retval = -EINVAL; switch (usb_endpoint_type(desc)) { case USB_ENDPOINT_XFER_BULK: - if (strstr (ep->ep.name, "-iso") - || strstr (ep->ep.name, "-int")) { + if (strstr(ep->ep.name, "-iso") + || strstr(ep->ep.name, "-int")) { goto done; } switch (dum->gadget.speed) { @@ -472,7 +470,7 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) } break; case USB_ENDPOINT_XFER_INT: - if (strstr (ep->ep.name, "-iso")) /* bulk is ok */ + if (strstr(ep->ep.name, "-iso")) /* bulk is ok */ goto done; /* real hardware might not handle all packet sizes */ switch (dum->gadget.speed) { @@ -492,8 +490,8 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) } break; case USB_ENDPOINT_XFER_ISOC: - if (strstr (ep->ep.name, "-bulk") - || strstr (ep->ep.name, "-int")) + if (strstr(ep->ep.name, "-bulk") + || strstr(ep->ep.name, "-int")) goto done; /* real hardware might not handle all packet sizes */ switch (dum->gadget.speed) { @@ -556,68 +554,65 @@ done: return retval; } -static int dummy_disable (struct usb_ep *_ep) +static int dummy_disable(struct usb_ep *_ep) { struct dummy_ep *ep; struct dummy *dum; unsigned long flags; int retval; - ep = usb_ep_to_dummy_ep (_ep); + ep = usb_ep_to_dummy_ep(_ep); if (!_ep || !ep->desc || _ep->name == ep0name) return -EINVAL; - dum = ep_to_dummy (ep); + dum = ep_to_dummy(ep); - spin_lock_irqsave (&dum->lock, flags); + spin_lock_irqsave(&dum->lock, flags); ep->desc = NULL; ep->stream_en = 0; retval = 0; - nuke (dum, ep); - spin_unlock_irqrestore (&dum->lock, flags); + nuke(dum, ep); + spin_unlock_irqrestore(&dum->lock, flags); - dev_dbg (udc_dev(dum), "disabled %s\n", _ep->name); + dev_dbg(udc_dev(dum), "disabled %s\n", _ep->name); return retval; } -static struct usb_request * -dummy_alloc_request (struct usb_ep *_ep, gfp_t mem_flags) +static struct usb_request *dummy_alloc_request(struct usb_ep *_ep, + gfp_t mem_flags) { struct dummy_ep *ep; struct dummy_request *req; if (!_ep) return NULL; - ep = usb_ep_to_dummy_ep (_ep); + ep = usb_ep_to_dummy_ep(_ep); req = kzalloc(sizeof(*req), mem_flags); if (!req) return NULL; - INIT_LIST_HEAD (&req->queue); + INIT_LIST_HEAD(&req->queue); return &req->req; } -static void -dummy_free_request (struct usb_ep *_ep, struct usb_request *_req) +static void dummy_free_request(struct usb_ep *_ep, struct usb_request *_req) { struct dummy_ep *ep; struct dummy_request *req; - ep = usb_ep_to_dummy_ep (_ep); + ep = usb_ep_to_dummy_ep(_ep); if (!ep || !_req || (!ep->desc && _ep->name != ep0name)) return; - req = usb_request_to_dummy_request (_req); - WARN_ON (!list_empty (&req->queue)); - kfree (req); + req = usb_request_to_dummy_request(_req); + WARN_ON(!list_empty(&req->queue)); + kfree(req); } -static void -fifo_complete (struct usb_ep *ep, struct usb_request *req) +static void fifo_complete(struct usb_ep *ep, struct usb_request *req) { } -static int -dummy_queue (struct usb_ep *_ep, struct usb_request *_req, +static int dummy_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t mem_flags) { struct dummy_ep *ep; @@ -626,49 +621,48 @@ dummy_queue (struct usb_ep *_ep, struct usb_request *_req, struct dummy_hcd *dum_hcd; unsigned long flags; - req = usb_request_to_dummy_request (_req); - if (!_req || !list_empty (&req->queue) || !_req->complete) + req = usb_request_to_dummy_request(_req); + if (!_req || !list_empty(&req->queue) || !_req->complete) return -EINVAL; - ep = usb_ep_to_dummy_ep (_ep); + ep = usb_ep_to_dummy_ep(_ep); if (!_ep || (!ep->desc && _ep->name != ep0name)) return -EINVAL; - dum = ep_to_dummy (ep); + dum = ep_to_dummy(ep); dum_hcd = gadget_to_dummy_hcd(&dum->gadget); if (!dum->driver || !is_enabled(dum_hcd)) return -ESHUTDOWN; #if 0 - dev_dbg (udc_dev(dum), "ep %p queue req %p to %s, len %d buf %p\n", + dev_dbg(udc_dev(dum), "ep %p queue req %p to %s, len %d buf %p\n", ep, _req, _ep->name, _req->length, _req->buf); #endif - _req->status = -EINPROGRESS; _req->actual = 0; - spin_lock_irqsave (&dum->lock, flags); + spin_lock_irqsave(&dum->lock, flags); /* implement an emulated single-request FIFO */ if (ep->desc && (ep->desc->bEndpointAddress & USB_DIR_IN) && - list_empty (&dum->fifo_req.queue) && - list_empty (&ep->queue) && + list_empty(&dum->fifo_req.queue) && + list_empty(&ep->queue) && _req->length <= FIFO_SIZE) { req = &dum->fifo_req; req->req = *_req; req->req.buf = dum->fifo_buf; - memcpy (dum->fifo_buf, _req->buf, _req->length); + memcpy(dum->fifo_buf, _req->buf, _req->length); req->req.context = dum; req->req.complete = fifo_complete; list_add_tail(&req->queue, &ep->queue); - spin_unlock (&dum->lock); + spin_unlock(&dum->lock); _req->actual = _req->length; _req->status = 0; - _req->complete (_ep, _req); - spin_lock (&dum->lock); + _req->complete(_ep, _req); + spin_lock(&dum->lock); } else list_add_tail(&req->queue, &ep->queue); - spin_unlock_irqrestore (&dum->lock, flags); + spin_unlock_irqrestore(&dum->lock, flags); /* real hardware would likely enable transfers here, in case * it'd been left NAKing. @@ -676,7 +670,7 @@ dummy_queue (struct usb_ep *_ep, struct usb_request *_req, return 0; } -static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req) +static int dummy_dequeue(struct usb_ep *_ep, struct usb_request *_req) { struct dummy_ep *ep; struct dummy *dum; @@ -686,31 +680,31 @@ static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req) if (!_ep || !_req) return retval; - ep = usb_ep_to_dummy_ep (_ep); - dum = ep_to_dummy (ep); + ep = usb_ep_to_dummy_ep(_ep); + dum = ep_to_dummy(ep); if (!dum->driver) return -ESHUTDOWN; - local_irq_save (flags); - spin_lock (&dum->lock); - list_for_each_entry (req, &ep->queue, queue) { + local_irq_save(flags); + spin_lock(&dum->lock); + list_for_each_entry(req, &ep->queue, queue) { if (&req->req == _req) { - list_del_init (&req->queue); + list_del_init(&req->queue); _req->status = -ECONNRESET; retval = 0; break; } } - spin_unlock (&dum->lock); + spin_unlock(&dum->lock); if (retval == 0) { - dev_dbg (udc_dev(dum), + dev_dbg(udc_dev(dum), "dequeued req %p from %s, len %d buf %p\n", req, _ep->name, _req->length, _req->buf); - _req->complete (_ep, _req); + _req->complete(_ep, _req); } - local_irq_restore (flags); + local_irq_restore(flags); return retval; } @@ -722,14 +716,14 @@ dummy_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged) if (!_ep) return -EINVAL; - ep = usb_ep_to_dummy_ep (_ep); - dum = ep_to_dummy (ep); + ep = usb_ep_to_dummy_ep(_ep); + dum = ep_to_dummy(ep); if (!dum->driver) return -ESHUTDOWN; if (!value) ep->halted = ep->wedged = 0; else if (ep->desc && (ep->desc->bEndpointAddress & USB_DIR_IN) && - !list_empty (&ep->queue)) + !list_empty(&ep->queue)) return -EAGAIN; else { ep->halted = 1; @@ -770,15 +764,15 @@ static const struct usb_ep_ops dummy_ep_ops = { /*-------------------------------------------------------------------------*/ /* there are both host and device side versions of this call ... */ -static int dummy_g_get_frame (struct usb_gadget *_gadget) +static int dummy_g_get_frame(struct usb_gadget *_gadget) { struct timeval tv; - do_gettimeofday (&tv); + do_gettimeofday(&tv); return tv.tv_usec / 1000; } -static int dummy_wakeup (struct usb_gadget *_gadget) +static int dummy_wakeup(struct usb_gadget *_gadget) { struct dummy_hcd *dum_hcd; @@ -801,11 +795,11 @@ static int dummy_wakeup (struct usb_gadget *_gadget) return 0; } -static int dummy_set_selfpowered (struct usb_gadget *_gadget, int value) +static int dummy_set_selfpowered(struct usb_gadget *_gadget, int value) { struct dummy *dum; - dum = (gadget_to_dummy_hcd(_gadget))->dum; + dum = gadget_to_dummy_hcd(_gadget)->dum; if (value) dum->devstatus |= (1 << USB_DEVICE_SELF_POWERED); else @@ -821,7 +815,7 @@ static void dummy_udc_update_ep0(struct dummy *dum) dum->ep[0].ep.maxpacket = 64; } -static int dummy_pullup (struct usb_gadget *_gadget, int value) +static int dummy_pullup(struct usb_gadget *_gadget, int value) { struct dummy_hcd *dum_hcd; struct dummy *dum; @@ -846,10 +840,10 @@ static int dummy_pullup (struct usb_gadget *_gadget, int value) } dum_hcd = gadget_to_dummy_hcd(_gadget); - spin_lock_irqsave (&dum->lock, flags); + spin_lock_irqsave(&dum->lock, flags); dum->pullup = (value != 0); set_link_state(dum_hcd); - spin_unlock_irqrestore (&dum->lock, flags); + spin_unlock_irqrestore(&dum->lock, flags); usb_hcd_poll_rh_status(dummy_hcd_to_hcd(dum_hcd)); return 0; @@ -872,16 +866,16 @@ static const struct usb_gadget_ops dummy_ops = { /*-------------------------------------------------------------------------*/ /* "function" sysfs attribute */ -static ssize_t -show_function (struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_function(struct device *dev, struct device_attribute *attr, + char *buf) { - struct dummy *dum = gadget_dev_to_dummy (dev); + struct dummy *dum = gadget_dev_to_dummy(dev); if (!dum->driver || !dum->driver->function) return 0; - return scnprintf (buf, PAGE_SIZE, "%s\n", dum->driver->function); + return scnprintf(buf, PAGE_SIZE, "%s\n", dum->driver->function); } -static DEVICE_ATTR (function, S_IRUGO, show_function, NULL); +static DEVICE_ATTR(function, S_IRUGO, show_function, NULL); /*-------------------------------------------------------------------------*/ @@ -916,7 +910,7 @@ static int dummy_udc_start(struct usb_gadget *g, dum->devstatus = 0; dum->driver = driver; - dev_dbg (udc_dev(dum), "binding gadget driver '%s'\n", + dev_dbg(udc_dev(dum), "binding gadget driver '%s'\n", driver->driver.name); return 0; } @@ -927,7 +921,7 @@ static int dummy_udc_stop(struct usb_gadget *g, struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g); struct dummy *dum = dum_hcd->dum; - dev_dbg (udc_dev(dum), "unregister gadget driver '%s'\n", + dev_dbg(udc_dev(dum), "unregister gadget driver '%s'\n", driver->driver.name); dum->driver = NULL; @@ -940,8 +934,7 @@ 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) +static void dummy_gadget_release(struct device *dev) { return; } @@ -978,7 +971,7 @@ static void init_dummy_udc_hw(struct dummy *dum) #endif } -static int dummy_udc_probe (struct platform_device *pdev) +static int dummy_udc_probe(struct platform_device *pdev) { struct dummy *dum = &the_controller; int rc; @@ -990,7 +983,7 @@ static int dummy_udc_probe (struct platform_device *pdev) 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); + rc = device_register(&dum->gadget.dev); if (rc < 0) { put_device(&dum->gadget.dev); return rc; @@ -1002,7 +995,7 @@ static int dummy_udc_probe (struct platform_device *pdev) if (rc < 0) goto err_udc; - rc = device_create_file (&dum->gadget.dev, &dev_attr_function); + rc = device_create_file(&dum->gadget.dev, &dev_attr_function); if (rc < 0) goto err_dev; platform_set_drvdata(pdev, dum); @@ -1015,14 +1008,14 @@ err_udc: return rc; } -static int dummy_udc_remove (struct platform_device *pdev) +static int dummy_udc_remove(struct platform_device *pdev) { - struct dummy *dum = platform_get_drvdata (pdev); + struct dummy *dum = platform_get_drvdata(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); + platform_set_drvdata(pdev, NULL); + device_remove_file(&dum->gadget.dev, &dev_attr_function); + device_unregister(&dum->gadget.dev); return 0; } @@ -1167,7 +1160,7 @@ static int dummy_validate_stream(struct dummy_hcd *dum_hcd, struct urb *urb) return 0; } -static int dummy_urb_enqueue ( +static int dummy_urb_enqueue( struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags @@ -1177,7 +1170,7 @@ static int dummy_urb_enqueue ( unsigned long flags; int rc; - urbp = kmalloc (sizeof *urbp, mem_flags); + urbp = kmalloc(sizeof *urbp, mem_flags); if (!urbp) return -ENOMEM; urbp->urb = urb; @@ -1206,7 +1199,7 @@ static int dummy_urb_enqueue ( list_add_tail(&urbp->urbp_list, &dum_hcd->urbp_list); urb->hcpriv = urbp; - if (usb_pipetype (urb->pipe) == PIPE_CONTROL) + if (usb_pipetype(urb->pipe) == PIPE_CONTROL) urb->error_count = 1; /* mark as a new urb */ /* kick the scheduler, it'll do the rest */ @@ -1313,7 +1306,7 @@ static int transfer(struct dummy_hcd *dum_hcd, struct urb *urb, top: /* if there's no request queued, the device is NAKing; return */ - list_for_each_entry (req, &ep->queue, queue) { + list_for_each_entry(req, &ep->queue, queue) { unsigned host_len, dev_len, len; int is_short, to_host; int rescan = 0; @@ -1332,18 +1325,18 @@ top: */ host_len = urb->transfer_buffer_length - urb->actual_length; dev_len = req->req.length - req->req.actual; - len = min (host_len, dev_len); + len = min(host_len, dev_len); /* FIXME update emulated data toggle too */ - to_host = usb_pipein (urb->pipe); - if (unlikely (len == 0)) + to_host = usb_pipein(urb->pipe); + if (unlikely(len == 0)) is_short = 1; else { /* not enough bandwidth left? */ if (limit < ep->ep.maxpacket && limit < len) break; - len = min (len, (unsigned) limit); + len = min_t(unsigned, len, limit); if (len == 0) break; @@ -1404,11 +1397,11 @@ top: /* device side completion --> continuable */ if (req->req.status != -EINPROGRESS) { - list_del_init (&req->queue); + list_del_init(&req->queue); - spin_unlock (&dum->lock); - req->req.complete (&ep->ep, &req->req); - spin_lock (&dum->lock); + spin_unlock(&dum->lock); + req->req.complete(&ep->ep, &req->req); + spin_lock(&dum->lock); /* requests might have been unlinked... */ rescan = 1; @@ -1425,7 +1418,7 @@ top: return limit; } -static int periodic_bytes (struct dummy *dum, struct dummy_ep *ep) +static int periodic_bytes(struct dummy *dum, struct dummy_ep *ep) { int limit = ep->ep.maxpacket; @@ -1461,7 +1454,7 @@ static int periodic_bytes (struct dummy *dum, struct dummy_ep *ep) USB_PORT_STAT_SUSPEND)) \ == (USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE)) -static struct dummy_ep *find_endpoint (struct dummy *dum, u8 address) +static struct dummy_ep *find_endpoint(struct dummy *dum, u8 address) { int i; @@ -1469,9 +1462,9 @@ static struct dummy_ep *find_endpoint (struct dummy *dum, u8 address) dum->ss_hcd : dum->hs_hcd))) return NULL; if ((address & ~USB_DIR_IN) == 0) - return &dum->ep [0]; + return &dum->ep[0]; for (i = 1; i < DUMMY_ENDPOINTS; i++) { - struct dummy_ep *ep = &dum->ep [i]; + struct dummy_ep *ep = &dum->ep[i]; if (!ep->desc) continue; @@ -1701,19 +1694,19 @@ static void dummy_timer(unsigned long _dum_hcd) /* FIXME if HZ != 1000 this will probably misbehave ... */ /* look at each urb queued by the host side driver */ - spin_lock_irqsave (&dum->lock, flags); + spin_lock_irqsave(&dum->lock, flags); if (!dum_hcd->udev) { dev_err(dummy_dev(dum_hcd), "timer fired with no URBs pending?\n"); - spin_unlock_irqrestore (&dum->lock, flags); + spin_unlock_irqrestore(&dum->lock, flags); return; } for (i = 0; i < DUMMY_ENDPOINTS; i++) { - if (!ep_name [i]) + if (!ep_name[i]) break; - dum->ep [i].already_seen = 0; + dum->ep[i].already_seen = 0; } restart: @@ -1730,7 +1723,7 @@ restart: goto return_urb; else if (dum_hcd->rh_state != DUMMY_RH_RUNNING) continue; - type = usb_pipetype (urb->pipe); + type = usb_pipetype(urb->pipe); /* used up this frame's non-periodic bandwidth? * FIXME there's infinite bandwidth for control and @@ -1741,7 +1734,7 @@ restart: /* find the gadget's ep for this request (if configured) */ address = usb_pipeendpoint (urb->pipe); - if (usb_pipein (urb->pipe)) + if (usb_pipein(urb->pipe)) address |= USB_DIR_IN; ep = find_endpoint(dum, address); if (!ep) { @@ -1756,7 +1749,7 @@ restart: if (ep->already_seen) continue; ep->already_seen = 1; - if (ep == &dum->ep [0] && urb->error_count) { + if (ep == &dum->ep[0] && urb->error_count) { ep->setup_stage = 1; /* a new urb */ urb->error_count = 0; } @@ -1770,21 +1763,21 @@ restart: /* FIXME make sure both ends agree on maxpacket */ /* handle control requests */ - if (ep == &dum->ep [0] && ep->setup_stage) { + if (ep == &dum->ep[0] && ep->setup_stage) { struct usb_ctrlrequest setup; int value = 1; - setup = *(struct usb_ctrlrequest*) urb->setup_packet; + setup = *(struct usb_ctrlrequest *) urb->setup_packet; /* paranoia, in case of stale queued data */ - list_for_each_entry (req, &ep->queue, queue) { - list_del_init (&req->queue); + list_for_each_entry(req, &ep->queue, queue) { + list_del_init(&req->queue); req->req.status = -EOVERFLOW; - dev_dbg (udc_dev(dum), "stale req = %p\n", + dev_dbg(udc_dev(dum), "stale req = %p\n", req); - spin_unlock (&dum->lock); - req->req.complete (&ep->ep, &req->req); - spin_lock (&dum->lock); + spin_unlock(&dum->lock); + req->req.complete(&ep->ep, &req->req); + spin_lock(&dum->lock); ep->already_seen = 0; goto restart; } @@ -1804,10 +1797,10 @@ restart: * until setup() returns; no reentrancy issues etc. */ if (value > 0) { - spin_unlock (&dum->lock); - value = dum->driver->setup (&dum->gadget, + spin_unlock(&dum->lock); + value = dum->driver->setup(&dum->gadget, &setup); - spin_lock (&dum->lock); + spin_lock(&dum->lock); if (value >= 0) { /* no delays (max 64KB data stage) */ @@ -1819,7 +1812,7 @@ restart: if (value < 0) { if (value != -EOPNOTSUPP) - dev_dbg (udc_dev(dum), + dev_dbg(udc_dev(dum), "setup --> %d\n", value); status = -EPIPE; @@ -1831,14 +1824,14 @@ restart: /* non-control requests */ limit = total; - switch (usb_pipetype (urb->pipe)) { + switch (usb_pipetype(urb->pipe)) { case PIPE_ISOCHRONOUS: /* FIXME is it urb->interval since the last xfer? * use urb->iso_frame_desc[i]. * complete whether or not ep has requests queued. * report random errors, to debug drivers. */ - limit = max (limit, periodic_bytes (dum, ep)); + limit = max(limit, periodic_bytes(dum, ep)); status = -ENOSYS; break; @@ -1846,12 +1839,11 @@ restart: /* FIXME is it urb->interval since the last xfer? * this almost certainly polls too fast. */ - limit = max (limit, periodic_bytes (dum, ep)); + limit = max(limit, periodic_bytes(dum, ep)); /* FALLTHROUGH */ - // case PIPE_BULK: case PIPE_CONTROL: default: - treat_control_like_bulk: +treat_control_like_bulk: ep->last_io = jiffies; total = transfer(dum_hcd, urb, ep, limit, &status); break; @@ -1862,15 +1854,15 @@ restart: continue; return_urb: - list_del (&urbp->urbp_list); - kfree (urbp); + list_del(&urbp->urbp_list); + kfree(urbp); if (ep) ep->already_seen = ep->setup_stage = 0; usb_hcd_unlink_urb_from_ep(dummy_hcd_to_hcd(dum_hcd), urb); - spin_unlock (&dum->lock); + spin_unlock(&dum->lock); usb_hcd_giveback_urb(dummy_hcd_to_hcd(dum_hcd), urb, status); - spin_lock (&dum->lock); + spin_lock(&dum->lock); goto restart; } @@ -1883,7 +1875,7 @@ return_urb: mod_timer(&dum_hcd->timer, jiffies + msecs_to_jiffies(1)); } - spin_unlock_irqrestore (&dum->lock, flags); + spin_unlock_irqrestore(&dum->lock, flags); } /*-------------------------------------------------------------------------*/ @@ -1895,7 +1887,7 @@ return_urb: | USB_PORT_STAT_C_OVERCURRENT \ | USB_PORT_STAT_C_RESET) << 16) -static int dummy_hub_status (struct usb_hcd *hcd, char *buf) +static int dummy_hub_status(struct usb_hcd *hcd, char *buf) { struct dummy_hcd *dum_hcd; unsigned long flags; @@ -1919,7 +1911,7 @@ static int dummy_hub_status (struct usb_hcd *hcd, char *buf) dum_hcd->port_status); retval = 1; if (dum_hcd->rh_state == DUMMY_RH_SUSPENDED) - usb_hcd_resume_root_hub (hcd); + usb_hcd_resume_root_hub(hcd); } done: spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); @@ -1938,10 +1930,9 @@ ss_hub_descriptor(struct usb_hub_descriptor *desc) desc->u.ss.DeviceRemovable = 0xffff; } -static inline void -hub_descriptor (struct usb_hub_descriptor *desc) +static inline void hub_descriptor(struct usb_hub_descriptor *desc) { - memset (desc, 0, sizeof *desc); + memset(desc, 0, sizeof *desc); desc->bDescriptorType = 0x29; desc->bDescLength = 9; desc->wHubCharacteristics = cpu_to_le16(0x0001); @@ -1950,7 +1941,7 @@ hub_descriptor (struct usb_hub_descriptor *desc) desc->u.hs.DeviceRemovable[1] = 0xff; } -static int dummy_hub_control ( +static int dummy_hub_control( struct usb_hcd *hcd, u16 typeReq, u16 wValue, @@ -2018,7 +2009,7 @@ static int dummy_hub_control ( hub_descriptor((struct usb_hub_descriptor *) buf); break; case GetHubStatus: - *(__le32 *) buf = cpu_to_le32 (0); + *(__le32 *) buf = cpu_to_le32(0); break; case GetPortStatus: if (wIndex != 1) @@ -2060,8 +2051,8 @@ static int dummy_hub_control ( } } set_link_state(dum_hcd); - ((__le16 *) buf)[0] = cpu_to_le16 (dum_hcd->port_status); - ((__le16 *) buf)[1] = cpu_to_le16 (dum_hcd->port_status >> 16); + ((__le16 *) buf)[0] = cpu_to_le16(dum_hcd->port_status); + ((__le16 *) buf)[1] = cpu_to_le16(dum_hcd->port_status >> 16); break; case SetHubFeature: retval = -EPIPE; @@ -2195,15 +2186,15 @@ error: spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); if ((dum_hcd->port_status & PORT_C_MASK) != 0) - usb_hcd_poll_rh_status (hcd); + usb_hcd_poll_rh_status(hcd); return retval; } -static int dummy_bus_suspend (struct usb_hcd *hcd) +static int dummy_bus_suspend(struct usb_hcd *hcd) { struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); - dev_dbg (&hcd->self.root_hub->dev, "%s\n", __func__); + dev_dbg(&hcd->self.root_hub->dev, "%s\n", __func__); spin_lock_irq(&dum_hcd->dum->lock); dum_hcd->rh_state = DUMMY_RH_SUSPENDED; @@ -2213,12 +2204,12 @@ static int dummy_bus_suspend (struct usb_hcd *hcd) return 0; } -static int dummy_bus_resume (struct usb_hcd *hcd) +static int dummy_bus_resume(struct usb_hcd *hcd) { struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); int rc = 0; - dev_dbg (&hcd->self.root_hub->dev, "%s\n", __func__); + dev_dbg(&hcd->self.root_hub->dev, "%s\n", __func__); spin_lock_irq(&dum_hcd->dum->lock); if (!HCD_HW_ACCESSIBLE(hcd)) { @@ -2236,55 +2227,54 @@ static int dummy_bus_resume (struct usb_hcd *hcd) /*-------------------------------------------------------------------------*/ -static inline ssize_t -show_urb (char *buf, size_t size, struct urb *urb) +static inline ssize_t show_urb(char *buf, size_t size, struct urb *urb) { - int ep = usb_pipeendpoint (urb->pipe); + int ep = usb_pipeendpoint(urb->pipe); - return snprintf (buf, size, + return snprintf(buf, size, "urb/%p %s ep%d%s%s len %d/%d\n", urb, ({ char *s; - switch (urb->dev->speed) { - case USB_SPEED_LOW: + switch (urb->dev->speed) { + case USB_SPEED_LOW: s = "ls"; break; - case USB_SPEED_FULL: + case USB_SPEED_FULL: s = "fs"; break; - case USB_SPEED_HIGH: + case USB_SPEED_HIGH: s = "hs"; break; - case USB_SPEED_SUPER: + case USB_SPEED_SUPER: s = "ss"; break; - default: + default: s = "?"; break; }; s; }), - ep, ep ? (usb_pipein (urb->pipe) ? "in" : "out") : "", + ep, ep ? (usb_pipein(urb->pipe) ? "in" : "out") : "", ({ char *s; \ - switch (usb_pipetype (urb->pipe)) { \ - case PIPE_CONTROL: \ + switch (usb_pipetype(urb->pipe)) { \ + case PIPE_CONTROL: \ s = ""; \ break; \ - case PIPE_BULK: \ + case PIPE_BULK: \ s = "-bulk"; \ break; \ - case PIPE_INTERRUPT: \ + case PIPE_INTERRUPT: \ s = "-int"; \ break; \ - default: \ + default: \ s = "-iso"; \ break; \ - }; s;}), + }; s; }), urb->actual_length, urb->transfer_buffer_length); } -static ssize_t -show_urbs (struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_urbs(struct device *dev, struct device_attribute *attr, + char *buf) { - struct usb_hcd *hcd = dev_get_drvdata (dev); + struct usb_hcd *hcd = dev_get_drvdata(dev); struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); struct urbp *urbp; size_t size = 0; @@ -2294,7 +2284,7 @@ show_urbs (struct device *dev, struct device_attribute *attr, char *buf) list_for_each_entry(urbp, &dum_hcd->urbp_list, urbp_list) { size_t temp; - temp = show_urb (buf, PAGE_SIZE - size, urbp->urb); + temp = show_urb(buf, PAGE_SIZE - size, urbp->urb); buf += temp; size += temp; } @@ -2302,7 +2292,7 @@ show_urbs (struct device *dev, struct device_attribute *attr, char *buf) return size; } -static DEVICE_ATTR (urbs, S_IRUGO, show_urbs, NULL); +static DEVICE_ATTR(urbs, S_IRUGO, show_urbs, NULL); static int dummy_start_ss(struct dummy_hcd *dum_hcd) { @@ -2356,11 +2346,11 @@ static int dummy_start(struct usb_hcd *hcd) return device_create_file(dummy_dev(dum_hcd), &dev_attr_urbs); } -static void dummy_stop (struct usb_hcd *hcd) +static void dummy_stop(struct usb_hcd *hcd) { struct dummy *dum; - dum = (hcd_to_dummy_hcd(hcd))->dum; + dum = hcd_to_dummy_hcd(hcd)->dum; device_remove_file(dummy_dev(hcd_to_dummy_hcd(hcd)), &dev_attr_urbs); usb_gadget_unregister_driver(dum->driver); dev_info(dummy_dev(hcd_to_dummy_hcd(hcd)), "stopped\n"); @@ -2368,9 +2358,9 @@ static void dummy_stop (struct usb_hcd *hcd) /*-------------------------------------------------------------------------*/ -static int dummy_h_get_frame (struct usb_hcd *hcd) +static int dummy_h_get_frame(struct usb_hcd *hcd) { - return dummy_g_get_frame (NULL); + return dummy_g_get_frame(NULL); } static int dummy_setup(struct usb_hcd *hcd) @@ -2485,13 +2475,13 @@ static struct hc_driver dummy_hcd = { .start = dummy_start, .stop = dummy_stop, - .urb_enqueue = dummy_urb_enqueue, - .urb_dequeue = dummy_urb_dequeue, + .urb_enqueue = dummy_urb_enqueue, + .urb_dequeue = dummy_urb_dequeue, - .get_frame_number = dummy_h_get_frame, + .get_frame_number = dummy_h_get_frame, - .hub_status_data = dummy_hub_status, - .hub_control = dummy_hub_control, + .hub_status_data = dummy_hub_status, + .hub_control = dummy_hub_control, .bus_suspend = dummy_bus_suspend, .bus_resume = dummy_bus_resume, @@ -2546,7 +2536,7 @@ static int dummy_hcd_remove(struct platform_device *pdev) { struct dummy *dum; - dum = (hcd_to_dummy_hcd(platform_get_drvdata(pdev)))->dum; + dum = hcd_to_dummy_hcd(platform_get_drvdata(pdev))->dum; if (dum->ss_hcd) { usb_remove_hcd(dummy_hcd_to_hcd(dum->ss_hcd)); @@ -2562,15 +2552,15 @@ static int dummy_hcd_remove(struct platform_device *pdev) return 0; } -static int dummy_hcd_suspend (struct platform_device *pdev, pm_message_t state) +static int dummy_hcd_suspend(struct platform_device *pdev, pm_message_t state) { struct usb_hcd *hcd; struct dummy_hcd *dum_hcd; int rc = 0; - dev_dbg (&pdev->dev, "%s\n", __func__); + dev_dbg(&pdev->dev, "%s\n", __func__); - hcd = platform_get_drvdata (pdev); + hcd = platform_get_drvdata(pdev); dum_hcd = hcd_to_dummy_hcd(hcd); if (dum_hcd->rh_state == DUMMY_RH_RUNNING) { dev_warn(&pdev->dev, "Root hub isn't suspended!\n"); @@ -2580,15 +2570,15 @@ static int dummy_hcd_suspend (struct platform_device *pdev, pm_message_t state) return rc; } -static int dummy_hcd_resume (struct platform_device *pdev) +static int dummy_hcd_resume(struct platform_device *pdev) { struct usb_hcd *hcd; - dev_dbg (&pdev->dev, "%s\n", __func__); + dev_dbg(&pdev->dev, "%s\n", __func__); - hcd = platform_get_drvdata (pdev); + hcd = platform_get_drvdata(pdev); set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - usb_hcd_poll_rh_status (hcd); + usb_hcd_poll_rh_status(hcd); return 0; } @@ -2608,11 +2598,11 @@ static struct platform_driver dummy_hcd_driver = { static struct platform_device *the_udc_pdev; static struct platform_device *the_hcd_pdev; -static int __init init (void) +static int __init init(void) { int retval = -ENOMEM; - if (usb_disabled ()) + if (usb_disabled()) return -ENODEV; if (!mod_data.is_high_speed && mod_data.is_super_speed) @@ -2671,13 +2661,13 @@ err_alloc_udc: platform_device_put(the_hcd_pdev); return retval; } -module_init (init); +module_init(init); -static void __exit cleanup (void) +static void __exit cleanup(void) { platform_device_unregister(the_udc_pdev); platform_device_unregister(the_hcd_pdev); platform_driver_unregister(&dummy_udc_driver); platform_driver_unregister(&dummy_hcd_driver); } -module_exit (cleanup); +module_exit(cleanup); -- cgit v1.2.3-70-g09d2 From 54b8360ffd4c8b2c128ca25233b8c6876fb92d30 Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Fri, 13 Jan 2012 15:05:16 +0100 Subject: usb: gadget: update Michal Nazarewicz's email address The m.nazarewicz@samsung.com email address is no longer valid, so this commit replaces it with mina86@mina86.com which is employer-agnostic and thus should be valid for foreseeable feature. Signed-off-by: Michal Nazarewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_acm.c | 2 +- drivers/usb/gadget/f_fs.c | 2 +- drivers/usb/gadget/f_mass_storage.c | 2 +- drivers/usb/gadget/f_rndis.c | 2 +- drivers/usb/gadget/g_ffs.c | 2 +- drivers/usb/gadget/mass_storage.c | 2 +- drivers/usb/gadget/multi.c | 2 +- drivers/usb/gadget/storage_common.c | 2 +- tools/usb/ffs-test.c | 2 +- tools/usb/testusb.c | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index 3f8849339ad..e4821219546 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c @@ -5,7 +5,7 @@ * Copyright (C) 2008 by David Brownell * Copyright (C) 2008 by Nokia Corporation * Copyright (C) 2009 by Samsung Electronics - * Author: Michal Nazarewicz (m.nazarewicz@samsung.com) + * 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, diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index f63dc6c150d..7e2216f1bbe 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -2,7 +2,7 @@ * f_fs.c -- user mode file system API for USB composite function controllers * * Copyright (C) 2010 Samsung Electronics - * Author: Michal Nazarewicz + * Author: Michal Nazarewicz * * Based on inode.c (GadgetFS) which was: * Copyright (C) 2003-2004 David Brownell diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 6353eca1e85..6cde0217a8d 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -3,7 +3,7 @@ * * Copyright (C) 2003-2008 Alan Stern * Copyright (C) 2009 Samsung Electronics - * Author: Michal Nazarewicz + * Author: Michal Nazarewicz * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index 704d1d94f72..7b1cf18df5e 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c @@ -5,7 +5,7 @@ * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger * Copyright (C) 2008 Nokia Corporation * Copyright (C) 2009 Samsung Electronics - * Author: Michal Nazarewicz (m.nazarewicz@samsung.com) + * 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 diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c index 0519d77915e..331cd6729d3 100644 --- a/drivers/usb/gadget/g_ffs.c +++ b/drivers/usb/gadget/g_ffs.c @@ -2,7 +2,7 @@ * g_ffs.c -- user mode file system API for USB composite function controllers * * Copyright (C) 2010 Samsung Electronics - * Author: Michal Nazarewicz + * Author: Michal Nazarewicz * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c index e24f72f82a4..1f376eba31f 100644 --- a/drivers/usb/gadget/mass_storage.c +++ b/drivers/usb/gadget/mass_storage.c @@ -3,7 +3,7 @@ * * Copyright (C) 2003-2008 Alan Stern * Copyright (C) 2009 Samsung Electronics - * Author: Michal Nazarewicz + * Author: Michal Nazarewicz * All rights reserved. * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index 7e7f515b8b1..c37fb33a3d1 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c @@ -4,7 +4,7 @@ * Copyright (C) 2008 David Brownell * Copyright (C) 2008 Nokia Corporation * Copyright (C) 2009 Samsung Electronics - * Author: Michal Nazarewicz (m.nazarewicz@samsung.com) + * 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 diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index c7f291a331d..9d450feaaea 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -3,7 +3,7 @@ * * Copyright (C) 2003-2008 Alan Stern * Copyeight (C) 2009 Samsung Electronics - * Author: Michal Nazarewicz (m.nazarewicz@samsung.com) + * 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 diff --git a/tools/usb/ffs-test.c b/tools/usb/ffs-test.c index b9c79863169..53452c35d5e 100644 --- a/tools/usb/ffs-test.c +++ b/tools/usb/ffs-test.c @@ -2,7 +2,7 @@ * ffs-test.c.c -- user mode filesystem api for usb composite function * * Copyright (C) 2010 Samsung Electronics - * Author: Michal Nazarewicz + * Author: Michal Nazarewicz * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/tools/usb/testusb.c b/tools/usb/testusb.c index f08e8946384..6e0f56701e4 100644 --- a/tools/usb/testusb.c +++ b/tools/usb/testusb.c @@ -3,7 +3,7 @@ /* * Copyright (c) 2002 by David Brownell * Copyright (c) 2010 by Samsung Electronics - * Author: Michal Nazarewicz + * Author: Michal Nazarewicz * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the -- cgit v1.2.3-70-g09d2 From fcc0bb5ace11e6d0a27bdbdbf2e5e6d361a4e701 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Fri, 13 Jan 2012 21:54:46 +0100 Subject: usb: gadget: f_mass_storage: remove one FSG_NO_INTR_EP Remove one define of FSG_NO_INTR_EP and we still have that we can use. Signed-off-by: Sebastian Andrzej Siewior Acked-by: Michal Nazarewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_mass_storage.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 6cde0217a8d..82462714582 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -304,7 +304,6 @@ static const char fsg_string_interface[] = "Mass Storage"; -#define FSG_NO_INTR_EP 1 #define FSG_NO_DEVICE_STRINGS 1 #define FSG_NO_OTG 1 #define FSG_NO_INTR_EP 1 -- cgit v1.2.3-70-g09d2 From f557978745bbea2e7305588d33aac60f4dd42447 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Thu, 12 Jan 2012 15:21:38 +0200 Subject: usb: musb: drop superfluous pm_runtime calls around musb_shutdown Since commit 4f9edd2d7e8d "usb: musb: Fix the crash issue during reboot" musb_shutdown() does pm_runtime_get_sync/pm_runtime_put by itself, so this no longer needs to be done by the caller. Also, musb_exit_debugfs() doesn't access the device, so just drop those runtime_pm calls. Signed-off-by: Grazvydas Ignotas Reviewed-by: Shubhrajyoti D 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 56cf0243979..6a929859b55 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2111,11 +2111,9 @@ static int __exit musb_remove(struct platform_device *pdev) * - Peripheral mode: peripheral is deactivated (or never-activated) * - OTG mode: both roles are deactivated (or never-activated) */ - pm_runtime_get_sync(musb->controller); musb_exit_debugfs(musb); musb_shutdown(pdev); - pm_runtime_put(musb->controller); musb_free(musb); iounmap(ctrl_base); device_init_wakeup(&pdev->dev, 0); -- cgit v1.2.3-70-g09d2 From 7a950ea81de6cbf96e721599bfacdb409908cd00 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Sat, 21 Jan 2012 15:22:48 +0530 Subject: ath6kl: Make sure to delete rx aggregation timer in aggr_reset_state() The timer which is used to flush rx aggregation frames needs to be disabled when resetting the aggregation state. This is found in code review. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/txrx.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index dd633714260..cb7421a3161 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -1685,6 +1685,11 @@ void aggr_reset_state(struct aggr_info *aggr_info) { u8 tid; + if (aggr_info->timer_scheduled) { + del_timer(&aggr_info->timer); + aggr_info->timer_scheduled = false; + } + for (tid = 0; tid < NUM_OF_TIDS; tid++) aggr_delete_tid_state(aggr_info, tid); } -- cgit v1.2.3-70-g09d2 From 0e7de662bcf33567cc957995c38dc10959cc22bf Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Sat, 21 Jan 2012 15:22:49 +0530 Subject: ath6kl: Fix memory leak when unloading ath6kl_sdio The patch "ath6kl: create core.c" removes wiphy_free() from ath6kl_cfg80211_cleanup() and misses to free wiphy in ath6kl_sdio_remove(). This patch fixes this regression. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/sdio.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index 7bb61077c40..d9f55914b89 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -1314,6 +1314,7 @@ static void ath6kl_sdio_remove(struct sdio_func *func) cancel_work_sync(&ar_sdio->wr_async_work); ath6kl_core_cleanup(ar_sdio->ar); + ath6kl_core_destroy(ar_sdio->ar); kfree(ar_sdio->dma_buffer); kfree(ar_sdio); -- cgit v1.2.3-70-g09d2 From 7baef812eb5f02ccacf6fac3888c1cfa36293e91 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Sat, 21 Jan 2012 15:22:50 +0530 Subject: ath6kl: Define a structure for connection specific aggregation information This patch just groups connection specific aggregation information from struct aggr_info into a new structure (struct aggr_info_conn) so that, in softAP mode, this can be used when each connected station is made to have it's own aggregation state. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 2 +- drivers/net/wireless/ath/ath6kl/core.h | 11 +- drivers/net/wireless/ath/ath6kl/txrx.c | 166 ++++++++++++++++------------- 3 files changed, 98 insertions(+), 81 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 594d246da8e..8bf447a6a84 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -2694,7 +2694,7 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar) static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif) { - vif->aggr_cntxt = aggr_init(vif->ndev); + vif->aggr_cntxt = aggr_init(vif); if (!vif->aggr_cntxt) { ath6kl_err("failed to initialize aggr\n"); return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 67b22e4bbcc..1b9054f8f4e 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -242,14 +242,19 @@ struct rxtid_stats { u32 num_bar; }; -struct aggr_info { +struct aggr_info_conn { u8 aggr_sz; u8 timer_scheduled; struct timer_list timer; struct net_device *dev; struct rxtid rx_tid[NUM_OF_TIDS]; - struct sk_buff_head free_q; struct rxtid_stats stat[NUM_OF_TIDS]; + struct aggr_info *aggr_info; +}; + +struct aggr_info { + struct aggr_info_conn *aggr_conn; + struct sk_buff_head rx_amsdu_freeq; }; struct ath6kl_wep_key { @@ -707,7 +712,7 @@ struct ath6kl_cookie *ath6kl_alloc_cookie(struct ath6kl *ar); void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie); int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev); -struct aggr_info *aggr_init(struct net_device *dev); +struct aggr_info *aggr_init(struct ath6kl_vif *vif); void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint); void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count); diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index cb7421a3161..8407d0103dc 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -819,10 +819,12 @@ static struct sk_buff *aggr_get_free_skb(struct aggr_info *p_aggr) { struct sk_buff *skb = NULL; - if (skb_queue_len(&p_aggr->free_q) < (AGGR_NUM_OF_FREE_NETBUFS >> 2)) - ath6kl_alloc_netbufs(&p_aggr->free_q, AGGR_NUM_OF_FREE_NETBUFS); + if (skb_queue_len(&p_aggr->rx_amsdu_freeq) < + (AGGR_NUM_OF_FREE_NETBUFS >> 2)) + ath6kl_alloc_netbufs(&p_aggr->rx_amsdu_freeq, + AGGR_NUM_OF_FREE_NETBUFS); - skb = skb_dequeue(&p_aggr->free_q); + skb = skb_dequeue(&p_aggr->rx_amsdu_freeq); return skb; } @@ -998,12 +1000,14 @@ static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, struct skb_hold_q *node; u16 idx, idx_end, seq_end; struct rxtid_stats *stats; + struct aggr_info_conn *agg_conn; - if (!p_aggr) + if (!p_aggr || !p_aggr->aggr_conn) return; - rxtid = &p_aggr->rx_tid[tid]; - stats = &p_aggr->stat[tid]; + agg_conn = p_aggr->aggr_conn; + rxtid = &agg_conn->rx_tid[tid]; + stats = &agg_conn->stat[tid]; idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz); @@ -1048,7 +1052,7 @@ static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, stats->num_delivered += skb_queue_len(&rxtid->q); while ((skb = skb_dequeue(&rxtid->q))) - ath6kl_deliver_frames_to_nw_stack(p_aggr->dev, skb); + ath6kl_deliver_frames_to_nw_stack(agg_conn->dev, skb); } static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, @@ -1062,9 +1066,10 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, u16 idx, st, cur, end; bool is_queued = false; u16 extended_end; + struct aggr_info_conn *agg_conn = agg_info->aggr_conn; - rxtid = &agg_info->rx_tid[tid]; - stats = &agg_info->stat[tid]; + rxtid = &agg_conn->rx_tid[tid]; + stats = &agg_conn->stat[tid]; stats->num_into_aggr++; @@ -1074,7 +1079,7 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, is_queued = true; stats->num_amsdu++; while ((skb = skb_dequeue(&rxtid->q))) - ath6kl_deliver_frames_to_nw_stack(agg_info->dev, + ath6kl_deliver_frames_to_nw_stack(agg_conn->dev, skb); } return is_queued; @@ -1152,7 +1157,7 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, aggr_deque_frms(agg_info, tid, 0, 1); - if (agg_info->timer_scheduled) + if (agg_conn->timer_scheduled) rxtid->progress = true; else for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) { @@ -1163,8 +1168,8 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, * the frame doesn't remain stuck * forever. */ - agg_info->timer_scheduled = true; - mod_timer(&agg_info->timer, + agg_conn->timer_scheduled = true; + mod_timer(&agg_conn->timer, (jiffies + HZ * (AGGR_RX_TIMEOUT) / 1000)); rxtid->progress = false; @@ -1525,13 +1530,13 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) static void aggr_timeout(unsigned long arg) { u8 i, j; - struct aggr_info *p_aggr = (struct aggr_info *) arg; + struct aggr_info_conn *aggr_conn = (struct aggr_info_conn *) arg; struct rxtid *rxtid; struct rxtid_stats *stats; for (i = 0; i < NUM_OF_TIDS; i++) { - rxtid = &p_aggr->rx_tid[i]; - stats = &p_aggr->stat[i]; + rxtid = &aggr_conn->rx_tid[i]; + stats = &aggr_conn->stat[i]; if (!rxtid->aggr || !rxtid->timer_mon || rxtid->progress) continue; @@ -1542,18 +1547,18 @@ static void aggr_timeout(unsigned long arg) rxtid->seq_next, ((rxtid->seq_next + rxtid->hold_q_sz-1) & ATH6KL_MAX_SEQ_NO)); - aggr_deque_frms(p_aggr, i, 0, 0); + aggr_deque_frms(aggr_conn->aggr_info, i, 0, 0); } - p_aggr->timer_scheduled = false; + aggr_conn->timer_scheduled = false; for (i = 0; i < NUM_OF_TIDS; i++) { - rxtid = &p_aggr->rx_tid[i]; + rxtid = &aggr_conn->rx_tid[i]; if (rxtid->aggr && rxtid->hold_q) { for (j = 0; j < rxtid->hold_q_sz; j++) { if (rxtid->hold_q[j].skb) { - p_aggr->timer_scheduled = true; + aggr_conn->timer_scheduled = true; rxtid->timer_mon = true; rxtid->progress = false; break; @@ -1565,24 +1570,24 @@ static void aggr_timeout(unsigned long arg) } } - if (p_aggr->timer_scheduled) - mod_timer(&p_aggr->timer, + if (aggr_conn->timer_scheduled) + mod_timer(&aggr_conn->timer, jiffies + msecs_to_jiffies(AGGR_RX_TIMEOUT)); } -static void aggr_delete_tid_state(struct aggr_info *p_aggr, u8 tid) +static void aggr_delete_tid_state(struct aggr_info_conn *aggr_conn, u8 tid) { struct rxtid *rxtid; struct rxtid_stats *stats; - if (!p_aggr || tid >= NUM_OF_TIDS) + if (!aggr_conn || tid >= NUM_OF_TIDS) return; - rxtid = &p_aggr->rx_tid[tid]; - stats = &p_aggr->stat[tid]; + rxtid = &aggr_conn->rx_tid[tid]; + stats = &aggr_conn->stat[tid]; if (rxtid->aggr) - aggr_deque_frms(p_aggr, tid, 0, 0); + aggr_deque_frms(aggr_conn->aggr_info, tid, 0, 0); rxtid->aggr = false; rxtid->progress = false; @@ -1601,22 +1606,25 @@ void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid, u16 seq_no, u8 win_sz) { struct aggr_info *p_aggr = vif->aggr_cntxt; + struct aggr_info_conn *aggr_conn; struct rxtid *rxtid; struct rxtid_stats *stats; u16 hold_q_size; - if (!p_aggr) + if (!p_aggr || !p_aggr->aggr_conn) return; - rxtid = &p_aggr->rx_tid[tid]; - stats = &p_aggr->stat[tid]; + aggr_conn = p_aggr->aggr_conn; + + rxtid = &aggr_conn->rx_tid[tid]; + stats = &aggr_conn->stat[tid]; if (win_sz < AGGR_WIN_SZ_MIN || win_sz > AGGR_WIN_SZ_MAX) ath6kl_dbg(ATH6KL_DBG_WLAN_RX, "%s: win_sz %d, tid %d\n", __func__, win_sz, tid); if (rxtid->aggr) - aggr_delete_tid_state(p_aggr, tid); + aggr_delete_tid_state(aggr_conn, tid); rxtid->seq_next = seq_no; hold_q_size = TID_WINDOW_SZ(win_sz) * sizeof(struct skb_hold_q); @@ -1632,31 +1640,23 @@ void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid, u16 seq_no, rxtid->aggr = true; } -struct aggr_info *aggr_init(struct net_device *dev) +static void aggr_conn_init(struct ath6kl_vif *vif, + struct aggr_info_conn *aggr_conn) { - struct aggr_info *p_aggr = NULL; struct rxtid *rxtid; u8 i; - p_aggr = kzalloc(sizeof(struct aggr_info), GFP_KERNEL); - if (!p_aggr) { - ath6kl_err("failed to alloc memory for aggr_node\n"); - return NULL; - } - - p_aggr->aggr_sz = AGGR_SZ_DEFAULT; - p_aggr->dev = dev; - init_timer(&p_aggr->timer); - p_aggr->timer.function = aggr_timeout; - p_aggr->timer.data = (unsigned long) p_aggr; - - p_aggr->timer_scheduled = false; - skb_queue_head_init(&p_aggr->free_q); + aggr_conn->aggr_sz = AGGR_SZ_DEFAULT; + aggr_conn->dev = vif->ndev; + init_timer(&aggr_conn->timer); + aggr_conn->timer.function = aggr_timeout; + aggr_conn->timer.data = (unsigned long) aggr_conn; + aggr_conn->aggr_info = vif->aggr_cntxt; - ath6kl_alloc_netbufs(&p_aggr->free_q, AGGR_NUM_OF_FREE_NETBUFS); + aggr_conn->timer_scheduled = false; for (i = 0; i < NUM_OF_TIDS; i++) { - rxtid = &p_aggr->rx_tid[i]; + rxtid = &aggr_conn->rx_tid[i]; rxtid->aggr = false; rxtid->progress = false; rxtid->timer_mon = false; @@ -1664,6 +1664,30 @@ struct aggr_info *aggr_init(struct net_device *dev) spin_lock_init(&rxtid->lock); } +} + +struct aggr_info *aggr_init(struct ath6kl_vif *vif) +{ + struct aggr_info *p_aggr = NULL; + + p_aggr = kzalloc(sizeof(struct aggr_info), GFP_KERNEL); + if (!p_aggr) { + ath6kl_err("failed to alloc memory for aggr_node\n"); + return NULL; + } + + p_aggr->aggr_conn = kzalloc(sizeof(struct aggr_info_conn), GFP_KERNEL); + if (!p_aggr->aggr_conn) { + ath6kl_err("failed to alloc memory for connection specific aggr info\n"); + kfree(p_aggr); + return NULL; + } + + aggr_conn_init(vif, p_aggr->aggr_conn); + + skb_queue_head_init(&p_aggr->rx_amsdu_freeq); + ath6kl_alloc_netbufs(&p_aggr->rx_amsdu_freeq, AGGR_NUM_OF_FREE_NETBUFS); + return p_aggr; } @@ -1671,27 +1695,32 @@ void aggr_recv_delba_req_evt(struct ath6kl_vif *vif, u8 tid) { struct aggr_info *p_aggr = vif->aggr_cntxt; struct rxtid *rxtid; + struct aggr_info_conn *aggr_conn; - if (!p_aggr) + if (!p_aggr || !p_aggr->aggr_conn) return; - rxtid = &p_aggr->rx_tid[tid]; + aggr_conn = p_aggr->aggr_conn; + rxtid = &aggr_conn->rx_tid[tid]; if (rxtid->aggr) - aggr_delete_tid_state(p_aggr, tid); + aggr_delete_tid_state(aggr_conn, tid); } void aggr_reset_state(struct aggr_info *aggr_info) { u8 tid; - if (aggr_info->timer_scheduled) { - del_timer(&aggr_info->timer); - aggr_info->timer_scheduled = false; + if (!aggr_info || !aggr_info->aggr_conn) + return; + + if (aggr_info->aggr_conn->timer_scheduled) { + del_timer(&aggr_info->aggr_conn->timer); + aggr_info->aggr_conn->timer_scheduled = false; } for (tid = 0; tid < NUM_OF_TIDS; tid++) - aggr_delete_tid_state(aggr_info, tid); + aggr_delete_tid_state(aggr_info->aggr_conn, tid); } /* clean up our amsdu buffer list */ @@ -1718,28 +1747,11 @@ void ath6kl_cleanup_amsdu_rxbufs(struct ath6kl *ar) void aggr_module_destroy(struct aggr_info *aggr_info) { - struct rxtid *rxtid; - u8 i, k; - - if (!aggr_info) + if (!aggr_info || !aggr_info->aggr_conn) return; - if (aggr_info->timer_scheduled) { - del_timer(&aggr_info->timer); - aggr_info->timer_scheduled = false; - } - - for (i = 0; i < NUM_OF_TIDS; i++) { - rxtid = &aggr_info->rx_tid[i]; - if (rxtid->hold_q) { - for (k = 0; k < rxtid->hold_q_sz; k++) - dev_kfree_skb(rxtid->hold_q[k].skb); - kfree(rxtid->hold_q); - } - - skb_queue_purge(&rxtid->q); - } - - skb_queue_purge(&aggr_info->free_q); + aggr_reset_state(aggr_info); + skb_queue_purge(&aggr_info->rx_amsdu_freeq); + kfree(aggr_info->aggr_conn); kfree(aggr_info); } -- cgit v1.2.3-70-g09d2 From 17741c8db4f53200a51600d1644ee6a2b76f0984 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Sat, 21 Jan 2012 15:22:51 +0530 Subject: ath6kl: Pass vif instead of ar to ath6kl_add_new_sta() This will be used when initializing station specific aggregation information. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index 3a3b2cc9940..acb4acb7171 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -52,10 +52,11 @@ struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid) return conn; } -static void ath6kl_add_new_sta(struct ath6kl *ar, u8 *mac, u16 aid, u8 *wpaie, - size_t ielen, u8 keymgmt, u8 ucipher, u8 auth, - u8 apsd_info) +static void ath6kl_add_new_sta(struct ath6kl_vif *vif, u8 *mac, u16 aid, + u8 *wpaie, size_t ielen, u8 keymgmt, + u8 ucipher, u8 auth, u8 apsd_info) { + struct ath6kl *ar = vif->ar; struct ath6kl_sta *sta; u8 free_slot; @@ -430,7 +431,6 @@ void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr, u8 keymgmt, u8 ucipher, u8 auth, u8 assoc_req_len, u8 *assoc_info, u8 apsd_info) { - struct ath6kl *ar = vif->ar; u8 *ies = NULL, *wpa_ie = NULL, *pos; size_t ies_len = 0; struct station_info sinfo; @@ -484,7 +484,7 @@ void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr, pos += 2 + pos[1]; } - ath6kl_add_new_sta(ar, mac_addr, aid, wpa_ie, + ath6kl_add_new_sta(vif, mac_addr, aid, wpa_ie, wpa_ie ? 2 + wpa_ie[1] : 0, keymgmt, ucipher, auth, apsd_info); -- cgit v1.2.3-70-g09d2 From 3fdc099109e75359e5de54c56478c06255850741 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Sat, 21 Jan 2012 15:22:52 +0530 Subject: ath6kl: Fix bug in using tid given by addba/delba req events The tid which is given in addba/delba req event is not just tid but also muxed with the assoc id (MSB 4 bits) which can be used to determine the corresponding connected station in softap mode. The actual tid is LSB 4 bits. Using the tid as it is with rx_tid[] would result in OOB or invalid memory access in AP mode. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/txrx.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index 8407d0103dc..8cf7b2fa0f4 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -17,6 +17,17 @@ #include "core.h" #include "debug.h" +/* + * tid - tid_mux0..tid_mux3 + * aid - tid_mux4..tid_mux7 + */ +#define ATH6KL_TID_MASK 0xf + +static inline u8 ath6kl_get_tid(u8 tid_mux) +{ + return tid_mux & ATH6KL_TID_MASK; +} + static u8 ath6kl_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, u32 *map_no) { @@ -1602,7 +1613,7 @@ static void aggr_delete_tid_state(struct aggr_info_conn *aggr_conn, u8 tid) memset(stats, 0, sizeof(struct rxtid_stats)); } -void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid, u16 seq_no, +void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid_mux, u16 seq_no, u8 win_sz) { struct aggr_info *p_aggr = vif->aggr_cntxt; @@ -1610,12 +1621,17 @@ void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid, u16 seq_no, struct rxtid *rxtid; struct rxtid_stats *stats; u16 hold_q_size; + u8 tid; if (!p_aggr || !p_aggr->aggr_conn) return; aggr_conn = p_aggr->aggr_conn; + tid = ath6kl_get_tid(tid_mux); + if (tid >= NUM_OF_TIDS) + return; + rxtid = &aggr_conn->rx_tid[tid]; stats = &aggr_conn->stat[tid]; @@ -1691,15 +1707,20 @@ struct aggr_info *aggr_init(struct ath6kl_vif *vif) return p_aggr; } -void aggr_recv_delba_req_evt(struct ath6kl_vif *vif, u8 tid) +void aggr_recv_delba_req_evt(struct ath6kl_vif *vif, u8 tid_mux) { struct aggr_info *p_aggr = vif->aggr_cntxt; struct rxtid *rxtid; struct aggr_info_conn *aggr_conn; + u8 tid; if (!p_aggr || !p_aggr->aggr_conn) return; + tid = ath6kl_get_tid(tid_mux); + if (tid >= NUM_OF_TIDS) + return; + aggr_conn = p_aggr->aggr_conn; rxtid = &aggr_conn->rx_tid[tid]; -- cgit v1.2.3-70-g09d2 From 1d2a4456de20db73362c86c88fe9c02169f29d0a Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Sat, 21 Jan 2012 15:22:53 +0530 Subject: ath6kl: Fix bug in maintaining aggregation state in AP mode Currently rx aggregation related states are maintained per vif, but this will not properly work when operating in AP mode. Aggregation is completely broken when more than one 11n stations are connected to AP mode vif. Fix this issue by keeping station specific aggregation state in sta_list. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 5 ++ drivers/net/wireless/ath/ath6kl/core.c | 7 ++ drivers/net/wireless/ath/ath6kl/core.h | 4 +- drivers/net/wireless/ath/ath6kl/init.c | 4 ++ drivers/net/wireless/ath/ath6kl/main.c | 7 +- drivers/net/wireless/ath/ath6kl/txrx.c | 106 ++++++++++++++++++----------- 6 files changed, 88 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 8bf447a6a84..fed7b8077f5 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -2871,6 +2871,11 @@ struct ath6kl *ath6kl_cfg80211_create(void) /* Note: ar variable must not be accessed after calling this! */ void ath6kl_cfg80211_destroy(struct ath6kl *ar) { + int i; + + for (i = 0; i < AP_MAX_NUM_STA; i++) + kfree(ar->sta_list[i].aggr_conn); + wiphy_free(ar->wiphy); } diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c index d764afec395..0d92e7179f8 100644 --- a/drivers/net/wireless/ath/ath6kl/core.c +++ b/drivers/net/wireless/ath/ath6kl/core.c @@ -253,6 +253,13 @@ struct ath6kl *ath6kl_core_create(struct device *dev) spin_lock_init(&ar->sta_list[ctr].psq_lock); skb_queue_head_init(&ar->sta_list[ctr].psq); skb_queue_head_init(&ar->sta_list[ctr].apsdq); + ar->sta_list[ctr].aggr_conn = + kzalloc(sizeof(struct aggr_info_conn), GFP_KERNEL); + if (!ar->sta_list[ctr].aggr_conn) { + ath6kl_err("Failed to allocate memory for sta aggregation information\n"); + ath6kl_core_destroy(ar); + return NULL; + } } skb_queue_head_init(&ar->mcastpsq); diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 1b9054f8f4e..ed9fcc11b5f 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -298,6 +298,7 @@ struct ath6kl_sta { spinlock_t psq_lock; u8 apsd_info; struct sk_buff_head apsdq; + struct aggr_info_conn *aggr_conn; }; struct ath6kl_version { @@ -713,6 +714,7 @@ void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie); int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev); struct aggr_info *aggr_init(struct ath6kl_vif *vif); +void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info_conn *aggr_conn); void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint); void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count); @@ -720,7 +722,7 @@ struct htc_packet *ath6kl_alloc_amsdu_rxbuf(struct htc_target *target, enum htc_endpoint_id endpoint, int len); void aggr_module_destroy(struct aggr_info *aggr_info); -void aggr_reset_state(struct aggr_info *aggr_info); +void aggr_reset_state(struct aggr_info_conn *aggr_conn); struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 * node_addr); struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid); diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 167dc41af2d..4d8eb1cca6e 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -1660,6 +1660,7 @@ void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready) void ath6kl_stop_txrx(struct ath6kl *ar) { struct ath6kl_vif *vif, *tmp_vif; + int i; set_bit(DESTROY_IN_PROGRESS, &ar->flag); @@ -1668,6 +1669,9 @@ void ath6kl_stop_txrx(struct ath6kl *ar) return; } + for (i = 0; i < AP_MAX_NUM_STA; i++) + aggr_reset_state(ar->sta_list[i].aggr_conn); + spin_lock_bh(&ar->list_lock); list_for_each_entry_safe(vif, tmp_vif, &ar->vif_list, list) { list_del(&vif->list); diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index acb4acb7171..39da1f98da8 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -74,6 +74,7 @@ static void ath6kl_add_new_sta(struct ath6kl_vif *vif, u8 *mac, u16 aid, ar->sta_list_index = ar->sta_list_index | (1 << free_slot); ar->ap_stats.sta[free_slot].aid = cpu_to_le32(aid); + aggr_conn_init(vif, sta->aggr_conn); } static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i) @@ -94,7 +95,7 @@ static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i) sta->sta_flags = 0; ar->sta_list_index = ar->sta_list_index & ~(1 << i); - + aggr_reset_state(sta->aggr_conn); } static u8 ath6kl_remove_sta(struct ath6kl *ar, u8 *mac, u16 reason) @@ -602,7 +603,7 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid, netif_carrier_on(vif->ndev); spin_unlock_bh(&vif->if_lock); - aggr_reset_state(vif->aggr_cntxt); + aggr_reset_state(vif->aggr_cntxt->aggr_conn); vif->reconnect_flag = 0; if ((vif->nw_type == ADHOC_NETWORK) && ar->ibss_ps_enable) { @@ -924,7 +925,7 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid, assoc_resp_len, assoc_info, prot_reason_status); - aggr_reset_state(vif->aggr_cntxt); + aggr_reset_state(vif->aggr_cntxt->aggr_conn); del_timer(&vif->disconnect_timer); diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index 8cf7b2fa0f4..62c12102e14 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -22,12 +22,18 @@ * aid - tid_mux4..tid_mux7 */ #define ATH6KL_TID_MASK 0xf +#define ATH6KL_AID_SHIFT 4 static inline u8 ath6kl_get_tid(u8 tid_mux) { return tid_mux & ATH6KL_TID_MASK; } +static inline u8 ath6kl_get_aid(u8 tid_mux) +{ + return tid_mux >> ATH6KL_AID_SHIFT; +} + static u8 ath6kl_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, u32 *map_no) { @@ -1003,7 +1009,7 @@ static void aggr_slice_amsdu(struct aggr_info *p_aggr, dev_kfree_skb(skb); } -static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, +static void aggr_deque_frms(struct aggr_info_conn *agg_conn, u8 tid, u16 seq_no, u8 order) { struct sk_buff *skb; @@ -1011,12 +1017,7 @@ static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, struct skb_hold_q *node; u16 idx, idx_end, seq_end; struct rxtid_stats *stats; - struct aggr_info_conn *agg_conn; - if (!p_aggr || !p_aggr->aggr_conn) - return; - - agg_conn = p_aggr->aggr_conn; rxtid = &agg_conn->rx_tid[tid]; stats = &agg_conn->stat[tid]; @@ -1047,7 +1048,8 @@ static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, if (node->skb) { if (node->is_amsdu) - aggr_slice_amsdu(p_aggr, rxtid, node->skb); + aggr_slice_amsdu(agg_conn->aggr_info, rxtid, + node->skb); else skb_queue_tail(&rxtid->q, node->skb); node->skb = NULL; @@ -1066,7 +1068,7 @@ static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, ath6kl_deliver_frames_to_nw_stack(agg_conn->dev, skb); } -static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, +static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid, u16 seq_no, bool is_amsdu, struct sk_buff *frame) { @@ -1077,7 +1079,6 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, u16 idx, st, cur, end; bool is_queued = false; u16 extended_end; - struct aggr_info_conn *agg_conn = agg_info->aggr_conn; rxtid = &agg_conn->rx_tid[tid]; stats = &agg_conn->stat[tid]; @@ -1086,7 +1087,7 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, if (!rxtid->aggr) { if (is_amsdu) { - aggr_slice_amsdu(agg_info, rxtid, frame); + aggr_slice_amsdu(agg_conn->aggr_info, rxtid, frame); is_queued = true; stats->num_amsdu++; while ((skb = skb_dequeue(&rxtid->q))) @@ -1110,7 +1111,7 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, (cur < end || cur > extended_end)) || ((end > extended_end) && (cur > extended_end) && (cur < end))) { - aggr_deque_frms(agg_info, tid, 0, 0); + aggr_deque_frms(agg_conn, tid, 0, 0); if (cur >= rxtid->hold_q_sz - 1) rxtid->seq_next = cur - (rxtid->hold_q_sz - 1); else @@ -1127,7 +1128,7 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, st = ATH6KL_MAX_SEQ_NO - (rxtid->hold_q_sz - 2 - cur); - aggr_deque_frms(agg_info, tid, st, 0); + aggr_deque_frms(agg_conn, tid, st, 0); } stats->num_oow++; @@ -1166,7 +1167,7 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, spin_unlock_bh(&rxtid->lock); - aggr_deque_frms(agg_info, tid, 0, 1); + aggr_deque_frms(agg_conn, tid, 0, 1); if (agg_conn->timer_scheduled) rxtid->progress = true; @@ -1278,6 +1279,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) struct sk_buff *skb1 = NULL; struct ethhdr *datap = NULL; struct ath6kl_vif *vif; + struct aggr_info_conn *aggr_conn; u16 seq_no, offset; u8 tid, if_idx; @@ -1529,11 +1531,21 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) datap = (struct ethhdr *) skb->data; - if (is_unicast_ether_addr(datap->h_dest) && - aggr_process_recv_frm(vif->aggr_cntxt, tid, seq_no, - is_amsdu, skb)) - /* aggregation code will handle the skb */ - return; + if (is_unicast_ether_addr(datap->h_dest)) { + if (vif->nw_type == AP_NETWORK) { + conn = ath6kl_find_sta(vif, datap->h_source); + if (!conn) + return; + aggr_conn = conn->aggr_conn; + } else + aggr_conn = vif->aggr_cntxt->aggr_conn; + + if (aggr_process_recv_frm(aggr_conn, tid, seq_no, + is_amsdu, skb)) { + /* aggregation code will handle the skb */ + return; + } + } ath6kl_deliver_frames_to_nw_stack(vif->ndev, skb); } @@ -1558,7 +1570,7 @@ static void aggr_timeout(unsigned long arg) rxtid->seq_next, ((rxtid->seq_next + rxtid->hold_q_sz-1) & ATH6KL_MAX_SEQ_NO)); - aggr_deque_frms(aggr_conn->aggr_info, i, 0, 0); + aggr_deque_frms(aggr_conn, i, 0, 0); } aggr_conn->timer_scheduled = false; @@ -1598,7 +1610,7 @@ static void aggr_delete_tid_state(struct aggr_info_conn *aggr_conn, u8 tid) stats = &aggr_conn->stat[tid]; if (rxtid->aggr) - aggr_deque_frms(aggr_conn->aggr_info, tid, 0, 0); + aggr_deque_frms(aggr_conn, tid, 0, 0); rxtid->aggr = false; rxtid->progress = false; @@ -1616,17 +1628,23 @@ static void aggr_delete_tid_state(struct aggr_info_conn *aggr_conn, u8 tid) void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid_mux, u16 seq_no, u8 win_sz) { - struct aggr_info *p_aggr = vif->aggr_cntxt; - struct aggr_info_conn *aggr_conn; + struct ath6kl_sta *sta; + struct aggr_info_conn *aggr_conn = NULL; struct rxtid *rxtid; struct rxtid_stats *stats; u16 hold_q_size; - u8 tid; + u8 tid, aid; - if (!p_aggr || !p_aggr->aggr_conn) - return; + if (vif->nw_type == AP_NETWORK) { + aid = ath6kl_get_aid(tid_mux); + sta = ath6kl_find_sta_by_aid(vif->ar, aid); + if (sta) + aggr_conn = sta->aggr_conn; + } else + aggr_conn = vif->aggr_cntxt->aggr_conn; - aggr_conn = p_aggr->aggr_conn; + if (!aggr_conn) + return; tid = ath6kl_get_tid(tid_mux); if (tid >= NUM_OF_TIDS) @@ -1656,8 +1674,7 @@ void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid_mux, u16 seq_no, rxtid->aggr = true; } -static void aggr_conn_init(struct ath6kl_vif *vif, - struct aggr_info_conn *aggr_conn) +void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info_conn *aggr_conn) { struct rxtid *rxtid; u8 i; @@ -1709,39 +1726,46 @@ struct aggr_info *aggr_init(struct ath6kl_vif *vif) void aggr_recv_delba_req_evt(struct ath6kl_vif *vif, u8 tid_mux) { - struct aggr_info *p_aggr = vif->aggr_cntxt; + struct ath6kl_sta *sta; struct rxtid *rxtid; - struct aggr_info_conn *aggr_conn; - u8 tid; + struct aggr_info_conn *aggr_conn = NULL; + u8 tid, aid; + + if (vif->nw_type == AP_NETWORK) { + aid = ath6kl_get_aid(tid_mux); + sta = ath6kl_find_sta_by_aid(vif->ar, aid); + if (sta) + aggr_conn = sta->aggr_conn; + } else + aggr_conn = vif->aggr_cntxt->aggr_conn; - if (!p_aggr || !p_aggr->aggr_conn) + if (!aggr_conn) return; tid = ath6kl_get_tid(tid_mux); if (tid >= NUM_OF_TIDS) return; - aggr_conn = p_aggr->aggr_conn; rxtid = &aggr_conn->rx_tid[tid]; if (rxtid->aggr) aggr_delete_tid_state(aggr_conn, tid); } -void aggr_reset_state(struct aggr_info *aggr_info) +void aggr_reset_state(struct aggr_info_conn *aggr_conn) { u8 tid; - if (!aggr_info || !aggr_info->aggr_conn) + if (!aggr_conn) return; - if (aggr_info->aggr_conn->timer_scheduled) { - del_timer(&aggr_info->aggr_conn->timer); - aggr_info->aggr_conn->timer_scheduled = false; + if (aggr_conn->timer_scheduled) { + del_timer(&aggr_conn->timer); + aggr_conn->timer_scheduled = false; } for (tid = 0; tid < NUM_OF_TIDS; tid++) - aggr_delete_tid_state(aggr_info->aggr_conn, tid); + aggr_delete_tid_state(aggr_conn, tid); } /* clean up our amsdu buffer list */ @@ -1768,10 +1792,10 @@ void ath6kl_cleanup_amsdu_rxbufs(struct ath6kl *ar) void aggr_module_destroy(struct aggr_info *aggr_info) { - if (!aggr_info || !aggr_info->aggr_conn) + if (!aggr_info) return; - aggr_reset_state(aggr_info); + aggr_reset_state(aggr_info->aggr_conn); skb_queue_purge(&aggr_info->rx_amsdu_freeq); kfree(aggr_info->aggr_conn); kfree(aggr_info); -- cgit v1.2.3-70-g09d2 From 8e636784b6f76653d358d521af9c2a8c246df38b Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sun, 22 Jan 2012 01:36:48 +0100 Subject: drm/i915: fixup assert_pipe to take the pipe A quirk into account This was completely spamming dmesg on my i855gm. This issue was just shortly introduced with: commit 931872fceabacf2d4f8b6fbd51611c167e83164c Author: Chris Wilson Date: Mon Jan 16 23:01:13 2012 +0000 drm/i915: Check that plane/pipe is disabled before removing the fb Reviewed-by: Jesse Barnes Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index cfd3a87807f..ebb34524490 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -936,6 +936,10 @@ void assert_pipe(struct drm_i915_private *dev_priv, u32 val; bool cur_state; + /* if we need the pipe A quirk it must be always on */ + if (pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) + state = true; + reg = PIPECONF(pipe); val = I915_READ(reg); cur_state = !!(val & PIPECONF_ENABLE); -- cgit v1.2.3-70-g09d2 From b0f70292053a0f68f406564a721a7a3f2d66b44f Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 2 Jan 2012 08:41:23 +0100 Subject: ssb: SPROM: extract each core power info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We already extract some basic info but it's incomplete, reads info about the first core only. Used data structure doesn't allow easy adding of more cores. This patch adds new struct and array for storing power info. The plan is to: switch all extractors (including the ones using NVRAM) to new struct, switch drivers, then deprecate and finally drop old SSB fields. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/ssb/pci.c | 40 +++++++++++++++++++++++++++++++++++++++- include/linux/ssb/ssb.h | 8 ++++++++ include/linux/ssb/ssb_regs.h | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index 973223f5de8..befa89eac6f 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c @@ -523,7 +523,13 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in) static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in) { int i; - u16 v; + u16 v, o; + u16 pwr_info_offset[] = { + SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1, + SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3 + }; + BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) != + ARRAY_SIZE(out->core_pwr_info)); /* extract the MAC address */ for (i = 0; i < 3; i++) { @@ -607,6 +613,38 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in) memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24, sizeof(out->antenna_gain.ghz5)); + /* Extract cores power info info */ + for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) { + o = pwr_info_offset[i]; + SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI, + SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT); + SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI, + SSB_SPROM8_2G_MAXP, 0); + + SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0); + SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0); + SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0); + + SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI, + SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT); + SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI, + SSB_SPROM8_5G_MAXP, 0); + SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP, + SSB_SPROM8_5GH_MAXP, 0); + SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP, + SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT); + + SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0); + SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0); + SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0); + SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0); + SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0); + SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0); + SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0); + SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0); + SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0); + } + /* Extract FEM info */ SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TSSIPOS, SSB_SROM8_FEM_TSSIPOS_SHIFT); diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index dcf35b0f303..bbc2612cb64 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h @@ -16,6 +16,12 @@ struct pcmcia_device; struct ssb_bus; struct ssb_driver; +struct ssb_sprom_core_pwr_info { + u8 itssi_2g, itssi_5g; + u8 maxpwr_2g, maxpwr_5gl, maxpwr_5g, maxpwr_5gh; + u16 pa_2g[3], pa_5gl[3], pa_5g[3], pa_5gh[3]; +}; + struct ssb_sprom { u8 revision; u8 il0mac[6]; /* MAC address for 802.11b/g */ @@ -82,6 +88,8 @@ struct ssb_sprom { u16 boardflags2_hi; /* Board flags (bits 48-63) */ /* TODO store board flags in a single u64 */ + struct ssb_sprom_core_pwr_info core_pwr_info[4]; + /* Antenna gain values for up to 4 antennas * on each band. Values in dBm/4 (Q5.2). Negative gain means the * loss in the connectors is bigger than the gain. */ diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h index c814ae6eeb2..40b1ef8595e 100644 --- a/include/linux/ssb/ssb_regs.h +++ b/include/linux/ssb/ssb_regs.h @@ -449,6 +449,39 @@ #define SSB_SPROM8_TS_SLP_OPT_CORRX 0x00B6 #define SSB_SPROM8_FOC_HWIQ_IQSWP 0x00B8 #define SSB_SPROM8_PHYCAL_TEMPDELTA 0x00BA + +/* There are 4 blocks with power info sharing the same layout */ +#define SSB_SROM8_PWR_INFO_CORE0 0x00C0 +#define SSB_SROM8_PWR_INFO_CORE1 0x00E0 +#define SSB_SROM8_PWR_INFO_CORE2 0x0100 +#define SSB_SROM8_PWR_INFO_CORE3 0x0120 + +#define SSB_SROM8_2G_MAXP_ITSSI 0x00 +#define SSB_SPROM8_2G_MAXP 0x00FF +#define SSB_SPROM8_2G_ITSSI 0xFF00 +#define SSB_SPROM8_2G_ITSSI_SHIFT 8 +#define SSB_SROM8_2G_PA_0 0x02 /* 2GHz power amp settings */ +#define SSB_SROM8_2G_PA_1 0x04 +#define SSB_SROM8_2G_PA_2 0x06 +#define SSB_SROM8_5G_MAXP_ITSSI 0x08 /* 5GHz ITSSI and 5.3GHz Max Power */ +#define SSB_SPROM8_5G_MAXP 0x00FF +#define SSB_SPROM8_5G_ITSSI 0xFF00 +#define SSB_SPROM8_5G_ITSSI_SHIFT 8 +#define SSB_SPROM8_5GHL_MAXP 0x0A /* 5.2GHz and 5.8GHz Max Power */ +#define SSB_SPROM8_5GH_MAXP 0x00FF +#define SSB_SPROM8_5GL_MAXP 0xFF00 +#define SSB_SPROM8_5GL_MAXP_SHIFT 8 +#define SSB_SROM8_5G_PA_0 0x0C /* 5.3GHz power amp settings */ +#define SSB_SROM8_5G_PA_1 0x0E +#define SSB_SROM8_5G_PA_2 0x10 +#define SSB_SROM8_5GL_PA_0 0x12 /* 5.2GHz power amp settings */ +#define SSB_SROM8_5GL_PA_1 0x14 +#define SSB_SROM8_5GL_PA_2 0x16 +#define SSB_SROM8_5GH_PA_0 0x18 /* 5.8GHz power amp settings */ +#define SSB_SROM8_5GH_PA_1 0x1A +#define SSB_SROM8_5GH_PA_2 0x1C + +/* TODO: Make it deprecated */ #define SSB_SPROM8_MAXP_BG 0x00C0 /* Max Power 2GHz in path 1 */ #define SSB_SPROM8_MAXP_BG_MASK 0x00FF /* Mask for Max Power 2GHz */ #define SSB_SPROM8_ITSSI_BG 0xFF00 /* Mask for path 1 itssi_bg */ @@ -473,6 +506,7 @@ #define SSB_SPROM8_PA1HIB0 0x00D8 /* 5.8GHz power amp settings */ #define SSB_SPROM8_PA1HIB1 0x00DA #define SSB_SPROM8_PA1HIB2 0x00DC + #define SSB_SPROM8_CCK2GPO 0x0140 /* CCK power offset */ #define SSB_SPROM8_OFDM2GPO 0x0142 /* 2.4GHz OFDM power offset */ #define SSB_SPROM8_OFDM5GPO 0x0146 /* 5.3GHz OFDM power offset */ -- cgit v1.2.3-70-g09d2 From b35a9aca631ee0cf67cd23098ea9076ca33c3f7b Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 2 Jan 2012 08:41:24 +0100 Subject: bcma: SPROM: add macro for easier extraction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/bcma/sprom.c | 139 ++++++++++++++++++++++++++------------------------- 1 file changed, 71 insertions(+), 68 deletions(-) (limited to 'drivers') diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c index 6f230fb087c..27f62cc2c8a 100644 --- a/drivers/bcma/sprom.c +++ b/drivers/bcma/sprom.c @@ -14,8 +14,6 @@ #include #include -#define SPOFF(offset) ((offset) / sizeof(u16)) - /************************************************** * R/W ops. **************************************************/ @@ -124,6 +122,11 @@ static int bcma_sprom_valid(const u16 *sprom) * SPROM extraction. **************************************************/ +#define SPOFF(offset) ((offset) / sizeof(u16)) + +#define SPEX(_field, _offset, _mask, _shift) \ + bus->sprom._field = ((sprom[SPOFF(_offset)] & (_mask)) >> (_shift)) + static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) { u16 v; @@ -137,72 +140,72 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v); } - bus->sprom.board_rev = sprom[SPOFF(SSB_SPROM8_BOARDREV)]; - - bus->sprom.txpid2g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] & - SSB_SPROM4_TXPID2G0) >> SSB_SPROM4_TXPID2G0_SHIFT; - bus->sprom.txpid2g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] & - SSB_SPROM4_TXPID2G1) >> SSB_SPROM4_TXPID2G1_SHIFT; - bus->sprom.txpid2g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] & - SSB_SPROM4_TXPID2G2) >> SSB_SPROM4_TXPID2G2_SHIFT; - bus->sprom.txpid2g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] & - SSB_SPROM4_TXPID2G3) >> SSB_SPROM4_TXPID2G3_SHIFT; - - bus->sprom.txpid5gl[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] & - SSB_SPROM4_TXPID5GL0) >> SSB_SPROM4_TXPID5GL0_SHIFT; - bus->sprom.txpid5gl[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] & - SSB_SPROM4_TXPID5GL1) >> SSB_SPROM4_TXPID5GL1_SHIFT; - bus->sprom.txpid5gl[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] & - SSB_SPROM4_TXPID5GL2) >> SSB_SPROM4_TXPID5GL2_SHIFT; - bus->sprom.txpid5gl[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] & - SSB_SPROM4_TXPID5GL3) >> SSB_SPROM4_TXPID5GL3_SHIFT; - - bus->sprom.txpid5g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] & - SSB_SPROM4_TXPID5G0) >> SSB_SPROM4_TXPID5G0_SHIFT; - bus->sprom.txpid5g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] & - SSB_SPROM4_TXPID5G1) >> SSB_SPROM4_TXPID5G1_SHIFT; - bus->sprom.txpid5g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] & - SSB_SPROM4_TXPID5G2) >> SSB_SPROM4_TXPID5G2_SHIFT; - bus->sprom.txpid5g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] & - SSB_SPROM4_TXPID5G3) >> SSB_SPROM4_TXPID5G3_SHIFT; - - bus->sprom.txpid5gh[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] & - SSB_SPROM4_TXPID5GH0) >> SSB_SPROM4_TXPID5GH0_SHIFT; - bus->sprom.txpid5gh[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] & - SSB_SPROM4_TXPID5GH1) >> SSB_SPROM4_TXPID5GH1_SHIFT; - bus->sprom.txpid5gh[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] & - SSB_SPROM4_TXPID5GH2) >> SSB_SPROM4_TXPID5GH2_SHIFT; - bus->sprom.txpid5gh[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] & - SSB_SPROM4_TXPID5GH3) >> SSB_SPROM4_TXPID5GH3_SHIFT; - - bus->sprom.boardflags_lo = sprom[SPOFF(SSB_SPROM8_BFLLO)]; - bus->sprom.boardflags_hi = sprom[SPOFF(SSB_SPROM8_BFLHI)]; - bus->sprom.boardflags2_lo = sprom[SPOFF(SSB_SPROM8_BFL2LO)]; - bus->sprom.boardflags2_hi = sprom[SPOFF(SSB_SPROM8_BFL2HI)]; - - bus->sprom.country_code = sprom[SPOFF(SSB_SPROM8_CCODE)]; - - bus->sprom.fem.ghz2.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & - SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT; - bus->sprom.fem.ghz2.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & - SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT; - bus->sprom.fem.ghz2.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & - SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT; - bus->sprom.fem.ghz2.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & - SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT; - bus->sprom.fem.ghz2.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & - SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT; - - bus->sprom.fem.ghz5.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & - SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT; - bus->sprom.fem.ghz5.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & - SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT; - bus->sprom.fem.ghz5.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & - SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT; - bus->sprom.fem.ghz5.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & - SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT; - bus->sprom.fem.ghz5.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & - SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT; + SPEX(board_rev, SSB_SPROM8_BOARDREV, ~0, 0); + + SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G0, + SSB_SPROM4_TXPID2G0_SHIFT); + SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G1, + SSB_SPROM4_TXPID2G1_SHIFT); + SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G2, + SSB_SPROM4_TXPID2G2_SHIFT); + SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G3, + SSB_SPROM4_TXPID2G3_SHIFT); + + SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL0, + SSB_SPROM4_TXPID5GL0_SHIFT); + SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL1, + SSB_SPROM4_TXPID5GL1_SHIFT); + SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL2, + SSB_SPROM4_TXPID5GL2_SHIFT); + SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL3, + SSB_SPROM4_TXPID5GL3_SHIFT); + + SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G0, + SSB_SPROM4_TXPID5G0_SHIFT); + SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G1, + SSB_SPROM4_TXPID5G1_SHIFT); + SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G2, + SSB_SPROM4_TXPID5G2_SHIFT); + SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G3, + SSB_SPROM4_TXPID5G3_SHIFT); + + SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH0, + SSB_SPROM4_TXPID5GH0_SHIFT); + SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH1, + SSB_SPROM4_TXPID5GH1_SHIFT); + SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH2, + SSB_SPROM4_TXPID5GH2_SHIFT); + SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH3, + SSB_SPROM4_TXPID5GH3_SHIFT); + + SPEX(boardflags_lo, SSB_SPROM8_BFLLO, ~0, 0); + SPEX(boardflags_hi, SSB_SPROM8_BFLHI, ~0, 0); + SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, ~0, 0); + SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, ~0, 0); + + SPEX(country_code, SSB_SPROM8_CCODE, ~0, 0); + + SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TSSIPOS, + SSB_SROM8_FEM_TSSIPOS_SHIFT); + SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_EXTPA_GAIN, + SSB_SROM8_FEM_EXTPA_GAIN_SHIFT); + SPEX(fem.ghz2.pdet_range, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_PDET_RANGE, + SSB_SROM8_FEM_PDET_RANGE_SHIFT); + SPEX(fem.ghz2.tr_iso, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TR_ISO, + SSB_SROM8_FEM_TR_ISO_SHIFT); + SPEX(fem.ghz2.antswlut, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_ANTSWLUT, + SSB_SROM8_FEM_ANTSWLUT_SHIFT); + + SPEX(fem.ghz5.tssipos, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TSSIPOS, + SSB_SROM8_FEM_TSSIPOS_SHIFT); + SPEX(fem.ghz5.extpa_gain, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_EXTPA_GAIN, + SSB_SROM8_FEM_EXTPA_GAIN_SHIFT); + SPEX(fem.ghz5.pdet_range, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_PDET_RANGE, + SSB_SROM8_FEM_PDET_RANGE_SHIFT); + SPEX(fem.ghz5.tr_iso, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TR_ISO, + SSB_SROM8_FEM_TR_ISO_SHIFT); + SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_ANTSWLUT, + SSB_SROM8_FEM_ANTSWLUT_SHIFT); } int bcma_sprom_get(struct bcma_bus *bus) -- cgit v1.2.3-70-g09d2 From 507f9a71846a3d25d0e5322754da6b65adceda80 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 2 Jan 2012 08:41:25 +0100 Subject: bcma: SPROM: extract power info for cores MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/bcma/sprom.c | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c index 27f62cc2c8a..cb835f026d9 100644 --- a/drivers/bcma/sprom.c +++ b/drivers/bcma/sprom.c @@ -129,8 +129,14 @@ static int bcma_sprom_valid(const u16 *sprom) static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) { - u16 v; + u16 v, o; int i; + u16 pwr_info_offset[] = { + SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1, + SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3 + }; + BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) != + ARRAY_SIZE(bus->sprom.core_pwr_info)); bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_REV; @@ -185,6 +191,38 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) SPEX(country_code, SSB_SPROM8_CCODE, ~0, 0); + /* Extract cores power info info */ + for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) { + o = pwr_info_offset[i]; + SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI, + SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT); + SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI, + SSB_SPROM8_2G_MAXP, 0); + + SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0); + SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0); + SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0); + + SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI, + SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT); + SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI, + SSB_SPROM8_5G_MAXP, 0); + SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP, + SSB_SPROM8_5GH_MAXP, 0); + SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP, + SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT); + + SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0); + SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0); + SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0); + SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0); + SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0); + SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0); + SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0); + SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0); + SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0); + } + SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TSSIPOS, SSB_SROM8_FEM_TSSIPOS_SHIFT); SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_EXTPA_GAIN, -- cgit v1.2.3-70-g09d2 From 5056635c10151970d87ae256b7f52f056291799e Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 2 Jan 2012 19:31:21 +0100 Subject: b43: add maskset helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/b43.h | 12 +++++++ drivers/net/wireless/b43/main.c | 67 ++++++++++++---------------------------- drivers/net/wireless/b43/phy_n.c | 14 +++------ 3 files changed, 36 insertions(+), 57 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 16e8f805815..835462dc120 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -999,6 +999,12 @@ static inline void b43_write16(struct b43_wldev *dev, u16 offset, u16 value) dev->dev->write16(dev->dev, offset, value); } +static inline void b43_maskset16(struct b43_wldev *dev, u16 offset, u16 mask, + u16 set) +{ + b43_write16(dev, offset, (b43_read16(dev, offset) & mask) | set); +} + static inline u32 b43_read32(struct b43_wldev *dev, u16 offset) { return dev->dev->read32(dev->dev, offset); @@ -1009,6 +1015,12 @@ static inline void b43_write32(struct b43_wldev *dev, u16 offset, u32 value) dev->dev->write32(dev->dev, offset, value); } +static inline void b43_maskset32(struct b43_wldev *dev, u16 offset, u32 mask, + u32 set) +{ + b43_write32(dev, offset, (b43_read32(dev, offset) & mask) | set); +} + static inline void b43_block_read(struct b43_wldev *dev, void *buffer, size_t count, u16 offset, u8 reg_width) { diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index b91f28ef103..268f2db5237 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -578,22 +578,14 @@ void b43_tsf_read(struct b43_wldev *dev, u64 *tsf) static void b43_time_lock(struct b43_wldev *dev) { - u32 macctl; - - macctl = b43_read32(dev, B43_MMIO_MACCTL); - macctl |= B43_MACCTL_TBTTHOLD; - b43_write32(dev, B43_MMIO_MACCTL, macctl); + b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_TBTTHOLD); /* Commit the write */ b43_read32(dev, B43_MMIO_MACCTL); } static void b43_time_unlock(struct b43_wldev *dev) { - u32 macctl; - - macctl = b43_read32(dev, B43_MMIO_MACCTL); - macctl &= ~B43_MACCTL_TBTTHOLD; - b43_write32(dev, B43_MMIO_MACCTL, macctl); + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_TBTTHOLD, 0); /* Commit the write */ b43_read32(dev, B43_MMIO_MACCTL); } @@ -2485,10 +2477,8 @@ static int b43_upload_microcode(struct b43_wldev *dev) b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, B43_IRQ_ALL); /* Start the microcode PSM */ - macctl = b43_read32(dev, B43_MMIO_MACCTL); - macctl &= ~B43_MACCTL_PSM_JMP0; - macctl |= B43_MACCTL_PSM_RUN; - b43_write32(dev, B43_MMIO_MACCTL, macctl); + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_PSM_JMP0, + B43_MACCTL_PSM_RUN); /* Wait for the microcode to load and respond */ i = 0; @@ -2588,10 +2578,9 @@ static int b43_upload_microcode(struct b43_wldev *dev) return 0; error: - macctl = b43_read32(dev, B43_MMIO_MACCTL); - macctl &= ~B43_MACCTL_PSM_RUN; - macctl |= B43_MACCTL_PSM_JMP0; - b43_write32(dev, B43_MMIO_MACCTL, macctl); + /* Stop the microcode PSM. */ + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_PSM_RUN, + B43_MACCTL_PSM_JMP0); return err; } @@ -2706,11 +2695,8 @@ static int b43_gpio_init(struct b43_wldev *dev) struct ssb_device *gpiodev; u32 mask, set; - b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) - & ~B43_MACCTL_GPOUTSMSK); - - b43_write16(dev, B43_MMIO_GPIO_MASK, b43_read16(dev, B43_MMIO_GPIO_MASK) - | 0x000F); + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0); + b43_maskset16(dev, B43_MMIO_GPIO_MASK, ~0, 0xF); mask = 0x0000001F; set = 0x0000000F; @@ -2798,9 +2784,7 @@ void b43_mac_enable(struct b43_wldev *dev) dev->mac_suspended--; B43_WARN_ON(dev->mac_suspended < 0); if (dev->mac_suspended == 0) { - b43_write32(dev, B43_MMIO_MACCTL, - b43_read32(dev, B43_MMIO_MACCTL) - | B43_MACCTL_ENABLED); + b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_ENABLED); b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, B43_IRQ_MAC_SUSPENDED); /* Commit writes */ @@ -2821,9 +2805,7 @@ void b43_mac_suspend(struct b43_wldev *dev) if (dev->mac_suspended == 0) { b43_power_saving_ctl_bits(dev, B43_PS_AWAKE); - b43_write32(dev, B43_MMIO_MACCTL, - b43_read32(dev, B43_MMIO_MACCTL) - & ~B43_MACCTL_ENABLED); + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_ENABLED, 0); /* force pci to flush the write */ b43_read32(dev, B43_MMIO_MACCTL); for (i = 35; i; i--) { @@ -2929,15 +2911,10 @@ static void b43_adjust_opmode(struct b43_wldev *dev) * so always disable it. If we want to implement PMQ, * we need to enable it here (clear DISCPMQ) in AP mode. */ - if (0 /* ctl & B43_MACCTL_AP */) { - b43_write32(dev, B43_MMIO_MACCTL, - b43_read32(dev, B43_MMIO_MACCTL) - & ~B43_MACCTL_DISCPMQ); - } else { - b43_write32(dev, B43_MMIO_MACCTL, - b43_read32(dev, B43_MMIO_MACCTL) - | B43_MACCTL_DISCPMQ); - } + if (0 /* ctl & B43_MACCTL_AP */) + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_DISCPMQ, 0); + else + b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_DISCPMQ); } static void b43_rate_memory_write(struct b43_wldev *dev, u16 rate, int is_ofdm) @@ -3081,10 +3058,8 @@ static int b43_chip_init(struct b43_wldev *dev) if (dev->dev->core_rev < 5) b43_write32(dev, 0x010C, 0x01000000); - b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) - & ~B43_MACCTL_INFRA); - b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) - | B43_MACCTL_INFRA); + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_INFRA, 0); + b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_INFRA); /* Probe Response Timeout value */ /* FIXME: Default to 0, has to be set by ioctl probably... :-/ */ @@ -4562,8 +4537,6 @@ static void b43_set_pretbtt(struct b43_wldev *dev) /* Locking: wl->mutex */ static void b43_wireless_core_exit(struct b43_wldev *dev) { - u32 macctl; - B43_WARN_ON(dev && b43_status(dev) > B43_STAT_INITIALIZED); if (!dev || b43_status(dev) != B43_STAT_INITIALIZED) return; @@ -4574,10 +4547,8 @@ static void b43_wireless_core_exit(struct b43_wldev *dev) b43_set_status(dev, B43_STAT_UNINIT); /* Stop the microcode PSM. */ - macctl = b43_read32(dev, B43_MMIO_MACCTL); - macctl &= ~B43_MACCTL_PSM_RUN; - macctl |= B43_MACCTL_PSM_JMP0; - b43_write32(dev, B43_MMIO_MACCTL, macctl); + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_PSM_RUN, + B43_MACCTL_PSM_JMP0); b43_dma_free(dev); b43_pio_free(dev); diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index bf5a4385535..9530f12c028 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -3968,13 +3968,10 @@ static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init) #endif } - b43_write32(dev, B43_MMIO_MACCTL, - b43_read32(dev, B43_MMIO_MACCTL) & - ~B43_MACCTL_GPOUTSMSK); - b43_write16(dev, B43_MMIO_GPIO_MASK, - b43_read16(dev, B43_MMIO_GPIO_MASK) | 0xFC00); - b43_write16(dev, B43_MMIO_GPIO_CONTROL, - b43_read16(dev, B43_MMIO_GPIO_CONTROL) & ~0xFC00); + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0); + b43_maskset16(dev, B43_MMIO_GPIO_MASK, ~0, 0xFC00); + b43_maskset16(dev, B43_MMIO_GPIO_CONTROL, (~0xFC00 & 0xFFFF), + 0); if (init) { b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8); @@ -4530,8 +4527,7 @@ static void b43_nphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask, { check_phyreg(dev, reg); b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); - b43_write16(dev, B43_MMIO_PHY_DATA, - (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set); + b43_maskset16(dev, B43_MMIO_PHY_DATA, mask, set); } static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg) -- cgit v1.2.3-70-g09d2 From d3fd8bf77affcbf80bb8297d177e17ad0b61abc8 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 2 Jan 2012 19:31:22 +0100 Subject: b43: N-PHY: implement TX power control setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 217 ++++++++++++++++++++++++++++++++++++++- drivers/net/wireless/b43/phy_n.h | 1 + 2 files changed, 217 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 9530f12c028..fbbdbdad101 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -2420,6 +2420,221 @@ static void b43_nphy_tx_power_ctl_idle_tssi(struct b43_wldev *dev) nphy->pwr_ctl_info[1].idle_tssi_2g = (tmp >> 8) & 0xFF; } +/* http://bcm-v4.sipsolutions.net/PHY/N/TxPwrLimitToTbl */ +static void b43_nphy_tx_prepare_adjusted_power_table(struct b43_wldev *dev) +{ + struct b43_phy_n *nphy = dev->phy.n; + + u8 idx, delta; + u8 i, stf_mode; + + for (i = 0; i < 4; i++) + nphy->adj_pwr_tbl[i] = nphy->tx_power_offset[i]; + + for (stf_mode = 0; stf_mode < 4; stf_mode++) { + delta = 0; + switch (stf_mode) { + case 0: + if (dev->phy.is_40mhz && dev->phy.rev >= 5) { + idx = 68; + } else { + delta = 1; + idx = dev->phy.is_40mhz ? 52 : 4; + } + break; + case 1: + idx = dev->phy.is_40mhz ? 76 : 28; + break; + case 2: + idx = dev->phy.is_40mhz ? 84 : 36; + break; + case 3: + idx = dev->phy.is_40mhz ? 92 : 44; + break; + } + + for (i = 0; i < 20; i++) { + nphy->adj_pwr_tbl[4 + 4 * i + stf_mode] = + nphy->tx_power_offset[idx]; + if (i == 0) + idx += delta; + if (i == 14) + idx += 1 - delta; + if (i == 3 || i == 4 || i == 7 || i == 8 || i == 11 || + i == 13) + idx += 1; + } + } +} + +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlSetup */ +static void b43_nphy_tx_power_ctl_setup(struct b43_wldev *dev) +{ + struct b43_phy_n *nphy = dev->phy.n; + struct ssb_sprom *sprom = dev->dev->bus_sprom; + + s16 a1[2], b0[2], b1[2]; + u8 idle[2]; + s8 target[2]; + s32 num, den, pwr; + u32 regval[64]; + + u16 freq = dev->phy.channel_freq; + u16 tmp; + u16 r; /* routing */ + u8 i, c; + + if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) { + b43_maskset32(dev, B43_MMIO_MACCTL, ~0, 0x200000); + b43_read32(dev, B43_MMIO_MACCTL); + udelay(1); + } + + if (nphy->hang_avoid) + b43_nphy_stay_in_carrier_search(dev, true); + + b43_phy_set(dev, B43_NPHY_TSSIMODE, B43_NPHY_TSSIMODE_EN); + if (dev->phy.rev >= 3) + b43_phy_mask(dev, B43_NPHY_TXPCTL_CMD, + ~B43_NPHY_TXPCTL_CMD_PCTLEN & 0xFFFF); + else + b43_phy_set(dev, B43_NPHY_TXPCTL_CMD, + B43_NPHY_TXPCTL_CMD_PCTLEN); + + if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) + b43_maskset32(dev, B43_MMIO_MACCTL, ~0x200000, 0); + + if (sprom->revision < 4) { + idle[0] = nphy->pwr_ctl_info[0].idle_tssi_2g; + idle[1] = nphy->pwr_ctl_info[1].idle_tssi_2g; + target[0] = target[1] = 52; + a1[0] = a1[1] = -424; + b0[0] = b0[1] = 5612; + b1[0] = b1[1] = -1393; + } else { + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { + for (c = 0; c < 2; c++) { + idle[c] = nphy->pwr_ctl_info[c].idle_tssi_2g; + target[c] = sprom->core_pwr_info[c].maxpwr_2g; + a1[c] = sprom->core_pwr_info[c].pa_2g[0]; + b0[c] = sprom->core_pwr_info[c].pa_2g[1]; + b1[c] = sprom->core_pwr_info[c].pa_2g[2]; + } + } else if (freq >= 4900 && freq < 5100) { + for (c = 0; c < 2; c++) { + idle[c] = nphy->pwr_ctl_info[c].idle_tssi_5g; + target[c] = sprom->core_pwr_info[c].maxpwr_5gl; + a1[c] = sprom->core_pwr_info[c].pa_5gl[0]; + b0[c] = sprom->core_pwr_info[c].pa_5gl[1]; + b1[c] = sprom->core_pwr_info[c].pa_5gl[2]; + } + } else if (freq >= 5100 && freq < 5500) { + for (c = 0; c < 2; c++) { + idle[c] = nphy->pwr_ctl_info[c].idle_tssi_5g; + target[c] = sprom->core_pwr_info[c].maxpwr_5g; + a1[c] = sprom->core_pwr_info[c].pa_5g[0]; + b0[c] = sprom->core_pwr_info[c].pa_5g[1]; + b1[c] = sprom->core_pwr_info[c].pa_5g[2]; + } + } else if (freq >= 5500) { + for (c = 0; c < 2; c++) { + idle[c] = nphy->pwr_ctl_info[c].idle_tssi_5g; + target[c] = sprom->core_pwr_info[c].maxpwr_5gh; + a1[c] = sprom->core_pwr_info[c].pa_5gh[0]; + b0[c] = sprom->core_pwr_info[c].pa_5gh[1]; + b1[c] = sprom->core_pwr_info[c].pa_5gh[2]; + } + } else { + idle[0] = nphy->pwr_ctl_info[0].idle_tssi_5g; + idle[1] = nphy->pwr_ctl_info[1].idle_tssi_5g; + target[0] = target[1] = 52; + a1[0] = a1[1] = -424; + b0[0] = b0[1] = 5612; + b1[0] = b1[1] = -1393; + } + } + /* target[0] = target[1] = nphy->tx_power_max; */ + + if (dev->phy.rev >= 3) { + if (sprom->fem.ghz2.tssipos) + b43_phy_set(dev, B43_NPHY_TXPCTL_ITSSI, 0x4000); + if (dev->phy.rev >= 7) { + for (c = 0; c < 2; c++) { + r = c ? 0x190 : 0x170; + if (b43_nphy_ipa(dev)) + b43_radio_write(dev, r + 0x9, (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) ? 0xE : 0xC); + } + } else { + if (b43_nphy_ipa(dev)) { + tmp = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ? 0xC : 0xE; + b43_radio_write(dev, + B2056_TX0 | B2056_TX_TX_SSI_MUX, tmp); + b43_radio_write(dev, + B2056_TX1 | B2056_TX_TX_SSI_MUX, tmp); + } else { + b43_radio_write(dev, + B2056_TX0 | B2056_TX_TX_SSI_MUX, 0x11); + b43_radio_write(dev, + B2056_TX1 | B2056_TX_TX_SSI_MUX, 0x11); + } + } + } + + if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) { + b43_maskset32(dev, B43_MMIO_MACCTL, ~0, 0x200000); + b43_read32(dev, B43_MMIO_MACCTL); + udelay(1); + } + + if (dev->phy.rev >= 7) { + b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD, + ~B43_NPHY_TXPCTL_CMD_INIT, 0x19); + b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT, + ~B43_NPHY_TXPCTL_INIT_PIDXI1, 0x19); + } else { + b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD, + ~B43_NPHY_TXPCTL_CMD_INIT, 0x40); + if (dev->phy.rev > 1) + b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT, + ~B43_NPHY_TXPCTL_INIT_PIDXI1, 0x40); + } + + if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) + b43_maskset32(dev, B43_MMIO_MACCTL, ~0x200000, 0); + + b43_phy_write(dev, B43_NPHY_TXPCTL_N, + 0xF0 << B43_NPHY_TXPCTL_N_TSSID_SHIFT | + 3 << B43_NPHY_TXPCTL_N_NPTIL2_SHIFT); + b43_phy_write(dev, B43_NPHY_TXPCTL_ITSSI, + idle[0] << B43_NPHY_TXPCTL_ITSSI_0_SHIFT | + idle[1] << B43_NPHY_TXPCTL_ITSSI_1_SHIFT | + B43_NPHY_TXPCTL_ITSSI_BINF); + b43_phy_write(dev, B43_NPHY_TXPCTL_TPWR, + target[0] << B43_NPHY_TXPCTL_TPWR_0_SHIFT | + target[1] << B43_NPHY_TXPCTL_TPWR_1_SHIFT); + + for (c = 0; c < 2; c++) { + for (i = 0; i < 64; i++) { + num = 8 * (16 * b0[c] + b1[c] * i); + den = 32768 + a1[c] * i; + pwr = max((4 * num + den / 2) / den, -8); + if (dev->phy.rev < 3 && (i <= (31 - idle[c] + 1))) + pwr = max(pwr, target[c] + 1); + regval[i] = pwr; + } + b43_ntab_write_bulk(dev, B43_NTAB32(26 + c, 0), 64, regval); + } + + b43_nphy_tx_prepare_adjusted_power_table(dev); + /* + b43_ntab_write_bulk(dev, B43_NTAB16(26, 64), 84, nphy->adj_pwr_tbl); + b43_ntab_write_bulk(dev, B43_NTAB16(27, 64), 84, nphy->adj_pwr_tbl); + */ + + if (nphy->hang_avoid) + b43_nphy_stay_in_carrier_search(dev, false); +} + static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev) { struct b43_phy *phy = &dev->phy; @@ -4107,7 +4322,7 @@ int b43_phy_initn(struct b43_wldev *dev) b43_nphy_tx_power_ctrl(dev, false); b43_nphy_tx_power_fix(dev); b43_nphy_tx_power_ctl_idle_tssi(dev); - /* TODO N PHY TX Power Control Setup */ + b43_nphy_tx_power_ctl_setup(dev); b43_nphy_tx_gain_table_upload(dev); if (nphy->phyrxchain != 3) diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h index 5de8f74cc02..fd12b386fea 100644 --- a/drivers/net/wireless/b43/phy_n.h +++ b/drivers/net/wireless/b43/phy_n.h @@ -798,6 +798,7 @@ struct b43_phy_n { bool txpwrctrl; bool pwg_gain_5ghz; u8 tx_pwr_idx[2]; + s8 tx_power_offset[101]; u16 adj_pwr_tbl[84]; u16 txcal_bbmult; u16 txiqlocal_bestc[11]; -- cgit v1.2.3-70-g09d2 From aeab57517cb7995626a60e8d1817fe95e5c07f42 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 3 Jan 2012 22:49:17 +0100 Subject: b43: N-PHY: add helper for getting gain table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also move the code to tables file. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 81 +++------------------------------- drivers/net/wireless/b43/tables_nphy.c | 65 +++++++++++++++++++++++---- drivers/net/wireless/b43/tables_nphy.h | 12 +---- 3 files changed, 64 insertions(+), 94 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index fbbdbdad101..d5d02aed9db 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -85,24 +85,6 @@ static inline bool b43_nphy_ipa(struct b43_wldev *dev) (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ)); } -/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */ -static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev) -{ - if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { - if (dev->phy.rev >= 6) { - if (dev->dev->chip_id == 47162) - return txpwrctrl_tx_gain_ipa_rev5; - return txpwrctrl_tx_gain_ipa_rev6; - } else if (dev->phy.rev >= 5) { - return txpwrctrl_tx_gain_ipa_rev5; - } else { - return txpwrctrl_tx_gain_ipa; - } - } else { - return txpwrctrl_tx_gain_ipa_5g; - } -} - /************************************************** * RF (just without b43_nphy_rf_control_intc_override) **************************************************/ @@ -2229,27 +2211,12 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev) */ for (i = 0; i < 2; i++) { - if (dev->phy.rev >= 3) { - if (b43_nphy_ipa(dev)) { - txgain = *(b43_nphy_get_ipa_gain_table(dev) + - txpi[i]); - } else if (b43_current_band(dev->wl) == - IEEE80211_BAND_5GHZ) { - /* FIXME: use 5GHz tables */ - txgain = - b43_ntab_tx_gain_rev3plus_2ghz[txpi[i]]; - } else { - if (dev->phy.rev >= 5 && - sprom->fem.ghz5.extpa_gain == 3) - ; /* FIXME: 5GHz_txgain_HiPwrEPA */ - txgain = - b43_ntab_tx_gain_rev3plus_2ghz[txpi[i]]; - } + txgain = *(b43_nphy_get_tx_gain_table(dev) + txpi[i]); + + if (dev->phy.rev >= 3) radio_gain = (txgain >> 16) & 0x1FFFF; - } else { - txgain = b43_ntab_tx_gain_rev0_1_2[txpi[i]]; + else radio_gain = (txgain >> 16) & 0x1FFF; - } if (dev->phy.rev >= 7) dac_gain = (txgain >> 8) & 0x7; @@ -2647,24 +2614,7 @@ static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev) int i; #endif - if (phy->rev >= 3) { - if (b43_nphy_ipa(dev)) { - table = b43_nphy_get_ipa_gain_table(dev); - } else { - if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { - if (phy->rev == 3) - table = b43_ntab_tx_gain_rev3_5ghz; - if (phy->rev == 4) - table = b43_ntab_tx_gain_rev4_5ghz; - else - table = b43_ntab_tx_gain_rev5plus_5ghz; - } else { - table = b43_ntab_tx_gain_rev3plus_2ghz; - } - } - } else { - table = b43_ntab_tx_gain_rev0_1_2; - } + table = b43_nphy_get_tx_gain_table(dev); b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128, table); b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128, table); @@ -3354,32 +3304,13 @@ static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev) B43_NPHY_TXPCTL_STAT_BIDX_SHIFT; for (i = 0; i < 2; ++i) { + table = b43_nphy_get_tx_gain_table(dev); if (dev->phy.rev >= 3) { - enum ieee80211_band band = - b43_current_band(dev->wl); - - if (b43_nphy_ipa(dev)) { - table = b43_nphy_get_ipa_gain_table(dev); - } else { - if (band == IEEE80211_BAND_5GHZ) { - if (dev->phy.rev == 3) - table = b43_ntab_tx_gain_rev3_5ghz; - else if (dev->phy.rev == 4) - table = b43_ntab_tx_gain_rev4_5ghz; - else - table = b43_ntab_tx_gain_rev5plus_5ghz; - } else { - table = b43_ntab_tx_gain_rev3plus_2ghz; - } - } - target.ipa[i] = (table[index[i]] >> 16) & 0xF; target.pad[i] = (table[index[i]] >> 20) & 0xF; target.pga[i] = (table[index[i]] >> 24) & 0xF; target.txgm[i] = (table[index[i]] >> 28) & 0xF; } else { - table = b43_ntab_tx_gain_rev0_1_2; - target.ipa[i] = (table[index[i]] >> 16) & 0x3; target.pad[i] = (table[index[i]] >> 18) & 0x3; target.pga[i] = (table[index[i]] >> 20) & 0x7; diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index f7def13524d..afcdca638cc 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c @@ -2214,7 +2214,7 @@ static const u16 b43_ntab_antswctl2g_r3[4][32] = { }; /* TX gain tables */ -const u32 b43_ntab_tx_gain_rev0_1_2[] = { +static const u32 b43_ntab_tx_gain_rev0_1_2[] = { 0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42, 0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44, 0x03c82a42, 0x03c82944, 0x03c82942, 0x03c82844, @@ -2249,7 +2249,7 @@ const u32 b43_ntab_tx_gain_rev0_1_2[] = { 0x03801442, 0x03801344, 0x03801342, 0x00002b00, }; -const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = { +static const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = { 0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e, 0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037, 0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e, @@ -2284,7 +2284,7 @@ const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = { 0x1041003c, 0x1041003b, 0x10410039, 0x10410037, }; -const u32 b43_ntab_tx_gain_rev3_5ghz[] = { +static const u32 b43_ntab_tx_gain_rev3_5ghz[] = { 0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e, 0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037, 0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e, @@ -2319,7 +2319,7 @@ const u32 b43_ntab_tx_gain_rev3_5ghz[] = { 0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037, }; -const u32 b43_ntab_tx_gain_rev4_5ghz[] = { +static const u32 b43_ntab_tx_gain_rev4_5ghz[] = { 0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e, 0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037, 0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e, @@ -2354,7 +2354,7 @@ const u32 b43_ntab_tx_gain_rev4_5ghz[] = { 0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034, }; -const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = { +static const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = { 0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044, 0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c, 0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e, @@ -2389,7 +2389,7 @@ const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = { 0x0062003b, 0x00620039, 0x00620037, 0x00620035, }; -const u32 txpwrctrl_tx_gain_ipa[] = { +static const u32 txpwrctrl_tx_gain_ipa[] = { 0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029, 0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025, 0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029, @@ -2424,7 +2424,7 @@ const u32 txpwrctrl_tx_gain_ipa[] = { 0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025, }; -const u32 txpwrctrl_tx_gain_ipa_rev5[] = { +static const u32 txpwrctrl_tx_gain_ipa_rev5[] = { 0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029, 0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025, 0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029, @@ -2459,7 +2459,7 @@ const u32 txpwrctrl_tx_gain_ipa_rev5[] = { 0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025, }; -const u32 txpwrctrl_tx_gain_ipa_rev6[] = { +static const u32 txpwrctrl_tx_gain_ipa_rev6[] = { 0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029, 0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025, 0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029, @@ -2494,7 +2494,7 @@ const u32 txpwrctrl_tx_gain_ipa_rev6[] = { 0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025, }; -const u32 txpwrctrl_tx_gain_ipa_5g[] = { +static const u32 txpwrctrl_tx_gain_ipa_5g[] = { 0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031, 0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b, 0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027, @@ -3126,6 +3126,53 @@ void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev) B43_WARN_ON(1); } +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */ +static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev) +{ + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { + if (dev->phy.rev >= 6) { + if (dev->dev->chip_id == 47162) + return txpwrctrl_tx_gain_ipa_rev5; + return txpwrctrl_tx_gain_ipa_rev6; + } else if (dev->phy.rev >= 5) { + return txpwrctrl_tx_gain_ipa_rev5; + } else { + return txpwrctrl_tx_gain_ipa; + } + } else { + return txpwrctrl_tx_gain_ipa_5g; + } +} + +const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev) +{ + enum ieee80211_band band = b43_current_band(dev->wl); + struct ssb_sprom *sprom = dev->dev->bus_sprom; + + if (dev->phy.rev < 3) + return b43_ntab_tx_gain_rev0_1_2; + + /* rev 3+ */ + if ((dev->phy.n->ipa2g_on && band == IEEE80211_BAND_2GHZ) || + (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ)) { + return b43_nphy_get_ipa_gain_table(dev); + } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { + if (dev->phy.rev == 3) + return b43_ntab_tx_gain_rev3_5ghz; + if (dev->phy.rev == 4) + return sprom->fem.ghz5.extpa_gain == 3 ? + b43_ntab_tx_gain_rev4_5ghz : + b43_ntab_tx_gain_rev4_5ghz; /* FIXME */ + else + return b43_ntab_tx_gain_rev5plus_5ghz; + } else { + if (dev->phy.rev >= 5 && sprom->fem.ghz5.extpa_gain == 3) + return b43_ntab_tx_gain_rev3plus_2ghz; /* FIXME */ + else + return b43_ntab_tx_gain_rev3plus_2ghz; + } +} + struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent( struct b43_wldev *dev, bool ghz5, bool ext_lna) { diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h index 97038c48193..2a9d5f14af9 100644 --- a/drivers/net/wireless/b43/tables_nphy.h +++ b/drivers/net/wireless/b43/tables_nphy.h @@ -177,16 +177,8 @@ void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset, void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev); void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev); -extern const u32 b43_ntab_tx_gain_rev0_1_2[]; -extern const u32 b43_ntab_tx_gain_rev3plus_2ghz[]; -extern const u32 b43_ntab_tx_gain_rev3_5ghz[]; -extern const u32 b43_ntab_tx_gain_rev4_5ghz[]; -extern const u32 b43_ntab_tx_gain_rev5plus_5ghz[]; - -extern const u32 txpwrctrl_tx_gain_ipa[]; -extern const u32 txpwrctrl_tx_gain_ipa_rev5[]; -extern const u32 txpwrctrl_tx_gain_ipa_rev6[]; -extern const u32 txpwrctrl_tx_gain_ipa_5g[]; +const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev); + extern const u16 tbl_iqcal_gainparams[2][9][8]; extern const struct nphy_txiqcal_ladder ladder_lo[]; extern const struct nphy_txiqcal_ladder ladder_iq[]; -- cgit v1.2.3-70-g09d2 From 603431e9e2cb158817c8403e100bb495755a2395 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 3 Jan 2012 22:49:18 +0100 Subject: b43: N-PHY: fix typos in RF control MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 6 +++--- drivers/net/wireless/b43/tables_nphy.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index d5d02aed9db..f1a856874a9 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -211,7 +211,7 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, reg = (i == 0) ? B43_NPHY_RFCTL_INTC1 : B43_NPHY_RFCTL_INTC2; - b43_phy_mask(dev, reg, 0xFBFF); + b43_phy_set(dev, reg, 0x400); switch (field) { case 0: @@ -227,7 +227,7 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, b43_phy_set(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_START); for (j = 0; j < 100; j++) { - if (b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_START) { + if (!(b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_START)) { j = 0; break; } @@ -246,7 +246,7 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, b43_phy_set(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_RXTX); for (j = 0; j < 100; j++) { - if (b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_RXTX) { + if (!(b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_RXTX)) { j = 0; break; } diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index afcdca638cc..8d96454081a 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c @@ -2739,11 +2739,11 @@ const struct nphy_rf_control_override_rev3 tbl_rf_control_override_rev3[] = { { 0x0001, 0, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0002 (fls 2) */ { 0x0002, 1, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0004 (fls 3) */ { 0x0004, 2, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0008 (fls 4) */ - { 0x0016, 4, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0010 (fls 5) */ + { 0x0010, 4, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0010 (fls 5) */ { 0x0020, 5, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0020 (fls 6) */ { 0x0040, 6, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0040 (fls 7) */ - { 0x0080, 6, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0080 (fls 8) */ - { 0x0100, 7, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0100 (fls 9) */ + { 0x0080, 7, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0080 (fls 8) */ + { 0x0100, 8, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0100 (fls 9) */ { 0x0007, 0, 0xE7, 0xF8, 0xEC, 0xFA }, /* field == 0x0200 (fls 10) */ { 0x0070, 4, 0xE7, 0xF8, 0xEC, 0xFA }, /* field == 0x0400 (fls 11) */ { 0xE000, 13, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0800 (fls 12) */ -- cgit v1.2.3-70-g09d2 From 34c5cf205ec27e170b7061f43cf6390486be9a78 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 3 Jan 2012 22:49:19 +0100 Subject: b43: N-PHY: upload PAPD PGA gain delta table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 11 +++++------ drivers/net/wireless/b43/tables_nphy.c | 5 +++++ drivers/net/wireless/b43/tables_nphy.h | 2 ++ 3 files changed, 12 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index f1a856874a9..f6ac18139b1 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -2607,12 +2607,9 @@ static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev) struct b43_phy *phy = &dev->phy; const u32 *table = NULL; -#if 0 - TODO: b43_ntab_papd_pga_gain_delta_ipa_2* u32 rfpwr_offset; u8 pga_gain; int i; -#endif table = b43_nphy_get_tx_gain_table(dev); b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128, table); @@ -2621,19 +2618,21 @@ static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev) if (phy->rev >= 3) { #if 0 nphy->gmval = (table[0] >> 16) & 0x7000; +#endif for (i = 0; i < 128; i++) { pga_gain = (table[i] >> 24) & 0xF; if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) - rfpwr_offset = b43_ntab_papd_pga_gain_delta_ipa_2g[pga_gain]; + rfpwr_offset = + b43_ntab_papd_pga_gain_delta_ipa_2g[pga_gain]; else - rfpwr_offset = b43_ntab_papd_pga_gain_delta_ipa_5g[pga_gain]; + rfpwr_offset = + 0; /* FIXME */ b43_ntab_write(dev, B43_NTAB32(26, 576 + i), rfpwr_offset); b43_ntab_write(dev, B43_NTAB32(27, 576 + i), rfpwr_offset); } -#endif } } diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index 8d96454081a..f0d8377429c 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c @@ -2529,6 +2529,11 @@ static const u32 txpwrctrl_tx_gain_ipa_5g[] = { 0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f, }; +const s8 b43_ntab_papd_pga_gain_delta_ipa_2g[] = { + -114, -108, -98, -91, -84, -78, -70, -62, + -54, -46, -39, -31, -23, -15, -8, 0 +}; + const u16 tbl_iqcal_gainparams[2][9][8] = { { { 0x000, 0, 0, 2, 0x69, 0x69, 0x69, 0x69 }, diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h index 2a9d5f14af9..f348953c023 100644 --- a/drivers/net/wireless/b43/tables_nphy.h +++ b/drivers/net/wireless/b43/tables_nphy.h @@ -179,6 +179,8 @@ void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev); const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev); +extern const s8 b43_ntab_papd_pga_gain_delta_ipa_2g[]; + extern const u16 tbl_iqcal_gainparams[2][9][8]; extern const struct nphy_txiqcal_ladder ladder_lo[]; extern const struct nphy_txiqcal_ladder ladder_iq[]; -- cgit v1.2.3-70-g09d2 From 3eb1fa7e0021bc03be1bf7f68b1913d959e29512 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 4 Jan 2012 14:52:51 -0800 Subject: brcm80211: make ethtool_ops const All usage of ethtool_ops should be const; also add comma at end of initializer list. Signed-off-by: Stephen Hemminger Acked-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index eb9eb766ac2..c3980c50a99 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -590,8 +590,8 @@ static void brcmf_ethtool_get_drvinfo(struct net_device *ndev, sprintf(info->bus_info, "%s", dev_name(drvr->dev)); } -static struct ethtool_ops brcmf_ethtool_ops = { - .get_drvinfo = brcmf_ethtool_get_drvinfo +static const struct ethtool_ops brcmf_ethtool_ops = { + .get_drvinfo = brcmf_ethtool_get_drvinfo, }; static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr) -- cgit v1.2.3-70-g09d2 From e0c9a0219a8f542e3946fe972a68aacf8c3f906c Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 5 Jan 2012 01:05:30 +0100 Subject: b43: N-PHY: implement RSSI calibration for rev3+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 193 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 187 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index f6ac18139b1..945aa5267d0 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -85,6 +85,13 @@ static inline bool b43_nphy_ipa(struct b43_wldev *dev) (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ)); } +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCoreGetState */ +static u8 b43_nphy_get_rx_core_state(struct b43_wldev *dev) +{ + return (b43_phy_read(dev, B43_NPHY_RFSEQCA) & B43_NPHY_RFSEQCA_RXEN) >> + B43_NPHY_RFSEQCA_RXEN_SHIFT; +} + /************************************************** * RF (just without b43_nphy_rf_control_intc_override) **************************************************/ @@ -1290,6 +1297,186 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, return out; } +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */ +static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev) +{ + struct b43_phy_n *nphy = dev->phy.n; + + u16 saved_regs_phy_rfctl[2]; + u16 saved_regs_phy[13]; + u16 regs_to_store[] = { + B43_NPHY_AFECTL_OVER1, B43_NPHY_AFECTL_OVER, + B43_NPHY_AFECTL_C1, B43_NPHY_AFECTL_C2, + B43_NPHY_TXF_40CO_B1S1, B43_NPHY_RFCTL_OVER, + B43_NPHY_TXF_40CO_B1S0, B43_NPHY_TXF_40CO_B32S1, + B43_NPHY_RFCTL_CMD, + B43_NPHY_RFCTL_LUT_TRSW_UP1, B43_NPHY_RFCTL_LUT_TRSW_UP2, + B43_NPHY_RFCTL_RSSIO1, B43_NPHY_RFCTL_RSSIO2 + }; + + u16 class; + + u16 clip_state[2]; + u16 clip_off[2] = { 0xFFFF, 0xFFFF }; + + u8 vcm_final = 0; + s8 offset[4]; + s32 results[8][4] = { }; + s32 results_min[4] = { }; + s32 poll_results[4] = { }; + + u16 *rssical_radio_regs = NULL; + u16 *rssical_phy_regs = NULL; + + u16 r; /* routing */ + u8 rx_core_state; + u8 core, i, j; + + class = b43_nphy_classifier(dev, 0, 0); + b43_nphy_classifier(dev, 7, 4); + b43_nphy_read_clip_detection(dev, clip_state); + b43_nphy_write_clip_detection(dev, clip_off); + + saved_regs_phy_rfctl[0] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1); + saved_regs_phy_rfctl[1] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2); + for (i = 0; i < ARRAY_SIZE(regs_to_store); i++) + saved_regs_phy[i] = b43_phy_read(dev, regs_to_store[i]); + + b43_nphy_rf_control_intc_override(dev, 0, 0, 7); + b43_nphy_rf_control_intc_override(dev, 1, 1, 7); + b43_nphy_rf_control_override(dev, 0x1, 0, 0, false); + b43_nphy_rf_control_override(dev, 0x2, 1, 0, false); + b43_nphy_rf_control_override(dev, 0x80, 1, 0, false); + b43_nphy_rf_control_override(dev, 0x40, 1, 0, false); + + if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { + b43_nphy_rf_control_override(dev, 0x20, 0, 0, false); + b43_nphy_rf_control_override(dev, 0x10, 1, 0, false); + } else { + b43_nphy_rf_control_override(dev, 0x10, 0, 0, false); + b43_nphy_rf_control_override(dev, 0x20, 1, 0, false); + } + + rx_core_state = b43_nphy_get_rx_core_state(dev); + for (core = 0; core < 2; core++) { + if (!(rx_core_state & (1 << core))) + continue; + r = core ? B2056_RX1 : B2056_RX0; + b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 0, 2); + b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 1, 2); + for (i = 0; i < 8; i++) { + b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC, 0xE3, + i << 2); + b43_nphy_poll_rssi(dev, 2, results[i], 8); + } + for (i = 0; i < 4; i++) { + s32 curr; + s32 mind = 40; + s32 minpoll = 249; + u8 minvcm = 0; + if (2 * core != i) + continue; + for (j = 0; j < 8; j++) { + curr = results[j][i] * results[j][i] + + results[j][i + 1] * results[j][i]; + if (curr < mind) { + mind = curr; + minvcm = j; + } + if (results[j][i] < minpoll) + minpoll = results[j][i]; + } + vcm_final = minvcm; + results_min[i] = minpoll; + } + b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC, 0xE3, + vcm_final << 2); + for (i = 0; i < 4; i++) { + if (core != i / 2) + continue; + offset[i] = -results[vcm_final][i]; + if (offset[i] < 0) + offset[i] = -((abs(offset[i]) + 4) / 8); + else + offset[i] = (offset[i] + 4) / 8; + if (results_min[i] == 248) + offset[i] = -32; + b43_nphy_scale_offset_rssi(dev, 0, offset[i], + (i / 2 == 0) ? 1 : 2, + (i % 2 == 0) ? 0 : 1, + 2); + } + } + for (core = 0; core < 2; core++) { + if (!(rx_core_state & (1 << core))) + continue; + for (i = 0; i < 2; i++) { + b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 0, i); + b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 1, i); + b43_nphy_poll_rssi(dev, i, poll_results, 8); + for (j = 0; j < 4; j++) { + if (j / 2 == core) + offset[j] = 232 - poll_results[j]; + if (offset[j] < 0) + offset[j] = -(abs(offset[j] + 4) / 8); + else + offset[j] = (offset[j] + 4) / 8; + b43_nphy_scale_offset_rssi(dev, 0, + offset[2 * core], core + 1, j % 2, i); + } + } + } + + b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, saved_regs_phy_rfctl[0]); + b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, saved_regs_phy_rfctl[1]); + + b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); + + b43_phy_set(dev, B43_NPHY_TXF_40CO_B1S1, 0x1); + b43_phy_set(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_START); + b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S1, ~0x1); + + b43_phy_set(dev, B43_NPHY_RFCTL_OVER, 0x1); + b43_phy_set(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_RXTX); + b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S1, ~0x1); + + for (i = 0; i < ARRAY_SIZE(regs_to_store); i++) + b43_phy_write(dev, regs_to_store[i], saved_regs_phy[i]); + + /* Store for future configuration */ + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { + rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G; + rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G; + } else { + rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G; + rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G; + } + rssical_radio_regs[0] = b43_radio_read(dev, 0x602B); + rssical_radio_regs[0] = b43_radio_read(dev, 0x702B); + rssical_phy_regs[0] = b43_phy_read(dev, B43_NPHY_RSSIMC_0I_RSSI_Z); + rssical_phy_regs[1] = b43_phy_read(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z); + rssical_phy_regs[2] = b43_phy_read(dev, B43_NPHY_RSSIMC_1I_RSSI_Z); + rssical_phy_regs[3] = b43_phy_read(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z); + rssical_phy_regs[4] = b43_phy_read(dev, B43_NPHY_RSSIMC_0I_RSSI_X); + rssical_phy_regs[5] = b43_phy_read(dev, B43_NPHY_RSSIMC_0Q_RSSI_X); + rssical_phy_regs[6] = b43_phy_read(dev, B43_NPHY_RSSIMC_1I_RSSI_X); + rssical_phy_regs[7] = b43_phy_read(dev, B43_NPHY_RSSIMC_1Q_RSSI_X); + rssical_phy_regs[8] = b43_phy_read(dev, B43_NPHY_RSSIMC_0I_RSSI_Y); + rssical_phy_regs[9] = b43_phy_read(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y); + rssical_phy_regs[10] = b43_phy_read(dev, B43_NPHY_RSSIMC_1I_RSSI_Y); + rssical_phy_regs[11] = b43_phy_read(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y); + + /* Remember for which channel we store configuration */ + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) + nphy->rssical_chanspec_2G.center_freq = dev->phy.channel_freq; + else + nphy->rssical_chanspec_5G.center_freq = dev->phy.channel_freq; + + /* End of calibration, restore configuration */ + b43_nphy_classifier(dev, 7, class); + b43_nphy_write_clip_detection(dev, clip_state); +} + /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) { @@ -1454,12 +1641,6 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) b43_nphy_reset_cca(dev); } -/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */ -static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev) -{ - /* TODO */ -} - /* * RSSI Calibration * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal -- cgit v1.2.3-70-g09d2 From 3084f3b65c178228bece6f7b166a19f3e38a75d4 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 3 Jan 2012 22:49:21 +0100 Subject: b43: N-PHY: trivial: change save&rest order in RSSI polling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 945aa5267d0..108118820b3 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -1220,12 +1220,12 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, u16 s[2]; if (dev->phy.rev >= 3) { - save_regs_phy[0] = b43_phy_read(dev, + save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1); + save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2); + save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1); - save_regs_phy[1] = b43_phy_read(dev, + save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2); - save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_C1); - save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_AFECTL_C2); save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1); save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0); @@ -1274,12 +1274,12 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, b43_phy_write(dev, B43_NPHY_GPIO_SEL, save_regs_phy[8]); if (dev->phy.rev >= 3) { + b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[0]); + b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[1]); b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, - save_regs_phy[0]); + save_regs_phy[2]); b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, - save_regs_phy[1]); - b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[2]); - b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[3]); + save_regs_phy[3]); b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, save_regs_phy[4]); b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[5]); b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, save_regs_phy[6]); -- cgit v1.2.3-70-g09d2 From 884dd24499df823f5c167223c7ae93bd764e2e4f Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 4 Jan 2012 19:40:39 -0800 Subject: rtlwifi: Neaten RT_ASSERT, RT_TRACE, RTPRINT, RT_PRINT_DATA macros Make the macros a bit more readable. Use do {...} while (0) without terminating semicolons. Add missing terminating semicolon to a few uses. Signed-off-by: Joe Perches Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/debug.h | 88 +++++++++++++--------------- drivers/net/wireless/rtlwifi/rtl8192ce/phy.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/phy.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/hw.c | 2 +- drivers/net/wireless/rtlwifi/usb.c | 6 +- 5 files changed, 47 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h index 160dd068521..802c491b3d8 100644 --- a/drivers/net/wireless/rtlwifi/debug.h +++ b/drivers/net/wireless/rtlwifi/debug.h @@ -156,53 +156,47 @@ enum dbgp_flag_e { DBGP_TYPE_MAX }; -#define RT_ASSERT(_exp, fmt) \ - do { \ - if (!(_exp)) { \ - printk(KERN_DEBUG "%s:%s(): ", KBUILD_MODNAME, \ - __func__); \ - printk fmt; \ - } \ - } while (0); - -#define RT_TRACE(rtlpriv, comp, level, fmt)\ - do { \ - if (unlikely(((comp) & rtlpriv->dbg.global_debugcomponents) && \ - ((level) <= rtlpriv->dbg.global_debuglevel))) {\ - printk(KERN_DEBUG "%s:%s():<%lx-%x> ", KBUILD_MODNAME, \ - __func__, in_interrupt(), in_atomic()); \ - printk fmt; \ - } \ - } while (0); - -#define RTPRINT(rtlpriv, dbgtype, dbgflag, printstr) \ - do { \ - if (unlikely(rtlpriv->dbg.dbgp_type[dbgtype] & dbgflag)) { \ - printk(KERN_DEBUG "%s: ", KBUILD_MODNAME); \ - printk printstr; \ - } \ - } while (0); - -#define RT_PRINT_DATA(rtlpriv, _comp, _level, _titlestring, _hexdata, \ - _hexdatalen) \ - do {\ - if (unlikely(((_comp) & rtlpriv->dbg.global_debugcomponents) &&\ - (_level <= rtlpriv->dbg.global_debuglevel))) { \ - int __i; \ - u8* ptr = (u8 *)_hexdata; \ - printk(KERN_DEBUG "%s: ", KBUILD_MODNAME); \ - printk("In process \"%s\" (pid %i):", current->comm,\ - current->pid); \ - printk(_titlestring); \ - for (__i = 0; __i < (int)_hexdatalen; __i++) { \ - printk("%02X%s", ptr[__i], (((__i + 1) % 4)\ - == 0) ? " " : " ");\ - if (((__i + 1) % 16) == 0) \ - printk("\n"); \ - } \ - printk(KERN_DEBUG "\n"); \ - } \ - } while (0); +#define RT_ASSERT(_exp, fmt) \ +do { \ + if (!(_exp)) { \ + printk(KERN_DEBUG "%s:%s(): ", \ + KBUILD_MODNAME, __func__); \ + printk fmt; \ + } \ +} while (0) + +#define RT_TRACE(rtlpriv, comp, level, fmt) \ +do { \ + if (unlikely(((comp) & rtlpriv->dbg.global_debugcomponents) && \ + ((level) <= rtlpriv->dbg.global_debuglevel))) { \ + printk(KERN_DEBUG "%s:%s():<%lx-%x> ", \ + KBUILD_MODNAME, __func__, \ + in_interrupt(), in_atomic()); \ + printk fmt; \ + } \ +} while (0) + +#define RTPRINT(rtlpriv, dbgtype, dbgflag, printstr) \ +do { \ + if (unlikely(rtlpriv->dbg.dbgp_type[dbgtype] & dbgflag)) { \ + printk(KERN_DEBUG "%s: ", KBUILD_MODNAME); \ + printk printstr; \ + } \ +} while (0) + +#define RT_PRINT_DATA(rtlpriv, _comp, _level, _titlestring, _hexdata, \ + _hexdatalen) \ +do { \ + if (unlikely(((_comp) & rtlpriv->dbg.global_debugcomponents) && \ + (_level <= rtlpriv->dbg.global_debuglevel))) { \ + printk(KERN_DEBUG "%s: ", KBUILD_MODNAME); \ + pr_cont("In process \"%s\" (pid %i):", \ + current->comm, current->pid); \ + printk(_titlestring); \ + print_hex_dump_bytes("", DUMP_PREFIX_NONE, \ + _hexdata, _hexdatalen); \ + } \ +} while (0) void rtl_dbgp_flag_init(struct ieee80211_hw *hw); #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index 3b585aadabf..ce9eea94bb5 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c @@ -374,7 +374,7 @@ void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("Switch to %s bandwidth\n", rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? - "20MHz" : "40MHz")) + "20MHz" : "40MHz")); if (is_hal_stop(rtlhal)) { rtlphy->set_bwmode_inprogress = false; diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c index e49cf2244c7..df491d38ecc 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c @@ -360,7 +360,7 @@ void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("Switch to %s bandwidth\n", rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? - "20MHz" : "40MHz")) + "20MHz" : "40MHz")); if (is_hal_stop(rtlhal)) { rtlphy->set_bwmode_inprogress = false; return; diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c index 9d89d7ccdaf..c8c4cf9240d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c @@ -1617,7 +1617,7 @@ static void _rtl92de_read_txpower_info(struct ieee80211_hw *hw, RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Is D cut,Internal PA0 %d Internal PA1 %d\n", rtlefuse->internal_pa_5g[0], - rtlefuse->internal_pa_5g[1])) + rtlefuse->internal_pa_5g[1])); } rtlefuse->eeprom_c9 = hwinfo[EEPROM_RF_OPT6]; rtlefuse->eeprom_cc = hwinfo[EEPROM_RF_OPT7]; diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index e956fa71d04..1b8e68e70f8 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -414,7 +414,7 @@ static struct sk_buff *_rtl_prep_rx_urb(struct ieee80211_hw *hw, gfp_mask); if (!skb) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Failed to __dev_alloc_skb!!\n")) + ("Failed to __dev_alloc_skb!!\n")); return ERR_PTR(-ENOMEM); } @@ -632,14 +632,14 @@ static int _rtl_usb_receive(struct ieee80211_hw *hw) urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Failed to alloc URB!!\n")) + ("Failed to alloc URB!!\n")); goto err_out; } skb = _rtl_prep_rx_urb(hw, rtlusb, urb, GFP_KERNEL); if (IS_ERR(skb)) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Failed to prep_rx_urb!!\n")) + ("Failed to prep_rx_urb!!\n")); err = PTR_ERR(skb); goto err_out; } -- cgit v1.2.3-70-g09d2 From af08687b4e6d44dcdb04b519e718eb58ecb99050 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 4 Jan 2012 19:40:40 -0800 Subject: rtlwifi: Standardize RT_PRINT_DATA macro and uses Use a single printk(KERN_DEBUG to emit the header line to avoid any possible output interleaving. Remove unnecessary parentheses from the calling uses. Standardize header arg without trailing \n or colon. Fix a few pairwiase/pairwise typos. Signed-off-by: Joe Perches Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/debug.h | 7 +++---- drivers/net/wireless/rtlwifi/efuse.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | 9 ++++----- drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 4 ++-- drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | 3 +-- drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/mac.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/fw.c | 8 ++++---- drivers/net/wireless/rtlwifi/rtl8192de/hw.c | 4 ++-- drivers/net/wireless/rtlwifi/rtl8192de/trx.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/hw.c | 4 ++-- 12 files changed, 23 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h index 802c491b3d8..588986a1e21 100644 --- a/drivers/net/wireless/rtlwifi/debug.h +++ b/drivers/net/wireless/rtlwifi/debug.h @@ -189,10 +189,9 @@ do { \ do { \ if (unlikely(((_comp) & rtlpriv->dbg.global_debugcomponents) && \ (_level <= rtlpriv->dbg.global_debuglevel))) { \ - printk(KERN_DEBUG "%s: ", KBUILD_MODNAME); \ - pr_cont("In process \"%s\" (pid %i):", \ - current->comm, current->pid); \ - printk(_titlestring); \ + printk(KERN_DEBUG "%s: In process \"%s\" (pid %i): %s\n", \ + KBUILD_MODNAME, current->comm, current->pid, \ + _titlestring); \ print_hex_dump_bytes("", DUMP_PREFIX_NONE, \ _hexdata, _hexdatalen); \ } \ diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c index ed1058b7158..91fd3639d73 100644 --- a/drivers/net/wireless/rtlwifi/efuse.c +++ b/drivers/net/wireless/rtlwifi/efuse.c @@ -478,7 +478,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw) &rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base], 8); RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, - ("U-efuse\n"), tmpdata, 8); + "U-efuse", tmpdata, 8); if (!efuse_pg_packet_write(hw, (u8) offset, word_en, tmpdata)) { diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index 931d97979b0..5401b32733d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c @@ -570,7 +570,7 @@ void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) ppsc->reg_max_lps_awakeintvl); RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "rtl92c_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n", + "rtl92c_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode", u1_h2c_set_pwrmode, 3); rtl92c_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode); @@ -780,10 +780,10 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished) totalpacketlen = TOTAL_RESERVED_PKT_LEN; RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, - "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL", &reserved_page_packet[0], totalpacketlen); RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL", u1RsvdPageLoc, 3); @@ -800,8 +800,7 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished) RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("Set RSVD page location to Fw.\n")); RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "H2C_RSVDPAGE:\n", - u1RsvdPageLoc, 3); + "H2C_RSVDPAGE", u1RsvdPageLoc, 3); rtl92c_fill_h2c_cmd(hw, H2C_RSVDPAGE, sizeof(u1RsvdPageLoc), u1RsvdPageLoc); } else diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index a3deaefa788..2156378de1e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -1570,7 +1570,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) ("RTL819X Not boot from eeprom, check it !!")); } - RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"), + RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP", hwinfo, HWSET_MAX_SIZE); eeprom_id = *((u16 *)&hwinfo[0]); @@ -2134,7 +2134,7 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, ("add one entry\n")); if (is_pairwise) { RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, - "Pairwiase Key content :", + "Pairwise Key content", rtlpriv->sec.pairwise_key, rtlpriv->sec. key_len[PAIRWISE_KEYIDX]); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 4fb5ae24dee..378bc567346 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -821,8 +821,7 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, } RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, - "H2C Tx Cmd Content\n", - pdesc, TX_DESC_SIZE); + "H2C Tx Cmd Content", pdesc, TX_DESC_SIZE); } void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 124cf633861..778c0e6e836 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -496,7 +496,7 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("RTL819X Not boot from eeprom, check it !!")); } - RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, ("MAP\n"), + RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, "MAP", hwinfo, HWSET_MAX_SIZE); eeprom_id = le16_to_cpu(*((__le16 *)&hwinfo[0])); if (eeprom_id != RTL8190_EEPROM_ID) { diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c index 9e0c8fcdf90..487ee908d7c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c @@ -331,7 +331,7 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index, ("add one entry\n")); if (is_pairwise) { RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, - "Pairwiase Key content :", + "Pairwise Key content", rtlpriv->sec.pairwise_key, rtlpriv->sec. key_len[PAIRWISE_KEYIDX]); diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index b3cc7b94999..128cfcd09fa 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c @@ -677,7 +677,7 @@ void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw, SET_TX_DESC_HWSEQ_EN(pdesc, 1); SET_TX_DESC_PKT_ID(pdesc, 8); } - RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C Tx Cmd Content\n", + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C Tx Cmd Content", pdesc, RTL_TX_DESC_SIZE); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c index 82f060bdbc0..db6972ffe50 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c @@ -565,7 +565,7 @@ void rtl92d_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode, ppsc->reg_max_lps_awakeintvl); RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "rtl92d_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n", + "rtl92d_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode", u1_h2c_set_pwrmode, 3); rtl92d_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode); } @@ -757,10 +757,10 @@ void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished) SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG); totalpacketlen = TOTAL_RESERVED_PKT_LEN; RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, - "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL", &reserved_page_packet[0], totalpacketlen); RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL", u1RsvdPageLoc, 3); skb = dev_alloc_skb(totalpacketlen); memcpy((u8 *) skb_put(skb, totalpacketlen), &reserved_page_packet, @@ -773,7 +773,7 @@ void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished) RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("Set RSVD page location to Fw.\n")); RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "H2C_RSVDPAGE:\n", u1RsvdPageLoc, 3); + "H2C_RSVDPAGE", u1RsvdPageLoc, 3); rtl92d_fill_h2c_cmd(hw, H2C_RSVDPAGE, sizeof(u1RsvdPageLoc), u1RsvdPageLoc); } else diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c index c8c4cf9240d..5c8a639582a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c @@ -1777,7 +1777,7 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("RTL819X Not boot from eeprom, check it !!")); } - RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"), + RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP", hwinfo, HWSET_MAX_SIZE); eeprom_id = *((u16 *)&hwinfo[0]); @@ -2279,7 +2279,7 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index, ("add one entry\n")); if (is_pairwise) { RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, - "Pairwiase Key content :", + "Pairwise Key content", rtlpriv->sec.pairwise_key, rtlpriv-> sec.key_len[PAIRWISE_KEYIDX]); diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c index 3637c0c3352..e84b8d5e4b1 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c @@ -776,7 +776,7 @@ void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, } RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, - "H2C Tx Cmd Content\n", pdesc, TX_DESC_SIZE); + "H2C Tx Cmd Content", pdesc, TX_DESC_SIZE); wmb(); SET_TX_DESC_OWN(pdesc, 1); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index c474486e391..f9ba077bc18 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c @@ -1636,7 +1636,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) HWSET_MAX_SIZE_92S); } - RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"), + RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP", hwinfo, HWSET_MAX_SIZE_92S); eeprom_id = *((u16 *)&hwinfo[0]); @@ -2453,7 +2453,7 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, ("add one entry\n")); if (is_pairwise) { RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, - "Pairwiase Key content :", + "Pairwise Key content", rtlpriv->sec.pairwise_key, rtlpriv->sec.key_len[PAIRWISE_KEYIDX]); -- cgit v1.2.3-70-g09d2 From f30d7507a8116e2099a9135c873411db8c0a3dc6 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 4 Jan 2012 19:40:41 -0800 Subject: rtlwifi: Convert RT_TRACE macro to use ##__VA_ARGS__ Consolidate printks to avoid possible message interleaving and reduce the object size. Remove unnecessary RT_TRACE parentheses. Miscellaneous typo and grammar fixes. Add missing newlines to formats. Remove duplicate KERN_DEBUG prefixes. Coalesce formats. Align arguments. $ size drivers/net/wireless/rtlwifi/built-in.o* text data bss dec hex filename 594841 55333 129680 779854 be64e drivers/net/wireless/rtlwifi/built-in.o.new 607022 55333 138720 801075 c3933 drivers/net/wireless/rtlwifi/built-in.o.old Signed-off-by: Joe Perches Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/base.c | 56 ++- drivers/net/wireless/rtlwifi/cam.c | 81 ++-- drivers/net/wireless/rtlwifi/core.c | 120 +++--- drivers/net/wireless/rtlwifi/debug.h | 7 +- drivers/net/wireless/rtlwifi/efuse.c | 31 +- drivers/net/wireless/rtlwifi/pci.c | 196 +++++----- drivers/net/wireless/rtlwifi/ps.c | 31 +- drivers/net/wireless/rtlwifi/rc.c | 2 +- drivers/net/wireless/rtlwifi/regd.c | 12 +- drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | 189 +++++----- drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | 69 ++-- drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c | 201 +++++----- drivers/net/wireless/rtlwifi/rtl8192ce/dm.c | 24 +- drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 182 +++++---- drivers/net/wireless/rtlwifi/rtl8192ce/led.c | 16 +- drivers/net/wireless/rtlwifi/rtl8192ce/phy.c | 108 +++--- drivers/net/wireless/rtlwifi/rtl8192ce/rf.c | 6 +- drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | 6 +- drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | 4 +- drivers/net/wireless/rtlwifi/rtl8192cu/dm.c | 24 +- drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 179 +++++---- drivers/net/wireless/rtlwifi/rtl8192cu/led.c | 15 +- drivers/net/wireless/rtlwifi/rtl8192cu/mac.c | 101 +++-- drivers/net/wireless/rtlwifi/rtl8192cu/phy.c | 121 +++--- drivers/net/wireless/rtlwifi/rtl8192cu/rf.c | 6 +- drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | 6 +- drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | 36 +- drivers/net/wireless/rtlwifi/rtl8192de/dm.c | 239 ++++++------ drivers/net/wireless/rtlwifi/rtl8192de/fw.c | 103 +++-- drivers/net/wireless/rtlwifi/rtl8192de/hw.c | 182 +++++---- drivers/net/wireless/rtlwifi/rtl8192de/led.c | 14 +- drivers/net/wireless/rtlwifi/rtl8192de/phy.c | 419 ++++++++++----------- drivers/net/wireless/rtlwifi/rtl8192de/rf.c | 26 +- drivers/net/wireless/rtlwifi/rtl8192de/sw.c | 6 +- drivers/net/wireless/rtlwifi/rtl8192de/trx.c | 8 +- drivers/net/wireless/rtlwifi/rtl8192se/dm.c | 30 +- drivers/net/wireless/rtlwifi/rtl8192se/fw.c | 66 ++-- drivers/net/wireless/rtlwifi/rtl8192se/hw.c | 155 ++++---- drivers/net/wireless/rtlwifi/rtl8192se/led.c | 15 +- drivers/net/wireless/rtlwifi/rtl8192se/phy.c | 200 +++++----- drivers/net/wireless/rtlwifi/rtl8192se/rf.c | 60 ++- drivers/net/wireless/rtlwifi/rtl8192se/sw.c | 6 +- drivers/net/wireless/rtlwifi/rtl8192se/trx.c | 2 +- drivers/net/wireless/rtlwifi/usb.c | 37 +- 44 files changed, 1613 insertions(+), 1784 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index 8d6eb0f56c0..fa16b1d708f 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -211,7 +211,7 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, */ if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_2T2R) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("1T2R or 2T2R\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "1T2R or 2T2R\n"); ht_cap->mcs.rx_mask[0] = 0xFF; ht_cap->mcs.rx_mask[1] = 0xFF; @@ -220,7 +220,7 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15); } else if (get_rf_type(rtlphy) == RF_1T1R) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("1T1R\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "1T1R\n"); ht_cap->mcs.rx_mask[0] = 0xFF; ht_cap->mcs.rx_mask[1] = 0x00; @@ -302,9 +302,8 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw) /* <4> set mac->sband to wiphy->sband */ hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Err BAND %d\n", - rtlhal->current_bandtype)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Err BAND %d\n", + rtlhal->current_bandtype); } } /* <5> set hw caps */ @@ -436,13 +435,13 @@ int rtl_init_core(struct ieee80211_hw *hw) * mac80211 hw in _rtl_init_mac80211. */ if (rtl_regd_init(hw, rtl_reg_notifier)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("REGD init failed\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "REGD init failed\n"); return 1; } else { /* CRDA regd hint must after init CRDA */ if (regulatory_hint(hw->wiphy, rtlpriv->regd.alpha2)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("regulatory_hint fail\n")); + "regulatory_hint fail\n"); } } @@ -922,17 +921,17 @@ bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) return false; RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, - ("%s ACT_ADDBAREQ From :%pM\n", - is_tx ? "Tx" : "Rx", hdr->addr2)); + "%s ACT_ADDBAREQ From :%pM\n", + is_tx ? "Tx" : "Rx", hdr->addr2); break; case ACT_ADDBARSP: RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, - ("%s ACT_ADDBARSP From :%pM\n", - is_tx ? "Tx" : "Rx", hdr->addr2)); + "%s ACT_ADDBARSP From :%pM\n", + is_tx ? "Tx" : "Rx", hdr->addr2); break; case ACT_DELBA: RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, - ("ACT_ADDBADEL From :%pM\n", hdr->addr2)); + "ACT_ADDBADEL From :%pM\n", hdr->addr2); break; } break; @@ -975,8 +974,8 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) * 67 : UDP BOOTP server */ RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), - DBG_DMESG, ("dhcp %s !!\n", - (is_tx) ? "Tx" : "Rx")); + DBG_DMESG, "dhcp %s !!\n", + is_tx ? "Tx" : "Rx"); if (is_tx) { rtl_lps_leave(hw); @@ -996,7 +995,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) return true; } else if (ETH_P_PAE == ether_type) { RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, - ("802.1X %s EAPOL pkt!!\n", (is_tx) ? "Tx" : "Rx")); + "802.1X %s EAPOL pkt!!\n", is_tx ? "Tx" : "Rx"); if (is_tx) { rtl_lps_leave(hw); @@ -1036,9 +1035,8 @@ int rtl_tx_agg_start(struct ieee80211_hw *hw, return -ENXIO; tid_data = &sta_entry->tids[tid]; - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, - ("on ra = %pM tid = %d seq:%d\n", sta->addr, tid, - tid_data->seq_number)); + RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "on ra = %pM tid = %d seq:%d\n", + sta->addr, tid, tid_data->seq_number); *ssn = tid_data->seq_number; tid_data->agg.agg_state = RTL_AGG_START; @@ -1059,12 +1057,12 @@ int rtl_tx_agg_stop(struct ieee80211_hw *hw, return -EINVAL; if (!sta->addr) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("ra = NULL\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "ra = NULL\n"); return -EINVAL; } - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, - ("on ra = %pM tid = %d\n", sta->addr, tid)); + RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "on ra = %pM tid = %d\n", + sta->addr, tid); if (unlikely(tid >= MAX_TID_COUNT)) return -EINVAL; @@ -1087,12 +1085,12 @@ int rtl_tx_agg_oper(struct ieee80211_hw *hw, return -EINVAL; if (!sta->addr) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("ra = NULL\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "ra = NULL\n"); return -EINVAL; } - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, - ("on ra = %pM tid = %d\n", sta->addr, tid)); + RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "on ra = %pM tid = %d\n", + sta->addr, tid); if (unlikely(tid >= MAX_TID_COUNT)) return -EINVAL; @@ -1474,29 +1472,29 @@ void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len) (memcmp(mac->bssid, ap5_6, 3) == 0) || vendor == PEER_ATH) { vendor = PEER_ATH; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>ath find\n")); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>ath find\n"); } else if ((memcmp(mac->bssid, ap4_4, 3) == 0) || (memcmp(mac->bssid, ap4_5, 3) == 0) || (memcmp(mac->bssid, ap4_1, 3) == 0) || (memcmp(mac->bssid, ap4_2, 3) == 0) || (memcmp(mac->bssid, ap4_3, 3) == 0) || vendor == PEER_RAL) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>ral findn\n")); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>ral find\n"); vendor = PEER_RAL; } else if (memcmp(mac->bssid, ap6_1, 3) == 0 || vendor == PEER_CISCO) { vendor = PEER_CISCO; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>cisco find\n")); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>cisco find\n"); } else if ((memcmp(mac->bssid, ap3_1, 3) == 0) || (memcmp(mac->bssid, ap3_2, 3) == 0) || (memcmp(mac->bssid, ap3_3, 3) == 0) || vendor == PEER_BROAD) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>broad find\n")); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>broad find\n"); vendor = PEER_BROAD; } else if (memcmp(mac->bssid, ap7_1, 3) == 0 || vendor == PEER_MARV) { vendor = PEER_MARV; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>marv find\n")); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>marv find\n"); } mac->vendor = vendor; diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c index dc36d7461ca..cbf5e3cdb44 100644 --- a/drivers/net/wireless/rtlwifi/cam.c +++ b/drivers/net/wireless/rtlwifi/cam.c @@ -55,10 +55,10 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, u8 entry_i; RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("key_cont_128:\n %x:%x:%x:%x:%x:%x\n", - key_cont_128[0], key_cont_128[1], - key_cont_128[2], key_cont_128[3], - key_cont_128[4], key_cont_128[5])); + "key_cont_128:\n %x:%x:%x:%x:%x:%x\n", + key_cont_128[0], key_cont_128[1], + key_cont_128[2], key_cont_128[3], + key_cont_128[4], key_cont_128[5]); for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) { target_command = entry_i + CAM_CONTENT_COUNT * entry_no; @@ -73,14 +73,12 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], target_command); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE %x: %x\n", + rtlpriv->cfg->maps[WCAMI], target_content); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("WRITE %x: %x\n", - rtlpriv->cfg->maps[WCAMI], target_content)); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The Key ID is %d\n", entry_no)); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("WRITE %x: %x\n", - rtlpriv->cfg->maps[RWCAM], target_command)); + "The Key ID is %d\n", entry_no); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE %x: %x\n", + rtlpriv->cfg->maps[RWCAM], target_command); } else if (entry_i == 1) { @@ -94,10 +92,10 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], target_command); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("WRITE A4: %x\n", target_content)); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("WRITE A0: %x\n", target_command)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE A4: %x\n", + target_content); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE A0: %x\n", + target_command); } else { @@ -114,15 +112,15 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, target_command); udelay(100); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("WRITE A4: %x\n", target_content)); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("WRITE A0: %x\n", target_command)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE A4: %x\n", + target_content); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE A0: %x\n", + target_command); } } - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("after set key, usconfig:%x\n", us_config)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "after set key, usconfig:%x\n", + us_config); } u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, @@ -133,14 +131,13 @@ u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, struct rtl_priv *rtlpriv = rtl_priv(hw); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, " - "ulUseDK=%x MacAddr %pM\n", - ul_entry_idx, ul_key_id, ul_enc_alg, - ul_default_key, mac_addr)); + "EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, ulUseDK=%x MacAddr %pM\n", + ul_entry_idx, ul_key_id, ul_enc_alg, + ul_default_key, mac_addr); if (ul_key_id == TOTAL_CAM_ENTRY) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("<=== ulKeyId exceed!\n")); + "<=== ulKeyId exceed!\n"); return 0; } @@ -153,7 +150,7 @@ u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, rtl_cam_program_entry(hw, ul_entry_idx, mac_addr, (u8 *) key_content, us_config); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("<===\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "<===\n"); return 1; @@ -166,7 +163,7 @@ int rtl_cam_delete_one_entry(struct ieee80211_hw *hw, u32 ul_command; struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("key_idx:%d\n", ul_key_id)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "key_idx:%d\n", ul_key_id); ul_command = ul_key_id * CAM_CONTENT_COUNT; ul_command = ul_command | BIT(31) | BIT(16); @@ -175,9 +172,9 @@ int rtl_cam_delete_one_entry(struct ieee80211_hw *hw, rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("rtl_cam_delete_one_entry(): WRITE A4: %x\n", 0)); + "rtl_cam_delete_one_entry(): WRITE A4: %x\n", 0); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("rtl_cam_delete_one_entry(): WRITE A0: %x\n", ul_command)); + "rtl_cam_delete_one_entry(): WRITE A0: %x\n", ul_command); return 0; @@ -229,9 +226,9 @@ void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index) rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("rtl_cam_mark_invalid(): WRITE A4: %x\n", ul_content)); + "rtl_cam_mark_invalid(): WRITE A4: %x\n", ul_content); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("rtl_cam_mark_invalid(): WRITE A0: %x\n", ul_command)); + "rtl_cam_mark_invalid(): WRITE A0: %x\n", ul_command); } EXPORT_SYMBOL(rtl_cam_mark_invalid); @@ -279,11 +276,11 @@ void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index) rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("rtl_cam_empty_entry(): WRITE A4: %x\n", - ul_content)); + "rtl_cam_empty_entry(): WRITE A4: %x\n", + ul_content); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("rtl_cam_empty_entry(): WRITE A0: %x\n", - ul_command)); + "rtl_cam_empty_entry(): WRITE A0: %x\n", + ul_command); } } @@ -297,8 +294,7 @@ u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr) u8 i, *addr; if (NULL == sta_addr) { - RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, - ("sta_addr is NULL.\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, "sta_addr is NULL\n"); return TOTAL_CAM_ENTRY; } /* Does STA already exist? */ @@ -311,8 +307,8 @@ u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr) for (entry_idx = 4; entry_idx < TOTAL_CAM_ENTRY; entry_idx++) { if ((bitmap & BIT(0)) == 0) { RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, - ("-----hwsec_cam_bitmap: 0x%x entry_idx=%d\n", - rtlpriv->sec.hwsec_cam_bitmap, entry_idx)); + "-----hwsec_cam_bitmap: 0x%x entry_idx=%d\n", + rtlpriv->sec.hwsec_cam_bitmap, entry_idx); rtlpriv->sec.hwsec_cam_bitmap |= BIT(0) << entry_idx; memcpy(rtlpriv->sec.hwsec_cam_sta_addr[entry_idx], sta_addr, ETH_ALEN); @@ -331,14 +327,13 @@ void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr) u8 i, *addr; if (NULL == sta_addr) { - RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, - ("sta_addr is NULL.\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, "sta_addr is NULL\n"); } if ((sta_addr[0]|sta_addr[1]|sta_addr[2]|sta_addr[3]|\ sta_addr[4]|sta_addr[5]) == 0) { RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, - ("sta_addr is 00:00:00:00:00:00.\n")); + "sta_addr is 00:00:00:00:00:00\n"); return; } /* Does STA already exist? */ diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index 3f0f056fae9..186c944c143 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -114,7 +114,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, if (mac->vif) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("vif has been set!! mac->vif = 0x%p\n", mac->vif)); + "vif has been set!! mac->vif = 0x%p\n", mac->vif); return -EOPNOTSUPP; } @@ -125,7 +125,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, case NL80211_IFTYPE_STATION: if (mac->beacon_enabled == 1) { RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("NL80211_IFTYPE_STATION\n")); + "NL80211_IFTYPE_STATION\n"); mac->beacon_enabled = 0; rtlpriv->cfg->ops->update_interrupt_mask(hw, 0, rtlpriv->cfg->maps @@ -134,7 +134,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, break; case NL80211_IFTYPE_ADHOC: RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("NL80211_IFTYPE_ADHOC\n")); + "NL80211_IFTYPE_ADHOC\n"); mac->link_state = MAC80211_LINKED; rtlpriv->cfg->ops->set_bcn_reg(hw); @@ -148,7 +148,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, break; case NL80211_IFTYPE_AP: RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("NL80211_IFTYPE_AP\n")); + "NL80211_IFTYPE_AP\n"); mac->link_state = MAC80211_LINKED; rtlpriv->cfg->ops->set_bcn_reg(hw); @@ -161,7 +161,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("operation mode %d is not support!\n", vif->type)); + "operation mode %d is not supported!\n", vif->type); err = -EOPNOTSUPP; goto out; } @@ -221,7 +221,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) mutex_lock(&rtlpriv->locks.conf_mutex); if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { /*BIT(2)*/ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n")); + "IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n"); } /*For IPS */ @@ -264,8 +264,8 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n", - hw->conf.long_frame_max_tx_count)); + "IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n", + hw->conf.long_frame_max_tx_count); mac->retry_long = hw->conf.long_frame_max_tx_count; mac->retry_short = hw->conf.long_frame_max_tx_count; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT, @@ -320,7 +320,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) default: mac->bw_40 = false; RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not processed\n")); + "switch case not processed\n"); break; } @@ -369,12 +369,12 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AM] | rtlpriv->cfg->maps[MAC_RCR_AB]; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("Enable receive multicast frame.\n")); + "Enable receive multicast frame\n"); } else { mac->rx_conf &= ~(rtlpriv->cfg->maps[MAC_RCR_AM] | rtlpriv->cfg->maps[MAC_RCR_AB]); RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("Disable receive multicast frame.\n")); + "Disable receive multicast frame\n"); } } @@ -382,11 +382,11 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, if (*new_flags & FIF_FCSFAIL) { mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACRC32]; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("Enable receive FCS error frame.\n")); + "Enable receive FCS error frame\n"); } else { mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACRC32]; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("Disable receive FCS error frame.\n")); + "Disable receive FCS error frame\n"); } } @@ -409,11 +409,11 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF]; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("Enable receive control frame.\n")); + "Enable receive control frame\n"); } else { mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF]; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("Disable receive control frame.\n")); + "Disable receive control frame\n"); } } @@ -421,11 +421,11 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, if (*new_flags & FIF_OTHER_BSS) { mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AAP]; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("Enable receive other BSS's frame.\n")); + "Enable receive other BSS's frame\n"); } else { mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_AAP]; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("Disable receive other BSS's frame.\n")); + "Disable receive other BSS's frame\n"); } } } @@ -456,7 +456,7 @@ static int rtl_op_sta_add(struct ieee80211_hw *hw, sta_entry->wireless_mode = WIRELESS_MODE_G; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - ("Add sta addr is %pM\n", sta->addr)); + "Add sta addr is %pM\n", sta->addr); rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0); } return 0; @@ -469,7 +469,7 @@ static int rtl_op_sta_remove(struct ieee80211_hw *hw, struct rtl_sta_info *sta_entry; if (sta) { RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - ("Remove sta addr is %pM\n", sta->addr)); + "Remove sta addr is %pM\n", sta->addr); sta_entry = (struct rtl_sta_info *) sta->drv_priv; sta_entry->wireless_mode = 0; sta_entry->ratr_index = 0; @@ -514,7 +514,7 @@ static int rtl_op_conf_tx(struct ieee80211_hw *hw, if (queue >= AC_MAX) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("queue number %d is incorrect!\n", queue)); + "queue number %d is incorrect!\n", queue); return -EINVAL; } @@ -547,7 +547,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, bss_conf->enable_beacon)) { if (mac->beacon_enabled == 0) { RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - ("BSS_CHANGED_BEACON_ENABLED\n")); + "BSS_CHANGED_BEACON_ENABLED\n"); /*start hw beacon interrupt. */ /*rtlpriv->cfg->ops->set_bcn_reg(hw); */ @@ -565,7 +565,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, !bss_conf->enable_beacon)) { if (mac->beacon_enabled == 1) { RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - ("ADHOC DISABLE BEACON\n")); + "ADHOC DISABLE BEACON\n"); mac->beacon_enabled = 0; rtlpriv->cfg->ops->update_interrupt_mask(hw, 0, @@ -575,7 +575,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_BEACON_INT) { RT_TRACE(rtlpriv, COMP_BEACON, DBG_TRACE, - ("BSS_CHANGED_BEACON_INT\n")); + "BSS_CHANGED_BEACON_INT\n"); mac->beacon_interval = bss_conf->beacon_int; rtlpriv->cfg->ops->set_bcn_intv(hw); } @@ -604,7 +604,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, if (mac->opmode == NL80211_IFTYPE_STATION && sta) rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0); RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - ("BSS_CHANGED_ASSOC\n")); + "BSS_CHANGED_ASSOC\n"); } else { if (mac->link_state == MAC80211_LINKED) rtl_lps_leave(hw); @@ -619,20 +619,20 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, mac->vendor = PEER_UNKNOWN; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - ("BSS_CHANGED_UN_ASSOC\n")); + "BSS_CHANGED_UN_ASSOC\n"); } } if (changed & BSS_CHANGED_ERP_CTS_PROT) { RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - ("BSS_CHANGED_ERP_CTS_PROT\n")); + "BSS_CHANGED_ERP_CTS_PROT\n"); mac->use_cts_protect = bss_conf->use_cts_prot; } if (changed & BSS_CHANGED_ERP_PREAMBLE) { RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("BSS_CHANGED_ERP_PREAMBLE use short preamble:%x\n", - bss_conf->use_short_preamble)); + "BSS_CHANGED_ERP_PREAMBLE use short preamble:%x\n", + bss_conf->use_short_preamble); mac->short_preamble = bss_conf->use_short_preamble; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACK_PREAMBLE, @@ -641,7 +641,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_ERP_SLOT) { RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - ("BSS_CHANGED_ERP_SLOT\n")); + "BSS_CHANGED_ERP_SLOT\n"); if (bss_conf->use_short_slot) mac->slot_time = RTL_SLOT_TIME_9; @@ -653,8 +653,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_HT) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - ("BSS_CHANGED_HT\n")); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, "BSS_CHANGED_HT\n"); rcu_read_lock(); sta = get_sta(hw, vif, bss_conf->bssid); if (sta) { @@ -683,8 +682,8 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BSSID, (u8 *) bss_conf->bssid); - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - ("%pM\n", bss_conf->bssid)); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, "%pM\n", + bss_conf->bssid); mac->vendor = PEER_UNKNOWN; memcpy(mac->bssid, bss_conf->bssid, 6); @@ -831,30 +830,30 @@ static int rtl_op_ampdu_action(struct ieee80211_hw *hw, switch (action) { case IEEE80211_AMPDU_TX_START: RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - ("IEEE80211_AMPDU_TX_START: TID:%d\n", tid)); + "IEEE80211_AMPDU_TX_START: TID:%d\n", tid); return rtl_tx_agg_start(hw, sta, tid, ssn); break; case IEEE80211_AMPDU_TX_STOP: RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - ("IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid)); + "IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid); return rtl_tx_agg_stop(hw, sta, tid); break; case IEEE80211_AMPDU_TX_OPERATIONAL: RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - ("IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid)); + "IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid); rtl_tx_agg_oper(hw, sta, tid); break; case IEEE80211_AMPDU_RX_START: RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - ("IEEE80211_AMPDU_RX_START:TID:%d\n", tid)); + "IEEE80211_AMPDU_RX_START:TID:%d\n", tid); break; case IEEE80211_AMPDU_RX_STOP: RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - ("IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid)); + "IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid); break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("IEEE80211_AMPDU_ERR!!!!:\n")); + "IEEE80211_AMPDU_ERR!!!!:\n"); return -EOPNOTSUPP; } return 0; @@ -867,7 +866,7 @@ static void rtl_op_sw_scan_start(struct ieee80211_hw *hw) mac->act_scanning = true; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n")); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n"); if (mac->link_state == MAC80211_LINKED) { rtl_lps_leave(hw); @@ -888,7 +887,7 @@ static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n")); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n"); mac->act_scanning = false; /* Dual mac */ rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false; @@ -921,13 +920,13 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("not open hw encryption\n")); + "not open hw encryption\n"); return -ENOSPC; /*User disabled HW-crypto */ } RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("%s hardware based encryption for keyidx: %d, mac: %pM\n", - cmd == SET_KEY ? "Using" : "Disabling", key->keyidx, - sta ? sta->addr : bcast_addr)); + "%s hardware based encryption for keyidx: %d, mac: %pM\n", + cmd == SET_KEY ? "Using" : "Disabling", key->keyidx, + sta ? sta->addr : bcast_addr); rtlpriv->sec.being_setkey = true; rtl_ips_nic_on(hw); mutex_lock(&rtlpriv->locks.conf_mutex); @@ -936,24 +935,23 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, switch (key->cipher) { case WLAN_CIPHER_SUITE_WEP40: key_type = WEP40_ENCRYPTION; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:WEP40\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:WEP40\n"); break; case WLAN_CIPHER_SUITE_WEP104: - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("alg:WEP104\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:WEP104\n"); key_type = WEP104_ENCRYPTION; break; case WLAN_CIPHER_SUITE_TKIP: key_type = TKIP_ENCRYPTION; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:TKIP\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:TKIP\n"); break; case WLAN_CIPHER_SUITE_CCMP: key_type = AESCCMP_ENCRYPTION; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:CCMP\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:CCMP\n"); break; default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("alg_err:%x!!!!:\n", key->cipher)); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "alg_err:%x!!!!\n", + key->cipher); goto out_unlock; } if (key_type == WEP40_ENCRYPTION || @@ -995,8 +993,8 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, wep_only = true; rtlpriv->sec.pairwise_enc_algorithm = key_type; RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set enable_hw_sec, key_type:%x(OPEN:0 WEP40:1" - " TKIP:2 AES:4 WEP104:5)\n", key_type)); + "set enable_hw_sec, key_type:%x(OPEN:0 WEP40:1 TKIP:2 AES:4 WEP104:5)\n", + key_type); rtlpriv->cfg->ops->enable_hw_sec(hw); } } @@ -1005,7 +1003,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, case SET_KEY: if (wep_only) { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set WEP(group/pairwise) key\n")); + "set WEP(group/pairwise) key\n"); /* Pairwise key with an assigned MAC address. */ rtlpriv->sec.pairwise_enc_algorithm = key_type; rtlpriv->sec.group_enc_algorithm = key_type; @@ -1016,7 +1014,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, memcpy(mac_addr, zero_addr, ETH_ALEN); } else if (group_key) { /* group key */ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set group key\n")); + "set group key\n"); /* group key */ rtlpriv->sec.group_enc_algorithm = key_type; /*set local buf about group key. */ @@ -1026,7 +1024,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, memcpy(mac_addr, bcast_addr, ETH_ALEN); } else { /* pairwise key */ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set pairwise key\n")); + "set pairwise key\n"); if (!sta) { RT_ASSERT(false, ("pairwise key withnot" "mac_addr\n")); @@ -1056,7 +1054,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, break; case DISABLE_KEY: RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("disable key delete one entry\n")); + "disable key delete one entry\n"); /*set local buf about wep key. */ if (mac->opmode == NL80211_IFTYPE_AP) { if (sta) @@ -1077,7 +1075,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("cmd_err:%x!!!!:\n", cmd)); + "cmd_err:%x!!!!\n", cmd); } out_unlock: mutex_unlock(&rtlpriv->locks.conf_mutex); @@ -1106,8 +1104,8 @@ static void rtl_op_rfkill_poll(struct ieee80211_hw *hw) rtlpriv->rfkill.rfkill_state = radio_state; RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - (KERN_INFO "wireless radio switch turned %s\n", - radio_state ? "on" : "off")); + "wireless radio switch turned %s\n", + radio_state ? "on" : "off"); blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1; wiphy_rfkill_set_hw_state(hw->wiphy, blocked); diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h index 588986a1e21..8c139693354 100644 --- a/drivers/net/wireless/rtlwifi/debug.h +++ b/drivers/net/wireless/rtlwifi/debug.h @@ -165,14 +165,13 @@ do { \ } \ } while (0) -#define RT_TRACE(rtlpriv, comp, level, fmt) \ +#define RT_TRACE(rtlpriv, comp, level, fmt, ...) \ do { \ if (unlikely(((comp) & rtlpriv->dbg.global_debugcomponents) && \ ((level) <= rtlpriv->dbg.global_debuglevel))) { \ - printk(KERN_DEBUG "%s:%s():<%lx-%x> ", \ + printk(KERN_DEBUG "%s:%s():<%lx-%x> " fmt, \ KBUILD_MODNAME, __func__, \ - in_interrupt(), in_atomic()); \ - printk fmt; \ + in_interrupt(), in_atomic(), ##__VA_ARGS__); \ } \ } while (0) diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c index 91fd3639d73..2885131cf1a 100644 --- a/drivers/net/wireless/rtlwifi/efuse.c +++ b/drivers/net/wireless/rtlwifi/efuse.c @@ -162,8 +162,8 @@ void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value) const u32 efuse_len = rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE]; - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - ("Addr=%x Data =%x\n", address, value)); + RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "Addr=%x Data =%x\n", + address, value); if (address < efuse_len) { rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], value); @@ -252,8 +252,8 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) if ((_offset + _size_byte) > rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]) { RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - ("read_efuse(): Invalid offset(%#x) with read " - "bytes(%#x)!!\n", _offset, _size_byte)); + "read_efuse(): Invalid offset(%#x) with read bytes(%#x)!!\n", + _offset, _size_byte); return; } @@ -395,9 +395,8 @@ bool efuse_shadow_update_chk(struct ieee80211_hw *hw) result = false; RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - ("efuse_shadow_update_chk(): totalbytes(%#x), " - "hdr_num(%#x), words_need(%#x), efuse_used(%d)\n", - totalbytes, hdr_num, words_need, efuse_used)); + "efuse_shadow_update_chk(): totalbytes(%#x), hdr_num(%#x), words_need(%#x), efuse_used(%d)\n", + totalbytes, hdr_num, words_need, efuse_used); return result; } @@ -434,7 +433,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw) u8 word_en = 0x0F; u8 first_pg = false; - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, ("--->\n")); + RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "--->\n"); if (!efuse_shadow_update_chk(hw)) { efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]); @@ -443,7 +442,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw) rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - ("<---efuse out of capacity!!\n")); + "<---efuse out of capacity!!\n"); return false; } efuse_power_switch(hw, true, true); @@ -483,7 +482,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw) if (!efuse_pg_packet_write(hw, (u8) offset, word_en, tmpdata)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("PG section(%#x) fail!!\n", offset)); + "PG section(%#x) fail!!\n", offset); break; } } @@ -497,7 +496,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw) &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, ("<---\n")); + RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "<---\n"); return true; } @@ -634,8 +633,8 @@ static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data) struct rtl_priv *rtlpriv = rtl_priv(hw); u8 tmpidx = 0; - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - ("Addr = %x Data=%x\n", addr, data)); + RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "Addr = %x Data=%x\n", + addr, data); rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1, (u8) (addr & 0xff)); @@ -1006,7 +1005,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, if (efuse_addr >= (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES)) { RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - ("efuse_addr(%#x) Out of size!!\n", efuse_addr)); + "efuse_addr(%#x) Out of size!!\n", efuse_addr); } return true; @@ -1046,8 +1045,8 @@ static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw, u8 tmpdata[8]; memset(tmpdata, 0xff, PGPKT_DATA_SIZE); - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - ("word_en = %x efuse_addr=%x\n", word_en, efuse_addr)); + RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "word_en = %x efuse_addr=%x\n", + word_en, efuse_addr); if (!(word_en & BIT(0))) { tmpaddr = start_addr; diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 39e0907a3c4..b52fef23575 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -170,7 +170,7 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } @@ -232,7 +232,7 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw) if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("PCI(Bridge) UNKNOWN.\n")); + "PCI(Bridge) UNKNOWN\n"); return; } @@ -286,7 +286,7 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw) if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("PCI(Bridge) UNKNOWN.\n")); + "PCI(Bridge) UNKNOWN\n"); return; } @@ -303,11 +303,10 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw) u_pcibridge_aspmsetting); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("PlatformEnableASPM():PciBridge busnumber[%x], " - "DevNumbe[%x], funcnumber[%x], Write reg[%x] = %x\n", - pcibridge_busnum, pcibridge_devnum, pcibridge_funcnum, - (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10), - u_pcibridge_aspmsetting)); + "PlatformEnableASPM():PciBridge busnumber[%x], DevNumbe[%x], funcnumber[%x], Write reg[%x] = %x\n", + pcibridge_busnum, pcibridge_devnum, pcibridge_funcnum, + (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10), + u_pcibridge_aspmsetting); udelay(50); @@ -382,9 +381,8 @@ static void rtl_pci_parse_configuration(struct pci_dev *pdev, pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &linkctrl_reg); pcipriv->ndis_adapter.linkctrl_reg = linkctrl_reg; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Link Control Register =%x\n", - pcipriv->ndis_adapter.linkctrl_reg)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Link Control Register =%x\n", + pcipriv->ndis_adapter.linkctrl_reg); pci_read_config_byte(pdev, 0x98, &tmp); tmp |= BIT(4); @@ -551,11 +549,10 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) skb_pull(skb, EM_HDR_LEN); RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_TRACE, - ("new ring->idx:%d, " - "free: skb_queue_len:%d, free: seq:%x\n", - ring->idx, - skb_queue_len(&ring->queue), - *(u16 *) (skb->data + 22))); + "new ring->idx:%d, free: skb_queue_len:%d, free: seq:%x\n", + ring->idx, + skb_queue_len(&ring->queue), + *(u16 *) (skb->data + 22)); if (prio == TXCMD_QUEUE) { dev_kfree_skb(skb); @@ -593,11 +590,9 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) == 2) { RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, - ("more desc left, wake" - "skb_queue@%d,ring->idx = %d," - "skb_queue_len = 0x%d\n", - prio, ring->idx, - skb_queue_len(&ring->queue))); + "more desc left, wake skb_queue@%d, ring->idx = %d, skb_queue_len = 0x%d\n", + prio, ring->idx, + skb_queue_len(&ring->queue)); ieee80211_wake_queue(hw, skb_get_queue_mapping @@ -709,9 +704,8 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) new_skb = dev_alloc_skb(rtlpci->rxbuffersize); if (unlikely(!new_skb)) { - RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), - DBG_DMESG, - ("can't alloc skb for rx\n")); + RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), DBG_DMESG, + "can't alloc skb for rx\n"); goto done; } @@ -796,38 +790,37 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) /*<1> beacon related */ if (inta & rtlpriv->cfg->maps[RTL_IMR_TBDOK]) { RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("beacon ok interrupt!\n")); + "beacon ok interrupt!\n"); } if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_TBDER])) { RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("beacon err interrupt!\n")); + "beacon err interrupt!\n"); } if (inta & rtlpriv->cfg->maps[RTL_IMR_BDOK]) { - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("beacon interrupt!\n")); + RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "beacon interrupt!\n"); } if (inta & rtlpriv->cfg->maps[RTL_IMR_BcnInt]) { RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("prepare beacon for interrupt!\n")); + "prepare beacon for interrupt!\n"); tasklet_schedule(&rtlpriv->works.irq_prepare_bcn_tasklet); } /*<3> Tx related */ if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_TXFOVW])) - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("IMR_TXFOVW!\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "IMR_TXFOVW!\n"); if (inta & rtlpriv->cfg->maps[RTL_IMR_MGNTDOK]) { RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("Manage ok interrupt!\n")); + "Manage ok interrupt!\n"); _rtl_pci_tx_isr(hw, MGNT_QUEUE); } if (inta & rtlpriv->cfg->maps[RTL_IMR_HIGHDOK]) { RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("HIGH_QUEUE ok interrupt!\n")); + "HIGH_QUEUE ok interrupt!\n"); _rtl_pci_tx_isr(hw, HIGH_QUEUE); } @@ -835,7 +828,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) rtlpriv->link_info.num_tx_inperiod++; RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("BK Tx OK interrupt!\n")); + "BK Tx OK interrupt!\n"); _rtl_pci_tx_isr(hw, BK_QUEUE); } @@ -843,7 +836,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) rtlpriv->link_info.num_tx_inperiod++; RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("BE TX OK interrupt!\n")); + "BE TX OK interrupt!\n"); _rtl_pci_tx_isr(hw, BE_QUEUE); } @@ -851,7 +844,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) rtlpriv->link_info.num_tx_inperiod++; RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("VI TX OK interrupt!\n")); + "VI TX OK interrupt!\n"); _rtl_pci_tx_isr(hw, VI_QUEUE); } @@ -859,7 +852,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) rtlpriv->link_info.num_tx_inperiod++; RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("Vo TX OK interrupt!\n")); + "Vo TX OK interrupt!\n"); _rtl_pci_tx_isr(hw, VO_QUEUE); } @@ -868,25 +861,25 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) rtlpriv->link_info.num_tx_inperiod++; RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("CMD TX OK interrupt!\n")); + "CMD TX OK interrupt!\n"); _rtl_pci_tx_isr(hw, TXCMD_QUEUE); } } /*<2> Rx related */ if (inta & rtlpriv->cfg->maps[RTL_IMR_ROK]) { - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, ("Rx ok interrupt!\n")); + RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "Rx ok interrupt!\n"); _rtl_pci_rx_interrupt(hw); } if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RDU])) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("rx descriptor unavailable!\n")); + "rx descriptor unavailable!\n"); _rtl_pci_rx_interrupt(hw); } if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RXFOVW])) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("rx overflow !\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "rx overflow !\n"); _rtl_pci_rx_interrupt(hw); } @@ -1028,7 +1021,7 @@ static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw, if (!ring || (unsigned long)ring & 0xFF) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Cannot allocate TX ring (prio = %d)\n", prio)); + "Cannot allocate TX ring (prio = %d)\n", prio); return -ENOMEM; } @@ -1039,8 +1032,8 @@ static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw, rtlpci->tx_ring[prio].entries = entries; skb_queue_head_init(&rtlpci->tx_ring[prio].queue); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("queue:%d, ring_addr:%p\n", prio, ring)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "queue:%d, ring_addr:%p\n", + prio, ring); for (i = 0; i < entries; i++) { nextdescaddress = (u32) dma + @@ -1078,7 +1071,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw) if (!rtlpci->rx_ring[rx_queue_idx].desc || (unsigned long)rtlpci->rx_ring[rx_queue_idx].desc & 0xFF) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Cannot allocate RX ring\n")); + "Cannot allocate RX ring\n"); return -ENOMEM; } @@ -1355,7 +1348,7 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb, u8 temp_one = 1; if (ieee80211_is_auth(fc)) { - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n")); + RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); rtl_ips_nic_on(hw); } @@ -1388,10 +1381,9 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb, if ((own == 1) && (hw_queue != BEACON_QUEUE)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("No more TX desc@%d, ring->idx = %d," - "idx = %d, skb_queue_len = 0x%d\n", - hw_queue, ring->idx, idx, - skb_queue_len(&ring->queue))); + "No more TX desc@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n", + hw_queue, ring->idx, idx, + skb_queue_len(&ring->queue)); spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); return skb->len; @@ -1426,11 +1418,9 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb, hw_queue != BEACON_QUEUE) { RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, - ("less desc left, stop skb_queue@%d, " - "ring->idx = %d," - "idx = %d, skb_queue_len = 0x%d\n", - hw_queue, ring->idx, idx, - skb_queue_len(&ring->queue))); + "less desc left, stop skb_queue@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n", + hw_queue, ring->idx, idx, + skb_queue_len(&ring->queue)); ieee80211_stop_queue(hw, skb_get_queue_mapping(skb)); } @@ -1497,7 +1487,7 @@ static int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev) err = _rtl_pci_init_trx_ring(hw); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("tx ring initialization failed")); + "tx ring initialization failed\n"); return err; } @@ -1519,12 +1509,12 @@ static int rtl_pci_start(struct ieee80211_hw *hw) err = rtlpriv->cfg->ops->hw_init(hw); if (err) { RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Failed to config hardware!\n")); + "Failed to config hardware!\n"); return err; } rtlpriv->cfg->ops->enable_interrupt(hw); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("enable_interrupt OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "enable_interrupt OK\n"); rtl_init_rx_config(hw); @@ -1535,7 +1525,7 @@ static int rtl_pci_start(struct ieee80211_hw *hw) rtlpci->up_first_time = false; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "OK\n"); return 0; } @@ -1622,20 +1612,20 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, switch (revisionid) { case RTL_PCI_REVISION_ID_8192PCIE: RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("8192 PCI-E is found - " - "vid/did=%x/%x\n", venderid, deviceid)); + "8192 PCI-E is found - vid/did=%x/%x\n", + venderid, deviceid); rtlhal->hw_type = HARDWARE_TYPE_RTL8192E; break; case RTL_PCI_REVISION_ID_8192SE: RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("8192SE is found - " - "vid/did=%x/%x\n", venderid, deviceid)); + "8192SE is found - vid/did=%x/%x\n", + venderid, deviceid); rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE; break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Err: Unknown device - " - "vid/did=%x/%x\n", venderid, deviceid)); + "Err: Unknown device - vid/did=%x/%x\n", + venderid, deviceid); rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE; break; @@ -1646,18 +1636,18 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, deviceid == RTL_PCI_8188CE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8192CE; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("8192C PCI-E is found - " - "vid/did=%x/%x\n", venderid, deviceid)); + "8192C PCI-E is found - vid/did=%x/%x\n", + venderid, deviceid); } else if (deviceid == RTL_PCI_8192DE_DID || deviceid == RTL_PCI_8192DE_DID2) { rtlhal->hw_type = HARDWARE_TYPE_RTL8192DE; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("8192D PCI-E is found - " - "vid/did=%x/%x\n", venderid, deviceid)); + "8192D PCI-E is found - vid/did=%x/%x\n", + venderid, deviceid); } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Err: Unknown device -" - " vid/did=%x/%x\n", venderid, deviceid)); + "Err: Unknown device - vid/did=%x/%x\n", + venderid, deviceid); rtlhal->hw_type = RTL_DEFAULT_HARDWARE_TYPE; } @@ -1665,19 +1655,18 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE) { if (revisionid == 0 || revisionid == 1) { if (revisionid == 0) { - RT_TRACE(rtlpriv, COMP_INIT, - DBG_LOUD, ("Find 92DE MAC0.\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "Find 92DE MAC0\n"); rtlhal->interfaceindex = 0; } else if (revisionid == 1) { RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Find 92DE MAC1.\n")); + "Find 92DE MAC1\n"); rtlhal->interfaceindex = 1; } } else { RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Unknown device - " - "VendorID/DeviceID=%x/%x, Revision=%x\n", - venderid, deviceid, revisionid)); + "Unknown device - VendorID/DeviceID=%x/%x, Revision=%x\n", + venderid, deviceid, revisionid); rtlhal->interfaceindex = 0; } } @@ -1693,8 +1682,8 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, if (bridge_pdev->vendor == pcibridge_vendors[tmp]) { pcipriv->ndis_adapter.pcibridge_vendor = tmp; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Pci Bridge Vendor is found index:" - " %d\n", tmp)); + "Pci Bridge Vendor is found index: %d\n", + tmp); break; } } @@ -1723,23 +1712,21 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, } RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("pcidev busnumber:devnumber:funcnumber:" - "vendor:link_ctl %d:%d:%d:%x:%x\n", - pcipriv->ndis_adapter.busnumber, - pcipriv->ndis_adapter.devnumber, - pcipriv->ndis_adapter.funcnumber, - pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg)); + "pcidev busnumber:devnumber:funcnumber:vendor:link_ctl %d:%d:%d:%x:%x\n", + pcipriv->ndis_adapter.busnumber, + pcipriv->ndis_adapter.devnumber, + pcipriv->ndis_adapter.funcnumber, + pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg); RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("pci_bridge busnumber:devnumber:funcnumber:vendor:" - "pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n", - pcipriv->ndis_adapter.pcibridge_busnum, - pcipriv->ndis_adapter.pcibridge_devnum, - pcipriv->ndis_adapter.pcibridge_funcnum, - pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor], - pcipriv->ndis_adapter.pcibridge_pciehdr_offset, - pcipriv->ndis_adapter.pcibridge_linkctrlreg, - pcipriv->ndis_adapter.amd_l1_patch)); + "pci_bridge busnumber:devnumber:funcnumber:vendor:pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n", + pcipriv->ndis_adapter.pcibridge_busnum, + pcipriv->ndis_adapter.pcibridge_devnum, + pcipriv->ndis_adapter.pcibridge_funcnum, + pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor], + pcipriv->ndis_adapter.pcibridge_pciehdr_offset, + pcipriv->ndis_adapter.pcibridge_linkctrlreg, + pcipriv->ndis_adapter.amd_l1_patch); rtl_pci_parse_configuration(pdev, hw); @@ -1828,10 +1815,9 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, } RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("mem mapped space: start: 0x%08lx len:%08lx " - "flags:%08lx, after map:0x%08lx\n", - pmem_start, pmem_len, pmem_flags, - rtlpriv->io.pci_mem_start)); + "mem mapped space: start: 0x%08lx len:%08lx flags:%08lx, after map:0x%08lx\n", + pmem_start, pmem_len, pmem_flags, + rtlpriv->io.pci_mem_start); /* Disable Clk Request */ pci_write_config_byte(pdev, 0x81, 0); @@ -1851,8 +1837,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, rtlpriv->cfg->ops->read_eeprom_info(hw); if (rtlpriv->cfg->ops->init_sw_vars(hw)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't init_sw_vars.\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n"); goto fail3; } @@ -1865,22 +1850,21 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, err = rtl_init_core(hw); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't allocate sw for mac80211.\n")); + "Can't allocate sw for mac80211\n"); goto fail3; } /* Init PCI sw */ err = !rtl_pci_init(hw, pdev); if (err) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to init PCI.\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Failed to init PCI\n"); goto fail3; } err = ieee80211_register_hw(hw); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't register mac80211 hw.\n")); + "Can't register mac80211 hw\n"); goto fail3; } else { rtlpriv->mac80211.mac80211_registered = 1; @@ -1889,7 +1873,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, err = sysfs_create_group(&pdev->dev.kobj, &rtl_attribute_group); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("failed to create sysfs device attributes\n")); + "failed to create sysfs device attributes\n"); goto fail3; } @@ -1901,8 +1885,8 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, IRQF_SHARED, KBUILD_MODNAME, hw); if (err) { RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("%s: failed to register IRQ handler\n", - wiphy_name(hw->wiphy))); + "%s: failed to register IRQ handler\n", + wiphy_name(hw->wiphy)); goto fail3; } else { rtlpci->irq_alloc = 1; diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index 130fdd99d57..a36dc3d5e04 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c @@ -44,7 +44,7 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw) if (is_hal_stop(rtlhal)) RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Driver is already down!\n")); + "Driver is already down!\n"); /*<2> Enable Adapter */ rtlpriv->cfg->ops->hw_init(hw); @@ -120,7 +120,7 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } @@ -176,7 +176,7 @@ void rtl_ips_nic_off_wq_callback(void *data) if (mac->opmode != NL80211_IFTYPE_STATION) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("not station return\n")); + "not station return\n"); return; } @@ -207,7 +207,7 @@ void rtl_ips_nic_off_wq_callback(void *data) (mac->link_state == MAC80211_NOLINK) && !mac->act_scanning) { RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("IPSEnter(): Turn off RF.\n")); + "IPSEnter(): Turn off RF\n"); ppsc->inactive_pwrstate = ERFOFF; ppsc->in_powersavemode = true; @@ -280,8 +280,7 @@ static bool rtl_get_fwlps_doze(struct ieee80211_hw *hw) if (ps_timediff < 2000) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Delay enter Fw LPS for DHCP, ARP," - " or EAPOL exchanging state.\n")); + "Delay enter Fw LPS for DHCP, ARP, or EAPOL exchanging state\n"); return false; } @@ -328,8 +327,8 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) bool fw_current_inps; if (ppsc->dot11_psmode == EACTIVE) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("FW LPS leave ps_mode:%x\n", - FW_PS_ACTIVE_MODE)); + "FW LPS leave ps_mode:%x\n", + FW_PS_ACTIVE_MODE); rpwm_val = 0x0C; /* RF on */ fw_pwrmode = FW_PS_ACTIVE_MODE; @@ -347,8 +346,8 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) } else { if (rtl_get_fwlps_doze(hw)) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("FW LPS enter ps_mode:%x\n", - ppsc->fwctrl_psmode)); + "FW LPS enter ps_mode:%x\n", + ppsc->fwctrl_psmode); rpwm_val = 0x02; /* RF off */ fw_current_inps = true; @@ -402,7 +401,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw) if (mac->cnt_after_linked >= 2) { if (ppsc->dot11_psmode == EACTIVE) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Enter 802.11 power save mode...\n")); + "Enter 802.11 power save mode...\n"); rtl_lps_set_psmode(hw, EAUTOPS); } @@ -434,7 +433,7 @@ void rtl_lps_leave(struct ieee80211_hw *hw) } RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Busy Traffic,Leave 802.11 power save..\n")); + "Busy Traffic,Leave 802.11 power save..\n"); rtl_lps_set_psmode(hw, EACTIVE); } @@ -518,8 +517,8 @@ void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len) queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_work, MSECS(5)); } else { - RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, ("u_bufferd: %x, " - "m_buffered: %x\n", u_buffed, m_buffed)); + RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, + "u_bufferd: %x, m_buffered: %x\n", u_buffed, m_buffed); } } @@ -607,8 +606,8 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw) * sleep = dtim_period, that meaons, we should * awake before every dtim */ RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - ("dtim_counter:%x will sleep :%d" - " beacon_intv\n", rtlpriv->psc.dtim_counter, sleep_intv)); + "dtim_counter:%x will sleep :%d beacon_intv\n", + rtlpriv->psc.dtim_counter, sleep_intv); /* we tested that 40ms is enough for sw & hw sw delay */ queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_rfon_wq, diff --git a/drivers/net/wireless/rtlwifi/rc.c b/drivers/net/wireless/rtlwifi/rc.c index 539df66dce0..4f560d6a386 100644 --- a/drivers/net/wireless/rtlwifi/rc.c +++ b/drivers/net/wireless/rtlwifi/rc.c @@ -251,7 +251,7 @@ static void *rtl_rate_alloc_sta(void *ppriv, rate_priv = kzalloc(sizeof(struct rtl_rate_priv), gfp); if (!rate_priv) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Unable to allocate private rc structure\n")); + "Unable to allocate private rc structure\n"); return NULL; } diff --git a/drivers/net/wireless/rtlwifi/regd.c b/drivers/net/wireless/rtlwifi/regd.c index 9fedb1f7091..c263df21760 100644 --- a/drivers/net/wireless/rtlwifi/regd.c +++ b/drivers/net/wireless/rtlwifi/regd.c @@ -398,13 +398,11 @@ int rtl_regd_init(struct ieee80211_hw *hw, rtlpriv->regd.country_code = rtlpriv->efuse.channel_plan; RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE, - (KERN_DEBUG "rtl: EEPROM regdomain: 0x%0x\n", - rtlpriv->regd.country_code)); + "rtl: EEPROM regdomain: 0x%0x\n", rtlpriv->regd.country_code); if (rtlpriv->regd.country_code >= COUNTRY_CODE_MAX) { RT_TRACE(rtlpriv, COMP_REGD, DBG_DMESG, - (KERN_DEBUG "rtl: EEPROM indicates invalid contry code" - "world wide 13 should be used\n")); + "rtl: EEPROM indicates invalid contry code, world wide 13 should be used\n"); rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13; } @@ -420,8 +418,8 @@ int rtl_regd_init(struct ieee80211_hw *hw, } RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE, - (KERN_DEBUG "rtl: Country alpha2 being used: %c%c\n", - rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1])); + "rtl: Country alpha2 being used: %c%c\n", + rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1]); _rtl_regd_init_wiphy(&rtlpriv->regd, wiphy, reg_notifier); @@ -433,7 +431,7 @@ int rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_REGD, DBG_LOUD, ("\n")); + RT_TRACE(rtlpriv, COMP_REGD, DBG_LOUD, "\n"); return _rtl_reg_notifier_apply(wiphy, request, &rtlpriv->regd); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index 72a98cab6f6..bf94cbfb4e3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c @@ -246,16 +246,15 @@ static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2); RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("cnt_parity_fail = %d, cnt_rate_illegal = %d, " - "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", - falsealm_cnt->cnt_parity_fail, - falsealm_cnt->cnt_rate_illegal, - falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail)); + "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", + falsealm_cnt->cnt_parity_fail, + falsealm_cnt->cnt_rate_illegal, + falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail); RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", - falsealm_cnt->cnt_ofdm_fail, - falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all)); + "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", + falsealm_cnt->cnt_ofdm_fail, + falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all); } static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw) @@ -313,8 +312,8 @@ static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw) dm_digtable.backoff_val; RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("rssi_val_min = %x backoff_val %x\n", - dm_digtable.rssi_val_min, dm_digtable.backoff_val)); + "rssi_val_min = %x backoff_val %x\n", + dm_digtable.rssi_val_min, dm_digtable.backoff_val); rtl92c_dm_write_dig(hw); } @@ -364,10 +363,9 @@ static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) } RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("curmultista_connectstate = " - "%x dig_ext_port_stage %x\n", - dm_digtable.curmultista_connectstate, - dm_digtable.dig_ext_port_stage)); + "curmultista_connectstate = %x dig_ext_port_stage %x\n", + dm_digtable.curmultista_connectstate, + dm_digtable.dig_ext_port_stage); } static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw) @@ -375,10 +373,9 @@ static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("presta_connectstate = %x," - " cursta_connectctate = %x\n", - dm_digtable.presta_connectstate, - dm_digtable.cursta_connectctate)); + "presta_connectstate = %x, cursta_connectctate = %x\n", + dm_digtable.presta_connectstate, + dm_digtable.cursta_connectctate); if (dm_digtable.presta_connectstate == dm_digtable.cursta_connectctate || dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT @@ -464,11 +461,11 @@ static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) dm_digtable.pre_cck_pd_state = dm_digtable.cur_cck_pd_state; } - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("CCKPDStage=%x\n", dm_digtable.cur_cck_pd_state)); + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, "CCKPDStage=%x\n", + dm_digtable.cur_cck_pd_state); - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("is92C=%x\n", IS_92C_SERIAL(rtlhal->version))); + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, "is92C=%x\n", + IS_92C_SERIAL(rtlhal->version)); } static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) @@ -519,10 +516,9 @@ void rtl92c_dm_write_dig(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("cur_igvalue = 0x%x, " - "pre_igvalue = 0x%x, backoff_val = %d\n", - dm_digtable.cur_igvalue, dm_digtable.pre_igvalue, - dm_digtable.backoff_val)); + "cur_igvalue = 0x%x, pre_igvalue = 0x%x, backoff_val = %d\n", + dm_digtable.cur_igvalue, dm_digtable.pre_igvalue, + dm_digtable.backoff_val); if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) { rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, @@ -676,15 +672,14 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw rtlpriv->dm.txpower_trackinginit = true; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("rtl92c_dm_txpower_tracking_callback_thermalmeter\n")); + "rtl92c_dm_txpower_tracking_callback_thermalmeter\n"); thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f); RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " - "eeprom_thermalmeter 0x%x\n", - thermalvalue, rtlpriv->dm.thermalvalue, - rtlefuse->eeprom_thermalmeter)); + "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n", + thermalvalue, rtlpriv->dm.thermalvalue, + rtlefuse->eeprom_thermalmeter); rtl92c_phy_ap_calibrate(hw, (thermalvalue - rtlefuse->eeprom_thermalmeter)); @@ -702,10 +697,9 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw ofdm_index_old[0] = (u8) i; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Initial pathA ele_d reg0x%x = 0x%lx, " - "ofdm_index=0x%x\n", + "Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index=0x%x\n", ROFDM0_XATXIQIMBALANCE, - ele_d, ofdm_index_old[0])); + ele_d, ofdm_index_old[0]); break; } } @@ -719,11 +713,10 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw MASKOFDM_D)) { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, - DBG_LOUD, - ("Initial pathB ele_d reg0x%x = " - "0x%lx, ofdm_index=0x%x\n", - ROFDM0_XBTXIQIMBALANCE, ele_d, - ofdm_index_old[1])); + DBG_LOUD, + "Initial pathB ele_d reg0x%x = 0x%lx, ofdm_index=0x%x\n", + ROFDM0_XBTXIQIMBALANCE, ele_d, + ofdm_index_old[1]); break; } } @@ -741,11 +734,10 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Initial reg0x%x = 0x%lx, " - "cck_index=0x%x, ch 14 %d\n", - RCCK0_TXFILTER2, temp_cck, - cck_index_old, - rtlpriv->dm.cck_inch14)); + "Initial reg0x%x = 0x%lx, cck_index=0x%x, ch 14 %d\n", + RCCK0_TXFILTER2, temp_cck, + cck_index_old, + rtlpriv->dm.cck_inch14); break; } } else { @@ -757,11 +749,10 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Initial reg0x%x = 0x%lx, " - "cck_index=0x%x, ch14 %d\n", - RCCK0_TXFILTER2, temp_cck, - cck_index_old, - rtlpriv->dm.cck_inch14)); + "Initial reg0x%x = 0x%lx, cck_index=0x%x, ch14 %d\n", + RCCK0_TXFILTER2, temp_cck, + cck_index_old, + rtlpriv->dm.cck_inch14); break; } } @@ -790,12 +781,10 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw (rtlpriv->dm.thermalvalue_iqk - thermalvalue); RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " - "eeprom_thermalmeter 0x%x delta 0x%x " - "delta_lck 0x%x delta_iqk 0x%x\n", + "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x delta 0x%x delta_lck 0x%x delta_iqk 0x%x\n", thermalvalue, rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter, delta, delta_lck, - delta_iqk)); + delta_iqk); if (delta_lck > 1) { rtlpriv->dm.thermalvalue_lck = thermalvalue; @@ -815,18 +804,15 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw if (is2t) { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("temp OFDM_A_index=0x%x, " - "OFDM_B_index=0x%x," - "cck_index=0x%x\n", - rtlpriv->dm.ofdm_index[0], - rtlpriv->dm.ofdm_index[1], - rtlpriv->dm.cck_index)); + "temp OFDM_A_index=0x%x, OFDM_B_index=0x%x, cck_index=0x%x\n", + rtlpriv->dm.ofdm_index[0], + rtlpriv->dm.ofdm_index[1], + rtlpriv->dm.cck_index); } else { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("temp OFDM_A_index=0x%x," - "cck_index=0x%x\n", - rtlpriv->dm.ofdm_index[0], - rtlpriv->dm.cck_index)); + "temp OFDM_A_index=0x%x, cck_index=0x%x\n", + rtlpriv->dm.ofdm_index[0], + rtlpriv->dm.cck_index); } if (thermalvalue > rtlefuse->eeprom_thermalmeter) { @@ -918,16 +904,13 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw if (is2t) { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("new OFDM_A_index=0x%x, " - "OFDM_B_index=0x%x," - "cck_index=0x%x\n", - ofdm_index[0], ofdm_index[1], - cck_index)); + "new OFDM_A_index=0x%x, OFDM_B_index=0x%x, cck_index=0x%x\n", + ofdm_index[0], ofdm_index[1], + cck_index); } else { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("new OFDM_A_index=0x%x," - "cck_index=0x%x\n", - ofdm_index[0], cck_index)); + "new OFDM_A_index=0x%x, cck_index=0x%x\n", + ofdm_index[0], cck_index); } } @@ -1085,7 +1068,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw rtlpriv->dm.thermalvalue = thermalvalue; } - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("<===\n")); + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "<===\n"); } @@ -1098,8 +1081,8 @@ static void rtl92c_dm_initialize_txpower_tracking_thermalmeter( rtlpriv->dm.txpower_trackinginit = false; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("pMgntInfo->txpower_tracking = %d\n", - rtlpriv->dm.txpower_tracking)); + "pMgntInfo->txpower_tracking = %d\n", + rtlpriv->dm.txpower_tracking); } static void rtl92c_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) @@ -1125,12 +1108,12 @@ static void rtl92c_dm_check_txpower_tracking_thermal_meter( rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, RFREG_OFFSET_MASK, 0x60); RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Trigger 92S Thermal Meter!!\n")); + "Trigger 92S Thermal Meter!!\n"); tm_trigger = 1; return; } else { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Schedule TxPowerTracking direct call!!\n")); + "Schedule TxPowerTracking direct call!!\n"); rtl92c_dm_txpower_tracking_directcall(hw); tm_trigger = 0; } @@ -1169,13 +1152,13 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) if (is_hal_stop(rtlhal)) { RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("<---- driver is going to unload\n")); + "<---- driver is going to unload\n"); return; } if (!rtlpriv->dm.useramask) { RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("<---- driver does not control rate adaptive mask\n")); + "<---- driver does not control rate adaptive mask\n"); return; } @@ -1210,14 +1193,13 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) p_ra->ratr_state = DM_RATR_STA_LOW; if (p_ra->pre_ratr_state != p_ra->ratr_state) { + RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, "RSSI = %ld\n", + rtlpriv->dm.undecorated_smoothed_pwdb); RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("RSSI = %ld\n", - rtlpriv->dm.undecorated_smoothed_pwdb)); + "RSSI_LEVEL = %d\n", p_ra->ratr_state); RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("RSSI_LEVEL = %d\n", p_ra->ratr_state)); - RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("PreState = %d, CurState = %d\n", - p_ra->pre_ratr_state, p_ra->ratr_state)); + "PreState = %d, CurState = %d\n", + p_ra->pre_ratr_state, p_ra->ratr_state); rcu_read_lock(); sta = ieee80211_find_sta(mac->vif, mac->bssid); @@ -1316,8 +1298,7 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw) if (((mac->link_state == MAC80211_NOLINK)) && (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { dm_pstable.rssi_val_min = 0; - RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - ("Not connected to any\n")); + RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, "Not connected to any\n"); } if (mac->link_state == MAC80211_LINKED) { @@ -1325,22 +1306,22 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw) dm_pstable.rssi_val_min = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - ("AP Client PWDB = 0x%lx\n", - dm_pstable.rssi_val_min)); + "AP Client PWDB = 0x%lx\n", + dm_pstable.rssi_val_min); } else { dm_pstable.rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - ("STA Default Port PWDB = 0x%lx\n", - dm_pstable.rssi_val_min)); + "STA Default Port PWDB = 0x%lx\n", + dm_pstable.rssi_val_min); } } else { dm_pstable.rssi_val_min = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - ("AP Ext Port PWDB = 0x%lx\n", - dm_pstable.rssi_val_min)); + "AP Ext Port PWDB = 0x%lx\n", + dm_pstable.rssi_val_min); } if (IS_92C_SERIAL(rtlhal->version)) @@ -1381,7 +1362,7 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) if ((mac->link_state < MAC80211_LINKED) && (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("Not connected to any\n")); + "Not connected to any\n"); rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; @@ -1394,28 +1375,28 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) undecorated_smoothed_pwdb = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Client PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "AP Client PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } else { undecorated_smoothed_pwdb = rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("STA Default Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "STA Default Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } } else { undecorated_smoothed_pwdb = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Ext Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "AP Ext Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n")); + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); } else if ((undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && (undecorated_smoothed_pwdb >= @@ -1423,18 +1404,18 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n")); + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); } else if (undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_NORMAL\n")); + "TXHIGHPWRLEVEL_NORMAL\n"); } if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("PHY_SetTxPowerLevel8192S() Channel = %d\n", - rtlphy->current_channel)); + "PHY_SetTxPowerLevel8192S() Channel = %d\n", + rtlphy->current_channel); rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index 5401b32733d..12c025bf53b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c @@ -172,7 +172,7 @@ static void _rtl92c_write_fw(struct ieee80211_hw *hw, struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); u8 *bufferPtr = (u8 *) buffer; - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size)); + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes\n", size); if (IS_CHIP_VER_B(version)) { u32 pageNums, remainSize; @@ -186,7 +186,7 @@ static void _rtl92c_write_fw(struct ieee80211_hw *hw, if (pageNums > 4) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Page numbers should not greater then 4\n")); + "Page numbers should not greater then 4\n"); } for (page = 0; page < pageNums; page++) { @@ -219,13 +219,12 @@ static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw) if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("chksum report faill ! REG_MCUFWDL:0x%08x .\n", - value32)); + "chksum report faill ! REG_MCUFWDL:0x%08x\n", value32); return -EIO; } RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32)); + "Checksum report OK ! REG_MCUFWDL:0x%08x\n", value32); value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); value32 |= MCUFWDL_RDY; @@ -238,9 +237,8 @@ static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw) value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); if (value32 & WINTINI_RDY) { RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - ("Polling FW ready success!!" - " REG_MCUFWDL:0x%08x .\n", - value32)); + "Polling FW ready success!! REG_MCUFWDL:0x%08x\n", + value32); return 0; } @@ -249,7 +247,7 @@ static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw) } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT); RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32)); + "Polling FW ready fail!! REG_MCUFWDL:0x%08x\n", value32); return -EIO; } @@ -272,10 +270,10 @@ int rtl92c_download_fw(struct ieee80211_hw *hw) if (IS_FW_HEADER_EXIST(pfwheader)) { RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - ("Firmware Version(%d), Signature(%#x),Size(%d)\n", + "Firmware Version(%d), Signature(%#x),Size(%d)\n", le16_to_cpu(pfwheader->version), le16_to_cpu(pfwheader->signature), - (uint)sizeof(struct rtl92c_firmware_header))); + (uint)sizeof(struct rtl92c_firmware_header)); pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header); fwsize = fwsize - sizeof(struct rtl92c_firmware_header); @@ -287,10 +285,10 @@ int rtl92c_download_fw(struct ieee80211_hw *hw) if (_rtl92c_fw_free_to_go(hw)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Firmware is not ready to run!\n")); + "Firmware is not ready to run!\n"); } else { RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - ("Firmware is ready to run!\n")); + "Firmware is ready to run!\n"); } return 0; @@ -328,22 +326,22 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, unsigned long flag; u8 idx; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("come in\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n"); while (true) { spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); if (rtlhal->h2c_setinprogress) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("H2C set in progress! Wait to set.." - "element_id(%d).\n", element_id)); + "H2C set in progress! Wait to set..element_id(%d)\n", + element_id); while (rtlhal->h2c_setinprogress) { spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); h2c_waitcounter++; RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Wait 100 us (%d times)...\n", - h2c_waitcounter)); + "Wait 100 us (%d times)...\n", + h2c_waitcounter); udelay(100); if (h2c_waitcounter > 1000) @@ -363,8 +361,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, wait_writeh2c_limmit--; if (wait_writeh2c_limmit == 0) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Write H2C fail because no trigger " - "for FW INT!\n")); + "Write H2C fail because no trigger for FW INT!\n"); break; } @@ -388,7 +385,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } @@ -398,8 +395,8 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, wait_h2c_limmit--; if (wait_h2c_limmit == 0) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Wating too long for FW read " - "clear HMEBox(%d)!\n", boxnum)); + "Waiting too long for FW read clear HMEBox(%d)!\n", + boxnum); break; } @@ -408,14 +405,14 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum); u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF); RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Wating for FW read clear HMEBox(%d)!!! " - "0x1BF = %2x\n", boxnum, u1b_tmp)); + "Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n", + boxnum, u1b_tmp); } if (!isfw_read) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Write H2C register BOX[%d] fail!!!!! " - "Fw do not read.\n", boxnum)); + "Write H2C register BOX[%d] fail!!!!! Fw do not read\n", + boxnum); break; } @@ -423,8 +420,8 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, memset(boxextcontent, 0, sizeof(boxextcontent)); boxcontent[0] = element_id; RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Write element_id box_reg(%4x) = %2x\n", - box_reg, element_id)); + "Write element_id box_reg(%4x) = %2x\n", + box_reg, element_id); switch (cmd_len) { case 1: @@ -493,7 +490,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } @@ -504,15 +501,15 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, rtlhal->last_hmeboxnum = 0; RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("pHalData->last_hmeboxnum = %d\n", - rtlhal->last_hmeboxnum)); + "pHalData->last_hmeboxnum = %d\n", + rtlhal->last_hmeboxnum); } spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); rtlhal->h2c_setinprogress = false; spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n"); } void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, @@ -562,7 +559,7 @@ void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) u8 u1_h2c_set_pwrmode[3] = {0}; struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode)); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode); SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode); SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1); @@ -798,14 +795,14 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished) if (dlok) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Set RSVD page location to Fw.\n")); + "Set RSVD page location to Fw\n"); RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, "H2C_RSVDPAGE", u1RsvdPageLoc, 3); rtl92c_fill_h2c_cmd(hw, H2C_RSVDPAGE, sizeof(u1RsvdPageLoc), u1RsvdPageLoc); } else RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Set RSVD page location to Fw FAIL!!!!!!.\n")); + "Set RSVD page location to Fw FAIL!!!!!!\n"); } EXPORT_SYMBOL(rtl92c_set_fw_rsvdpagepkt); diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c index 1f07558debf..8ab93a69f33 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c @@ -42,16 +42,15 @@ u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) struct rtl_priv *rtlpriv = rtl_priv(hw); u32 returnvalue, originalvalue, bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "bitmask(%#x)\n", regaddr, - bitmask)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", + regaddr, bitmask); originalvalue = rtl_read_dword(rtlpriv, regaddr); bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); returnvalue = (originalvalue & bitmask) >> bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("BBR MASK=0x%x " - "Addr[0x%x]=0x%x\n", bitmask, - regaddr, originalvalue)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "BBR MASK=0x%x Addr[0x%x]=0x%x\n", + bitmask, regaddr, originalvalue); return returnvalue; @@ -64,9 +63,9 @@ void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); u32 originalvalue, bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," - " data(%#x)\n", regaddr, bitmask, - data)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); if (bitmask != MASKDWORD) { originalvalue = rtl_read_dword(rtlpriv, regaddr); @@ -76,9 +75,9 @@ void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, rtl_write_dword(rtlpriv, regaddr, data); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," - " data(%#x)\n", regaddr, bitmask, - data)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); } EXPORT_SYMBOL(rtl92c_phy_set_bb_reg); @@ -114,7 +113,7 @@ u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, offset &= 0x3f; newoffset = offset; if (RT_CANNOT_IO(hw)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("return all one\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "return all one\n"); return 0xFFFFFFFF; } tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); @@ -144,9 +143,8 @@ u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, else retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, BLSSIREADBACKDATA); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rflssi_readback, - retvalue)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rflssi_readback, retvalue); return retvalue; } EXPORT_SYMBOL(_rtl92c_phy_rf_serial_read); @@ -162,16 +160,15 @@ void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; if (RT_CANNOT_IO(hw)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("stop\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "stop\n"); return; } offset &= 0x3f; newoffset = offset; data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rf3wire_offset, - data_and_addr)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rf3wire_offset, data_and_addr); } EXPORT_SYMBOL(_rtl92c_phy_rf_serial_write); @@ -216,16 +213,16 @@ bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw) struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); bool rtstatus; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("==>\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "==>\n"); rtstatus = rtlpriv->cfg->ops->config_bb_with_headerfile(hw, BASEBAND_CONFIG_PHY_REG); if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!\n"); return false; } if (rtlphy->rf_type == RF_1T2R) { _rtl92c_phy_bb_config_1t(hw); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Config to 1T!!\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n"); } if (rtlefuse->autoload_failflag == false) { rtlphy->pwrgroup_cnt = 0; @@ -233,13 +230,13 @@ bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw) BASEBAND_CONFIG_PHY_REG); } if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!\n"); return false; } rtstatus = rtlpriv->cfg->ops->config_bb_with_headerfile(hw, BASEBAND_CONFIG_AGC_TAB); if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("AGC Table Fail\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n"); return false; } rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw, @@ -260,114 +257,114 @@ void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, if (regaddr == RTXAGC_A_RATE18_06) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0])); + "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0]); } if (regaddr == RTXAGC_A_RATE54_24) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1])); + "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1]); } if (regaddr == RTXAGC_A_CCK1_MCS32) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6])); + "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6]); } if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7])); + "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7]); } if (regaddr == RTXAGC_A_MCS03_MCS00) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2])); + "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2]); } if (regaddr == RTXAGC_A_MCS07_MCS04) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3])); + "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3]); } if (regaddr == RTXAGC_A_MCS11_MCS08) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4])); + "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4]); } if (regaddr == RTXAGC_A_MCS15_MCS12) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5])); + "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5]); } if (regaddr == RTXAGC_B_RATE18_06) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8])); + "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8]); } if (regaddr == RTXAGC_B_RATE54_24) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9])); + "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9]); } if (regaddr == RTXAGC_B_CCK1_55_MCS32) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14])); + "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14]); } if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15])); + "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15]); } if (regaddr == RTXAGC_B_MCS03_MCS00) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10])); + "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10]); } if (regaddr == RTXAGC_B_MCS07_MCS04) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11])); + "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11]); } if (regaddr == RTXAGC_B_MCS11_MCS08) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12])); + "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12]); } if (regaddr == RTXAGC_B_MCS15_MCS12) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13])); + "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13]); rtlphy->pwrgroup_cnt++; } @@ -389,12 +386,11 @@ void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Default initial gain (c50=0x%x, " - "c58=0x%x, c60=0x%x, c68=0x%x\n", - rtlphy->default_initialgain[0], - rtlphy->default_initialgain[1], - rtlphy->default_initialgain[2], - rtlphy->default_initialgain[3])); + "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n", + rtlphy->default_initialgain[0], + rtlphy->default_initialgain[1], + rtlphy->default_initialgain[2], + rtlphy->default_initialgain[3]); rtlphy->framesync = (u8) rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, MASKBYTE0); @@ -402,8 +398,8 @@ void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) ROFDM0_RXDETECTOR2, MASKDWORD); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Default framesync (0x%x) = 0x%x\n", - ROFDM0_RXDETECTOR3, rtlphy->framesync)); + "Default framesync (0x%x) = 0x%x\n", + ROFDM0_RXDETECTOR3, rtlphy->framesync); } void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) @@ -615,8 +611,8 @@ bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm) else ofdmtxpwridx = 0; RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE, - ("%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n", - power_indbm, ccktxpwridx, ofdmtxpwridx)); + "%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n", + power_indbm, ccktxpwridx, ofdmtxpwridx); for (idx = 0; idx < 14; idx++) { for (rf_path = 0; rf_path < 2; rf_path++) { rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx; @@ -710,7 +706,7 @@ void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Unknown Scan Backup operation.\n")); + "Unknown Scan Backup operation\n"); break; } } @@ -732,7 +728,7 @@ void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, rtlpriv->cfg->ops->phy_set_bw_mode_callback(hw); } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("FALSE driver sleep or unload\n")); + "FALSE driver sleep or unload\n"); rtlphy->set_bwmode_inprogress = false; rtlphy->current_chan_bw = tmp_bw; } @@ -747,7 +743,7 @@ void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw) u32 delay; RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, - ("switch to channel%d\n", rtlphy->current_channel)); + "switch to channel%d\n", rtlphy->current_channel); if (is_hal_stop(rtlhal)) return; do { @@ -765,7 +761,7 @@ void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw) } break; } while (true); - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); } EXPORT_SYMBOL(rtl92c_phy_sw_chnl_callback); @@ -787,12 +783,11 @@ u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw) if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { rtl92c_phy_sw_chnl_callback(hw); RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, - ("sw_chnl_inprogress false schdule workitem\n")); + "sw_chnl_inprogress false schdule workitem\n"); rtlphy->sw_chnl_inprogress = false; } else { RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, - ("sw_chnl_inprogress false driver sleep or" - " unload\n")); + "sw_chnl_inprogress false driver sleep or unload\n"); rtlphy->sw_chnl_inprogress = false; } return 1; @@ -916,7 +911,7 @@ bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } @@ -1920,23 +1915,23 @@ bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) bool postprocessing = false; RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("-->IO Cmd(%#x), set_io_inprogress(%d)\n", - iotype, rtlphy->set_io_inprogress)); + "-->IO Cmd(%#x), set_io_inprogress(%d)\n", + iotype, rtlphy->set_io_inprogress); do { switch (iotype) { case IO_CMD_RESUME_DM_BY_SCAN: RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("[IO CMD] Resume DM after scan.\n")); + "[IO CMD] Resume DM after scan\n"); postprocessing = true; break; case IO_CMD_PAUSE_DM_BY_SCAN: RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("[IO CMD] Pause DM before scan.\n")); + "[IO CMD] Pause DM before scan\n"); postprocessing = true; break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } while (false); @@ -1947,7 +1942,7 @@ bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) return false; } rtl92c_phy_set_io(hw); - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, ("<--IO Type(%#x)\n", iotype)); + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<--IO Type(%#x)\n", iotype); return true; } EXPORT_SYMBOL(rtl92c_phy_set_io_cmd); @@ -1958,8 +1953,8 @@ void rtl92c_phy_set_io(struct ieee80211_hw *hw) struct rtl_phy *rtlphy = &(rtlpriv->phy); RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("--->Cmd(%#x), set_io_inprogress(%d)\n", - rtlphy->current_io_type, rtlphy->set_io_inprogress)); + "--->Cmd(%#x), set_io_inprogress(%d)\n", + rtlphy->current_io_type, rtlphy->set_io_inprogress); switch (rtlphy->current_io_type) { case IO_CMD_RESUME_DM_BY_SCAN: dm_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1; @@ -1973,12 +1968,12 @@ void rtl92c_phy_set_io(struct ieee80211_hw *hw) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } rtlphy->set_io_inprogress = false; - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("<---(%#x)\n", rtlphy->current_io_type)); + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<---(%#x)\n", + rtlphy->current_io_type); } EXPORT_SYMBOL(rtl92c_phy_set_io); @@ -2018,7 +2013,7 @@ void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("Switch RF timeout !!!.\n")); + "Switch RF timeout !!!\n"); return; } rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c index 2df33e53e15..6730e683aba 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c @@ -54,7 +54,7 @@ void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw) if ((mac->link_state < MAC80211_LINKED) && (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("Not connected to any\n")); + "Not connected to any\n"); rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; @@ -67,28 +67,28 @@ void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw) undecorated_smoothed_pwdb = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Client PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "AP Client PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } else { undecorated_smoothed_pwdb = rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("STA Default Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "STA Default Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } } else { undecorated_smoothed_pwdb = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Ext Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "AP Ext Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n")); + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); } else if ((undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && (undecorated_smoothed_pwdb >= @@ -96,18 +96,18 @@ void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw) rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n")); + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); } else if (undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_NORMAL\n")); + "TXHIGHPWRLEVEL_NORMAL\n"); } if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("PHY_SetTxPowerLevel8192S() Channel = %d\n", - rtlphy->current_channel)); + "PHY_SetTxPowerLevel8192S() Channel = %d\n", + rtlphy->current_channel); rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 2156378de1e..4aa228fe96e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -141,7 +141,7 @@ void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) } default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } @@ -207,7 +207,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) u8 e_aci; RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("HW_VAR_SLOT_TIME %x\n", val[0])); + "HW_VAR_SLOT_TIME %x\n", val[0]); rtl_write_byte(rtlpriv, REG_SLOT, val[0]); @@ -246,8 +246,8 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) *val = min_spacing_to_set; RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", - mac->min_space_cfg)); + "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", + mac->min_space_cfg); rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, mac->min_space_cfg); @@ -261,8 +261,8 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) mac->min_space_cfg |= (density_to_set << 3); RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_SHORTGI_DENSITY: %#x\n", - mac->min_space_cfg)); + "Set HW_VAR_SHORTGI_DENSITY: %#x\n", + mac->min_space_cfg); rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, mac->min_space_cfg); @@ -310,8 +310,8 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) } RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_AMPDU_FACTOR: %#x\n", - factor_toset)); + "Set HW_VAR_AMPDU_FACTOR: %#x\n", + factor_toset); } break; } @@ -348,8 +348,8 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("HW_VAR_ACM_CTRL acm set " - "failed: eACI is %d\n", acm)); + "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", + acm); break; } } else { @@ -365,14 +365,14 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE, - ("SetHwReg8190pci(): [HW_VAR_ACM_CTRL] " - "Write 0x%X\n", acm_ctrl)); + "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", + acm_ctrl); rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); break; } @@ -507,8 +507,8 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) } default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case " - "not process\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "switch case not processed\n"); break; } } @@ -530,8 +530,8 @@ static bool _rtl92ce_llt_write(struct ieee80211_hw *hw, u32 address, u32 data) if (count > POLLING_LLT_THRESHOLD) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to polling write LLT done at " - "address %d!\n", address)); + "Failed to polling write LLT done at address %d!\n", + address); status = false; break; } @@ -669,18 +669,15 @@ static bool _rtl92ce_init_mac(struct ieee80211_hw *hw) udelay(2); retry = 0; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("reg0xec:%x:%x\n", - rtl_read_dword(rtlpriv, 0xEC), - bytetmp)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "reg0xec:%x:%x\n", + rtl_read_dword(rtlpriv, 0xEC), bytetmp); while ((bytetmp & BIT(0)) && retry < 1000) { retry++; udelay(50); bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("reg0xec:%x:%x\n", - rtl_read_dword(rtlpriv, - 0xEC), - bytetmp)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "reg0xec:%x:%x\n", + rtl_read_dword(rtlpriv, 0xEC), bytetmp); udelay(50); } @@ -864,13 +861,13 @@ void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw) u8 sec_reg_value; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", - rtlpriv->sec.pairwise_enc_algorithm, - rtlpriv->sec.group_enc_algorithm)); + "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", + rtlpriv->sec.pairwise_enc_algorithm, + rtlpriv->sec.group_enc_algorithm); if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("not open " - "hw encryption\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + "not open hw encryption\n"); return; } @@ -886,7 +883,7 @@ void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The SECR-value %x\n", sec_reg_value)); + "The SECR-value %x\n", sec_reg_value); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); @@ -910,7 +907,7 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) rtlpriv->intf_ops->disable_aspm(hw); rtstatus = _rtl92ce_init_mac(hw); if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Init MAC failed\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n"); err = 1; return err; } @@ -918,8 +915,7 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) err = rtl92c_download_fw(hw); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Failed to download FW. Init HW " - "without FW now..\n")); + "Failed to download FW. Init HW without FW now..\n"); err = 1; rtlhal->fw_ready = false; return err; @@ -968,12 +964,12 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) tmp_u1b = efuse_read_1byte(hw, 0x1FA); if (!(tmp_u1b & BIT(0))) { rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("PA BIAS path A\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "PA BIAS path A\n"); } if (!(tmp_u1b & BIT(1)) && is92c) { rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0F, 0x05); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("PA BIAS path B\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "PA BIAS path B\n"); } if (!(tmp_u1b & BIT(4))) { @@ -982,7 +978,7 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x80); udelay(10); rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x90); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("under 1.5V\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n"); } rtl92c_dm_init(hw); rtlpci->being_init_adapter = false; @@ -1008,23 +1004,23 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw) switch (version) { case VERSION_B_CHIP_92C: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_B_CHIP_92C.\n")); + "Chip Version ID: VERSION_B_CHIP_92C\n"); break; case VERSION_B_CHIP_88C: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_B_CHIP_88C.\n")); + "Chip Version ID: VERSION_B_CHIP_88C\n"); break; case VERSION_A_CHIP_92C: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_A_CHIP_92C.\n")); + "Chip Version ID: VERSION_A_CHIP_92C\n"); break; case VERSION_A_CHIP_88C: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_A_CHIP_88C.\n")); + "Chip Version ID: VERSION_A_CHIP_88C\n"); break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Chip Version ID: Unknown. Bug?\n")); + "Chip Version ID: Unknown. Bug?\n"); break; } @@ -1041,13 +1037,12 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw) default: rtlphy->rf_type = RF_1T1R; RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("ERROR RF_Type is set!!")); + "ERROR RF_Type is set!!\n"); break; } - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ? - "RF_2T2R" : "RF_1T1R")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Chip RF Type: %s\n", + rtlphy->rf_type == RF_2T2R ? "RF_2T2R" : "RF_1T1R"); return version; } @@ -1069,8 +1064,8 @@ static int _rtl92ce_set_media_status(struct ieee80211_hw *hw, _rtl92ce_disable_bcn_sub_func(hw); } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Set HW_VAR_MEDIA_STATUS: " - "No such media status(%x).\n", type)); + "Set HW_VAR_MEDIA_STATUS: No such media status(%x)\n", + type); } switch (type) { @@ -1078,27 +1073,27 @@ static int _rtl92ce_set_media_status(struct ieee80211_hw *hw, bt_msr |= MSR_NOLINK; ledaction = LED_CTL_LINK; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to NO LINK!\n")); + "Set Network type to NO LINK!\n"); break; case NL80211_IFTYPE_ADHOC: bt_msr |= MSR_ADHOC; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to Ad Hoc!\n")); + "Set Network type to Ad Hoc!\n"); break; case NL80211_IFTYPE_STATION: bt_msr |= MSR_INFRA; ledaction = LED_CTL_LINK; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to STA!\n")); + "Set Network type to STA!\n"); break; case NL80211_IFTYPE_AP: bt_msr |= MSR_AP; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to AP!\n")); + "Set Network type to AP!\n"); break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Network type %d not support!\n", type)); + "Network type %d not supported!\n", type); return 1; break; @@ -1300,7 +1295,7 @@ void rtl92ce_set_beacon_interval(struct ieee80211_hw *hw) u16 bcn_interval = mac->beacon_interval; RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, - ("beacon_interval:%d\n", bcn_interval)); + "beacon_interval:%d\n", bcn_interval); rtl92ce_disable_interrupt(hw); rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); rtl92ce_enable_interrupt(hw); @@ -1312,8 +1307,8 @@ void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, - ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr)); + RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, "add_msr:%x, rm_msr:%x\n", + add_msr, rm_msr); if (add_msr) rtlpci->irq_mask[0] |= add_msr; @@ -1567,7 +1562,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) HWSET_MAX_SIZE); } else if (rtlefuse->epromtype == EEPROM_93C46) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("RTL819X Not boot from eeprom, check it !!")); + "RTL819X Not boot from eeprom, check it !!"); } RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP", @@ -1576,10 +1571,10 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) eeprom_id = *((u16 *)&hwinfo[0]); if (eeprom_id != RTL8190_EEPROM_ID) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("EEPROM ID(%#x) is invalid!!\n", eeprom_id)); + "EEPROM ID(%#x) is invalid!!\n", eeprom_id); rtlefuse->autoload_failflag = true; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; } @@ -1591,8 +1586,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue; } - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("%pM\n", rtlefuse->dev_addr)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr); _rtl92ce_read_txpower_info_from_hwpg(hw, rtlefuse->autoload_failflag, @@ -1608,7 +1602,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid)); + "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); /* set channel paln to world wide 13 */ rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13; @@ -1662,7 +1656,7 @@ static void _rtl92ce_hal_customized_behavior(struct ieee80211_hw *hw) break; } RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("RT Customized ID: 0x%02X\n", rtlhal->oem_id)); + "RT Customized ID: 0x%02X\n", rtlhal->oem_id); } void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw) @@ -1679,22 +1673,22 @@ void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw) else rtlpriv->dm.rfpath_rxenable[0] = rtlpriv->dm.rfpath_rxenable[1] = true; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("VersionID = 0x%4x\n", - rtlhal->version)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n", + rtlhal->version); tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); if (tmp_u1b & BIT(4)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); rtlefuse->epromtype = EEPROM_93C46; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); rtlefuse->epromtype = EEPROM_BOOT_EFUSE; } if (tmp_u1b & BIT(5)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; _rtl92ce_read_adapter_info(hw); } else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Autoload ERR!!\n"); } _rtl92ce_hal_customized_behavior(hw); } @@ -1790,8 +1784,8 @@ static void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw, 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))); + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n", + rtl_read_dword(rtlpriv, REG_ARFR0)); } static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, @@ -1919,16 +1913,15 @@ static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, break; } RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, - ("ratr_bitmap :%x\n", ratr_bitmap)); + "ratr_bitmap :%x\n", ratr_bitmap); *(u32 *)&rate_mask = EF4BYTE((ratr_bitmap & 0x0fffffff) | (ratr_index << 28)); rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("Rate_index:%x, " - "ratr_val:%x, %x:%x:%x:%x:%x\n", - ratr_index, ratr_bitmap, - rate_mask[0], rate_mask[1], - rate_mask[2], rate_mask[3], - rate_mask[4])); + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, + "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x\n", + ratr_index, ratr_bitmap, + rate_mask[0], rate_mask[1], rate_mask[2], rate_mask[3], + rate_mask[4]); rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); if (macid != 0) @@ -1994,7 +1987,7 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("GPIOChangeRF - HW Radio ON, RF ON\n")); + "GPIOChangeRF - HW Radio ON, RF ON\n"); e_rfpowerstate_toset = ERFON; ppsc->hwradiooff = false; @@ -2002,7 +1995,7 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) } else if ((ppsc->hwradiooff == false) && (e_rfpowerstate_toset == ERFOFF)) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("GPIOChangeRF - HW Radio OFF, RF OFF\n")); + "GPIOChangeRF - HW Radio OFF, RF OFF\n"); e_rfpowerstate_toset = ERFOFF; ppsc->hwradiooff = true; @@ -2053,7 +2046,7 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, u8 cam_offset = 0; u8 clear_number = 5; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); for (idx = 0; idx < clear_number; idx++) { rtl_cam_mark_invalid(hw, cam_offset + idx); @@ -2081,8 +2074,8 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, enc_algo = CAM_AES; break; default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case " - "not process\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "switch case not processed\n"); enc_algo = CAM_TKIP; break; } @@ -2100,9 +2093,8 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, p_macaddr); if (entry_id >= TOTAL_CAM_ENTRY) { RT_TRACE(rtlpriv, COMP_SEC, - DBG_EMERG, - ("Can not find free hw" - " security cam entry\n")); + DBG_EMERG, + "Can not find free hw security cam entry\n"); return; } } else { @@ -2116,22 +2108,22 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, if (rtlpriv->sec.key_len[key_index] == 0) { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("delete one entry, entry_id is %d\n", - entry_id)); + "delete one entry, entry_id is %d\n", + entry_id); if (mac->opmode == NL80211_IFTYPE_AP) rtl_cam_del_entry(hw, p_macaddr); rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); } else { RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The insert KEY length is %d\n", - rtlpriv->sec.key_len[PAIRWISE_KEYIDX])); + "The insert KEY length is %d\n", + rtlpriv->sec.key_len[PAIRWISE_KEYIDX]); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The insert KEY is %x %x\n", - rtlpriv->sec.key_buf[0][0], - rtlpriv->sec.key_buf[0][1])); + "The insert KEY is %x %x\n", + rtlpriv->sec.key_buf[0][0], + rtlpriv->sec.key_buf[0][1]); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("add one entry\n")); + "add one entry\n"); if (is_pairwise) { RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, "Pairwise Key content", @@ -2140,7 +2132,7 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, key_len[PAIRWISE_KEYIDX]); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set Pairwiase key\n")); + "set Pairwise key\n"); rtl_cam_add_one_entry(hw, macaddr, key_index, entry_id, enc_algo, @@ -2149,7 +2141,7 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, key_buf[key_index]); } else { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set group key\n")); + "set group key\n"); if (mac->opmode == NL80211_IFTYPE_ADHOC) { rtl_cam_add_one_entry(hw, diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c index 28a1a707d09..09758f48d3e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c @@ -45,8 +45,8 @@ void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) u8 ledcfg; struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2, pled->ledpin); ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); @@ -62,7 +62,7 @@ void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } pled->ledon = true; @@ -74,8 +74,8 @@ void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); u8 ledcfg; - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2, pled->ledpin); ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); @@ -97,7 +97,7 @@ void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } pled->ledon = false; @@ -145,7 +145,7 @@ void rtl92ce_led_control(struct ieee80211_hw *hw, ledaction == LED_CTL_POWER_ON)) { return; } - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d.\n", - ledaction)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d\n", + ledaction); _rtl92ce_sw_led_control(hw, ledaction); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index ce9eea94bb5..03ee82e05f2 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c @@ -47,9 +47,9 @@ u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, u32 original_value, readback_value, bitshift; struct rtl_phy *rtlphy = &(rtlpriv->phy); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "rfpath(%#x), bitmask(%#x)\n", - regaddr, rfpath, bitmask)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", + regaddr, rfpath, bitmask); spin_lock(&rtlpriv->locks.rf_lock); @@ -67,9 +67,8 @@ u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, spin_unlock(&rtlpriv->locks.rf_lock); RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("regaddr(%#x), rfpath(%#x), " - "bitmask(%#x), original_value(%#x)\n", - regaddr, rfpath, bitmask, original_value)); + "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value); return readback_value; } @@ -121,8 +120,8 @@ void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, u32 original_value, bitshift; RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", - regaddr, bitmask, data, rfpath)); + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); spin_lock(&rtlpriv->locks.rf_lock); @@ -153,10 +152,9 @@ void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, spin_unlock(&rtlpriv->locks.rf_lock); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "bitmask(%#x), data(%#x), " - "rfpath(%#x)\n", regaddr, - bitmask, data, rfpath)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); } static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) @@ -166,11 +164,10 @@ static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) u32 arraylength; u32 *ptrarray; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Read Rtl819XMACPHY_Array\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n"); arraylength = MAC_2T_ARRAYLENGTH; ptrarray = RTL8192CEMAC_2T_ARRAY; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Img:RTL8192CEMAC_2T_ARRAY\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Img:RTL8192CEMAC_2T_ARRAY\n"); for (i = 0; i < arraylength; i = i + 2) rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); return true; @@ -215,10 +212,9 @@ bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, phy_regarray_table[i + 1]); udelay(1); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("The phy_regarray_table[0] is %x" - " Rtl819XPHY_REGArray[1] is %x\n", - phy_regarray_table[i], - phy_regarray_table[i + 1])); + "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n", + phy_regarray_table[i], + phy_regarray_table[i + 1]); } } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { for (i = 0; i < agctab_arraylen; i = i + 2) { @@ -226,10 +222,9 @@ bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, agctab_array_table[i + 1]); udelay(1); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("The agctab_array_table[0] is " - "%x Rtl819XPHY_REGArray[1] is %x\n", - agctab_array_table[i], - agctab_array_table[i + 1])); + "The agctab_array_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n", + agctab_array_table[i], + agctab_array_table[i + 1]); } } return true; @@ -269,7 +264,7 @@ bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, } else { RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, - ("configtype != BaseBand_Config_PHY_REG\n")); + "configtype != BaseBand_Config_PHY_REG\n"); } return true; } @@ -291,20 +286,20 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, radiob_arraylen = RADIOB_2TARRAYLENGTH; radiob_array_table = RTL8192CE_RADIOB_2TARRAY; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_A:RTL8192CERADIOA_2TARRAY\n")); + "Radio_A:RTL8192CERADIOA_2TARRAY\n"); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_B:RTL8192CE_RADIOB_2TARRAY\n")); + "Radio_B:RTL8192CE_RADIOB_2TARRAY\n"); } else { radioa_arraylen = RADIOA_1TARRAYLENGTH; radioa_array_table = RTL8192CE_RADIOA_1TARRAY; radiob_arraylen = RADIOB_1TARRAYLENGTH; radiob_array_table = RTL8192CE_RADIOB_1TARRAY; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_A:RTL8192CE_RADIOA_1TARRAY\n")); + "Radio_A:RTL8192CE_RADIOA_1TARRAY\n"); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_B:RTL8192CE_RADIOB_1TARRAY\n")); + "Radio_B:RTL8192CE_RADIOB_1TARRAY\n"); } - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath); switch (rfpath) { case RF90_PATH_A: for (i = 0; i < radioa_arraylen; i = i + 2) { @@ -352,11 +347,11 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, break; case RF90_PATH_C: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; case RF90_PATH_D: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } return true; @@ -371,10 +366,9 @@ void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw) u8 reg_bw_opmode; u8 reg_prsr_rsc; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, - ("Switch to %s bandwidth\n", - rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? - "20MHz" : "40MHz")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz"); if (is_hal_stop(rtlhal)) { rtlphy->set_bwmode_inprogress = false; @@ -398,7 +392,7 @@ void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); break; } @@ -423,12 +417,12 @@ void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); break; } rtl92ce_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); rtlphy->set_bwmode_inprogress = false; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); } void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) @@ -499,7 +493,7 @@ static void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("Switch RF timeout !!!.\n")); + "Switch RF timeout !!!\n"); return; } rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); @@ -526,7 +520,7 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, do { InitializeCount++; RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("IPS Set eRf nic enable\n")); + "IPS Set eRf nic enable\n"); rtstatus = rtl_ps_enable_nic(hw); } while ((rtstatus != true) && (InitializeCount < 10)); @@ -534,10 +528,10 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, RT_RF_OFF_LEVL_HALT_NIC); } else { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("Set ERFON sleeped:%d ms\n", - jiffies_to_msecs(jiffies - - ppsc-> - last_sleep_jiffies))); + "Set ERFON sleeped:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc-> + last_sleep_jiffies)); ppsc->last_awake_jiffies = jiffies; rtl92ce_phy_set_rf_on(hw); } @@ -553,7 +547,7 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, case ERFOFF:{ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("IPS Set eRf nic disable\n")); + "IPS Set eRf nic disable\n"); rtl_ps_disable_nic(hw); RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); } else { @@ -578,35 +572,33 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, continue; } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("eRf Off/Sleep: %d times " - "TcbBusyQueue[%d] =%d before " - "doze!\n", (i + 1), queue_id, - skb_queue_len(&ring->queue))); + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + i + 1, queue_id, + skb_queue_len(&ring->queue)); udelay(10); i++; } if (i >= MAX_DOZE_WAITING_TIMES_9x) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("\n ERFSLEEP: %d times " - "TcbBusyQueue[%d] = %d !\n", - MAX_DOZE_WAITING_TIMES_9x, - queue_id, - skb_queue_len(&ring->queue))); + "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue)); break; } } RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("Set ERFSLEEP awaked:%d ms\n", - jiffies_to_msecs(jiffies - - ppsc->last_awake_jiffies))); + "Set ERFSLEEP awaked:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc->last_awake_jiffies)); ppsc->last_sleep_jiffies = jiffies; _rtl92ce_phy_set_rf_sleep(hw); break; } default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); bresult = false; break; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c index d3b01e6023b..3ba1a4feeb3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c @@ -56,7 +56,7 @@ void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", bandwidth)); + "unknown bandwidth: %#X\n", bandwidth); break; } } @@ -512,12 +512,12 @@ static bool _rtl92ce_phy_rf6052_config_parafile(struct ieee80211_hw *hw) if (rtstatus != true) { RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio[%d] Fail!!", rfpath)); + "Radio[%d] Fail!!\n", rfpath); return false; } } - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n"); return rtstatus; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index 89ef6982ce5..d2a3576fdaa 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c @@ -159,7 +159,7 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->rtlhal.pfirmware = vzalloc(0x4000); if (!rtlpriv->rtlhal.pfirmware) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't alloc buffer for fw.\n")); + "Can't alloc buffer for fw\n"); return 1; } @@ -174,12 +174,12 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) err = request_firmware(&firmware, fw_name, rtlpriv->io.dev); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to request firmware!\n")); + "Failed to request firmware!\n"); return 1; } if (firmware->size > 0x4000) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Firmware is too big!\n")); + "Firmware is too big!\n"); release_firmware(firmware); return 1; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 378bc567346..9f6fac450a4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -725,7 +725,7 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, if (ieee80211_is_data_qos(fc)) { if (mac->rdg_en) { RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, - ("Enable RDG function.\n")); + "Enable RDG function\n"); SET_TX_DESC_RDG_ENABLE(pdesc, 1); SET_TX_DESC_HTC(pdesc, 1); } @@ -763,7 +763,7 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, SET_TX_DESC_BMC(pdesc, 1); } - RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n")); + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n"); } void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c index f311baee668..c0016f3194e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c @@ -52,7 +52,7 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw) if ((mac->link_state < MAC80211_LINKED) && (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("Not connected to any\n")); + "Not connected to any\n"); rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; @@ -65,28 +65,28 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw) undecorated_smoothed_pwdb = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Client PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "AP Client PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } else { undecorated_smoothed_pwdb = rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("STA Default Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "STA Default Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } } else { undecorated_smoothed_pwdb = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Ext Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "AP Ext Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n")); + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); } else if ((undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && (undecorated_smoothed_pwdb >= @@ -94,18 +94,18 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw) rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n")); + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); } else if (undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_NORMAL\n")); + "TXHIGHPWRLEVEL_NORMAL\n"); } if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("PHY_SetTxPowerLevel8192S() Channel = %d\n", - rtlphy->current_channel)); + "PHY_SetTxPowerLevel8192S() Channel = %d\n", + rtlphy->current_channel); rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 778c0e6e836..80bd17d8593 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -494,17 +494,17 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw) HWSET_MAX_SIZE); } else if (rtlefuse->epromtype == EEPROM_93C46) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("RTL819X Not boot from eeprom, check it !!")); + "RTL819X Not boot from eeprom, check it !!\n"); } RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, "MAP", hwinfo, HWSET_MAX_SIZE); eeprom_id = le16_to_cpu(*((__le16 *)&hwinfo[0])); if (eeprom_id != RTL8190_EEPROM_ID) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("EEPROM ID(%#x) is invalid!!\n", eeprom_id)); + "EEPROM ID(%#x) is invalid!!\n", eeprom_id); rtlefuse->autoload_failflag = true; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; } if (rtlefuse->autoload_failflag) @@ -518,16 +518,15 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->autoload_failflag, hwinfo); rtlefuse->eeprom_vid = le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_VID]); rtlefuse->eeprom_did = le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_DID]); - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - (" VID = 0x%02x PID = 0x%02x\n", - rtlefuse->eeprom_vid, rtlefuse->eeprom_did)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, " VID = 0x%02x PID = 0x%02x\n", + rtlefuse->eeprom_vid, rtlefuse->eeprom_did); rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; rtlefuse->eeprom_version = le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_VERSION]); rtlefuse->txpwr_fromeprom = true; rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x\n", + rtlefuse->eeprom_oemid); if (rtlhal->oem_id == RT_CID_DEFAULT) { switch (rtlefuse->eeprom_oemid) { case EEPROM_CID_DEFAULT: @@ -579,8 +578,8 @@ static void _rtl92cu_hal_customized_behavior(struct ieee80211_hw *hw) default: break; } - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("RT Customized ID: 0x%02X\n", rtlhal->oem_id)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "RT Customized ID: 0x%02X\n", + rtlhal->oem_id); } void rtl92cu_read_eeprom_info(struct ieee80211_hw *hw) @@ -596,11 +595,11 @@ void rtl92cu_read_eeprom_info(struct ieee80211_hw *hw) tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); rtlefuse->epromtype = (tmp_u1b & BOOT_FROM_EEPROM) ? EEPROM_93C46 : EEPROM_BOOT_EFUSE; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from %s\n", - (tmp_u1b & BOOT_FROM_EEPROM) ? "EERROM" : "EFUSE")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from %s\n", + tmp_u1b & BOOT_FROM_EEPROM ? "EERROM" : "EFUSE"); rtlefuse->autoload_failflag = (tmp_u1b & EEPROM_EN) ? false : true; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload %s\n", - (tmp_u1b & EEPROM_EN) ? "OK!!" : "ERR!!")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload %s\n", + tmp_u1b & EEPROM_EN ? "OK!!" : "ERR!!"); _rtl92cu_read_adapter_info(hw); _rtl92cu_hal_customized_behavior(hw); return; @@ -618,13 +617,12 @@ static int _rtl92cu_init_power_on(struct ieee80211_hw *hw) do { if (rtl_read_byte(rtlpriv, REG_APS_FSMCO) & PFM_ALDN) { RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Autoload Done!\n")); + "Autoload Done!\n"); break; } if (pollingCount++ > 100) { RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Failed to polling REG_APS_FSMCO[PFM_ALDN]" - " done!\n")); + "Failed to polling REG_APS_FSMCO[PFM_ALDN] done!\n"); return -ENODEV; } } while (true); @@ -639,8 +637,8 @@ static int _rtl92cu_init_power_on(struct ieee80211_hw *hw) value8 |= LDV12_EN; rtl_write_byte(rtlpriv, REG_LDOV12D_CTRL, value8); RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - (" power-on :REG_LDOV12D_CTRL Reg0x21:0x%02x.\n", - value8)); + " power-on :REG_LDOV12D_CTRL Reg0x21:0x%02x\n", + value8); udelay(100); value8 = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL); value8 &= ~ISO_MD2PP; @@ -658,8 +656,7 @@ static int _rtl92cu_init_power_on(struct ieee80211_hw *hw) } if (pollingCount++ > 100) { RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Failed to polling REG_APS_FSMCO[APFM_ONMAC]" - " done!\n")); + "Failed to polling REG_APS_FSMCO[APFM_ONMAC] done!\n"); return -ENODEV; } } while (true); @@ -877,8 +874,8 @@ static void _rtl92cu_init_chipN_three_out_ep_priority(struct ieee80211_hw *hw, hiQ = QUEUE_HIGH; } _rtl92c_init_chipN_reg_priority(hw, beQ, bkQ, viQ, voQ, mgtQ, hiQ); - RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Tx queue select :0x%02x..\n", queue_sel)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Tx queue select :0x%02x..\n", + queue_sel); } static void _rtl92cu_init_chipN_queue_priority(struct ieee80211_hw *hw, @@ -937,8 +934,8 @@ static void _rtl92cu_init_chipT_queue_priority(struct ieee80211_hw *hw, break; } rtl_write_byte(rtlpriv, (REG_TRXDMA_CTRL+1), hq_sele); - RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Tx queue select :0x%02x..\n", hq_sele)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Tx queue select :0x%02x..\n", + hq_sele); } static void _rtl92cu_init_queue_priority(struct ieee80211_hw *hw, @@ -998,7 +995,7 @@ static int _rtl92cu_init_mac(struct ieee80211_hw *hw) if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to init power on!\n")); + "Failed to init power on!\n"); return err; } if (!wmm_enable) { @@ -1010,7 +1007,7 @@ static int _rtl92cu_init_mac(struct ieee80211_hw *hw) } if (false == rtl92c_init_llt_table(hw, boundary)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to init LLT Table!\n")); + "Failed to init LLT Table!\n"); return -EINVAL; } _rtl92cu_init_queue_reserved_page(hw, wmm_enable, out_ep_nums, @@ -1043,12 +1040,12 @@ void rtl92cu_enable_hw_security_config(struct ieee80211_hw *hw) struct rtl_hal *rtlhal = rtl_hal(rtlpriv); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", - rtlpriv->sec.pairwise_enc_algorithm, - rtlpriv->sec.group_enc_algorithm)); + "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", + rtlpriv->sec.pairwise_enc_algorithm, + rtlpriv->sec.group_enc_algorithm); if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("not open sw encryption\n")); + "not open sw encryption\n"); return; } sec_reg_value = SCR_TxEncEnable | SCR_RxDecEnable; @@ -1059,8 +1056,8 @@ void rtl92cu_enable_hw_security_config(struct ieee80211_hw *hw) if (IS_NORMAL_CHIP(rtlhal->version)) sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The SECR-value %x\n", sec_reg_value)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "The SECR-value %x\n", + sec_reg_value); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); } @@ -1163,13 +1160,13 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw) rtlhal->hw_type = HARDWARE_TYPE_RTL8192CU; err = _rtl92cu_init_mac(hw); if (err) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("init mac failed!\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "init mac failed!\n"); return err; } err = rtl92c_download_fw(hw); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Failed to download FW. Init HW without FW now..\n")); + "Failed to download FW. Init HW without FW now..\n"); err = 1; rtlhal->fw_ready = false; return err; @@ -1280,8 +1277,7 @@ static void _ResetDigitalProcedure1(struct ieee80211_hw *hw, bool bWithoutHWSM) } if (retry_cnts >= 100) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("#####=> 8051 reset failed!.." - ".......................\n");); + "#####=> 8051 reset failed!.........................\n"); /* if 8051 reset fail, reset MAC. */ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, @@ -1495,35 +1491,36 @@ static int _rtl92cu_set_media_status(struct ieee80211_hw *hw, _rtl92cu_resume_tx_beacon(hw); _rtl92cu_disable_bcn_sub_func(hw); } else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("Set HW_VAR_MEDIA_" - "STATUS:No such media status(%x).\n", type)); + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + "Set HW_VAR_MEDIA_STATUS:No such media status(%x)\n", + type); } switch (type) { case NL80211_IFTYPE_UNSPECIFIED: bt_msr |= MSR_NOLINK; ledaction = LED_CTL_LINK; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to NO LINK!\n")); + "Set Network type to NO LINK!\n"); break; case NL80211_IFTYPE_ADHOC: bt_msr |= MSR_ADHOC; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to Ad Hoc!\n")); + "Set Network type to Ad Hoc!\n"); break; case NL80211_IFTYPE_STATION: bt_msr |= MSR_INFRA; ledaction = LED_CTL_LINK; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to STA!\n")); + "Set Network type to STA!\n"); break; case NL80211_IFTYPE_AP: bt_msr |= MSR_AP; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to AP!\n")); + "Set Network type to AP!\n"); break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Network type %d not support!\n", type)); + "Network type %d not supported!\n", type); goto error_out; } rtl_write_byte(rtlpriv, (MSR), bt_msr); @@ -1684,8 +1681,8 @@ void rtl92cu_set_beacon_related_registers(struct ieee80211_hw *hw) value32 |= TSFRST; rtl_write_dword(rtlpriv, REG_TCR, value32); RT_TRACE(rtlpriv, COMP_INIT|COMP_BEACON, DBG_LOUD, - ("SetBeaconRelatedRegisters8192CUsb(): Set TCR(%x)\n", - value32)); + "SetBeaconRelatedRegisters8192CUsb(): Set TCR(%x)\n", + value32); /* TODO: Modify later (Find the right parameters) * NOTE: Fix test chip's bug (about contention windows's randomness) */ if ((mac->opmode == NL80211_IFTYPE_ADHOC) || @@ -1702,8 +1699,8 @@ void rtl92cu_set_beacon_interval(struct ieee80211_hw *hw) struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); u16 bcn_interval = mac->beacon_interval; - RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, - ("beacon_interval:%d\n", bcn_interval)); + RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, "beacon_interval:%d\n", + bcn_interval); rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); } @@ -1767,7 +1764,7 @@ void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } @@ -1827,8 +1824,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]); rtl_write_byte(rtlpriv, REG_R2T_SIFS+1, val[0]); rtl_write_byte(rtlpriv, REG_T2T_SIFS+1, val[0]); - RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("HW_VAR_SIFS\n")); + RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, "HW_VAR_SIFS\n"); break; } case HW_VAR_SLOT_TIME:{ @@ -1837,7 +1833,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtl_write_byte(rtlpriv, REG_SLOT, val[0]); RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("HW_VAR_SLOT_TIME %x\n", val[0])); + "HW_VAR_SLOT_TIME %x\n", val[0]); if (QOS_MODE) { for (e_aci = 0; e_aci < AC_MAX; e_aci++) rtlpriv->cfg->ops->set_hw_reg(hw, @@ -1901,8 +1897,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) min_spacing_to_set); *val = min_spacing_to_set; RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", - mac->min_space_cfg)); + "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", + mac->min_space_cfg); rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, mac->min_space_cfg); } @@ -1916,8 +1912,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) mac->min_space_cfg &= 0x07; mac->min_space_cfg |= (density_to_set << 3); RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_SHORTGI_DENSITY: %#x\n", - mac->min_space_cfg)); + "Set HW_VAR_SHORTGI_DENSITY: %#x\n", + mac->min_space_cfg); rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, mac->min_space_cfg); break; @@ -1950,8 +1946,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) p_regtoset[index]); } RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_AMPDU_FACTOR: %#x\n", - factor_toset)); + "Set HW_VAR_AMPDU_FACTOR: %#x\n", + factor_toset); } break; } @@ -1969,8 +1965,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) AC_PARAM_ECW_MAX_OFFSET); u4b_ac_param |= (u32) tx_op << AC_PARAM_TXOP_OFFSET; RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("queue:%x, ac_param:%x\n", e_aci, - u4b_ac_param)); + "queue:%x, ac_param:%x\n", + e_aci, u4b_ac_param); switch (e_aci) { case AC1_BK: rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, @@ -2020,8 +2016,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("HW_VAR_ACM_CTRL acm set " - "failed: eACI is %d\n", acm)); + "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", + acm); break; } } else { @@ -2037,13 +2033,13 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE, - ("SetHwReg8190pci(): [HW_VAR_ACM_CTRL] " - "Write 0x%X\n", acm_ctrl)); + "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", + acm_ctrl); rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); break; } @@ -2051,7 +2047,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtl_write_dword(rtlpriv, REG_RCR, ((u32 *) (val))[0]); mac->rx_conf = ((u32 *) (val))[0]; RT_TRACE(rtlpriv, COMP_RECV, DBG_DMESG, - ("### Set RCR(0x%08x) ###\n", mac->rx_conf)); + "### Set RCR(0x%08x) ###\n", mac->rx_conf); break; } case HW_VAR_RETRY_LIMIT:{ @@ -2060,8 +2056,9 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtl_write_word(rtlpriv, REG_RL, retry_limit << RETRY_LIMIT_SHORT_SHIFT | retry_limit << RETRY_LIMIT_LONG_SHIFT); - RT_TRACE(rtlpriv, COMP_MLME, DBG_DMESG, ("Set HW_VAR_R" - "ETRY_LIMIT(0x%08x)\n", retry_limit)); + RT_TRACE(rtlpriv, COMP_MLME, DBG_DMESG, + "Set HW_VAR_RETRY_LIMIT(0x%08x)\n", + retry_limit); break; } case HW_VAR_DUAL_TSF_RST: @@ -2165,8 +2162,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtl_write_word(rtlpriv, REG_RXFLTMAP2, *(u16 *)val); break; default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case " - "not process\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "switch case not processed\n"); break; } } @@ -2239,8 +2236,8 @@ 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))); + 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) @@ -2344,17 +2341,16 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) ratr_bitmap &= 0x0f0ff0ff; break; } - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("ratr_bitmap :%x\n", - ratr_bitmap)); + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "ratr_bitmap :%x\n", + ratr_bitmap); *(u32 *)&rate_mask = ((ratr_bitmap & 0x0fffffff) | ratr_index << 28); rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("Rate_index:%x, " - "ratr_val:%x, %x:%x:%x:%x:%x\n", - ratr_index, ratr_bitmap, - rate_mask[0], rate_mask[1], - rate_mask[2], rate_mask[3], - rate_mask[4])); + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, + "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x\n", + ratr_index, ratr_bitmap, + rate_mask[0], rate_mask[1], rate_mask[2], rate_mask[3], + rate_mask[4]); rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); } @@ -2404,7 +2400,7 @@ bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid) e_rfpowerstate_toset = (u1tmp & BIT(7)) ? ERFOFF : ERFON; RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - ("pwrdown, 0x5c(BIT7)=%02x\n", u1tmp)); + "pwrdown, 0x5c(BIT7)=%02x\n", u1tmp); } else { rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, rtl_read_byte(rtlpriv, @@ -2413,27 +2409,26 @@ bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid) e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF; RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - ("GPIO_IN=%02x\n", u1tmp)); + "GPIO_IN=%02x\n", u1tmp); } - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("N-SS RF =%x\n", - e_rfpowerstate_toset)); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "N-SS RF =%x\n", + e_rfpowerstate_toset); } if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("GPIOChangeRF - HW " - "Radio ON, RF ON\n")); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "GPIOChangeRF - HW Radio ON, RF ON\n"); ppsc->hwradiooff = false; actuallyset = true; } else if ((!ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFOFF)) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("GPIOChangeRF - HW" - " Radio OFF\n")); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "GPIOChangeRF - HW Radio OFF\n"); ppsc->hwradiooff = true; actuallyset = true; } else { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD , - ("pHalData->bHwRadioOff and eRfPowerStateToSet do not" - " match: pHalData->bHwRadioOff %x, eRfPowerStateToSet " - "%x\n", ppsc->hwradiooff, e_rfpowerstate_toset)); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "pHalData->bHwRadioOff and eRfPowerStateToSet do not match: pHalData->bHwRadioOff %x, eRfPowerStateToSet %x\n", + ppsc->hwradiooff, e_rfpowerstate_toset); } if (actuallyset) { ppsc->hwradiooff = true; diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/led.c b/drivers/net/wireless/rtlwifi/rtl8192cu/led.c index 2ff9d8314e7..65fd0442462 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/led.c @@ -47,8 +47,8 @@ void rtl92cu_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) u8 ledcfg; struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2, pled->ledpin); ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); switch (pled->ledpin) { case LED_PIN_GPIO0: @@ -62,7 +62,7 @@ void rtl92cu_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } pled->ledon = true; @@ -74,8 +74,8 @@ void rtl92cu_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) struct rtl_usb_priv *usbpriv = rtl_usbpriv(hw); u8 ledcfg; - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2, pled->ledpin); ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); switch (pled->ledpin) { case LED_PIN_GPIO0: @@ -95,7 +95,7 @@ void rtl92cu_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } pled->ledon = false; @@ -136,7 +136,6 @@ void rtl92cu_led_control(struct ieee80211_hw *hw, ledaction == LED_CTL_POWER_ON)) { return; } - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n", - ledaction)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d\n", ledaction); _rtl92cu_sw_led_control(hw, ledaction); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c index 487ee908d7c..9f09844d7d5 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c @@ -88,67 +88,59 @@ void rtl92c_read_chip_version(struct ieee80211_hw *hw) switch (rtlhal->version) { case VERSION_NORMAL_TSMC_CHIP_92C_1T2R: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_B_CHIP_92C.\n")); + "Chip Version ID: VERSION_B_CHIP_92C\n"); break; case VERSION_NORMAL_TSMC_CHIP_92C: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMAL_TSMC_CHIP_92C.\n")); + "Chip Version ID: VERSION_NORMAL_TSMC_CHIP_92C\n"); break; case VERSION_NORMAL_TSMC_CHIP_88C: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMAL_TSMC_CHIP_88C.\n")); + "Chip Version ID: VERSION_NORMAL_TSMC_CHIP_88C\n"); break; case VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMAL_UMC_CHIP_i" - "92C_1T2R_A_CUT.\n")); + "Chip Version ID: VERSION_NORMAL_UMC_CHIP_i92C_1T2R_A_CUT\n"); break; case VERSION_NORMAL_UMC_CHIP_92C_A_CUT: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMAL_UMC_CHIP_" - "92C_A_CUT.\n")); + "Chip Version ID: VERSION_NORMAL_UMC_CHIP_92C_A_CUT\n"); break; case VERSION_NORMAL_UMC_CHIP_88C_A_CUT: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMAL_UMC_CHIP" - "_88C_A_CUT.\n")); + "Chip Version ID: VERSION_NORMAL_UMC_CHIP_88C_A_CUT\n"); break; case VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMAL_UMC_CHIP" - "_92C_1T2R_B_CUT.\n")); + "Chip Version ID: VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT\n"); break; case VERSION_NORMAL_UMC_CHIP_92C_B_CUT: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMAL_UMC_CHIP" - "_92C_B_CUT.\n")); + "Chip Version ID: VERSION_NORMAL_UMC_CHIP_92C_B_CUT\n"); break; case VERSION_NORMAL_UMC_CHIP_88C_B_CUT: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMAL_UMC_CHIP" - "_88C_B_CUT.\n")); + "Chip Version ID: VERSION_NORMAL_UMC_CHIP_88C_B_CUT\n"); break; case VERSION_NORMA_UMC_CHIP_8723_1T1R_A_CUT: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMA_UMC_CHIP" - "_8723_1T1R_A_CUT.\n")); + "Chip Version ID: VERSION_NORMA_UMC_CHIP_8723_1T1R_A_CUT\n"); break; case VERSION_NORMA_UMC_CHIP_8723_1T1R_B_CUT: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMA_UMC_CHIP" - "_8723_1T1R_B_CUT.\n")); + "Chip Version ID: VERSION_NORMA_UMC_CHIP_8723_1T1R_B_CUT\n"); break; case VERSION_TEST_CHIP_92C: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_TEST_CHIP_92C.\n")); + "Chip Version ID: VERSION_TEST_CHIP_92C\n"); break; case VERSION_TEST_CHIP_88C: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_TEST_CHIP_88C.\n")); + "Chip Version ID: VERSION_TEST_CHIP_88C\n"); break; default: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: ???????????????.\n")); + "Chip Version ID: ???????????????\n"); break; } if (IS_92C_SERIAL(rtlhal->version)) @@ -157,15 +149,15 @@ void rtl92c_read_chip_version(struct ieee80211_hw *hw) else rtlphy->rf_type = RF_1T1R; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ? - "RF_2T2R" : "RF_1T1R")); + "Chip RF Type: %s\n", + rtlphy->rf_type == RF_2T2R ? "RF_2T2R" : "RF_1T1R"); if (get_rf_type(rtlphy) == RF_1T1R) rtlpriv->dm.rfpath_rxenable[0] = true; else rtlpriv->dm.rfpath_rxenable[0] = rtlpriv->dm.rfpath_rxenable[1] = true; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("VersionID = 0x%4x\n", - rtlhal->version)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n", + rtlhal->version); } /** @@ -192,9 +184,8 @@ bool rtl92c_llt_write(struct ieee80211_hw *hw, u32 address, u32 data) break; if (count > POLLING_LLT_THRESHOLD) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to polling write LLT done at" - " address %d! _LLT_OP_VALUE(%x)\n", - address, _LLT_OP_VALUE(value))); + "Failed to polling write LLT done at address %d! _LLT_OP_VALUE(%x)\n", + address, _LLT_OP_VALUE(value)); status = false; break; } @@ -272,7 +263,7 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index, u8 cam_offset = 0; u8 clear_number = 5; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); for (idx = 0; idx < clear_number; idx++) { rtl_cam_mark_invalid(hw, cam_offset + idx); rtl_cam_empty_entry(hw, cam_offset + idx); @@ -298,7 +289,7 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("iillegal switch case\n")); + "illegal switch case\n"); enc_algo = CAM_TKIP; break; } @@ -317,18 +308,18 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index, } if (rtlpriv->sec.key_len[key_index] == 0) { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("delete one entry\n")); + "delete one entry\n"); rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); } else { RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The insert KEY length is %d\n", - rtlpriv->sec.key_len[PAIRWISE_KEYIDX])); + "The insert KEY length is %d\n", + rtlpriv->sec.key_len[PAIRWISE_KEYIDX]); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The insert KEY is %x %x\n", - rtlpriv->sec.key_buf[0][0], - rtlpriv->sec.key_buf[0][1])); + "The insert KEY is %x %x\n", + rtlpriv->sec.key_buf[0][0], + rtlpriv->sec.key_buf[0][1]); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("add one entry\n")); + "add one entry\n"); if (is_pairwise) { RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, "Pairwise Key content", @@ -336,7 +327,7 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index, rtlpriv->sec. key_len[PAIRWISE_KEYIDX]); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set Pairwiase key\n")); + "set Pairwise key\n"); rtl_cam_add_one_entry(hw, macaddr, key_index, entry_id, enc_algo, @@ -345,7 +336,7 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index, key_buf[key_index]); } else { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set group key\n")); + "set group key\n"); if (mac->opmode == NL80211_IFTYPE_ADHOC) { rtl_cam_add_one_entry(hw, rtlefuse->dev_addr, @@ -421,8 +412,8 @@ void rtl92c_set_qos(struct ieee80211_hw *hw, int aci) AC_PARAM_ECW_MAX_OFFSET; u4b_ac_param |= (u32) le16_to_cpu(mac->ac[aci].tx_op) << AC_PARAM_TXOP_OFFSET; - RT_TRACE(rtlpriv, COMP_QOS, DBG_LOUD, - ("queue:%x, ac_param:%x\n", aci, u4b_ac_param)); + RT_TRACE(rtlpriv, COMP_QOS, DBG_LOUD, "queue:%x, ac_param:%x\n", + aci, u4b_ac_param); switch (aci) { case AC1_BK: rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, u4b_ac_param); @@ -453,14 +444,14 @@ void rtl92c_set_mac_addr(struct ieee80211_hw *hw, const u8 *addr) for (i = 0 ; i < ETH_ALEN ; i++) rtl_write_byte(rtlpriv, (REG_MACID + i), *(addr+i)); - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, ("MAC Address: %02X-%02X-%02X-" - "%02X-%02X-%02X\n", - rtl_read_byte(rtlpriv, REG_MACID), - rtl_read_byte(rtlpriv, REG_MACID+1), - rtl_read_byte(rtlpriv, REG_MACID+2), - rtl_read_byte(rtlpriv, REG_MACID+3), - rtl_read_byte(rtlpriv, REG_MACID+4), - rtl_read_byte(rtlpriv, REG_MACID+5))); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, + "MAC Address: %02X-%02X-%02X-%02X-%02X-%02X\n", + rtl_read_byte(rtlpriv, REG_MACID), + rtl_read_byte(rtlpriv, REG_MACID+1), + rtl_read_byte(rtlpriv, REG_MACID+2), + rtl_read_byte(rtlpriv, REG_MACID+3), + rtl_read_byte(rtlpriv, REG_MACID+4), + rtl_read_byte(rtlpriv, REG_MACID+5)); } void rtl92c_init_driver_info_size(struct ieee80211_hw *hw, u8 size) @@ -478,26 +469,26 @@ int rtl92c_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) case NL80211_IFTYPE_UNSPECIFIED: value = NT_NO_LINK; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Set Network type to NO LINK!\n")); + "Set Network type to NO LINK!\n"); break; case NL80211_IFTYPE_ADHOC: value = NT_LINK_AD_HOC; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Set Network type to Ad Hoc!\n")); + "Set Network type to Ad Hoc!\n"); break; case NL80211_IFTYPE_STATION: value = NT_LINK_AP; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Set Network type to STA!\n")); + "Set Network type to STA!\n"); break; case NL80211_IFTYPE_AP: value = NT_AS_AP; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Set Network type to AP!\n")); + "Set Network type to AP!\n"); break; default: RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Network type %d not support!\n", type)); + "Network type %d not supported!\n", type); return -EOPNOTSUPP; } rtl_write_byte(rtlpriv, (REG_CR + 2), value); diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c index df491d38ecc..e7ea2bae210 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c @@ -44,9 +44,9 @@ u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw, u32 original_value, readback_value, bitshift; struct rtl_phy *rtlphy = &(rtlpriv->phy); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "rfpath(%#x), bitmask(%#x)\n", - regaddr, rfpath, bitmask)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", + regaddr, rfpath, bitmask); if (rtlphy->rf_mode != RF_OP_BY_FW) { original_value = _rtl92c_phy_rf_serial_read(hw, rfpath, regaddr); @@ -57,9 +57,8 @@ u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw, bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); readback_value = (original_value & bitmask) >> bitshift; RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("regaddr(%#x), rfpath(%#x), " - "bitmask(%#x), original_value(%#x)\n", - regaddr, rfpath, bitmask, original_value)); + "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value); return readback_value; } @@ -72,8 +71,8 @@ void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw, u32 original_value, bitshift; RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", - regaddr, bitmask, data, rfpath)); + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); if (rtlphy->rf_mode != RF_OP_BY_FW) { if (bitmask != RFREG_OFFSET_MASK) { original_value = _rtl92c_phy_rf_serial_read(hw, @@ -97,9 +96,9 @@ void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw, } _rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data); } - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "bitmask(%#x), data(%#x), rfpath(%#x)\n", - regaddr, bitmask, data, rfpath)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); } bool rtl92cu_phy_mac_config(struct ieee80211_hw *hw) @@ -152,11 +151,10 @@ bool _rtl92cu_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) u32 arraylength; u32 *ptrarray; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Read Rtl819XMACPHY_Array\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n"); arraylength = rtlphy->hwparam_tables[MAC_REG].length ; ptrarray = rtlphy->hwparam_tables[MAC_REG].pdata; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Img:RTL8192CEMAC_2T_ARRAY\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Img:RTL8192CEMAC_2T_ARRAY\n"); for (i = 0; i < arraylength; i = i + 2) rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); return true; @@ -202,10 +200,9 @@ bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, phy_regarray_table[i + 1]); udelay(1); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("The phy_regarray_table[0] is %x" - " Rtl819XPHY_REGArray[1] is %x\n", - phy_regarray_table[i], - phy_regarray_table[i + 1])); + "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n", + phy_regarray_table[i], + phy_regarray_table[i + 1]); } } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { for (i = 0; i < agctab_arraylen; i = i + 2) { @@ -213,10 +210,9 @@ bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, agctab_array_table[i + 1]); udelay(1); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("The agctab_array_table[0] is " - "%x Rtl819XPHY_REGArray[1] is %x\n", - agctab_array_table[i], - agctab_array_table[i + 1])); + "The agctab_array_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n", + agctab_array_table[i], + agctab_array_table[i + 1]); } } return true; @@ -255,7 +251,7 @@ bool _rtl92cu_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, } } else { RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, - ("configtype != BaseBand_Config_PHY_REG\n")); + "configtype != BaseBand_Config_PHY_REG\n"); } return true; } @@ -277,20 +273,20 @@ bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, radiob_arraylen = rtlphy->hwparam_tables[RADIOB_2T].length; radiob_array_table = rtlphy->hwparam_tables[RADIOB_2T].pdata; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_A:RTL8192CERADIOA_2TARRAY\n")); + "Radio_A:RTL8192CERADIOA_2TARRAY\n"); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_B:RTL8192CE_RADIOB_2TARRAY\n")); + "Radio_B:RTL8192CE_RADIOB_2TARRAY\n"); } else { radioa_arraylen = rtlphy->hwparam_tables[RADIOA_1T].length; radioa_array_table = rtlphy->hwparam_tables[RADIOA_1T].pdata; radiob_arraylen = rtlphy->hwparam_tables[RADIOB_1T].length; radiob_array_table = rtlphy->hwparam_tables[RADIOB_1T].pdata; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_A:RTL8192CE_RADIOA_1TARRAY\n")); + "Radio_A:RTL8192CE_RADIOA_1TARRAY\n"); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_B:RTL8192CE_RADIOB_1TARRAY\n")); + "Radio_B:RTL8192CE_RADIOB_1TARRAY\n"); } - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath); switch (rfpath) { case RF90_PATH_A: for (i = 0; i < radioa_arraylen; i = i + 2) { @@ -338,11 +334,11 @@ bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, break; case RF90_PATH_C: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; case RF90_PATH_D: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } return true; @@ -357,10 +353,9 @@ void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw) u8 reg_bw_opmode; u8 reg_prsr_rsc; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, - ("Switch to %s bandwidth\n", - rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? - "20MHz" : "40MHz")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz"); if (is_hal_stop(rtlhal)) { rtlphy->set_bwmode_inprogress = false; return; @@ -381,7 +376,7 @@ void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); break; } switch (rtlphy->current_chan_bw) { @@ -403,12 +398,12 @@ void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); break; } rtl92cu_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); rtlphy->set_bwmode_inprogress = false; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); } void rtl92cu_bb_block_on(struct ieee80211_hw *hw) @@ -480,7 +475,7 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, do { InitializeCount++; RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("IPS Set eRf nic enable\n")); + "IPS Set eRf nic enable\n"); rtstatus = rtl_ps_enable_nic(hw); } while ((rtstatus != true) && (InitializeCount < 10)); @@ -488,10 +483,9 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, RT_RF_OFF_LEVL_HALT_NIC); } else { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("Set ERFON sleeped:%d ms\n", - jiffies_to_msecs(jiffies - - ppsc-> - last_sleep_jiffies))); + "Set ERFON sleeped:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc->last_sleep_jiffies)); ppsc->last_awake_jiffies = jiffies; rtl92ce_phy_set_rf_on(hw); } @@ -513,27 +507,25 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, continue; } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("eRf Off/Sleep: %d times " - "TcbBusyQueue[%d] " - "=%d before doze!\n", (i + 1), - queue_id, - skb_queue_len(&ring->queue))); + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + i + 1, + queue_id, + skb_queue_len(&ring->queue)); udelay(10); i++; } if (i >= MAX_DOZE_WAITING_TIMES_9x) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("\nERFOFF: %d times " - "TcbBusyQueue[%d] = %d !\n", - MAX_DOZE_WAITING_TIMES_9x, - queue_id, - skb_queue_len(&ring->queue))); + "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue)); break; } } if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("IPS Set eRf nic disable\n")); + "IPS Set eRf nic disable\n"); rtl_ps_disable_nic(hw); RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); } else { @@ -557,33 +549,30 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, continue; } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("eRf Off/Sleep: %d times " - "TcbBusyQueue[%d] =%d before " - "doze!\n", (i + 1), queue_id, - skb_queue_len(&ring->queue))); + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + i + 1, queue_id, + skb_queue_len(&ring->queue)); udelay(10); i++; } if (i >= MAX_DOZE_WAITING_TIMES_9x) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("\n ERFSLEEP: %d times " - "TcbBusyQueue[%d] = %d !\n", - MAX_DOZE_WAITING_TIMES_9x, - queue_id, - skb_queue_len(&ring->queue))); + "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue)); break; } } RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("Set ERFSLEEP awaked:%d ms\n", - jiffies_to_msecs(jiffies - - ppsc->last_awake_jiffies))); + "Set ERFSLEEP awaked:%d ms\n", + jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies)); ppsc->last_sleep_jiffies = jiffies; _rtl92c_phy_set_rf_sleep(hw); break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); bresult = false; break; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c index 1e851aae58d..7b48ee9acb1 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c @@ -56,7 +56,7 @@ void rtl92cu_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", bandwidth)); + "unknown bandwidth: %#X\n", bandwidth); break; } } @@ -482,11 +482,11 @@ static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw) } if (rtstatus != true) { RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio[%d] Fail!!", rfpath)); + "Radio[%d] Fail!!", rfpath); goto phy_rf_cfg_fail; } } - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n"); return rtstatus; phy_rf_cfg_fail: return rtstatus; diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index 6d2ca773bbc..dee7aab4faa 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -65,7 +65,7 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->rtlhal.pfirmware = vmalloc(0x4000); if (!rtlpriv->rtlhal.pfirmware) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't alloc buffer for fw.\n")); + "Can't alloc buffer for fw\n"); return 1; } /* request fw */ @@ -73,12 +73,12 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->io.dev); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to request firmware!\n")); + "Failed to request firmware!\n"); return 1; } if (firmware->size > 0x4000) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Firmware is too big!\n")); + "Firmware is too big!\n"); release_firmware(firmware); return 1; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index 128cfcd09fa..b875af75b89 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c @@ -108,7 +108,7 @@ static void _TwoOutEpMapping(struct ieee80211_hw *hw, bool bIsChipB, if (bwificfg) { /* for WMM */ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("USB Chip-B & WMM Setting.....\n")); + "USB Chip-B & WMM Setting.....\n"); ep_map->ep_mapping[RTL_TXQ_BE] = 2; ep_map->ep_mapping[RTL_TXQ_BK] = 3; ep_map->ep_mapping[RTL_TXQ_VI] = 3; @@ -118,7 +118,7 @@ static void _TwoOutEpMapping(struct ieee80211_hw *hw, bool bIsChipB, ep_map->ep_mapping[RTL_TXQ_HI] = 2; } else { /* typical setting */ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("USB typical Setting.....\n")); + "USB typical Setting.....\n"); ep_map->ep_mapping[RTL_TXQ_BE] = 3; ep_map->ep_mapping[RTL_TXQ_BK] = 3; ep_map->ep_mapping[RTL_TXQ_VI] = 2; @@ -135,7 +135,7 @@ static void _ThreeOutEpMapping(struct ieee80211_hw *hw, bool bwificfg, struct rtl_priv *rtlpriv = rtl_priv(hw); if (bwificfg) { /* for WMM */ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("USB 3EP Setting for WMM.....\n")); + "USB 3EP Setting for WMM.....\n"); ep_map->ep_mapping[RTL_TXQ_BE] = 5; ep_map->ep_mapping[RTL_TXQ_BK] = 3; ep_map->ep_mapping[RTL_TXQ_VI] = 3; @@ -145,7 +145,7 @@ static void _ThreeOutEpMapping(struct ieee80211_hw *hw, bool bwificfg, ep_map->ep_mapping[RTL_TXQ_HI] = 2; } else { /* typical setting */ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("USB 3EP Setting for typical.....\n")); + "USB 3EP Setting for typical.....\n"); ep_map->ep_mapping[RTL_TXQ_BE] = 5; ep_map->ep_mapping[RTL_TXQ_BK] = 5; ep_map->ep_mapping[RTL_TXQ_VI] = 3; @@ -270,23 +270,23 @@ static enum rtl_desc_qsel _rtl8192cu_mq_to_descq(struct ieee80211_hw *hw, case 0: /* VO */ qsel = QSLT_VO; RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG, - ("VO queue, set qsel = 0x%x\n", QSLT_VO)); + "VO queue, set qsel = 0x%x\n", QSLT_VO); break; case 1: /* VI */ qsel = QSLT_VI; RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG, - ("VI queue, set qsel = 0x%x\n", QSLT_VI)); + "VI queue, set qsel = 0x%x\n", QSLT_VI); break; case 3: /* BK */ qsel = QSLT_BK; RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG, - ("BK queue, set qsel = 0x%x\n", QSLT_BK)); + "BK queue, set qsel = 0x%x\n", QSLT_BK); break; case 2: /* BE */ default: qsel = QSLT_BE; RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG, - ("BE queue, set qsel = 0x%x\n", QSLT_BE)); + "BE queue, set qsel = 0x%x\n", QSLT_BE); break; } out: @@ -422,17 +422,17 @@ static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb) bv = ieee80211_is_probe_resp(fc); if (bv) RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Got probe response frame.\n")); + "Got probe response frame\n"); if (ieee80211_is_beacon(fc)) - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Got beacon frame.\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Got beacon frame\n"); if (ieee80211_is_data(fc)) - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Got data frame.\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Got data frame\n"); RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Fram: fc = 0x%X addr1 = 0x%02X:0x%02X:0x%02X:0x%02X:0x%02X:" - "0x%02X\n", fc, (u32)hdr->addr1[0], (u32)hdr->addr1[1], - (u32)hdr->addr1[2], (u32)hdr->addr1[3], (u32)hdr->addr1[4], - (u32)hdr->addr1[5])); + "Fram: fc = 0x%X addr1 = 0x%02X:0x%02X:0x%02X:0x%02X:0x%02X:0x%02X\n", + fc, + (u32)hdr->addr1[0], (u32)hdr->addr1[1], + (u32)hdr->addr1[2], (u32)hdr->addr1[3], + (u32)hdr->addr1[4], (u32)hdr->addr1[5]); memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status)); ieee80211_rx_irqsafe(hw, skb); } @@ -594,7 +594,7 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, if (ieee80211_is_data_qos(fc)) { if (mac->rdg_en) { RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, - ("Enable RDG function.\n")); + "Enable RDG function\n"); SET_TX_DESC_RDG_ENABLE(txdesc, 1); SET_TX_DESC_HTC(txdesc, 1); } @@ -620,7 +620,7 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, SET_TX_DESC_BMC(txdesc, 1); _rtl_fill_usb_tx_desc(txdesc); _rtl_tx_desc_checksum(txdesc); - RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, (" %s ==>\n", __func__)); + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, " %s ==>\n", __func__); } void rtl92cu_fill_fake_txdesc(struct ieee80211_hw *hw, u8 * pDesc, diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c index 3cd0736fe8e..32537c4faf9 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c @@ -246,23 +246,21 @@ static void rtl92d_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2); rtl92d_release_cckandrw_pagea_ctl(hw, &flag); } - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("Cnt_Fast_Fsync_fail = %x, " - "Cnt_SB_Search_fail = %x\n", + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, + "Cnt_Fast_Fsync_fail = %x, Cnt_SB_Search_fail = %x\n", falsealm_cnt->cnt_fast_fsync_fail, - falsealm_cnt->cnt_sb_search_fail)); - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("Cnt_Parity_Fail = %x, " - "Cnt_Rate_Illegal = %x, Cnt_Crc8_fail = %x, " - "Cnt_Mcs_fail = %x\n", + falsealm_cnt->cnt_sb_search_fail); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, + "Cnt_Parity_Fail = %x, Cnt_Rate_Illegal = %x, Cnt_Crc8_fail = %x, Cnt_Mcs_fail = %x\n", falsealm_cnt->cnt_parity_fail, falsealm_cnt->cnt_rate_illegal, falsealm_cnt->cnt_crc8_fail, - falsealm_cnt->cnt_mcs_fail)); + falsealm_cnt->cnt_mcs_fail); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("Cnt_Ofdm_fail = %x, " "Cnt_Cck_fail = %x, " - "Cnt_all = %x\n", + "Cnt_Ofdm_fail = %x, Cnt_Cck_fail = %x, Cnt_all = %x\n", falsealm_cnt->cnt_ofdm_fail, falsealm_cnt->cnt_cck_fail, - falsealm_cnt->cnt_all)); + falsealm_cnt->cnt_all); } static void rtl92d_dm_find_minimum_rssi(struct ieee80211_hw *hw) @@ -275,7 +273,7 @@ static void rtl92d_dm_find_minimum_rssi(struct ieee80211_hw *hw) (rtlpriv->dm.UNDEC_SM_PWDB == 0)) { de_digtable.min_undecorated_pwdb_for_dm = 0; RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, - ("Not connected to any\n")); + "Not connected to any\n"); } if (mac->link_state >= MAC80211_LINKED) { if (mac->opmode == NL80211_IFTYPE_AP || @@ -283,25 +281,25 @@ static void rtl92d_dm_find_minimum_rssi(struct ieee80211_hw *hw) de_digtable.min_undecorated_pwdb_for_dm = rtlpriv->dm.UNDEC_SM_PWDB; RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, - ("AP Client PWDB = 0x%lx\n", - rtlpriv->dm.UNDEC_SM_PWDB)); + "AP Client PWDB = 0x%lx\n", + rtlpriv->dm.UNDEC_SM_PWDB); } else { de_digtable.min_undecorated_pwdb_for_dm = rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, - ("STA Default Port PWDB = 0x%x\n", - de_digtable.min_undecorated_pwdb_for_dm)); + "STA Default Port PWDB = 0x%x\n", + de_digtable.min_undecorated_pwdb_for_dm); } } else { de_digtable.min_undecorated_pwdb_for_dm = rtlpriv->dm.UNDEC_SM_PWDB; RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, - ("AP Ext Port or disconnet PWDB = 0x%x\n", - de_digtable.min_undecorated_pwdb_for_dm)); + "AP Ext Port or disconnet PWDB = 0x%x\n", + de_digtable.min_undecorated_pwdb_for_dm); } - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("MinUndecoratedPWDBForDM =%d\n", - de_digtable.min_undecorated_pwdb_for_dm)); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "MinUndecoratedPWDBForDM =%d\n", + de_digtable.min_undecorated_pwdb_for_dm); } static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) @@ -340,14 +338,14 @@ static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) } de_digtable.pre_cck_pd_state = de_digtable.cur_cck_pd_state; } - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("CurSTAConnectState=%s\n", - (de_digtable.cursta_connectctate == DIG_STA_CONNECT ? - "DIG_STA_CONNECT " : "DIG_STA_DISCONNECT"))); - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("CCKPDStage=%s\n", - (de_digtable.cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI ? - "Low RSSI " : "High RSSI "))); - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("is92d single phy =%x\n", - IS_92D_SINGLEPHY(rtlpriv->rtlhal.version))); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "CurSTAConnectState=%s\n", + de_digtable.cursta_connectctate == DIG_STA_CONNECT ? + "DIG_STA_CONNECT " : "DIG_STA_DISCONNECT"); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "CCKPDStage=%s\n", + de_digtable.cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI ? + "Low RSSI " : "High RSSI "); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "is92d single phy =%x\n", + IS_92D_SINGLEPHY(rtlpriv->rtlhal.version)); } @@ -355,12 +353,12 @@ void rtl92d_dm_write_dig(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("cur_igvalue = 0x%x, " - "pre_igvalue = 0x%x, backoff_val = %d\n", + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, + "cur_igvalue = 0x%x, pre_igvalue = 0x%x, backoff_val = %d\n", de_digtable.cur_igvalue, de_digtable.pre_igvalue, - de_digtable.backoff_val)); + de_digtable.backoff_val); if (de_digtable.dig_enable_flag == false) { - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("DIG is disabled\n")); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "DIG is disabled\n"); de_digtable.pre_igvalue = 0x17; return; } @@ -377,22 +375,21 @@ static void rtl92d_early_mode_enabled(struct rtl_priv *rtlpriv) { if ((rtlpriv->mac80211.link_state >= MAC80211_LINKED) && (rtlpriv->mac80211.vendor == PEER_CISCO)) { - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("IOT_PEER = CISCO\n")); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "IOT_PEER = CISCO\n"); if (de_digtable.last_min_undecorated_pwdb_for_dm >= 50 && de_digtable.min_undecorated_pwdb_for_dm < 50) { rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x00); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("Early Mode Off\n")); + "Early Mode Off\n"); } else if (de_digtable.last_min_undecorated_pwdb_for_dm <= 55 && de_digtable.min_undecorated_pwdb_for_dm > 55) { rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x0f); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("Early Mode On\n")); + "Early Mode On\n"); } } else if (!(rtl_read_byte(rtlpriv, REG_EARLY_MODE_CONTROL) & 0xf)) { rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x0f); - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("Early Mode On\n")); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "Early Mode On\n"); } } @@ -402,7 +399,7 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw) u8 value_igi = de_digtable.cur_igvalue; struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("==>\n")); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "==>\n"); if (rtlpriv->rtlhal.earlymode_enable) { rtl92d_early_mode_enabled(rtlpriv); de_digtable.last_min_undecorated_pwdb_for_dm = @@ -421,7 +418,7 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw) /* Not STA mode return tmp */ if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION) return; - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("progress\n")); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "progress\n"); /* Decide the current status and if modify initial gain or not */ if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) de_digtable.cursta_connectctate = DIG_STA_CONNECT; @@ -438,16 +435,16 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw) else if (falsealm_cnt->cnt_all >= DM_DIG_FA_TH2) value_igi += 2; RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("dm_DIG() Before: large_fa_hit=%d, forbidden_igi=%x\n", - de_digtable.large_fa_hit, de_digtable.forbidden_igi)); + "dm_DIG() Before: large_fa_hit=%d, forbidden_igi=%x\n", + de_digtable.large_fa_hit, de_digtable.forbidden_igi); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("dm_DIG() Before: Recover_cnt=%d, rx_gain_range_min=%x\n", - de_digtable.recover_cnt, de_digtable.rx_gain_range_min)); + "dm_DIG() Before: Recover_cnt=%d, rx_gain_range_min=%x\n", + de_digtable.recover_cnt, de_digtable.rx_gain_range_min); /* deal with abnorally large false alarm */ if (falsealm_cnt->cnt_all > 10000) { RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("dm_DIG(): Abnornally false alarm case.\n")); + "dm_DIG(): Abnormally false alarm case\n"); de_digtable.large_fa_hit++; if (de_digtable.forbidden_igi < de_digtable.cur_igvalue) { @@ -486,11 +483,11 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw) } } RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("dm_DIG() After: large_fa_hit=%d, forbidden_igi=%x\n", - de_digtable.large_fa_hit, de_digtable.forbidden_igi)); + "dm_DIG() After: large_fa_hit=%d, forbidden_igi=%x\n", + de_digtable.large_fa_hit, de_digtable.forbidden_igi); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("dm_DIG() After: recover_cnt=%d, rx_gain_range_min=%x\n", - de_digtable.recover_cnt, de_digtable.rx_gain_range_min)); + "dm_DIG() After: recover_cnt=%d, rx_gain_range_min=%x\n", + de_digtable.recover_cnt, de_digtable.rx_gain_range_min); if (value_igi > DM_DIG_MAX) value_igi = DM_DIG_MAX; @@ -500,7 +497,7 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw) rtl92d_dm_write_dig(hw); if (rtlpriv->rtlhal.current_bandtype != BAND_ON_5G) rtl92d_dm_cck_packet_detection_thresh(hw); - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("<<==\n")); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "<<==\n"); } static void rtl92d_dm_init_dynamic_txpower(struct ieee80211_hw *hw) @@ -528,7 +525,7 @@ static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw) if ((mac->link_state < MAC80211_LINKED) && (rtlpriv->dm.UNDEC_SM_PWDB == 0)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("Not connected to any\n")); + "Not connected to any\n"); rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; return; @@ -538,40 +535,40 @@ static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw) undecorated_smoothed_pwdb = rtlpriv->dm.UNDEC_SM_PWDB; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("IBSS Client PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "IBSS Client PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } else { undecorated_smoothed_pwdb = rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("STA Default Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "STA Default Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } } else { undecorated_smoothed_pwdb = rtlpriv->dm.UNDEC_SM_PWDB; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Ext Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "AP Ext Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } if (rtlhal->current_bandtype == BAND_ON_5G) { if (undecorated_smoothed_pwdb >= 0x33) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL2; RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD, - ("5G:TxHighPwrLevel_Level2 (TxPwr=0x0)\n")); + "5G:TxHighPwrLevel_Level2 (TxPwr=0x0)\n"); } else if ((undecorated_smoothed_pwdb < 0x33) && (undecorated_smoothed_pwdb >= 0x2b)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD, - ("5G:TxHighPwrLevel_Level1 (TxPwr=0x10)\n")); + "5G:TxHighPwrLevel_Level1 (TxPwr=0x10)\n"); } else if (undecorated_smoothed_pwdb < 0x2b) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD, - ("5G:TxHighPwrLevel_Normal\n")); + "5G:TxHighPwrLevel_Normal\n"); } } else { if (undecorated_smoothed_pwdb >= @@ -579,7 +576,7 @@ static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw) rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL2; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n")); + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); } else if ((undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) @@ -589,19 +586,19 @@ static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw) rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n")); + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); } else if (undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_NORMAL\n")); + "TXHIGHPWRLEVEL_NORMAL\n"); } } if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("PHY_SetTxPowerLevel8192S() Channel = %d\n", - rtlphy->current_channel)); + "PHY_SetTxPowerLevel8192S() Channel = %d\n", + rtlphy->current_channel); rtl92d_phy_set_txpower_level(hw, rtlphy->current_channel); } rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; @@ -717,7 +714,7 @@ static void rtl92d_dm_rxgain_tracking_thermalmeter(struct ieee80211_hw *hw) u4tmp = (index_mapping[(rtlpriv->efuse.eeprom_thermalmeter - rtlpriv->dm.thermalvalue_rxgain)]) << 12; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("===> Rx Gain %x\n", u4tmp)); + "===> Rx Gain %x\n", u4tmp); for (i = RF90_PATH_A; i < rtlpriv->phy.num_total_rfpath; i++) rtl_set_rfreg(hw, i, 0x3C, BRFREGOFFSETMASK, (rtlpriv->phy.reg_rf3c[i] & (~(0xF000))) | u4tmp); @@ -741,27 +738,22 @@ static void rtl92d_bandtype_2_4G(struct ieee80211_hw *hw, long *temp_cckg, if (!memcmp((void *)&temp_cck, (void *)&cckswing_table_ch14[i][2], 4)) { *cck_index_old = (u8) i; - RT_TRACE(rtlpriv, - COMP_POWER_TRACKING, - DBG_LOUD, - ("Initial reg0x%x = 0x%lx, " - "cck_index=0x%x, ch 14 %d\n", - RCCK0_TXFILTER2, - temp_cck, *cck_index_old, - rtlpriv->dm.cck_inch14)); + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Initial reg0x%x = 0x%lx, cck_index=0x%x, ch 14 %d\n", + RCCK0_TXFILTER2, temp_cck, + *cck_index_old, + rtlpriv->dm.cck_inch14); break; } } else { if (!memcmp((void *) &temp_cck, &cckswing_table_ch1ch13[i][2], 4)) { *cck_index_old = (u8) i; - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, - DBG_LOUD, - ("Initial reg0x%x = 0x%lx, " - "cck_index = 0x%x, ch14 %d\n", - RCCK0_TXFILTER2, - temp_cck, *cck_index_old, - rtlpriv->dm.cck_inch14)); + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch14 %d\n", + RCCK0_TXFILTER2, temp_cck, + *cck_index_old, + rtlpriv->dm.cck_inch14); break; } } @@ -884,12 +876,12 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( }; rtlpriv->dm.txpower_trackinginit = true; - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("\n")); + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "\n"); thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0xf800); RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " - "eeprom_thermalmeter 0x%x\n", thermalvalue, - rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter)); + "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n", + thermalvalue, + rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter); rtl92d_phy_ap_calibrate(hw, (thermalvalue - rtlefuse->eeprom_thermalmeter)); if (is2t) @@ -904,10 +896,9 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( ofdm_index_old[0] = (u8) i; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Initial pathA ele_d reg0x%x = 0x%lx," - " ofdm_index=0x%x\n", + "Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index=0x%x\n", ROFDM0_XATxIQIMBALANCE, - ele_d, ofdm_index_old[0])); + ele_d, ofdm_index_old[0]); break; } } @@ -920,11 +911,9 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( ofdm_index_old[1] = (u8) i; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Initial pathB ele_d reg " - "0x%x = 0x%lx, ofdm_index " - "= 0x%x\n", + "Initial pathB ele_d reg 0x%x = 0x%lx, ofdm_index = 0x%x\n", ROFDM0_XBTxIQIMBALANCE, ele_d, - ofdm_index_old[1])); + ofdm_index_old[1]); break; } } @@ -952,7 +941,7 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i]; rtlpriv->dm.cck_index = cck_index_old; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("reload ofdm index for band switch\n")); + "reload ofdm index for band switch\n"); } rtlpriv->dm.thermalvalue_avg [rtlpriv->dm.thermalvalue_avg_index] = thermalvalue; @@ -995,12 +984,10 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( (thermalvalue - rtlpriv->dm.thermalvalue_rxgain) : (rtlpriv->dm.thermalvalue_rxgain - thermalvalue); RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x" - " eeprom_thermalmeter 0x%x delta 0x%x " - "delta_lck 0x%x delta_iqk 0x%x\n", - thermalvalue, rtlpriv->dm.thermalvalue, - rtlefuse->eeprom_thermalmeter, delta, delta_lck, - delta_iqk)); + "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x delta 0x%x delta_lck 0x%x delta_iqk 0x%x\n", + thermalvalue, rtlpriv->dm.thermalvalue, + rtlefuse->eeprom_thermalmeter, delta, delta_lck, + delta_iqk); if ((delta_lck > rtlefuse->delta_lck) && (rtlefuse->delta_lck != 0)) { rtlpriv->dm.thermalvalue_lck = thermalvalue; @@ -1036,17 +1023,15 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( } if (is2t) { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("temp OFDM_A_index=0x%x, OFDM_B_index" - " = 0x%x,cck_index=0x%x\n", - rtlpriv->dm.ofdm_index[0], - rtlpriv->dm.ofdm_index[1], - rtlpriv->dm.cck_index)); + "temp OFDM_A_index=0x%x, OFDM_B_index = 0x%x,cck_index=0x%x\n", + rtlpriv->dm.ofdm_index[0], + rtlpriv->dm.ofdm_index[1], + rtlpriv->dm.cck_index); } else { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("temp OFDM_A_index=0x%x,cck_index = " - "0x%x\n", - rtlpriv->dm.ofdm_index[0], - rtlpriv->dm.cck_index)); + "temp OFDM_A_index=0x%x,cck_index = 0x%x\n", + rtlpriv->dm.ofdm_index[0], + rtlpriv->dm.cck_index); } for (i = 0; i < rf; i++) { if (ofdm_index[i] > OFDM_TABLE_SIZE_92D - 1) @@ -1070,15 +1055,13 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( } if (is2t) { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("new OFDM_A_index=0x%x, OFDM_B_index " - "= 0x%x, cck_index=0x%x\n", + "new OFDM_A_index=0x%x, OFDM_B_index = 0x%x, cck_index=0x%x\n", ofdm_index[0], ofdm_index[1], - cck_index)); + cck_index); } else { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("new OFDM_A_index=0x%x,cck_index = " - "0x%x\n", - ofdm_index[0], cck_index)); + "new OFDM_A_index=0x%x,cck_index = 0x%x\n", + ofdm_index[0], cck_index); } ele_d = (ofdmswing_table[(u8) ofdm_index[0]] & 0xFFC00000) >> 22; @@ -1124,12 +1107,10 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( } RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("TxPwrTracking for interface %d path A: X =" - " 0x%lx, Y = 0x%lx ele_A = 0x%lx ele_C = " - "0x%lx ele_D = 0x%lx 0xe94 = 0x%lx 0xe9c = " - "0x%lx\n", rtlhal->interfaceindex, + "TxPwrTracking for interface %d path A: X = 0x%lx, Y = 0x%lx ele_A = 0x%lx ele_C = 0x%lx ele_D = 0x%lx 0xe94 = 0x%lx 0xe9c = 0x%lx\n", + rtlhal->interfaceindex, val_x, val_y, ele_a, ele_c, ele_d, - val_x, val_y)); + val_x, val_y); if (rtlhal->current_bandtype == BAND_ON_2_4G) { /* Adjust CCK according to IQK result */ @@ -1232,20 +1213,16 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( BIT(28), 0x00); } RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("TxPwrTracking path B: X = 0x%lx, " - "Y = 0x%lx ele_A = 0x%lx ele_C = 0x" - "%lx ele_D = 0x%lx 0xeb4 = 0x%lx " - "0xebc = 0x%lx\n", - val_x, val_y, ele_a, ele_c, - ele_d, val_x, val_y)); + "TxPwrTracking path B: X = 0x%lx, Y = 0x%lx ele_A = 0x%lx ele_C = 0x%lx ele_D = 0x%lx 0xeb4 = 0x%lx 0xebc = 0x%lx\n", + val_x, val_y, ele_a, ele_c, + ele_d, val_x, val_y); } RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("TxPwrTracking 0xc80 = 0x%x, 0xc94 = " - "0x%x RF 0x24 = 0x%x\n", + "TxPwrTracking 0xc80 = 0x%x, 0xc94 = 0x%x RF 0x24 = 0x%x\n", rtl_get_bbreg(hw, 0xc80, BMASKDWORD), rtl_get_bbreg(hw, 0xc94, BMASKDWORD), rtl_get_rfreg(hw, RF90_PATH_A, 0x24, - BRFREGOFFSETMASK))); + BRFREGOFFSETMASK)); } if ((delta_iqk > rtlefuse->delta_iqk) && (rtlefuse->delta_iqk != 0)) { @@ -1262,7 +1239,7 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( rtlpriv->dm.thermalvalue = thermalvalue; } - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("<===\n")); + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "<===\n"); } static void rtl92d_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) @@ -1273,8 +1250,8 @@ static void rtl92d_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) rtlpriv->dm.txpower_trackinginit = false; rtlpriv->dm.txpower_track_control = true; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("pMgntInfo->txpower_tracking = %d\n", - rtlpriv->dm.txpower_tracking)); + "pMgntInfo->txpower_tracking = %d\n", + rtlpriv->dm.txpower_tracking); } void rtl92d_dm_check_txpower_tracking_thermal_meter(struct ieee80211_hw *hw) @@ -1289,12 +1266,12 @@ void rtl92d_dm_check_txpower_tracking_thermal_meter(struct ieee80211_hw *hw) rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17) | BIT(16), 0x03); RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Trigger 92S Thermal Meter!!\n")); + "Trigger 92S Thermal Meter!!\n"); tm_trigger = 1; return; } else { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Schedule TxPowerTracking direct call!!\n")); + "Schedule TxPowerTracking direct call!!\n"); rtl92d_dm_txpower_tracking_callback_thermalmeter(hw); tm_trigger = 0; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c index db6972ffe50..b84f10d60c0 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c @@ -124,14 +124,14 @@ static void _rtl92d_write_fw(struct ieee80211_hw *hw, u32 pagenums, remainSize; u32 page, offset; - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size)); + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size); if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE) _rtl92d_fill_dummy(bufferPtr, &size); pagenums = size / FW_8192D_PAGE_SIZE; remainSize = size % FW_8192D_PAGE_SIZE; if (pagenums > 8) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Page numbers should not greater then 8\n")); + "Page numbers should not greater then 8\n"); } for (page = 0; page < pagenums; page++) { offset = page * FW_8192D_PAGE_SIZE; @@ -158,12 +158,12 @@ static int _rtl92d_fw_free_to_go(struct ieee80211_hw *hw) (!(value32 & FWDL_ChkSum_rpt))); if (counter >= FW_8192D_POLLING_TIMEOUT_COUNT) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("chksum report faill ! REG_MCUFWDL:0x%08x .\n", - value32)); + "chksum report faill ! REG_MCUFWDL:0x%08x\n", + value32); return -EIO; } RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32)); + "Checksum report OK ! REG_MCUFWDL:0x%08x\n", value32); value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); value32 |= MCUFWDL_RDY; rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); @@ -188,7 +188,7 @@ void rtl92d_firmware_selfreset(struct ieee80211_hw *hw) } RT_ASSERT((delay > 0), ("8051 reset failed!\n")); RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - ("=====> 8051 reset success (%d) .\n", delay)); + "=====> 8051 reset success (%d)\n", delay); } static int _rtl92d_fw_init(struct ieee80211_hw *hw) @@ -197,7 +197,7 @@ static int _rtl92d_fw_init(struct ieee80211_hw *hw) struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); u32 counter; - RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, ("FW already have download\n")); + RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, "FW already have download\n"); /* polling for FW ready */ counter = 0; do { @@ -205,10 +205,9 @@ static int _rtl92d_fw_init(struct ieee80211_hw *hw) if (rtl_read_byte(rtlpriv, FW_MAC0_READY) & MAC0_READY) { RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - ("Polling FW ready success!! " - "REG_MCUFWDL: 0x%x .\n", + "Polling FW ready success!! REG_MCUFWDL: 0x%x\n", rtl_read_byte(rtlpriv, - FW_MAC0_READY))); + FW_MAC0_READY)); return 0; } udelay(5); @@ -216,10 +215,9 @@ static int _rtl92d_fw_init(struct ieee80211_hw *hw) if (rtl_read_byte(rtlpriv, FW_MAC1_READY) & MAC1_READY) { RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - ("Polling FW ready success!! " - "REG_MCUFWDL: 0x%x .\n", + "Polling FW ready success!! REG_MCUFWDL: 0x%x\n", rtl_read_byte(rtlpriv, - FW_MAC1_READY))); + FW_MAC1_READY)); return 0; } udelay(5); @@ -228,18 +226,16 @@ static int _rtl92d_fw_init(struct ieee80211_hw *hw) if (rtlhal->interfaceindex == 0) { RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - ("Polling FW ready fail!! MAC0 FW init not ready: " - "0x%x .\n", - rtl_read_byte(rtlpriv, FW_MAC0_READY))); + "Polling FW ready fail!! MAC0 FW init not ready: 0x%x\n", + rtl_read_byte(rtlpriv, FW_MAC0_READY)); } else { RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - ("Polling FW ready fail!! MAC1 FW init not ready: " - "0x%x .\n", - rtl_read_byte(rtlpriv, FW_MAC1_READY))); + "Polling FW ready fail!! MAC1 FW init not ready: 0x%x\n", + rtl_read_byte(rtlpriv, FW_MAC1_READY)); } RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - ("Polling FW ready fail!! REG_MCUFWDL:0x%08ul .\n", - rtl_read_dword(rtlpriv, REG_MCUFWDL))); + "Polling FW ready fail!! REG_MCUFWDL:0x%08ul\n", + rtl_read_dword(rtlpriv, REG_MCUFWDL)); return -1; } @@ -264,13 +260,13 @@ int rtl92d_download_fw(struct ieee80211_hw *hw) pfwdata = (u8 *) rtlhal->pfirmware; rtlhal->fw_version = (u16) GET_FIRMWARE_HDR_VERSION(pfwheader); rtlhal->fw_subversion = (u16) GET_FIRMWARE_HDR_SUB_VER(pfwheader); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, (" FirmwareVersion(%d)," - "FirmwareSubVersion(%d), Signature(%#x)\n", - rtlhal->fw_version, rtlhal->fw_subversion, - GET_FIRMWARE_HDR_SIGNATURE(pfwheader))); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "FirmwareVersion(%d), FirmwareSubVersion(%d), Signature(%#x)\n", + rtlhal->fw_version, rtlhal->fw_subversion, + GET_FIRMWARE_HDR_SIGNATURE(pfwheader)); if (IS_FW_HEADER_EXIST(pfwheader)) { RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Shift 32 bytes for FW header!!\n")); + "Shift 32 bytes for FW header!!\n"); pfwdata = pfwdata + 32; fwsize = fwsize - 32; } @@ -302,8 +298,7 @@ int rtl92d_download_fw(struct ieee80211_hw *hw) break; else RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - ("Wait for another mac " - "download fw\n")); + "Wait for another mac download fw\n"); } spin_lock_irqsave(&globalmutex_for_fwdownload, flags); value = rtl_read_byte(rtlpriv, 0x1f); @@ -337,11 +332,10 @@ int rtl92d_download_fw(struct ieee80211_hw *hw) spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("fw is not ready to run!\n")); + "fw is not ready to run!\n"); goto exit; } else { - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - ("fw is ready to run!\n")); + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "fw is ready to run!\n"); } exit: err = _rtl92d_fw_init(hw); @@ -381,24 +375,24 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw, if (ppsc->rfpwr_state == ERFOFF || ppsc->inactive_pwrstate == ERFOFF) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Return as RF is off!!!\n")); + "Return as RF is off!!!\n"); return; } - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("come in\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n"); while (true) { spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); if (rtlhal->h2c_setinprogress) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("H2C set in progress! Wait to set.." - "element_id(%d).\n", element_id)); + "H2C set in progress! Wait to set..element_id(%d)\n", + element_id); while (rtlhal->h2c_setinprogress) { spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); h2c_waitcounter++; RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Wait 100 us (%d times)...\n", - h2c_waitcounter)); + "Wait 100 us (%d times)...\n", + h2c_waitcounter); udelay(100); if (h2c_waitcounter > 1000) @@ -418,8 +412,7 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw, wait_writeh2c_limmit--; if (wait_writeh2c_limmit == 0) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Write H2C fail because no trigger " - "for FW INT!\n")); + "Write H2C fail because no trigger for FW INT!\n"); break; } boxnum = rtlhal->last_hmeboxnum; @@ -442,7 +435,7 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum); @@ -450,29 +443,29 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw, wait_h2c_limmit--; if (wait_h2c_limmit == 0) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Wating too long for FW read " - "clear HMEBox(%d)!\n", boxnum)); + "Waiting too long for FW read clear HMEBox(%d)!\n", + boxnum); break; } udelay(10); isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum); u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF); RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Wating for FW read clear HMEBox(%d)!!! " - "0x1BF = %2x\n", boxnum, u1b_tmp)); + "Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n", + boxnum, u1b_tmp); } if (!isfw_read) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Write H2C register BOX[%d] fail!!!!! " - "Fw do not read.\n", boxnum)); + "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n", + boxnum); break; } memset(boxcontent, 0, sizeof(boxcontent)); memset(boxextcontent, 0, sizeof(boxextcontent)); boxcontent[0] = element_id; RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Write element_id box_reg(%4x) = %2x\n", - box_reg, element_id)); + "Write element_id box_reg(%4x) = %2x\n", + box_reg, element_id); switch (cmd_len) { case 1: boxcontent[0] &= ~(BIT(7)); @@ -519,7 +512,7 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } bwrite_sucess = true; @@ -527,13 +520,13 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw, if (rtlhal->last_hmeboxnum == 4) rtlhal->last_hmeboxnum = 0; RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("pHalData->last_hmeboxnum = %d\n", - rtlhal->last_hmeboxnum)); + "pHalData->last_hmeboxnum = %d\n", + rtlhal->last_hmeboxnum); } spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); rtlhal->h2c_setinprogress = false; spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n"); } void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw, @@ -559,7 +552,7 @@ void rtl92d_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) u8 u1_h2c_set_pwrmode[3] = { 0 }; struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode)); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode); SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode); SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1); SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode, @@ -771,14 +764,14 @@ void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished) dlok = true; if (dlok) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Set RSVD page location to Fw.\n")); + "Set RSVD page location to Fw\n"); RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, "H2C_RSVDPAGE", u1RsvdPageLoc, 3); rtl92d_fill_h2c_cmd(hw, H2C_RSVDPAGE, sizeof(u1RsvdPageLoc), u1RsvdPageLoc); } else RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Set RSVD page location to Fw FAIL!!!!!!.\n")); + "Set RSVD page location to Fw FAIL!!!!!!\n"); } void rtl92d_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus) diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c index 5c8a639582a..5eecf403a5c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c @@ -166,7 +166,7 @@ void rtl92de_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } @@ -230,7 +230,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) u8 e_aci; RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("HW_VAR_SLOT_TIME %x\n", val[0])); + "HW_VAR_SLOT_TIME %x\n", val[0]); rtl_write_byte(rtlpriv, REG_SLOT, val[0]); for (e_aci = 0; e_aci < AC_MAX; e_aci++) rtlpriv->cfg->ops->set_hw_reg(hw, @@ -261,8 +261,8 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) min_spacing_to_set); *val = min_spacing_to_set; RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", - mac->min_space_cfg)); + "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", + mac->min_space_cfg); rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, mac->min_space_cfg); } @@ -275,8 +275,8 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) mac->min_space_cfg = rtlpriv->rtlhal.minspace_cfg; mac->min_space_cfg |= (density_to_set << 3); RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_SHORTGI_DENSITY: %#x\n", - mac->min_space_cfg)); + "Set HW_VAR_SHORTGI_DENSITY: %#x\n", + mac->min_space_cfg); rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, mac->min_space_cfg); break; @@ -310,8 +310,8 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) } rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, regtoSet); RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_AMPDU_FACTOR: %#x\n", - factor_toset)); + "Set HW_VAR_AMPDU_FACTOR: %#x\n", + factor_toset); } break; } @@ -344,8 +344,8 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("HW_VAR_ACM_CTRL acm set " - "failed: eACI is %d\n", acm)); + "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", + acm); break; } } else { @@ -361,13 +361,13 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE, - ("SetHwReg8190pci(): [HW_VAR_ACM_CTRL] " - "Write 0x%X\n", acm_ctrl)); + "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", + acm_ctrl); rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); break; } @@ -502,7 +502,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) } default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } @@ -522,8 +522,8 @@ static bool _rtl92de_llt_write(struct ieee80211_hw *hw, u32 address, u32 data) break; if (count > POLLING_LLT_THRESHOLD) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to polling write LLT done at " - "address %d!\n", address)); + "Failed to polling write LLT done at address %d!\n", + address); status = false; break; } @@ -879,12 +879,12 @@ void rtl92de_enable_hw_security_config(struct ieee80211_hw *hw) u8 sec_reg_value; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", - rtlpriv->sec.pairwise_enc_algorithm, - rtlpriv->sec.group_enc_algorithm)); + "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", + rtlpriv->sec.pairwise_enc_algorithm, + rtlpriv->sec.group_enc_algorithm); if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("not open hw encryption\n")); + "not open hw encryption\n"); return; } sec_reg_value = SCR_TXENCENABLE | SCR_RXENCENABLE; @@ -895,7 +895,7 @@ void rtl92de_enable_hw_security_config(struct ieee80211_hw *hw) sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The SECR-value %x\n", sec_reg_value)); + "The SECR-value %x\n", sec_reg_value); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); } @@ -921,7 +921,7 @@ int rtl92de_hw_init(struct ieee80211_hw *hw) /* rtlpriv->intf_ops->disable_aspm(hw); */ rtstatus = _rtl92de_init_mac(hw); if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Init MAC failed\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n"); err = 1; spin_unlock_irqrestore(&globalmutex_for_power_and_efuse, flags); return err; @@ -930,8 +930,7 @@ int rtl92de_hw_init(struct ieee80211_hw *hw) spin_unlock_irqrestore(&globalmutex_for_power_and_efuse, flags); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Failed to download FW. Init HW " - "without FW..\n")); + "Failed to download FW. Init HW without FW..\n"); rtlhal->fw_ready = false; return 1; } else { @@ -946,7 +945,7 @@ int rtl92de_hw_init(struct ieee80211_hw *hw) if (rtlhal->earlymode_enable) { RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EarlyMode Enabled!!!\n")); + "EarlyMode Enabled!!!\n"); tmp_u1b = rtl_read_byte(rtlpriv, 0x4d0); tmp_u1b = tmp_u1b | 0x1f; @@ -1064,10 +1063,10 @@ static enum version_8192d _rtl92de_read_chip_version(struct ieee80211_hw *hw) value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG); if (!(value32 & 0x000f0000)) { version = VERSION_TEST_CHIP_92D_SINGLEPHY; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("TEST CHIP!!!\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "TEST CHIP!!!\n"); } else { version = VERSION_NORMAL_CHIP_92D_SINGLEPHY; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Normal CHIP!!!\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Normal CHIP!!!\n"); } return version; } @@ -1092,8 +1091,8 @@ static int _rtl92de_set_media_status(struct ieee80211_hw *hw, _rtl92de_disable_bcn_sub_func(hw); } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Set HW_VAR_MEDIA_STATUS: No such media " - "status(%x).\n", type)); + "Set HW_VAR_MEDIA_STATUS: No such media status(%x)\n", + type); } bcnfunc_enable = rtl_read_byte(rtlpriv, REG_BCN_CTRL); switch (type) { @@ -1102,30 +1101,30 @@ static int _rtl92de_set_media_status(struct ieee80211_hw *hw, ledaction = LED_CTL_LINK; bcnfunc_enable &= 0xF7; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to NO LINK!\n")); + "Set Network type to NO LINK!\n"); break; case NL80211_IFTYPE_ADHOC: bt_msr |= MSR_ADHOC; bcnfunc_enable |= 0x08; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to Ad Hoc!\n")); + "Set Network type to Ad Hoc!\n"); break; case NL80211_IFTYPE_STATION: bt_msr |= MSR_INFRA; ledaction = LED_CTL_LINK; bcnfunc_enable &= 0xF7; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to STA!\n")); + "Set Network type to STA!\n"); break; case NL80211_IFTYPE_AP: bt_msr |= MSR_AP; bcnfunc_enable |= 0x08; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to AP!\n")); + "Set Network type to AP!\n"); break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Network type %d not support!\n", type)); + "Network type %d not supported!\n", type); return 1; break; @@ -1189,7 +1188,7 @@ void rtl92d_linked_set_reg(struct ieee80211_hw *hw) indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel); if (!rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done) { RT_TRACE(rtlpriv, COMP_SCAN | COMP_INIT, DBG_DMESG, - ("Do IQK for channel:%d.\n", channel)); + "Do IQK for channel:%d\n", channel); rtl92d_phy_iq_calibrate(hw); } } @@ -1305,8 +1304,8 @@ static void _rtl92de_poweroff_adapter(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, 0x10); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("In PowerOff,reg0x%x=%X\n", REG_SPS0_CTRL, - rtl_read_byte(rtlpriv, REG_SPS0_CTRL))); + "In PowerOff,reg0x%x=%X\n", + REG_SPS0_CTRL, rtl_read_byte(rtlpriv, REG_SPS0_CTRL)); /* r. Note: for PCIe interface, PON will not turn */ /* off m-bias and BandGap in PCIe suspend mode. */ @@ -1319,7 +1318,7 @@ static void _rtl92de_poweroff_adapter(struct ieee80211_hw *hw) spin_unlock_irqrestore(&globalmutex_power, flags); } - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("<=======\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "<=======\n"); } void rtl92de_card_disable(struct ieee80211_hw *hw) @@ -1377,7 +1376,7 @@ void rtl92de_card_disable(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xff); udelay(50); rtl_write_byte(rtlpriv, REG_CR, 0x0); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("==> Do power off.......\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "==> Do power off.......\n"); if (rtl92d_phy_check_poweroff(hw)) _rtl92de_poweroff_adapter(hw); return; @@ -1425,7 +1424,7 @@ void rtl92de_set_beacon_interval(struct ieee80211_hw *hw) u16 bcn_interval = mac->beacon_interval; RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, - ("beacon_interval:%d\n", bcn_interval)); + "beacon_interval:%d\n", bcn_interval); /* rtl92de_disable_interrupt(hw); */ rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); /* rtl92de_enable_interrupt(hw); */ @@ -1437,8 +1436,8 @@ void rtl92de_update_interrupt_mask(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, - ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr)); + RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, "add_msr:%x, rm_msr:%x\n", + add_msr, rm_msr); if (add_msr) rtlpci->irq_mask[0] |= add_msr; if (rm_msr) @@ -1615,9 +1614,9 @@ static void _rtl92de_read_txpower_info(struct ieee80211_hw *hw, rtlefuse->internal_pa_5g[1] = !((hwinfo[EEPROM_TSSI_B_5G] & BIT(6)) >> 6); RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Is D cut,Internal PA0 %d Internal PA1 %d\n", + "Is D cut,Internal PA0 %d Internal PA1 %d\n", rtlefuse->internal_pa_5g[0], - rtlefuse->internal_pa_5g[1])); + rtlefuse->internal_pa_5g[1]); } rtlefuse->eeprom_c9 = hwinfo[EEPROM_RF_OPT6]; rtlefuse->eeprom_cc = hwinfo[EEPROM_RF_OPT7]; @@ -1667,14 +1666,14 @@ static void _rtl92de_read_txpower_info(struct ieee80211_hw *hw, if (rtlefuse->eeprom_c9 == 0xFF) rtlefuse->eeprom_c9 = 0x00; RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, - ("EEPROMRegulatory = 0x%x\n", rtlefuse->eeprom_regulatory)); + "EEPROMRegulatory = 0x%x\n", rtlefuse->eeprom_regulatory); RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, - ("ThermalMeter = 0x%x\n", rtlefuse->eeprom_thermalmeter)); + "ThermalMeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, - ("CrystalCap = 0x%x\n", rtlefuse->crystalcap)); + "CrystalCap = 0x%x\n", rtlefuse->crystalcap); RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, - ("Delta_IQK = 0x%x Delta_LCK = 0x%x\n", rtlefuse->delta_iqk, - rtlefuse->delta_lck)); + "Delta_IQK = 0x%x Delta_LCK = 0x%x\n", + rtlefuse->delta_iqk, rtlefuse->delta_lck); for (rfPath = 0; rfPath < RF6052_MAX_PATH; rfPath++) { for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) { @@ -1710,11 +1709,11 @@ static void _rtl92de_read_macphymode_from_prom(struct ieee80211_hw *hw, if (macphy_crvalue & BIT(3)) { rtlhal->macphymode = SINGLEMAC_SINGLEPHY; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("MacPhyMode SINGLEMAC_SINGLEPHY\n")); + "MacPhyMode SINGLEMAC_SINGLEPHY\n"); } else { rtlhal->macphymode = DUALMAC_DUALPHY; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("MacPhyMode DUALMAC_DUALPHY\n")); + "MacPhyMode DUALMAC_DUALPHY\n"); } } @@ -1741,15 +1740,15 @@ static void _rtl92de_efuse_update_chip_version(struct ieee80211_hw *hw) switch (chipvalue) { case 0xAA55: chipver |= CHIP_92D_C_CUT; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("C-CUT!!!\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "C-CUT!!!\n"); break; case 0x9966: chipver |= CHIP_92D_D_CUT; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("D-CUT!!!\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "D-CUT!!!\n"); break; default: chipver |= CHIP_92D_D_CUT; - RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, ("Unkown CUT!\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Unkown CUT!\n"); break; } rtlpriv->rtlhal.version = chipver; @@ -1775,7 +1774,7 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw) HWSET_MAX_SIZE); } else if (rtlefuse->epromtype == EEPROM_93C46) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("RTL819X Not boot from eeprom, check it !!")); + "RTL819X Not boot from eeprom, check it !!\n"); } RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP", hwinfo, HWSET_MAX_SIZE); @@ -1783,15 +1782,15 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw) eeprom_id = *((u16 *)&hwinfo[0]); if (eeprom_id != RTL8190_EEPROM_ID) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("EEPROM ID(%#x) is invalid!!\n", eeprom_id)); + "EEPROM ID(%#x) is invalid!!\n", eeprom_id); rtlefuse->autoload_failflag = true; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; } if (rtlefuse->autoload_failflag) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("RTL819X Not boot from eeprom, check it !!")); + "RTL819X Not boot from eeprom, check it !!\n"); return; } rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; @@ -1802,16 +1801,15 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID]; rtlefuse->eeprom_svid = *(u16 *)&hwinfo[EEPROM_SVID]; rtlefuse->eeprom_smid = *(u16 *)&hwinfo[EEPROM_SMID]; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROMId = 0x%4x\n", eeprom_id); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROMId = 0x%4x\n", eeprom_id)); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid)); + "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did)); + "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid)); + "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid)); + "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid); /* Read Permanent MAC address */ if (rtlhal->interfaceindex == 0) { @@ -1827,8 +1825,7 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw) } rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, rtlefuse->dev_addr); - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("%pM\n", rtlefuse->dev_addr)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr); _rtl92de_read_txpower_info(hw, rtlefuse->autoload_failflag, hwinfo); /* Read Channel Plan */ @@ -1849,7 +1846,7 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; rtlefuse->txpwr_fromeprom = true; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid)); + "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); } void rtl92de_read_eeprom_info(struct ieee80211_hw *hw) @@ -1863,19 +1860,19 @@ void rtl92de_read_eeprom_info(struct ieee80211_hw *hw) tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); rtlefuse->autoload_status = tmp_u1b; if (tmp_u1b & BIT(4)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); rtlefuse->epromtype = EEPROM_93C46; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); rtlefuse->epromtype = EEPROM_BOOT_EFUSE; } if (tmp_u1b & BIT(5)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; _rtl92de_read_adapter_info(hw); } else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Autoload ERR!!\n"); } return; } @@ -1958,8 +1955,8 @@ static void rtl92de_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))); + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n", + rtl_read_dword(rtlpriv, REG_ARFR0)); } static void rtl92de_update_hal_rate_mask(struct ieee80211_hw *hw, @@ -2092,8 +2089,8 @@ static void rtl92de_update_hal_rate_mask(struct ieee80211_hw *hw, value[0] = (ratr_bitmap & 0x0fffffff) | (ratr_index << 28); value[1] = macid | (shortgi ? 0x20 : 0x00) | 0x80; RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, - ("ratr_bitmap :%x value0:%x value1:%x\n", - ratr_bitmap, value[0], value[1])); + "ratr_bitmap :%x value0:%x value1:%x\n", + ratr_bitmap, value[0], value[1]); rtl92d_fill_h2c_cmd(hw, H2C_RA_MASK, 5, (u8 *) value); if (macid != 0) sta_entry->ratr_index = ratr_index; @@ -2153,14 +2150,14 @@ bool rtl92de_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF; if (ppsc->hwradiooff && (e_rfpowerstate_toset == ERFON)) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("GPIOChangeRF - HW Radio ON, RF ON\n")); + "GPIOChangeRF - HW Radio ON, RF ON\n"); e_rfpowerstate_toset = ERFON; ppsc->hwradiooff = false; actuallyset = true; } else if ((ppsc->hwradiooff == false) && (e_rfpowerstate_toset == ERFOFF)) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("GPIOChangeRF - HW Radio OFF, RF OFF\n")); + "GPIOChangeRF - HW Radio OFF, RF OFF\n"); e_rfpowerstate_toset = ERFOFF; ppsc->hwradiooff = true; actuallyset = true; @@ -2204,7 +2201,7 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index, u8 idx; u8 cam_offset = 0; u8 clear_number = 5; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); for (idx = 0; idx < clear_number; idx++) { rtl_cam_mark_invalid(hw, cam_offset + idx); rtl_cam_empty_entry(hw, cam_offset + idx); @@ -2230,8 +2227,8 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index, enc_algo = CAM_AES; break; default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case " - "not process\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "switch case not processed\n"); enc_algo = CAM_TKIP; break; } @@ -2248,9 +2245,8 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index, p_macaddr); if (entry_id >= TOTAL_CAM_ENTRY) { RT_TRACE(rtlpriv, COMP_SEC, - DBG_EMERG, ("Can not " - "find free hw security" - " cam entry\n")); + DBG_EMERG, + "Can not find free hw security cam entry\n"); return; } } else { @@ -2262,21 +2258,21 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index, } if (rtlpriv->sec.key_len[key_index] == 0) { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("delete one entry, entry_id is %d\n", - entry_id)); + "delete one entry, entry_id is %d\n", + entry_id); if (mac->opmode == NL80211_IFTYPE_AP) rtl_cam_del_entry(hw, p_macaddr); rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); } else { RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The insert KEY length is %d\n", - rtlpriv->sec.key_len[PAIRWISE_KEYIDX])); + "The insert KEY length is %d\n", + rtlpriv->sec.key_len[PAIRWISE_KEYIDX]); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The insert KEY is %x %x\n", - rtlpriv->sec.key_buf[0][0], - rtlpriv->sec.key_buf[0][1])); + "The insert KEY is %x %x\n", + rtlpriv->sec.key_buf[0][0], + rtlpriv->sec.key_buf[0][1]); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("add one entry\n")); + "add one entry\n"); if (is_pairwise) { RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, "Pairwise Key content", @@ -2284,7 +2280,7 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index, rtlpriv-> sec.key_len[PAIRWISE_KEYIDX]); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set Pairwiase key\n")); + "set Pairwise key\n"); rtl_cam_add_one_entry(hw, macaddr, key_index, entry_id, enc_algo, CAM_CONFIG_NO_USEDK, @@ -2292,7 +2288,7 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index, sec.key_buf[key_index]); } else { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set group key\n")); + "set group key\n"); if (mac->opmode == NL80211_IFTYPE_ADHOC) { rtl_cam_add_one_entry(hw, rtlefuse->dev_addr, diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/led.c b/drivers/net/wireless/rtlwifi/rtl8192de/led.c index f1552f4df65..f2358f20b9c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/led.c @@ -45,8 +45,8 @@ void rtl92de_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) u8 ledcfg; struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2, pled->ledpin); switch (pled->ledpin) { case LED_PIN_GPIO0: @@ -71,7 +71,7 @@ void rtl92de_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } pled->ledon = true; @@ -83,8 +83,8 @@ void rtl92de_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); u8 ledcfg; - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2, pled->ledpin); ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); @@ -106,7 +106,7 @@ void rtl92de_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } pled->ledon = false; @@ -153,7 +153,7 @@ void rtl92de_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction) ledaction == LED_CTL_POWER_ON)) { return; } - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n", ledaction)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d,\n", ledaction); _rtl92ce_sw_led_control(hw, ledaction); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c index 0883349e1c8..82cc052fc98 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c @@ -204,8 +204,8 @@ u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) u32 returnvalue, originalvalue, bitshift; u8 dbi_direct; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "bitmask(%#x)\n", regaddr, bitmask)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", + regaddr, bitmask); if (rtlhal->during_mac1init_radioa || rtlhal->during_mac0init_radiob) { /* mac1 use phy0 read radio_b. */ /* mac0 use phy1 read radio_b. */ @@ -220,8 +220,9 @@ u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) } bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); returnvalue = (originalvalue & bitmask) >> bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("BBR MASK=0x%x " - "Addr[0x%x]=0x%x\n", bitmask, regaddr, originalvalue)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "BBR MASK=0x%x Addr[0x%x]=0x%x\n", + bitmask, regaddr, originalvalue); return returnvalue; } @@ -233,8 +234,9 @@ void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw, u8 dbi_direct = 0; u32 originalvalue, bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," - " data(%#x)\n", regaddr, bitmask, data)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); if (rtlhal->during_mac1init_radioa) dbi_direct = BIT(3); else if (rtlhal->during_mac0init_radiob) @@ -255,8 +257,9 @@ void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw, rtl92de_write_dword_dbi(hw, (u16) regaddr, data, dbi_direct); else rtl_write_dword(rtlpriv, regaddr, data); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," - " data(%#x)\n", regaddr, bitmask, data)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); } static u32 _rtl92d_phy_rf_serial_read(struct ieee80211_hw *hw, @@ -300,8 +303,8 @@ static u32 _rtl92d_phy_rf_serial_read(struct ieee80211_hw *hw, else retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, BLSSIREADBACKDATA); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x] = 0x%x\n", - rfpath, pphyreg->rflssi_readback, retvalue)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x] = 0x%x\n", + rfpath, pphyreg->rflssi_readback, retvalue); return retvalue; } @@ -319,8 +322,8 @@ static void _rtl92d_phy_rf_serial_write(struct ieee80211_hw *hw, /* T65 RF */ data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; rtl_set_bbreg(hw, pphyreg->rf3wire_offset, BMASKDWORD, data_and_addr); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rf3wire_offset, data_and_addr)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rf3wire_offset, data_and_addr); } u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw, @@ -330,17 +333,17 @@ u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw, u32 original_value, readback_value, bitshift; unsigned long flags; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "rfpath(%#x), bitmask(%#x)\n", - regaddr, rfpath, bitmask)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", + regaddr, rfpath, bitmask); spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); original_value = _rtl92d_phy_rf_serial_read(hw, rfpath, regaddr); bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); readback_value = (original_value & bitmask) >> bitshift; spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), " - "bitmask(%#x), original_value(%#x)\n", - regaddr, rfpath, bitmask, original_value)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value); return readback_value; } @@ -353,8 +356,8 @@ void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, unsigned long flags; RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", - regaddr, bitmask, data, rfpath)); + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); if (bitmask == 0) return; spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); @@ -369,9 +372,9 @@ void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, _rtl92d_phy_rf_serial_write(hw, rfpath, regaddr, data); } spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "bitmask(%#x), data(%#x), rfpath(%#x)\n", - regaddr, bitmask, data, rfpath)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); } bool rtl92d_phy_mac_config(struct ieee80211_hw *hw) @@ -381,10 +384,10 @@ bool rtl92d_phy_mac_config(struct ieee80211_hw *hw) u32 arraylength; u32 *ptrarray; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Read Rtl819XMACPHY_Array\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n"); arraylength = MAC_2T_ARRAYLENGTH; ptrarray = rtl8192de_mac_2tarray; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Img:Rtl819XMAC_Array\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Img:Rtl819XMAC_Array\n"); for (i = 0; i < arraylength; i = i + 2) rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY) { @@ -561,25 +564,25 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, agctab_arraylen = AGCTAB_ARRAYLENGTH; agctab_array_table = rtl8192de_agctab_array; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - (" ===> phy:MAC0, Rtl819XAGCTAB_Array\n")); + " ===> phy:MAC0, Rtl819XAGCTAB_Array\n"); } else { if (rtlhal->current_bandtype == BAND_ON_2_4G) { agctab_arraylen = AGCTAB_2G_ARRAYLENGTH; agctab_array_table = rtl8192de_agctab_2garray; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - (" ===> phy:MAC1, Rtl819XAGCTAB_2GArray\n")); + " ===> phy:MAC1, Rtl819XAGCTAB_2GArray\n"); } else { agctab_5garraylen = AGCTAB_5G_ARRAYLENGTH; agctab_5garray_table = rtl8192de_agctab_5garray; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - (" ===> phy:MAC1, Rtl819XAGCTAB_5GArray\n")); + " ===> phy:MAC1, Rtl819XAGCTAB_5GArray\n"); } } phy_reg_arraylen = PHY_REG_2T_ARRAYLENGTH; phy_regarray_table = rtl8192de_phy_reg_2tarray; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - (" ===> phy:Rtl819XPHY_REG_Array_PG\n")); + " ===> phy:Rtl819XPHY_REG_Array_PG\n"); if (configtype == BASEBAND_CONFIG_PHY_REG) { for (i = 0; i < phy_reg_arraylen; i = i + 2) { if (phy_regarray_table[i] == 0xfe) @@ -598,10 +601,9 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, phy_regarray_table[i + 1]); udelay(1); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("The phy_regarray_table[0] is %x" - " Rtl819XPHY_REGArray[1] is %x\n", - phy_regarray_table[i], - phy_regarray_table[i + 1])); + "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n", + phy_regarray_table[i], + phy_regarray_table[i + 1]); } } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { if (rtlhal->interfaceindex == 0) { @@ -613,15 +615,12 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, * setting. */ udelay(1); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("The Rtl819XAGCTAB_Array_" - "Table[0] is %ul " - "Rtl819XPHY_REGArray[1] is %ul\n", + "The Rtl819XAGCTAB_Array_Table[0] is %ul Rtl819XPHY_REGArray[1] is %ul\n", agctab_array_table[i], - agctab_array_table[i + 1])); + agctab_array_table[i + 1]); } RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Normal Chip, MAC0, load " - "Rtl819XAGCTAB_Array\n")); + "Normal Chip, MAC0, load Rtl819XAGCTAB_Array\n"); } else { if (rtlhal->current_bandtype == BAND_ON_2_4G) { for (i = 0; i < agctab_arraylen; i = i + 2) { @@ -632,14 +631,12 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, * setting. */ udelay(1); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("The Rtl819XAGCTAB_Array_" - "Table[0] is %ul Rtl819XPHY_" - "REGArray[1] is %ul\n", + "The Rtl819XAGCTAB_Array_Table[0] is %ul Rtl819XPHY_REGArray[1] is %ul\n", agctab_array_table[i], - agctab_array_table[i + 1])); + agctab_array_table[i + 1]); } RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Load Rtl819XAGCTAB_2GArray\n")); + "Load Rtl819XAGCTAB_2GArray\n"); } else { for (i = 0; i < agctab_5garraylen; i = i + 2) { rtl_set_bbreg(hw, @@ -650,14 +647,12 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, * setting. */ udelay(1); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("The Rtl819XAGCTAB_5GArray_" - "Table[0] is %ul Rtl819XPHY_" - "REGArray[1] is %ul\n", + "The Rtl819XAGCTAB_5GArray_Table[0] is %ul Rtl819XPHY_REGArray[1] is %ul\n", agctab_5garray_table[i], - agctab_5garray_table[i + 1])); + agctab_5garray_table[i + 1]); } RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Load Rtl819XAGCTAB_5GArray\n")); + "Load Rtl819XAGCTAB_5GArray\n"); } } } @@ -675,145 +670,145 @@ static void _rtl92d_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw, rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][0])); + [rtlphy->pwrgroup_cnt][0]); } if (regaddr == RTXAGC_A_RATE54_24) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][1])); + [rtlphy->pwrgroup_cnt][1]); } if (regaddr == RTXAGC_A_CCK1_MCS32) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][6])); + [rtlphy->pwrgroup_cnt][6]); } if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][7] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][7])); + [rtlphy->pwrgroup_cnt][7]); } if (regaddr == RTXAGC_A_MCS03_MCS00) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][2])); + [rtlphy->pwrgroup_cnt][2]); } if (regaddr == RTXAGC_A_MCS07_MCS04) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][3])); + [rtlphy->pwrgroup_cnt][3]); } if (regaddr == RTXAGC_A_MCS11_MCS08) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][4])); + [rtlphy->pwrgroup_cnt][4]); } if (regaddr == RTXAGC_A_MCS15_MCS12) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][5])); + [rtlphy->pwrgroup_cnt][5]); } if (regaddr == RTXAGC_B_RATE18_06) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][8] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][8])); + [rtlphy->pwrgroup_cnt][8]); } if (regaddr == RTXAGC_B_RATE54_24) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][9] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][9])); + [rtlphy->pwrgroup_cnt][9]); } if (regaddr == RTXAGC_B_CCK1_55_MCS32) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][14] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][14])); + [rtlphy->pwrgroup_cnt][14]); } if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][15] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][15])); + [rtlphy->pwrgroup_cnt][15]); } if (regaddr == RTXAGC_B_MCS03_MCS00) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][10] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][10])); + [rtlphy->pwrgroup_cnt][10]); } if (regaddr == RTXAGC_B_MCS07_MCS04) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][11] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][11])); + [rtlphy->pwrgroup_cnt][11]); } if (regaddr == RTXAGC_B_MCS11_MCS08) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][12] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%ulx\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][12])); + "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%ulx\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][12]); } if (regaddr == RTXAGC_B_MCS15_MCS12) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][13] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%ulx\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][13])); + "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%ulx\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][13]); rtlphy->pwrgroup_cnt++; } } @@ -849,7 +844,7 @@ static bool _rtl92d_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, } } else { RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, - ("configtype != BaseBand_Config_PHY_REG\n")); + "configtype != BaseBand_Config_PHY_REG\n"); } return true; } @@ -861,17 +856,17 @@ static bool _rtl92d_phy_bb_config(struct ieee80211_hw *hw) struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); bool rtstatus = true; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("==>\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "==>\n"); rtstatus = _rtl92d_phy_config_bb_with_headerfile(hw, BASEBAND_CONFIG_PHY_REG); if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!\n"); return false; } /* if (rtlphy->rf_type == RF_1T2R) { * _rtl92c_phy_bb_config_1t(hw); - * RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Config to 1T!!\n")); + * RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n"); *} */ if (rtlefuse->autoload_failflag == false) { @@ -880,13 +875,13 @@ static bool _rtl92d_phy_bb_config(struct ieee80211_hw *hw) BASEBAND_CONFIG_PHY_REG); } if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!\n"); return false; } rtstatus = _rtl92d_phy_config_bb_with_headerfile(hw, BASEBAND_CONFIG_AGC_TAB); if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("AGC Table Fail\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n"); return false; } rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw, @@ -951,19 +946,17 @@ bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, radiob_array_table = rtl8192de_radiob_2t_int_paarray; } RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("PHY_ConfigRFWithHeaderFile() " - "Radio_A:Rtl819XRadioA_1TArray\n")); + "PHY_ConfigRFWithHeaderFile() Radio_A:Rtl819XRadioA_1TArray\n"); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("PHY_ConfigRFWithHeaderFile() " - "Radio_B:Rtl819XRadioB_1TArray\n")); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath)); + "PHY_ConfigRFWithHeaderFile() Radio_B:Rtl819XRadioB_1TArray\n"); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath); /* this only happens when DMDP, mac0 start on 2.4G, * mac1 start on 5G, mac 0 has to set phy0&phy1 * pathA or mac1 has to set phy0&phy1 pathA */ if ((content == radiob_txt) && (rfpath == RF90_PATH_A)) { RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - (" ===> althougth Path A, we load radiob.txt\n")); + " ===> althougth Path A, we load radiob.txt\n"); radioa_arraylen = radiob_arraylen; radioa_array_table = radiob_array_table; } @@ -1022,11 +1015,11 @@ bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, break; case RF90_PATH_C: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; case RF90_PATH_D: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } return true; @@ -1046,19 +1039,18 @@ void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) rtlphy->default_initialgain[3] = (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, BMASKBYTE0); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Default initial gain (c50=0x%x, " - "c58=0x%x, c60=0x%x, c68=0x%x\n", - rtlphy->default_initialgain[0], - rtlphy->default_initialgain[1], - rtlphy->default_initialgain[2], - rtlphy->default_initialgain[3])); + "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n", + rtlphy->default_initialgain[0], + rtlphy->default_initialgain[1], + rtlphy->default_initialgain[2], + rtlphy->default_initialgain[3]); rtlphy->framesync = (u8)rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, BMASKBYTE0); rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2, BMASKDWORD); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Default framesync (0x%x) = 0x%x\n", - ROFDM0_RXDETECTOR3, rtlphy->framesync)); + "Default framesync (0x%x) = 0x%x\n", + ROFDM0_RXDETECTOR3, rtlphy->framesync); } static void _rtl92d_get_txpower_index(struct ieee80211_hw *hw, u8 channel, @@ -1172,7 +1164,7 @@ void rtl92d_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Unknown Scan Backup operation.\n")); + "Unknown Scan Backup operation\n"); break; } } @@ -1193,14 +1185,13 @@ void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw, return; if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("FALSE driver sleep or unload\n")); + "FALSE driver sleep or unload\n"); return; } rtlphy->set_bwmode_inprogress = true; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, - ("Switch to %s bandwidth\n", - rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? - "20MHz" : "40MHz")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz"); reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); switch (rtlphy->current_chan_bw) { @@ -1218,7 +1209,7 @@ void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); break; } switch (rtlphy->current_chan_bw) { @@ -1250,13 +1241,13 @@ void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); break; } rtl92d_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); rtlphy->set_bwmode_inprogress = false; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); } static void _rtl92d_phy_stop_trx_before_changeband(struct ieee80211_hw *hw) @@ -1273,7 +1264,7 @@ static void rtl92d_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band) struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); u8 value8; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("==>\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "==>\n"); rtlhal->bandset = band; rtlhal->current_bandtype = band; if (IS_92D_SINGLEPHY(rtlhal->version)) @@ -1283,13 +1274,13 @@ static void rtl92d_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band) /* reconfig BB/RF according to wireless mode */ if (rtlhal->current_bandtype == BAND_ON_2_4G) { /* BB & RF Config */ - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, ("====>2.4G\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "====>2.4G\n"); if (rtlhal->interfaceindex == 1) _rtl92d_phy_config_bb_with_headerfile(hw, BASEBAND_CONFIG_AGC_TAB); } else { /* 5G band */ - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, ("====>5G\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "====>5G\n"); if (rtlhal->interfaceindex == 1) _rtl92d_phy_config_bb_with_headerfile(hw, BASEBAND_CONFIG_AGC_TAB); @@ -1317,7 +1308,7 @@ static void rtl92d_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band) 0 ? REG_MAC0 : REG_MAC1), value8); } mdelay(1); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("<==Switch Band OK.\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "<==Switch Band OK\n"); } static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw, @@ -1329,9 +1320,9 @@ static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw, u8 group, i; unsigned long flag = 0; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>path %d\n", rfpath)); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>path %d\n", rfpath); if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) { - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>5G\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>5G\n"); rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(25) | BIT(24), 0); rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf); /* fc area 0xd2c */ @@ -1353,14 +1344,13 @@ static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw, } else { /* G band. */ RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, - ("Load RF IMR parameters for G band. IMR already " - "setting %d\n", - rtlpriv->rtlhal.load_imrandiqk_setting_for2g)); - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>2.4G\n")); + "Load RF IMR parameters for G band. IMR already setting %d\n", + rtlpriv->rtlhal.load_imrandiqk_setting_for2g); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>2.4G\n"); if (!rtlpriv->rtlhal.load_imrandiqk_setting_for2g) { RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, - ("Load RF IMR parameters " - "for G band. %d\n", rfpath)); + "Load RF IMR parameters for G band. %d\n", + rfpath); rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(25) | BIT(24), 0); rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, @@ -1378,7 +1368,7 @@ static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw, rtl92d_release_cckandrw_pagea_ctl(hw, &flag); } } - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n"); } static void _rtl92d_phy_enable_rf_env(struct ieee80211_hw *hw, @@ -1388,7 +1378,7 @@ static void _rtl92d_phy_enable_rf_env(struct ieee80211_hw *hw, struct rtl_phy *rtlphy = &(rtlpriv->phy); struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; - RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("====>\n")); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "====>\n"); /*----Store original RFENV control type----*/ switch (rfpath) { case RF90_PATH_A: @@ -1414,7 +1404,7 @@ static void _rtl92d_phy_enable_rf_env(struct ieee80211_hw *hw, /*Set 0 to 12 bits for 8255 */ rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0); udelay(1); - RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<====\n")); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<====\n"); } static void _rtl92d_phy_restore_rf_env(struct ieee80211_hw *hw, u8 rfpath, @@ -1424,7 +1414,7 @@ static void _rtl92d_phy_restore_rf_env(struct ieee80211_hw *hw, u8 rfpath, struct rtl_phy *rtlphy = &(rtlpriv->phy); struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; - RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("=====>\n")); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "=====>\n"); /*----Restore RFENV control type----*/ ; switch (rfpath) { case RF90_PATH_A: @@ -1437,7 +1427,7 @@ static void _rtl92d_phy_restore_rf_env(struct ieee80211_hw *hw, u8 rfpath, *pu4_regval); break; } - RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<=====\n")); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<=====\n"); } static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) @@ -1451,10 +1441,10 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) bool need_pwr_down = false, internal_pa = false; u32 u4regvalue, mask = 0x1C000, value = 0, u4tmp, u4tmp2; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>\n"); /* config path A for 5G */ if (rtlhal->current_bandtype == BAND_ON_5G) { - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>5G\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>5G\n"); u4tmp = curveindex_5g[channel - 1]; RTPRINT(rtlpriv, FINIT, INIT_IQK, ("ver 1 set RF-A, 5G, " "0x28 = 0x%x !!\n", u4tmp)); @@ -1503,12 +1493,13 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) rf_reg_pram_c_5g[index][i]); } RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("offset 0x%x value 0x%x " - "path %d index %d readback 0x%x\n", - rf_reg_for_c_cut_5g[i], - rf_reg_pram_c_5g[index][i], path, - index, rtl_get_rfreg(hw, (enum radio_path)path, - rf_reg_for_c_cut_5g[i], BRFREGOFFSETMASK))); + "offset 0x%x value 0x%x path %d index %d readback 0x%x\n", + rf_reg_for_c_cut_5g[i], + rf_reg_pram_c_5g[index][i], + path, index, + rtl_get_rfreg(hw, (enum radio_path)path, + rf_reg_for_c_cut_5g[i], + BRFREGOFFSETMASK)); } if (need_pwr_down) _rtl92d_phy_restore_rf_env(hw, path, &u4regvalue); @@ -1541,11 +1532,10 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) BRFREGOFFSETMASK, rf_pram_c_5g_int_pa[index][i]); RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, - ("offset 0x%x value 0x%x " - "path %d index %d\n", + "offset 0x%x value 0x%x path %d index %d\n", rf_for_c_cut_5g_internal_pa[i], rf_pram_c_5g_int_pa[index][i], - rfpath, index)); + rfpath, index); } } else { rtl_set_rfreg(hw, (enum radio_path)rfpath, 0x0B, @@ -1553,7 +1543,7 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) } } } else if (rtlhal->current_bandtype == BAND_ON_2_4G) { - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>2.4G\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>2.4G\n"); u4tmp = curveindex_2g[channel - 1]; RTPRINT(rtlpriv, FINIT, INIT_IQK, ("ver 3 set RF-B, 2G, " "0x28 = 0x%x !!\n", u4tmp)); @@ -1590,14 +1580,13 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) rf_reg_param_for_c_cut_2g [index][i]); RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("offset 0x%x value 0x%x mak 0x%x path %d " - "index %d readback 0x%x\n", - rf_reg_for_c_cut_2g[i], - rf_reg_param_for_c_cut_2g[index][i], - rf_reg_mask_for_c_cut_2g[i], path, index, - rtl_get_rfreg(hw, (enum radio_path)path, - rf_reg_for_c_cut_2g[i], - BRFREGOFFSETMASK))); + "offset 0x%x value 0x%x mak 0x%x path %d index %d readback 0x%x\n", + rf_reg_for_c_cut_2g[i], + rf_reg_param_for_c_cut_2g[index][i], + rf_reg_mask_for_c_cut_2g[i], path, index, + rtl_get_rfreg(hw, (enum radio_path)path, + rf_reg_for_c_cut_2g[i], + BRFREGOFFSETMASK)); } RTPRINT(rtlpriv, FINIT, INIT_IQK, ("cosa ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", @@ -1611,7 +1600,7 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) if (rtlhal->during_mac0init_radiob) rtl92d_phy_powerdown_anotherphy(hw, true); } - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n"); } u8 rtl92d_get_rightchnlplace_for_iqk(u8 chnl) @@ -2618,7 +2607,7 @@ void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw) true; RT_TRACE(rtlpriv, COMP_SCAN | COMP_MLME, DBG_LOUD, - ("\nIQK OK indexforchannel %d.\n", indexforchannel)); + "IQK OK indexforchannel %d\n", indexforchannel); } } @@ -2629,17 +2618,17 @@ void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel) struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); u8 indexforchannel; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("channel %d\n", channel)); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "channel %d\n", channel); /*------Do IQK for normal chip and test chip 5G band------- */ indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel); - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("indexforchannel %d done %d\n", indexforchannel, - rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done)); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "indexforchannel %d done %d\n", + indexforchannel, + rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done); if (0 && !rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done && rtlphy->need_iqk) { /* Re Do IQK. */ RT_TRACE(rtlpriv, COMP_SCAN | COMP_INIT, DBG_LOUD, - ("Do IQK Matrix reg for channel:%d....\n", channel)); + "Do IQK Matrix reg for channel:%d....\n", channel); rtl92d_phy_iq_calibrate(hw); } else { /* Just load the value. */ @@ -2647,8 +2636,8 @@ void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel) if (((!rtlhal->load_imrandiqk_setting_for2g) && indexforchannel == 0) || indexforchannel > 0) { RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, - ("Just Read IQK Matrix reg for channel:%d" - "....\n", channel)); + "Just Read IQK Matrix reg for channel:%d....\n", + channel); if ((rtlphy->iqk_matrix_regsetting[indexforchannel]. value[0] != NULL) /*&&(regea4 != 0) */) @@ -2672,7 +2661,7 @@ void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel) } } rtlphy->need_iqk = false; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n"); } static u32 _rtl92d_phy_get_abs(u32 val1, u32 val2) @@ -2743,7 +2732,7 @@ static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw, u32 u4tmp = 0, u4regvalue = 0; bool bneed_powerdown_radio = false; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("path %d\n", erfpath)); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "path %d\n", erfpath); RTPRINT(rtlpriv, FINIT, INIT_IQK, ("band type = %d\n", rtlpriv->rtlhal.current_bandtype)); RTPRINT(rtlpriv, FINIT, INIT_IQK, ("channel = %d\n", channel)); @@ -2788,7 +2777,7 @@ static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw, if (rtlpriv->rtlhal.during_mac0init_radiob) rtl92d_phy_powerdown_anotherphy(hw, true); } - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n"); } static void _rtl92d_phy_lc_calibrate_sw(struct ieee80211_hw *hw, bool is2t) @@ -2962,10 +2951,10 @@ void rtl92d_phy_reset_iqk_result(struct ieee80211_hw *hw) u8 i; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("settings regs %d default regs %d\n", - (int)(sizeof(rtlphy->iqk_matrix_regsetting) / - sizeof(struct iqk_matrix_regs)), - IQK_MATRIX_REG_NUM)); + "settings regs %d default regs %d\n", + (int)(sizeof(rtlphy->iqk_matrix_regsetting) / + sizeof(struct iqk_matrix_regs)), + IQK_MATRIX_REG_NUM); /* 0xe94, 0xe9c, 0xea4, 0xeac, 0xeb4, 0xebc, 0xec4, 0xecc */ for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) { rtlphy->iqk_matrix_regsetting[i].value[0][0] = 0x100; @@ -3084,7 +3073,7 @@ static bool _rtl92d_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } break; @@ -3111,7 +3100,7 @@ u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw) if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) { RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, - ("sw_chnl_inprogress false driver sleep or unload\n")); + "sw_chnl_inprogress false driver sleep or unload\n"); return 0; } while (rtlphy->lck_inprogress && timecount < timeout) { @@ -3154,7 +3143,7 @@ u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw) rtlphy->sw_chnl_stage = 0; rtlphy->sw_chnl_step = 0; RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, - ("switch to channel%d\n", rtlphy->current_channel)); + "switch to channel%d\n", rtlphy->current_channel); do { if (!rtlphy->sw_chnl_inprogress) @@ -3171,7 +3160,7 @@ u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw) } break; } while (true); - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); rtlphy->sw_chnl_inprogress = false; return 1; } @@ -3182,8 +3171,8 @@ static void rtl92d_phy_set_io(struct ieee80211_hw *hw) struct rtl_phy *rtlphy = &(rtlpriv->phy); RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("--->Cmd(%#x), set_io_inprogress(%d)\n", - rtlphy->current_io_type, rtlphy->set_io_inprogress)); + "--->Cmd(%#x), set_io_inprogress(%d)\n", + rtlphy->current_io_type, rtlphy->set_io_inprogress); switch (rtlphy->current_io_type) { case IO_CMD_RESUME_DM_BY_SCAN: de_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1; @@ -3197,12 +3186,12 @@ static void rtl92d_phy_set_io(struct ieee80211_hw *hw) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } rtlphy->set_io_inprogress = false; - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("<---(%#x)\n", rtlphy->current_io_type)); + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<---(%#x)\n", + rtlphy->current_io_type); } bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) @@ -3212,23 +3201,23 @@ bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) bool postprocessing = false; RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("-->IO Cmd(%#x), set_io_inprogress(%d)\n", - iotype, rtlphy->set_io_inprogress)); + "-->IO Cmd(%#x), set_io_inprogress(%d)\n", + iotype, rtlphy->set_io_inprogress); do { switch (iotype) { case IO_CMD_RESUME_DM_BY_SCAN: RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("[IO CMD] Resume DM after scan.\n")); + "[IO CMD] Resume DM after scan\n"); postprocessing = true; break; case IO_CMD_PAUSE_DM_BY_SCAN: RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("[IO CMD] Pause DM before scan.\n")); + "[IO CMD] Pause DM before scan\n"); postprocessing = true; break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } while (false); @@ -3239,7 +3228,7 @@ bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) return false; } rtl92d_phy_set_io(hw); - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, ("<--IO Type(%#x)\n", iotype)); + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<--IO Type(%#x)\n", iotype); return true; } @@ -3297,7 +3286,7 @@ static void _rtl92d_phy_set_rfsleep(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Fail !!! Switch RF timeout.\n")); + "Fail !!! Switch RF timeout\n"); return; } /* e. For PCIE: SYS_FUNC_EN 0x02[7:0] = 0xE2 reset BB TRX function */ @@ -3332,7 +3321,7 @@ bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw, do { InitializeCount++; RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("IPS Set eRf nic enable\n")); + "IPS Set eRf nic enable\n"); rtstatus = rtl_ps_enable_nic(hw); } while ((rtstatus != true) && (InitializeCount < 10)); @@ -3341,11 +3330,10 @@ bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw, RT_RF_OFF_LEVL_HALT_NIC); } else { RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - ("awake, sleeped:%d ms state_" - "inap:%x\n", + "awake, sleeped:%d ms state_inap:%x\n", jiffies_to_msecs(jiffies - - ppsc->last_sleep_jiffies), - rtlpriv->psc.state_inap)); + ppsc->last_sleep_jiffies), + rtlpriv->psc.state_inap); ppsc->last_awake_jiffies = jiffies; _rtl92d_phy_set_rfon(hw); } @@ -3360,7 +3348,7 @@ bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw, case ERFOFF: if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("IPS Set eRf nic disable\n")); + "IPS Set eRf nic disable\n"); rtl_ps_disable_nic(hw); RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); } else { @@ -3385,41 +3373,40 @@ bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw, continue; } else if (rtlpci->pdev->current_state != PCI_D0) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("eRf Off/Sleep: %d times TcbBusyQueu" - "e[%d] !=0 but lower power state!\n", - (i + 1), queue_id)); + "eRf Off/Sleep: %d times TcbBusyQueue[%d] !=0 but lower power state!\n", + i + 1, queue_id); break; } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("eRf Off/Sleep: %d times TcbBusyQueu" - "e[%d] =%d " - "before doze!\n", (i + 1), queue_id, - skb_queue_len(&ring->queue))); + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + i + 1, queue_id, + skb_queue_len(&ring->queue)); udelay(10); i++; } if (i >= MAX_DOZE_WAITING_TIMES_9x) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("\nERFOFF: %d times TcbBusyQueue[%d] " - "= %d !\n", - MAX_DOZE_WAITING_TIMES_9x, queue_id, - skb_queue_len(&ring->queue))); + "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, queue_id, + skb_queue_len(&ring->queue)); break; } } RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - ("Set rfsleep awaked:%d ms\n", - jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies))); - RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, ("sleep awaked:%d ms " - "state_inap:%x\n", jiffies_to_msecs(jiffies - - ppsc->last_awake_jiffies), rtlpriv->psc.state_inap)); + "Set rfsleep awaked:%d ms\n", + jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies)); + RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, + "sleep awaked:%d ms state_inap:%x\n", + jiffies_to_msecs(jiffies - + ppsc->last_awake_jiffies), + rtlpriv->psc.state_inap); ppsc->last_sleep_jiffies = jiffies; _rtl92d_phy_set_rfsleep(hw); break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); bresult = false; break; } @@ -3437,17 +3424,17 @@ void rtl92d_phy_config_macphymode(struct ieee80211_hw *hw) switch (rtlhal->macphymode) { case DUALMAC_DUALPHY: RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("MacPhyMode: DUALMAC_DUALPHY\n")); + "MacPhyMode: DUALMAC_DUALPHY\n"); rtl_write_byte(rtlpriv, offset, 0xF3); break; case SINGLEMAC_SINGLEPHY: RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("MacPhyMode: SINGLEMAC_SINGLEPHY\n")); + "MacPhyMode: SINGLEMAC_SINGLEPHY\n"); rtl_write_byte(rtlpriv, offset, 0xF4); break; case DUALMAC_SINGLEPHY: RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("MacPhyMode: DUALMAC_SINGLEPHY\n")); + "MacPhyMode: DUALMAC_SINGLEPHY\n"); rtl_write_byte(rtlpriv, offset, 0xF1); break; } @@ -3615,7 +3602,7 @@ void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw) struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); u8 rfpath, i; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("==>\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "==>\n"); /* r_select_5G for path_A/B 0 for 2.4G, 1 for 5G */ if (rtlhal->current_bandtype == BAND_ON_2_4G) { /* r_select_5G for path_A/B,0x878 */ @@ -3764,7 +3751,7 @@ void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw) } else { rtl92d_phy_enable_anotherphy(hw, false); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("MAC1 use DBI to update 0x888")); + "MAC1 use DBI to update 0x888\n"); /* 0x888 */ rtl92de_write_dword_dbi(hw, RFPGA0_ADDALLOCKEN, rtl92de_read_dword_dbi(hw, @@ -3789,9 +3776,9 @@ void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw) BRFREGOFFSETMASK); } for (i = 0; i < 2; i++) - RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("RF 0x18 = 0x%x\n", - rtlphy->rfreg_chnlval[i])); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("<==\n")); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "RF 0x18 = 0x%x\n", + rtlphy->rfreg_chnlval[i]); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "<==\n"); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c b/drivers/net/wireless/rtlwifi/rtl8192de/rf.c index db27cebaac2..3bf21c2cf08 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/rf.c @@ -50,8 +50,8 @@ void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) BIT(11), 0x01); RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, - ("20M RF 0x18 = 0x%x\n", - rtlphy->rfreg_chnlval[rfpath])); + "20M RF 0x18 = 0x%x\n", + rtlphy->rfreg_chnlval[rfpath]); } break; @@ -62,13 +62,13 @@ void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(10) | BIT(11), 0x00); RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, - ("40M RF 0x18 = 0x%x\n", - rtlphy->rfreg_chnlval[rfpath])); + "40M RF 0x18 = 0x%x\n", + rtlphy->rfreg_chnlval[rfpath]); } break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", bandwidth)); + "unknown bandwidth: %#X\n", bandwidth); break; } } @@ -423,11 +423,11 @@ bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0) rtlhal->during_mac0init_radiob = false; rtlhal->during_mac1init_radioa = false; - RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("===>\n")); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "===>\n"); /* MAC0 Need PHY1 load radio_b.txt . Driver use DBI to write. */ u1btmp = rtl_read_byte(rtlpriv, mac_reg); if (!(u1btmp & mac_on_bit)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("enable BB & RF\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "enable BB & RF\n"); /* Enable BB and RF power */ rtl92de_write_dword_dbi(hw, REG_SYS_ISO_CTRL, rtl92de_read_dword_dbi(hw, REG_SYS_ISO_CTRL, direct) | @@ -437,7 +437,7 @@ bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0) * and radio_b.txt has been load. */ bresult = false; } - RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<===\n")); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<===\n"); return bresult; } @@ -453,17 +453,17 @@ void rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw *hw, bool bmac0) rtlhal->during_mac0init_radiob = false; rtlhal->during_mac1init_radioa = false; - RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("====>\n")); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "====>\n"); /* check MAC0 enable or not again now, if * enabled, not power down radio A. */ u1btmp = rtl_read_byte(rtlpriv, mac_reg); if (!(u1btmp & mac_on_bit)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("power down\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "power down\n"); /* power down RF radio A according to YuNan's advice. */ rtl92de_write_dword_dbi(hw, RFPGA0_XA_LSSIPARAMETER, 0x00000000, direct); } - RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<====\n")); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<====\n"); } bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw) @@ -606,7 +606,7 @@ bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw) } if (rtstatus != true) { RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio[%d] Fail!!", rfpath)); + "Radio[%d] Fail!!", rfpath); goto phy_rf_cfg_fail; } @@ -620,7 +620,7 @@ bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw) rtl92d_phy_powerdown_anotherphy(hw, false); else if (need_pwrdown_radiob) rtl92d_phy_powerdown_anotherphy(hw, true); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n"); return rtstatus; phy_rf_cfg_fail: diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c index 7911c9c8708..db7579684b1 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c @@ -174,7 +174,7 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->rtlhal.pfirmware = vzalloc(0x8000); if (!rtlpriv->rtlhal.pfirmware) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't alloc buffer for fw.\n")); + "Can't alloc buffer for fw\n"); return 1; } @@ -188,12 +188,12 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->io.dev); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to request firmware!\n")); + "Failed to request firmware!\n"); return 1; } if (firmware->size > 0x8000) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Firmware is too big!\n")); + "Firmware is too big!\n"); release_firmware(firmware); return 1; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c index e84b8d5e4b1..f6ec0a12884 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c @@ -602,8 +602,8 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw, EM_HDR_LEN); if (ptcb_desc->empkt_num) { RT_TRACE(rtlpriv, COMP_SEND, DBG_LOUD, - ("Insert 8 byte.pTcb->EMPktNum:%d\n", - ptcb_desc->empkt_num)); + "Insert 8 byte.pTcb->EMPktNum:%d\n", + ptcb_desc->empkt_num); _rtl92de_insert_emcontent(ptcb_desc, (u8 *)(skb->data)); } @@ -700,7 +700,7 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw, if (ieee80211_is_data_qos(fc)) { if (mac->rdg_en) { RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, - ("Enable RDG function.\n")); + "Enable RDG function\n"); SET_TX_DESC_RDG_ENABLE(pdesc, 1); SET_TX_DESC_HTC(pdesc, 1); } @@ -726,7 +726,7 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw, SET_TX_DESC_PKT_ID(pdesc, 8); } SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1)); - RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n")); + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n"); } void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c index 4203a8531ca..4a5e3a952a4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c @@ -170,9 +170,9 @@ static void _rtl92s_dm_txpowertracking_callback_thermalmeter( thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f); RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " - "eeprom_thermalmeter 0x%x\n", thermalvalue, - rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter)); + "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermal meter 0x%x\n", + thermalvalue, + rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter); if (thermalvalue) { rtlpriv->dm.thermalvalue = thermalvalue; @@ -282,11 +282,11 @@ static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw) } if (ra->pre_ratr_state != ra->ratr_state) { - RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, ("RSSI = %ld " - "RSSI_LEVEL = %d PreState = %d, CurState = %d\n", - rtlpriv->dm.undecorated_smoothed_pwdb, - ra->ratr_state, - ra->pre_ratr_state, ra->ratr_state)); + RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, + "RSSI = %ld RSSI_LEVEL = %d PreState = %d, CurState = %d\n", + rtlpriv->dm.undecorated_smoothed_pwdb, + ra->ratr_state, + ra->pre_ratr_state, ra->ratr_state); rtlpriv->cfg->ops->update_rate_tbl(hw, sta, ra->ratr_state); @@ -586,7 +586,7 @@ static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw) if ((mac->link_state < MAC80211_LINKED) && (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("Not connected to any\n")); + "Not connected to any\n"); rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL; @@ -599,22 +599,22 @@ static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw) undecorated_smoothed_pwdb = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Client PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "AP Client PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } else { undecorated_smoothed_pwdb = rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("STA Default Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "STA Default Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } } else { undecorated_smoothed_pwdb = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Ext Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "AP Ext Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } txpwr_threshold_lv2 = TX_POWER_NEAR_FIELD_THRESH_LVL2; diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c index 3fda6b1dcf4..2a9699feee3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c @@ -66,7 +66,7 @@ static bool _rtl92s_firmware_enable_cpu(struct ieee80211_hw *hw) cpustatus = rtl_read_byte(rtlpriv, TCR); if (cpustatus & IMEM_RDY) { RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("IMEM Ready after CPU has refilled.\n")); + "IMEM Ready after CPU has refilled\n"); break; } @@ -120,9 +120,8 @@ static u8 _rtl92s_firmware_header_map_rftype(struct ieee80211_hw *hw) return 0x22; break; default: - RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Unknown RF type(%x)\n", - rtlphy->rf_type)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Unknown RF type(%x)\n", + rtlphy->rf_type); break; } return 0x22; @@ -177,7 +176,7 @@ static bool _rtl92s_firmware_downloadcode(struct ieee80211_hw *hw, if (buffer_len >= MAX_FIRMWARE_CODE_SIZE) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Size over FIRMWARE_CODE_SIZE!\n")); + "Size over FIRMWARE_CODE_SIZE!\n"); return false; } @@ -231,8 +230,8 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw, short pollingcnt = 1000; bool rtstatus = true; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("LoadStaus(%d)\n", - loadfw_status)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "LoadStaus(%d)\n", loadfw_status); firmware->fwstatus = (enum fw_status)loadfw_status; @@ -248,8 +247,8 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw, if (!(cpustatus & IMEM_CHK_RPT) || (pollingcnt <= 0)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("FW_STATUS_LOAD_IMEM" - " FAIL CPU, Status=%x\r\n", cpustatus)); + "FW_STATUS_LOAD_IMEM FAIL CPU, Status=%x\n", + cpustatus); goto status_check_fail; } break; @@ -266,8 +265,8 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw, if (!(cpustatus & EMEM_CHK_RPT) || (pollingcnt <= 0)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("FW_STATUS_LOAD_EMEM" - " FAIL CPU, Status=%x\r\n", cpustatus)); + "FW_STATUS_LOAD_EMEM FAIL CPU, Status=%x\n", + cpustatus); goto status_check_fail; } @@ -275,7 +274,7 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw, rtstatus = _rtl92s_firmware_enable_cpu(hw); if (rtstatus != true) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Enable CPU fail!\n")); + "Enable CPU fail!\n"); goto status_check_fail; } break; @@ -291,14 +290,14 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw, if (!(cpustatus & DMEM_CODE_DONE) || (pollingcnt <= 0)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Polling DMEM code done" - " fail ! cpustatus(%#x)\n", cpustatus)); + "Polling DMEM code done fail ! cpustatus(%#x)\n", + cpustatus); goto status_check_fail; } RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("DMEM code download success," - " cpustatus(%#x)\n", cpustatus)); + "DMEM code download success, cpustatus(%#x)\n", + cpustatus); /* Prevent Delay too much and being scheduled out */ /* Polling Load Firmware ready */ @@ -311,14 +310,14 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw, } while (pollingcnt--); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Polling Load Firmware ready," - " cpustatus(%x)\n", cpustatus)); + "Polling Load Firmware ready, cpustatus(%x)\n", + cpustatus); if (((cpustatus & LOAD_FW_READY) != LOAD_FW_READY) || (pollingcnt <= 0)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Polling Load Firmware" - " ready fail ! cpustatus(%x)\n", cpustatus)); + "Polling Load Firmware ready fail ! cpustatus(%x)\n", + cpustatus); goto status_check_fail; } @@ -332,7 +331,7 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw, RCR_APP_ICV | RCR_APP_MIC)); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Current RCR settings(%#x)\n", tmpu4b)); + "Current RCR settings(%#x)\n", tmpu4b); /* Set to normal mode. */ rtl_write_byte(rtlpriv, LBKMD_SEL, LBK_NORMAL); @@ -340,14 +339,15 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw, default: RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Unknown status check!\n")); + "Unknown status check!\n"); rtstatus = false; break; } status_check_fail: - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("loadfw_status(%d), " - "rtstatus(%x)\n", loadfw_status, rtstatus)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "loadfw_status(%d), rtstatus(%x)\n", + loadfw_status, rtstatus); return rtstatus; } @@ -378,17 +378,17 @@ int rtl92s_download_fw(struct ieee80211_hw *hw) firmware->firmwareversion = byte(pfwheader->version, 0); firmware->pfwheader->fwpriv.hci_sel = 1;/* pcie */ - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("signature:%x, version:" - "%x, size:%x," - "imemsize:%x, sram size:%x\n", pfwheader->signature, + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "signature:%x, version:%x, size:%x, imemsize:%x, sram size:%x\n", + pfwheader->signature, pfwheader->version, pfwheader->dmem_size, - pfwheader->img_imem_size, pfwheader->img_sram_size)); + pfwheader->img_imem_size, pfwheader->img_sram_size); /* 2. Retrieve IMEM image. */ if ((pfwheader->img_imem_size == 0) || (pfwheader->img_imem_size > sizeof(firmware->fw_imem))) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("memory for data image is less than IMEM required\n")); + "memory for data image is less than IMEM required\n"); goto fail; } else { puc_mappedfile += fwhdr_size; @@ -401,7 +401,7 @@ int rtl92s_download_fw(struct ieee80211_hw *hw) /* 3. Retriecve EMEM image. */ if (pfwheader->img_sram_size > sizeof(firmware->fw_emem)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("memory for data image is less than EMEM required\n")); + "memory for data image is less than EMEM required\n"); goto fail; } else { puc_mappedfile += firmware->fw_imem_len; @@ -436,7 +436,7 @@ int rtl92s_download_fw(struct ieee80211_hw *hw) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Unexpected Download step!!\n")); + "Unexpected Download step!!\n"); goto fail; break; } @@ -446,14 +446,14 @@ int rtl92s_download_fw(struct ieee80211_hw *hw) ul_filelength); if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("fail!\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "fail!\n"); goto fail; } /* <3> Check whether load FW process is ready */ rtstatus = _rtl92s_firmware_checkready(hw, fwstatus); if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("fail!\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "fail!\n"); goto fail; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index f9ba077bc18..dffcafe01a3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c @@ -80,8 +80,8 @@ void rtl92se_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; } default: { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "switch case not processed\n"); break; } } @@ -140,7 +140,7 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) u8 e_aci; RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("HW_VAR_SLOT_TIME %x\n", val[0])); + "HW_VAR_SLOT_TIME %x\n", val[0]); rtl_write_byte(rtlpriv, SLOT_TIME, val[0]); @@ -185,8 +185,8 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) *val = min_spacing_to_set; RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", - mac->min_space_cfg)); + "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", + mac->min_space_cfg); rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, mac->min_space_cfg); @@ -201,8 +201,8 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) mac->min_space_cfg |= (density_to_set << 3); RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_SHORTGI_DENSITY: %#x\n", - mac->min_space_cfg)); + "Set HW_VAR_SHORTGI_DENSITY: %#x\n", + mac->min_space_cfg); rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, mac->min_space_cfg); @@ -244,8 +244,8 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtl_write_byte(rtlpriv, AGGLEN_LMT_H, regtoset); RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_AMPDU_FACTOR: %#x\n", - factor_toset)); + "Set HW_VAR_AMPDU_FACTOR: %#x\n", + factor_toset); } break; } @@ -282,8 +282,8 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("HW_VAR_ACM_CTRL acm set " - "failed: eACI is %d\n", acm)); + "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", + acm); break; } } else { @@ -299,13 +299,13 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE, - ("HW_VAR_ACM_CTRL Write 0x%X\n", acm_ctrl)); + "HW_VAR_ACM_CTRL Write 0x%X\n", acm_ctrl); rtl_write_byte(rtlpriv, AcmHwCtrl, acm_ctrl); break; } @@ -404,7 +404,7 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) } default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } @@ -415,14 +415,14 @@ void rtl92se_enable_hw_security_config(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); u8 sec_reg_value = 0x0; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("PairwiseEncAlgorithm = %d " - "GroupEncAlgorithm = %d\n", + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", rtlpriv->sec.pairwise_enc_algorithm, - rtlpriv->sec.group_enc_algorithm)); + rtlpriv->sec.group_enc_algorithm); if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("not open hw encryption\n")); + "not open hw encryption\n"); return; } @@ -433,8 +433,8 @@ void rtl92se_enable_hw_security_config(struct ieee80211_hw *hw) sec_reg_value |= SCR_RXUSEDK; } - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, ("The SECR-value %x\n", - sec_reg_value)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "The SECR-value %x\n", + sec_reg_value); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); @@ -718,8 +718,8 @@ static void _rtl92se_macconfig_before_fwdownload(struct ieee80211_hw *hw) if (pollingcnt <= 0) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Polling TXDMA_INIT_VALUE " - "timeout!! Current TCR(%#x)\n", tmpu1b)); + "Polling TXDMA_INIT_VALUE timeout!! Current TCR(%#x)\n", + tmpu1b); tmpu1b = rtl_read_byte(rtlpriv, CMDR); rtl_write_byte(rtlpriv, CMDR, tmpu1b & (~TXDMA_EN)); udelay(2); @@ -870,10 +870,10 @@ static void _rtl92se_macconfig_after_fwdownload(struct ieee80211_hw *hw) /* Change Program timing */ rtl_write_byte(rtlpriv, REG_EFUSE_CTRL + 3, 0x72); - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("EFUSE CONFIG OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "EFUSE CONFIG OK\n"); } - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "OK\n"); } @@ -951,9 +951,7 @@ int rtl92se_hw_init(struct ieee80211_hw *hw) rtstatus = rtl92s_download_fw(hw); if (!rtstatus) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Failed to download FW. " - "Init HW without FW now.., Please copy FW into" - "/lib/firmware/rtlwifi\n")); + "Failed to download FW. Init HW without FW now... Please copy FW into /lib/firmware/rtlwifi\n"); rtlhal->fw_ready = false; } else { rtlhal->fw_ready = true; @@ -968,7 +966,7 @@ int rtl92se_hw_init(struct ieee80211_hw *hw) /* 3. Initialize MAC/PHY Config by MACPHY_reg.txt */ if (rtl92s_phy_mac_config(hw) != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("MAC Config failed\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "MAC Config failed\n"); return rtstatus; } @@ -978,7 +976,7 @@ int rtl92se_hw_init(struct ieee80211_hw *hw) /* 4. Initialize BB After MAC Config PHY_reg.txt, AGC_Tab.txt */ if (rtl92s_phy_bb_config(hw) != true) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, ("BB Config failed\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "BB Config failed\n"); return rtstatus; } @@ -1014,7 +1012,7 @@ int rtl92se_hw_init(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, RF_CTRL, 0x07); if (rtl92s_phy_rf_config(hw) != true) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("RF Config failed\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "RF Config failed\n"); return rtstatus; } @@ -1129,26 +1127,26 @@ static int _rtl92se_set_media_status(struct ieee80211_hw *hw, case NL80211_IFTYPE_UNSPECIFIED: bt_msr |= (MSR_LINK_NONE << MSR_LINK_SHIFT); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to NO LINK!\n")); + "Set Network type to NO LINK!\n"); break; case NL80211_IFTYPE_ADHOC: bt_msr |= (MSR_LINK_ADHOC << MSR_LINK_SHIFT); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to Ad Hoc!\n")); + "Set Network type to Ad Hoc!\n"); break; case NL80211_IFTYPE_STATION: bt_msr |= (MSR_LINK_MANAGED << MSR_LINK_SHIFT); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to STA!\n")); + "Set Network type to STA!\n"); break; case NL80211_IFTYPE_AP: bt_msr |= (MSR_LINK_MASTER << MSR_LINK_SHIFT); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to AP!\n")); + "Set Network type to AP!\n"); break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Network type %d not support!\n", type)); + "Network type %d not supported!\n", type); return 1; break; @@ -1583,8 +1581,8 @@ void rtl92se_update_interrupt_mask(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, - ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr)); + RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, "add_msr:%x, rm_msr:%x\n", + add_msr, rm_msr); if (add_msr) rtlpci->irq_mask[0] |= add_msr; @@ -1627,7 +1625,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) if (rtlefuse->epromtype == EEPROM_93C46) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("RTL819X Not boot from eeprom, check it !!")); + "RTL819X Not boot from eeprom, check it !!\n"); } else if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) { rtl_efuse_shadow_map_update(hw); @@ -1642,10 +1640,10 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) eeprom_id = *((u16 *)&hwinfo[0]); if (eeprom_id != RTL8190_EEPROM_ID) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("EEPROM ID(%#x) is invalid!!\n", eeprom_id)); + "EEPROM ID(%#x) is invalid!!\n", eeprom_id); rtlefuse->autoload_failflag = true; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; } @@ -1663,15 +1661,15 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROMId = 0x%4x\n", eeprom_id)); + "EEPROMId = 0x%4x\n", eeprom_id); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid)); + "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did)); + "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid)); + "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid)); + "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid); for (i = 0; i < 6; i += 2) { usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i]; @@ -1681,8 +1679,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) for (i = 0; i < 6; i++) rtl_write_byte(rtlpriv, MACIDR0 + i, rtlefuse->dev_addr[i]); - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("%pM\n", rtlefuse->dev_addr)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr); /* Get Tx Power Level by Channel */ /* Read Tx power of Channel 1 ~ 14 from EEPROM. */ @@ -1937,14 +1934,14 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) if (!(tempval & BIT(0))) { rtlefuse->b1x1_recvcombine = true; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("RF_TYPE=1T2R but only 1SS\n")); + "RF_TYPE=1T2R but only 1SS\n"); } } rtlefuse->b1ss_support = rtlefuse->b1x1_recvcombine; rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMID]; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("EEPROM Customer ID: 0x%2x", - rtlefuse->eeprom_oemid)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x", + rtlefuse->eeprom_oemid); /* set channel paln to world wide 13 */ rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13; @@ -1959,19 +1956,19 @@ void rtl92se_read_eeprom_info(struct ieee80211_hw *hw) tmp_u1b = rtl_read_byte(rtlpriv, EPROM_CMD); if (tmp_u1b & BIT(4)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); rtlefuse->epromtype = EEPROM_93C46; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); rtlefuse->epromtype = EEPROM_BOOT_EFUSE; } if (tmp_u1b & BIT(5)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; _rtl92se_read_adapter_info(hw); } else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Autoload ERR!!\n"); rtlefuse->autoload_failflag = true; } } @@ -2071,8 +2068,8 @@ static void rtl92se_update_hal_rate_table(struct ieee80211_hw *hw, else rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_REFRESH_BG); - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, - ("%x\n", rtl_read_dword(rtlpriv, ARFR0))); + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n", + rtl_read_dword(rtlpriv, ARFR0)); } static void rtl92se_update_hal_rate_mask(struct ieee80211_hw *hw, @@ -2224,8 +2221,8 @@ static void rtl92se_update_hal_rate_mask(struct ieee80211_hw *hw, mask |= (bmulticast ? 1 : 0) << 9 | (macid & 0x1f) << 4 | (band & 0xf); - RT_TRACE(rtlpriv, COMP_RATR, DBG_TRACE, ("mask = %x, bitmap = %x\n", - mask, ratr_bitmap)); + RT_TRACE(rtlpriv, COMP_RATR, DBG_TRACE, "mask = %x, bitmap = %x\n", + mask, ratr_bitmap); rtl_write_dword(rtlpriv, 0x2c4, ratr_bitmap); rtl_write_dword(rtlpriv, WFM5, (FW_RA_UPDATE_MASK | (mask << 8))); @@ -2301,14 +2298,14 @@ bool rtl92se_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) if ((ppsc->hwradiooff) && (rfpwr_toset == ERFON)) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("RFKILL-HW Radio ON, RF ON\n")); + "RFKILL-HW Radio ON, RF ON\n"); rfpwr_toset = ERFON; ppsc->hwradiooff = false; actuallyset = true; } else if ((ppsc->hwradiooff == false) && (rfpwr_toset == ERFOFF)) { - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("RFKILL-HW Radio OFF, RF OFF\n")); + RT_TRACE(rtlpriv, COMP_RF, + DBG_DMESG, "RFKILL-HW Radio OFF, RF OFF\n"); rfpwr_toset = ERFOFF; ppsc->hwradiooff = true; @@ -2372,7 +2369,7 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, u8 cam_offset = 0; u8 clear_number = 5; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); for (idx = 0; idx < clear_number; idx++) { rtl_cam_mark_invalid(hw, cam_offset + idx); @@ -2401,7 +2398,7 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); enc_algo = CAM_TKIP; break; } @@ -2419,9 +2416,8 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, p_macaddr); if (entry_id >= TOTAL_CAM_ENTRY) { RT_TRACE(rtlpriv, - COMP_SEC, DBG_EMERG, - ("Can not find free hw" - " security cam entry\n")); + COMP_SEC, DBG_EMERG, + "Can not find free hw security cam entry\n"); return; } } else { @@ -2435,30 +2431,31 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, if (rtlpriv->sec.key_len[key_index] == 0) { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("delete one entry, entry_id is %d\n", - entry_id)); + "delete one entry, entry_id is %d\n", + entry_id); if (mac->opmode == NL80211_IFTYPE_AP) rtl_cam_del_entry(hw, p_macaddr); rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); } else { RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The insert KEY length is %d\n", - rtlpriv->sec.key_len[PAIRWISE_KEYIDX])); + "The insert KEY length is %d\n", + rtlpriv->sec.key_len[PAIRWISE_KEYIDX]); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The insert KEY is %x %x\n", - rtlpriv->sec.key_buf[0][0], - rtlpriv->sec.key_buf[0][1])); + "The insert KEY is %x %x\n", + rtlpriv->sec.key_buf[0][0], + rtlpriv->sec.key_buf[0][1]); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("add one entry\n")); + "add one entry\n"); if (is_pairwise) { RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, - "Pairwise Key content", - rtlpriv->sec.pairwise_key, - rtlpriv->sec.key_len[PAIRWISE_KEYIDX]); + "Pairwise Key content", + rtlpriv->sec.pairwise_key, + rtlpriv->sec. + key_len[PAIRWISE_KEYIDX]); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set Pairwiase key\n")); + "set Pairwise key\n"); rtl_cam_add_one_entry(hw, macaddr, key_index, entry_id, enc_algo, @@ -2466,7 +2463,7 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, rtlpriv->sec.key_buf[key_index]); } else { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set group key\n")); + "set group key\n"); if (mac->opmode == NL80211_IFTYPE_ADHOC) { rtl_cam_add_one_entry(hw, diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/led.c b/drivers/net/wireless/rtlwifi/rtl8192se/led.c index e3fe7c90ebf..1a6b0caf084 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/led.c @@ -52,8 +52,8 @@ void rtl92se_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) u8 ledcfg; struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin=%d\n", LEDCFG, pled->ledpin)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + LEDCFG, pled->ledpin); ledcfg = rtl_read_byte(rtlpriv, LEDCFG); @@ -68,7 +68,7 @@ void rtl92se_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } pled->ledon = true; @@ -80,8 +80,8 @@ void rtl92se_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); u8 ledcfg; - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin=%d\n", LEDCFG, pled->ledpin)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + LEDCFG, pled->ledpin); ledcfg = rtl_read_byte(rtlpriv, LEDCFG); @@ -101,7 +101,7 @@ void rtl92se_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } pled->ledon = false; @@ -141,8 +141,7 @@ void rtl92se_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction) ledaction == LED_CTL_POWER_ON)) { return; } - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n", - ledaction)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d\n", ledaction); _rtl92se_sw_led_control(hw, ledaction); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c index f10ac1ad908..ec5520e6847 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c @@ -58,16 +58,15 @@ u32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) struct rtl_priv *rtlpriv = rtl_priv(hw); u32 returnvalue = 0, originalvalue, bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)\n", - regaddr, bitmask)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", + regaddr, bitmask); originalvalue = rtl_read_dword(rtlpriv, regaddr); bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); returnvalue = (originalvalue & bitmask) >> bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("BBR MASK=0x%x Addr[0x%x]=0x%x\n", - bitmask, regaddr, originalvalue)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "BBR MASK=0x%x Addr[0x%x]=0x%x\n", + bitmask, regaddr, originalvalue); return returnvalue; @@ -79,8 +78,9 @@ void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, struct rtl_priv *rtlpriv = rtl_priv(hw); u32 originalvalue, bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," - " data(%#x)\n", regaddr, bitmask, data)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); if (bitmask != MASKDWORD) { originalvalue = rtl_read_dword(rtlpriv, regaddr); @@ -90,8 +90,9 @@ void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, rtl_write_dword(rtlpriv, regaddr, data); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," - " data(%#x)\n", regaddr, bitmask, data)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); } @@ -149,8 +150,8 @@ static u32 _rtl92s_phy_rf_serial_read(struct ieee80211_hw *hw, retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, BLSSI_READBACK_DATA); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rflssi_readback, retvalue)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rflssi_readback, retvalue); return retvalue; @@ -172,8 +173,8 @@ static void _rtl92s_phy_rf_serial_write(struct ieee80211_hw *hw, data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rf3wire_offset, data_and_addr)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rf3wire_offset, data_and_addr); } @@ -183,8 +184,9 @@ u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, struct rtl_priv *rtlpriv = rtl_priv(hw); u32 original_value, readback_value, bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), " - "bitmask(%#x)\n", regaddr, rfpath, bitmask)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", + regaddr, rfpath, bitmask); spin_lock(&rtlpriv->locks.rf_lock); @@ -195,9 +197,9 @@ u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, spin_unlock(&rtlpriv->locks.rf_lock); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), " - "bitmask(%#x), original_value(%#x)\n", regaddr, rfpath, - bitmask, original_value)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value); return readback_value; } @@ -212,8 +214,9 @@ void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, if (!((rtlphy->rf_pathmap >> rfpath) & 0x1)) return; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," - " data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); spin_lock(&rtlpriv->locks.rf_lock); @@ -228,8 +231,9 @@ void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, spin_unlock(&rtlpriv->locks.rf_lock); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x), " - "data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); } @@ -249,7 +253,7 @@ void rtl92s_phy_scan_operation_backup(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Unknown operation.\n")); + "Unknown operation\n"); break; } } @@ -264,9 +268,9 @@ void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw, struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); u8 reg_bw_opmode; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("Switch to %s bandwidth\n", - rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? - "20MHz" : "40MHz")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz"); if (rtlphy->set_bwmode_inprogress) return; @@ -290,8 +294,7 @@ void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", - rtlphy->current_chan_bw)); + "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); break; } @@ -316,13 +319,13 @@ void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); break; } rtl92s_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); rtlphy->set_bwmode_inprogress = false; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); } static bool _rtl92s_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, @@ -438,7 +441,7 @@ static bool _rtl92s_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } @@ -458,9 +461,8 @@ u8 rtl92s_phy_sw_chnl(struct ieee80211_hw *hw) u32 delay; bool ret; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, - ("switch to channel%d\n", - rtlphy->current_channel)); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "switch to channel%d\n", + rtlphy->current_channel); if (rtlphy->sw_chnl_inprogress) return 0; @@ -496,7 +498,7 @@ u8 rtl92s_phy_sw_chnl(struct ieee80211_hw *hw) rtlphy->sw_chnl_inprogress = false; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); return 1; } @@ -556,7 +558,7 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw, do { InitializeCount++; RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("IPS Set eRf nic enable\n")); + "IPS Set eRf nic enable\n"); rtstatus = rtl_ps_enable_nic(hw); } while ((rtstatus != true) && (InitializeCount < 10)); @@ -565,11 +567,11 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw, RT_RF_OFF_LEVL_HALT_NIC); } else { RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - ("awake, sleeped:%d ms " - "state_inap:%x\n", - jiffies_to_msecs(jiffies - - ppsc->last_sleep_jiffies), - rtlpriv->psc.state_inap)); + "awake, sleeped:%d ms state_inap:%x\n", + jiffies_to_msecs(jiffies - + ppsc-> + last_sleep_jiffies), + rtlpriv->psc.state_inap); ppsc->last_awake_jiffies = jiffies; rtl_write_word(rtlpriv, CMDR, 0x37FC); rtl_write_byte(rtlpriv, TXPAUSE, 0x00); @@ -587,7 +589,7 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw, case ERFOFF:{ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("IPS Set eRf nic disable\n")); + "IPS Set eRf nic disable\n"); rtl_ps_disable_nic(hw); RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); } else { @@ -613,11 +615,9 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw, continue; } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("eRf Off/Sleep: " - "%d times TcbBusyQueue[%d] = " - "%d before doze!\n", - (i + 1), queue_id, - skb_queue_len(&ring->queue))); + "eRf Off/Sleep: %d times TcbBusyQueue[%d] = %d before doze!\n", + i + 1, queue_id, + skb_queue_len(&ring->queue)); udelay(10); i++; @@ -625,31 +625,30 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw, if (i >= MAX_DOZE_WAITING_TIMES_9x) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("\nERFOFF: %d times" - "TcbBusyQueue[%d] = %d !\n", + "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n", MAX_DOZE_WAITING_TIMES_9x, queue_id, - skb_queue_len(&ring->queue))); + skb_queue_len(&ring->queue)); break; } } RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - ("Set ERFSLEEP awaked:%d ms\n", + "Set ERFSLEEP awaked:%d ms\n", jiffies_to_msecs(jiffies - - ppsc->last_awake_jiffies))); + ppsc->last_awake_jiffies)); RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - ("sleep awaked:%d ms " - "state_inap:%x\n", jiffies_to_msecs(jiffies - - ppsc->last_awake_jiffies), - rtlpriv->psc.state_inap)); + "sleep awaked:%d ms state_inap:%x\n", + jiffies_to_msecs(jiffies - + ppsc->last_awake_jiffies), + rtlpriv->psc.state_inap); ppsc->last_sleep_jiffies = jiffies; _rtl92se_phy_set_rf_sleep(hw); break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); bresult = false; break; } @@ -995,7 +994,7 @@ static bool _rtl92s_phy_bb_config_parafile(struct ieee80211_hw *hw) if (rtstatus != true) { RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Write BB Reg Fail!!")); + "Write BB Reg Fail!!\n"); goto phy_BB8190_Config_ParaFile_Fail; } @@ -1009,8 +1008,7 @@ static bool _rtl92s_phy_bb_config_parafile(struct ieee80211_hw *hw) } if (rtstatus != true) { RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("_rtl92s_phy_bb_config_parafile(): " - "BB_PG Reg Fail!!")); + "_rtl92s_phy_bb_config_parafile(): BB_PG Reg Fail!!\n"); goto phy_BB8190_Config_ParaFile_Fail; } @@ -1053,7 +1051,7 @@ u8 rtl92s_phy_config_rf(struct ieee80211_hw *hw, enum radio_path rfpath) radio_b_tblen = RADIOB_ARRAYLENGTH; } - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Radio No %x\n", rfpath)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath); rtstatus = true; switch (rfpath) { @@ -1175,11 +1173,11 @@ bool rtl92s_phy_bb_config(struct ieee80211_hw *hw) (rtlphy->rf_type == RF_2T2R && rf_num != 2) || (rtlphy->rf_type == RF_2T2R_GREEN && rf_num != 2)) { RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("RF_Type(%x) does not match " - "RF_Num(%x)!!\n", rtlphy->rf_type, rf_num)); + "RF_Type(%x) does not match RF_Num(%x)!!\n", + rtlphy->rf_type, rf_num); RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("path1 0x%x, path2 0x%x, pathmap " - "0x%x\n", path1, path2, pathmap)); + "path1 0x%x, path2 0x%x, pathmap 0x%x\n", + path1, path2, pathmap); } return rtstatus; @@ -1214,20 +1212,20 @@ void rtl92s_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) ROFDM0_XCAGCCORE1, MASKBYTE0); rtlphy->default_initialgain[3] = rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Default initial gain " - "(c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n", + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n", rtlphy->default_initialgain[0], rtlphy->default_initialgain[1], rtlphy->default_initialgain[2], - rtlphy->default_initialgain[3])); + rtlphy->default_initialgain[3]); /* read framesync */ rtlphy->framesync = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, MASKBYTE0); rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2, MASKDWORD); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Default framesync (0x%x) = 0x%x\n", - ROFDM0_RXDETECTOR3, rtlphy->framesync)); + "Default framesync (0x%x) = 0x%x\n", + ROFDM0_RXDETECTOR3, rtlphy->framesync); } @@ -1287,10 +1285,9 @@ void rtl92s_phy_set_txpower(struct ieee80211_hw *hw, u8 channel) &ofdmpowerLevel[0]); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Channel-%d, cckPowerLevel (A / B) = " - "0x%x / 0x%x, ofdmPowerLevel (A / B) = 0x%x / 0x%x\n", - channel, cckpowerlevel[0], cckpowerlevel[1], - ofdmpowerLevel[0], ofdmpowerLevel[1])); + "Channel-%d, cckPowerLevel (A / B) = 0x%x / 0x%x, ofdmPowerLevel (A / B) = 0x%x / 0x%x\n", + channel, cckpowerlevel[0], cckpowerlevel[1], + ofdmpowerLevel[0], ofdmpowerLevel[1]); _rtl92s_phy_ccxpower_indexcheck(hw, channel, &cckpowerlevel[0], &ofdmpowerLevel[0]); @@ -1316,7 +1313,7 @@ void rtl92s_phy_chk_fwcmd_iodone(struct ieee80211_hw *hw) } while (--pollingcnt); if (pollingcnt == 0) - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Set FW Cmd fail!!\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Set FW Cmd fail!!\n"); } @@ -1345,20 +1342,17 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw) switch (rtlhal->current_fwcmd_io) { case FW_CMD_RA_RESET: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_RA_RESET\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_RESET\n"); rtl_write_dword(rtlpriv, WFM5, FW_RA_RESET); rtl92s_phy_chk_fwcmd_iodone(hw); break; case FW_CMD_RA_ACTIVE: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_RA_ACTIVE\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_ACTIVE\n"); rtl_write_dword(rtlpriv, WFM5, FW_RA_ACTIVE); rtl92s_phy_chk_fwcmd_iodone(hw); break; case FW_CMD_RA_REFRESH_N: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_RA_REFRESH_N\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_REFRESH_N\n"); input = FW_RA_REFRESH; rtl_write_dword(rtlpriv, WFM5, input); rtl92s_phy_chk_fwcmd_iodone(hw); @@ -1367,7 +1361,7 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw) break; case FW_CMD_RA_REFRESH_BG: RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_RA_REFRESH_BG\n")); + "FW_CMD_RA_REFRESH_BG\n"); rtl_write_dword(rtlpriv, WFM5, FW_RA_REFRESH); rtl92s_phy_chk_fwcmd_iodone(hw); rtl_write_dword(rtlpriv, WFM5, FW_RA_DISABLE_RSSI_MASK); @@ -1375,21 +1369,20 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw) break; case FW_CMD_RA_REFRESH_N_COMB: RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_RA_REFRESH_N_COMB\n")); + "FW_CMD_RA_REFRESH_N_COMB\n"); input = FW_RA_IOT_N_COMB; rtl_write_dword(rtlpriv, WFM5, input); rtl92s_phy_chk_fwcmd_iodone(hw); break; case FW_CMD_RA_REFRESH_BG_COMB: RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_RA_REFRESH_BG_COMB\n")); + "FW_CMD_RA_REFRESH_BG_COMB\n"); input = FW_RA_IOT_BG_COMB; rtl_write_dword(rtlpriv, WFM5, input); rtl92s_phy_chk_fwcmd_iodone(hw); break; case FW_CMD_IQK_ENABLE: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_IQK_ENABLE\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_IQK_ENABLE\n"); rtl_write_dword(rtlpriv, WFM5, FW_IQK_ENABLE); rtl92s_phy_chk_fwcmd_iodone(hw); break; @@ -1424,8 +1417,7 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw) rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); break; case FW_CMD_LPS_ENTER: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_LPS_ENTER\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_ENTER\n"); current_aid = rtlpriv->mac80211.assoc_id; rtl_write_dword(rtlpriv, WFM5, (FW_LPS_ENTER | ((current_aid | 0xc000) << 8))); @@ -1434,20 +1426,18 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw) * turbo mode until driver leave LPS */ break; case FW_CMD_LPS_LEAVE: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_LPS_LEAVE\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_LEAVE\n"); rtl_write_dword(rtlpriv, WFM5, FW_LPS_LEAVE); rtl92s_phy_chk_fwcmd_iodone(hw); break; case FW_CMD_ADD_A2_ENTRY: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_ADD_A2_ENTRY\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_ADD_A2_ENTRY\n"); rtl_write_dword(rtlpriv, WFM5, FW_ADD_A2_ENTRY); rtl92s_phy_chk_fwcmd_iodone(hw); break; case FW_CMD_CTRL_DM_BY_DRIVER: RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("FW_CMD_CTRL_DM_BY_DRIVER\n")); + "FW_CMD_CTRL_DM_BY_DRIVER\n"); rtl_write_dword(rtlpriv, WFM5, FW_CTRL_DM_BY_DRIVER); rtl92s_phy_chk_fwcmd_iodone(hw); break; @@ -1472,8 +1462,8 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) bool bPostProcessing = false; RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Set FW Cmd(%#x), set_fwcmd_inprogress(%d)\n", - fw_cmdio, rtlhal->set_fwcmd_inprogress)); + "Set FW Cmd(%#x), set_fwcmd_inprogress(%d)\n", + fw_cmdio, rtlhal->set_fwcmd_inprogress); do { /* We re-map to combined FW CMD ones if firmware version */ @@ -1501,7 +1491,7 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) * DM map table in the future. */ switch (fw_cmdio) { case FW_CMD_RA_INIT: - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("RA init!!\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "RA init!!\n"); fw_cmdmap |= FW_RA_INIT_CTL; FW_CMD_IO_SET(rtlpriv, fw_cmdmap); /* Clear control flag to sync with FW. */ @@ -1509,7 +1499,7 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) break; case FW_CMD_DIG_DISABLE: RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Set DIG disable!!\n")); + "Set DIG disable!!\n"); fw_cmdmap &= ~FW_DIG_ENABLE_CTL; FW_CMD_IO_SET(rtlpriv, fw_cmdmap); break; @@ -1517,14 +1507,14 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) case FW_CMD_DIG_RESUME: if (!(rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE)) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Set DIG enable or resume!!\n")); + "Set DIG enable or resume!!\n"); fw_cmdmap |= (FW_DIG_ENABLE_CTL | FW_SS_CTL); FW_CMD_IO_SET(rtlpriv, fw_cmdmap); } break; case FW_CMD_DIG_HALT: RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Set DIG halt!!\n")); + "Set DIG halt!!\n"); fw_cmdmap &= ~(FW_DIG_ENABLE_CTL | FW_SS_CTL); FW_CMD_IO_SET(rtlpriv, fw_cmdmap); break; @@ -1540,9 +1530,8 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) (rtlefuse->thermalmeter[0] << 16)); RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Set TxPwr tracking!! " - "FwCmdMap(%#x), FwParam(%#x)\n", - fw_cmdmap, fw_param)); + "Set TxPwr tracking!! FwCmdMap(%#x), FwParam(%#x)\n", + fw_cmdmap, fw_param); FW_CMD_PARA_SET(rtlpriv, fw_param); FW_CMD_IO_SET(rtlpriv, fw_cmdmap); @@ -1563,9 +1552,8 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) fw_param &= FW_RA_PARAM_CLR; RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("[FW CMD] [New Version] " - "Set RA/IOT Comb in n mode!! FwCmdMap(%#x), " - "FwParam(%#x)\n", fw_cmdmap, fw_param)); + "[FW CMD] [New Version] Set RA/IOT Comb in n mode!! FwCmdMap(%#x), FwParam(%#x)\n", + fw_cmdmap, fw_param); FW_CMD_PARA_SET(rtlpriv, fw_param); FW_CMD_IO_SET(rtlpriv, fw_cmdmap); @@ -1652,7 +1640,7 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) break; case FW_CMD_PAPE_CONTROL: RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("[FW CMD] Set PAPE Control\n")); + "[FW CMD] Set PAPE Control\n"); fw_cmdmap &= ~FW_PAPE_CTL_BY_SW_HW; FW_CMD_IO_SET(rtlpriv, fw_cmdmap); diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c index 0ad50fe44aa..8966b731f7e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c @@ -123,13 +123,13 @@ static void _rtl92s_get_powerbase(struct ieee80211_hw *hw, u8 *p_pwrlevel, } if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("40MHz finalpwr_idx " - "(A / B) = 0x%x / 0x%x\n", p_final_pwridx[0], - p_final_pwridx[1])); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "40MHz finalpwr_idx (A / B) = 0x%x / 0x%x\n", + p_final_pwridx[0], p_final_pwridx[1]); } else { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("20MHz finalpwr_idx " - "(A / B) = 0x%x / 0x%x\n", p_final_pwridx[0], - p_final_pwridx[1])); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "20MHz finalpwr_idx (A / B) = 0x%x / 0x%x\n", + p_final_pwridx[0], p_final_pwridx[1]); } } @@ -153,9 +153,8 @@ static void _rtl92s_set_antennadiff(struct ieee80211_hw *hw, ant_pwr_diff = -8; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Antenna Diff from RF-B " - "to RF-A = %d (0x%x)\n", ant_pwr_diff, - ant_pwr_diff & 0xf)); + "Antenna Diff from RF-B to RF-A = %d (0x%x)\n", + ant_pwr_diff, ant_pwr_diff & 0xf); ant_pwr_diff &= 0xf; } @@ -172,9 +171,8 @@ static void _rtl92s_set_antennadiff(struct ieee80211_hw *hw, rtl_set_bbreg(hw, RFPGA0_TXGAINSTAGE, (BXBTXAGC | BXCTXAGC | BXDTXAGC), u4reg_val); - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Write BCD-Diff(0x%x) = 0x%x\n", - RFPGA0_TXGAINSTAGE, u4reg_val)); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Write BCD-Diff(0x%x) = 0x%x\n", + RFPGA0_TXGAINSTAGE, u4reg_val); } static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, @@ -201,8 +199,7 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, ((index < 2) ? pwrbase0 : pwrbase1); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("RTK better performance, " - "writeval = 0x%x\n", writeval)); + "RTK better performance, writeval = 0x%x\n", writeval); break; case 1: /* Realtek regulatory increase power diff defined @@ -211,8 +208,8 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, writeval = ((index < 2) ? pwrbase0 : pwrbase1); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Realtek regulatory, " - "40MHz, writeval = 0x%x\n", writeval)); + "Realtek regulatory, 40MHz, writeval = 0x%x\n", + writeval); } else { if (rtlphy->pwrgroup_cnt == 1) chnlgroup = 0; @@ -234,16 +231,15 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, pwrbase0 : pwrbase1); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Realtek regulatory, " - "20MHz, writeval = 0x%x\n", writeval)); + "Realtek regulatory, 20MHz, writeval = 0x%x\n", + writeval); } break; case 2: /* Better regulatory don't increase any power diff */ writeval = ((index < 2) ? pwrbase0 : pwrbase1); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Better regulatory, " - "writeval = 0x%x\n", writeval)); + "Better regulatory, writeval = 0x%x\n", writeval); break; case 3: /* Customer defined power diff. increase power diff @@ -252,14 +248,14 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("customer's limit, 40MHz = 0x%x\n", - rtlefuse->pwrgroup_ht40 - [RF90_PATH_A][chnl - 1])); + "customer's limit, 40MHz = 0x%x\n", + rtlefuse->pwrgroup_ht40 + [RF90_PATH_A][chnl - 1]); } else { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("customer's limit, 20MHz = 0x%x\n", - rtlefuse->pwrgroup_ht20 - [RF90_PATH_A][chnl - 1])); + "customer's limit, 20MHz = 0x%x\n", + rtlefuse->pwrgroup_ht20 + [RF90_PATH_A][chnl - 1]); } for (i = 0; i < 4; i++) { @@ -293,22 +289,19 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, (pwrdiff_limit[1] << 8) | (pwrdiff_limit[0]); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Customer's limit = 0x%x\n", - customer_limit)); + "Customer's limit = 0x%x\n", customer_limit); writeval = customer_limit + ((index < 2) ? pwrbase0 : pwrbase1); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Customer, writeval = " - "0x%x\n", writeval)); + "Customer, writeval = 0x%x\n", writeval); break; default: chnlgroup = 0; writeval = rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index] + ((index < 2) ? pwrbase0 : pwrbase1); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("RTK better performance, " - "writeval = 0x%x\n", writeval)); + "RTK better performance, writeval = 0x%x\n", writeval); break; } @@ -541,8 +534,7 @@ void rtl92s_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", - bandwidth)); + "unknown bandwidth: %#X\n", bandwidth); break; } } diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c index 78723cf5949..bc4b6fa4fc8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c @@ -188,7 +188,7 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->rtlhal.pfirmware = vzalloc(sizeof(struct rt_firmware)); if (!rtlpriv->rtlhal.pfirmware) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't alloc buffer for fw.\n")); + "Can't alloc buffer for fw\n"); return 1; } @@ -199,12 +199,12 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->io.dev); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to request firmware!\n")); + "Failed to request firmware!\n"); return 1; } if (firmware->size > sizeof(struct rt_firmware)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Firmware is too big!\n")); + "Firmware is too big!\n"); release_firmware(firmware); return 1; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index fbebe3ea0a2..1f266d1d795 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c @@ -756,7 +756,7 @@ void rtl92se_tx_fill_desc(struct ieee80211_hw *hw, /* DOWRD 8 */ SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping)); - RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n")); + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n"); } void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index 1b8e68e70f8..d670e6886c1 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -276,14 +276,14 @@ static int _rtl_usb_init_tx(struct ieee80211_hw *hw) ? USB_HIGH_SPEED_BULK_SIZE : USB_FULL_SPEED_BULK_SIZE; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("USB Max Bulk-out Size=%d\n", - rtlusb->max_bulk_out_size)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "USB Max Bulk-out Size=%d\n", + rtlusb->max_bulk_out_size); for (i = 0; i < __RTL_TXQ_NUM; i++) { u32 ep_num = rtlusb->ep_map.ep_mapping[i]; if (!ep_num) { RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Invalid endpoint map setting!\n")); + "Invalid endpoint map setting!\n"); return -EINVAL; } } @@ -345,9 +345,9 @@ static int _rtl_usb_init(struct ieee80211_hw *hw) rtlusb->out_ep_nums++; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("USB EP(0x%02x), MaxPacketSize=%d ,Interval=%d.\n", + "USB EP(0x%02x), MaxPacketSize=%d, Interval=%d\n", pep_desc->bEndpointAddress, pep_desc->wMaxPacketSize, - pep_desc->bInterval)); + pep_desc->bInterval); } if (rtlusb->in_ep_nums < rtlpriv->cfg->usb_interface_cfg->in_ep_num) return -EINVAL ; @@ -414,7 +414,7 @@ static struct sk_buff *_rtl_prep_rx_urb(struct ieee80211_hw *hw, gfp_mask); if (!skb) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Failed to __dev_alloc_skb!!\n")); + "Failed to __dev_alloc_skb!!\n"); return ERR_PTR(-ENOMEM); } @@ -575,7 +575,7 @@ static void _rtl_rx_completed(struct urb *_urb) if (IS_ERR(_skb)) { err = PTR_ERR(_skb); RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Can't allocate skb for bulk IN!\n")); + "Can't allocate skb for bulk IN!\n"); return; } skb = _skb; @@ -632,14 +632,14 @@ static int _rtl_usb_receive(struct ieee80211_hw *hw) urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Failed to alloc URB!!\n")); + "Failed to alloc URB!!\n"); goto err_out; } skb = _rtl_prep_rx_urb(hw, rtlusb, urb, GFP_KERNEL); if (IS_ERR(skb)) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Failed to prep_rx_urb!!\n")); + "Failed to prep_rx_urb!!\n"); err = PTR_ERR(skb); goto err_out; } @@ -745,7 +745,7 @@ static void _rtl_submit_tx_urb(struct ieee80211_hw *hw, struct urb *_urb) struct sk_buff *skb; RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Failed to submit urb.\n")); + "Failed to submit urb\n"); usb_unanchor_urb(_urb); skb = (struct sk_buff *)_urb->context; kfree_skb(skb); @@ -768,7 +768,7 @@ static int _usb_tx_post(struct ieee80211_hw *hw, struct urb *urb, if (urb->status) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Urb has error status 0x%X\n", urb->status)); + "Urb has error status 0x%X\n", urb->status); goto out; } /* TODO: statistics */ @@ -805,7 +805,7 @@ static struct urb *_rtl_usb_tx_urb_setup(struct ieee80211_hw *hw, _urb = usb_alloc_urb(0, GFP_ATOMIC); if (!_urb) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Can't allocate URB for bulk out!\n")); + "Can't allocate URB for bulk out!\n"); kfree_skb(skb); return NULL; } @@ -830,7 +830,7 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb, WARN_ON(NULL == rtlusb->usb_tx_aggregate_hdl); if (unlikely(IS_USB_STOP(rtlusb))) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("USB device is stopping...\n")); + "USB device is stopping...\n"); kfree_skb(skb); return; } @@ -840,7 +840,7 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb, _urb = _rtl_usb_tx_urb_setup(hw, _skb, ep_num); if (unlikely(!_urb)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't allocate urb. Drop skb!\n")); + "Can't allocate urb. Drop skb!\n"); return; } urb_list = &rtlusb->tx_pending[ep_num]; @@ -865,7 +865,7 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, struct sk_buff *skb, memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); if (ieee80211_is_auth(fc)) { - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n")); + RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); rtl_ips_nic_on(hw); } @@ -969,8 +969,7 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, /*like read eeprom and so on */ rtlpriv->cfg->ops->read_eeprom_info(hw); if (rtlpriv->cfg->ops->init_sw_vars(hw)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't init_sw_vars.\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n"); goto error_out; } rtlpriv->cfg->ops->init_sw_leds(hw); @@ -980,7 +979,7 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, err = rtl_init_core(hw); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't allocate sw for mac80211.\n")); + "Can't allocate sw for mac80211\n"); goto error_out; } @@ -990,7 +989,7 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, err = ieee80211_register_hw(hw); if (err) { RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Can't register mac80211 hw.\n")); + "Can't register mac80211 hw\n"); goto error_out; } else { rtlpriv->mac80211.mac80211_registered = 1; -- cgit v1.2.3-70-g09d2 From 4c48869f5d6e4ee4a773fd67a01e1b934faa57f8 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 4 Jan 2012 19:40:42 -0800 Subject: rtlwifi: Convert RTPRINT macro to use ##__VA_ARGS__ Consolidate printks to avoid possible message interleaving and reduce the object size. Remove unnecessary RTPRINT parentheses. Coalesce formats. Align arguments. $ size drivers/net/wireless/rtlwifi/built-in.o* text data bss dec hex filename 590002 55333 127560 772895 bcb1f drivers/net/wireless/rtlwifi/built-in.o.new 594841 55333 129680 779854 be64e drivers/net/wireless/rtlwifi/built-in.o.old Signed-off-by: Joe Perches Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/debug.h | 6 +- drivers/net/wireless/rtlwifi/efuse.c | 28 +-- drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 74 ++++---- drivers/net/wireless/rtlwifi/rtl8192ce/rf.c | 77 ++++----- drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 71 ++++---- drivers/net/wireless/rtlwifi/rtl8192cu/rf.c | 65 ++++--- drivers/net/wireless/rtlwifi/rtl8192de/phy.c | 250 +++++++++++++-------------- drivers/net/wireless/rtlwifi/rtl8192de/rf.c | 69 ++++---- drivers/net/wireless/rtlwifi/rtl8192se/hw.c | 85 ++++----- 9 files changed, 355 insertions(+), 370 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h index 8c139693354..8b51a828eff 100644 --- a/drivers/net/wireless/rtlwifi/debug.h +++ b/drivers/net/wireless/rtlwifi/debug.h @@ -175,11 +175,11 @@ do { \ } \ } while (0) -#define RTPRINT(rtlpriv, dbgtype, dbgflag, printstr) \ +#define RTPRINT(rtlpriv, dbgtype, dbgflag, fmt, ...) \ do { \ if (unlikely(rtlpriv->dbg.dbgp_type[dbgtype] & dbgflag)) { \ - printk(KERN_DEBUG "%s: ", KBUILD_MODNAME); \ - printk printstr; \ + printk(KERN_DEBUG KBUILD_MODNAME ": " fmt, \ + ##__VA_ARGS__); \ } \ } while (0) diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c index 2885131cf1a..a079a31b4ed 100644 --- a/drivers/net/wireless/rtlwifi/efuse.c +++ b/drivers/net/wireless/rtlwifi/efuse.c @@ -280,7 +280,7 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) if (*rtemp8 != 0xFF) { efuse_utilized++; RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL, - ("Addr=%d\n", efuse_addr)); + "Addr=%d\n", efuse_addr); efuse_addr++; } @@ -290,13 +290,13 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) if (offset < efuse_max_section) { wren = (*rtemp8 & 0x0f); RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL, - ("offset-%d Worden=%x\n", offset, wren)); + "offset-%d Worden=%x\n", offset, wren); for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { if (!(wren & 0x01)) { RTPRINT(rtlpriv, FEEPROM, - EFUSE_READ_ALL, ("Addr=%d\n", - efuse_addr)); + EFUSE_READ_ALL, + "Addr=%d\n", efuse_addr); read_efuse_byte(hw, efuse_addr, rtemp8); efuse_addr++; @@ -308,8 +308,8 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) break; RTPRINT(rtlpriv, FEEPROM, - EFUSE_READ_ALL, ("Addr=%d\n", - efuse_addr)); + EFUSE_READ_ALL, + "Addr=%d\n", efuse_addr); read_efuse_byte(hw, efuse_addr, rtemp8); efuse_addr++; @@ -326,7 +326,7 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) } RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL, - ("Addr=%d\n", efuse_addr)); + "Addr=%d\n", efuse_addr); read_efuse_byte(hw, efuse_addr, rtemp8); if (*rtemp8 != 0xFF && (efuse_addr < efuse_len)) { efuse_utilized++; @@ -850,7 +850,7 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, } } } - RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse PG_STATE_HEADER-1\n")); + RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, "efuse PG_STATE_HEADER-1\n"); } static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr, @@ -915,7 +915,7 @@ static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr, } RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, - ("efuse PG_STATE_HEADER-2\n")); + "efuse PG_STATE_HEADER-2\n"); } } @@ -935,7 +935,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, if (efuse_get_current_size(hw) >= (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES)) { RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, - ("efuse_pg_packet_write error\n")); + "efuse_pg_packet_write error\n"); return false; } @@ -947,7 +947,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, efuse_word_enable_data_read(word_en, data, target_pkt.data); target_word_cnts = efuse_calculate_word_cnts(target_pkt.word_en); - RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse Power ON\n")); + RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, "efuse Power ON\n"); while (continual && (efuse_addr < (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES))) { @@ -955,7 +955,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, if (write_state == PG_STATE_HEADER) { badworden = 0x0F; RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, - ("efuse PG_STATE_HEADER\n")); + "efuse PG_STATE_HEADER\n"); if (efuse_one_byte_read(hw, efuse_addr, &efuse_data) && (efuse_data != 0xFF)) @@ -975,7 +975,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, } else if (write_state == PG_STATE_DATA) { RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, - ("efuse PG_STATE_DATA\n")); + "efuse PG_STATE_DATA\n"); badworden = efuse_word_enable_data_write(hw, efuse_addr + 1, target_pkt.word_en, @@ -998,7 +998,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, result = false; } RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, - ("efuse PG_STATE_HEADER-3\n")); + "efuse PG_STATE_HEADER-3\n"); } } } diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 4aa228fe96e..2d01673a208 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -1362,25 +1362,24 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, for (rf_path = 0; rf_path < 2; rf_path++) for (i = 0; i < 3; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path, - i, - rtlefuse-> - eeprom_chnlarea_txpwr_cck[rf_path][i])); + "RF(%d) EEPROM CCK Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_cck[rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) for (i = 0; i < 3; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", - rf_path, i, - rtlefuse-> - eeprom_chnlarea_txpwr_ht40_1s[rf_path][i])); + "RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) for (i = 0; i < 3; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", - rf_path, i, - rtlefuse-> - eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path] - [i])); + "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) { for (i = 0; i < 14; i++) { @@ -1411,11 +1410,11 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, for (i = 0; i < 14; i++) { RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = " - "[0x%x / 0x%x / 0x%x]\n", rf_path, i, - rtlefuse->txpwrlevel_cck[rf_path][i], - rtlefuse->txpwrlevel_ht40_1s[rf_path][i], - rtlefuse->txpwrlevel_ht40_2s[rf_path][i])); + "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n", + rf_path, i, + rtlefuse->txpwrlevel_cck[rf_path][i], + rtlefuse->txpwrlevel_ht40_1s[rf_path][i], + rtlefuse->txpwrlevel_ht40_2s[rf_path][i]); } } @@ -1452,13 +1451,13 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, } RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-%d pwrgroup_ht20[%d] = 0x%x\n", - rf_path, i, - rtlefuse->pwrgroup_ht20[rf_path][i])); + "RF-%d pwrgroup_ht20[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht20[rf_path][i]); RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-%d pwrgroup_ht40[%d] = 0x%x\n", - rf_path, i, - rtlefuse->pwrgroup_ht40[rf_path][i])); + "RF-%d pwrgroup_ht40[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht40[rf_path][i]); } } @@ -1497,27 +1496,27 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_ht20diff[RF90_PATH_A][i])); + "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i])); + "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_ht20diff[RF90_PATH_B][i])); + "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i])); + "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]); if (!autoload_fail) rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7); else rtlefuse->eeprom_regulatory = 0; RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory)); + "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); if (!autoload_fail) { rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A]; @@ -1526,10 +1525,9 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI; rtlefuse->eeprom_tssi[RF90_PATH_B] = EEPROM_DEFAULT_TSSI; } - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("TSSI_A = 0x%x, TSSI_B = 0x%x\n", - rtlefuse->eeprom_tssi[RF90_PATH_A], - rtlefuse->eeprom_tssi[RF90_PATH_B])); + RTPRINT(rtlpriv, FINIT, INIT_TxPower, "TSSI_A = 0x%x, TSSI_B = 0x%x\n", + rtlefuse->eeprom_tssi[RF90_PATH_A], + rtlefuse->eeprom_tssi[RF90_PATH_B]); if (!autoload_fail) tempval = hwinfo[EEPROM_THERMAL_METER]; @@ -1542,7 +1540,7 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter)); + "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); } static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c index 3ba1a4feeb3..5ef960499a4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c @@ -123,8 +123,8 @@ void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_A_CCK1_MCS32)); + "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_A_CCK1_MCS32); tmpval = tx_agc[RF90_PATH_A] >> 8; @@ -133,22 +133,22 @@ void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK11_A_CCK2_11)); + "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK11_A_CCK2_11); tmpval = tx_agc[RF90_PATH_B] >> 24; rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK11_A_CCK2_11)); + "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK11_A_CCK2_11); tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff; rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK1_55_MCS32)); + "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK1_55_MCS32); } static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw, @@ -171,8 +171,8 @@ static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw, (powerBase0 << 8) | powerBase0; *(ofdmbase + i) = powerBase0; RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - (" [OFDM power base index rf(%c) = 0x%x]\n", - ((i == 0) ? 'A' : 'B'), *(ofdmbase + i))); + " [OFDM power base index rf(%c) = 0x%x]\n", + i == 0 ? 'A' : 'B', *(ofdmbase + i)); } for (i = 0; i < 2; i++) { @@ -187,8 +187,8 @@ static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw, *(mcsbase + i) = powerBase1; RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - (" [MCS power base index rf(%c) = 0x%x]\n", - ((i == 0) ? 'A' : 'B'), *(mcsbase + i))); + " [MCS power base index rf(%c) = 0x%x]\n", + i == 0 ? 'A' : 'B', *(mcsbase + i)); } } @@ -215,9 +215,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("RTK better performance, " - "writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "RTK better performance, writeVal(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); break; case 1: if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { @@ -225,9 +224,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Realtek regulatory, 40MHz, " - "writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "Realtek regulatory, 40MHz, writeVal(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); } else { if (rtlphy->pwrgroup_cnt == 1) chnlgroup = 0; @@ -249,9 +247,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Realtek regulatory, 20MHz, " - "writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "Realtek regulatory, 20MHz, writeVal(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); } break; case 2: @@ -259,27 +256,24 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Better regulatory, " - "writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "Better regulatory, writeVal(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); break; case 3: chnlgroup = 0; if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("customer's limit, 40MHz " - "rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), - rtlefuse->pwrgroup_ht40[rf][channel - - 1])); + "customer's limit, 40MHz rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', + rtlefuse->pwrgroup_ht40[rf][channel - + 1]); } else { RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("customer's limit, 20MHz " - "rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), - rtlefuse->pwrgroup_ht20[rf][channel - - 1])); + "customer's limit, 20MHz rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', + rtlefuse->pwrgroup_ht20[rf][channel - + 1]); } for (i = 0; i < 4; i++) { pwr_diff_limit[i] = @@ -311,15 +305,15 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Customer's limit rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), customer_limit)); + "Customer's limit rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', customer_limit); writeVal = customer_limit + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Customer, writeVal rf(%c)= 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "Customer, writeVal rf(%c)= 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); break; default: chnlgroup = 0; @@ -329,9 +323,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("RTK better performance, writeVal " - "rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "RTK better performance, writeVal rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); break; } @@ -383,7 +376,7 @@ static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw, rtl_set_bbreg(hw, regoffset, MASKDWORD, writeVal); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Set 0x%x = %08x\n", regoffset, writeVal)); + "Set 0x%x = %08x\n", regoffset, writeVal); if (((get_rf_type(rtlphy) == RF_2T2R) && (regoffset == RTXAGC_A_MCS15_MCS12 || diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 80bd17d8593..de1542f1485 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -162,24 +162,24 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, for (rf_path = 0; rf_path < 2; rf_path++) for (i = 0; i < 3; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path, - i, rtlefuse-> - eeprom_chnlarea_txpwr_cck[rf_path][i])); + "RF(%d) EEPROM CCK Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_cck[rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) for (i = 0; i < 3; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", - rf_path, i, - rtlefuse-> - eeprom_chnlarea_txpwr_ht40_1s[rf_path][i])); + "RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) for (i = 0; i < 3; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", - rf_path, i, - rtlefuse-> - eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path] - [i])); + "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) { for (i = 0; i < 14; i++) { index = _rtl92c_get_chnl_group((u8) i); @@ -205,11 +205,10 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, } for (i = 0; i < 14; i++) { RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = " - "[0x%x / 0x%x / 0x%x]\n", rf_path, i, - rtlefuse->txpwrlevel_cck[rf_path][i], - rtlefuse->txpwrlevel_ht40_1s[rf_path][i], - rtlefuse->txpwrlevel_ht40_2s[rf_path][i])); + "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n", rf_path, i, + rtlefuse->txpwrlevel_cck[rf_path][i], + rtlefuse->txpwrlevel_ht40_1s[rf_path][i], + rtlefuse->txpwrlevel_ht40_2s[rf_path][i]); } } for (i = 0; i < 3; i++) { @@ -242,13 +241,13 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, & 0xf0) >> 4); } RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-%d pwrgroup_ht20[%d] = 0x%x\n", - rf_path, i, - rtlefuse->pwrgroup_ht20[rf_path][i])); + "RF-%d pwrgroup_ht20[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht20[rf_path][i]); RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-%d pwrgroup_ht40[%d] = 0x%x\n", - rf_path, i, - rtlefuse->pwrgroup_ht40[rf_path][i])); + "RF-%d pwrgroup_ht40[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht40[rf_path][i]); } } for (i = 0; i < 14; i++) { @@ -277,26 +276,26 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7]; for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_ht20diff[RF90_PATH_A][i])); + "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i])); + "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_ht20diff[RF90_PATH_B][i])); + "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i])); + "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]); if (!autoload_fail) rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7); else rtlefuse->eeprom_regulatory = 0; RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory)); + "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); if (!autoload_fail) { rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A]; rtlefuse->eeprom_tssi[RF90_PATH_B] = hwinfo[EEPROM_TSSI_B]; @@ -305,9 +304,9 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, rtlefuse->eeprom_tssi[RF90_PATH_B] = EEPROM_DEFAULT_TSSI; } RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("TSSI_A = 0x%x, TSSI_B = 0x%x\n", - rtlefuse->eeprom_tssi[RF90_PATH_A], - rtlefuse->eeprom_tssi[RF90_PATH_B])); + "TSSI_A = 0x%x, TSSI_B = 0x%x\n", + rtlefuse->eeprom_tssi[RF90_PATH_A], + rtlefuse->eeprom_tssi[RF90_PATH_B]); if (!autoload_fail) tempval = hwinfo[EEPROM_THERMAL_METER]; else @@ -320,7 +319,7 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, rtlefuse->apk_thermalmeterignore = true; rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter)); + "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); } static void _rtl92cu_read_board_type(struct ieee80211_hw *hw, u8 *contents) diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c index 7b48ee9acb1..e132cb30a30 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c @@ -140,26 +140,26 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_A_CCK1_MCS32)); + "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_A_CCK1_MCS32); tmpval = tx_agc[RF90_PATH_A] >> 8; if (mac->mode == WIRELESS_MODE_B) tmpval = tmpval & 0xff00ffff; rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK11_A_CCK2_11)); + "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK11_A_CCK2_11); tmpval = tx_agc[RF90_PATH_B] >> 24; rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK11_A_CCK2_11)); + "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK11_A_CCK2_11); tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff; rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK1_55_MCS32)); + "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK1_55_MCS32); } static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw, @@ -181,8 +181,8 @@ static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw, (powerBase0 << 8) | powerBase0; *(ofdmbase + i) = powerBase0; RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - (" [OFDM power base index rf(%c) = 0x%x]\n", - ((i == 0) ? 'A' : 'B'), *(ofdmbase + i))); + " [OFDM power base index rf(%c) = 0x%x]\n", + i == 0 ? 'A' : 'B', *(ofdmbase + i)); } for (i = 0; i < 2; i++) { if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) { @@ -194,8 +194,8 @@ static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw, (powerBase1 << 16) | (powerBase1 << 8) | powerBase1; *(mcsbase + i) = powerBase1; RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - (" [MCS power base index rf(%c) = 0x%x]\n", - ((i == 0) ? 'A' : 'B'), *(mcsbase + i))); + " [MCS power base index rf(%c) = 0x%x]\n", + i == 0 ? 'A' : 'B', *(mcsbase + i)); } } @@ -219,8 +219,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, [chnlgroup][index + (rf ? 8 : 0)] + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("RTK better performance,writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "RTK better performance,writeVal(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); break; case 1: if (rtlphy->pwrgroup_cnt == 1) @@ -244,32 +244,31 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Realtek regulatory, 20MHz, " - "writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "Realtek regulatory, 20MHz, writeVal(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); break; case 2: writeVal = ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Better regulatory,writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "Better regulatory,writeVal(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); break; case 3: chnlgroup = 0; if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("customer's limit, 40MHzrf(%c) = " - "0x%x\n", ((rf == 0) ? 'A' : 'B'), + "customer's limit, 40MHzrf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', rtlefuse->pwrgroup_ht40[rf] - [channel - 1])); + [channel - 1]); } else { RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("customer's limit, 20MHz rf(%c) = " - "0x%x\n", ((rf == 0) ? 'A' : 'B'), + "customer's limit, 20MHz rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', rtlefuse->pwrgroup_ht20[rf] - [channel - 1])); + [channel - 1]); } for (i = 0; i < 4; i++) { pwr_diff_limit[i] = @@ -297,22 +296,22 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, (pwr_diff_limit[2] << 16) | (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Customer's limit rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), customer_limit)); + "Customer's limit rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', customer_limit); writeVal = customer_limit + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Customer, writeVal rf(%c)= 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "Customer, writeVal rf(%c)= 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); break; default: chnlgroup = 0; writeVal = rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] [index + (rf ? 8 : 0)] + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, ("RTK better " - "performance, writeValrf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "RTK better performance, writeValrf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); break; } if (rtlpriv->dm.dynamic_txhighpower_lvl == @@ -365,7 +364,7 @@ static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw, regoffset = regoffset_b[index]; rtl_set_bbreg(hw, regoffset, MASKDWORD, writeVal); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Set 0x%x = %08x\n", regoffset, writeVal)); + "Set 0x%x = %08x\n", regoffset, writeVal); if (((get_rf_type(rtlphy) == RF_2T2R) && (regoffset == RTXAGC_A_MCS15_MCS12 || regoffset == RTXAGC_B_MCS15_MCS12)) || diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c index 82cc052fc98..c736b933488 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c @@ -1446,8 +1446,8 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) if (rtlhal->current_bandtype == BAND_ON_5G) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>5G\n"); u4tmp = curveindex_5g[channel - 1]; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("ver 1 set RF-A, 5G, " - "0x28 = 0x%x !!\n", u4tmp)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "ver 1 set RF-A, 5G, 0x28 = 0x%x !!\n", u4tmp); for (i = 0; i < RF_CHNL_NUM_5G; i++) { if (channel == rf_chnl_5g[i] && channel <= 140) index = 0; @@ -1545,8 +1545,8 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) } else if (rtlhal->current_bandtype == BAND_ON_2_4G) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>2.4G\n"); u4tmp = curveindex_2g[channel - 1]; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("ver 3 set RF-B, 2G, " - "0x28 = 0x%x !!\n", u4tmp)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", u4tmp); if (channel == 1 || channel == 2 || channel == 4 || channel == 9 || channel == 10 || channel == 11 || channel == 12) index = 0; @@ -1589,8 +1589,8 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) BRFREGOFFSETMASK)); } RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("cosa ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", - rf_syn_g4_for_c_cut_2g | (u4tmp << 11))); + "cosa ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", + rf_syn_g4_for_c_cut_2g | (u4tmp << 11)); rtl_set_rfreg(hw, (enum radio_path)path, RF_SYN_G4, BRFREGOFFSETMASK, @@ -1637,9 +1637,9 @@ static u8 _rtl92d_phy_patha_iqk(struct ieee80211_hw *hw, bool configpathb) u32 regeac, rege94, rege9c, regea4; u8 result = 0; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK!\n"); /* path-A IQK setting */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A IQK setting!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A IQK setting!\n"); if (rtlhal->interfaceindex == 0) { rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x10008c1f); rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x10008c1f); @@ -1657,26 +1657,26 @@ static u8 _rtl92d_phy_patha_iqk(struct ieee80211_hw *hw, bool configpathb) rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x28160206); } /* LO calibration setting */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LO calibration setting!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "LO calibration setting!\n"); rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911); /* One shot, path A LOK & IQK */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("One shot, path A LOK & IQK!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "One shot, path A LOK & IQK!\n"); rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf9000000); rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000); /* delay x ms */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Delay %d ms for One shot, path A LOK & IQK.\n", - IQK_DELAY_TIME)); + "Delay %d ms for One shot, path A LOK & IQK\n", + IQK_DELAY_TIME); mdelay(IQK_DELAY_TIME); /* Check failed */ regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac); rege94 = rtl_get_bbreg(hw, 0xe94, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe94 = 0x%x\n", rege94)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe94 = 0x%x\n", rege94); rege9c = rtl_get_bbreg(hw, 0xe9c, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe9c = 0x%x\n", rege9c)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe9c = 0x%x\n", rege9c); regea4 = rtl_get_bbreg(hw, 0xea4, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xea4 = 0x%x\n", regea4)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xea4 = 0x%x\n", regea4); if (!(regeac & BIT(28)) && (((rege94 & 0x03FF0000) >> 16) != 0x142) && (((rege9c & 0x03FF0000) >> 16) != 0x42)) result |= 0x01; @@ -1687,7 +1687,7 @@ static u8 _rtl92d_phy_patha_iqk(struct ieee80211_hw *hw, bool configpathb) (((regeac & 0x03FF0000) >> 16) != 0x36)) result |= 0x02; else - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A Rx IQK fail!!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A Rx IQK fail!!\n"); return result; } @@ -1708,9 +1708,9 @@ static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw, TxOKBit = BIT(31); RxOKBit = BIT(30); } - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK!\n"); /* path-A IQK setting */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A IQK setting!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A IQK setting!\n"); rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x18008c1f); rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x18008c1f); rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82140307); @@ -1723,7 +1723,7 @@ static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw, rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x68110000); } /* LO calibration setting */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LO calibration setting!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "LO calibration setting!\n"); rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911); /* path-A PA on */ rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD, 0x07000f60); @@ -1731,29 +1731,29 @@ static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw, for (i = 0; i < retrycount; i++) { /* One shot, path A LOK & IQK */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("One shot, path A LOK & IQK!\n")); + "One shot, path A LOK & IQK!\n"); rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf9000000); rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000); /* delay x ms */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Delay %d ms for One shot, path A LOK & IQK.\n", - IQK_DELAY_TIME)); + "Delay %d ms for One shot, path A LOK & IQK.\n", + IQK_DELAY_TIME); mdelay(IQK_DELAY_TIME * 10); /* Check failed */ regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac); rege94 = rtl_get_bbreg(hw, 0xe94, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe94 = 0x%x\n", rege94)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe94 = 0x%x\n", rege94); rege9c = rtl_get_bbreg(hw, 0xe9c, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe9c = 0x%x\n", rege9c)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe9c = 0x%x\n", rege9c); regea4 = rtl_get_bbreg(hw, 0xea4, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xea4 = 0x%x\n", regea4)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xea4 = 0x%x\n", regea4); if (!(regeac & TxOKBit) && (((rege94 & 0x03FF0000) >> 16) != 0x142)) { result |= 0x01; } else { /* if Tx not OK, ignore Rx */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path A Tx IQK fail!!\n")); + "Path A Tx IQK fail!!\n"); continue; } @@ -1764,7 +1764,7 @@ static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw, break; } else { RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path A Rx IQK fail!!\n")); + "Path A Rx IQK fail!!\n"); } } /* path A PA off */ @@ -1782,27 +1782,26 @@ static u8 _rtl92d_phy_pathb_iqk(struct ieee80211_hw *hw) u32 regeac, regeb4, regebc, regec4, regecc; u8 result = 0; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B IQK!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B IQK!\n"); /* One shot, path B LOK & IQK */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("One shot, path A LOK & IQK!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "One shot, path A LOK & IQK!\n"); rtl_set_bbreg(hw, 0xe60, BMASKDWORD, 0x00000002); rtl_set_bbreg(hw, 0xe60, BMASKDWORD, 0x00000000); /* delay x ms */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Delay %d ms for One shot, path B LOK & IQK.\n", - IQK_DELAY_TIME)); + "Delay %d ms for One shot, path B LOK & IQK\n", IQK_DELAY_TIME); mdelay(IQK_DELAY_TIME); /* Check failed */ regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac); regeb4 = rtl_get_bbreg(hw, 0xeb4, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeb4 = 0x%x\n", regeb4)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeb4 = 0x%x\n", regeb4); regebc = rtl_get_bbreg(hw, 0xebc, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xebc = 0x%x\n", regebc)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xebc = 0x%x\n", regebc); regec4 = rtl_get_bbreg(hw, 0xec4, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xec4 = 0x%x\n", regec4)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xec4 = 0x%x\n", regec4); regecc = rtl_get_bbreg(hw, 0xecc, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xecc = 0x%x\n", regecc)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xecc = 0x%x\n", regecc); if (!(regeac & BIT(31)) && (((regeb4 & 0x03FF0000) >> 16) != 0x142) && (((regebc & 0x03FF0000) >> 16) != 0x42)) result |= 0x01; @@ -1812,7 +1811,7 @@ static u8 _rtl92d_phy_pathb_iqk(struct ieee80211_hw *hw) (((regecc & 0x03FF0000) >> 16) != 0x36)) result |= 0x02; else - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B Rx IQK fail!!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B Rx IQK fail!!\n"); return result; } @@ -1826,9 +1825,9 @@ static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw) u8 i; u8 retrycount = 2; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B IQK!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B IQK!\n"); /* path-A IQK setting */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A IQK setting!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A IQK setting!\n"); rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x18008c1f); rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x18008c1f); rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82110000); @@ -1841,7 +1840,7 @@ static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw) rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x68160960); /* LO calibration setting */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LO calibration setting!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "LO calibration setting!\n"); rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911); /* path-B PA on */ @@ -1851,26 +1850,26 @@ static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw) for (i = 0; i < retrycount; i++) { /* One shot, path B LOK & IQK */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("One shot, path A LOK & IQK!\n")); + "One shot, path A LOK & IQK!\n"); rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xfa000000); rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000); /* delay x ms */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Delay %d ms for One shot, path B LOK & IQK.\n", 10)); + "Delay %d ms for One shot, path B LOK & IQK.\n", 10); mdelay(IQK_DELAY_TIME * 10); /* Check failed */ regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac); regeb4 = rtl_get_bbreg(hw, 0xeb4, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeb4 = 0x%x\n", regeb4)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeb4 = 0x%x\n", regeb4); regebc = rtl_get_bbreg(hw, 0xebc, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xebc = 0x%x\n", regebc)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xebc = 0x%x\n", regebc); regec4 = rtl_get_bbreg(hw, 0xec4, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xec4 = 0x%x\n", regec4)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xec4 = 0x%x\n", regec4); regecc = rtl_get_bbreg(hw, 0xecc, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xecc = 0x%x\n", regecc)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xecc = 0x%x\n", regecc); if (!(regeac & BIT(31)) && (((regeb4 & 0x03FF0000) >> 16) != 0x142)) result |= 0x01; @@ -1882,7 +1881,7 @@ static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw) break; } else { RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path B Rx IQK fail!!\n")); + "Path B Rx IQK fail!!\n"); } } @@ -1901,7 +1900,7 @@ static void _rtl92d_phy_save_adda_registers(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); u32 i; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Save ADDA parameters.\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Save ADDA parameters.\n"); for (i = 0; i < regnum; i++) adda_backup[i] = rtl_get_bbreg(hw, adda_reg[i], BMASKDWORD); } @@ -1912,7 +1911,7 @@ static void _rtl92d_phy_save_mac_registers(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); u32 i; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Save MAC parameters.\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Save MAC parameters.\n"); for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]); macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]); @@ -1926,7 +1925,7 @@ static void _rtl92d_phy_reload_adda_registers(struct ieee80211_hw *hw, u32 i; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Reload ADDA power saving parameters !\n")); + "Reload ADDA power saving parameters !\n"); for (i = 0; i < regnum; i++) rtl_set_bbreg(hw, adda_reg[i], BMASKDWORD, adda_backup[i]); } @@ -1937,7 +1936,7 @@ static void _rtl92d_phy_reload_mac_registers(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); u32 i; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Reload MAC parameters !\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Reload MAC parameters !\n"); for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]); rtl_write_byte(rtlpriv, macreg[i], macbackup[i]); @@ -1950,7 +1949,7 @@ static void _rtl92d_phy_path_adda_on(struct ieee80211_hw *hw, u32 pathon; u32 i; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("ADDA ON.\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "ADDA ON.\n"); pathon = patha_on ? 0x04db25a4 : 0x0b1b25a4; if (patha_on) pathon = rtlpriv->rtlhal.interfaceindex == 0 ? @@ -1965,7 +1964,7 @@ static void _rtl92d_phy_mac_setting_calibration(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); u32 i; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("MAC settings for Calibration.\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "MAC settings for Calibration.\n"); rtl_write_byte(rtlpriv, macreg[0], 0x3F); for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) @@ -1977,7 +1976,7 @@ static void _rtl92d_phy_mac_setting_calibration(struct ieee80211_hw *hw, static void _rtl92d_phy_patha_standby(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A standby mode!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A standby mode!\n"); rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x0); rtl_set_bbreg(hw, RFPGA0_XA_LSSIPARAMETER, BMASKDWORD, 0x00010000); @@ -1990,7 +1989,7 @@ static void _rtl92d_phy_pimode_switch(struct ieee80211_hw *hw, bool pi_mode) u32 mode; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("BB Switch to %s mode!\n", (pi_mode ? "PI" : "SI"))); + "BB Switch to %s mode!\n", pi_mode ? "PI" : "SI"); mode = pi_mode ? 0x01000100 : 0x01000000; rtl_set_bbreg(hw, 0x820, BMASKDWORD, mode); rtl_set_bbreg(hw, 0x828, BMASKDWORD, mode); @@ -2022,12 +2021,12 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], const u32 retrycount = 2; u32 bbvalue; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK for 2.4G :Start!!!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK for 2.4G :Start!!!\n"); if (t == 0) { bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("==>0x%08x\n", bbvalue)); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQ Calibration for %s\n", - (is2t ? "2T2R" : "1T1R"))); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "==>0x%08x\n", bbvalue); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQ Calibration for %s\n", + is2t ? "2T2R" : "1T1R"); /* Save ADDA parameters, turn Path A ADDA on */ _rtl92d_phy_save_adda_registers(hw, adda_reg, @@ -2065,7 +2064,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], if (is2t) rtl_set_bbreg(hw, 0xb6c, BMASKDWORD, 0x0f600000); /* IQ calibration setting */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK setting!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK setting!\n"); rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000); rtl_set_bbreg(hw, 0xe40, BMASKDWORD, 0x01007c00); rtl_set_bbreg(hw, 0xe44, BMASKDWORD, 0x01004800); @@ -2073,7 +2072,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], patha_ok = _rtl92d_phy_patha_iqk(hw, is2t); if (patha_ok == 0x03) { RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path A IQK Success!!\n")); + "Path A IQK Success!!\n"); result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) & 0x3FF0000) >> 16; result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) & @@ -2086,7 +2085,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], } else if (i == (retrycount - 1) && patha_ok == 0x01) { /* Tx IQK OK */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path A IQK Only Tx Success!!\n")); + "Path A IQK Only Tx Success!!\n"); result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) & 0x3FF0000) >> 16; @@ -2095,7 +2094,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], } } if (0x00 == patha_ok) - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK failed!!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK failed!!\n"); if (is2t) { _rtl92d_phy_patha_standby(hw); /* Turn Path B ADDA on */ @@ -2104,7 +2103,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], pathb_ok = _rtl92d_phy_pathb_iqk(hw); if (pathb_ok == 0x03) { RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path B IQK Success!!\n")); + "Path B IQK Success!!\n"); result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) & 0x3FF0000) >> 16; result[t][5] = (rtl_get_bbreg(hw, 0xebc, @@ -2117,7 +2116,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], } else if (i == (retrycount - 1) && pathb_ok == 0x01) { /* Tx IQK OK */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path B Only Tx IQK Success!!\n")); + "Path B Only Tx IQK Success!!\n"); result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) & 0x3FF0000) >> 16; result[t][5] = (rtl_get_bbreg(hw, 0xebc, @@ -2126,12 +2125,12 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], } if (0x00 == pathb_ok) RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path B IQK failed!!\n")); + "Path B IQK failed!!\n"); } /* Back to BB mode, load original value */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("IQK:Back to BB mode, load original value!\n")); + "IQK:Back to BB mode, load original value!\n"); rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0); if (t != 0) { @@ -2156,7 +2155,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x01008c00); rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x01008c00); } - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("<==\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "<==\n"); } static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw, @@ -2188,13 +2187,13 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw, /* Note: IQ calibration must be performed after loading * PHY_REG.txt , and radio_a, radio_b.txt */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK for 5G NORMAL:Start!!!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK for 5G NORMAL:Start!!!\n"); mdelay(IQK_DELAY_TIME * 20); if (t == 0) { bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("==>0x%08x\n", bbvalue)); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQ Calibration for %s\n", - (is2t ? "2T2R" : "1T1R"))); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "==>0x%08x\n", bbvalue); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQ Calibration for %s\n", + is2t ? "2T2R" : "1T1R"); /* Save ADDA parameters, turn Path A ADDA on */ _rtl92d_phy_save_adda_registers(hw, adda_reg, rtlphy->adda_backup, @@ -2231,13 +2230,13 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw, if (is2t) rtl_set_bbreg(hw, 0xb6c, BMASKDWORD, 0x0f600000); /* IQ calibration setting */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK setting!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK setting!\n"); rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000); rtl_set_bbreg(hw, 0xe40, BMASKDWORD, 0x10007c00); rtl_set_bbreg(hw, 0xe44, BMASKDWORD, 0x01004800); patha_ok = _rtl92d_phy_patha_iqk_5g_normal(hw, is2t); if (patha_ok == 0x03) { - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK Success!!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK Success!!\n"); result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) & 0x3FF0000) >> 16; result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) & @@ -2248,14 +2247,14 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw, 0x3FF0000) >> 16; } else if (patha_ok == 0x01) { /* Tx IQK OK */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path A IQK Only Tx Success!!\n")); + "Path A IQK Only Tx Success!!\n"); result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) & 0x3FF0000) >> 16; result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) & 0x3FF0000) >> 16; } else { - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK Fail!!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK Fail!!\n"); } if (is2t) { /* _rtl92d_phy_patha_standby(hw); */ @@ -2264,7 +2263,7 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw, pathb_ok = _rtl92d_phy_pathb_iqk_5g_normal(hw); if (pathb_ok == 0x03) { RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path B IQK Success!!\n")); + "Path B IQK Success!!\n"); result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) & 0x3FF0000) >> 16; result[t][5] = (rtl_get_bbreg(hw, 0xebc, BMASKDWORD) & @@ -2275,20 +2274,20 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw, 0x3FF0000) >> 16; } else if (pathb_ok == 0x01) { /* Tx IQK OK */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path B Only Tx IQK Success!!\n")); + "Path B Only Tx IQK Success!!\n"); result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) & 0x3FF0000) >> 16; result[t][5] = (rtl_get_bbreg(hw, 0xebc, BMASKDWORD) & 0x3FF0000) >> 16; } else { RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path B IQK failed!!\n")); + "Path B IQK failed!!\n"); } } /* Back to BB mode, load original value */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("IQK:Back to BB mode, load original value!\n")); + "IQK:Back to BB mode, load original value!\n"); rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0); if (t != 0) { if (is2t) @@ -2310,7 +2309,7 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw, rtlphy->adda_backup, IQK_ADDA_REG_NUM); } - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("<==\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "<==\n"); } static bool _rtl92d_phy_simularity_compare(struct ieee80211_hw *hw, @@ -2384,8 +2383,7 @@ static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw, rtlhal->macphymode == DUALMAC_DUALPHY; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path A IQ Calibration %s !\n", - (iqk_ok) ? "Success" : "Failed")); + "Path A IQ Calibration %s !\n", iqk_ok ? "Success" : "Failed"); if (final_candidate == 0xFF) { return; } else if (iqk_ok) { @@ -2395,8 +2393,9 @@ static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw, if ((val_x & 0x00000200) != 0) val_x = val_x | 0xFFFFFC00; tx0_a = (val_x * oldval_0) >> 8; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("X = 0x%x, tx0_a = 0x%x," - " oldval_0 0x%x\n", val_x, tx0_a, oldval_0)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "X = 0x%x, tx0_a = 0x%x, oldval_0 0x%x\n", + val_x, tx0_a, oldval_0); rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, 0x3FF, tx0_a); rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24), ((val_x * oldval_0 >> 7) & 0x1)); @@ -2408,8 +2407,9 @@ static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw, rtlhal->current_bandtype == BAND_ON_5G) val_y += 3; tx0_c = (val_y * oldval_0) >> 8; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Y = 0x%lx, tx0_c = 0x%lx\n", - val_y, tx0_c)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Y = 0x%lx, tx0_c = 0x%lx\n", + val_y, tx0_c); rtl_set_bbreg(hw, ROFDM0_XCTxAFE, 0xF0000000, ((tx0_c & 0x3C0) >> 6)); rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, 0x003F0000, @@ -2417,11 +2417,11 @@ static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw, if (is2t) rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(26), ((val_y * oldval_0 >> 7) & 0x1)); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xC80 = 0x%x\n", - rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE, - BMASKDWORD))); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xC80 = 0x%x\n", + rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE, + BMASKDWORD)); if (txonly) { - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("only Tx OK\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "only Tx OK\n"); return; } reg = result[final_candidate][2]; @@ -2441,8 +2441,8 @@ static void _rtl92d_phy_pathb_fill_iqk_matrix(struct ieee80211_hw *hw, u32 oldval_1, val_x, tx1_a, reg; long val_y, tx1_c; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B IQ Calibration %s !\n", - (iqk_ok) ? "Success" : "Failed")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B IQ Calibration %s !\n", + iqk_ok ? "Success" : "Failed"); if (final_candidate == 0xFF) { return; } else if (iqk_ok) { @@ -2452,8 +2452,8 @@ static void _rtl92d_phy_pathb_fill_iqk_matrix(struct ieee80211_hw *hw, if ((val_x & 0x00000200) != 0) val_x = val_x | 0xFFFFFC00; tx1_a = (val_x * oldval_1) >> 8; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("X = 0x%x, tx1_a = 0x%x\n", - val_x, tx1_a)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "X = 0x%x, tx1_a = 0x%x\n", + val_x, tx1_a); rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, 0x3FF, tx1_a); rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(28), ((val_x * oldval_1 >> 7) & 0x1)); @@ -2463,8 +2463,8 @@ static void _rtl92d_phy_pathb_fill_iqk_matrix(struct ieee80211_hw *hw, if (rtlhal->current_bandtype == BAND_ON_5G) val_y += 3; tx1_c = (val_y * oldval_1) >> 8; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Y = 0x%lx, tx1_c = 0x%lx\n", - val_y, tx1_c)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Y = 0x%lx, tx1_c = 0x%lx\n", + val_y, tx1_c); rtl_set_bbreg(hw, ROFDM0_XDTxAFE, 0xF0000000, ((tx1_c & 0x3C0) >> 6)); rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, 0x003F0000, @@ -2496,7 +2496,7 @@ void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw) unsigned long flag = 0; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("IQK:Start!!!channel %d\n", rtlphy->current_channel)); + "IQK:Start!!!channel %d\n", rtlphy->current_channel); for (i = 0; i < 8; i++) { result[0][i] = 0; result[1][i] = 0; @@ -2510,7 +2510,7 @@ void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw) is23simular = false; is13simular = false; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("IQK !!!currentband %d\n", rtlhal->current_bandtype)); + "IQK !!!currentband %d\n", rtlhal->current_bandtype); rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); for (i = 0; i < 3; i++) { if (rtlhal->current_bandtype == BAND_ON_5G) { @@ -2562,10 +2562,9 @@ void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw) regec4 = result[i][6]; regecc = result[i][7]; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx " - "regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n ", + "IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n", rege94, rege9c, regea4, regeac, regeb4, regebc, regec4, - regecc)); + regecc); } if (final_candidate != 0xff) { rtlphy->reg_e94 = rege94 = result[final_candidate][0]; @@ -2577,12 +2576,11 @@ void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw) regec4 = result[final_candidate][6]; regecc = result[final_candidate][7]; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("IQK: final_candidate is %x\n", final_candidate)); + "IQK: final_candidate is %x\n", final_candidate); RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx " - "regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n ", + "IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n", rege94, rege9c, regea4, regeac, regeb4, regebc, regec4, - regecc)); + regecc); patha_ok = pathb_ok = true; } else { rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; /* X default value */ @@ -2716,8 +2714,8 @@ static void _rtl92d_phy_calc_curvindex(struct ieee80211_hw *hw, } } smallest_abs_val = 0xffffffff; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("curveindex[%d] = %x\n", i, - curveindex[i])); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "curveindex[%d] = %x\n", + i, curveindex[i]); } } @@ -2733,13 +2731,13 @@ static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw, bool bneed_powerdown_radio = false; RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "path %d\n", erfpath); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("band type = %d\n", - rtlpriv->rtlhal.current_bandtype)); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("channel = %d\n", channel)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "band type = %d\n", + rtlpriv->rtlhal.current_bandtype); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "channel = %d\n", channel); if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) {/* Path-A for 5G */ u4tmp = curveindex_5g[channel-1]; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("ver 1 set RF-A, 5G, 0x28 = 0x%ulx !!\n", u4tmp)); + "ver 1 set RF-A, 5G, 0x28 = 0x%ulx !!\n", u4tmp); if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY && rtlpriv->rtlhal.interfaceindex == 1) { bneed_powerdown_radio = @@ -2758,7 +2756,7 @@ static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw, } else if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) { u4tmp = curveindex_2g[channel-1]; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n", u4tmp)); + "ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n", u4tmp); if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY && rtlpriv->rtlhal.interfaceindex == 0) { bneed_powerdown_radio = @@ -2770,8 +2768,8 @@ static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw, } rtl_set_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800, u4tmp); RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n", - rtl_get_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800))); + "ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n", + rtl_get_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800)); if (bneed_powerdown_radio) _rtl92d_phy_restore_rf_env(hw, erfpath, &u4regvalue); if (rtlpriv->rtlhal.during_mac0init_radiob) @@ -2825,20 +2823,20 @@ static void _rtl92d_phy_lc_calibrate_sw(struct ieee80211_hw *hw, bool is2t) RF_SYN_G6, BRFREGOFFSETMASK); } RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("PHY_LCK finish delay for %d ms=2\n", timecount)); + "PHY_LCK finish delay for %d ms=2\n", timecount); u4tmp = rtl_get_rfreg(hw, index, RF_SYN_G4, BRFREGOFFSETMASK); if (index == 0 && rtlhal->interfaceindex == 0) { RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("path-A / 5G LCK\n")); + "path-A / 5G LCK\n"); } else { RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("path-B / 2.4G LCK\n")); + "path-B / 2.4G LCK\n"); } memset(&curvecount_val[0], 0, CV_CURVE_CNT * 2); /* Set LC calibration off */ rtl_set_rfreg(hw, (enum radio_path)index, RF_CHNLBW, 0x08000, 0x0); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("set RF 0x18[15] = 0\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "set RF 0x18[15] = 0\n"); /* save Curve-counting number */ for (i = 0; i < CV_CURVE_CNT; i++) { u32 readval = 0, readval2 = 0; @@ -2888,7 +2886,7 @@ static void _rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) { struct rtl_priv *rtlpriv = rtl_priv(hw); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("cosa PHY_LCK ver=2\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "cosa PHY_LCK ver=2\n"); _rtl92d_phy_lc_calibrate_sw(hw, is2t); } @@ -2906,8 +2904,8 @@ void rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw) rtlphy->lck_inprogress = true; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("LCK:Start!!! currentband %x delay %d ms\n", - rtlhal->current_bandtype, timecount)); + "LCK:Start!!! currentband %x delay %d ms\n", + rtlhal->current_bandtype, timecount); if (IS_92D_SINGLEPHY(rtlhal->version)) { _rtl92d_phy_lc_calibrate(hw, true); } else { @@ -2915,7 +2913,7 @@ void rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw) _rtl92d_phy_lc_calibrate(hw, false); } rtlphy->lck_inprogress = false; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LCK:Finish!!!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "LCK:Finish!!!\n"); } void rtl92d_phy_ap_calibrate(struct ieee80211_hw *hw, char delta) diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c b/drivers/net/wireless/rtlwifi/rtl8192de/rf.c index 3bf21c2cf08..2e174f48946 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/rf.c @@ -127,23 +127,23 @@ void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, tmpval = tx_agc[RF90_PATH_A] & 0xff; rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, BMASKBYTE1, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_A_CCK1_MCS32)); + "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_A_CCK1_MCS32); tmpval = tx_agc[RF90_PATH_A] >> 8; rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK11_A_CCK2_11)); + "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK11_A_CCK2_11); tmpval = tx_agc[RF90_PATH_B] >> 24; rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, BMASKBYTE0, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK11_A_CCK2_11)); + "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK11_A_CCK2_11); tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff; rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK1_55_MCS32)); + "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK1_55_MCS32); } static void _rtl92d_phy_get_power_base(struct ieee80211_hw *hw, @@ -165,8 +165,8 @@ static void _rtl92d_phy_get_power_base(struct ieee80211_hw *hw, (powerbase0 << 8) | powerbase0; *(ofdmbase + i) = powerbase0; RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - (" [OFDM power base index rf(%c) = 0x%x]\n", - ((i == 0) ? 'A' : 'B'), *(ofdmbase + i))); + " [OFDM power base index rf(%c) = 0x%x]\n", + i == 0 ? 'A' : 'B', *(ofdmbase + i)); } for (i = 0; i < 2; i++) { @@ -179,8 +179,8 @@ static void _rtl92d_phy_get_power_base(struct ieee80211_hw *hw, (powerbase1 << 8) | powerbase1; *(mcsbase + i) = powerbase1; RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - (" [MCS power base index rf(%c) = 0x%x]\n", - ((i == 0) ? 'A' : 'B'), *(mcsbase + i))); + " [MCS power base index rf(%c) = 0x%x]\n", + i == 0 ? 'A' : 'B', *(mcsbase + i)); } } @@ -232,9 +232,9 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, (rf ? 8 : 0)] + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, ("RTK better " - "performance, writeval(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeval)); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "RTK better performance, writeval(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeval); break; case 1: if (rtlphy->pwrgroup_cnt == 1) @@ -253,33 +253,31 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, powerbase0[rf] : powerbase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Realtek regulatory, " - "20MHz, writeval(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), - writeval)); + "Realtek regulatory, 20MHz, writeval(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeval); } break; case 2: writeval = ((index < 2) ? powerbase0[rf] : powerbase1[rf]); - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, ("Better regulatory, " - "writeval(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeval)); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Better regulatory, writeval(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeval); break; case 3: chnlgroup = 0; if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("customer's limit, 40MHz rf(%c) = " - "0x%x\n", ((rf == 0) ? 'A' : 'B'), + "customer's limit, 40MHz rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', rtlefuse->pwrgroup_ht40[rf] - [channel - 1])); + [channel - 1]); } else { RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("customer's limit, 20MHz rf(%c) = " - "0x%x\n", ((rf == 0) ? 'A' : 'B'), + "customer's limit, 20MHz rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', rtlefuse->pwrgroup_ht20[rf] - [channel - 1])); + [channel - 1]); } for (i = 0; i < 4; i++) { pwr_diff_limit[i] = @@ -308,13 +306,13 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Customer's limit rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), customer_limit)); + "Customer's limit rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', customer_limit); writeval = customer_limit + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Customer, writeval rf(%c)= 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeval)); + "Customer, writeval rf(%c)= 0x%x\n", + rf == 0 ? 'A' : 'B', writeval); break; default: chnlgroup = 0; @@ -323,9 +321,8 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, (rf ? 8 : 0)] + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("RTK better performance, writeval " - "rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeval)); + "RTK better performance, writeval rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeval); break; } *(p_outwriteval + rf) = writeval; @@ -367,7 +364,7 @@ static void _rtl92d_write_ofdm_power_reg(struct ieee80211_hw *hw, regoffset = regoffset_b[index]; rtl_set_bbreg(hw, regoffset, BMASKDWORD, writeval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Set 0x%x = %08x\n", regoffset, writeval)); + "Set 0x%x = %08x\n", regoffset, writeval); if (((get_rf_type(rtlphy) == RF_2T2R) && (regoffset == RTXAGC_A_MCS15_MCS12 || regoffset == RTXAGC_B_MCS15_MCS12)) || diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index dffcafe01a3..acab8781cc7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c @@ -1704,23 +1704,24 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) for (rf_path = 0; rf_path < 2; rf_path++) for (i = 0; i < 3; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path, - i, rtlefuse->eeprom_chnlarea_txpwr_cck - [rf_path][i])); + "RF(%d) EEPROM CCK Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse->eeprom_chnlarea_txpwr_cck + [rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) for (i = 0; i < 3; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", - rf_path, i, - rtlefuse->eeprom_chnlarea_txpwr_ht40_1s - [rf_path][i])); + "RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse->eeprom_chnlarea_txpwr_ht40_1s + [rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) for (i = 0; i < 3; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", - rf_path, i, - rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif - [rf_path][i])); + "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif + [rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) { @@ -1751,11 +1752,11 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) for (i = 0; i < 14; i++) { RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = " - "[0x%x / 0x%x / 0x%x]\n", rf_path, i, - rtlefuse->txpwrlevel_cck[rf_path][i], - rtlefuse->txpwrlevel_ht40_1s[rf_path][i], - rtlefuse->txpwrlevel_ht40_2s[rf_path][i])); + "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n", + rf_path, i, + rtlefuse->txpwrlevel_cck[rf_path][i], + rtlefuse->txpwrlevel_ht40_1s[rf_path][i], + rtlefuse->txpwrlevel_ht40_2s[rf_path][i]); } } @@ -1788,13 +1789,13 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) 0xf0) >> 4); RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-%d pwrgroup_ht20[%d] = 0x%x\n", - rf_path, i, - rtlefuse->pwrgroup_ht20[rf_path][i])); + "RF-%d pwrgroup_ht20[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht20[rf_path][i]); RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-%d pwrgroup_ht40[%d] = 0x%x\n", - rf_path, i, - rtlefuse->pwrgroup_ht40[rf_path][i])); + "RF-%d pwrgroup_ht40[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht40[rf_path][i]); } } @@ -1849,27 +1850,27 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) (hwinfo[EEPROM_REGULATORY] & 0x1); } RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory)); + "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_ht20diff[RF90_PATH_A][i])); + "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i])); + "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_ht20diff[RF90_PATH_B][i])); + "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i])); + "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]); - RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("TxPwrSafetyFlag = %d\n", - rtlefuse->txpwr_safetyflag)); + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + "TxPwrSafetyFlag = %d\n", rtlefuse->txpwr_safetyflag); /* Read RF-indication and Tx Power gain * index diff of legacy to HT OFDM rate. */ @@ -1878,8 +1879,8 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->legacy_httxpowerdiff = rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][0]; - RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("TxPowerDiff = %#x\n", - rtlefuse->eeprom_txpowerdiff)); + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + "TxPowerDiff = %#x\n", rtlefuse->eeprom_txpowerdiff); /* Get TSSI value for each path. */ usvalue = *(u16 *)&hwinfo[EEPROM_TSSI_A]; @@ -1887,16 +1888,16 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) usvalue = *(u8 *)&hwinfo[EEPROM_TSSI_B]; rtlefuse->eeprom_tssi[RF90_PATH_B] = (u8)(usvalue & 0xff); - RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("TSSI_A = 0x%x, TSSI_B = 0x%x\n", - rtlefuse->eeprom_tssi[RF90_PATH_A], - rtlefuse->eeprom_tssi[RF90_PATH_B])); + RTPRINT(rtlpriv, FINIT, INIT_TxPower, "TSSI_A = 0x%x, TSSI_B = 0x%x\n", + rtlefuse->eeprom_tssi[RF90_PATH_A], + rtlefuse->eeprom_tssi[RF90_PATH_B]); /* Read antenna tx power offset of B/C/D to A from EEPROM */ /* and read ThermalMeter from EEPROM */ tempval = *(u8 *)&hwinfo[EEPROM_THERMALMETER]; rtlefuse->eeprom_thermalmeter = tempval; - RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("thermalmeter = 0x%x\n", - rtlefuse->eeprom_thermalmeter)); + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); /* ThermalMeter, BIT(0)~3 for RFIC1, BIT(4)~7 for RFIC2 */ rtlefuse->thermalmeter[0] = (rtlefuse->eeprom_thermalmeter & 0x1f); @@ -1912,8 +1913,8 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) /* Version ID, Channel plan */ rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; rtlefuse->txpwr_fromeprom = true; - RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("EEPROM ChannelPlan = 0x%4x\n", - rtlefuse->eeprom_channelplan)); + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + "EEPROM ChannelPlan = 0x%4x\n", rtlefuse->eeprom_channelplan); /* Read Customer ID or Board Type!!! */ tempval = *(u8 *)&hwinfo[EEPROM_BOARDTYPE]; -- cgit v1.2.3-70-g09d2 From 9d833ed752e91c71792dd8ebfd0f865e6a568a37 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 4 Jan 2012 19:40:43 -0800 Subject: rtlwifi: Convert RT_ASSERT macro to use ##__VA_ARGS__ Consolidate printks to avoid possible message interleaving and reduce the object size. Remove unnecessary RT_ASSERT parentheses. Align arguments. Coalesce formats. Remove unnecessary __func__ use as the macro uses it. $ size drivers/net/wireless/rtlwifi/built-in.o* text data bss dec hex filename 588901 55333 127216 771450 bc57a drivers/net/wireless/rtlwifi/built-in.o.new 590002 55333 127560 772895 bcb1f drivers/net/wireless/rtlwifi/built-in.o.old Signed-off-by: Joe Perches Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/core.c | 4 ++-- drivers/net/wireless/rtlwifi/debug.h | 7 +++---- drivers/net/wireless/rtlwifi/pci.c | 15 +++++++-------- drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | 6 +++--- drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c | 10 +++++----- drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | 16 ++++++++-------- drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 5 +++-- drivers/net/wireless/rtlwifi/rtl8192cu/mac.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | 4 ++-- drivers/net/wireless/rtlwifi/rtl8192de/fw.c | 6 +++--- drivers/net/wireless/rtlwifi/rtl8192de/hw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/phy.c | 13 ++++++------- drivers/net/wireless/rtlwifi/rtl8192de/sw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/trx.c | 16 ++++++++-------- drivers/net/wireless/rtlwifi/rtl8192se/hw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/phy.c | 4 ++-- drivers/net/wireless/rtlwifi/rtl8192se/sw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/trx.c | 16 ++++++++-------- drivers/net/wireless/rtlwifi/usb.c | 2 +- 21 files changed, 68 insertions(+), 70 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index 186c944c143..ab6a4068764 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -1026,8 +1026,8 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "set pairwise key\n"); if (!sta) { - RT_ASSERT(false, ("pairwise key withnot" - "mac_addr\n")); + RT_ASSERT(false, + "pairwise key without mac_addr\n"); err = -EOPNOTSUPP; goto out_unlock; diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h index 8b51a828eff..74b6780880f 100644 --- a/drivers/net/wireless/rtlwifi/debug.h +++ b/drivers/net/wireless/rtlwifi/debug.h @@ -156,12 +156,11 @@ enum dbgp_flag_e { DBGP_TYPE_MAX }; -#define RT_ASSERT(_exp, fmt) \ +#define RT_ASSERT(_exp, fmt, ...) \ do { \ if (!(_exp)) { \ - printk(KERN_DEBUG "%s:%s(): ", \ - KBUILD_MODNAME, __func__); \ - printk fmt; \ + printk(KERN_DEBUG KBUILD_MODNAME ":%s(): " fmt, \ + __func__, ##__VA_ARGS__); \ } \ } while (0) diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index b52fef23575..3c4ae5d9de4 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -1746,16 +1746,15 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, err = pci_enable_device(pdev); if (err) { - RT_ASSERT(false, - ("%s : Cannot enable new PCI device\n", - pci_name(pdev))); + RT_ASSERT(false, "%s : Cannot enable new PCI device\n", + pci_name(pdev)); return err; } if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { - RT_ASSERT(false, ("Unable to obtain 32bit DMA " - "for consistent allocations\n")); + RT_ASSERT(false, + "Unable to obtain 32bit DMA for consistent allocations\n"); pci_disable_device(pdev); return -ENOMEM; } @@ -1767,7 +1766,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, sizeof(struct rtl_priv), &rtl_ops); if (!hw) { RT_ASSERT(false, - ("%s : ieee80211 alloc failed\n", pci_name(pdev))); + "%s : ieee80211 alloc failed\n", pci_name(pdev)); err = -ENOMEM; goto fail1; } @@ -1797,7 +1796,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, /* MEM map */ err = pci_request_regions(pdev, KBUILD_MODNAME); if (err) { - RT_ASSERT(false, ("Can't obtain PCI resources\n")); + RT_ASSERT(false, "Can't obtain PCI resources\n"); return err; } @@ -1810,7 +1809,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, (unsigned long)pci_iomap(pdev, rtlpriv->cfg->bar_id, pmem_len); if (rtlpriv->io.pci_mem_start == 0) { - RT_ASSERT(false, ("Can't map PCI mem\n")); + RT_ASSERT(false, "Can't map PCI mem\n"); goto fail2; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index 12c025bf53b..1eae3baae51 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c @@ -519,8 +519,8 @@ void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, u32 tmp_cmdbuf[2]; if (rtlhal->fw_ready == false) { - RT_ASSERT(false, ("return H2C cmd because of Fw " - "download fail!!!\n")); + RT_ASSERT(false, + "return H2C cmd because of Fw download fail!!!\n"); return; } @@ -544,7 +544,7 @@ void rtl92c_firmware_selfreset(struct ieee80211_hw *hw) while (u1b_tmp & BIT(2)) { delay--; if (delay == 0) { - RT_ASSERT(false, ("8051 reset fail.\n")); + RT_ASSERT(false, "8051 reset fail\n"); break; } udelay(50); diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c index 8ab93a69f33..25bde968699 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c @@ -85,7 +85,7 @@ EXPORT_SYMBOL(rtl92c_phy_set_bb_reg); u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, enum radio_path rfpath, u32 offset) { - RT_ASSERT(false, ("deprecated!\n")); + RT_ASSERT(false, "deprecated!\n"); return 0; } @@ -95,7 +95,7 @@ void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, enum radio_path rfpath, u32 offset, u32 data) { - RT_ASSERT(false, ("deprecated!\n")); + RT_ASSERT(false, "deprecated!\n"); } EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_write); @@ -776,7 +776,7 @@ u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw) if (rtlphy->set_bwmode_inprogress) return 0; RT_ASSERT((rtlphy->current_channel <= 14), - ("WIRELESS_MODE_G but channel>14")); + "WIRELESS_MODE_G but channel>14\n"); rtlphy->sw_chnl_inprogress = true; rtlphy->sw_chnl_stage = 0; rtlphy->sw_chnl_step = 0; @@ -802,7 +802,7 @@ static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, struct swchnlcmd *pcmd; if (cmdtable == NULL) { - RT_ASSERT(false, ("cmdtable cannot be NULL.\n")); + RT_ASSERT(false, "cmdtable cannot be NULL\n"); return false; } @@ -848,7 +848,7 @@ bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, rfdependcmdcnt = 0; RT_ASSERT((channel >= 1 && channel <= 14), - ("illegal channel for Zebra: %d\n", channel)); + "invalid channel for Zebra: %d\n", channel); _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 2d01673a208..18f615c4121 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -1166,7 +1166,7 @@ void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci) rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222); break; default: - RT_ASSERT(false, ("invalid aci: %d !\n", aci)); + RT_ASSERT(false, "invalid aci: %d !\n", aci); break; } } diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index d2a3576fdaa..4a224dbc693 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c @@ -404,7 +404,7 @@ static int __init rtl92ce_module_init(void) ret = pci_register_driver(&rtl92ce_driver); if (ret) - RT_ASSERT(false, (": No device found\n")); + RT_ASSERT(false, "No device found\n"); return ret; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 9f6fac450a4..46892cc1a08 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -836,8 +836,8 @@ void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val); break; default: - RT_ASSERT(false, ("ERR txdesc :%d" - " not process\n", desc_name)); + RT_ASSERT(false, "ERR txdesc :%d not process\n", + desc_name); break; } } else { @@ -856,8 +856,8 @@ void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) SET_RX_DESC_EOR(pdesc, 1); break; default: - RT_ASSERT(false, ("ERR rxdesc :%d " - "not process\n", desc_name)); + RT_ASSERT(false, "ERR rxdesc :%d not process\n", + desc_name); break; } } @@ -876,8 +876,8 @@ u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name) ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc); break; default: - RT_ASSERT(false, ("ERR txdesc :%d " - "not process\n", desc_name)); + RT_ASSERT(false, "ERR txdesc :%d not process\n", + desc_name); break; } } else { @@ -890,8 +890,8 @@ u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name) ret = GET_RX_DESC_PKT_LEN(pdesc); break; default: - RT_ASSERT(false, ("ERR rxdesc :%d " - "not process\n", desc_name)); + RT_ASSERT(false, "ERR rxdesc :%d not process\n", + desc_name); break; } } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index de1542f1485..ae38bc52a71 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -1984,8 +1984,9 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) u4b_ac_param); break; default: - RT_ASSERT(false, ("SetHwReg8185(): invalid" - " aci: %d !\n", e_aci)); + RT_ASSERT(false, + "SetHwReg8185(): invalid aci: %d !\n", + e_aci); break; } if (rtlusb->acm_method != eAcmWay2_SW) diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c index 9f09844d7d5..943f3d49d1f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c @@ -428,7 +428,7 @@ void rtl92c_set_qos(struct ieee80211_hw *hw, int aci) rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, u4b_ac_param); break; default: - RT_ASSERT(false, ("invalid aci: %d !\n", aci)); + RT_ASSERT(false, "invalid aci: %d !\n", aci); break; } } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index b875af75b89..aca0fd5d116 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c @@ -244,8 +244,8 @@ u16 rtl8192cu_mq_to_hwq(__le16 fc, u16 mac80211_queue_index) break; default: hw_queue_index = RTL_TXQ_BE; - RT_ASSERT(false, ("QSLT_BE queue, skb_queue:%d\n", - mac80211_queue_index)); + RT_ASSERT(false, "QSLT_BE queue, skb_queue:%d\n", + mac80211_queue_index); break; } out: diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c index b84f10d60c0..94f5b7dd06e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c @@ -186,7 +186,7 @@ void rtl92d_firmware_selfreset(struct ieee80211_hw *hw) udelay(50); u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); } - RT_ASSERT((delay > 0), ("8051 reset failed!\n")); + RT_ASSERT((delay > 0), "8051 reset failed!\n"); RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, "=====> 8051 reset success (%d)\n", delay); } @@ -536,8 +536,8 @@ void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw, u32 tmp_cmdbuf[2]; if (rtlhal->fw_ready == false) { - RT_ASSERT(false, ("return H2C cmd because of Fw " - "download fail!!!\n")); + RT_ASSERT(false, + "return H2C cmd because of Fw download fail!!!\n"); return; } memset(tmp_cmdbuf, 0, 8); diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c index 5eecf403a5c..d94ce371572 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c @@ -1213,7 +1213,7 @@ void rtl92de_set_qos(struct ieee80211_hw *hw, int aci) rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222); break; default: - RT_ASSERT(false, ("invalid aci: %d !\n", aci)); + RT_ASSERT(false, "invalid aci: %d !\n", aci); break; } } diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c index c736b933488..f27acc75494 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c @@ -2928,7 +2928,7 @@ static bool _rtl92d_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, struct swchnlcmd *pcmd; if (cmdtable == NULL) { - RT_ASSERT(false, ("cmdtable cannot be NULL.\n")); + RT_ASSERT(false, "cmdtable cannot be NULL\n"); return false; } if (cmdtableidx >= cmdtablesz) @@ -3120,19 +3120,18 @@ u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw) * 5G and 2.4G band. */ if (channel <= 14) return 0; - RT_ASSERT((channel > 14), ("5G but channel<=14")); + RT_ASSERT((channel > 14), "5G but channel<=14\n"); break; case BAND_ON_2_4G: /* Get first channel error when change between * 5G and 2.4G band. */ if (channel > 14) return 0; - RT_ASSERT((channel <= 14), ("2G but channel>14")); + RT_ASSERT((channel <= 14), "2G but channel>14\n"); break; default: - RT_ASSERT(false, - ("Invalid WirelessMode(%#x)!!\n", - rtlpriv->mac80211.mode)); + RT_ASSERT(false, "Invalid WirelessMode(%#x)!!\n", + rtlpriv->mac80211.mode); break; } rtlphy->sw_chnl_inprogress = true; @@ -3563,7 +3562,7 @@ void rtl92d_phy_set_poweron(struct ieee80211_hw *hw) } } if (i == 200) - RT_ASSERT(false, ("Another mac power off over time\n")); + RT_ASSERT(false, "Another mac power off over time\n"); } } diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c index db7579684b1..022f0652970 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c @@ -424,7 +424,7 @@ static int __init rtl92de_module_init(void) ret = pci_register_driver(&rtl92de_driver); if (ret) - RT_ASSERT(false, (": No device found\n")); + RT_ASSERT(false, "No device found\n"); return ret; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c index f6ec0a12884..e7c985b372f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c @@ -793,8 +793,8 @@ void rtl92de_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val); break; default: - RT_ASSERT(false, ("ERR txdesc :%d" - " not process\n", desc_name)); + RT_ASSERT(false, "ERR txdesc :%d not process\n", + desc_name); break; } } else { @@ -813,8 +813,8 @@ void rtl92de_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) SET_RX_DESC_EOR(pdesc, 1); break; default: - RT_ASSERT(false, ("ERR rxdesc :%d " - "not process\n", desc_name)); + RT_ASSERT(false, "ERR rxdesc :%d not process\n", + desc_name); break; } } @@ -833,8 +833,8 @@ u32 rtl92de_get_desc(u8 *p_desc, bool istx, u8 desc_name) ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc); break; default: - RT_ASSERT(false, ("ERR txdesc :%d " - "not process\n", desc_name)); + RT_ASSERT(false, "ERR txdesc :%d not process\n", + desc_name); break; } } else { @@ -847,8 +847,8 @@ u32 rtl92de_get_desc(u8 *p_desc, bool istx, u8 desc_name) ret = GET_RX_DESC_PKT_LEN(pdesc); break; default: - RT_ASSERT(false, ("ERR rxdesc :%d " - "not process\n", desc_name)); + RT_ASSERT(false, "ERR rxdesc :%d not process\n", + desc_name); break; } } diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index acab8781cc7..b03001b2328 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c @@ -1200,7 +1200,7 @@ void rtl92se_set_qos(struct ieee80211_hw *hw, int aci) rtl_write_dword(rtlpriv, EDCAPARA_VO, 0x2f3222); break; default: - RT_ASSERT(false, ("invalid aci: %d !\n", aci)); + RT_ASSERT(false, "invalid aci: %d !\n", aci); break; } } diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c index ec5520e6847..e24dbb3a9ba 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c @@ -335,7 +335,7 @@ static bool _rtl92s_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, struct swchnlcmd *pcmd; if (cmdtable == NULL) { - RT_ASSERT(false, ("cmdtable cannot be NULL.\n")); + RT_ASSERT(false, "cmdtable cannot be NULL\n"); return false; } @@ -380,7 +380,7 @@ static bool _rtl92s_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, rfdependcmdcnt = 0; RT_ASSERT((channel >= 1 && channel <= 14), - ("illegal channel for Zebra: %d\n", channel)); + "invalid channel for Zebra: %d\n", channel); _rtl92s_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c index bc4b6fa4fc8..a933aef3d1a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c @@ -426,7 +426,7 @@ static int __init rtl92se_module_init(void) ret = pci_register_driver(&rtl92se_driver); if (ret) - RT_ASSERT(false, (": No device found\n")); + RT_ASSERT(false, "No device found\n"); return ret; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index 1f266d1d795..216a3e140de 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c @@ -823,8 +823,8 @@ void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val); break; default: - RT_ASSERT(false, ("ERR txdesc :%d not process\n", - desc_name)); + RT_ASSERT(false, "ERR txdesc :%d not process\n", + desc_name); break; } } else { @@ -843,8 +843,8 @@ void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) SET_RX_STATUS_DESC_EOR(pdesc, 1); break; default: - RT_ASSERT(false, ("ERR rxdesc :%d not process\n", - desc_name)); + RT_ASSERT(false, "ERR rxdesc :%d not process\n", + desc_name); break; } } @@ -863,8 +863,8 @@ u32 rtl92se_get_desc(u8 *desc, bool istx, u8 desc_name) ret = GET_TX_DESC_TX_BUFFER_ADDRESS(desc); break; default: - RT_ASSERT(false, ("ERR txdesc :%d not process\n", - desc_name)); + RT_ASSERT(false, "ERR txdesc :%d not process\n", + desc_name); break; } } else { @@ -876,8 +876,8 @@ u32 rtl92se_get_desc(u8 *desc, bool istx, u8 desc_name) ret = GET_RX_STATUS_DESC_PKT_LEN(desc); break; default: - RT_ASSERT(false, ("ERR rxdesc :%d not process\n", - desc_name)); + RT_ASSERT(false, "ERR rxdesc :%d not process\n", + desc_name); break; } } diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index d670e6886c1..6ae1b212ad9 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -946,7 +946,7 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, hw = ieee80211_alloc_hw(sizeof(struct rtl_priv) + sizeof(struct rtl_usb_priv), &rtl_ops); if (!hw) { - RT_ASSERT(false, ("%s : ieee80211 alloc failed\n", __func__)); + RT_ASSERT(false, "ieee80211 alloc failed\n"); return -ENOMEM; } rtlpriv = hw->priv; -- cgit v1.2.3-70-g09d2 From 4cd9f40c66e36c59f3a753d5167a89a312f5aa87 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 4 Jan 2012 19:40:44 -0800 Subject: rtlwifi: Remove duplicate __func__ The RT_TRACE macro already prepends it. Signed-off-by: Joe Perches Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index aca0fd5d116..7d5f79991f8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c @@ -620,7 +620,7 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, SET_TX_DESC_BMC(txdesc, 1); _rtl_fill_usb_tx_desc(txdesc); _rtl_tx_desc_checksum(txdesc); - RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, " %s ==>\n", __func__); + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "==>\n"); } void rtl92cu_fill_fake_txdesc(struct ieee80211_hw *hw, u8 * pDesc, -- cgit v1.2.3-70-g09d2 From f56e7eb4dd3124d53a5200ff093bc6bcbae671e9 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 4 Jan 2012 19:40:45 -0800 Subject: rtlwifi: Optimize RT_TRACE macro use of KBUILD_MODNAME for size Moving the KBUILD_MODNAME to the format reduces the overall object size a small amount. $ size drivers/net/wireless/rtlwifi/built-in.o* text data bss dec hex filename 586904 55333 127216 769453 bbdad drivers/net/wireless/rtlwifi/built-in.o.new 588901 55333 127216 771450 bc57a drivers/net/wireless/rtlwifi/built-in.o.old Signed-off-by: Joe Perches Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/debug.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h index 74b6780880f..b024c23b652 100644 --- a/drivers/net/wireless/rtlwifi/debug.h +++ b/drivers/net/wireless/rtlwifi/debug.h @@ -168,9 +168,9 @@ do { \ do { \ if (unlikely(((comp) & rtlpriv->dbg.global_debugcomponents) && \ ((level) <= rtlpriv->dbg.global_debuglevel))) { \ - printk(KERN_DEBUG "%s:%s():<%lx-%x> " fmt, \ - KBUILD_MODNAME, __func__, \ - in_interrupt(), in_atomic(), ##__VA_ARGS__); \ + printk(KERN_DEBUG KBUILD_MODNAME ":%s():<%lx-%x> " fmt, \ + __func__, in_interrupt(), in_atomic(), \ + ##__VA_ARGS__); \ } \ } while (0) -- cgit v1.2.3-70-g09d2 From 481b9606ec7276401c7f746fe37873855c49d1b8 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 5 Jan 2012 08:29:07 -0800 Subject: rtlwifi: add CONFIG_RTLWIFI_DEBUG to remove all of the debug logging code It does seem odd though to have a DBG_EMERG and not always emit it. What might also be useful for any embedded use is to add CONFIG_RTLWIFI_DEBUG to conditionally remove all of the debug logging code to reduce the largish object size. This reduces the object size by about 1/3 (250KB) when CONFIG_RTLWIFI_DEBUG is not set. $ size drivers/net/wireless/rtlwifi/built-in.o* text data bss dec hex filename 368722 55333 94224 518279 7e887 drivers/net/wireless/rtlwifi/built-in.o.new 586904 55333 127216 769453 bbdad drivers/net/wireless/rtlwifi/built-in.o.old Signed-off-by: Joe Perches Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/Kconfig | 5 +++++ drivers/net/wireless/rtlwifi/debug.h | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/rtlwifi/Kconfig index d6c42e69bdb..44b9c0a5770 100644 --- a/drivers/net/wireless/rtlwifi/Kconfig +++ b/drivers/net/wireless/rtlwifi/Kconfig @@ -49,6 +49,11 @@ config RTLWIFI depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE default m +config RTLWIFI_DEBUG + tristate "Additional debugging output" + depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE + default y + config RTL8192C_COMMON tristate depends on RTL8192CE || RTL8192CU diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h index b024c23b652..fd5600c6942 100644 --- a/drivers/net/wireless/rtlwifi/debug.h +++ b/drivers/net/wireless/rtlwifi/debug.h @@ -156,6 +156,8 @@ enum dbgp_flag_e { DBGP_TYPE_MAX }; +#ifdef CONFIG_RTLWIFI_DEBUG + #define RT_ASSERT(_exp, fmt, ...) \ do { \ if (!(_exp)) { \ @@ -195,5 +197,37 @@ do { \ } \ } while (0) +#else + +struct rtl_priv; + +__printf(2, 3) +static inline void RT_ASSERT(int exp, const char *fmt, ...) +{ +} + +__printf(4, 5) +static inline void RT_TRACE(struct rtl_priv *rtlpriv, + int comp, int level, + const char *fmt, ...) +{ +} + +__printf(4, 5) +static inline void RTPRINT(struct rtl_priv *rtlpriv, + int dbgtype, int dbgflag, + const char *fmt, ...) +{ +} + +static inline void RT_PRINT_DATA(struct rtl_priv *rtlpriv, + int comp, int level, + const char *titlestring, + const void *hexdata, size_t hexdatalen) +{ +} + +#endif + void rtl_dbgp_flag_init(struct ieee80211_hw *hw); #endif -- cgit v1.2.3-70-g09d2 From d9595ce30bd860a1c5bcafef8430f46faa26d6eb Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 6 Jan 2012 11:31:42 -0800 Subject: rtlwifi: Remove incorrect logging message prefixes pr_fmt() adds them. These are unnecessary and wrong. Signed-off-by: Joe Perches Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192cu/mac.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/sw.c | 4 ++-- drivers/net/wireless/rtlwifi/rtl8192se/sw.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c index 943f3d49d1f..71c7aca0b43 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c @@ -84,7 +84,7 @@ void rtl92c_read_chip_version(struct ieee80211_hw *hw) } } rtlhal->version = (enum version_8192c)chip_version; - pr_info("rtl8192cu: Chip version 0x%x\n", chip_version); + pr_info("Chip version 0x%x\n", chip_version); switch (rtlhal->version) { case VERSION_NORMAL_TSMC_CHIP_92C_1T2R: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c index 022f0652970..364aa402245 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c @@ -154,9 +154,9 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; if (!rtlpriv->psc.inactiveps) - pr_info("rtl8192ce: Power Save off (module option)\n"); + pr_info("Power Save off (module option)\n"); if (!rtlpriv->psc.fwctrl_lps) - pr_info("rtl8192ce: FW Power Save off (module option)\n"); + pr_info("FW Power Save off (module option)\n"); rtlpriv->psc.reg_fwctrl_lps = 3; rtlpriv->psc.reg_max_lps_awakeintvl = 5; /* for ASPM, you can close aspm through diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c index a933aef3d1a..5795a542bdf 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c @@ -168,9 +168,9 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; if (!rtlpriv->psc.inactiveps) - pr_info("rtl8192ce: Power Save off (module option)\n"); + pr_info("Power Save off (module option)\n"); if (!rtlpriv->psc.fwctrl_lps) - pr_info("rtl8192ce: FW Power Save off (module option)\n"); + pr_info("FW Power Save off (module option)\n"); rtlpriv->psc.reg_fwctrl_lps = 3; rtlpriv->psc.reg_max_lps_awakeintvl = 5; /* for ASPM, you can close aspm through -- cgit v1.2.3-70-g09d2 From 07839b143a360f9dcf38afb5600cf049f8cbee0e Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 6 Jan 2012 11:31:43 -0800 Subject: rtlwifi: Simplify chip version id logging Reduce object size a few KB too. $ size drivers/net/wireless/rtlwifi/built-in.o* text data bss dec hex filename 584493 55333 126800 766626 bb2a2 drivers/net/wireless/rtlwifi/built-in.o.new 586904 55333 127216 769453 bbdad drivers/net/wireless/rtlwifi/built-in.o.old Signed-off-by: Joe Perches Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 19 ++++++------ drivers/net/wireless/rtlwifi/rtl8192cu/mac.c | 46 +++++++++++----------------- 2 files changed, 27 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 18f615c4121..971bd29ef9b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -991,6 +991,7 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw) struct rtl_phy *rtlphy = &(rtlpriv->phy); enum version_8192c version = VERSION_UNKNOWN; u32 value32; + const char *versionid; value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG); if (value32 & TRP_VAUX_EN) { @@ -1003,27 +1004,25 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw) switch (version) { case VERSION_B_CHIP_92C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_B_CHIP_92C\n"); + versionid = "B_CHIP_92C"; break; case VERSION_B_CHIP_88C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_B_CHIP_88C\n"); + versionid = "B_CHIP_88C"; break; case VERSION_A_CHIP_92C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_A_CHIP_92C\n"); + versionid = "A_CHIP_92C"; break; case VERSION_A_CHIP_88C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_A_CHIP_88C\n"); + versionid = "A_CHIP_88C"; break; default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Chip Version ID: Unknown. Bug?\n"); + versionid = "Unknown. Bug?"; break; } + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + "Chip Version ID: %s\n", versionid); + switch (version & 0x3) { case CHIP_88C: rtlphy->rf_type = RF_1T1R; diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c index 71c7aca0b43..060ed5fec69 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c @@ -57,6 +57,7 @@ void rtl92c_read_chip_version(struct ieee80211_hw *hw) struct rtl_phy *rtlphy = &(rtlpriv->phy); struct rtl_hal *rtlhal = rtl_hal(rtlpriv); enum version_8192c chip_version = VERSION_UNKNOWN; + const char *versionid; u32 value32; value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG); @@ -87,62 +88,51 @@ void rtl92c_read_chip_version(struct ieee80211_hw *hw) pr_info("Chip version 0x%x\n", chip_version); switch (rtlhal->version) { case VERSION_NORMAL_TSMC_CHIP_92C_1T2R: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_B_CHIP_92C\n"); + versionid = "NORMAL_B_CHIP_92C"; break; case VERSION_NORMAL_TSMC_CHIP_92C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_NORMAL_TSMC_CHIP_92C\n"); + versionid = "NORMAL_TSMC_CHIP_92C"; break; case VERSION_NORMAL_TSMC_CHIP_88C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_NORMAL_TSMC_CHIP_88C\n"); + versionid = "NORMAL_TSMC_CHIP_88C"; break; case VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_NORMAL_UMC_CHIP_i92C_1T2R_A_CUT\n"); + versionid = "NORMAL_UMC_CHIP_i92C_1T2R_A_CUT"; break; case VERSION_NORMAL_UMC_CHIP_92C_A_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_NORMAL_UMC_CHIP_92C_A_CUT\n"); + versionid = "NORMAL_UMC_CHIP_92C_A_CUT"; break; case VERSION_NORMAL_UMC_CHIP_88C_A_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_NORMAL_UMC_CHIP_88C_A_CUT\n"); + versionid = "NORMAL_UMC_CHIP_88C_A_CUT"; break; case VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT\n"); + versionid = "NORMAL_UMC_CHIP_92C_1T2R_B_CUT"; break; case VERSION_NORMAL_UMC_CHIP_92C_B_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_NORMAL_UMC_CHIP_92C_B_CUT\n"); + versionid = "NORMAL_UMC_CHIP_92C_B_CUT"; break; case VERSION_NORMAL_UMC_CHIP_88C_B_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_NORMAL_UMC_CHIP_88C_B_CUT\n"); + versionid = "NORMAL_UMC_CHIP_88C_B_CUT"; break; case VERSION_NORMA_UMC_CHIP_8723_1T1R_A_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_NORMA_UMC_CHIP_8723_1T1R_A_CUT\n"); + versionid = "NORMAL_UMC_CHIP_8723_1T1R_A_CUT"; break; case VERSION_NORMA_UMC_CHIP_8723_1T1R_B_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_NORMA_UMC_CHIP_8723_1T1R_B_CUT\n"); + versionid = "NORMAL_UMC_CHIP_8723_1T1R_B_CUT"; break; case VERSION_TEST_CHIP_92C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_TEST_CHIP_92C\n"); + versionid = "TEST_CHIP_92C"; break; case VERSION_TEST_CHIP_88C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_TEST_CHIP_88C\n"); + versionid = "TEST_CHIP_88C"; break; default: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: ???????????????\n"); + versionid = "UNKNOWN"; break; } + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + "Chip Version ID: %s\n", versionid); + if (IS_92C_SERIAL(rtlhal->version)) rtlphy->rf_type = (IS_92C_1T2R(rtlhal->version)) ? RF_1T2R : RF_2T2R; -- cgit v1.2.3-70-g09d2 From 017664fe8e11ec93dfe3faca5b7ff21071011e6a Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 6 Jan 2012 13:16:27 -0800 Subject: iwlwifi: don't process the info from uCode if does not has ownership When enable the testmode from user space and working with uCode, driver does not own the uCode and should not process the notifications or pkts from uCode Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index b22b2976f89..eda95ae88ef 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -1172,20 +1172,22 @@ int iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, wake_up_all(&priv->shrd->notif_waitq); } - if (priv->pre_rx_handler) + if (priv->pre_rx_handler && + priv->shrd->ucode_owner == IWL_OWNERSHIP_TM) priv->pre_rx_handler(priv, rxb); - - /* Based on type of command response or notification, - * handle those that need handling via function in - * rx_handlers table. See iwl_setup_rx_handlers() */ - if (priv->rx_handlers[pkt->hdr.cmd]) { - priv->rx_handlers_stats[pkt->hdr.cmd]++; - err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd); - } else { - /* No handling needed */ - IWL_DEBUG_RX(priv, - "No handler needed for %s, 0x%02x\n", - get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); + else { + /* Based on type of command response or notification, + * handle those that need handling via function in + * rx_handlers table. See iwl_setup_rx_handlers() */ + if (priv->rx_handlers[pkt->hdr.cmd]) { + priv->rx_handlers_stats[pkt->hdr.cmd]++; + err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd); + } else { + /* No handling needed */ + IWL_DEBUG_RX(priv, + "No handler needed for %s, 0x%02x\n", + get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); + } } return err; } -- cgit v1.2.3-70-g09d2 From 2da424b0773cea3db47e1e81db71eeebde8269d4 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 6 Jan 2012 13:16:28 -0800 Subject: iwlwifi: Sanity check for sta_id On my testing, I saw some strange behavior [ 421.739708] iwlwifi 0000:01:00.0: ACTIVATE a non DRIVER active station id 148 addr 00:00:00:00:00:00 [ 421.739719] iwlwifi 0000:01:00.0: iwl_sta_ucode_activate Added STA id 148 addr 00:00:00:00:00:00 to uCode not sure how it happen, but adding the sanity check to prevent memory corruption Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 7353826095f..8d4353a4256 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -35,9 +35,12 @@ #include "iwl-trans.h" /* priv->shrd->sta_lock must be held */ -static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) +static int iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) { - + if (sta_id >= IWLAGN_STATION_COUNT) { + IWL_ERR(priv, "invalid sta_id %u", sta_id); + return -EINVAL; + } if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) IWL_ERR(priv, "ACTIVATE a non DRIVER active station id %u " "addr %pM\n", @@ -53,6 +56,7 @@ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) IWL_DEBUG_ASSOC(priv, "Added STA id %u addr %pM to uCode\n", sta_id, priv->stations[sta_id].sta.sta.addr); } + return 0; } static int iwl_process_add_sta_resp(struct iwl_priv *priv, @@ -77,8 +81,7 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv, switch (pkt->u.add_sta.status) { case ADD_STA_SUCCESS_MSK: IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n"); - iwl_sta_ucode_activate(priv, sta_id); - ret = 0; + ret = iwl_sta_ucode_activate(priv, sta_id); break; case ADD_STA_NO_ROOM_IN_TABLE: IWL_ERR(priv, "Adding station %d failed, no room in table.\n", -- cgit v1.2.3-70-g09d2 From 102f097f1937db41f59674caca0a1e38c963baba Mon Sep 17 00:00:00 2001 From: Kenny Hsu Date: Fri, 6 Jan 2012 13:16:29 -0800 Subject: iwlwifi: update testmode command of direct register access In order to make sure the testcommand function of direct register access can be performed even NIC is asleep, replace corresponding handler iwl_read32 and iwl_write32 by using iwl_direct_read32 and iwl_direct_write32. Signed-off-by: Kenny Hsu Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-testmode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index 4a5cddd2d56..2fc20675dc7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -299,7 +299,7 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb) switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32: - val32 = iwl_read32(bus(priv), ofs); + val32 = iwl_read_direct32(bus(priv), ofs); IWL_INFO(priv, "32bit value to read 0x%x\n", val32); skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); @@ -321,7 +321,7 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb) } else { val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]); IWL_INFO(priv, "32bit value to write 0x%x\n", val32); - iwl_write32(bus(priv), ofs, val32); + iwl_write_direct32(bus(priv), ofs, val32); } break; case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8: -- cgit v1.2.3-70-g09d2 From b07f08a56524cdc49001b1467743acc3c5b78962 Mon Sep 17 00:00:00 2001 From: Kenny Hsu Date: Fri, 6 Jan 2012 13:16:30 -0800 Subject: iwlwifi: enhance testmode command sram_read This patch enables SRAM read function to support entire target memory. Signed-off-by: Kenny Hsu Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-testmode.c | 7 +++---- drivers/net/wireless/iwlwifi/iwl-testmode.h | 3 +++ 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index 2fc20675dc7..58575fdc450 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -733,7 +733,7 @@ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb) static int iwl_testmode_sram(struct ieee80211_hw *hw, struct nlattr **tb) { struct iwl_priv *priv = hw->priv; - u32 base, ofs, size, maxsize; + u32 ofs, size, maxsize; if (priv->testmode_sram.sram_readed) return -EBUSY; @@ -765,7 +765,7 @@ static int iwl_testmode_sram(struct ieee80211_hw *hw, struct nlattr **tb) IWL_DEBUG_INFO(priv, "Error, unsupported uCode type\n"); return -ENOSYS; } - if ((ofs + size) > maxsize) { + if ((ofs + size) > (maxsize + SRAM_DATA_SEG_OFFSET)) { IWL_DEBUG_INFO(priv, "Invalid offset/size: out of range\n"); return -EINVAL; } @@ -776,8 +776,7 @@ static int iwl_testmode_sram(struct ieee80211_hw *hw, struct nlattr **tb) IWL_DEBUG_INFO(priv, "Error allocating memory\n"); return -ENOMEM; } - base = 0x800000; - _iwl_read_targ_mem_words(bus(priv), base + ofs, + _iwl_read_targ_mem_words(bus(priv), ofs, priv->testmode_sram.buff_addr, priv->testmode_sram.buff_size / 4); priv->testmode_sram.num_chunks = diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h index 26138f11034..9c6a67ab5c3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h @@ -271,4 +271,7 @@ enum iwl_tm_attr_t { /* Maximum data size of each dump it packet */ #define DUMP_CHUNK_SIZE (PAGE_SIZE - 1024) +/* Address offset of data segment in SRAM */ +#define SRAM_DATA_SEG_OFFSET 0x800000 + #endif -- cgit v1.2.3-70-g09d2 From 907781b5c46a1bec51548af2135903017b546924 Mon Sep 17 00:00:00 2001 From: Kenny Hsu Date: Fri, 6 Jan 2012 13:16:31 -0800 Subject: iwlwifi: update error dump in testmode command sram_read The error message will be show up by using IWL_ERR insteads of IWl_DEBUG_INFO. Signed-off-by: Kenny Hsu Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-testmode.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index 58575fdc450..b56cd900805 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -759,21 +759,21 @@ static int iwl_testmode_sram(struct ieee80211_hw *hw, struct nlattr **tb) maxsize = trans(priv)->ucode_wowlan.data.len; break; case IWL_UCODE_NONE: - IWL_DEBUG_INFO(priv, "Error, uCode does not been loaded\n"); + IWL_ERR(priv, "Error, uCode does not been loaded\n"); return -ENOSYS; default: - IWL_DEBUG_INFO(priv, "Error, unsupported uCode type\n"); + IWL_ERR(priv, "Error, unsupported uCode type\n"); return -ENOSYS; } if ((ofs + size) > (maxsize + SRAM_DATA_SEG_OFFSET)) { - IWL_DEBUG_INFO(priv, "Invalid offset/size: out of range\n"); + IWL_ERR(priv, "Invalid offset/size: out of range\n"); return -EINVAL; } priv->testmode_sram.buff_size = (size / 4) * 4; priv->testmode_sram.buff_addr = kmalloc(priv->testmode_sram.buff_size, GFP_KERNEL); if (priv->testmode_sram.buff_addr == NULL) { - IWL_DEBUG_INFO(priv, "Error allocating memory\n"); + IWL_ERR(priv, "Error allocating memory\n"); return -ENOMEM; } _iwl_read_targ_mem_words(bus(priv), ofs, -- cgit v1.2.3-70-g09d2 From 668bd6a81bd6a3e0c10144201c6f58097de220bf Mon Sep 17 00:00:00 2001 From: Kenny Hsu Date: Fri, 6 Jan 2012 13:16:32 -0800 Subject: iwlwifi: add testmode cmd IWL_TM_CMD_APP2DEV_GET_FW_INFO Add new testmode command IWL_TM_CMD_APP2DEV_GET_FW_INFO for reporting the following information of existing loaded uCode image. + uCode type + Instruction section size + Data section size Signed-off-by: Kenny Hsu Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-testmode.c | 41 ++++++++++++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-testmode.h | 19 +++++++++++-- 2 files changed, 57 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index b56cd900805..7684c0e2f21 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -115,6 +115,9 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { [IWL_TM_ATTR_FW_VERSION] = { .type = NLA_U32, }, [IWL_TM_ATTR_DEVICE_ID] = { .type = NLA_U32, }, + [IWL_TM_ATTR_FW_TYPE] = { .type = NLA_U32, }, + [IWL_TM_ATTR_FW_INST_SIZE] = { .type = NLA_U32, }, + [IWL_TM_ATTR_FW_DATA_SIZE] = { .type = NLA_U32, }, }; /* @@ -422,7 +425,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) struct sk_buff *skb; unsigned char *rsp_data_ptr = NULL; int status = 0, rsp_data_len = 0; - u32 devid; + u32 devid, inst_size = 0, data_size = 0; switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { case IWL_TM_CMD_APP2DEV_GET_DEVICENAME: @@ -548,6 +551,41 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) "Error sending msg : %d\n", status); break; + case IWL_TM_CMD_APP2DEV_GET_FW_INFO: + skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20 + 8); + if (!skb) { + IWL_DEBUG_INFO(priv, "Error allocating memory\n"); + return -ENOMEM; + } + switch (priv->shrd->ucode_type) { + case IWL_UCODE_REGULAR: + inst_size = trans(priv)->ucode_rt.code.len; + data_size = trans(priv)->ucode_rt.data.len; + break; + case IWL_UCODE_INIT: + inst_size = trans(priv)->ucode_init.code.len; + data_size = trans(priv)->ucode_init.data.len; + break; + case IWL_UCODE_WOWLAN: + inst_size = trans(priv)->ucode_wowlan.code.len; + data_size = trans(priv)->ucode_wowlan.data.len; + break; + case IWL_UCODE_NONE: + IWL_DEBUG_INFO(priv, "The uCode has not been loaded\n"); + break; + default: + IWL_DEBUG_INFO(priv, "Unsupported uCode type\n"); + break; + } + NLA_PUT_U32(skb, IWL_TM_ATTR_FW_TYPE, priv->shrd->ucode_type); + NLA_PUT_U32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size); + NLA_PUT_U32(skb, IWL_TM_ATTR_FW_DATA_SIZE, data_size); + status = cfg80211_testmode_reply(skb); + if (status < 0) + IWL_DEBUG_INFO(priv, + "Error sending msg : %d\n", status); + break; + default: IWL_DEBUG_INFO(priv, "Unknown testmode driver command ID\n"); return -ENOSYS; @@ -881,6 +919,7 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: case IWL_TM_CMD_APP2DEV_GET_FW_VERSION: case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: + case IWL_TM_CMD_APP2DEV_GET_FW_INFO: IWL_DEBUG_INFO(priv, "testmode cmd to driver\n"); result = iwl_testmode_driver(hw, tb); break; diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h index 9c6a67ab5c3..cb0cf35f91b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h @@ -120,6 +120,8 @@ * @IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: load Weak On Wireless LAN uCode image * @IWL_TM_CMD_APP2DEV_GET_FW_VERSION: retrieve uCode version * @IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: retrieve ID information in device + * @IWL_TM_CMD_APP2DEV_GET_FW_INFO: + * retrieve informration of existing loaded uCode image * */ enum iwl_tm_cmd_t { @@ -147,7 +149,8 @@ enum iwl_tm_cmd_t { IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW = 22, IWL_TM_CMD_APP2DEV_GET_FW_VERSION = 23, IWL_TM_CMD_APP2DEV_GET_DEVICE_ID = 24, - IWL_TM_CMD_MAX = 25, + IWL_TM_CMD_APP2DEV_GET_FW_INFO = 25, + IWL_TM_CMD_MAX = 26, }; /* @@ -237,6 +240,15 @@ enum iwl_tm_cmd_t { * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_DEVICE_ID, * IWL_TM_ATTR_DEVICE_ID for the device ID information * + * @IWL_TM_ATTR_FW_TYPE: + * @IWL_TM_ATTR_FW_INST_SIZE: + * @IWL_TM_ATTR_FW_DATA_SIZE: + * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_FW_INFO, + * The mandatory fields are: + * IWL_TM_ATTR_FW_TYPE for the uCode type (INIT/RUNTIME/...) + * IWL_TM_ATTR_FW_INST_SIZE for the size of instruction section + * IWL_TM_ATTR_FW_DATA_SIZE for the size of data section + * */ enum iwl_tm_attr_t { IWL_TM_ATTR_NOT_APPLICABLE = 0, @@ -259,7 +271,10 @@ enum iwl_tm_attr_t { IWL_TM_ATTR_SRAM_DUMP = 17, IWL_TM_ATTR_FW_VERSION = 18, IWL_TM_ATTR_DEVICE_ID = 19, - IWL_TM_ATTR_MAX = 20, + IWL_TM_ATTR_FW_TYPE = 20, + IWL_TM_ATTR_FW_INST_SIZE = 21, + IWL_TM_ATTR_FW_DATA_SIZE = 22, + IWL_TM_ATTR_MAX = 23, }; /* uCode trace buffer */ -- cgit v1.2.3-70-g09d2 From fb4961dbc27d40cdbed297aa9bd74fa4a0e2ba6c Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 6 Jan 2012 13:16:33 -0800 Subject: iwlwifi: update Copyright Update Copyright to 2012 Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-2000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-5000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-6000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-calib.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-agn-calib.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-agn-hw.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-rs.h | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-tt.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-tt.h | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-bus.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-cfg.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-commands.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-core.c | 2 +- drivers/net/wireless/iwlwifi/iwl-core.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-csr.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-debug.h | 2 +- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 2 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 +- drivers/net/wireless/iwlwifi/iwl-devtrace.c | 2 +- drivers/net/wireless/iwlwifi/iwl-devtrace.h | 2 +- drivers/net/wireless/iwlwifi/iwl-eeprom.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-eeprom.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-fh.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-io.c | 2 +- drivers/net/wireless/iwlwifi/iwl-io.h | 2 +- drivers/net/wireless/iwlwifi/iwl-led.c | 2 +- drivers/net/wireless/iwlwifi/iwl-led.h | 2 +- drivers/net/wireless/iwlwifi/iwl-mac80211.c | 2 +- drivers/net/wireless/iwlwifi/iwl-pci.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-power.c | 2 +- drivers/net/wireless/iwlwifi/iwl-power.h | 2 +- drivers/net/wireless/iwlwifi/iwl-prph.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-scan.c | 2 +- drivers/net/wireless/iwlwifi/iwl-shared.h | 6 +++--- drivers/net/wireless/iwlwifi/iwl-testmode.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-testmode.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-trans.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-trans.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-ucode.c | 2 +- drivers/net/wireless/iwlwifi/iwl-wifi.h | 4 ++-- 53 files changed, 75 insertions(+), 75 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 1ef7bfc2ab2..cc04cce1156 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 094693328db..00db092d8cd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index b3a365fea7b..47fd98b3652 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 54b753399e6..ab62c018fcd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 50ff849c9f6..6aa00982786 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h index 10275ce92bd..9ed6683314a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h index 123ef5e129d..d0ec0abd3c8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 64cf439035c..a8f7689aaac 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 334b5ae8fdd..b9ba404d15c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h index 6675b3c816d..203b1c13c49 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index eda95ae88ef..f127f913e5a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portionhelp of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 1c665941662..8ca9570ec36 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 8d4353a4256..d6aab00272b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c index b0dff7a753a..56c6def015a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h b/drivers/net/wireless/iwlwifi/iwl-agn-tt.h index 7282a23e8f1..86bbf47501c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index c664c272655..a8c6880af34 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b5c7c5f0a75..7321e7d3140 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index f84fb3c5356..39cbe1a1577 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-bus.h b/drivers/net/wireless/iwlwifi/iwl-bus.h index 940d5038b39..941b9cb2344 100644 --- a/drivers/net/wireless/iwlwifi/iwl-bus.h +++ b/drivers/net/wireless/iwlwifi/iwl-bus.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-cfg.h b/drivers/net/wireless/iwlwifi/iwl-cfg.h index e1d78257e4a..957bc00cdaf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-cfg.h +++ b/drivers/net/wireless/iwlwifi/iwl-cfg.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 265de39d394..b4779c25a4b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 7bcfa781e0b..7d6eef96454 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 7bf76ab94dd..63f29111da1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index fbc3095c7b4..5f96ce105f0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index f8fc2393dd4..6f7612781e0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project. * diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 04a3343f461..f837f32bb71 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index e54a4d11e58..4579d61da25 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c index 2a2c8de64a0..91f45e71e0a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2009 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 9b212a8f30b..4d892211ce4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2009 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index c1eda9724f4..e27d9f55267 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 9fa937ec35e..13f2d3928ef 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index 5bede9d7f95..90208094b8e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index d57ea6484bb..83fdff38115 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project. * diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index aae2eeb331a..427d065435c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project. * diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 14dcbfcdc0f..eca79087afb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h index 2550b3c7dcb..b02a853103d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.h +++ b/drivers/net/wireless/iwlwifi/iwl-led.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index f980e574e1f..965d0475aff 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index fb30ea7ca96..03702a2e913 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 2b188a6025b..c7394ef2e49 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h index 5f7b720cf1a..07a19fce5fd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.h +++ b/drivers/net/wireless/iwlwifi/iwl-power.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index bebdd828f32..a4d11016c3b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index a6454726737..2aea20bf0f1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index dc55cc4a810..e406d49f418 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -102,7 +102,7 @@ struct iwl_trans_ops; #define DRV_NAME "iwlwifi" #define IWLWIFI_VERSION "in-tree:" -#define DRV_COPYRIGHT "Copyright(c) 2003-2011 Intel Corporation" +#define DRV_COPYRIGHT "Copyright(c) 2003-2012 Intel Corporation" #define DRV_AUTHOR "" extern struct iwl_mod_params iwlagn_mod_params; diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index 7684c0e2f21..a56a77b8f92 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h index cb0cf35f91b..185b69ef753 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index f6debf91d7b..0ac9b4d3027 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 752493f0040..848c598bfad 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index bd29568177e..30814b55705 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 67d6e324e26..5e6af4ba965 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c index 1b20c4fb791..506c062343b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index e6bf3f55477..42a9f303f54 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 36a1b5b2585..2edf0ef65a5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-wifi.h b/drivers/net/wireless/iwlwifi/iwl-wifi.h index 18501101a53..7e6eb20823c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-wifi.h +++ b/drivers/net/wireless/iwlwifi/iwl-wifi.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without -- cgit v1.2.3-70-g09d2 From 76a92be537f1c8c259e393632301446257ca3ea9 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 7 Jan 2012 20:46:40 -0600 Subject: rtlwifi: rtl8192c_common: rtl8192de: Check for allocation failures In https://bugzilla.redhat.com/show_bug.cgi?id=771656, a kernel bug was triggered due to a failed skb allocation that was not checked. This event lead to an audit of all memory allocations in the complete rtlwifi family of drivers. This patch fixes the rest. Signed-off-by: Larry Finger Cc: Stable Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/pci.c | 2 ++ drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | 2 ++ drivers/net/wireless/rtlwifi/rtl8192de/fw.c | 14 +++++++++----- drivers/net/wireless/rtlwifi/usb.c | 12 +++++++----- 4 files changed, 20 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 3c4ae5d9de4..8758b3db072 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -652,6 +652,8 @@ static void _rtl_receive_one(struct ieee80211_hw *hw, struct sk_buff *skb, return; uskb = dev_alloc_skb(skb->len + 128); + if (!uskb) + return; /* exit if allocation failed */ memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status, sizeof(rx_status)); pdata = (u8 *)skb_put(uskb, skb->len); memcpy(pdata, skb->data, skb->len); diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index 1eae3baae51..e9e9c26d496 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c @@ -785,6 +785,8 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished) skb = dev_alloc_skb(totalpacketlen); + if (!skb) + return; memcpy((u8 *) skb_put(skb, totalpacketlen), &reserved_page_packet, totalpacketlen); diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c index 94f5b7dd06e..da58ca4966c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c @@ -756,12 +756,16 @@ void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished) "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL", u1RsvdPageLoc, 3); skb = dev_alloc_skb(totalpacketlen); - memcpy((u8 *) skb_put(skb, totalpacketlen), &reserved_page_packet, - totalpacketlen); - rtstatus = _rtl92d_cmd_send_packet(hw, skb); + if (!skb) { + dlok = false; + } else { + memcpy((u8 *) skb_put(skb, totalpacketlen), + &reserved_page_packet, totalpacketlen); + rtstatus = _rtl92d_cmd_send_packet(hw, skb); - if (rtstatus) - dlok = true; + if (rtstatus) + dlok = true; + } if (dlok) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Set RSVD page location to Fw\n"); diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index 6ae1b212ad9..4db06f6f908 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -520,12 +520,14 @@ static void _rtl_usb_rx_process_noagg(struct ieee80211_hw *hw, u8 *pdata; uskb = dev_alloc_skb(skb->len + 128); - memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status, - sizeof(rx_status)); - pdata = (u8 *)skb_put(uskb, skb->len); - memcpy(pdata, skb->data, skb->len); + if (uskb) { /* drop packet on allocation failure */ + memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status, + sizeof(rx_status)); + pdata = (u8 *)skb_put(uskb, skb->len); + memcpy(pdata, skb->data, skb->len); + ieee80211_rx_irqsafe(hw, uskb); + } dev_kfree_skb_any(skb); - ieee80211_rx_irqsafe(hw, uskb); } else { dev_kfree_skb_any(skb); } -- cgit v1.2.3-70-g09d2 From 9ef11f7b34c0896a1d476dd8cb9a18671aaab892 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 7 Jan 2012 20:46:41 -0600 Subject: rtl8192cu: Remove dead code never selected The original driver contained some conditional code that was not selected, but was not deleted in case it would be used later. That code can now be removed. Reported-by: Joe Perches Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 170 ---------------------------- 1 file changed, 170 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index ae38bc52a71..b8af2cf4db2 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -339,144 +339,8 @@ static void _rtl92cu_read_board_type(struct ieee80211_hw *hw, u8 *contents) if (IS_HIGHT_PA(rtlefuse->board_type)) rtlefuse->external_pa = 1; pr_info("Board Type %x\n", rtlefuse->board_type); - -#ifdef CONFIG_ANTENNA_DIVERSITY - /* Antenna Diversity setting. */ - if (registry_par->antdiv_cfg == 2) /* 2: From Efuse */ - rtl_efuse->antenna_cfg = (contents[EEPROM_RF_OPT1]&0x18)>>3; - else - rtl_efuse->antenna_cfg = registry_par->antdiv_cfg; /* 0:OFF, */ - - pr_info("Antenna Config %x\n", rtl_efuse->antenna_cfg); -#endif } -#ifdef CONFIG_BT_COEXIST -static void _update_bt_param(_adapter *padapter) -{ - struct btcoexist_priv *pbtpriv = &(padapter->halpriv.bt_coexist); - struct registry_priv *registry_par = &padapter->registrypriv; - if (2 != registry_par->bt_iso) { - /* 0:Low, 1:High, 2:From Efuse */ - pbtpriv->BT_Ant_isolation = registry_par->bt_iso; - } - if (registry_par->bt_sco == 1) { - /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter, 4.Busy, - * 5.OtherBusy */ - pbtpriv->BT_Service = BT_OtherAction; - } else if (registry_par->bt_sco == 2) { - pbtpriv->BT_Service = BT_SCO; - } else if (registry_par->bt_sco == 4) { - pbtpriv->BT_Service = BT_Busy; - } else if (registry_par->bt_sco == 5) { - pbtpriv->BT_Service = BT_OtherBusy; - } else { - pbtpriv->BT_Service = BT_Idle; - } - pbtpriv->BT_Ampdu = registry_par->bt_ampdu; - pbtpriv->bCOBT = _TRUE; - pbtpriv->BtEdcaUL = 0; - pbtpriv->BtEdcaDL = 0; - pbtpriv->BtRssiState = 0xff; - pbtpriv->bInitSet = _FALSE; - pbtpriv->bBTBusyTraffic = _FALSE; - pbtpriv->bBTTrafficModeSet = _FALSE; - pbtpriv->bBTNonTrafficModeSet = _FALSE; - pbtpriv->CurrentState = 0; - pbtpriv->PreviousState = 0; - pr_info("BT Coexistance = %s\n", - (pbtpriv->BT_Coexist == _TRUE) ? "enable" : "disable"); - if (pbtpriv->BT_Coexist) { - if (pbtpriv->BT_Ant_Num == Ant_x2) - pr_info("BlueTooth BT_Ant_Num = Antx2\n"); - else if (pbtpriv->BT_Ant_Num == Ant_x1) - pr_info("BlueTooth BT_Ant_Num = Antx1\n"); - switch (pbtpriv->BT_CoexistType) { - case BT_2Wire: - pr_info("BlueTooth BT_CoexistType = BT_2Wire\n"); - break; - case BT_ISSC_3Wire: - pr_info("BlueTooth BT_CoexistType = BT_ISSC_3Wire\n"); - break; - case BT_Accel: - pr_info("BlueTooth BT_CoexistType = BT_Accel\n"); - break; - case BT_CSR_BC4: - pr_info("BlueTooth BT_CoexistType = BT_CSR_BC4\n"); - break; - case BT_CSR_BC8: - pr_info("BlueTooth BT_CoexistType = BT_CSR_BC8\n"); - break; - case BT_RTL8756: - pr_info("BlueTooth BT_CoexistType = BT_RTL8756\n"); - break; - default: - pr_info("BlueTooth BT_CoexistType = Unknown\n"); - break; - } - pr_info("BlueTooth BT_Ant_isolation = %d\n", - pbtpriv->BT_Ant_isolation); - switch (pbtpriv->BT_Service) { - case BT_OtherAction: - pr_info("BlueTooth BT_Service = BT_OtherAction\n"); - break; - case BT_SCO: - pr_info("BlueTooth BT_Service = BT_SCO\n"); - break; - case BT_Busy: - pr_info("BlueTooth BT_Service = BT_Busy\n"); - break; - case BT_OtherBusy: - pr_info("BlueTooth BT_Service = BT_OtherBusy\n"); - break; - default: - pr_info("BlueTooth BT_Service = BT_Idle\n"); - break; - } - pr_info("BT_RadioSharedType = 0x%x\n", - pbtpriv->BT_RadioSharedType); - } -} - -#define GET_BT_COEXIST(priv) (&priv->bt_coexist) - -static void _rtl92cu_read_bluetooth_coexistInfo(struct ieee80211_hw *hw, - u8 *contents, - bool bautoloadfailed); -{ - HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); - bool isNormal = IS_NORMAL_CHIP(pHalData->VersionID); - struct btcoexist_priv *pbtpriv = &pHalData->bt_coexist; - u8 rf_opt4; - - _rtw_memset(pbtpriv, 0, sizeof(struct btcoexist_priv)); - if (AutoloadFail) { - pbtpriv->BT_Coexist = _FALSE; - pbtpriv->BT_CoexistType = BT_2Wire; - pbtpriv->BT_Ant_Num = Ant_x2; - pbtpriv->BT_Ant_isolation = 0; - pbtpriv->BT_RadioSharedType = BT_Radio_Shared; - return; - } - if (isNormal) { - if (pHalData->BoardType == BOARD_USB_COMBO) - pbtpriv->BT_Coexist = _TRUE; - else - pbtpriv->BT_Coexist = ((PROMContent[EEPROM_RF_OPT3] & - 0x20) >> 5); /* bit[5] */ - rf_opt4 = PROMContent[EEPROM_RF_OPT4]; - pbtpriv->BT_CoexistType = ((rf_opt4&0xe)>>1); /* bit [3:1] */ - pbtpriv->BT_Ant_Num = (rf_opt4&0x1); /* bit [0] */ - pbtpriv->BT_Ant_isolation = ((rf_opt4&0x10)>>4); /* bit [4] */ - pbtpriv->BT_RadioSharedType = ((rf_opt4&0x20)>>5); /* bit [5] */ - } else { - pbtpriv->BT_Coexist = (PROMContent[EEPROM_RF_OPT4] >> 4) ? - _TRUE : _FALSE; - } - _update_bt_param(Adapter); -} -#endif - static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -552,10 +416,6 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw) } } _rtl92cu_read_board_type(hw, hwinfo); -#ifdef CONFIG_BT_COEXIST - _rtl92cu_read_bluetooth_coexistInfo(hw, hwinfo, - rtlefuse->autoload_failflag); -#endif } static void _rtl92cu_hal_customized_behavior(struct ieee80211_hw *hw) @@ -1107,34 +967,6 @@ static void _InitPABias(struct ieee80211_hw *hw) } } -static void _InitAntenna_Selection(struct ieee80211_hw *hw) -{ -#ifdef CONFIG_ANTENNA_DIVERSITY - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - if (pHalData->AntDivCfg == 0) - return; - - if (rtlphy->rf_type == RF_1T1R) { - rtl_write_dword(rtlpriv, REG_LEDCFG0, - rtl_read_dword(rtlpriv, - REG_LEDCFG0)|BIT(23)); - rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); - if (rtl_get_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300) == - Antenna_A) - pHalData->CurAntenna = Antenna_A; - else - pHalData->CurAntenna = Antenna_B; - } -#endif -} - -static void _dump_registers(struct ieee80211_hw *hw) -{ -} - static void _update_mac_setting(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -1205,10 +1037,8 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw) } _rtl92cu_hw_configure(hw); _InitPABias(hw); - _InitAntenna_Selection(hw); _update_mac_setting(hw); rtl92c_dm_init(hw); - _dump_registers(hw); return err; } -- cgit v1.2.3-70-g09d2 From a8d760668eebc98915383481cb3d9eaf74c2a615 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 7 Jan 2012 20:46:42 -0600 Subject: rtlwifi: Update copyright dates Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/base.c | 2 +- drivers/net/wireless/rtlwifi/base.h | 2 +- drivers/net/wireless/rtlwifi/cam.c | 2 +- drivers/net/wireless/rtlwifi/cam.h | 2 +- drivers/net/wireless/rtlwifi/core.c | 2 +- drivers/net/wireless/rtlwifi/core.h | 2 +- drivers/net/wireless/rtlwifi/debug.c | 2 +- drivers/net/wireless/rtlwifi/debug.h | 2 +- drivers/net/wireless/rtlwifi/efuse.c | 2 +- drivers/net/wireless/rtlwifi/efuse.h | 2 +- drivers/net/wireless/rtlwifi/pci.c | 2 +- drivers/net/wireless/rtlwifi/pci.h | 2 +- drivers/net/wireless/rtlwifi/ps.c | 2 +- drivers/net/wireless/rtlwifi/ps.h | 2 +- drivers/net/wireless/rtlwifi/rc.c | 2 +- drivers/net/wireless/rtlwifi/rc.h | 2 +- drivers/net/wireless/rtlwifi/regd.c | 2 +- drivers/net/wireless/rtlwifi/regd.h | 2 +- drivers/net/wireless/rtlwifi/usb.c | 2 +- drivers/net/wireless/rtlwifi/usb.h | 2 +- drivers/net/wireless/rtlwifi/wifi.h | 2 +- 21 files changed, 21 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index fa16b1d708f..6f80142580f 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h index f66b5757f6b..5a23a6d0f49 100644 --- a/drivers/net/wireless/rtlwifi/base.h +++ b/drivers/net/wireless/rtlwifi/base.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c index cbf5e3cdb44..8fd820d85ee 100644 --- a/drivers/net/wireless/rtlwifi/cam.c +++ b/drivers/net/wireless/rtlwifi/cam.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/cam.h b/drivers/net/wireless/rtlwifi/cam.h index c62da4eefc7..35e00086a52 100644 --- a/drivers/net/wireless/rtlwifi/cam.h +++ b/drivers/net/wireless/rtlwifi/cam.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index ab6a4068764..d6e37e6a1d5 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h index f02824a3b74..a45c3892e36 100644 --- a/drivers/net/wireless/rtlwifi/core.h +++ b/drivers/net/wireless/rtlwifi/core.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * Tmis program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/debug.c b/drivers/net/wireless/rtlwifi/debug.c index 1b5cb7153a5..67dcbcdfaa7 100644 --- a/drivers/net/wireless/rtlwifi/debug.c +++ b/drivers/net/wireless/rtlwifi/debug.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * Tmis program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h index fd5600c6942..07493d2957f 100644 --- a/drivers/net/wireless/rtlwifi/debug.h +++ b/drivers/net/wireless/rtlwifi/debug.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * Tmis program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c index a079a31b4ed..b24cbe6e16d 100644 --- a/drivers/net/wireless/rtlwifi/efuse.c +++ b/drivers/net/wireless/rtlwifi/efuse.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * Tmis program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/efuse.h b/drivers/net/wireless/rtlwifi/efuse.h index 164dabaa761..2bdea9a8699 100644 --- a/drivers/net/wireless/rtlwifi/efuse.h +++ b/drivers/net/wireless/rtlwifi/efuse.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 8758b3db072..4326fd1e319 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h index ebe0b42c051..99d81ede17b 100644 --- a/drivers/net/wireless/rtlwifi/pci.h +++ b/drivers/net/wireless/rtlwifi/pci.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index a36dc3d5e04..b151266ef9f 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/ps.h b/drivers/net/wireless/rtlwifi/ps.h index 84628e6041c..1357856998c 100644 --- a/drivers/net/wireless/rtlwifi/ps.h +++ b/drivers/net/wireless/rtlwifi/ps.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rc.c b/drivers/net/wireless/rtlwifi/rc.c index 4f560d6a386..c66f08a0524 100644 --- a/drivers/net/wireless/rtlwifi/rc.c +++ b/drivers/net/wireless/rtlwifi/rc.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rc.h b/drivers/net/wireless/rtlwifi/rc.h index 4afa2c20adc..4d617616061 100644 --- a/drivers/net/wireless/rtlwifi/rc.h +++ b/drivers/net/wireless/rtlwifi/rc.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/regd.c b/drivers/net/wireless/rtlwifi/regd.c index c263df21760..c1608cddc52 100644 --- a/drivers/net/wireless/rtlwifi/regd.c +++ b/drivers/net/wireless/rtlwifi/regd.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/regd.h b/drivers/net/wireless/rtlwifi/regd.h index d23118938fa..70ef2f418a4 100644 --- a/drivers/net/wireless/rtlwifi/regd.h +++ b/drivers/net/wireless/rtlwifi/regd.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index 4db06f6f908..78194e30fcd 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2011 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/usb.h b/drivers/net/wireless/rtlwifi/usb.h index d2a63fb3e1e..cdad7c2507e 100644 --- a/drivers/net/wireless/rtlwifi/usb.h +++ b/drivers/net/wireless/rtlwifi/usb.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2011 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index cdaf1429fa0..b2d98548500 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as -- cgit v1.2.3-70-g09d2 From fc6168563aeb26cbc9a9ba9dd168cfdabc6f3778 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 7 Jan 2012 20:46:43 -0600 Subject: rtl8192c_common: Update copyright dates Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192c/main.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index bf94cbfb4e3..cb5535cf3ae 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h index b9736d3e9a3..2178e376188 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index e9e9c26d496..75be221fde4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h index cec5a3a1cc5..780ea5b1e24 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/main.c b/drivers/net/wireless/rtlwifi/rtl8192c/main.c index 605ff191aeb..8ae65b57612 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/main.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/main.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c index 25bde968699..22e998dd2f3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h index 9a264c0d612..cec10d69649 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as -- cgit v1.2.3-70-g09d2 From 9003a4aba4b040be265ce8ed51f6fe437d369453 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 7 Jan 2012 20:46:44 -0600 Subject: rtl8192ce: Update copyright dates Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192ce/def.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/dm.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/dm.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/hw.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/led.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/led.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/phy.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/phy.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/reg.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/rf.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/rf.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/sw.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/table.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/table.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/trx.h | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h index 9fc804d89d6..04c3aef8a4f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c index 6730e683aba..27b3af880d9 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h index 07dd9552e82..26747fa8600 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 971bd29ef9b..c5aced459cd 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h index 07dbe3e340a..52a3aea9b3d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c index 09758f48d3e..8283e9b2763 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h index 7dfccea2095..c5761066d38 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index 03ee82e05f2..c64daf25566 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h index be2c92adef3..d5e3b704f93 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h index ba5ff0411f0..43806d9d1e1 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c index 5ef960499a4..69d720dd9c3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h index 39ff0368598..6c8d56efcea 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index 4a224dbc693..7e59b689bff 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h index b7dc3263e43..d2367a5d0cf 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/table.c b/drivers/net/wireless/rtlwifi/rtl8192ce/table.c index ba938b91aa6..752f943a84a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/table.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/table.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/table.h b/drivers/net/wireless/rtlwifi/rtl8192ce/table.h index 3a6e8b6aeee..8b79161f71b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/table.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/table.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 46892cc1a08..37b13636a77 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h index c8977a50ca3..efb9ab27040 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as -- cgit v1.2.3-70-g09d2 From c1d6604d1e3357d734d209a04cc1f80af948364b Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 7 Jan 2012 20:46:45 -0600 Subject: rtl8192cu: Update copyright dates Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192cu/def.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/dm.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/dm.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/hw.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/led.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/led.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/mac.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/mac.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/phy.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/phy.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/reg.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/rf.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/rf.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/sw.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/table.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/table.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/trx.h | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/def.h b/drivers/net/wireless/rtlwifi/rtl8192cu/def.h index d097efb1e71..f916555e631 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/def.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/def.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c index c0016f3194e..6fd39eaf361 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h index 7f966c666b5..d947e7d350b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index b8af2cf4db2..edb52987f5e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h index 32f85cba106..f41a3aa4a26 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/led.c b/drivers/net/wireless/rtlwifi/rtl8192cu/led.c index 65fd0442462..75a2deb23af 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/led.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/led.h b/drivers/net/wireless/rtlwifi/rtl8192cu/led.h index decaee4d1eb..0f372278b7a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/led.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/led.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c index 060ed5fec69..d028f6f2199 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h index 626d88e88e2..bf53652e4ed 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c index e7ea2bae210..8ac3bcca4d4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h index ff81a61729d..42b06866048 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/reg.h b/drivers/net/wireless/rtlwifi/rtl8192cu/reg.h index 7f1be614c99..8b81465c629 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/reg.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c index e132cb30a30..780c0d98a83 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h index 500a2094b6b..090fd33a158 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index dee7aab4faa..aec8cae733a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h index 43b1177924a..a1310abd0d5 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/table.c b/drivers/net/wireless/rtlwifi/rtl8192cu/table.c index d57ef5e88a9..966be519edb 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/table.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/table.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/table.h b/drivers/net/wireless/rtlwifi/rtl8192cu/table.h index c3d5cd826cf..4b020e9e30b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/table.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/table.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index 7d5f79991f8..21bc827c5fa 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h index 53de5f66e24..332b06e78b0 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as -- cgit v1.2.3-70-g09d2 From 6a57b08e222f4e054a7e7160ef7426c5614c0cc0 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 7 Jan 2012 20:46:46 -0600 Subject: rtl8192de: Update copyright dates Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192de/def.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/dm.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/dm.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/fw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/fw.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/hw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/hw.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/led.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/led.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/phy.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/phy.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/reg.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/rf.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/rf.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/sw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/sw.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/table.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/table.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/trx.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/trx.h | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/def.h b/drivers/net/wireless/rtlwifi/rtl8192de/def.h index 94630477174..eafdf76ed64 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/def.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/def.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c index 32537c4faf9..181ed6fc90e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.h b/drivers/net/wireless/rtlwifi/rtl8192de/dm.h index 69354657f0f..91030ec8ac3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c index da58ca4966c..b59de75a364 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.h b/drivers/net/wireless/rtlwifi/rtl8192de/fw.h index 0c4d489eaa4..1ffacdda734 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c index d94ce371572..695bccb4375 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.h b/drivers/net/wireless/rtlwifi/rtl8192de/hw.h index ad44ffa520e..7c9f7a2f1e4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/led.c b/drivers/net/wireless/rtlwifi/rtl8192de/led.c index f2358f20b9c..76a57ae4af3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/led.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/led.h b/drivers/net/wireless/rtlwifi/rtl8192de/led.h index 57f4a3c583d..a29df30c302 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/led.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/led.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c index f27acc75494..9581a19c254 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.h b/drivers/net/wireless/rtlwifi/rtl8192de/phy.h index a52c824b41e..f074952bf25 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/reg.h b/drivers/net/wireless/rtlwifi/rtl8192de/reg.h index 131acc306fc..9bc46233107 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/reg.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c b/drivers/net/wireless/rtlwifi/rtl8192de/rf.c index 2e174f48946..ff34d2dd39b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/rf.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/rf.h b/drivers/net/wireless/rtlwifi/rtl8192de/rf.h index 74b9cfc39a8..0fe1a48593e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/rf.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c index 364aa402245..b8d7fe39e5a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.h b/drivers/net/wireless/rtlwifi/rtl8192de/sw.h index c95e47de134..0e6035b8fd8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/table.c b/drivers/net/wireless/rtlwifi/rtl8192de/table.c index bad7f9449ec..8ea6f528dfa 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/table.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/table.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/table.h b/drivers/net/wireless/rtlwifi/rtl8192de/table.h index 93f30ca62d8..8b724a86117 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/table.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/table.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c index e7c985b372f..a7f6126e2f8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.h b/drivers/net/wireless/rtlwifi/rtl8192de/trx.h index 4d55d0b6816..0dc736c2723 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as -- cgit v1.2.3-70-g09d2 From ca742cd9766ff519b0e927a9296e29541ee13c7b Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 7 Jan 2012 20:46:47 -0600 Subject: rtl8192se: Update copyright dates Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192se/def.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/dm.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/dm.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/fw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/fw.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/hw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/hw.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/led.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/led.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/phy.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/phy.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/reg.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/rf.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/rf.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/sw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/sw.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/table.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/table.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/trx.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/trx.h | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/def.h b/drivers/net/wireless/rtlwifi/rtl8192se/def.h index c6c044816d3..d1b0a1e1497 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/def.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/def.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c index 4a5e3a952a4..fbabae17259 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.h b/drivers/net/wireless/rtlwifi/rtl8192se/dm.h index 9051a556acc..e1b19a64176 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/dm.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c index 2a9699feee3..595ecd22ffa 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.h b/drivers/net/wireless/rtlwifi/rtl8192se/fw.h index 74cc503efe8..babe85d4b69 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/fw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index b03001b2328..625c9eb0a11 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.h b/drivers/net/wireless/rtlwifi/rtl8192se/hw.h index 6160a9bfe98..1886c2644a2 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/led.c b/drivers/net/wireless/rtlwifi/rtl8192se/led.c index 1a6b0caf084..ef4211bca58 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/led.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/led.h b/drivers/net/wireless/rtlwifi/rtl8192se/led.h index 8cce3870af3..2182dbeb5f3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/led.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/led.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c index e24dbb3a9ba..adfac569b67 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.h b/drivers/net/wireless/rtlwifi/rtl8192se/phy.h index 37e504af644..ac038777063 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/reg.h b/drivers/net/wireless/rtlwifi/rtl8192se/reg.h index 11f125c030c..84d1181795b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/reg.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c index 8966b731f7e..46be4cc8ba9 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.h b/drivers/net/wireless/rtlwifi/rtl8192se/rf.h index 3843baa1a87..8a29eb94ab1 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/rf.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c index 5795a542bdf..3bc0128deea 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.h b/drivers/net/wireless/rtlwifi/rtl8192se/sw.h index fc4eb285a0a..2eb88862ebe 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/table.c b/drivers/net/wireless/rtlwifi/rtl8192se/table.c index 154185b3969..f1a73f75127 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/table.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/table.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/table.h b/drivers/net/wireless/rtlwifi/rtl8192se/table.h index b4ed6d951eb..2feb73b71a4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/table.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/table.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Realtek Corporation. All rights reserved. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index 216a3e140de..2fd3d13b7ce 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.h b/drivers/net/wireless/rtlwifi/rtl8192se/trx.h index 05862c51b86..011e7b0695f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as -- cgit v1.2.3-70-g09d2 From 75ac9a28a0c6b818ba1aba874b6b3ae17241552c Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 9 Jan 2012 10:40:50 +0100 Subject: drivers/net/wireless/mwifiex/scan.c: convert GFP_KERNEL to GFP_ATOMIC The function is called with locks held and thus should not use GFP_KERNEL. The semantic patch that makes this report is available in scripts/coccinelle/locks/call_kern.cocci. More information about semantic patching is available at http://coccinelle.lip6.fr/ Signed-off-by: Julia Lawall Acked-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 6396d3318ea..98f1ca9cd6d 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -2001,7 +2001,7 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv) kfree(priv->curr_bcn_buf); priv->curr_bcn_buf = kmalloc(curr_bss->beacon_buf_size, - GFP_KERNEL); + GFP_ATOMIC); if (!priv->curr_bcn_buf) { dev_err(priv->adapter->dev, "failed to alloc curr_bcn_buf\n"); -- cgit v1.2.3-70-g09d2 From e2d75c136f8df4a4e28ece75c475a65b9292729a Mon Sep 17 00:00:00 2001 From: Nicolas Cavallari Date: Wed, 11 Jan 2012 16:44:50 +0100 Subject: carl9170: claim to support IBSS RSN. On carl9170, HW encryption is disabled on IBSS; the mac80211 software-based encryption is used instead. As mac80211 supports IBSS RSN (per-STA GTK), claim its support in the carl9170 PHY. Signed-off-by: Nicolas Cavallari Acked-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/main.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index db774212161..4dfb0290b43 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -1796,6 +1796,9 @@ void *carl9170_alloc(size_t priv_size) ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */ hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; + + /* As IBSS Encryption is software-based, IBSS RSN is supported. */ + hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; return ar; err_nomem: -- cgit v1.2.3-70-g09d2 From cebcab9e18725d8249f607af787ee92107a665b7 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Wed, 11 Jan 2012 14:39:32 -0600 Subject: bcma: Enable logging of SPROM offset The SPROM location has been relocated again for some devices. This patch will log the offset when CONFIG_BCMA_DEBUG has been selected. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/bcma/sprom.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c index cb835f026d9..e35134f724f 100644 --- a/drivers/bcma/sprom.c +++ b/drivers/bcma/sprom.c @@ -271,6 +271,7 @@ int bcma_sprom_get(struct bcma_bus *bus) * TODO: understand this condition and use it */ offset = (bus->chipinfo.id == 0x4331) ? BCMA_CC_SPROM : BCMA_CC_SPROM_PCIE6; + pr_debug("SPROM offset 0x%x\n", offset); bcma_sprom_read(bus, offset, sprom); if (bus->chipinfo.id == 0x4331) -- cgit v1.2.3-70-g09d2 From 9da9a3b29ba6a9a98e437f24576f13cbe259997b Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Wed, 11 Jan 2012 20:06:11 -0800 Subject: mwifiex: use bss_type and bss_num to retrieve priv Current implementation, for retrieving priv from adapter, uses bss_index. In multi interface environment supporting different types, bss_index may not be unique. Use bss_type along with bss_num to retrieve the priv. bss_index is removed with this change. Signed-off-by: Yogesh Ashok Powar Signed-off-by: Kiran Divekar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/11n_aggr.c | 3 ++- drivers/net/wireless/mwifiex/cfg80211.c | 1 - drivers/net/wireless/mwifiex/cmdevt.c | 3 ++- drivers/net/wireless/mwifiex/decl.h | 6 ++++-- drivers/net/wireless/mwifiex/init.c | 5 +++-- drivers/net/wireless/mwifiex/main.c | 23 ++++++----------------- drivers/net/wireless/mwifiex/main.h | 3 --- drivers/net/wireless/mwifiex/sta_rx.c | 6 ++++-- drivers/net/wireless/mwifiex/sta_tx.c | 3 ++- drivers/net/wireless/mwifiex/txrx.c | 6 ++++-- drivers/net/wireless/mwifiex/util.c | 3 ++- drivers/net/wireless/mwifiex/wmm.c | 3 ++- 12 files changed, 31 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c index 079e5532e68..ea6832dc667 100644 --- a/drivers/net/wireless/mwifiex/11n_aggr.c +++ b/drivers/net/wireless/mwifiex/11n_aggr.c @@ -182,7 +182,8 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, skb_reserve(skb_aggr, headroom + sizeof(struct txpd)); tx_info_aggr = MWIFIEX_SKB_TXCB(skb_aggr); - tx_info_aggr->bss_index = tx_info_src->bss_index; + tx_info_aggr->bss_type = tx_info_src->bss_type; + tx_info_aggr->bss_num = tx_info_src->bss_num; skb_aggr->priority = skb_src->priority; do { diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index c3b6c4652cd..36f67da8fa4 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1217,7 +1217,6 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II; priv->bss_priority = 0; priv->bss_role = MWIFIEX_BSS_ROLE_STA; - priv->bss_index = 0; priv->bss_num = 0; break; diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index 6e0a3eaecf7..6623db69e15 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -391,7 +391,8 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter) if (skb) { rx_info = MWIFIEX_SKB_RXCB(skb); - rx_info->bss_index = priv->bss_index; + rx_info->bss_num = priv->bss_num; + rx_info->bss_type = priv->bss_type; } if (eventcause != EVENT_PS_SLEEP && eventcause != EVENT_PS_AWAKE) { diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h index ae17ce02a3d..3735c775495 100644 --- a/drivers/net/wireless/mwifiex/decl.h +++ b/drivers/net/wireless/mwifiex/decl.h @@ -102,7 +102,8 @@ struct mwifiex_wait_queue { }; struct mwifiex_rxinfo { - u8 bss_index; + u8 bss_num; + u8 bss_type; struct sk_buff *parent; u8 use_count; }; @@ -110,7 +111,8 @@ struct mwifiex_rxinfo { struct mwifiex_txinfo { u32 status_code; u8 flags; - u8 bss_index; + u8 bss_num; + u8 bss_type; }; enum mwifiex_wmm_ac_e { diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index e05b417a3fa..e13b6d99171 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -526,8 +526,9 @@ static void mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv) cur = &adapter->bss_prio_tbl[i].bss_prio_cur; lock = &adapter->bss_prio_tbl[i].bss_prio_lock; dev_dbg(adapter->dev, "info: delete BSS priority table," - " index = %d, i = %d, head = %p, cur = %p\n", - priv->bss_index, i, head, *cur); + " bss_type = %d, bss_num = %d, i = %d," + " head = %p, cur = %p\n", + priv->bss_type, priv->bss_num, i, head, *cur); if (*cur) { spin_lock_irqsave(lock, flags); if (list_empty(head)) { diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 84be196188c..1a0775d19ad 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -424,8 +424,8 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) struct sk_buff *new_skb; struct mwifiex_txinfo *tx_info; - dev_dbg(priv->adapter->dev, "data: %lu BSS(%d): Data <= kernel\n", - jiffies, priv->bss_index); + dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n", + jiffies, priv->bss_type, priv->bss_num); if (priv->adapter->surprise_removed) { kfree_skb(skb); @@ -458,7 +458,8 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) } tx_info = MWIFIEX_SKB_TXCB(skb); - tx_info->bss_index = priv->bss_index; + tx_info->bss_num = priv->bss_num; + tx_info->bss_type = priv->bss_type; mwifiex_fill_buffer(skb); mwifiex_wmm_add_buf_txqueue(priv->adapter, skb); @@ -531,8 +532,8 @@ mwifiex_tx_timeout(struct net_device *dev) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); - dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_index=%d\n", - jiffies, priv->bss_index); + dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_type-num = %d-%d\n", + jiffies, priv->bss_type, priv->bss_num); mwifiex_set_trans_start(dev); priv->num_tx_timeout++; } @@ -604,18 +605,6 @@ int is_command_pending(struct mwifiex_adapter *adapter) return !is_cmd_pend_q_empty; } -/* - * This function returns the correct private structure pointer based - * upon the BSS number. - */ -struct mwifiex_private * -mwifiex_bss_index_to_priv(struct mwifiex_adapter *adapter, u8 bss_index) -{ - if (!adapter || (bss_index >= adapter->priv_num)) - return NULL; - return adapter->priv[bss_index]; -} - /* * This is the main work queue function. * diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 3186aa437f4..6712ea89ef7 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -352,7 +352,6 @@ struct mwifiex_private; struct mwifiex_private { struct mwifiex_adapter *adapter; - u8 bss_index; u8 bss_type; u8 bss_role; u8 bss_priority; @@ -884,8 +883,6 @@ mwifiex_netdev_get_priv(struct net_device *dev) return (struct mwifiex_private *) (*(unsigned long *) netdev_priv(dev)); } -struct mwifiex_private *mwifiex_bss_index_to_priv(struct mwifiex_adapter - *adapter, u8 bss_index); int mwifiex_init_shutdown_fw(struct mwifiex_private *priv, u32 func_init_shutdown); int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *, u8); diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c index 5e1ef7e5da4..d7a5d7616f2 100644 --- a/drivers/net/wireless/mwifiex/sta_rx.c +++ b/drivers/net/wireless/mwifiex/sta_rx.c @@ -43,7 +43,8 @@ int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter, { int ret; struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); - struct mwifiex_private *priv = adapter->priv[rx_info->bss_index]; + struct mwifiex_private *priv = mwifiex_get_priv_by_id(adapter, + rx_info->bss_num, rx_info->bss_type); struct rx_packet_hdr *rx_pkt_hdr; struct rxpd *local_rx_pd; int hdr_chop; @@ -124,7 +125,8 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter, struct rx_packet_hdr *rx_pkt_hdr; u8 ta[ETH_ALEN]; u16 rx_pkt_type; - struct mwifiex_private *priv = adapter->priv[rx_info->bss_index]; + struct mwifiex_private *priv = mwifiex_get_priv_by_id(adapter, + rx_info->bss_num, rx_info->bss_type); if (!priv) return -1; diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c index d97facd70e8..94d31a94620 100644 --- a/drivers/net/wireless/mwifiex/sta_tx.c +++ b/drivers/net/wireless/mwifiex/sta_tx.c @@ -136,7 +136,8 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags) return -1; tx_info = MWIFIEX_SKB_TXCB(skb); - tx_info->bss_index = priv->bss_index; + tx_info->bss_num = priv->bss_num; + tx_info->bss_type = priv->bss_type; skb_reserve(skb, sizeof(struct txpd) + INTF_HEADER_LEN); skb_push(skb, sizeof(struct txpd)); diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c index d9274a1b77a..9a6eacc9d6f 100644 --- a/drivers/net/wireless/mwifiex/txrx.c +++ b/drivers/net/wireless/mwifiex/txrx.c @@ -48,7 +48,8 @@ int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter, if (!priv) priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); - rx_info->bss_index = priv->bss_index; + rx_info->bss_num = priv->bss_num; + rx_info->bss_type = priv->bss_type; return mwifiex_process_sta_rx_packet(adapter, skb); } @@ -130,7 +131,8 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, return 0; tx_info = MWIFIEX_SKB_TXCB(skb); - priv = mwifiex_bss_index_to_priv(adapter, tx_info->bss_index); + priv = mwifiex_get_priv_by_id(adapter, tx_info->bss_num, + tx_info->bss_type); if (!priv) goto done; diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c index 06976f517f6..9c48f37069f 100644 --- a/drivers/net/wireless/mwifiex/util.c +++ b/drivers/net/wireless/mwifiex/util.c @@ -159,7 +159,8 @@ int mwifiex_recv_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb) return -1; rx_info = MWIFIEX_SKB_RXCB(skb); - priv = mwifiex_bss_index_to_priv(adapter, rx_info->bss_index); + priv = mwifiex_get_priv_by_id(adapter, rx_info->bss_num, + rx_info->bss_type); if (!priv) return -1; diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 6c239c3c824..e6a2cb127d2 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -603,7 +603,8 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter, struct sk_buff *skb) { struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb); - struct mwifiex_private *priv = adapter->priv[tx_info->bss_index]; + struct mwifiex_private *priv = mwifiex_get_priv_by_id(adapter, + tx_info->bss_num, tx_info->bss_type); u32 tid; struct mwifiex_ra_list_tbl *ra_list; u8 ra[ETH_ALEN], tid_down; -- cgit v1.2.3-70-g09d2 From f540f9f34b35d3c8a1d4b8d47ad5f00da951bfe7 Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Wed, 11 Jan 2012 20:06:12 -0800 Subject: mwifiex: derive priv from net_device instead of wiphy Currently mwifiex_private pointers are derived from wiphy structures. This will always work as long as there is only one net_device associated with one wiphy. In scenarios where there are multiple net_devices associated with single wiphy, one should use net_device to derive the priv. Signed-off-by: Yogesh Ashok Powar Signed-off-by: Avinash Patil Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 36f67da8fa4..00f10059ecb 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -79,7 +79,7 @@ static int mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, bool pairwise, const u8 *mac_addr) { - struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); if (mwifiex_set_encode(priv, NULL, 0, key_index, 1)) { wiphy_err(wiphy, "deleting the crypto keys\n"); @@ -122,7 +122,7 @@ mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, bool enabled, int timeout) { - struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); u32 ps_mode; if (timeout) @@ -143,7 +143,7 @@ mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, bool unicast, bool multicast) { - struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); /* Return if WEP key not configured */ if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED) @@ -165,7 +165,7 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params) { - struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); if (mwifiex_set_encode(priv, params->key, params->key_len, key_index, 0)) { @@ -376,7 +376,7 @@ mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type) { - struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); if (priv->media_connected) { wiphy_err(wiphy, "This setting is valid only when station " @@ -1004,7 +1004,7 @@ static int mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ibss_params *params) { - struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); int ret = 0; if (priv->bss_mode != NL80211_IFTYPE_ADHOC) { @@ -1042,7 +1042,7 @@ done: static int mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) { - struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n", priv->cfg_bssid); @@ -1280,10 +1280,7 @@ EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf); */ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev) { - struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); - - if (!priv || !dev) - return 0; + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); #ifdef CONFIG_DEBUG_FS mwifiex_dev_debugfs_remove(priv); -- cgit v1.2.3-70-g09d2 From 6ae4bb6612c675d4132bd4fcc7cac4eef46f9624 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 13 Jan 2012 16:35:05 +0100 Subject: carl9170: remove eeprom data injection option In the early days, this was a quite useful software feature for testing different regdomains and chain configurations without adding debugfs cruft into the driver. Nowadays, the driver's phy code seems to be stable and there's no need for it anymore. Therefore I decided to removed altogether. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/carl9170.h | 1 - drivers/net/wireless/ath/carl9170/fw.c | 33 ---------------------------- drivers/net/wireless/ath/carl9170/main.c | 4 ---- 3 files changed, 38 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h index 6cfbb419e2f..f0f44c30b2f 100644 --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h @@ -593,7 +593,6 @@ int carl9170_get_noisefloor(struct ar9170 *ar); /* FW */ int carl9170_parse_firmware(struct ar9170 *ar); -int carl9170_fw_fix_eeprom(struct ar9170 *ar); extern struct ieee80211_rate __carl9170_ratetable[]; extern int modparam_noht; diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c index 3de61adacd3..cffde8d9a52 100644 --- a/drivers/net/wireless/ath/carl9170/fw.c +++ b/drivers/net/wireless/ath/carl9170/fw.c @@ -389,39 +389,6 @@ carl9170_find_fw_desc(struct ar9170 *ar, const __u8 *fw_data, const size_t len) return (void *)&fw_data[scan - found]; } -int carl9170_fw_fix_eeprom(struct ar9170 *ar) -{ - const struct carl9170fw_fix_desc *fix_desc = NULL; - unsigned int i, n, off; - u32 *data = (void *)&ar->eeprom; - - fix_desc = carl9170_fw_find_desc(ar, FIX_MAGIC, - sizeof(*fix_desc), CARL9170FW_FIX_DESC_CUR_VER); - - if (!fix_desc) - return 0; - - n = (le16_to_cpu(fix_desc->head.length) - sizeof(*fix_desc)) / - sizeof(struct carl9170fw_fix_entry); - - for (i = 0; i < n; i++) { - off = le32_to_cpu(fix_desc->data[i].address) - - AR9170_EEPROM_START; - - if (off >= sizeof(struct ar9170_eeprom) || (off & 3)) { - dev_err(&ar->udev->dev, "Skip invalid entry %d\n", i); - continue; - } - - data[off / sizeof(*data)] &= - le32_to_cpu(fix_desc->data[i].mask); - data[off / sizeof(*data)] |= - le32_to_cpu(fix_desc->data[i].value); - } - - return 0; -} - int carl9170_parse_firmware(struct ar9170 *ar) { const struct carl9170fw_desc_head *fw_desc = NULL; diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 4dfb0290b43..6ee7c55f75a 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -1934,10 +1934,6 @@ int carl9170_register(struct ar9170 *ar) if (err) return err; - err = carl9170_fw_fix_eeprom(ar); - if (err) - return err; - err = carl9170_parse_eeprom(ar); if (err) return err; -- cgit v1.2.3-70-g09d2 From f99725777e0f57e71f37191eee5f10071ed7b423 Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Sat, 14 Jan 2012 11:42:43 +0100 Subject: ath5k: claim support for IBSS RSN Disable group keys programming when using IBSS RSN. Keys will be managed using software. In this way IBSS RSN can correctly work. Signed-off-by: Antonio Quartulli Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 3 +++ drivers/net/wireless/ath/ath5k/mac80211-ops.c | 8 ++++++++ 2 files changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index d366dadcf86..4ab835f08a4 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2442,6 +2442,9 @@ ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops) BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_MESH_POINT); + /* SW support for IBSS_RSN is provided by mac80211 */ + hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; + /* both antennas can be configured as RX or TX */ hw->wiphy->available_antennas_tx = 0x3; hw->wiphy->available_antennas_rx = 0x3; diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 6ed4c0717e3..af4c7ecb4b3 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c @@ -483,6 +483,14 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (ath5k_modparam_nohwcrypt) return -EOPNOTSUPP; + if (vif->type == NL80211_IFTYPE_ADHOC && + (key->cipher == WLAN_CIPHER_SUITE_TKIP || + key->cipher == WLAN_CIPHER_SUITE_CCMP) && + !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { + /* don't program group keys when using IBSS_RSN */ + return -EOPNOTSUPP; + } + switch (key->cipher) { case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: -- cgit v1.2.3-70-g09d2 From 8ae746543c8370fd04c28aaf8f185c1687b0e694 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 15 Jan 2012 00:38:38 -0800 Subject: brcm80211: Use normal DEBUG define Current CONFIG_BRCMDBG flag when enabled does not necessarily enable proper pr_debug output when DEBUG is not also enabled. Remove BCMDBG define and just use DEBUG instead. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/Makefile | 2 +- drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 4 +- .../net/wireless/brcm80211/brcmfmac/dhd_common.c | 10 +-- drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h | 6 +- .../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 4 +- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 86 +++++++++++----------- .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.h | 6 +- drivers/net/wireless/brcm80211/brcmsmac/aiutils.c | 4 +- drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | 2 +- drivers/net/wireless/brcm80211/brcmsmac/dma.c | 8 +- .../net/wireless/brcm80211/brcmsmac/mac80211_if.c | 18 ++--- .../net/wireless/brcm80211/brcmsmac/mac80211_if.h | 2 +- drivers/net/wireless/brcm80211/brcmsmac/main.c | 42 +++++------ drivers/net/wireless/brcm80211/brcmsmac/main.h | 2 +- drivers/net/wireless/brcm80211/brcmutil/utils.c | 4 +- .../net/wireless/brcm80211/include/brcmu_utils.h | 4 +- 16 files changed, 102 insertions(+), 102 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/Makefile b/drivers/net/wireless/brcm80211/Makefile index f41c047eca8..b987920e982 100644 --- a/drivers/net/wireless/brcm80211/Makefile +++ b/drivers/net/wireless/brcm80211/Makefile @@ -16,7 +16,7 @@ # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # common flags -subdir-ccflags-$(CONFIG_BRCMDBG) += -DBCMDBG +subdir-ccflags-$(CONFIG_BRCMDBG) += -DDEBUG obj-$(CONFIG_BRCMUTIL) += brcmutil/ obj-$(CONFIG_BRCMFMAC) += brcmfmac/ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index e58ea40a75b..07686a748d3 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h @@ -644,9 +644,9 @@ extern char *brcmf_ifname(struct brcmf_pub *drvr, int idx); extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf, uint len); -#ifdef BCMDBG +#ifdef DEBUG extern int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size); -#endif /* BCMDBG */ +#endif /* DEBUG */ extern int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name); extern int brcmf_c_host_event(struct brcmf_pub *drvr, int *idx, diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index a51d8f5d36f..9385c84646e 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -38,7 +38,7 @@ #define BRCMF_PKT_FILTER_PATTERN_FIXED_LEN \ offsetof(struct brcmf_pkt_filter_pattern_le, mask_and_pattern) -#ifdef BCMDBG +#ifdef DEBUG static const char brcmf_version[] = "Dongle Host Driver, version " BRCMF_VERSION_STR "\nCompiled on " __DATE__ " at " __TIME__; @@ -133,7 +133,7 @@ bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, return p != NULL; } -#ifdef BCMDBG +#ifdef DEBUG static void brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data) { @@ -430,7 +430,7 @@ brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data) brcmf_dbg(EVENT, "\n"); } } -#endif /* BCMDBG */ +#endif /* DEBUG */ int brcmf_c_host_event(struct brcmf_pub *drvr, int *ifidx, void *pktdata, @@ -518,9 +518,9 @@ brcmf_c_host_event(struct brcmf_pub *drvr, int *ifidx, void *pktdata, break; } -#ifdef BCMDBG +#ifdef DEBUG brcmf_c_show_host_event(event, event_data); -#endif /* BCMDBG */ +#endif /* DEBUG */ return 0; } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h index bb26ee36bc6..8b2060b578d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h @@ -32,7 +32,7 @@ #define BRCMF_BTA_VAL 0x1000 #define BRCMF_ISCAN_VAL 0x2000 -#if defined(BCMDBG) +#if defined(DEBUG) #define brcmf_dbg(level, fmt, ...) \ do { \ @@ -56,7 +56,7 @@ do { \ #define BRCMF_BYTES_ON() (brcmf_msg_level & BRCMF_BYTES_VAL) #define BRCMF_GLOM_ON() (brcmf_msg_level & BRCMF_GLOM_VAL) -#else /* (defined BCMDBG) || (defined BCMDBG) */ +#else /* (defined DEBUG) || (defined DEBUG) */ #define brcmf_dbg(level, fmt, ...) no_printk(fmt, ##__VA_ARGS__) @@ -66,7 +66,7 @@ do { \ #define BRCMF_BYTES_ON() 0 #define BRCMF_GLOM_ON() 0 -#endif /* defined(BCMDBG) */ +#endif /* defined(DEBUG) */ extern int brcmf_msg_level; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index c3980c50a99..16fd1ab3540 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -1146,7 +1146,7 @@ int brcmf_netdev_wait_pend8021x(struct net_device *ndev) return pend; } -#ifdef BCMDBG +#ifdef DEBUG int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size) { int ret = 0; @@ -1180,4 +1180,4 @@ exit: return ret; } -#endif /* BCMDBG */ +#endif /* DEBUG */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index f7eeee1dcdb..7157a60c94b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -40,7 +40,7 @@ #define DCMD_RESP_TIMEOUT 2000 /* In milli second */ -#ifdef BCMDBG +#ifdef DEBUG #define BRCMF_TRAP_INFO_SIZE 80 @@ -84,7 +84,7 @@ struct rte_console { char cbuf[CBUF_LEN]; }; -#endif /* BCMDBG */ +#endif /* DEBUG */ #include #include "dhd_bus.h" @@ -416,7 +416,7 @@ struct sdpcmd_regs { u16 PAD[0x80]; }; -#ifdef BCMDBG +#ifdef DEBUG /* Device console log buffer state */ struct brcmf_console { uint count; /* Poll interval msec counter */ @@ -426,7 +426,7 @@ struct brcmf_console { u8 *buf; /* Log buffer (host copy) */ uint last; /* Last buffer read index */ }; -#endif /* BCMDBG */ +#endif /* DEBUG */ struct sdpcm_shared { u32 flags; @@ -507,11 +507,11 @@ struct brcmf_sdio { uint polltick; /* Tick counter */ uint pollcnt; /* Count of active polls */ -#ifdef BCMDBG +#ifdef DEBUG uint console_interval; struct brcmf_console console; /* Console output polling support */ uint console_addr; /* Console address from shared struct */ -#endif /* BCMDBG */ +#endif /* DEBUG */ uint regfails; /* Count of R_REG failures */ @@ -587,10 +587,10 @@ struct brcmf_sdio { #define CLK_PENDING 2 /* Not used yet */ #define CLK_AVAIL 3 -#ifdef BCMDBG +#ifdef DEBUG static int qcount[NUMPRIO]; static int tx_packets[NUMPRIO]; -#endif /* BCMDBG */ +#endif /* DEBUG */ #define SDIO_DRIVE_STRENGTH 6 /* in milliamps */ @@ -764,12 +764,12 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok) bus->clkstate = CLK_AVAIL; brcmf_dbg(INFO, "CLKCTL: turned ON\n"); -#if defined(BCMDBG) +#if defined(DEBUG) if (bus->alp_only != true) { if (SBSDIO_ALPONLY(clkctl)) brcmf_dbg(ERROR, "HT Clock should be on\n"); } -#endif /* defined (BCMDBG) */ +#endif /* defined (DEBUG) */ bus->activity = true; } else { @@ -814,9 +814,9 @@ static int brcmf_sdbrcm_sdclk(struct brcmf_sdio *bus, bool on) /* Transition SD and backplane clock readiness */ static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok) { -#ifdef BCMDBG +#ifdef DEBUG uint oldstate = bus->clkstate; -#endif /* BCMDBG */ +#endif /* DEBUG */ brcmf_dbg(TRACE, "Enter\n"); @@ -861,9 +861,9 @@ static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok) brcmf_sdbrcm_wd_timer(bus, 0); break; } -#ifdef BCMDBG +#ifdef DEBUG brcmf_dbg(INFO, "%d -> %d\n", oldstate, bus->clkstate); -#endif /* BCMDBG */ +#endif /* DEBUG */ return 0; } @@ -1279,7 +1279,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) } return 0; } -#ifdef BCMDBG +#ifdef DEBUG if (BRCMF_GLOM_ON()) { printk(KERN_DEBUG "SUPERFRAME:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, @@ -1362,7 +1362,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) check = get_unaligned_le16(dptr + sizeof(u16)); chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); -#ifdef BCMDBG +#ifdef DEBUG if (BRCMF_GLOM_ON()) { printk(KERN_DEBUG "subframe:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, @@ -1433,7 +1433,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) } rxseq++; -#ifdef BCMDBG +#ifdef DEBUG if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) { printk(KERN_DEBUG "Rx Subframe Data:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, @@ -1457,7 +1457,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) continue; } -#ifdef BCMDBG +#ifdef DEBUG if (BRCMF_GLOM_ON()) { brcmf_dbg(GLOM, "subframe %d to stack, %p (%p/%d) nxt/lnk %p/%p\n", bus->glom.qlen, pfirst, pfirst->data, @@ -1467,7 +1467,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) pfirst->data, min_t(int, pfirst->len, 32)); } -#endif /* BCMDBG */ +#endif /* DEBUG */ } /* sent any remaining packets up */ if (bus->glom.qlen) { @@ -1584,7 +1584,7 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) gotpkt: -#ifdef BCMDBG +#ifdef DEBUG if (BRCMF_BYTES_ON() && BRCMF_CTL_ON()) { printk(KERN_DEBUG "RxCtrl:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, bus->rxctl, len); @@ -1818,7 +1818,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) } bus->tx_max = txmax; -#ifdef BCMDBG +#ifdef DEBUG if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) { printk(KERN_DEBUG "Rx Data:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, @@ -1865,7 +1865,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) brcmf_sdbrcm_rxfail(bus, true, true); continue; } -#ifdef BCMDBG +#ifdef DEBUG if (BRCMF_BYTES_ON() || BRCMF_HDRS_ON()) { printk(KERN_DEBUG "RxHdr:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, @@ -2024,7 +2024,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) skb_push(pkt, BRCMF_FIRSTREAD); memcpy(pkt->data, bus->rxhdr, BRCMF_FIRSTREAD); -#ifdef BCMDBG +#ifdef DEBUG if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) { printk(KERN_DEBUG "Rx Data:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, @@ -2038,7 +2038,7 @@ deliver: if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_FRAMETAG_LEN])) { brcmf_dbg(GLOM, "glom descriptor, %d bytes:\n", len); -#ifdef BCMDBG +#ifdef DEBUG if (BRCMF_GLOM_ON()) { printk(KERN_DEBUG "Glom Data:\n"); print_hex_dump_bytes("", @@ -2078,13 +2078,13 @@ deliver: down(&bus->sdsem); } rxcount = maxframes - rxleft; -#ifdef BCMDBG +#ifdef DEBUG /* Message if we hit the limit */ if (!rxleft) brcmf_dbg(DATA, "hit rx limit of %d frames\n", maxframes); else -#endif /* BCMDBG */ +#endif /* DEBUG */ brcmf_dbg(DATA, "processed %d frames\n", rxcount); /* Back off rxseq if awaiting rtx, update rx_seq */ if (bus->rxskip) @@ -2176,7 +2176,7 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN); put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader)); -#ifdef BCMDBG +#ifdef DEBUG tx_packets[pkt->priority]++; if (BRCMF_BYTES_ON() && (((BRCMF_CTL_ON() && (chan == SDPCM_CONTROL_CHANNEL)) || @@ -2410,7 +2410,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) int err; u8 clkctl, devctl = 0; -#ifdef BCMDBG +#ifdef DEBUG /* Check for inconsistent device control */ devctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); @@ -2418,7 +2418,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) brcmf_dbg(ERROR, "error reading DEVCTL: %d\n", err); bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; } -#endif /* BCMDBG */ +#endif /* DEBUG */ /* Read CSR, if clock on switch to AVAIL, else ignore */ clkctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, @@ -2701,7 +2701,7 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) brcmf_txflowcontrol(bus->sdiodev->dev, 0, ON); } -#ifdef BCMDBG +#ifdef DEBUG if (pktq_plen(&bus->txq, prec) > qcount[prec]) qcount[prec] = pktq_plen(&bus->txq, prec); #endif @@ -2774,7 +2774,7 @@ xfer_done: return bcmerror; } -#ifdef BCMDBG +#ifdef DEBUG #define CONSOLE_LINE_MAX 192 static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus) @@ -2852,7 +2852,7 @@ break2: return 0; } -#endif /* BCMDBG */ +#endif /* DEBUG */ static int brcmf_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len) { @@ -2982,7 +2982,7 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) } if (ret == -1) { -#ifdef BCMDBG +#ifdef DEBUG if (BRCMF_BYTES_ON() && BRCMF_CTL_ON()) { printk(KERN_DEBUG "Tx Frame:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, @@ -3096,9 +3096,9 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus) u8 *vbuffer; u32 varsizew; __le32 varsizew_le; -#ifdef BCMDBG +#ifdef DEBUG char *nvram_ularray; -#endif /* BCMDBG */ +#endif /* DEBUG */ /* Even if there are no vars are to be written, we still need to set the ramsize. */ @@ -3115,7 +3115,7 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus) /* Write the vars list */ bcmerror = brcmf_sdbrcm_membytes(bus, true, varaddr, vbuffer, varsize); -#ifdef BCMDBG +#ifdef DEBUG /* Verify NVRAM bytes */ brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n", varsize); nvram_ularray = kmalloc(varsize, GFP_ATOMIC); @@ -3142,7 +3142,7 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus) brcmf_dbg(ERROR, "Download/Upload/Compare of NVRAM ok\n"); kfree(nvram_ularray); -#endif /* BCMDBG */ +#endif /* DEBUG */ kfree(vbuffer); } @@ -3569,9 +3569,9 @@ void brcmf_sdbrcm_isr(void *arg) static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) { -#ifdef BCMDBG +#ifdef DEBUG struct brcmf_bus *bus_if = dev_get_drvdata(bus->sdiodev->dev); -#endif /* BCMDBG */ +#endif /* DEBUG */ brcmf_dbg(TIMER, "Enter\n"); @@ -3616,7 +3616,7 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) /* Update interrupt tracking */ bus->lastintrs = bus->intrcount; } -#ifdef BCMDBG +#ifdef DEBUG /* Poll for console output periodically */ if (bus_if->state == BRCMF_BUS_DATA && bus->console_interval != 0) { @@ -3630,7 +3630,7 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) bus->console_interval = 0; } } -#endif /* BCMDBG */ +#endif /* DEBUG */ /* On idle timeout clear activity flag and/or turn off clock */ if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) { @@ -3721,11 +3721,11 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) if (brcmf_sdcard_set_sbaddr_window(bus->sdiodev, SI_ENUM_BASE)) brcmf_dbg(ERROR, "FAILED to return to SI_ENUM_BASE\n"); -#ifdef BCMDBG +#ifdef DEBUG printk(KERN_DEBUG "F1 signature read @0x18000000=0x%4x\n", brcmf_sdcard_reg_read(bus->sdiodev, SI_ENUM_BASE, 4)); -#endif /* BCMDBG */ +#endif /* DEBUG */ /* * Force PLL off until brcmf_sdio_chip_attach() diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h index a613b49cb13..69a48729a72 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h @@ -42,7 +42,7 @@ do { \ } \ } while (0) -#if (defined BCMDBG) +#if (defined DEBUG) #define WL_INFO(fmt, args...) \ do { \ if (brcmf_dbg_level & WL_DBG_INFO) { \ @@ -83,12 +83,12 @@ do { \ } \ } while (0) -#else /* (defined BCMDBG) */ +#else /* (defined DEBUG) */ #define WL_INFO(fmt, args...) #define WL_TRACE(fmt, args...) #define WL_SCAN(fmt, args...) #define WL_CONN(fmt, args...) -#endif /* (defined BCMDBG) */ +#endif /* (defined DEBUG) */ #define WL_NUM_SCAN_MAX 1 #define WL_NUM_PMKIDS_MAX MAXPMKID /* will be used diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c index ab9bb11abfb..c93ea35bcee 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c @@ -326,11 +326,11 @@ #define PCI_FORCEHT(sih) (PCIE(sih) && (ai_get_chip_id(sih) == BCM4716_CHIP_ID)) -#ifdef BCMDBG +#ifdef DEBUG #define SI_MSG(fmt, ...) pr_debug(fmt, ##__VA_ARGS__) #else #define SI_MSG(fmt, ...) no_printk(fmt, ##__VA_ARGS__) -#endif /* BCMDBG */ +#endif /* DEBUG */ #define GOODCOREADDR(x, b) \ (((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c index 90911eec0cf..d89dcb14cb6 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c @@ -915,7 +915,7 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p); struct wiphy *wiphy = wlc->wiphy; -#ifdef BCMDBG +#ifdef DEBUG u8 hole[AMPDU_MAX_MPDU]; memset(hole, 0, sizeof(hole)); #endif diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c index 2e90a9a16ed..11054ae9d4f 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c @@ -177,7 +177,7 @@ #define BCMEXTRAHDROOM 172 /* debug/trace */ -#ifdef BCMDBG +#ifdef DEBUG #define DMA_ERROR(fmt, ...) \ do { \ if (*di->msg_level & 1) \ @@ -193,7 +193,7 @@ do { \ no_printk(fmt, ##__VA_ARGS__) #define DMA_TRACE(fmt, ...) \ no_printk(fmt, ##__VA_ARGS__) -#endif /* BCMDBG */ +#endif /* DEBUG */ #define DMA_NONE(fmt, ...) \ no_printk(fmt, ##__VA_ARGS__) @@ -968,7 +968,7 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list) pktcnt++; } -#ifdef BCMDBG +#ifdef DEBUG if (resid > 0) { uint cur; cur = @@ -979,7 +979,7 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list) DMA_ERROR("rxin %d rxout %d, hw_curr %d\n", di->rxin, di->rxout, cur); } -#endif /* BCMDBG */ +#endif /* DEBUG */ if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) { DMA_ERROR("%s: bad frame length (%d)\n", diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 448ab9c4eb4..04ba9a878f4 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c @@ -96,10 +96,10 @@ static struct bcma_device_id brcms_coreid_table[] = { }; MODULE_DEVICE_TABLE(bcma, brcms_coreid_table); -#ifdef BCMDBG +#ifdef DEBUG static int msglevel = 0xdeadbeef; module_param(msglevel, int, 0); -#endif /* BCMDBG */ +#endif /* DEBUG */ static struct ieee80211_channel brcms_2ghz_chantable[] = { CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS), @@ -857,7 +857,7 @@ static void brcms_free(struct brcms_info *wl) /* free timers */ for (t = wl->timers; t; t = next) { next = t->next; -#ifdef BCMDBG +#ifdef DEBUG kfree(t->name); #endif kfree(t); @@ -1177,10 +1177,10 @@ static int __init brcms_module_init(void) { int error = -ENODEV; -#ifdef BCMDBG +#ifdef DEBUG if (msglevel != 0xdeadbeef) brcm_msg_level = msglevel; -#endif /* BCMDBG */ +#endif /* DEBUG */ error = bcma_driver_register(&brcms_bcma_driver); printk(KERN_ERR "%s: register returned %d\n", __func__, error); @@ -1367,7 +1367,7 @@ struct brcms_timer *brcms_init_timer(struct brcms_info *wl, t->next = wl->timers; wl->timers = t; -#ifdef BCMDBG +#ifdef DEBUG t->name = kmalloc(strlen(name) + 1, GFP_ATOMIC); if (t->name) strcpy(t->name, name); @@ -1386,7 +1386,7 @@ void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic) { struct ieee80211_hw *hw = t->wl->pub->ieee_hw; -#ifdef BCMDBG +#ifdef DEBUG if (t->set) wiphy_err(hw->wiphy, "%s: Already set. Name: %s, per %d\n", __func__, t->name, periodic); @@ -1431,7 +1431,7 @@ void brcms_free_timer(struct brcms_timer *t) if (wl->timers == t) { wl->timers = wl->timers->next; -#ifdef BCMDBG +#ifdef DEBUG kfree(t->name); #endif kfree(t); @@ -1443,7 +1443,7 @@ void brcms_free_timer(struct brcms_timer *t) while (tmp) { if (tmp->next == t) { tmp->next = t->next; -#ifdef BCMDBG +#ifdef DEBUG kfree(t->name); #endif kfree(t); diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h index 8f60419c37b..9358bd5ebd3 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h @@ -40,7 +40,7 @@ struct brcms_timer { bool periodic; bool set; /* indicates if timer is active */ struct brcms_timer *next; /* for freeing on unload */ -#ifdef BCMDBG +#ifdef DEBUG char *name; /* Description of the timer */ #endif }; diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index f7ed34034f8..3ae07bb9cc6 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -293,11 +293,11 @@ const u8 prio2fifo[NUMPRIO] = { /* debug/trace */ uint brcm_msg_level = -#if defined(BCMDBG) +#if defined(DEBUG) LOG_ERROR_VAL; #else 0; -#endif /* BCMDBG */ +#endif /* DEBUG */ /* TX FIFO number to WME/802.1E Access Category */ static const u8 wme_fifo2ac[] = { @@ -342,14 +342,14 @@ static const u16 xmtfifo_sz[][NFIFO] = { {9, 58, 22, 14, 14, 5}, }; -#ifdef BCMDBG +#ifdef DEBUG static const char * const fifo_names[] = { "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" }; #else static const char fifo_names[6][0]; #endif -#ifdef BCMDBG +#ifdef DEBUG /* pointer to most recently allocated wl/wlc */ static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL); #endif @@ -3075,30 +3075,30 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc) { int i; struct macstat macstats; -#ifdef BCMDBG +#ifdef DEBUG u16 delta; u16 rxf0ovfl; u16 txfunfl[NFIFO]; -#endif /* BCMDBG */ +#endif /* DEBUG */ /* if driver down, make no sense to update stats */ if (!wlc->pub->up) return; -#ifdef BCMDBG +#ifdef DEBUG /* save last rx fifo 0 overflow count */ rxf0ovfl = wlc->core->macstat_snapshot->rxf0ovfl; /* save last tx fifo underflow count */ for (i = 0; i < NFIFO; i++) txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i]; -#endif /* BCMDBG */ +#endif /* DEBUG */ /* Read mac stats from contiguous shared memory */ brcms_b_copyfrom_objmem(wlc->hw, M_UCODE_MACSTAT, &macstats, sizeof(struct macstat), OBJADDR_SHM_SEL); -#ifdef BCMDBG +#ifdef DEBUG /* check for rx fifo 0 overflow */ delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl); if (delta) @@ -3114,7 +3114,7 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc) wiphy_err(wlc->wiphy, "wl%d: %u tx fifo %d underflows!" "\n", wlc->pub->unit, delta, i); } -#endif /* BCMDBG */ +#endif /* DEBUG */ /* merge counters from dma module */ for (i = 0; i < NFIFO; i++) { @@ -5765,7 +5765,7 @@ int brcms_c_module_unregister(struct brcms_pub *pub, const char *name, return -ENODATA; } -#ifdef BCMDBG +#ifdef DEBUG static const char * const supr_reason[] = { "None", "PMQ Entry", "Flush request", "Previous frag failure", "Channel mismatch", @@ -5790,11 +5790,11 @@ static void brcms_c_print_txs_status(u16 s) printk(KERN_DEBUG " [1] %d acked\n", ((s & TX_STATUS_ACK_RCV) ? 1 : 0)); } -#endif /* BCMDBG */ +#endif /* DEBUG */ void brcms_c_print_txstatus(struct tx_status *txs) { -#if defined(BCMDBG) +#if defined(DEBUG) u16 s = txs->status; u16 ackphyrxsh = txs->ackphyrxsh; @@ -5814,7 +5814,7 @@ void brcms_c_print_txstatus(struct tx_status *txs) printk(KERN_DEBUG "RxAckSQ: %04x", (ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT); printk(KERN_DEBUG "\n"); -#endif /* defined(BCMDBG) */ +#endif /* defined(DEBUG) */ } bool brcms_c_chipmatch(u16 vendor, u16 device) @@ -5837,7 +5837,7 @@ bool brcms_c_chipmatch(u16 vendor, u16 device) return false; } -#if defined(BCMDBG) +#if defined(DEBUG) void brcms_c_print_txdesc(struct d11txh *txh) { u16 mtcl = le16_to_cpu(txh->MacTxControlLow); @@ -5919,9 +5919,9 @@ void brcms_c_print_txdesc(struct d11txh *txh) (u8 *)&rts, sizeof(txh->rts_frame)); printk(KERN_DEBUG "\n"); } -#endif /* defined(BCMDBG) */ +#endif /* defined(DEBUG) */ -#if defined(BCMDBG) +#if defined(DEBUG) static int brcms_c_format_flags(const struct brcms_c_bit_desc *bd, u32 flags, char *buf, int len) @@ -5975,9 +5975,9 @@ brcms_c_format_flags(const struct brcms_c_bit_desc *bd, u32 flags, char *buf, return (int)(p - buf); } -#endif /* defined(BCMDBG) */ +#endif /* defined(DEBUG) */ -#if defined(BCMDBG) +#if defined(DEBUG) void brcms_c_print_rxh(struct d11rxhdr *rxh) { u16 len = rxh->RxFrameSize; @@ -6016,7 +6016,7 @@ void brcms_c_print_rxh(struct d11rxhdr *rxh) (macstatus2 & RXS_AGGTYPE_MASK)); printk(KERN_DEBUG "RxTSFTime: %04x\n", rxh->RxTSFTime); } -#endif /* defined(BCMDBG) */ +#endif /* defined(DEBUG) */ u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate) { @@ -8346,7 +8346,7 @@ brcms_c_attach(struct brcms_info *wl, struct bcma_device *core, uint unit, wlc->wiphy = wl->wiphy; pub = wlc->pub; -#if defined(BCMDBG) +#if defined(DEBUG) wlc_info_dbg = wlc; #endif diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h index adb136ec1f0..84a2a0d9dd3 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h @@ -648,7 +648,7 @@ extern void brcms_c_print_txstatus(struct tx_status *txs); extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, uint *blocks); -#if defined(BCMDBG) +#if defined(DEBUG) extern void brcms_c_print_txdesc(struct d11txh *txh); #else #define brcms_c_print_txdesc(a) diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c index b7537f70a79..e25fb2da8e6 100644 --- a/drivers/net/wireless/brcm80211/brcmutil/utils.c +++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c @@ -240,7 +240,7 @@ struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp, } EXPORT_SYMBOL(brcmu_pktq_mdeq); -#if defined(BCMDBG) +#if defined(DEBUG) /* pretty hex print a pkt buffer chain */ void brcmu_prpkt(const char *msg, struct sk_buff *p0) { @@ -253,4 +253,4 @@ void brcmu_prpkt(const char *msg, struct sk_buff *p0) print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, p->data, p->len); } EXPORT_SYMBOL(brcmu_prpkt); -#endif /* defined(BCMDBG) */ +#endif /* defined(DEBUG) */ diff --git a/drivers/net/wireless/brcm80211/include/brcmu_utils.h b/drivers/net/wireless/brcm80211/include/brcmu_utils.h index ad249a0b473..0cde38aa63f 100644 --- a/drivers/net/wireless/brcm80211/include/brcmu_utils.h +++ b/drivers/net/wireless/brcm80211/include/brcmu_utils.h @@ -176,10 +176,10 @@ struct ipv4_addr; /* externs */ /* format/print */ -#ifdef BCMDBG +#ifdef DEBUG extern void brcmu_prpkt(const char *msg, struct sk_buff *p0); #else #define brcmu_prpkt(a, b) -#endif /* BCMDBG */ +#endif /* DEBUG */ #endif /* _BRCMU_UTILS_H_ */ -- cgit v1.2.3-70-g09d2 From d6400c29abcd218bcc9be5d09f76e0770e25face Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 15 Jan 2012 00:38:39 -0800 Subject: brcmfmac: Convert printk(KERN_DEBUG to pr_debug Allow dynamic debugging. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h index 8b2060b578d..f5ca9fc526e 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h @@ -39,13 +39,13 @@ do { \ if (BRCMF_ERROR_VAL == BRCMF_##level##_VAL) { \ if (brcmf_msg_level & BRCMF_##level##_VAL) { \ if (net_ratelimit()) \ - printk(KERN_DEBUG "%s: " fmt, \ - __func__, ##__VA_ARGS__); \ + pr_debug("%s: " fmt, \ + __func__, ##__VA_ARGS__); \ } \ } else { \ if (brcmf_msg_level & BRCMF_##level##_VAL) { \ - printk(KERN_DEBUG "%s: " fmt, \ - __func__, ##__VA_ARGS__); \ + pr_debug("%s: " fmt, \ + __func__, ##__VA_ARGS__); \ } \ } \ } while (0) -- cgit v1.2.3-70-g09d2 From 1e02382979dd422e3b1bdb45545a0699497e3692 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 15 Jan 2012 00:38:40 -0800 Subject: brcm80211: Add and use brcmX_dbg_dump_hex Reduce the number of #ifdef DEBUG uses by adding a dbg_hex_dump routine which has the appropriate #ifdef DEBUG test. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h | 6 + drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 141 +++++++-------------- drivers/net/wireless/brcm80211/brcmutil/utils.c | 18 +++ .../net/wireless/brcm80211/include/brcmu_utils.h | 11 ++ 4 files changed, 84 insertions(+), 92 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h index f5ca9fc526e..a2c4576cf9f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h @@ -68,6 +68,12 @@ do { \ #endif /* defined(DEBUG) */ +#define brcmf_dbg_hex_dump(test, data, len, fmt, ...) \ +do { \ + if (test) \ + brcmu_dbg_hex_dump(data, len, fmt, ##__VA_ARGS__); \ +} while (0) + extern int brcmf_msg_level; #endif /* _BRCMF_DBG_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 7157a60c94b..4ab1023352a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -1279,13 +1279,10 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) } return 0; } -#ifdef DEBUG - if (BRCMF_GLOM_ON()) { - printk(KERN_DEBUG "SUPERFRAME:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - pfirst->data, min_t(int, pfirst->len, 48)); - } -#endif + + brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), + pfirst->data, min_t(int, pfirst->len, 48), + "SUPERFRAME:\n"); /* Validate the superframe header */ dptr = (u8 *) (pfirst->data); @@ -1362,13 +1359,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) check = get_unaligned_le16(dptr + sizeof(u16)); chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); -#ifdef DEBUG - if (BRCMF_GLOM_ON()) { - printk(KERN_DEBUG "subframe:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - dptr, 32); - } -#endif + brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), + dptr, 32, "subframe:\n"); if ((u16)~(sublen ^ check)) { brcmf_dbg(ERROR, "(subframe %d): HW hdr error: len/check 0x%04x/0x%04x\n", @@ -1433,13 +1425,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) } rxseq++; -#ifdef DEBUG - if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) { - printk(KERN_DEBUG "Rx Subframe Data:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - dptr, dlen); - } -#endif + brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(), + dptr, dlen, "Rx Subframe Data:\n"); __skb_trim(pfirst, sublen); skb_pull(pfirst, doff); @@ -1457,17 +1444,13 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) continue; } -#ifdef DEBUG - if (BRCMF_GLOM_ON()) { - brcmf_dbg(GLOM, "subframe %d to stack, %p (%p/%d) nxt/lnk %p/%p\n", - bus->glom.qlen, pfirst, pfirst->data, - pfirst->len, pfirst->next, - pfirst->prev); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - pfirst->data, - min_t(int, pfirst->len, 32)); - } -#endif /* DEBUG */ + brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), + pfirst->data, + min_t(int, pfirst->len, 32), + "subframe %d to stack, %p (%p/%d) nxt/lnk %p/%p\n", + bus->glom.qlen, pfirst, pfirst->data, + pfirst->len, pfirst->next, + pfirst->prev); } /* sent any remaining packets up */ if (bus->glom.qlen) { @@ -1584,12 +1567,8 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) gotpkt: -#ifdef DEBUG - if (BRCMF_BYTES_ON() && BRCMF_CTL_ON()) { - printk(KERN_DEBUG "RxCtrl:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, bus->rxctl, len); - } -#endif + brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(), + bus->rxctl, len, "RxCtrl:\n"); /* Point to valid data and indicate its length */ bus->rxctl += doff; @@ -1818,17 +1797,13 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) } bus->tx_max = txmax; -#ifdef DEBUG - if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) { - printk(KERN_DEBUG "Rx Data:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - rxbuf, len); - } else if (BRCMF_HDRS_ON()) { - printk(KERN_DEBUG "RxHdr:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - bus->rxhdr, SDPCM_HDRLEN); - } -#endif + brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(), + rxbuf, len, "Rx Data:\n"); + brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() && + BRCMF_DATA_ON()) && + BRCMF_HDRS_ON(), + bus->rxhdr, SDPCM_HDRLEN, + "RxHdr:\n"); if (chan == SDPCM_CONTROL_CHANNEL) { brcmf_dbg(ERROR, "(nextlen): readahead on control packet %d?\n", @@ -1865,13 +1840,9 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) brcmf_sdbrcm_rxfail(bus, true, true); continue; } -#ifdef DEBUG - if (BRCMF_BYTES_ON() || BRCMF_HDRS_ON()) { - printk(KERN_DEBUG "RxHdr:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - bus->rxhdr, SDPCM_HDRLEN); - } -#endif + brcmf_dbg_hex_dump(BRCMF_BYTES_ON() || BRCMF_HDRS_ON(), + bus->rxhdr, SDPCM_HDRLEN, "RxHdr:\n"); + /* Extract hardware header fields */ len = get_unaligned_le16(bus->rxhdr); @@ -2024,13 +1995,8 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) skb_push(pkt, BRCMF_FIRSTREAD); memcpy(pkt->data, bus->rxhdr, BRCMF_FIRSTREAD); -#ifdef DEBUG - if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) { - printk(KERN_DEBUG "Rx Data:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - pkt->data, len); - } -#endif + brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(), + pkt->data, len, "Rx Data:\n"); deliver: /* Save superframe descriptor and allocate packet frame */ @@ -2038,14 +2004,9 @@ deliver: if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_FRAMETAG_LEN])) { brcmf_dbg(GLOM, "glom descriptor, %d bytes:\n", len); -#ifdef DEBUG - if (BRCMF_GLOM_ON()) { - printk(KERN_DEBUG "Glom Data:\n"); - print_hex_dump_bytes("", - DUMP_PREFIX_OFFSET, - pkt->data, len); - } -#endif + brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), + pkt->data, len, + "Glom Data:\n"); __skb_trim(pkt, len); skb_pull(pkt, SDPCM_HDRLEN); bus->glomd = pkt; @@ -2178,16 +2139,18 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, #ifdef DEBUG tx_packets[pkt->priority]++; - if (BRCMF_BYTES_ON() && - (((BRCMF_CTL_ON() && (chan == SDPCM_CONTROL_CHANNEL)) || - (BRCMF_DATA_ON() && (chan != SDPCM_CONTROL_CHANNEL))))) { - printk(KERN_DEBUG "Tx Frame:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, frame, len); - } else if (BRCMF_HDRS_ON()) { - printk(KERN_DEBUG "TxHdr:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - frame, min_t(u16, len, 16)); - } + + brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && + ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) || + (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL)), + frame, len, "Tx Frame:\n"); + brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() && + ((BRCMF_CTL_ON() && + chan == SDPCM_CONTROL_CHANNEL) || + (BRCMF_DATA_ON() && + chan != SDPCM_CONTROL_CHANNEL))) && + BRCMF_HDRS_ON(), + frame, min_t(u16, len, 16), "TxHdr:\n"); #endif /* Raise len to next SDIO block to eliminate tail command */ @@ -2982,17 +2945,11 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) } if (ret == -1) { -#ifdef DEBUG - if (BRCMF_BYTES_ON() && BRCMF_CTL_ON()) { - printk(KERN_DEBUG "Tx Frame:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - frame, len); - } else if (BRCMF_HDRS_ON()) { - printk(KERN_DEBUG "TxHdr:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - frame, min_t(u16, len, 16)); - } -#endif + brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(), + frame, len, "Tx Frame:\n"); + brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() && BRCMF_CTL_ON()) && + BRCMF_HDRS_ON(), + frame, min_t(u16, len, 16), "TxHdr:\n"); do { ret = brcmf_tx_frame(bus, frame, len); diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c index e25fb2da8e6..2207eaa34f8 100644 --- a/drivers/net/wireless/brcm80211/brcmutil/utils.c +++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c @@ -253,4 +253,22 @@ void brcmu_prpkt(const char *msg, struct sk_buff *p0) print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, p->data, p->len); } EXPORT_SYMBOL(brcmu_prpkt); + +void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + pr_debug("%pV", &vaf); + + va_end(args); + + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, data, size); +} +EXPORT_SYMBOL(brcmu_dbg_hex_dump); #endif /* defined(DEBUG) */ diff --git a/drivers/net/wireless/brcm80211/include/brcmu_utils.h b/drivers/net/wireless/brcm80211/include/brcmu_utils.h index 0cde38aa63f..477b92ad3d6 100644 --- a/drivers/net/wireless/brcm80211/include/brcmu_utils.h +++ b/drivers/net/wireless/brcm80211/include/brcmu_utils.h @@ -182,4 +182,15 @@ extern void brcmu_prpkt(const char *msg, struct sk_buff *p0); #define brcmu_prpkt(a, b) #endif /* DEBUG */ +#ifdef DEBUG +extern __printf(3, 4) +void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...); +#else +__printf(3, 4) +static inline +void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...) +{ +} +#endif + #endif /* _BRCMU_UTILS_H_ */ -- cgit v1.2.3-70-g09d2 From 8fb1eb8b221f1cf81128b7f681b5a5112bfcd3a2 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 15 Jan 2012 00:38:41 -0800 Subject: brcmfmac: Remove useless #ifdef DEBUG This doesn't do anything anymore. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 4ab1023352a..79230e7edb3 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -2039,13 +2039,11 @@ deliver: down(&bus->sdsem); } rxcount = maxframes - rxleft; -#ifdef DEBUG /* Message if we hit the limit */ if (!rxleft) brcmf_dbg(DATA, "hit rx limit of %d frames\n", maxframes); else -#endif /* DEBUG */ brcmf_dbg(DATA, "processed %d frames\n", rxcount); /* Back off rxseq if awaiting rtx, update rx_seq */ if (bus->rxskip) -- cgit v1.2.3-70-g09d2 From 18aad4f8e11530fd7e41d0faea0752c3a0ce799c Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 15 Jan 2012 00:38:42 -0800 Subject: brcm80211: Convert printk(KERN_DEBUG to pr_debug Use pr_debug to allow dynamic debugging to work. Move an #endif to allow brcmf_dbg_hex_dump to be outside the #if/#endif block. Move a const char* declaration to be inside a pr_debug so the function doesn't need a #if/#endif block. Don't use temporaries in debugging functions so the code can be optimized away. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmfmac/dhd_common.c | 4 +- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 11 +- drivers/net/wireless/brcm80211/brcmsmac/main.c | 147 ++++++++++----------- drivers/net/wireless/brcm80211/brcmsmac/main.h | 4 +- .../net/wireless/brcm80211/brcmsmac/phy/phy_n.c | 3 +- drivers/net/wireless/brcm80211/brcmutil/utils.c | 2 +- 6 files changed, 78 insertions(+), 93 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 9385c84646e..1c75ea887ac 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -399,10 +399,10 @@ brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data) p = (char *)&buf[sizeof(struct msgtrace_hdr)]; while ((s = strstr(p, "\n")) != NULL) { *s = '\0'; - printk(KERN_DEBUG"%s\n", p); + pr_debug("%s\n", p); p = s + 1; } - printk(KERN_DEBUG "%s\n", p); + pr_debug("%s\n", p); /* Reset datalen to avoid display below */ datalen = 0; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 79230e7edb3..91ec0235047 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -2137,6 +2137,7 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, #ifdef DEBUG tx_packets[pkt->priority]++; +#endif brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) || @@ -2149,7 +2150,6 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, chan != SDPCM_CONTROL_CHANNEL))) && BRCMF_HDRS_ON(), frame, min_t(u16, len, 16), "TxHdr:\n"); -#endif /* Raise len to next SDIO block to eliminate tail command */ if (bus->roundup && bus->blocksize && (len > bus->blocksize)) { @@ -2806,7 +2806,7 @@ static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus) if (line[n - 1] == '\r') n--; line[n] = 0; - printk(KERN_DEBUG "CONSOLE: %s\n", line); + pr_debug("CONSOLE: %s\n", line); } } break2: @@ -3676,11 +3676,8 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) if (brcmf_sdcard_set_sbaddr_window(bus->sdiodev, SI_ENUM_BASE)) brcmf_dbg(ERROR, "FAILED to return to SI_ENUM_BASE\n"); -#ifdef DEBUG - printk(KERN_DEBUG "F1 signature read @0x18000000=0x%4x\n", - brcmf_sdcard_reg_read(bus->sdiodev, SI_ENUM_BASE, 4)); - -#endif /* DEBUG */ + pr_debug("F1 signature read @0x18000000=0x%4x\n", + brcmf_sdcard_reg_read(bus->sdiodev, SI_ENUM_BASE, 4)); /* * Force PLL off until brcmf_sdio_chip_attach() diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 3ae07bb9cc6..14ab606de74 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -5765,56 +5765,43 @@ int brcms_c_module_unregister(struct brcms_pub *pub, const char *name, return -ENODATA; } -#ifdef DEBUG -static const char * const supr_reason[] = { - "None", "PMQ Entry", "Flush request", - "Previous frag failure", "Channel mismatch", - "Lifetime Expiry", "Underflow" -}; - -static void brcms_c_print_txs_status(u16 s) -{ - printk(KERN_DEBUG "[15:12] %d frame attempts\n", - (s & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT); - printk(KERN_DEBUG " [11:8] %d rts attempts\n", - (s & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT); - printk(KERN_DEBUG " [7] %d PM mode indicated\n", - ((s & TX_STATUS_PMINDCTD) ? 1 : 0)); - printk(KERN_DEBUG " [6] %d intermediate status\n", - ((s & TX_STATUS_INTERMEDIATE) ? 1 : 0)); - printk(KERN_DEBUG " [5] %d AMPDU\n", - (s & TX_STATUS_AMPDU) ? 1 : 0); - printk(KERN_DEBUG " [4:2] %d Frame Suppressed Reason (%s)\n", - ((s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT), - supr_reason[(s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT]); - printk(KERN_DEBUG " [1] %d acked\n", - ((s & TX_STATUS_ACK_RCV) ? 1 : 0)); -} -#endif /* DEBUG */ - void brcms_c_print_txstatus(struct tx_status *txs) { -#if defined(DEBUG) - u16 s = txs->status; - u16 ackphyrxsh = txs->ackphyrxsh; - - printk(KERN_DEBUG "\ntxpkt (MPDU) Complete\n"); - - printk(KERN_DEBUG "FrameID: %04x ", txs->frameid); - printk(KERN_DEBUG "TxStatus: %04x", s); - printk(KERN_DEBUG "\n"); - - brcms_c_print_txs_status(s); - - printk(KERN_DEBUG "LastTxTime: %04x ", txs->lasttxtime); - printk(KERN_DEBUG "Seq: %04x ", txs->sequence); - printk(KERN_DEBUG "PHYTxStatus: %04x ", txs->phyerr); - printk(KERN_DEBUG "RxAckRSSI: %04x ", - (ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT); - printk(KERN_DEBUG "RxAckSQ: %04x", - (ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT); - printk(KERN_DEBUG "\n"); -#endif /* defined(DEBUG) */ + pr_debug("\ntxpkt (MPDU) Complete\n"); + + pr_debug("FrameID: %04x TxStatus: %04x\n", txs->frameid, txs->status); + + pr_debug("[15:12] %d frame attempts\n", + (txs->status & TX_STATUS_FRM_RTX_MASK) >> + TX_STATUS_FRM_RTX_SHIFT); + pr_debug(" [11:8] %d rts attempts\n", + (txs->status & TX_STATUS_RTS_RTX_MASK) >> + TX_STATUS_RTS_RTX_SHIFT); + pr_debug(" [7] %d PM mode indicated\n", + txs->status & TX_STATUS_PMINDCTD ? 1 : 0); + pr_debug(" [6] %d intermediate status\n", + txs->status & TX_STATUS_INTERMEDIATE ? 1 : 0); + pr_debug(" [5] %d AMPDU\n", + txs->status & TX_STATUS_AMPDU ? 1 : 0); + pr_debug(" [4:2] %d Frame Suppressed Reason (%s)\n", + (txs->status & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT, + (const char *[]) { + "None", + "PMQ Entry", + "Flush request", + "Previous frag failure", + "Channel mismatch", + "Lifetime Expiry", + "Underflow" + } [(txs->status & TX_STATUS_SUPR_MASK) >> + TX_STATUS_SUPR_SHIFT]); + pr_debug(" [1] %d acked\n", + txs->status & TX_STATUS_ACK_RCV ? 1 : 0); + + pr_debug("LastTxTime: %04x Seq: %04x PHYTxStatus: %04x RxAckRSSI: %04x RxAckSQ: %04x\n", + txs->lasttxtime, txs->sequence, txs->phyerr, + (txs->ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT, + (txs->ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT); } bool brcms_c_chipmatch(u16 vendor, u16 device) @@ -5871,53 +5858,53 @@ void brcms_c_print_txdesc(struct d11txh *txh) struct ieee80211_rts rts = txh->rts_frame; /* add plcp header along with txh descriptor */ - printk(KERN_DEBUG "Raw TxDesc + plcp header:\n"); + pr_debug("Raw TxDesc + plcp header:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, txh, sizeof(struct d11txh) + 48); - printk(KERN_DEBUG "TxCtlLow: %04x ", mtcl); - printk(KERN_DEBUG "TxCtlHigh: %04x ", mtch); - printk(KERN_DEBUG "FC: %04x ", mfc); - printk(KERN_DEBUG "FES Time: %04x\n", tfest); - printk(KERN_DEBUG "PhyCtl: %04x%s ", ptcw, + pr_debug("TxCtlLow: %04x ", mtcl); + pr_debug("TxCtlHigh: %04x ", mtch); + pr_debug("FC: %04x ", mfc); + pr_debug("FES Time: %04x\n", tfest); + pr_debug("PhyCtl: %04x%s ", ptcw, (ptcw & PHY_TXC_SHORT_HDR) ? " short" : ""); - printk(KERN_DEBUG "PhyCtl_1: %04x ", ptcw_1); - printk(KERN_DEBUG "PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr); - printk(KERN_DEBUG "PhyCtl_1_Rts: %04x ", ptcw_1_Rts); - printk(KERN_DEBUG "PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts); - printk(KERN_DEBUG "MainRates: %04x ", mainrates); - printk(KERN_DEBUG "XtraFrameTypes: %04x ", xtraft); - printk(KERN_DEBUG "\n"); + pr_debug("PhyCtl_1: %04x ", ptcw_1); + pr_debug("PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr); + pr_debug("PhyCtl_1_Rts: %04x ", ptcw_1_Rts); + pr_debug("PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts); + pr_debug("MainRates: %04x ", mainrates); + pr_debug("XtraFrameTypes: %04x ", xtraft); + pr_debug("\n"); print_hex_dump_bytes("SecIV:", DUMP_PREFIX_OFFSET, iv, sizeof(txh->IV)); print_hex_dump_bytes("RA:", DUMP_PREFIX_OFFSET, ra, sizeof(txh->TxFrameRA)); - printk(KERN_DEBUG "Fb FES Time: %04x ", tfestfb); + pr_debug("Fb FES Time: %04x ", tfestfb); print_hex_dump_bytes("Fb RTS PLCP:", DUMP_PREFIX_OFFSET, rtspfb, sizeof(txh->RTSPLCPFallback)); - printk(KERN_DEBUG "RTS DUR: %04x ", rtsdfb); + pr_debug("RTS DUR: %04x ", rtsdfb); print_hex_dump_bytes("PLCP:", DUMP_PREFIX_OFFSET, fragpfb, sizeof(txh->FragPLCPFallback)); - printk(KERN_DEBUG "DUR: %04x", fragdfb); - printk(KERN_DEBUG "\n"); + pr_debug("DUR: %04x", fragdfb); + pr_debug("\n"); - printk(KERN_DEBUG "MModeLen: %04x ", mmodelen); - printk(KERN_DEBUG "MModeFbrLen: %04x\n", mmodefbrlen); + pr_debug("MModeLen: %04x ", mmodelen); + pr_debug("MModeFbrLen: %04x\n", mmodefbrlen); - printk(KERN_DEBUG "FrameID: %04x\n", tfid); - printk(KERN_DEBUG "TxStatus: %04x\n", txs); + pr_debug("FrameID: %04x\n", tfid); + pr_debug("TxStatus: %04x\n", txs); - printk(KERN_DEBUG "MaxNumMpdu: %04x\n", mnmpdu); - printk(KERN_DEBUG "MaxAggbyte: %04x\n", mabyte); - printk(KERN_DEBUG "MaxAggbyte_fb: %04x\n", mabyte_f); - printk(KERN_DEBUG "MinByte: %04x\n", mmbyte); + pr_debug("MaxNumMpdu: %04x\n", mnmpdu); + pr_debug("MaxAggbyte: %04x\n", mabyte); + pr_debug("MaxAggbyte_fb: %04x\n", mabyte_f); + pr_debug("MinByte: %04x\n", mmbyte); print_hex_dump_bytes("RTS PLCP:", DUMP_PREFIX_OFFSET, rtsph, sizeof(txh->RTSPhyHeader)); print_hex_dump_bytes("RTS Frame:", DUMP_PREFIX_OFFSET, (u8 *)&rts, sizeof(txh->rts_frame)); - printk(KERN_DEBUG "\n"); + pr_debug("\n"); } #endif /* defined(DEBUG) */ @@ -5999,7 +5986,7 @@ void brcms_c_print_rxh(struct d11rxhdr *rxh) {0, NULL} }; - printk(KERN_DEBUG "Raw RxDesc:\n"); + pr_debug("Raw RxDesc:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, rxh, sizeof(struct d11rxhdr)); @@ -6007,14 +5994,14 @@ void brcms_c_print_rxh(struct d11rxhdr *rxh) snprintf(lenbuf, sizeof(lenbuf), "0x%x", len); - printk(KERN_DEBUG "RxFrameSize: %6s (%d)%s\n", lenbuf, len, + pr_debug("RxFrameSize: %6s (%d)%s\n", lenbuf, len, (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : ""); - printk(KERN_DEBUG "RxPHYStatus: %04x %04x %04x %04x\n", + pr_debug("RxPHYStatus: %04x %04x %04x %04x\n", phystatus_0, phystatus_1, phystatus_2, phystatus_3); - printk(KERN_DEBUG "RxMACStatus: %x %s\n", macstatus1, flagstr); - printk(KERN_DEBUG "RXMACaggtype: %x\n", + pr_debug("RxMACStatus: %x %s\n", macstatus1, flagstr); + pr_debug("RXMACaggtype: %x\n", (macstatus2 & RXS_AGGTYPE_MASK)); - printk(KERN_DEBUG "RxTSFTime: %04x\n", rxh->RxTSFTime); + pr_debug("RxTSFTime: %04x\n", rxh->RxTSFTime); } #endif /* defined(DEBUG) */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h index 84a2a0d9dd3..8debc74c54e 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h @@ -651,7 +651,9 @@ extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, #if defined(DEBUG) extern void brcms_c_print_txdesc(struct d11txh *txh); #else -#define brcms_c_print_txdesc(a) +static inline void brcms_c_print_txdesc(struct d11txh *txh) +{ +} #endif extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config); diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c index a16f1ab292f..a0909be6ef3 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c @@ -26434,8 +26434,7 @@ cal_try: } if (bcmerror != 0) { - printk(KERN_DEBUG "%s: Failed, cnt = %d\n", __func__, - cal_retry); + pr_debug("%s: Failed, cnt = %d\n", __func__, cal_retry); if (cal_retry < CAL_RETRY_CNT) { cal_retry++; diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c index 2207eaa34f8..49086606485 100644 --- a/drivers/net/wireless/brcm80211/brcmutil/utils.c +++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c @@ -247,7 +247,7 @@ void brcmu_prpkt(const char *msg, struct sk_buff *p0) struct sk_buff *p; if (msg && (msg[0] != '\0')) - printk(KERN_DEBUG "%s:\n", msg); + pr_debug("%s:\n", msg); for (p = p0; p; p = p->next) print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, p->data, p->len); -- cgit v1.2.3-70-g09d2 From c2e6d5abab73df316d2ae7caa6d902c143b2d52d Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 15 Jan 2012 00:38:43 -0800 Subject: brcm80211: Use brcmu_dbg_hex_dump Convert a couple of pr_debug/print_hex_dump to the standard utility. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmsmac/main.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 14ab606de74..72701a4bf89 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -5858,9 +5858,8 @@ void brcms_c_print_txdesc(struct d11txh *txh) struct ieee80211_rts rts = txh->rts_frame; /* add plcp header along with txh descriptor */ - pr_debug("Raw TxDesc + plcp header:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - txh, sizeof(struct d11txh) + 48); + brcmu_dbg_hex_dump(txh, sizeof(struct d11txh) + 48, + "Raw TxDesc + plcp header:\n"); pr_debug("TxCtlLow: %04x ", mtcl); pr_debug("TxCtlHigh: %04x ", mtch); @@ -5986,9 +5985,7 @@ void brcms_c_print_rxh(struct d11rxhdr *rxh) {0, NULL} }; - pr_debug("Raw RxDesc:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, rxh, - sizeof(struct d11rxhdr)); + brcmu_dbg_hex_dump(rxh, sizeof(struct d11rxhdr), "Raw RxDesc:\n"); brcms_c_format_flags(macstat_flags, macstatus1, flagstr, 64); -- cgit v1.2.3-70-g09d2 From 02f77195db6ce252d5488b6d48d8edc1c5e2aa30 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 15 Jan 2012 00:38:44 -0800 Subject: brcm80211: Use pr_fmt and pr_ Convert printks to pr_ Prefix logging with pr_fmt. Use ##__VA_ARGS__ in some WL_ logging macros. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 2 ++ .../net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 3 +++ drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c | 2 ++ .../net/wireless/brcm80211/brcmfmac/dhd_common.c | 3 +++ .../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 2 ++ drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 8 +++--- .../net/wireless/brcm80211/brcmfmac/sdio_chip.c | 2 ++ .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 2 ++ .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.h | 30 +++++++++++----------- .../net/wireless/brcm80211/brcmsmac/mac80211_if.c | 6 ++--- drivers/net/wireless/brcm80211/brcmsmac/main.c | 6 +++-- .../net/wireless/brcm80211/brcmsmac/phy/phy_n.c | 2 ++ drivers/net/wireless/brcm80211/brcmutil/utils.c | 2 ++ 13 files changed, 46 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 4bc8d251acf..e925290b432 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -15,6 +15,8 @@ */ /* ****************** SDIO CARD Interface Functions **************************/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 9b8c0ed833d..ac71adeece5 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -13,6 +13,9 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c index ac8d1f43788..b3e3b7f25d8 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c @@ -19,6 +19,8 @@ * For certain dcmd codes, the dongle interprets string data from the host. ******************************************************************************/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 1c75ea887ac..4187435220f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -13,6 +13,9 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 16fd1ab3540..db2df1f1e6b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -14,6 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 91ec0235047..6e4b5e85a09 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -14,6 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -3896,8 +3898,7 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) bus->watchdog_tsk = kthread_run(brcmf_sdbrcm_watchdog_thread, bus, "brcmf_watchdog"); if (IS_ERR(bus->watchdog_tsk)) { - printk(KERN_WARNING - "brcmf_watchdog thread failed to start\n"); + pr_warn("brcmf_watchdog thread failed to start\n"); bus->watchdog_tsk = NULL; } /* Initialize DPC thread */ @@ -3905,8 +3906,7 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) bus->dpc_tsk = kthread_run(brcmf_sdbrcm_dpc_thread, bus, "brcmf_dpc"); if (IS_ERR(bus->dpc_tsk)) { - printk(KERN_WARNING - "brcmf_dpc thread failed to start\n"); + pr_warn("brcmf_dpc thread failed to start\n"); bus->dpc_tsk = NULL; } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c index 11b2d7c97ba..1534efc2163 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c @@ -15,6 +15,8 @@ */ /* ***** SDIO interface chip backplane handle functions ***** */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index bf11850a20f..886b0ccbc5c 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -16,6 +16,8 @@ /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h index 69a48729a72..b5d9b36df3d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h @@ -32,53 +32,53 @@ struct brcmf_cfg80211_ibss; #define WL_DBG_MASK ((WL_DBG_INFO | WL_DBG_ERR | WL_DBG_TRACE) | \ (WL_DBG_SCAN) | (WL_DBG_CONN)) -#define WL_ERR(fmt, args...) \ +#define WL_ERR(fmt, ...) \ do { \ if (brcmf_dbg_level & WL_DBG_ERR) { \ if (net_ratelimit()) { \ - printk(KERN_ERR "ERROR @%s : " fmt, \ - __func__, ##args); \ + pr_err("ERROR @%s : " fmt, \ + __func__, ##__VA_ARGS__); \ } \ } \ } while (0) #if (defined DEBUG) -#define WL_INFO(fmt, args...) \ +#define WL_INFO(fmt, ...) \ do { \ if (brcmf_dbg_level & WL_DBG_INFO) { \ if (net_ratelimit()) { \ - printk(KERN_ERR "INFO @%s : " fmt, \ - __func__, ##args); \ + pr_err("INFO @%s : " fmt, \ + __func__, ##__VA_ARGS__); \ } \ } \ } while (0) -#define WL_TRACE(fmt, args...) \ +#define WL_TRACE(fmt, ...) \ do { \ if (brcmf_dbg_level & WL_DBG_TRACE) { \ if (net_ratelimit()) { \ - printk(KERN_ERR "TRACE @%s : " fmt, \ - __func__, ##args); \ + pr_err("TRACE @%s : " fmt, \ + __func__, ##__VA_ARGS__); \ } \ } \ } while (0) -#define WL_SCAN(fmt, args...) \ +#define WL_SCAN(fmt, ...) \ do { \ if (brcmf_dbg_level & WL_DBG_SCAN) { \ if (net_ratelimit()) { \ - printk(KERN_ERR "SCAN @%s : " fmt, \ - __func__, ##args); \ + pr_err("SCAN @%s : " fmt, \ + __func__, ##__VA_ARGS__); \ } \ } \ } while (0) -#define WL_CONN(fmt, args...) \ +#define WL_CONN(fmt, ...) \ do { \ if (brcmf_dbg_level & WL_DBG_CONN) { \ if (net_ratelimit()) { \ - printk(KERN_ERR "CONN @%s : " fmt, \ - __func__, ##args); \ + pr_err("CONN @%s : " fmt, \ + __func__, ##__VA_ARGS__); \ } \ } \ } while (0) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 04ba9a878f4..c8427978d09 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c @@ -15,6 +15,7 @@ */ #define __UNDEF_NO_VERSION__ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include #include @@ -1121,8 +1122,7 @@ static int __devinit brcms_bcma_probe(struct bcma_device *pdev) wl = brcms_attach(pdev); if (!wl) { - pr_err("%s: %s: brcms_attach failed!\n", KBUILD_MODNAME, - __func__); + pr_err("%s: brcms_attach failed!\n", __func__); return -ENODEV; } return 0; @@ -1183,7 +1183,7 @@ static int __init brcms_module_init(void) #endif /* DEBUG */ error = bcma_driver_register(&brcms_bcma_driver); - printk(KERN_ERR "%s: register returned %d\n", __func__, error); + pr_err("%s: register returned %d\n", __func__, error); if (!error) return 0; diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 72701a4bf89..976a53183f6 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -14,6 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -5807,7 +5809,7 @@ void brcms_c_print_txstatus(struct tx_status *txs) bool brcms_c_chipmatch(u16 vendor, u16 device) { if (vendor != PCI_VENDOR_ID_BROADCOM) { - pr_err("chipmatch: unknown vendor id %04x\n", vendor); + pr_err("unknown vendor id %04x\n", vendor); return false; } @@ -5820,7 +5822,7 @@ bool brcms_c_chipmatch(u16 vendor, u16 device) if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID)) return true; - pr_err("chipmatch: unknown device id %04x\n", device); + pr_err("unknown device id %04x\n", device); return false; } diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c index a0909be6ef3..ec7450d2fbd 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c @@ -14,6 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c index 49086606485..b45ab34cdfd 100644 --- a/drivers/net/wireless/brcm80211/brcmutil/utils.c +++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c @@ -14,6 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include -- cgit v1.2.3-70-g09d2 From bfeb4dbc5cb36ae774fabe7b0e0d559e621a2ccd Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 15 Jan 2012 00:38:45 -0800 Subject: brcmfmac: Trivial typo of "couldn" to "could" fix Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 886b0ccbc5c..74c95a59795 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -2785,7 +2785,7 @@ static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface, wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_priv) + sizeof_iface); if (!wdev->wiphy) { - WL_ERR("Couldn not allocate wiphy device\n"); + WL_ERR("Could not allocate wiphy device\n"); err = -ENOMEM; goto wiphy_new_out; } @@ -2811,7 +2811,7 @@ static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface, */ err = wiphy_register(wdev->wiphy); if (err < 0) { - WL_ERR("Couldn not register wiphy device (%d)\n", err); + WL_ERR("Could not register wiphy device (%d)\n", err); goto wiphy_register_out; } return wdev; -- cgit v1.2.3-70-g09d2 From 3ed1326d2e693d555e62241c2e2209f01506214e Mon Sep 17 00:00:00 2001 From: Ilan Elias Date: Tue, 17 Jan 2012 14:11:31 +0200 Subject: NFC: Add endian annotations to nfcwilink driver Add endian annotations to TI nfcwilink driver. Signed-off-by: Ilan Elias Acked-by: Samuel Ortiz Signed-off-by: John W. Linville --- drivers/nfc/nfcwilink.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/nfc/nfcwilink.c b/drivers/nfc/nfcwilink.c index 06c3642e5bd..ee60d084433 100644 --- a/drivers/nfc/nfcwilink.c +++ b/drivers/nfc/nfcwilink.c @@ -28,6 +28,7 @@ */ #include #include +#include #include #include #include @@ -42,9 +43,9 @@ #define NFCWILINK_REGISTER_TIMEOUT 8000 /* 8 sec */ struct nfcwilink_hdr { - u8 chnl; - u8 opcode; - u16 len; + __u8 chnl; + __u8 opcode; + __le16 len; } __packed; struct nfcwilink { @@ -212,7 +213,7 @@ static int nfcwilink_send(struct sk_buff *skb) return -EBUSY; /* add the ST hdr to the start of the buffer */ - hdr.len = skb->len; + hdr.len = cpu_to_le16(skb->len); memcpy(skb_push(skb, NFCWILINK_HDR_LEN), &hdr, NFCWILINK_HDR_LEN); /* Insert skb to shared transport layer's transmit queue. @@ -239,7 +240,7 @@ static int nfcwilink_probe(struct platform_device *pdev) { static struct nfcwilink *drv; int rc; - u32 protocols; + __u32 protocols; nfc_dev_dbg(&pdev->dev, "probe entry"); -- cgit v1.2.3-70-g09d2 From 1195d89b2defd92829ed54938e60312e62dc8747 Mon Sep 17 00:00:00 2001 From: Ilan Elias Date: Tue, 17 Jan 2012 14:11:32 +0200 Subject: NFC: Download TI NFC init script Download TI NFC init script during nfcwilink open operation, after the NFC channel is registered with TI shared transport. TI NFC init script is written in BTS format. First, read the chip version via a special vendor specific command. Second, we request the relevant BTS file from the user space, and then send the BTS commands to the chip. Signed-off-by: Ilan Elias Acked-by: Samuel Ortiz Signed-off-by: John W. Linville --- drivers/nfc/nfcwilink.c | 288 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 284 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/nfc/nfcwilink.c b/drivers/nfc/nfcwilink.c index ee60d084433..90af28d611f 100644 --- a/drivers/nfc/nfcwilink.c +++ b/drivers/nfc/nfcwilink.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,17 @@ #define NFCWILINK_OFFSET_LEN_IN_HDR 1 #define NFCWILINK_LEN_SIZE 2 #define NFCWILINK_REGISTER_TIMEOUT 8000 /* 8 sec */ +#define NFCWILINK_CMD_TIMEOUT 5000 /* 5 sec */ + +#define BTS_FILE_NAME_MAX_SIZE 40 +#define BTS_FILE_HDR_MAGIC 0x42535442 +#define BTS_FILE_CMD_MAX_LEN 0xff +#define BTS_FILE_ACTION_TYPE_SEND_CMD 1 + +#define NCI_VS_NFCC_INFO_CMD_GID 0x2f +#define NCI_VS_NFCC_INFO_CMD_OID 0x12 +#define NCI_VS_NFCC_INFO_RSP_GID 0x4f +#define NCI_VS_NFCC_INFO_RSP_OID 0x12 struct nfcwilink_hdr { __u8 chnl; @@ -48,6 +60,36 @@ struct nfcwilink_hdr { __le16 len; } __packed; +struct nci_vs_nfcc_info_cmd { + __u8 gid; + __u8 oid; + __u8 plen; +} __packed; + +struct nci_vs_nfcc_info_rsp { + __u8 gid; + __u8 oid; + __u8 plen; + __u8 status; + __u8 hw_id; + __u8 sw_ver_x; + __u8 sw_ver_z; + __u8 patch_id; +} __packed; + +struct bts_file_hdr { + __le32 magic; + __le32 ver; + __u8 rfu[24]; + __u8 actions[0]; +} __packed; + +struct bts_file_action { + __le16 type; + __le16 len; + __u8 data[0]; +} __packed; + struct nfcwilink { struct platform_device *pdev; struct nci_dev *ndev; @@ -55,14 +97,241 @@ struct nfcwilink { char st_register_cb_status; long (*st_write) (struct sk_buff *); - struct completion st_register_completed; + + struct completion completed; + + struct nci_vs_nfcc_info_rsp nfcc_info; }; /* NFCWILINK driver flags */ enum { NFCWILINK_RUNNING, + NFCWILINK_FW_DOWNLOAD, }; +static int nfcwilink_send(struct sk_buff *skb); + +static inline struct sk_buff *nfcwilink_skb_alloc(unsigned int len, gfp_t how) +{ + struct sk_buff *skb; + + skb = alloc_skb(len + NFCWILINK_HDR_LEN, how); + if (skb) + skb_reserve(skb, NFCWILINK_HDR_LEN); + + return skb; +} + +static void nfcwilink_fw_download_receive(struct nfcwilink *drv, + struct sk_buff *skb) +{ + struct nci_vs_nfcc_info_rsp *rsp = (void *)skb->data; + + /* Detect NCI_VS_NFCC_INFO_RSP and store the result */ + if ((skb->len > 3) && (rsp->gid == NCI_VS_NFCC_INFO_RSP_GID) && + (rsp->oid == NCI_VS_NFCC_INFO_RSP_OID)) { + memcpy(&drv->nfcc_info, rsp, + sizeof(struct nci_vs_nfcc_info_rsp)); + } + + kfree_skb(skb); + + complete(&drv->completed); +} + +static int nfcwilink_get_bts_file_name(struct nfcwilink *drv, char *file_name) +{ + struct nci_vs_nfcc_info_cmd *cmd; + struct sk_buff *skb; + unsigned long comp_ret; + int rc; + + nfc_dev_dbg(&drv->pdev->dev, "get_bts_file_name entry"); + + skb = nfcwilink_skb_alloc(sizeof(struct nci_vs_nfcc_info_cmd), + GFP_KERNEL); + if (!skb) { + nfc_dev_err(&drv->pdev->dev, + "no memory for nci_vs_nfcc_info_cmd"); + return -ENOMEM; + } + + skb->dev = (void *)drv->ndev; + + cmd = (struct nci_vs_nfcc_info_cmd *) + skb_put(skb, sizeof(struct nci_vs_nfcc_info_cmd)); + cmd->gid = NCI_VS_NFCC_INFO_CMD_GID; + cmd->oid = NCI_VS_NFCC_INFO_CMD_OID; + cmd->plen = 0; + + drv->nfcc_info.plen = 0; + + rc = nfcwilink_send(skb); + if (rc) + return rc; + + comp_ret = wait_for_completion_timeout(&drv->completed, + msecs_to_jiffies(NFCWILINK_CMD_TIMEOUT)); + nfc_dev_dbg(&drv->pdev->dev, "wait_for_completion_timeout returned %ld", + comp_ret); + if (comp_ret == 0) { + nfc_dev_err(&drv->pdev->dev, + "timeout on wait_for_completion_timeout"); + return -ETIMEDOUT; + } + + nfc_dev_dbg(&drv->pdev->dev, "nci_vs_nfcc_info_rsp: plen %d, status %d", + drv->nfcc_info.plen, + drv->nfcc_info.status); + + if ((drv->nfcc_info.plen != 5) || (drv->nfcc_info.status != 0)) { + nfc_dev_err(&drv->pdev->dev, + "invalid nci_vs_nfcc_info_rsp"); + return -EINVAL; + } + + snprintf(file_name, BTS_FILE_NAME_MAX_SIZE, + "TINfcInit_%d.%d.%d.%d.bts", + drv->nfcc_info.hw_id, + drv->nfcc_info.sw_ver_x, + drv->nfcc_info.sw_ver_z, + drv->nfcc_info.patch_id); + + nfc_dev_info(&drv->pdev->dev, "nfcwilink FW file name: %s", file_name); + + return 0; +} + +static int nfcwilink_send_bts_cmd(struct nfcwilink *drv, __u8 *data, int len) +{ + struct nfcwilink_hdr *hdr = (struct nfcwilink_hdr *)data; + struct sk_buff *skb; + unsigned long comp_ret; + int rc; + + nfc_dev_dbg(&drv->pdev->dev, "send_bts_cmd entry"); + + /* verify valid cmd for the NFC channel */ + if ((len <= sizeof(struct nfcwilink_hdr)) || + (len > BTS_FILE_CMD_MAX_LEN) || + (hdr->chnl != NFCWILINK_CHNL) || + (hdr->opcode != NFCWILINK_OPCODE)) { + nfc_dev_err(&drv->pdev->dev, + "ignoring invalid bts cmd, len %d, chnl %d, opcode %d", + len, hdr->chnl, hdr->opcode); + return 0; + } + + /* remove the ST header */ + len -= sizeof(struct nfcwilink_hdr); + data += sizeof(struct nfcwilink_hdr); + + skb = nfcwilink_skb_alloc(len, GFP_KERNEL); + if (!skb) { + nfc_dev_err(&drv->pdev->dev, "no memory for bts cmd"); + return -ENOMEM; + } + + skb->dev = (void *)drv->ndev; + + memcpy(skb_put(skb, len), data, len); + + rc = nfcwilink_send(skb); + if (rc) + return rc; + + comp_ret = wait_for_completion_timeout(&drv->completed, + msecs_to_jiffies(NFCWILINK_CMD_TIMEOUT)); + nfc_dev_dbg(&drv->pdev->dev, "wait_for_completion_timeout returned %ld", + comp_ret); + if (comp_ret == 0) { + nfc_dev_err(&drv->pdev->dev, + "timeout on wait_for_completion_timeout"); + return -ETIMEDOUT; + } + + return 0; +} + +static int nfcwilink_download_fw(struct nfcwilink *drv) +{ + unsigned char file_name[BTS_FILE_NAME_MAX_SIZE]; + const struct firmware *fw; + __u16 action_type, action_len; + __u8 *ptr; + int len, rc; + + nfc_dev_dbg(&drv->pdev->dev, "download_fw entry"); + + set_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags); + + rc = nfcwilink_get_bts_file_name(drv, file_name); + if (rc) + goto exit; + + rc = request_firmware(&fw, file_name, &drv->pdev->dev); + if (rc) { + nfc_dev_err(&drv->pdev->dev, "request_firmware failed %d", rc); + + /* if the file is not found, don't exit with failure */ + if (rc == -ENOENT) + rc = 0; + + goto exit; + } + + len = fw->size; + ptr = (__u8 *)fw->data; + + if ((len == 0) || (ptr == NULL)) { + nfc_dev_dbg(&drv->pdev->dev, + "request_firmware returned size %d", len); + goto release_fw; + } + + if (__le32_to_cpu(((struct bts_file_hdr *)ptr)->magic) != + BTS_FILE_HDR_MAGIC) { + nfc_dev_err(&drv->pdev->dev, "wrong bts magic number"); + rc = -EINVAL; + goto release_fw; + } + + /* remove the BTS header */ + len -= sizeof(struct bts_file_hdr); + ptr += sizeof(struct bts_file_hdr); + + while (len > 0) { + action_type = + __le16_to_cpu(((struct bts_file_action *)ptr)->type); + action_len = + __le16_to_cpu(((struct bts_file_action *)ptr)->len); + + nfc_dev_dbg(&drv->pdev->dev, "bts_file_action type %d, len %d", + action_type, action_len); + + switch (action_type) { + case BTS_FILE_ACTION_TYPE_SEND_CMD: + rc = nfcwilink_send_bts_cmd(drv, + ((struct bts_file_action *)ptr)->data, + action_len); + if (rc) + goto release_fw; + break; + } + + /* advance to the next action */ + len -= (sizeof(struct bts_file_action) + action_len); + ptr += (sizeof(struct bts_file_action) + action_len); + } + +release_fw: + release_firmware(fw); + +exit: + clear_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags); + return rc; +} + /* Called by ST when registration is complete */ static void nfcwilink_register_complete(void *priv_data, char data) { @@ -74,7 +343,7 @@ static void nfcwilink_register_complete(void *priv_data, char data) drv->st_register_cb_status = data; /* complete the wait in nfc_st_open() */ - complete(&drv->st_register_completed); + complete(&drv->completed); } /* Called by ST when receive data is available */ @@ -97,6 +366,11 @@ static long nfcwilink_receive(void *priv_data, struct sk_buff *skb) (apart for the chnl byte, which is not received in the hdr) */ skb_pull(skb, (NFCWILINK_HDR_LEN-1)); + if (test_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags)) { + nfcwilink_fw_download_receive(drv, skb); + return 0; + } + skb->dev = (void *) drv->ndev; /* Forward skb to NCI core layer */ @@ -137,14 +411,14 @@ static int nfcwilink_open(struct nci_dev *ndev) nfcwilink_proto.priv_data = drv; - init_completion(&drv->st_register_completed); + init_completion(&drv->completed); drv->st_register_cb_status = -EINPROGRESS; rc = st_register(&nfcwilink_proto); if (rc < 0) { if (rc == -EINPROGRESS) { comp_ret = wait_for_completion_timeout( - &drv->st_register_completed, + &drv->completed, msecs_to_jiffies(NFCWILINK_REGISTER_TIMEOUT)); nfc_dev_dbg(&drv->pdev->dev, @@ -172,6 +446,12 @@ static int nfcwilink_open(struct nci_dev *ndev) BUG_ON(nfcwilink_proto.write == NULL); drv->st_write = nfcwilink_proto.write; + if (nfcwilink_download_fw(drv)) { + nfc_dev_err(&drv->pdev->dev, "nfcwilink_download_fw failed %d", + rc); + /* open should succeed, even if the FW download failed */ + } + goto exit; clear_exit: -- cgit v1.2.3-70-g09d2 From ea9917d6f9e355646258b8d08ac69108908618a2 Mon Sep 17 00:00:00 2001 From: Ilan Elias Date: Tue, 17 Jan 2012 14:11:33 +0200 Subject: NFC: Free sk_buff if nfcwilink_send fails Free sk_buff if nfcwilink_send fails. Signed-off-by: Ilan Elias Acked-by: Samuel Ortiz Signed-off-by: John W. Linville --- drivers/nfc/nfcwilink.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/nfc/nfcwilink.c b/drivers/nfc/nfcwilink.c index 90af28d611f..1f74a77d040 100644 --- a/drivers/nfc/nfcwilink.c +++ b/drivers/nfc/nfcwilink.c @@ -489,8 +489,10 @@ static int nfcwilink_send(struct sk_buff *skb) nfc_dev_dbg(&drv->pdev->dev, "send entry, len %d", skb->len); - if (!test_bit(NFCWILINK_RUNNING, &drv->flags)) - return -EBUSY; + if (!test_bit(NFCWILINK_RUNNING, &drv->flags)) { + kfree_skb(skb); + return -EINVAL; + } /* add the ST hdr to the start of the buffer */ hdr.len = cpu_to_le16(skb->len); -- cgit v1.2.3-70-g09d2 From d7d312cab41b2c973951fcc7f752411cbaaf8338 Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Tue, 17 Jan 2012 23:13:30 +0100 Subject: ath9k_htc: claim support for IBSS RSN Skip group keys configuration in hardware in order to make IBSS RSN work. Keys will be managed using software. Signed-off-by: Antonio Quartulli Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 2 ++ drivers/net/wireless/ath/ath9k/htc_drv_main.c | 15 +++++++++++++++ 2 files changed, 17 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 9be10a2da1c..fc7519c9339 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -741,6 +741,8 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; + hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; + hw->queues = 4; hw->channel_change_time = 5000; hw->max_listen_interval = 10; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index ef4c6066129..06101b6bdea 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1409,6 +1409,21 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw, if (htc_modparam_nohwcrypt) return -ENOSPC; + if ((vif->type == NL80211_IFTYPE_ADHOC || + vif->type == NL80211_IFTYPE_MESH_POINT) && + (key->cipher == WLAN_CIPHER_SUITE_TKIP || + key->cipher == WLAN_CIPHER_SUITE_CCMP) && + !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { + /* + * For now, disable hw crypto for the RSN IBSS group keys. This + * could be optimized in the future to use a modified key cache + * design to support per-STA RX GTK, but until that gets + * implemented, use of software crypto for group addressed + * frames is a acceptable to allow RSN IBSS to be used. + */ + return -EOPNOTSUPP; + } + mutex_lock(&priv->mutex); ath_dbg(common, CONFIG, "Set HW Key\n"); ath9k_htc_ps_wakeup(priv); -- cgit v1.2.3-70-g09d2 From 11deb53328a06ad4edbf774f5c3b61c6dbb9104c Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Tue, 24 Jan 2012 14:58:47 -0500 Subject: ath5k: use bool type for no_hw_rfkill_switch module parameter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoids this: CC [M] drivers/net/wireless/ath/ath5k/base.o drivers/net/wireless/ath/ath5k/base.c: In function ‘__check_no_hw_rfkill_switch’: drivers/net/wireless/ath/ath5k/base.c:85:1: warning: return from incompatible pointer type Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 4ab835f08a4..a339693fbe2 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -80,7 +80,7 @@ static bool modparam_fastchanswitch; module_param_named(fastchanswitch, modparam_fastchanswitch, bool, S_IRUGO); MODULE_PARM_DESC(fastchanswitch, "Enable fast channel switching for AR2413/AR5413 radios."); -static int ath5k_modparam_no_hw_rfkill_switch; +static bool ath5k_modparam_no_hw_rfkill_switch; module_param_named(no_hw_rfkill_switch, ath5k_modparam_no_hw_rfkill_switch, bool, S_IRUGO); MODULE_PARM_DESC(no_hw_rfkill_switch, "Ignore the GPIO RFKill switch state"); -- cgit v1.2.3-70-g09d2 From e371ceb89f531280d30cadbdb8371656468705b1 Mon Sep 17 00:00:00 2001 From: Karol Lewandowski Date: Tue, 24 Jan 2012 12:31:11 +0100 Subject: regulator: max8997: Avoid spaces in regulator names max8997-pmic instantiated from device tree uses names, not numerical ids to distinguish between outputs. Replace spaces with underscores in said names to make it possible to describe these outputs as regulators in DTS. Signed-off-by: Karol Lewandowski Signed-off-by: Kyungmin Park Signed-off-by: Mark Brown --- drivers/regulator/max8997.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index d26e8646277..bb7cd9df948 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c @@ -908,13 +908,13 @@ static struct regulator_desc regulators[] = { }, regulator_desc_buck(7), { - .name = "EN32KHz AP", + .name = "EN32KHz_AP", .id = MAX8997_EN32KHZ_AP, .ops = &max8997_fixedvolt_ops, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, { - .name = "EN32KHz CP", + .name = "EN32KHz_CP", .id = MAX8997_EN32KHZ_CP, .ops = &max8997_fixedvolt_ops, .type = REGULATOR_VOLTAGE, @@ -938,7 +938,7 @@ static struct regulator_desc regulators[] = { .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, { - .name = "CHARGER CV", + .name = "CHARGER_CV", .id = MAX8997_CHARGER_CV, .ops = &max8997_fixedstate_ops, .type = REGULATOR_VOLTAGE, @@ -950,7 +950,7 @@ static struct regulator_desc regulators[] = { .type = REGULATOR_CURRENT, .owner = THIS_MODULE, }, { - .name = "CHARGER TOPOFF", + .name = "CHARGER_TOPOFF", .id = MAX8997_CHARGER_TOPOFF, .ops = &max8997_charger_fixedstate_ops, .type = REGULATOR_CURRENT, -- cgit v1.2.3-70-g09d2 From 47d505ccc7535c825f6b28aaaf105d4b75f25196 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Tue, 24 Jan 2012 15:03:04 -0500 Subject: orinoco_usb: remove version definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoids this: CC [M] drivers/net/wireless/orinoco/orinoco_usb.o drivers/net/wireless/orinoco/orinoco_usb.c:1759:13: warning: ‘version’ defined but not used Signed-off-by: John W. Linville --- drivers/net/wireless/orinoco/orinoco_usb.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/orinoco/orinoco_usb.c b/drivers/net/wireless/orinoco/orinoco_usb.c index ae8ce56670b..f634d4582bf 100644 --- a/drivers/net/wireless/orinoco/orinoco_usb.c +++ b/drivers/net/wireless/orinoco/orinoco_usb.c @@ -1754,11 +1754,6 @@ static struct usb_driver orinoco_driver = { .id_table = ezusb_table, }; -/* Can't be declared "const" or the whole __initdata section will - * become const */ -static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION - " (Manuel Estrada Sainz)"; - module_usb_driver(orinoco_driver); MODULE_AUTHOR("Manuel Estrada Sainz"); -- cgit v1.2.3-70-g09d2 From 2343933921efd553dea888fc844abb653824c4c8 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 24 Jan 2012 18:37:16 -0200 Subject: regulator: mc13xxx-regulator-core: Fix the build when driver is selected as module Fix the following build error when mc138xxx driver is built as module: ERROR: "mc13xxx_parse_regulators_dt" [drivers/regulator/mc13892-regulator.ko] undefined! ERROR: "mc13xxx_get_num_regulators_dt" [drivers/regulator/mc13892-regulator.ko] undefined! Reported-by: Randy Dunlap Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- drivers/regulator/mc13xxx-regulator-core.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/mc13xxx-regulator-core.c b/drivers/regulator/mc13xxx-regulator-core.c index 80ecafef1bc..62dcd0a432b 100644 --- a/drivers/regulator/mc13xxx-regulator-core.c +++ b/drivers/regulator/mc13xxx-regulator-core.c @@ -254,6 +254,7 @@ int __devinit mc13xxx_get_num_regulators_dt(struct platform_device *pdev) return num; } +EXPORT_SYMBOL_GPL(mc13xxx_get_num_regulators_dt); struct mc13xxx_regulator_init_data * __devinit mc13xxx_parse_regulators_dt( struct platform_device *pdev, struct mc13xxx_regulator *regulators, @@ -291,6 +292,7 @@ struct mc13xxx_regulator_init_data * __devinit mc13xxx_parse_regulators_dt( return data; } +EXPORT_SYMBOL_GPL(mc13xxx_parse_regulators_dt); #endif MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-70-g09d2 From 2897a563a55442379e5e59ec68c229a7f27fb7c6 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Sun, 8 Jan 2012 10:12:18 -0800 Subject: drivers: hv: Get rid of some unnecessary code The current code unnecessarily limits the number of offers we handle. Get rid of this limitation. As part of this cleanup, also get rid of an unused define - MAX_MSG_TYPES. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/hv/channel_mgmt.c | 87 ----------------------------------------------- 1 file changed, 87 deletions(-) (limited to 'drivers') diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 36484db36ba..9ffbfc575a0 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -37,81 +37,6 @@ struct vmbus_channel_message_table_entry { void (*message_handler)(struct vmbus_channel_message_header *msg); }; -#define MAX_MSG_TYPES 4 -#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 8 - -static const uuid_le - supported_device_classes[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = { - /* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */ - /* Storage - SCSI */ - { - .b = { - 0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, - 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f - } - }, - - /* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */ - /* Network */ - { - .b = { - 0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, - 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E - } - }, - - /* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */ - /* Input */ - { - .b = { - 0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c, - 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A - } - }, - - /* {32412632-86cb-44a2-9b5c-50d1417354f5} */ - /* IDE */ - { - .b = { - 0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, - 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5 - } - }, - /* 0E0B6031-5213-4934-818B-38D90CED39DB */ - /* Shutdown */ - { - .b = { - 0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49, - 0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB - } - }, - /* {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */ - /* TimeSync */ - { - .b = { - 0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49, - 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf - } - }, - /* {57164f39-9115-4e78-ab55-382f3bd5422d} */ - /* Heartbeat */ - { - .b = { - 0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e, - 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d - } - }, - /* {A9A0F4E7-5A45-4d96-B827-8A841E8C03E6} */ - /* KVP */ - { - .b = { - 0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d, - 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6 - } - }, - -}; - /** * vmbus_prep_negotiate_resp() - Create default response for Hyper-V Negotiate message @@ -321,20 +246,8 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr) struct vmbus_channel *newchannel; uuid_le *guidtype; uuid_le *guidinstance; - int i; - int fsupported = 0; offer = (struct vmbus_channel_offer_channel *)hdr; - for (i = 0; i < MAX_NUM_DEVICE_CLASSES_SUPPORTED; i++) { - if (!uuid_le_cmp(offer->offer.if_type, - supported_device_classes[i])) { - fsupported = 1; - break; - } - } - - if (!fsupported) - return; guidtype = &offer->offer.if_type; guidinstance = &offer->offer.if_instance; -- cgit v1.2.3-70-g09d2 From 593a27c4b212e2afdf772a1f8dcb894e91bda0fa Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Thu, 5 Jan 2012 13:04:21 +0400 Subject: tty: cleanup prohibition of direct opening for unix98 pty master cleanup hack added in v2.6.27-3203-g15582d3 comment from that patch: : pty: If the administrator creates a device for a ptmx slave we should not error : : The open path for ptmx slaves is via the ptmx device. Opening them any : other way is not allowed. Vegard Nossum found that previously this was not : the case and mknod foo c 128 42; cat foo would produce nasty diagnostics : : Signed-off-by: Alan Cox : Signed-off-by: Linus Torvalds devpts_get_tty() returns non-null only for inodes on devpts, but there is no inodes for master-devices, /dev/ptmx (/dev/pts/ptmx) is the only way to open them. Thus we can completely forbid lookup for master-devices and eliminate that hack in tty_init_dev() because tty_open() will get EIO from tty_driver_lookup_tty(). Signed-off-by: Konstantin Khlebnikov Signed-off-by: Greg Kroah-Hartman --- drivers/tty/pty.c | 8 +++----- drivers/tty/tty_io.c | 12 ++---------- include/linux/tty.h | 3 +-- 3 files changed, 6 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index d8653ab6f49..03147fa31d4 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -515,10 +515,8 @@ static int pty_unix98_ioctl(struct tty_struct *tty, static struct tty_struct *ptm_unix98_lookup(struct tty_driver *driver, struct inode *ptm_inode, int idx) { - struct tty_struct *tty = devpts_get_tty(ptm_inode, idx); - if (tty) - tty = tty->link; - return tty; + /* Master must be open via /dev/ptmx */ + return ERR_PTR(-EIO); } /** @@ -677,7 +675,7 @@ static int ptmx_open(struct inode *inode, struct file *filp) mutex_lock(&tty_mutex); tty_lock(); - tty = tty_init_dev(ptm_driver, index, 1); + tty = tty_init_dev(ptm_driver, index); mutex_unlock(&tty_mutex); if (IS_ERR(tty)) { diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index e41b9bbc107..fbcc1406380 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1365,7 +1365,6 @@ static int tty_reopen(struct tty_struct *tty) * @driver: tty driver we are opening a device on * @idx: device index * @ret_tty: returned tty structure - * @first_ok: ok to open a new device (used by ptmx) * * Prepare a tty device. This may not be a "new" clean device but * could also be an active device. The pty drivers require special @@ -1385,18 +1384,11 @@ static int tty_reopen(struct tty_struct *tty) * relaxed for the (most common) case of reopening a tty. */ -struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, - int first_ok) +struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) { struct tty_struct *tty; int retval; - /* Check if pty master is being opened multiple times */ - if (driver->subtype == PTY_TYPE_MASTER && - (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) { - return ERR_PTR(-EIO); - } - /* * First time open is complex, especially for PTY devices. * This code guarantees that either everything succeeds and the @@ -1950,7 +1942,7 @@ retry_open: if (retval) tty = ERR_PTR(retval); } else - tty = tty_init_dev(driver, index, 0); + tty = tty_init_dev(driver, index); mutex_unlock(&tty_mutex); if (driver) diff --git a/include/linux/tty.h b/include/linux/tty.h index 5dbb3cb05a8..d3ebd765b54 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -480,8 +480,7 @@ extern void free_tty_struct(struct tty_struct *tty); extern void initialize_tty_struct(struct tty_struct *tty, struct tty_driver *driver, int idx); extern void deinitialize_tty_struct(struct tty_struct *tty); -extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, - int first_ok); +extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx); extern int tty_release(struct inode *inode, struct file *filp); extern int tty_init_termios(struct tty_struct *tty); -- cgit v1.2.3-70-g09d2 From a4834c102f4a46808630cad1a545cb0706b3b0a2 Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Thu, 5 Jan 2012 13:06:02 +0400 Subject: tty: move pty count limiting into devpts Let's move this stuff to the better place, where we can account pty right in tty-indexes managing code. Signed-off-by: Konstantin Khlebnikov Signed-off-by: Greg Kroah-Hartman --- drivers/tty/pty.c | 51 --------------------------------------------------- fs/devpts/inode.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 52 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 03147fa31d4..d505837b347 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -439,55 +438,9 @@ static inline void legacy_pty_init(void) { } /* Unix98 devices */ #ifdef CONFIG_UNIX98_PTYS -/* - * sysctl support for setting limits on the number of Unix98 ptys allocated. - * Otherwise one can eat up all kernel memory by opening /dev/ptmx repeatedly. - */ -int pty_limit = NR_UNIX98_PTY_DEFAULT; -static int pty_limit_min; -static int pty_limit_max = NR_UNIX98_PTY_MAX; -static int pty_count; static struct cdev ptmx_cdev; -static struct ctl_table pty_table[] = { - { - .procname = "max", - .maxlen = sizeof(int), - .mode = 0644, - .data = &pty_limit, - .proc_handler = proc_dointvec_minmax, - .extra1 = &pty_limit_min, - .extra2 = &pty_limit_max, - }, { - .procname = "nr", - .maxlen = sizeof(int), - .mode = 0444, - .data = &pty_count, - .proc_handler = proc_dointvec, - }, - {} -}; - -static struct ctl_table pty_kern_table[] = { - { - .procname = "pty", - .mode = 0555, - .child = pty_table, - }, - {} -}; - -static struct ctl_table pty_root_table[] = { - { - .procname = "kernel", - .mode = 0555, - .child = pty_kern_table, - }, - {} -}; - - static int pty_unix98_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { @@ -587,7 +540,6 @@ static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty) */ tty_driver_kref_get(driver); tty->count++; - pty_count++; return 0; err_free_mem: deinitialize_tty_struct(o_tty); @@ -601,7 +553,6 @@ err_free_tty: static void ptm_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) { - pty_count--; } static void pts_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) @@ -760,8 +711,6 @@ static void __init unix98_pty_init(void) if (tty_register_driver(pts_driver)) panic("Couldn't register Unix98 pts driver"); - register_sysctl_table(pty_root_table); - /* Now create the /dev/ptmx special device */ tty_default_fops(&ptmx_fops); ptmx_fops.open = ptmx_open; diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index c4e2a58a2e8..c2c7317d568 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c @@ -36,7 +36,52 @@ #define DEVPTS_DEFAULT_PTMX_MODE 0000 #define PTMX_MINOR 2 -extern int pty_limit; /* Config limit on Unix98 ptys */ +/* + * sysctl support for setting limits on the number of Unix98 ptys allocated. + * Otherwise one can eat up all kernel memory by opening /dev/ptmx repeatedly. + */ +static int pty_limit = NR_UNIX98_PTY_DEFAULT; +static int pty_limit_min; +static int pty_limit_max = NR_UNIX98_PTY_MAX; +static int pty_count; + +static struct ctl_table pty_table[] = { + { + .procname = "max", + .maxlen = sizeof(int), + .mode = 0644, + .data = &pty_limit, + .proc_handler = proc_dointvec_minmax, + .extra1 = &pty_limit_min, + .extra2 = &pty_limit_max, + }, { + .procname = "nr", + .maxlen = sizeof(int), + .mode = 0444, + .data = &pty_count, + .proc_handler = proc_dointvec, + }, + {} +}; + +static struct ctl_table pty_kern_table[] = { + { + .procname = "pty", + .mode = 0555, + .child = pty_table, + }, + {} +}; + +static struct ctl_table pty_root_table[] = { + { + .procname = "kernel", + .mode = 0555, + .child = pty_kern_table, + }, + {} +}; + static DEFINE_MUTEX(allocated_ptys_lock); static struct vfsmount *devpts_mnt; @@ -451,6 +496,7 @@ retry: mutex_unlock(&allocated_ptys_lock); return -EIO; } + pty_count++; mutex_unlock(&allocated_ptys_lock); return index; } @@ -462,6 +508,7 @@ void devpts_kill_index(struct inode *ptmx_inode, int idx) mutex_lock(&allocated_ptys_lock); ida_remove(&fsi->allocated_ptys, idx); + pty_count--; mutex_unlock(&allocated_ptys_lock); } @@ -558,11 +605,15 @@ void devpts_pty_kill(struct tty_struct *tty) static int __init init_devpts_fs(void) { int err = register_filesystem(&devpts_fs_type); + struct ctl_table_header *table; + if (!err) { + table = register_sysctl_table(pty_root_table); devpts_mnt = kern_mount(&devpts_fs_type); if (IS_ERR(devpts_mnt)) { err = PTR_ERR(devpts_mnt); unregister_filesystem(&devpts_fs_type); + unregister_sysctl_table(table); } } return err; -- cgit v1.2.3-70-g09d2 From 1493138af1463112e42eebcdab5db61452821e97 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 5 Jan 2012 15:39:57 +0100 Subject: USB: code cleanup in suspend/resume path (3rd try) Do the cleanup to avoid behaviorial parameters Linus requested. Signed-off-by: Oliver Neukum Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/driver.c | 93 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index d40ff956881..b7dfdecc7fd 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -958,13 +958,8 @@ void usb_rebind_intf(struct usb_interface *intf) int rc; /* Delayed unbind of an existing driver */ - if (intf->dev.driver) { - struct usb_driver *driver = - to_usb_driver(intf->dev.driver); - - dev_dbg(&intf->dev, "forced unbind\n"); - usb_driver_release_interface(driver, intf); - } + if (intf->dev.driver) + usb_forced_unbind_intf(intf); /* Try to rebind the interface */ if (!intf->dev.power.is_prepared) { @@ -977,15 +972,13 @@ void usb_rebind_intf(struct usb_interface *intf) #ifdef CONFIG_PM -#define DO_UNBIND 0 -#define DO_REBIND 1 - -/* Unbind drivers for @udev's interfaces that don't support suspend/resume, - * or rebind interfaces that have been unbound, according to @action. +/* Unbind drivers for @udev's interfaces that don't support suspend/resume + * There is no check for reset_resume here because it can be determined + * only during resume whether reset_resume is needed. * * The caller must hold @udev's device lock. */ -static void do_unbind_rebind(struct usb_device *udev, int action) +static void unbind_no_pm_drivers_interfaces(struct usb_device *udev) { struct usb_host_config *config; int i; @@ -996,23 +989,53 @@ static void do_unbind_rebind(struct usb_device *udev, int action) if (config) { for (i = 0; i < config->desc.bNumInterfaces; ++i) { intf = config->interface[i]; - switch (action) { - case DO_UNBIND: - if (intf->dev.driver) { - drv = to_usb_driver(intf->dev.driver); - if (!drv->suspend || !drv->resume) - usb_forced_unbind_intf(intf); - } - break; - case DO_REBIND: - if (intf->needs_binding) - usb_rebind_intf(intf); - break; + + if (intf->dev.driver) { + drv = to_usb_driver(intf->dev.driver); + if (!drv->suspend || !drv->resume) + usb_forced_unbind_intf(intf); } } } } +/* Unbind drivers for @udev's interfaces that failed to support reset-resume. + * These interfaces have the needs_binding flag set by usb_resume_interface(). + * + * The caller must hold @udev's device lock. + */ +static void unbind_no_reset_resume_drivers_interfaces(struct usb_device *udev) +{ + struct usb_host_config *config; + int i; + struct usb_interface *intf; + + config = udev->actconfig; + if (config) { + for (i = 0; i < config->desc.bNumInterfaces; ++i) { + intf = config->interface[i]; + if (intf->dev.driver && intf->needs_binding) + usb_forced_unbind_intf(intf); + } + } +} + +static void do_rebind_interfaces(struct usb_device *udev) +{ + struct usb_host_config *config; + int i; + struct usb_interface *intf; + + config = udev->actconfig; + if (config) { + for (i = 0; i < config->desc.bNumInterfaces; ++i) { + intf = config->interface[i]; + if (intf->needs_binding) + usb_rebind_intf(intf); + } + } +} + static int usb_suspend_device(struct usb_device *udev, pm_message_t msg) { struct usb_device_driver *udriver; @@ -1302,7 +1325,12 @@ int usb_suspend(struct device *dev, pm_message_t msg) { struct usb_device *udev = to_usb_device(dev); - do_unbind_rebind(udev, DO_UNBIND); + unbind_no_pm_drivers_interfaces(udev); + + /* From now on we are sure all drivers support suspend/resume + * but not necessarily reset_resume() + * so we may still need to unbind and rebind upon resume + */ choose_wakeup(udev, msg); return usb_suspend_both(udev, msg); } @@ -1313,15 +1341,20 @@ int usb_resume(struct device *dev, pm_message_t msg) struct usb_device *udev = to_usb_device(dev); int status; - /* For PM complete calls, all we do is rebind interfaces */ + /* For PM complete calls, all we do is rebind interfaces + * whose needs_binding flag is set + */ if (msg.event == PM_EVENT_ON) { if (udev->state != USB_STATE_NOTATTACHED) - do_unbind_rebind(udev, DO_REBIND); + do_rebind_interfaces(udev); status = 0; /* For all other calls, take the device back to full power and * tell the PM core in case it was autosuspended previously. - * Unbind the interfaces that will need rebinding later. + * Unbind the interfaces that will need rebinding later, + * because they fail to support reset_resume. + * (This can't be done in usb_resume_interface() + * above because it doesn't own the right set of locks.) */ } else { status = usb_resume_both(udev, msg); @@ -1329,7 +1362,7 @@ int usb_resume(struct device *dev, pm_message_t msg) pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); - do_unbind_rebind(udev, DO_REBIND); + unbind_no_reset_resume_drivers_interfaces(udev); } } -- cgit v1.2.3-70-g09d2 From 98d9a82e5f753a2483d7b4638802d60e94e5d2e4 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Wed, 11 Jan 2012 08:38:35 +0100 Subject: USB: cleanup the handling of the PM complete call This eliminates the last instance of a function's behavior controlled by a parameter as Linus hates such things. Signed-off-by: Oliver Neukum Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/driver.c | 37 ++++++++++++++++++++----------------- drivers/usb/core/usb.c | 2 +- drivers/usb/core/usb.h | 1 + 3 files changed, 22 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index b7dfdecc7fd..d77daf3683d 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1336,34 +1336,37 @@ int usb_suspend(struct device *dev, pm_message_t msg) } /* The device lock is held by the PM core */ -int usb_resume(struct device *dev, pm_message_t msg) +int usb_resume_complete(struct device *dev) { - struct usb_device *udev = to_usb_device(dev); - int status; + struct usb_device *udev = to_usb_device(dev); /* For PM complete calls, all we do is rebind interfaces * whose needs_binding flag is set */ - if (msg.event == PM_EVENT_ON) { - if (udev->state != USB_STATE_NOTATTACHED) - do_rebind_interfaces(udev); - status = 0; + if (udev->state != USB_STATE_NOTATTACHED) + do_rebind_interfaces(udev); + return 0; +} - /* For all other calls, take the device back to full power and +/* The device lock is held by the PM core */ +int usb_resume(struct device *dev, pm_message_t msg) +{ + struct usb_device *udev = to_usb_device(dev); + int status; + + /* For all calls, take the device back to full power and * tell the PM core in case it was autosuspended previously. * Unbind the interfaces that will need rebinding later, * because they fail to support reset_resume. * (This can't be done in usb_resume_interface() - * above because it doesn't own the right set of locks.) + * above because it doesn't own the right set of locks.) */ - } else { - status = usb_resume_both(udev, msg); - if (status == 0) { - pm_runtime_disable(dev); - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - unbind_no_reset_resume_drivers_interfaces(udev); - } + status = usb_resume_both(udev, msg); + if (status == 0) { + pm_runtime_disable(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + unbind_no_reset_resume_drivers_interfaces(udev); } /* Avoid PM error messages for devices disconnected while suspended diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 8ca9f994a28..c74ba7bbc74 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -274,7 +274,7 @@ static int usb_dev_prepare(struct device *dev) static void usb_dev_complete(struct device *dev) { /* Currently used only for rebinding interfaces */ - usb_resume(dev, PMSG_ON); /* FIXME: change to PMSG_COMPLETE */ + usb_resume_complete(dev); } static int usb_dev_suspend(struct device *dev) diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 45e8479c377..71648dcbe43 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -56,6 +56,7 @@ extern void usb_major_cleanup(void); extern int usb_suspend(struct device *dev, pm_message_t msg); extern int usb_resume(struct device *dev, pm_message_t msg); +extern int usb_resume_complete(struct device *dev); extern int usb_port_suspend(struct usb_device *dev, pm_message_t msg); extern int usb_port_resume(struct usb_device *dev, pm_message_t msg); -- cgit v1.2.3-70-g09d2 From 2851784f4d820bc697a8cc608509f9e3975c80e5 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Fri, 13 Jan 2012 19:04:17 +0100 Subject: usb/uhci: initialize sg_table properly Commit 689d6eac ("USB: UHCI: add native scatter-gather support(v1)) added sg support to uhci but forgot to set the sg_table so this feature remained unused. Cc: Ming Lei Signed-off-by: Sebastian Andrzej Siewior Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/uhci-hcd.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 6b5eb1017e2..e37dea87bb5 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -565,6 +565,9 @@ static int uhci_start(struct usb_hcd *hcd) struct dentry __maybe_unused *dentry; hcd->uses_new_polling = 1; + /* Accept arbitrarily long scatter-gather lists */ + if (!(hcd->driver->flags & HCD_LOCAL_MEM)) + hcd->self.sg_tablesize = ~0; spin_lock_init(&uhci->lock); setup_timer(&uhci->fsbr_timer, uhci_fsbr_timeout, -- cgit v1.2.3-70-g09d2 From e73b2db6c9bc5bd9a3c080f286964e594351991a Mon Sep 17 00:00:00 2001 From: Huajun Li Date: Sat, 14 Jan 2012 10:15:21 +0800 Subject: usb: Disable dynamic id of USB storage subdrivers Storage subdrivers, like alauda, datafab and others, don't support dynamic id currently, and it needs lots of work but with very little gain to enable the feature, so disable them in the patch. Signed-off-by: Huajun Li Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/alauda.c | 1 + drivers/usb/storage/cypress_atacb.c | 1 + drivers/usb/storage/datafab.c | 1 + drivers/usb/storage/ene_ub6250.c | 1 + drivers/usb/storage/freecom.c | 1 + drivers/usb/storage/isd200.c | 1 + drivers/usb/storage/jumpshot.c | 1 + drivers/usb/storage/karma.c | 1 + drivers/usb/storage/onetouch.c | 1 + drivers/usb/storage/realtek_cr.c | 1 + drivers/usb/storage/sddr09.c | 1 + drivers/usb/storage/sddr55.c | 1 + drivers/usb/storage/shuttle_usbat.c | 1 + 13 files changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c index 51af2fee2ef..bab8c8fe829 100644 --- a/drivers/usb/storage/alauda.c +++ b/drivers/usb/storage/alauda.c @@ -1276,6 +1276,7 @@ static struct usb_driver alauda_driver = { .post_reset = usb_stor_post_reset, .id_table = alauda_usb_ids, .soft_unbind = 1, + .no_dynamic_id = 1, }; module_usb_driver(alauda_driver); diff --git a/drivers/usb/storage/cypress_atacb.c b/drivers/usb/storage/cypress_atacb.c index 387cbd47acc..5fe451d16e6 100644 --- a/drivers/usb/storage/cypress_atacb.c +++ b/drivers/usb/storage/cypress_atacb.c @@ -272,6 +272,7 @@ static struct usb_driver cypress_driver = { .post_reset = usb_stor_post_reset, .id_table = cypress_usb_ids, .soft_unbind = 1, + .no_dynamic_id = 1, }; module_usb_driver(cypress_driver); diff --git a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c index 15d41f2b3d6..35e9c51e669 100644 --- a/drivers/usb/storage/datafab.c +++ b/drivers/usb/storage/datafab.c @@ -751,6 +751,7 @@ static struct usb_driver datafab_driver = { .post_reset = usb_stor_post_reset, .id_table = datafab_usb_ids, .soft_unbind = 1, + .no_dynamic_id = 1, }; module_usb_driver(datafab_driver); diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c index a6ade4071a9..30532d93eec 100644 --- a/drivers/usb/storage/ene_ub6250.c +++ b/drivers/usb/storage/ene_ub6250.c @@ -2407,6 +2407,7 @@ static struct usb_driver ene_ub6250_driver = { .post_reset = usb_stor_post_reset, .id_table = ene_ub6250_usb_ids, .soft_unbind = 1, + .no_dynamic_id = 1, }; module_usb_driver(ene_ub6250_driver); diff --git a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c index fa161574847..042cf9ef315 100644 --- a/drivers/usb/storage/freecom.c +++ b/drivers/usb/storage/freecom.c @@ -553,6 +553,7 @@ static struct usb_driver freecom_driver = { .post_reset = usb_stor_post_reset, .id_table = freecom_usb_ids, .soft_unbind = 1, + .no_dynamic_id = 1, }; module_usb_driver(freecom_driver); diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c index bd550270083..31fa24e7e68 100644 --- a/drivers/usb/storage/isd200.c +++ b/drivers/usb/storage/isd200.c @@ -1566,6 +1566,7 @@ static struct usb_driver isd200_driver = { .post_reset = usb_stor_post_reset, .id_table = isd200_usb_ids, .soft_unbind = 1, + .no_dynamic_id = 1, }; module_usb_driver(isd200_driver); diff --git a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c index a19211b5c26..e3b97383186 100644 --- a/drivers/usb/storage/jumpshot.c +++ b/drivers/usb/storage/jumpshot.c @@ -677,6 +677,7 @@ static struct usb_driver jumpshot_driver = { .post_reset = usb_stor_post_reset, .id_table = jumpshot_usb_ids, .soft_unbind = 1, + .no_dynamic_id = 1, }; module_usb_driver(jumpshot_driver); diff --git a/drivers/usb/storage/karma.c b/drivers/usb/storage/karma.c index e720f8ebdf9..a8708eae978 100644 --- a/drivers/usb/storage/karma.c +++ b/drivers/usb/storage/karma.c @@ -230,6 +230,7 @@ static struct usb_driver karma_driver = { .post_reset = usb_stor_post_reset, .id_table = karma_usb_ids, .soft_unbind = 1, + .no_dynamic_id = 1, }; module_usb_driver(karma_driver); diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c index d75155c3820..886567a3806 100644 --- a/drivers/usb/storage/onetouch.c +++ b/drivers/usb/storage/onetouch.c @@ -312,6 +312,7 @@ static struct usb_driver onetouch_driver = { .post_reset = usb_stor_post_reset, .id_table = onetouch_usb_ids, .soft_unbind = 1, + .no_dynamic_id = 1, }; module_usb_driver(onetouch_driver); diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c index 1f62723ef1a..ccf271d2f67 100644 --- a/drivers/usb/storage/realtek_cr.c +++ b/drivers/usb/storage/realtek_cr.c @@ -1100,6 +1100,7 @@ static struct usb_driver realtek_cr_driver = { .id_table = realtek_cr_ids, .soft_unbind = 1, .supports_autosuspend = 1, + .no_dynamic_id = 1, }; module_usb_driver(realtek_cr_driver); diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c index 425df7df2e5..3252a62b31b 100644 --- a/drivers/usb/storage/sddr09.c +++ b/drivers/usb/storage/sddr09.c @@ -1787,6 +1787,7 @@ static struct usb_driver sddr09_driver = { .post_reset = usb_stor_post_reset, .id_table = sddr09_usb_ids, .soft_unbind = 1, + .no_dynamic_id = 1, }; module_usb_driver(sddr09_driver); diff --git a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c index e4ca5fcb7cc..c144078065a 100644 --- a/drivers/usb/storage/sddr55.c +++ b/drivers/usb/storage/sddr55.c @@ -1006,6 +1006,7 @@ static struct usb_driver sddr55_driver = { .post_reset = usb_stor_post_reset, .id_table = sddr55_usb_ids, .soft_unbind = 1, + .no_dynamic_id = 1, }; module_usb_driver(sddr55_driver); diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index 1369d259061..fa1ceebc465 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c @@ -1863,6 +1863,7 @@ static struct usb_driver usbat_driver = { .post_reset = usb_stor_post_reset, .id_table = usbat_usb_ids, .soft_unbind = 1, + .no_dynamic_id = 1, }; module_usb_driver(usbat_driver); -- cgit v1.2.3-70-g09d2 From fd7ff36d6a3f6413f838a2037b957b0e33ba9056 Mon Sep 17 00:00:00 2001 From: Huajun Li Date: Sat, 14 Jan 2012 10:16:40 +0800 Subject: usb: Re-enable usb-storage support dynamic id Enable usb-storage support dynamic id again by using a fixed id entry that describes a device using the Bulk-Only transport with the Transparent SCSI protocol. Signed-off-by: Huajun Li Reviewed-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/usb.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 3dd7da9fd50..58f56775ecd 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -125,6 +125,9 @@ static struct us_unusual_dev us_unusual_dev_list[] = { { } /* Terminating entry */ }; +static struct us_unusual_dev for_dynamic_ids = + USUAL_DEV(USB_SC_SCSI, USB_PR_BULK, 0); + #undef UNUSUAL_DEV #undef COMPLIANT_DEV #undef USUAL_DEV @@ -1027,8 +1030,10 @@ EXPORT_SYMBOL_GPL(usb_stor_disconnect); static int storage_probe(struct usb_interface *intf, const struct usb_device_id *id) { + struct us_unusual_dev *unusual_dev; struct us_data *us; int result; + int size; /* * If libusual is configured, let it decide whether a standard @@ -1047,8 +1052,19 @@ static int storage_probe(struct usb_interface *intf, * table, so we use the index of the id entry to find the * corresponding unusual_devs entry. */ - result = usb_stor_probe1(&us, intf, id, - (id - usb_storage_usb_ids) + us_unusual_dev_list); + + size = ARRAY_SIZE(us_unusual_dev_list); + if (id >= usb_storage_usb_ids && id < usb_storage_usb_ids + size) { + unusual_dev = (id - usb_storage_usb_ids) + us_unusual_dev_list; + } else { + unusual_dev = &for_dynamic_ids; + + US_DEBUGP("%s %s 0x%04x 0x%04x\n", "Use Bulk-Only transport", + "with the Transparent SCSI protocol for dynamic id:", + id->idVendor, id->idProduct); + } + + result = usb_stor_probe1(&us, intf, id, unusual_dev); if (result) return result; @@ -1074,7 +1090,6 @@ static struct usb_driver usb_storage_driver = { .id_table = usb_storage_usb_ids, .supports_autosuspend = 1, .soft_unbind = 1, - .no_dynamic_id = 1, }; static int __init usb_stor_init(void) -- cgit v1.2.3-70-g09d2 From 0b238583ac8db66762bba021de1b7c60b6bc29ad Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 16 Jan 2012 00:36:47 +0100 Subject: USB: cp210x: fix debug output Remove superfluous newlines from debug statements. Remove unnecessary line breaks. Signed-off-by: Johan Hovold Cc: Preston Fick Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp210x.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index fba1147ed91..92aadd889a6 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -279,7 +279,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request, if (result != size) { dbg("%s - Unable to send config request, " - "request=0x%x size=%d result=%d\n", + "request=0x%x size=%d result=%d", __func__, request, size, result); if (result > 0) result = -EPROTO; @@ -333,7 +333,7 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request, if ((size > 2 && result != size) || result < 0) { dbg("%s - Unable to send request, " - "request=0x%x size=%d result=%d\n", + "request=0x%x size=%d result=%d", __func__, request, size, result); if (result > 0) result = -EPROTO; @@ -636,13 +636,13 @@ static void cp210x_set_termios(struct tty_struct *tty, default: dbg("cp210x driver does not " "support the number of bits requested," - " using 8 bit mode\n"); + " using 8 bit mode"); bits |= BITS_DATA_8; break; } if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2)) dbg("Number of data bits requested " - "not supported by device\n"); + "not supported by device"); } if ((cflag & (PARENB|PARODD|CMSPAR)) != @@ -669,8 +669,7 @@ static void cp210x_set_termios(struct tty_struct *tty, } } if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2)) - dbg("Parity mode not supported " - "by device\n"); + dbg("Parity mode not supported by device"); } if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) { @@ -685,7 +684,7 @@ static void cp210x_set_termios(struct tty_struct *tty, } if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2)) dbg("Number of stop bits requested " - "not supported by device\n"); + "not supported by device"); } if ((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) { -- cgit v1.2.3-70-g09d2 From 19b85b3b87fd1388df1f4a35969823521d35d243 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Mon, 16 Jan 2012 15:11:58 +0100 Subject: USB: cdc-wdm: no need to fill the in request URB every time it's submitted MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Filling the same URB with the exact same data is pointless. It can be filled once and resubmitted. And not doing buffer allocation and URB filling at the same place only serves to hide size mismatch bugs Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 1c50baff772..9734863a3a4 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -159,11 +159,9 @@ static void wdm_int_callback(struct urb *urb) int rv = 0; int status = urb->status; struct wdm_device *desc; - struct usb_ctrlrequest *req; struct usb_cdc_notification *dr; desc = urb->context; - req = desc->irq; dr = (struct usb_cdc_notification *)desc->sbuf; if (status) { @@ -210,24 +208,6 @@ static void wdm_int_callback(struct urb *urb) goto exit; } - req->bRequestType = (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE); - req->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE; - req->wValue = 0; - req->wIndex = desc->inum; - req->wLength = cpu_to_le16(desc->wMaxCommand); - - usb_fill_control_urb( - desc->response, - interface_to_usbdev(desc->intf), - /* using common endpoint 0 */ - usb_rcvctrlpipe(interface_to_usbdev(desc->intf), 0), - (unsigned char *)req, - desc->inbuf, - desc->wMaxCommand, - wdm_in_callback, - desc - ); - desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; spin_lock(&desc->iuspin); clear_bit(WDM_READ, &desc->flags); set_bit(WDM_RESPONDING, &desc->flags); @@ -734,6 +714,25 @@ next_desc: ); desc->validity->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + desc->irq->bRequestType = (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE); + desc->irq->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE; + desc->irq->wValue = 0; + desc->irq->wIndex = desc->inum; + desc->irq->wLength = cpu_to_le16(desc->wMaxCommand); + + usb_fill_control_urb( + desc->response, + interface_to_usbdev(desc->intf), + /* using common endpoint 0 */ + usb_rcvctrlpipe(interface_to_usbdev(desc->intf), 0), + (unsigned char *)desc->irq, + desc->inbuf, + desc->wMaxCommand, + wdm_in_callback, + desc + ); + desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + usb_set_intfdata(intf, desc); rv = usb_register_dev(intf, &wdm_class); if (rv < 0) -- cgit v1.2.3-70-g09d2 From cafbe85fb0d00d32988905c4978df433ca9b6512 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Mon, 16 Jan 2012 15:11:59 +0100 Subject: USB: cdc-wdm: better allocate a buffer that is at least as big as we tell the USB core MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As it turns out, there was a mismatch between the allocated inbuf size (desc->bMaxPacketSize0, typically something like 64) and the length we specified in the URB (desc->wMaxCommand, typically something like 2048) Signed-off-by: Bjørn Mork Cc: Oliver Neukum Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 9734863a3a4..846dfa60344 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -696,7 +696,7 @@ next_desc: goto err; desc->inbuf = usb_alloc_coherent(interface_to_usbdev(intf), - desc->bMaxPacketSize0, + desc->wMaxCommand, GFP_KERNEL, &desc->response->transfer_dma); if (!desc->inbuf) -- cgit v1.2.3-70-g09d2 From 8457d99cab81e91724b43363f7fccd851d766187 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Mon, 16 Jan 2012 15:12:00 +0100 Subject: USB: cdc-wdm: no need to use usb_alloc_coherent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As Documentation/usb/dma.txt states: Most drivers should *NOT* be using these primitives; they don't need to use this type of memory (dma-coherent), and memory returned from kmalloc() will work just fine. This driver handle only very low bandwith transfers. It is not an obvious candidate for usb_alloc_coherent(). Using these calls only serves to complicate the code for no gain, as has been shown by multiple bugs related to this allocation path. Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 39 +++++++++------------------------------ 1 file changed, 9 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 846dfa60344..8909058b1bb 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -256,14 +256,8 @@ static void free_urbs(struct wdm_device *desc) static void cleanup(struct wdm_device *desc) { - usb_free_coherent(interface_to_usbdev(desc->intf), - desc->wMaxPacketSize, - desc->sbuf, - desc->validity->transfer_dma); - usb_free_coherent(interface_to_usbdev(desc->intf), - desc->bMaxPacketSize0, - desc->inbuf, - desc->response->transfer_dma); + kfree(desc->sbuf); + kfree(desc->inbuf); kfree(desc->orq); kfree(desc->irq); kfree(desc->ubuf); @@ -688,19 +682,13 @@ next_desc: if (!desc->ubuf) goto err; - desc->sbuf = usb_alloc_coherent(interface_to_usbdev(intf), - desc->wMaxPacketSize, - GFP_KERNEL, - &desc->validity->transfer_dma); + desc->sbuf = kmalloc(desc->wMaxPacketSize, GFP_KERNEL); if (!desc->sbuf) goto err; - desc->inbuf = usb_alloc_coherent(interface_to_usbdev(intf), - desc->wMaxCommand, - GFP_KERNEL, - &desc->response->transfer_dma); + desc->inbuf = kmalloc(desc->wMaxCommand, GFP_KERNEL); if (!desc->inbuf) - goto err2; + goto err; usb_fill_int_urb( desc->validity, @@ -712,7 +700,6 @@ next_desc: desc, ep->bInterval ); - desc->validity->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; desc->irq->bRequestType = (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE); desc->irq->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE; @@ -731,30 +718,22 @@ next_desc: wdm_in_callback, desc ); - desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; usb_set_intfdata(intf, desc); rv = usb_register_dev(intf, &wdm_class); if (rv < 0) - goto err3; + goto err2; else dev_info(&intf->dev, "cdc-wdm%d: USB WDM device\n", intf->minor - WDM_MINOR_BASE); out: return rv; -err3: - usb_set_intfdata(intf, NULL); - usb_free_coherent(interface_to_usbdev(desc->intf), - desc->bMaxPacketSize0, - desc->inbuf, - desc->response->transfer_dma); err2: - usb_free_coherent(interface_to_usbdev(desc->intf), - desc->wMaxPacketSize, - desc->sbuf, - desc->validity->transfer_dma); + usb_set_intfdata(intf, NULL); err: free_urbs(desc); + kfree(desc->inbuf); + kfree(desc->sbuf); kfree(desc->ubuf); kfree(desc->orq); kfree(desc->irq); -- cgit v1.2.3-70-g09d2 From 8143a8963c374116f84aba15dcaeaf02370c8098 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Mon, 16 Jan 2012 15:12:01 +0100 Subject: USB: cdc-wdm: kill the now unnecessary bMaxPacketSize0 field and udev variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't need bMaxPacketSize0, and keeping all these different size fields around will only cause us to use the wrong one. Seems the udev variable was only used for getting bMaxPacketSize0. We could have used it for the usb_fill_*_urb() calls, but as it wasn't before - why start now? Instead make the interface_to_usbdev() calls consistent. Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 8909058b1bb..bb8208a13a5 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -80,7 +80,6 @@ struct wdm_device { u16 bufsize; u16 wMaxCommand; u16 wMaxPacketSize; - u16 bMaxPacketSize0; __le16 inum; int reslength; int length; @@ -597,7 +596,6 @@ static void wdm_rxwork(struct work_struct *work) static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) { int rv = -EINVAL; - struct usb_device *udev = interface_to_usbdev(intf); struct wdm_device *desc; struct usb_host_interface *iface; struct usb_endpoint_descriptor *ep; @@ -657,7 +655,6 @@ next_desc: goto err; desc->wMaxPacketSize = usb_endpoint_maxp(ep); - desc->bMaxPacketSize0 = udev->descriptor.bMaxPacketSize0; desc->orq = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); if (!desc->orq) @@ -709,7 +706,7 @@ next_desc: usb_fill_control_urb( desc->response, - interface_to_usbdev(desc->intf), + interface_to_usbdev(intf), /* using common endpoint 0 */ usb_rcvctrlpipe(interface_to_usbdev(desc->intf), 0), (unsigned char *)desc->irq, -- cgit v1.2.3-70-g09d2 From 7e3054a005537f28544ab2870c375458362f7473 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Fri, 20 Jan 2012 01:49:57 +0100 Subject: USB: cdc-wdm: Avoid hanging on interface with no USB_CDC_DMM_TYPE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe does not strictly require the USB_CDC_DMM_TYPE descriptor, which is a good thing as it makes the driver usable on non-conforming interfaces. A user could e.g. bind to it to a CDC ECM interface by using the new_id and bind sysfs files. But this would fail with a 0 buffer length due to the missing descriptor. Fix by defining a reasonable fallback size: The minimum device receive buffer size required by the CDC WMC standard, revision 1.1 Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index bb8208a13a5..c0197af22fd 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -57,6 +57,8 @@ MODULE_DEVICE_TABLE (usb, wdm_ids); #define WDM_MAX 16 +/* CDC-WMC r1.1 requires wMaxCommand to be "at least 256 decimal (0x100)" */ +#define WDM_DEFAULT_BUFSIZE 256 static DEFINE_MUTEX(wdm_mutex); @@ -602,7 +604,7 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) struct usb_cdc_dmm_desc *dmhd; u8 *buffer = intf->altsetting->extra; int buflen = intf->altsetting->extralen; - u16 maxcom = 0; + u16 maxcom = WDM_DEFAULT_BUFSIZE; if (!buffer) goto out; -- cgit v1.2.3-70-g09d2 From 820c629a595ad8d8f2694641e494738b18d29e7b Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Fri, 20 Jan 2012 04:17:25 +0100 Subject: USB: cdc-wdm: avoid printing odd-looking "cdc-wdm-176" names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit usb_register_dev() will change our .minor_base to 0 if CONFIG_USB_DYNAMIC_MINORS is set. And it usually is, of course. Use dev_name() to print the proper interface name instead Signed-off-by: Bjørn Mork Acked-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index c0197af22fd..c154d4f1d67 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -723,8 +723,7 @@ next_desc: if (rv < 0) goto err2; else - dev_info(&intf->dev, "cdc-wdm%d: USB WDM device\n", - intf->minor - WDM_MINOR_BASE); + dev_info(&intf->dev, "%s: USB WDM device\n", dev_name(intf->usb_dev)); out: return rv; err2: -- cgit v1.2.3-70-g09d2 From 761bbcb74e4611414937ea480ba60bb970648755 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Tue, 24 Jan 2012 22:17:38 +0100 Subject: usb: ehci-fsl: set INCR8 mode for system bus interface on MPC512x Use INCR8 mode for system bus interface of the USB controller on MPC512x. This is a work-around for the AHB bus lock up problem observed on MPC512x when there is heavy simultaneous PATA write or network (FEC) activity. See also "12.4 The USB controller can issue transactions that lock up the AHB bus under certain conditions" in MPC5121e (M36P) Errata. Signed-off-by: Anatolij Gustschin Tested-by: Matthias Fuchs Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-fsl.c | 14 ++++++++++++++ drivers/usb/host/ehci-fsl.h | 2 ++ 2 files changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index e90344a1763..42414cd7357 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -316,7 +316,9 @@ static int ehci_fsl_setup(struct usb_hcd *hcd) struct ehci_hcd *ehci = hcd_to_ehci(hcd); int retval; struct fsl_usb2_platform_data *pdata; + struct device *dev; + dev = hcd->self.controller; pdata = hcd->self.controller->platform_data; ehci->big_endian_desc = pdata->big_endian_desc; ehci->big_endian_mmio = pdata->big_endian_mmio; @@ -346,6 +348,16 @@ static int ehci_fsl_setup(struct usb_hcd *hcd) ehci_reset(ehci); + if (of_device_is_compatible(dev->parent->of_node, + "fsl,mpc5121-usb2-dr")) { + /* + * set SBUSCFG:AHBBRST so that control msgs don't + * fail when doing heavy PATA writes. + */ + ehci_writel(ehci, SBUSCFG_INCR8, + hcd->regs + FSL_SOC_USB_SBUSCFG); + } + retval = ehci_fsl_reinit(ehci); return retval; } @@ -469,6 +481,8 @@ static int ehci_fsl_mpc512x_drv_resume(struct device *dev) ehci_writel(ehci, ISIPHYCTRL_PXE | ISIPHYCTRL_PHYE, hcd->regs + FSL_SOC_USB_ISIPHYCTRL); + ehci_writel(ehci, SBUSCFG_INCR8, hcd->regs + FSL_SOC_USB_SBUSCFG); + /* restore EHCI registers */ ehci_writel(ehci, pdata->pm_command, &ehci->regs->command); ehci_writel(ehci, pdata->pm_intr_enable, &ehci->regs->intr_enable); diff --git a/drivers/usb/host/ehci-fsl.h b/drivers/usb/host/ehci-fsl.h index 49180622116..0855be8b5b4 100644 --- a/drivers/usb/host/ehci-fsl.h +++ b/drivers/usb/host/ehci-fsl.h @@ -19,6 +19,8 @@ #define _EHCI_FSL_H /* offsets for the non-ehci registers in the FSL SOC USB controller */ +#define FSL_SOC_USB_SBUSCFG 0x90 +#define SBUSCFG_INCR8 0x02 /* INCR8, specified */ #define FSL_SOC_USB_ULPIVP 0x170 #define FSL_SOC_USB_PORTSC1 0x184 #define PORT_PTS_MSK (3<<30) -- cgit v1.2.3-70-g09d2 From f30cdbcb2e6a7b9cdebe2117a7b623a5b3832a75 Mon Sep 17 00:00:00 2001 From: Kelvin Cheung Date: Wed, 18 Jan 2012 14:41:16 +0800 Subject: USB: Add EHCI bus glue for Loongson1x SoCs (UPDATED) Use ehci_setup() in ehci_ls1x_reset(). The Loongson1x SoCs have a built-in EHCI controller. This patch adds the necessary glue code to make the generic EHCI driver usable for them. Signed-off-by: Kelvin Cheung Signed-off-by: Greg Kroah-Hartman --- drivers/usb/Kconfig | 1 + drivers/usb/host/ehci-hcd.c | 5 ++ drivers/usb/host/ehci-ls1x.c | 159 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 165 insertions(+) create mode 100644 drivers/usb/host/ehci-ls1x.c (limited to 'drivers') diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 75823a1abeb..0b0afc81a54 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -76,6 +76,7 @@ config USB_ARCH_HAS_EHCI default y if MICROBLAZE default y if SPARC_LEON default y if ARCH_MMP + default y if MACH_LOONGSON1 default PCI # some non-PCI HCDs implement xHCI diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index a007a9fe0f8..4918b0c59af 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1376,6 +1376,11 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ehci_mv_driver #endif +#ifdef CONFIG_MACH_LOONGSON1 +#include "ehci-ls1x.c" +#define PLATFORM_DRIVER ehci_ls1x_driver +#endif + #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \ !defined(XILINX_OF_PLATFORM_DRIVER) diff --git a/drivers/usb/host/ehci-ls1x.c b/drivers/usb/host/ehci-ls1x.c new file mode 100644 index 00000000000..a283e59709d --- /dev/null +++ b/drivers/usb/host/ehci-ls1x.c @@ -0,0 +1,159 @@ +/* + * Bus Glue for Loongson LS1X built-in EHCI controller. + * + * Copyright (c) 2012 Zhang, Keguang + * + * 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 + +static int ehci_ls1x_reset(struct usb_hcd *hcd) +{ + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + int ret; + + ehci->caps = hcd->regs; + + ret = ehci_setup(hcd); + if (ret) + return ret; + + ehci_port_power(ehci, 0); + + return 0; +} + +static const struct hc_driver ehci_ls1x_hc_driver = { + .description = hcd_name, + .product_desc = "LOONGSON1 EHCI", + .hcd_priv_size = sizeof(struct ehci_hcd), + + /* + * generic hardware linkage + */ + .irq = ehci_irq, + .flags = HCD_MEMORY | HCD_USB2, + + /* + * basic lifecycle operations + */ + .reset = ehci_ls1x_reset, + .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, + + /* + * scheduling support + */ + .get_frame_number = ehci_get_frame, + + /* + * root hub support + */ + .hub_status_data = ehci_hub_status_data, + .hub_control = ehci_hub_control, + .relinquish_port = ehci_relinquish_port, + .port_handed_over = ehci_port_handed_over, + + .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, +}; + +static int ehci_hcd_ls1x_probe(struct platform_device *pdev) +{ + struct usb_hcd *hcd; + struct resource *res; + int irq; + int ret; + + pr_debug("initializing loongson1 ehci USB Controller\n"); + + if (usb_disabled()) + return -ENODEV; + + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res) { + dev_err(&pdev->dev, + "Found HC with no IRQ. Check %s setup!\n", + dev_name(&pdev->dev)); + return -ENODEV; + } + irq = res->start; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, + "Found HC with no register addr. Check %s setup!\n", + dev_name(&pdev->dev)); + return -ENODEV; + } + + hcd = usb_create_hcd(&ehci_ls1x_hc_driver, &pdev->dev, + dev_name(&pdev->dev)); + if (!hcd) + return -ENOMEM; + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); + + if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { + dev_dbg(&pdev->dev, "controller already in use\n"); + ret = -EBUSY; + goto err_put_hcd; + } + + hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); + if (hcd->regs == NULL) { + dev_dbg(&pdev->dev, "error mapping memory\n"); + ret = -EFAULT; + goto err_release_region; + } + + ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); + if (ret) + goto err_iounmap; + + return ret; + +err_iounmap: + iounmap(hcd->regs); +err_release_region: + release_mem_region(hcd->rsrc_start, hcd->rsrc_len); +err_put_hcd: + usb_put_hcd(hcd); + return ret; +} + +static int ehci_hcd_ls1x_remove(struct platform_device *pdev) +{ + struct usb_hcd *hcd = platform_get_drvdata(pdev); + + usb_remove_hcd(hcd); + iounmap(hcd->regs); + release_mem_region(hcd->rsrc_start, hcd->rsrc_len); + usb_put_hcd(hcd); + + return 0; +} + +static struct platform_driver ehci_ls1x_driver = { + .probe = ehci_hcd_ls1x_probe, + .remove = ehci_hcd_ls1x_remove, + .shutdown = usb_hcd_platform_shutdown, + .driver = { + .name = "ls1x-ehci", + .owner = THIS_MODULE, + }, +}; + +MODULE_ALIAS(PLATFORM_MODULE_PREFIX "ls1x-ehci"); -- cgit v1.2.3-70-g09d2 From 2b31594a9523449b168946725689d039c80204de Mon Sep 17 00:00:00 2001 From: Jonghwan Choi Date: Sat, 14 Jan 2012 11:06:03 +0900 Subject: driver-core: Fix possible null reference in subsys_interface_unregister Check if the sif is not NULL before de-referencing it Signed-off-by: Jonghwan Choi Signed-off-by: Greg Kroah-Hartman --- drivers/base/bus.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 99dc5921e1d..4ddb38b696f 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -1193,13 +1193,15 @@ EXPORT_SYMBOL_GPL(subsys_interface_register); void subsys_interface_unregister(struct subsys_interface *sif) { - struct bus_type *subsys = sif->subsys; + struct bus_type *subsys; struct subsys_dev_iter iter; struct device *dev; - if (!sif) + if (!sif || !sif->subsys) return; + subsys = sif->subsys; + mutex_lock(&subsys->p->mutex); list_del_init(&sif->node); if (sif->remove_dev) { -- cgit v1.2.3-70-g09d2 From fde25a9b63b9a3dc91365c394a426ebe64cfc2da Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 24 Jan 2012 13:34:24 -0500 Subject: Driver core: driver_find() drops reference before returning As part of the removal of get_driver()/put_driver(), this patch (as1510) changes driver_find(); it now drops the reference it acquires before returning. The patch also adjusts all the callers of driver_find() to remove the now unnecessary calls to put_driver(). In addition, the patch adds a warning to driver_find(): Callers must make sure the driver they are searching for does not get unloaded while they are using it. This has always been the case; driver_find() has never prevented a driver from being unregistered or unloaded. Hence the patch will not introduce any new bugs. The existing callers all seem to be okay in this respect, however I don't understand the video drivers well enough to be certain about them. Signed-off-by: Alan Stern CC: Dmitry Torokhov CC: Kyungmin Park CC: Andy Walls CC: Martin Schwidefsky Signed-off-by: Greg Kroah-Hartman --- drivers/base/driver.c | 7 +++++-- drivers/input/gameport/gameport.c | 1 - drivers/input/serio/serio.c | 1 - drivers/media/video/cx18/cx18-alsa-main.c | 1 - drivers/media/video/ivtv/ivtvfb.c | 2 -- drivers/media/video/s5p-fimc/fimc-mdevice.c | 5 +---- drivers/media/video/s5p-tv/mixer_video.c | 1 - drivers/s390/net/smsgiucv_app.c | 9 ++++----- 8 files changed, 10 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/base/driver.c b/drivers/base/driver.c index b631f7c5945..e979cad75c6 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -234,7 +234,6 @@ int driver_register(struct device_driver *drv) other = driver_find(drv->name, drv->bus); if (other) { - put_driver(other); printk(KERN_ERR "Error: Driver '%s' is already registered, " "aborting...\n", drv->name); return -EBUSY; @@ -275,7 +274,9 @@ EXPORT_SYMBOL_GPL(driver_unregister); * Call kset_find_obj() to iterate over list of drivers on * a bus to find driver by name. Return driver if found. * - * Note that kset_find_obj increments driver's reference count. + * This routine provides no locking to prevent the driver it returns + * from being unregistered or unloaded while the caller is using it. + * The caller is responsible for preventing this. */ struct device_driver *driver_find(const char *name, struct bus_type *bus) { @@ -283,6 +284,8 @@ struct device_driver *driver_find(const char *name, struct bus_type *bus) struct driver_private *priv; if (k) { + /* Drop reference added by kset_find_obj() */ + kobject_put(k); priv = to_driver(k); return priv->driver; } diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index c351aa421f8..da739d9d190 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c @@ -449,7 +449,6 @@ static ssize_t gameport_rebind_driver(struct device *dev, struct device_attribut } else if ((drv = driver_find(buf, &gameport_bus)) != NULL) { gameport_disconnect_port(gameport); error = gameport_bind_driver(gameport, to_gameport_driver(drv)); - put_driver(drv); } else { error = -EINVAL; } diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index ba70058e2be..d0f7533dbf8 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -441,7 +441,6 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute * } else if ((drv = driver_find(buf, &serio_bus)) != NULL) { serio_disconnect_port(serio); error = serio_bind_driver(serio, to_serio_driver(drv)); - put_driver(drv); serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT); } else { error = -EINVAL; diff --git a/drivers/media/video/cx18/cx18-alsa-main.c b/drivers/media/video/cx18/cx18-alsa-main.c index a1e6c2a3247..e118361c2e7 100644 --- a/drivers/media/video/cx18/cx18-alsa-main.c +++ b/drivers/media/video/cx18/cx18-alsa-main.c @@ -285,7 +285,6 @@ static void __exit cx18_alsa_exit(void) drv = driver_find("cx18", &pci_bus_type); ret = driver_for_each_device(drv, NULL, NULL, cx18_alsa_exit_callback); - put_driver(drv); cx18_ext_init = NULL; printk(KERN_INFO "cx18-alsa: module unload complete\n"); diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c index d0fbfcf7133..e5e7fa9e737 100644 --- a/drivers/media/video/ivtv/ivtvfb.c +++ b/drivers/media/video/ivtv/ivtvfb.c @@ -1293,7 +1293,6 @@ static int __init ivtvfb_init(void) drv = driver_find("ivtv", &pci_bus_type); err = driver_for_each_device(drv, NULL, ®istered, ivtvfb_callback_init); - put_driver(drv); if (!registered) { printk(KERN_ERR "ivtvfb: no cards found\n"); return -ENODEV; @@ -1310,7 +1309,6 @@ static void ivtvfb_cleanup(void) drv = driver_find("ivtv", &pci_bus_type); err = driver_for_each_device(drv, NULL, NULL, ivtvfb_callback_cleanup); - put_driver(drv); } module_init(ivtvfb_init); diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.c b/drivers/media/video/s5p-fimc/fimc-mdevice.c index 8ea4ee116e4..63eccb55728 100644 --- a/drivers/media/video/s5p-fimc/fimc-mdevice.c +++ b/drivers/media/video/s5p-fimc/fimc-mdevice.c @@ -344,16 +344,13 @@ static int fimc_md_register_platform_entities(struct fimc_md *fmd) return -ENODEV; ret = driver_for_each_device(driver, NULL, fmd, fimc_register_callback); - put_driver(driver); if (ret) return ret; driver = driver_find(CSIS_DRIVER_NAME, &platform_bus_type); - if (driver) { + if (driver) ret = driver_for_each_device(driver, NULL, fmd, csis_register_callback); - put_driver(driver); - } return ret; } diff --git a/drivers/media/video/s5p-tv/mixer_video.c b/drivers/media/video/s5p-tv/mixer_video.c index 7884baeff76..f7ca5cc143c 100644 --- a/drivers/media/video/s5p-tv/mixer_video.c +++ b/drivers/media/video/s5p-tv/mixer_video.c @@ -58,7 +58,6 @@ static struct v4l2_subdev *find_and_register_subdev( } done: - put_driver(drv); return sd; } diff --git a/drivers/s390/net/smsgiucv_app.c b/drivers/s390/net/smsgiucv_app.c index 4d2ea400042..32515a201bb 100644 --- a/drivers/s390/net/smsgiucv_app.c +++ b/drivers/s390/net/smsgiucv_app.c @@ -168,7 +168,7 @@ static int __init smsgiucv_app_init(void) rc = dev_set_name(smsg_app_dev, KMSG_COMPONENT); if (rc) { kfree(smsg_app_dev); - goto fail_put_driver; + goto fail; } smsg_app_dev->bus = &iucv_bus; smsg_app_dev->parent = iucv_root; @@ -177,7 +177,7 @@ static int __init smsgiucv_app_init(void) rc = device_register(smsg_app_dev); if (rc) { put_device(smsg_app_dev); - goto fail_put_driver; + goto fail; } /* convert sender to uppercase characters */ @@ -191,12 +191,11 @@ static int __init smsgiucv_app_init(void) rc = smsg_register_callback(SMSG_PREFIX, smsg_app_callback); if (rc) { device_unregister(smsg_app_dev); - goto fail_put_driver; + goto fail; } rc = 0; -fail_put_driver: - put_driver(smsgiucv_drv); +fail: return rc; } module_init(smsgiucv_app_init); -- cgit v1.2.3-70-g09d2 From cef9bc56e1e944afd11f96de569657117a138c6d Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 24 Jan 2012 13:34:41 -0500 Subject: Dynamic ID addition doesn't need get_driver() As part of the removal of get_driver()/put_driver(), this patch (as1511) changes all the places that add dynamic IDs for drivers. Since these additions are done by writing to the drivers' sysfs attribute files, and the attributes are removed when the drivers are unregistered, there is no reason to take an extra reference to the drivers. The one exception is the pci-stub driver, which calls pci_add_dynid() as part of its registration. But again, there's no reason to take an extra reference here, because the driver can't be unloaded while it is being registered. Signed-off-by: Alan Stern CC: Dmitry Torokhov CC: Jiri Kosina CC: Jesse Barnes CC: Dominik Brodowski Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-core.c | 6 +----- drivers/pci/pci-driver.c | 2 -- drivers/pcmcia/ds.c | 5 +---- drivers/usb/core/driver.c | 5 +---- 4 files changed, 3 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index af08ce7207d..bce53fa0e16 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1619,11 +1619,7 @@ static ssize_t store_new_id(struct device_driver *drv, const char *buf, list_add_tail(&dynid->list, &hdrv->dyn_list); spin_unlock(&hdrv->dyn_lock); - ret = 0; - if (get_driver(&hdrv->driver)) { - ret = driver_attach(&hdrv->driver); - put_driver(&hdrv->driver); - } + ret = driver_attach(&hdrv->driver); return ret ? : count; } diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 3623d65f8b8..ff540477fe8 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -72,9 +72,7 @@ int pci_add_dynid(struct pci_driver *drv, list_add_tail(&dynid->node, &drv->dynids.list); spin_unlock(&drv->dynids.lock); - get_driver(&drv->driver); retval = driver_attach(&drv->driver); - put_driver(&drv->driver); return retval; } diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 749c2a16012..059699f6363 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -127,10 +127,7 @@ pcmcia_store_new_id(struct device_driver *driver, const char *buf, size_t count) list_add_tail(&dynid->node, &pdrv->dynids.list); mutex_unlock(&pdrv->dynids.lock); - if (get_driver(&pdrv->drv)) { - retval = driver_attach(&pdrv->drv); - put_driver(&pdrv->drv); - } + retval = driver_attach(&pdrv->drv); if (retval) return retval; diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index d40ff956881..54c493b4226 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -71,10 +71,7 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids, list_add_tail(&dynid->node, &dynids->list); spin_unlock(&dynids->lock); - if (get_driver(driver)) { - retval = driver_attach(driver); - put_driver(driver); - } + retval = driver_attach(driver); if (retval) return retval; -- cgit v1.2.3-70-g09d2 From 9f30ea950edfaefa51221dd26a065b3442599778 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Tue, 24 Jan 2012 13:35:02 -0500 Subject: cio: remove {get,put}_driver Remove useless {get,put}_driver - the caller of the functions has to ensure valid driver pointers. Signed-off-by: Sebastian Ott Signed-off-by: Alan Stern CC: Martin Schwidefsky Signed-off-by: Greg Kroah-Hartman --- drivers/s390/cio/ccwgroup.c | 2 -- drivers/s390/cio/device.c | 8 +------- 2 files changed, 1 insertion(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index 4f1989d27b1..5f1dc6fb570 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c @@ -580,7 +580,6 @@ void ccwgroup_driver_unregister(struct ccwgroup_driver *cdriver) struct device *dev; /* We don't want ccwgroup devices to live longer than their driver. */ - get_driver(&cdriver->driver); while ((dev = driver_find_device(&cdriver->driver, NULL, NULL, __ccwgroup_match_all))) { struct ccwgroup_device *gdev = to_ccwgroupdev(dev); @@ -592,7 +591,6 @@ void ccwgroup_driver_unregister(struct ccwgroup_driver *cdriver) mutex_unlock(&gdev->reg_mutex); put_device(dev); } - put_driver(&cdriver->driver); driver_unregister(&cdriver->driver); } EXPORT_SYMBOL(ccwgroup_driver_unregister); diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 47269858ecb..02d01525946 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -1676,15 +1676,9 @@ struct ccw_device *get_ccwdev_by_busid(struct ccw_driver *cdrv, const char *bus_id) { struct device *dev; - struct device_driver *drv; - drv = get_driver(&cdrv->driver); - if (!drv) - return NULL; - - dev = driver_find_device(drv, NULL, (void *)bus_id, + dev = driver_find_device(&cdrv->driver, NULL, (void *)bus_id, __ccwdev_check_busid); - put_driver(drv); return dev ? to_ccwdev(dev) : NULL; } -- cgit v1.2.3-70-g09d2 From f3ff9247088a0af0c192a28908dab76ff3d8871f Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 24 Jan 2012 13:35:24 -0500 Subject: Remove useless get_driver()/put_driver() calls As part of the removal of get_driver()/put_driver(), this patch (as1512) gets rid of various useless and unnecessary calls in several drivers. In some cases it may be desirable to pin the driver by calling try_module_get(), but that can be done later. Signed-off-by: Alan Stern CC: "David S. Miller" CC: Konrad Rzeszutek Wilk CC: Michael Buesch CC: Joerg Roedel Signed-off-by: Greg Kroah-Hartman --- drivers/net/phy/phy_device.c | 6 +----- drivers/pci/xen-pcifront.c | 3 +-- drivers/ssb/main.c | 20 ++------------------ lib/dma-debug.c | 3 +-- 4 files changed, 5 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index f320f466f03..e8c42d6a7d1 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -915,9 +915,7 @@ static int phy_probe(struct device *dev) phydev = to_phy_device(dev); - /* Make sure the driver is held. - * XXX -- Is this correct? */ - drv = get_driver(phydev->dev.driver); + drv = phydev->dev.driver; phydrv = to_phy_driver(drv); phydev->drv = phydrv; @@ -957,8 +955,6 @@ static int phy_remove(struct device *dev) if (phydev->drv->remove) phydev->drv->remove(phydev); - - put_driver(dev->driver); phydev->drv = NULL; return 0; diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c index 7cf3d2fcf56..6f819988a8d 100644 --- a/drivers/pci/xen-pcifront.c +++ b/drivers/pci/xen-pcifront.c @@ -593,7 +593,7 @@ static pci_ers_result_t pcifront_common_process(int cmd, } pdrv = pcidev->driver; - if (get_driver(&pdrv->driver)) { + if (pdrv->driver) { if (pdrv->err_handler && pdrv->err_handler->error_detected) { dev_dbg(&pcidev->dev, "trying to call AER service\n"); @@ -623,7 +623,6 @@ static pci_ers_result_t pcifront_common_process(int cmd, } } } - put_driver(&pdrv->driver); } if (!flag) result = PCI_ERS_RESULT_NONE; diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index bb6317fb925..ff109ae9476 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -140,19 +140,6 @@ static void ssb_device_put(struct ssb_device *dev) put_device(dev->dev); } -static inline struct ssb_driver *ssb_driver_get(struct ssb_driver *drv) -{ - if (drv) - get_driver(&drv->drv); - return drv; -} - -static inline void ssb_driver_put(struct ssb_driver *drv) -{ - if (drv) - put_driver(&drv->drv); -} - static int ssb_device_resume(struct device *dev) { struct ssb_device *ssb_dev = dev_to_ssb_dev(dev); @@ -250,11 +237,9 @@ int ssb_devices_freeze(struct ssb_bus *bus, struct ssb_freeze_context *ctx) ssb_device_put(sdev); continue; } - sdrv = ssb_driver_get(drv_to_ssb_drv(sdev->dev->driver)); - if (!sdrv || SSB_WARN_ON(!sdrv->remove)) { - ssb_device_put(sdev); + sdrv = drv_to_ssb_drv(sdev->dev->driver); + if (SSB_WARN_ON(!sdrv->remove)) continue; - } sdrv->remove(sdev); ctx->device_frozen[i] = 1; } @@ -293,7 +278,6 @@ int ssb_devices_thaw(struct ssb_freeze_context *ctx) dev_name(sdev->dev)); result = err; } - ssb_driver_put(sdrv); ssb_device_put(sdev); } diff --git a/lib/dma-debug.c b/lib/dma-debug.c index fea790a2b17..13ef2338be4 100644 --- a/lib/dma-debug.c +++ b/lib/dma-debug.c @@ -170,7 +170,7 @@ static bool driver_filter(struct device *dev) return false; /* driver filter on but not yet initialized */ - drv = get_driver(dev->driver); + drv = dev->driver; if (!drv) return false; @@ -185,7 +185,6 @@ static bool driver_filter(struct device *dev) } read_unlock_irqrestore(&driver_name_lock, flags); - put_driver(drv); return ret; } -- cgit v1.2.3-70-g09d2 From 9875bb480cc89d9b690f7028aadf7e58454f0dae Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 24 Jan 2012 13:35:37 -0500 Subject: Eliminate get_driver() and put_driver() Now that there are no users of get_driver() or put_driver(), this patch (as1513) removes those routines completely. Signed-off-by: Alan Stern CC: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/base/driver.c | 28 ---------------------------- include/linux/device.h | 2 -- 2 files changed, 30 deletions(-) (limited to 'drivers') diff --git a/drivers/base/driver.c b/drivers/base/driver.c index e979cad75c6..60e4f77ca66 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -153,34 +153,6 @@ int driver_add_kobj(struct device_driver *drv, struct kobject *kobj, } EXPORT_SYMBOL_GPL(driver_add_kobj); -/** - * get_driver - increment driver reference count. - * @drv: driver. - */ -struct device_driver *get_driver(struct device_driver *drv) -{ - if (drv) { - struct driver_private *priv; - struct kobject *kobj; - - kobj = kobject_get(&drv->p->kobj); - priv = to_driver(kobj); - return priv->driver; - } - return NULL; -} -EXPORT_SYMBOL_GPL(get_driver); - -/** - * put_driver - decrement driver's refcount. - * @drv: driver. - */ -void put_driver(struct device_driver *drv) -{ - kobject_put(&drv->p->kobj); -} -EXPORT_SYMBOL_GPL(put_driver); - static int driver_add_groups(struct device_driver *drv, const struct attribute_group **groups) { diff --git a/include/linux/device.h b/include/linux/device.h index a782d7ff9e8..d28bd829567 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -238,8 +238,6 @@ struct device_driver { extern int __must_check driver_register(struct device_driver *drv); extern void driver_unregister(struct device_driver *drv); -extern struct device_driver *get_driver(struct device_driver *drv); -extern void put_driver(struct device_driver *drv); extern struct device_driver *driver_find(const char *name, struct bus_type *bus); extern int driver_probe_done(void); -- cgit v1.2.3-70-g09d2 From b00e126ffea89b687a83093546058b07aa054b4c Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 22 Jan 2012 15:33:49 +0800 Subject: MISC: convert drivers/misc/* to use module_platform_driver() This patch converts the drivers in drivers/misc/* to use the module_platform_driver() macro which makes the code smaller and a bit simpler. Signed-off-by: Axel Lin Acked-by: Ira W. Snyder Cc: Pavan Savoy Cc: Donggeun Kim Acked-By: Pratyush Anand Acked-by: Arnd Bergmann Acked-by: Pratyush Anand Signed-off-by: Greg Kroah-Hartman --- drivers/misc/carma/carma-fpga.c | 17 +---------------- drivers/misc/max8997-muic.c | 12 +----------- drivers/misc/spear13xx_pcie_gadget.c | 12 +----------- drivers/misc/ti-st/st_kim.c | 13 +------------ 4 files changed, 4 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/carma/carma-fpga.c b/drivers/misc/carma/carma-fpga.c index 14e974b2a78..366bc156e34 100644 --- a/drivers/misc/carma/carma-fpga.c +++ b/drivers/misc/carma/carma-fpga.c @@ -1410,23 +1410,8 @@ static struct platform_driver data_of_driver = { }, }; -/* - * Module Init / Exit - */ - -static int __init data_init(void) -{ - return platform_driver_register(&data_of_driver); -} - -static void __exit data_exit(void) -{ - platform_driver_unregister(&data_of_driver); -} +module_platform_driver(data_of_driver); MODULE_AUTHOR("Ira W. Snyder "); MODULE_DESCRIPTION("CARMA DATA-FPGA Access Driver"); MODULE_LICENSE("GPL"); - -module_init(data_init); -module_exit(data_exit); diff --git a/drivers/misc/max8997-muic.c b/drivers/misc/max8997-muic.c index d74ef41aabd..19591eaa492 100644 --- a/drivers/misc/max8997-muic.c +++ b/drivers/misc/max8997-muic.c @@ -488,17 +488,7 @@ static struct platform_driver max8997_muic_driver = { .remove = __devexit_p(max8997_muic_remove), }; -static int __init max8997_muic_init(void) -{ - return platform_driver_register(&max8997_muic_driver); -} -module_init(max8997_muic_init); - -static void __exit max8997_muic_exit(void) -{ - platform_driver_unregister(&max8997_muic_driver); -} -module_exit(max8997_muic_exit); +module_platform_driver(max8997_muic_driver); MODULE_DESCRIPTION("Maxim MAX8997 MUIC driver"); MODULE_AUTHOR("Donggeun Kim "); diff --git a/drivers/misc/spear13xx_pcie_gadget.c b/drivers/misc/spear13xx_pcie_gadget.c index 43d073bc1d9..123ed98eec3 100644 --- a/drivers/misc/spear13xx_pcie_gadget.c +++ b/drivers/misc/spear13xx_pcie_gadget.c @@ -891,17 +891,7 @@ static struct platform_driver spear_pcie_gadget_driver = { }, }; -static int __init spear_pcie_gadget_init(void) -{ - return platform_driver_register(&spear_pcie_gadget_driver); -} -module_init(spear_pcie_gadget_init); - -static void __exit spear_pcie_gadget_exit(void) -{ - platform_driver_unregister(&spear_pcie_gadget_driver); -} -module_exit(spear_pcie_gadget_exit); +module_platform_driver(spear_pcie_gadget_driver); MODULE_ALIAS("platform:pcie-gadget-spear"); MODULE_AUTHOR("Pratyush Anand"); diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c index a7a861ceee2..7c14f8fd98d 100644 --- a/drivers/misc/ti-st/st_kim.c +++ b/drivers/misc/ti-st/st_kim.c @@ -837,19 +837,8 @@ static struct platform_driver kim_platform_driver = { }, }; -static int __init st_kim_init(void) -{ - return platform_driver_register(&kim_platform_driver); -} - -static void __exit st_kim_deinit(void) -{ - platform_driver_unregister(&kim_platform_driver); -} - +module_platform_driver(kim_platform_driver); -module_init(st_kim_init); -module_exit(st_kim_deinit); MODULE_AUTHOR("Pavan Savoy "); MODULE_DESCRIPTION("Shared Transport Driver for TI BT/FM/GPS combo chips "); MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From a64fe2ed76614d37abb6966a67f4f39d10efba3c Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 22 Jan 2012 15:36:45 +0800 Subject: MISC: convert drivers/misc/* to use module_i2c_driver() This patch converts the drivers in drivers/misc/* to use the module_i2c_driver() macro which makes the code smaller and a bit simpler. Signed-off-by: Axel Lin Cc: Michael Hennerich Cc: Anantha Narayanan Cc: Hemanth V Cc: Christoph Mair Cc: Grant Likely Cc: Ben Gardner Cc: Minkyu Kang Cc: Kalhan Trisal Cc: Darrick J. Wong Cc: Daniel Mack Cc: Rodolfo Giometti Acked-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ad525x_dpot-i2c.c | 12 +----------- drivers/misc/apds9802als.c | 12 +----------- drivers/misc/apds990x.c | 13 +------------ drivers/misc/bh1770glc.c | 13 +------------ drivers/misc/bh1780gli.c | 15 ++------------- drivers/misc/bmp085.c | 14 +------------- drivers/misc/ds1682.c | 13 +------------ drivers/misc/eeprom/eeprom.c | 14 +------------- drivers/misc/eeprom/max6875.c | 14 +------------- drivers/misc/fsa9480.c | 12 +----------- drivers/misc/hmc6352.c | 13 +------------ drivers/misc/ics932s401.c | 13 +------------ drivers/misc/isl29003.c | 14 +------------- drivers/misc/isl29020.c | 13 +------------ drivers/misc/lis3lv02d/lis3lv02d_i2c.c | 13 +------------ drivers/misc/tsl2550.c | 13 +------------ 16 files changed, 17 insertions(+), 194 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/ad525x_dpot-i2c.c b/drivers/misc/ad525x_dpot-i2c.c index 83adab69bfd..820826270b6 100644 --- a/drivers/misc/ad525x_dpot-i2c.c +++ b/drivers/misc/ad525x_dpot-i2c.c @@ -113,17 +113,7 @@ static struct i2c_driver ad_dpot_i2c_driver = { .id_table = ad_dpot_id, }; -static int __init ad_dpot_i2c_init(void) -{ - return i2c_add_driver(&ad_dpot_i2c_driver); -} -module_init(ad_dpot_i2c_init); - -static void __exit ad_dpot_i2c_exit(void) -{ - i2c_del_driver(&ad_dpot_i2c_driver); -} -module_exit(ad_dpot_i2c_exit); +module_i2c_driver(ad_dpot_i2c_driver); MODULE_AUTHOR("Michael Hennerich "); MODULE_DESCRIPTION("digital potentiometer I2C bus driver"); diff --git a/drivers/misc/apds9802als.c b/drivers/misc/apds9802als.c index 81db7811cf6..0314773f6db 100644 --- a/drivers/misc/apds9802als.c +++ b/drivers/misc/apds9802als.c @@ -332,17 +332,7 @@ static struct i2c_driver apds9802als_driver = { .id_table = apds9802als_id, }; -static int __init sensor_apds9802als_init(void) -{ - return i2c_add_driver(&apds9802als_driver); -} - -static void __exit sensor_apds9802als_exit(void) -{ - i2c_del_driver(&apds9802als_driver); -} -module_init(sensor_apds9802als_init); -module_exit(sensor_apds9802als_exit); +module_i2c_driver(apds9802als_driver); MODULE_AUTHOR("Anantha Narayanan "); MODULE_DESCRIPTION("DS1682 Elapsed Time Indicator driver"); MODULE_LICENSE("GPL"); - -module_init(ds1682_init); -module_exit(ds1682_exit); diff --git a/drivers/misc/eeprom/eeprom.c b/drivers/misc/eeprom/eeprom.c index 45060ddc4e5..c169e07654c 100644 --- a/drivers/misc/eeprom/eeprom.c +++ b/drivers/misc/eeprom/eeprom.c @@ -229,22 +229,10 @@ static struct i2c_driver eeprom_driver = { .address_list = normal_i2c, }; -static int __init eeprom_init(void) -{ - return i2c_add_driver(&eeprom_driver); -} - -static void __exit eeprom_exit(void) -{ - i2c_del_driver(&eeprom_driver); -} - +module_i2c_driver(eeprom_driver); MODULE_AUTHOR("Frodo Looijaard and " "Philip Edelbrock and " "Greg Kroah-Hartman "); MODULE_DESCRIPTION("I2C EEPROM driver"); MODULE_LICENSE("GPL"); - -module_init(eeprom_init); -module_exit(eeprom_exit); diff --git a/drivers/misc/eeprom/max6875.c b/drivers/misc/eeprom/max6875.c index 5653a3ce051..e36157d5d3a 100644 --- a/drivers/misc/eeprom/max6875.c +++ b/drivers/misc/eeprom/max6875.c @@ -208,20 +208,8 @@ static struct i2c_driver max6875_driver = { .id_table = max6875_id, }; -static int __init max6875_init(void) -{ - return i2c_add_driver(&max6875_driver); -} - -static void __exit max6875_exit(void) -{ - i2c_del_driver(&max6875_driver); -} - +module_i2c_driver(max6875_driver); MODULE_AUTHOR("Ben Gardner "); MODULE_DESCRIPTION("MAX6875 driver"); MODULE_LICENSE("GPL"); - -module_init(max6875_init); -module_exit(max6875_exit); diff --git a/drivers/misc/fsa9480.c b/drivers/misc/fsa9480.c index f6586d53e1a..483d6b73809 100644 --- a/drivers/misc/fsa9480.c +++ b/drivers/misc/fsa9480.c @@ -541,17 +541,7 @@ static struct i2c_driver fsa9480_i2c_driver = { .id_table = fsa9480_id, }; -static int __init fsa9480_init(void) -{ - return i2c_add_driver(&fsa9480_i2c_driver); -} -module_init(fsa9480_init); - -static void __exit fsa9480_exit(void) -{ - i2c_del_driver(&fsa9480_i2c_driver); -} -module_exit(fsa9480_exit); +module_i2c_driver(fsa9480_i2c_driver); MODULE_AUTHOR("Minkyu Kang "); MODULE_DESCRIPTION("FSA9480 USB Switch driver"); diff --git a/drivers/misc/hmc6352.c b/drivers/misc/hmc6352.c index ca938fc8a8d..423cd40f1c0 100644 --- a/drivers/misc/hmc6352.c +++ b/drivers/misc/hmc6352.c @@ -148,18 +148,7 @@ static struct i2c_driver hmc6352_driver = { .id_table = hmc6352_id, }; -static int __init sensor_hmc6352_init(void) -{ - return i2c_add_driver(&hmc6352_driver); -} - -static void __exit sensor_hmc6352_exit(void) -{ - i2c_del_driver(&hmc6352_driver); -} - -module_init(sensor_hmc6352_init); -module_exit(sensor_hmc6352_exit); +module_i2c_driver(hmc6352_driver); MODULE_AUTHOR("Kalhan Trisal "); MODULE_DESCRIPTION("ICS932S401 driver"); MODULE_LICENSE("GPL"); -module_init(ics932s401_init); -module_exit(ics932s401_exit); - /* IBM IntelliStation Z30 */ MODULE_ALIAS("dmi:bvnIBM:*:rn9228:*"); MODULE_ALIAS("dmi:bvnIBM:*:rn9232:*"); diff --git a/drivers/misc/isl29003.c b/drivers/misc/isl29003.c index a71e245801e..eb5de2e210d 100644 --- a/drivers/misc/isl29003.c +++ b/drivers/misc/isl29003.c @@ -455,21 +455,9 @@ static struct i2c_driver isl29003_driver = { .id_table = isl29003_id, }; -static int __init isl29003_init(void) -{ - return i2c_add_driver(&isl29003_driver); -} - -static void __exit isl29003_exit(void) -{ - i2c_del_driver(&isl29003_driver); -} +module_i2c_driver(isl29003_driver); MODULE_AUTHOR("Daniel Mack "); MODULE_DESCRIPTION("ISL29003 ambient light sensor driver"); MODULE_LICENSE("GPL v2"); MODULE_VERSION(DRIVER_VERSION); - -module_init(isl29003_init); -module_exit(isl29003_exit); - diff --git a/drivers/misc/isl29020.c b/drivers/misc/isl29020.c index 3d6cce663be..0aa08c74646 100644 --- a/drivers/misc/isl29020.c +++ b/drivers/misc/isl29020.c @@ -230,18 +230,7 @@ static struct i2c_driver isl29020_driver = { .id_table = isl29020_id, }; -static int __init sensor_isl29020_init(void) -{ - return i2c_add_driver(&isl29020_driver); -} - -static void __exit sensor_isl29020_exit(void) -{ - i2c_del_driver(&isl29020_driver); -} - -module_init(sensor_isl29020_init); -module_exit(sensor_isl29020_exit); +module_i2c_driver(isl29020_driver); MODULE_AUTHOR("Kalhan Trisal "); MODULE_DESCRIPTION("Intersil isl29020 ALS Driver"); diff --git a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c index c02fea029dc..e8c0019da97 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c +++ b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c @@ -256,19 +256,8 @@ static struct i2c_driver lis3lv02d_i2c_driver = { .id_table = lis3lv02d_id, }; -static int __init lis3lv02d_init(void) -{ - return i2c_add_driver(&lis3lv02d_i2c_driver); -} - -static void __exit lis3lv02d_exit(void) -{ - i2c_del_driver(&lis3lv02d_i2c_driver); -} +module_i2c_driver(lis3lv02d_i2c_driver); MODULE_AUTHOR("Nokia Corporation"); MODULE_DESCRIPTION("lis3lv02d I2C interface"); MODULE_LICENSE("GPL"); - -module_init(lis3lv02d_init); -module_exit(lis3lv02d_exit); diff --git a/drivers/misc/tsl2550.c b/drivers/misc/tsl2550.c index 483ae5f7f68..0beb298a17d 100644 --- a/drivers/misc/tsl2550.c +++ b/drivers/misc/tsl2550.c @@ -454,20 +454,9 @@ static struct i2c_driver tsl2550_driver = { .id_table = tsl2550_id, }; -static int __init tsl2550_init(void) -{ - return i2c_add_driver(&tsl2550_driver); -} - -static void __exit tsl2550_exit(void) -{ - i2c_del_driver(&tsl2550_driver); -} +module_i2c_driver(tsl2550_driver); MODULE_AUTHOR("Rodolfo Giometti "); MODULE_DESCRIPTION("TSL2550 ambient light sensor driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRIVER_VERSION); - -module_init(tsl2550_init); -module_exit(tsl2550_exit); -- cgit v1.2.3-70-g09d2 From a3dc3c9eb0a7bcf17604ee444c48b94e2591812d Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 22 Jan 2012 15:38:22 +0800 Subject: MISC: convert drivers/misc/* to use module_spi_driver() This patch converts the drivers in drivers/misc/* to use the module_spi_driver() macro which makes the code smaller and a bit simpler. Signed-off-by: Axel Lin Cc: Michael Hennerich Cc: Anatolij Gustschin Cc: Daniel Mack Acked-by: Michael Hennerich Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ad525x_dpot-spi.c | 12 +----------- drivers/misc/eeprom/at25.c | 12 +----------- drivers/misc/eeprom/eeprom_93xx46.c | 12 +----------- drivers/misc/lis3lv02d/lis3lv02d_spi.c | 13 +------------ drivers/misc/ti_dac7512.c | 13 +------------ 5 files changed, 5 insertions(+), 57 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/ad525x_dpot-spi.c b/drivers/misc/ad525x_dpot-spi.c index 822749e41fe..f62317540d0 100644 --- a/drivers/misc/ad525x_dpot-spi.c +++ b/drivers/misc/ad525x_dpot-spi.c @@ -135,17 +135,7 @@ static struct spi_driver ad_dpot_spi_driver = { .id_table = ad_dpot_spi_id, }; -static int __init ad_dpot_spi_init(void) -{ - return spi_register_driver(&ad_dpot_spi_driver); -} -module_init(ad_dpot_spi_init); - -static void __exit ad_dpot_spi_exit(void) -{ - spi_unregister_driver(&ad_dpot_spi_driver); -} -module_exit(ad_dpot_spi_exit); +module_spi_driver(ad_dpot_spi_driver); MODULE_AUTHOR("Michael Hennerich "); MODULE_DESCRIPTION("digital potentiometer SPI bus driver"); diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c index c627e4174cc..01ab3c9b4cf 100644 --- a/drivers/misc/eeprom/at25.c +++ b/drivers/misc/eeprom/at25.c @@ -405,17 +405,7 @@ static struct spi_driver at25_driver = { .remove = __devexit_p(at25_remove), }; -static int __init at25_init(void) -{ - return spi_register_driver(&at25_driver); -} -module_init(at25_init); - -static void __exit at25_exit(void) -{ - spi_unregister_driver(&at25_driver); -} -module_exit(at25_exit); +module_spi_driver(at25_driver); MODULE_DESCRIPTION("Driver for most SPI EEPROMs"); MODULE_AUTHOR("David Brownell"); diff --git a/drivers/misc/eeprom/eeprom_93xx46.c b/drivers/misc/eeprom/eeprom_93xx46.c index 0c7ebb1e19e..ce3fe3633dd 100644 --- a/drivers/misc/eeprom/eeprom_93xx46.c +++ b/drivers/misc/eeprom/eeprom_93xx46.c @@ -392,17 +392,7 @@ static struct spi_driver eeprom_93xx46_driver = { .remove = __devexit_p(eeprom_93xx46_remove), }; -static int __init eeprom_93xx46_init(void) -{ - return spi_register_driver(&eeprom_93xx46_driver); -} -module_init(eeprom_93xx46_init); - -static void __exit eeprom_93xx46_exit(void) -{ - spi_unregister_driver(&eeprom_93xx46_driver); -} -module_exit(eeprom_93xx46_exit); +module_spi_driver(eeprom_93xx46_driver); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Driver for 93xx46 EEPROMs"); diff --git a/drivers/misc/lis3lv02d/lis3lv02d_spi.c b/drivers/misc/lis3lv02d/lis3lv02d_spi.c index b2c1be12d16..80880e984b4 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d_spi.c +++ b/drivers/misc/lis3lv02d/lis3lv02d_spi.c @@ -126,18 +126,7 @@ static struct spi_driver lis302dl_spi_driver = { .remove = __devexit_p(lis302dl_spi_remove), }; -static int __init lis302dl_init(void) -{ - return spi_register_driver(&lis302dl_spi_driver); -} - -static void __exit lis302dl_exit(void) -{ - spi_unregister_driver(&lis302dl_spi_driver); -} - -module_init(lis302dl_init); -module_exit(lis302dl_exit); +module_spi_driver(lis302dl_spi_driver); MODULE_AUTHOR("Daniel Mack "); MODULE_DESCRIPTION("lis3lv02d SPI glue layer"); diff --git a/drivers/misc/ti_dac7512.c b/drivers/misc/ti_dac7512.c index d3f229a3a77..5acbba120de 100644 --- a/drivers/misc/ti_dac7512.c +++ b/drivers/misc/ti_dac7512.c @@ -82,20 +82,9 @@ static struct spi_driver dac7512_driver = { .remove = __devexit_p(dac7512_remove), }; -static int __init dac7512_init(void) -{ - return spi_register_driver(&dac7512_driver); -} - -static void __exit dac7512_exit(void) -{ - spi_unregister_driver(&dac7512_driver); -} +module_spi_driver(dac7512_driver); MODULE_AUTHOR("Daniel Mack "); MODULE_DESCRIPTION("DAC7512 16-bit DAC"); MODULE_LICENSE("GPL v2"); MODULE_VERSION(DRIVER_VERSION); - -module_init(dac7512_init); -module_exit(dac7512_exit); -- cgit v1.2.3-70-g09d2 From cf66f9d48a9c95baf8f13b199a633ce1c4cf952a Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Mon, 23 Jan 2012 08:24:43 +0000 Subject: xen/netfront: add netconsole support. add polling interface to xen-netfront device to support netconsole This patch also alters the spin_lock usage to use irqsave variant. Documentation/networking/netdevices.txt states that start_xmit can be called with interrupts disabled by netconsole and therefore using the irqsave/restore locking in this function is looks correct. Signed-off-by: Tina.Yang Cc: Jeremy Fitzhardinge Signed-off-by: Zhenzhong.Duan Tested-by: gurudas.pai [v1: Copy-n-pasted Ian Campbell comments] Signed-off-by: Konrad Rzeszutek Wilk Acked-by: Ian Campbell Signed-off-by: David S. Miller --- drivers/net/xen-netfront.c | 57 +++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index fa679057630..db638b4454e 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -489,6 +489,7 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) int frags = skb_shinfo(skb)->nr_frags; unsigned int offset = offset_in_page(data); unsigned int len = skb_headlen(skb); + unsigned long flags; frags += DIV_ROUND_UP(offset + len, PAGE_SIZE); if (unlikely(frags > MAX_SKB_FRAGS + 1)) { @@ -498,12 +499,12 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) goto drop; } - spin_lock_irq(&np->tx_lock); + spin_lock_irqsave(&np->tx_lock, flags); if (unlikely(!netif_carrier_ok(dev) || (frags > 1 && !xennet_can_sg(dev)) || netif_needs_gso(skb, netif_skb_features(skb)))) { - spin_unlock_irq(&np->tx_lock); + spin_unlock_irqrestore(&np->tx_lock, flags); goto drop; } @@ -574,7 +575,7 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) if (!netfront_tx_slot_available(np)) netif_stop_queue(dev); - spin_unlock_irq(&np->tx_lock); + spin_unlock_irqrestore(&np->tx_lock, flags); return NETDEV_TX_OK; @@ -1228,6 +1229,33 @@ static int xennet_set_features(struct net_device *dev, return 0; } +static irqreturn_t xennet_interrupt(int irq, void *dev_id) +{ + struct net_device *dev = dev_id; + struct netfront_info *np = netdev_priv(dev); + unsigned long flags; + + spin_lock_irqsave(&np->tx_lock, flags); + + if (likely(netif_carrier_ok(dev))) { + xennet_tx_buf_gc(dev); + /* Under tx_lock: protects access to rx shared-ring indexes. */ + if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx)) + napi_schedule(&np->napi); + } + + spin_unlock_irqrestore(&np->tx_lock, flags); + + return IRQ_HANDLED; +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +static void xennet_poll_controller(struct net_device *dev) +{ + xennet_interrupt(0, dev); +} +#endif + static const struct net_device_ops xennet_netdev_ops = { .ndo_open = xennet_open, .ndo_uninit = xennet_uninit, @@ -1239,6 +1267,9 @@ static const struct net_device_ops xennet_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_fix_features = xennet_fix_features, .ndo_set_features = xennet_set_features, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = xennet_poll_controller, +#endif }; static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev) @@ -1448,26 +1479,6 @@ static int xen_net_read_mac(struct xenbus_device *dev, u8 mac[]) return 0; } -static irqreturn_t xennet_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - struct netfront_info *np = netdev_priv(dev); - unsigned long flags; - - spin_lock_irqsave(&np->tx_lock, flags); - - if (likely(netif_carrier_ok(dev))) { - xennet_tx_buf_gc(dev); - /* Under tx_lock: protects access to rx shared-ring indexes. */ - if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx)) - napi_schedule(&np->napi); - } - - spin_unlock_irqrestore(&np->tx_lock, flags); - - return IRQ_HANDLED; -} - static int setup_netfront(struct xenbus_device *dev, struct netfront_info *info) { struct xen_netif_tx_sring *txs; -- cgit v1.2.3-70-g09d2 From aaca2377e9c08d1964a5cacb95330708a6f6d106 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 23 Jan 2012 16:44:50 +0000 Subject: net: fec: use module_platform_driver Using module_platform_driver can make the code smaller. Signed-off-by: Fabio Estevam Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index 7b25e9cf13f..e5885ccfc8f 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -1739,21 +1739,6 @@ static struct platform_driver fec_driver = { .remove = __devexit_p(fec_drv_remove), }; -static int __init -fec_enet_module_init(void) -{ - printk(KERN_INFO "FEC Ethernet Driver\n"); - - return platform_driver_register(&fec_driver); -} - -static void __exit -fec_enet_cleanup(void) -{ - platform_driver_unregister(&fec_driver); -} - -module_exit(fec_enet_cleanup); -module_init(fec_enet_module_init); +module_platform_driver(fec_driver); MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From 8d79c3490aecfe6e51f0ba6f9780746fb1434954 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 19 Jan 2012 10:50:05 -0800 Subject: drm/i915: Remove the MI_FLUSH_ENABLE setting. We have always been using the wrong bit -- it's bit 12. However, the bit also doesn't do anything -- hardware has always accepted the MI_FLUSH command even when it was specced not to. Given that there is only one MI_FLUSH emitted in all of the driver stack on gen6+ (in i965_video.c of the 2d driver, and it should be using other code to do its flush instead), just remove the MI_FLUSH enable instead of trying to fix it. Signed-off-by: Eric Anholt Reviewed-by: Kenneth Graunke Reviewed-by: Ben Widawsky Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ringbuffer.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 77e729d4e4f..b3da17af899 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -399,8 +399,6 @@ static int init_render_ring(struct intel_ring_buffer *ring) if (INTEL_INFO(dev)->gen > 3) { int mode = VS_TIMER_DISPATCH << 16 | VS_TIMER_DISPATCH; - if (IS_GEN6(dev) || IS_GEN7(dev)) - mode |= MI_FLUSH_ENABLE << 16 | MI_FLUSH_ENABLE; I915_WRITE(MI_MODE, mode); if (IS_GEN7(dev)) I915_WRITE(GFX_MODE_GEN7, -- cgit v1.2.3-70-g09d2 From d5dc9271b25822f36d299f8cab985379743424b9 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 18 Dec 2011 11:07:47 +0000 Subject: ARM: amba: add amba_device allocation/add/put functions Add functions to allocate and initialize AMBA device structures, and add them to the Linux device manager. This allows us to kill this type of operation from individual platforms, moving it to core code. Signed-off-by: Russell King --- drivers/amba/bus.c | 100 +++++++++++++++++++++++++++++++++++------------ include/linux/amba/bus.h | 3 ++ 2 files changed, 78 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 54eaf96ab21..82b65e1e12b 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -497,38 +497,20 @@ static void amba_device_release(struct device *dev) } /** - * amba_device_register - register an AMBA device - * @dev: AMBA device to register - * @parent: parent memory resource + * amba_device_add - add a previously allocated AMBA device structure + * @dev: AMBA device allocated by amba_device_alloc + * @parent: resource parent for this devices resources * - * Setup the AMBA device, reading the cell ID if present. - * Claim the resource, and register the AMBA device with - * the Linux device manager. + * Claim the resource, and read the device cell ID if not already + * initialized. Register the AMBA device with the Linux device + * manager. */ -int amba_device_register(struct amba_device *dev, struct resource *parent) +int amba_device_add(struct amba_device *dev, struct resource *parent) { u32 size; void __iomem *tmp; int i, ret; - device_initialize(&dev->dev); - - /* - * Copy from device_add - */ - if (dev->dev.init_name) { - dev_set_name(&dev->dev, "%s", dev->dev.init_name); - dev->dev.init_name = NULL; - } - - dev->dev.release = amba_device_release; - dev->dev.bus = &amba_bustype; - dev->dev.dma_mask = &dev->dma_mask; - dev->res.name = dev_name(&dev->dev); - - if (!dev->dev.coherent_dma_mask && dev->dma_mask) - dev_warn(&dev->dev, "coherent dma mask is unset\n"); - ret = request_resource(parent, &dev->res); if (ret) goto err_out; @@ -596,6 +578,74 @@ int amba_device_register(struct amba_device *dev, struct resource *parent) err_out: return ret; } +EXPORT_SYMBOL_GPL(amba_device_add); + +static void amba_device_initialize(struct amba_device *dev, const char *name) +{ + device_initialize(&dev->dev); + if (name) + dev_set_name(&dev->dev, "%s", name); + dev->dev.release = amba_device_release; + dev->dev.bus = &amba_bustype; + dev->dev.dma_mask = &dev->dma_mask; + dev->res.name = dev_name(&dev->dev); +} + +/** + * amba_device_alloc - allocate an AMBA device + * @name: sysfs name of the AMBA device + * @base: base of AMBA device + * @size: size of AMBA device + * + * Allocate and initialize an AMBA device structure. Returns %NULL + * on failure. + */ +struct amba_device *amba_device_alloc(const char *name, resource_size_t base, + size_t size) +{ + struct amba_device *dev; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (dev) { + amba_device_initialize(dev, name); + dev->res.start = base; + dev->res.end = base + size - 1; + dev->res.flags = IORESOURCE_MEM; + } + + return dev; +} +EXPORT_SYMBOL_GPL(amba_device_alloc); + +/** + * amba_device_register - register an AMBA device + * @dev: AMBA device to register + * @parent: parent memory resource + * + * Setup the AMBA device, reading the cell ID if present. + * Claim the resource, and register the AMBA device with + * the Linux device manager. + */ +int amba_device_register(struct amba_device *dev, struct resource *parent) +{ + amba_device_initialize(dev, dev->dev.init_name); + dev->dev.init_name = NULL; + + if (!dev->dev.coherent_dma_mask && dev->dma_mask) + dev_warn(&dev->dev, "coherent dma mask is unset\n"); + + return amba_device_add(dev, parent); +} + +/** + * amba_device_put - put an AMBA device + * @dev: AMBA device to put + */ +void amba_device_put(struct amba_device *dev) +{ + put_device(&dev->dev); +} +EXPORT_SYMBOL_GPL(amba_device_put); /** * amba_device_unregister - unregister an AMBA device diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h index 724c69c40bb..e1929620e5a 100644 --- a/include/linux/amba/bus.h +++ b/include/linux/amba/bus.h @@ -60,6 +60,9 @@ extern struct bus_type amba_bustype; int amba_driver_register(struct amba_driver *); void amba_driver_unregister(struct amba_driver *); +struct amba_device *amba_device_alloc(const char *, resource_size_t, size_t); +void amba_device_put(struct amba_device *); +int amba_device_add(struct amba_device *, struct resource *); int amba_device_register(struct amba_device *, struct resource *); void amba_device_unregister(struct amba_device *); struct amba_device *amba_find_device(const char *, struct device *, unsigned int, unsigned int); -- cgit v1.2.3-70-g09d2 From c0f72f8a9279f82520fc476c32c09f693661c5f4 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 18 Dec 2011 11:45:17 +0000 Subject: ARM: amba: of: convert to use amba_device_alloc Convert DT code to use the new amba_device_alloc APIs. Acked-by: Rob Herring Signed-off-by: Russell King --- drivers/of/platform.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 63b3ec48c20..cae9477a6ed 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -253,7 +253,7 @@ static struct amba_device *of_amba_device_create(struct device_node *node, if (!of_device_is_available(node)) return NULL; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = amba_device_alloc(NULL, 0, 0); if (!dev) return NULL; @@ -283,14 +283,14 @@ static struct amba_device *of_amba_device_create(struct device_node *node, if (ret) goto err_free; - ret = amba_device_register(dev, &iomem_resource); + ret = amba_device_add(dev, &iomem_resource); if (ret) goto err_free; return dev; err_free: - kfree(dev); + amba_device_put(dev); return NULL; } #else /* CONFIG_ARM_AMBA */ -- cgit v1.2.3-70-g09d2 From 023f117c547719fbc087ad72276aec5a026370df Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 18 Dec 2011 11:31:51 +0000 Subject: ARM: amba: make irq 0 invalid Fix core bus and MMCI such that irq 0 means that there is no IRQ attached. Signed-off-by: Russell King --- drivers/amba/bus.c | 4 ++-- drivers/mmc/host/mmci.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 82b65e1e12b..d15acbb4d59 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -564,9 +564,9 @@ int amba_device_add(struct amba_device *dev, struct resource *parent) if (ret) goto err_release; - if (dev->irq[0] != NO_IRQ) + if (dev->irq[0] && dev->irq[0] != NO_IRQ) ret = device_create_file(&dev->dev, &dev_attr_irq0); - if (ret == 0 && dev->irq[1] != NO_IRQ) + if (ret == 0 && dev->irq[1] && dev->irq[1] != NO_IRQ) ret = device_create_file(&dev->dev, &dev_attr_irq1); if (ret == 0) return ret; diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 0d955ffaf44..304f2f98b68 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1325,7 +1325,7 @@ static int __devinit mmci_probe(struct amba_device *dev, if (ret) goto unmap; - if (dev->irq[1] == NO_IRQ) + if (dev->irq[1] == NO_IRQ || !dev->irq[1]) host->singleirq = true; else { ret = request_irq(dev->irq[1], mmci_pio_irq, IRQF_SHARED, -- cgit v1.2.3-70-g09d2 From 2eac58d5026e4ec8b17ff8b62877fea9e1d2f1b3 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 18 Dec 2011 11:43:56 +0000 Subject: ARM: amba: make use of -1 IRQs warn Make the core warn about the use of -1 (NO_IRQ) Signed-off-by: Russell King --- drivers/amba/bus.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index d15acbb4d59..01c2cf4efcd 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -511,6 +511,9 @@ int amba_device_add(struct amba_device *dev, struct resource *parent) void __iomem *tmp; int i, ret; + WARN_ON(dev->irq[0] == (unsigned int)-1); + WARN_ON(dev->irq[1] == (unsigned int)-1); + ret = request_resource(parent, &dev->res); if (ret) goto err_out; -- cgit v1.2.3-70-g09d2 From e6b0f884520e604408ebda3b60605cabe0a8d162 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 13 Jan 2012 13:24:04 +0200 Subject: OMAPDSS: FEAT: Add FIFO_MERGE feature Add feature flag for fifo merge. OMAP2 doesn't contain fifo merge, later OMAPs do. dispc_enable_fifomerge() checks for the flag when called, and gives a WARN if fifo merge is being enabled when it is not supported. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dispc.c | 5 +++++ drivers/video/omap2/dss/dss_features.c | 9 +++++---- drivers/video/omap2/dss/dss_features.h | 1 + 3 files changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index a5ec7f37c18..d711518f9f1 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1054,6 +1054,11 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high) void dispc_enable_fifomerge(bool enable) { + if (!dss_has_feature(FEAT_FIFO_MERGE)) { + WARN_ON(enable); + return; + } + DSSDBG("FIFO merge %s\n", enable ? "enabled" : "disabled"); REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14); } diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c index afcb59301c3..c2456c5bcd3 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/omap2/dss/dss_features.c @@ -370,7 +370,7 @@ static const struct omap_dss_features omap3430_dss_features = { FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF | FEAT_DSI_PLL_FREQSEL | FEAT_DSI_REVERSE_TXCLKESC | FEAT_VENC_REQUIRES_TV_DAC_CLK | FEAT_CPR | FEAT_PRELOAD | - FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER, + FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER | FEAT_FIFO_MERGE, .num_mgrs = 2, .num_ovls = 3, @@ -394,7 +394,7 @@ static const struct omap_dss_features omap3630_dss_features = { FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF | FEAT_DSI_PLL_PWR_BUG | FEAT_DSI_PLL_FREQSEL | FEAT_CPR | FEAT_PRELOAD | - FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER, + FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER | FEAT_FIFO_MERGE, .num_mgrs = 2, .num_ovls = 3, @@ -419,7 +419,7 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = { FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH | FEAT_DSI_GNQ | FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2 | FEAT_CPR | FEAT_PRELOAD | FEAT_FIR_COEF_V | - FEAT_ALPHA_FREE_ZORDER, + FEAT_ALPHA_FREE_ZORDER | FEAT_FIFO_MERGE, .num_mgrs = 3, .num_ovls = 4, @@ -443,7 +443,8 @@ static const struct omap_dss_features omap4_dss_features = { FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH | FEAT_DSI_GNQ | FEAT_HDMI_CTS_SWMODE | FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2 | FEAT_CPR | - FEAT_PRELOAD | FEAT_FIR_COEF_V | FEAT_ALPHA_FREE_ZORDER, + FEAT_PRELOAD | FEAT_FIR_COEF_V | FEAT_ALPHA_FREE_ZORDER | + FEAT_FIFO_MERGE, .num_mgrs = 3, .num_ovls = 4, diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h index cd833bbaac3..50caee9192a 100644 --- a/drivers/video/omap2/dss/dss_features.h +++ b/drivers/video/omap2/dss/dss_features.h @@ -58,6 +58,7 @@ enum dss_feat_id { FEAT_FIR_COEF_V = 1 << 25, FEAT_ALPHA_FIXED_ZORDER = 1 << 26, FEAT_ALPHA_FREE_ZORDER = 1 << 27, + FEAT_FIFO_MERGE = 1 << 28, }; /* DSS register field id */ -- cgit v1.2.3-70-g09d2 From fb0119742291b6f30cd97026ee137b2d3d1f4de8 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 16 Nov 2011 15:00:22 +0200 Subject: OMAPDSS: APPLY: add fifo merge support funcs Add mechanism to set/unset the DISPC fifo-merge: Add new fields to dss_data, fifo_merge and fifo_merge_dirty. These are similar to the other info/dirty flags in ovl_priv_data and ovl_mgr_data, but fifo merge is a common attribute to all managers and thus outside the ovl_mgr_data. The fifo-merge field is used in the dss_write_regs_common, which handles writing the register. dss_apply_fifo_merge() can be used to set/unset the fifo merge field in the dss_data. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/apply.c | 43 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 052dc874cd3..604737f1187 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -105,6 +105,9 @@ static struct { struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS]; struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS]; + bool fifo_merge_dirty; + bool fifo_merge; + bool irq_enabled; } dss_data; @@ -585,11 +588,40 @@ static void dss_mgr_write_regs(struct omap_overlay_manager *mgr) } } +static void dss_write_regs_common(void) +{ + const int num_mgrs = omap_dss_get_num_overlay_managers(); + int i; + + if (!dss_data.fifo_merge_dirty) + return; + + for (i = 0; i < num_mgrs; ++i) { + struct omap_overlay_manager *mgr; + struct mgr_priv_data *mp; + + mgr = omap_dss_get_overlay_manager(i); + mp = get_mgr_priv(mgr); + + if (mp->enabled) { + if (dss_data.fifo_merge_dirty) { + dispc_enable_fifomerge(dss_data.fifo_merge); + dss_data.fifo_merge_dirty = false; + } + + if (mp->updating) + mp->shadow_info_dirty = true; + } + } +} + static void dss_write_regs(void) { const int num_mgrs = omap_dss_get_num_overlay_managers(); int i; + dss_write_regs_common(); + for (i = 0; i < num_mgrs; ++i) { struct omap_overlay_manager *mgr; struct mgr_priv_data *mp; @@ -659,6 +691,8 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr) dss_mgr_write_regs(mgr); + dss_write_regs_common(); + mp->updating = true; if (!dss_data.irq_enabled && need_isr()) @@ -859,6 +893,15 @@ static void dss_apply_ovl_fifo_thresholds(struct omap_overlay *ovl, op->extra_info_dirty = true; } +static void dss_apply_fifo_merge(bool use_fifo_merge) +{ + if (dss_data.fifo_merge == use_fifo_merge) + return; + + dss_data.fifo_merge = use_fifo_merge; + dss_data.fifo_merge_dirty = true; +} + static void dss_ovl_setup_fifo(struct omap_overlay *ovl) { struct ovl_priv_data *op = get_ovl_priv(ovl); -- cgit v1.2.3-70-g09d2 From 1d71f42b35ed66d90a9a39bc515bb16cfe2d4a46 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 16 Nov 2011 16:44:08 +0200 Subject: OMAPDSS: APPLY: add fifo-merge support Add fifo-merge support. This is done mainly in four functions: mgr_enable/disable and ovl_enable/disable. These are the functions where overlays are taken into and out of active use. The process to enable and disable fifo-merge is not simple. We need to do it in steps, waiting in between for certain settings to be taken into use, and continuing after that. The reason for this is that fifo-merge is a common thing for all managers/overlays, and its use must be synchronized. As an example, when we disable an overlay, we first set the overlay as disabled, then wait until the overlay is actually disabled in the HW, and only after that we may re-configure the fifos, possibly taking fifo-merge into use. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/apply.c | 164 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 156 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 604737f1187..6f7b213e096 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -902,7 +902,8 @@ static void dss_apply_fifo_merge(bool use_fifo_merge) dss_data.fifo_merge_dirty = true; } -static void dss_ovl_setup_fifo(struct omap_overlay *ovl) +static void dss_ovl_setup_fifo(struct omap_overlay *ovl, + bool use_fifo_merge) { struct ovl_priv_data *op = get_ovl_priv(ovl); struct omap_dss_device *dssdev; @@ -914,7 +915,16 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl) dssdev = ovl->manager->device; - size = dispc_ovl_get_fifo_size(ovl->id); + if (use_fifo_merge) { + int i; + + size = 0; + + for (i = 0; i < omap_dss_get_num_overlays(); ++i) + size += dispc_ovl_get_fifo_size(i); + } else { + size = dispc_ovl_get_fifo_size(ovl->id); + } burst_size = dispc_ovl_get_burst_size(ovl->id); @@ -940,7 +950,8 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl) dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high); } -static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr) +static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr, + bool use_fifo_merge) { struct omap_overlay *ovl; struct mgr_priv_data *mp; @@ -951,10 +962,10 @@ static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr) return; list_for_each_entry(ovl, &mgr->overlays, list) - dss_ovl_setup_fifo(ovl); + dss_ovl_setup_fifo(ovl, use_fifo_merge); } -static void dss_setup_fifos(void) +static void dss_setup_fifos(bool use_fifo_merge) { const int num_mgrs = omap_dss_get_num_overlay_managers(); struct omap_overlay_manager *mgr; @@ -962,15 +973,91 @@ static void dss_setup_fifos(void) for (i = 0; i < num_mgrs; ++i) { mgr = omap_dss_get_overlay_manager(i); - dss_mgr_setup_fifos(mgr); + dss_mgr_setup_fifos(mgr, use_fifo_merge); } } +static int get_num_used_managers(void) +{ + const int num_mgrs = omap_dss_get_num_overlay_managers(); + struct omap_overlay_manager *mgr; + struct mgr_priv_data *mp; + int i; + int enabled_mgrs; + + enabled_mgrs = 0; + + for (i = 0; i < num_mgrs; ++i) { + mgr = omap_dss_get_overlay_manager(i); + mp = get_mgr_priv(mgr); + + if (!mp->enabled) + continue; + + enabled_mgrs++; + } + + return enabled_mgrs; +} + +static int get_num_used_overlays(void) +{ + const int num_ovls = omap_dss_get_num_overlays(); + struct omap_overlay *ovl; + struct ovl_priv_data *op; + struct mgr_priv_data *mp; + int i; + int enabled_ovls; + + enabled_ovls = 0; + + for (i = 0; i < num_ovls; ++i) { + ovl = omap_dss_get_overlay(i); + op = get_ovl_priv(ovl); + + if (!op->enabled && !op->enabling) + continue; + + mp = get_mgr_priv(ovl->manager); + + if (!mp->enabled) + continue; + + enabled_ovls++; + } + + return enabled_ovls; +} + +static bool get_use_fifo_merge(void) +{ + int enabled_mgrs = get_num_used_managers(); + int enabled_ovls = get_num_used_overlays(); + + if (!dss_has_feature(FEAT_FIFO_MERGE)) + return false; + + /* + * In theory the only requirement for fifomerge is enabled_ovls <= 1. + * However, if we have two managers enabled and set/unset the fifomerge, + * we need to set the GO bits in particular sequence for the managers, + * and wait in between. + * + * This is rather difficult as new apply calls can happen at any time, + * so we simplify the problem by requiring also that enabled_mgrs <= 1. + * In practice this shouldn't matter, because when only one overlay is + * enabled, most likely only one output is enabled. + */ + + return enabled_mgrs <= 1 && enabled_ovls <= 1; +} + int dss_mgr_enable(struct omap_overlay_manager *mgr) { struct mgr_priv_data *mp = get_mgr_priv(mgr); unsigned long flags; int r; + bool fifo_merge; mutex_lock(&apply_lock); @@ -988,11 +1075,23 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr) goto err; } - dss_setup_fifos(); + /* step 1: setup fifos/fifomerge before enabling the manager */ + + fifo_merge = get_use_fifo_merge(); + dss_setup_fifos(fifo_merge); + dss_apply_fifo_merge(fifo_merge); dss_write_regs(); dss_set_go_bits(); + spin_unlock_irqrestore(&data_lock, flags); + + /* wait until fifo config is in */ + wait_pending_extra_info_updates(); + + /* step 2: enable the manager */ + spin_lock_irqsave(&data_lock, flags); + if (!mgr_manual_update(mgr)) mp->updating = true; @@ -1017,6 +1116,7 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr) { struct mgr_priv_data *mp = get_mgr_priv(mgr); unsigned long flags; + bool fifo_merge; mutex_lock(&apply_lock); @@ -1031,8 +1131,16 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr) mp->updating = false; mp->enabled = false; + fifo_merge = get_use_fifo_merge(); + dss_setup_fifos(fifo_merge); + dss_apply_fifo_merge(fifo_merge); + + dss_write_regs(); + dss_set_go_bits(); + spin_unlock_irqrestore(&data_lock, flags); + wait_pending_extra_info_updates(); out: mutex_unlock(&apply_lock); } @@ -1284,6 +1392,7 @@ int dss_ovl_enable(struct omap_overlay *ovl) { struct ovl_priv_data *op = get_ovl_priv(ovl); unsigned long flags; + bool fifo_merge; int r; mutex_lock(&apply_lock); @@ -1309,7 +1418,22 @@ int dss_ovl_enable(struct omap_overlay *ovl) goto err2; } - dss_setup_fifos(); + /* step 1: configure fifos/fifomerge for currently enabled ovls */ + + fifo_merge = get_use_fifo_merge(); + dss_setup_fifos(fifo_merge); + dss_apply_fifo_merge(fifo_merge); + + dss_write_regs(); + dss_set_go_bits(); + + spin_unlock_irqrestore(&data_lock, flags); + + /* wait for fifo configs to go in */ + wait_pending_extra_info_updates(); + + /* step 2: enable the overlay */ + spin_lock_irqsave(&data_lock, flags); op->enabling = false; dss_apply_ovl_enable(ovl, true); @@ -1319,6 +1443,9 @@ int dss_ovl_enable(struct omap_overlay *ovl) spin_unlock_irqrestore(&data_lock, flags); + /* wait for overlay to be enabled */ + wait_pending_extra_info_updates(); + mutex_unlock(&apply_lock); return 0; @@ -1334,6 +1461,7 @@ int dss_ovl_disable(struct omap_overlay *ovl) { struct ovl_priv_data *op = get_ovl_priv(ovl); unsigned long flags; + bool fifo_merge; int r; mutex_lock(&apply_lock); @@ -1348,14 +1476,34 @@ int dss_ovl_disable(struct omap_overlay *ovl) goto err; } + /* step 1: disable the overlay */ spin_lock_irqsave(&data_lock, flags); dss_apply_ovl_enable(ovl, false); + dss_write_regs(); dss_set_go_bits(); spin_unlock_irqrestore(&data_lock, flags); + /* wait for the overlay to be disabled */ + wait_pending_extra_info_updates(); + + /* step 2: configure fifos/fifomerge */ + spin_lock_irqsave(&data_lock, flags); + + fifo_merge = get_use_fifo_merge(); + dss_setup_fifos(fifo_merge); + dss_apply_fifo_merge(fifo_merge); + + dss_write_regs(); + dss_set_go_bits(); + + spin_unlock_irqrestore(&data_lock, flags); + + /* wait for fifo config to go in */ + wait_pending_extra_info_updates(); + mutex_unlock(&apply_lock); return 0; -- cgit v1.2.3-70-g09d2 From 3cb5d966e233167fcbeb7c7d7a66294e13ee9d90 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 13 Jan 2012 13:14:57 +0200 Subject: OMAPDSS: DISPC: print fifo threshold values in bytes Fifo thresholds are calculated using bytes, but the debug print prints values in buffer units. Change the prints to use bytes to be in line with the calculations, and also to print in the same units on all OMAPs. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dispc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index d711518f9f1..ba907bd6009 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1039,13 +1039,13 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high) dss_feat_get_reg_field(FEAT_REG_FIFOHIGHTHRESHOLD, &hi_start, &hi_end); dss_feat_get_reg_field(FEAT_REG_FIFOLOWTHRESHOLD, &lo_start, &lo_end); - DSSDBG("fifo(%d) low/high old %u/%u, new %u/%u\n", + DSSDBG("fifo(%d) threshold (bytes), old %u/%u, new %u/%u\n", plane, REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane), - lo_start, lo_end), + lo_start, lo_end) * unit, REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane), - hi_start, hi_end), - low, high); + hi_start, hi_end) * unit, + low * unit, high * unit); dispc_write_reg(DISPC_OVL_FIFO_THRESHOLD(plane), FLD_VAL(high, hi_start, hi_end) | -- cgit v1.2.3-70-g09d2 From 83fa2f2e940dc21a204cff697d84d37214a91708 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 13 Jan 2012 13:17:01 +0200 Subject: OMAPDSS: DISPC: move fifo threhold calc to dispc.c Move fifo threshold calculation into dispc.c, as the thresholds are really dispc internal thing. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/apply.c | 34 ++-------------------------------- drivers/video/omap2/dss/dispc.c | 22 ++++++++++++++++++++-- drivers/video/omap2/dss/display.c | 10 ---------- drivers/video/omap2/dss/dsi.c | 8 -------- drivers/video/omap2/dss/dss.h | 10 ++-------- 5 files changed, 24 insertions(+), 60 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 6f7b213e096..b0264a16465 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -907,7 +907,6 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl, { struct ovl_priv_data *op = get_ovl_priv(ovl); struct omap_dss_device *dssdev; - u32 size, burst_size; u32 fifo_low, fifo_high; if (!op->enabled && !op->enabling) @@ -915,37 +914,8 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl, dssdev = ovl->manager->device; - if (use_fifo_merge) { - int i; - - size = 0; - - for (i = 0; i < omap_dss_get_num_overlays(); ++i) - size += dispc_ovl_get_fifo_size(i); - } else { - size = dispc_ovl_get_fifo_size(ovl->id); - } - - burst_size = dispc_ovl_get_burst_size(ovl->id); - - switch (dssdev->type) { - case OMAP_DISPLAY_TYPE_DPI: - case OMAP_DISPLAY_TYPE_DBI: - case OMAP_DISPLAY_TYPE_SDI: - case OMAP_DISPLAY_TYPE_VENC: - case OMAP_DISPLAY_TYPE_HDMI: - default_get_overlay_fifo_thresholds(ovl->id, size, - burst_size, &fifo_low, &fifo_high); - break; -#ifdef CONFIG_OMAP2_DSS_DSI - case OMAP_DISPLAY_TYPE_DSI: - dsi_get_overlay_fifo_thresholds(ovl->id, size, - burst_size, &fifo_low, &fifo_high); - break; -#endif - default: - BUG(); - } + dispc_ovl_compute_fifo_thresholds(ovl->id, &fifo_low, &fifo_high, + use_fifo_merge); dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high); } diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index ba907bd6009..a75972250a2 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -909,7 +909,7 @@ static void dispc_configure_burst_sizes(void) dispc_ovl_set_burst_size(i, burst_size); } -u32 dispc_ovl_get_burst_size(enum omap_plane plane) +static u32 dispc_ovl_get_burst_size(enum omap_plane plane) { unsigned unit = dss_feat_get_burst_size_unit(); /* burst multiplier is always x8 (see dispc_configure_burst_sizes()) */ @@ -1018,7 +1018,7 @@ static void dispc_read_plane_fifo_sizes(void) } } -u32 dispc_ovl_get_fifo_size(enum omap_plane plane) +static u32 dispc_ovl_get_fifo_size(enum omap_plane plane) { return dispc.fifo_size[plane]; } @@ -1063,6 +1063,24 @@ void dispc_enable_fifomerge(bool enable) REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14); } +void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, + u32 *fifo_low, u32 *fifo_high, bool use_fifomerge) +{ + /* + * All sizes are in bytes. Both the buffer and burst are made of + * buffer_units, and the fifo thresholds must be buffer_unit aligned. + */ + + unsigned buf_unit = dss_feat_get_buffer_size_unit(); + unsigned fifo_size, burst_size; + + burst_size = dispc_ovl_get_burst_size(plane); + fifo_size = dispc_ovl_get_fifo_size(plane); + + *fifo_low = fifo_size - burst_size; + *fifo_high = fifo_size - buf_unit; +} + static void dispc_ovl_set_fir(enum omap_plane plane, int hinc, int vinc, enum omap_color_component color_comp) diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c index be331dc5a61..4424c198dbc 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/omap2/dss/display.c @@ -279,16 +279,6 @@ void omapdss_default_get_resolution(struct omap_dss_device *dssdev, } EXPORT_SYMBOL(omapdss_default_get_resolution); -void default_get_overlay_fifo_thresholds(enum omap_plane plane, - u32 fifo_size, u32 burst_size, - u32 *fifo_low, u32 *fifo_high) -{ - unsigned buf_unit = dss_feat_get_buffer_size_unit(); - - *fifo_high = fifo_size - buf_unit; - *fifo_low = fifo_size - burst_size; -} - int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev) { switch (dssdev->type) { diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index d4d676c82c1..a4b9d58e8b4 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -4524,14 +4524,6 @@ int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable) } EXPORT_SYMBOL(omapdss_dsi_enable_te); -void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, - u32 fifo_size, u32 burst_size, - u32 *fifo_low, u32 *fifo_high) -{ - *fifo_high = fifo_size - burst_size; - *fifo_low = fifo_size - burst_size * 2; -} - int dsi_init_display(struct omap_dss_device *dssdev) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 32ff69fb333..d4b3dff2ead 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -202,9 +202,6 @@ void dss_uninit_device(struct platform_device *pdev, struct omap_dss_device *dssdev); bool dss_use_replication(struct omap_dss_device *dssdev, enum omap_color_mode mode); -void default_get_overlay_fifo_thresholds(enum omap_plane plane, - u32 fifo_size, u32 burst_size, - u32 *fifo_low, u32 *fifo_high); /* manager */ int dss_init_overlay_managers(struct platform_device *pdev); @@ -313,9 +310,6 @@ int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft, int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, bool enable_hsdiv); void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes); -void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, - u32 fifo_size, u32 burst_size, - u32 *fifo_low, u32 *fifo_high); void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev); void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev); struct platform_device *dsi_get_dsidev_from_id(int module); @@ -429,8 +423,8 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate, void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); -u32 dispc_ovl_get_fifo_size(enum omap_plane plane); -u32 dispc_ovl_get_burst_size(enum omap_plane plane); +void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, + u32 *fifo_low, u32 *fifo_high, bool use_fifomerge); int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, bool ilace, bool replication); int dispc_ovl_enable(enum omap_plane plane, bool enable); -- cgit v1.2.3-70-g09d2 From e0e405b9252e5e8926786d796e0d4293bc90cd56 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 13 Jan 2012 13:18:11 +0200 Subject: OMAPDSS: DISPC: Add naive threshold calc for fifomerge Take fifo merge into use by implementing a rather naive fifo merge threshold calculation: keep the low threshold always the same, but increase the high threshold when fifo merge is used. This should greatly increase the time between pixel data fetches from SDRAM, as the usable fifo size is much larger. However, it probably won't help for fifo underflows, as the low threshols is kept the same. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dispc.c | 28 ++++++++++++++++++++++++---- drivers/video/omap2/dss/dss_features.c | 6 ++++-- drivers/video/omap2/dss/dss_features.h | 2 ++ 3 files changed, 30 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index a75972250a2..374c987038a 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1072,13 +1072,33 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, */ unsigned buf_unit = dss_feat_get_buffer_size_unit(); - unsigned fifo_size, burst_size; + unsigned ovl_fifo_size, total_fifo_size, burst_size; + int i; burst_size = dispc_ovl_get_burst_size(plane); - fifo_size = dispc_ovl_get_fifo_size(plane); + ovl_fifo_size = dispc_ovl_get_fifo_size(plane); - *fifo_low = fifo_size - burst_size; - *fifo_high = fifo_size - buf_unit; + if (use_fifomerge) { + total_fifo_size = 0; + for (i = 0; i < omap_dss_get_num_overlays(); ++i) + total_fifo_size += dispc_ovl_get_fifo_size(i); + } else { + total_fifo_size = ovl_fifo_size; + } + + /* + * We use the same low threshold for both fifomerge and non-fifomerge + * cases, but for fifomerge we calculate the high threshold using the + * combined fifo size + */ + + if (dss_has_feature(FEAT_OMAP3_DSI_FIFO_BUG)) { + *fifo_low = ovl_fifo_size - burst_size * 2; + *fifo_high = total_fifo_size - burst_size; + } else { + *fifo_low = ovl_fifo_size - burst_size; + *fifo_high = total_fifo_size - buf_unit; + } } static void dispc_ovl_set_fir(enum omap_plane plane, diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c index c2456c5bcd3..419419ad049 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/omap2/dss/dss_features.c @@ -370,7 +370,8 @@ static const struct omap_dss_features omap3430_dss_features = { FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF | FEAT_DSI_PLL_FREQSEL | FEAT_DSI_REVERSE_TXCLKESC | FEAT_VENC_REQUIRES_TV_DAC_CLK | FEAT_CPR | FEAT_PRELOAD | - FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER | FEAT_FIFO_MERGE, + FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER | FEAT_FIFO_MERGE | + FEAT_OMAP3_DSI_FIFO_BUG, .num_mgrs = 2, .num_ovls = 3, @@ -394,7 +395,8 @@ static const struct omap_dss_features omap3630_dss_features = { FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF | FEAT_DSI_PLL_PWR_BUG | FEAT_DSI_PLL_FREQSEL | FEAT_CPR | FEAT_PRELOAD | - FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER | FEAT_FIFO_MERGE, + FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER | FEAT_FIFO_MERGE | + FEAT_OMAP3_DSI_FIFO_BUG, .num_mgrs = 2, .num_ovls = 3, diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h index 50caee9192a..5f9b8215677 100644 --- a/drivers/video/omap2/dss/dss_features.h +++ b/drivers/video/omap2/dss/dss_features.h @@ -59,6 +59,8 @@ enum dss_feat_id { FEAT_ALPHA_FIXED_ZORDER = 1 << 26, FEAT_ALPHA_FREE_ZORDER = 1 << 27, FEAT_FIFO_MERGE = 1 << 28, + /* An unknown HW bug causing the normal FIFO thresholds not to work */ + FEAT_OMAP3_DSI_FIFO_BUG = 1 << 29, }; /* DSS register field id */ -- cgit v1.2.3-70-g09d2 From aeec1a6ccbe28c2cea5f19803394f99859566552 Mon Sep 17 00:00:00 2001 From: Mythri P K Date: Fri, 6 Jan 2012 17:52:07 +0530 Subject: OMAPDSS: HDMI: remove duplicate video interface code video interface structure is a duplicate structure with parameters which are already present in ip_data config structure, Thus removing the structure and modifying corresponding code. Signed-off-by: Mythri P K Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c | 31 ++++++++----------------------- drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h | 7 ------- 2 files changed, 8 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c index 9af81f18f16..bafbd9fad4b 100644 --- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c +++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c @@ -629,8 +629,7 @@ static void hdmi_core_av_packet_config(struct hdmi_ip_data *ip_data, } static void hdmi_wp_init(struct omap_video_timings *timings, - struct hdmi_video_format *video_fmt, - struct hdmi_video_interface *video_int) + struct hdmi_video_format *video_fmt) { pr_debug("Enter hdmi_wp_init\n"); @@ -645,12 +644,6 @@ static void hdmi_wp_init(struct omap_video_timings *timings, video_fmt->y_res = 0; video_fmt->x_res = 0; - video_int->vsp = 0; - video_int->hsp = 0; - - video_int->interlacing = 0; - video_int->tm = 0; /* HDMI_TIMING_SLAVE */ - } void ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start) @@ -687,17 +680,16 @@ static void hdmi_wp_video_config_format(struct hdmi_ip_data *ip_data, hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_SIZE, l); } -static void hdmi_wp_video_config_interface(struct hdmi_ip_data *ip_data, - struct hdmi_video_interface *video_int) +static void hdmi_wp_video_config_interface(struct hdmi_ip_data *ip_data) { u32 r; pr_debug("Enter hdmi_wp_video_config_interface\n"); r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG); - r = FLD_MOD(r, video_int->vsp, 7, 7); - r = FLD_MOD(r, video_int->hsp, 6, 6); - r = FLD_MOD(r, video_int->interlacing, 3, 3); - r = FLD_MOD(r, video_int->tm, 1, 0); + r = FLD_MOD(r, ip_data->cfg.timings.vsync_pol, 7, 7); + r = FLD_MOD(r, ip_data->cfg.timings.hsync_pol, 6, 6); + r = FLD_MOD(r, ip_data->cfg.interlace, 3, 3); + r = FLD_MOD(r, 1, 1, 0); /* HDMI_TIMING_MASTER_24BIT */ hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, r); } @@ -725,15 +717,13 @@ void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data) /* HDMI */ struct omap_video_timings video_timing; struct hdmi_video_format video_format; - struct hdmi_video_interface video_interface; /* HDMI core */ struct hdmi_core_infoframe_avi avi_cfg; struct hdmi_core_video_config v_core_cfg; struct hdmi_core_packet_enable_repeat repeat_cfg; struct hdmi_config *cfg = &ip_data->cfg; - hdmi_wp_init(&video_timing, &video_format, - &video_interface); + hdmi_wp_init(&video_timing, &video_format); hdmi_core_init(&v_core_cfg, &avi_cfg, @@ -748,12 +738,7 @@ void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data) hdmi_wp_video_config_format(ip_data, &video_format); - video_interface.vsp = cfg->timings.vsync_pol; - video_interface.hsp = cfg->timings.hsync_pol; - video_interface.interlacing = cfg->interlace; - video_interface.tm = 1 ; /* HDMI_TIMING_MASTER_24BIT */ - - hdmi_wp_video_config_interface(ip_data, &video_interface); + hdmi_wp_video_config_interface(ip_data); /* * configure core video part diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h index a442998980f..004b4182bdd 100644 --- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h +++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h @@ -517,13 +517,6 @@ struct hdmi_video_format { u32 x_res; /* pixel per line */ }; -struct hdmi_video_interface { - int vsp; /* Vsync polarity */ - int hsp; /* Hsync polarity */ - int interlacing; - int tm; /* Timing mode */ -}; - struct hdmi_audio_format { enum hdmi_stereo_channels stereo_channels; u8 active_chnnls_msk; -- cgit v1.2.3-70-g09d2 From a05ce78f308fa22b6254995c25ff79e82a27de75 Mon Sep 17 00:00:00 2001 From: Mythri P K Date: Fri, 6 Jan 2012 17:52:08 +0530 Subject: OMAPDSS: HDMI: update static timing table Add the vsync polarity, hsync polarity, interlace to hdmi_video_timings. Remove the now duplicate structure hdmi_timings. update the static table structure in HDMI with CEA/VESA code and mode. Signed-off-by: Mythri P K Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/hdmi.c | 96 +++++++++++++++---------------- drivers/video/omap2/dss/ti_hdmi.h | 14 ++--- drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c | 20 +++---- 3 files changed, 63 insertions(+), 67 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index b4c270edb91..266af264eb9 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -88,42 +88,42 @@ static struct { * map it to corresponding CEA or VESA index. */ -static const struct hdmi_timings cea_vesa_timings[OMAP_HDMI_TIMINGS_NB] = { - { {640, 480, 25200, 96, 16, 48, 2, 10, 33} , 0 , 0}, - { {1280, 720, 74250, 40, 440, 220, 5, 5, 20}, 1, 1}, - { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1}, - { {720, 480, 27027, 62, 16, 60, 6, 9, 30}, 0, 0}, - { {2880, 576, 108000, 256, 48, 272, 5, 5, 39}, 0, 0}, - { {1440, 240, 27027, 124, 38, 114, 3, 4, 15}, 0, 0}, - { {1440, 288, 27000, 126, 24, 138, 3, 2, 19}, 0, 0}, - { {1920, 540, 74250, 44, 528, 148, 5, 2, 15}, 1, 1}, - { {1920, 540, 74250, 44, 88, 148, 5, 2, 15}, 1, 1}, - { {1920, 1080, 148500, 44, 88, 148, 5, 4, 36}, 1, 1}, - { {720, 576, 27000, 64, 12, 68, 5, 5, 39}, 0, 0}, - { {1440, 576, 54000, 128, 24, 136, 5, 5, 39}, 0, 0}, - { {1920, 1080, 148500, 44, 528, 148, 5, 4, 36}, 1, 1}, - { {2880, 480, 108108, 248, 64, 240, 6, 9, 30}, 0, 0}, - { {1920, 1080, 74250, 44, 638, 148, 5, 4, 36}, 1, 1}, - /* VESA From Here */ - { {640, 480, 25175, 96, 16, 48, 2 , 11, 31}, 0, 0}, - { {800, 600, 40000, 128, 40, 88, 4 , 1, 23}, 1, 1}, - { {848, 480, 33750, 112, 16, 112, 8 , 6, 23}, 1, 1}, - { {1280, 768, 79500, 128, 64, 192, 7 , 3, 20}, 1, 0}, - { {1280, 800, 83500, 128, 72, 200, 6 , 3, 22}, 1, 0}, - { {1360, 768, 85500, 112, 64, 256, 6 , 3, 18}, 1, 1}, - { {1280, 960, 108000, 112, 96, 312, 3 , 1, 36}, 1, 1}, - { {1280, 1024, 108000, 112, 48, 248, 3 , 1, 38}, 1, 1}, - { {1024, 768, 65000, 136, 24, 160, 6, 3, 29}, 0, 0}, - { {1400, 1050, 121750, 144, 88, 232, 4, 3, 32}, 1, 0}, - { {1440, 900, 106500, 152, 80, 232, 6, 3, 25}, 1, 0}, - { {1680, 1050, 146250, 176 , 104, 280, 6, 3, 30}, 1, 0}, - { {1366, 768, 85500, 143, 70, 213, 3, 3, 24}, 1, 1}, - { {1920, 1080, 148500, 44, 148, 80, 5, 4, 36}, 1, 1}, - { {1280, 768, 68250, 32, 48, 80, 7, 3, 12}, 0, 1}, - { {1400, 1050, 101000, 32, 48, 80, 4, 3, 23}, 0, 1}, - { {1680, 1050, 119000, 32, 48, 80, 6, 3, 21}, 0, 1}, - { {1280, 800, 79500, 32, 48, 80, 6, 3, 14}, 0, 1}, - { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1} +static const struct hdmi_config cea_vesa_timings[OMAP_HDMI_TIMINGS_NB] = { +{ {640, 480, 25200, 96, 16, 48, 2, 10, 33, 0, 0, 0}, {1, HDMI_HDMI} }, +{ {720, 480, 27027, 62, 16, 60, 6, 9, 30, 0, 0, 0}, {2, HDMI_HDMI} }, +{ {1280, 720, 74250, 40, 110, 220, 5, 5, 20, 1, 1, 0}, {4, HDMI_HDMI} }, +{ {1920, 540, 74250, 44, 88, 148, 5, 2, 15, 1, 1, 1}, {5, HDMI_HDMI} }, +{ {1440, 240, 27027, 124, 38, 114, 3, 4, 15, 0, 0, 1}, {6, HDMI_HDMI} }, +{ {1920, 1080, 148500, 44, 88, 148, 5, 4, 36, 1, 1, 0}, {16, HDMI_HDMI} }, +{ {720, 576, 27000, 64, 12, 68, 5, 5, 39, 0, 0, 0}, {17, HDMI_HDMI} }, +{ {1280, 720, 74250, 40, 440, 220, 5, 5, 20, 1, 1, 0}, {19, HDMI_HDMI} }, +{ {1920, 540, 74250, 44, 528, 148, 5, 2, 15, 1, 1, 1}, {20, HDMI_HDMI} }, +{ {1440, 288, 27000, 126, 24, 138, 3, 2, 19, 0, 0, 1}, {21, HDMI_HDMI} }, +{ {1440, 576, 54000, 128, 24, 136, 5, 5, 39, 0, 0, 0}, {29, HDMI_HDMI} }, +{ {1920, 1080, 148500, 44, 528, 148, 5, 4, 36, 1, 1, 0}, {31, HDMI_HDMI} }, +{ {1920, 1080, 74250, 44, 638, 148, 5, 4, 36, 1, 1, 0}, {32, HDMI_HDMI} }, +{ {2880, 480, 108108, 248, 64, 240, 6, 9, 30, 0, 0, 0}, {35, HDMI_HDMI} }, +{ {2880, 576, 108000, 256, 48, 272, 5, 5, 39, 0, 0, 0}, {37, HDMI_HDMI} }, +/* VESA From Here */ +{ {640, 480, 25175, 96, 16, 48, 2 , 11, 31, 0, 0, 0}, {4, HDMI_DVI} }, +{ {800, 600, 40000, 128, 40, 88, 4 , 1, 23, 1, 1, 0}, {9, HDMI_DVI} }, +{ {848, 480, 33750, 112, 16, 112, 8 , 6, 23, 1, 1, 0}, {0xE, HDMI_DVI} }, +{ {1280, 768, 79500, 128, 64, 192, 7 , 3, 20, 1, 0, 0}, {0x17, HDMI_DVI} }, +{ {1280, 800, 83500, 128, 72, 200, 6 , 3, 22, 1, 0, 0}, {0x1C, HDMI_DVI} }, +{ {1360, 768, 85500, 112, 64, 256, 6 , 3, 18, 1, 1, 0}, {0x27, HDMI_DVI} }, +{ {1280, 960, 108000, 112, 96, 312, 3 , 1, 36, 1, 1, 0}, {0x20, HDMI_DVI} }, +{ {1280, 1024, 108000, 112, 48, 248, 3 , 1, 38, 1, 1, 0}, {0x23, HDMI_DVI} }, +{ {1024, 768, 65000, 136, 24, 160, 6, 3, 29, 0, 0, 0}, {0x10, HDMI_DVI} }, +{ {1400, 1050, 121750, 144, 88, 232, 4, 3, 32, 1, 0, 0}, {0x2A, HDMI_DVI} }, +{ {1440, 900, 106500, 152, 80, 232, 6, 3, 25, 1, 0, 0}, {0x2F, HDMI_DVI} }, +{ {1680, 1050, 146250, 176 , 104, 280, 6, 3, 30, 1, 0, 0}, {0x3A, HDMI_DVI} }, +{ {1366, 768, 85500, 143, 70, 213, 3, 3, 24, 1, 1, 0}, {0x51, HDMI_DVI} }, +{ {1920, 1080, 148500, 44, 148, 80, 5, 4, 36, 1, 1, 0}, {0x52, HDMI_DVI} }, +{ {1280, 768, 68250, 32, 48, 80, 7, 3, 12, 0, 1, 0}, {0x16, HDMI_DVI} }, +{ {1400, 1050, 101000, 32, 48, 80, 4, 3, 23, 0, 1, 0}, {0x29, HDMI_DVI} }, +{ {1680, 1050, 119000, 32, 48, 80, 6, 3, 21, 0, 1, 0}, {0x39, HDMI_DVI} }, +{ {1280, 800, 79500, 32, 48, 80, 6, 3, 14, 0, 1, 0}, {0x1B, HDMI_DVI} }, +{ {1280, 720, 74250, 40, 110, 220, 5, 5, 20, 1, 1, 0}, {0x55, HDMI_DVI} } }; /* @@ -253,23 +253,23 @@ static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing) static void update_hdmi_timings(struct hdmi_config *cfg, struct omap_video_timings *timings, int code) { - cfg->timings.timings.x_res = timings->x_res; - cfg->timings.timings.y_res = timings->y_res; - cfg->timings.timings.hbp = timings->hbp; - cfg->timings.timings.hfp = timings->hfp; - cfg->timings.timings.hsw = timings->hsw; - cfg->timings.timings.vbp = timings->vbp; - cfg->timings.timings.vfp = timings->vfp; - cfg->timings.timings.vsw = timings->vsw; - cfg->timings.timings.pixel_clock = timings->pixel_clock; - cfg->timings.vsync_pol = cea_vesa_timings[code].vsync_pol; - cfg->timings.hsync_pol = cea_vesa_timings[code].hsync_pol; + cfg->timings.x_res = timings->x_res; + cfg->timings.y_res = timings->y_res; + cfg->timings.hbp = timings->hbp; + cfg->timings.hfp = timings->hfp; + cfg->timings.hsw = timings->hsw; + cfg->timings.vbp = timings->vbp; + cfg->timings.vfp = timings->vfp; + cfg->timings.vsw = timings->vsw; + cfg->timings.pixel_clock = timings->pixel_clock; + cfg->timings.vsync_pol = cea_vesa_timings[code].timings.vsync_pol; + cfg->timings.hsync_pol = cea_vesa_timings[code].timings.hsync_pol; } unsigned long hdmi_get_pixel_clock(void) { /* HDMI Pixel Clock in Mhz */ - return hdmi.ip_data.cfg.timings.timings.pixel_clock * 1000; + return hdmi.ip_data.cfg.timings.pixel_clock * 1000; } static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy, diff --git a/drivers/video/omap2/dss/ti_hdmi.h b/drivers/video/omap2/dss/ti_hdmi.h index 7503f7f619a..26ec6d1162f 100644 --- a/drivers/video/omap2/dss/ti_hdmi.h +++ b/drivers/video/omap2/dss/ti_hdmi.h @@ -42,6 +42,7 @@ enum hdmi_clk_refsel { HDMI_REFSEL_SYSCLK = 3 }; +/* HDMI timing structure */ struct hdmi_video_timings { u16 x_res; u16 y_res; @@ -53,13 +54,9 @@ struct hdmi_video_timings { u16 vsw; u16 vfp; u16 vbp; -}; - -/* HDMI timing structure */ -struct hdmi_timings { - struct hdmi_video_timings timings; - int vsync_pol; - int hsync_pol; + bool vsync_pol; + bool hsync_pol; + bool interlace; }; struct hdmi_cm { @@ -68,8 +65,7 @@ struct hdmi_cm { }; struct hdmi_config { - struct hdmi_timings timings; - u16 interlace; + struct hdmi_video_timings timings; struct hdmi_cm cm; }; diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c index bafbd9fad4b..a229ae71be7 100644 --- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c +++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c @@ -656,15 +656,15 @@ static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt, { pr_debug("Enter hdmi_wp_video_init_format\n"); - video_fmt->y_res = param->timings.timings.y_res; - video_fmt->x_res = param->timings.timings.x_res; - - timings->hbp = param->timings.timings.hbp; - timings->hfp = param->timings.timings.hfp; - timings->hsw = param->timings.timings.hsw; - timings->vbp = param->timings.timings.vbp; - timings->vfp = param->timings.timings.vfp; - timings->vsw = param->timings.timings.vsw; + video_fmt->y_res = param->timings.y_res; + video_fmt->x_res = param->timings.x_res; + + timings->hbp = param->timings.hbp; + timings->hfp = param->timings.hfp; + timings->hsw = param->timings.hsw; + timings->vbp = param->timings.vbp; + timings->vfp = param->timings.vfp; + timings->vsw = param->timings.vsw; } static void hdmi_wp_video_config_format(struct hdmi_ip_data *ip_data, @@ -688,7 +688,7 @@ static void hdmi_wp_video_config_interface(struct hdmi_ip_data *ip_data) r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG); r = FLD_MOD(r, ip_data->cfg.timings.vsync_pol, 7, 7); r = FLD_MOD(r, ip_data->cfg.timings.hsync_pol, 6, 6); - r = FLD_MOD(r, ip_data->cfg.interlace, 3, 3); + r = FLD_MOD(r, ip_data->cfg.timings.interlace, 3, 3); r = FLD_MOD(r, 1, 1, 0); /* HDMI_TIMING_MASTER_24BIT */ hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, r); } -- cgit v1.2.3-70-g09d2 From 46095b2d96bac92c2cc5ca557ec7de73e13311ab Mon Sep 17 00:00:00 2001 From: Mythri P K Date: Fri, 6 Jan 2012 17:52:09 +0530 Subject: OMAPDSS: HDMI: change the timing match logic Change the timing match logic, Instead of the statically mapped method to get the corresponding timings for a given code and mode, move to a simpler array indexed method. It will help to scale up to add more timings when needed. Signed-off-by: Mythri P K Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/hdmi.c | 176 ++++++++++++++++++----------------------- 1 file changed, 76 insertions(+), 100 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index 266af264eb9..6f027d30d5d 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -58,8 +58,6 @@ #define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR 4 #define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR 4 -#define OMAP_HDMI_TIMINGS_NB 34 - #define HDMI_DEFAULT_REGN 16 #define HDMI_DEFAULT_REGM2 1 @@ -88,7 +86,7 @@ static struct { * map it to corresponding CEA or VESA index. */ -static const struct hdmi_config cea_vesa_timings[OMAP_HDMI_TIMINGS_NB] = { +static const struct hdmi_config cea_timings[] = { { {640, 480, 25200, 96, 16, 48, 2, 10, 33, 0, 0, 0}, {1, HDMI_HDMI} }, { {720, 480, 27027, 62, 16, 60, 6, 9, 30, 0, 0, 0}, {2, HDMI_HDMI} }, { {1280, 720, 74250, 40, 110, 220, 5, 5, 20, 1, 1, 0}, {4, HDMI_HDMI} }, @@ -104,6 +102,8 @@ static const struct hdmi_config cea_vesa_timings[OMAP_HDMI_TIMINGS_NB] = { { {1920, 1080, 74250, 44, 638, 148, 5, 4, 36, 1, 1, 0}, {32, HDMI_HDMI} }, { {2880, 480, 108108, 248, 64, 240, 6, 9, 30, 0, 0, 0}, {35, HDMI_HDMI} }, { {2880, 576, 108000, 256, 48, 272, 5, 5, 39, 0, 0, 0}, {37, HDMI_HDMI} }, +}; +static const struct hdmi_config vesa_timings[] = { /* VESA From Here */ { {640, 480, 25175, 96, 16, 48, 2 , 11, 31, 0, 0, 0}, {4, HDMI_DVI} }, { {800, 600, 40000, 128, 40, 88, 4 , 1, 23, 1, 1, 0}, {9, HDMI_DVI} }, @@ -126,39 +126,6 @@ static const struct hdmi_config cea_vesa_timings[OMAP_HDMI_TIMINGS_NB] = { { {1280, 720, 74250, 40, 110, 220, 5, 5, 20, 1, 1, 0}, {0x55, HDMI_DVI} } }; -/* - * This is a static mapping array which maps the timing values - * with corresponding CEA / VESA code - */ -static const int code_index[OMAP_HDMI_TIMINGS_NB] = { - 1, 19, 4, 2, 37, 6, 21, 20, 5, 16, 17, 29, 31, 35, 32, - /* <--15 CEA 17--> vesa*/ - 4, 9, 0xE, 0x17, 0x1C, 0x27, 0x20, 0x23, 0x10, 0x2A, - 0X2F, 0x3A, 0X51, 0X52, 0x16, 0x29, 0x39, 0x1B -}; - -/* - * This is reverse static mapping which maps the CEA / VESA code - * to the corresponding timing values - */ -static const int code_cea[39] = { - -1, 0, 3, 3, 2, 8, 5, 5, -1, -1, - -1, -1, -1, -1, -1, -1, 9, 10, 10, 1, - 7, 6, 6, -1, -1, -1, -1, -1, -1, 11, - 11, 12, 14, -1, -1, 13, 13, 4, 4 -}; - -static const int code_vesa[85] = { - -1, -1, -1, -1, 15, -1, -1, -1, -1, 16, - -1, -1, -1, -1, 17, -1, 23, -1, -1, -1, - -1, -1, 29, 18, -1, -1, -1, 32, 19, -1, - -1, -1, 21, -1, -1, 22, -1, -1, -1, 20, - -1, 30, 24, -1, -1, -1, -1, 25, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 31, 26, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 27, 28, -1, 33}; - static int hdmi_runtime_get(void) { int r; @@ -188,82 +155,83 @@ int hdmi_init_display(struct omap_dss_device *dssdev) return 0; } -static int get_timings_index(void) +static const struct hdmi_config *hdmi_find_timing( + const struct hdmi_config *timings_arr, + int len) { - int code; + int i; - if (hdmi.mode == 0) - code = code_vesa[hdmi.code]; - else - code = code_cea[hdmi.code]; + for (i = 0; i < len; i++) { + if (timings_arr[i].cm.code == hdmi.code) + return &timings_arr[i]; + } + return NULL; +} - if (code == -1) { - /* HDMI code 4 corresponds to 640 * 480 VGA */ - hdmi.code = 4; - /* DVI mode 1 corresponds to HDMI 0 to DVI */ - hdmi.mode = HDMI_DVI; +static const struct hdmi_config *hdmi_get_timings(void) +{ + const struct hdmi_config *arr; + int len; + + if (hdmi.mode == HDMI_DVI) { + arr = vesa_timings; + len = ARRAY_SIZE(vesa_timings); + } else { + arr = cea_timings; + len = ARRAY_SIZE(cea_timings); + } + + return hdmi_find_timing(arr, len); +} + +static bool hdmi_timings_compare(struct omap_video_timings *timing1, + const struct hdmi_video_timings *timing2) +{ + int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync; + + if ((timing2->pixel_clock == timing1->pixel_clock) && + (timing2->x_res == timing1->x_res) && + (timing2->y_res == timing1->y_res)) { + + timing2_hsync = timing2->hfp + timing2->hsw + timing2->hbp; + timing1_hsync = timing1->hfp + timing1->hsw + timing1->hbp; + timing2_vsync = timing2->vfp + timing2->vsw + timing2->vbp; + timing1_vsync = timing2->vfp + timing2->vsw + timing2->vbp; - code = code_vesa[hdmi.code]; + DSSDBG("timing1_hsync = %d timing1_vsync = %d"\ + "timing2_hsync = %d timing2_vsync = %d\n", + timing1_hsync, timing1_vsync, + timing2_hsync, timing2_vsync); + + if ((timing1_hsync == timing2_hsync) && + (timing1_vsync == timing2_vsync)) { + return true; + } } - return code; + return false; } static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing) { - int i = 0, code = -1, temp_vsync = 0, temp_hsync = 0; - int timing_vsync = 0, timing_hsync = 0; - struct hdmi_video_timings temp; + int i; struct hdmi_cm cm = {-1}; DSSDBG("hdmi_get_code\n"); - for (i = 0; i < OMAP_HDMI_TIMINGS_NB; i++) { - temp = cea_vesa_timings[i].timings; - if ((temp.pixel_clock == timing->pixel_clock) && - (temp.x_res == timing->x_res) && - (temp.y_res == timing->y_res)) { - - temp_hsync = temp.hfp + temp.hsw + temp.hbp; - timing_hsync = timing->hfp + timing->hsw + timing->hbp; - temp_vsync = temp.vfp + temp.vsw + temp.vbp; - timing_vsync = timing->vfp + timing->vsw + timing->vbp; - - DSSDBG("temp_hsync = %d , temp_vsync = %d" - "timing_hsync = %d, timing_vsync = %d\n", - temp_hsync, temp_hsync, - timing_hsync, timing_vsync); - - if ((temp_hsync == timing_hsync) && - (temp_vsync == timing_vsync)) { - code = i; - cm.code = code_index[i]; - if (code < 14) - cm.mode = HDMI_HDMI; - else - cm.mode = HDMI_DVI; - DSSDBG("Hdmi_code = %d mode = %d\n", - cm.code, cm.mode); - break; - } + for (i = 0; i < ARRAY_SIZE(cea_timings); i++) { + if (hdmi_timings_compare(timing, &cea_timings[i].timings)) { + cm = cea_timings[i].cm; + goto end; + } + } + for (i = 0; i < ARRAY_SIZE(vesa_timings); i++) { + if (hdmi_timings_compare(timing, &vesa_timings[i].timings)) { + cm = vesa_timings[i].cm; + goto end; } } - return cm; -} +end: return cm; -static void update_hdmi_timings(struct hdmi_config *cfg, - struct omap_video_timings *timings, int code) -{ - cfg->timings.x_res = timings->x_res; - cfg->timings.y_res = timings->y_res; - cfg->timings.hbp = timings->hbp; - cfg->timings.hfp = timings->hfp; - cfg->timings.hsw = timings->hsw; - cfg->timings.vbp = timings->vbp; - cfg->timings.vfp = timings->vfp; - cfg->timings.vsw = timings->vsw; - cfg->timings.pixel_clock = timings->pixel_clock; - cfg->timings.vsync_pol = cea_vesa_timings[code].timings.vsync_pol; - cfg->timings.hsync_pol = cea_vesa_timings[code].timings.hsync_pol; } unsigned long hdmi_get_pixel_clock(void) @@ -325,7 +293,8 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy, static int hdmi_power_on(struct omap_dss_device *dssdev) { - int r, code = 0; + int r; + const struct hdmi_config *timing; struct omap_video_timings *p; unsigned long phy; @@ -341,9 +310,16 @@ static int hdmi_power_on(struct omap_dss_device *dssdev) dssdev->panel.timings.x_res, dssdev->panel.timings.y_res); - code = get_timings_index(); - update_hdmi_timings(&hdmi.ip_data.cfg, p, code); - + timing = hdmi_get_timings(); + if (timing == NULL) { + /* HDMI code 4 corresponds to 640 * 480 VGA */ + hdmi.code = 4; + /* DVI mode 1 corresponds to HDMI 0 to DVI */ + hdmi.mode = HDMI_DVI; + hdmi.ip_data.cfg = vesa_timings[0]; + } else { + hdmi.ip_data.cfg = *timing; + } phy = p->pixel_clock; hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data); -- cgit v1.2.3-70-g09d2 From 9e4ed603e6ec71da9e0a7484a694f98dff869068 Mon Sep 17 00:00:00 2001 From: Mythri P K Date: Fri, 6 Jan 2012 17:52:10 +0530 Subject: OMAPDSS: HDMI: remove duplicate code and mode parameter code and mode parameters are already a part of the ip_data structure so no need to keep the same parameters again in hdmi global structure. Signed-off-by: Mythri P K Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/hdmi.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index 6f027d30d5d..92a66798f67 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -66,8 +66,6 @@ static struct { struct omap_display_platform_data *pdata; struct platform_device *pdev; struct hdmi_ip_data ip_data; - int code; - int mode; struct clk *sys_clk; } hdmi; @@ -162,7 +160,7 @@ static const struct hdmi_config *hdmi_find_timing( int i; for (i = 0; i < len; i++) { - if (timings_arr[i].cm.code == hdmi.code) + if (timings_arr[i].cm.code == hdmi.ip_data.cfg.cm.code) return &timings_arr[i]; } return NULL; @@ -173,7 +171,7 @@ static const struct hdmi_config *hdmi_get_timings(void) const struct hdmi_config *arr; int len; - if (hdmi.mode == HDMI_DVI) { + if (hdmi.ip_data.cfg.cm.mode == HDMI_DVI) { arr = vesa_timings; len = ARRAY_SIZE(vesa_timings); } else { @@ -313,9 +311,9 @@ static int hdmi_power_on(struct omap_dss_device *dssdev) timing = hdmi_get_timings(); if (timing == NULL) { /* HDMI code 4 corresponds to 640 * 480 VGA */ - hdmi.code = 4; + hdmi.ip_data.cfg.cm.code = 4; /* DVI mode 1 corresponds to HDMI 0 to DVI */ - hdmi.mode = HDMI_DVI; + hdmi.ip_data.cfg.cm.mode = HDMI_DVI; hdmi.ip_data.cfg = vesa_timings[0]; } else { hdmi.ip_data.cfg = *timing; @@ -339,8 +337,6 @@ static int hdmi_power_on(struct omap_dss_device *dssdev) goto err; } - hdmi.ip_data.cfg.cm.mode = hdmi.mode; - hdmi.ip_data.cfg.cm.code = hdmi.code; hdmi.ip_data.ops->video_configure(&hdmi.ip_data); /* Make selection of HDMI in DSS */ @@ -407,8 +403,8 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev) struct hdmi_cm cm; cm = hdmi_get_code(&dssdev->panel.timings); - hdmi.code = cm.code; - hdmi.mode = cm.mode; + hdmi.ip_data.cfg.cm.code = cm.code; + hdmi.ip_data.cfg.cm.mode = cm.mode; if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { int r; @@ -707,7 +703,7 @@ static int hdmi_audio_hw_params(struct snd_pcm_substream *substream, static int hdmi_audio_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - if (!hdmi.mode) { + if (!hdmi.ip_data.cfg.cm.mode) { pr_err("Current video settings do not support audio.\n"); return -EIO; } -- cgit v1.2.3-70-g09d2 From 1149c74419179d57fdcd506424da2444755e65d9 Mon Sep 17 00:00:00 2001 From: Ricardo Neri Date: Thu, 19 Jan 2012 12:21:41 -0600 Subject: OMAPDSS: HDMI: Correct source of the pixel clock in ACR calculation Due to changes in struct hdmi_config, the pixel clock has to be obtained differently. The pixel clock is needed to calculate the CTS value as defined in the HDMI specification. Signed-off-by: Ricardo Neri Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c index a229ae71be7..9bbf9614fe0 100644 --- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c +++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c @@ -1137,7 +1137,7 @@ int hdmi_config_audio_acr(struct hdmi_ip_data *ip_data, { u32 r; u32 deep_color = 0; - u32 pclk = ip_data->cfg.timings.timings.pixel_clock; + u32 pclk = ip_data->cfg.timings.pixel_clock; if (n == NULL || cts == NULL) return -EINVAL; -- cgit v1.2.3-70-g09d2 From cc1d3e032df53d83d0ca4d537d8eb67eb5b3e808 Mon Sep 17 00:00:00 2001 From: Danny Kukawka Date: Tue, 24 Jan 2012 16:44:42 +0100 Subject: OMAPDSS: VENC: fix NULL pointer dereference in DSS2 VENC sysfs debug attr on OMAP4 Commit ba02fa37de80bea10d706f39f076dd848348320a disabled the venc driver registration on OMAP4. Since the driver never gets probed/initialised your get a dereferenceed NULL pointer if you try to get info from /sys/kernel/debug/omapdss/venc Return info message about disabled venc if venc_dump_regs() gets called. Signed-off-by: Danny Kukawka Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/venc.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index b3e9f909158..82865bec945 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c @@ -699,6 +699,11 @@ void venc_dump_regs(struct seq_file *s) { #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r)) + if (cpu_is_omap44xx()) { + seq_printf(s, "VENC currently disabled on OMAP44xx\n"); + return; + } + if (venc_runtime_get()) return; -- cgit v1.2.3-70-g09d2 From 6e2a14d2c59f6208310eeb6b031e9d1c22b38c6a Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 24 Jan 2012 14:00:45 +0100 Subject: OMAPDSS: use devm_ functions The various devm_ functions allocate memory that is released when a driver detaches. This patch uses these functions for data that is allocated in the probe function of a platform device and is only freed in the remove function. Signed-off-by: Julia Lawall Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dispc.c | 16 ++++++---------- drivers/video/omap2/dss/dsi.c | 28 +++++++++------------------- drivers/video/omap2/dss/dss.c | 9 +++------ drivers/video/omap2/dss/rfbi.c | 5 ++--- drivers/video/omap2/dss/venc.c | 8 +++----- 5 files changed, 23 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index a5ec7f37c18..6fa866a83f1 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -3322,7 +3322,8 @@ static int omap_dispchw_probe(struct platform_device *pdev) r = -EINVAL; goto err_ioremap; } - dispc.base = ioremap(dispc_mem->start, resource_size(dispc_mem)); + dispc.base = devm_ioremap(&pdev->dev, dispc_mem->start, + resource_size(dispc_mem)); if (!dispc.base) { DSSERR("can't ioremap DISPC\n"); r = -ENOMEM; @@ -3332,14 +3333,14 @@ static int omap_dispchw_probe(struct platform_device *pdev) if (dispc.irq < 0) { DSSERR("platform_get_irq failed\n"); r = -ENODEV; - goto err_irq; + goto err_ioremap; } - r = request_irq(dispc.irq, omap_dispc_irq_handler, IRQF_SHARED, - "OMAP DISPC", dispc.pdev); + r = devm_request_irq(&pdev->dev, dispc.irq, omap_dispc_irq_handler, + IRQF_SHARED, "OMAP DISPC", dispc.pdev); if (r < 0) { DSSERR("request_irq failed\n"); - goto err_irq; + goto err_ioremap; } pm_runtime_enable(&pdev->dev); @@ -3362,9 +3363,6 @@ static int omap_dispchw_probe(struct platform_device *pdev) err_runtime_get: pm_runtime_disable(&pdev->dev); - free_irq(dispc.irq, dispc.pdev); -err_irq: - iounmap(dispc.base); err_ioremap: clk_put(dispc.dss_clk); err_get_clk: @@ -3377,8 +3375,6 @@ static int omap_dispchw_remove(struct platform_device *pdev) clk_put(dispc.dss_clk); - free_irq(dispc.irq, dispc.pdev); - iounmap(dispc.base); return 0; } diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index d4d676c82c1..52b93597730 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -4695,7 +4695,7 @@ static int omap_dsihw_probe(struct platform_device *dsidev) struct resource *dsi_mem; struct dsi_data *dsi; - dsi = kzalloc(sizeof(*dsi), GFP_KERNEL); + dsi = devm_kzalloc(&dsidev->dev, sizeof(*dsi), GFP_KERNEL); if (!dsi) { r = -ENOMEM; goto err_alloc; @@ -4724,7 +4724,7 @@ static int omap_dsihw_probe(struct platform_device *dsidev) r = dsi_get_clocks(dsidev); if (r) - goto err_get_clk; + goto err_alloc; pm_runtime_enable(&dsidev->dev); @@ -4742,7 +4742,8 @@ static int omap_dsihw_probe(struct platform_device *dsidev) r = -EINVAL; goto err_ioremap; } - dsi->base = ioremap(dsi_mem->start, resource_size(dsi_mem)); + dsi->base = devm_ioremap(&dsidev->dev, dsi_mem->start, + resource_size(dsi_mem)); if (!dsi->base) { DSSERR("can't ioremap DSI\n"); r = -ENOMEM; @@ -4752,14 +4753,14 @@ static int omap_dsihw_probe(struct platform_device *dsidev) if (dsi->irq < 0) { DSSERR("platform_get_irq failed\n"); r = -ENODEV; - goto err_get_irq; + goto err_ioremap; } - r = request_irq(dsi->irq, omap_dsi_irq_handler, IRQF_SHARED, - dev_name(&dsidev->dev), dsi->pdev); + r = devm_request_irq(&dsidev->dev, dsi->irq, omap_dsi_irq_handler, + IRQF_SHARED, dev_name(&dsidev->dev), dsi->pdev); if (r < 0) { DSSERR("request_irq failed\n"); - goto err_get_irq; + goto err_ioremap; } /* DSI VCs initialization */ @@ -4773,7 +4774,7 @@ static int omap_dsihw_probe(struct platform_device *dsidev) r = dsi_runtime_get(dsidev); if (r) - goto err_get_dsi; + goto err_ioremap; rev = dsi_read_reg(dsidev, DSI_REVISION); dev_dbg(&dsidev->dev, "OMAP DSI rev %d.%d\n", @@ -4791,14 +4792,8 @@ static int omap_dsihw_probe(struct platform_device *dsidev) return 0; -err_get_dsi: - free_irq(dsi->irq, dsi->pdev); -err_get_irq: - iounmap(dsi->base); err_ioremap: pm_runtime_disable(&dsidev->dev); -err_get_clk: - kfree(dsi); err_alloc: return r; } @@ -4823,11 +4818,6 @@ static int omap_dsihw_remove(struct platform_device *dsidev) dsi->vdds_dsi_reg = NULL; } - free_irq(dsi->irq, dsi->pdev); - iounmap(dsi->base); - - kfree(dsi); - return 0; } diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 17033457ee8..e75f837c766 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -751,7 +751,8 @@ static int omap_dsshw_probe(struct platform_device *pdev) r = -EINVAL; goto err_ioremap; } - dss.base = ioremap(dss_mem->start, resource_size(dss_mem)); + dss.base = devm_ioremap(&pdev->dev, dss_mem->start, + resource_size(dss_mem)); if (!dss.base) { DSSERR("can't ioremap DSS\n"); r = -ENOMEM; @@ -760,7 +761,7 @@ static int omap_dsshw_probe(struct platform_device *pdev) r = dss_get_clocks(); if (r) - goto err_clocks; + goto err_ioremap; pm_runtime_enable(&pdev->dev); @@ -808,8 +809,6 @@ err_dpi: err_runtime_get: pm_runtime_disable(&pdev->dev); dss_put_clocks(); -err_clocks: - iounmap(dss.base); err_ioremap: return r; } @@ -819,8 +818,6 @@ static int omap_dsshw_remove(struct platform_device *pdev) dpi_exit(); sdi_exit(); - iounmap(dss.base); - pm_runtime_disable(&pdev->dev); dss_put_clocks(); diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c index 814bb9500dc..159e914063c 100644 --- a/drivers/video/omap2/dss/rfbi.c +++ b/drivers/video/omap2/dss/rfbi.c @@ -925,7 +925,8 @@ static int omap_rfbihw_probe(struct platform_device *pdev) r = -EINVAL; goto err_ioremap; } - rfbi.base = ioremap(rfbi_mem->start, resource_size(rfbi_mem)); + rfbi.base = devm_ioremap(&pdev->dev, rfbi_mem->start, + resource_size(rfbi_mem)); if (!rfbi.base) { DSSERR("can't ioremap RFBI\n"); r = -ENOMEM; @@ -963,7 +964,6 @@ err_get_ick: rfbi_runtime_put(); err_get_rfbi: pm_runtime_disable(&pdev->dev); - iounmap(rfbi.base); err_ioremap: return r; } @@ -971,7 +971,6 @@ err_ioremap: static int omap_rfbihw_remove(struct platform_device *pdev) { pm_runtime_disable(&pdev->dev); - iounmap(rfbi.base); return 0; } diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index 82865bec945..4172232cdec 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c @@ -798,7 +798,8 @@ static int omap_venchw_probe(struct platform_device *pdev) r = -EINVAL; goto err_ioremap; } - venc.base = ioremap(venc_mem->start, resource_size(venc_mem)); + venc.base = devm_ioremap(&pdev->dev, venc_mem->start, + resource_size(venc_mem)); if (!venc.base) { DSSERR("can't ioremap VENC\n"); r = -ENOMEM; @@ -807,7 +808,7 @@ static int omap_venchw_probe(struct platform_device *pdev) r = venc_get_clocks(pdev); if (r) - goto err_get_clk; + goto err_ioremap; pm_runtime_enable(&pdev->dev); @@ -825,8 +826,6 @@ static int omap_venchw_probe(struct platform_device *pdev) err_get_venc: pm_runtime_disable(&pdev->dev); venc_put_clocks(); -err_get_clk: - iounmap(venc.base); err_ioremap: return r; } @@ -842,7 +841,6 @@ static int omap_venchw_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); venc_put_clocks(); - iounmap(venc.base); return 0; } -- cgit v1.2.3-70-g09d2 From 49e226323d462785582750d9f38acca5ffa5dd48 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 25 Jan 2012 12:35:38 +0100 Subject: regulator: Reverse the disable sequence in regulator_bulk_disable() Often there is a need for disabling a set of regulators in order opposite to the enable order. Currently the function regulator_bulk_disable() walks list of regulators in same order as regulator_bulk_enable(). This may cause trouble, especially for devices with mixed analogue and digital circuits. So reverse the disabling sequence of regulator_bulk_disable(). While at it, also correct the comment. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mark Brown --- drivers/regulator/core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index ca86f39a0fd..daba2f60f7d 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2463,8 +2463,8 @@ EXPORT_SYMBOL_GPL(regulator_bulk_enable); * @return 0 on success, an errno on failure * * This convenience API allows consumers to disable multiple regulator - * clients in a single API call. If any consumers cannot be enabled - * then any others that were disabled will be disabled again prior to + * clients in a single API call. If any consumers cannot be disabled + * then any others that were disabled will be enabled again prior to * return. */ int regulator_bulk_disable(int num_consumers, @@ -2473,7 +2473,7 @@ int regulator_bulk_disable(int num_consumers, int i; int ret; - for (i = 0; i < num_consumers; i++) { + for (i = num_consumers - 1; i >= 0; --i) { ret = regulator_disable(consumers[i].consumer); if (ret != 0) goto err; @@ -2483,7 +2483,7 @@ int regulator_bulk_disable(int num_consumers, err: pr_err("Failed to disable %s: %d\n", consumers[i].supply, ret); - for (--i; i >= 0; --i) + for (++i; i < num_consumers; ++i) regulator_enable(consumers[i].consumer); return ret; -- cgit v1.2.3-70-g09d2 From 7e53b195e412a813e915843adc7e4d91868e8e94 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 25 Jan 2012 20:46:53 +0000 Subject: regmap: Unexport regcache_write() and regcache_read() They have no current users which is fortunate as they don't take the lock and therefore aren't safe to use externally. We'll need to add new operations if direct cache access is needed. Signed-off-by: Mark Brown --- drivers/base/regmap/regcache.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 1ead66186b7..99beccfad4d 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -211,7 +211,6 @@ int regcache_read(struct regmap *map, return -EINVAL; } -EXPORT_SYMBOL_GPL(regcache_read); /** * regcache_write: Set the value of a given register in the cache. @@ -238,7 +237,6 @@ int regcache_write(struct regmap *map, return 0; } -EXPORT_SYMBOL_GPL(regcache_write); /** * regcache_sync: Sync the register cache with the hardware. -- cgit v1.2.3-70-g09d2 From d9db762708e27c2892db9d8a54e735a8e506e16e Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 25 Jan 2012 21:06:33 +0000 Subject: regmap: Skip patch application when the cache is not dirty on sync On the basis that if we don't actually need to resync the cache then the patches are probably also already applied. Signed-off-by: Mark Brown --- drivers/base/regmap/regcache.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index ce2034c10ff..9c6a5c13f1d 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -269,6 +269,9 @@ int regcache_sync(struct regmap *map) name = map->cache_ops->name; trace_regcache_sync(map->dev, name, "start"); + if (!map->cache_dirty) + goto out; + /* Apply any patch first */ for (i = 0; i < map->patch_regs; i++) { ret = _regmap_write(map, map->patch[i].reg, map->patch[i].def); @@ -279,8 +282,6 @@ int regcache_sync(struct regmap *map) } } - if (!map->cache_dirty) - goto out; if (map->cache_ops->sync) { ret = map->cache_ops->sync(map); } else { -- cgit v1.2.3-70-g09d2 From 8a892d6996b60c822f19ad1844eb15b96ce393c7 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 25 Jan 2012 21:05:48 +0000 Subject: regmap: Bypass the cache when applying patches Otherwise any patch that affects a register which is writable may trash cached values. Signed-off-by: Mark Brown --- drivers/base/regmap/regcache.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 9c6a5c13f1d..ee36bed9479 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -273,6 +273,7 @@ int regcache_sync(struct regmap *map) goto out; /* Apply any patch first */ + map->cache_bypass = 1; for (i = 0; i < map->patch_regs; i++) { ret = _regmap_write(map, map->patch[i].reg, map->patch[i].def); if (ret != 0) { @@ -281,6 +282,7 @@ int regcache_sync(struct regmap *map) goto out; } } + map->cache_bypass = 0; if (map->cache_ops->sync) { ret = map->cache_ops->sync(map); -- cgit v1.2.3-70-g09d2 From 8bca5d1ebb8bf18187256845ba3aaff5fbc01934 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 24 Jan 2012 19:47:21 +0000 Subject: vmxnet3: cleanup tso headers manipulation Use existing helpers to clarify skb headers manipulation. Signed-off-by: Eric Dumazet Cc: Shreyas Bhatewara Signed-off-by: David S. Miller --- drivers/net/vmxnet3/vmxnet3_drv.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index de7fc345148..be6aa353f6a 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -816,27 +816,24 @@ vmxnet3_parse_and_copy_hdr(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, if (ctx->mss) { /* TSO */ ctx->eth_ip_hdr_size = skb_transport_offset(skb); - ctx->l4_hdr_size = ((struct tcphdr *) - skb_transport_header(skb))->doff * 4; + ctx->l4_hdr_size = tcp_hdrlen(skb); ctx->copy_size = ctx->eth_ip_hdr_size + ctx->l4_hdr_size; } else { if (skb->ip_summed == CHECKSUM_PARTIAL) { ctx->eth_ip_hdr_size = skb_checksum_start_offset(skb); if (ctx->ipv4) { - struct iphdr *iph = (struct iphdr *) - skb_network_header(skb); + const struct iphdr *iph = ip_hdr(skb); + if (iph->protocol == IPPROTO_TCP) - ctx->l4_hdr_size = ((struct tcphdr *) - skb_transport_header(skb))->doff * 4; + ctx->l4_hdr_size = tcp_hdrlen(skb); else if (iph->protocol == IPPROTO_UDP) /* * Use tcp header size so that bytes to * be copied are more than required by * the device. */ - ctx->l4_hdr_size = - sizeof(struct tcphdr); + ctx->l4_hdr_size = sizeof(struct tcphdr); else ctx->l4_hdr_size = 0; } else { @@ -881,14 +878,17 @@ static void vmxnet3_prepare_tso(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx) { - struct tcphdr *tcph = (struct tcphdr *)skb_transport_header(skb); + struct tcphdr *tcph = tcp_hdr(skb); + if (ctx->ipv4) { - struct iphdr *iph = (struct iphdr *)skb_network_header(skb); + struct iphdr *iph = ip_hdr(skb); + iph->check = 0; tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, 0, IPPROTO_TCP, 0); } else { - struct ipv6hdr *iph = (struct ipv6hdr *)skb_network_header(skb); + struct ipv6hdr *iph = ipv6_hdr(skb); + tcph->check = ~csum_ipv6_magic(&iph->saddr, &iph->daddr, 0, IPPROTO_TCP, 0); } -- cgit v1.2.3-70-g09d2 From a44acd551467d78a26bfa76ea348225575830efc Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 24 Jan 2012 21:59:31 +0000 Subject: bnx2x: unlock before returning an error We introduced a new return here but forgot to drop the lock. Signed-off-by: Dan Carpenter Acked-by: Dmitry Kravkov Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index cb6339c3557..69465c32e5f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c @@ -1836,6 +1836,7 @@ static int bnx2x_vlan_mac_del_all(struct bnx2x *bp, rc = exeq->remove(bp, exeq->owner, exeq_pos); if (rc) { BNX2X_ERR("Failed to remove command\n"); + spin_unlock_bh(&exeq->lock); return rc; } list_del(&exeq_pos->link); -- cgit v1.2.3-70-g09d2 From 8a3b7a252dca9fb28c23b5bf76c49180a2b60d3b Mon Sep 17 00:00:00 2001 From: "danborkmann@iogearbox.net" Date: Thu, 19 Jan 2012 00:39:31 +0000 Subject: drivers/net/ethernet/xilinx: added Xilinx AXI Ethernet driver This driver adds support for Xilinx 10/100/1000 AXI Ethernet. It can be used, for instance, on Xilinx boards with a Microblaze architecture like the ML605. The patch is against the latest net-next tree and checkpatch clean. Signed-off-by: Ariane Keller Signed-off-by: Daniel Borkmann Signed-off-by: David S. Miller --- MAINTAINERS | 6 + drivers/net/ethernet/xilinx/Kconfig | 8 + drivers/net/ethernet/xilinx/Makefile | 2 + drivers/net/ethernet/xilinx/xilinx_axienet.h | 508 +++++++ drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 1682 +++++++++++++++++++++ drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c | 238 +++ 6 files changed, 2444 insertions(+) create mode 100644 drivers/net/ethernet/xilinx/xilinx_axienet.h create mode 100644 drivers/net/ethernet/xilinx/xilinx_axienet_main.c create mode 100644 drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c (limited to 'drivers') diff --git a/MAINTAINERS b/MAINTAINERS index 93c68d5f1cf..087b65d1258 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7469,6 +7469,12 @@ S: Supported F: Documentation/filesystems/xfs.txt F: fs/xfs/ +XILINX AXI ETHERNET DRIVER +M: Ariane Keller +M: Daniel Borkmann +S: Maintained +F: drivers/net/ethernet/xilinx/xilinx_axienet* + XILINX SYSTEMACE DRIVER M: Grant Likely W: http://www.secretlab.ca/ diff --git a/drivers/net/ethernet/xilinx/Kconfig b/drivers/net/ethernet/xilinx/Kconfig index d5a826063a8..5778a4ae116 100644 --- a/drivers/net/ethernet/xilinx/Kconfig +++ b/drivers/net/ethernet/xilinx/Kconfig @@ -25,6 +25,14 @@ config XILINX_EMACLITE ---help--- This driver supports the 10/100 Ethernet Lite from Xilinx. +config XILINX_AXI_EMAC + tristate "Xilinx 10/100/1000 AXI Ethernet support" + depends on (PPC32 || MICROBLAZE) + select PHYLIB + ---help--- + This driver supports the 10/100/1000 Ethernet from Xilinx for the + AXI bus interface used in Xilinx Virtex FPGAs. + config XILINX_LL_TEMAC tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver" depends on (PPC || MICROBLAZE) diff --git a/drivers/net/ethernet/xilinx/Makefile b/drivers/net/ethernet/xilinx/Makefile index 5feac734ea4..214205e975e 100644 --- a/drivers/net/ethernet/xilinx/Makefile +++ b/drivers/net/ethernet/xilinx/Makefile @@ -5,3 +5,5 @@ ll_temac-objs := ll_temac_main.o ll_temac_mdio.o obj-$(CONFIG_XILINX_LL_TEMAC) += ll_temac.o obj-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o +xilinx_emac-objs := xilinx_axienet_main.o xilinx_axienet_mdio.o +obj-$(CONFIG_XILINX_AXI_EMAC) += xilinx_emac.o diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/ethernet/xilinx/xilinx_axienet.h new file mode 100644 index 00000000000..cc83af083fd --- /dev/null +++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h @@ -0,0 +1,508 @@ +/* + * Definitions for Xilinx Axi Ethernet device driver. + * + * Copyright (c) 2009 Secret Lab Technologies, Ltd. + * Copyright (c) 2010 Xilinx, Inc. All rights reserved. + * Copyright (c) 2012 Daniel Borkmann, + * Copyright (c) 2012 Ariane Keller, + */ + +#ifndef XILINX_AXIENET_H +#define XILINX_AXIENET_H + +#include +#include +#include + +/* Packet size info */ +#define XAE_HDR_SIZE 14 /* Size of Ethernet header */ +#define XAE_HDR_VLAN_SIZE 18 /* Size of an Ethernet hdr + VLAN */ +#define XAE_TRL_SIZE 4 /* Size of Ethernet trailer (FCS) */ +#define XAE_MTU 1500 /* Max MTU of an Ethernet frame */ +#define XAE_JUMBO_MTU 9000 /* Max MTU of a jumbo Eth. frame */ + +#define XAE_MAX_FRAME_SIZE (XAE_MTU + XAE_HDR_SIZE + XAE_TRL_SIZE) +#define XAE_MAX_VLAN_FRAME_SIZE (XAE_MTU + XAE_HDR_VLAN_SIZE + XAE_TRL_SIZE) +#define XAE_MAX_JUMBO_FRAME_SIZE (XAE_JUMBO_MTU + XAE_HDR_SIZE + XAE_TRL_SIZE) + +/* Configuration options */ + +/* Accept all incoming packets. Default: disabled (cleared) */ +#define XAE_OPTION_PROMISC (1 << 0) + +/* Jumbo frame support for Tx & Rx. Default: disabled (cleared) */ +#define XAE_OPTION_JUMBO (1 << 1) + +/* VLAN Rx & Tx frame support. Default: disabled (cleared) */ +#define XAE_OPTION_VLAN (1 << 2) + +/* Enable recognition of flow control frames on Rx. Default: enabled (set) */ +#define XAE_OPTION_FLOW_CONTROL (1 << 4) + +/* Strip FCS and PAD from incoming frames. Note: PAD from VLAN frames is not + * stripped. Default: disabled (set) */ +#define XAE_OPTION_FCS_STRIP (1 << 5) + +/* Generate FCS field and add PAD automatically for outgoing frames. + * Default: enabled (set) */ +#define XAE_OPTION_FCS_INSERT (1 << 6) + +/* Enable Length/Type error checking for incoming frames. When this option is + * set, the MAC will filter frames that have a mismatched type/length field + * and if XAE_OPTION_REPORT_RXERR is set, the user is notified when these + * types of frames are encountered. When this option is cleared, the MAC will + * allow these types of frames to be received. Default: enabled (set) */ +#define XAE_OPTION_LENTYPE_ERR (1 << 7) + +/* Enable the transmitter. Default: enabled (set) */ +#define XAE_OPTION_TXEN (1 << 11) + +/* Enable the receiver. Default: enabled (set) */ +#define XAE_OPTION_RXEN (1 << 12) + +/* Default options set when device is initialized or reset */ +#define XAE_OPTION_DEFAULTS \ + (XAE_OPTION_TXEN | \ + XAE_OPTION_FLOW_CONTROL | \ + XAE_OPTION_RXEN) + +/* Axi DMA Register definitions */ + +#define XAXIDMA_TX_CR_OFFSET 0x00000000 /* Channel control */ +#define XAXIDMA_TX_SR_OFFSET 0x00000004 /* Status */ +#define XAXIDMA_TX_CDESC_OFFSET 0x00000008 /* Current descriptor pointer */ +#define XAXIDMA_TX_TDESC_OFFSET 0x00000010 /* Tail descriptor pointer */ + +#define XAXIDMA_RX_CR_OFFSET 0x00000030 /* Channel control */ +#define XAXIDMA_RX_SR_OFFSET 0x00000034 /* Status */ +#define XAXIDMA_RX_CDESC_OFFSET 0x00000038 /* Current descriptor pointer */ +#define XAXIDMA_RX_TDESC_OFFSET 0x00000040 /* Tail descriptor pointer */ + +#define XAXIDMA_CR_RUNSTOP_MASK 0x00000001 /* Start/stop DMA channel */ +#define XAXIDMA_CR_RESET_MASK 0x00000004 /* Reset DMA engine */ + +#define XAXIDMA_BD_NDESC_OFFSET 0x00 /* Next descriptor pointer */ +#define XAXIDMA_BD_BUFA_OFFSET 0x08 /* Buffer address */ +#define XAXIDMA_BD_CTRL_LEN_OFFSET 0x18 /* Control/buffer length */ +#define XAXIDMA_BD_STS_OFFSET 0x1C /* Status */ +#define XAXIDMA_BD_USR0_OFFSET 0x20 /* User IP specific word0 */ +#define XAXIDMA_BD_USR1_OFFSET 0x24 /* User IP specific word1 */ +#define XAXIDMA_BD_USR2_OFFSET 0x28 /* User IP specific word2 */ +#define XAXIDMA_BD_USR3_OFFSET 0x2C /* User IP specific word3 */ +#define XAXIDMA_BD_USR4_OFFSET 0x30 /* User IP specific word4 */ +#define XAXIDMA_BD_ID_OFFSET 0x34 /* Sw ID */ +#define XAXIDMA_BD_HAS_STSCNTRL_OFFSET 0x38 /* Whether has stscntrl strm */ +#define XAXIDMA_BD_HAS_DRE_OFFSET 0x3C /* Whether has DRE */ + +#define XAXIDMA_BD_HAS_DRE_SHIFT 8 /* Whether has DRE shift */ +#define XAXIDMA_BD_HAS_DRE_MASK 0xF00 /* Whether has DRE mask */ +#define XAXIDMA_BD_WORDLEN_MASK 0xFF /* Whether has DRE mask */ + +#define XAXIDMA_BD_CTRL_LENGTH_MASK 0x007FFFFF /* Requested len */ +#define XAXIDMA_BD_CTRL_TXSOF_MASK 0x08000000 /* First tx packet */ +#define XAXIDMA_BD_CTRL_TXEOF_MASK 0x04000000 /* Last tx packet */ +#define XAXIDMA_BD_CTRL_ALL_MASK 0x0C000000 /* All control bits */ + +#define XAXIDMA_DELAY_MASK 0xFF000000 /* Delay timeout counter */ +#define XAXIDMA_COALESCE_MASK 0x00FF0000 /* Coalesce counter */ + +#define XAXIDMA_DELAY_SHIFT 24 +#define XAXIDMA_COALESCE_SHIFT 16 + +#define XAXIDMA_IRQ_IOC_MASK 0x00001000 /* Completion intr */ +#define XAXIDMA_IRQ_DELAY_MASK 0x00002000 /* Delay interrupt */ +#define XAXIDMA_IRQ_ERROR_MASK 0x00004000 /* Error interrupt */ +#define XAXIDMA_IRQ_ALL_MASK 0x00007000 /* All interrupts */ + +/* Default TX/RX Threshold and waitbound values for SGDMA mode */ +#define XAXIDMA_DFT_TX_THRESHOLD 24 +#define XAXIDMA_DFT_TX_WAITBOUND 254 +#define XAXIDMA_DFT_RX_THRESHOLD 24 +#define XAXIDMA_DFT_RX_WAITBOUND 254 + +#define XAXIDMA_BD_CTRL_TXSOF_MASK 0x08000000 /* First tx packet */ +#define XAXIDMA_BD_CTRL_TXEOF_MASK 0x04000000 /* Last tx packet */ +#define XAXIDMA_BD_CTRL_ALL_MASK 0x0C000000 /* All control bits */ + +#define XAXIDMA_BD_STS_ACTUAL_LEN_MASK 0x007FFFFF /* Actual len */ +#define XAXIDMA_BD_STS_COMPLETE_MASK 0x80000000 /* Completed */ +#define XAXIDMA_BD_STS_DEC_ERR_MASK 0x40000000 /* Decode error */ +#define XAXIDMA_BD_STS_SLV_ERR_MASK 0x20000000 /* Slave error */ +#define XAXIDMA_BD_STS_INT_ERR_MASK 0x10000000 /* Internal err */ +#define XAXIDMA_BD_STS_ALL_ERR_MASK 0x70000000 /* All errors */ +#define XAXIDMA_BD_STS_RXSOF_MASK 0x08000000 /* First rx pkt */ +#define XAXIDMA_BD_STS_RXEOF_MASK 0x04000000 /* Last rx pkt */ +#define XAXIDMA_BD_STS_ALL_MASK 0xFC000000 /* All status bits */ + +#define XAXIDMA_BD_MINIMUM_ALIGNMENT 0x40 + +/* Axi Ethernet registers definition */ +#define XAE_RAF_OFFSET 0x00000000 /* Reset and Address filter */ +#define XAE_TPF_OFFSET 0x00000004 /* Tx Pause Frame */ +#define XAE_IFGP_OFFSET 0x00000008 /* Tx Inter-frame gap adjustment*/ +#define XAE_IS_OFFSET 0x0000000C /* Interrupt status */ +#define XAE_IP_OFFSET 0x00000010 /* Interrupt pending */ +#define XAE_IE_OFFSET 0x00000014 /* Interrupt enable */ +#define XAE_TTAG_OFFSET 0x00000018 /* Tx VLAN TAG */ +#define XAE_RTAG_OFFSET 0x0000001C /* Rx VLAN TAG */ +#define XAE_UAWL_OFFSET 0x00000020 /* Unicast address word lower */ +#define XAE_UAWU_OFFSET 0x00000024 /* Unicast address word upper */ +#define XAE_TPID0_OFFSET 0x00000028 /* VLAN TPID0 register */ +#define XAE_TPID1_OFFSET 0x0000002C /* VLAN TPID1 register */ +#define XAE_PPST_OFFSET 0x00000030 /* PCS PMA Soft Temac Status Reg */ +#define XAE_RCW0_OFFSET 0x00000400 /* Rx Configuration Word 0 */ +#define XAE_RCW1_OFFSET 0x00000404 /* Rx Configuration Word 1 */ +#define XAE_TC_OFFSET 0x00000408 /* Tx Configuration */ +#define XAE_FCC_OFFSET 0x0000040C /* Flow Control Configuration */ +#define XAE_EMMC_OFFSET 0x00000410 /* EMAC mode configuration */ +#define XAE_PHYC_OFFSET 0x00000414 /* RGMII/SGMII configuration */ +#define XAE_MDIO_MC_OFFSET 0x00000500 /* MII Management Config */ +#define XAE_MDIO_MCR_OFFSET 0x00000504 /* MII Management Control */ +#define XAE_MDIO_MWD_OFFSET 0x00000508 /* MII Management Write Data */ +#define XAE_MDIO_MRD_OFFSET 0x0000050C /* MII Management Read Data */ +#define XAE_MDIO_MIS_OFFSET 0x00000600 /* MII Management Interrupt Status */ +#define XAE_MDIO_MIP_OFFSET 0x00000620 /* MII Mgmt Interrupt Pending + * register offset */ +#define XAE_MDIO_MIE_OFFSET 0x00000640 /* MII Management Interrupt Enable + * register offset */ +#define XAE_MDIO_MIC_OFFSET 0x00000660 /* MII Management Interrupt Clear + * register offset. */ +#define XAE_UAW0_OFFSET 0x00000700 /* Unicast address word 0 */ +#define XAE_UAW1_OFFSET 0x00000704 /* Unicast address word 1 */ +#define XAE_FMI_OFFSET 0x00000708 /* Filter Mask Index */ +#define XAE_AF0_OFFSET 0x00000710 /* Address Filter 0 */ +#define XAE_AF1_OFFSET 0x00000714 /* Address Filter 1 */ + +#define XAE_TX_VLAN_DATA_OFFSET 0x00004000 /* TX VLAN data table address */ +#define XAE_RX_VLAN_DATA_OFFSET 0x00008000 /* RX VLAN data table address */ +#define XAE_MCAST_TABLE_OFFSET 0x00020000 /* Multicast table address */ + +/* Bit Masks for Axi Ethernet RAF register */ +#define XAE_RAF_MCSTREJ_MASK 0x00000002 /* Reject receive multicast + * destination address */ +#define XAE_RAF_BCSTREJ_MASK 0x00000004 /* Reject receive broadcast + * destination address */ +#define XAE_RAF_TXVTAGMODE_MASK 0x00000018 /* Tx VLAN TAG mode */ +#define XAE_RAF_RXVTAGMODE_MASK 0x00000060 /* Rx VLAN TAG mode */ +#define XAE_RAF_TXVSTRPMODE_MASK 0x00000180 /* Tx VLAN STRIP mode */ +#define XAE_RAF_RXVSTRPMODE_MASK 0x00000600 /* Rx VLAN STRIP mode */ +#define XAE_RAF_NEWFNCENBL_MASK 0x00000800 /* New function mode */ +#define XAE_RAF_EMULTIFLTRENBL_MASK 0x00001000 /* Exteneded Multicast + * Filtering mode + */ +#define XAE_RAF_STATSRST_MASK 0x00002000 /* Stats. Counter Reset */ +#define XAE_RAF_RXBADFRMEN_MASK 0x00004000 /* Recv Bad Frame Enable */ +#define XAE_RAF_TXVTAGMODE_SHIFT 3 /* Tx Tag mode shift bits */ +#define XAE_RAF_RXVTAGMODE_SHIFT 5 /* Rx Tag mode shift bits */ +#define XAE_RAF_TXVSTRPMODE_SHIFT 7 /* Tx strip mode shift bits*/ +#define XAE_RAF_RXVSTRPMODE_SHIFT 9 /* Rx Strip mode shift bits*/ + +/* Bit Masks for Axi Ethernet TPF and IFGP registers */ +#define XAE_TPF_TPFV_MASK 0x0000FFFF /* Tx pause frame value */ +#define XAE_IFGP0_IFGP_MASK 0x0000007F /* Transmit inter-frame + * gap adjustment value */ + +/* Bit Masks for Axi Ethernet IS, IE and IP registers, Same masks apply + * for all 3 registers. */ +#define XAE_INT_HARDACSCMPLT_MASK 0x00000001 /* Hard register access + * complete */ +#define XAE_INT_AUTONEG_MASK 0x00000002 /* Auto negotiation + * complete */ +#define XAE_INT_RXCMPIT_MASK 0x00000004 /* Rx complete */ +#define XAE_INT_RXRJECT_MASK 0x00000008 /* Rx frame rejected */ +#define XAE_INT_RXFIFOOVR_MASK 0x00000010 /* Rx fifo overrun */ +#define XAE_INT_TXCMPIT_MASK 0x00000020 /* Tx complete */ +#define XAE_INT_RXDCMLOCK_MASK 0x00000040 /* Rx Dcm Lock */ +#define XAE_INT_MGTRDY_MASK 0x00000080 /* MGT clock Lock */ +#define XAE_INT_PHYRSTCMPLT_MASK 0x00000100 /* Phy Reset complete */ +#define XAE_INT_ALL_MASK 0x0000003F /* All the ints */ + +#define XAE_INT_RECV_ERROR_MASK \ + (XAE_INT_RXRJECT_MASK | XAE_INT_RXFIFOOVR_MASK) /* INT bits that + * indicate receive + * errors */ + +/* Bit masks for Axi Ethernet VLAN TPID Word 0 register */ +#define XAE_TPID_0_MASK 0x0000FFFF /* TPID 0 */ +#define XAE_TPID_1_MASK 0xFFFF0000 /* TPID 1 */ + +/* Bit masks for Axi Ethernet VLAN TPID Word 1 register */ +#define XAE_TPID_2_MASK 0x0000FFFF /* TPID 0 */ +#define XAE_TPID_3_MASK 0xFFFF0000 /* TPID 1 */ + +/* Bit masks for Axi Ethernet RCW1 register */ +#define XAE_RCW1_RST_MASK 0x80000000 /* Reset */ +#define XAE_RCW1_JUM_MASK 0x40000000 /* Jumbo frame enable */ +#define XAE_RCW1_FCS_MASK 0x20000000 /* In-Band FCS enable + * (FCS not stripped) */ +#define XAE_RCW1_RX_MASK 0x10000000 /* Receiver enable */ +#define XAE_RCW1_VLAN_MASK 0x08000000 /* VLAN frame enable */ +#define XAE_RCW1_LT_DIS_MASK 0x02000000 /* Length/type field valid check + * disable */ +#define XAE_RCW1_CL_DIS_MASK 0x01000000 /* Control frame Length check + * disable */ +#define XAE_RCW1_PAUSEADDR_MASK 0x0000FFFF /* Pause frame source address + * bits [47:32]. Bits [31:0] are + * stored in register RCW0 */ + +/* Bit masks for Axi Ethernet TC register */ +#define XAE_TC_RST_MASK 0x80000000 /* Reset */ +#define XAE_TC_JUM_MASK 0x40000000 /* Jumbo frame enable */ +#define XAE_TC_FCS_MASK 0x20000000 /* In-Band FCS enable + * (FCS not generated) */ +#define XAE_TC_TX_MASK 0x10000000 /* Transmitter enable */ +#define XAE_TC_VLAN_MASK 0x08000000 /* VLAN frame enable */ +#define XAE_TC_IFG_MASK 0x02000000 /* Inter-frame gap adjustment + * enable */ + +/* Bit masks for Axi Ethernet FCC register */ +#define XAE_FCC_FCRX_MASK 0x20000000 /* Rx flow control enable */ +#define XAE_FCC_FCTX_MASK 0x40000000 /* Tx flow control enable */ + +/* Bit masks for Axi Ethernet EMMC register */ +#define XAE_EMMC_LINKSPEED_MASK 0xC0000000 /* Link speed */ +#define XAE_EMMC_RGMII_MASK 0x20000000 /* RGMII mode enable */ +#define XAE_EMMC_SGMII_MASK 0x10000000 /* SGMII mode enable */ +#define XAE_EMMC_GPCS_MASK 0x08000000 /* 1000BaseX mode enable */ +#define XAE_EMMC_HOST_MASK 0x04000000 /* Host interface enable */ +#define XAE_EMMC_TX16BIT 0x02000000 /* 16 bit Tx client enable */ +#define XAE_EMMC_RX16BIT 0x01000000 /* 16 bit Rx client enable */ +#define XAE_EMMC_LINKSPD_10 0x00000000 /* Link Speed mask for 10 Mbit */ +#define XAE_EMMC_LINKSPD_100 0x40000000 /* Link Speed mask for 100 Mbit */ +#define XAE_EMMC_LINKSPD_1000 0x80000000 /* Link Speed mask for 1000 Mbit */ + +/* Bit masks for Axi Ethernet PHYC register */ +#define XAE_PHYC_SGMIILINKSPEED_MASK 0xC0000000 /* SGMII link speed mask*/ +#define XAE_PHYC_RGMIILINKSPEED_MASK 0x0000000C /* RGMII link speed */ +#define XAE_PHYC_RGMIIHD_MASK 0x00000002 /* RGMII Half-duplex */ +#define XAE_PHYC_RGMIILINK_MASK 0x00000001 /* RGMII link status */ +#define XAE_PHYC_RGLINKSPD_10 0x00000000 /* RGMII link 10 Mbit */ +#define XAE_PHYC_RGLINKSPD_100 0x00000004 /* RGMII link 100 Mbit */ +#define XAE_PHYC_RGLINKSPD_1000 0x00000008 /* RGMII link 1000 Mbit */ +#define XAE_PHYC_SGLINKSPD_10 0x00000000 /* SGMII link 10 Mbit */ +#define XAE_PHYC_SGLINKSPD_100 0x40000000 /* SGMII link 100 Mbit */ +#define XAE_PHYC_SGLINKSPD_1000 0x80000000 /* SGMII link 1000 Mbit */ + +/* Bit masks for Axi Ethernet MDIO interface MC register */ +#define XAE_MDIO_MC_MDIOEN_MASK 0x00000040 /* MII management enable */ +#define XAE_MDIO_MC_CLOCK_DIVIDE_MAX 0x3F /* Maximum MDIO divisor */ + +/* Bit masks for Axi Ethernet MDIO interface MCR register */ +#define XAE_MDIO_MCR_PHYAD_MASK 0x1F000000 /* Phy Address Mask */ +#define XAE_MDIO_MCR_PHYAD_SHIFT 24 /* Phy Address Shift */ +#define XAE_MDIO_MCR_REGAD_MASK 0x001F0000 /* Reg Address Mask */ +#define XAE_MDIO_MCR_REGAD_SHIFT 16 /* Reg Address Shift */ +#define XAE_MDIO_MCR_OP_MASK 0x0000C000 /* Operation Code Mask */ +#define XAE_MDIO_MCR_OP_SHIFT 13 /* Operation Code Shift */ +#define XAE_MDIO_MCR_OP_READ_MASK 0x00008000 /* Op Code Read Mask */ +#define XAE_MDIO_MCR_OP_WRITE_MASK 0x00004000 /* Op Code Write Mask */ +#define XAE_MDIO_MCR_INITIATE_MASK 0x00000800 /* Ready Mask */ +#define XAE_MDIO_MCR_READY_MASK 0x00000080 /* Ready Mask */ + +/* Bit masks for Axi Ethernet MDIO interface MIS, MIP, MIE, MIC registers */ +#define XAE_MDIO_INT_MIIM_RDY_MASK 0x00000001 /* MIIM Interrupt */ + +/* Bit masks for Axi Ethernet UAW1 register */ +#define XAE_UAW1_UNICASTADDR_MASK 0x0000FFFF /* Station address bits + * [47:32]; Station address + * bits [31:0] are stored in + * register UAW0 */ + +/* Bit masks for Axi Ethernet FMI register */ +#define XAE_FMI_PM_MASK 0x80000000 /* Promis. mode enable */ +#define XAE_FMI_IND_MASK 0x00000003 /* Index Mask */ + +#define XAE_MDIO_DIV_DFT 29 /* Default MDIO clock divisor */ + +/* Defines for different options for C_PHY_TYPE parameter in Axi Ethernet IP */ +#define XAE_PHY_TYPE_MII 0 +#define XAE_PHY_TYPE_GMII 1 +#define XAE_PHY_TYPE_RGMII_1_3 2 +#define XAE_PHY_TYPE_RGMII_2_0 3 +#define XAE_PHY_TYPE_SGMII 4 +#define XAE_PHY_TYPE_1000BASE_X 5 + +#define XAE_MULTICAST_CAM_TABLE_NUM 4 /* Total number of entries in the + * hardware multicast table. */ + +/* Axi Ethernet Synthesis features */ +#define XAE_FEATURE_PARTIAL_RX_CSUM (1 << 0) +#define XAE_FEATURE_PARTIAL_TX_CSUM (1 << 1) +#define XAE_FEATURE_FULL_RX_CSUM (1 << 2) +#define XAE_FEATURE_FULL_TX_CSUM (1 << 3) + +#define XAE_NO_CSUM_OFFLOAD 0 + +#define XAE_FULL_CSUM_STATUS_MASK 0x00000038 +#define XAE_IP_UDP_CSUM_VALIDATED 0x00000003 +#define XAE_IP_TCP_CSUM_VALIDATED 0x00000002 + +#define DELAY_OF_ONE_MILLISEC 1000 + +/** + * struct axidma_bd - Axi Dma buffer descriptor layout + * @next: MM2S/S2MM Next Descriptor Pointer + * @reserved1: Reserved and not used + * @phys: MM2S/S2MM Buffer Address + * @reserved2: Reserved and not used + * @reserved3: Reserved and not used + * @reserved4: Reserved and not used + * @cntrl: MM2S/S2MM Control value + * @status: MM2S/S2MM Status value + * @app0: MM2S/S2MM User Application Field 0. + * @app1: MM2S/S2MM User Application Field 1. + * @app2: MM2S/S2MM User Application Field 2. + * @app3: MM2S/S2MM User Application Field 3. + * @app4: MM2S/S2MM User Application Field 4. + * @sw_id_offset: MM2S/S2MM Sw ID + * @reserved5: Reserved and not used + * @reserved6: Reserved and not used + */ +struct axidma_bd { + u32 next; /* Physical address of next buffer descriptor */ + u32 reserved1; + u32 phys; + u32 reserved2; + u32 reserved3; + u32 reserved4; + u32 cntrl; + u32 status; + u32 app0; + u32 app1; /* TX start << 16 | insert */ + u32 app2; /* TX csum seed */ + u32 app3; + u32 app4; + u32 sw_id_offset; + u32 reserved5; + u32 reserved6; +}; + +/** + * struct axienet_local - axienet private per device data + * @ndev: Pointer for net_device to which it will be attached. + * @dev: Pointer to device structure + * @phy_dev: Pointer to PHY device structure attached to the axienet_local + * @phy_node: Pointer to device node structure + * @mii_bus: Pointer to MII bus structure + * @mdio_irqs: IRQs table for MDIO bus required in mii_bus structure + * @regs: Base address for the axienet_local device address space + * @dma_regs: Base address for the axidma device address space + * @dma_err_tasklet: Tasklet structure to process Axi DMA errors + * @tx_irq: Axidma TX IRQ number + * @rx_irq: Axidma RX IRQ number + * @temac_type: axienet type to identify between soft and hard temac + * @phy_type: Phy type to identify between MII/GMII/RGMII/SGMII/1000 Base-X + * @options: AxiEthernet option word + * @last_link: Phy link state in which the PHY was negotiated earlier + * @features: Stores the extended features supported by the axienet hw + * @tx_bd_v: Virtual address of the TX buffer descriptor ring + * @tx_bd_p: Physical address(start address) of the TX buffer descr. ring + * @rx_bd_v: Virtual address of the RX buffer descriptor ring + * @rx_bd_p: Physical address(start address) of the RX buffer descr. ring + * @tx_bd_ci: Stores the index of the Tx buffer descriptor in the ring being + * accessed currently. Used while alloc. BDs before a TX starts + * @tx_bd_tail: Stores the index of the Tx buffer descriptor in the ring being + * accessed currently. Used while processing BDs after the TX + * completed. + * @rx_bd_ci: Stores the index of the Rx buffer descriptor in the ring being + * accessed currently. + * @max_frm_size: Stores the maximum size of the frame that can be that + * Txed/Rxed in the existing hardware. If jumbo option is + * supported, the maximum frame size would be 9k. Else it is + * 1522 bytes (assuming support for basic VLAN) + * @jumbo_support: Stores hardware configuration for jumbo support. If hardware + * can handle jumbo packets, this entry will be 1, else 0. + */ +struct axienet_local { + struct net_device *ndev; + struct device *dev; + + /* Connection to PHY device */ + struct phy_device *phy_dev; /* Pointer to PHY device */ + struct device_node *phy_node; + + /* MDIO bus data */ + struct mii_bus *mii_bus; /* MII bus reference */ + int mdio_irqs[PHY_MAX_ADDR]; /* IRQs table for MDIO bus */ + + /* IO registers, dma functions and IRQs */ + void __iomem *regs; + void __iomem *dma_regs; + + struct tasklet_struct dma_err_tasklet; + + int tx_irq; + int rx_irq; + u32 temac_type; + u32 phy_type; + + u32 options; /* Current options word */ + u32 last_link; + u32 features; + + /* Buffer descriptors */ + struct axidma_bd *tx_bd_v; + dma_addr_t tx_bd_p; + struct axidma_bd *rx_bd_v; + dma_addr_t rx_bd_p; + u32 tx_bd_ci; + u32 tx_bd_tail; + u32 rx_bd_ci; + + u32 max_frm_size; + u32 jumbo_support; + + int csum_offload_on_tx_path; + int csum_offload_on_rx_path; + + u32 coalesce_count_rx; + u32 coalesce_count_tx; +}; + +/** + * struct axiethernet_option - Used to set axi ethernet hardware options + * @opt: Option to be set. + * @reg: Register offset to be written for setting the option + * @m_or: Mask to be ORed for setting the option in the register + */ +struct axienet_option { + u32 opt; + u32 reg; + u32 m_or; +}; + +/** + * axienet_ior - Memory mapped Axi Ethernet register read + * @lp: Pointer to axienet local structure + * @offset: Address offset from the base address of Axi Ethernet core + * + * returns: The contents of the Axi Ethernet register + * + * This function returns the contents of the corresponding register. + */ +static inline u32 axienet_ior(struct axienet_local *lp, off_t offset) +{ + return in_be32(lp->regs + offset); +} + +/** + * axienet_iow - Memory mapped Axi Ethernet register write + * @lp: Pointer to axienet local structure + * @offset: Address offset from the base address of Axi Ethernet core + * @value: Value to be written into the Axi Ethernet register + * + * This function writes the desired value into the corresponding Axi Ethernet + * register. + */ +static inline void axienet_iow(struct axienet_local *lp, off_t offset, + u32 value) +{ + out_be32((lp->regs + offset), value); +} + +/* Function prototypes visible in xilinx_axienet_mdio.c for other files */ +int axienet_mdio_setup(struct axienet_local *lp, struct device_node *np); +int axienet_mdio_wait_until_ready(struct axienet_local *lp); +void axienet_mdio_teardown(struct axienet_local *lp); + +#endif /* XILINX_AXI_ENET_H */ diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c new file mode 100644 index 00000000000..ea50caf8925 --- /dev/null +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -0,0 +1,1682 @@ +/* + * Xilinx Axi Ethernet device driver + * + * Copyright (c) 2008 Nissin Systems Co., Ltd., Yoshio Kashiwagi + * Copyright (c) 2005-2008 DLA Systems, David H. Lynch Jr. + * Copyright (c) 2008-2009 Secret Lab Technologies Ltd. + * Copyright (c) 2010 Xilinx, Inc. All rights reserved. + * Copyright (c) 2012 Daniel Borkmann, + * Copyright (c) 2012 Ariane Keller, + * + * This is a driver for the Xilinx Axi Ethernet which is used in the Virtex6 + * and Spartan6. + * + * TODO: + * - Add Axi Fifo support. + * - Factor out Axi DMA code into separate driver. + * - Test and fix basic multicast filtering. + * - Add support for extended multicast filtering. + * - Test basic VLAN support. + * - Add support for extended VLAN support. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xilinx_axienet.h" + +/* Descriptors defines for Tx and Rx DMA - 2^n for the best performance */ +#define TX_BD_NUM 64 +#define RX_BD_NUM 128 + +/* Must be shorter than length of ethtool_drvinfo.driver field to fit */ +#define DRIVER_NAME "xaxienet" +#define DRIVER_DESCRIPTION "Xilinx Axi Ethernet driver" +#define DRIVER_VERSION "1.00a" + +#define AXIENET_REGS_N 32 + +/* Match table for of_platform binding */ +static struct of_device_id axienet_of_match[] __devinitdata = { + { .compatible = "xlnx,axi-ethernet-1.00.a", }, + { .compatible = "xlnx,axi-ethernet-1.01.a", }, + { .compatible = "xlnx,axi-ethernet-2.01.a", }, + {}, +}; + +MODULE_DEVICE_TABLE(of, axienet_of_match); + +/* Option table for setting up Axi Ethernet hardware options */ +static struct axienet_option axienet_options[] = { + /* Turn on jumbo packet support for both Rx and Tx */ + { + .opt = XAE_OPTION_JUMBO, + .reg = XAE_TC_OFFSET, + .m_or = XAE_TC_JUM_MASK, + }, { + .opt = XAE_OPTION_JUMBO, + .reg = XAE_RCW1_OFFSET, + .m_or = XAE_RCW1_JUM_MASK, + }, { /* Turn on VLAN packet support for both Rx and Tx */ + .opt = XAE_OPTION_VLAN, + .reg = XAE_TC_OFFSET, + .m_or = XAE_TC_VLAN_MASK, + }, { + .opt = XAE_OPTION_VLAN, + .reg = XAE_RCW1_OFFSET, + .m_or = XAE_RCW1_VLAN_MASK, + }, { /* Turn on FCS stripping on receive packets */ + .opt = XAE_OPTION_FCS_STRIP, + .reg = XAE_RCW1_OFFSET, + .m_or = XAE_RCW1_FCS_MASK, + }, { /* Turn on FCS insertion on transmit packets */ + .opt = XAE_OPTION_FCS_INSERT, + .reg = XAE_TC_OFFSET, + .m_or = XAE_TC_FCS_MASK, + }, { /* Turn off length/type field checking on receive packets */ + .opt = XAE_OPTION_LENTYPE_ERR, + .reg = XAE_RCW1_OFFSET, + .m_or = XAE_RCW1_LT_DIS_MASK, + }, { /* Turn on Rx flow control */ + .opt = XAE_OPTION_FLOW_CONTROL, + .reg = XAE_FCC_OFFSET, + .m_or = XAE_FCC_FCRX_MASK, + }, { /* Turn on Tx flow control */ + .opt = XAE_OPTION_FLOW_CONTROL, + .reg = XAE_FCC_OFFSET, + .m_or = XAE_FCC_FCTX_MASK, + }, { /* Turn on promiscuous frame filtering */ + .opt = XAE_OPTION_PROMISC, + .reg = XAE_FMI_OFFSET, + .m_or = XAE_FMI_PM_MASK, + }, { /* Enable transmitter */ + .opt = XAE_OPTION_TXEN, + .reg = XAE_TC_OFFSET, + .m_or = XAE_TC_TX_MASK, + }, { /* Enable receiver */ + .opt = XAE_OPTION_RXEN, + .reg = XAE_RCW1_OFFSET, + .m_or = XAE_RCW1_RX_MASK, + }, + {} +}; + +/** + * axienet_dma_in32 - Memory mapped Axi DMA register read + * @lp: Pointer to axienet local structure + * @reg: Address offset from the base address of the Axi DMA core + * + * returns: The contents of the Axi DMA register + * + * This function returns the contents of the corresponding Axi DMA register. + */ +static inline u32 axienet_dma_in32(struct axienet_local *lp, off_t reg) +{ + return in_be32(lp->dma_regs + reg); +} + +/** + * axienet_dma_out32 - Memory mapped Axi DMA register write. + * @lp: Pointer to axienet local structure + * @reg: Address offset from the base address of the Axi DMA core + * @value: Value to be written into the Axi DMA register + * + * This function writes the desired value into the corresponding Axi DMA + * register. + */ +static inline void axienet_dma_out32(struct axienet_local *lp, + off_t reg, u32 value) +{ + out_be32((lp->dma_regs + reg), value); +} + +/** + * axienet_dma_bd_release - Release buffer descriptor rings + * @ndev: Pointer to the net_device structure + * + * This function is used to release the descriptors allocated in + * axienet_dma_bd_init. axienet_dma_bd_release is called when Axi Ethernet + * driver stop api is called. + */ +static void axienet_dma_bd_release(struct net_device *ndev) +{ + int i; + struct axienet_local *lp = netdev_priv(ndev); + + for (i = 0; i < RX_BD_NUM; i++) { + dma_unmap_single(ndev->dev.parent, lp->rx_bd_v[i].phys, + lp->max_frm_size, DMA_FROM_DEVICE); + dev_kfree_skb((struct sk_buff *) + (lp->rx_bd_v[i].sw_id_offset)); + } + + if (lp->rx_bd_v) { + dma_free_coherent(ndev->dev.parent, + sizeof(*lp->rx_bd_v) * RX_BD_NUM, + lp->rx_bd_v, + lp->rx_bd_p); + } + if (lp->tx_bd_v) { + dma_free_coherent(ndev->dev.parent, + sizeof(*lp->tx_bd_v) * TX_BD_NUM, + lp->tx_bd_v, + lp->tx_bd_p); + } +} + +/** + * axienet_dma_bd_init - Setup buffer descriptor rings for Axi DMA + * @ndev: Pointer to the net_device structure + * + * returns: 0, on success + * -ENOMEM, on failure + * + * This function is called to initialize the Rx and Tx DMA descriptor + * rings. This initializes the descriptors with required default values + * and is called when Axi Ethernet driver reset is called. + */ +static int axienet_dma_bd_init(struct net_device *ndev) +{ + u32 cr; + int i; + struct sk_buff *skb; + struct axienet_local *lp = netdev_priv(ndev); + + /* Reset the indexes which are used for accessing the BDs */ + lp->tx_bd_ci = 0; + lp->tx_bd_tail = 0; + lp->rx_bd_ci = 0; + + /* + * Allocate the Tx and Rx buffer descriptors. + */ + lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent, + sizeof(*lp->tx_bd_v) * TX_BD_NUM, + &lp->tx_bd_p, + GFP_KERNEL); + if (!lp->tx_bd_v) { + dev_err(&ndev->dev, "unable to allocate DMA Tx buffer " + "descriptors"); + goto out; + } + + lp->rx_bd_v = dma_alloc_coherent(ndev->dev.parent, + sizeof(*lp->rx_bd_v) * RX_BD_NUM, + &lp->rx_bd_p, + GFP_KERNEL); + if (!lp->rx_bd_v) { + dev_err(&ndev->dev, "unable to allocate DMA Rx buffer " + "descriptors"); + goto out; + } + + memset(lp->tx_bd_v, 0, sizeof(*lp->tx_bd_v) * TX_BD_NUM); + for (i = 0; i < TX_BD_NUM; i++) { + lp->tx_bd_v[i].next = lp->tx_bd_p + + sizeof(*lp->tx_bd_v) * + ((i + 1) % TX_BD_NUM); + } + + memset(lp->rx_bd_v, 0, sizeof(*lp->rx_bd_v) * RX_BD_NUM); + for (i = 0; i < RX_BD_NUM; i++) { + lp->rx_bd_v[i].next = lp->rx_bd_p + + sizeof(*lp->rx_bd_v) * + ((i + 1) % RX_BD_NUM); + + skb = netdev_alloc_skb_ip_align(ndev, lp->max_frm_size); + if (!skb) { + dev_err(&ndev->dev, "alloc_skb error %d\n", i); + goto out; + } + + lp->rx_bd_v[i].sw_id_offset = (u32) skb; + lp->rx_bd_v[i].phys = dma_map_single(ndev->dev.parent, + skb->data, + lp->max_frm_size, + DMA_FROM_DEVICE); + lp->rx_bd_v[i].cntrl = lp->max_frm_size; + } + + /* Start updating the Rx channel control register */ + cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET); + /* Update the interrupt coalesce count */ + cr = ((cr & ~XAXIDMA_COALESCE_MASK) | + ((lp->coalesce_count_rx) << XAXIDMA_COALESCE_SHIFT)); + /* Update the delay timer count */ + cr = ((cr & ~XAXIDMA_DELAY_MASK) | + (XAXIDMA_DFT_RX_WAITBOUND << XAXIDMA_DELAY_SHIFT)); + /* Enable coalesce, delay timer and error interrupts */ + cr |= XAXIDMA_IRQ_ALL_MASK; + /* Write to the Rx channel control register */ + axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr); + + /* Start updating the Tx channel control register */ + cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET); + /* Update the interrupt coalesce count */ + cr = (((cr & ~XAXIDMA_COALESCE_MASK)) | + ((lp->coalesce_count_tx) << XAXIDMA_COALESCE_SHIFT)); + /* Update the delay timer count */ + cr = (((cr & ~XAXIDMA_DELAY_MASK)) | + (XAXIDMA_DFT_TX_WAITBOUND << XAXIDMA_DELAY_SHIFT)); + /* Enable coalesce, delay timer and error interrupts */ + cr |= XAXIDMA_IRQ_ALL_MASK; + /* Write to the Tx channel control register */ + axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, cr); + + /* Populate the tail pointer and bring the Rx Axi DMA engine out of + * halted state. This will make the Rx side ready for reception.*/ + axienet_dma_out32(lp, XAXIDMA_RX_CDESC_OFFSET, lp->rx_bd_p); + cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET); + axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, + cr | XAXIDMA_CR_RUNSTOP_MASK); + axienet_dma_out32(lp, XAXIDMA_RX_TDESC_OFFSET, lp->rx_bd_p + + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1))); + + /* Write to the RS (Run-stop) bit in the Tx channel control register. + * Tx channel is now ready to run. But only after we write to the + * tail pointer register that the Tx channel will start transmitting */ + axienet_dma_out32(lp, XAXIDMA_TX_CDESC_OFFSET, lp->tx_bd_p); + cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET); + axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, + cr | XAXIDMA_CR_RUNSTOP_MASK); + + return 0; +out: + axienet_dma_bd_release(ndev); + return -ENOMEM; +} + +/** + * axienet_set_mac_address - Write the MAC address + * @ndev: Pointer to the net_device structure + * @address: 6 byte Address to be written as MAC address + * + * This function is called to initialize the MAC address of the Axi Ethernet + * core. It writes to the UAW0 and UAW1 registers of the core. + */ +static void axienet_set_mac_address(struct net_device *ndev, void *address) +{ + struct axienet_local *lp = netdev_priv(ndev); + + if (address) + memcpy(ndev->dev_addr, address, ETH_ALEN); + if (!is_valid_ether_addr(ndev->dev_addr)) + random_ether_addr(ndev->dev_addr); + + /* Set up unicast MAC address filter set its mac address */ + axienet_iow(lp, XAE_UAW0_OFFSET, + (ndev->dev_addr[0]) | + (ndev->dev_addr[1] << 8) | + (ndev->dev_addr[2] << 16) | + (ndev->dev_addr[3] << 24)); + axienet_iow(lp, XAE_UAW1_OFFSET, + (((axienet_ior(lp, XAE_UAW1_OFFSET)) & + ~XAE_UAW1_UNICASTADDR_MASK) | + (ndev->dev_addr[4] | + (ndev->dev_addr[5] << 8)))); +} + +/** + * netdev_set_mac_address - Write the MAC address (from outside the driver) + * @ndev: Pointer to the net_device structure + * @p: 6 byte Address to be written as MAC address + * + * returns: 0 for all conditions. Presently, there is no failure case. + * + * This function is called to initialize the MAC address of the Axi Ethernet + * core. It calls the core specific axienet_set_mac_address. This is the + * function that goes into net_device_ops structure entry ndo_set_mac_address. + */ +static int netdev_set_mac_address(struct net_device *ndev, void *p) +{ + struct sockaddr *addr = p; + axienet_set_mac_address(ndev, addr->sa_data); + return 0; +} + +/** + * axienet_set_multicast_list - Prepare the multicast table + * @ndev: Pointer to the net_device structure + * + * This function is called to initialize the multicast table during + * initialization. The Axi Ethernet basic multicast support has a four-entry + * multicast table which is initialized here. Additionally this function + * goes into the net_device_ops structure entry ndo_set_multicast_list. This + * means whenever the multicast table entries need to be updated this + * function gets called. + */ +static void axienet_set_multicast_list(struct net_device *ndev) +{ + int i; + u32 reg, af0reg, af1reg; + struct axienet_local *lp = netdev_priv(ndev); + + if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC) || + netdev_mc_count(ndev) > XAE_MULTICAST_CAM_TABLE_NUM) { + /* We must make the kernel realize we had to move into + * promiscuous mode. If it was a promiscuous mode request + * the flag is already set. If not we set it. */ + ndev->flags |= IFF_PROMISC; + reg = axienet_ior(lp, XAE_FMI_OFFSET); + reg |= XAE_FMI_PM_MASK; + axienet_iow(lp, XAE_FMI_OFFSET, reg); + dev_info(&ndev->dev, "Promiscuous mode enabled.\n"); + } else if (!netdev_mc_empty(ndev)) { + struct netdev_hw_addr *ha; + + i = 0; + netdev_for_each_mc_addr(ha, ndev) { + if (i >= XAE_MULTICAST_CAM_TABLE_NUM) + break; + + af0reg = (ha->addr[0]); + af0reg |= (ha->addr[1] << 8); + af0reg |= (ha->addr[2] << 16); + af0reg |= (ha->addr[3] << 24); + + af1reg = (ha->addr[4]); + af1reg |= (ha->addr[5] << 8); + + reg = axienet_ior(lp, XAE_FMI_OFFSET) & 0xFFFFFF00; + reg |= i; + + axienet_iow(lp, XAE_FMI_OFFSET, reg); + axienet_iow(lp, XAE_AF0_OFFSET, af0reg); + axienet_iow(lp, XAE_AF1_OFFSET, af1reg); + i++; + } + } else { + reg = axienet_ior(lp, XAE_FMI_OFFSET); + reg &= ~XAE_FMI_PM_MASK; + + axienet_iow(lp, XAE_FMI_OFFSET, reg); + + for (i = 0; i < XAE_MULTICAST_CAM_TABLE_NUM; i++) { + reg = axienet_ior(lp, XAE_FMI_OFFSET) & 0xFFFFFF00; + reg |= i; + + axienet_iow(lp, XAE_FMI_OFFSET, reg); + axienet_iow(lp, XAE_AF0_OFFSET, 0); + axienet_iow(lp, XAE_AF1_OFFSET, 0); + } + + dev_info(&ndev->dev, "Promiscuous mode disabled.\n"); + } +} + +/** + * axienet_setoptions - Set an Axi Ethernet option + * @ndev: Pointer to the net_device structure + * @options: Option to be enabled/disabled + * + * The Axi Ethernet core has multiple features which can be selectively turned + * on or off. The typical options could be jumbo frame option, basic VLAN + * option, promiscuous mode option etc. This function is used to set or clear + * these options in the Axi Ethernet hardware. This is done through + * axienet_option structure . + */ +static void axienet_setoptions(struct net_device *ndev, u32 options) +{ + int reg; + struct axienet_local *lp = netdev_priv(ndev); + struct axienet_option *tp = &axienet_options[0]; + + while (tp->opt) { + reg = ((axienet_ior(lp, tp->reg)) & ~(tp->m_or)); + if (options & tp->opt) + reg |= tp->m_or; + axienet_iow(lp, tp->reg, reg); + tp++; + } + + lp->options |= options; +} + +static void __axienet_device_reset(struct axienet_local *lp, + struct device *dev, off_t offset) +{ + u32 timeout; + /* Reset Axi DMA. This would reset Axi Ethernet core as well. The reset + * process of Axi DMA takes a while to complete as all pending + * commands/transfers will be flushed or completed during this + * reset process. */ + axienet_dma_out32(lp, offset, XAXIDMA_CR_RESET_MASK); + timeout = DELAY_OF_ONE_MILLISEC; + while (axienet_dma_in32(lp, offset) & XAXIDMA_CR_RESET_MASK) { + udelay(1); + if (--timeout == 0) { + dev_err(dev, "axienet_device_reset DMA " + "reset timeout!\n"); + break; + } + } +} + +/** + * axienet_device_reset - Reset and initialize the Axi Ethernet hardware. + * @ndev: Pointer to the net_device structure + * + * This function is called to reset and initialize the Axi Ethernet core. This + * is typically called during initialization. It does a reset of the Axi DMA + * Rx/Tx channels and initializes the Axi DMA BDs. Since Axi DMA reset lines + * areconnected to Axi Ethernet reset lines, this in turn resets the Axi + * Ethernet core. No separate hardware reset is done for the Axi Ethernet + * core. + */ +static void axienet_device_reset(struct net_device *ndev) +{ + u32 axienet_status; + struct axienet_local *lp = netdev_priv(ndev); + + __axienet_device_reset(lp, &ndev->dev, XAXIDMA_TX_CR_OFFSET); + __axienet_device_reset(lp, &ndev->dev, XAXIDMA_RX_CR_OFFSET); + + lp->max_frm_size = XAE_MAX_VLAN_FRAME_SIZE; + lp->options &= (~XAE_OPTION_JUMBO); + + if ((ndev->mtu > XAE_MTU) && + (ndev->mtu <= XAE_JUMBO_MTU) && + (lp->jumbo_support)) { + lp->max_frm_size = ndev->mtu + XAE_HDR_VLAN_SIZE + + XAE_TRL_SIZE; + lp->options |= XAE_OPTION_JUMBO; + } + + if (axienet_dma_bd_init(ndev)) { + dev_err(&ndev->dev, "axienet_device_reset descriptor " + "allocation failed\n"); + } + + axienet_status = axienet_ior(lp, XAE_RCW1_OFFSET); + axienet_status &= ~XAE_RCW1_RX_MASK; + axienet_iow(lp, XAE_RCW1_OFFSET, axienet_status); + + axienet_status = axienet_ior(lp, XAE_IP_OFFSET); + if (axienet_status & XAE_INT_RXRJECT_MASK) + axienet_iow(lp, XAE_IS_OFFSET, XAE_INT_RXRJECT_MASK); + + axienet_iow(lp, XAE_FCC_OFFSET, XAE_FCC_FCRX_MASK); + + /* Sync default options with HW but leave receiver and + * transmitter disabled.*/ + axienet_setoptions(ndev, lp->options & + ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN)); + axienet_set_mac_address(ndev, NULL); + axienet_set_multicast_list(ndev); + axienet_setoptions(ndev, lp->options); + + ndev->trans_start = jiffies; +} + +/** + * axienet_adjust_link - Adjust the PHY link speed/duplex. + * @ndev: Pointer to the net_device structure + * + * This function is called to change the speed and duplex setting after + * auto negotiation is done by the PHY. This is the function that gets + * registered with the PHY interface through the "of_phy_connect" call. + */ +static void axienet_adjust_link(struct net_device *ndev) +{ + u32 emmc_reg; + u32 link_state; + u32 setspeed = 1; + struct axienet_local *lp = netdev_priv(ndev); + struct phy_device *phy = lp->phy_dev; + + link_state = phy->speed | (phy->duplex << 1) | phy->link; + if (lp->last_link != link_state) { + if ((phy->speed == SPEED_10) || (phy->speed == SPEED_100)) { + if (lp->phy_type == XAE_PHY_TYPE_1000BASE_X) + setspeed = 0; + } else { + if ((phy->speed == SPEED_1000) && + (lp->phy_type == XAE_PHY_TYPE_MII)) + setspeed = 0; + } + + if (setspeed == 1) { + emmc_reg = axienet_ior(lp, XAE_EMMC_OFFSET); + emmc_reg &= ~XAE_EMMC_LINKSPEED_MASK; + + switch (phy->speed) { + case SPEED_1000: + emmc_reg |= XAE_EMMC_LINKSPD_1000; + break; + case SPEED_100: + emmc_reg |= XAE_EMMC_LINKSPD_100; + break; + case SPEED_10: + emmc_reg |= XAE_EMMC_LINKSPD_10; + break; + default: + dev_err(&ndev->dev, "Speed other than 10, 100 " + "or 1Gbps is not supported\n"); + break; + } + + axienet_iow(lp, XAE_EMMC_OFFSET, emmc_reg); + lp->last_link = link_state; + phy_print_status(phy); + } else { + dev_err(&ndev->dev, "Error setting Axi Ethernet " + "mac speed\n"); + } + } +} + +/** + * axienet_start_xmit_done - Invoked once a transmit is completed by the + * Axi DMA Tx channel. + * @ndev: Pointer to the net_device structure + * + * This function is invoked from the Axi DMA Tx isr to notify the completion + * of transmit operation. It clears fields in the corresponding Tx BDs and + * unmaps the corresponding buffer so that CPU can regain ownership of the + * buffer. It finally invokes "netif_wake_queue" to restart transmission if + * required. + */ +static void axienet_start_xmit_done(struct net_device *ndev) +{ + u32 size = 0; + u32 packets = 0; + struct axienet_local *lp = netdev_priv(ndev); + struct axidma_bd *cur_p; + unsigned int status = 0; + + cur_p = &lp->tx_bd_v[lp->tx_bd_ci]; + status = cur_p->status; + while (status & XAXIDMA_BD_STS_COMPLETE_MASK) { + dma_unmap_single(ndev->dev.parent, cur_p->phys, + (cur_p->cntrl & XAXIDMA_BD_CTRL_LENGTH_MASK), + DMA_TO_DEVICE); + if (cur_p->app4) + dev_kfree_skb_irq((struct sk_buff *)cur_p->app4); + /*cur_p->phys = 0;*/ + cur_p->app0 = 0; + cur_p->app1 = 0; + cur_p->app2 = 0; + cur_p->app4 = 0; + cur_p->status = 0; + + size += status & XAXIDMA_BD_STS_ACTUAL_LEN_MASK; + packets++; + + lp->tx_bd_ci = ++lp->tx_bd_ci % TX_BD_NUM; + cur_p = &lp->tx_bd_v[lp->tx_bd_ci]; + status = cur_p->status; + } + + ndev->stats.tx_packets += packets; + ndev->stats.tx_bytes += size; + netif_wake_queue(ndev); +} + +/** + * axienet_check_tx_bd_space - Checks if a BD/group of BDs are currently busy + * @lp: Pointer to the axienet_local structure + * @num_frag: The number of BDs to check for + * + * returns: 0, on success + * NETDEV_TX_BUSY, if any of the descriptors are not free + * + * This function is invoked before BDs are allocated and transmission starts. + * This function returns 0 if a BD or group of BDs can be allocated for + * transmission. If the BD or any of the BDs are not free the function + * returns a busy status. This is invoked from axienet_start_xmit. + */ +static inline int axienet_check_tx_bd_space(struct axienet_local *lp, + int num_frag) +{ + struct axidma_bd *cur_p; + cur_p = &lp->tx_bd_v[(lp->tx_bd_tail + num_frag) % TX_BD_NUM]; + if (cur_p->status & XAXIDMA_BD_STS_ALL_MASK) + return NETDEV_TX_BUSY; + return 0; +} + +/** + * axienet_start_xmit - Starts the transmission. + * @skb: sk_buff pointer that contains data to be Txed. + * @ndev: Pointer to net_device structure. + * + * returns: NETDEV_TX_OK, on success + * NETDEV_TX_BUSY, if any of the descriptors are not free + * + * This function is invoked from upper layers to initiate transmission. The + * function uses the next available free BDs and populates their fields to + * start the transmission. Additionally if checksum offloading is supported, + * it populates AXI Stream Control fields with appropriate values. + */ +static int axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev) +{ + u32 ii; + u32 num_frag; + u32 csum_start_off; + u32 csum_index_off; + skb_frag_t *frag; + dma_addr_t tail_p; + struct axienet_local *lp = netdev_priv(ndev); + struct axidma_bd *cur_p; + + num_frag = skb_shinfo(skb)->nr_frags; + cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; + + if (axienet_check_tx_bd_space(lp, num_frag)) { + if (!netif_queue_stopped(ndev)) + netif_stop_queue(ndev); + return NETDEV_TX_BUSY; + } + + if (skb->ip_summed == CHECKSUM_PARTIAL) { + if (lp->features & XAE_FEATURE_FULL_TX_CSUM) { + /* Tx Full Checksum Offload Enabled */ + cur_p->app0 |= 2; + } else if (lp->features & XAE_FEATURE_PARTIAL_RX_CSUM) { + csum_start_off = skb_transport_offset(skb); + csum_index_off = csum_start_off + skb->csum_offset; + /* Tx Partial Checksum Offload Enabled */ + cur_p->app0 |= 1; + cur_p->app1 = (csum_start_off << 16) | csum_index_off; + } + } else if (skb->ip_summed == CHECKSUM_UNNECESSARY) { + cur_p->app0 |= 2; /* Tx Full Checksum Offload Enabled */ + } + + cur_p->cntrl = skb_headlen(skb) | XAXIDMA_BD_CTRL_TXSOF_MASK; + cur_p->phys = dma_map_single(ndev->dev.parent, skb->data, + skb_headlen(skb), DMA_TO_DEVICE); + + for (ii = 0; ii < num_frag; ii++) { + lp->tx_bd_tail = ++lp->tx_bd_tail % TX_BD_NUM; + cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; + frag = &skb_shinfo(skb)->frags[ii]; + cur_p->phys = dma_map_single(ndev->dev.parent, + skb_frag_address(frag), + skb_frag_size(frag), + DMA_TO_DEVICE); + cur_p->cntrl = skb_frag_size(frag); + } + + cur_p->cntrl |= XAXIDMA_BD_CTRL_TXEOF_MASK; + cur_p->app4 = (unsigned long)skb; + + tail_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail; + /* Start the transfer */ + axienet_dma_out32(lp, XAXIDMA_TX_TDESC_OFFSET, tail_p); + lp->tx_bd_tail = ++lp->tx_bd_tail % TX_BD_NUM; + + return NETDEV_TX_OK; +} + +/** + * axienet_recv - Is called from Axi DMA Rx Isr to complete the received + * BD processing. + * @ndev: Pointer to net_device structure. + * + * This function is invoked from the Axi DMA Rx isr to process the Rx BDs. It + * does minimal processing and invokes "netif_rx" to complete further + * processing. + */ +static void axienet_recv(struct net_device *ndev) +{ + u32 length; + u32 csumstatus; + u32 size = 0; + u32 packets = 0; + dma_addr_t tail_p; + struct axienet_local *lp = netdev_priv(ndev); + struct sk_buff *skb, *new_skb; + struct axidma_bd *cur_p; + + tail_p = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_ci; + cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; + + while ((cur_p->status & XAXIDMA_BD_STS_COMPLETE_MASK)) { + skb = (struct sk_buff *) (cur_p->sw_id_offset); + length = cur_p->app4 & 0x0000FFFF; + + dma_unmap_single(ndev->dev.parent, cur_p->phys, + lp->max_frm_size, + DMA_FROM_DEVICE); + + skb_put(skb, length); + skb->protocol = eth_type_trans(skb, ndev); + /*skb_checksum_none_assert(skb);*/ + skb->ip_summed = CHECKSUM_NONE; + + /* if we're doing Rx csum offload, set it up */ + if (lp->features & XAE_FEATURE_FULL_RX_CSUM) { + csumstatus = (cur_p->app2 & + XAE_FULL_CSUM_STATUS_MASK) >> 3; + if ((csumstatus == XAE_IP_TCP_CSUM_VALIDATED) || + (csumstatus == XAE_IP_UDP_CSUM_VALIDATED)) { + skb->ip_summed = CHECKSUM_UNNECESSARY; + } + } else if ((lp->features & XAE_FEATURE_PARTIAL_RX_CSUM) != 0 && + skb->protocol == __constant_htons(ETH_P_IP) && + skb->len > 64) { + skb->csum = be32_to_cpu(cur_p->app3 & 0xFFFF); + skb->ip_summed = CHECKSUM_COMPLETE; + } + + netif_rx(skb); + + size += length; + packets++; + + new_skb = netdev_alloc_skb_ip_align(ndev, lp->max_frm_size); + if (!new_skb) { + dev_err(&ndev->dev, "no memory for new sk_buff\n"); + return; + } + cur_p->phys = dma_map_single(ndev->dev.parent, new_skb->data, + lp->max_frm_size, + DMA_FROM_DEVICE); + cur_p->cntrl = lp->max_frm_size; + cur_p->status = 0; + cur_p->sw_id_offset = (u32) new_skb; + + lp->rx_bd_ci = ++lp->rx_bd_ci % RX_BD_NUM; + cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; + } + + ndev->stats.rx_packets += packets; + ndev->stats.rx_bytes += size; + + axienet_dma_out32(lp, XAXIDMA_RX_TDESC_OFFSET, tail_p); +} + +/** + * axienet_tx_irq - Tx Done Isr. + * @irq: irq number + * @_ndev: net_device pointer + * + * returns: IRQ_HANDLED for all cases. + * + * This is the Axi DMA Tx done Isr. It invokes "axienet_start_xmit_done" + * to complete the BD processing. + */ +static irqreturn_t axienet_tx_irq(int irq, void *_ndev) +{ + u32 cr; + unsigned int status; + struct net_device *ndev = _ndev; + struct axienet_local *lp = netdev_priv(ndev); + + status = axienet_dma_in32(lp, XAXIDMA_TX_SR_OFFSET); + if (status & (XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_DELAY_MASK)) { + axienet_start_xmit_done(lp->ndev); + goto out; + } + if (!(status & XAXIDMA_IRQ_ALL_MASK)) + dev_err(&ndev->dev, "No interrupts asserted in Tx path"); + if (status & XAXIDMA_IRQ_ERROR_MASK) { + dev_err(&ndev->dev, "DMA Tx error 0x%x\n", status); + dev_err(&ndev->dev, "Current BD is at: 0x%x\n", + (lp->tx_bd_v[lp->tx_bd_ci]).phys); + + cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET); + /* Disable coalesce, delay timer and error interrupts */ + cr &= (~XAXIDMA_IRQ_ALL_MASK); + /* Write to the Tx channel control register */ + axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, cr); + + cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET); + /* Disable coalesce, delay timer and error interrupts */ + cr &= (~XAXIDMA_IRQ_ALL_MASK); + /* Write to the Rx channel control register */ + axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr); + + tasklet_schedule(&lp->dma_err_tasklet); + } +out: + axienet_dma_out32(lp, XAXIDMA_TX_SR_OFFSET, status); + return IRQ_HANDLED; +} + +/** + * axienet_rx_irq - Rx Isr. + * @irq: irq number + * @_ndev: net_device pointer + * + * returns: IRQ_HANDLED for all cases. + * + * This is the Axi DMA Rx Isr. It invokes "axienet_recv" to complete the BD + * processing. + */ +static irqreturn_t axienet_rx_irq(int irq, void *_ndev) +{ + u32 cr; + unsigned int status; + struct net_device *ndev = _ndev; + struct axienet_local *lp = netdev_priv(ndev); + + status = axienet_dma_in32(lp, XAXIDMA_RX_SR_OFFSET); + if (status & (XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_DELAY_MASK)) { + axienet_recv(lp->ndev); + goto out; + } + if (!(status & XAXIDMA_IRQ_ALL_MASK)) + dev_err(&ndev->dev, "No interrupts asserted in Rx path"); + if (status & XAXIDMA_IRQ_ERROR_MASK) { + dev_err(&ndev->dev, "DMA Rx error 0x%x\n", status); + dev_err(&ndev->dev, "Current BD is at: 0x%x\n", + (lp->rx_bd_v[lp->rx_bd_ci]).phys); + + cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET); + /* Disable coalesce, delay timer and error interrupts */ + cr &= (~XAXIDMA_IRQ_ALL_MASK); + /* Finally write to the Tx channel control register */ + axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, cr); + + cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET); + /* Disable coalesce, delay timer and error interrupts */ + cr &= (~XAXIDMA_IRQ_ALL_MASK); + /* write to the Rx channel control register */ + axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr); + + tasklet_schedule(&lp->dma_err_tasklet); + } +out: + axienet_dma_out32(lp, XAXIDMA_RX_SR_OFFSET, status); + return IRQ_HANDLED; +} + +/** + * axienet_open - Driver open routine. + * @ndev: Pointer to net_device structure + * + * returns: 0, on success. + * -ENODEV, if PHY cannot be connected to + * non-zero error value on failure + * + * This is the driver open routine. It calls phy_start to start the PHY device. + * It also allocates interrupt service routines, enables the interrupt lines + * and ISR handling. Axi Ethernet core is reset through Axi DMA core. Buffer + * descriptors are initialized. + */ +static int axienet_open(struct net_device *ndev) +{ + int ret, mdio_mcreg; + struct axienet_local *lp = netdev_priv(ndev); + + dev_dbg(&ndev->dev, "axienet_open()\n"); + + mdio_mcreg = axienet_ior(lp, XAE_MDIO_MC_OFFSET); + ret = axienet_mdio_wait_until_ready(lp); + if (ret < 0) + return ret; + /* Disable the MDIO interface till Axi Ethernet Reset is completed. + * When we do an Axi Ethernet reset, it resets the complete core + * including the MDIO. If MDIO is not disabled when the reset + * process is started, MDIO will be broken afterwards. */ + axienet_iow(lp, XAE_MDIO_MC_OFFSET, + (mdio_mcreg & (~XAE_MDIO_MC_MDIOEN_MASK))); + axienet_device_reset(ndev); + /* Enable the MDIO */ + axienet_iow(lp, XAE_MDIO_MC_OFFSET, mdio_mcreg); + ret = axienet_mdio_wait_until_ready(lp); + if (ret < 0) + return ret; + + if (lp->phy_node) { + lp->phy_dev = of_phy_connect(lp->ndev, lp->phy_node, + axienet_adjust_link, 0, + PHY_INTERFACE_MODE_GMII); + if (!lp->phy_dev) { + dev_err(lp->dev, "of_phy_connect() failed\n"); + return -ENODEV; + } + phy_start(lp->phy_dev); + } + + /* Enable interrupts for Axi DMA Tx */ + ret = request_irq(lp->tx_irq, axienet_tx_irq, 0, ndev->name, ndev); + if (ret) + goto err_tx_irq; + /* Enable interrupts for Axi DMA Rx */ + ret = request_irq(lp->rx_irq, axienet_rx_irq, 0, ndev->name, ndev); + if (ret) + goto err_rx_irq; + /* Enable tasklets for Axi DMA error handling */ + tasklet_enable(&lp->dma_err_tasklet); + return 0; + +err_rx_irq: + free_irq(lp->tx_irq, ndev); +err_tx_irq: + if (lp->phy_dev) + phy_disconnect(lp->phy_dev); + lp->phy_dev = NULL; + dev_err(lp->dev, "request_irq() failed\n"); + return ret; +} + +/** + * axienet_stop - Driver stop routine. + * @ndev: Pointer to net_device structure + * + * returns: 0, on success. + * + * This is the driver stop routine. It calls phy_disconnect to stop the PHY + * device. It also removes the interrupt handlers and disables the interrupts. + * The Axi DMA Tx/Rx BDs are released. + */ +static int axienet_stop(struct net_device *ndev) +{ + u32 cr; + struct axienet_local *lp = netdev_priv(ndev); + + dev_dbg(&ndev->dev, "axienet_close()\n"); + + cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET); + axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, + cr & (~XAXIDMA_CR_RUNSTOP_MASK)); + cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET); + axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, + cr & (~XAXIDMA_CR_RUNSTOP_MASK)); + axienet_setoptions(ndev, lp->options & + ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN)); + + tasklet_disable(&lp->dma_err_tasklet); + + free_irq(lp->tx_irq, ndev); + free_irq(lp->rx_irq, ndev); + + if (lp->phy_dev) + phy_disconnect(lp->phy_dev); + lp->phy_dev = NULL; + + axienet_dma_bd_release(ndev); + return 0; +} + +/** + * axienet_change_mtu - Driver change mtu routine. + * @ndev: Pointer to net_device structure + * @new_mtu: New mtu value to be applied + * + * returns: Always returns 0 (success). + * + * This is the change mtu driver routine. It checks if the Axi Ethernet + * hardware supports jumbo frames before changing the mtu. This can be + * called only when the device is not up. + */ +static int axienet_change_mtu(struct net_device *ndev, int new_mtu) +{ + struct axienet_local *lp = netdev_priv(ndev); + + if (netif_running(ndev)) + return -EBUSY; + if (lp->jumbo_support) { + if ((new_mtu > XAE_JUMBO_MTU) || (new_mtu < 64)) + return -EINVAL; + ndev->mtu = new_mtu; + } else { + if ((new_mtu > XAE_MTU) || (new_mtu < 64)) + return -EINVAL; + ndev->mtu = new_mtu; + } + + return 0; +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +/** + * axienet_poll_controller - Axi Ethernet poll mechanism. + * @ndev: Pointer to net_device structure + * + * This implements Rx/Tx ISR poll mechanisms. The interrupts are disabled prior + * to polling the ISRs and are enabled back after the polling is done. + */ +static void axienet_poll_controller(struct net_device *ndev) +{ + struct axienet_local *lp = netdev_priv(ndev); + disable_irq(lp->tx_irq); + disable_irq(lp->rx_irq); + axienet_rx_irq(lp->tx_irq, ndev); + axienet_tx_irq(lp->rx_irq, ndev); + enable_irq(lp->tx_irq); + enable_irq(lp->rx_irq); +} +#endif + +static const struct net_device_ops axienet_netdev_ops = { + .ndo_open = axienet_open, + .ndo_stop = axienet_stop, + .ndo_start_xmit = axienet_start_xmit, + .ndo_change_mtu = axienet_change_mtu, + .ndo_set_mac_address = netdev_set_mac_address, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_rx_mode = axienet_set_multicast_list, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = axienet_poll_controller, +#endif +}; + +/** + * axienet_ethtools_get_settings - Get Axi Ethernet settings related to PHY. + * @ndev: Pointer to net_device structure + * @ecmd: Pointer to ethtool_cmd structure + * + * This implements ethtool command for getting PHY settings. If PHY could + * not be found, the function returns -ENODEV. This function calls the + * relevant PHY ethtool API to get the PHY settings. + * Issue "ethtool ethX" under linux prompt to execute this function. + */ +static int axienet_ethtools_get_settings(struct net_device *ndev, + struct ethtool_cmd *ecmd) +{ + struct axienet_local *lp = netdev_priv(ndev); + struct phy_device *phydev = lp->phy_dev; + if (!phydev) + return -ENODEV; + return phy_ethtool_gset(phydev, ecmd); +} + +/** + * axienet_ethtools_set_settings - Set PHY settings as passed in the argument. + * @ndev: Pointer to net_device structure + * @ecmd: Pointer to ethtool_cmd structure + * + * This implements ethtool command for setting various PHY settings. If PHY + * could not be found, the function returns -ENODEV. This function calls the + * relevant PHY ethtool API to set the PHY. + * Issue e.g. "ethtool -s ethX speed 1000" under linux prompt to execute this + * function. + */ +static int axienet_ethtools_set_settings(struct net_device *ndev, + struct ethtool_cmd *ecmd) +{ + struct axienet_local *lp = netdev_priv(ndev); + struct phy_device *phydev = lp->phy_dev; + if (!phydev) + return -ENODEV; + return phy_ethtool_sset(phydev, ecmd); +} + +/** + * axienet_ethtools_get_drvinfo - Get various Axi Ethernet driver information. + * @ndev: Pointer to net_device structure + * @ed: Pointer to ethtool_drvinfo structure + * + * This implements ethtool command for getting the driver information. + * Issue "ethtool -i ethX" under linux prompt to execute this function. + */ +static void axienet_ethtools_get_drvinfo(struct net_device *ndev, + struct ethtool_drvinfo *ed) +{ + memset(ed, 0, sizeof(struct ethtool_drvinfo)); + strcpy(ed->driver, DRIVER_NAME); + strcpy(ed->version, DRIVER_VERSION); + ed->regdump_len = sizeof(u32) * AXIENET_REGS_N; +} + +/** + * axienet_ethtools_get_regs_len - Get the total regs length present in the + * AxiEthernet core. + * @ndev: Pointer to net_device structure + * + * This implements ethtool command for getting the total register length + * information. + */ +static int axienet_ethtools_get_regs_len(struct net_device *ndev) +{ + return sizeof(u32) * AXIENET_REGS_N; +} + +/** + * axienet_ethtools_get_regs - Dump the contents of all registers present + * in AxiEthernet core. + * @ndev: Pointer to net_device structure + * @regs: Pointer to ethtool_regs structure + * @ret: Void pointer used to return the contents of the registers. + * + * This implements ethtool command for getting the Axi Ethernet register dump. + * Issue "ethtool -d ethX" to execute this function. + */ +static void axienet_ethtools_get_regs(struct net_device *ndev, + struct ethtool_regs *regs, void *ret) +{ + u32 *data = (u32 *) ret; + size_t len = sizeof(u32) * AXIENET_REGS_N; + struct axienet_local *lp = netdev_priv(ndev); + + regs->version = 0; + regs->len = len; + + memset(data, 0, len); + data[0] = axienet_ior(lp, XAE_RAF_OFFSET); + data[1] = axienet_ior(lp, XAE_TPF_OFFSET); + data[2] = axienet_ior(lp, XAE_IFGP_OFFSET); + data[3] = axienet_ior(lp, XAE_IS_OFFSET); + data[4] = axienet_ior(lp, XAE_IP_OFFSET); + data[5] = axienet_ior(lp, XAE_IE_OFFSET); + data[6] = axienet_ior(lp, XAE_TTAG_OFFSET); + data[7] = axienet_ior(lp, XAE_RTAG_OFFSET); + data[8] = axienet_ior(lp, XAE_UAWL_OFFSET); + data[9] = axienet_ior(lp, XAE_UAWU_OFFSET); + data[10] = axienet_ior(lp, XAE_TPID0_OFFSET); + data[11] = axienet_ior(lp, XAE_TPID1_OFFSET); + data[12] = axienet_ior(lp, XAE_PPST_OFFSET); + data[13] = axienet_ior(lp, XAE_RCW0_OFFSET); + data[14] = axienet_ior(lp, XAE_RCW1_OFFSET); + data[15] = axienet_ior(lp, XAE_TC_OFFSET); + data[16] = axienet_ior(lp, XAE_FCC_OFFSET); + data[17] = axienet_ior(lp, XAE_EMMC_OFFSET); + data[18] = axienet_ior(lp, XAE_PHYC_OFFSET); + data[19] = axienet_ior(lp, XAE_MDIO_MC_OFFSET); + data[20] = axienet_ior(lp, XAE_MDIO_MCR_OFFSET); + data[21] = axienet_ior(lp, XAE_MDIO_MWD_OFFSET); + data[22] = axienet_ior(lp, XAE_MDIO_MRD_OFFSET); + data[23] = axienet_ior(lp, XAE_MDIO_MIS_OFFSET); + data[24] = axienet_ior(lp, XAE_MDIO_MIP_OFFSET); + data[25] = axienet_ior(lp, XAE_MDIO_MIE_OFFSET); + data[26] = axienet_ior(lp, XAE_MDIO_MIC_OFFSET); + data[27] = axienet_ior(lp, XAE_UAW0_OFFSET); + data[28] = axienet_ior(lp, XAE_UAW1_OFFSET); + data[29] = axienet_ior(lp, XAE_FMI_OFFSET); + data[30] = axienet_ior(lp, XAE_AF0_OFFSET); + data[31] = axienet_ior(lp, XAE_AF1_OFFSET); +} + +/** + * axienet_ethtools_get_pauseparam - Get the pause parameter setting for + * Tx and Rx paths. + * @ndev: Pointer to net_device structure + * @epauseparm: Pointer to ethtool_pauseparam structure. + * + * This implements ethtool command for getting axi ethernet pause frame + * setting. Issue "ethtool -a ethX" to execute this function. + */ +static void +axienet_ethtools_get_pauseparam(struct net_device *ndev, + struct ethtool_pauseparam *epauseparm) +{ + u32 regval; + struct axienet_local *lp = netdev_priv(ndev); + epauseparm->autoneg = 0; + regval = axienet_ior(lp, XAE_FCC_OFFSET); + epauseparm->tx_pause = regval & XAE_FCC_FCTX_MASK; + epauseparm->rx_pause = regval & XAE_FCC_FCRX_MASK; +} + +/** + * axienet_ethtools_set_pauseparam - Set device pause parameter(flow control) + * settings. + * @ndev: Pointer to net_device structure + * @epauseparam:Pointer to ethtool_pauseparam structure + * + * This implements ethtool command for enabling flow control on Rx and Tx + * paths. Issue "ethtool -A ethX tx on|off" under linux prompt to execute this + * function. + */ +static int +axienet_ethtools_set_pauseparam(struct net_device *ndev, + struct ethtool_pauseparam *epauseparm) +{ + u32 regval = 0; + struct axienet_local *lp = netdev_priv(ndev); + + if (netif_running(ndev)) { + printk(KERN_ERR "%s: Please stop netif before applying " + "configruation\n", ndev->name); + return -EFAULT; + } + + regval = axienet_ior(lp, XAE_FCC_OFFSET); + if (epauseparm->tx_pause) + regval |= XAE_FCC_FCTX_MASK; + else + regval &= ~XAE_FCC_FCTX_MASK; + if (epauseparm->rx_pause) + regval |= XAE_FCC_FCRX_MASK; + else + regval &= ~XAE_FCC_FCRX_MASK; + axienet_iow(lp, XAE_FCC_OFFSET, regval); + + return 0; +} + +/** + * axienet_ethtools_get_coalesce - Get DMA interrupt coalescing count. + * @ndev: Pointer to net_device structure + * @ecoalesce: Pointer to ethtool_coalesce structure + * + * This implements ethtool command for getting the DMA interrupt coalescing + * count on Tx and Rx paths. Issue "ethtool -c ethX" under linux prompt to + * execute this function. + */ +static int axienet_ethtools_get_coalesce(struct net_device *ndev, + struct ethtool_coalesce *ecoalesce) +{ + u32 regval = 0; + struct axienet_local *lp = netdev_priv(ndev); + regval = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET); + ecoalesce->rx_max_coalesced_frames = (regval & XAXIDMA_COALESCE_MASK) + >> XAXIDMA_COALESCE_SHIFT; + regval = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET); + ecoalesce->tx_max_coalesced_frames = (regval & XAXIDMA_COALESCE_MASK) + >> XAXIDMA_COALESCE_SHIFT; + return 0; +} + +/** + * axienet_ethtools_set_coalesce - Set DMA interrupt coalescing count. + * @ndev: Pointer to net_device structure + * @ecoalesce: Pointer to ethtool_coalesce structure + * + * This implements ethtool command for setting the DMA interrupt coalescing + * count on Tx and Rx paths. Issue "ethtool -C ethX rx-frames 5" under linux + * prompt to execute this function. + */ +static int axienet_ethtools_set_coalesce(struct net_device *ndev, + struct ethtool_coalesce *ecoalesce) +{ + struct axienet_local *lp = netdev_priv(ndev); + + if (netif_running(ndev)) { + printk(KERN_ERR "%s: Please stop netif before applying " + "configruation\n", ndev->name); + return -EFAULT; + } + + if ((ecoalesce->rx_coalesce_usecs) || + (ecoalesce->rx_coalesce_usecs_irq) || + (ecoalesce->rx_max_coalesced_frames_irq) || + (ecoalesce->tx_coalesce_usecs) || + (ecoalesce->tx_coalesce_usecs_irq) || + (ecoalesce->tx_max_coalesced_frames_irq) || + (ecoalesce->stats_block_coalesce_usecs) || + (ecoalesce->use_adaptive_rx_coalesce) || + (ecoalesce->use_adaptive_tx_coalesce) || + (ecoalesce->pkt_rate_low) || + (ecoalesce->rx_coalesce_usecs_low) || + (ecoalesce->rx_max_coalesced_frames_low) || + (ecoalesce->tx_coalesce_usecs_low) || + (ecoalesce->tx_max_coalesced_frames_low) || + (ecoalesce->pkt_rate_high) || + (ecoalesce->rx_coalesce_usecs_high) || + (ecoalesce->rx_max_coalesced_frames_high) || + (ecoalesce->tx_coalesce_usecs_high) || + (ecoalesce->tx_max_coalesced_frames_high) || + (ecoalesce->rate_sample_interval)) + return -EOPNOTSUPP; + if (ecoalesce->rx_max_coalesced_frames) + lp->coalesce_count_rx = ecoalesce->rx_max_coalesced_frames; + if (ecoalesce->tx_max_coalesced_frames) + lp->coalesce_count_tx = ecoalesce->tx_max_coalesced_frames; + + return 0; +} + +static struct ethtool_ops axienet_ethtool_ops = { + .get_settings = axienet_ethtools_get_settings, + .set_settings = axienet_ethtools_set_settings, + .get_drvinfo = axienet_ethtools_get_drvinfo, + .get_regs_len = axienet_ethtools_get_regs_len, + .get_regs = axienet_ethtools_get_regs, + .get_link = ethtool_op_get_link, + .get_pauseparam = axienet_ethtools_get_pauseparam, + .set_pauseparam = axienet_ethtools_set_pauseparam, + .get_coalesce = axienet_ethtools_get_coalesce, + .set_coalesce = axienet_ethtools_set_coalesce, +}; + +/** + * axienet_dma_err_handler - Tasklet handler for Axi DMA Error + * @data: Data passed + * + * Resets the Axi DMA and Axi Ethernet devices, and reconfigures the + * Tx/Rx BDs. + */ +static void axienet_dma_err_handler(unsigned long data) +{ + u32 axienet_status; + u32 cr, i; + int mdio_mcreg; + struct axienet_local *lp = (struct axienet_local *) data; + struct net_device *ndev = lp->ndev; + struct axidma_bd *cur_p; + + axienet_setoptions(ndev, lp->options & + ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN)); + mdio_mcreg = axienet_ior(lp, XAE_MDIO_MC_OFFSET); + axienet_mdio_wait_until_ready(lp); + /* Disable the MDIO interface till Axi Ethernet Reset is completed. + * When we do an Axi Ethernet reset, it resets the complete core + * including the MDIO. So if MDIO is not disabled when the reset + * process is started, MDIO will be broken afterwards. */ + axienet_iow(lp, XAE_MDIO_MC_OFFSET, (mdio_mcreg & + ~XAE_MDIO_MC_MDIOEN_MASK)); + + __axienet_device_reset(lp, &ndev->dev, XAXIDMA_TX_CR_OFFSET); + __axienet_device_reset(lp, &ndev->dev, XAXIDMA_RX_CR_OFFSET); + + axienet_iow(lp, XAE_MDIO_MC_OFFSET, mdio_mcreg); + axienet_mdio_wait_until_ready(lp); + + for (i = 0; i < TX_BD_NUM; i++) { + cur_p = &lp->tx_bd_v[i]; + if (cur_p->phys) + dma_unmap_single(ndev->dev.parent, cur_p->phys, + (cur_p->cntrl & + XAXIDMA_BD_CTRL_LENGTH_MASK), + DMA_TO_DEVICE); + if (cur_p->app4) + dev_kfree_skb_irq((struct sk_buff *) cur_p->app4); + cur_p->phys = 0; + cur_p->cntrl = 0; + cur_p->status = 0; + cur_p->app0 = 0; + cur_p->app1 = 0; + cur_p->app2 = 0; + cur_p->app3 = 0; + cur_p->app4 = 0; + cur_p->sw_id_offset = 0; + } + + for (i = 0; i < RX_BD_NUM; i++) { + cur_p = &lp->rx_bd_v[i]; + cur_p->status = 0; + cur_p->app0 = 0; + cur_p->app1 = 0; + cur_p->app2 = 0; + cur_p->app3 = 0; + cur_p->app4 = 0; + } + + lp->tx_bd_ci = 0; + lp->tx_bd_tail = 0; + lp->rx_bd_ci = 0; + + /* Start updating the Rx channel control register */ + cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET); + /* Update the interrupt coalesce count */ + cr = ((cr & ~XAXIDMA_COALESCE_MASK) | + (XAXIDMA_DFT_RX_THRESHOLD << XAXIDMA_COALESCE_SHIFT)); + /* Update the delay timer count */ + cr = ((cr & ~XAXIDMA_DELAY_MASK) | + (XAXIDMA_DFT_RX_WAITBOUND << XAXIDMA_DELAY_SHIFT)); + /* Enable coalesce, delay timer and error interrupts */ + cr |= XAXIDMA_IRQ_ALL_MASK; + /* Finally write to the Rx channel control register */ + axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr); + + /* Start updating the Tx channel control register */ + cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET); + /* Update the interrupt coalesce count */ + cr = (((cr & ~XAXIDMA_COALESCE_MASK)) | + (XAXIDMA_DFT_TX_THRESHOLD << XAXIDMA_COALESCE_SHIFT)); + /* Update the delay timer count */ + cr = (((cr & ~XAXIDMA_DELAY_MASK)) | + (XAXIDMA_DFT_TX_WAITBOUND << XAXIDMA_DELAY_SHIFT)); + /* Enable coalesce, delay timer and error interrupts */ + cr |= XAXIDMA_IRQ_ALL_MASK; + /* Finally write to the Tx channel control register */ + axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, cr); + + /* Populate the tail pointer and bring the Rx Axi DMA engine out of + * halted state. This will make the Rx side ready for reception.*/ + axienet_dma_out32(lp, XAXIDMA_RX_CDESC_OFFSET, lp->rx_bd_p); + cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET); + axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, + cr | XAXIDMA_CR_RUNSTOP_MASK); + axienet_dma_out32(lp, XAXIDMA_RX_TDESC_OFFSET, lp->rx_bd_p + + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1))); + + /* Write to the RS (Run-stop) bit in the Tx channel control register. + * Tx channel is now ready to run. But only after we write to the + * tail pointer register that the Tx channel will start transmitting */ + axienet_dma_out32(lp, XAXIDMA_TX_CDESC_OFFSET, lp->tx_bd_p); + cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET); + axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, + cr | XAXIDMA_CR_RUNSTOP_MASK); + + axienet_status = axienet_ior(lp, XAE_RCW1_OFFSET); + axienet_status &= ~XAE_RCW1_RX_MASK; + axienet_iow(lp, XAE_RCW1_OFFSET, axienet_status); + + axienet_status = axienet_ior(lp, XAE_IP_OFFSET); + if (axienet_status & XAE_INT_RXRJECT_MASK) + axienet_iow(lp, XAE_IS_OFFSET, XAE_INT_RXRJECT_MASK); + axienet_iow(lp, XAE_FCC_OFFSET, XAE_FCC_FCRX_MASK); + + /* Sync default options with HW but leave receiver and + * transmitter disabled.*/ + axienet_setoptions(ndev, lp->options & + ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN)); + axienet_set_mac_address(ndev, NULL); + axienet_set_multicast_list(ndev); + axienet_setoptions(ndev, lp->options); +} + +/** + * axienet_of_probe - Axi Ethernet probe function. + * @op: Pointer to platform device structure. + * @match: Pointer to device id structure + * + * returns: 0, on success + * Non-zero error value on failure. + * + * This is the probe routine for Axi Ethernet driver. This is called before + * any other driver routines are invoked. It allocates and sets up the Ethernet + * device. Parses through device tree and populates fields of + * axienet_local. It registers the Ethernet device. + */ +static int __devinit axienet_of_probe(struct platform_device *op) +{ + __be32 *p; + int size, ret = 0; + struct device_node *np; + struct axienet_local *lp; + struct net_device *ndev; + const void *addr; + + ndev = alloc_etherdev(sizeof(*lp)); + if (!ndev) { + dev_err(&op->dev, "could not allocate device.\n"); + return -ENOMEM; + } + + ether_setup(ndev); + dev_set_drvdata(&op->dev, ndev); + + SET_NETDEV_DEV(ndev, &op->dev); + ndev->flags &= ~IFF_MULTICAST; /* clear multicast */ + ndev->features = NETIF_F_SG | NETIF_F_FRAGLIST; + ndev->netdev_ops = &axienet_netdev_ops; + ndev->ethtool_ops = &axienet_ethtool_ops; + + lp = netdev_priv(ndev); + lp->ndev = ndev; + lp->dev = &op->dev; + lp->options = XAE_OPTION_DEFAULTS; + /* Map device registers */ + lp->regs = of_iomap(op->dev.of_node, 0); + if (!lp->regs) { + dev_err(&op->dev, "could not map Axi Ethernet regs.\n"); + goto nodev; + } + /* Setup checksum offload, but default to off if not specified */ + lp->features = 0; + + p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,txcsum", NULL); + if (p) { + switch (be32_to_cpup(p)) { + case 1: + lp->csum_offload_on_tx_path = + XAE_FEATURE_PARTIAL_TX_CSUM; + lp->features |= XAE_FEATURE_PARTIAL_TX_CSUM; + /* Can checksum TCP/UDP over IPv4. */ + ndev->features |= NETIF_F_IP_CSUM; + break; + case 2: + lp->csum_offload_on_tx_path = + XAE_FEATURE_FULL_TX_CSUM; + lp->features |= XAE_FEATURE_FULL_TX_CSUM; + /* Can checksum TCP/UDP over IPv4. */ + ndev->features |= NETIF_F_IP_CSUM; + break; + default: + lp->csum_offload_on_tx_path = XAE_NO_CSUM_OFFLOAD; + } + } + p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,rxcsum", NULL); + if (p) { + switch (be32_to_cpup(p)) { + case 1: + lp->csum_offload_on_rx_path = + XAE_FEATURE_PARTIAL_RX_CSUM; + lp->features |= XAE_FEATURE_PARTIAL_RX_CSUM; + break; + case 2: + lp->csum_offload_on_rx_path = + XAE_FEATURE_FULL_RX_CSUM; + lp->features |= XAE_FEATURE_FULL_RX_CSUM; + break; + default: + lp->csum_offload_on_rx_path = XAE_NO_CSUM_OFFLOAD; + } + } + /* For supporting jumbo frames, the Axi Ethernet hardware must have + * a larger Rx/Tx Memory. Typically, the size must be more than or + * equal to 16384 bytes, so that we can enable jumbo option and start + * supporting jumbo frames. Here we check for memory allocated for + * Rx/Tx in the hardware from the device-tree and accordingly set + * flags. */ + p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,rxmem", NULL); + if (p) { + if ((be32_to_cpup(p)) >= 0x4000) + lp->jumbo_support = 1; + } + p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,temac-type", + NULL); + if (p) + lp->temac_type = be32_to_cpup(p); + p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,phy-type", NULL); + if (p) + lp->phy_type = be32_to_cpup(p); + + /* Find the DMA node, map the DMA registers, and decode the DMA IRQs */ + np = of_parse_phandle(op->dev.of_node, "axistream-connected", 0); + if (!np) { + dev_err(&op->dev, "could not find DMA node\n"); + goto err_iounmap; + } + lp->dma_regs = of_iomap(np, 0); + if (lp->dma_regs) { + dev_dbg(&op->dev, "MEM base: %p\n", lp->dma_regs); + } else { + dev_err(&op->dev, "unable to map DMA registers\n"); + of_node_put(np); + } + lp->rx_irq = irq_of_parse_and_map(np, 1); + lp->tx_irq = irq_of_parse_and_map(np, 0); + of_node_put(np); + if ((lp->rx_irq == NO_IRQ) || (lp->tx_irq == NO_IRQ)) { + dev_err(&op->dev, "could not determine irqs\n"); + ret = -ENOMEM; + goto err_iounmap_2; + } + + /* Retrieve the MAC address */ + addr = of_get_property(op->dev.of_node, "local-mac-address", &size); + if ((!addr) || (size != 6)) { + dev_err(&op->dev, "could not find MAC address\n"); + ret = -ENODEV; + goto err_iounmap_2; + } + axienet_set_mac_address(ndev, (void *) addr); + + lp->coalesce_count_rx = XAXIDMA_DFT_RX_THRESHOLD; + lp->coalesce_count_tx = XAXIDMA_DFT_TX_THRESHOLD; + + lp->phy_node = of_parse_phandle(op->dev.of_node, "phy-handle", 0); + ret = axienet_mdio_setup(lp, op->dev.of_node); + if (ret) + dev_warn(&op->dev, "error registering MDIO bus\n"); + + ret = register_netdev(lp->ndev); + if (ret) { + dev_err(lp->dev, "register_netdev() error (%i)\n", ret); + goto err_iounmap_2; + } + + tasklet_init(&lp->dma_err_tasklet, axienet_dma_err_handler, + (unsigned long) lp); + tasklet_disable(&lp->dma_err_tasklet); + + return 0; + +err_iounmap_2: + if (lp->dma_regs) + iounmap(lp->dma_regs); +err_iounmap: + iounmap(lp->regs); +nodev: + free_netdev(ndev); + ndev = NULL; + return ret; +} + +static int __devexit axienet_of_remove(struct platform_device *op) +{ + struct net_device *ndev = dev_get_drvdata(&op->dev); + struct axienet_local *lp = netdev_priv(ndev); + + axienet_mdio_teardown(lp); + unregister_netdev(ndev); + + if (lp->phy_node) + of_node_put(lp->phy_node); + lp->phy_node = NULL; + + dev_set_drvdata(&op->dev, NULL); + + iounmap(lp->regs); + if (lp->dma_regs) + iounmap(lp->dma_regs); + free_netdev(ndev); + + return 0; +} + +static struct platform_driver axienet_of_driver = { + .probe = axienet_of_probe, + .remove = __devexit_p(axienet_of_remove), + .driver = { + .owner = THIS_MODULE, + .name = "xilinx_axienet", + .of_match_table = axienet_of_match, + }, +}; + +static int __init axienet_init(void) +{ + return platform_driver_register(&axienet_of_driver); +} + +static void __exit axienet_exit(void) +{ + platform_driver_unregister(&axienet_of_driver); +} + +module_init(axienet_init); +module_exit(axienet_exit); + +MODULE_DESCRIPTION("Xilinx Axi Ethernet driver"); +MODULE_AUTHOR("Xilinx"); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c new file mode 100644 index 00000000000..d70b6e79f6c --- /dev/null +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c @@ -0,0 +1,238 @@ +/* + * MDIO bus driver for the Xilinx Axi Ethernet device + * + * Copyright (c) 2009 Secret Lab Technologies, Ltd. + * Copyright (c) 2010 Xilinx, Inc. All rights reserved. + * Copyright (c) 2012 Daniel Borkmann, + * Copyright (c) 2012 Ariane Keller, + */ + +#include +#include +#include + +#include "xilinx_axienet.h" + +#define MAX_MDIO_FREQ 2500000 /* 2.5 MHz */ +#define DEFAULT_CLOCK_DIVISOR XAE_MDIO_DIV_DFT + +/* Wait till MDIO interface is ready to accept a new transaction.*/ +int axienet_mdio_wait_until_ready(struct axienet_local *lp) +{ + long end = jiffies + 2; + while (!(axienet_ior(lp, XAE_MDIO_MCR_OFFSET) & + XAE_MDIO_MCR_READY_MASK)) { + if (end - jiffies <= 0) { + WARN_ON(1); + return -ETIMEDOUT; + } + udelay(1); + } + return 0; +} + +/** + * axienet_mdio_read - MDIO interface read function + * @bus: Pointer to mii bus structure + * @phy_id: Address of the PHY device + * @reg: PHY register to read + * + * returns: The register contents on success, -ETIMEDOUT on a timeout + * + * Reads the contents of the requested register from the requested PHY + * address by first writing the details into MCR register. After a while + * the register MRD is read to obtain the PHY register content. + */ +static int axienet_mdio_read(struct mii_bus *bus, int phy_id, int reg) +{ + u32 rc; + int ret; + struct axienet_local *lp = bus->priv; + + ret = axienet_mdio_wait_until_ready(lp); + if (ret < 0) + return ret; + + axienet_iow(lp, XAE_MDIO_MCR_OFFSET, + (((phy_id << XAE_MDIO_MCR_PHYAD_SHIFT) & + XAE_MDIO_MCR_PHYAD_MASK) | + ((reg << XAE_MDIO_MCR_REGAD_SHIFT) & + XAE_MDIO_MCR_REGAD_MASK) | + XAE_MDIO_MCR_INITIATE_MASK | + XAE_MDIO_MCR_OP_READ_MASK)); + + ret = axienet_mdio_wait_until_ready(lp); + if (ret < 0) + return ret; + + rc = axienet_ior(lp, XAE_MDIO_MRD_OFFSET) & 0x0000FFFF; + + dev_dbg(lp->dev, "axienet_mdio_read(phy_id=%i, reg=%x) == %x\n", + phy_id, reg, rc); + + return rc; +} + +/** + * axienet_mdio_write - MDIO interface write function + * @bus: Pointer to mii bus structure + * @phy_id: Address of the PHY device + * @reg: PHY register to write to + * @val: Value to be written into the register + * + * returns: 0 on success, -ETIMEDOUT on a timeout + * + * Writes the value to the requested register by first writing the value + * into MWD register. The the MCR register is then appropriately setup + * to finish the write operation. + */ +static int axienet_mdio_write(struct mii_bus *bus, int phy_id, int reg, + u16 val) +{ + int ret; + struct axienet_local *lp = bus->priv; + + dev_dbg(lp->dev, "axienet_mdio_write(phy_id=%i, reg=%x, val=%x)\n", + phy_id, reg, val); + + ret = axienet_mdio_wait_until_ready(lp); + if (ret < 0) + return ret; + + axienet_iow(lp, XAE_MDIO_MWD_OFFSET, (u32) val); + axienet_iow(lp, XAE_MDIO_MCR_OFFSET, + (((phy_id << XAE_MDIO_MCR_PHYAD_SHIFT) & + XAE_MDIO_MCR_PHYAD_MASK) | + ((reg << XAE_MDIO_MCR_REGAD_SHIFT) & + XAE_MDIO_MCR_REGAD_MASK) | + XAE_MDIO_MCR_INITIATE_MASK | + XAE_MDIO_MCR_OP_WRITE_MASK)); + + ret = axienet_mdio_wait_until_ready(lp); + if (ret < 0) + return ret; + return 0; +} + +/** + * axienet_mdio_setup - MDIO setup function + * @lp: Pointer to axienet local data structure. + * @np: Pointer to device node + * + * returns: 0 on success, -ETIMEDOUT on a timeout, -ENOMEM when + * mdiobus_alloc (to allocate memory for mii bus structure) fails. + * + * Sets up the MDIO interface by initializing the MDIO clock and enabling the + * MDIO interface in hardware. Register the MDIO interface. + **/ +int axienet_mdio_setup(struct axienet_local *lp, struct device_node *np) +{ + int ret; + u32 clk_div, host_clock; + u32 *property_p; + struct mii_bus *bus; + struct resource res; + struct device_node *np1; + + /* clk_div can be calculated by deriving it from the equation: + * fMDIO = fHOST / ((1 + clk_div) * 2) + * + * Where fMDIO <= 2500000, so we get: + * fHOST / ((1 + clk_div) * 2) <= 2500000 + * + * Then we get: + * 1 / ((1 + clk_div) * 2) <= (2500000 / fHOST) + * + * Then we get: + * 1 / (1 + clk_div) <= ((2500000 * 2) / fHOST) + * + * Then we get: + * 1 / (1 + clk_div) <= (5000000 / fHOST) + * + * So: + * (1 + clk_div) >= (fHOST / 5000000) + * + * And finally: + * clk_div >= (fHOST / 5000000) - 1 + * + * fHOST can be read from the flattened device tree as property + * "clock-frequency" from the CPU + */ + + np1 = of_find_node_by_name(NULL, "cpu"); + if (!np1) { + printk(KERN_WARNING "%s(): Could not find CPU device node.", + __func__); + printk(KERN_WARNING "Setting MDIO clock divisor to " + "default %d\n", DEFAULT_CLOCK_DIVISOR); + clk_div = DEFAULT_CLOCK_DIVISOR; + goto issue; + } + property_p = (u32 *) of_get_property(np1, "clock-frequency", NULL); + if (!property_p) { + printk(KERN_WARNING "%s(): Could not find CPU property: " + "clock-frequency.", __func__); + printk(KERN_WARNING "Setting MDIO clock divisor to " + "default %d\n", DEFAULT_CLOCK_DIVISOR); + clk_div = DEFAULT_CLOCK_DIVISOR; + goto issue; + } + + host_clock = be32_to_cpup(property_p); + clk_div = (host_clock / (MAX_MDIO_FREQ * 2)) - 1; + /* If there is any remainder from the division of + * fHOST / (MAX_MDIO_FREQ * 2), then we need to add + * 1 to the clock divisor or we will surely be above 2.5 MHz */ + if (host_clock % (MAX_MDIO_FREQ * 2)) + clk_div++; + + printk(KERN_DEBUG "%s(): Setting MDIO clock divisor to %u based " + "on %u Hz host clock.\n", __func__, clk_div, host_clock); + + of_node_put(np1); +issue: + axienet_iow(lp, XAE_MDIO_MC_OFFSET, + (((u32) clk_div) | XAE_MDIO_MC_MDIOEN_MASK)); + + ret = axienet_mdio_wait_until_ready(lp); + if (ret < 0) + return ret; + + bus = mdiobus_alloc(); + if (!bus) + return -ENOMEM; + + np1 = of_get_parent(lp->phy_node); + of_address_to_resource(np1, 0, &res); + snprintf(bus->id, MII_BUS_ID_SIZE, "%.8llx", + (unsigned long long) res.start); + + bus->priv = lp; + bus->name = "Xilinx Axi Ethernet MDIO"; + bus->read = axienet_mdio_read; + bus->write = axienet_mdio_write; + bus->parent = lp->dev; + bus->irq = lp->mdio_irqs; /* preallocated IRQ table */ + lp->mii_bus = bus; + + ret = of_mdiobus_register(bus, np1); + if (ret) { + mdiobus_free(bus); + return ret; + } + return 0; +} + +/** + * axienet_mdio_teardown - MDIO remove function + * @lp: Pointer to axienet local data structure. + * + * Unregisters the MDIO and frees any associate memory for mii bus. + */ +void axienet_mdio_teardown(struct axienet_local *lp) +{ + mdiobus_unregister(lp->mii_bus); + kfree(lp->mii_bus->irq); + mdiobus_free(lp->mii_bus); + lp->mii_bus = NULL; +} -- cgit v1.2.3-70-g09d2 From 9b28ecd66b391349d3492574500f978566195454 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Thu, 19 Jan 2012 15:37:22 +0000 Subject: net: usb: qmi_wwan: New driver for Huawei QMI based WWAN devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some WWAN LTE/3G devices based on chipsets from Qualcomm provide near standard CDC ECM interfaces in addition to the usual serial interfaces. The Huawei E392/E398 are examples of such devices. These typically cannot be fully configured using AT commands over a serial interface. It is necessary to speak the proprietary Qualcomm MSM Interface (QMI) protocol to the device to enable the ethernet proxy functionality. The devices embed the QMI protocol in CDC on the control interface, using standard CDC commands and notifications. The do not otherwise use CDC commands for the ethernet function. This driver does therefore not need access to any other aspects of the control interface than the descriptors attached to it. Another driver, cdc-wdm, will provide userspace access to the QMI protocol independently of this driver. To facilitate this, this driver avoids binding to the control interface, and uses only the associated data interface after parsing the common CDC functional descriptors on the control interface. You will want both the cdc-wdm and option drivers as companions to this driver, to have full access to all interfaces and protocols exported by the device. Signed-off-by: Bjørn Mork Signed-off-by: David S. Miller --- drivers/net/usb/Kconfig | 22 +++++ drivers/net/usb/Makefile | 1 + drivers/net/usb/qmi_wwan.c | 228 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 251 insertions(+) create mode 100644 drivers/net/usb/qmi_wwan.c (limited to 'drivers') diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 23357612793..4bad899fb38 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -398,6 +398,27 @@ config USB_NET_KALMIA To compile this driver as a module, choose M here: the module will be called kalmia. +config USB_NET_QMI_WWAN + tristate "QMI WWAN driver for Qualcomm MSM based 3G and LTE modems" + depends on USB_USBNET + help + Support WWAN LTE/3G devices based on Qualcomm Mobile Data Modem + (MDM) chipsets. Examples of such devices are + * Huawei E392/E398 + + This driver will only drive the ethernet part of the chips. + The devices require additional configuration to be usable. + Multiple management interfaces with linux drivers are + available: + + * option: AT commands on /dev/ttyUSBx + * cdc-wdm: Qualcomm MSM Interface (QMI) protocol on /dev/cdc-wdmx + + A modem manager with support for QMI is recommended. + + To compile this driver as a module, choose M here: the + module will be called qmi_wwan. + config USB_HSO tristate "Option USB High Speed Mobile Devices" depends on USB && RFKILL @@ -461,4 +482,5 @@ config USB_VL600 http://ubuntuforums.org/showpost.php?p=10589647&postcount=17 + endmenu diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index c203fa21f6b..a2e2d72c52a 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile @@ -29,4 +29,5 @@ obj-$(CONFIG_USB_SIERRA_NET) += sierra_net.o obj-$(CONFIG_USB_NET_CX82310_ETH) += cx82310_eth.o obj-$(CONFIG_USB_NET_CDC_NCM) += cdc_ncm.o obj-$(CONFIG_USB_VL600) += lg-vl600.o +obj-$(CONFIG_USB_NET_QMI_WWAN) += qmi_wwan.o diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c new file mode 100644 index 00000000000..739e6de7abc --- /dev/null +++ b/drivers/net/usb/qmi_wwan.c @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2012 Bjørn Mork + * + * 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 + +/* The name of the CDC Device Management driver */ +#define DM_DRIVER "cdc_wdm" + +/* + * This driver supports wwan (3G/LTE/?) devices using a vendor + * specific management protocol called Qualcomm MSM Interface (QMI) - + * in addition to the more common AT commands over serial interface + * management + * + * QMI is wrapped in CDC, using CDC encapsulated commands on the + * control ("master") interface of a two-interface CDC Union + * resembling standard CDC ECM. The devices do not use the control + * interface for any other CDC messages. Most likely because the + * management protocol is used in place of the standard CDC + * notifications NOTIFY_NETWORK_CONNECTION and NOTIFY_SPEED_CHANGE + * + * Handling a protocol like QMI is out of the scope for any driver. + * It can be exported as a character device using the cdc-wdm driver, + * which will enable userspace applications ("modem managers") to + * handle it. This may be required to use the network interface + * provided by the driver. + * + * These devices may alternatively/additionally be configured using AT + * commands on any of the serial interfaces driven by the option driver + * + * This driver binds only to the data ("slave") interface to enable + * the cdc-wdm driver to bind to the control interface. It still + * parses the CDC functional descriptors on the control interface to + * a) verify that this is indeed a handled interface (CDC Union + * header lists it as slave) + * b) get MAC address and other ethernet config from the CDC Ethernet + * header + * c) enable user bind requests against the control interface, which + * is the common way to bind to CDC Ethernet Control Model type + * interfaces + * d) provide a hint to the user about which interface is the + * corresponding management interface + */ + +static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf) +{ + int status = -1; + struct usb_interface *control = NULL; + u8 *buf = intf->cur_altsetting->extra; + int len = intf->cur_altsetting->extralen; + struct usb_interface_descriptor *desc = &intf->cur_altsetting->desc; + struct usb_cdc_union_desc *cdc_union = NULL; + struct usb_cdc_ether_desc *cdc_ether = NULL; + u32 required = 1 << USB_CDC_HEADER_TYPE | 1 << USB_CDC_UNION_TYPE; + u32 found = 0; + + /* + * assume a data interface has no additional descriptors and + * that the control and data interface are numbered + * consecutively - this holds for the Huawei device at least + */ + if (len == 0 && desc->bInterfaceNumber > 0) { + control = usb_ifnum_to_if(dev->udev, desc->bInterfaceNumber - 1); + if (!control) + goto err; + + buf = control->cur_altsetting->extra; + len = control->cur_altsetting->extralen; + dev_dbg(&intf->dev, "guessing \"control\" => %s, \"data\" => this\n", + dev_name(&control->dev)); + } + + while (len > 3) { + struct usb_descriptor_header *h = (void *)buf; + + /* ignore any misplaced descriptors */ + if (h->bDescriptorType != USB_DT_CS_INTERFACE) + goto next_desc; + + /* buf[2] is CDC descriptor subtype */ + switch (buf[2]) { + case USB_CDC_HEADER_TYPE: + if (found & 1 << USB_CDC_HEADER_TYPE) { + dev_dbg(&intf->dev, "extra CDC header\n"); + goto err; + } + if (h->bLength != sizeof(struct usb_cdc_header_desc)) { + dev_dbg(&intf->dev, "CDC header len %u\n", h->bLength); + goto err; + } + break; + case USB_CDC_UNION_TYPE: + if (found & 1 << USB_CDC_UNION_TYPE) { + dev_dbg(&intf->dev, "extra CDC union\n"); + goto err; + } + if (h->bLength != sizeof(struct usb_cdc_union_desc)) { + dev_dbg(&intf->dev, "CDC union len %u\n", h->bLength); + goto err; + } + cdc_union = (struct usb_cdc_union_desc *)buf; + break; + case USB_CDC_ETHERNET_TYPE: + if (found & 1 << USB_CDC_ETHERNET_TYPE) { + dev_dbg(&intf->dev, "extra CDC ether\n"); + goto err; + } + if (h->bLength != sizeof(struct usb_cdc_ether_desc)) { + dev_dbg(&intf->dev, "CDC ether len %u\n", h->bLength); + goto err; + } + cdc_ether = (struct usb_cdc_ether_desc *)buf; + break; + } + + /* + * Remember which CDC functional descriptors we've seen. Works + * for all types we care about, of which USB_CDC_ETHERNET_TYPE + * (0x0f) is the highest numbered + */ + if (buf[2] < 32) + found |= 1 << buf[2]; + +next_desc: + len -= h->bLength; + buf += h->bLength; + } + + /* did we find all the required ones? */ + if ((found & required) != required) { + dev_err(&intf->dev, "CDC functional descriptors missing\n"); + goto err; + } + + /* give the user a helpful hint if trying to bind to the wrong interface */ + if (cdc_union && desc->bInterfaceNumber == cdc_union->bMasterInterface0) { + dev_err(&intf->dev, "leaving \"control\" interface for " DM_DRIVER " - try binding to %s instead!\n", + dev_name(&usb_ifnum_to_if(dev->udev, cdc_union->bSlaveInterface0)->dev)); + goto err; + } + + /* errors aren't fatal - we can live with the dynamic address */ + if (cdc_ether) { + dev->hard_mtu = le16_to_cpu(cdc_ether->wMaxSegmentSize); + usbnet_get_ethernet_addr(dev, cdc_ether->iMACAddress); + } + + /* success! point the user to the management interface */ + if (control) + dev_info(&intf->dev, "Use \"" DM_DRIVER "\" for QMI interface %s\n", + dev_name(&control->dev)); + + /* XXX: add a sysfs symlink somewhere to help management applications find it? */ + + /* collect bulk endpoints now that we know intf == "data" interface */ + status = usbnet_get_endpoints(dev, intf); + +err: + return status; +} + +/* stolen from cdc_ether.c */ +static int qmi_wwan_manage_power(struct usbnet *dev, int on) +{ + dev->intf->needs_remote_wakeup = on; + return 0; +} + +static const struct driver_info qmi_wwan_info = { + .description = "QMI speaking wwan device", + .flags = FLAG_WWAN, + .bind = qmi_wwan_bind, + .manage_power = qmi_wwan_manage_power, +}; + +#define HUAWEI_VENDOR_ID 0x12D1 + +static const struct usb_device_id products[] = { +{ + /* Huawei E392, E398 and possibly others sharing both device id and more... */ + .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = HUAWEI_VENDOR_ID, + .bInterfaceClass = USB_CLASS_VENDOR_SPEC, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 8, /* NOTE: This is the *slave* interface of the CDC Union! */ + .driver_info = (unsigned long)&qmi_wwan_info, +}, { +}, /* END */ +}; +MODULE_DEVICE_TABLE(usb, products); + +static struct usb_driver qmi_wwan_driver = { + .name = "qmi_wwan", + .id_table = products, + .probe = usbnet_probe, + .disconnect = usbnet_disconnect, + .suspend = usbnet_suspend, + .resume = usbnet_resume, + .reset_resume = usbnet_resume, + .supports_autosuspend = 1, +}; + +static int __init qmi_wwan_init(void) +{ + return usb_register(&qmi_wwan_driver); +} +module_init(qmi_wwan_init); + +static void __exit qmi_wwan_exit(void) +{ + usb_deregister(&qmi_wwan_driver); +} +module_exit(qmi_wwan_exit); + +MODULE_AUTHOR("Bjørn Mork "); +MODULE_DESCRIPTION("Qualcomm MSM Interface (QMI) WWAN driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From fc74d8e01165b567922921d110b6d16320a61fa6 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 19 Jan 2012 10:50:06 -0800 Subject: drm/i915: Correct the bit number for the MI_FLUSH_ENABLE. Older specs claimed this was bit 11, but newer specs and the actual simulator code say it was bit 12. Regardless, we don't use MI_FLUSH, or try to enable it any more. Signed-off-by: Eric Anholt Reviewed-by: Kenneth Graunke Reviewed-by: Ben Widawsky [danvet: Anyone trying to use this bit, please read all the relevant discussions, it's epic.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c3afb783cb9..bbad7885348 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -391,7 +391,7 @@ #define MI_MODE 0x0209c # define VS_TIMER_DISPATCH (1 << 6) -# define MI_FLUSH_ENABLE (1 << 11) +# define MI_FLUSH_ENABLE (1 << 12) #define GFX_MODE 0x02520 #define GFX_MODE_GEN7 0x0229c -- cgit v1.2.3-70-g09d2 From 02b619555ad68884bacfbe41893245394cb44885 Mon Sep 17 00:00:00 2001 From: David Miller Date: Tue, 24 Jan 2012 13:15:52 +0000 Subject: infiniband: Convert dst_fetch_ha() over to dst_neigh_lookup(). Now we must provide the IP destination address, and a reference has to be dropped when we're done with the entry. Signed-off-by: David S. Miller --- drivers/infiniband/core/addr.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index 1612cfd50f3..6ef660c1332 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -178,22 +178,26 @@ static void queue_req(struct addr_req *req) mutex_unlock(&lock); } -static int dst_fetch_ha(struct dst_entry *dst, struct rdma_dev_addr *addr) +static int dst_fetch_ha(struct dst_entry *dst, struct rdma_dev_addr *dev_addr, void *daddr) { struct neighbour *n; int ret; + n = dst_neigh_lookup(dst, daddr); + rcu_read_lock(); - n = dst_get_neighbour_noref(dst); if (!n || !(n->nud_state & NUD_VALID)) { if (n) neigh_event_send(n, NULL); ret = -ENODATA; } else { - ret = rdma_copy_addr(addr, dst->dev, n->ha); + ret = rdma_copy_addr(dev_addr, dst->dev, n->ha); } rcu_read_unlock(); + if (n) + neigh_release(n); + return ret; } @@ -232,7 +236,7 @@ static int addr4_resolve(struct sockaddr_in *src_in, goto put; } - ret = dst_fetch_ha(&rt->dst, addr); + ret = dst_fetch_ha(&rt->dst, addr, &fl4.daddr); put: ip_rt_put(rt); out: @@ -280,7 +284,7 @@ static int addr6_resolve(struct sockaddr_in6 *src_in, goto put; } - ret = dst_fetch_ha(dst, addr); + ret = dst_fetch_ha(dst, addr, &fl6.daddr); put: dst_release(dst); return ret; -- cgit v1.2.3-70-g09d2 From 64b7007eb99b78cbdd6cca7a98e12794201b9725 Mon Sep 17 00:00:00 2001 From: David Miller Date: Tue, 24 Jan 2012 13:15:57 +0000 Subject: infiniband: cxgb4: Convert import_ep() over to dst_neigh_lookup(). Now we must provide the IP destination address, and a reference has to be dropped when we're done with the entry. Signed-off-by: David S. Miller Signed-off-by: Steve Wise Signed-off-by: David S. Miller --- drivers/infiniband/hw/cxgb4/cm.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 0668bb3472d..0cf61554f17 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -1562,11 +1562,11 @@ static int import_ep(struct c4iw_ep *ep, __be32 peer_ip, struct dst_entry *dst, struct neighbour *n; int err, step; - rcu_read_lock(); - n = dst_get_neighbour_noref(dst); - err = -ENODEV; + n = dst_neigh_lookup(dst, &peer_ip); if (!n) - goto out; + return -ENODEV; + + rcu_read_lock(); err = -ENOMEM; if (n->dev->flags & IFF_LOOPBACK) { struct net_device *pdev; @@ -1614,6 +1614,8 @@ static int import_ep(struct c4iw_ep *ep, __be32 peer_ip, struct dst_entry *dst, out: rcu_read_unlock(); + neigh_release(n); + return err; } -- cgit v1.2.3-70-g09d2 From e55684fadbc5c9c69cad1b3bae228c8374b99b85 Mon Sep 17 00:00:00 2001 From: David Miller Date: Tue, 24 Jan 2012 13:16:03 +0000 Subject: infiniband: nes: Convert nes_addr_resolve_neigh() over to dst_neigh_lookup(). Now we must provide the IP destination address, and a reference has to be dropped when we're done with the entry. Signed-off-by: David S. Miller --- drivers/infiniband/hw/nes/nes_cm.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 425065b36b8..fc5192ee928 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -1348,8 +1348,9 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi else netdev = nesvnic->netdev; + neigh = dst_neigh_lookup(&rt->dst, &dst_ip); + rcu_read_lock(); - neigh = dst_get_neighbour_noref(&rt->dst); if (neigh) { if (neigh->nud_state & NUD_VALID) { nes_debug(NES_DBG_CM, "Neighbor MAC address for 0x%08X" @@ -1360,8 +1361,7 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi if (!memcmp(nesadapter->arp_table[arpindex].mac_addr, neigh->ha, ETH_ALEN)) { /* Mac address same as in nes_arp_table */ - ip_rt_put(rt); - return rc; + goto out; } nes_manage_arp_cache(nesvnic->netdev, @@ -1377,7 +1377,12 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi neigh_event_send(neigh, NULL); } } +out: rcu_read_unlock(); + + if (neigh) + neigh_release(neigh); + ip_rt_put(rt); return rc; } -- cgit v1.2.3-70-g09d2 From 65a4a573b74f8f27e33a99c21a5a5d2fc4d82a1a Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Wed, 18 Jan 2012 18:34:34 -0600 Subject: crypto: caam - fix gcc 4.6 warning drivers/crypto/caam/ctrl.c: In function 'caam_probe': drivers/crypto/caam/ctrl.c:49:6: warning: unused variable 'd' [-Wunused-variable] Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/ctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index 8ae3ba2a160..c5f61c55d92 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c @@ -46,7 +46,7 @@ static int caam_remove(struct platform_device *pdev) /* Probe routine for CAAM top (controller) level */ static int caam_probe(struct platform_device *pdev) { - int d, ring, rspec; + int ring, rspec; struct device *dev; struct device_node *nprop, *np; struct caam_ctrl __iomem *ctrl; -- cgit v1.2.3-70-g09d2 From afd12939a09ca8f96cf8349c913dc143471c9b3c Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Thu, 5 Jan 2012 00:34:05 +0000 Subject: e1000e: cleanup Rx checksum offload code 1) cleanup whitespace in e1000_rx_checksum() function header comment 2) do not check hardware checksum when Rx checksum is disabled 3) reduce duplicated calls to le16_to_cpu() by just using it within e1000_rx_checksum() instead of in each call to the function v2: use swab16 instead of le16_to_cpu & htons and corrected type for the passed-in csum Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/netdev.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 3911401ed65..263bf5f02eb 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -487,22 +487,27 @@ static void e1000_receive_skb(struct e1000_adapter *adapter, /** * e1000_rx_checksum - Receive Checksum Offload - * @adapter: board private structure - * @status_err: receive descriptor status and error fields - * @csum: receive descriptor csum field - * @sk_buff: socket buffer with received data + * @adapter: board private structure + * @status_err: receive descriptor status and error fields + * @csum: receive descriptor csum field + * @sk_buff: socket buffer with received data **/ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, - u32 csum, struct sk_buff *skb) + __le16 csum, struct sk_buff *skb) { u16 status = (u16)status_err; u8 errors = (u8)(status_err >> 24); skb_checksum_none_assert(skb); + /* Rx checksum disabled */ + if (!(adapter->netdev->features & NETIF_F_RXCSUM)) + return; + /* Ignore Checksum bit is set */ if (status & E1000_RXD_STAT_IXSM) return; + /* TCP/UDP checksum error bit is set */ if (errors & E1000_RXD_ERR_TCPE) { /* let the stack verify checksum errors */ @@ -524,7 +529,7 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, * Hardware complements the payload checksum, so we undo it * and then put the value in host order for further stack use. */ - __sum16 sum = (__force __sum16)htons(csum); + __sum16 sum = (__force __sum16)swab16((__force u16)csum); skb->csum = csum_unfold(~sum); skb->ip_summed = CHECKSUM_COMPLETE; } @@ -957,8 +962,7 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, /* Receive Checksum Offload */ e1000_rx_checksum(adapter, staterr, - le16_to_cpu(rx_desc->wb.lower.hi_dword. - csum_ip.csum), skb); + rx_desc->wb.lower.hi_dword.csum_ip.csum, skb); e1000_receive_skb(adapter, netdev, skb, staterr, rx_desc->wb.upper.vlan); @@ -1318,8 +1322,8 @@ copydone: total_rx_bytes += skb->len; total_rx_packets++; - e1000_rx_checksum(adapter, staterr, le16_to_cpu( - rx_desc->wb.lower.hi_dword.csum_ip.csum), skb); + e1000_rx_checksum(adapter, staterr, + rx_desc->wb.lower.hi_dword.csum_ip.csum, skb); if (rx_desc->wb.upper.header_status & cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP)) @@ -1491,8 +1495,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, /* Receive Checksum Offload XXX recompute due to CRC strip? */ e1000_rx_checksum(adapter, staterr, - le16_to_cpu(rx_desc->wb.lower.hi_dword. - csum_ip.csum), skb); + rx_desc->wb.lower.hi_dword.csum_ip.csum, skb); /* probably a little skewed due to removing CRC */ total_rx_bytes += skb->len; -- cgit v1.2.3-70-g09d2 From 70495a500d787c0c90a136acf454cb7d0eecd82e Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 11 Jan 2012 01:26:50 +0000 Subject: e1000e: add Receive Packet Steering (RPS) support Enable RPS by default. Disallow jumbo frames when both receive checksum and receive hashing are enabled because the hardware cannot do both IP payload checksum (enabled when receive checksum is enabled when using packet split which is used for jumbo frames) and provide RSS hash at the same time. v2: added ethtool command to query flow hashing behavior per Ben Hutchings and changed the type of rsskey to cleanup the setting of the register array and avoid unnecessary casts (as pointed out by Joe Perches). The long error messages are not changed since there is nothing in the kernel ./Documentation that suggests the preferred method for dealing with long messages other than to never break strings; leaving them as-is for now. Signed-off-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/defines.h | 8 +++ drivers/net/ethernet/intel/e1000e/ethtool.c | 48 +++++++++++++++ drivers/net/ethernet/intel/e1000e/hw.h | 5 ++ drivers/net/ethernet/intel/e1000e/netdev.c | 90 +++++++++++++++++++++++++++-- 4 files changed, 145 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/defines.h b/drivers/net/ethernet/intel/e1000e/defines.h index c516a7440be..c73795f4653 100644 --- a/drivers/net/ethernet/intel/e1000e/defines.h +++ b/drivers/net/ethernet/intel/e1000e/defines.h @@ -126,6 +126,13 @@ E1000_RXDEXT_STATERR_CXE | \ E1000_RXDEXT_STATERR_RXE) +#define E1000_MRQC_RSS_FIELD_MASK 0xFFFF0000 +#define E1000_MRQC_RSS_FIELD_IPV4_TCP 0x00010000 +#define E1000_MRQC_RSS_FIELD_IPV4 0x00020000 +#define E1000_MRQC_RSS_FIELD_IPV6_TCP_EX 0x00040000 +#define E1000_MRQC_RSS_FIELD_IPV6 0x00100000 +#define E1000_MRQC_RSS_FIELD_IPV6_TCP 0x00200000 + #define E1000_RXDPS_HDRSTAT_HDRSP 0x00008000 /* Management Control */ @@ -326,6 +333,7 @@ /* Receive Checksum Control */ #define E1000_RXCSUM_TUOFL 0x00000200 /* TCP / UDP checksum offload */ #define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */ +#define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */ /* Header split receive */ #define E1000_RFCTL_NFSW_DIS 0x00000040 diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index fb2c28e799a..0a3137a791e 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -1955,6 +1955,53 @@ static void e1000_get_strings(struct net_device *netdev, u32 stringset, } } +static int e1000_get_rxnfc(struct net_device *netdev, + struct ethtool_rxnfc *info, u32 *rule_locs) +{ + info->data = 0; + + switch (info->cmd) { + case ETHTOOL_GRXFH: { + struct e1000_adapter *adapter = netdev_priv(netdev); + struct e1000_hw *hw = &adapter->hw; + u32 mrqc = er32(MRQC); + + if (!(mrqc & E1000_MRQC_RSS_FIELD_MASK)) + return 0; + + switch (info->flow_type) { + case TCP_V4_FLOW: + if (mrqc & E1000_MRQC_RSS_FIELD_IPV4_TCP) + info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; + /* fall through */ + case UDP_V4_FLOW: + case SCTP_V4_FLOW: + case AH_ESP_V4_FLOW: + case IPV4_FLOW: + if (mrqc & E1000_MRQC_RSS_FIELD_IPV4) + info->data |= RXH_IP_SRC | RXH_IP_DST; + break; + case TCP_V6_FLOW: + if (mrqc & E1000_MRQC_RSS_FIELD_IPV6_TCP) + info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; + /* fall through */ + case UDP_V6_FLOW: + case SCTP_V6_FLOW: + case AH_ESP_V6_FLOW: + case IPV6_FLOW: + if (mrqc & E1000_MRQC_RSS_FIELD_IPV6) + info->data |= RXH_IP_SRC | RXH_IP_DST; + break; + default: + break; + } + return 0; + } + default: + return -EOPNOTSUPP; + } +} + static const struct ethtool_ops e1000_ethtool_ops = { .get_settings = e1000_get_settings, .set_settings = e1000_set_settings, @@ -1981,6 +2028,7 @@ static const struct ethtool_ops e1000_ethtool_ops = { .get_sset_count = e1000e_get_sset_count, .get_coalesce = e1000_get_coalesce, .set_coalesce = e1000_set_coalesce, + .get_rxnfc = e1000_get_rxnfc, }; void e1000e_set_ethtool_ops(struct net_device *netdev) diff --git a/drivers/net/ethernet/intel/e1000e/hw.h b/drivers/net/ethernet/intel/e1000e/hw.h index 29670397079..93c349ee565 100644 --- a/drivers/net/ethernet/intel/e1000e/hw.h +++ b/drivers/net/ethernet/intel/e1000e/hw.h @@ -204,6 +204,7 @@ enum e1e_registers { E1000_WUC = 0x05800, /* Wakeup Control - RW */ E1000_WUFC = 0x05808, /* Wakeup Filter Control - RW */ E1000_WUS = 0x05810, /* Wakeup Status - RO */ + E1000_MRQC = 0x05818, /* Multiple Receive Control - RW */ E1000_MANC = 0x05820, /* Management Control - RW */ E1000_FFLT = 0x05F00, /* Flexible Filter Length Table - RW Array */ E1000_HOST_IF = 0x08800, /* Host Interface */ @@ -219,6 +220,10 @@ enum e1e_registers { E1000_SWSM = 0x05B50, /* SW Semaphore */ E1000_FWSM = 0x05B54, /* FW Semaphore */ E1000_SWSM2 = 0x05B58, /* Driver-only SW semaphore */ + E1000_RETA_BASE = 0x05C00, /* Redirection Table - RW */ +#define E1000_RETA(_n) (E1000_RETA_BASE + ((_n) * 4)) + E1000_RSSRK_BASE = 0x05C80, /* RSS Random Key - RW */ +#define E1000_RSSRK(_n) (E1000_RSSRK_BASE + ((_n) * 4)) E1000_FFLT_DBG = 0x05F04, /* Debug Register */ E1000_PCH_RAICC_BASE = 0x05F50, /* Receive Address Initial CRC */ #define E1000_PCH_RAICC(_n) (E1000_PCH_RAICC_BASE + ((_n) * 4)) diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 263bf5f02eb..b196d79e108 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -845,6 +845,13 @@ check_page: } } +static inline void e1000_rx_hash(struct net_device *netdev, __le32 rss, + struct sk_buff *skb) +{ + if (netdev->features & NETIF_F_RXHASH) + skb->rxhash = le32_to_cpu(rss); +} + /** * e1000_clean_rx_irq - Send received data up the network stack; legacy * @adapter: board private structure @@ -964,6 +971,8 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, e1000_rx_checksum(adapter, staterr, rx_desc->wb.lower.hi_dword.csum_ip.csum, skb); + e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb); + e1000_receive_skb(adapter, netdev, skb, staterr, rx_desc->wb.upper.vlan); @@ -1325,6 +1334,8 @@ copydone: e1000_rx_checksum(adapter, staterr, rx_desc->wb.lower.hi_dword.csum_ip.csum, skb); + e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb); + if (rx_desc->wb.upper.header_status & cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP)) adapter->rx_hdr_split++; @@ -1497,6 +1508,8 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, e1000_rx_checksum(adapter, staterr, rx_desc->wb.lower.hi_dword.csum_ip.csum, skb); + e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb); + /* probably a little skewed due to removing CRC */ total_rx_bytes += skb->len; total_rx_packets++; @@ -3271,6 +3284,42 @@ static void e1000e_set_rx_mode(struct net_device *netdev) e1000e_vlan_strip_disable(adapter); } +static void e1000e_setup_rss_hash(struct e1000_adapter *adapter) +{ + struct e1000_hw *hw = &adapter->hw; + u32 mrqc, rxcsum; + int i; + static const u32 rsskey[10] = { + 0xda565a6d, 0xc20e5b25, 0x3d256741, 0xb08fa343, 0xcb2bcad0, + 0xb4307bae, 0xa32dcb77, 0x0cf23080, 0x3bb7426a, 0xfa01acbe + }; + + /* Fill out hash function seed */ + for (i = 0; i < 10; i++) + ew32(RSSRK(i), rsskey[i]); + + /* Direct all traffic to queue 0 */ + for (i = 0; i < 32; i++) + ew32(RETA(i), 0); + + /* + * Disable raw packet checksumming so that RSS hash is placed in + * descriptor on writeback. + */ + rxcsum = er32(RXCSUM); + rxcsum |= E1000_RXCSUM_PCSD; + + ew32(RXCSUM, rxcsum); + + mrqc = (E1000_MRQC_RSS_FIELD_IPV4 | + E1000_MRQC_RSS_FIELD_IPV4_TCP | + E1000_MRQC_RSS_FIELD_IPV6 | + E1000_MRQC_RSS_FIELD_IPV6_TCP | + E1000_MRQC_RSS_FIELD_IPV6_TCP_EX); + + ew32(MRQC, mrqc); +} + /** * e1000_configure - configure the hardware for Rx and Tx * @adapter: private board structure @@ -3283,6 +3332,9 @@ static void e1000_configure(struct e1000_adapter *adapter) e1000_init_manageability_pt(adapter); e1000_configure_tx(adapter); + + if (adapter->netdev->features & NETIF_F_RXHASH) + e1000e_setup_rss_hash(adapter); e1000_setup_rctl(adapter); e1000_configure_rx(adapter); adapter->alloc_rx_buf(adapter, e1000_desc_unused(adapter->rx_ring), @@ -5168,10 +5220,22 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; /* Jumbo frame support */ - if ((max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) && - !(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) { - e_err("Jumbo Frames not supported.\n"); - return -EINVAL; + if (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) { + if (!(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) { + e_err("Jumbo Frames not supported.\n"); + return -EINVAL; + } + + /* + * IP payload checksum (enabled with jumbos/packet-split when + * Rx checksum is enabled) and generation of RSS hash is + * mutually exclusive in the hardware. + */ + if ((netdev->features & NETIF_F_RXCSUM) && + (netdev->features & NETIF_F_RXHASH)) { + e_err("Jumbo frames cannot be enabled when both receive checksum offload and receive hashing are enabled. Disable one of the receive offload features before enabling jumbos.\n"); + return -EINVAL; + } } /* Supported frame sizes */ @@ -5934,7 +5998,7 @@ static void e1000_eeprom_checks(struct e1000_adapter *adapter) } static int e1000_set_features(struct net_device *netdev, - netdev_features_t features) + netdev_features_t features) { struct e1000_adapter *adapter = netdev_priv(netdev); netdev_features_t changed = features ^ netdev->features; @@ -5943,9 +6007,22 @@ static int e1000_set_features(struct net_device *netdev, adapter->flags |= FLAG_TSO_FORCE; if (!(changed & (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX | - NETIF_F_RXCSUM))) + NETIF_F_RXCSUM | NETIF_F_RXHASH))) return 0; + /* + * IP payload checksum (enabled with jumbos/packet-split when Rx + * checksum is enabled) and generation of RSS hash is mutually + * exclusive in the hardware. + */ + if (adapter->rx_ps_pages && + (features & NETIF_F_RXCSUM) && (features & NETIF_F_RXHASH)) { + e_err("Enabling both receive checksum offload and receive hashing is not possible with jumbo frames. Disable jumbos or enable only one of the receive offload features.\n"); + return -EINVAL; + } + + netdev->features = features; + if (netif_running(netdev)) e1000e_reinit_locked(adapter); else @@ -6136,6 +6213,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, NETIF_F_HW_VLAN_TX | NETIF_F_TSO | NETIF_F_TSO6 | + NETIF_F_RXHASH | NETIF_F_RXCSUM | NETIF_F_HW_CSUM); -- cgit v1.2.3-70-g09d2 From 7ee913562fb7937595ba97f9b9adbf294b657d5b Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:45:35 +0000 Subject: e1000e: re-enable alternate MAC address for all devices which support it Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/lib.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/lib.c b/drivers/net/ethernet/intel/e1000e/lib.c index 0893ab107ad..78e3f4c0c36 100644 --- a/drivers/net/ethernet/intel/e1000e/lib.c +++ b/drivers/net/ethernet/intel/e1000e/lib.c @@ -187,11 +187,8 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) if (ret_val) goto out; - /* Check for LOM (vs. NIC) or one of two valid mezzanine cards */ - if (!((nvm_data & NVM_COMPAT_LOM) || - (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_DUAL) || - (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD) || - (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES))) + /* not supported on older hardware or 82573 */ + if ((hw->mac.type < e1000_82571) || (hw->mac.type == e1000_82573)) goto out; ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1, -- cgit v1.2.3-70-g09d2 From c5083cf6d286e4d3485eaf7904e5d60a2d9df6f5 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:45:40 +0000 Subject: e1000e: convert head, tail and itr_register offsets to __iomem pointers The Tx/Rx head and tail registers and itr_register are always at known addresses based on the __iomem address at which the PCI region (from BAR 0) is mapped and known offsets within the region for each of these registers. Store and use the full address rather than just the region offset to reduce unnecessary address calculations. Also, change current u8 __iomem pointers to void __iomem pointers. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/e1000.h | 6 ++-- drivers/net/ethernet/intel/e1000e/hw.h | 4 +-- drivers/net/ethernet/intel/e1000e/netdev.c | 53 +++++++++++++++--------------- 3 files changed, 31 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index f478a22ed57..f6ac1975166 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -242,8 +242,8 @@ struct e1000_ring { u16 next_to_use; u16 next_to_clean; - u16 head; - u16 tail; + void __iomem *head; + void __iomem *tail; /* array of buffer information structs */ struct e1000_buffer *buffer_info; @@ -251,7 +251,7 @@ struct e1000_ring { char name[IFNAMSIZ + 5]; u32 ims_val; u32 itr_val; - u16 itr_register; + void __iomem *itr_register; int set_itr; struct sk_buff *rx_skb_top; diff --git a/drivers/net/ethernet/intel/e1000e/hw.h b/drivers/net/ethernet/intel/e1000e/hw.h index 93c349ee565..a15da4712f8 100644 --- a/drivers/net/ethernet/intel/e1000e/hw.h +++ b/drivers/net/ethernet/intel/e1000e/hw.h @@ -969,8 +969,8 @@ struct e1000_dev_spec_ich8lan { struct e1000_hw { struct e1000_adapter *adapter; - u8 __iomem *hw_addr; - u8 __iomem *flash_address; + void __iomem *hw_addr; + void __iomem *flash_address; struct e1000_mac_info mac; struct e1000_fc_info fc; diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index b196d79e108..462bdeec90e 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -550,7 +550,7 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, * which has bit 24 set while ME is accessing Host CSR registers, wait * if it is set and try again a number of times. **/ -static inline s32 e1000e_update_tail_wa(struct e1000_hw *hw, u8 __iomem * tail, +static inline s32 e1000e_update_tail_wa(struct e1000_hw *hw, void __iomem *tail, unsigned int i) { unsigned int j = 0; @@ -569,10 +569,9 @@ static inline s32 e1000e_update_tail_wa(struct e1000_hw *hw, u8 __iomem * tail, static void e1000e_update_rdt_wa(struct e1000_adapter *adapter, unsigned int i) { - u8 __iomem *tail = (adapter->hw.hw_addr + adapter->rx_ring->tail); struct e1000_hw *hw = &adapter->hw; - if (e1000e_update_tail_wa(hw, tail, i)) { + if (e1000e_update_tail_wa(hw, adapter->rx_ring->tail, i)) { u32 rctl = er32(RCTL); ew32(RCTL, rctl & ~E1000_RCTL_EN); e_err("ME firmware caused invalid RDT - resetting\n"); @@ -582,10 +581,9 @@ static void e1000e_update_rdt_wa(struct e1000_adapter *adapter, unsigned int i) static void e1000e_update_tdt_wa(struct e1000_adapter *adapter, unsigned int i) { - u8 __iomem *tail = (adapter->hw.hw_addr + adapter->tx_ring->tail); struct e1000_hw *hw = &adapter->hw; - if (e1000e_update_tail_wa(hw, tail, i)) { + if (e1000e_update_tail_wa(hw, adapter->tx_ring->tail, i)) { u32 tctl = er32(TCTL); ew32(TCTL, tctl & ~E1000_TCTL_EN); e_err("ME firmware caused invalid TDT - resetting\n"); @@ -651,7 +649,7 @@ map_skb: if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) e1000e_update_rdt_wa(adapter, i); else - writel(i, adapter->hw.hw_addr + rx_ring->tail); + writel(i, rx_ring->tail); } i++; if (i == rx_ring->count) @@ -754,8 +752,7 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) e1000e_update_rdt_wa(adapter, i << 1); else - writel(i << 1, - adapter->hw.hw_addr + rx_ring->tail); + writel(i << 1, rx_ring->tail); } i++; @@ -841,7 +838,7 @@ check_page: if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) e1000e_update_rdt_wa(adapter, i); else - writel(i, adapter->hw.hw_addr + rx_ring->tail); + writel(i, rx_ring->tail); } } @@ -1076,8 +1073,8 @@ static void e1000_print_hw_hang(struct work_struct *work) "PHY 1000BASE-T Status <%x>\n" "PHY Extended Status <%x>\n" "PCI Status <%x>\n", - readl(adapter->hw.hw_addr + tx_ring->head), - readl(adapter->hw.hw_addr + tx_ring->tail), + readl(tx_ring->head), + readl(tx_ring->tail), tx_ring->next_to_use, tx_ring->next_to_clean, tx_ring->buffer_info[eop].time_stamp, @@ -1617,8 +1614,8 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter) rx_ring->next_to_use = 0; adapter->flags2 &= ~FLAG2_IS_DISCARDING; - writel(0, adapter->hw.hw_addr + rx_ring->head); - writel(0, adapter->hw.hw_addr + rx_ring->tail); + writel(0, rx_ring->head); + writel(0, rx_ring->tail); } static void e1000e_downshift_workaround(struct work_struct *work) @@ -1814,7 +1811,7 @@ static irqreturn_t e1000_intr_msix_rx(int irq, void *data) */ if (adapter->rx_ring->set_itr) { writel(1000000000 / (adapter->rx_ring->itr_val * 256), - adapter->hw.hw_addr + adapter->rx_ring->itr_register); + adapter->rx_ring->itr_register); adapter->rx_ring->set_itr = 0; } @@ -1855,9 +1852,9 @@ static void e1000_configure_msix(struct e1000_adapter *adapter) adapter->eiac_mask |= rx_ring->ims_val; if (rx_ring->itr_val) writel(1000000000 / (rx_ring->itr_val * 256), - hw->hw_addr + rx_ring->itr_register); + rx_ring->itr_register); else - writel(1, hw->hw_addr + rx_ring->itr_register); + writel(1, rx_ring->itr_register); ivar = E1000_IVAR_INT_ALLOC_VALID | vector; /* Configure Tx vector */ @@ -1865,9 +1862,9 @@ static void e1000_configure_msix(struct e1000_adapter *adapter) vector++; if (tx_ring->itr_val) writel(1000000000 / (tx_ring->itr_val * 256), - hw->hw_addr + tx_ring->itr_register); + tx_ring->itr_register); else - writel(1, hw->hw_addr + tx_ring->itr_register); + writel(1, tx_ring->itr_register); adapter->eiac_mask |= tx_ring->ims_val; ivar |= ((E1000_IVAR_INT_ALLOC_VALID | vector) << 8); @@ -1982,7 +1979,8 @@ static int e1000_request_msix(struct e1000_adapter *adapter) netdev); if (err) goto out; - adapter->rx_ring->itr_register = E1000_EITR_82574(vector); + adapter->rx_ring->itr_register = adapter->hw.hw_addr + + E1000_EITR_82574(vector); adapter->rx_ring->itr_val = adapter->itr; vector++; @@ -1997,7 +1995,8 @@ static int e1000_request_msix(struct e1000_adapter *adapter) netdev); if (err) goto out; - adapter->tx_ring->itr_register = E1000_EITR_82574(vector); + adapter->tx_ring->itr_register = adapter->hw.hw_addr + + E1000_EITR_82574(vector); adapter->tx_ring->itr_val = adapter->itr; vector++; @@ -2288,8 +2287,8 @@ static void e1000_clean_tx_ring(struct e1000_adapter *adapter) tx_ring->next_to_use = 0; tx_ring->next_to_clean = 0; - writel(0, adapter->hw.hw_addr + tx_ring->head); - writel(0, adapter->hw.hw_addr + tx_ring->tail); + writel(0, tx_ring->head); + writel(0, tx_ring->tail); } /** @@ -2773,8 +2772,8 @@ static void e1000_configure_tx(struct e1000_adapter *adapter) ew32(TDLEN, tdlen); ew32(TDH, 0); ew32(TDT, 0); - tx_ring->head = E1000_TDH; - tx_ring->tail = E1000_TDT; + tx_ring->head = adapter->hw.hw_addr + E1000_TDH; + tx_ring->tail = adapter->hw.hw_addr + E1000_TDT; /* Set the default values for the Tx Inter Packet Gap timer */ tipg = DEFAULT_82543_TIPG_IPGT_COPPER; /* 8 */ @@ -3088,8 +3087,8 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) ew32(RDLEN, rdlen); ew32(RDH, 0); ew32(RDT, 0); - rx_ring->head = E1000_RDH; - rx_ring->tail = E1000_RDT; + rx_ring->head = adapter->hw.hw_addr + E1000_RDH; + rx_ring->tail = adapter->hw.hw_addr + E1000_RDT; /* Enable Receive Checksum Offload for TCP and UDP */ rxcsum = er32(RXCSUM); @@ -4914,7 +4913,7 @@ static void e1000_tx_queue(struct e1000_adapter *adapter, if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) e1000e_update_tdt_wa(adapter, i); else - writel(i, adapter->hw.hw_addr + tx_ring->tail); + writel(i, tx_ring->tail); /* * we need this if more than one processor can write to our tail -- cgit v1.2.3-70-g09d2 From 55aa69854a93d7aaf123a882b0b1f93c86cf3c7e Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:45:45 +0000 Subject: e1000e: pass pointer to ring struct instead of adapter struct For ring-specific functions, pass a pointer to the ring struct instead of a pointer to the adapter struct. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/e1000.h | 21 +-- drivers/net/ethernet/intel/e1000e/ethtool.c | 10 +- drivers/net/ethernet/intel/e1000e/netdev.c | 232 ++++++++++++++-------------- 3 files changed, 136 insertions(+), 127 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index f6ac1975166..db604cdd998 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -234,6 +234,7 @@ struct e1000_buffer { }; struct e1000_ring { + struct e1000_adapter *adapter; /* back pointer to adapter */ void *desc; /* pointer to ring memory */ dma_addr_t dma; /* phys address of ring */ unsigned int size; /* length of ring in bytes */ @@ -334,11 +335,10 @@ struct e1000_adapter { /* * Rx */ - bool (*clean_rx) (struct e1000_adapter *adapter, - int *work_done, int work_to_do) - ____cacheline_aligned_in_smp; - void (*alloc_rx_buf) (struct e1000_adapter *adapter, - int cleaned_count, gfp_t gfp); + bool (*clean_rx) (struct e1000_ring *ring, int *work_done, + int work_to_do) ____cacheline_aligned_in_smp; + void (*alloc_rx_buf) (struct e1000_ring *ring, int cleaned_count, + gfp_t gfp); struct e1000_ring *rx_ring; u32 rx_int_delay; @@ -398,6 +398,9 @@ struct e1000_adapter { bool idle_check; int phy_hang_count; + + u16 tx_ring_count; + u16 rx_ring_count; }; struct e1000_info { @@ -492,10 +495,10 @@ extern void e1000e_down(struct e1000_adapter *adapter); extern void e1000e_reinit_locked(struct e1000_adapter *adapter); extern void e1000e_reset(struct e1000_adapter *adapter); extern void e1000e_power_up_phy(struct e1000_adapter *adapter); -extern int e1000e_setup_rx_resources(struct e1000_adapter *adapter); -extern int e1000e_setup_tx_resources(struct e1000_adapter *adapter); -extern void e1000e_free_rx_resources(struct e1000_adapter *adapter); -extern void e1000e_free_tx_resources(struct e1000_adapter *adapter); +extern int e1000e_setup_rx_resources(struct e1000_ring *ring); +extern int e1000e_setup_tx_resources(struct e1000_ring *ring); +extern void e1000e_free_rx_resources(struct e1000_ring *ring); +extern void e1000e_free_tx_resources(struct e1000_ring *ring); extern struct rtnl_link_stats64 *e1000e_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats); diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index 0a3137a791e..01c73aee7fd 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -656,10 +656,10 @@ static int e1000_set_ringparam(struct net_device *netdev, if (netif_running(adapter->netdev)) { /* Try to get new resources before deleting old */ - err = e1000e_setup_rx_resources(adapter); + err = e1000e_setup_rx_resources(rx_ring); if (err) goto err_setup_rx; - err = e1000e_setup_tx_resources(adapter); + err = e1000e_setup_tx_resources(tx_ring); if (err) goto err_setup_tx; @@ -669,8 +669,8 @@ static int e1000_set_ringparam(struct net_device *netdev, */ adapter->rx_ring = rx_old; adapter->tx_ring = tx_old; - e1000e_free_rx_resources(adapter); - e1000e_free_tx_resources(adapter); + e1000e_free_rx_resources(adapter->rx_ring); + e1000e_free_tx_resources(adapter->tx_ring); kfree(tx_old); kfree(rx_old); adapter->rx_ring = rx_ring; @@ -683,7 +683,7 @@ static int e1000_set_ringparam(struct net_device *netdev, clear_bit(__E1000_RESETTING, &adapter->state); return 0; err_setup_tx: - e1000e_free_rx_resources(adapter); + e1000e_free_rx_resources(rx_ring); err_setup_rx: adapter->rx_ring = rx_old; adapter->tx_ring = tx_old; diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 462bdeec90e..ffe4583994d 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -567,11 +567,12 @@ static inline s32 e1000e_update_tail_wa(struct e1000_hw *hw, void __iomem *tail, return 0; } -static void e1000e_update_rdt_wa(struct e1000_adapter *adapter, unsigned int i) +static void e1000e_update_rdt_wa(struct e1000_ring *rx_ring, unsigned int i) { + struct e1000_adapter *adapter = rx_ring->adapter; struct e1000_hw *hw = &adapter->hw; - if (e1000e_update_tail_wa(hw, adapter->rx_ring->tail, i)) { + if (e1000e_update_tail_wa(hw, rx_ring->tail, i)) { u32 rctl = er32(RCTL); ew32(RCTL, rctl & ~E1000_RCTL_EN); e_err("ME firmware caused invalid RDT - resetting\n"); @@ -579,11 +580,12 @@ static void e1000e_update_rdt_wa(struct e1000_adapter *adapter, unsigned int i) } } -static void e1000e_update_tdt_wa(struct e1000_adapter *adapter, unsigned int i) +static void e1000e_update_tdt_wa(struct e1000_ring *tx_ring, unsigned int i) { + struct e1000_adapter *adapter = tx_ring->adapter; struct e1000_hw *hw = &adapter->hw; - if (e1000e_update_tail_wa(hw, adapter->tx_ring->tail, i)) { + if (e1000e_update_tail_wa(hw, tx_ring->tail, i)) { u32 tctl = er32(TCTL); ew32(TCTL, tctl & ~E1000_TCTL_EN); e_err("ME firmware caused invalid TDT - resetting\n"); @@ -593,14 +595,14 @@ static void e1000e_update_tdt_wa(struct e1000_adapter *adapter, unsigned int i) /** * e1000_alloc_rx_buffers - Replace used receive buffers - * @adapter: address of board private structure + * @rx_ring: Rx descriptor ring **/ -static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter, +static void e1000_alloc_rx_buffers(struct e1000_ring *rx_ring, int cleaned_count, gfp_t gfp) { + struct e1000_adapter *adapter = rx_ring->adapter; struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; - struct e1000_ring *rx_ring = adapter->rx_ring; union e1000_rx_desc_extended *rx_desc; struct e1000_buffer *buffer_info; struct sk_buff *skb; @@ -647,7 +649,7 @@ map_skb: */ wmb(); if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) - e1000e_update_rdt_wa(adapter, i); + e1000e_update_rdt_wa(rx_ring, i); else writel(i, rx_ring->tail); } @@ -662,15 +664,15 @@ map_skb: /** * e1000_alloc_rx_buffers_ps - Replace used receive buffers; packet split - * @adapter: address of board private structure + * @rx_ring: Rx descriptor ring **/ -static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, +static void e1000_alloc_rx_buffers_ps(struct e1000_ring *rx_ring, int cleaned_count, gfp_t gfp) { + struct e1000_adapter *adapter = rx_ring->adapter; struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; union e1000_rx_desc_packet_split *rx_desc; - struct e1000_ring *rx_ring = adapter->rx_ring; struct e1000_buffer *buffer_info; struct e1000_ps_page *ps_page; struct sk_buff *skb; @@ -750,7 +752,7 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, */ wmb(); if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) - e1000e_update_rdt_wa(adapter, i << 1); + e1000e_update_rdt_wa(rx_ring, i << 1); else writel(i << 1, rx_ring->tail); } @@ -767,17 +769,17 @@ no_buffers: /** * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers - * @adapter: address of board private structure + * @rx_ring: Rx descriptor ring * @cleaned_count: number of buffers to allocate this pass **/ -static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter, +static void e1000_alloc_jumbo_rx_buffers(struct e1000_ring *rx_ring, int cleaned_count, gfp_t gfp) { + struct e1000_adapter *adapter = rx_ring->adapter; struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; union e1000_rx_desc_extended *rx_desc; - struct e1000_ring *rx_ring = adapter->rx_ring; struct e1000_buffer *buffer_info; struct sk_buff *skb; unsigned int i; @@ -836,7 +838,7 @@ check_page: * such as IA-64). */ wmb(); if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) - e1000e_update_rdt_wa(adapter, i); + e1000e_update_rdt_wa(rx_ring, i); else writel(i, rx_ring->tail); } @@ -850,19 +852,19 @@ static inline void e1000_rx_hash(struct net_device *netdev, __le32 rss, } /** - * e1000_clean_rx_irq - Send received data up the network stack; legacy - * @adapter: board private structure + * e1000_clean_rx_irq - Send received data up the network stack + * @rx_ring: Rx descriptor ring * * the return value indicates whether actual cleaning was done, there * is no guarantee that everything was cleaned **/ -static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, - int *work_done, int work_to_do) +static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done, + int work_to_do) { + struct e1000_adapter *adapter = rx_ring->adapter; struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; struct e1000_hw *hw = &adapter->hw; - struct e1000_ring *rx_ring = adapter->rx_ring; union e1000_rx_desc_extended *rx_desc, *next_rxd; struct e1000_buffer *buffer_info, *next_buffer; u32 length, staterr; @@ -978,7 +980,7 @@ next_desc: /* return some buffers to hardware, one at a time is too slow */ if (cleaned_count >= E1000_RX_BUFFER_WRITE) { - adapter->alloc_rx_buf(adapter, cleaned_count, + adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC); cleaned_count = 0; } @@ -993,16 +995,18 @@ next_desc: cleaned_count = e1000_desc_unused(rx_ring); if (cleaned_count) - adapter->alloc_rx_buf(adapter, cleaned_count, GFP_ATOMIC); + adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC); adapter->total_rx_bytes += total_rx_bytes; adapter->total_rx_packets += total_rx_packets; return cleaned; } -static void e1000_put_txbuf(struct e1000_adapter *adapter, - struct e1000_buffer *buffer_info) +static void e1000_put_txbuf(struct e1000_ring *tx_ring, + struct e1000_buffer *buffer_info) { + struct e1000_adapter *adapter = tx_ring->adapter; + if (buffer_info->dma) { if (buffer_info->mapped_as_page) dma_unmap_page(&adapter->pdev->dev, buffer_info->dma, @@ -1090,16 +1094,16 @@ static void e1000_print_hw_hang(struct work_struct *work) /** * e1000_clean_tx_irq - Reclaim resources after transmit completes - * @adapter: board private structure + * @tx_ring: Tx descriptor ring * * the return value indicates whether actual cleaning was done, there * is no guarantee that everything was cleaned **/ -static bool e1000_clean_tx_irq(struct e1000_adapter *adapter) +static bool e1000_clean_tx_irq(struct e1000_ring *tx_ring) { + struct e1000_adapter *adapter = tx_ring->adapter; struct net_device *netdev = adapter->netdev; struct e1000_hw *hw = &adapter->hw; - struct e1000_ring *tx_ring = adapter->tx_ring; struct e1000_tx_desc *tx_desc, *eop_desc; struct e1000_buffer *buffer_info; unsigned int i, eop; @@ -1129,7 +1133,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter) } } - e1000_put_txbuf(adapter, buffer_info); + e1000_put_txbuf(tx_ring, buffer_info); tx_desc->upper.data = 0; i++; @@ -1183,19 +1187,19 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter) /** * e1000_clean_rx_irq_ps - Send received data up the network stack; packet split - * @adapter: board private structure + * @rx_ring: Rx descriptor ring * * the return value indicates whether actual cleaning was done, there * is no guarantee that everything was cleaned **/ -static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, - int *work_done, int work_to_do) +static bool e1000_clean_rx_irq_ps(struct e1000_ring *rx_ring, int *work_done, + int work_to_do) { + struct e1000_adapter *adapter = rx_ring->adapter; struct e1000_hw *hw = &adapter->hw; union e1000_rx_desc_packet_split *rx_desc, *next_rxd; struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; - struct e1000_ring *rx_ring = adapter->rx_ring; struct e1000_buffer *buffer_info, *next_buffer; struct e1000_ps_page *ps_page; struct sk_buff *skb; @@ -1346,7 +1350,7 @@ next_desc: /* return some buffers to hardware, one at a time is too slow */ if (cleaned_count >= E1000_RX_BUFFER_WRITE) { - adapter->alloc_rx_buf(adapter, cleaned_count, + adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC); cleaned_count = 0; } @@ -1361,7 +1365,7 @@ next_desc: cleaned_count = e1000_desc_unused(rx_ring); if (cleaned_count) - adapter->alloc_rx_buf(adapter, cleaned_count, GFP_ATOMIC); + adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC); adapter->total_rx_bytes += total_rx_bytes; adapter->total_rx_packets += total_rx_packets; @@ -1387,13 +1391,12 @@ static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb, * the return value indicates whether actual cleaning was done, there * is no guarantee that everything was cleaned **/ - -static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, - int *work_done, int work_to_do) +static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done, + int work_to_do) { + struct e1000_adapter *adapter = rx_ring->adapter; struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; - struct e1000_ring *rx_ring = adapter->rx_ring; union e1000_rx_desc_extended *rx_desc, *next_rxd; struct e1000_buffer *buffer_info, *next_buffer; u32 length, staterr; @@ -1526,7 +1529,7 @@ next_desc: /* return some buffers to hardware, one at a time is too slow */ if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) { - adapter->alloc_rx_buf(adapter, cleaned_count, + adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC); cleaned_count = 0; } @@ -1541,7 +1544,7 @@ next_desc: cleaned_count = e1000_desc_unused(rx_ring); if (cleaned_count) - adapter->alloc_rx_buf(adapter, cleaned_count, GFP_ATOMIC); + adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC); adapter->total_rx_bytes += total_rx_bytes; adapter->total_rx_packets += total_rx_packets; @@ -1550,11 +1553,11 @@ next_desc: /** * e1000_clean_rx_ring - Free Rx Buffers per Queue - * @adapter: board private structure + * @rx_ring: Rx descriptor ring **/ -static void e1000_clean_rx_ring(struct e1000_adapter *adapter) +static void e1000_clean_rx_ring(struct e1000_ring *rx_ring) { - struct e1000_ring *rx_ring = adapter->rx_ring; + struct e1000_adapter *adapter = rx_ring->adapter; struct e1000_buffer *buffer_info; struct e1000_ps_page *ps_page; struct pci_dev *pdev = adapter->pdev; @@ -1794,7 +1797,7 @@ static irqreturn_t e1000_intr_msix_tx(int irq, void *data) adapter->total_tx_bytes = 0; adapter->total_tx_packets = 0; - if (!e1000_clean_tx_irq(adapter)) + if (!e1000_clean_tx_irq(tx_ring)) /* Ring was not completely cleaned, so fire another interrupt */ ew32(ICS, tx_ring->ims_val); @@ -1805,14 +1808,15 @@ static irqreturn_t e1000_intr_msix_rx(int irq, void *data) { struct net_device *netdev = data; struct e1000_adapter *adapter = netdev_priv(netdev); + struct e1000_ring *rx_ring = adapter->rx_ring; /* Write the ITR value calculated at the end of the * previous interrupt. */ - if (adapter->rx_ring->set_itr) { - writel(1000000000 / (adapter->rx_ring->itr_val * 256), - adapter->rx_ring->itr_register); - adapter->rx_ring->set_itr = 0; + if (rx_ring->set_itr) { + writel(1000000000 / (rx_ring->itr_val * 256), + rx_ring->itr_register); + rx_ring->set_itr = 0; } if (napi_schedule_prep(&adapter->napi)) { @@ -2177,13 +2181,13 @@ static int e1000_alloc_ring_dma(struct e1000_adapter *adapter, /** * e1000e_setup_tx_resources - allocate Tx resources (Descriptors) - * @adapter: board private structure + * @tx_ring: Tx descriptor ring * * Return 0 on success, negative on failure **/ -int e1000e_setup_tx_resources(struct e1000_adapter *adapter) +int e1000e_setup_tx_resources(struct e1000_ring *tx_ring) { - struct e1000_ring *tx_ring = adapter->tx_ring; + struct e1000_adapter *adapter = tx_ring->adapter; int err = -ENOMEM, size; size = sizeof(struct e1000_buffer) * tx_ring->count; @@ -2211,13 +2215,13 @@ err: /** * e1000e_setup_rx_resources - allocate Rx resources (Descriptors) - * @adapter: board private structure + * @rx_ring: Rx descriptor ring * * Returns 0 on success, negative on failure **/ -int e1000e_setup_rx_resources(struct e1000_adapter *adapter) +int e1000e_setup_rx_resources(struct e1000_ring *rx_ring) { - struct e1000_ring *rx_ring = adapter->rx_ring; + struct e1000_adapter *adapter = rx_ring->adapter; struct e1000_buffer *buffer_info; int i, size, desc_len, err = -ENOMEM; @@ -2264,18 +2268,18 @@ err: /** * e1000_clean_tx_ring - Free Tx Buffers - * @adapter: board private structure + * @tx_ring: Tx descriptor ring **/ -static void e1000_clean_tx_ring(struct e1000_adapter *adapter) +static void e1000_clean_tx_ring(struct e1000_ring *tx_ring) { - struct e1000_ring *tx_ring = adapter->tx_ring; + struct e1000_adapter *adapter = tx_ring->adapter; struct e1000_buffer *buffer_info; unsigned long size; unsigned int i; for (i = 0; i < tx_ring->count; i++) { buffer_info = &tx_ring->buffer_info[i]; - e1000_put_txbuf(adapter, buffer_info); + e1000_put_txbuf(tx_ring, buffer_info); } netdev_reset_queue(adapter->netdev); @@ -2293,16 +2297,16 @@ static void e1000_clean_tx_ring(struct e1000_adapter *adapter) /** * e1000e_free_tx_resources - Free Tx Resources per Queue - * @adapter: board private structure + * @tx_ring: Tx descriptor ring * * Free all transmit software resources **/ -void e1000e_free_tx_resources(struct e1000_adapter *adapter) +void e1000e_free_tx_resources(struct e1000_ring *tx_ring) { + struct e1000_adapter *adapter = tx_ring->adapter; struct pci_dev *pdev = adapter->pdev; - struct e1000_ring *tx_ring = adapter->tx_ring; - e1000_clean_tx_ring(adapter); + e1000_clean_tx_ring(tx_ring); vfree(tx_ring->buffer_info); tx_ring->buffer_info = NULL; @@ -2314,18 +2318,17 @@ void e1000e_free_tx_resources(struct e1000_adapter *adapter) /** * e1000e_free_rx_resources - Free Rx Resources - * @adapter: board private structure + * @rx_ring: Rx descriptor ring * * Free all receive software resources **/ - -void e1000e_free_rx_resources(struct e1000_adapter *adapter) +void e1000e_free_rx_resources(struct e1000_ring *rx_ring) { + struct e1000_adapter *adapter = rx_ring->adapter; struct pci_dev *pdev = adapter->pdev; - struct e1000_ring *rx_ring = adapter->rx_ring; int i; - e1000_clean_rx_ring(adapter); + e1000_clean_rx_ring(rx_ring); for (i = 0; i < rx_ring->count; i++) kfree(rx_ring->buffer_info[i].ps_pages); @@ -2479,13 +2482,19 @@ set_itr_now: **/ static int __devinit e1000_alloc_queues(struct e1000_adapter *adapter) { - adapter->tx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL); + int size = sizeof(struct e1000_ring); + + adapter->tx_ring = kzalloc(size, GFP_KERNEL); if (!adapter->tx_ring) goto err; + adapter->tx_ring->count = adapter->tx_ring_count; + adapter->tx_ring->adapter = adapter; - adapter->rx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL); + adapter->rx_ring = kzalloc(size, GFP_KERNEL); if (!adapter->rx_ring) goto err; + adapter->rx_ring->count = adapter->rx_ring_count; + adapter->rx_ring->adapter = adapter; return 0; err: @@ -2513,10 +2522,10 @@ static int e1000_clean(struct napi_struct *napi, int budget) !(adapter->rx_ring->ims_val & adapter->tx_ring->ims_val)) goto clean_rx; - tx_cleaned = e1000_clean_tx_irq(adapter); + tx_cleaned = e1000_clean_tx_irq(adapter->tx_ring); clean_rx: - adapter->clean_rx(adapter, &work_done, budget); + adapter->clean_rx(adapter->rx_ring, &work_done, budget); if (!tx_cleaned) work_done = budget; @@ -3325,6 +3334,8 @@ static void e1000e_setup_rss_hash(struct e1000_adapter *adapter) **/ static void e1000_configure(struct e1000_adapter *adapter) { + struct e1000_ring *rx_ring = adapter->rx_ring; + e1000e_set_rx_mode(adapter->netdev); e1000_restore_vlan(adapter); @@ -3336,8 +3347,7 @@ static void e1000_configure(struct e1000_adapter *adapter) e1000e_setup_rss_hash(adapter); e1000_setup_rctl(adapter); e1000_configure_rx(adapter); - adapter->alloc_rx_buf(adapter, e1000_desc_unused(adapter->rx_ring), - GFP_KERNEL); + adapter->alloc_rx_buf(rx_ring, e1000_desc_unused(rx_ring), GFP_KERNEL); } /** @@ -3647,8 +3657,8 @@ void e1000e_down(struct e1000_adapter *adapter) spin_unlock(&adapter->stats64_lock); e1000e_flush_descriptors(adapter); - e1000_clean_tx_ring(adapter); - e1000_clean_rx_ring(adapter); + e1000_clean_tx_ring(adapter->tx_ring); + e1000_clean_rx_ring(adapter->rx_ring); adapter->link_speed = 0; adapter->link_duplex = 0; @@ -3688,6 +3698,8 @@ static int __devinit e1000_sw_init(struct e1000_adapter *adapter) adapter->rx_ps_bsize0 = 128; adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN; + adapter->tx_ring_count = E1000_DEFAULT_TXD; + adapter->rx_ring_count = E1000_DEFAULT_RXD; spin_lock_init(&adapter->stats64_lock); @@ -3846,12 +3858,12 @@ static int e1000_open(struct net_device *netdev) netif_carrier_off(netdev); /* allocate transmit descriptors */ - err = e1000e_setup_tx_resources(adapter); + err = e1000e_setup_tx_resources(adapter->tx_ring); if (err) goto err_setup_tx; /* allocate receive descriptors */ - err = e1000e_setup_rx_resources(adapter); + err = e1000e_setup_rx_resources(adapter->rx_ring); if (err) goto err_setup_rx; @@ -3927,9 +3939,9 @@ static int e1000_open(struct net_device *netdev) err_req_irq: e1000e_release_hw_control(adapter); e1000_power_down_phy(adapter); - e1000e_free_rx_resources(adapter); + e1000e_free_rx_resources(adapter->rx_ring); err_setup_rx: - e1000e_free_tx_resources(adapter); + e1000e_free_tx_resources(adapter->tx_ring); err_setup_tx: e1000e_reset(adapter); pm_runtime_put_sync(&pdev->dev); @@ -3965,8 +3977,8 @@ static int e1000_close(struct net_device *netdev) } e1000_power_down_phy(adapter); - e1000e_free_tx_resources(adapter); - e1000e_free_rx_resources(adapter); + e1000e_free_tx_resources(adapter->tx_ring); + e1000e_free_rx_resources(adapter->rx_ring); /* * kill manageability vlan ID if supported, but not if a vlan with @@ -4623,10 +4635,8 @@ link_up: #define E1000_TX_FLAGS_VLAN_MASK 0xffff0000 #define E1000_TX_FLAGS_VLAN_SHIFT 16 -static int e1000_tso(struct e1000_adapter *adapter, - struct sk_buff *skb) +static int e1000_tso(struct e1000_ring *tx_ring, struct sk_buff *skb) { - struct e1000_ring *tx_ring = adapter->tx_ring; struct e1000_context_desc *context_desc; struct e1000_buffer *buffer_info; unsigned int i; @@ -4695,9 +4705,9 @@ static int e1000_tso(struct e1000_adapter *adapter, return 1; } -static bool e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb) +static bool e1000_tx_csum(struct e1000_ring *tx_ring, struct sk_buff *skb) { - struct e1000_ring *tx_ring = adapter->tx_ring; + struct e1000_adapter *adapter = tx_ring->adapter; struct e1000_context_desc *context_desc; struct e1000_buffer *buffer_info; unsigned int i; @@ -4758,12 +4768,11 @@ static bool e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb) #define E1000_MAX_PER_TXD 8192 #define E1000_MAX_TXD_PWR 12 -static int e1000_tx_map(struct e1000_adapter *adapter, - struct sk_buff *skb, unsigned int first, - unsigned int max_per_txd, unsigned int nr_frags, - unsigned int mss) +static int e1000_tx_map(struct e1000_ring *tx_ring, struct sk_buff *skb, + unsigned int first, unsigned int max_per_txd, + unsigned int nr_frags, unsigned int mss) { - struct e1000_ring *tx_ring = adapter->tx_ring; + struct e1000_adapter *adapter = tx_ring->adapter; struct pci_dev *pdev = adapter->pdev; struct e1000_buffer *buffer_info; unsigned int len = skb_headlen(skb); @@ -4849,16 +4858,15 @@ dma_error: i += tx_ring->count; i--; buffer_info = &tx_ring->buffer_info[i]; - e1000_put_txbuf(adapter, buffer_info); + e1000_put_txbuf(tx_ring, buffer_info); } return 0; } -static void e1000_tx_queue(struct e1000_adapter *adapter, - int tx_flags, int count) +static void e1000_tx_queue(struct e1000_ring *tx_ring, int tx_flags, int count) { - struct e1000_ring *tx_ring = adapter->tx_ring; + struct e1000_adapter *adapter = tx_ring->adapter; struct e1000_tx_desc *tx_desc = NULL; struct e1000_buffer *buffer_info; u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS; @@ -4911,7 +4919,7 @@ static void e1000_tx_queue(struct e1000_adapter *adapter, tx_ring->next_to_use = i; if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) - e1000e_update_tdt_wa(adapter, i); + e1000e_update_tdt_wa(tx_ring, i); else writel(i, tx_ring->tail); @@ -4961,11 +4969,11 @@ static int e1000_transfer_dhcp_info(struct e1000_adapter *adapter, return 0; } -static int __e1000_maybe_stop_tx(struct net_device *netdev, int size) +static int __e1000_maybe_stop_tx(struct e1000_ring *tx_ring, int size) { - struct e1000_adapter *adapter = netdev_priv(netdev); + struct e1000_adapter *adapter = tx_ring->adapter; - netif_stop_queue(netdev); + netif_stop_queue(adapter->netdev); /* * Herbert's original patch had: * smp_mb__after_netif_stop_queue(); @@ -4977,22 +4985,20 @@ static int __e1000_maybe_stop_tx(struct net_device *netdev, int size) * We need to check again in a case another CPU has just * made room available. */ - if (e1000_desc_unused(adapter->tx_ring) < size) + if (e1000_desc_unused(tx_ring) < size) return -EBUSY; /* A reprieve! */ - netif_start_queue(netdev); + netif_start_queue(adapter->netdev); ++adapter->restart_queue; return 0; } -static int e1000_maybe_stop_tx(struct net_device *netdev, int size) +static int e1000_maybe_stop_tx(struct e1000_ring *tx_ring, int size) { - struct e1000_adapter *adapter = netdev_priv(netdev); - - if (e1000_desc_unused(adapter->tx_ring) >= size) + if (e1000_desc_unused(tx_ring) >= size) return 0; - return __e1000_maybe_stop_tx(netdev, size); + return __e1000_maybe_stop_tx(tx_ring, size); } #define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 ) @@ -5078,7 +5084,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, * need: count + 2 desc gap to keep tail from touching * head, otherwise try next time */ - if (e1000_maybe_stop_tx(netdev, count + 2)) + if (e1000_maybe_stop_tx(tx_ring, count + 2)) return NETDEV_TX_BUSY; if (vlan_tx_tag_present(skb)) { @@ -5088,7 +5094,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, first = tx_ring->next_to_use; - tso = e1000_tso(adapter, skb); + tso = e1000_tso(tx_ring, skb); if (tso < 0) { dev_kfree_skb_any(skb); return NETDEV_TX_OK; @@ -5096,7 +5102,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, if (tso) tx_flags |= E1000_TX_FLAGS_TSO; - else if (e1000_tx_csum(adapter, skb)) + else if (e1000_tx_csum(tx_ring, skb)) tx_flags |= E1000_TX_FLAGS_CSUM; /* @@ -5108,12 +5114,12 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, tx_flags |= E1000_TX_FLAGS_IPV4; /* if count is 0 then mapping error has occurred */ - count = e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss); + count = e1000_tx_map(tx_ring, skb, first, max_per_txd, nr_frags, mss); if (count) { netdev_sent_queue(netdev, skb->len); - e1000_tx_queue(adapter, tx_flags, count); + e1000_tx_queue(tx_ring, tx_flags, count); /* Make sure there is space in the ring for the next send. */ - e1000_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 2); + e1000_maybe_stop_tx(tx_ring, MAX_SKB_FRAGS + 2); } else { dev_kfree_skb_any(skb); -- cgit v1.2.3-70-g09d2 From 508da4264add2eb13bd4d32bb896e79e6f8821fc Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:45:51 +0000 Subject: e1000e: re-factor ethtool get/set ring parameter Make it more like how igb does it, with some additional error checking. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/ethtool.c | 136 ++++++++++++++++------------ 1 file changed, 77 insertions(+), 59 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index 01c73aee7fd..ffb6c14cbbb 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -605,94 +605,112 @@ static void e1000_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring) { struct e1000_adapter *adapter = netdev_priv(netdev); - struct e1000_ring *tx_ring = adapter->tx_ring; - struct e1000_ring *rx_ring = adapter->rx_ring; ring->rx_max_pending = E1000_MAX_RXD; ring->tx_max_pending = E1000_MAX_TXD; - ring->rx_pending = rx_ring->count; - ring->tx_pending = tx_ring->count; + ring->rx_pending = adapter->rx_ring_count; + ring->tx_pending = adapter->tx_ring_count; } static int e1000_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring) { struct e1000_adapter *adapter = netdev_priv(netdev); - struct e1000_ring *tx_ring, *tx_old; - struct e1000_ring *rx_ring, *rx_old; - int err; + struct e1000_ring *temp_tx = NULL, *temp_rx = NULL; + int err = 0, size = sizeof(struct e1000_ring); + bool set_tx = false, set_rx = false; + u16 new_rx_count, new_tx_count; if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) return -EINVAL; - while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) - usleep_range(1000, 2000); + new_rx_count = clamp_t(u32, ring->rx_pending, E1000_MIN_RXD, + E1000_MAX_RXD); + new_rx_count = ALIGN(new_rx_count, REQ_RX_DESCRIPTOR_MULTIPLE); - if (netif_running(adapter->netdev)) - e1000e_down(adapter); + new_tx_count = clamp_t(u32, ring->tx_pending, E1000_MIN_TXD, + E1000_MAX_TXD); + new_tx_count = ALIGN(new_tx_count, REQ_TX_DESCRIPTOR_MULTIPLE); - tx_old = adapter->tx_ring; - rx_old = adapter->rx_ring; + if ((new_tx_count == adapter->tx_ring_count) && + (new_rx_count == adapter->rx_ring_count)) + /* nothing to do */ + return 0; - err = -ENOMEM; - tx_ring = kmemdup(tx_old, sizeof(struct e1000_ring), GFP_KERNEL); - if (!tx_ring) - goto err_alloc_tx; + while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) + usleep_range(1000, 2000); - rx_ring = kmemdup(rx_old, sizeof(struct e1000_ring), GFP_KERNEL); - if (!rx_ring) - goto err_alloc_rx; + if (!netif_running(adapter->netdev)) { + /* Set counts now and allocate resources during open() */ + adapter->tx_ring->count = new_tx_count; + adapter->rx_ring->count = new_rx_count; + adapter->tx_ring_count = new_tx_count; + adapter->rx_ring_count = new_rx_count; + goto clear_reset; + } - adapter->tx_ring = tx_ring; - adapter->rx_ring = rx_ring; + set_tx = (new_tx_count != adapter->tx_ring_count); + set_rx = (new_rx_count != adapter->rx_ring_count); - rx_ring->count = max(ring->rx_pending, (u32)E1000_MIN_RXD); - rx_ring->count = min(rx_ring->count, (u32)(E1000_MAX_RXD)); - rx_ring->count = ALIGN(rx_ring->count, REQ_RX_DESCRIPTOR_MULTIPLE); + /* Allocate temporary storage for ring updates */ + if (set_tx) { + temp_tx = vmalloc(size); + if (!temp_tx) { + err = -ENOMEM; + goto free_temp; + } + } + if (set_rx) { + temp_rx = vmalloc(size); + if (!temp_rx) { + err = -ENOMEM; + goto free_temp; + } + } - tx_ring->count = max(ring->tx_pending, (u32)E1000_MIN_TXD); - tx_ring->count = min(tx_ring->count, (u32)(E1000_MAX_TXD)); - tx_ring->count = ALIGN(tx_ring->count, REQ_TX_DESCRIPTOR_MULTIPLE); + e1000e_down(adapter); - if (netif_running(adapter->netdev)) { - /* Try to get new resources before deleting old */ - err = e1000e_setup_rx_resources(rx_ring); + /* + * We can't just free everything and then setup again, because the + * ISRs in MSI-X mode get passed pointers to the Tx and Rx ring + * structs. First, attempt to allocate new resources... + */ + if (set_tx) { + memcpy(temp_tx, adapter->tx_ring, size); + temp_tx->count = new_tx_count; + err = e1000e_setup_tx_resources(temp_tx); if (err) - goto err_setup_rx; - err = e1000e_setup_tx_resources(tx_ring); + goto err_setup; + } + if (set_rx) { + memcpy(temp_rx, adapter->rx_ring, size); + temp_rx->count = new_rx_count; + err = e1000e_setup_rx_resources(temp_rx); if (err) - goto err_setup_tx; + goto err_setup_rx; + } - /* - * restore the old in order to free it, - * then add in the new - */ - adapter->rx_ring = rx_old; - adapter->tx_ring = tx_old; - e1000e_free_rx_resources(adapter->rx_ring); + /* ...then free the old resources and copy back any new ring data */ + if (set_tx) { e1000e_free_tx_resources(adapter->tx_ring); - kfree(tx_old); - kfree(rx_old); - adapter->rx_ring = rx_ring; - adapter->tx_ring = tx_ring; - err = e1000e_up(adapter); - if (err) - goto err_setup; + memcpy(adapter->tx_ring, temp_tx, size); + adapter->tx_ring_count = new_tx_count; + } + if (set_rx) { + e1000e_free_rx_resources(adapter->rx_ring); + memcpy(adapter->rx_ring, temp_rx, size); + adapter->rx_ring_count = new_rx_count; } - clear_bit(__E1000_RESETTING, &adapter->state); - return 0; -err_setup_tx: - e1000e_free_rx_resources(rx_ring); err_setup_rx: - adapter->rx_ring = rx_old; - adapter->tx_ring = tx_old; - kfree(rx_ring); -err_alloc_rx: - kfree(tx_ring); -err_alloc_tx: - e1000e_up(adapter); + if (err && set_tx) + e1000e_free_tx_resources(temp_tx); err_setup: + e1000e_up(adapter); +free_temp: + vfree(temp_tx); + vfree(temp_rx); +clear_reset: clear_bit(__E1000_RESETTING, &adapter->state); return err; } -- cgit v1.2.3-70-g09d2 From b6fbca2af36530ef307069cff0fe3b1f387c00a9 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:45:56 +0000 Subject: e1000e: default IntMode based on kernel config & available hardware support Based on a patch from Prabhakar Kushwaha , set appropriate default interrupt mode dependent on whether CONFIG_PCI_MSI is enabled in the kernel configuration and if the hardware supports MSI-X. Set the module parameter log message accordingly. Signed-off-by: Bruce Allan Cc: Jin Qing Cc: Prabhakar Kushwaha Cc: Jin Qing Cc: Kumar Gala Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/param.c | 48 ++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/param.c b/drivers/net/ethernet/intel/e1000e/param.c index 20e93b08e7f..40664f5bfbd 100644 --- a/drivers/net/ethernet/intel/e1000e/param.c +++ b/drivers/net/ethernet/intel/e1000e/param.c @@ -113,11 +113,20 @@ E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate"); #define MAX_ITR 100000 #define MIN_ITR 100 -/* IntMode (Interrupt Mode) +/* + * IntMode (Interrupt Mode) + * + * Valid Range: varies depending on kernel configuration & hardware support + * + * legacy=0, MSI=1, MSI-X=2 * - * Valid Range: 0 - 2 + * When MSI/MSI-X support is enabled in kernel- + * Default Value: 2 (MSI-X) when supported by hardware, 1 (MSI) otherwise + * When MSI/MSI-X support is not enabled in kernel- + * Default Value: 0 (legacy) * - * Default Value: 2 (MSI-X) + * When a mode is specified that is not allowed/supported, it will be + * demoted to the most advanced interrupt mode available. */ E1000_PARAM(IntMode, "Interrupt Mode"); #define MAX_INTMODE 2 @@ -388,12 +397,33 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter) static struct e1000_option opt = { .type = range_option, .name = "Interrupt Mode", - .err = "defaulting to 2 (MSI-X)", - .def = E1000E_INT_MODE_MSIX, - .arg = { .r = { .min = MIN_INTMODE, - .max = MAX_INTMODE } } +#ifndef CONFIG_PCI_MSI + .err = "defaulting to 0 (legacy)", + .def = E1000E_INT_MODE_LEGACY, + .arg = { .r = { .min = 0, + .max = 0 } } +#endif }; +#ifdef CONFIG_PCI_MSI + if (adapter->flags & FLAG_HAS_MSIX) { + opt.err = kstrdup("defaulting to 2 (MSI-X)", + GFP_KERNEL); + opt.def = E1000E_INT_MODE_MSIX; + opt.arg.r.max = E1000E_INT_MODE_MSIX; + } else { + opt.err = kstrdup("defaulting to 1 (MSI)", GFP_KERNEL); + opt.def = E1000E_INT_MODE_MSI; + opt.arg.r.max = E1000E_INT_MODE_MSI; + } + + if (!opt.err) { + dev_err(&adapter->pdev->dev, + "Failed to allocate memory\n"); + return; + } +#endif + if (num_IntMode > bd) { unsigned int int_mode = IntMode[bd]; e1000_validate_option(&int_mode, &opt, adapter); @@ -401,6 +431,10 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter) } else { adapter->int_mode = opt.def; } + +#ifdef CONFIG_PCI_MSI + kfree(opt.err); +#endif } { /* Smart Power Down */ static const struct e1000_option opt = { -- cgit v1.2.3-70-g09d2 From 56032be77c7eab50e2020247ffa35ca61850503f Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:46:01 +0000 Subject: e1000e: always set transmit descriptor control registers the same The hardware erratum workaround where the TXDCTL register must be the same setting for both queues should always be done. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/netdev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index ffe4583994d..6081dee5ce4 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -2817,9 +2817,9 @@ static void e1000_configure_tx(struct e1000_adapter *adapter) */ txdctl |= E1000_TXDCTL_DMA_BURST_ENABLE; ew32(TXDCTL(0), txdctl); - /* erratum work around: set txdctl the same for both queues */ - ew32(TXDCTL(1), txdctl); } + /* erratum work around: set txdctl the same for both queues */ + ew32(TXDCTL(1), er32(TXDCTL(0))); /* Program the Transmit Control Register */ tctl = er32(TCTL); -- cgit v1.2.3-70-g09d2 From 4d24136c8ea03ecfdb6b8256571da8b520b92d8b Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:46:06 +0000 Subject: e1000e: 82579: workaround for link drop issue When connected to certain switches, the 82579 PHY might drop link unexpectedly. Work around the issue by setting the Mean Square Error higher than the hardware default. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/ich8lan.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index e2a80a283fd..1b69c2d6b41 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -145,6 +145,8 @@ #define I82579_EMI_ADDR 0x10 #define I82579_EMI_DATA 0x11 #define I82579_LPI_UPDATE_TIMER 0x4805 /* in 40ns units + 40 ns base value */ +#define I82579_MSE_THRESHOLD 0x084F /* Mean Square Error Threshold */ +#define I82579_MSE_LINK_DOWN 0x2411 /* MSE count before dropping link */ /* Strapping Option Register - RO */ #define E1000_STRAP 0x0000C @@ -1669,6 +1671,26 @@ static s32 e1000_lv_phy_workarounds_ich8lan(struct e1000_hw *hw) /* Set MDIO slow mode before any other MDIO access */ ret_val = e1000_set_mdio_slow_mode_hv(hw); + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + goto out; + ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_ADDR, + I82579_MSE_THRESHOLD); + if (ret_val) + goto release; + /* set MSE higher to enable link to stay up when noise is high */ + ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_DATA, 0x0034); + if (ret_val) + goto release; + ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_ADDR, + I82579_MSE_LINK_DOWN); + if (ret_val) + goto release; + /* drop link after 5 times MSE threshold was reached */ + ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_DATA, 0x0005); +release: + hw->phy.ops.release(hw); + out: return ret_val; } -- cgit v1.2.3-70-g09d2 From 6a92f732f557401ca8cc0b16f8e8914c133cf6c6 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:46:12 +0000 Subject: e1000e: use default settings for Tx Inter Packet Gap timer Use the default hardware values for TIPG except for 80003es2lan(*). The code that is removed in this patch is either unnecessarily writing the TIPG register with the hardware default values for some devices (82571/2/3/4) or writing the wrong value for others (ICH/PCH LOMs). The only change in functionality is setting the correct default TIPG for the latter devices. (*) The correct value for 80003es2lan is already set properly in e1000_init_hw_80003es2lan() and e1000_cfg_kmrn_{10_100|1000}_80003es2lan(), and the unused flag FLAG_TIPG_MEDIUM_FOR_80003ESLAN is removed. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/80003es2lan.c | 3 +-- drivers/net/ethernet/intel/e1000e/e1000.h | 2 +- drivers/net/ethernet/intel/e1000e/netdev.c | 15 +-------------- 3 files changed, 3 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/80003es2lan.c b/drivers/net/ethernet/intel/e1000e/80003es2lan.c index e1159e54334..b3a235c8ed8 100644 --- a/drivers/net/ethernet/intel/e1000e/80003es2lan.c +++ b/drivers/net/ethernet/intel/e1000e/80003es2lan.c @@ -1502,8 +1502,7 @@ const struct e1000_info e1000_es2_info = { | FLAG_RX_NEEDS_RESTART /* errata */ | FLAG_TARC_SET_BIT_ZERO /* errata */ | FLAG_APME_CHECK_PORT_B - | FLAG_DISABLE_FC_PAUSE_TIME /* errata */ - | FLAG_TIPG_MEDIUM_FOR_80003ESLAN, + | FLAG_DISABLE_FC_PAUSE_TIME, /* errata */ .flags2 = FLAG2_DMA_BURST, .pba = 38, .max_hw_frame_size = DEFAULT_JUMBO, diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index db604cdd998..4b3a27670a6 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -430,7 +430,7 @@ struct e1000_info { #define FLAG_HAS_SMART_POWER_DOWN (1 << 11) #define FLAG_IS_QUAD_PORT_A (1 << 12) #define FLAG_IS_QUAD_PORT (1 << 13) -#define FLAG_TIPG_MEDIUM_FOR_80003ESLAN (1 << 14) +/* reserved bit14 */ #define FLAG_APME_IN_WUC (1 << 15) #define FLAG_APME_IN_CTRL3 (1 << 16) #define FLAG_APME_CHECK_PORT_B (1 << 17) diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 6081dee5ce4..fb299905b1f 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -2770,8 +2770,7 @@ static void e1000_configure_tx(struct e1000_adapter *adapter) struct e1000_hw *hw = &adapter->hw; struct e1000_ring *tx_ring = adapter->tx_ring; u64 tdba; - u32 tdlen, tctl, tipg, tarc; - u32 ipgr1, ipgr2; + u32 tdlen, tctl, tarc; /* Setup the HW Tx Head and Tail descriptor pointers */ tdba = tx_ring->dma; @@ -2784,18 +2783,6 @@ static void e1000_configure_tx(struct e1000_adapter *adapter) tx_ring->head = adapter->hw.hw_addr + E1000_TDH; tx_ring->tail = adapter->hw.hw_addr + E1000_TDT; - /* Set the default values for the Tx Inter Packet Gap timer */ - tipg = DEFAULT_82543_TIPG_IPGT_COPPER; /* 8 */ - ipgr1 = DEFAULT_82543_TIPG_IPGR1; /* 8 */ - ipgr2 = DEFAULT_82543_TIPG_IPGR2; /* 6 */ - - if (adapter->flags & FLAG_TIPG_MEDIUM_FOR_80003ESLAN) - ipgr2 = DEFAULT_80003ES2LAN_TIPG_IPGR2; /* 7 */ - - tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT; - tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT; - ew32(TIPG, tipg); - /* Set the Tx Interrupt Delay register */ ew32(TIDV, adapter->tx_int_delay); /* Tx irq moderation */ -- cgit v1.2.3-70-g09d2 From c550b121854eb1300148da1c2c8df6ed0dabdc66 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:46:17 +0000 Subject: e1000e: use hardware default values for Transmit Control register This code snippet is simply writing default values to the register which is unnecessary since the values are programmed into the register by default. There is a special case for 80003es2lan needing the Retransmit on Late Collision bit set but that is also done in e1000_init_hw_80003es2lan(). Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/netdev.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index fb299905b1f..89af6c02623 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -2770,7 +2770,7 @@ static void e1000_configure_tx(struct e1000_adapter *adapter) struct e1000_hw *hw = &adapter->hw; struct e1000_ring *tx_ring = adapter->tx_ring; u64 tdba; - u32 tdlen, tctl, tarc; + u32 tdlen, tarc; /* Setup the HW Tx Head and Tail descriptor pointers */ tdba = tx_ring->dma; @@ -2808,12 +2808,6 @@ static void e1000_configure_tx(struct e1000_adapter *adapter) /* erratum work around: set txdctl the same for both queues */ ew32(TXDCTL(1), er32(TXDCTL(0))); - /* Program the Transmit Control Register */ - tctl = er32(TCTL); - tctl &= ~E1000_TCTL_CT; - tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC | - (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT); - if (adapter->flags & FLAG_TARC_SPEED_MODE_BIT) { tarc = er32(TARC(0)); /* @@ -2845,8 +2839,6 @@ static void e1000_configure_tx(struct e1000_adapter *adapter) /* enable Report Status bit */ adapter->txd_cmd |= E1000_TXD_CMD_RS; - ew32(TCTL, tctl); - e1000e_config_collision_dist(hw); } -- cgit v1.2.3-70-g09d2 From d6cb17d5f8015717f6963d24d52b06292a4cb40a Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:46:22 +0000 Subject: e1000e: 82574/82583 Tx hang workaround On 82574/82583, there is a hardware bug which might cause a Tx hang when the internal buffer is full. Setting this bit enables a hardware fix to work around the issue. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/82571.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/82571.c b/drivers/net/ethernet/intel/e1000e/82571.c index a3e65fd26e0..0609ac69bb3 100644 --- a/drivers/net/ethernet/intel/e1000e/82571.c +++ b/drivers/net/ethernet/intel/e1000e/82571.c @@ -1227,6 +1227,10 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw) case e1000_82572: reg |= (1 << 23) | (1 << 24) | (1 << 25) | (1 << 26); break; + case e1000_82574: + case e1000_82583: + reg |= (1 << 26); + break; default: break; } -- cgit v1.2.3-70-g09d2 From b93f9cf14e714c20ce9a544ed1a6070ee7604588 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Wed, 25 Jan 2012 15:39:34 -0800 Subject: drm/i915: argument to control retiring behavior Sometimes it may be the case when we idle the gpu or wait on something we don't actually want to process the retiring list. This patch allows callers to choose the behavior. Reviewed-by: Keith Packard Reviewed-by: Eugeni Dodonov Signed-off-by: Ben Widawsky Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 5 +++-- drivers/gpu/drm/i915/i915_gem.c | 28 ++++++++++++++++------------ drivers/gpu/drm/i915/i915_gem_evict.c | 2 +- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 2 +- drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +- drivers/gpu/drm/i915/intel_overlay.c | 6 ++++-- 7 files changed, 27 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 8122738db91..3f27173fb51 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -2131,7 +2131,7 @@ int i915_driver_unload(struct drm_device *dev) unregister_shrinker(&dev_priv->mm.inactive_shrinker); mutex_lock(&dev->struct_mutex); - ret = i915_gpu_idle(dev); + ret = i915_gpu_idle(dev, true); if (ret) DRM_ERROR("failed to idle hardware: %d\n", ret); mutex_unlock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f02a5f525f0..1d10b8c26c9 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1179,13 +1179,14 @@ void i915_gem_do_init(struct drm_device *dev, unsigned long start, unsigned long mappable_end, unsigned long end); -int __must_check i915_gpu_idle(struct drm_device *dev); +int __must_check i915_gpu_idle(struct drm_device *dev, bool do_retire); int __must_check i915_gem_idle(struct drm_device *dev); int __must_check i915_add_request(struct intel_ring_buffer *ring, struct drm_file *file, struct drm_i915_gem_request *request); int __must_check i915_wait_request(struct intel_ring_buffer *ring, - uint32_t seqno); + uint32_t seqno, + bool do_retire); int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); int __must_check i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index eb98a7f55cf..ff3066c4c76 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1943,7 +1943,8 @@ i915_gem_retire_work_handler(struct work_struct *work) */ int i915_wait_request(struct intel_ring_buffer *ring, - uint32_t seqno) + uint32_t seqno, + bool do_retire) { drm_i915_private_t *dev_priv = ring->dev->dev_private; u32 ier; @@ -2027,7 +2028,7 @@ i915_wait_request(struct intel_ring_buffer *ring, * buffer to have made it to the inactive list, and we would need * a separate wait queue to handle that. */ - if (ret == 0) + if (ret == 0 && do_retire) i915_gem_retire_requests_ring(ring); return ret; @@ -2051,7 +2052,8 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj) * it. */ if (obj->active) { - ret = i915_wait_request(obj->ring, obj->last_rendering_seqno); + ret = i915_wait_request(obj->ring, obj->last_rendering_seqno, + true); if (ret) return ret; } @@ -2172,7 +2174,7 @@ i915_gem_flush_ring(struct intel_ring_buffer *ring, return 0; } -static int i915_ring_idle(struct intel_ring_buffer *ring) +static int i915_ring_idle(struct intel_ring_buffer *ring, bool do_retire) { int ret; @@ -2186,18 +2188,18 @@ static int i915_ring_idle(struct intel_ring_buffer *ring) return ret; } - return i915_wait_request(ring, i915_gem_next_request_seqno(ring)); + return i915_wait_request(ring, i915_gem_next_request_seqno(ring), + do_retire); } -int -i915_gpu_idle(struct drm_device *dev) +int i915_gpu_idle(struct drm_device *dev, bool do_retire) { drm_i915_private_t *dev_priv = dev->dev_private; int ret, i; /* Flush everything onto the inactive list. */ for (i = 0; i < I915_NUM_RINGS; i++) { - ret = i915_ring_idle(&dev_priv->ring[i]); + ret = i915_ring_idle(&dev_priv->ring[i], do_retire); if (ret) return ret; } @@ -2400,7 +2402,8 @@ i915_gem_object_flush_fence(struct drm_i915_gem_object *obj, if (!ring_passed_seqno(obj->last_fenced_ring, obj->last_fenced_seqno)) { ret = i915_wait_request(obj->last_fenced_ring, - obj->last_fenced_seqno); + obj->last_fenced_seqno, + true); if (ret) return ret; } @@ -2541,7 +2544,8 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj, if (!ring_passed_seqno(obj->last_fenced_ring, reg->setup_seqno)) { ret = i915_wait_request(obj->last_fenced_ring, - reg->setup_seqno); + reg->setup_seqno, + true); if (ret) return ret; } @@ -3710,7 +3714,7 @@ i915_gem_idle(struct drm_device *dev) return 0; } - ret = i915_gpu_idle(dev); + ret = i915_gpu_idle(dev, true); if (ret) { mutex_unlock(&dev->struct_mutex); return ret; @@ -4201,7 +4205,7 @@ rescan: * This has a dramatic impact to reduce the number of * OOM-killer events whilst running the GPU aggressively. */ - if (i915_gpu_idle(dev) == 0) + if (i915_gpu_idle(dev, true) == 0) goto rescan; } mutex_unlock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index ead5d00f91b..097119caa36 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c @@ -195,7 +195,7 @@ i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only) trace_i915_gem_evict_everything(dev, purgeable_only); /* Flush everything (on to the inactive lists) and evict */ - ret = i915_gpu_idle(dev); + ret = i915_gpu_idle(dev, true); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index c01cb201849..c649e0f255b 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1186,7 +1186,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, * so every billion or so execbuffers, we need to stall * the GPU in order to reset the counters. */ - ret = i915_gpu_idle(dev); + ret = i915_gpu_idle(dev, true); if (ret) goto err; diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 6042c5e6d27..e050b903da9 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -55,7 +55,7 @@ static bool do_idling(struct drm_i915_private *dev_priv) if (unlikely(dev_priv->mm.gtt->do_idle_maps)) { dev_priv->mm.interruptible = false; - if (i915_gpu_idle(dev_priv->dev)) { + if (i915_gpu_idle(dev_priv->dev, true)) { DRM_ERROR("Couldn't idle GPU\n"); /* Wait a bit, in hopes it avoids the hang */ udelay(10); diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index cdf17d4cc1f..23a543cdfa9 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -227,7 +227,8 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay, } overlay->last_flip_req = request->seqno; overlay->flip_tail = tail; - ret = i915_wait_request(LP_RING(dev_priv), overlay->last_flip_req); + ret = i915_wait_request(LP_RING(dev_priv), overlay->last_flip_req, + true); if (ret) return ret; @@ -448,7 +449,8 @@ static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay) if (overlay->last_flip_req == 0) return 0; - ret = i915_wait_request(LP_RING(dev_priv), overlay->last_flip_req); + ret = i915_wait_request(LP_RING(dev_priv), overlay->last_flip_req, + true); if (ret) return ret; -- cgit v1.2.3-70-g09d2 From 8436473a4b10243fd4c3009b97b6646c2ba642f7 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Tue, 24 Jan 2012 20:36:15 -0800 Subject: drm/i915: drm/i915: Fix recursive calls to unmap After the ILK vt-d workaround patches it became clear that we had introduced a bug. Chris Wilson tracked down the issue to recursive calls to unmap. This happens because we try to optimize waiting on requests by calling retire requests after the wait, which may drop the last reference on an object and end up freeing the object (and then unmap the object from the gtt). After the last patch we can now choose to defer processing the retire list. Kudos to Chris Wilson for tracking this one down. This patch fixes gem_unref_active_buffers from i-g-t. It was tested by forcing do_idle_maps to true. This also fixes tests/gem_linear_blits in intel-gpu-tools. Reported-by: guang.a.yang@intel.com Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=42180 Reviewed-by: Keith Packard Signed-off-by: Ben Widawsky Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index e050b903da9..11bddd5a5a6 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -55,7 +55,7 @@ static bool do_idling(struct drm_i915_private *dev_priv) if (unlikely(dev_priv->mm.gtt->do_idle_maps)) { dev_priv->mm.interruptible = false; - if (i915_gpu_idle(dev_priv->dev, true)) { + if (i915_gpu_idle(dev_priv->dev, false)) { DRM_ERROR("Couldn't idle GPU\n"); /* Wait a bit, in hopes it avoids the hang */ udelay(10); -- cgit v1.2.3-70-g09d2 From 6dc0e816bb7478fd4dfebddcc65257f9ef161f7a Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Mon, 23 Jan 2012 15:30:02 -0800 Subject: drm/i915: correct lock type in destroy This is only relevant when using module unloading, and really only helps get rid of a probably benign warning. I can't remember if I sent this out already, but it's not turning up in any of my searches. Signed-off-by: Ben Widawsky Reviewed-by: Keith Packard Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 5 +++-- 1 file changed, 3 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 5d433fc11ac..275ab6fecbd 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1017,11 +1017,12 @@ void i915_destroy_error_state(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_error_state *error; + unsigned long flags; - spin_lock(&dev_priv->error_lock); + spin_lock_irqsave(&dev_priv->error_lock, flags); error = dev_priv->first_error; dev_priv->first_error = NULL; - spin_unlock(&dev_priv->error_lock); + spin_unlock_irqrestore(&dev_priv->error_lock, flags); if (error) i915_error_state_free(dev, error); -- cgit v1.2.3-70-g09d2 From d53e54b4d43b2559c5a424188894fd63d145b5d7 Mon Sep 17 00:00:00 2001 From: Hiroshi DOYU Date: Wed, 16 Nov 2011 17:36:37 +0200 Subject: ARM: IOMMU: Tegra20: Add iommu_ops for GART driver Tegra 20 IOMMU H/W, GART (Graphics Address Relocation Table). This patch implements struct iommu_ops for GART for the upper IOMMU API. This H/W module supports only single virtual address space(domain), and manages a single level 1-to-1 mapping H/W translation page table. [With small fixes by Joerg Roedel] Signed-off-by: Hiroshi DOYU Signed-off-by: Joerg Roedel --- drivers/iommu/Kconfig | 10 + drivers/iommu/Makefile | 1 + drivers/iommu/tegra-gart.c | 451 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 462 insertions(+) create mode 100644 drivers/iommu/tegra-gart.c (limited to 'drivers') diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 6bea6962f8e..76c86da2b41 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -142,4 +142,14 @@ config OMAP_IOMMU_DEBUG Say N unless you know you need this. +config TEGRA_IOMMU_GART + bool "Tegra GART IOMMU Support" + depends on ARCH_TEGRA_2x_SOC + select IOMMU_API + help + Enables support for remapping discontiguous physical memory + shared with the operating system into contiguous I/O virtual + space through the GART (Graphics Address Relocation Table) + hardware included on Tegra SoCs. + endif # IOMMU_SUPPORT diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 0e36b4934af..3238a31d260 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_IRQ_REMAP) += intr_remapping.o obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o obj-$(CONFIG_OMAP_IOVMM) += omap-iovmm.o obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o +obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c new file mode 100644 index 00000000000..b21598fc262 --- /dev/null +++ b/drivers/iommu/tegra-gart.c @@ -0,0 +1,451 @@ +/* + * IOMMU API for GART in Tegra20 + * + * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#define pr_fmt(fmt) "%s(): " fmt, __func__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* bitmap of the page sizes currently supported */ +#define GART_IOMMU_PGSIZES (SZ_4K) + +#define GART_CONFIG 0x24 +#define GART_ENTRY_ADDR 0x28 +#define GART_ENTRY_DATA 0x2c +#define GART_ENTRY_PHYS_ADDR_VALID (1 << 31) + +#define GART_PAGE_SHIFT 12 +#define GART_PAGE_SIZE (1 << GART_PAGE_SHIFT) +#define GART_PAGE_MASK \ + (~(GART_PAGE_SIZE - 1) & ~GART_ENTRY_PHYS_ADDR_VALID) + +struct gart_client { + struct device *dev; + struct list_head list; +}; + +struct gart_device { + void __iomem *regs; + u32 *savedata; + u32 page_count; /* total remappable size */ + dma_addr_t iovmm_base; /* offset to vmm_area */ + spinlock_t pte_lock; /* for pagetable */ + struct list_head client; + spinlock_t client_lock; /* for client list */ + struct device *dev; +}; + +static struct gart_device *gart_handle; /* unique for a system */ + +#define GART_PTE(_pfn) \ + (GART_ENTRY_PHYS_ADDR_VALID | ((_pfn) << PAGE_SHIFT)) + +/* + * Any interaction between any block on PPSB and a block on APB or AHB + * must have these read-back to ensure the APB/AHB bus transaction is + * complete before initiating activity on the PPSB block. + */ +#define FLUSH_GART_REGS(gart) ((void)readl((gart)->regs + GART_CONFIG)) + +#define for_each_gart_pte(gart, iova) \ + for (iova = gart->iovmm_base; \ + iova < gart->iovmm_base + GART_PAGE_SIZE * gart->page_count; \ + iova += GART_PAGE_SIZE) + +static inline void gart_set_pte(struct gart_device *gart, + unsigned long offs, u32 pte) +{ + writel(offs, gart->regs + GART_ENTRY_ADDR); + writel(pte, gart->regs + GART_ENTRY_DATA); + + dev_dbg(gart->dev, "%s %08lx:%08x\n", + pte ? "map" : "unmap", offs, pte & GART_PAGE_MASK); +} + +static inline unsigned long gart_read_pte(struct gart_device *gart, + unsigned long offs) +{ + unsigned long pte; + + writel(offs, gart->regs + GART_ENTRY_ADDR); + pte = readl(gart->regs + GART_ENTRY_DATA); + + return pte; +} + +static void do_gart_setup(struct gart_device *gart, const u32 *data) +{ + unsigned long iova; + + for_each_gart_pte(gart, iova) + gart_set_pte(gart, iova, data ? *(data++) : 0); + + writel(1, gart->regs + GART_CONFIG); + FLUSH_GART_REGS(gart); +} + +#ifdef DEBUG +static void gart_dump_table(struct gart_device *gart) +{ + unsigned long iova; + unsigned long flags; + + spin_lock_irqsave(&gart->pte_lock, flags); + for_each_gart_pte(gart, iova) { + unsigned long pte; + + pte = gart_read_pte(gart, iova); + + dev_dbg(gart->dev, "%s %08lx:%08lx\n", + (GART_ENTRY_PHYS_ADDR_VALID & pte) ? "v" : " ", + iova, pte & GART_PAGE_MASK); + } + spin_unlock_irqrestore(&gart->pte_lock, flags); +} +#else +static inline void gart_dump_table(struct gart_device *gart) +{ +} +#endif + +static inline bool gart_iova_range_valid(struct gart_device *gart, + unsigned long iova, size_t bytes) +{ + unsigned long iova_start, iova_end, gart_start, gart_end; + + iova_start = iova; + iova_end = iova_start + bytes - 1; + gart_start = gart->iovmm_base; + gart_end = gart_start + gart->page_count * GART_PAGE_SIZE - 1; + + if (iova_start < gart_start) + return false; + if (iova_end > gart_end) + return false; + return true; +} + +static int gart_iommu_attach_dev(struct iommu_domain *domain, + struct device *dev) +{ + struct gart_device *gart; + struct gart_client *client, *c; + int err = 0; + + gart = dev_get_drvdata(dev->parent); + if (!gart) + return -EINVAL; + domain->priv = gart; + + client = devm_kzalloc(gart->dev, sizeof(*c), GFP_KERNEL); + if (!client) + return -ENOMEM; + client->dev = dev; + + spin_lock(&gart->client_lock); + list_for_each_entry(c, &gart->client, list) { + if (c->dev == dev) { + dev_err(gart->dev, + "%s is already attached\n", dev_name(dev)); + err = -EINVAL; + goto fail; + } + } + list_add(&client->list, &gart->client); + spin_unlock(&gart->client_lock); + dev_dbg(gart->dev, "Attached %s\n", dev_name(dev)); + return 0; + +fail: + devm_kfree(gart->dev, client); + spin_unlock(&gart->client_lock); + return err; +} + +static void gart_iommu_detach_dev(struct iommu_domain *domain, + struct device *dev) +{ + struct gart_device *gart = domain->priv; + struct gart_client *c; + + spin_lock(&gart->client_lock); + + list_for_each_entry(c, &gart->client, list) { + if (c->dev == dev) { + list_del(&c->list); + devm_kfree(gart->dev, c); + dev_dbg(gart->dev, "Detached %s\n", dev_name(dev)); + goto out; + } + } + dev_err(gart->dev, "Couldn't find\n"); +out: + spin_unlock(&gart->client_lock); +} + +static int gart_iommu_domain_init(struct iommu_domain *domain) +{ + return 0; +} + +static void gart_iommu_domain_destroy(struct iommu_domain *domain) +{ + struct gart_device *gart = domain->priv; + + if (!gart) + return; + + spin_lock(&gart->client_lock); + if (!list_empty(&gart->client)) { + struct gart_client *c; + + list_for_each_entry(c, &gart->client, list) + gart_iommu_detach_dev(domain, c->dev); + } + spin_unlock(&gart->client_lock); + domain->priv = NULL; +} + +static int gart_iommu_map(struct iommu_domain *domain, unsigned long iova, + phys_addr_t pa, size_t bytes, int prot) +{ + struct gart_device *gart = domain->priv; + unsigned long flags; + unsigned long pfn; + + if (!gart_iova_range_valid(gart, iova, bytes)) + return -EINVAL; + + spin_lock_irqsave(&gart->pte_lock, flags); + pfn = __phys_to_pfn(pa); + if (!pfn_valid(pfn)) { + dev_err(gart->dev, "Invalid page: %08x\n", pa); + spin_lock_irqsave(&gart->pte_lock, flags); + return -EINVAL; + } + gart_set_pte(gart, iova, GART_PTE(pfn)); + FLUSH_GART_REGS(gart); + spin_unlock_irqrestore(&gart->pte_lock, flags); + return 0; +} + +static size_t gart_iommu_unmap(struct iommu_domain *domain, unsigned long iova, + size_t bytes) +{ + struct gart_device *gart = domain->priv; + unsigned long flags; + + if (!gart_iova_range_valid(gart, iova, bytes)) + return 0; + + spin_lock_irqsave(&gart->pte_lock, flags); + gart_set_pte(gart, iova, 0); + FLUSH_GART_REGS(gart); + spin_unlock_irqrestore(&gart->pte_lock, flags); + return 0; +} + +static phys_addr_t gart_iommu_iova_to_phys(struct iommu_domain *domain, + unsigned long iova) +{ + struct gart_device *gart = domain->priv; + unsigned long pte; + phys_addr_t pa; + unsigned long flags; + + if (!gart_iova_range_valid(gart, iova, 0)) + return -EINVAL; + + spin_lock_irqsave(&gart->pte_lock, flags); + pte = gart_read_pte(gart, iova); + spin_unlock_irqrestore(&gart->pte_lock, flags); + + pa = (pte & GART_PAGE_MASK); + if (!pfn_valid(__phys_to_pfn(pa))) { + dev_err(gart->dev, "No entry for %08lx:%08x\n", iova, pa); + gart_dump_table(gart); + return -EINVAL; + } + return pa; +} + +static int gart_iommu_domain_has_cap(struct iommu_domain *domain, + unsigned long cap) +{ + return 0; +} + +static struct iommu_ops gart_iommu_ops = { + .domain_init = gart_iommu_domain_init, + .domain_destroy = gart_iommu_domain_destroy, + .attach_dev = gart_iommu_attach_dev, + .detach_dev = gart_iommu_detach_dev, + .map = gart_iommu_map, + .unmap = gart_iommu_unmap, + .iova_to_phys = gart_iommu_iova_to_phys, + .domain_has_cap = gart_iommu_domain_has_cap, + .pgsize_bitmap = GART_IOMMU_PGSIZES, +}; + +static int tegra_gart_suspend(struct device *dev) +{ + struct gart_device *gart = dev_get_drvdata(dev); + unsigned long iova; + u32 *data = gart->savedata; + unsigned long flags; + + spin_lock_irqsave(&gart->pte_lock, flags); + for_each_gart_pte(gart, iova) + *(data++) = gart_read_pte(gart, iova); + spin_unlock_irqrestore(&gart->pte_lock, flags); + return 0; +} + +static int tegra_gart_resume(struct device *dev) +{ + struct gart_device *gart = dev_get_drvdata(dev); + unsigned long flags; + + spin_lock_irqsave(&gart->pte_lock, flags); + do_gart_setup(gart, gart->savedata); + spin_unlock_irqrestore(&gart->pte_lock, flags); + return 0; +} + +static int tegra_gart_probe(struct platform_device *pdev) +{ + struct gart_device *gart; + struct resource *res, *res_remap; + void __iomem *gart_regs; + int err; + struct device *dev = &pdev->dev; + + if (gart_handle) + return -EIO; + + BUILD_BUG_ON(PAGE_SHIFT != GART_PAGE_SHIFT); + + /* the GART memory aperture is required */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + res_remap = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res || !res_remap) { + dev_err(dev, "GART memory aperture expected\n"); + return -ENXIO; + } + + gart = devm_kzalloc(dev, sizeof(*gart), GFP_KERNEL); + if (!gart) { + dev_err(dev, "failed to allocate gart_device\n"); + return -ENOMEM; + } + + gart_regs = devm_ioremap(dev, res->start, resource_size(res)); + if (!gart_regs) { + dev_err(dev, "failed to remap GART registers\n"); + err = -ENXIO; + goto fail; + } + + gart->dev = &pdev->dev; + spin_lock_init(&gart->pte_lock); + spin_lock_init(&gart->client_lock); + INIT_LIST_HEAD(&gart->client); + gart->regs = gart_regs; + gart->iovmm_base = (dma_addr_t)res_remap->start; + gart->page_count = (resource_size(res_remap) >> GART_PAGE_SHIFT); + + gart->savedata = vmalloc(sizeof(u32) * gart->page_count); + if (!gart->savedata) { + dev_err(dev, "failed to allocate context save area\n"); + err = -ENOMEM; + goto fail; + } + + platform_set_drvdata(pdev, gart); + do_gart_setup(gart, NULL); + + gart_handle = gart; + return 0; + +fail: + if (gart_regs) + devm_iounmap(dev, gart_regs); + if (gart && gart->savedata) + vfree(gart->savedata); + devm_kfree(dev, gart); + return err; +} + +static int tegra_gart_remove(struct platform_device *pdev) +{ + struct gart_device *gart = platform_get_drvdata(pdev); + struct device *dev = gart->dev; + + writel(0, gart->regs + GART_CONFIG); + if (gart->savedata) + vfree(gart->savedata); + if (gart->regs) + devm_iounmap(dev, gart->regs); + devm_kfree(dev, gart); + gart_handle = NULL; + return 0; +} + +const struct dev_pm_ops tegra_gart_pm_ops = { + .suspend = tegra_gart_suspend, + .resume = tegra_gart_resume, +}; + +static struct platform_driver tegra_gart_driver = { + .probe = tegra_gart_probe, + .remove = tegra_gart_remove, + .driver = { + .owner = THIS_MODULE, + .name = "tegra-gart", + .pm = &tegra_gart_pm_ops, + }, +}; + +static int __devinit tegra_gart_init(void) +{ + bus_set_iommu(&platform_bus_type, &gart_iommu_ops); + return platform_driver_register(&tegra_gart_driver); +} + +static void __exit tegra_gart_exit(void) +{ + platform_driver_unregister(&tegra_gart_driver); +} + +subsys_initcall(tegra_gart_init); +module_exit(tegra_gart_exit); + +MODULE_DESCRIPTION("IOMMU API for GART in Tegra20"); +MODULE_AUTHOR("Hiroshi DOYU "); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-70-g09d2 From 7a31f6f48bb6e37b3195fcecd69d30740f6b0036 Mon Sep 17 00:00:00 2001 From: Hiroshi DOYU Date: Thu, 17 Nov 2011 07:31:31 +0200 Subject: ARM: IOMMU: Tegra30: Add iommu_ops for SMMU driver Tegra 30 IOMMU H/W, SMMU (System Memory Management Unit). This patch implements struct iommu_ops for SMMU for the upper IOMMU API. This H/W module supports multiple virtual address spaces(domain x4), and manages 2 level H/W translation pagetable. Signed-off-by: Hiroshi DOYU Signed-off-by: Joerg Roedel --- arch/arm/mach-tegra/include/mach/smmu.h | 63 ++ drivers/iommu/Kconfig | 10 + drivers/iommu/Makefile | 1 + drivers/iommu/tegra-smmu.c | 1034 +++++++++++++++++++++++++++++++ 4 files changed, 1108 insertions(+) create mode 100644 arch/arm/mach-tegra/include/mach/smmu.h create mode 100644 drivers/iommu/tegra-smmu.c (limited to 'drivers') diff --git a/arch/arm/mach-tegra/include/mach/smmu.h b/arch/arm/mach-tegra/include/mach/smmu.h new file mode 100644 index 00000000000..dad403a9cf0 --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/smmu.h @@ -0,0 +1,63 @@ +/* + * IOMMU API for SMMU in Tegra30 + * + * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MACH_SMMU_H +#define MACH_SMMU_H + +enum smmu_hwgrp { + HWGRP_AFI, + HWGRP_AVPC, + HWGRP_DC, + HWGRP_DCB, + HWGRP_EPP, + HWGRP_G2, + HWGRP_HC, + HWGRP_HDA, + HWGRP_ISP, + HWGRP_MPE, + HWGRP_NV, + HWGRP_NV2, + HWGRP_PPCS, + HWGRP_SATA, + HWGRP_VDE, + HWGRP_VI, + + HWGRP_COUNT, + + HWGRP_END = ~0, +}; + +#define HWG_AFI (1 << HWGRP_AFI) +#define HWG_AVPC (1 << HWGRP_AVPC) +#define HWG_DC (1 << HWGRP_DC) +#define HWG_DCB (1 << HWGRP_DCB) +#define HWG_EPP (1 << HWGRP_EPP) +#define HWG_G2 (1 << HWGRP_G2) +#define HWG_HC (1 << HWGRP_HC) +#define HWG_HDA (1 << HWGRP_HDA) +#define HWG_ISP (1 << HWGRP_ISP) +#define HWG_MPE (1 << HWGRP_MPE) +#define HWG_NV (1 << HWGRP_NV) +#define HWG_NV2 (1 << HWGRP_NV2) +#define HWG_PPCS (1 << HWGRP_PPCS) +#define HWG_SATA (1 << HWGRP_SATA) +#define HWG_VDE (1 << HWGRP_VDE) +#define HWG_VI (1 << HWGRP_VI) + +#endif /* MACH_SMMU_H */ diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 76c86da2b41..3bd9fff5c58 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -152,4 +152,14 @@ config TEGRA_IOMMU_GART space through the GART (Graphics Address Relocation Table) hardware included on Tegra SoCs. +config TEGRA_IOMMU_SMMU + bool "Tegra SMMU IOMMU Support" + depends on ARCH_TEGRA_3x_SOC + select IOMMU_API + help + Enables support for remapping discontiguous physical memory + shared with the operating system into contiguous I/O virtual + space through the SMMU (System Memory Management Unit) + hardware included on Tegra SoCs. + endif # IOMMU_SUPPORT diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 3238a31d260..7ad7a3bc124 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -9,3 +9,4 @@ obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o obj-$(CONFIG_OMAP_IOVMM) += omap-iovmm.o obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o +obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c new file mode 100644 index 00000000000..eb93c821f59 --- /dev/null +++ b/drivers/iommu/tegra-smmu.c @@ -0,0 +1,1034 @@ +/* + * IOMMU API for SMMU in Tegra30 + * + * Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#define pr_fmt(fmt) "%s(): " fmt, __func__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +/* bitmap of the page sizes currently supported */ +#define SMMU_IOMMU_PGSIZES (SZ_4K) + +#define SMMU_CONFIG 0x10 +#define SMMU_CONFIG_DISABLE 0 +#define SMMU_CONFIG_ENABLE 1 + +#define SMMU_TLB_CONFIG 0x14 +#define SMMU_TLB_CONFIG_STATS__MASK (1 << 31) +#define SMMU_TLB_CONFIG_STATS__ENABLE (1 << 31) +#define SMMU_TLB_CONFIG_HIT_UNDER_MISS__ENABLE (1 << 29) +#define SMMU_TLB_CONFIG_ACTIVE_LINES__VALUE 0x10 +#define SMMU_TLB_CONFIG_RESET_VAL 0x20000010 + +#define SMMU_PTC_CONFIG 0x18 +#define SMMU_PTC_CONFIG_STATS__MASK (1 << 31) +#define SMMU_PTC_CONFIG_STATS__ENABLE (1 << 31) +#define SMMU_PTC_CONFIG_CACHE__ENABLE (1 << 29) +#define SMMU_PTC_CONFIG_INDEX_MAP__PATTERN 0x3f +#define SMMU_PTC_CONFIG_RESET_VAL 0x2000003f + +#define SMMU_PTB_ASID 0x1c +#define SMMU_PTB_ASID_CURRENT_SHIFT 0 + +#define SMMU_PTB_DATA 0x20 +#define SMMU_PTB_DATA_RESET_VAL 0 +#define SMMU_PTB_DATA_ASID_NONSECURE_SHIFT 29 +#define SMMU_PTB_DATA_ASID_WRITABLE_SHIFT 30 +#define SMMU_PTB_DATA_ASID_READABLE_SHIFT 31 + +#define SMMU_TLB_FLUSH 0x30 +#define SMMU_TLB_FLUSH_VA_MATCH_ALL 0 +#define SMMU_TLB_FLUSH_VA_MATCH_SECTION 2 +#define SMMU_TLB_FLUSH_VA_MATCH_GROUP 3 +#define SMMU_TLB_FLUSH_ASID_SHIFT 29 +#define SMMU_TLB_FLUSH_ASID_MATCH_DISABLE 0 +#define SMMU_TLB_FLUSH_ASID_MATCH_ENABLE 1 +#define SMMU_TLB_FLUSH_ASID_MATCH_SHIFT 31 + +#define SMMU_PTC_FLUSH 0x34 +#define SMMU_PTC_FLUSH_TYPE_ALL 0 +#define SMMU_PTC_FLUSH_TYPE_ADR 1 +#define SMMU_PTC_FLUSH_ADR_SHIFT 4 + +#define SMMU_ASID_SECURITY 0x38 + +#define SMMU_STATS_TLB_HIT_COUNT 0x1f0 +#define SMMU_STATS_TLB_MISS_COUNT 0x1f4 +#define SMMU_STATS_PTC_HIT_COUNT 0x1f8 +#define SMMU_STATS_PTC_MISS_COUNT 0x1fc + +#define SMMU_TRANSLATION_ENABLE_0 0x228 +#define SMMU_TRANSLATION_ENABLE_1 0x22c +#define SMMU_TRANSLATION_ENABLE_2 0x230 + +#define SMMU_AFI_ASID 0x238 /* PCIE */ +#define SMMU_AVPC_ASID 0x23c /* AVP */ +#define SMMU_DC_ASID 0x240 /* Display controller */ +#define SMMU_DCB_ASID 0x244 /* Display controller B */ +#define SMMU_EPP_ASID 0x248 /* Encoder pre-processor */ +#define SMMU_G2_ASID 0x24c /* 2D engine */ +#define SMMU_HC_ASID 0x250 /* Host1x */ +#define SMMU_HDA_ASID 0x254 /* High-def audio */ +#define SMMU_ISP_ASID 0x258 /* Image signal processor */ +#define SMMU_MPE_ASID 0x264 /* MPEG encoder */ +#define SMMU_NV_ASID 0x268 /* (3D) */ +#define SMMU_NV2_ASID 0x26c /* (3D) */ +#define SMMU_PPCS_ASID 0x270 /* AHB */ +#define SMMU_SATA_ASID 0x278 /* SATA */ +#define SMMU_VDE_ASID 0x27c /* Video decoder */ +#define SMMU_VI_ASID 0x280 /* Video input */ + +#define SMMU_PDE_NEXT_SHIFT 28 + +/* AHB Arbiter Registers */ +#define AHB_XBAR_CTRL 0xe0 +#define AHB_XBAR_CTRL_SMMU_INIT_DONE_DONE 1 +#define AHB_XBAR_CTRL_SMMU_INIT_DONE_SHIFT 17 + +#define SMMU_NUM_ASIDS 4 +#define SMMU_TLB_FLUSH_VA_SECTION__MASK 0xffc00000 +#define SMMU_TLB_FLUSH_VA_SECTION__SHIFT 12 /* right shift */ +#define SMMU_TLB_FLUSH_VA_GROUP__MASK 0xffffc000 +#define SMMU_TLB_FLUSH_VA_GROUP__SHIFT 12 /* right shift */ +#define SMMU_TLB_FLUSH_VA(iova, which) \ + ((((iova) & SMMU_TLB_FLUSH_VA_##which##__MASK) >> \ + SMMU_TLB_FLUSH_VA_##which##__SHIFT) | \ + SMMU_TLB_FLUSH_VA_MATCH_##which) +#define SMMU_PTB_ASID_CUR(n) \ + ((n) << SMMU_PTB_ASID_CURRENT_SHIFT) +#define SMMU_TLB_FLUSH_ASID_MATCH_disable \ + (SMMU_TLB_FLUSH_ASID_MATCH_DISABLE << \ + SMMU_TLB_FLUSH_ASID_MATCH_SHIFT) +#define SMMU_TLB_FLUSH_ASID_MATCH__ENABLE \ + (SMMU_TLB_FLUSH_ASID_MATCH_ENABLE << \ + SMMU_TLB_FLUSH_ASID_MATCH_SHIFT) + +#define SMMU_PAGE_SHIFT 12 +#define SMMU_PAGE_SIZE (1 << SMMU_PAGE_SHIFT) + +#define SMMU_PDIR_COUNT 1024 +#define SMMU_PDIR_SIZE (sizeof(unsigned long) * SMMU_PDIR_COUNT) +#define SMMU_PTBL_COUNT 1024 +#define SMMU_PTBL_SIZE (sizeof(unsigned long) * SMMU_PTBL_COUNT) +#define SMMU_PDIR_SHIFT 12 +#define SMMU_PDE_SHIFT 12 +#define SMMU_PTE_SHIFT 12 +#define SMMU_PFN_MASK 0x000fffff + +#define SMMU_ADDR_TO_PFN(addr) ((addr) >> 12) +#define SMMU_ADDR_TO_PDN(addr) ((addr) >> 22) +#define SMMU_PDN_TO_ADDR(addr) ((pdn) << 22) + +#define _READABLE (1 << SMMU_PTB_DATA_ASID_READABLE_SHIFT) +#define _WRITABLE (1 << SMMU_PTB_DATA_ASID_WRITABLE_SHIFT) +#define _NONSECURE (1 << SMMU_PTB_DATA_ASID_NONSECURE_SHIFT) +#define _PDE_NEXT (1 << SMMU_PDE_NEXT_SHIFT) +#define _MASK_ATTR (_READABLE | _WRITABLE | _NONSECURE) + +#define _PDIR_ATTR (_READABLE | _WRITABLE | _NONSECURE) + +#define _PDE_ATTR (_READABLE | _WRITABLE | _NONSECURE) +#define _PDE_ATTR_N (_PDE_ATTR | _PDE_NEXT) +#define _PDE_VACANT(pdn) (((pdn) << 10) | _PDE_ATTR) + +#define _PTE_ATTR (_READABLE | _WRITABLE | _NONSECURE) +#define _PTE_VACANT(addr) (((addr) >> SMMU_PAGE_SHIFT) | _PTE_ATTR) + +#define SMMU_MK_PDIR(page, attr) \ + ((page_to_phys(page) >> SMMU_PDIR_SHIFT) | (attr)) +#define SMMU_MK_PDE(page, attr) \ + (unsigned long)((page_to_phys(page) >> SMMU_PDE_SHIFT) | (attr)) +#define SMMU_EX_PTBL_PAGE(pde) \ + pfn_to_page((unsigned long)(pde) & SMMU_PFN_MASK) +#define SMMU_PFN_TO_PTE(pfn, attr) (unsigned long)((pfn) | (attr)) + +#define SMMU_ASID_ENABLE(asid) ((asid) | (1 << 31)) +#define SMMU_ASID_DISABLE 0 +#define SMMU_ASID_ASID(n) ((n) & ~SMMU_ASID_ENABLE(0)) + +#define smmu_client_enable_hwgrp(c, m) smmu_client_set_hwgrp(c, m, 1) +#define smmu_client_disable_hwgrp(c) smmu_client_set_hwgrp(c, 0, 0) +#define __smmu_client_enable_hwgrp(c, m) __smmu_client_set_hwgrp(c, m, 1) +#define __smmu_client_disable_hwgrp(c) __smmu_client_set_hwgrp(c, 0, 0) + +#define HWGRP_INIT(client) [HWGRP_##client] = SMMU_##client##_ASID + +static const u32 smmu_hwgrp_asid_reg[] = { + HWGRP_INIT(AFI), + HWGRP_INIT(AVPC), + HWGRP_INIT(DC), + HWGRP_INIT(DCB), + HWGRP_INIT(EPP), + HWGRP_INIT(G2), + HWGRP_INIT(HC), + HWGRP_INIT(HDA), + HWGRP_INIT(ISP), + HWGRP_INIT(MPE), + HWGRP_INIT(NV), + HWGRP_INIT(NV2), + HWGRP_INIT(PPCS), + HWGRP_INIT(SATA), + HWGRP_INIT(VDE), + HWGRP_INIT(VI), +}; +#define HWGRP_ASID_REG(x) (smmu_hwgrp_asid_reg[x]) + +/* + * Per client for address space + */ +struct smmu_client { + struct device *dev; + struct list_head list; + struct smmu_as *as; + u32 hwgrp; +}; + +/* + * Per address space + */ +struct smmu_as { + struct smmu_device *smmu; /* back pointer to container */ + unsigned int asid; + spinlock_t lock; /* for pagetable */ + struct page *pdir_page; + unsigned long pdir_attr; + unsigned long pde_attr; + unsigned long pte_attr; + unsigned int *pte_count; + + struct list_head client; + spinlock_t client_lock; /* for client list */ +}; + +/* + * Per SMMU device - IOMMU device + */ +struct smmu_device { + void __iomem *regs, *regs_ahbarb; + unsigned long iovmm_base; /* remappable base address */ + unsigned long page_count; /* total remappable size */ + spinlock_t lock; + char *name; + struct device *dev; + int num_as; + struct smmu_as *as; /* Run-time allocated array */ + struct page *avp_vector_page; /* dummy page shared by all AS's */ + + /* + * Register image savers for suspend/resume + */ + unsigned long translation_enable_0; + unsigned long translation_enable_1; + unsigned long translation_enable_2; + unsigned long asid_security; +}; + +static struct smmu_device *smmu_handle; /* unique for a system */ + +/* + * SMMU/AHB register accessors + */ +static inline u32 smmu_read(struct smmu_device *smmu, size_t offs) +{ + return readl(smmu->regs + offs); +} +static inline void smmu_write(struct smmu_device *smmu, u32 val, size_t offs) +{ + writel(val, smmu->regs + offs); +} + +static inline u32 ahb_read(struct smmu_device *smmu, size_t offs) +{ + return readl(smmu->regs_ahbarb + offs); +} +static inline void ahb_write(struct smmu_device *smmu, u32 val, size_t offs) +{ + writel(val, smmu->regs_ahbarb + offs); +} + +#define VA_PAGE_TO_PA(va, page) \ + (page_to_phys(page) + ((unsigned long)(va) & ~PAGE_MASK)) + +#define FLUSH_CPU_DCACHE(va, page, size) \ + do { \ + unsigned long _pa_ = VA_PAGE_TO_PA(va, page); \ + __cpuc_flush_dcache_area((void *)(va), (size_t)(size)); \ + outer_flush_range(_pa_, _pa_+(size_t)(size)); \ + } while (0) + +/* + * Any interaction between any block on PPSB and a block on APB or AHB + * must have these read-back barriers to ensure the APB/AHB bus + * transaction is complete before initiating activity on the PPSB + * block. + */ +#define FLUSH_SMMU_REGS(smmu) smmu_read(smmu, SMMU_CONFIG) + +#define smmu_client_hwgrp(c) (u32)((c)->dev->platform_data) + +static int __smmu_client_set_hwgrp(struct smmu_client *c, + unsigned long map, int on) +{ + int i; + struct smmu_as *as = c->as; + u32 val, offs, mask = SMMU_ASID_ENABLE(as->asid); + struct smmu_device *smmu = as->smmu; + + WARN_ON(!on && map); + if (on && !map) + return -EINVAL; + if (!on) + map = smmu_client_hwgrp(c); + + for_each_set_bit(i, &map, HWGRP_COUNT) { + offs = HWGRP_ASID_REG(i); + val = smmu_read(smmu, offs); + if (on) { + if (WARN_ON(val & mask)) + goto err_hw_busy; + val |= mask; + } else { + WARN_ON((val & mask) == mask); + val &= ~mask; + } + smmu_write(smmu, val, offs); + } + FLUSH_SMMU_REGS(smmu); + c->hwgrp = map; + return 0; + +err_hw_busy: + for_each_set_bit(i, &map, HWGRP_COUNT) { + offs = HWGRP_ASID_REG(i); + val = smmu_read(smmu, offs); + val &= ~mask; + smmu_write(smmu, val, offs); + } + return -EBUSY; +} + +static int smmu_client_set_hwgrp(struct smmu_client *c, u32 map, int on) +{ + u32 val; + unsigned long flags; + struct smmu_as *as = c->as; + struct smmu_device *smmu = as->smmu; + + spin_lock_irqsave(&smmu->lock, flags); + val = __smmu_client_set_hwgrp(c, map, on); + spin_unlock_irqrestore(&smmu->lock, flags); + return val; +} + +/* + * Flush all TLB entries and all PTC entries + * Caller must lock smmu + */ +static void smmu_flush_regs(struct smmu_device *smmu, int enable) +{ + u32 val; + + smmu_write(smmu, SMMU_PTC_FLUSH_TYPE_ALL, SMMU_PTC_FLUSH); + FLUSH_SMMU_REGS(smmu); + val = SMMU_TLB_FLUSH_VA_MATCH_ALL | + SMMU_TLB_FLUSH_ASID_MATCH_disable; + smmu_write(smmu, val, SMMU_TLB_FLUSH); + + if (enable) + smmu_write(smmu, SMMU_CONFIG_ENABLE, SMMU_CONFIG); + FLUSH_SMMU_REGS(smmu); +} + +static void smmu_setup_regs(struct smmu_device *smmu) +{ + int i; + u32 val; + + for (i = 0; i < smmu->num_as; i++) { + struct smmu_as *as = &smmu->as[i]; + struct smmu_client *c; + + smmu_write(smmu, SMMU_PTB_ASID_CUR(as->asid), SMMU_PTB_ASID); + val = as->pdir_page ? + SMMU_MK_PDIR(as->pdir_page, as->pdir_attr) : + SMMU_PTB_DATA_RESET_VAL; + smmu_write(smmu, val, SMMU_PTB_DATA); + + list_for_each_entry(c, &as->client, list) + __smmu_client_set_hwgrp(c, c->hwgrp, 1); + } + + smmu_write(smmu, smmu->translation_enable_0, SMMU_TRANSLATION_ENABLE_0); + smmu_write(smmu, smmu->translation_enable_1, SMMU_TRANSLATION_ENABLE_1); + smmu_write(smmu, smmu->translation_enable_2, SMMU_TRANSLATION_ENABLE_2); + smmu_write(smmu, smmu->asid_security, SMMU_ASID_SECURITY); + smmu_write(smmu, SMMU_TLB_CONFIG_RESET_VAL, SMMU_TLB_CONFIG); + smmu_write(smmu, SMMU_PTC_CONFIG_RESET_VAL, SMMU_PTC_CONFIG); + + smmu_flush_regs(smmu, 1); + + val = ahb_read(smmu, AHB_XBAR_CTRL); + val |= AHB_XBAR_CTRL_SMMU_INIT_DONE_DONE << + AHB_XBAR_CTRL_SMMU_INIT_DONE_SHIFT; + ahb_write(smmu, val, AHB_XBAR_CTRL); +} + +static void flush_ptc_and_tlb(struct smmu_device *smmu, + struct smmu_as *as, dma_addr_t iova, + unsigned long *pte, struct page *page, int is_pde) +{ + u32 val; + unsigned long tlb_flush_va = is_pde + ? SMMU_TLB_FLUSH_VA(iova, SECTION) + : SMMU_TLB_FLUSH_VA(iova, GROUP); + + val = SMMU_PTC_FLUSH_TYPE_ADR | VA_PAGE_TO_PA(pte, page); + smmu_write(smmu, val, SMMU_PTC_FLUSH); + FLUSH_SMMU_REGS(smmu); + val = tlb_flush_va | + SMMU_TLB_FLUSH_ASID_MATCH__ENABLE | + (as->asid << SMMU_TLB_FLUSH_ASID_SHIFT); + smmu_write(smmu, val, SMMU_TLB_FLUSH); + FLUSH_SMMU_REGS(smmu); +} + +static void free_ptbl(struct smmu_as *as, dma_addr_t iova) +{ + unsigned long pdn = SMMU_ADDR_TO_PDN(iova); + unsigned long *pdir = (unsigned long *)page_address(as->pdir_page); + + if (pdir[pdn] != _PDE_VACANT(pdn)) { + dev_dbg(as->smmu->dev, "pdn: %lx\n", pdn); + + ClearPageReserved(SMMU_EX_PTBL_PAGE(pdir[pdn])); + __free_page(SMMU_EX_PTBL_PAGE(pdir[pdn])); + pdir[pdn] = _PDE_VACANT(pdn); + FLUSH_CPU_DCACHE(&pdir[pdn], as->pdir_page, sizeof pdir[pdn]); + flush_ptc_and_tlb(as->smmu, as, iova, &pdir[pdn], + as->pdir_page, 1); + } +} + +static void free_pdir(struct smmu_as *as) +{ + unsigned addr; + int count; + struct device *dev = as->smmu->dev; + + if (!as->pdir_page) + return; + + addr = as->smmu->iovmm_base; + count = as->smmu->page_count; + while (count-- > 0) { + free_ptbl(as, addr); + addr += SMMU_PAGE_SIZE * SMMU_PTBL_COUNT; + } + ClearPageReserved(as->pdir_page); + __free_page(as->pdir_page); + as->pdir_page = NULL; + devm_kfree(dev, as->pte_count); + as->pte_count = NULL; +} + +/* + * Maps PTBL for given iova and returns the PTE address + * Caller must unmap the mapped PTBL returned in *ptbl_page_p + */ +static unsigned long *locate_pte(struct smmu_as *as, + dma_addr_t iova, bool allocate, + struct page **ptbl_page_p, + unsigned int **count) +{ + unsigned long ptn = SMMU_ADDR_TO_PFN(iova); + unsigned long pdn = SMMU_ADDR_TO_PDN(iova); + unsigned long *pdir = page_address(as->pdir_page); + unsigned long *ptbl; + + if (pdir[pdn] != _PDE_VACANT(pdn)) { + /* Mapped entry table already exists */ + *ptbl_page_p = SMMU_EX_PTBL_PAGE(pdir[pdn]); + ptbl = page_address(*ptbl_page_p); + } else if (!allocate) { + return NULL; + } else { + int pn; + unsigned long addr = SMMU_PDN_TO_ADDR(pdn); + + /* Vacant - allocate a new page table */ + dev_dbg(as->smmu->dev, "New PTBL pdn: %lx\n", pdn); + + *ptbl_page_p = alloc_page(GFP_ATOMIC); + if (!*ptbl_page_p) { + dev_err(as->smmu->dev, + "failed to allocate smmu_device page table\n"); + return NULL; + } + SetPageReserved(*ptbl_page_p); + ptbl = (unsigned long *)page_address(*ptbl_page_p); + for (pn = 0; pn < SMMU_PTBL_COUNT; + pn++, addr += SMMU_PAGE_SIZE) { + ptbl[pn] = _PTE_VACANT(addr); + } + FLUSH_CPU_DCACHE(ptbl, *ptbl_page_p, SMMU_PTBL_SIZE); + pdir[pdn] = SMMU_MK_PDE(*ptbl_page_p, + as->pde_attr | _PDE_NEXT); + FLUSH_CPU_DCACHE(&pdir[pdn], as->pdir_page, sizeof pdir[pdn]); + flush_ptc_and_tlb(as->smmu, as, iova, &pdir[pdn], + as->pdir_page, 1); + } + *count = &as->pte_count[pdn]; + + return &ptbl[ptn % SMMU_PTBL_COUNT]; +} + +#ifdef CONFIG_SMMU_SIG_DEBUG +static void put_signature(struct smmu_as *as, + dma_addr_t iova, unsigned long pfn) +{ + struct page *page; + unsigned long *vaddr; + + page = pfn_to_page(pfn); + vaddr = page_address(page); + if (!vaddr) + return; + + vaddr[0] = iova; + vaddr[1] = pfn << PAGE_SHIFT; + FLUSH_CPU_DCACHE(vaddr, page, sizeof(vaddr[0]) * 2); +} +#else +static inline void put_signature(struct smmu_as *as, + unsigned long addr, unsigned long pfn) +{ +} +#endif + +/* + * Caller must lock/unlock as + */ +static int alloc_pdir(struct smmu_as *as) +{ + unsigned long *pdir; + int pdn; + u32 val; + struct smmu_device *smmu = as->smmu; + + if (as->pdir_page) + return 0; + + as->pte_count = devm_kzalloc(smmu->dev, + sizeof(as->pte_count[0]) * SMMU_PDIR_COUNT, GFP_KERNEL); + if (!as->pte_count) { + dev_err(smmu->dev, + "failed to allocate smmu_device PTE cunters\n"); + return -ENOMEM; + } + as->pdir_page = alloc_page(GFP_KERNEL | __GFP_DMA); + if (!as->pdir_page) { + dev_err(smmu->dev, + "failed to allocate smmu_device page directory\n"); + devm_kfree(smmu->dev, as->pte_count); + as->pte_count = NULL; + return -ENOMEM; + } + SetPageReserved(as->pdir_page); + pdir = page_address(as->pdir_page); + + for (pdn = 0; pdn < SMMU_PDIR_COUNT; pdn++) + pdir[pdn] = _PDE_VACANT(pdn); + FLUSH_CPU_DCACHE(pdir, as->pdir_page, SMMU_PDIR_SIZE); + val = SMMU_PTC_FLUSH_TYPE_ADR | VA_PAGE_TO_PA(pdir, as->pdir_page); + smmu_write(smmu, val, SMMU_PTC_FLUSH); + FLUSH_SMMU_REGS(as->smmu); + val = SMMU_TLB_FLUSH_VA_MATCH_ALL | + SMMU_TLB_FLUSH_ASID_MATCH__ENABLE | + (as->asid << SMMU_TLB_FLUSH_ASID_SHIFT); + smmu_write(smmu, val, SMMU_TLB_FLUSH); + FLUSH_SMMU_REGS(as->smmu); + + return 0; +} + +static void __smmu_iommu_unmap(struct smmu_as *as, dma_addr_t iova) +{ + unsigned long *pte; + struct page *page; + unsigned int *count; + + pte = locate_pte(as, iova, false, &page, &count); + if (WARN_ON(!pte)) + return; + + if (WARN_ON(*pte == _PTE_VACANT(iova))) + return; + + *pte = _PTE_VACANT(iova); + FLUSH_CPU_DCACHE(pte, page, sizeof(*pte)); + flush_ptc_and_tlb(as->smmu, as, iova, pte, page, 0); + if (!--(*count)) { + free_ptbl(as, iova); + smmu_flush_regs(as->smmu, 0); + } +} + +static void __smmu_iommu_map_pfn(struct smmu_as *as, dma_addr_t iova, + unsigned long pfn) +{ + struct smmu_device *smmu = as->smmu; + unsigned long *pte; + unsigned int *count; + struct page *page; + + pte = locate_pte(as, iova, true, &page, &count); + if (WARN_ON(!pte)) + return; + + if (*pte == _PTE_VACANT(iova)) + (*count)++; + *pte = SMMU_PFN_TO_PTE(pfn, as->pte_attr); + if (unlikely((*pte == _PTE_VACANT(iova)))) + (*count)--; + FLUSH_CPU_DCACHE(pte, page, sizeof(*pte)); + flush_ptc_and_tlb(smmu, as, iova, pte, page, 0); + put_signature(as, iova, pfn); +} + +static int smmu_iommu_map(struct iommu_domain *domain, unsigned long iova, + phys_addr_t pa, size_t bytes, int prot) +{ + struct smmu_as *as = domain->priv; + unsigned long pfn = __phys_to_pfn(pa); + unsigned long flags; + + dev_dbg(as->smmu->dev, "[%d] %08lx:%08x\n", as->asid, iova, pa); + + if (!pfn_valid(pfn)) + return -ENOMEM; + + spin_lock_irqsave(&as->lock, flags); + __smmu_iommu_map_pfn(as, iova, pfn); + spin_unlock_irqrestore(&as->lock, flags); + return 0; +} + +static size_t smmu_iommu_unmap(struct iommu_domain *domain, unsigned long iova, + size_t bytes) +{ + struct smmu_as *as = domain->priv; + unsigned long flags; + + dev_dbg(as->smmu->dev, "[%d] %08lx\n", as->asid, iova); + + spin_lock_irqsave(&as->lock, flags); + __smmu_iommu_unmap(as, iova); + spin_unlock_irqrestore(&as->lock, flags); + return SMMU_PAGE_SIZE; +} + +static phys_addr_t smmu_iommu_iova_to_phys(struct iommu_domain *domain, + unsigned long iova) +{ + struct smmu_as *as = domain->priv; + unsigned long *pte; + unsigned int *count; + struct page *page; + unsigned long pfn; + unsigned long flags; + + spin_lock_irqsave(&as->lock, flags); + + pte = locate_pte(as, iova, true, &page, &count); + pfn = *pte & SMMU_PFN_MASK; + WARN_ON(!pfn_valid(pfn)); + dev_dbg(as->smmu->dev, + "iova:%08lx pfn:%08lx asid:%d\n", iova, pfn, as->asid); + + spin_unlock_irqrestore(&as->lock, flags); + return PFN_PHYS(pfn); +} + +static int smmu_iommu_domain_has_cap(struct iommu_domain *domain, + unsigned long cap) +{ + return 0; +} + +static int smmu_iommu_attach_dev(struct iommu_domain *domain, + struct device *dev) +{ + struct smmu_as *as = domain->priv; + struct smmu_device *smmu = as->smmu; + struct smmu_client *client, *c; + u32 map; + int err; + + client = devm_kzalloc(smmu->dev, sizeof(*c), GFP_KERNEL); + if (!client) + return -ENOMEM; + client->dev = dev; + client->as = as; + map = (unsigned long)dev->platform_data; + if (!map) + return -EINVAL; + + err = smmu_client_enable_hwgrp(client, map); + if (err) + goto err_hwgrp; + + spin_lock(&as->client_lock); + list_for_each_entry(c, &as->client, list) { + if (c->dev == dev) { + dev_err(smmu->dev, + "%s is already attached\n", dev_name(c->dev)); + err = -EINVAL; + goto err_client; + } + } + list_add(&client->list, &as->client); + spin_unlock(&as->client_lock); + + /* + * Reserve "page zero" for AVP vectors using a common dummy + * page. + */ + if (map & HWG_AVPC) { + struct page *page; + + page = as->smmu->avp_vector_page; + __smmu_iommu_map_pfn(as, 0, page_to_pfn(page)); + + pr_info("Reserve \"page zero\" for AVP vectors using a common dummy\n"); + } + + dev_dbg(smmu->dev, "%s is attached\n", dev_name(c->dev)); + return 0; + +err_client: + smmu_client_disable_hwgrp(client); + spin_unlock(&as->client_lock); +err_hwgrp: + devm_kfree(smmu->dev, client); + return err; +} + +static void smmu_iommu_detach_dev(struct iommu_domain *domain, + struct device *dev) +{ + struct smmu_as *as = domain->priv; + struct smmu_device *smmu = as->smmu; + struct smmu_client *c; + + spin_lock(&as->client_lock); + + list_for_each_entry(c, &as->client, list) { + if (c->dev == dev) { + smmu_client_disable_hwgrp(c); + list_del(&c->list); + devm_kfree(smmu->dev, c); + c->as = NULL; + dev_dbg(smmu->dev, + "%s is detached\n", dev_name(c->dev)); + goto out; + } + } + dev_err(smmu->dev, "Couldn't find %s\n", dev_name(c->dev)); +out: + spin_unlock(&as->client_lock); +} + +static int smmu_iommu_domain_init(struct iommu_domain *domain) +{ + int i; + unsigned long flags; + struct smmu_as *as; + struct smmu_device *smmu = smmu_handle; + + /* Look for a free AS with lock held */ + for (i = 0; i < smmu->num_as; i++) { + struct smmu_as *tmp = &smmu->as[i]; + + spin_lock_irqsave(&tmp->lock, flags); + if (!tmp->pdir_page) { + as = tmp; + goto found; + } + spin_unlock_irqrestore(&tmp->lock, flags); + } + dev_err(smmu->dev, "no free AS\n"); + return -ENODEV; + +found: + if (alloc_pdir(as) < 0) + goto err_alloc_pdir; + + spin_lock(&smmu->lock); + + /* Update PDIR register */ + smmu_write(smmu, SMMU_PTB_ASID_CUR(as->asid), SMMU_PTB_ASID); + smmu_write(smmu, + SMMU_MK_PDIR(as->pdir_page, as->pdir_attr), SMMU_PTB_DATA); + FLUSH_SMMU_REGS(smmu); + + spin_unlock(&smmu->lock); + + spin_unlock_irqrestore(&as->lock, flags); + domain->priv = as; + + dev_dbg(smmu->dev, "smmu_as@%p\n", as); + return 0; + +err_alloc_pdir: + spin_unlock_irqrestore(&as->lock, flags); + return -ENODEV; +} + +static void smmu_iommu_domain_destroy(struct iommu_domain *domain) +{ + struct smmu_as *as = domain->priv; + struct smmu_device *smmu = as->smmu; + unsigned long flags; + + spin_lock_irqsave(&as->lock, flags); + + if (as->pdir_page) { + spin_lock(&smmu->lock); + smmu_write(smmu, SMMU_PTB_ASID_CUR(as->asid), SMMU_PTB_ASID); + smmu_write(smmu, SMMU_PTB_DATA_RESET_VAL, SMMU_PTB_DATA); + FLUSH_SMMU_REGS(smmu); + spin_unlock(&smmu->lock); + + free_pdir(as); + } + + if (!list_empty(&as->client)) { + struct smmu_client *c; + + list_for_each_entry(c, &as->client, list) + smmu_iommu_detach_dev(domain, c->dev); + } + + spin_unlock_irqrestore(&as->lock, flags); + + domain->priv = NULL; + dev_dbg(smmu->dev, "smmu_as@%p\n", as); +} + +static struct iommu_ops smmu_iommu_ops = { + .domain_init = smmu_iommu_domain_init, + .domain_destroy = smmu_iommu_domain_destroy, + .attach_dev = smmu_iommu_attach_dev, + .detach_dev = smmu_iommu_detach_dev, + .map = smmu_iommu_map, + .unmap = smmu_iommu_unmap, + .iova_to_phys = smmu_iommu_iova_to_phys, + .domain_has_cap = smmu_iommu_domain_has_cap, + .pgsize_bitmap = SMMU_IOMMU_PGSIZES, +}; + +static int tegra_smmu_suspend(struct device *dev) +{ + struct smmu_device *smmu = dev_get_drvdata(dev); + + smmu->translation_enable_0 = smmu_read(smmu, SMMU_TRANSLATION_ENABLE_0); + smmu->translation_enable_1 = smmu_read(smmu, SMMU_TRANSLATION_ENABLE_1); + smmu->translation_enable_2 = smmu_read(smmu, SMMU_TRANSLATION_ENABLE_2); + smmu->asid_security = smmu_read(smmu, SMMU_ASID_SECURITY); + return 0; +} + +static int tegra_smmu_resume(struct device *dev) +{ + struct smmu_device *smmu = dev_get_drvdata(dev); + unsigned long flags; + + spin_lock_irqsave(&smmu->lock, flags); + smmu_setup_regs(smmu); + spin_unlock_irqrestore(&smmu->lock, flags); + return 0; +} + +static int tegra_smmu_probe(struct platform_device *pdev) +{ + struct smmu_device *smmu; + struct resource *regs, *regs2, *window; + struct device *dev = &pdev->dev; + int i, err = 0; + + if (smmu_handle) + return -EIO; + + BUILD_BUG_ON(PAGE_SHIFT != SMMU_PAGE_SHIFT); + + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + regs2 = platform_get_resource(pdev, IORESOURCE_MEM, 1); + window = platform_get_resource(pdev, IORESOURCE_MEM, 2); + if (!regs || !regs2 || !window) { + dev_err(dev, "No SMMU resources\n"); + return -ENODEV; + } + + smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL); + if (!smmu) { + dev_err(dev, "failed to allocate smmu_device\n"); + return -ENOMEM; + } + + smmu->dev = dev; + smmu->num_as = SMMU_NUM_ASIDS; + smmu->iovmm_base = (unsigned long)window->start; + smmu->page_count = resource_size(window) >> SMMU_PAGE_SHIFT; + smmu->regs = devm_ioremap(dev, regs->start, resource_size(regs)); + smmu->regs_ahbarb = devm_ioremap(dev, regs2->start, + resource_size(regs2)); + if (!smmu->regs || !smmu->regs_ahbarb) { + dev_err(dev, "failed to remap SMMU registers\n"); + err = -ENXIO; + goto fail; + } + + smmu->translation_enable_0 = ~0; + smmu->translation_enable_1 = ~0; + smmu->translation_enable_2 = ~0; + smmu->asid_security = 0; + + smmu->as = devm_kzalloc(dev, + sizeof(smmu->as[0]) * smmu->num_as, GFP_KERNEL); + if (!smmu->as) { + dev_err(dev, "failed to allocate smmu_as\n"); + err = -ENOMEM; + goto fail; + } + + for (i = 0; i < smmu->num_as; i++) { + struct smmu_as *as = &smmu->as[i]; + + as->smmu = smmu; + as->asid = i; + as->pdir_attr = _PDIR_ATTR; + as->pde_attr = _PDE_ATTR; + as->pte_attr = _PTE_ATTR; + + spin_lock_init(&as->lock); + INIT_LIST_HEAD(&as->client); + } + spin_lock_init(&smmu->lock); + smmu_setup_regs(smmu); + platform_set_drvdata(pdev, smmu); + + smmu->avp_vector_page = alloc_page(GFP_KERNEL); + if (!smmu->avp_vector_page) + goto fail; + + smmu_handle = smmu; + return 0; + +fail: + if (smmu->avp_vector_page) + __free_page(smmu->avp_vector_page); + if (smmu->regs) + devm_iounmap(dev, smmu->regs); + if (smmu->regs_ahbarb) + devm_iounmap(dev, smmu->regs_ahbarb); + if (smmu && smmu->as) { + for (i = 0; i < smmu->num_as; i++) { + if (smmu->as[i].pdir_page) { + ClearPageReserved(smmu->as[i].pdir_page); + __free_page(smmu->as[i].pdir_page); + } + } + devm_kfree(dev, smmu->as); + } + devm_kfree(dev, smmu); + return err; +} + +static int tegra_smmu_remove(struct platform_device *pdev) +{ + struct smmu_device *smmu = platform_get_drvdata(pdev); + struct device *dev = smmu->dev; + + smmu_write(smmu, SMMU_CONFIG_DISABLE, SMMU_CONFIG); + platform_set_drvdata(pdev, NULL); + if (smmu->as) { + int i; + + for (i = 0; i < smmu->num_as; i++) + free_pdir(&smmu->as[i]); + devm_kfree(dev, smmu->as); + } + if (smmu->avp_vector_page) + __free_page(smmu->avp_vector_page); + if (smmu->regs) + devm_iounmap(dev, smmu->regs); + if (smmu->regs_ahbarb) + devm_iounmap(dev, smmu->regs_ahbarb); + devm_kfree(dev, smmu); + smmu_handle = NULL; + return 0; +} + +const struct dev_pm_ops tegra_smmu_pm_ops = { + .suspend = tegra_smmu_suspend, + .resume = tegra_smmu_resume, +}; + +static struct platform_driver tegra_smmu_driver = { + .probe = tegra_smmu_probe, + .remove = tegra_smmu_remove, + .driver = { + .owner = THIS_MODULE, + .name = "tegra-smmu", + .pm = &tegra_smmu_pm_ops, + }, +}; + +static int __devinit tegra_smmu_init(void) +{ + bus_set_iommu(&platform_bus_type, &smmu_iommu_ops); + return platform_driver_register(&tegra_smmu_driver); +} + +static void __exit tegra_smmu_exit(void) +{ + platform_driver_unregister(&tegra_smmu_driver); +} + +subsys_initcall(tegra_smmu_init); +module_exit(tegra_smmu_exit); + +MODULE_DESCRIPTION("IOMMU API for SMMU in Tegra30"); +MODULE_AUTHOR("Hiroshi DOYU "); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-70-g09d2 From cf427952adcee0210e64b77ae7de9c8f256cce5c Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sat, 21 Jan 2012 11:19:29 -0300 Subject: [media] anysee: repeat failed USB control messages Control message load increased heavily after CI/CAM support due to dvb_ca_en50221. It looks like CI/CAM drops to non-working state easily after error is returned to its callbacks. Due to that, add some logic to avoid errors repeating failed messages. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/anysee.c | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c index cf0c318d698..03c28655af1 100644 --- a/drivers/media/dvb/dvb-usb/anysee.c +++ b/drivers/media/dvb/dvb-usb/anysee.c @@ -58,7 +58,7 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, u8 *rbuf, u8 rlen) { struct anysee_state *state = d->priv; - int act_len, ret; + int act_len, ret, i; u8 buf[64]; memcpy(&buf[0], sbuf, slen); @@ -73,26 +73,52 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, /* We need receive one message more after dvb_usb_generic_rw due to weird transaction flow, which is 1 x send + 2 x receive. */ ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0); - if (!ret) { + if (ret) + goto error_unlock; + + /* TODO FIXME: dvb_usb_generic_rw() fails rarely with error code -32 + * (EPIPE, Broken pipe). Function supports currently msleep() as a + * parameter but I would not like to use it, since according to + * Documentation/timers/timers-howto.txt it should not be used such + * short, under < 20ms, sleeps. Repeating failed message would be + * better choice as not to add unwanted delays... + * Fixing that correctly is one of those or both; + * 1) use repeat if possible + * 2) add suitable delay + */ + + /* get answer, retry few times if error returned */ + for (i = 0; i < 3; i++) { /* receive 2nd answer */ ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint), buf, sizeof(buf), &act_len, 2000); - if (ret) - err("%s: recv bulk message failed: %d", __func__, ret); - else { + + if (ret) { + deb_info("%s: recv bulk message failed: %d", + __func__, ret); + } else { deb_xfer("<<< "); debug_dump(buf, rlen, deb_xfer); if (buf[63] != 0x4f) deb_info("%s: cmd failed\n", __func__); + + break; } } + if (ret) { + /* all retries failed, it is fatal */ + err("%s: recv bulk message failed: %d", __func__, ret); + goto error_unlock; + } + /* read request, copy returned data to return buf */ - if (!ret && rbuf && rlen) + if (rbuf && rlen) memcpy(rbuf, buf, rlen); +error_unlock: mutex_unlock(&anysee_usb_mutex); return ret; -- cgit v1.2.3-70-g09d2 From e4b444369c75604ef6e656969039b1c6b4ca61c5 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 23 Jan 2012 18:45:58 -0300 Subject: [media] drxk_hard: does not need to include linux/version.h This patch removes the unneeded include. Signed-off-by: Jesper Juhl Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/drxk_hard.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c index 5fa192731fc..47bf16d44bc 100644 --- a/drivers/media/dvb/frontends/drxk_hard.c +++ b/drivers/media/dvb/frontends/drxk_hard.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include "dvb_frontend.h" -- cgit v1.2.3-70-g09d2 From 23268ae5f0447316101ff320ac89d5ee8a0b5f70 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 24 Jan 2012 05:24:36 -0300 Subject: [media] vivi: don't set V4L2_CAP_DEVICE_CAPS for the device_caps field V4L2_CAP_DEVICE_CAPS is valid for the capabilities field only as per the spec. Found with v4l2-compliance. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/vivi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 84ea88dc10a..5578c195358 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c @@ -819,9 +819,9 @@ static int vidioc_querycap(struct file *file, void *priv, strcpy(cap->driver, "vivi"); strcpy(cap->card, "vivi"); strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | - V4L2_CAP_READWRITE | V4L2_CAP_DEVICE_CAPS; - cap->device_caps = cap->capabilities; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | + V4L2_CAP_READWRITE; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } -- cgit v1.2.3-70-g09d2 From a24f64a648376766497fddd8bc24b1ca5b906431 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 26 Jan 2012 18:30:16 +0000 Subject: regmap: Reset device debugfs when reinitialising the cache Most of the data exposed via debugfs is for or from the cache so reset all the debugfs configuration to make sure everything is up to date with the latest configuration, especially if we're changing cache type. Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index e9c2ac0174c..2d71aeae310 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -278,6 +278,7 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config) mutex_lock(&map->lock); regcache_exit(map); + regmap_debugfs_exit(map); map->max_register = config->max_register; map->writeable_reg = config->writeable_reg; @@ -286,6 +287,8 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config) map->precious_reg = config->precious_reg; map->cache_type = config->cache_type; + regmap_debugfs_init(map); + ret = regcache_init(map, config); mutex_unlock(&map->lock); -- cgit v1.2.3-70-g09d2 From 8d7b02783bc2b05974f6e47c2be8157f3a9cd89e Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Thu, 26 Jan 2012 06:01:45 +0000 Subject: bnx2x: Support Queue Per Cos in 5771xx devices Enable the use of up to three hardware queues for transmission. The queues are always dequed round robin (i.e. strict priority, PFC and ETS are not supported). This does allow the allocation of a seperate HW queue for low volume, high priority traffic which will be serviced more promptly. Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 7 ++++--- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index bf27c54ff2e..0dd22bb44f0 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -984,10 +984,11 @@ static inline int bnx2x_func_start(struct bnx2x *bp) /* Function parameters */ start_params->mf_mode = bp->mf_mode; start_params->sd_vlan_tag = bp->mf_ov; - if (CHIP_IS_E1x(bp)) - start_params->network_cos_mode = OVERRIDE_COS; - else + + if (CHIP_IS_E2(bp) || CHIP_IS_E3(bp)) start_params->network_cos_mode = STATIC_COS; + else /* CHIP_IS_E1X */ + start_params->network_cos_mode = FW_WRR; return bnx2x_func_state_change(bp, &func_params); } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h index 66da39f0c84..f33bc5722e5 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h @@ -803,10 +803,10 @@ enum bnx2x_q_type { }; #define BNX2X_PRIMARY_CID_INDEX 0 -#define BNX2X_MULTI_TX_COS_E1X 1 +#define BNX2X_MULTI_TX_COS_E1X 3 /* QM only */ #define BNX2X_MULTI_TX_COS_E2_E3A0 2 #define BNX2X_MULTI_TX_COS_E3B0 3 -#define BNX2X_MULTI_TX_COS BNX2X_MULTI_TX_COS_E3B0 +#define BNX2X_MULTI_TX_COS 3 /* Maximum possible */ struct bnx2x_queue_init_params { -- cgit v1.2.3-70-g09d2 From 127a425e8f05b9813879e8ca909ef4338ec8ec04 Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Thu, 26 Jan 2012 06:01:46 +0000 Subject: bnx2x: Removing indirect register access In virtualized environments indirect access to the device may not be supported (depending on the Hypervisor type). Indirect device access was used since in some harware contexts (i.e. certain chipset and BIOS) every access the driver makes across the pci is followed by a BIOS initiated Zero Length Read to the same address. When accessing widebus registers this zero length read corrupts the serialization of the read/write sequence resulting with errors. To avoid this problem widebus registers are always accessed via the DMAE or the indirect interface. However, the 57712x and 578xx devices intercept the zero length read and so using the indirect interface with these devices is not necessary. Since PDA is only supported for 57712x and 578xx the indirect access to device was restricted to 57710 and 57711x. Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- .../net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h | 53 ++++++++++++---------- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 24 +++++++--- 2 files changed, 47 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h index 7ec1724753a..f05ee2f137f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h @@ -69,12 +69,12 @@ static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len, { if (bp->dmae_ready) bnx2x_write_dmae_phys_len(bp, GUNZIP_PHYS(bp), addr, len); - else if (wb) - /* - * Wide bus registers with no dmae need to be written - * using indirect write. - */ + + /* in E1 chips BIOS initiated ZLR may interrupt widebus writes */ + else if (wb && CHIP_IS_E1(bp)) bnx2x_init_ind_wr(bp, addr, GUNZIP_BUF(bp), len); + + /* in later chips PXP root complex handles BIOS ZLR w/o interrupting */ else bnx2x_init_str_wr(bp, addr, GUNZIP_BUF(bp), len); } @@ -99,8 +99,14 @@ static void bnx2x_write_big_buf_wb(struct bnx2x *bp, u32 addr, u32 len) { if (bp->dmae_ready) bnx2x_write_dmae_phys_len(bp, GUNZIP_PHYS(bp), addr, len); - else + + /* in E1 chips BIOS initiated ZLR may interrupt widebus writes */ + else if (CHIP_IS_E1(bp)) bnx2x_init_ind_wr(bp, addr, GUNZIP_BUF(bp), len); + + /* in later chips PXP root complex handles BIOS ZLR w/o interrupting */ + else + bnx2x_init_str_wr(bp, addr, GUNZIP_BUF(bp), len); } static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, @@ -177,8 +183,14 @@ static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, { if (bp->dmae_ready) VIRT_WR_DMAE_LEN(bp, data, addr, len, 0); - else + + /* in E1 chips BIOS initiated ZLR may interrupt widebus writes */ + else if (CHIP_IS_E1(bp)) bnx2x_init_ind_wr(bp, addr, data, len); + + /* in later chips PXP root complex handles BIOS ZLR w/o interrupting */ + else + bnx2x_init_str_wr(bp, addr, data, len); } static void bnx2x_wr_64(struct bnx2x *bp, u32 reg, u32 val_lo, @@ -840,25 +852,15 @@ static void bnx2x_qm_init_cid_count(struct bnx2x *bp, int qm_cid_count, } } -static void bnx2x_qm_set_ptr_table(struct bnx2x *bp, int qm_cid_count) +static void bnx2x_qm_set_ptr_table(struct bnx2x *bp, int qm_cid_count, + u32 base_reg, u32 reg) { int i; - u32 wb_data[2]; - - wb_data[0] = wb_data[1] = 0; - + u32 wb_data[2] = {0, 0}; for (i = 0; i < 4 * QM_QUEUES_PER_FUNC; i++) { - REG_WR(bp, QM_REG_BASEADDR + i*4, + REG_WR(bp, base_reg + i*4, qm_cid_count * 4 * (i % QM_QUEUES_PER_FUNC)); - bnx2x_init_ind_wr(bp, QM_REG_PTRTBL + i*8, - wb_data, 2); - - if (CHIP_IS_E1H(bp)) { - REG_WR(bp, QM_REG_BASEADDR_EXT_A + i*4, - qm_cid_count * 4 * (i % QM_QUEUES_PER_FUNC)); - bnx2x_init_ind_wr(bp, QM_REG_PTRTBL_EXT_A + i*8, - wb_data, 2); - } + bnx2x_init_wr_wb(bp, reg + i*8, wb_data, 2); } } @@ -873,7 +875,12 @@ static void bnx2x_qm_init_ptr_table(struct bnx2x *bp, int qm_cid_count, case INITOP_INIT: /* set in the init-value array */ case INITOP_SET: - bnx2x_qm_set_ptr_table(bp, qm_cid_count); + bnx2x_qm_set_ptr_table(bp, qm_cid_count, + QM_REG_BASEADDR, QM_REG_PTRTBL); + if (CHIP_IS_E1H(bp)) + bnx2x_qm_set_ptr_table(bp, qm_cid_count, + QM_REG_BASEADDR_EXT_A, + QM_REG_PTRTBL_EXT_A); break; case INITOP_CLEAR: break; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 1e3f978ee6d..e56b8326652 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -498,9 +498,13 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr, if (!bp->dmae_ready) { u32 *data = bnx2x_sp(bp, wb_data[0]); - DP(BNX2X_MSG_OFF, "DMAE is not ready (dst_addr %08x len32 %d)" - " using indirect\n", dst_addr, len32); - bnx2x_init_ind_wr(bp, dst_addr, data, len32); + DP(BNX2X_MSG_OFF, + "DMAE is not ready (dst_addr %08x len32 %d) using indirect\n", + dst_addr, len32); + if (CHIP_IS_E1(bp)) + bnx2x_init_ind_wr(bp, dst_addr, data, len32); + else + bnx2x_init_str_wr(bp, dst_addr, data, len32); return; } @@ -528,10 +532,16 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32) u32 *data = bnx2x_sp(bp, wb_data[0]); int i; - DP(BNX2X_MSG_OFF, "DMAE is not ready (src_addr %08x len32 %d)" - " using indirect\n", src_addr, len32); - for (i = 0; i < len32; i++) - data[i] = bnx2x_reg_rd_ind(bp, src_addr + i*4); + if (CHIP_IS_E1(bp)) { + DP(BNX2X_MSG_OFF, + "DMAE is not ready (src_addr %08x len32 %d) using indirect\n", + src_addr, len32); + for (i = 0; i < len32; i++) + data[i] = bnx2x_reg_rd_ind(bp, src_addr + i*4); + } else + for (i = 0; i < len32; i++) + data[i] = REG_RD(bp, src_addr + i*4); + return; } -- cgit v1.2.3-70-g09d2 From c22610d0001ebf3420d39f419056a56c5aa43096 Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Thu, 26 Jan 2012 06:01:47 +0000 Subject: bnx2x: Obtain Bus Device Function from register BDF was obtained from kernel but since in virtualized environment (e.g. physical device assigment in KVM) the function number may not be the real one, the info must be obtained from the device. Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 17 ++++++++++++++++- drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h | 3 ++- 2 files changed, 18 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index e56b8326652..115d77a8beb 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -10546,6 +10546,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, { struct bnx2x *bp; int rc; + u32 pci_cfg_dword; bool chip_is_e1x = (board_type == BCM57710 || board_type == BCM57711 || board_type == BCM57711E); @@ -10556,7 +10557,6 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, bp->dev = dev; bp->pdev = pdev; bp->flags = 0; - bp->pf_num = PCI_FUNC(pdev->devfn); rc = pci_enable_device(pdev); if (rc) { @@ -10623,6 +10623,21 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, goto err_out_release; } + /* In E1/E1H use pci device function given by kernel. + * In E2/E3 read physical function from ME register since these chips + * support Physical Device Assignment where kernel BDF maybe arbitrary + * (depending on hypervisor). + */ + if (chip_is_e1x) + bp->pf_num = PCI_FUNC(pdev->devfn); + else {/* chip is E2/3*/ + pci_read_config_dword(bp->pdev, + PCICFG_ME_REGISTER, &pci_cfg_dword); + bp->pf_num = (u8)((pci_cfg_dword & ME_REG_ABS_PF_NUM) >> + ME_REG_ABS_PF_NUM_SHIFT); + } + DP(BNX2X_MSG_SP, "me reg PF num: %d\n", bp->pf_num); + bnx2x_set_power_state(bp, PCI_D0); /* clean indirect addresses */ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h index dddbcf6e154..8c79e00b37e 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h @@ -6023,7 +6023,8 @@ #define PCICFG_MSI_CONTROL_64_BIT_ADDR_CAP (0x1<<23) #define PCICFG_MSI_CONTROL_MSI_PVMASK_CAPABLE (0x1<<24) #define PCICFG_GRC_ADDRESS 0x78 -#define PCICFG_GRC_DATA 0x80 +#define PCICFG_GRC_DATA 0x80 +#define PCICFG_ME_REGISTER 0x98 #define PCICFG_MSIX_CAP_ID_OFFSET 0xa0 #define PCICFG_MSIX_CONTROL_TABLE_SIZE (0x7ff<<16) #define PCICFG_MSIX_CONTROL_RESERVED (0x7<<27) -- cgit v1.2.3-70-g09d2 From 89db4ad830fbdde9c2d990b88bbac8245718177d Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Thu, 26 Jan 2012 06:01:48 +0000 Subject: bnx2x: Function Level Reset Final Cleanup 1. Fix bug where return value is ignored 2. Improve printouts 3. Fix typos Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 28 ++++++++++++++---------- 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 115d77a8beb..9a1c4501f0e 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -1017,8 +1017,8 @@ void bnx2x_panic_dump(struct bnx2x *bp) * initialization. */ #define FLR_WAIT_USEC 10000 /* 10 miliseconds */ -#define FLR_WAIT_INTERAVAL 50 /* usec */ -#define FLR_POLL_CNT (FLR_WAIT_USEC/FLR_WAIT_INTERAVAL) /* 200 */ +#define FLR_WAIT_INTERVAL 50 /* usec */ +#define FLR_POLL_CNT (FLR_WAIT_USEC/FLR_WAIT_INTERVAL) /* 200 */ struct pbf_pN_buf_regs { int pN; @@ -1051,7 +1051,7 @@ static void bnx2x_pbf_pN_buf_flushed(struct bnx2x *bp, while ((crd != init_crd) && ((u32)SUB_S32(crd_freed, crd_freed_start) < (init_crd - crd_start))) { if (cur_cnt--) { - udelay(FLR_WAIT_INTERAVAL); + udelay(FLR_WAIT_INTERVAL); crd = REG_RD(bp, regs->crd); crd_freed = REG_RD(bp, regs->crd_freed); } else { @@ -1065,7 +1065,7 @@ static void bnx2x_pbf_pN_buf_flushed(struct bnx2x *bp, } } DP(BNX2X_MSG_SP, "Waited %d*%d usec for PBF tx buffer[%d]\n", - poll_count-cur_cnt, FLR_WAIT_INTERAVAL, regs->pN); + poll_count-cur_cnt, FLR_WAIT_INTERVAL, regs->pN); } static void bnx2x_pbf_pN_cmd_flushed(struct bnx2x *bp, @@ -1083,7 +1083,7 @@ static void bnx2x_pbf_pN_cmd_flushed(struct bnx2x *bp, while (occup && ((u32)SUB_S32(freed, freed_start) < to_free)) { if (cur_cnt--) { - udelay(FLR_WAIT_INTERAVAL); + udelay(FLR_WAIT_INTERVAL); occup = REG_RD(bp, regs->lines_occup); freed = REG_RD(bp, regs->lines_freed); } else { @@ -1097,7 +1097,7 @@ static void bnx2x_pbf_pN_cmd_flushed(struct bnx2x *bp, } } DP(BNX2X_MSG_SP, "Waited %d*%d usec for PBF cmd queue[%d]\n", - poll_count-cur_cnt, FLR_WAIT_INTERAVAL, regs->pN); + poll_count-cur_cnt, FLR_WAIT_INTERVAL, regs->pN); } static inline u32 bnx2x_flr_clnup_reg_poll(struct bnx2x *bp, u32 reg, @@ -1107,7 +1107,7 @@ static inline u32 bnx2x_flr_clnup_reg_poll(struct bnx2x *bp, u32 reg, u32 val; while ((val = REG_RD(bp, reg)) != expected && cur_cnt--) - udelay(FLR_WAIT_INTERAVAL); + udelay(FLR_WAIT_INTERVAL); return val; } @@ -1220,7 +1220,7 @@ static inline int bnx2x_send_final_clnup(struct bnx2x *bp, u8 clnup_func, int ret = 0; if (REG_RD(bp, comp_addr)) { - BNX2X_ERR("Cleanup complete is not 0\n"); + BNX2X_ERR("Cleanup complete was not 0 before sending\n"); return 1; } @@ -1229,7 +1229,7 @@ static inline int bnx2x_send_final_clnup(struct bnx2x *bp, u8 clnup_func, op_gen.command |= OP_GEN_AGG_VECT(clnup_func); op_gen.command |= 1 << SDM_OP_GEN_AGG_VECT_IDX_VALID_SHIFT; - DP(BNX2X_MSG_SP, "FW Final cleanup\n"); + DP(BNX2X_MSG_SP, "sending FW Final cleanup\n"); REG_WR(bp, XSDM_REG_OPERATION_GEN, op_gen.command); if (bnx2x_flr_clnup_reg_poll(bp, comp_addr, 1, poll_cnt) != 1) { @@ -1344,6 +1344,7 @@ static int bnx2x_pf_flr_clnup(struct bnx2x *bp) REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ, 1); /* Poll HW usage counters */ + DP(BNX2X_MSG_SP, "Polling usage counters\n"); if (bnx2x_poll_hw_usage_counters(bp, poll_cnt)) return -EBUSY; @@ -6697,13 +6698,16 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) u16 cdu_ilt_start; u32 addr, val; u32 main_mem_base, main_mem_size, main_mem_prty_clr; - int i, main_mem_width; + int i, main_mem_width, rc; DP(BNX2X_MSG_MCP, "starting func init func %d\n", func); /* FLR cleanup - hmmm */ - if (!CHIP_IS_E1x(bp)) - bnx2x_pf_flr_clnup(bp); + if (!CHIP_IS_E1x(bp)) { + rc = bnx2x_pf_flr_clnup(bp); + if (rc) + return rc; + } /* set MSI reconfigure capability */ if (bp->common.int_block == INT_BLOCK_HC) { -- cgit v1.2.3-70-g09d2 From d1e2d9660e6bca2f06606b4bc65ea669bf669b0a Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Thu, 26 Jan 2012 06:01:49 +0000 Subject: bnx2x: Loaded Firmware Version Validation In a virtualized environment it is possible for a loading driver to discover that Firmware is already loaded to the device, and that this FW does not match its own. This can happen for example if different Physical Functions are Assigned to different VMs in which different driver versions are loaded. The code in this patch ensures that only drivers with matching FW are loaded over the device, and that in the case described above where the Firmware version doesn't match the driver load is aborted. Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 03f3935fd8c..b75c8eab095 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -1783,6 +1783,29 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) rc = -EBUSY; /* other port in diagnostic mode */ LOAD_ERROR_EXIT(bp, load_error1); } + if (load_code != FW_MSG_CODE_DRV_LOAD_COMMON_CHIP && + load_code != FW_MSG_CODE_DRV_LOAD_COMMON) { + /* build FW version dword */ + u32 my_fw = (BCM_5710_FW_MAJOR_VERSION) + + (BCM_5710_FW_MINOR_VERSION << 8) + + (BCM_5710_FW_REVISION_VERSION << 16) + + (BCM_5710_FW_ENGINEERING_VERSION << 24); + + /* read loaded FW from chip */ + u32 loaded_fw = REG_RD(bp, XSEM_REG_PRAM); + + DP(BNX2X_MSG_SP, "loaded fw %x, my fw %x", + loaded_fw, my_fw); + + /* abort nic load if version mismatch */ + if (my_fw != loaded_fw) { + BNX2X_ERR("bnx2x with FW %x already loaded, " + "which mismatches my %x FW. aborting", + loaded_fw, my_fw); + rc = -EBUSY; + LOAD_ERROR_EXIT(bp, load_error2); + } + } } else { int path = BP_PATH(bp); -- cgit v1.2.3-70-g09d2 From f16da43b5df947cef427f19b8f5c4b2f5d566231 Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Thu, 26 Jan 2012 06:01:50 +0000 Subject: bnx2x: Lock PF-common resources Use hardware locks to protect resources common to several Physical Functions. In a virtualized environment the RTNL lock only protects a PF's driver against the PFs sharing it's VMs with regard to device resources. Other PFs may reside in other VMs under other OSs, and are not subject to the lock. Such resources which were previously protected implicitly by the RTNL lock must now be protected explicitly with dedicated HW locks. Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 4 +- .../net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 22 ++++++- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 73 ++++++++++++---------- drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h | 7 ++- 4 files changed, 68 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index 0dd22bb44f0..bd990c2e5d1 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -1540,7 +1540,7 @@ static inline void bnx2x_update_drv_flags(struct bnx2x *bp, u32 flags, u32 set) { if (SHMEM2_HAS(bp, drv_flags)) { u32 drv_flags; - bnx2x_acquire_hw_lock(bp, HW_LOCK_DRV_FLAGS); + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_DRV_FLAGS); drv_flags = SHMEM2_RD(bp, drv_flags); if (set) @@ -1550,7 +1550,7 @@ static inline void bnx2x_update_drv_flags(struct bnx2x *bp, u32 flags, u32 set) SHMEM2_WR(bp, drv_flags, drv_flags); DP(NETIF_MSG_HW, "drv_flags 0x%08x\n", drv_flags); - bnx2x_release_hw_lock(bp, HW_LOCK_DRV_FLAGS); + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_DRV_FLAGS); } } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index 31a8b38ab15..37a5c52197e 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -882,11 +882,27 @@ static int bnx2x_get_eeprom_len(struct net_device *dev) return bp->common.flash_size; } +/* Per pf misc lock must be aquired before the per port mcp lock. Otherwise, had + * we done things the other way around, if two pfs from the same port would + * attempt to access nvram at the same time, we could run into a scenario such + * as: + * pf A takes the port lock. + * pf B succeeds in taking the same lock since they are from the same port. + * pf A takes the per pf misc lock. Performs eeprom access. + * pf A finishes. Unlocks the per pf misc lock. + * Pf B takes the lock and proceeds to perform it's own access. + * pf A unlocks the per port lock, while pf B is still working (!). + * mcp takes the per port lock and corrupts pf B's access (and/or has it's own + * acess corrupted by pf B).* + */ static int bnx2x_acquire_nvram_lock(struct bnx2x *bp) { int port = BP_PORT(bp); int count, i; - u32 val = 0; + u32 val; + + /* acquire HW lock: protect against other PFs in PF Direct Assignment */ + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_NVRAM); /* adjust timeout for emulation/FPGA */ count = BNX2X_NVRAM_TIMEOUT_COUNT; @@ -917,7 +933,7 @@ static int bnx2x_release_nvram_lock(struct bnx2x *bp) { int port = BP_PORT(bp); int count, i; - u32 val = 0; + u32 val; /* adjust timeout for emulation/FPGA */ count = BNX2X_NVRAM_TIMEOUT_COUNT; @@ -941,6 +957,8 @@ static int bnx2x_release_nvram_lock(struct bnx2x *bp) return -EBUSY; } + /* release HW lock: protect against other PFs in PF Direct Assignment */ + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_NVRAM); return 0; } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 9a1c4501f0e..4824b0f8bd2 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -3724,11 +3724,11 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) */ void bnx2x_set_reset_global(struct bnx2x *bp) { - u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); - + u32 val; + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); + val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val | BNX2X_GLOBAL_RESET_BIT); - barrier(); - mmiowb(); + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); } /* @@ -3738,11 +3738,11 @@ void bnx2x_set_reset_global(struct bnx2x *bp) */ static inline void bnx2x_clear_reset_global(struct bnx2x *bp) { - u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); - + u32 val; + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); + val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val & (~BNX2X_GLOBAL_RESET_BIT)); - barrier(); - mmiowb(); + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); } /* @@ -3765,15 +3765,17 @@ static inline bool bnx2x_reset_is_global(struct bnx2x *bp) */ static inline void bnx2x_set_reset_done(struct bnx2x *bp) { - u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); + u32 val; u32 bit = BP_PATH(bp) ? BNX2X_PATH1_RST_IN_PROG_BIT : BNX2X_PATH0_RST_IN_PROG_BIT; + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); + val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); /* Clear the bit */ val &= ~bit; REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val); - barrier(); - mmiowb(); + + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); } /* @@ -3783,15 +3785,16 @@ static inline void bnx2x_set_reset_done(struct bnx2x *bp) */ void bnx2x_set_reset_in_progress(struct bnx2x *bp) { - u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); + u32 val; u32 bit = BP_PATH(bp) ? BNX2X_PATH1_RST_IN_PROG_BIT : BNX2X_PATH0_RST_IN_PROG_BIT; + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); + val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); /* Set the bit */ val |= bit; REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val); - barrier(); - mmiowb(); + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); } /* @@ -3815,12 +3818,15 @@ bool bnx2x_reset_is_done(struct bnx2x *bp, int engine) */ void bnx2x_inc_load_cnt(struct bnx2x *bp) { - u32 val1, val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); + u32 val1, val; u32 mask = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK : BNX2X_PATH0_LOAD_CNT_MASK; u32 shift = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_SHIFT : BNX2X_PATH0_LOAD_CNT_SHIFT; + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); + val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); + DP(NETIF_MSG_HW, "Old GEN_REG_VAL=0x%08x\n", val); /* get the current counter value */ @@ -3836,8 +3842,7 @@ void bnx2x_inc_load_cnt(struct bnx2x *bp) val |= ((val1 << shift) & mask); REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val); - barrier(); - mmiowb(); + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); } /** @@ -3851,12 +3856,14 @@ void bnx2x_inc_load_cnt(struct bnx2x *bp) */ u32 bnx2x_dec_load_cnt(struct bnx2x *bp) { - u32 val1, val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); + u32 val1, val; u32 mask = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK : BNX2X_PATH0_LOAD_CNT_MASK; u32 shift = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_SHIFT : BNX2X_PATH0_LOAD_CNT_SHIFT; + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); + val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); DP(NETIF_MSG_HW, "Old GEN_REG_VAL=0x%08x\n", val); /* get the current counter value */ @@ -3872,10 +3879,8 @@ u32 bnx2x_dec_load_cnt(struct bnx2x *bp) val |= ((val1 << shift) & mask); REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val); - barrier(); - mmiowb(); - - return val1; + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); + return val1 != 0; } /* @@ -3907,11 +3912,13 @@ static inline u32 bnx2x_get_load_cnt(struct bnx2x *bp, int engine) */ static inline void bnx2x_clear_load_cnt(struct bnx2x *bp) { - u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); + u32 val; u32 mask = (BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK : - BNX2X_PATH0_LOAD_CNT_MASK); - + BNX2X_PATH0_LOAD_CNT_MASK); + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); + val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val & (~mask)); + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); } static inline void _print_next_block(int idx, const char *blk) @@ -8809,11 +8816,13 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) { u32 val; - /* Check if there is any driver already loaded */ - val = REG_RD(bp, MISC_REG_UNPREPARED); - if (val == 0x1) { + /* possibly another driver is trying to reset the chip */ + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RESET); + + /* check if doorbell queue is reset */ + if (REG_RD(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET) + & MISC_REGISTERS_RESET_REG_1_RST_DORQ) { - bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RESET); /* * Check if it is the UNDI driver * UNDI driver initializes CID offset for normal bell to 0x7 @@ -8905,10 +8914,10 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) (SHMEM_RD(bp, func_mb[bp->pf_num].drv_mb_header) & DRV_MSG_SEQ_NUMBER_MASK); } - - /* now it's safe to release the lock */ - bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RESET); } + + /* now it's safe to release the lock */ + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RESET); } static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h index 8c79e00b37e..8ade7bd9a71 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h @@ -5731,6 +5731,7 @@ #define MISC_REGISTERS_GPIO_PORT_SHIFT 4 #define MISC_REGISTERS_GPIO_SET_POS 8 #define MISC_REGISTERS_RESET_REG_1_CLEAR 0x588 +#define MISC_REGISTERS_RESET_REG_1_RST_DORQ (0x1<<19) #define MISC_REGISTERS_RESET_REG_1_RST_HC (0x1<<29) #define MISC_REGISTERS_RESET_REG_1_RST_NIG (0x1<<7) #define MISC_REGISTERS_RESET_REG_1_RST_PXP (0x1<<26) @@ -5783,15 +5784,17 @@ #define MISC_REGISTERS_SPIO_OUTPUT_HIGH 1 #define MISC_REGISTERS_SPIO_OUTPUT_LOW 0 #define MISC_REGISTERS_SPIO_SET_POS 8 -#define HW_LOCK_DRV_FLAGS 10 #define HW_LOCK_MAX_RESOURCE_VALUE 31 +#define HW_LOCK_RESOURCE_DRV_FLAGS 10 #define HW_LOCK_RESOURCE_GPIO 1 #define HW_LOCK_RESOURCE_MDIO 0 +#define HW_LOCK_RESOURCE_NVRAM 12 #define HW_LOCK_RESOURCE_PORT0_ATT_MASK 3 #define HW_LOCK_RESOURCE_RECOVERY_LEADER_0 8 #define HW_LOCK_RESOURCE_RECOVERY_LEADER_1 9 -#define HW_LOCK_RESOURCE_SPIO 2 +#define HW_LOCK_RESOURCE_RECOVERY_REG 11 #define HW_LOCK_RESOURCE_RESET 5 +#define HW_LOCK_RESOURCE_SPIO 2 #define AEU_INPUTS_ATTN_BITS_ATC_HW_INTERRUPT (0x1<<4) #define AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR (0x1<<5) #define AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR (0x1<<18) -- cgit v1.2.3-70-g09d2 From 889b9af34f986138eebebfe781567cb950b3a22b Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Thu, 26 Jan 2012 06:01:51 +0000 Subject: bnx2x: Track active PFs with bitmap The recovery register (to which a hardware lock has been added in previous patch) is used amongst other things to track the active PFs. The old implementation which used a per path counter is not viable in a virtualized environment where a pf may increment the counter and then have the kernel crash around it preventing the counter from ever reaching zero. In the new implementation the scenario described will result in the PF timing out against the mcp, which will clear the PF's bit in the bitmask allowing recovery process to proceed. Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 8 +++- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 4 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 56 ++++++++++++------------ 3 files changed, 35 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index b75c8eab095..15db2d679a1 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -1767,6 +1767,9 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) bnx2x_napi_enable(bp); + /* set pf load just before approaching the MCP */ + bnx2x_set_pf_load(bp); + /* Send LOAD_REQUEST command to MCP * Returns the type of LOAD command: * if it is the first port to be initialized @@ -1972,7 +1975,6 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) if (bp->state == BNX2X_STATE_OPEN) bnx2x_cnic_notify(bp, CNIC_CTL_START_CMD); #endif - bnx2x_inc_load_cnt(bp); /* Wait for all pending SP commands to complete */ if (!bnx2x_wait_sp_comp(bp, ~0x0UL)) { @@ -2012,6 +2014,8 @@ load_error2: bp->port.pmf = 0; load_error1: bnx2x_napi_disable(bp); + /* clear pf_load status, as it was already set */ + bnx2x_clear_pf_load(bp); load_error0: bnx2x_free_mem(bp); @@ -2132,7 +2136,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) /* The last driver must disable a "close the gate" if there is no * parity attention or "process kill" pending. */ - if (!bnx2x_dec_load_cnt(bp) && bnx2x_reset_is_done(bp, BP_PATH(bp))) + if (!bnx2x_clear_pf_load(bp) && bnx2x_reset_is_done(bp, BP_PATH(bp))) bnx2x_disable_close_the_gate(bp); return 0; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index bd990c2e5d1..a6ef3ef85e5 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -379,8 +379,8 @@ void bnx2x_set_q_rx_mode(struct bnx2x *bp, u8 cl_id, unsigned long ramrod_flags); /* Parity errors related */ -void bnx2x_inc_load_cnt(struct bnx2x *bp); -u32 bnx2x_dec_load_cnt(struct bnx2x *bp); +void bnx2x_set_pf_load(struct bnx2x *bp); +bool bnx2x_clear_pf_load(struct bnx2x *bp); bool bnx2x_chk_parity_attn(struct bnx2x *bp, bool *global, bool print); bool bnx2x_reset_is_done(struct bnx2x *bp, int engine); void bnx2x_set_reset_in_progress(struct bnx2x *bp); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 4824b0f8bd2..f7f167a0f85 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -3812,11 +3812,11 @@ bool bnx2x_reset_is_done(struct bnx2x *bp, int engine) } /* - * Increment the load counter for the current engine. + * set pf load for the current pf. * * should be run under rtnl lock */ -void bnx2x_inc_load_cnt(struct bnx2x *bp) +void bnx2x_set_pf_load(struct bnx2x *bp) { u32 val1, val; u32 mask = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK : @@ -3832,8 +3832,8 @@ void bnx2x_inc_load_cnt(struct bnx2x *bp) /* get the current counter value */ val1 = (val & mask) >> shift; - /* increment... */ - val1++; + /* set bit of that PF */ + val1 |= (1 << bp->pf_num); /* clear the old value */ val &= ~mask; @@ -3846,15 +3846,15 @@ void bnx2x_inc_load_cnt(struct bnx2x *bp) } /** - * bnx2x_dec_load_cnt - decrement the load counter + * bnx2x_clear_pf_load - clear pf load mark * * @bp: driver handle * * Should be run under rtnl lock. * Decrements the load counter for the current engine. Returns - * the new counter value. + * whether other functions are still loaded */ -u32 bnx2x_dec_load_cnt(struct bnx2x *bp) +bool bnx2x_clear_pf_load(struct bnx2x *bp) { u32 val1, val; u32 mask = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK : @@ -3869,8 +3869,8 @@ u32 bnx2x_dec_load_cnt(struct bnx2x *bp) /* get the current counter value */ val1 = (val & mask) >> shift; - /* decrement... */ - val1--; + /* clear bit of that PF */ + val1 &= ~(1 << bp->pf_num); /* clear the old value */ val &= ~mask; @@ -3884,11 +3884,11 @@ u32 bnx2x_dec_load_cnt(struct bnx2x *bp) } /* - * Read the load counter for the current engine. + * Read the load status for the current engine. * * should be run under rtnl lock */ -static inline u32 bnx2x_get_load_cnt(struct bnx2x *bp, int engine) +static inline bool bnx2x_get_load_status(struct bnx2x *bp, int engine) { u32 mask = (engine ? BNX2X_PATH1_LOAD_CNT_MASK : BNX2X_PATH0_LOAD_CNT_MASK); @@ -3900,17 +3900,15 @@ static inline u32 bnx2x_get_load_cnt(struct bnx2x *bp, int engine) val = (val & mask) >> shift; - DP(NETIF_MSG_HW, "load_cnt for engine %d = %d\n", engine, val); + DP(NETIF_MSG_HW, "load mask for engine %d = 0x%x\n", engine, val); - return val; + return val != 0; } /* - * Reset the load counter for the current engine. - * - * should be run under rtnl lock + * Reset the load status for the current engine. */ -static inline void bnx2x_clear_load_cnt(struct bnx2x *bp) +static inline void bnx2x_clear_load_status(struct bnx2x *bp) { u32 val; u32 mask = (BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK : @@ -8582,10 +8580,10 @@ static void bnx2x_parity_recover(struct bnx2x *bp) DP(NETIF_MSG_HW, "State is BNX2X_RECOVERY_WAIT\n"); if (bp->is_leader) { int other_engine = BP_PATH(bp) ? 0 : 1; - u32 other_load_counter = - bnx2x_get_load_cnt(bp, other_engine); - u32 load_counter = - bnx2x_get_load_cnt(bp, BP_PATH(bp)); + bool other_load_status = + bnx2x_get_load_status(bp, other_engine); + bool load_status = + bnx2x_get_load_status(bp, BP_PATH(bp)); global = bnx2x_reset_is_global(bp); /* @@ -8596,8 +8594,8 @@ static void bnx2x_parity_recover(struct bnx2x *bp) * the the gates will remain closed for that * engine. */ - if (load_counter || - (global && other_load_counter)) { + if (load_status || + (global && other_load_status)) { /* Wait until all other functions get * down. */ @@ -10206,14 +10204,14 @@ static int bnx2x_open(struct net_device *dev) struct bnx2x *bp = netdev_priv(dev); bool global = false; int other_engine = BP_PATH(bp) ? 0 : 1; - u32 other_load_counter, load_counter; + bool other_load_status, load_status; netif_carrier_off(dev); bnx2x_set_power_state(bp, PCI_D0); - other_load_counter = bnx2x_get_load_cnt(bp, other_engine); - load_counter = bnx2x_get_load_cnt(bp, BP_PATH(bp)); + other_load_status = bnx2x_get_load_status(bp, other_engine); + load_status = bnx2x_get_load_status(bp, BP_PATH(bp)); /* * If parity had happen during the unload, then attentions @@ -10239,8 +10237,8 @@ static int bnx2x_open(struct net_device *dev) * global blocks only the first in the chip should try * to recover. */ - if ((!load_counter && - (!global || !other_load_counter)) && + if ((!load_status && + (!global || !other_load_status)) && bnx2x_trylock_leader_lock(bp) && !bnx2x_leader_reset(bp)) { netdev_info(bp->dev, "Recovered in open\n"); @@ -10680,7 +10678,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ, 1); /* Reset the load counter */ - bnx2x_clear_load_cnt(bp); + bnx2x_clear_load_status(bp); dev->watchdog_timeo = TX_TIMEOUT; -- cgit v1.2.3-70-g09d2 From 95c6c6165eaf5a031bcf31606e081c72e4acdeb8 Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Thu, 26 Jan 2012 06:01:52 +0000 Subject: bnx2x: Recovery flow bug fixes 1. Sample mcp pulse and mcp sequence in nic load instead of in init_one as they may change by the time we want to use them. 2. Allow cnic to access device during nic load (by adding a new "LOADING" state to recovery flow). This prevents the unnecessary cnic timeout which resulted by cnic attempting to access because nic is loading, but being blocked because of the Recovery state. 3. Issue 'fake' driver load command to mcp when last driver unloads to prevent mcp from taking ownership. When recovery is complete unload fake driver to allow mcp to initialize the hardware before first driver loads. Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 3 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 18 +++- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 102 +++++++++++++---------- 3 files changed, 75 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 8c73d34b2ff..06bbef742fa 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -1088,7 +1088,8 @@ enum bnx2x_recovery_state { BNX2X_RECOVERY_DONE, BNX2X_RECOVERY_INIT, BNX2X_RECOVERY_WAIT, - BNX2X_RECOVERY_FAILED + BNX2X_RECOVERY_FAILED, + BNX2X_RECOVERY_NIC_LOADING }; /* diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 15db2d679a1..8fdd71b7bef 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -1776,6 +1776,18 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) * common blocks should be initialized, otherwise - not */ if (!BP_NOMCP(bp)) { + /* init fw_seq */ + bp->fw_seq = + (SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) & + DRV_MSG_SEQ_NUMBER_MASK); + BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq); + + /* Get current FW pulse sequence */ + bp->fw_drv_pulse_wr_seq = + (SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_pulse_mb) & + DRV_PULSE_SEQ_MASK); + BNX2X_DEV_INFO("drv_pulse 0x%x\n", bp->fw_drv_pulse_wr_seq); + load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ, 0); if (!load_code) { BNX2X_ERR("MCP response failure, aborting\n"); @@ -3442,7 +3454,7 @@ int bnx2x_change_mtu(struct net_device *dev, int new_mtu) struct bnx2x *bp = netdev_priv(dev); if (bp->recovery_state != BNX2X_RECOVERY_DONE) { - pr_err("Handling parity error recovery. Try again later\n"); + netdev_err(dev, "Handling parity error recovery. Try again later\n"); return -EAGAIN; } @@ -3569,7 +3581,7 @@ int bnx2x_resume(struct pci_dev *pdev) bp = netdev_priv(dev); if (bp->recovery_state != BNX2X_RECOVERY_DONE) { - pr_err("Handling parity error recovery. Try again later\n"); + netdev_err(dev, "Handling parity error recovery. Try again later\n"); return -EAGAIN; } @@ -3585,8 +3597,6 @@ int bnx2x_resume(struct pci_dev *pdev) bnx2x_set_power_state(bp, PCI_D0); netif_device_attach(dev); - /* Since the chip was reset, clear the FW sequence number */ - bp->fw_seq = 0; rc = bnx2x_nic_load(bp, LOAD_OPEN); rtnl_unlock(); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index f7f167a0f85..c945df06161 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -468,7 +468,9 @@ static int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, while ((*wb_comp & ~DMAE_PCI_ERR_FLAG) != DMAE_COMP_VAL) { DP(BNX2X_MSG_OFF, "wb_comp 0x%08x\n", *wb_comp); - if (!cnt) { + if (!cnt || + (bp->recovery_state != BNX2X_RECOVERY_DONE && + bp->recovery_state != BNX2X_RECOVERY_NIC_LOADING)) { BNX2X_ERR("DMAE timeout!\n"); rc = DMAE_TIMEOUT; goto unlock; @@ -8477,13 +8479,38 @@ int bnx2x_leader_reset(struct bnx2x *bp) { int rc = 0; bool global = bnx2x_reset_is_global(bp); + u32 load_code; + + /* if not going to reset MCP - load "fake" driver to reset HW while + * driver is owner of the HW + */ + if (!global && !BP_NOMCP(bp)) { + load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ, 0); + if (!load_code) { + BNX2X_ERR("MCP response failure, aborting\n"); + rc = -EAGAIN; + goto exit_leader_reset; + } + if ((load_code != FW_MSG_CODE_DRV_LOAD_COMMON_CHIP) && + (load_code != FW_MSG_CODE_DRV_LOAD_COMMON)) { + BNX2X_ERR("MCP unexpected resp, aborting\n"); + rc = -EAGAIN; + goto exit_leader_reset2; + } + load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0); + if (!load_code) { + BNX2X_ERR("MCP response failure, aborting\n"); + rc = -EAGAIN; + goto exit_leader_reset2; + } + } /* Try to recover after the failure */ if (bnx2x_process_kill(bp, global)) { netdev_err(bp->dev, "Something bad had happen on engine %d! " "Aii!\n", BP_PATH(bp)); rc = -EAGAIN; - goto exit_leader_reset; + goto exit_leader_reset2; } /* @@ -8494,6 +8521,12 @@ int bnx2x_leader_reset(struct bnx2x *bp) if (global) bnx2x_clear_reset_global(bp); +exit_leader_reset2: + /* unload "fake driver" if it was loaded */ + if (!global && !BP_NOMCP(bp)) { + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP, 0); + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); + } exit_leader_reset: bp->is_leader = 0; bnx2x_release_leader_lock(bp); @@ -8530,13 +8563,15 @@ static inline void bnx2x_recovery_failed(struct bnx2x *bp) static void bnx2x_parity_recover(struct bnx2x *bp) { bool global = false; + bool is_parity; DP(NETIF_MSG_HW, "Handling parity\n"); while (1) { switch (bp->recovery_state) { case BNX2X_RECOVERY_INIT: DP(NETIF_MSG_HW, "State is BNX2X_RECOVERY_INIT\n"); - bnx2x_chk_parity_attn(bp, &global, false); + is_parity = bnx2x_chk_parity_attn(bp, &global, false); + WARN_ON(!is_parity); /* Try to get a LEADER_LOCK HW lock */ if (bnx2x_trylock_leader_lock(bp)) { @@ -8560,15 +8595,6 @@ static void bnx2x_parity_recover(struct bnx2x *bp) bp->recovery_state = BNX2X_RECOVERY_WAIT; - /* - * Reset MCP command sequence number and MCP mail box - * sequence as we are going to reset the MCP. - */ - if (global) { - bp->fw_seq = 0; - bp->fw_drv_pulse_wr_seq = 0; - } - /* Ensure "is_leader", MCP command sequence and * "recovery_state" update values are seen on other * CPUs. @@ -8652,9 +8678,20 @@ static void bnx2x_parity_recover(struct bnx2x *bp) return; } - if (bnx2x_nic_load(bp, LOAD_NORMAL)) - bnx2x_recovery_failed(bp); - else { + bp->recovery_state = + BNX2X_RECOVERY_NIC_LOADING; + if (bnx2x_nic_load(bp, LOAD_NORMAL)) { + netdev_err(bp->dev, + "Recovery failed. " + "Power cycle " + "needed\n"); + /* Disconnect this device */ + netif_device_detach(bp->dev); + /* Shut down the power */ + bnx2x_set_power_state( + bp, PCI_D3hot); + smp_mb(); + } else { bp->recovery_state = BNX2X_RECOVERY_DONE; smp_mb(); @@ -8908,9 +8945,6 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) /* restore our func and fw_seq */ bp->pf_num = orig_pf_num; - bp->fw_seq = - (SHMEM_RD(bp, func_mb[bp->pf_num].drv_mb_header) & - DRV_MSG_SEQ_NUMBER_MASK); } } @@ -9936,16 +9970,6 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) bnx2x_get_cnic_info(bp); - /* Get current FW pulse sequence */ - if (!BP_NOMCP(bp)) { - int mb_idx = BP_FW_MB_IDX(bp); - - bp->fw_drv_pulse_wr_seq = - (SHMEM_RD(bp, func_mb[mb_idx].drv_pulse_mb) & - DRV_PULSE_SEQ_MASK); - BNX2X_DEV_INFO("drv_pulse 0x%x\n", bp->fw_drv_pulse_wr_seq); - } - return rc; } @@ -10115,14 +10139,6 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) if (!BP_NOMCP(bp)) bnx2x_undi_unload(bp); - /* init fw_seq after undi_unload! */ - if (!BP_NOMCP(bp)) { - bp->fw_seq = - (SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) & - DRV_MSG_SEQ_NUMBER_MASK); - BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq); - } - if (CHIP_REV_IS_FPGA(bp)) dev_err(&bp->pdev->dev, "FPGA detected\n"); @@ -11331,13 +11347,6 @@ static void bnx2x_eeh_recover(struct bnx2x *bp) if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) != (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) BNX2X_ERR("BAD MCP validity signature\n"); - - if (!BP_NOMCP(bp)) { - bp->fw_seq = - (SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) & - DRV_MSG_SEQ_NUMBER_MASK); - BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq); - } } /** @@ -11593,6 +11602,13 @@ static int bnx2x_cnic_sp_queue(struct net_device *dev, return -EIO; #endif + if ((bp->recovery_state != BNX2X_RECOVERY_DONE) && + (bp->recovery_state != BNX2X_RECOVERY_NIC_LOADING)) { + netdev_err(dev, "Handling parity error recovery. Try again " + "later\n"); + return -EAGAIN; + } + spin_lock_bh(&bp->spq_lock); for (i = 0; i < count; i++) { -- cgit v1.2.3-70-g09d2 From 7a752993fe90adf8e150cc1a85beef5f782429e7 Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Thu, 26 Jan 2012 06:01:53 +0000 Subject: bnx2x: Recoverable and unrecoverable error statistics Add statistics for tracking parity errors from which we successfully recovered and those which were deemed unrecoverable. Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 12 +++++++++--- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 13 +++++++++++++ drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h | 4 ++++ 3 files changed, 26 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index 37a5c52197e..06cb2442c8f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -175,7 +175,11 @@ static const struct { { STATS_OFFSET32(total_tpa_aggregated_frames_hi), 8, STATS_FLAGS_FUNC, "tpa_aggregated_frames"}, { STATS_OFFSET32(total_tpa_bytes_hi), - 8, STATS_FLAGS_FUNC, "tpa_bytes"} + 8, STATS_FLAGS_FUNC, "tpa_bytes"}, + { STATS_OFFSET32(recoverable_error), + 4, STATS_FLAGS_FUNC, "recoverable_errors" }, + { STATS_OFFSET32(unrecoverable_error), + 4, STATS_FLAGS_FUNC, "unrecoverable_errors" }, }; #define BNX2X_NUM_STATS ARRAY_SIZE(bnx2x_stats_arr) @@ -1388,7 +1392,8 @@ static int bnx2x_set_ringparam(struct net_device *dev, struct bnx2x *bp = netdev_priv(dev); if (bp->recovery_state != BNX2X_RECOVERY_DONE) { - pr_err("Handling parity error recovery. Try again later\n"); + netdev_err(dev, "Handling parity error recovery. " + "Try again later\n"); return -EAGAIN; } @@ -2042,7 +2047,8 @@ static void bnx2x_self_test(struct net_device *dev, struct bnx2x *bp = netdev_priv(dev); u8 is_serdes; if (bp->recovery_state != BNX2X_RECOVERY_DONE) { - pr_err("Handling parity error recovery. Try again later\n"); + netdev_err(bp->dev, "Handling parity error recovery. " + "Try again later\n"); etest->flags |= ETH_TEST_FL_FAILED; return; } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index c945df06161..cdce7663efd 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -784,6 +784,7 @@ void bnx2x_panic_dump(struct bnx2x *bp) #endif bp->stats_state = STATS_STATE_DISABLED; + bp->eth_stats.unrecoverable_error++; DP(BNX2X_MSG_STATS, "stats_state - DISABLED\n"); BNX2X_ERR("begin crash dump -----------------\n"); @@ -5441,6 +5442,7 @@ static void bnx2x_init_eth_fp(struct bnx2x *bp, int fp_idx) /* init shortcut */ fp->ustorm_rx_prods_offset = bnx2x_rx_ustorm_prods_offset(fp); + /* Setup SB indicies */ fp->rx_cons_sb = BNX2X_RX_SB_INDEX; @@ -8563,6 +8565,7 @@ static inline void bnx2x_recovery_failed(struct bnx2x *bp) static void bnx2x_parity_recover(struct bnx2x *bp) { bool global = false; + u32 error_recovered, error_unrecovered; bool is_parity; DP(NETIF_MSG_HW, "Handling parity\n"); @@ -8678,9 +8681,14 @@ static void bnx2x_parity_recover(struct bnx2x *bp) return; } + error_recovered = + bp->eth_stats.recoverable_error; + error_unrecovered = + bp->eth_stats.unrecoverable_error; bp->recovery_state = BNX2X_RECOVERY_NIC_LOADING; if (bnx2x_nic_load(bp, LOAD_NORMAL)) { + error_unrecovered++; netdev_err(bp->dev, "Recovery failed. " "Power cycle " @@ -8694,8 +8702,13 @@ static void bnx2x_parity_recover(struct bnx2x *bp) } else { bp->recovery_state = BNX2X_RECOVERY_DONE; + error_recovered++; smp_mb(); } + bp->eth_stats.recoverable_error = + error_recovered; + bp->eth_stats.unrecoverable_error = + error_unrecovered; return; } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h index 683deb05310..9c28db167fa 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h @@ -199,6 +199,10 @@ struct bnx2x_eth_stats { u32 pfc_frames_received_lo; u32 pfc_frames_sent_hi; u32 pfc_frames_sent_lo; + + /* Recovery */ + u32 recoverable_error; + u32 unrecoverable_error; }; -- cgit v1.2.3-70-g09d2 From 85b26ea18ee63be83d65ec6db72ad7857980a04b Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Thu, 26 Jan 2012 06:01:54 +0000 Subject: bnx2x: Update version to 1.72.0 and copyrights Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 6 +++--- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_file_hdr.h | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h | 2 +- 20 files changed, 22 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 06bbef742fa..7d184fbffaf 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -1,6 +1,6 @@ /* bnx2x.h: Broadcom Everest network driver. * - * Copyright (c) 2007-2011 Broadcom Corporation + * Copyright (c) 2007-2012 Broadcom 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 @@ -23,8 +23,8 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION "1.70.35-0" -#define DRV_MODULE_RELDATE "2011/11/10" +#define DRV_MODULE_VERSION "1.72.00-0" +#define DRV_MODULE_RELDATE "2012/01/26" #define BNX2X_BC_VER 0x040200 #if defined(CONFIG_DCB) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 8fdd71b7bef..6e6a684359b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -1,6 +1,6 @@ /* bnx2x_cmn.c: Broadcom Everest network driver. * - * Copyright (c) 2007-2011 Broadcom Corporation + * Copyright (c) 2007-2012 Broadcom 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 diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index a6ef3ef85e5..c7c7bf1e573 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -1,6 +1,6 @@ /* bnx2x_cmn.h: Broadcom Everest network driver. * - * Copyright (c) 2007-2011 Broadcom Corporation + * Copyright (c) 2007-2012 Broadcom 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 diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c index 5051cf3deb2..9a9bd3ab479 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c @@ -1,6 +1,6 @@ /* bnx2x_dcb.c: Broadcom Everest network driver. * - * Copyright 2009-2011 Broadcom Corporation + * Copyright 2009-2012 Broadcom Corporation * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h index 2ab9254e2d5..06c7a043594 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h @@ -1,6 +1,6 @@ /* bnx2x_dcb.h: Broadcom Everest network driver. * - * Copyright 2009-2011 Broadcom Corporation + * Copyright 2009-2012 Broadcom Corporation * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h index b983825d0ee..3e4cff9b1eb 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h @@ -1,6 +1,6 @@ /* bnx2x_dump.h: Broadcom Everest network driver. * - * Copyright (c) 2011 Broadcom Corporation + * Copyright (c) 2012 Broadcom Corporation * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index 06cb2442c8f..137968d33d1 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -1,6 +1,6 @@ /* bnx2x_ethtool.c: Broadcom Everest network driver. * - * Copyright (c) 2007-2011 Broadcom Corporation + * Copyright (c) 2007-2012 Broadcom 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 diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h index 998652a1b85..e5c5982ae06 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h @@ -1,6 +1,6 @@ /* bnx2x_fw_defs.h: Broadcom Everest network driver. * - * Copyright (c) 2007-2011 Broadcom Corporation + * Copyright (c) 2007-2012 Broadcom 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 diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_file_hdr.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_file_hdr.h index f4a07fbaed0..4bed52ba300 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_file_hdr.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_file_hdr.h @@ -1,6 +1,6 @@ /* bnx2x_fw_file_hdr.h: FW binary file header structure. * - * Copyright (c) 2007-2011 Broadcom Corporation + * Copyright (c) 2007-2012 Broadcom 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 diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h index 3e30c8642c2..78b77de728b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h @@ -1,6 +1,6 @@ /* bnx2x_hsi.h: Broadcom Everest network driver. * - * Copyright (c) 2007-2011 Broadcom Corporation + * Copyright (c) 2007-2012 Broadcom 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 diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h index 4d748e77d1a..29f5c3cca31 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h @@ -1,7 +1,7 @@ /* bnx2x_init.h: Broadcom Everest network driver. * Structures and macroes needed during the initialization. * - * Copyright (c) 2007-2011 Broadcom Corporation + * Copyright (c) 2007-2012 Broadcom 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 diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h index f05ee2f137f..fe66d902dc6 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h @@ -2,7 +2,7 @@ * Static functions needed during the initialization. * This file is "included" in bnx2x_main.c. * - * Copyright (c) 2007-2011 Broadcom Corporation + * Copyright (c) 2007-2012 Broadcom 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 diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index 2091e5dbbcd..2102ad593c1 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -1,4 +1,4 @@ -/* Copyright 2008-2011 Broadcom Corporation +/* Copyright 2008-2012 Broadcom Corporation * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h index e02a68a7fb8..9cc7bafb3df 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h @@ -1,4 +1,4 @@ -/* Copyright 2008-2011 Broadcom Corporation +/* Copyright 2008-2012 Broadcom Corporation * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index cdce7663efd..fea96150539 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -1,6 +1,6 @@ /* bnx2x_main.c: Broadcom Everest network driver. * - * Copyright (c) 2007-2011 Broadcom Corporation + * Copyright (c) 2007-2012 Broadcom 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 diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h index 8ade7bd9a71..c95d9dcac6d 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h @@ -1,6 +1,6 @@ /* bnx2x_reg.h: Broadcom Everest network driver. * - * Copyright (c) 2007-2011 Broadcom Corporation + * Copyright (c) 2007-2012 Broadcom 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 diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index 69465c32e5f..ac15f747f8d 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c @@ -1,6 +1,6 @@ /* bnx2x_sp.c: Broadcom Everest network driver. * - * Copyright 2011 Broadcom Corporation + * Copyright (c) 2011-2012 Broadcom Corporation * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h index f33bc5722e5..71e039b618a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h @@ -1,6 +1,6 @@ /* bnx2x_sp.h: Broadcom Everest network driver. * - * Copyright 2011 Broadcom Corporation + * Copyright (c) 2011-2012 Broadcom Corporation * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c index bc0121ac291..7b9b304b910 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c @@ -1,6 +1,6 @@ /* bnx2x_stats.c: Broadcom Everest network driver. * - * Copyright (c) 2007-2011 Broadcom Corporation + * Copyright (c) 2007-2012 Broadcom 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 diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h index 9c28db167fa..7e979686cd6 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h @@ -1,6 +1,6 @@ /* bnx2x_stats.h: Broadcom Everest network driver. * - * Copyright (c) 2007-2011 Broadcom Corporation + * Copyright (c) 2007-2012 Broadcom 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 -- cgit v1.2.3-70-g09d2 From bb349bb4b19b39830e0486aedfd7c7dca23b7baf Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 25 Jan 2012 03:56:30 +0000 Subject: be2net: allocate more headroom in incoming skbs Allocation of 64 bytes in skb headroom is not enough if we have to pull ethernet + ipv6 + tcp headers, and/or extra tunneling header. Its currently not noticed because netdev_alloc_skb_ip_align(64) give us more room, thanks to power-of-two kmalloc() roundups. Make sure we ask for 128 bytes so that side effects of upcoming patches from Ian Campbell dont decrease benet rx performance, because of extra skb head reallocations. Signed-off-by: Eric Dumazet Cc: Ian Campbell Cc: Vasundhara Volam Cc: Sathya Perla Cc: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be.h | 3 +++ drivers/net/ethernet/emulex/benet/be_main.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index cbdec2536da..453d48612f8 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h @@ -74,6 +74,9 @@ static inline char *nic_name(struct pci_dev *pdev) /* Number of bytes of an RX frame that are copied to skb->data */ #define BE_HDR_LEN ((u16) 64) +/* allocate extra space to allow tunneling decapsulation without head reallocation */ +#define BE_RX_SKB_ALLOC_SIZE (BE_HDR_LEN + 64) + #define BE_MAX_JUMBO_FRAME_SIZE 9018 #define BE_MIN_MTU 256 diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index e703d64434f..0fbf365f5c6 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -1189,7 +1189,7 @@ static void be_rx_compl_process(struct be_adapter *adapter, struct net_device *netdev = adapter->netdev; struct sk_buff *skb; - skb = netdev_alloc_skb_ip_align(netdev, BE_HDR_LEN); + skb = netdev_alloc_skb_ip_align(netdev, BE_RX_SKB_ALLOC_SIZE); if (unlikely(!skb)) { rx_stats(rxo)->rx_drops_no_skbs++; be_rx_compl_discard(adapter, rxo, rxcp); -- cgit v1.2.3-70-g09d2 From fec67b45bf045582c3172101970090d640cd56d9 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Wed, 25 Jan 2012 13:03:29 +0100 Subject: usb: cdc-wdm: Add device-id for Huawei 3G/LTE modems MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [v2: Editorial changes suggested by Sergei Shtylyov] These modems use the Qualcomm MSM Interface (QMI) protocol for management of their CDC ECM like wwan interface. This driver is perfect for exporting the protocol to userspace. The created character device will be indistinguishable from a common AT command based Device Management interface, so userspace applications must do some intelligent matching on the USB device. Cc: Sergei Shtylyov Signed-off-by: Bjørn Mork Acked-by: Oliver Neukum Acked-by: Marcel Holtmann Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index c154d4f1d67..23cf9d38eb5 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -31,6 +31,8 @@ #define DRIVER_AUTHOR "Oliver Neukum" #define DRIVER_DESC "USB Abstract Control Model driver for USB WCM Device Management" +#define HUAWEI_VENDOR_ID 0x12D1 + static const struct usb_device_id wdm_ids[] = { { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS | @@ -38,6 +40,20 @@ static const struct usb_device_id wdm_ids[] = { .bInterfaceClass = USB_CLASS_COMM, .bInterfaceSubClass = USB_CDC_SUBCLASS_DMM }, + { + /* + * Huawei E392, E398 and possibly other Qualcomm based modems + * embed the Qualcomm QMI protocol inside CDC on CDC ECM like + * control interfaces. Userspace access to this is required + * to configure the accompanying data interface + */ + .match_flags = USB_DEVICE_ID_MATCH_VENDOR | + USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = HUAWEI_VENDOR_ID, + .bInterfaceClass = USB_CLASS_VENDOR_SPEC, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 9, /* NOTE: CDC ECM control interface! */ + }, { } }; -- cgit v1.2.3-70-g09d2 From 3afbd89c9639c344300dcdd7d4e5e18dda559fd4 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 25 Jan 2012 09:05:04 +0100 Subject: serial/efm32: add new driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/tty/serial/efm32-uart.txt | 14 + drivers/tty/serial/Kconfig | 13 + drivers/tty/serial/Makefile | 1 + drivers/tty/serial/efm32-uart.c | 830 +++++++++++++++++++++ include/linux/platform_data/efm32-uart.h | 18 + include/linux/serial_core.h | 2 + 6 files changed, 878 insertions(+) create mode 100644 Documentation/devicetree/bindings/tty/serial/efm32-uart.txt create mode 100644 drivers/tty/serial/efm32-uart.c create mode 100644 include/linux/platform_data/efm32-uart.h (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/tty/serial/efm32-uart.txt b/Documentation/devicetree/bindings/tty/serial/efm32-uart.txt new file mode 100644 index 00000000000..6588b6950a7 --- /dev/null +++ b/Documentation/devicetree/bindings/tty/serial/efm32-uart.txt @@ -0,0 +1,14 @@ +* Energymicro efm32 UART + +Required properties: +- compatible : Should be "efm32,uart" +- reg : Address and length of the register set +- interrupts : Should contain uart interrupt + +Example: + +uart@0x4000c400 { + compatible = "efm32,uart"; + reg = <0x4000c400 0x400>; + interrupts = <15>; +}; diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index aca2386c5ef..6e24a8f5fd2 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1628,4 +1628,17 @@ config SERIAL_AR933X_NR_UARTS Set this to the number of serial ports you want the driver to support. +config SERIAL_EFM32_UART + tristate "EFM32 UART/USART port." + depends on ARCH_EFM32 + select SERIAL_CORE + help + This driver support the USART and UART ports on + Energy Micro's efm32 SoCs. + +config SERIAL_EFM32_UART_CONSOLE + bool "EFM32 UART/USART console support" + depends on SERIAL_EFM32_UART=y + select SERIAL_CORE_CONSOLE + endmenu diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index f5b01f2ce52..1997ad4a39a 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -92,3 +92,4 @@ obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o obj-$(CONFIG_SERIAL_SIRFSOC) += sirfsoc_uart.o obj-$(CONFIG_SERIAL_AR933X) += ar933x_uart.o +obj-$(CONFIG_SERIAL_EFM32_UART) += efm32-uart.o diff --git a/drivers/tty/serial/efm32-uart.c b/drivers/tty/serial/efm32-uart.c new file mode 100644 index 00000000000..615e4647049 --- /dev/null +++ b/drivers/tty/serial/efm32-uart.c @@ -0,0 +1,830 @@ +#if defined(CONFIG_SERIAL_EFM32_UART_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#define SUPPORT_SYSRQ +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define DRIVER_NAME "efm32-uart" +#define DEV_NAME "ttyefm" + +#define UARTn_CTRL 0x00 +#define UARTn_CTRL_SYNC 0x0001 +#define UARTn_CTRL_TXBIL 0x1000 + +#define UARTn_FRAME 0x04 +#define UARTn_FRAME_DATABITS__MASK 0x000f +#define UARTn_FRAME_DATABITS(n) ((n) - 3) +#define UARTn_FRAME_PARITY_NONE 0x0000 +#define UARTn_FRAME_PARITY_EVEN 0x0200 +#define UARTn_FRAME_PARITY_ODD 0x0300 +#define UARTn_FRAME_STOPBITS_HALF 0x0000 +#define UARTn_FRAME_STOPBITS_ONE 0x1000 +#define UARTn_FRAME_STOPBITS_TWO 0x3000 + +#define UARTn_CMD 0x0c +#define UARTn_CMD_RXEN 0x0001 +#define UARTn_CMD_RXDIS 0x0002 +#define UARTn_CMD_TXEN 0x0004 +#define UARTn_CMD_TXDIS 0x0008 + +#define UARTn_STATUS 0x10 +#define UARTn_STATUS_TXENS 0x0002 +#define UARTn_STATUS_TXC 0x0020 +#define UARTn_STATUS_TXBL 0x0040 +#define UARTn_STATUS_RXDATAV 0x0080 + +#define UARTn_CLKDIV 0x14 + +#define UARTn_RXDATAX 0x18 +#define UARTn_RXDATAX_RXDATA__MASK 0x01ff +#define UARTn_RXDATAX_PERR 0x4000 +#define UARTn_RXDATAX_FERR 0x8000 +/* + * This is a software only flag used for ignore_status_mask and + * read_status_mask! It's used for breaks that the hardware doesn't report + * explicitly. + */ +#define SW_UARTn_RXDATAX_BERR 0x2000 + +#define UARTn_TXDATA 0x34 + +#define UARTn_IF 0x40 +#define UARTn_IF_TXC 0x0001 +#define UARTn_IF_TXBL 0x0002 +#define UARTn_IF_RXDATAV 0x0004 +#define UARTn_IF_RXOF 0x0010 + +#define UARTn_IFS 0x44 +#define UARTn_IFC 0x48 +#define UARTn_IEN 0x4c + +#define UARTn_ROUTE 0x54 +#define UARTn_ROUTE_LOCATION__MASK 0x0700 +#define UARTn_ROUTE_LOCATION(n) (((n) << 8) & UARTn_ROUTE_LOCATION__MASK) +#define UARTn_ROUTE_RXPEN 0x0001 +#define UARTn_ROUTE_TXPEN 0x0002 + +struct efm32_uart_port { + struct uart_port port; + unsigned int txirq; + struct clk *clk; +}; +#define to_efm_port(_port) container_of(_port, struct efm32_uart_port, port) +#define efm_debug(efm_port, format, arg...) \ + dev_dbg(efm_port->port.dev, format, ##arg) + +static void efm32_uart_write32(struct efm32_uart_port *efm_port, + u32 value, unsigned offset) +{ + writel_relaxed(value, efm_port->port.membase + offset); +} + +static u32 efm32_uart_read32(struct efm32_uart_port *efm_port, + unsigned offset) +{ + return readl_relaxed(efm_port->port.membase + offset); +} + +static unsigned int efm32_uart_tx_empty(struct uart_port *port) +{ + struct efm32_uart_port *efm_port = to_efm_port(port); + u32 status = efm32_uart_read32(efm_port, UARTn_STATUS); + + if (status & UARTn_STATUS_TXC) + return TIOCSER_TEMT; + else + return 0; +} + +static void efm32_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ + /* sorry, neither handshaking lines nor loop functionallity */ +} + +static unsigned int efm32_uart_get_mctrl(struct uart_port *port) +{ + /* sorry, no handshaking lines available */ + return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR; +} + +static void efm32_uart_stop_tx(struct uart_port *port) +{ + struct efm32_uart_port *efm_port = to_efm_port(port); + u32 ien = efm32_uart_read32(efm_port, UARTn_IEN); + + efm32_uart_write32(efm_port, UARTn_CMD_TXDIS, UARTn_CMD); + ien &= ~(UARTn_IF_TXC | UARTn_IF_TXBL); + efm32_uart_write32(efm_port, ien, UARTn_IEN); +} + +static void efm32_uart_tx_chars(struct efm32_uart_port *efm_port) +{ + struct uart_port *port = &efm_port->port; + struct circ_buf *xmit = &port->state->xmit; + + while (efm32_uart_read32(efm_port, UARTn_STATUS) & + UARTn_STATUS_TXBL) { + if (port->x_char) { + port->icount.tx++; + efm32_uart_write32(efm_port, port->x_char, + UARTn_TXDATA); + port->x_char = 0; + continue; + } + if (!uart_circ_empty(xmit) && !uart_tx_stopped(port)) { + port->icount.tx++; + efm32_uart_write32(efm_port, xmit->buf[xmit->tail], + UARTn_TXDATA); + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + } else + break; + } + + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(port); + + if (!port->x_char && uart_circ_empty(xmit) && + efm32_uart_read32(efm_port, UARTn_STATUS) & + UARTn_STATUS_TXC) + efm32_uart_stop_tx(port); +} + +static void efm32_uart_start_tx(struct uart_port *port) +{ + struct efm32_uart_port *efm_port = to_efm_port(port); + u32 ien; + + efm32_uart_write32(efm_port, + UARTn_IF_TXBL | UARTn_IF_TXC, UARTn_IFC); + ien = efm32_uart_read32(efm_port, UARTn_IEN); + efm32_uart_write32(efm_port, + ien | UARTn_IF_TXBL | UARTn_IF_TXC, UARTn_IEN); + efm32_uart_write32(efm_port, UARTn_CMD_TXEN, UARTn_CMD); + + efm32_uart_tx_chars(efm_port); +} + +static void efm32_uart_stop_rx(struct uart_port *port) +{ + struct efm32_uart_port *efm_port = to_efm_port(port); + + efm32_uart_write32(efm_port, UARTn_CMD_RXDIS, UARTn_CMD); +} + +static void efm32_uart_enable_ms(struct uart_port *port) +{ + /* no handshake lines, no modem status interrupts */ +} + +static void efm32_uart_break_ctl(struct uart_port *port, int ctl) +{ + /* not possible without fiddling with gpios */ +} + +static void efm32_uart_rx_chars(struct efm32_uart_port *efm_port, + struct tty_struct *tty) +{ + struct uart_port *port = &efm_port->port; + + while (efm32_uart_read32(efm_port, UARTn_STATUS) & + UARTn_STATUS_RXDATAV) { + u32 rxdata = efm32_uart_read32(efm_port, UARTn_RXDATAX); + int flag = 0; + + /* + * This is a reserved bit and I only saw it read as 0. But to be + * sure not to be confused too much by new devices adhere to the + * warning in the reference manual that reserverd bits might + * read as 1 in the future. + */ + rxdata &= ~SW_UARTn_RXDATAX_BERR; + + port->icount.rx++; + + if ((rxdata & UARTn_RXDATAX_FERR) && + !(rxdata & UARTn_RXDATAX_RXDATA__MASK)) { + rxdata |= SW_UARTn_RXDATAX_BERR; + port->icount.brk++; + if (uart_handle_break(port)) + continue; + } else if (rxdata & UARTn_RXDATAX_PERR) + port->icount.parity++; + else if (rxdata & UARTn_RXDATAX_FERR) + port->icount.frame++; + + rxdata &= port->read_status_mask; + + if (rxdata & SW_UARTn_RXDATAX_BERR) + flag = TTY_BREAK; + else if (rxdata & UARTn_RXDATAX_PERR) + flag = TTY_PARITY; + else if (rxdata & UARTn_RXDATAX_FERR) + flag = TTY_FRAME; + else if (uart_handle_sysrq_char(port, + rxdata & UARTn_RXDATAX_RXDATA__MASK)) + continue; + + if (tty && (rxdata & port->ignore_status_mask) == 0) + tty_insert_flip_char(tty, + rxdata & UARTn_RXDATAX_RXDATA__MASK, flag); + } +} + +static irqreturn_t efm32_uart_rxirq(int irq, void *data) +{ + struct efm32_uart_port *efm_port = data; + u32 irqflag = efm32_uart_read32(efm_port, UARTn_IF); + int handled = IRQ_NONE; + struct uart_port *port = &efm_port->port; + struct tty_struct *tty; + + spin_lock(&port->lock); + + tty = tty_kref_get(port->state->port.tty); + + if (irqflag & UARTn_IF_RXDATAV) { + efm32_uart_write32(efm_port, UARTn_IF_RXDATAV, UARTn_IFC); + efm32_uart_rx_chars(efm_port, tty); + + handled = IRQ_HANDLED; + } + + if (irqflag & UARTn_IF_RXOF) { + efm32_uart_write32(efm_port, UARTn_IF_RXOF, UARTn_IFC); + port->icount.overrun++; + if (tty) + tty_insert_flip_char(tty, 0, TTY_OVERRUN); + + handled = IRQ_HANDLED; + } + + if (tty) { + tty_flip_buffer_push(tty); + tty_kref_put(tty); + } + + spin_unlock(&port->lock); + + return handled; +} + +static irqreturn_t efm32_uart_txirq(int irq, void *data) +{ + struct efm32_uart_port *efm_port = data; + u32 irqflag = efm32_uart_read32(efm_port, UARTn_IF); + + /* TXBL doesn't need to be cleared */ + if (irqflag & UARTn_IF_TXC) + efm32_uart_write32(efm_port, UARTn_IF_TXC, UARTn_IFC); + + if (irqflag & (UARTn_IF_TXC | UARTn_IF_TXBL)) { + efm32_uart_tx_chars(efm_port); + return IRQ_HANDLED; + } else + return IRQ_NONE; +} + +static int efm32_uart_startup(struct uart_port *port) +{ + struct efm32_uart_port *efm_port = to_efm_port(port); + u32 location = 0; + struct efm32_uart_pdata *pdata = dev_get_platdata(port->dev); + int ret; + + if (pdata) + location = UARTn_ROUTE_LOCATION(pdata->location); + + ret = clk_enable(efm_port->clk); + if (ret) { + efm_debug(efm_port, "failed to enable clk\n"); + goto err_clk_enable; + } + port->uartclk = clk_get_rate(efm_port->clk); + + /* Enable pins at configured location */ + efm32_uart_write32(efm_port, location | UARTn_ROUTE_RXPEN | UARTn_ROUTE_TXPEN, + UARTn_ROUTE); + + ret = request_irq(port->irq, efm32_uart_rxirq, 0, + DRIVER_NAME, efm_port); + if (ret) { + efm_debug(efm_port, "failed to register rxirq\n"); + goto err_request_irq_rx; + } + + /* disable all irqs */ + efm32_uart_write32(efm_port, 0, UARTn_IEN); + + ret = request_irq(efm_port->txirq, efm32_uart_txirq, 0, + DRIVER_NAME, efm_port); + if (ret) { + efm_debug(efm_port, "failed to register txirq\n"); + free_irq(port->irq, efm_port); +err_request_irq_rx: + + clk_disable(efm_port->clk); + } else { + efm32_uart_write32(efm_port, + UARTn_IF_RXDATAV | UARTn_IF_RXOF, UARTn_IEN); + efm32_uart_write32(efm_port, UARTn_CMD_RXEN, UARTn_CMD); + } + +err_clk_enable: + return ret; +} + +static void efm32_uart_shutdown(struct uart_port *port) +{ + struct efm32_uart_port *efm_port = to_efm_port(port); + + efm32_uart_write32(efm_port, 0, UARTn_IEN); + free_irq(port->irq, efm_port); + + clk_disable(efm_port->clk); +} + +static void efm32_uart_set_termios(struct uart_port *port, + struct ktermios *new, struct ktermios *old) +{ + struct efm32_uart_port *efm_port = to_efm_port(port); + unsigned long flags; + unsigned baud; + u32 clkdiv; + u32 frame = 0; + + /* no modem control lines */ + new->c_cflag &= ~(CRTSCTS | CMSPAR); + + baud = uart_get_baud_rate(port, new, old, + DIV_ROUND_CLOSEST(port->uartclk, 16 * 8192), + DIV_ROUND_CLOSEST(port->uartclk, 16)); + + switch (new->c_cflag & CSIZE) { + case CS5: + frame |= UARTn_FRAME_DATABITS(5); + break; + case CS6: + frame |= UARTn_FRAME_DATABITS(6); + break; + case CS7: + frame |= UARTn_FRAME_DATABITS(7); + break; + case CS8: + frame |= UARTn_FRAME_DATABITS(8); + break; + } + + if (new->c_cflag & CSTOPB) + /* the receiver only verifies the first stop bit */ + frame |= UARTn_FRAME_STOPBITS_TWO; + else + frame |= UARTn_FRAME_STOPBITS_ONE; + + if (new->c_cflag & PARENB) { + if (new->c_cflag & PARODD) + frame |= UARTn_FRAME_PARITY_ODD; + else + frame |= UARTn_FRAME_PARITY_EVEN; + } else + frame |= UARTn_FRAME_PARITY_NONE; + + /* + * the 6 lowest bits of CLKDIV are dc, bit 6 has value 0.25. + * port->uartclk <= 14e6, so 4 * port->uartclk doesn't overflow. + */ + clkdiv = (DIV_ROUND_CLOSEST(4 * port->uartclk, 16 * baud) - 4) << 6; + + spin_lock_irqsave(&port->lock, flags); + + efm32_uart_write32(efm_port, + UARTn_CMD_TXDIS | UARTn_CMD_RXDIS, UARTn_CMD); + + port->read_status_mask = UARTn_RXDATAX_RXDATA__MASK; + if (new->c_iflag & INPCK) + port->read_status_mask |= + UARTn_RXDATAX_FERR | UARTn_RXDATAX_PERR; + if (new->c_iflag & (BRKINT | PARMRK)) + port->read_status_mask |= SW_UARTn_RXDATAX_BERR; + + port->ignore_status_mask = 0; + if (new->c_iflag & IGNPAR) + port->ignore_status_mask |= + UARTn_RXDATAX_FERR | UARTn_RXDATAX_PERR; + if (new->c_iflag & IGNBRK) + port->ignore_status_mask |= SW_UARTn_RXDATAX_BERR; + + uart_update_timeout(port, new->c_cflag, baud); + + efm32_uart_write32(efm_port, UARTn_CTRL_TXBIL, UARTn_CTRL); + efm32_uart_write32(efm_port, frame, UARTn_FRAME); + efm32_uart_write32(efm_port, clkdiv, UARTn_CLKDIV); + + efm32_uart_write32(efm_port, UARTn_CMD_TXEN | UARTn_CMD_RXEN, + UARTn_CMD); + + spin_unlock_irqrestore(&port->lock, flags); +} + +static const char *efm32_uart_type(struct uart_port *port) +{ + return port->type == PORT_EFMUART ? "efm32-uart" : NULL; +} + +static void efm32_uart_release_port(struct uart_port *port) +{ + struct efm32_uart_port *efm_port = to_efm_port(port); + + clk_unprepare(efm_port->clk); + clk_put(efm_port->clk); + iounmap(port->membase); +} + +static int efm32_uart_request_port(struct uart_port *port) +{ + struct efm32_uart_port *efm_port = to_efm_port(port); + int ret; + + port->membase = ioremap(port->mapbase, 60); + if (!efm_port->port.membase) { + ret = -ENOMEM; + efm_debug(efm_port, "failed to remap\n"); + goto err_ioremap; + } + + efm_port->clk = clk_get(port->dev, NULL); + if (IS_ERR(efm_port->clk)) { + ret = PTR_ERR(efm_port->clk); + efm_debug(efm_port, "failed to get clock\n"); + goto err_clk_get; + } + + ret = clk_prepare(efm_port->clk); + if (ret) { + clk_put(efm_port->clk); +err_clk_get: + + iounmap(port->membase); +err_ioremap: + return ret; + } + return 0; +} + +static void efm32_uart_config_port(struct uart_port *port, int type) +{ + if (type & UART_CONFIG_TYPE && + !efm32_uart_request_port(port)) + port->type = PORT_EFMUART; +} + +static int efm32_uart_verify_port(struct uart_port *port, + struct serial_struct *serinfo) +{ + int ret = 0; + + if (serinfo->type != PORT_UNKNOWN && serinfo->type != PORT_EFMUART) + ret = -EINVAL; + + return ret; +} + +static struct uart_ops efm32_uart_pops = { + .tx_empty = efm32_uart_tx_empty, + .set_mctrl = efm32_uart_set_mctrl, + .get_mctrl = efm32_uart_get_mctrl, + .stop_tx = efm32_uart_stop_tx, + .start_tx = efm32_uart_start_tx, + .stop_rx = efm32_uart_stop_rx, + .enable_ms = efm32_uart_enable_ms, + .break_ctl = efm32_uart_break_ctl, + .startup = efm32_uart_startup, + .shutdown = efm32_uart_shutdown, + .set_termios = efm32_uart_set_termios, + .type = efm32_uart_type, + .release_port = efm32_uart_release_port, + .request_port = efm32_uart_request_port, + .config_port = efm32_uart_config_port, + .verify_port = efm32_uart_verify_port, +}; + +static struct efm32_uart_port *efm32_uart_ports[5]; + +#ifdef CONFIG_SERIAL_EFM32_UART_CONSOLE +static void efm32_uart_console_putchar(struct uart_port *port, int ch) +{ + struct efm32_uart_port *efm_port = to_efm_port(port); + unsigned int timeout = 0x400; + u32 status; + + while (1) { + status = efm32_uart_read32(efm_port, UARTn_STATUS); + + if (status & UARTn_STATUS_TXBL) + break; + if (!timeout--) + return; + } + efm32_uart_write32(efm_port, ch, UARTn_TXDATA); +} + +static void efm32_uart_console_write(struct console *co, const char *s, + unsigned int count) +{ + struct efm32_uart_port *efm_port = efm32_uart_ports[co->index]; + u32 status = efm32_uart_read32(efm_port, UARTn_STATUS); + unsigned int timeout = 0x400; + + if (!(status & UARTn_STATUS_TXENS)) + efm32_uart_write32(efm_port, UARTn_CMD_TXEN, UARTn_CMD); + + uart_console_write(&efm_port->port, s, count, + efm32_uart_console_putchar); + + /* Wait for the transmitter to become empty */ + while (1) { + u32 status = efm32_uart_read32(efm_port, UARTn_STATUS); + if (status & UARTn_STATUS_TXC) + break; + if (!timeout--) + break; + } + + if (!(status & UARTn_STATUS_TXENS)) + efm32_uart_write32(efm_port, UARTn_CMD_TXDIS, UARTn_CMD); +} + +static void efm32_uart_console_get_options(struct efm32_uart_port *efm_port, + int *baud, int *parity, int *bits) +{ + u32 ctrl = efm32_uart_read32(efm_port, UARTn_CTRL); + u32 route, clkdiv, frame; + + if (ctrl & UARTn_CTRL_SYNC) + /* not operating in async mode */ + return; + + route = efm32_uart_read32(efm_port, UARTn_ROUTE); + if (!(route & UARTn_ROUTE_TXPEN)) + /* tx pin not routed */ + return; + + clkdiv = efm32_uart_read32(efm_port, UARTn_CLKDIV); + + *baud = DIV_ROUND_CLOSEST(4 * efm_port->port.uartclk, + 16 * (4 + (clkdiv >> 6))); + + frame = efm32_uart_read32(efm_port, UARTn_FRAME); + if (frame & UARTn_FRAME_PARITY_ODD) + *parity = 'o'; + else if (frame & UARTn_FRAME_PARITY_EVEN) + *parity = 'e'; + else + *parity = 'n'; + + *bits = (frame & UARTn_FRAME_DATABITS__MASK) - + UARTn_FRAME_DATABITS(4) + 4; + + efm_debug(efm_port, "get_opts: options=%d%c%d\n", + *baud, *parity, *bits); +} + +static int efm32_uart_console_setup(struct console *co, char *options) +{ + struct efm32_uart_port *efm_port; + int baud = 115200; + int bits = 8; + int parity = 'n'; + int flow = 'n'; + int ret; + + if (co->index < 0 || co->index >= ARRAY_SIZE(efm32_uart_ports)) { + unsigned i; + for (i = 0; i < ARRAY_SIZE(efm32_uart_ports); ++i) { + if (efm32_uart_ports[i]) { + pr_warn("efm32-console: fall back to console index %u (from %hhi)\n", + i, co->index); + co->index = i; + break; + } + } + } + + efm_port = efm32_uart_ports[co->index]; + if (!efm_port) { + pr_warn("efm32-console: No port at %d\n", co->index); + return -ENODEV; + } + + ret = clk_prepare(efm_port->clk); + if (ret) { + dev_warn(efm_port->port.dev, + "console: clk_prepare failed: %d\n", ret); + return ret; + } + + efm_port->port.uartclk = clk_get_rate(efm_port->clk); + + if (options) + uart_parse_options(options, &baud, &parity, &bits, &flow); + else + efm32_uart_console_get_options(efm_port, + &baud, &parity, &bits); + + return uart_set_options(&efm_port->port, co, baud, parity, bits, flow); +} + +static struct uart_driver efm32_uart_reg; + +static struct console efm32_uart_console = { + .name = DEV_NAME, + .write = efm32_uart_console_write, + .device = uart_console_device, + .setup = efm32_uart_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, + .data = &efm32_uart_reg, +}; + +#else +#define efm32_uart_console (*(struct console *)NULL) +#endif /* ifdef CONFIG_SERIAL_EFM32_UART_CONSOLE / else */ + +static struct uart_driver efm32_uart_reg = { + .owner = THIS_MODULE, + .driver_name = DRIVER_NAME, + .dev_name = DEV_NAME, + .nr = ARRAY_SIZE(efm32_uart_ports), + .cons = &efm32_uart_console, +}; + +static int efm32_uart_probe_dt(struct platform_device *pdev, + struct efm32_uart_port *efm_port) +{ + struct device_node *np = pdev->dev.of_node; + int ret; + + if (!np) + return 1; + + ret = of_alias_get_id(np, "serial"); + if (ret < 0) { + dev_err(&pdev->dev, "failed to get alias id: %d\n", ret); + return ret; + } else { + efm_port->port.line = ret; + return 0; + } + +} + +static int __devinit efm32_uart_probe(struct platform_device *pdev) +{ + struct efm32_uart_port *efm_port; + struct resource *res; + int ret; + + efm_port = kzalloc(sizeof(*efm_port), GFP_KERNEL); + if (!efm_port) { + dev_dbg(&pdev->dev, "failed to allocate private data\n"); + return -ENOMEM; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + ret = -ENODEV; + dev_dbg(&pdev->dev, "failed to determine base address\n"); + goto err_get_base; + } + + if (resource_size(res) < 60) { + ret = -EINVAL; + dev_dbg(&pdev->dev, "memory resource too small\n"); + goto err_too_small; + } + + ret = platform_get_irq(pdev, 0); + if (ret <= 0) { + dev_dbg(&pdev->dev, "failed to get rx irq\n"); + goto err_get_rxirq; + } + + efm_port->port.irq = ret; + + ret = platform_get_irq(pdev, 1); + if (ret <= 0) + ret = efm_port->port.irq + 1; + + efm_port->txirq = ret; + + efm_port->port.dev = &pdev->dev; + efm_port->port.mapbase = res->start; + efm_port->port.type = PORT_EFMUART; + efm_port->port.iotype = UPIO_MEM32; + efm_port->port.fifosize = 2; + efm_port->port.ops = &efm32_uart_pops; + efm_port->port.flags = UPF_BOOT_AUTOCONF; + + ret = efm32_uart_probe_dt(pdev, efm_port); + if (ret > 0) + /* not created by device tree */ + efm_port->port.line = pdev->id; + + if (efm_port->port.line >= 0 && + efm_port->port.line < ARRAY_SIZE(efm32_uart_ports)) + efm32_uart_ports[efm_port->port.line] = efm_port; + + ret = uart_add_one_port(&efm32_uart_reg, &efm_port->port); + if (ret) { + dev_dbg(&pdev->dev, "failed to add port: %d\n", ret); + + if (pdev->id >= 0 && pdev->id < ARRAY_SIZE(efm32_uart_ports)) + efm32_uart_ports[pdev->id] = NULL; +err_get_rxirq: +err_too_small: +err_get_base: + kfree(efm_port); + } else { + platform_set_drvdata(pdev, efm_port); + dev_dbg(&pdev->dev, "\\o/\n"); + } + + return ret; +} + +static int __devexit efm32_uart_remove(struct platform_device *pdev) +{ + struct efm32_uart_port *efm_port = platform_get_drvdata(pdev); + + platform_set_drvdata(pdev, NULL); + + uart_remove_one_port(&efm32_uart_reg, &efm_port->port); + + if (pdev->id >= 0 && pdev->id < ARRAY_SIZE(efm32_uart_ports)) + efm32_uart_ports[pdev->id] = NULL; + + kfree(efm_port); + + return 0; +} + +static struct of_device_id efm32_uart_dt_ids[] = { + { + .compatible = "efm32,uart", + }, { + /* sentinel */ + } +}; +MODULE_DEVICE_TABLE(of, efm32_uart_dt_ids); + +static struct platform_driver efm32_uart_driver = { + .probe = efm32_uart_probe, + .remove = __devexit_p(efm32_uart_remove), + + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = efm32_uart_dt_ids, + }, +}; + +static int __init efm32_uart_init(void) +{ + int ret; + + ret = uart_register_driver(&efm32_uart_reg); + if (ret) + return ret; + + ret = platform_driver_register(&efm32_uart_driver); + if (ret) + uart_unregister_driver(&efm32_uart_reg); + + pr_info("EFM32 UART/USART driver\n"); + + return ret; +} +module_init(efm32_uart_init); + +static void __exit efm32_uart_exit(void) +{ + platform_driver_unregister(&efm32_uart_driver); + uart_unregister_driver(&efm32_uart_reg); +} + +MODULE_AUTHOR("Uwe Kleine-Koenig "); +MODULE_DESCRIPTION("EFM32 UART/USART driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRIVER_NAME); diff --git a/include/linux/platform_data/efm32-uart.h b/include/linux/platform_data/efm32-uart.h new file mode 100644 index 00000000000..ed0e975b3c5 --- /dev/null +++ b/include/linux/platform_data/efm32-uart.h @@ -0,0 +1,18 @@ +/* + * + * + */ +#ifndef __LINUX_PLATFORM_DATA_EFM32_UART_H__ +#define __LINUX_PLATFORM_DATA_EFM32_UART_H__ + +#include + +/** + * struct efm32_uart_pdata + * @location: pinmux location for the I/O pins (to be written to the ROUTE + * register) + */ +struct efm32_uart_pdata { + u8 location; +}; +#endif /* ifndef __LINUX_PLATFORM_DATA_EFM32_UART_H__ */ diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index c91ace70c21..585bfd03d2e 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -210,6 +210,8 @@ /* Atheros AR933X SoC */ #define PORT_AR933X 99 +/* Energy Micro efm32 SoC */ +#define PORT_EFMUART 100 #ifdef __KERNEL__ -- cgit v1.2.3-70-g09d2 From e0d21178ceb06f5bfa81a5697f68384f74af054a Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 19 Dec 2011 14:07:31 +0000 Subject: PCMCIA: soc_common: move common initialization into soc_common Move common socket initialization into soc_common.c. Acked-by: Dominik Brodowski Signed-off-by: Russell King --- drivers/pcmcia/pxa2xx_base.c | 5 +---- drivers/pcmcia/sa1111_generic.c | 4 +--- drivers/pcmcia/sa11xx_base.c | 5 +---- drivers/pcmcia/soc_common.c | 10 ++++++++++ drivers/pcmcia/soc_common.h | 3 ++- 5 files changed, 15 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index a87e2728b2c..18474f046e7 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c @@ -318,10 +318,7 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev) skt->nr = ops->first + i; skt->clk = clk; - skt->ops = ops; - skt->socket.owner = ops->owner; - skt->socket.dev.parent = &dev->dev; - skt->socket.pci_irq = NO_IRQ; + soc_pcmcia_init_one(skt, ops, &dev->dev); ret = pxa2xx_drv_pcmcia_add_one(skt); if (ret) diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c index 59866905ea3..7d6d3d423ef 100644 --- a/drivers/pcmcia/sa1111_generic.c +++ b/drivers/pcmcia/sa1111_generic.c @@ -141,9 +141,7 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, return -ENOMEM; s->soc.nr = ops->first + i; - s->soc.ops = ops; - s->soc.socket.owner = ops->owner; - s->soc.socket.dev.parent = &dev->dev; + soc_pcmcia_init_one(&s->soc, ops, &dev->dev); s->soc.socket.pci_irq = s->soc.nr ? dev->irq[IDX_IRQ_S0_READY_NINT] : dev->irq[IDX_IRQ_S1_READY_NINT]; diff --git a/drivers/pcmcia/sa11xx_base.c b/drivers/pcmcia/sa11xx_base.c index 0c62fe31a40..a3ee89a6dd0 100644 --- a/drivers/pcmcia/sa11xx_base.c +++ b/drivers/pcmcia/sa11xx_base.c @@ -236,10 +236,7 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, skt = &sinfo->skt[i]; skt->nr = first + i; - skt->ops = ops; - skt->socket.owner = ops->owner; - skt->socket.dev.parent = dev; - skt->socket.pci_irq = NO_IRQ; + soc_pcmcia_init_one(skt, ops, dev); ret = sa11xx_drv_pcmcia_add_one(skt); if (ret) diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c index a0a9c2aa8d7..84d90d5220c 100644 --- a/drivers/pcmcia/soc_common.c +++ b/drivers/pcmcia/soc_common.c @@ -635,6 +635,16 @@ module_exit(soc_pcmcia_cpufreq_unregister); #endif +void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt, + struct pcmcia_low_level *ops, struct device *dev) +{ + skt->ops = ops; + skt->socket.owner = ops->owner; + skt->socket.dev.parent = dev; + skt->socket.pci_irq = NO_IRQ; +} +EXPORT_SYMBOL(soc_pcmcia_init_one); + void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt) { mutex_lock(&soc_pcmcia_sockets_lock); diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h index 9daa73615c8..3ff7ead11b1 100644 --- a/drivers/pcmcia/soc_common.h +++ b/drivers/pcmcia/soc_common.h @@ -133,7 +133,8 @@ extern void soc_pcmcia_disable_irqs(struct soc_pcmcia_socket *skt, struct pcmcia extern void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr); extern void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *, struct soc_pcmcia_timing *); - +void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt, + struct pcmcia_low_level *ops, struct device *dev); void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt); int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt); -- cgit v1.2.3-70-g09d2 From d9dc878769f521f494d1617d7cd0c92073df75d8 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 19 Dec 2011 22:00:22 +0000 Subject: PCMCIA: soc_common: add GPIO support for card status signals Add GPIO support for reading the card status (card detect, ready, battery voltage detect) signals into soc_common code. As we want interrupts from these GPIOs, this takes over the old irq handling infrastructure for card status signals, which will now be managed entirely by the soc_common code. Acked-by: Dominik Brodowski Signed-off-by: Russell King --- drivers/pcmcia/soc_common.c | 120 ++++++++++++++++++++++++++++++++++++++++++-- drivers/pcmcia/soc_common.h | 10 ++++ 2 files changed, 127 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c index 84d90d5220c..09a9a52ad65 100644 --- a/drivers/pcmcia/soc_common.c +++ b/drivers/pcmcia/soc_common.c @@ -32,6 +32,7 @@ #include +#include #include #include #include @@ -49,6 +50,8 @@ #include "soc_common.h" +static irqreturn_t soc_common_pcmcia_interrupt(int irq, void *dev); + #ifdef CONFIG_PCMCIA_DEBUG static int pc_debug; @@ -104,6 +107,93 @@ void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *skt, } EXPORT_SYMBOL(soc_common_pcmcia_get_timing); +static void __soc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt, + unsigned int nr) +{ + unsigned int i; + + for (i = 0; i < nr; i++) { + if (skt->stat[i].irq) + free_irq(skt->stat[i].irq, skt); + if (gpio_is_valid(skt->stat[i].gpio)) + gpio_free(skt->stat[i].gpio); + } + + if (skt->ops->hw_shutdown) + skt->ops->hw_shutdown(skt); +} + +static void soc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) +{ + __soc_pcmcia_hw_shutdown(skt, ARRAY_SIZE(skt->stat)); +} + +static int soc_pcmcia_hw_init(struct soc_pcmcia_socket *skt) +{ + int ret = 0, i; + + if (skt->ops->hw_init) { + ret = skt->ops->hw_init(skt); + if (ret) + return ret; + } + + for (i = 0; i < ARRAY_SIZE(skt->stat); i++) { + if (gpio_is_valid(skt->stat[i].gpio)) { + int irq; + + ret = gpio_request_one(skt->stat[i].gpio, GPIOF_IN, + skt->stat[i].name); + if (ret) { + __soc_pcmcia_hw_shutdown(skt, i); + return ret; + } + + irq = gpio_to_irq(skt->stat[i].gpio); + + if (i == SOC_STAT_RDY) + skt->socket.pci_irq = irq; + else + skt->stat[i].irq = irq; + } + + if (skt->stat[i].irq) { + ret = request_irq(skt->stat[i].irq, + soc_common_pcmcia_interrupt, + IRQF_TRIGGER_NONE, + skt->stat[i].name, skt); + if (ret) { + if (gpio_is_valid(skt->stat[i].gpio)) + gpio_free(skt->stat[i].gpio); + __soc_pcmcia_hw_shutdown(skt, i); + return ret; + } + } + } + + return ret; +} + +static void soc_pcmcia_hw_enable(struct soc_pcmcia_socket *skt) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(skt->stat); i++) + if (skt->stat[i].irq) { + irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_EDGE_RISING); + irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_EDGE_BOTH); + } +} + +static void soc_pcmcia_hw_disable(struct soc_pcmcia_socket *skt) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(skt->stat); i++) + if (skt->stat[i].irq) + irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_NONE); +} + static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt) { struct pcmcia_state state; @@ -111,6 +201,22 @@ static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt) memset(&state, 0, sizeof(struct pcmcia_state)); + /* Make battery voltage state report 'good' */ + state.bvd1 = 1; + state.bvd2 = 1; + + /* CD is active low by default */ + if (gpio_is_valid(skt->stat[SOC_STAT_CD].gpio)) + state.detect = !gpio_get_value(skt->stat[SOC_STAT_CD].gpio); + + /* RDY and BVD are active high by default */ + if (gpio_is_valid(skt->stat[SOC_STAT_RDY].gpio)) + state.ready = !!gpio_get_value(skt->stat[SOC_STAT_RDY].gpio); + if (gpio_is_valid(skt->stat[SOC_STAT_BVD1].gpio)) + state.bvd1 = !!gpio_get_value(skt->stat[SOC_STAT_BVD1].gpio); + if (gpio_is_valid(skt->stat[SOC_STAT_BVD2].gpio)) + state.bvd2 = !!gpio_get_value(skt->stat[SOC_STAT_BVD2].gpio); + skt->ops->socket_state(skt, &state); stat = state.detect ? SS_DETECT : 0; @@ -188,6 +294,7 @@ static int soc_common_pcmcia_sock_init(struct pcmcia_socket *sock) debug(skt, 2, "initializing socket\n"); if (skt->ops->socket_init) skt->ops->socket_init(skt); + soc_pcmcia_hw_enable(skt); return 0; } @@ -207,6 +314,7 @@ static int soc_common_pcmcia_suspend(struct pcmcia_socket *sock) debug(skt, 2, "suspending socket\n"); + soc_pcmcia_hw_disable(skt); if (skt->ops->socket_suspend) skt->ops->socket_suspend(skt); @@ -638,10 +746,15 @@ module_exit(soc_pcmcia_cpufreq_unregister); void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt, struct pcmcia_low_level *ops, struct device *dev) { + int i; + skt->ops = ops; skt->socket.owner = ops->owner; skt->socket.dev.parent = dev; skt->socket.pci_irq = NO_IRQ; + + for (i = 0; i < ARRAY_SIZE(skt->stat); i++) + skt->stat[i].gpio = -EINVAL; } EXPORT_SYMBOL(soc_pcmcia_init_one); @@ -652,8 +765,9 @@ void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt) pcmcia_unregister_socket(&skt->socket); - skt->ops->hw_shutdown(skt); + soc_pcmcia_hw_shutdown(skt); + /* should not be required; violates some lowlevel drivers */ soc_common_pcmcia_config_skt(skt, &dead_socket); list_del(&skt->node); @@ -710,7 +824,7 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt) */ skt->ops->set_timing(skt); - ret = skt->ops->hw_init(skt); + ret = soc_pcmcia_hw_init(skt); if (ret) goto out_err_6; @@ -743,7 +857,7 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt) pcmcia_unregister_socket(&skt->socket); out_err_7: - skt->ops->hw_shutdown(skt); + soc_pcmcia_hw_shutdown(skt); out_err_6: list_del(&skt->node); mutex_unlock(&soc_pcmcia_sockets_lock); diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h index 3ff7ead11b1..ebdfa6c1630 100644 --- a/drivers/pcmcia/soc_common.h +++ b/drivers/pcmcia/soc_common.h @@ -50,6 +50,16 @@ struct soc_pcmcia_socket { struct resource res_attr; void __iomem *virt_io; + struct { + int gpio; + unsigned int irq; + const char *name; + } stat[4]; +#define SOC_STAT_CD 0 /* Card detect */ +#define SOC_STAT_BVD1 1 /* BATDEAD / IOSTSCHG */ +#define SOC_STAT_BVD2 2 /* BATWARN / IOSPKR */ +#define SOC_STAT_RDY 3 /* Ready / Interrupt */ + unsigned int irq_state; struct timer_list poll_timer; -- cgit v1.2.3-70-g09d2 From c85c21ad1fe18daf26bfe8684df974d88cec50b7 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 26 Jan 2012 16:25:55 -0500 Subject: e1000e: Need to include vmalloc.h Otherwise (on sparc64): drivers/net/ethernet/intel/e1000e/ethtool.c:657:3: error: implicit declaration of function 'vmalloc' [-Werror=implicit-function-declaration] Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/e1000e/ethtool.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index ffb6c14cbbb..1ea317f1adc 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "e1000.h" -- cgit v1.2.3-70-g09d2 From e332bcb3d149644c344ee5fdf1f6e4ac39e9d9a3 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 20 Dec 2011 01:22:51 +0000 Subject: sfc: Remove fallback for invalid permanent MAC address By the time we look at the MAC address in efx_probe_port(), either the driver or the firmware has already validated the board configuration. The possibility of having an invalid MAC address just isn't worth considering. It certainly isn't worth having a compile-time option for this. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 32 ++------------------------------ 1 file changed, 2 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index d7301d2e81a..eff5d300aa0 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -122,15 +122,6 @@ static int napi_weight = 64; */ static unsigned int efx_monitor_interval = 1 * HZ; -/* This controls whether or not the driver will initialise devices - * with invalid MAC addresses stored in the EEPROM or flash. If true, - * such devices will be initialised with a random locally-generated - * MAC address. This allows for loading the sfc_mtd driver to - * reprogram the flash, even if the flash contents (including the MAC - * address) have previously been erased. - */ -static unsigned int allow_bad_hwaddr; - /* Initial interrupt moderation settings. They can be modified after * module load with ethtool. * @@ -916,7 +907,6 @@ static void efx_mac_work(struct work_struct *data) static int efx_probe_port(struct efx_nic *efx) { - unsigned char *perm_addr; int rc; netif_dbg(efx, probe, efx->net_dev, "create port\n"); @@ -929,28 +919,10 @@ static int efx_probe_port(struct efx_nic *efx) if (rc) return rc; - /* Sanity check MAC address */ - perm_addr = efx->net_dev->perm_addr; - if (is_valid_ether_addr(perm_addr)) { - memcpy(efx->net_dev->dev_addr, perm_addr, ETH_ALEN); - } else { - netif_err(efx, probe, efx->net_dev, "invalid MAC address %pM\n", - perm_addr); - if (!allow_bad_hwaddr) { - rc = -EINVAL; - goto err; - } - random_ether_addr(efx->net_dev->dev_addr); - netif_info(efx, probe, efx->net_dev, - "using locally-generated MAC %pM\n", - efx->net_dev->dev_addr); - } + /* Initialise MAC address to permanent address */ + memcpy(efx->net_dev->dev_addr, efx->net_dev->perm_addr, ETH_ALEN); return 0; - - err: - efx->type->remove_port(efx); - return rc; } static int efx_init_port(struct efx_nic *efx) -- cgit v1.2.3-70-g09d2 From 3f713bf4dd9f7ef2a2c5e9ec124b3d992a2669db Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 20 Dec 2011 23:39:31 +0000 Subject: sfc: Make handling of MC reboot more reliable When the MC reboots, either as part of a firmware upgrade or due to a bug, it attempts to complete (with an error) any requests that were outstanding before the reboot. Since there is an inherent race condition in checking this, it will also write to a status word in shared memory. If we look at each of these separately, we may detect each reboot twice, resulting in a spurious command failure after a firmware upgrade or frustrating recovery from a firmware bug. Instead, if a request completion indicates a reboot, we must poll and clear the status word. This bug was previously masked by use of an incorrect address for the status word. Fix that, using the definition now included in mcdi_pcol.h. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/mcdi.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index 7c405d16692..f16145d9281 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c @@ -27,8 +27,6 @@ #define CMD_NOTIFY_PORT1 4 #define CMD_PDU_PORT0 0x008 #define CMD_PDU_PORT1 0x108 -#define REBOOT_FLAG_PORT0 0x3f8 -#define REBOOT_FLAG_PORT1 0x3fc #define MCDI_RPC_TIMEOUT 10 /*seconds */ @@ -36,8 +34,16 @@ (efx_port_num(efx) ? CMD_PDU_PORT1 : CMD_PDU_PORT0) #define MCDI_DOORBELL(efx) \ (efx_port_num(efx) ? CMD_NOTIFY_PORT1 : CMD_NOTIFY_PORT0) -#define MCDI_REBOOT_FLAG(efx) \ - (efx_port_num(efx) ? REBOOT_FLAG_PORT1 : REBOOT_FLAG_PORT0) +#define MCDI_STATUS(efx) \ + (efx_port_num(efx) ? MC_SMEM_P1_STATUS_OFST : MC_SMEM_P0_STATUS_OFST) + +/* A reboot/assertion causes the MCDI status word to be set after the + * command word is set or a REBOOT event is sent. If we notice a reboot + * via these mechanisms then wait 10ms for the status word to be set. */ +#define MCDI_STATUS_DELAY_US 100 +#define MCDI_STATUS_DELAY_COUNT 100 +#define MCDI_STATUS_SLEEP_MS \ + (MCDI_STATUS_DELAY_US * MCDI_STATUS_DELAY_COUNT / 1000) #define SEQ_MASK \ EFX_MASK32(EFX_WIDTH(MCDI_HEADER_SEQ)) @@ -210,7 +216,7 @@ out: /* Test and clear MC-rebooted flag for this port/function */ int efx_mcdi_poll_reboot(struct efx_nic *efx) { - unsigned int addr = FR_CZ_MC_TREG_SMEM + MCDI_REBOOT_FLAG(efx); + unsigned int addr = FR_CZ_MC_TREG_SMEM + MCDI_STATUS(efx); efx_dword_t reg; uint32_t value; @@ -384,6 +390,11 @@ int efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd, netif_dbg(efx, hw, efx->net_dev, "MC command 0x%x inlen %d failed rc=%d\n", cmd, (int)inlen, -rc); + + if (rc == -EIO || rc == -EINTR) { + msleep(MCDI_STATUS_SLEEP_MS); + efx_mcdi_poll_reboot(efx); + } } efx_mcdi_release(mcdi); @@ -465,10 +476,20 @@ static void efx_mcdi_ev_death(struct efx_nic *efx, int rc) mcdi->resplen = 0; ++mcdi->credits; } - } else + } else { + int count; + /* Nobody was waiting for an MCDI request, so trigger a reset */ efx_schedule_reset(efx, RESET_TYPE_MC_FAILURE); + /* Consume the status word since efx_mcdi_rpc_finish() won't */ + for (count = 0; count < MCDI_STATUS_DELAY_COUNT; ++count) { + if (efx_mcdi_poll_reboot(efx)) + break; + udelay(MCDI_STATUS_DELAY_US); + } + } + spin_unlock(&mcdi->iface_lock); } -- cgit v1.2.3-70-g09d2 From 788ec41cc843f12e8d0eba5f2b37af18b76654a5 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 20 Dec 2011 23:52:02 +0000 Subject: sfc: Use new names for MC shared memory layout constants These are defined alongside the firmware protocol in mcdi_pcol.h. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/mcdi.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index f16145d9281..e5837a6485a 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c @@ -22,18 +22,12 @@ ************************************************************************** */ -/* Software-defined structure to the shared-memory */ -#define CMD_NOTIFY_PORT0 0 -#define CMD_NOTIFY_PORT1 4 -#define CMD_PDU_PORT0 0x008 -#define CMD_PDU_PORT1 0x108 - #define MCDI_RPC_TIMEOUT 10 /*seconds */ #define MCDI_PDU(efx) \ - (efx_port_num(efx) ? CMD_PDU_PORT1 : CMD_PDU_PORT0) + (efx_port_num(efx) ? MC_SMEM_P1_PDU_OFST : MC_SMEM_P0_PDU_OFST) #define MCDI_DOORBELL(efx) \ - (efx_port_num(efx) ? CMD_NOTIFY_PORT1 : CMD_NOTIFY_PORT0) + (efx_port_num(efx) ? MC_SMEM_P1_DOORBELL_OFST : MC_SMEM_P0_DOORBELL_OFST) #define MCDI_STATUS(efx) \ (efx_port_num(efx) ? MC_SMEM_P1_STATUS_OFST : MC_SMEM_P0_STATUS_OFST) @@ -83,7 +77,7 @@ static void efx_mcdi_copyin(struct efx_nic *efx, unsigned cmd, u32 xflags, seqno; BUG_ON(atomic_read(&mcdi->state) == MCDI_STATE_QUIESCENT); - BUG_ON(inlen & 3 || inlen >= 0x100); + BUG_ON(inlen & 3 || inlen >= MC_SMEM_PDU_LEN); seqno = mcdi->seqno & SEQ_MASK; xflags = 0; @@ -117,7 +111,7 @@ static void efx_mcdi_copyout(struct efx_nic *efx, u8 *outbuf, size_t outlen) int i; BUG_ON(atomic_read(&mcdi->state) == MCDI_STATE_QUIESCENT); - BUG_ON(outlen & 3 || outlen >= 0x100); + BUG_ON(outlen & 3 || outlen >= MC_SMEM_PDU_LEN); for (i = 0; i < outlen; i += 4) *((__le32 *)(outbuf + i)) = _efx_readd(efx, pdu + 4 + i); -- cgit v1.2.3-70-g09d2 From 1cb345220f135dcca24f01cc04cbb97a8242d419 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 2 Sep 2011 23:23:00 +0100 Subject: sfc: Hold efx_nic::stats_lock while reading efx_nic::mac_stats efx_nic::stats_lock is used to serialise stats updates, but each reader was dropping it before it finished reading efx_nic::mac_stats. If there were concurrent stats reads using procfs, or one using procfs and one using ethtool, an update could race with a read. On a 32-bit system, the reader could see word-tearing of 64-bit stats (32 bits of the old value and 32 bits of the new). Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 4 +++- drivers/net/ethernet/sfc/ethtool.c | 7 +++++-- drivers/net/ethernet/sfc/net_driver.h | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index eff5d300aa0..8f4cbb642bf 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -1743,8 +1743,8 @@ static struct rtnl_link_stats64 *efx_net_stats(struct net_device *net_dev, struc struct efx_mac_stats *mac_stats = &efx->mac_stats; spin_lock_bh(&efx->stats_lock); + efx->type->update_stats(efx); - spin_unlock_bh(&efx->stats_lock); stats->rx_packets = mac_stats->rx_packets; stats->tx_packets = mac_stats->tx_packets; @@ -1768,6 +1768,8 @@ static struct rtnl_link_stats64 *efx_net_stats(struct net_device *net_dev, struc stats->tx_errors = (stats->tx_window_errors + mac_stats->tx_bad); + spin_unlock_bh(&efx->stats_lock); + return stats; } diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index 52c9ee4c8aa..55a25b14d30 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c @@ -489,13 +489,14 @@ static void efx_ethtool_get_stats(struct net_device *net_dev, const struct efx_ethtool_stat *stat; struct efx_channel *channel; struct efx_tx_queue *tx_queue; - struct rtnl_link_stats64 temp; int i; EFX_BUG_ON_PARANOID(stats->n_stats != EFX_ETHTOOL_NUM_STATS); + spin_lock_bh(&efx->stats_lock); + /* Update MAC and NIC statistics */ - dev_get_stats(net_dev, &temp); + efx->type->update_stats(efx); /* Fill detailed statistics buffer */ for (i = 0; i < EFX_ETHTOOL_NUM_STATS; i++) { @@ -525,6 +526,8 @@ static void efx_ethtool_get_stats(struct net_device *net_dev, break; } } + + spin_unlock_bh(&efx->stats_lock); } static void efx_ethtool_self_test(struct net_device *net_dev, diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 9353ce80175..b6040141ef7 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -704,6 +704,7 @@ struct efx_filter_state; * can provide. Generic code converts these into a standard * &struct net_device_stats. * @stats_lock: Statistics update lock. Serialises statistics fetches + * and access to @mac_stats. * * This is stored in the private area of the &struct net_device. */ -- cgit v1.2.3-70-g09d2 From 710b208dc2687fdb3370110d54a67fb2288835eb Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 3 Sep 2011 00:15:00 +0100 Subject: sfc: Merge efx_mac_operations into efx_nic_type No NICs need to switch efx_mac_operations at run-time, and the MAC operations are fairly closely bound to NIC types. Move efx_mac_operations::reconfigure to efx_nic_type::reconfigure_mac and efx_mac_operations::check_fault fo efx_nic_type::check_mac_fault. Change callers to call through efx->type or directly if the NIC type is known. Remove efx_mac_operations::update_stats. The implementations for Falcon used to fetch MAC statistics synchronously and this was used by efx_register_netdev() to clear statistics after running self-tests. However, it now only converts statistics that have already been fetched (and that only for Falcon), and the call from efx_register_netdev() has no effect. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 17 ++++++----------- drivers/net/ethernet/sfc/ethtool.c | 4 ++-- drivers/net/ethernet/sfc/falcon.c | 15 ++++++++------- drivers/net/ethernet/sfc/falcon_xmac.c | 13 +++---------- drivers/net/ethernet/sfc/mac.h | 21 --------------------- drivers/net/ethernet/sfc/mcdi.h | 4 ++++ drivers/net/ethernet/sfc/mcdi_mac.c | 12 ++---------- drivers/net/ethernet/sfc/net_driver.h | 21 ++++----------------- drivers/net/ethernet/sfc/nic.h | 3 +++ drivers/net/ethernet/sfc/selftest.c | 2 +- drivers/net/ethernet/sfc/siena.c | 4 ++-- 11 files changed, 35 insertions(+), 81 deletions(-) delete mode 100644 drivers/net/ethernet/sfc/mac.h (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 8f4cbb642bf..1d20e01c6ae 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -900,7 +900,7 @@ static void efx_mac_work(struct work_struct *data) mutex_lock(&efx->mac_lock); if (efx->port_enabled) { efx->type->push_multicast_hash(efx); - efx->mac_op->reconfigure(efx); + efx->type->reconfigure_mac(efx); } mutex_unlock(&efx->mac_lock); } @@ -941,7 +941,7 @@ static int efx_init_port(struct efx_nic *efx) /* Reconfigure the MAC before creating dma queues (required for * Falcon/A1 where RX_INGR_EN/TX_DRAIN_EN isn't supported) */ - efx->mac_op->reconfigure(efx); + efx->type->reconfigure_mac(efx); /* Ensure the PHY advertises the correct flow control settings */ rc = efx->phy_op->reconfigure(efx); @@ -969,7 +969,7 @@ static void efx_start_port(struct efx_nic *efx) /* efx_mac_work() might have been scheduled after efx_stop_port(), * and then cancelled by efx_flush_all() */ efx->type->push_multicast_hash(efx); - efx->mac_op->reconfigure(efx); + efx->type->reconfigure_mac(efx); mutex_unlock(&efx->mac_lock); } @@ -1807,7 +1807,7 @@ static int efx_change_mtu(struct net_device *net_dev, int new_mtu) /* Reconfigure the MAC before enabling the dma queues so that * the RX buffers don't overflow */ net_dev->mtu = new_mtu; - efx->mac_op->reconfigure(efx); + efx->type->reconfigure_mac(efx); mutex_unlock(&efx->mac_lock); efx_init_channels(efx); @@ -1835,7 +1835,7 @@ static int efx_set_mac_address(struct net_device *net_dev, void *data) /* Reconfigure the MAC */ mutex_lock(&efx->mac_lock); - efx->mac_op->reconfigure(efx); + efx->type->reconfigure_mac(efx); mutex_unlock(&efx->mac_lock); return 0; @@ -1949,10 +1949,6 @@ static int efx_register_netdev(struct efx_nic *efx) net_dev->netdev_ops = &efx_netdev_ops; SET_ETHTOOL_OPS(net_dev, &efx_ethtool_ops); - /* Clear MAC statistics */ - efx->mac_op->update_stats(efx); - memset(&efx->mac_stats, 0, sizeof(efx->mac_stats)); - rtnl_lock(); rc = dev_alloc_name(net_dev, net_dev->name); @@ -2069,7 +2065,7 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok) "could not restore PHY settings\n"); } - efx->mac_op->reconfigure(efx); + efx->type->reconfigure_mac(efx); efx_init_channels(efx); efx_restore_filters(efx); @@ -2274,7 +2270,6 @@ static int efx_init_struct(struct efx_nic *efx, const struct efx_nic_type *type, efx->net_dev = net_dev; spin_lock_init(&efx->stats_lock); mutex_init(&efx->mac_lock); - efx->mac_op = type->default_mac_ops; efx->phy_op = &efx_dummy_phy_operations; efx->mdio.dev = net_dev; INIT_WORK(&efx->mac_work, efx_mac_work); diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index 55a25b14d30..1a7f7ba27be 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c @@ -750,7 +750,7 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev, /* Recover by resetting the EM block */ falcon_stop_nic_stats(efx); falcon_drain_tx_fifo(efx); - efx->mac_op->reconfigure(efx); + falcon_reconfigure_xmac(efx); falcon_start_nic_stats(efx); } else { /* Schedule a reset to recover */ @@ -775,7 +775,7 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev, /* Reconfigure the MAC. The PHY *may* generate a link state change event * if the user just changed the advertised capabilities, but there's no * harm doing this twice */ - efx->mac_op->reconfigure(efx); + efx->type->reconfigure_mac(efx); out: mutex_unlock(&efx->mac_lock); diff --git a/drivers/net/ethernet/sfc/falcon.c b/drivers/net/ethernet/sfc/falcon.c index 5c7548959dd..1a8a316bb53 100644 --- a/drivers/net/ethernet/sfc/falcon.c +++ b/drivers/net/ethernet/sfc/falcon.c @@ -19,7 +19,6 @@ #include "net_driver.h" #include "bitfield.h" #include "efx.h" -#include "mac.h" #include "spi.h" #include "nic.h" #include "regs.h" @@ -613,7 +612,7 @@ static void falcon_stats_complete(struct efx_nic *efx) nic_data->stats_pending = false; if (*nic_data->stats_dma_done == FALCON_STATS_DONE) { rmb(); /* read the done flag before the stats */ - efx->mac_op->update_stats(efx); + falcon_update_stats_xmac(efx); } else { netif_err(efx, hw, efx->net_dev, "timed out waiting for statistics\n"); @@ -670,7 +669,7 @@ static int falcon_reconfigure_port(struct efx_nic *efx) falcon_reset_macs(efx); efx->phy_op->reconfigure(efx); - rc = efx->mac_op->reconfigure(efx); + rc = falcon_reconfigure_xmac(efx); BUG_ON(rc); falcon_start_nic_stats(efx); @@ -1218,7 +1217,7 @@ static void falcon_monitor(struct efx_nic *efx) falcon_deconfigure_mac_wrapper(efx); falcon_reset_macs(efx); - rc = efx->mac_op->reconfigure(efx); + rc = falcon_reconfigure_xmac(efx); BUG_ON(rc); falcon_start_nic_stats(efx); @@ -1676,7 +1675,7 @@ static void falcon_update_nic_stats(struct efx_nic *efx) *nic_data->stats_dma_done == FALCON_STATS_DONE) { nic_data->stats_pending = false; rmb(); /* read the done flag before the stats */ - efx->mac_op->update_stats(efx); + falcon_update_stats_xmac(efx); } } @@ -1769,11 +1768,12 @@ const struct efx_nic_type falcon_a1_nic_type = { .push_irq_moderation = falcon_push_irq_moderation, .push_multicast_hash = falcon_push_multicast_hash, .reconfigure_port = falcon_reconfigure_port, + .reconfigure_mac = falcon_reconfigure_xmac, + .check_mac_fault = falcon_xmac_check_fault, .get_wol = falcon_get_wol, .set_wol = falcon_set_wol, .resume_wol = efx_port_dummy_op_void, .test_nvram = falcon_test_nvram, - .default_mac_ops = &falcon_xmac_operations, .revision = EFX_REV_FALCON_A1, .mem_map_size = 0x20000, @@ -1811,12 +1811,13 @@ const struct efx_nic_type falcon_b0_nic_type = { .push_irq_moderation = falcon_push_irq_moderation, .push_multicast_hash = falcon_push_multicast_hash, .reconfigure_port = falcon_reconfigure_port, + .reconfigure_mac = falcon_reconfigure_xmac, + .check_mac_fault = falcon_xmac_check_fault, .get_wol = falcon_get_wol, .set_wol = falcon_set_wol, .resume_wol = efx_port_dummy_op_void, .test_registers = falcon_b0_test_registers, .test_nvram = falcon_test_nvram, - .default_mac_ops = &falcon_xmac_operations, .revision = EFX_REV_FALCON_B0, /* Map everything up to and including the RSS indirection diff --git a/drivers/net/ethernet/sfc/falcon_xmac.c b/drivers/net/ethernet/sfc/falcon_xmac.c index 57434593f07..6106ef15dee 100644 --- a/drivers/net/ethernet/sfc/falcon_xmac.c +++ b/drivers/net/ethernet/sfc/falcon_xmac.c @@ -14,7 +14,6 @@ #include "nic.h" #include "regs.h" #include "io.h" -#include "mac.h" #include "mdio_10g.h" #include "workarounds.h" @@ -270,12 +269,12 @@ static bool falcon_xmac_link_ok_retry(struct efx_nic *efx, int tries) return mac_up; } -static bool falcon_xmac_check_fault(struct efx_nic *efx) +bool falcon_xmac_check_fault(struct efx_nic *efx) { return !falcon_xmac_link_ok_retry(efx, 5); } -static int falcon_reconfigure_xmac(struct efx_nic *efx) +int falcon_reconfigure_xmac(struct efx_nic *efx) { struct falcon_nic_data *nic_data = efx->nic_data; @@ -290,7 +289,7 @@ static int falcon_reconfigure_xmac(struct efx_nic *efx) return 0; } -static void falcon_update_stats_xmac(struct efx_nic *efx) +void falcon_update_stats_xmac(struct efx_nic *efx) { struct efx_mac_stats *mac_stats = &efx->mac_stats; @@ -361,9 +360,3 @@ void falcon_poll_xmac(struct efx_nic *efx) nic_data->xmac_poll_required = !falcon_xmac_link_ok_retry(efx, 1); falcon_ack_status_intr(efx); } - -const struct efx_mac_operations falcon_xmac_operations = { - .reconfigure = falcon_reconfigure_xmac, - .update_stats = falcon_update_stats_xmac, - .check_fault = falcon_xmac_check_fault, -}; diff --git a/drivers/net/ethernet/sfc/mac.h b/drivers/net/ethernet/sfc/mac.h deleted file mode 100644 index d6a255d0856..00000000000 --- a/drivers/net/ethernet/sfc/mac.h +++ /dev/null @@ -1,21 +0,0 @@ -/**************************************************************************** - * Driver for Solarflare Solarstorm network controllers and boards - * Copyright 2005-2006 Fen Systems Ltd. - * Copyright 2006-2009 Solarflare Communications Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation, incorporated herein by reference. - */ - -#ifndef EFX_MAC_H -#define EFX_MAC_H - -#include "net_driver.h" - -extern const struct efx_mac_operations falcon_xmac_operations; -extern const struct efx_mac_operations efx_mcdi_mac_operations; -extern int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr, - u32 dma_len, int enable, int clear); - -#endif diff --git a/drivers/net/ethernet/sfc/mcdi.h b/drivers/net/ethernet/sfc/mcdi.h index aced2a7856f..c59667bf64a 100644 --- a/drivers/net/ethernet/sfc/mcdi.h +++ b/drivers/net/ethernet/sfc/mcdi.h @@ -126,5 +126,9 @@ extern int efx_mcdi_wol_filter_set_magic(struct efx_nic *efx, extern int efx_mcdi_wol_filter_get_magic(struct efx_nic *efx, int *id_out); extern int efx_mcdi_wol_filter_remove(struct efx_nic *efx, int id); extern int efx_mcdi_wol_filter_reset(struct efx_nic *efx); +extern int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr, + u32 dma_len, int enable, int clear); +extern int efx_mcdi_mac_reconfigure(struct efx_nic *efx); +extern bool efx_mcdi_mac_check_fault(struct efx_nic *efx); #endif /* EFX_MCDI_H */ diff --git a/drivers/net/ethernet/sfc/mcdi_mac.c b/drivers/net/ethernet/sfc/mcdi_mac.c index 85fe24f8639..4907062b24a 100644 --- a/drivers/net/ethernet/sfc/mcdi_mac.c +++ b/drivers/net/ethernet/sfc/mcdi_mac.c @@ -9,7 +9,6 @@ #include "net_driver.h" #include "efx.h" -#include "mac.h" #include "mcdi.h" #include "mcdi_pcol.h" @@ -115,7 +114,7 @@ fail: return rc; } -static int efx_mcdi_mac_reconfigure(struct efx_nic *efx) +int efx_mcdi_mac_reconfigure(struct efx_nic *efx) { int rc; @@ -130,16 +129,9 @@ static int efx_mcdi_mac_reconfigure(struct efx_nic *efx) } -static bool efx_mcdi_mac_check_fault(struct efx_nic *efx) +bool efx_mcdi_mac_check_fault(struct efx_nic *efx) { u32 faults; int rc = efx_mcdi_get_mac_faults(efx, &faults); return (rc != 0) || (faults != 0); } - - -const struct efx_mac_operations efx_mcdi_mac_operations = { - .reconfigure = efx_mcdi_mac_reconfigure, - .update_stats = efx_port_dummy_op_void, - .check_fault = efx_mcdi_mac_check_fault, -}; diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index b6040141ef7..aa5a321a141 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -473,18 +473,6 @@ static inline bool efx_link_state_equal(const struct efx_link_state *left, left->fc == right->fc && left->speed == right->speed; } -/** - * struct efx_mac_operations - Efx MAC operations table - * @reconfigure: Reconfigure MAC. Serialised by the mac_lock - * @update_stats: Update statistics - * @check_fault: Check fault state. True if fault present. - */ -struct efx_mac_operations { - int (*reconfigure) (struct efx_nic *efx); - void (*update_stats) (struct efx_nic *efx); - bool (*check_fault)(struct efx_nic *efx); -}; - /** * struct efx_phy_operations - Efx PHY operations table * @probe: Probe PHY and initialise efx->mdio.mode_support, efx->mdio.mmds, @@ -676,7 +664,6 @@ struct efx_filter_state; * @port_initialized: Port initialized? * @net_dev: Operating system network device. Consider holding the rtnl lock * @stats_buffer: DMA buffer for statistics - * @mac_op: MAC interface * @phy_type: PHY type * @phy_op: PHY interface * @phy_data: PHY private data (including PHY-specific stats) @@ -767,8 +754,6 @@ struct efx_nic { struct efx_buffer stats_buffer; - const struct efx_mac_operations *mac_op; - unsigned int phy_type; const struct efx_phy_operations *phy_op; void *phy_data; @@ -843,12 +828,13 @@ static inline unsigned int efx_port_num(struct efx_nic *efx) * @push_irq_moderation: Apply interrupt moderation value * @push_multicast_hash: Apply multicast hash table * @reconfigure_port: Push loopback/power/txdis changes to the MAC and PHY + * @reconfigure_mac: Reconfigure MAC only. Serialised by the mac_lock + * @check_mac_fault: Check MAC fault state. True if fault present. * @get_wol: Get WoL configuration from driver state * @set_wol: Push WoL configuration to the NIC * @resume_wol: Synchronise WoL state between driver and MC (e.g. after resume) * @test_registers: Test read/write functionality of control registers * @test_nvram: Test validity of NVRAM contents - * @default_mac_ops: efx_mac_operations to set at startup * @revision: Hardware architecture revision * @mem_map_size: Memory BAR mapped size * @txd_ptr_tbl_base: TX descriptor ring base address @@ -888,12 +874,13 @@ struct efx_nic_type { void (*push_irq_moderation)(struct efx_channel *channel); void (*push_multicast_hash)(struct efx_nic *efx); int (*reconfigure_port)(struct efx_nic *efx); + int (*reconfigure_mac)(struct efx_nic *efx); + bool (*check_mac_fault)(struct efx_nic *efx); void (*get_wol)(struct efx_nic *efx, struct ethtool_wolinfo *wol); int (*set_wol)(struct efx_nic *efx, u32 type); void (*resume_wol)(struct efx_nic *efx); int (*test_registers)(struct efx_nic *efx); int (*test_nvram)(struct efx_nic *efx); - const struct efx_mac_operations *default_mac_ops; int revision; unsigned int mem_map_size; diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h index 5fb24d3aa3c..cfda6ded24f 100644 --- a/drivers/net/ethernet/sfc/nic.h +++ b/drivers/net/ethernet/sfc/nic.h @@ -189,6 +189,9 @@ extern bool efx_nic_event_present(struct efx_channel *channel); /* MAC/PHY */ extern void falcon_drain_tx_fifo(struct efx_nic *efx); extern void falcon_reconfigure_mac_wrapper(struct efx_nic *efx); +extern bool falcon_xmac_check_fault(struct efx_nic *efx); +extern int falcon_reconfigure_xmac(struct efx_nic *efx); +extern void falcon_update_stats_xmac(struct efx_nic *efx); /* Interrupts and test events */ extern int efx_nic_init_interrupt(struct efx_nic *efx); diff --git a/drivers/net/ethernet/sfc/selftest.c b/drivers/net/ethernet/sfc/selftest.c index 5226d9857f3..9df2a794250 100644 --- a/drivers/net/ethernet/sfc/selftest.c +++ b/drivers/net/ethernet/sfc/selftest.c @@ -569,7 +569,7 @@ static int efx_wait_for_link(struct efx_nic *efx) mutex_lock(&efx->mac_lock); link_up = link_state->up; if (link_up) - link_up = !efx->mac_op->check_fault(efx); + link_up = !efx->type->check_mac_fault(efx); mutex_unlock(&efx->mac_lock); if (link_up) { diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c index 4d5d619feaa..775b6784cbd 100644 --- a/drivers/net/ethernet/sfc/siena.c +++ b/drivers/net/ethernet/sfc/siena.c @@ -18,7 +18,6 @@ #include "bitfield.h" #include "efx.h" #include "nic.h" -#include "mac.h" #include "spi.h" #include "regs.h" #include "io.h" @@ -631,13 +630,14 @@ const struct efx_nic_type siena_a0_nic_type = { .set_id_led = efx_mcdi_set_id_led, .push_irq_moderation = siena_push_irq_moderation, .push_multicast_hash = siena_push_multicast_hash, + .reconfigure_mac = efx_mcdi_mac_reconfigure, + .check_mac_fault = efx_mcdi_mac_check_fault, .reconfigure_port = efx_mcdi_phy_reconfigure, .get_wol = siena_get_wol, .set_wol = siena_set_wol, .resume_wol = siena_init_wol, .test_registers = siena_test_registers, .test_nvram = efx_mcdi_nvram_test_all, - .default_mac_ops = &efx_mcdi_mac_operations, .revision = EFX_REV_SIENA_A0, .mem_map_size = (FR_CZ_MC_TREG_SMEM + -- cgit v1.2.3-70-g09d2 From 1daf417029ddc10b7854430c1e1118df791d0eaf Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 8 Sep 2011 02:09:42 +0100 Subject: sfc: Merge efx_mcdi_mac_check_fault() and efx_mcdi_get_mac_faults() The latter is only called by the former, which is a very short wrapper. Further, gcc 4.5 may currently wrongly warn that the 'faults' variable may be used uninitialised. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/mcdi_mac.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/mcdi_mac.c b/drivers/net/ethernet/sfc/mcdi_mac.c index 4907062b24a..559d79861fa 100644 --- a/drivers/net/ethernet/sfc/mcdi_mac.c +++ b/drivers/net/ethernet/sfc/mcdi_mac.c @@ -51,7 +51,7 @@ static int efx_mcdi_set_mac(struct efx_nic *efx) NULL, 0, NULL); } -static int efx_mcdi_get_mac_faults(struct efx_nic *efx, u32 *faults) +bool efx_mcdi_mac_check_fault(struct efx_nic *efx) { u8 outbuf[MC_CMD_GET_LINK_OUT_LEN]; size_t outlength; @@ -61,16 +61,13 @@ static int efx_mcdi_get_mac_faults(struct efx_nic *efx, u32 *faults) rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0, outbuf, sizeof(outbuf), &outlength); - if (rc) - goto fail; - - *faults = MCDI_DWORD(outbuf, GET_LINK_OUT_MAC_FAULT); - return 0; + if (rc) { + netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", + __func__, rc); + return true; + } -fail: - netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", - __func__, rc); - return rc; + return MCDI_DWORD(outbuf, GET_LINK_OUT_MAC_FAULT) != 0; } int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr, @@ -127,11 +124,3 @@ int efx_mcdi_mac_reconfigure(struct efx_nic *efx) return 0; } - - -bool efx_mcdi_mac_check_fault(struct efx_nic *efx) -{ - u32 faults; - int rc = efx_mcdi_get_mac_faults(efx, &faults); - return (rc != 0) || (faults != 0); -} -- cgit v1.2.3-70-g09d2 From 30b81cda9516878906b44fed16aac9df1dbb89c7 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 13 Sep 2011 19:47:48 +0100 Subject: sfc: Remove efx_nic_type::push_multicast_hash operation Both implementations of efx_nic_type::reconfigure_mac operation push the multicast hash filter to the hardware. It is therefore redundant to call efx_nic_type::push_multicast_hash as well. efx_mcdi_mac_reconfigure() also uses this operation, but the implementation for Siena just uses MCDI anyway. Merge that into efx_mcdi_mac_reconfigure(). Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 5 +---- drivers/net/ethernet/sfc/falcon.c | 2 -- drivers/net/ethernet/sfc/mcdi_mac.c | 10 ++++++---- drivers/net/ethernet/sfc/net_driver.h | 5 ++--- drivers/net/ethernet/sfc/siena.c | 10 ---------- 5 files changed, 9 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 1d20e01c6ae..de162474c3c 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -898,10 +898,8 @@ static void efx_mac_work(struct work_struct *data) struct efx_nic *efx = container_of(data, struct efx_nic, mac_work); mutex_lock(&efx->mac_lock); - if (efx->port_enabled) { - efx->type->push_multicast_hash(efx); + if (efx->port_enabled) efx->type->reconfigure_mac(efx); - } mutex_unlock(&efx->mac_lock); } @@ -968,7 +966,6 @@ static void efx_start_port(struct efx_nic *efx) /* efx_mac_work() might have been scheduled after efx_stop_port(), * and then cancelled by efx_flush_all() */ - efx->type->push_multicast_hash(efx); efx->type->reconfigure_mac(efx); mutex_unlock(&efx->mac_lock); diff --git a/drivers/net/ethernet/sfc/falcon.c b/drivers/net/ethernet/sfc/falcon.c index 1a8a316bb53..fe21c7e349b 100644 --- a/drivers/net/ethernet/sfc/falcon.c +++ b/drivers/net/ethernet/sfc/falcon.c @@ -1766,7 +1766,6 @@ const struct efx_nic_type falcon_a1_nic_type = { .stop_stats = falcon_stop_nic_stats, .set_id_led = falcon_set_id_led, .push_irq_moderation = falcon_push_irq_moderation, - .push_multicast_hash = falcon_push_multicast_hash, .reconfigure_port = falcon_reconfigure_port, .reconfigure_mac = falcon_reconfigure_xmac, .check_mac_fault = falcon_xmac_check_fault, @@ -1809,7 +1808,6 @@ const struct efx_nic_type falcon_b0_nic_type = { .stop_stats = falcon_stop_nic_stats, .set_id_led = falcon_set_id_led, .push_irq_moderation = falcon_push_irq_moderation, - .push_multicast_hash = falcon_push_multicast_hash, .reconfigure_port = falcon_reconfigure_port, .reconfigure_mac = falcon_reconfigure_xmac, .check_mac_fault = falcon_xmac_check_fault, diff --git a/drivers/net/ethernet/sfc/mcdi_mac.c b/drivers/net/ethernet/sfc/mcdi_mac.c index 559d79861fa..f67cf921bd1 100644 --- a/drivers/net/ethernet/sfc/mcdi_mac.c +++ b/drivers/net/ethernet/sfc/mcdi_mac.c @@ -115,12 +115,14 @@ int efx_mcdi_mac_reconfigure(struct efx_nic *efx) { int rc; + WARN_ON(!mutex_is_locked(&efx->mac_lock)); + rc = efx_mcdi_set_mac(efx); if (rc != 0) return rc; - /* Restore the multicast hash registers. */ - efx->type->push_multicast_hash(efx); - - return 0; + return efx_mcdi_rpc(efx, MC_CMD_SET_MCAST_HASH, + efx->multicast_hash.byte, + sizeof(efx->multicast_hash), + NULL, 0, NULL); } diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index aa5a321a141..a88e95f58b0 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -826,9 +826,9 @@ static inline unsigned int efx_port_num(struct efx_nic *efx) * @stop_stats: Stop the regular fetching of statistics * @set_id_led: Set state of identifying LED or revert to automatic function * @push_irq_moderation: Apply interrupt moderation value - * @push_multicast_hash: Apply multicast hash table * @reconfigure_port: Push loopback/power/txdis changes to the MAC and PHY - * @reconfigure_mac: Reconfigure MAC only. Serialised by the mac_lock + * @reconfigure_mac: Push MAC address, MTU, flow control and filter settings + * to the hardware. Serialised by the mac_lock. * @check_mac_fault: Check MAC fault state. True if fault present. * @get_wol: Get WoL configuration from driver state * @set_wol: Push WoL configuration to the NIC @@ -872,7 +872,6 @@ struct efx_nic_type { void (*stop_stats)(struct efx_nic *efx); void (*set_id_led)(struct efx_nic *efx, enum efx_led_mode mode); void (*push_irq_moderation)(struct efx_channel *channel); - void (*push_multicast_hash)(struct efx_nic *efx); int (*reconfigure_port)(struct efx_nic *efx); int (*reconfigure_mac)(struct efx_nic *efx); bool (*check_mac_fault)(struct efx_nic *efx); diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c index 775b6784cbd..d681f2597e7 100644 --- a/drivers/net/ethernet/sfc/siena.c +++ b/drivers/net/ethernet/sfc/siena.c @@ -52,15 +52,6 @@ static void siena_push_irq_moderation(struct efx_channel *channel) channel->channel); } -static void siena_push_multicast_hash(struct efx_nic *efx) -{ - WARN_ON(!mutex_is_locked(&efx->mac_lock)); - - efx_mcdi_rpc(efx, MC_CMD_SET_MCAST_HASH, - efx->multicast_hash.byte, sizeof(efx->multicast_hash), - NULL, 0, NULL); -} - static int siena_mdio_write(struct net_device *net_dev, int prtad, int devad, u16 addr, u16 value) { @@ -629,7 +620,6 @@ const struct efx_nic_type siena_a0_nic_type = { .stop_stats = siena_stop_nic_stats, .set_id_led = efx_mcdi_set_id_led, .push_irq_moderation = siena_push_irq_moderation, - .push_multicast_hash = siena_push_multicast_hash, .reconfigure_mac = efx_mcdi_mac_reconfigure, .check_mac_fault = efx_mcdi_mac_check_fault, .reconfigure_port = efx_mcdi_phy_reconfigure, -- cgit v1.2.3-70-g09d2 From 5f3f9d6c441faa323444b2f6b092d630fcd7d04c Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 4 Nov 2011 22:29:14 +0000 Subject: sfc: Consistently test DEBUG macro, not EFX_ENABLE_DEBUG The netif_dbg() macro is defined in . If the DEBUG macro is defined, it logs a message at 'debug' level, otherwise it does nothing. In net_driver.h we define DEBUG if EFX_ENABLE_DEBUG is defined, but this is too late for those source files that already got a definition of netif_dbg() by including Get rid of EFX_ENABLE_DEBUG, and only define and test DEBUG. In mtd.c, we do not use DEBUG as a condition flag but are forced to use the DEBUG macro-function from . Undefine DEBUG before including it. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/mtd.c | 1 + drivers/net/ethernet/sfc/net_driver.h | 6 +----- drivers/net/ethernet/sfc/nic.c | 2 +- drivers/net/ethernet/sfc/selftest.c | 2 +- 4 files changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/mtd.c b/drivers/net/ethernet/sfc/mtd.c index 7f61cd3812d..b702862a092 100644 --- a/drivers/net/ethernet/sfc/mtd.c +++ b/drivers/net/ethernet/sfc/mtd.c @@ -10,6 +10,7 @@ #include #include +#undef DEBUG /* has its own use for DEBUG */ #include #include #include diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index a88e95f58b0..4cbd997e378 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -13,10 +13,6 @@ #ifndef EFX_NET_DRIVER_H #define EFX_NET_DRIVER_H -#if defined(EFX_ENABLE_DEBUG) && !defined(DEBUG) -#define DEBUG -#endif - #include #include #include @@ -42,7 +38,7 @@ #define EFX_DRIVER_VERSION "3.1" -#ifdef EFX_ENABLE_DEBUG +#ifdef DEBUG #define EFX_BUG_ON_PARANOID(x) BUG_ON(x) #define EFX_WARN_ON_PARANOID(x) WARN_ON(x) #else diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c index b1df2f39c8f..bf07bd0488c 100644 --- a/drivers/net/ethernet/sfc/nic.c +++ b/drivers/net/ethernet/sfc/nic.c @@ -801,7 +801,7 @@ static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue, * error message. FRM_TRUNC indicates RXDP dropped the packet due * to a FIFO overflow. */ -#ifdef EFX_ENABLE_DEBUG +#ifdef DEBUG if (rx_ev_other_err && net_ratelimit()) { netif_dbg(efx, rx_err, efx->net_dev, " RX queue %d unexpected RX event " diff --git a/drivers/net/ethernet/sfc/selftest.c b/drivers/net/ethernet/sfc/selftest.c index 9df2a794250..7718287ad0b 100644 --- a/drivers/net/ethernet/sfc/selftest.c +++ b/drivers/net/ethernet/sfc/selftest.c @@ -315,7 +315,7 @@ void efx_loopback_rx_packet(struct efx_nic *efx, return; err: -#ifdef EFX_ENABLE_DEBUG +#ifdef DEBUG if (atomic_read(&state->rx_bad) == 0) { netif_err(efx, drv, efx->net_dev, "received packet:\n"); print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 0x10, 1, -- cgit v1.2.3-70-g09d2 From 6aa9c7f625e8ce07060467051b68fc068118ee64 Mon Sep 17 00:00:00 2001 From: Matthew Slattery Date: Wed, 14 Jul 2010 15:36:19 +0100 Subject: sfc: Support extraction of CAPABILITIES from GET_BOARD_CFG response. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/mcdi.c | 10 +++++++++- drivers/net/ethernet/sfc/mcdi.h | 2 +- drivers/net/ethernet/sfc/mtd.c | 2 +- drivers/net/ethernet/sfc/siena.c | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index e5837a6485a..f1cad22b30f 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c @@ -678,7 +678,7 @@ fail: } int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address, - u16 *fw_subtype_list) + u16 *fw_subtype_list, u32 *capabilities) { uint8_t outbuf[MC_CMD_GET_BOARD_CFG_OUT_LENMIN]; size_t outlen; @@ -708,6 +708,14 @@ int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address, outbuf + MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_OFST, MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MINNUM * sizeof(fw_subtype_list[0])); + if (capabilities) { + if (port_num) + *capabilities = MCDI_DWORD(outbuf, + GET_BOARD_CFG_OUT_CAPABILITIES_PORT1); + else + *capabilities = MCDI_DWORD(outbuf, + GET_BOARD_CFG_OUT_CAPABILITIES_PORT0); + } return 0; diff --git a/drivers/net/ethernet/sfc/mcdi.h b/drivers/net/ethernet/sfc/mcdi.h index c59667bf64a..4dd39fcca67 100644 --- a/drivers/net/ethernet/sfc/mcdi.h +++ b/drivers/net/ethernet/sfc/mcdi.h @@ -97,7 +97,7 @@ extern void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len); extern int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating, bool *was_attached_out); extern int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address, - u16 *fw_subtype_list); + u16 *fw_subtype_list, u32 *capabilities); extern int efx_mcdi_log_ctrl(struct efx_nic *efx, bool evq, bool uart, u32 dest_evq); extern int efx_mcdi_nvram_types(struct efx_nic *efx, u32 *nvram_types_out); diff --git a/drivers/net/ethernet/sfc/mtd.c b/drivers/net/ethernet/sfc/mtd.c index b702862a092..eff49da458e 100644 --- a/drivers/net/ethernet/sfc/mtd.c +++ b/drivers/net/ethernet/sfc/mtd.c @@ -631,7 +631,7 @@ static int siena_mtd_get_fw_subtypes(struct efx_nic *efx, uint16_t fw_subtype_list[MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MINNUM]; int rc; - rc = efx_mcdi_get_board_cfg(efx, NULL, fw_subtype_list); + rc = efx_mcdi_get_board_cfg(efx, NULL, fw_subtype_list, NULL); if (rc) return rc; diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c index d681f2597e7..65cb5e4f426 100644 --- a/drivers/net/ethernet/sfc/siena.c +++ b/drivers/net/ethernet/sfc/siena.c @@ -216,7 +216,7 @@ static int siena_reset_hw(struct efx_nic *efx, enum reset_type method) static int siena_probe_nvconfig(struct efx_nic *efx) { - return efx_mcdi_get_board_cfg(efx, efx->net_dev->perm_addr, NULL); + return efx_mcdi_get_board_cfg(efx, efx->net_dev->perm_addr, NULL, NULL); } static int siena_probe_nic(struct efx_nic *efx) -- cgit v1.2.3-70-g09d2 From cc180b69c009ec52f67a56d96b9073b9f774b323 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 8 Dec 2011 19:51:47 +0000 Subject: sfc: Correct interrupt timer quantum for Siena (normal and turbo mode) We currently assume that the timer quantum for Siena is 5 us, the same as for Falcon. This is not correct; timer ticks are generated on a rota which takes a minimum of 768 cycles (each event delivery or other timer change will delay it by 3 cycles). The timer quantum should be 6.144 or 3.072 us depending on whether turbo mode is active. Replace EFX_IRQ_MOD_RESOLUTION with a timer_quantum_ns field in struct efx_nic, initialised by the efx_nic_type::probe function. While we're at it, replace EFX_IRQ_MOD_MAX with a timer_period_max field in struct efx_nic_type. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 31 ++++++++++++++++++++++--------- drivers/net/ethernet/sfc/falcon.c | 6 ++++-- drivers/net/ethernet/sfc/net_driver.h | 4 ++++ drivers/net/ethernet/sfc/nic.h | 3 --- drivers/net/ethernet/sfc/siena.c | 13 ++++++++++--- 5 files changed, 40 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index de162474c3c..9d4ab5e5e1f 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -1513,13 +1513,13 @@ static void efx_remove_all(struct efx_nic *efx) * **************************************************************************/ -static unsigned int irq_mod_ticks(unsigned int usecs, unsigned int resolution) +static unsigned int irq_mod_ticks(unsigned int usecs, unsigned int quantum_ns) { if (usecs == 0) return 0; - if (usecs < resolution) + if (usecs * 1000 < quantum_ns) return 1; /* never round down to 0 */ - return usecs / resolution; + return usecs * 1000 / quantum_ns; } /* Set interrupt moderation parameters */ @@ -1528,14 +1528,20 @@ int efx_init_irq_moderation(struct efx_nic *efx, unsigned int tx_usecs, bool rx_may_override_tx) { struct efx_channel *channel; - unsigned tx_ticks = irq_mod_ticks(tx_usecs, EFX_IRQ_MOD_RESOLUTION); - unsigned rx_ticks = irq_mod_ticks(rx_usecs, EFX_IRQ_MOD_RESOLUTION); + unsigned int irq_mod_max = DIV_ROUND_UP(efx->type->timer_period_max * + efx->timer_quantum_ns, + 1000); + unsigned int tx_ticks; + unsigned int rx_ticks; EFX_ASSERT_RESET_SERIALISED(efx); - if (tx_ticks > EFX_IRQ_MOD_MAX || rx_ticks > EFX_IRQ_MOD_MAX) + if (tx_usecs > irq_mod_max || rx_usecs > irq_mod_max) return -EINVAL; + tx_ticks = irq_mod_ticks(tx_usecs, efx->timer_quantum_ns); + rx_ticks = irq_mod_ticks(rx_usecs, efx->timer_quantum_ns); + if (tx_ticks != rx_ticks && efx->tx_channel_offset == 0 && !rx_may_override_tx) { netif_err(efx, drv, efx->net_dev, "Channels are shared. " @@ -1558,8 +1564,14 @@ int efx_init_irq_moderation(struct efx_nic *efx, unsigned int tx_usecs, void efx_get_irq_moderation(struct efx_nic *efx, unsigned int *tx_usecs, unsigned int *rx_usecs, bool *rx_adaptive) { + /* We must round up when converting ticks to microseconds + * because we round down when converting the other way. + */ + *rx_adaptive = efx->irq_rx_adaptive; - *rx_usecs = efx->irq_rx_moderation * EFX_IRQ_MOD_RESOLUTION; + *rx_usecs = DIV_ROUND_UP(efx->irq_rx_moderation * + efx->timer_quantum_ns, + 1000); /* If channels are shared between RX and TX, so is IRQ * moderation. Otherwise, IRQ moderation is the same for all @@ -1568,9 +1580,10 @@ void efx_get_irq_moderation(struct efx_nic *efx, unsigned int *tx_usecs, if (efx->tx_channel_offset == 0) *tx_usecs = *rx_usecs; else - *tx_usecs = + *tx_usecs = DIV_ROUND_UP( efx->channel[efx->tx_channel_offset]->irq_moderation * - EFX_IRQ_MOD_RESOLUTION; + efx->timer_quantum_ns, + 1000); } /************************************************************************** diff --git a/drivers/net/ethernet/sfc/falcon.c b/drivers/net/ethernet/sfc/falcon.c index fe21c7e349b..0b7880b0b8f 100644 --- a/drivers/net/ethernet/sfc/falcon.c +++ b/drivers/net/ethernet/sfc/falcon.c @@ -103,8 +103,6 @@ static void falcon_push_irq_moderation(struct efx_channel *channel) efx_dword_t timer_cmd; struct efx_nic *efx = channel->efx; - BUILD_BUG_ON(EFX_IRQ_MOD_MAX > (1 << FRF_AB_TC_TIMER_VAL_WIDTH)); - /* Set timer register */ if (channel->irq_moderation) { EFX_POPULATE_DWORD_2(timer_cmd, @@ -1471,6 +1469,8 @@ static int falcon_probe_nic(struct efx_nic *efx) goto fail5; } + efx->timer_quantum_ns = 4968; /* 621 cycles */ + /* Initialise I2C adapter */ board = falcon_board(efx); board->i2c_adap.owner = THIS_MODULE; @@ -1785,6 +1785,7 @@ const struct efx_nic_type falcon_a1_nic_type = { .rx_buffer_padding = 0x24, .max_interrupt_mode = EFX_INT_MODE_MSI, .phys_addr_channels = 4, + .timer_period_max = 1 << FRF_AB_TC_TIMER_VAL_WIDTH, .tx_dc_base = 0x130000, .rx_dc_base = 0x100000, .offload_features = NETIF_F_IP_CSUM, @@ -1836,6 +1837,7 @@ const struct efx_nic_type falcon_b0_nic_type = { .phys_addr_channels = 32, /* Hardware limit is 64, but the legacy * interrupt handler only supports 32 * channels */ + .timer_period_max = 1 << FRF_AB_TC_TIMER_VAL_WIDTH, .tx_dc_base = 0x130000, .rx_dc_base = 0x100000, .offload_features = NETIF_F_IP_CSUM | NETIF_F_RXHASH | NETIF_F_NTUPLE, diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 4cbd997e378..8ce4d068bba 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -624,6 +624,7 @@ struct efx_filter_state; * @membase_phys: Memory BAR value as physical address * @membase: Memory BAR value * @interrupt_mode: Interrupt mode + * @timer_quantum_ns: Interrupt timer quantum, in nanoseconds * @irq_rx_adaptive: Adaptive IRQ moderation enabled for RX event queues * @irq_rx_moderation: IRQ moderation time for RX event queues * @msg_enable: Log message enable flags @@ -706,6 +707,7 @@ struct efx_nic { void __iomem *membase; enum efx_int_mode interrupt_mode; + unsigned int timer_quantum_ns; bool irq_rx_adaptive; unsigned int irq_rx_moderation; u32 msg_enable; @@ -845,6 +847,7 @@ static inline unsigned int efx_port_num(struct efx_nic *efx) * from &enum efx_init_mode. * @phys_addr_channels: Number of channels with physically addressed * descriptors + * @timer_period_max: Maximum period of interrupt timer (in ticks) * @tx_dc_base: Base address in SRAM of TX queue descriptor caches * @rx_dc_base: Base address in SRAM of RX queue descriptor caches * @offload_features: net_device feature flags for protocol offload @@ -889,6 +892,7 @@ struct efx_nic_type { unsigned int rx_buffer_padding; unsigned int max_interrupt_mode; unsigned int phys_addr_channels; + unsigned int timer_period_max; unsigned int tx_dc_base; unsigned int rx_dc_base; netdev_features_t offload_features; diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h index cfda6ded24f..a3ccd0b9d78 100644 --- a/drivers/net/ethernet/sfc/nic.h +++ b/drivers/net/ethernet/sfc/nic.h @@ -205,9 +205,6 @@ extern irqreturn_t efx_nic_fatal_interrupt(struct efx_nic *efx); extern irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id); extern void falcon_irq_ack_a1(struct efx_nic *efx); -#define EFX_IRQ_MOD_RESOLUTION 5 -#define EFX_IRQ_MOD_MAX 0x1000 - /* Global Resources */ extern int efx_nic_flush_queues(struct efx_nic *efx); extern void falcon_start_nic_stats(struct efx_nic *efx); diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c index 65cb5e4f426..f05425842b3 100644 --- a/drivers/net/ethernet/sfc/siena.c +++ b/drivers/net/ethernet/sfc/siena.c @@ -35,8 +35,6 @@ static void siena_push_irq_moderation(struct efx_channel *channel) { efx_dword_t timer_cmd; - BUILD_BUG_ON(EFX_IRQ_MOD_MAX > (1 << FRF_CZ_TC_TIMER_VAL_WIDTH)); - if (channel->irq_moderation) EFX_POPULATE_DWORD_2(timer_cmd, FRF_CZ_TC_TIMER_MODE, @@ -216,7 +214,15 @@ static int siena_reset_hw(struct efx_nic *efx, enum reset_type method) static int siena_probe_nvconfig(struct efx_nic *efx) { - return efx_mcdi_get_board_cfg(efx, efx->net_dev->perm_addr, NULL, NULL); + u32 caps = 0; + int rc; + + rc = efx_mcdi_get_board_cfg(efx, efx->net_dev->perm_addr, NULL, &caps); + + efx->timer_quantum_ns = + (caps & (1 << MC_CMD_CAPABILITIES_TURBO_ACTIVE_LBN)) ? + 3072 : 6144; /* 768 cycles */ + return rc; } static int siena_probe_nic(struct efx_nic *efx) @@ -644,6 +650,7 @@ const struct efx_nic_type siena_a0_nic_type = { .phys_addr_channels = 32, /* Hardware limit is 64, but the legacy * interrupt handler only supports 32 * channels */ + .timer_period_max = 1 << FRF_CZ_TC_TIMER_VAL_WIDTH, .tx_dc_base = 0x88000, .rx_dc_base = 0x68000, .offload_features = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | -- cgit v1.2.3-70-g09d2 From 0fb53faa2e6fe67a76b8cfc6eb70a88d9d623648 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 4 Nov 2011 23:06:04 +0000 Subject: sfc: Remove dependence on NAPI polling in efx_test_eventq_irq() We cannot safely assume that the NAPI handler will complete within the 20 ms that we allow for the event self-test. The handler may be deferred for longer than this, particularly on realtime kernels. Instead, check whether either an event has been handled or (as in the old failure path) whether an interrupt has been received and an event has been delivered but not yet handled. Use napi_disable() to synchronize with the NAPI handler before checking, since it will clear events before updating eventq_read_ptr. Remove the test result chan.N.eventq.poll, since it is not an error if the NAPI handler does not run during the test. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/ethtool.c | 4 -- drivers/net/ethernet/sfc/selftest.c | 79 +++++++++++++++++++------------------ drivers/net/ethernet/sfc/selftest.h | 1 - 3 files changed, 40 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index 1a7f7ba27be..ba901167801 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c @@ -404,10 +404,6 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx, &tests->eventq_int[channel->channel], EFX_CHANNEL_NAME(channel), "eventq.int", NULL); - efx_fill_test(n++, strings, data, - &tests->eventq_poll[channel->channel], - EFX_CHANNEL_NAME(channel), - "eventq.poll", NULL); } efx_fill_test(n++, strings, data, &tests->registers, diff --git a/drivers/net/ethernet/sfc/selftest.c b/drivers/net/ethernet/sfc/selftest.c index 7718287ad0b..0f847892447 100644 --- a/drivers/net/ethernet/sfc/selftest.c +++ b/drivers/net/ethernet/sfc/selftest.c @@ -161,11 +161,8 @@ static int efx_test_eventq_irq(struct efx_channel *channel, struct efx_self_tests *tests) { struct efx_nic *efx = channel->efx; - unsigned int read_ptr, count; - - tests->eventq_dma[channel->channel] = -1; - tests->eventq_int[channel->channel] = -1; - tests->eventq_poll[channel->channel] = -1; + unsigned int read_ptr; + bool napi_ran, dma_seen, int_seen; read_ptr = channel->eventq_read_ptr; channel->efx->last_irq_cpu = -1; @@ -173,44 +170,48 @@ static int efx_test_eventq_irq(struct efx_channel *channel, efx_nic_generate_test_event(channel); - /* Wait for arrival of interrupt */ - count = 0; - do { - schedule_timeout_uninterruptible(HZ / 100); - - if (ACCESS_ONCE(channel->eventq_read_ptr) != read_ptr) - goto eventq_ok; - } while (++count < 2); - - netif_err(efx, drv, efx->net_dev, - "channel %d timed out waiting for event queue\n", - channel->channel); - - /* See if interrupt arrived */ - if (channel->efx->last_irq_cpu >= 0) { - netif_err(efx, drv, efx->net_dev, - "channel %d saw interrupt on CPU%d " - "during event queue test\n", channel->channel, - raw_smp_processor_id()); - tests->eventq_int[channel->channel] = 1; + /* Wait for arrival of interrupt. NAPI processing may or may + * not complete in time, but we can cope in any case. + */ + msleep(10); + napi_disable(&channel->napi_str); + if (channel->eventq_read_ptr != read_ptr) { + napi_ran = true; + dma_seen = true; + int_seen = true; + } else { + napi_ran = false; + dma_seen = efx_nic_event_present(channel); + int_seen = efx->last_irq_cpu >= 0; } + napi_enable(&channel->napi_str); + efx_nic_eventq_read_ack(channel); + + tests->eventq_dma[channel->channel] = dma_seen ? 1 : -1; + tests->eventq_int[channel->channel] = int_seen ? 1 : -1; - /* Check to see if event was received even if interrupt wasn't */ - if (efx_nic_event_present(channel)) { + if (dma_seen && int_seen) { + netif_dbg(efx, drv, efx->net_dev, + "channel %d event queue passed (with%s NAPI)\n", + channel->channel, napi_ran ? "" : "out"); + return 0; + } else { + /* Report failure and whether either interrupt or DMA worked */ netif_err(efx, drv, efx->net_dev, - "channel %d event was generated, but " - "failed to trigger an interrupt\n", channel->channel); - tests->eventq_dma[channel->channel] = 1; + "channel %d timed out waiting for event queue\n", + channel->channel); + if (int_seen) + netif_err(efx, drv, efx->net_dev, + "channel %d saw interrupt " + "during event queue test\n", + channel->channel); + if (dma_seen) + netif_err(efx, drv, efx->net_dev, + "channel %d event was generated, but " + "failed to trigger an interrupt\n", + channel->channel); + return -ETIMEDOUT; } - - return -ETIMEDOUT; - eventq_ok: - netif_dbg(efx, drv, efx->net_dev, "channel %d event queue passed\n", - channel->channel); - tests->eventq_dma[channel->channel] = 1; - tests->eventq_int[channel->channel] = 1; - tests->eventq_poll[channel->channel] = 1; - return 0; } static int efx_test_phy(struct efx_nic *efx, struct efx_self_tests *tests, diff --git a/drivers/net/ethernet/sfc/selftest.h b/drivers/net/ethernet/sfc/selftest.h index dba5456e70f..87abe2a5384 100644 --- a/drivers/net/ethernet/sfc/selftest.h +++ b/drivers/net/ethernet/sfc/selftest.h @@ -37,7 +37,6 @@ struct efx_self_tests { int interrupt; int eventq_dma[EFX_MAX_CHANNELS]; int eventq_int[EFX_MAX_CHANNELS]; - int eventq_poll[EFX_MAX_CHANNELS]; /* offline tests */ int registers; int phy_ext[EFX_MAX_PHY_TESTS]; -- cgit v1.2.3-70-g09d2 From f70d1847348e9548a9a56e4434946315bca297c8 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 6 Jan 2012 01:08:24 +0000 Subject: Partly revert "sfc: Handle serious errors in exactly one interrupt handler" This reverts commit 6369545945b90daa1a73fca174da9194c398417c in drivers/net/ethernet/sfc/falcon.c. Unlike the INT_ISR0 register on later controller revisions, the NET_IVEC_INT_Q bits written to memory are only ever set for interrupting event queues, not for any other interrupt sources. By definition there can only be one legacy interrupt handler per function, so there is no need to worry about detecting a fatal interrupt more than once. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/falcon.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/falcon.c b/drivers/net/ethernet/sfc/falcon.c index 0b7880b0b8f..b4e91edec0f 100644 --- a/drivers/net/ethernet/sfc/falcon.c +++ b/drivers/net/ethernet/sfc/falcon.c @@ -174,19 +174,16 @@ irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id) "IRQ %d on CPU %d status " EFX_OWORD_FMT "\n", irq, raw_smp_processor_id(), EFX_OWORD_VAL(*int_ker)); + /* Check to see if we have a serious error condition */ + syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT); + if (unlikely(syserr)) + return efx_nic_fatal_interrupt(efx); + /* Determine interrupting queues, clear interrupt status * register and acknowledge the device interrupt. */ BUILD_BUG_ON(FSF_AZ_NET_IVEC_INT_Q_WIDTH > EFX_MAX_CHANNELS); queues = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_INT_Q); - - /* Check to see if we have a serious error condition */ - if (queues & (1U << efx->fatal_irq_level)) { - syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT); - if (unlikely(syserr)) - return efx_nic_fatal_interrupt(efx); - } - EFX_ZERO_OWORD(*int_ker); wmb(); /* Ensure the vector is cleared before interrupt ack */ falcon_irq_ack_a1(efx); -- cgit v1.2.3-70-g09d2 From 1646a6f352a6f70fcca828589ed04797aa09d494 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 5 Jan 2012 20:14:10 +0000 Subject: sfc: Clean up test interrupt handling Interrupts are normally generated by the event queues, moderated by timers. However, they may also be triggered by detection of a 'fatal' error condition (e.g. memory parity error) or by the host writing to certain CSR fields as part of a self-test. The IRQ level/index used for these on Falcon rev B0 and Siena is set by the KER_INT_LEVE_SEL field and cached by the driver in efx_nic::fatal_irq_level. Since this value is also relevant to self-tests rename the field to just 'irq_level'. Avoid unnecessary cache traffic by using a per-channel 'last_irq_cpu' field and only writing to the per-controller field when the interrupt matches efx_nic::irq_level. Remove the volatile qualifier and use ACCESS_ONCE in the places we read these fields. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.h | 6 ++++++ drivers/net/ethernet/sfc/falcon.c | 4 ++-- drivers/net/ethernet/sfc/net_driver.h | 15 ++++++++------- drivers/net/ethernet/sfc/nic.c | 27 +++++++++++++-------------- drivers/net/ethernet/sfc/selftest.c | 12 +++++++----- 5 files changed, 36 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h index a3541ac6ea0..e0b66d158d7 100644 --- a/drivers/net/ethernet/sfc/efx.h +++ b/drivers/net/ethernet/sfc/efx.h @@ -145,6 +145,12 @@ static inline void efx_schedule_channel(struct efx_channel *channel) napi_schedule(&channel->napi_str); } +static inline void efx_schedule_channel_irq(struct efx_channel *channel) +{ + channel->last_irq_cpu = raw_smp_processor_id(); + efx_schedule_channel(channel); +} + extern void efx_link_status_changed(struct efx_nic *efx); extern void efx_link_set_advertising(struct efx_nic *efx, u32); extern void efx_link_set_wanted_fc(struct efx_nic *efx, u8); diff --git a/drivers/net/ethernet/sfc/falcon.c b/drivers/net/ethernet/sfc/falcon.c index b4e91edec0f..98285115df1 100644 --- a/drivers/net/ethernet/sfc/falcon.c +++ b/drivers/net/ethernet/sfc/falcon.c @@ -189,9 +189,9 @@ irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id) falcon_irq_ack_a1(efx); if (queues & 1) - efx_schedule_channel(efx_get_channel(efx, 0)); + efx_schedule_channel_irq(efx_get_channel(efx, 0)); if (queues & 2) - efx_schedule_channel(efx_get_channel(efx, 1)); + efx_schedule_channel_irq(efx_get_channel(efx, 1)); return IRQ_HANDLED; } /************************************************************************** diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 8ce4d068bba..a4cf8cb8180 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -325,6 +325,7 @@ enum efx_rx_alloc_method { * @eventq_mask: Event queue pointer mask * @eventq_read_ptr: Event queue read pointer * @last_eventq_read_ptr: Last event queue read pointer value. + * @last_irq_cpu: Last CPU to handle interrupt for this channel * @irq_count: Number of IRQs since last adaptive moderation decision * @irq_mod_score: IRQ moderation score * @rx_alloc_level: Watermark based heuristic counter for pushing descriptors @@ -355,6 +356,7 @@ struct efx_channel { unsigned int eventq_read_ptr; unsigned int last_eventq_read_ptr; + int last_irq_cpu; unsigned int irq_count; unsigned int irq_mod_score; #ifdef CONFIG_RFS_ACCEL @@ -648,7 +650,7 @@ struct efx_filter_state; * @int_error_expire: Time at which error count will be expired * @irq_status: Interrupt status buffer * @irq_zero_count: Number of legacy IRQs seen with queue flags == 0 - * @fatal_irq_level: IRQ level (bit number) used for serious errors + * @irq_level: IRQ level/index for IRQs not triggered by an event queue * @mtd_list: List of MTDs attached to the NIC * @nic_data: Hardware dependent state * @mac_lock: MAC access lock. Protects @port_enabled, @phy_mode, @@ -679,10 +681,9 @@ struct efx_filter_state; * @loopback_selftest: Offline self-test private state * @monitor_work: Hardware monitor workitem * @biu_lock: BIU (bus interface unit) lock - * @last_irq_cpu: Last CPU to handle interrupt. - * This register is written with the SMP processor ID whenever an - * interrupt is handled. It is used by efx_nic_test_interrupt() - * to verify that an interrupt has occurred. + * @last_irq_cpu: Last CPU to handle a possible test interrupt. This + * field is used by efx_test_interrupts() to verify that an + * interrupt has occurred. * @n_rx_nodesc_drop_cnt: RX no descriptor drop count * @mac_stats: MAC statistics. These include all statistics the MACs * can provide. Generic code converts these into a standard @@ -735,7 +736,7 @@ struct efx_nic { struct efx_buffer irq_status; unsigned irq_zero_count; - unsigned fatal_irq_level; + unsigned irq_level; #ifdef CONFIG_SFC_MTD struct list_head mtd_list; @@ -779,7 +780,7 @@ struct efx_nic { struct delayed_work monitor_work ____cacheline_aligned_in_smp; spinlock_t biu_lock; - volatile signed int last_irq_cpu; + int last_irq_cpu; unsigned n_rx_nodesc_drop_cnt; struct efx_mac_stats mac_stats; spinlock_t stats_lock; diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c index bf07bd0488c..de7aa1c8ebd 100644 --- a/drivers/net/ethernet/sfc/nic.c +++ b/drivers/net/ethernet/sfc/nic.c @@ -1311,7 +1311,7 @@ static inline void efx_nic_interrupts(struct efx_nic *efx, efx_oword_t int_en_reg_ker; EFX_POPULATE_OWORD_3(int_en_reg_ker, - FRF_AZ_KER_INT_LEVE_SEL, efx->fatal_irq_level, + FRF_AZ_KER_INT_LEVE_SEL, efx->irq_level, FRF_AZ_KER_INT_KER, force, FRF_AZ_DRV_INT_EN_KER, enabled); efx_writeo(efx, &int_en_reg_ker, FR_AZ_INT_EN_KER); @@ -1427,11 +1427,12 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id) efx_readd(efx, ®, FR_BZ_INT_ISR0); queues = EFX_EXTRACT_DWORD(reg, 0, 31); - /* Check to see if we have a serious error condition */ - if (queues & (1U << efx->fatal_irq_level)) { + /* Handle non-event-queue sources */ + if (queues & (1U << efx->irq_level)) { syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT); if (unlikely(syserr)) return efx_nic_fatal_interrupt(efx); + efx->last_irq_cpu = raw_smp_processor_id(); } if (queues != 0) { @@ -1441,7 +1442,7 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id) /* Schedule processing of any interrupting queues */ efx_for_each_channel(channel, efx) { if (queues & 1) - efx_schedule_channel(channel); + efx_schedule_channel_irq(channel); queues >>= 1; } result = IRQ_HANDLED; @@ -1458,18 +1459,16 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id) efx_for_each_channel(channel, efx) { event = efx_event(channel, channel->eventq_read_ptr); if (efx_event_present(event)) - efx_schedule_channel(channel); + efx_schedule_channel_irq(channel); else efx_nic_eventq_read_ack(channel); } } - if (result == IRQ_HANDLED) { - efx->last_irq_cpu = raw_smp_processor_id(); + if (result == IRQ_HANDLED) netif_vdbg(efx, intr, efx->net_dev, "IRQ %d on CPU %d status " EFX_DWORD_FMT "\n", irq, raw_smp_processor_id(), EFX_DWORD_VAL(reg)); - } return result; } @@ -1488,20 +1487,20 @@ static irqreturn_t efx_msi_interrupt(int irq, void *dev_id) efx_oword_t *int_ker = efx->irq_status.addr; int syserr; - efx->last_irq_cpu = raw_smp_processor_id(); netif_vdbg(efx, intr, efx->net_dev, "IRQ %d on CPU %d status " EFX_OWORD_FMT "\n", irq, raw_smp_processor_id(), EFX_OWORD_VAL(*int_ker)); - /* Check to see if we have a serious error condition */ - if (channel->channel == efx->fatal_irq_level) { + /* Handle non-event-queue sources */ + if (channel->channel == efx->irq_level) { syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT); if (unlikely(syserr)) return efx_nic_fatal_interrupt(efx); + efx->last_irq_cpu = raw_smp_processor_id(); } /* Schedule processing of the channel */ - efx_schedule_channel(channel); + efx_schedule_channel_irq(channel); return IRQ_HANDLED; } @@ -1640,10 +1639,10 @@ void efx_nic_init_common(struct efx_nic *efx) if (EFX_WORKAROUND_17213(efx) && !EFX_INT_MODE_USE_MSI(efx)) /* Use an interrupt level unused by event queues */ - efx->fatal_irq_level = 0x1f; + efx->irq_level = 0x1f; else /* Use a valid MSI-X vector */ - efx->fatal_irq_level = 0; + efx->irq_level = 0; /* Enable all the genuinely fatal interrupts. (They are still * masked by the overall interrupt mask, controlled by diff --git a/drivers/net/ethernet/sfc/selftest.c b/drivers/net/ethernet/sfc/selftest.c index 0f847892447..7def480570c 100644 --- a/drivers/net/ethernet/sfc/selftest.c +++ b/drivers/net/ethernet/sfc/selftest.c @@ -130,6 +130,8 @@ static int efx_test_chip(struct efx_nic *efx, struct efx_self_tests *tests) static int efx_test_interrupts(struct efx_nic *efx, struct efx_self_tests *tests) { + int cpu; + netif_dbg(efx, drv, efx->net_dev, "testing interrupts\n"); tests->interrupt = -1; @@ -142,7 +144,8 @@ static int efx_test_interrupts(struct efx_nic *efx, /* Wait for arrival of test interrupt. */ netif_dbg(efx, drv, efx->net_dev, "waiting for test interrupt\n"); schedule_timeout_uninterruptible(HZ / 10); - if (efx->last_irq_cpu >= 0) + cpu = ACCESS_ONCE(efx->last_irq_cpu); + if (cpu >= 0) goto success; netif_err(efx, drv, efx->net_dev, "timed out waiting for interrupt\n"); @@ -150,8 +153,7 @@ static int efx_test_interrupts(struct efx_nic *efx, success: netif_dbg(efx, drv, efx->net_dev, "%s test interrupt seen on CPU%d\n", - INT_MODE(efx), - efx->last_irq_cpu); + INT_MODE(efx), cpu); tests->interrupt = 1; return 0; } @@ -165,7 +167,7 @@ static int efx_test_eventq_irq(struct efx_channel *channel, bool napi_ran, dma_seen, int_seen; read_ptr = channel->eventq_read_ptr; - channel->efx->last_irq_cpu = -1; + channel->last_irq_cpu = -1; smp_wmb(); efx_nic_generate_test_event(channel); @@ -182,7 +184,7 @@ static int efx_test_eventq_irq(struct efx_channel *channel, } else { napi_ran = false; dma_seen = efx_nic_event_present(channel); - int_seen = efx->last_irq_cpu >= 0; + int_seen = ACCESS_ONCE(channel->last_irq_cpu) >= 0; } napi_enable(&channel->napi_str); efx_nic_eventq_read_ack(channel); -- cgit v1.2.3-70-g09d2 From 55c5e0f85dc550f03dc8a0b0097da6af3b4865c5 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 6 Jan 2012 20:25:39 +0000 Subject: sfc: Add hwmon driver for boards using SFC9000-family controllers The SFC9000-family controllers have firmware to manage all board peripherals including temperature, heat sink continuity and voltage sensors. The firmware reports sensor alarms, which we log, and will shut down the board if necessary. Some users may want to monitor their boards more closely, so add an hwmon driver that exposes all sensors reported by the firmware. Move efx_mcdi_sensor_event() into the new file so it can share the array of sensor labels with the hwmon driver. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/Kconfig | 7 + drivers/net/ethernet/sfc/Makefile | 2 +- drivers/net/ethernet/sfc/mcdi.c | 43 ---- drivers/net/ethernet/sfc/mcdi.h | 28 +++ drivers/net/ethernet/sfc/mcdi_mon.c | 415 ++++++++++++++++++++++++++++++++++++ drivers/net/ethernet/sfc/nic.h | 14 ++ drivers/net/ethernet/sfc/siena.c | 6 + 7 files changed, 471 insertions(+), 44 deletions(-) create mode 100644 drivers/net/ethernet/sfc/mcdi_mon.c (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/Kconfig b/drivers/net/ethernet/sfc/Kconfig index 5d18841f0f3..ae40b666739 100644 --- a/drivers/net/ethernet/sfc/Kconfig +++ b/drivers/net/ethernet/sfc/Kconfig @@ -19,3 +19,10 @@ config SFC_MTD This exposes the on-board flash memory as MTD devices (e.g. /dev/mtd1). This makes it possible to upload new firmware to the NIC. +config SFC_MCDI_MON + bool "Solarflare SFC9000-family hwmon support" + depends on SFC && HWMON && !(SFC=y && HWMON=m) + default y + ----help--- + This exposes the on-board firmware-managed sensors as a + hardware monitor device. diff --git a/drivers/net/ethernet/sfc/Makefile b/drivers/net/ethernet/sfc/Makefile index ab31c7124db..3fa2e25ccc4 100644 --- a/drivers/net/ethernet/sfc/Makefile +++ b/drivers/net/ethernet/sfc/Makefile @@ -2,7 +2,7 @@ sfc-y += efx.o nic.o falcon.o siena.o tx.o rx.o filter.o \ falcon_xmac.o mcdi_mac.o \ selftest.o ethtool.o qt202x_phy.o mdio_10g.o \ tenxpress.o txc43128_phy.o falcon_boards.o \ - mcdi.o mcdi_phy.o + mcdi.o mcdi_phy.o mcdi_mon.o sfc-$(CONFIG_SFC_MTD) += mtd.o obj-$(CONFIG_SFC) += sfc.o diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index f1cad22b30f..619f63a66ce 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c @@ -517,49 +517,6 @@ static void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev) efx_link_status_changed(efx); } -static const char *const sensor_names[] = { - [MC_CMD_SENSOR_CONTROLLER_TEMP] = "Controller temp. sensor", - [MC_CMD_SENSOR_PHY_COMMON_TEMP] = "PHY shared temp. sensor", - [MC_CMD_SENSOR_CONTROLLER_COOLING] = "Controller cooling", - [MC_CMD_SENSOR_PHY0_TEMP] = "PHY 0 temp. sensor", - [MC_CMD_SENSOR_PHY0_COOLING] = "PHY 0 cooling", - [MC_CMD_SENSOR_PHY1_TEMP] = "PHY 1 temp. sensor", - [MC_CMD_SENSOR_PHY1_COOLING] = "PHY 1 cooling", - [MC_CMD_SENSOR_IN_1V0] = "1.0V supply sensor", - [MC_CMD_SENSOR_IN_1V2] = "1.2V supply sensor", - [MC_CMD_SENSOR_IN_1V8] = "1.8V supply sensor", - [MC_CMD_SENSOR_IN_2V5] = "2.5V supply sensor", - [MC_CMD_SENSOR_IN_3V3] = "3.3V supply sensor", - [MC_CMD_SENSOR_IN_12V0] = "12V supply sensor" -}; - -static const char *const sensor_status_names[] = { - [MC_CMD_SENSOR_STATE_OK] = "OK", - [MC_CMD_SENSOR_STATE_WARNING] = "Warning", - [MC_CMD_SENSOR_STATE_FATAL] = "Fatal", - [MC_CMD_SENSOR_STATE_BROKEN] = "Device failure", -}; - -static void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev) -{ - unsigned int monitor, state, value; - const char *name, *state_txt; - monitor = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_MONITOR); - state = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_STATE); - value = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_VALUE); - /* Deal gracefully with the board having more drivers than we - * know about, but do not expect new sensor states. */ - name = (monitor >= ARRAY_SIZE(sensor_names)) - ? "No sensor name available" : - sensor_names[monitor]; - EFX_BUG_ON_PARANOID(state >= ARRAY_SIZE(sensor_status_names)); - state_txt = sensor_status_names[state]; - - netif_err(efx, hw, efx->net_dev, - "Sensor %d (%s) reports condition '%s' for raw value %d\n", - monitor, name, state_txt, value); -} - /* Called from falcon_process_eventq for MCDI events */ void efx_mcdi_process_event(struct efx_channel *channel, efx_qword_t *event) diff --git a/drivers/net/ethernet/sfc/mcdi.h b/drivers/net/ethernet/sfc/mcdi.h index 4dd39fcca67..fbaa6efcd74 100644 --- a/drivers/net/ethernet/sfc/mcdi.h +++ b/drivers/net/ethernet/sfc/mcdi.h @@ -56,6 +56,15 @@ struct efx_mcdi_iface { size_t resplen; }; +struct efx_mcdi_mon { + struct efx_buffer dma_buf; + struct mutex update_lock; + unsigned long last_update; + struct device *device; + struct efx_mcdi_mon_attribute *attrs; + unsigned int n_attrs; +}; + extern void efx_mcdi_init(struct efx_nic *efx); extern int efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd, const u8 *inbuf, @@ -68,6 +77,7 @@ extern void efx_mcdi_mode_event(struct efx_nic *efx); extern void efx_mcdi_process_event(struct efx_channel *channel, efx_qword_t *event); +extern void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev); #define MCDI_PTR2(_buf, _ofst) \ (((u8 *)_buf) + _ofst) @@ -83,6 +93,10 @@ extern void efx_mcdi_process_event(struct efx_channel *channel, #define MCDI_PTR(_buf, _ofst) \ MCDI_PTR2(_buf, MC_CMD_ ## _ofst ## _OFST) +#define MCDI_ARRAY_PTR(_buf, _field, _type, _index) \ + MCDI_PTR2(_buf, \ + MC_CMD_ ## _field ## _OFST + \ + (_index) * MC_CMD_ ## _type ## _TYPEDEF_LEN) #define MCDI_SET_DWORD(_buf, _ofst, _value) \ MCDI_SET_DWORD2(_buf, MC_CMD_ ## _ofst ## _OFST, _value) #define MCDI_DWORD(_buf, _ofst) \ @@ -92,6 +106,12 @@ extern void efx_mcdi_process_event(struct efx_channel *channel, #define MCDI_EVENT_FIELD(_ev, _field) \ EFX_QWORD_FIELD(_ev, MCDI_EVENT_ ## _field) +#define MCDI_ARRAY_FIELD(_buf, _field1, _type, _index, _field2) \ + EFX_DWORD_FIELD( \ + *((efx_dword_t *) \ + (MCDI_ARRAY_PTR(_buf, _field1, _type, _index) + \ + (MC_CMD_ ## _type ## _TYPEDEF_ ## _field2 ## _OFST & ~3))), \ + MC_CMD_ ## _type ## _TYPEDEF_ ## _field2) extern void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len); extern int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating, @@ -131,4 +151,12 @@ extern int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr, extern int efx_mcdi_mac_reconfigure(struct efx_nic *efx); extern bool efx_mcdi_mac_check_fault(struct efx_nic *efx); +#ifdef CONFIG_SFC_MCDI_MON +extern int efx_mcdi_mon_probe(struct efx_nic *efx); +extern void efx_mcdi_mon_remove(struct efx_nic *efx); +#else +static inline int efx_mcdi_mon_probe(struct efx_nic *efx) { return 0; } +static inline void efx_mcdi_mon_remove(struct efx_nic *efx) {} +#endif + #endif /* EFX_MCDI_H */ diff --git a/drivers/net/ethernet/sfc/mcdi_mon.c b/drivers/net/ethernet/sfc/mcdi_mon.c new file mode 100644 index 00000000000..8a72c10b9a6 --- /dev/null +++ b/drivers/net/ethernet/sfc/mcdi_mon.c @@ -0,0 +1,415 @@ +/**************************************************************************** + * Driver for Solarflare Solarstorm network controllers and boards + * Copyright 2011 Solarflare Communications Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation, incorporated herein by reference. + */ + +#include +#include +#include +#include + +#include "net_driver.h" +#include "mcdi.h" +#include "mcdi_pcol.h" +#include "nic.h" + +enum efx_hwmon_type { + EFX_HWMON_UNKNOWN, + EFX_HWMON_TEMP, /* temperature */ + EFX_HWMON_COOL, /* cooling device, probably a heatsink */ + EFX_HWMON_IN /* input voltage */ +}; + +static const struct { + const char *label; + enum efx_hwmon_type hwmon_type; + int port; +} efx_mcdi_sensor_type[MC_CMD_SENSOR_ENTRY_MAXNUM] = { +#define SENSOR(name, label, hwmon_type, port) \ + [MC_CMD_SENSOR_##name] = { label, hwmon_type, port } + SENSOR(CONTROLLER_TEMP, "Controller temp.", EFX_HWMON_TEMP, -1), + SENSOR(PHY_COMMON_TEMP, "PHY temp.", EFX_HWMON_TEMP, -1), + SENSOR(CONTROLLER_COOLING, "Controller cooling", EFX_HWMON_COOL, -1), + SENSOR(PHY0_TEMP, "PHY temp.", EFX_HWMON_TEMP, 0), + SENSOR(PHY0_COOLING, "PHY cooling", EFX_HWMON_COOL, 0), + SENSOR(PHY1_TEMP, "PHY temp.", EFX_HWMON_TEMP, 1), + SENSOR(PHY1_COOLING, "PHY cooling", EFX_HWMON_COOL, 1), + SENSOR(IN_1V0, "1.0V supply", EFX_HWMON_IN, -1), + SENSOR(IN_1V2, "1.2V supply", EFX_HWMON_IN, -1), + SENSOR(IN_1V8, "1.8V supply", EFX_HWMON_IN, -1), + SENSOR(IN_2V5, "2.5V supply", EFX_HWMON_IN, -1), + SENSOR(IN_3V3, "3.3V supply", EFX_HWMON_IN, -1), + SENSOR(IN_12V0, "12.0V supply", EFX_HWMON_IN, -1), + SENSOR(IN_1V2A, "1.2V analogue supply", EFX_HWMON_IN, -1), + SENSOR(IN_VREF, "ref. voltage", EFX_HWMON_IN, -1), +#undef SENSOR +}; + +static const char *const sensor_status_names[] = { + [MC_CMD_SENSOR_STATE_OK] = "OK", + [MC_CMD_SENSOR_STATE_WARNING] = "Warning", + [MC_CMD_SENSOR_STATE_FATAL] = "Fatal", + [MC_CMD_SENSOR_STATE_BROKEN] = "Device failure", +}; + +void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev) +{ + unsigned int type, state, value; + const char *name = NULL, *state_txt; + + type = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_MONITOR); + state = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_STATE); + value = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_VALUE); + + /* Deal gracefully with the board having more drivers than we + * know about, but do not expect new sensor states. */ + if (type < ARRAY_SIZE(efx_mcdi_sensor_type)) + name = efx_mcdi_sensor_type[type].label; + if (!name) + name = "No sensor name available"; + EFX_BUG_ON_PARANOID(state >= ARRAY_SIZE(sensor_status_names)); + state_txt = sensor_status_names[state]; + + netif_err(efx, hw, efx->net_dev, + "Sensor %d (%s) reports condition '%s' for raw value %d\n", + type, name, state_txt, value); +} + +#ifdef CONFIG_SFC_MCDI_MON + +struct efx_mcdi_mon_attribute { + struct device_attribute dev_attr; + unsigned int index; + unsigned int type; + unsigned int limit_value; + char name[12]; +}; + +static int efx_mcdi_mon_update(struct efx_nic *efx) +{ + struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx); + u8 inbuf[MC_CMD_READ_SENSORS_IN_LEN]; + int rc; + + MCDI_SET_DWORD(inbuf, READ_SENSORS_IN_DMA_ADDR_LO, + hwmon->dma_buf.dma_addr & 0xffffffff); + MCDI_SET_DWORD(inbuf, READ_SENSORS_IN_DMA_ADDR_HI, + (u64)hwmon->dma_buf.dma_addr >> 32); + + rc = efx_mcdi_rpc(efx, MC_CMD_READ_SENSORS, + inbuf, sizeof(inbuf), NULL, 0, NULL); + if (rc == 0) + hwmon->last_update = jiffies; + return rc; +} + +static ssize_t efx_mcdi_mon_show_name(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "%s\n", KBUILD_MODNAME); +} + +static int efx_mcdi_mon_get_entry(struct device *dev, unsigned int index, + efx_dword_t *entry) +{ + struct efx_nic *efx = dev_get_drvdata(dev); + struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx); + int rc; + + BUILD_BUG_ON(MC_CMD_READ_SENSORS_OUT_LEN != 0); + + mutex_lock(&hwmon->update_lock); + + /* Use cached value if last update was < 1 s ago */ + if (time_before(jiffies, hwmon->last_update + HZ)) + rc = 0; + else + rc = efx_mcdi_mon_update(efx); + + /* Copy out the requested entry */ + *entry = ((efx_dword_t *)hwmon->dma_buf.addr)[index]; + + mutex_unlock(&hwmon->update_lock); + + return rc; +} + +static ssize_t efx_mcdi_mon_show_value(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct efx_mcdi_mon_attribute *mon_attr = + container_of(attr, struct efx_mcdi_mon_attribute, dev_attr); + efx_dword_t entry; + unsigned int value; + int rc; + + rc = efx_mcdi_mon_get_entry(dev, mon_attr->index, &entry); + if (rc) + return rc; + + value = EFX_DWORD_FIELD(entry, MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE); + + /* Convert temperature from degrees to milli-degrees Celsius */ + if (efx_mcdi_sensor_type[mon_attr->type].hwmon_type == EFX_HWMON_TEMP) + value *= 1000; + + return sprintf(buf, "%u\n", value); +} + +static ssize_t efx_mcdi_mon_show_limit(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct efx_mcdi_mon_attribute *mon_attr = + container_of(attr, struct efx_mcdi_mon_attribute, dev_attr); + unsigned int value; + + value = mon_attr->limit_value; + + /* Convert temperature from degrees to milli-degrees Celsius */ + if (efx_mcdi_sensor_type[mon_attr->type].hwmon_type == EFX_HWMON_TEMP) + value *= 1000; + + return sprintf(buf, "%u\n", value); +} + +static ssize_t efx_mcdi_mon_show_alarm(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct efx_mcdi_mon_attribute *mon_attr = + container_of(attr, struct efx_mcdi_mon_attribute, dev_attr); + efx_dword_t entry; + int state; + int rc; + + rc = efx_mcdi_mon_get_entry(dev, mon_attr->index, &entry); + if (rc) + return rc; + + state = EFX_DWORD_FIELD(entry, MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE); + return sprintf(buf, "%d\n", state != MC_CMD_SENSOR_STATE_OK); +} + +static ssize_t efx_mcdi_mon_show_label(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct efx_mcdi_mon_attribute *mon_attr = + container_of(attr, struct efx_mcdi_mon_attribute, dev_attr); + return sprintf(buf, "%s\n", + efx_mcdi_sensor_type[mon_attr->type].label); +} + +static int +efx_mcdi_mon_add_attr(struct efx_nic *efx, const char *name, + ssize_t (*reader)(struct device *, + struct device_attribute *, char *), + unsigned int index, unsigned int type, + unsigned int limit_value) +{ + struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx); + struct efx_mcdi_mon_attribute *attr = &hwmon->attrs[hwmon->n_attrs]; + int rc; + + strlcpy(attr->name, name, sizeof(attr->name)); + attr->index = index; + attr->type = type; + attr->limit_value = limit_value; + attr->dev_attr.attr.name = attr->name; + attr->dev_attr.attr.mode = S_IRUGO; + attr->dev_attr.show = reader; + rc = device_create_file(&efx->pci_dev->dev, &attr->dev_attr); + if (rc == 0) + ++hwmon->n_attrs; + return rc; +} + +int efx_mcdi_mon_probe(struct efx_nic *efx) +{ + struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx); + unsigned int n_attrs, n_temp = 0, n_cool = 0, n_in = 0; + u8 outbuf[MC_CMD_SENSOR_INFO_OUT_LENMAX]; + size_t outlen; + char name[12]; + u32 mask; + int rc, i, type; + + BUILD_BUG_ON(MC_CMD_SENSOR_INFO_IN_LEN != 0); + + rc = efx_mcdi_rpc(efx, MC_CMD_SENSOR_INFO, NULL, 0, + outbuf, sizeof(outbuf), &outlen); + if (rc) + return rc; + if (outlen < MC_CMD_SENSOR_INFO_OUT_LENMIN) + return -EIO; + + /* Find out which sensors are present. Don't create a device + * if there are none. + */ + mask = MCDI_DWORD(outbuf, SENSOR_INFO_OUT_MASK); + if (mask == 0) + return 0; + + /* Check again for short response */ + if (outlen < MC_CMD_SENSOR_INFO_OUT_LEN(hweight32(mask))) + return -EIO; + + rc = efx_nic_alloc_buffer(efx, &hwmon->dma_buf, + 4 * MC_CMD_SENSOR_ENTRY_MAXNUM); + if (rc) + return rc; + + mutex_init(&hwmon->update_lock); + efx_mcdi_mon_update(efx); + + /* Allocate space for the maximum possible number of + * attributes for this set of sensors: name of the driver plus + * value, min, max, crit, alarm and label for each sensor. + */ + n_attrs = 1 + 6 * hweight32(mask); + hwmon->attrs = kcalloc(n_attrs, sizeof(*hwmon->attrs), GFP_KERNEL); + if (!hwmon->attrs) { + rc = -ENOMEM; + goto fail; + } + + hwmon->device = hwmon_device_register(&efx->pci_dev->dev); + if (IS_ERR(hwmon->device)) { + rc = PTR_ERR(hwmon->device); + goto fail; + } + + rc = efx_mcdi_mon_add_attr(efx, "name", efx_mcdi_mon_show_name, 0, 0, 0); + if (rc) + goto fail; + + for (i = 0, type = -1; ; i++) { + const char *hwmon_prefix; + unsigned hwmon_index; + u16 min1, max1, min2, max2; + + /* Find next sensor type or exit if there is none */ + type++; + while (!(mask & (1 << type))) { + type++; + if (type == 32) + return 0; + } + + /* Skip sensors specific to a different port */ + if (efx_mcdi_sensor_type[type].hwmon_type != EFX_HWMON_UNKNOWN && + efx_mcdi_sensor_type[type].port >= 0 && + efx_mcdi_sensor_type[type].port != efx_port_num(efx)) + continue; + + switch (efx_mcdi_sensor_type[type].hwmon_type) { + case EFX_HWMON_TEMP: + hwmon_prefix = "temp"; + hwmon_index = ++n_temp; /* 1-based */ + break; + case EFX_HWMON_COOL: + /* This is likely to be a heatsink, but there + * is no convention for representing cooling + * devices other than fans. + */ + hwmon_prefix = "fan"; + hwmon_index = ++n_cool; /* 1-based */ + break; + default: + hwmon_prefix = "in"; + hwmon_index = n_in++; /* 0-based */ + break; + } + + min1 = MCDI_ARRAY_FIELD(outbuf, SENSOR_ENTRY, + SENSOR_INFO_ENTRY, i, MIN1); + max1 = MCDI_ARRAY_FIELD(outbuf, SENSOR_ENTRY, + SENSOR_INFO_ENTRY, i, MAX1); + min2 = MCDI_ARRAY_FIELD(outbuf, SENSOR_ENTRY, + SENSOR_INFO_ENTRY, i, MIN2); + max2 = MCDI_ARRAY_FIELD(outbuf, SENSOR_ENTRY, + SENSOR_INFO_ENTRY, i, MAX2); + + if (min1 != max1) { + snprintf(name, sizeof(name), "%s%u_input", + hwmon_prefix, hwmon_index); + rc = efx_mcdi_mon_add_attr( + efx, name, efx_mcdi_mon_show_value, i, type, 0); + if (rc) + goto fail; + + snprintf(name, sizeof(name), "%s%u_min", + hwmon_prefix, hwmon_index); + rc = efx_mcdi_mon_add_attr( + efx, name, efx_mcdi_mon_show_limit, + i, type, min1); + if (rc) + goto fail; + + snprintf(name, sizeof(name), "%s%u_max", + hwmon_prefix, hwmon_index); + rc = efx_mcdi_mon_add_attr( + efx, name, efx_mcdi_mon_show_limit, + i, type, max1); + if (rc) + goto fail; + + if (min2 != max2) { + /* Assume max2 is critical value. + * But we have no good way to expose min2. + */ + snprintf(name, sizeof(name), "%s%u_crit", + hwmon_prefix, hwmon_index); + rc = efx_mcdi_mon_add_attr( + efx, name, efx_mcdi_mon_show_limit, + i, type, max2); + if (rc) + goto fail; + } + } + + snprintf(name, sizeof(name), "%s%u_alarm", + hwmon_prefix, hwmon_index); + rc = efx_mcdi_mon_add_attr( + efx, name, efx_mcdi_mon_show_alarm, i, type, 0); + if (rc) + goto fail; + + if (efx_mcdi_sensor_type[type].label) { + snprintf(name, sizeof(name), "%s%u_label", + hwmon_prefix, hwmon_index); + rc = efx_mcdi_mon_add_attr( + efx, name, efx_mcdi_mon_show_label, i, type, 0); + if (rc) + goto fail; + } + } + +fail: + efx_mcdi_mon_remove(efx); + return rc; +} + +void efx_mcdi_mon_remove(struct efx_nic *efx) +{ + struct siena_nic_data *nic_data = efx->nic_data; + struct efx_mcdi_mon *hwmon = &nic_data->hwmon; + unsigned int i; + + for (i = 0; i < hwmon->n_attrs; i++) + device_remove_file(&efx->pci_dev->dev, + &hwmon->attrs[i].dev_attr); + kfree(hwmon->attrs); + if (hwmon->device) + hwmon_device_unregister(hwmon->device); + efx_nic_free_buffer(efx, &hwmon->dma_buf); +} + +#endif /* CONFIG_SFC_MCDI_MON */ diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h index a3ccd0b9d78..905a1877d60 100644 --- a/drivers/net/ethernet/sfc/nic.h +++ b/drivers/net/ethernet/sfc/nic.h @@ -144,12 +144,26 @@ static inline struct falcon_board *falcon_board(struct efx_nic *efx) * struct siena_nic_data - Siena NIC state * @mcdi: Management-Controller-to-Driver Interface * @wol_filter_id: Wake-on-LAN packet filter id + * @hwmon: Hardware monitor state */ struct siena_nic_data { struct efx_mcdi_iface mcdi; int wol_filter_id; +#ifdef CONFIG_SFC_MCDI_MON + struct efx_mcdi_mon hwmon; +#endif }; +#ifdef CONFIG_SFC_MCDI_MON +static inline struct efx_mcdi_mon *efx_mcdi_mon(struct efx_nic *efx) +{ + struct siena_nic_data *nic_data; + EFX_BUG_ON_PARANOID(efx_nic_rev(efx) < EFX_REV_SIENA_A0); + nic_data = efx->nic_data; + return &nic_data->hwmon; +} +#endif + extern const struct efx_nic_type falcon_a1_nic_type; extern const struct efx_nic_type falcon_b0_nic_type; extern const struct efx_nic_type siena_a0_nic_type; diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c index f05425842b3..d3c4169e2a0 100644 --- a/drivers/net/ethernet/sfc/siena.c +++ b/drivers/net/ethernet/sfc/siena.c @@ -300,6 +300,10 @@ static int siena_probe_nic(struct efx_nic *efx) goto fail5; } + rc = efx_mcdi_mon_probe(efx); + if (rc) + goto fail5; + return 0; fail5: @@ -387,6 +391,8 @@ static int siena_init_nic(struct efx_nic *efx) static void siena_remove_nic(struct efx_nic *efx) { + efx_mcdi_mon_remove(efx); + efx_nic_free_buffer(efx, &efx->irq_status); siena_reset_hw(efx, RESET_TYPE_ALL); -- cgit v1.2.3-70-g09d2 From 94813b86bf1981338de0a6e2ab50be3b4366f3bd Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 6 Jan 2012 22:47:17 +0000 Subject: sfc: Update the description of SFC_MTD SFC4000 boards also have an EEPROM exposed as MTD. The boot configuration is accessed through MTD. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/Kconfig b/drivers/net/ethernet/sfc/Kconfig index ae40b666739..8d423544a7e 100644 --- a/drivers/net/ethernet/sfc/Kconfig +++ b/drivers/net/ethernet/sfc/Kconfig @@ -16,9 +16,9 @@ config SFC_MTD depends on SFC && MTD && !(SFC=y && MTD=m) default y ---help--- - This exposes the on-board flash memory as MTD devices (e.g. - /dev/mtd1). This makes it possible to upload new firmware - to the NIC. + This exposes the on-board flash and/or EEPROM as MTD devices + (e.g. /dev/mtd1). This is required to update the firmware or + the boot configuration under Linux. config SFC_MCDI_MON bool "Solarflare SFC9000-family hwmon support" depends on SFC && HWMON && !(SFC=y && HWMON=m) -- cgit v1.2.3-70-g09d2 From b249513e8ba3ca8bc2c87e78eb6e302d5d8abd6f Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 9 Jan 2012 19:41:48 +0000 Subject: sfc: Remove obsolete function efx_dev_name() Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/net_driver.h | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index a4cf8cb8180..310c50f0645 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -791,15 +791,6 @@ static inline int efx_dev_registered(struct efx_nic *efx) return efx->net_dev->reg_state == NETREG_REGISTERED; } -/* Net device name, for inclusion in log messages if it has been registered. - * Use efx->name not efx->net_dev->name so that races with (un)registration - * are harmless. - */ -static inline const char *efx_dev_name(struct efx_nic *efx) -{ - return efx_dev_registered(efx) ? efx->name : ""; -} - static inline unsigned int efx_port_num(struct efx_nic *efx) { return efx->net_dev->dev_id; -- cgit v1.2.3-70-g09d2 From 73ba7b68e952d98b0885e35402b204a7a675f4a9 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 9 Jan 2012 19:47:08 +0000 Subject: sfc: Remove remnants of on-load self-test The out-of-tree version of the sfc driver used to run a self-test on each device before registering it. Although this was never included in-tree, some functions have checks for this special case which is not really possible. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 34 +++++++++++++--------------------- drivers/net/ethernet/sfc/nic.c | 6 ++---- drivers/net/ethernet/sfc/selftest.c | 12 ++++-------- drivers/net/ethernet/sfc/tx.c | 4 +--- 4 files changed, 20 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 9d4ab5e5e1f..4f412fe22e8 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -855,10 +855,8 @@ int __efx_reconfigure_port(struct efx_nic *efx) WARN_ON(!mutex_is_locked(&efx->mac_lock)); /* Serialise the promiscuous flag with efx_set_multicast_list. */ - if (efx_dev_registered(efx)) { - netif_addr_lock_bh(efx->net_dev); - netif_addr_unlock_bh(efx->net_dev); - } + netif_addr_lock_bh(efx->net_dev); + netif_addr_unlock_bh(efx->net_dev); /* Disable PHY transmit in mac level loopbacks */ phy_mode = efx->phy_mode; @@ -981,10 +979,8 @@ static void efx_stop_port(struct efx_nic *efx) mutex_unlock(&efx->mac_lock); /* Serialise against efx_set_multicast_list() */ - if (efx_dev_registered(efx)) { - netif_addr_lock_bh(efx->net_dev); - netif_addr_unlock_bh(efx->net_dev); - } + netif_addr_lock_bh(efx->net_dev); + netif_addr_unlock_bh(efx->net_dev); } static void efx_fini_port(struct efx_nic *efx) @@ -1394,14 +1390,14 @@ static void efx_start_all(struct efx_nic *efx) return; if ((efx->state != STATE_RUNNING) && (efx->state != STATE_INIT)) return; - if (efx_dev_registered(efx) && !netif_running(efx->net_dev)) + if (!netif_running(efx->net_dev)) return; /* Mark the port as enabled so port reconfigurations can start, then * restart the transmit interface early so the watchdog timer stops */ efx_start_port(efx); - if (efx_dev_registered(efx) && netif_device_present(efx->net_dev)) + if (netif_device_present(efx->net_dev)) netif_tx_wake_all_queues(efx->net_dev); efx_for_each_channel(channel, efx) @@ -1492,11 +1488,9 @@ static void efx_stop_all(struct efx_nic *efx) /* Stop the kernel transmit interface late, so the watchdog * timer isn't ticking over the flush */ - if (efx_dev_registered(efx)) { - netif_tx_stop_all_queues(efx->net_dev); - netif_tx_lock_bh(efx->net_dev); - netif_tx_unlock_bh(efx->net_dev); - } + netif_tx_stop_all_queues(efx->net_dev); + netif_tx_lock_bh(efx->net_dev); + netif_tx_unlock_bh(efx->net_dev); } static void efx_remove_all(struct efx_nic *efx) @@ -2018,11 +2012,9 @@ static void efx_unregister_netdev(struct efx_nic *efx) efx_release_tx_buffers(tx_queue); } - if (efx_dev_registered(efx)) { - strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name)); - device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_type); - unregister_netdev(efx->net_dev); - } + strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name)); + device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_type); + unregister_netdev(efx->net_dev); } /************************************************************************** @@ -2438,7 +2430,7 @@ static int efx_pci_probe_main(struct efx_nic *efx) /* NIC initialisation * * This is called at module load (or hotplug insertion, - * theoretically). It sets up PCI mappings, tests and resets the NIC, + * theoretically). It sets up PCI mappings, resets the NIC, * sets up and registers the network devices with the kernel and hooks * the interrupt service routine. It does not prepare the device for * transmission; this is left to the first time one of the network diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c index de7aa1c8ebd..cd250f197b3 100644 --- a/drivers/net/ethernet/sfc/nic.c +++ b/drivers/net/ethernet/sfc/nic.c @@ -726,11 +726,9 @@ efx_handle_tx_event(struct efx_channel *channel, efx_qword_t *event) tx_queue = efx_channel_get_tx_queue( channel, tx_ev_q_label % EFX_TXQ_TYPES); - if (efx_dev_registered(efx)) - netif_tx_lock(efx->net_dev); + netif_tx_lock(efx->net_dev); efx_notify_tx_desc(tx_queue); - if (efx_dev_registered(efx)) - netif_tx_unlock(efx->net_dev); + netif_tx_unlock(efx->net_dev); } else if (EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_PKT_ERR) && EFX_WORKAROUND_10727(efx)) { efx_schedule_reset(efx, RESET_TYPE_TX_DESC_FETCH); diff --git a/drivers/net/ethernet/sfc/selftest.c b/drivers/net/ethernet/sfc/selftest.c index 7def480570c..febe2a9e621 100644 --- a/drivers/net/ethernet/sfc/selftest.c +++ b/drivers/net/ethernet/sfc/selftest.c @@ -397,11 +397,9 @@ static int efx_begin_loopback(struct efx_tx_queue *tx_queue) * interrupt handler. */ smp_wmb(); - if (efx_dev_registered(efx)) - netif_tx_lock_bh(efx->net_dev); + netif_tx_lock_bh(efx->net_dev); rc = efx_enqueue_skb(tx_queue, skb); - if (efx_dev_registered(efx)) - netif_tx_unlock_bh(efx->net_dev); + netif_tx_unlock_bh(efx->net_dev); if (rc != NETDEV_TX_OK) { netif_err(efx, drv, efx->net_dev, @@ -442,8 +440,7 @@ static int efx_end_loopback(struct efx_tx_queue *tx_queue, int tx_done = 0, rx_good, rx_bad; int i, rc = 0; - if (efx_dev_registered(efx)) - netif_tx_lock_bh(efx->net_dev); + netif_tx_lock_bh(efx->net_dev); /* Count the number of tx completions, and decrement the refcnt. Any * skbs not already completed will be free'd when the queue is flushed */ @@ -454,8 +451,7 @@ static int efx_end_loopback(struct efx_tx_queue *tx_queue, dev_kfree_skb_any(skb); } - if (efx_dev_registered(efx)) - netif_tx_unlock_bh(efx->net_dev); + netif_tx_unlock_bh(efx->net_dev); /* Check TX completion and received packet counts */ rx_good = atomic_read(&state->rx_good); diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c index 72f0fbc73b1..5cb81fa3fcb 100644 --- a/drivers/net/ethernet/sfc/tx.c +++ b/drivers/net/ethernet/sfc/tx.c @@ -446,10 +446,8 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) likely(efx->port_enabled) && likely(netif_device_present(efx->net_dev))) { fill_level = tx_queue->insert_count - tx_queue->read_count; - if (fill_level < EFX_TXQ_THRESHOLD(efx)) { - EFX_BUG_ON_PARANOID(!efx_dev_registered(efx)); + if (fill_level < EFX_TXQ_THRESHOLD(efx)) netif_tx_wake_queue(tx_queue->core_txq); - } } /* Check whether the hardware queue is now empty */ -- cgit v1.2.3-70-g09d2 From 86ee53020abe4eb9c85e612129e3848ee98302fd Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 9 Jan 2012 19:51:22 +0000 Subject: sfc: Use existing local variables instead of repeated indirect lookups Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 4f412fe22e8..c8e1c8a93ed 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -364,7 +364,7 @@ static int efx_probe_eventq(struct efx_channel *channel) struct efx_nic *efx = channel->efx; unsigned long entries; - netif_dbg(channel->efx, probe, channel->efx->net_dev, + netif_dbg(efx, probe, efx->net_dev, "chan %d create event queue\n", channel->channel); /* Build an event queue with room for one event per tx and rx buffer, @@ -1971,7 +1971,7 @@ static int efx_register_netdev(struct efx_nic *efx) } /* Always start with carrier off; PHY events will detect the link */ - netif_carrier_off(efx->net_dev); + netif_carrier_off(net_dev); rtnl_unlock(); -- cgit v1.2.3-70-g09d2 From 2aa9ef11e70c47ed26f831798f02ad3794e5ad41 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 9 Jan 2012 19:53:41 +0000 Subject: sfc: Minor formatting fixes Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index c8e1c8a93ed..8ecddd05667 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -798,16 +798,14 @@ void efx_link_status_changed(struct efx_nic *efx) } /* Status message for kernel log */ - if (link_state->up) { + if (link_state->up) netif_info(efx, link, efx->net_dev, "link up at %uMbps %s-duplex (MTU %d)%s\n", link_state->speed, link_state->fd ? "full" : "half", efx->net_dev->mtu, (efx->promiscuous ? " [PROMISC]" : "")); - } else { + else netif_info(efx, link, efx->net_dev, "link down\n"); - } - } void efx_link_set_advertising(struct efx_nic *efx, u32 advertising) @@ -1741,7 +1739,8 @@ static int efx_net_stop(struct net_device *net_dev) } /* Context: process, dev_base_lock or RTNL held, non-blocking. */ -static struct rtnl_link_stats64 *efx_net_stats(struct net_device *net_dev, struct rtnl_link_stats64 *stats) +static struct rtnl_link_stats64 *efx_net_stats(struct net_device *net_dev, + struct rtnl_link_stats64 *stats) { struct efx_nic *efx = netdev_priv(net_dev); struct efx_mac_stats *mac_stats = &efx->mac_stats; -- cgit v1.2.3-70-g09d2 From 6c8eef4ac8dfd888be5b46e363f8e42b9f0d5b6a Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 9 Jan 2012 19:54:16 +0000 Subject: sfc: Remove redundant 'rc' variable, always set to 0 Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 8ecddd05667..fce42f428c6 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -1793,7 +1793,6 @@ static void efx_watchdog(struct net_device *net_dev) static int efx_change_mtu(struct net_device *net_dev, int new_mtu) { struct efx_nic *efx = netdev_priv(net_dev); - int rc = 0; EFX_ASSERT_RESET_SERIALISED(efx); @@ -1816,7 +1815,7 @@ static int efx_change_mtu(struct net_device *net_dev, int new_mtu) efx_init_channels(efx); efx_start_all(efx); - return rc; + return 0; } static int efx_set_mac_address(struct net_device *net_dev, void *data) -- cgit v1.2.3-70-g09d2 From 0fca8c97612f90a68ff6e1873e674b4d69a435db Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 9 Jan 2012 19:54:44 +0000 Subject: sfc: Rename implementation of ndo_set_rx_mode Rename efx_set_multicast_list() to efx_set_rx_mode(), in line with the operation name net_device_ops::ndo_set_rx_mode. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index fce42f428c6..a352c55cb54 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -852,7 +852,7 @@ int __efx_reconfigure_port(struct efx_nic *efx) WARN_ON(!mutex_is_locked(&efx->mac_lock)); - /* Serialise the promiscuous flag with efx_set_multicast_list. */ + /* Serialise the promiscuous flag with efx_set_rx_mode. */ netif_addr_lock_bh(efx->net_dev); netif_addr_unlock_bh(efx->net_dev); @@ -1844,7 +1844,7 @@ static int efx_set_mac_address(struct net_device *net_dev, void *data) } /* Context: netif_addr_lock held, BHs disabled. */ -static void efx_set_multicast_list(struct net_device *net_dev) +static void efx_set_rx_mode(struct net_device *net_dev) { struct efx_nic *efx = netdev_priv(net_dev); struct netdev_hw_addr *ha; @@ -1898,7 +1898,7 @@ static const struct net_device_ops efx_netdev_ops = { .ndo_do_ioctl = efx_ioctl, .ndo_change_mtu = efx_change_mtu, .ndo_set_mac_address = efx_set_mac_address, - .ndo_set_rx_mode = efx_set_multicast_list, + .ndo_set_rx_mode = efx_set_rx_mode, .ndo_set_features = efx_set_features, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = efx_netpoll, -- cgit v1.2.3-70-g09d2 From f9c762500ae77ab8940094be1325c8a2a1c8e5f5 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 12 Oct 2011 17:20:25 +0100 Subject: sfc: Make all MAC statistics consistently 64 bits wide Currently we use type u64 for byte counts, which can very quickly exceed 2^32, and unsigned long for packet counts, which do not. But it can still take only 20-something minutes to send or receive 2^32 packets, and not all tools properly handle overflow even if they sample more often than this. The MAC statistics are all updated synchronously, so it costs very little to make them all 64-bit regardless of native word size. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/ethtool.c | 117 ++++++++++++++++------------------ drivers/net/ethernet/sfc/net_driver.h | 110 ++++++++++++++++---------------- 2 files changed, 109 insertions(+), 118 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index ba901167801..f887f65e418 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c @@ -52,11 +52,6 @@ static u64 efx_get_uint_stat(void *field) return *(unsigned int *)field; } -static u64 efx_get_ulong_stat(void *field) -{ - return *(unsigned long *)field; -} - static u64 efx_get_u64_stat(void *field) { return *(u64 *) field; @@ -67,10 +62,6 @@ static u64 efx_get_atomic_stat(void *field) return atomic_read((atomic_t *) field); } -#define EFX_ETHTOOL_ULONG_MAC_STAT(field) \ - EFX_ETHTOOL_STAT(field, mac_stats, field, \ - unsigned long, efx_get_ulong_stat) - #define EFX_ETHTOOL_U64_MAC_STAT(field) \ EFX_ETHTOOL_STAT(field, mac_stats, field, \ u64, efx_get_u64_stat) @@ -95,32 +86,32 @@ static const struct efx_ethtool_stat efx_ethtool_stats[] = { EFX_ETHTOOL_U64_MAC_STAT(tx_bytes), EFX_ETHTOOL_U64_MAC_STAT(tx_good_bytes), EFX_ETHTOOL_U64_MAC_STAT(tx_bad_bytes), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_packets), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_bad), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_pause), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_control), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_unicast), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_multicast), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_broadcast), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_lt64), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_64), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_65_to_127), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_128_to_255), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_256_to_511), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_512_to_1023), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_1024_to_15xx), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_15xx_to_jumbo), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_gtjumbo), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_collision), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_single_collision), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_multiple_collision), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_excessive_collision), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_deferred), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_late_collision), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_excessive_deferred), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_non_tcpudp), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_mac_src_error), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_ip_src_error), + EFX_ETHTOOL_U64_MAC_STAT(tx_packets), + EFX_ETHTOOL_U64_MAC_STAT(tx_bad), + EFX_ETHTOOL_U64_MAC_STAT(tx_pause), + EFX_ETHTOOL_U64_MAC_STAT(tx_control), + EFX_ETHTOOL_U64_MAC_STAT(tx_unicast), + EFX_ETHTOOL_U64_MAC_STAT(tx_multicast), + EFX_ETHTOOL_U64_MAC_STAT(tx_broadcast), + EFX_ETHTOOL_U64_MAC_STAT(tx_lt64), + EFX_ETHTOOL_U64_MAC_STAT(tx_64), + EFX_ETHTOOL_U64_MAC_STAT(tx_65_to_127), + EFX_ETHTOOL_U64_MAC_STAT(tx_128_to_255), + EFX_ETHTOOL_U64_MAC_STAT(tx_256_to_511), + EFX_ETHTOOL_U64_MAC_STAT(tx_512_to_1023), + EFX_ETHTOOL_U64_MAC_STAT(tx_1024_to_15xx), + EFX_ETHTOOL_U64_MAC_STAT(tx_15xx_to_jumbo), + EFX_ETHTOOL_U64_MAC_STAT(tx_gtjumbo), + EFX_ETHTOOL_U64_MAC_STAT(tx_collision), + EFX_ETHTOOL_U64_MAC_STAT(tx_single_collision), + EFX_ETHTOOL_U64_MAC_STAT(tx_multiple_collision), + EFX_ETHTOOL_U64_MAC_STAT(tx_excessive_collision), + EFX_ETHTOOL_U64_MAC_STAT(tx_deferred), + EFX_ETHTOOL_U64_MAC_STAT(tx_late_collision), + EFX_ETHTOOL_U64_MAC_STAT(tx_excessive_deferred), + EFX_ETHTOOL_U64_MAC_STAT(tx_non_tcpudp), + EFX_ETHTOOL_U64_MAC_STAT(tx_mac_src_error), + EFX_ETHTOOL_U64_MAC_STAT(tx_ip_src_error), EFX_ETHTOOL_UINT_TXQ_STAT(tso_bursts), EFX_ETHTOOL_UINT_TXQ_STAT(tso_long_headers), EFX_ETHTOOL_UINT_TXQ_STAT(tso_packets), @@ -128,34 +119,34 @@ static const struct efx_ethtool_stat efx_ethtool_stats[] = { EFX_ETHTOOL_U64_MAC_STAT(rx_bytes), EFX_ETHTOOL_U64_MAC_STAT(rx_good_bytes), EFX_ETHTOOL_U64_MAC_STAT(rx_bad_bytes), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_packets), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_good), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_pause), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_control), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_unicast), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_multicast), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_broadcast), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_lt64), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_64), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_65_to_127), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_128_to_255), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_256_to_511), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_512_to_1023), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_1024_to_15xx), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_15xx_to_jumbo), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_gtjumbo), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_lt64), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_64_to_15xx), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_15xx_to_jumbo), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_gtjumbo), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_overflow), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_missed), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_false_carrier), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_symbol_error), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_align_error), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_length_error), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_internal_error), + EFX_ETHTOOL_U64_MAC_STAT(rx_packets), + EFX_ETHTOOL_U64_MAC_STAT(rx_good), + EFX_ETHTOOL_U64_MAC_STAT(rx_bad), + EFX_ETHTOOL_U64_MAC_STAT(rx_pause), + EFX_ETHTOOL_U64_MAC_STAT(rx_control), + EFX_ETHTOOL_U64_MAC_STAT(rx_unicast), + EFX_ETHTOOL_U64_MAC_STAT(rx_multicast), + EFX_ETHTOOL_U64_MAC_STAT(rx_broadcast), + EFX_ETHTOOL_U64_MAC_STAT(rx_lt64), + EFX_ETHTOOL_U64_MAC_STAT(rx_64), + EFX_ETHTOOL_U64_MAC_STAT(rx_65_to_127), + EFX_ETHTOOL_U64_MAC_STAT(rx_128_to_255), + EFX_ETHTOOL_U64_MAC_STAT(rx_256_to_511), + EFX_ETHTOOL_U64_MAC_STAT(rx_512_to_1023), + EFX_ETHTOOL_U64_MAC_STAT(rx_1024_to_15xx), + EFX_ETHTOOL_U64_MAC_STAT(rx_15xx_to_jumbo), + EFX_ETHTOOL_U64_MAC_STAT(rx_gtjumbo), + EFX_ETHTOOL_U64_MAC_STAT(rx_bad_lt64), + EFX_ETHTOOL_U64_MAC_STAT(rx_bad_64_to_15xx), + EFX_ETHTOOL_U64_MAC_STAT(rx_bad_15xx_to_jumbo), + EFX_ETHTOOL_U64_MAC_STAT(rx_bad_gtjumbo), + EFX_ETHTOOL_U64_MAC_STAT(rx_overflow), + EFX_ETHTOOL_U64_MAC_STAT(rx_missed), + EFX_ETHTOOL_U64_MAC_STAT(rx_false_carrier), + EFX_ETHTOOL_U64_MAC_STAT(rx_symbol_error), + EFX_ETHTOOL_U64_MAC_STAT(rx_align_error), + EFX_ETHTOOL_U64_MAC_STAT(rx_length_error), + EFX_ETHTOOL_U64_MAC_STAT(rx_internal_error), EFX_ETHTOOL_UINT_NIC_STAT(rx_nodesc_drop_cnt), EFX_ETHTOOL_ATOMIC_NIC_ERROR_STAT(rx_reset), EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_tobe_disc), diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 310c50f0645..c20483efc22 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -538,64 +538,64 @@ struct efx_mac_stats { u64 tx_bytes; u64 tx_good_bytes; u64 tx_bad_bytes; - unsigned long tx_packets; - unsigned long tx_bad; - unsigned long tx_pause; - unsigned long tx_control; - unsigned long tx_unicast; - unsigned long tx_multicast; - unsigned long tx_broadcast; - unsigned long tx_lt64; - unsigned long tx_64; - unsigned long tx_65_to_127; - unsigned long tx_128_to_255; - unsigned long tx_256_to_511; - unsigned long tx_512_to_1023; - unsigned long tx_1024_to_15xx; - unsigned long tx_15xx_to_jumbo; - unsigned long tx_gtjumbo; - unsigned long tx_collision; - unsigned long tx_single_collision; - unsigned long tx_multiple_collision; - unsigned long tx_excessive_collision; - unsigned long tx_deferred; - unsigned long tx_late_collision; - unsigned long tx_excessive_deferred; - unsigned long tx_non_tcpudp; - unsigned long tx_mac_src_error; - unsigned long tx_ip_src_error; + u64 tx_packets; + u64 tx_bad; + u64 tx_pause; + u64 tx_control; + u64 tx_unicast; + u64 tx_multicast; + u64 tx_broadcast; + u64 tx_lt64; + u64 tx_64; + u64 tx_65_to_127; + u64 tx_128_to_255; + u64 tx_256_to_511; + u64 tx_512_to_1023; + u64 tx_1024_to_15xx; + u64 tx_15xx_to_jumbo; + u64 tx_gtjumbo; + u64 tx_collision; + u64 tx_single_collision; + u64 tx_multiple_collision; + u64 tx_excessive_collision; + u64 tx_deferred; + u64 tx_late_collision; + u64 tx_excessive_deferred; + u64 tx_non_tcpudp; + u64 tx_mac_src_error; + u64 tx_ip_src_error; u64 rx_bytes; u64 rx_good_bytes; u64 rx_bad_bytes; - unsigned long rx_packets; - unsigned long rx_good; - unsigned long rx_bad; - unsigned long rx_pause; - unsigned long rx_control; - unsigned long rx_unicast; - unsigned long rx_multicast; - unsigned long rx_broadcast; - unsigned long rx_lt64; - unsigned long rx_64; - unsigned long rx_65_to_127; - unsigned long rx_128_to_255; - unsigned long rx_256_to_511; - unsigned long rx_512_to_1023; - unsigned long rx_1024_to_15xx; - unsigned long rx_15xx_to_jumbo; - unsigned long rx_gtjumbo; - unsigned long rx_bad_lt64; - unsigned long rx_bad_64_to_15xx; - unsigned long rx_bad_15xx_to_jumbo; - unsigned long rx_bad_gtjumbo; - unsigned long rx_overflow; - unsigned long rx_missed; - unsigned long rx_false_carrier; - unsigned long rx_symbol_error; - unsigned long rx_align_error; - unsigned long rx_length_error; - unsigned long rx_internal_error; - unsigned long rx_good_lt64; + u64 rx_packets; + u64 rx_good; + u64 rx_bad; + u64 rx_pause; + u64 rx_control; + u64 rx_unicast; + u64 rx_multicast; + u64 rx_broadcast; + u64 rx_lt64; + u64 rx_64; + u64 rx_65_to_127; + u64 rx_128_to_255; + u64 rx_256_to_511; + u64 rx_512_to_1023; + u64 rx_1024_to_15xx; + u64 rx_15xx_to_jumbo; + u64 rx_gtjumbo; + u64 rx_bad_lt64; + u64 rx_bad_64_to_15xx; + u64 rx_bad_15xx_to_jumbo; + u64 rx_bad_gtjumbo; + u64 rx_overflow; + u64 rx_missed; + u64 rx_false_carrier; + u64 rx_symbol_error; + u64 rx_align_error; + u64 rx_length_error; + u64 rx_internal_error; + u64 rx_good_lt64; }; /* Number of bits used in a multicast filter hash address */ -- cgit v1.2.3-70-g09d2 From 1ddceb4c69463e09b6929c750046c59589d45d82 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 23 Jan 2012 22:41:30 +0000 Subject: sfc: Move the end of the non-GRO RX path into its own function Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/rx.c | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index 3572c34a79f..d97c6ebcf06 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -568,12 +568,30 @@ out: channel->rx_pkt_csummed = checksummed; } +static void efx_rx_deliver(struct efx_channel *channel, + struct efx_rx_buffer *rx_buf) +{ + struct sk_buff *skb; + + /* We now own the SKB */ + skb = rx_buf->u.skb; + rx_buf->u.skb = NULL; + + /* Set the SKB flags */ + skb_checksum_none_assert(skb); + + /* Pass the packet up */ + netif_receive_skb(skb); + + /* Update allocation strategy method */ + channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB; +} + /* Handle a received packet. Second half: Touches packet payload. */ void __efx_rx_packet(struct efx_channel *channel, struct efx_rx_buffer *rx_buf, bool checksummed) { struct efx_nic *efx = channel->efx; - struct sk_buff *skb; u8 *eh = efx_rx_buf_eh(efx, rx_buf); /* If we're in loopback test, then pass the packet directly to the @@ -586,7 +604,7 @@ void __efx_rx_packet(struct efx_channel *channel, } if (!rx_buf->is_page) { - skb = rx_buf->u.skb; + struct sk_buff *skb = rx_buf->u.skb; prefetch(skb_shinfo(skb)); @@ -606,23 +624,10 @@ void __efx_rx_packet(struct efx_channel *channel, if (unlikely(!(efx->net_dev->features & NETIF_F_RXCSUM))) checksummed = false; - if (likely(checksummed || rx_buf->is_page)) { + if (likely(checksummed || rx_buf->is_page)) efx_rx_packet_gro(channel, rx_buf, eh, checksummed); - return; - } - - /* We now own the SKB */ - skb = rx_buf->u.skb; - rx_buf->u.skb = NULL; - - /* Set the SKB flags */ - skb_checksum_none_assert(skb); - - /* Pass the packet up */ - netif_receive_skb(skb); - - /* Update allocation strategy method */ - channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB; + else + efx_rx_deliver(channel, rx_buf); } void efx_rx_strategy(struct efx_channel *channel) -- cgit v1.2.3-70-g09d2 From db3395697cad6e9dff8d21249e0b59dc9bb83b48 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 26 Aug 2011 18:05:11 +0100 Subject: sfc: Replace efx_rx_buffer::is_page and other booleans with a flags field Replace checksummed and discard booleans from efx_handle_rx_event() with a bitmask, added to the flags field. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 3 +- drivers/net/ethernet/sfc/efx.h | 4 +-- drivers/net/ethernet/sfc/net_driver.h | 16 +++++---- drivers/net/ethernet/sfc/nic.c | 32 ++++++++--------- drivers/net/ethernet/sfc/rx.c | 65 +++++++++++++++++------------------ 5 files changed, 59 insertions(+), 61 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index a352c55cb54..952d0bf7695 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -229,8 +229,7 @@ static int efx_process_channel(struct efx_channel *channel, int budget) /* Deliver last RX packet. */ if (channel->rx_pkt) { - __efx_rx_packet(channel, channel->rx_pkt, - channel->rx_pkt_csummed); + __efx_rx_packet(channel, channel->rx_pkt); channel->rx_pkt = NULL; } diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h index e0b66d158d7..7f546e2c39e 100644 --- a/drivers/net/ethernet/sfc/efx.h +++ b/drivers/net/ethernet/sfc/efx.h @@ -40,9 +40,9 @@ extern void efx_rx_strategy(struct efx_channel *channel); extern void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue); extern void efx_rx_slow_fill(unsigned long context); extern void __efx_rx_packet(struct efx_channel *channel, - struct efx_rx_buffer *rx_buf, bool checksummed); + struct efx_rx_buffer *rx_buf); extern void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, - unsigned int len, bool checksummed, bool discard); + unsigned int len, u16 flags); extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue); #define EFX_MAX_DMAQ_SIZE 4096UL diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index c20483efc22..53864014c2b 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -205,12 +205,12 @@ struct efx_tx_queue { /** * struct efx_rx_buffer - An Efx RX data buffer * @dma_addr: DMA base address of the buffer - * @skb: The associated socket buffer, if any. - * If both this and page are %NULL, the buffer slot is currently free. - * @page: The associated page buffer, if any. - * If both this and skb are %NULL, the buffer slot is currently free. + * @skb: The associated socket buffer. Valid iff !(@flags & %EFX_RX_BUF_PAGE). + * 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. * @len: Buffer length, in bytes. - * @is_page: Indicates if @page is valid. If false, @skb is valid. + * @flags: Flags for buffer and packet state. */ struct efx_rx_buffer { dma_addr_t dma_addr; @@ -219,8 +219,11 @@ struct efx_rx_buffer { struct page *page; } u; unsigned int len; - bool is_page; + u16 flags; }; +#define EFX_RX_BUF_PAGE 0x0001 +#define EFX_RX_PKT_CSUMMED 0x0002 +#define EFX_RX_PKT_DISCARD 0x0004 /** * struct efx_rx_page_state - Page-based rx buffer state @@ -378,7 +381,6 @@ struct efx_channel { * access with prefetches. */ struct efx_rx_buffer *rx_pkt; - bool rx_pkt_csummed; struct efx_rx_queue rx_queue; struct efx_tx_queue tx_queue[EFX_TXQ_TYPES]; diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c index cd250f197b3..a43d1ca270c 100644 --- a/drivers/net/ethernet/sfc/nic.c +++ b/drivers/net/ethernet/sfc/nic.c @@ -743,10 +743,8 @@ efx_handle_tx_event(struct efx_channel *channel, efx_qword_t *event) } /* Detect errors included in the rx_evt_pkt_ok bit. */ -static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue, - const efx_qword_t *event, - bool *rx_ev_pkt_ok, - bool *discard) +static u16 efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue, + const efx_qword_t *event) { struct efx_channel *channel = efx_rx_queue_channel(rx_queue); struct efx_nic *efx = rx_queue->efx; @@ -791,10 +789,6 @@ static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue, ++channel->n_rx_tcp_udp_chksum_err; } - /* The frame must be discarded if any of these are true. */ - *discard = (rx_ev_eth_crc_err | rx_ev_frm_trunc | rx_ev_drib_nib | - rx_ev_tobe_disc | rx_ev_pause_frm); - /* TOBE_DISC is expected on unicast mismatches; don't print out an * error message. FRM_TRUNC indicates RXDP dropped the packet due * to a FIFO overflow. @@ -817,6 +811,11 @@ static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue, rx_ev_pause_frm ? " [PAUSE]" : ""); } #endif + + /* The frame must be discarded if any of these are true. */ + return (rx_ev_eth_crc_err | rx_ev_frm_trunc | rx_ev_drib_nib | + rx_ev_tobe_disc | rx_ev_pause_frm) ? + EFX_RX_PKT_DISCARD : 0; } /* Handle receive events that are not in-order. */ @@ -849,7 +848,8 @@ efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event) unsigned int rx_ev_desc_ptr, rx_ev_byte_cnt; unsigned int rx_ev_hdr_type, rx_ev_mcast_pkt; unsigned expected_ptr; - bool rx_ev_pkt_ok, discard = false, checksummed; + bool rx_ev_pkt_ok; + u16 flags; struct efx_rx_queue *rx_queue; /* Basic packet information */ @@ -872,12 +872,11 @@ efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event) /* If packet is marked as OK and packet type is TCP/IP or * UDP/IP, then we can rely on the hardware checksum. */ - checksummed = - rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_TCP || - rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_UDP; + flags = (rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_TCP || + rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_UDP) ? + EFX_RX_PKT_CSUMMED : 0; } else { - efx_handle_rx_not_ok(rx_queue, event, &rx_ev_pkt_ok, &discard); - checksummed = false; + flags = efx_handle_rx_not_ok(rx_queue, event); } /* Detect multicast packets that didn't match the filter */ @@ -888,15 +887,14 @@ efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event) if (unlikely(!rx_ev_mcast_hash_match)) { ++channel->n_rx_mcast_mismatch; - discard = true; + flags |= EFX_RX_PKT_DISCARD; } } channel->irq_mod_score += 2; /* Handle received packet */ - efx_rx_packet(rx_queue, rx_ev_desc_ptr, rx_ev_byte_cnt, - checksummed, discard); + efx_rx_packet(rx_queue, rx_ev_desc_ptr, rx_ev_byte_cnt, flags); } static void diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index d97c6ebcf06..a33aef25ead 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -108,7 +108,7 @@ static inline unsigned int efx_rx_buf_size(struct efx_nic *efx) static u8 *efx_rx_buf_eh(struct efx_nic *efx, struct efx_rx_buffer *buf) { - if (buf->is_page) + if (buf->flags & EFX_RX_BUF_PAGE) return page_address(buf->u.page) + efx_rx_buf_offset(efx, buf); else return (u8 *)buf->u.skb->data + efx->type->rx_buffer_hash_size; @@ -158,7 +158,7 @@ static int efx_init_rx_buffers_skb(struct efx_rx_queue *rx_queue) /* Adjust the SKB for padding and checksum */ skb_reserve(skb, NET_IP_ALIGN); rx_buf->len = skb_len - NET_IP_ALIGN; - rx_buf->is_page = false; + rx_buf->flags = 0; skb->ip_summed = CHECKSUM_UNNECESSARY; rx_buf->dma_addr = pci_map_single(efx->pci_dev, @@ -227,7 +227,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue) rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN; rx_buf->u.page = page; rx_buf->len = efx->rx_buffer_len - EFX_PAGE_IP_ALIGN; - rx_buf->is_page = true; + rx_buf->flags = EFX_RX_BUF_PAGE; ++rx_queue->added_count; ++rx_queue->alloc_page_count; ++state->refcnt; @@ -248,7 +248,7 @@ 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) { - if (rx_buf->is_page && rx_buf->u.page) { + if ((rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.page) { struct efx_rx_page_state *state; state = page_address(rx_buf->u.page); @@ -258,7 +258,7 @@ static void efx_unmap_rx_buffer(struct efx_nic *efx, efx_rx_buf_size(efx), PCI_DMA_FROMDEVICE); } - } else if (!rx_buf->is_page && rx_buf->u.skb) { + } else if (!(rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.skb) { pci_unmap_single(efx->pci_dev, rx_buf->dma_addr, rx_buf->len, PCI_DMA_FROMDEVICE); } @@ -267,10 +267,10 @@ static void efx_unmap_rx_buffer(struct efx_nic *efx, static void efx_free_rx_buffer(struct efx_nic *efx, struct efx_rx_buffer *rx_buf) { - if (rx_buf->is_page && rx_buf->u.page) { + if ((rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.page) { __free_pages(rx_buf->u.page, efx->rx_buffer_order); rx_buf->u.page = NULL; - } else if (!rx_buf->is_page && rx_buf->u.skb) { + } else if (!(rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.skb) { dev_kfree_skb_any(rx_buf->u.skb); rx_buf->u.skb = NULL; } @@ -310,7 +310,7 @@ static void efx_resurrect_rx_buffer(struct efx_rx_queue *rx_queue, new_buf->dma_addr = rx_buf->dma_addr ^ (PAGE_SIZE >> 1); new_buf->u.page = rx_buf->u.page; new_buf->len = rx_buf->len; - new_buf->is_page = true; + new_buf->flags = EFX_RX_BUF_PAGE; ++rx_queue->added_count; } @@ -324,7 +324,10 @@ static void efx_recycle_rx_buffer(struct efx_channel *channel, struct efx_rx_buffer *new_buf; unsigned index; - if (rx_buf->is_page && efx->rx_buffer_len <= EFX_RX_HALF_PAGE && + rx_buf->flags &= EFX_RX_BUF_PAGE; + + if ((rx_buf->flags & EFX_RX_BUF_PAGE) && + efx->rx_buffer_len <= EFX_RX_HALF_PAGE && page_count(rx_buf->u.page) == 1) efx_resurrect_rx_buffer(rx_queue, rx_buf); @@ -411,8 +414,7 @@ void efx_rx_slow_fill(unsigned long context) static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue, struct efx_rx_buffer *rx_buf, - int len, bool *discard, - bool *leak_packet) + int len, bool *leak_packet) { struct efx_nic *efx = rx_queue->efx; unsigned max_len = rx_buf->len - efx->type->rx_buffer_padding; @@ -423,7 +425,7 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue, /* The packet must be discarded, but this is only a fatal error * if the caller indicated it was */ - *discard = true; + rx_buf->flags |= EFX_RX_PKT_DISCARD; if ((len > rx_buf->len) && EFX_WORKAROUND_8071(efx)) { if (net_ratelimit()) @@ -436,7 +438,7 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue, * data at the end of the skb will be trashed. So * we have no choice but to leak the fragment. */ - *leak_packet = !rx_buf->is_page; + *leak_packet = !(rx_buf->flags & EFX_RX_BUF_PAGE); efx_schedule_reset(efx, RESET_TYPE_RX_RECOVERY); } else { if (net_ratelimit()) @@ -456,13 +458,13 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue, */ static void efx_rx_packet_gro(struct efx_channel *channel, struct efx_rx_buffer *rx_buf, - const u8 *eh, bool checksummed) + const u8 *eh) { struct napi_struct *napi = &channel->napi_str; gro_result_t gro_result; /* Pass the skb/page into the GRO engine */ - if (rx_buf->is_page) { + if (rx_buf->flags & EFX_RX_BUF_PAGE) { struct efx_nic *efx = channel->efx; struct page *page = rx_buf->u.page; struct sk_buff *skb; @@ -484,8 +486,8 @@ static void efx_rx_packet_gro(struct efx_channel *channel, skb->len = rx_buf->len; skb->data_len = rx_buf->len; skb->truesize += rx_buf->len; - skb->ip_summed = - checksummed ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE; + skb->ip_summed = ((rx_buf->flags & EFX_RX_PKT_CSUMMED) ? + CHECKSUM_UNNECESSARY : CHECKSUM_NONE); skb_record_rx_queue(skb, channel->channel); @@ -493,7 +495,7 @@ static void efx_rx_packet_gro(struct efx_channel *channel, } else { struct sk_buff *skb = rx_buf->u.skb; - EFX_BUG_ON_PARANOID(!checksummed); + EFX_BUG_ON_PARANOID(!(rx_buf->flags & EFX_RX_PKT_CSUMMED)); rx_buf->u.skb = NULL; gro_result = napi_gro_receive(napi, skb); @@ -508,7 +510,7 @@ static void efx_rx_packet_gro(struct efx_channel *channel, } void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, - unsigned int len, bool checksummed, bool discard) + unsigned int len, u16 flags) { struct efx_nic *efx = rx_queue->efx; struct efx_channel *channel = efx_rx_queue_channel(rx_queue); @@ -516,6 +518,7 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, bool leak_packet = false; rx_buf = efx_rx_buffer(rx_queue, index); + rx_buf->flags |= flags; /* This allows the refill path to post another buffer. * EFX_RXD_HEAD_ROOM ensures that the slot we are using @@ -524,18 +527,17 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, rx_queue->removed_count++; /* Validate the length encoded in the event vs the descriptor pushed */ - efx_rx_packet__check_len(rx_queue, rx_buf, len, - &discard, &leak_packet); + efx_rx_packet__check_len(rx_queue, rx_buf, len, &leak_packet); netif_vdbg(efx, rx_status, efx->net_dev, "RX queue %d received id %x at %llx+%x %s%s\n", efx_rx_queue_index(rx_queue), index, (unsigned long long)rx_buf->dma_addr, len, - (checksummed ? " [SUMMED]" : ""), - (discard ? " [DISCARD]" : "")); + (rx_buf->flags & EFX_RX_PKT_CSUMMED) ? " [SUMMED]" : "", + (rx_buf->flags & EFX_RX_PKT_DISCARD) ? " [DISCARD]" : ""); /* Discard packet, if instructed to do so */ - if (unlikely(discard)) { + if (unlikely(rx_buf->flags & EFX_RX_PKT_DISCARD)) { if (unlikely(leak_packet)) channel->n_skbuff_leaks++; else @@ -562,10 +564,8 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, rx_buf->len = len - efx->type->rx_buffer_hash_size; out: if (channel->rx_pkt) - __efx_rx_packet(channel, - channel->rx_pkt, channel->rx_pkt_csummed); + __efx_rx_packet(channel, channel->rx_pkt); channel->rx_pkt = rx_buf; - channel->rx_pkt_csummed = checksummed; } static void efx_rx_deliver(struct efx_channel *channel, @@ -588,8 +588,7 @@ static void efx_rx_deliver(struct efx_channel *channel, } /* Handle a received packet. Second half: Touches packet payload. */ -void __efx_rx_packet(struct efx_channel *channel, - struct efx_rx_buffer *rx_buf, bool checksummed) +void __efx_rx_packet(struct efx_channel *channel, struct efx_rx_buffer *rx_buf) { struct efx_nic *efx = channel->efx; u8 *eh = efx_rx_buf_eh(efx, rx_buf); @@ -603,7 +602,7 @@ void __efx_rx_packet(struct efx_channel *channel, return; } - if (!rx_buf->is_page) { + if (!(rx_buf->flags & EFX_RX_BUF_PAGE)) { struct sk_buff *skb = rx_buf->u.skb; prefetch(skb_shinfo(skb)); @@ -622,10 +621,10 @@ void __efx_rx_packet(struct efx_channel *channel, } if (unlikely(!(efx->net_dev->features & NETIF_F_RXCSUM))) - checksummed = false; + rx_buf->flags &= ~EFX_RX_PKT_CSUMMED; - if (likely(checksummed || rx_buf->is_page)) - efx_rx_packet_gro(channel, rx_buf, eh, checksummed); + if (likely(rx_buf->flags & (EFX_RX_BUF_PAGE | EFX_RX_PKT_CSUMMED))) + efx_rx_packet_gro(channel, rx_buf, eh); else efx_rx_deliver(channel, rx_buf); } -- cgit v1.2.3-70-g09d2 From 3bd391f056df61e928de1680ff4a3e7e07e5b399 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 26 Jan 2012 00:09:06 +0100 Subject: crypto: Add support for x86 cpuid auto loading for x86 crypto drivers Add support for auto-loading of crypto drivers based on cpuid features. This enables auto-loading of the VIA and Intel specific drivers for AES, hashing and CRCs. Requires the earlier infrastructure patch to add x86 modinfo. I kept it all in a single patch for now. I dropped the printks when the driver cpuid doesn't match (imho drivers never should print anything in such a case) One drawback is that udev doesn't know if the drivers are used or not, so they will be unconditionally loaded at boot up. That's better than not loading them at all, like it often happens. Cc: Dave Jones Cc: Kay Sievers Cc: Jen Axboe Cc: Herbert Xu Cc: Huang Ying Signed-off-by: Andi Kleen Signed-off-by: Thomas Renninger Acked-by: H. Peter Anvin Signed-off-by: Greg Kroah-Hartman --- arch/x86/crypto/aesni-intel_glue.c | 12 +++++++++--- arch/x86/crypto/crc32c-intel.c | 11 ++++++++--- arch/x86/crypto/ghash-clmulni-intel_glue.c | 12 ++++++++---- drivers/crypto/padlock-aes.c | 9 ++++++++- drivers/crypto/padlock-sha.c | 16 ++++++++-------- 5 files changed, 41 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c index 545d0ce5981..b3350bd32c6 100644 --- a/arch/x86/crypto/aesni-intel_glue.c +++ b/arch/x86/crypto/aesni-intel_glue.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -1253,14 +1254,19 @@ static struct crypto_alg __rfc4106_alg = { }; #endif + +static const struct x86_cpu_id aesni_cpu_id[] = { + X86_FEATURE_MATCH(X86_FEATURE_AES), + {} +}; +MODULE_DEVICE_TABLE(x86cpu, aesni_cpu_id); + static int __init aesni_init(void) { int err; - if (!cpu_has_aes) { - printk(KERN_INFO "Intel AES-NI instructions are not detected.\n"); + if (!x86_match_cpu(aesni_cpu_id)) return -ENODEV; - } if ((err = crypto_fpu_init())) goto fpu_err; diff --git a/arch/x86/crypto/crc32c-intel.c b/arch/x86/crypto/crc32c-intel.c index b9d00261703..493f959261f 100644 --- a/arch/x86/crypto/crc32c-intel.c +++ b/arch/x86/crypto/crc32c-intel.c @@ -31,6 +31,7 @@ #include #include +#include #define CHKSUM_BLOCK_SIZE 1 #define CHKSUM_DIGEST_SIZE 4 @@ -173,13 +174,17 @@ static struct shash_alg alg = { } }; +static const struct x86_cpu_id crc32c_cpu_id[] = { + X86_FEATURE_MATCH(X86_FEATURE_XMM4_2), + {} +}; +MODULE_DEVICE_TABLE(x86cpu, crc32c_cpu_id); static int __init crc32c_intel_mod_init(void) { - if (cpu_has_xmm4_2) - return crypto_register_shash(&alg); - else + if (!x86_match_cpu(crc32c_cpu_id)) return -ENODEV; + return crypto_register_shash(&alg); } static void __exit crc32c_intel_mod_fini(void) diff --git a/arch/x86/crypto/ghash-clmulni-intel_glue.c b/arch/x86/crypto/ghash-clmulni-intel_glue.c index 976aa64d9a2..b4bf0a63b52 100644 --- a/arch/x86/crypto/ghash-clmulni-intel_glue.c +++ b/arch/x86/crypto/ghash-clmulni-intel_glue.c @@ -20,6 +20,7 @@ #include #include #include +#include #define GHASH_BLOCK_SIZE 16 #define GHASH_DIGEST_SIZE 16 @@ -294,15 +295,18 @@ static struct ahash_alg ghash_async_alg = { }, }; +static const struct x86_cpu_id pcmul_cpu_id[] = { + X86_FEATURE_MATCH(X86_FEATURE_PCLMULQDQ), /* Pickle-Mickle-Duck */ + {} +}; +MODULE_DEVICE_TABLE(x86cpu, pcmul_cpu_id); + static int __init ghash_pclmulqdqni_mod_init(void) { int err; - if (!cpu_has_pclmulqdq) { - printk(KERN_INFO "Intel PCLMULQDQ-NI instructions are not" - " detected.\n"); + if (!x86_match_cpu(pcmul_cpu_id)) return -ENODEV; - } err = crypto_register_shash(&ghash_alg); if (err) diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index 29b9469f837..37b2e9406af 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -503,12 +504,18 @@ static struct crypto_alg cbc_aes_alg = { } }; +static struct x86_cpu_id padlock_cpu_id[] = { + X86_FEATURE_MATCH(X86_FEATURE_XCRYPT), + {} +}; +MODULE_DEVICE_TABLE(x86cpu, padlock_cpu_id); + static int __init padlock_init(void) { int ret; struct cpuinfo_x86 *c = &cpu_data(0); - if (!cpu_has_xcrypt) + if (!x86_match_cpu(padlock_cpu_id)) return -ENODEV; if (!cpu_has_xcrypt_enabled) { diff --git a/drivers/crypto/padlock-sha.c b/drivers/crypto/padlock-sha.c index 06bdb4b2c6a..9266c0e2549 100644 --- a/drivers/crypto/padlock-sha.c +++ b/drivers/crypto/padlock-sha.c @@ -22,6 +22,7 @@ #include #include #include +#include #include struct padlock_sha_desc { @@ -526,6 +527,12 @@ static struct shash_alg sha256_alg_nano = { } }; +static struct x86_cpu_id padlock_sha_ids[] = { + X86_FEATURE_MATCH(X86_FEATURE_PHE), + {} +}; +MODULE_DEVICE_TABLE(x86cpu, padlock_sha_ids); + static int __init padlock_init(void) { int rc = -ENODEV; @@ -533,15 +540,8 @@ static int __init padlock_init(void) struct shash_alg *sha1; struct shash_alg *sha256; - if (!cpu_has_phe) { - printk(KERN_NOTICE PFX "VIA PadLock Hash Engine not detected.\n"); - return -ENODEV; - } - - if (!cpu_has_phe_enabled) { - printk(KERN_NOTICE PFX "VIA PadLock detected, but not enabled. Hmm, strange...\n"); + if (!x86_match_cpu(padlock_sha_ids) || !cpu_has_phe_enabled) return -ENODEV; - } /* Register the newly added algorithm module if on * * VIA Nano processor, or else just do as before */ -- cgit v1.2.3-70-g09d2 From b66b8b9a4a79087dde1b358a016e5c8739ccf186 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 26 Jan 2012 00:09:07 +0100 Subject: intel-idle: convert to x86_cpu_id auto probing With this it should be automatically loaded on suitable systems by udev. The old switch () is replaced with a table based approach, this also cleans up the code. Cc: Len Brown Signed-off-by: Andi Kleen Signed-off-by: Thomas Renninger Acked-by: H. Peter Anvin Signed-off-by: Greg Kroah-Hartman --- drivers/idle/intel_idle.c | 116 ++++++++++++++++++++++++++-------------------- 1 file changed, 66 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 20bce51c2e8..ef6a409ff1a 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include @@ -81,18 +82,23 @@ static unsigned int mwait_substates; /* Reliable LAPIC Timer States, bit 1 for C1 etc. */ static unsigned int lapic_timer_reliable_states = (1 << 1); /* Default to only C1 */ +struct idle_cpu { + struct cpuidle_state *state_table; + + /* + * Hardware C-state auto-demotion may not always be optimal. + * Indicate which enable bits to clear here. + */ + unsigned long auto_demotion_disable_flags; +}; + +static const struct idle_cpu *icpu; static struct cpuidle_device __percpu *intel_idle_cpuidle_devices; static int intel_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index); static struct cpuidle_state *cpuidle_state_table; -/* - * Hardware C-state auto-demotion may not always be optimal. - * Indicate which enable bits to clear here. - */ -static unsigned long long auto_demotion_disable_flags; - /* * Set this flag for states where the HW flushes the TLB for us * and so we don't need cross-calls to keep it consistent. @@ -319,27 +325,72 @@ static void auto_demotion_disable(void *dummy) unsigned long long msr_bits; rdmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits); - msr_bits &= ~auto_demotion_disable_flags; + msr_bits &= ~(icpu->auto_demotion_disable_flags); wrmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits); } +static const struct idle_cpu idle_cpu_nehalem = { + .state_table = nehalem_cstates, +}; + +static const struct idle_cpu idle_cpu_westmere = { + .state_table = nehalem_cstates, + .auto_demotion_disable_flags = NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE, +}; + +static const struct idle_cpu idle_cpu_atom = { + .state_table = atom_cstates, +}; + +static const struct idle_cpu idle_cpu_lincroft = { + .state_table = atom_cstates, + .auto_demotion_disable_flags = ATM_LNC_C6_AUTO_DEMOTE, +}; + +static const struct idle_cpu idle_cpu_snb = { + .state_table = snb_cstates, +}; + +#define ICPU(model, cpu) \ + { X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (unsigned long)&cpu } + +static const struct x86_cpu_id intel_idle_ids[] = { + ICPU(0x1a, idle_cpu_nehalem), + ICPU(0x1e, idle_cpu_nehalem), + ICPU(0x1f, idle_cpu_nehalem), + ICPU(0x25, idle_cpu_westmere), + ICPU(0x2c, idle_cpu_westmere), + ICPU(0x2f, idle_cpu_westmere), + ICPU(0x1c, idle_cpu_atom), + ICPU(0x26, idle_cpu_lincroft), + ICPU(0x2f, idle_cpu_westmere), + ICPU(0x2a, idle_cpu_snb), + ICPU(0x2d, idle_cpu_snb), + {} +}; +MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids); + /* * intel_idle_probe() */ static int intel_idle_probe(void) { unsigned int eax, ebx, ecx; + const struct x86_cpu_id *id; if (max_cstate == 0) { pr_debug(PREFIX "disabled\n"); return -EPERM; } - if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) - return -ENODEV; - - if (!boot_cpu_has(X86_FEATURE_MWAIT)) + id = x86_match_cpu(intel_idle_ids); + if (!id) { + if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && + boot_cpu_data.x86 == 6) + pr_debug(PREFIX "does not run on family %d model %d\n", + boot_cpu_data.x86, boot_cpu_data.x86_model); return -ENODEV; + } if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF) return -ENODEV; @@ -353,43 +404,8 @@ static int intel_idle_probe(void) pr_debug(PREFIX "MWAIT substates: 0x%x\n", mwait_substates); - - if (boot_cpu_data.x86 != 6) /* family 6 */ - return -ENODEV; - - switch (boot_cpu_data.x86_model) { - - case 0x1A: /* Core i7, Xeon 5500 series */ - case 0x1E: /* Core i7 and i5 Processor - Lynnfield Jasper Forest */ - case 0x1F: /* Core i7 and i5 Processor - Nehalem */ - case 0x2E: /* Nehalem-EX Xeon */ - case 0x2F: /* Westmere-EX Xeon */ - case 0x25: /* Westmere */ - case 0x2C: /* Westmere */ - cpuidle_state_table = nehalem_cstates; - auto_demotion_disable_flags = - (NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE); - break; - - case 0x1C: /* 28 - Atom Processor */ - cpuidle_state_table = atom_cstates; - break; - - case 0x26: /* 38 - Lincroft Atom Processor */ - cpuidle_state_table = atom_cstates; - auto_demotion_disable_flags = ATM_LNC_C6_AUTO_DEMOTE; - break; - - case 0x2A: /* SNB */ - case 0x2D: /* SNB Xeon */ - cpuidle_state_table = snb_cstates; - break; - - default: - pr_debug(PREFIX "does not run on family %d model %d\n", - boot_cpu_data.x86, boot_cpu_data.x86_model); - return -ENODEV; - } + icpu = (const struct idle_cpu *)id->driver_data; + cpuidle_state_table = icpu->state_table; if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */ lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE; @@ -470,7 +486,7 @@ static int intel_idle_cpuidle_driver_init(void) drv->state_count += 1; } - if (auto_demotion_disable_flags) + if (icpu->auto_demotion_disable_flags) on_each_cpu(auto_demotion_disable, NULL, 1); return 0; @@ -522,7 +538,7 @@ int intel_idle_cpu_init(int cpu) return -EIO; } - if (auto_demotion_disable_flags) + if (icpu->auto_demotion_disable_flags) smp_call_function_single(cpu, auto_demotion_disable, NULL, 1); return 0; -- cgit v1.2.3-70-g09d2 From 9061e0e16700ef228837e96987ff51794c956197 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 26 Jan 2012 00:09:08 +0100 Subject: ACPI: Load acpi-cpufreq from processor driver automatically The only left over hole in automatic cpufreq driver loading was the loading of ACPI cpufreq. This driver should be loaded when ACPI supports a _PDC method and the CPU vendor wants to use acpi cpufreq. Simply add a request module call to the acpi processor core driver when this is true. This seems like the simplest solution for this. Cc: Len Brown Signed-off-by: Andi Kleen Signed-off-by: Thomas Renninger Acked-by: H. Peter Anvin Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/processor_driver.c | 1 + drivers/acpi/processor_perflib.c | 22 ++++++++++++++++++++++ include/acpi/processor.h | 1 + 3 files changed, 24 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 0034ede3871..e6920d0aca5 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -497,6 +497,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) #ifdef CONFIG_CPU_FREQ acpi_processor_ppc_has_changed(pr, 0); + acpi_processor_load_module(pr); #endif acpi_processor_get_throttling_info(pr); acpi_processor_get_limit_info(pr); diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 85b32376dad..0af48a8554c 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -240,6 +240,28 @@ void acpi_processor_ppc_exit(void) acpi_processor_ppc_status &= ~PPC_REGISTERED; } +/* + * Do a quick check if the systems looks like it should use ACPI + * cpufreq. We look at a _PCT method being available, but don't + * do a whole lot of sanity checks. + */ +void acpi_processor_load_module(struct acpi_processor *pr) +{ + static int requested; + acpi_status status = 0; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + + if (!arch_has_acpi_pdc() || requested) + return; + status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer); + if (!ACPI_FAILURE(status)) { + printk(KERN_INFO PREFIX "Requesting acpi_cpufreq\n"); + request_module_nowait("acpi_cpufreq"); + requested = 1; + } + kfree(buffer.pointer); +} + static int acpi_processor_get_performance_control(struct acpi_processor *pr) { int result = 0; diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 610f6fb1bbc..da57fdcc57d 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -224,6 +224,7 @@ struct acpi_processor_errata { } piix4; }; +extern void acpi_processor_load_module(struct acpi_processor *pr); extern int acpi_processor_preregister_performance(struct acpi_processor_performance __percpu *performance); -- cgit v1.2.3-70-g09d2 From 267fc9788d0cdb77edafb506063f06961e1418f5 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 26 Jan 2012 00:09:09 +0100 Subject: HWMON: Convert via-cputemp to x86 cpuid autoprobing Use the new x86 cpuid autoprobe interface. Cc: Jean Delvare Cc: Guenter Roeck Signed-off-by: Andi Kleen Signed-off-by: Thomas Renninger Acked-by: H. Peter Anvin Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/via-cputemp.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/via-cputemp.c b/drivers/hwmon/via-cputemp.c index 8eac67d769f..8689664ef03 100644 --- a/drivers/hwmon/via-cputemp.c +++ b/drivers/hwmon/via-cputemp.c @@ -37,6 +37,7 @@ #include #include #include +#include #define DRVNAME "via_cputemp" @@ -308,15 +309,20 @@ static struct notifier_block via_cputemp_cpu_notifier __refdata = { .notifier_call = via_cputemp_cpu_callback, }; +static const struct x86_cpu_id cputemp_ids[] = { + { X86_VENDOR_CENTAUR, 6, 0xa, }, /* C7 A */ + { X86_VENDOR_CENTAUR, 6, 0xd, }, /* C7 D */ + { X86_VENDOR_CENTAUR, 6, 0xf, }, /* Nano */ + {} +}; +MODULE_DEVICE_TABLE(x86cpu, cputemp_ids); + static int __init via_cputemp_init(void) { int i, err; - if (cpu_data(0).x86_vendor != X86_VENDOR_CENTAUR) { - printk(KERN_DEBUG DRVNAME ": Not a VIA CPU\n"); - err = -ENODEV; - goto exit; - } + if (!x86_match_cpu(cputemp_ids)) + return -ENODEV; err = platform_driver_register(&via_cputemp_driver); if (err) -- cgit v1.2.3-70-g09d2 From 9b38096fde5f9b93c3657911c3be7892cc155cbd Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 26 Jan 2012 00:09:10 +0100 Subject: HWMON: Convert coretemp to x86 cpuid autoprobing Use the new x86 cpuid autoprobe interface for the Intel coretemp driver. Cc: Fenghua Yu Cc: Jean Delvare Cc: Guenter Roeck Signed-off-by: Andi Kleen Signed-off-by: Thomas Renninger Acked-by: H. Peter Anvin Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/coretemp.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index a6c6ec36615..249ac460e3d 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -39,6 +39,7 @@ #include #include #include +#include #define DRVNAME "coretemp" @@ -759,13 +760,23 @@ static struct notifier_block coretemp_cpu_notifier __refdata = { .notifier_call = coretemp_cpu_callback, }; +static const struct x86_cpu_id coretemp_ids[] = { + { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_DTS }, + {} +}; +MODULE_DEVICE_TABLE(x86cpu, coretemp_ids); + static int __init coretemp_init(void) { int i, err = -ENODEV; - /* quick check if we run Intel */ - if (cpu_data(0).x86_vendor != X86_VENDOR_INTEL) - goto exit; + /* + * CPUID.06H.EAX[0] indicates whether the CPU has thermal + * sensors. We check this bit only, all the early CPUs + * without thermal sensors will be filtered out. + */ + if (!x86_match_cpu(coretemp_ids)) + return -ENODEV; err = platform_driver_register(&coretemp_driver); if (err) -- cgit v1.2.3-70-g09d2 From fa8031aefec0cf7ea6c2387c93610d99d9659aa2 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 26 Jan 2012 00:09:12 +0100 Subject: cpufreq: Add support for x86 cpuinfo auto loading v4 This marks all the x86 cpuinfo tables to the CPU specific device drivers, to allow auto loading by udev. This should simplify the distribution startup scripts for this greatly. I didn't add MODULE_DEVICE_IDs to the centrino and p4-clockmod drivers, because those probably shouldn't be auto loaded and the acpi driver be used instead (not fully sure on that, would appreciate feedback) The old nforce drivers autoload based on the PCI ID. ACPI cpufreq is autoloaded in another patch. v3: Autoload gx based on PCI IDs only. Remove cpu check (Dave Jones) v4: Use newly introduce HW_PSTATE feature for powernow-k8 loading Cc: Dave Jones Cc: Kay Sievers Signed-off-by: Andi Kleen Signed-off-by: Thomas Renninger Acked-by: H. Peter Anvin Signed-off-by: Greg Kroah-Hartman --- drivers/cpufreq/cpufreq-nforce2.c | 8 ++++++++ drivers/cpufreq/e_powersaver.c | 20 +++++++++++--------- drivers/cpufreq/elanfreq.c | 14 +++++++------- drivers/cpufreq/gx-suspmod.c | 9 ++------- drivers/cpufreq/longhaul.c | 8 +++++++- drivers/cpufreq/longrun.c | 13 ++++++++----- drivers/cpufreq/p4-clockmod.c | 17 +++++++++++------ drivers/cpufreq/powernow-k6.c | 12 ++++++++---- drivers/cpufreq/powernow-k7.c | 14 ++++++++------ drivers/cpufreq/powernow-k8.c | 19 +++++++++++++------ drivers/cpufreq/sc520_freq.c | 14 ++++++++------ drivers/cpufreq/speedstep-centrino.c | 24 ++++++++++++++++++++---- drivers/cpufreq/speedstep-ich.c | 15 +++++++++++++++ drivers/cpufreq/speedstep-lib.c | 1 + drivers/cpufreq/speedstep-smi.c | 15 +++++++++++++++ 15 files changed, 142 insertions(+), 61 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq-nforce2.c b/drivers/cpufreq/cpufreq-nforce2.c index 7bac808804f..13d311ee08b 100644 --- a/drivers/cpufreq/cpufreq-nforce2.c +++ b/drivers/cpufreq/cpufreq-nforce2.c @@ -385,6 +385,14 @@ static struct cpufreq_driver nforce2_driver = { .owner = THIS_MODULE, }; +#ifdef MODULE +static DEFINE_PCI_DEVICE_TABLE(nforce2_ids) = { + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2 }, + {} +}; +MODULE_DEVICE_TABLE(pci, nforce2_ids); +#endif + /** * nforce2_detect_chipset - detect the Southbridge which contains FSB PLL logic * diff --git a/drivers/cpufreq/e_powersaver.c b/drivers/cpufreq/e_powersaver.c index 4bd6815d317..3fffbe6025c 100644 --- a/drivers/cpufreq/e_powersaver.c +++ b/drivers/cpufreq/e_powersaver.c @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -437,18 +438,19 @@ static struct cpufreq_driver eps_driver = { .attr = eps_attr, }; + +/* This driver will work only on Centaur C7 processors with + * Enhanced SpeedStep/PowerSaver registers */ +static const struct x86_cpu_id eps_cpu_id[] = { + { X86_VENDOR_CENTAUR, 6, X86_MODEL_ANY, X86_FEATURE_EST }, + {} +}; +MODULE_DEVICE_TABLE(x86cpu, eps_cpu_id); + static int __init eps_init(void) { - struct cpuinfo_x86 *c = &cpu_data(0); - - /* This driver will work only on Centaur C7 processors with - * Enhanced SpeedStep/PowerSaver registers */ - if (c->x86_vendor != X86_VENDOR_CENTAUR - || c->x86 != 6 || c->x86_model < 10) - return -ENODEV; - if (!cpu_has(c, X86_FEATURE_EST)) + if (!x86_match_cpu(eps_cpu_id) || boot_cpu_data.x86_model < 10) return -ENODEV; - if (cpufreq_register_driver(&eps_driver)) return -EINVAL; return 0; diff --git a/drivers/cpufreq/elanfreq.c b/drivers/cpufreq/elanfreq.c index c587db472a7..960671fd3d7 100644 --- a/drivers/cpufreq/elanfreq.c +++ b/drivers/cpufreq/elanfreq.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -277,17 +278,16 @@ static struct cpufreq_driver elanfreq_driver = { .attr = elanfreq_attr, }; +static const struct x86_cpu_id elan_id[] = { + { X86_VENDOR_AMD, 4, 10, }, + {} +}; +MODULE_DEVICE_TABLE(x86cpu, elan_id); static int __init elanfreq_init(void) { - struct cpuinfo_x86 *c = &cpu_data(0); - - /* Test if we have the right hardware */ - if ((c->x86_vendor != X86_VENDOR_AMD) || - (c->x86 != 4) || (c->x86_model != 10)) { - printk(KERN_INFO "elanfreq: error: no Elan processor found!\n"); + if (!x86_match_cpu(elan_id)) return -ENODEV; - } return cpufreq_register_driver(&elanfreq_driver); } diff --git a/drivers/cpufreq/gx-suspmod.c b/drivers/cpufreq/gx-suspmod.c index ffe1f2c92ed..5a06c0ba245 100644 --- a/drivers/cpufreq/gx-suspmod.c +++ b/drivers/cpufreq/gx-suspmod.c @@ -82,6 +82,7 @@ #include #include +#include #include /* PCI config registers, all at F0 */ @@ -171,6 +172,7 @@ static struct pci_device_id gx_chipset_tbl[] __initdata = { { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), }, { 0, }, }; +MODULE_DEVICE_TABLE(gx_chipset_tbl); static void gx_write_byte(int reg, int value) { @@ -185,13 +187,6 @@ static __init struct pci_dev *gx_detect_chipset(void) { struct pci_dev *gx_pci = NULL; - /* check if CPU is a MediaGX or a Geode. */ - if ((boot_cpu_data.x86_vendor != X86_VENDOR_NSC) && - (boot_cpu_data.x86_vendor != X86_VENDOR_CYRIX)) { - pr_debug("error: no MediaGX/Geode processor found!\n"); - return NULL; - } - /* detect which companion chip is used */ for_each_pci_dev(gx_pci) { if ((pci_match_id(gx_chipset_tbl, gx_pci)) != NULL) diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c index f47d26e2a13..53ddbc760af 100644 --- a/drivers/cpufreq/longhaul.c +++ b/drivers/cpufreq/longhaul.c @@ -35,6 +35,7 @@ #include #include +#include #include #include "longhaul.h" @@ -951,12 +952,17 @@ static struct cpufreq_driver longhaul_driver = { .attr = longhaul_attr, }; +static const struct x86_cpu_id longhaul_id[] = { + { X86_VENDOR_CENTAUR, 6 }, + {} +}; +MODULE_DEVICE_TABLE(x86cpu, longhaul_id); static int __init longhaul_init(void) { struct cpuinfo_x86 *c = &cpu_data(0); - if (c->x86_vendor != X86_VENDOR_CENTAUR || c->x86 != 6) + if (!x86_match_cpu(longhaul_id)) return -ENODEV; #ifdef CONFIG_SMP diff --git a/drivers/cpufreq/longrun.c b/drivers/cpufreq/longrun.c index 34ea359b370..8bc9f5fbbae 100644 --- a/drivers/cpufreq/longrun.c +++ b/drivers/cpufreq/longrun.c @@ -14,6 +14,7 @@ #include #include +#include static struct cpufreq_driver longrun_driver; @@ -288,6 +289,12 @@ static struct cpufreq_driver longrun_driver = { .owner = THIS_MODULE, }; +static const struct x86_cpu_id longrun_ids[] = { + { X86_VENDOR_TRANSMETA, X86_FAMILY_ANY, X86_MODEL_ANY, + X86_FEATURE_LONGRUN }, + {} +}; +MODULE_DEVICE_TABLE(x86cpu, longrun_ids); /** * longrun_init - initializes the Transmeta Crusoe LongRun CPUFreq driver @@ -296,12 +303,8 @@ static struct cpufreq_driver longrun_driver = { */ static int __init longrun_init(void) { - struct cpuinfo_x86 *c = &cpu_data(0); - - if (c->x86_vendor != X86_VENDOR_TRANSMETA || - !cpu_has(c, X86_FEATURE_LONGRUN)) + if (!x86_match_cpu(longrun_ids)) return -ENODEV; - return cpufreq_register_driver(&longrun_driver); } diff --git a/drivers/cpufreq/p4-clockmod.c b/drivers/cpufreq/p4-clockmod.c index 6be3e0760c2..827629c9aad 100644 --- a/drivers/cpufreq/p4-clockmod.c +++ b/drivers/cpufreq/p4-clockmod.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "speedstep-lib.h" @@ -289,21 +290,25 @@ static struct cpufreq_driver p4clockmod_driver = { .attr = p4clockmod_attr, }; +static const struct x86_cpu_id cpufreq_p4_id[] = { + { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_ACC }, + {} +}; + +/* + * Intentionally no MODULE_DEVICE_TABLE here: this driver should not + * be auto loaded. Please don't add one. + */ static int __init cpufreq_p4_init(void) { - struct cpuinfo_x86 *c = &cpu_data(0); int ret; /* * THERM_CONTROL is architectural for IA32 now, so * we can rely on the capability checks */ - if (c->x86_vendor != X86_VENDOR_INTEL) - return -ENODEV; - - if (!test_cpu_cap(c, X86_FEATURE_ACPI) || - !test_cpu_cap(c, X86_FEATURE_ACC)) + if (!x86_match_cpu(cpufreq_p4_id) || !boot_cpu_has(X86_FEATURE_ACPI)) return -ENODEV; ret = cpufreq_register_driver(&p4clockmod_driver); diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c index b3379d6a5c5..54dd031394f 100644 --- a/drivers/cpufreq/powernow-k6.c +++ b/drivers/cpufreq/powernow-k6.c @@ -16,6 +16,7 @@ #include #include +#include #include #define POWERNOW_IOPORT 0xfff0 /* it doesn't matter where, as long @@ -210,6 +211,12 @@ static struct cpufreq_driver powernow_k6_driver = { .attr = powernow_k6_attr, }; +static const struct x86_cpu_id powernow_k6_ids[] = { + { X86_VENDOR_AMD, 5, 12 }, + { X86_VENDOR_AMD, 5, 13 }, + {} +}; + /** * powernow_k6_init - initializes the k6 PowerNow! CPUFreq driver @@ -220,10 +227,7 @@ static struct cpufreq_driver powernow_k6_driver = { */ static int __init powernow_k6_init(void) { - struct cpuinfo_x86 *c = &cpu_data(0); - - if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 5) || - ((c->x86_model != 12) && (c->x86_model != 13))) + if (!x86_match_cpu(powernow_k6_ids)) return -ENODEV; if (!request_region(POWERNOW_IOPORT, 16, "PowerNow!")) { diff --git a/drivers/cpufreq/powernow-k7.c b/drivers/cpufreq/powernow-k7.c index d71d9f37235..501d167368d 100644 --- a/drivers/cpufreq/powernow-k7.c +++ b/drivers/cpufreq/powernow-k7.c @@ -28,6 +28,7 @@ #include /* Needed for recalibrate_cpu_khz() */ #include #include +#include #ifdef CONFIG_X86_POWERNOW_K7_ACPI #include @@ -110,18 +111,19 @@ static int check_fsb(unsigned int fsbspeed) return delta < 5; } +static const struct x86_cpu_id powernow_k7_cpuids[] = { + { X86_VENDOR_AMD, 7, }, + {} +}; +MODULE_DEVICE_TABLE(x86cpu, powernow_k7_cpuids); + static int check_powernow(void) { struct cpuinfo_x86 *c = &cpu_data(0); unsigned int maxei, eax, ebx, ecx, edx; - if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 6)) { -#ifdef MODULE - printk(KERN_INFO PFX "This module only works with " - "AMD K7 CPUs\n"); -#endif + if (!x86_match_cpu(powernow_k7_cpuids)) return 0; - } /* Get maximum capabilities */ maxei = cpuid_eax(0x80000000); diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c index 8f9b2ceeec8..c0e816468e3 100644 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c @@ -40,6 +40,7 @@ #include #include +#include #include #include @@ -520,6 +521,15 @@ static int core_voltage_post_transition(struct powernow_k8_data *data, return 0; } +static const struct x86_cpu_id powernow_k8_ids[] = { + /* IO based frequency switching */ + { X86_VENDOR_AMD, 0xf }, + /* MSR based frequency switching supported */ + X86_FEATURE_MATCH(X86_FEATURE_HW_PSTATE), + {} +}; +MODULE_DEVICE_TABLE(x86cpu, powernow_k8_ids); + static void check_supported_cpu(void *_rc) { u32 eax, ebx, ecx, edx; @@ -527,13 +537,7 @@ static void check_supported_cpu(void *_rc) *rc = -ENODEV; - if (__this_cpu_read(cpu_info.x86_vendor) != X86_VENDOR_AMD) - return; - eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); - if (((eax & CPUID_XFAM) != CPUID_XFAM_K8) && - ((eax & CPUID_XFAM) < CPUID_XFAM_10H)) - return; if ((eax & CPUID_XFAM) == CPUID_XFAM_K8) { if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) || @@ -1553,6 +1557,9 @@ static int __cpuinit powernowk8_init(void) unsigned int i, supported_cpus = 0, cpu; int rv; + if (!x86_match_cpu(powernow_k8_ids)) + return -ENODEV; + for_each_online_cpu(i) { int rc; smp_call_function_single(i, check_supported_cpu, &rc, 1); diff --git a/drivers/cpufreq/sc520_freq.c b/drivers/cpufreq/sc520_freq.c index 1e205e6b172..e42e073cd9b 100644 --- a/drivers/cpufreq/sc520_freq.c +++ b/drivers/cpufreq/sc520_freq.c @@ -22,6 +22,7 @@ #include #include +#include #include #define MMCR_BASE 0xfffef000 /* The default base address */ @@ -150,18 +151,19 @@ static struct cpufreq_driver sc520_freq_driver = { .attr = sc520_freq_attr, }; +static const struct x86_cpu_id sc520_ids[] = { + { X86_VENDOR_AMD, 4, 9 }, + {} +}; +MODULE_DEVICE_TABLE(x86cpu, sc520_ids); static int __init sc520_freq_init(void) { - struct cpuinfo_x86 *c = &cpu_data(0); int err; - /* Test if we have the right hardware */ - if (c->x86_vendor != X86_VENDOR_AMD || - c->x86 != 4 || c->x86_model != 9) { - pr_debug("no Elan SC520 processor found!\n"); + if (!x86_match_cpu(sc520_ids)) return -ENODEV; - } + cpuctl = ioremap((unsigned long)(MMCR_BASE + OFFS_CPUCTL), 1); if (!cpuctl) { printk(KERN_ERR "sc520_freq: error: failed to remap memory\n"); diff --git a/drivers/cpufreq/speedstep-centrino.c b/drivers/cpufreq/speedstep-centrino.c index 6ea3455def2..3a953d519f4 100644 --- a/drivers/cpufreq/speedstep-centrino.c +++ b/drivers/cpufreq/speedstep-centrino.c @@ -25,6 +25,7 @@ #include #include #include +#include #define PFX "speedstep-centrino: " #define MAINTAINER "cpufreq@vger.kernel.org" @@ -595,6 +596,24 @@ static struct cpufreq_driver centrino_driver = { .owner = THIS_MODULE, }; +/* + * This doesn't replace the detailed checks above because + * the generic CPU IDs don't have a way to match for steppings + * or ASCII model IDs. + */ +static const struct x86_cpu_id centrino_ids[] = { + { X86_VENDOR_INTEL, 6, 9, X86_FEATURE_EST }, + { X86_VENDOR_INTEL, 6, 13, X86_FEATURE_EST }, + { X86_VENDOR_INTEL, 6, 13, X86_FEATURE_EST }, + { X86_VENDOR_INTEL, 6, 13, X86_FEATURE_EST }, + { X86_VENDOR_INTEL, 15, 3, X86_FEATURE_EST }, + { X86_VENDOR_INTEL, 15, 4, X86_FEATURE_EST }, + {} +}; +#if 0 +/* Autoload or not? Do not for now. */ +MODULE_DEVICE_TABLE(x86cpu, centrino_ids); +#endif /** * centrino_init - initializes the Enhanced SpeedStep CPUFreq driver @@ -612,11 +631,8 @@ static struct cpufreq_driver centrino_driver = { */ static int __init centrino_init(void) { - struct cpuinfo_x86 *cpu = &cpu_data(0); - - if (!cpu_has(cpu, X86_FEATURE_EST)) + if (!x86_match_cpu(centrino_ids)) return -ENODEV; - return cpufreq_register_driver(¢rino_driver); } diff --git a/drivers/cpufreq/speedstep-ich.c b/drivers/cpufreq/speedstep-ich.c index a748ce782fe..7432b3a72cd 100644 --- a/drivers/cpufreq/speedstep-ich.c +++ b/drivers/cpufreq/speedstep-ich.c @@ -25,6 +25,8 @@ #include #include +#include + #include "speedstep-lib.h" @@ -388,6 +390,16 @@ static struct cpufreq_driver speedstep_driver = { .attr = speedstep_attr, }; +static const struct x86_cpu_id ss_smi_ids[] = { + { X86_VENDOR_INTEL, 6, 0xb, }, + { X86_VENDOR_INTEL, 6, 0x8, }, + { X86_VENDOR_INTEL, 15, 2 }, + {} +}; +#if 0 +/* Autoload or not? Do not for now. */ +MODULE_DEVICE_TABLE(x86cpu, ss_smi_ids); +#endif /** * speedstep_init - initializes the SpeedStep CPUFreq driver @@ -398,6 +410,9 @@ static struct cpufreq_driver speedstep_driver = { */ static int __init speedstep_init(void) { + if (!x86_match_cpu(ss_smi_ids)) + return -ENODEV; + /* detect processor */ speedstep_processor = speedstep_detect_processor(); if (!speedstep_processor) { diff --git a/drivers/cpufreq/speedstep-lib.c b/drivers/cpufreq/speedstep-lib.c index 8af2d2fd9d5..7047821a7f8 100644 --- a/drivers/cpufreq/speedstep-lib.c +++ b/drivers/cpufreq/speedstep-lib.c @@ -249,6 +249,7 @@ EXPORT_SYMBOL_GPL(speedstep_get_frequency); * DETECT SPEEDSTEP-CAPABLE PROCESSOR * *********************************************************************/ +/* Keep in sync with the x86_cpu_id tables in the different modules */ unsigned int speedstep_detect_processor(void) { struct cpuinfo_x86 *c = &cpu_data(0); diff --git a/drivers/cpufreq/speedstep-smi.c b/drivers/cpufreq/speedstep-smi.c index c76ead3490b..6a457fcaaad 100644 --- a/drivers/cpufreq/speedstep-smi.c +++ b/drivers/cpufreq/speedstep-smi.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "speedstep-lib.h" @@ -379,6 +380,17 @@ static struct cpufreq_driver speedstep_driver = { .attr = speedstep_attr, }; +static const struct x86_cpu_id ss_smi_ids[] = { + { X86_VENDOR_INTEL, 6, 0xb, }, + { X86_VENDOR_INTEL, 6, 0x8, }, + { X86_VENDOR_INTEL, 15, 2 }, + {} +}; +#if 0 +/* Not auto loaded currently */ +MODULE_DEVICE_TABLE(x86cpu, ss_smi_ids); +#endif + /** * speedstep_init - initializes the SpeedStep CPUFreq driver * @@ -388,6 +400,9 @@ static struct cpufreq_driver speedstep_driver = { */ static int __init speedstep_init(void) { + if (!x86_match_cpu(ss_smi_ids)) + return -ENODEV; + speedstep_processor = speedstep_detect_processor(); switch (speedstep_processor) { -- cgit v1.2.3-70-g09d2 From fad12ac8c8c2591c7f4e61d19b6a9d76cd49fafa Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Thu, 26 Jan 2012 00:09:14 +0100 Subject: CPU: Introduce ARCH_HAS_CPU_AUTOPROBE and X86 parts This patch is based on Andi Kleen's work: Implement autoprobing/loading of modules serving CPU specific features (x86cpu autoloading). And Kay Siever's work to get rid of sysdev cpu structures and making use of struct device instead. Before, the cpuid driver had to be loaded to get the x86cpu autoloading feature. With this patch autoloading works through the /sys/devices/system/cpu object Cc: Kay Sievers Cc: Dave Jones Cc: Jens Axboe Cc: Herbert Xu Cc: Huang Ying Cc: Len Brown Acked-by: Andi Kleen Signed-off-by: Thomas Renninger Acked-by: H. Peter Anvin Signed-off-by: Greg Kroah-Hartman --- arch/x86/Kconfig | 3 +++ arch/x86/kernel/cpu/match.c | 44 +++++++++++++++++++++++++++++++++ arch/x86/kernel/cpuid.c | 59 +-------------------------------------------- drivers/base/cpu.c | 11 +++++++++ include/linux/cpu.h | 7 ++++++ 5 files changed, 66 insertions(+), 58 deletions(-) (limited to 'drivers') diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 864cc6e6ac8..6baa1e66e1b 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -179,6 +179,9 @@ config ARCH_HAS_DEFAULT_IDLE config ARCH_HAS_CACHE_LINE_SIZE def_bool y +config ARCH_HAS_CPU_AUTOPROBE + def_bool y + config HAVE_SETUP_PER_CPU_AREA def_bool y diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c index 7acc961422e..940e2d48307 100644 --- a/arch/x86/kernel/cpu/match.c +++ b/arch/x86/kernel/cpu/match.c @@ -2,6 +2,7 @@ #include #include #include +#include /** * x86_match_cpu - match current CPU again an array of x86_cpu_ids @@ -46,3 +47,46 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match) return NULL; } EXPORT_SYMBOL(x86_match_cpu); + +ssize_t arch_print_cpu_modalias(struct device *dev, + struct device_attribute *attr, + char *bufptr) +{ + int size = PAGE_SIZE; + int i, n; + char *buf = bufptr; + + n = snprintf(buf, size, "x86cpu:vendor:%04X:family:%04X:" + "model:%04X:feature:", + boot_cpu_data.x86_vendor, + boot_cpu_data.x86, + boot_cpu_data.x86_model); + size -= n; + buf += n; + size -= 2; + for (i = 0; i < NCAPINTS*32; i++) { + if (boot_cpu_has(i)) { + n = snprintf(buf, size, ",%04X", i); + if (n < 0) { + WARN(1, "x86 features overflow page\n"); + break; + } + size -= n; + buf += n; + } + } + *buf++ = ','; + *buf++ = '\n'; + return buf - bufptr; +} + +int arch_cpu_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + char *buf = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (buf) { + arch_print_cpu_modalias(NULL, NULL, buf); + add_uevent_var(env, "MODALIAS=%s", buf); + kfree(buf); + } + return 0; +} diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c index 7c89880eefd..a524353d93f 100644 --- a/arch/x86/kernel/cpuid.c +++ b/arch/x86/kernel/cpuid.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include @@ -139,57 +138,13 @@ static const struct file_operations cpuid_fops = { .open = cpuid_open, }; -static ssize_t print_cpu_modalias(struct device *dev, - struct device_attribute *attr, - char *bufptr) -{ - int size = PAGE_SIZE; - int i, n; - char *buf = bufptr; - - n = snprintf(buf, size, "x86cpu:vendor:%04X:family:" - "%04X:model:%04X:feature:", - boot_cpu_data.x86_vendor, - boot_cpu_data.x86, - boot_cpu_data.x86_model); - size -= n; - buf += n; - size -= 2; - for (i = 0; i < NCAPINTS*32; i++) { - if (boot_cpu_has(i)) { - n = snprintf(buf, size, ",%04X", i); - if (n < 0) { - WARN(1, "x86 features overflow page\n"); - break; - } - size -= n; - buf += n; - } - } - *buf++ = ','; - *buf++ = '\n'; - return buf - bufptr; -} - -static DEVICE_ATTR(modalias, 0444, print_cpu_modalias, NULL); - static __cpuinit int cpuid_device_create(int cpu) { struct device *dev; - int err; dev = device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, cpu), NULL, "cpu%d", cpu); - if (IS_ERR(dev)) - return PTR_ERR(dev); - - err = device_create_file(dev, &dev_attr_modalias); - if (err) { - /* keep device around on error. attribute is optional. */ - err = 0; - } - - return 0; + return IS_ERR(dev) ? PTR_ERR(dev) : 0; } static void cpuid_device_destroy(int cpu) @@ -227,17 +182,6 @@ static char *cpuid_devnode(struct device *dev, umode_t *mode) return kasprintf(GFP_KERNEL, "cpu/%u/cpuid", MINOR(dev->devt)); } -static int cpuid_dev_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - char *buf = kzalloc(PAGE_SIZE, GFP_KERNEL); - if (buf) { - print_cpu_modalias(NULL, NULL, buf); - add_uevent_var(env, "MODALIAS=%s", buf); - kfree(buf); - } - return 0; -} - static int __init cpuid_init(void) { int i, err = 0; @@ -256,7 +200,6 @@ static int __init cpuid_init(void) goto out_chrdev; } cpuid_class->devnode = cpuid_devnode; - cpuid_class->dev_uevent = cpuid_dev_uevent; for_each_online_cpu(i) { err = cpuid_device_create(i); if (err != 0) diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index db87e78d745..2a0c670c281 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include "base.h" @@ -223,6 +224,9 @@ int __cpuinit register_cpu(struct cpu *cpu, int num) cpu->node_id = cpu_to_node(num); cpu->dev.id = num; cpu->dev.bus = &cpu_subsys; +#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE + cpu->dev.bus->uevent = arch_cpu_uevent; +#endif error = device_register(&cpu->dev); if (!error && cpu->hotpluggable) register_cpu_control(cpu); @@ -247,6 +251,10 @@ struct device *get_cpu_device(unsigned cpu) } EXPORT_SYMBOL_GPL(get_cpu_device); +#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE +static DEVICE_ATTR(modalias, 0444, arch_print_cpu_modalias, NULL); +#endif + static struct attribute *cpu_root_attrs[] = { #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE &dev_attr_probe.attr, @@ -257,6 +265,9 @@ static struct attribute *cpu_root_attrs[] = { &cpu_attrs[2].attr.attr, &dev_attr_kernel_max.attr, &dev_attr_offline.attr, +#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE + &dev_attr_modalias.attr, +#endif NULL }; diff --git a/include/linux/cpu.h b/include/linux/cpu.h index 1f6587590a1..6e53b4823d7 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -44,6 +44,13 @@ extern ssize_t arch_cpu_release(const char *, size_t); #endif struct notifier_block; +#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE +extern int arch_cpu_uevent(struct device *dev, struct kobj_uevent_env *env); +extern ssize_t arch_print_cpu_modalias(struct device *dev, + struct device_attribute *attr, + char *bufptr); +#endif + /* * CPU notifier priorities. */ -- cgit v1.2.3-70-g09d2 From ed283e9f0a2cc0541870828c76c6c6997c51a318 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 24 Jan 2012 14:35:13 -0500 Subject: USB/PCI/PCMCIA: Clean up new_id and remove_id sysfs attribute routines This patch (as1514) cleans up some places where new_id and remove_id sysfs attributes are created and deleted. Handling both attributes in a single routine rather than a pair of routines makes the code smaller. It also prevents certain kinds of errors, like one we currently have in the USB subsystem: The removeid attribute is often created even when newid isn't (because the driver's no_dynamid_id flag is set). In the case of the PCMCIA subsystem, the newid attribute is created but never explicitly deleted. The patch adds a deletion routine. Signed-off-by: Alan Stern Acked-by: Jesse Barnes Acked-by: Dominik Brodowski Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci-driver.c | 50 +++++++++++++------------------------- drivers/pcmcia/ds.c | 6 +++++ drivers/usb/core/driver.c | 61 ++++++++++++++++------------------------------- 3 files changed, 43 insertions(+), 74 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index ff540477fe8..8d9616b821c 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -188,43 +188,34 @@ store_remove_id(struct device_driver *driver, const char *buf, size_t count) static DRIVER_ATTR(remove_id, S_IWUSR, NULL, store_remove_id); static int -pci_create_newid_file(struct pci_driver *drv) +pci_create_newid_files(struct pci_driver *drv) { int error = 0; - if (drv->probe != NULL) - error = driver_create_file(&drv->driver, &driver_attr_new_id); - return error; -} - -static void pci_remove_newid_file(struct pci_driver *drv) -{ - driver_remove_file(&drv->driver, &driver_attr_new_id); -} -static int -pci_create_removeid_file(struct pci_driver *drv) -{ - int error = 0; - if (drv->probe != NULL) - error = driver_create_file(&drv->driver,&driver_attr_remove_id); + if (drv->probe != NULL) { + error = driver_create_file(&drv->driver, &driver_attr_new_id); + if (error == 0) { + error = driver_create_file(&drv->driver, + &driver_attr_remove_id); + if (error) + driver_remove_file(&drv->driver, + &driver_attr_new_id); + } + } return error; } -static void pci_remove_removeid_file(struct pci_driver *drv) +static void pci_remove_newid_files(struct pci_driver *drv) { driver_remove_file(&drv->driver, &driver_attr_remove_id); + driver_remove_file(&drv->driver, &driver_attr_new_id); } #else /* !CONFIG_HOTPLUG */ -static inline int pci_create_newid_file(struct pci_driver *drv) +static inline int pci_create_newid_files(struct pci_driver *drv) { return 0; } -static inline void pci_remove_newid_file(struct pci_driver *drv) {} -static inline int pci_create_removeid_file(struct pci_driver *drv) -{ - return 0; -} -static inline void pci_remove_removeid_file(struct pci_driver *drv) {} +static inline void pci_remove_newid_files(struct pci_driver *drv) {} #endif /** @@ -1136,18 +1127,12 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner, if (error) goto out; - error = pci_create_newid_file(drv); + error = pci_create_newid_files(drv); if (error) goto out_newid; - - error = pci_create_removeid_file(drv); - if (error) - goto out_removeid; out: return error; -out_removeid: - pci_remove_newid_file(drv); out_newid: driver_unregister(&drv->driver); goto out; @@ -1166,8 +1151,7 @@ out_newid: void pci_unregister_driver(struct pci_driver *drv) { - pci_remove_removeid_file(drv); - pci_remove_newid_file(drv); + pci_remove_newid_files(drv); driver_unregister(&drv->driver); pci_free_dynids(drv); } diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 059699f6363..249b8895807 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -157,6 +157,11 @@ pcmcia_create_newid_file(struct pcmcia_driver *drv) return error; } +static void +pcmcia_remove_newid_file(struct pcmcia_driver *drv) +{ + driver_remove_file(&drv->drv, &driver_attr_new_id); +} /** * pcmcia_register_driver - register a PCMCIA driver with the bus core @@ -201,6 +206,7 @@ EXPORT_SYMBOL(pcmcia_register_driver); void pcmcia_unregister_driver(struct pcmcia_driver *driver) { pr_debug("unregistering driver %s\n", driver->name); + pcmcia_remove_newid_file(driver); driver_unregister(&driver->drv); pcmcia_free_dynids(driver); } diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 54c493b4226..4fee024ecc9 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -129,43 +129,39 @@ store_remove_id(struct device_driver *driver, const char *buf, size_t count) } static DRIVER_ATTR(remove_id, S_IWUSR, NULL, store_remove_id); -static int usb_create_newid_file(struct usb_driver *usb_drv) +static int usb_create_newid_files(struct usb_driver *usb_drv) { int error = 0; if (usb_drv->no_dynamic_id) goto exit; - if (usb_drv->probe != NULL) + if (usb_drv->probe != NULL) { error = driver_create_file(&usb_drv->drvwrap.driver, &driver_attr_new_id); + if (error == 0) { + error = driver_create_file(&usb_drv->drvwrap.driver, + &driver_attr_remove_id); + if (error) + driver_remove_file(&usb_drv->drvwrap.driver, + &driver_attr_new_id); + } + } exit: return error; } -static void usb_remove_newid_file(struct usb_driver *usb_drv) +static void usb_remove_newid_files(struct usb_driver *usb_drv) { if (usb_drv->no_dynamic_id) return; - if (usb_drv->probe != NULL) + if (usb_drv->probe != NULL) { driver_remove_file(&usb_drv->drvwrap.driver, - &driver_attr_new_id); -} - -static int -usb_create_removeid_file(struct usb_driver *drv) -{ - int error = 0; - if (drv->probe != NULL) - error = driver_create_file(&drv->drvwrap.driver, &driver_attr_remove_id); - return error; -} - -static void usb_remove_removeid_file(struct usb_driver *drv) -{ - driver_remove_file(&drv->drvwrap.driver, &driver_attr_remove_id); + driver_remove_file(&usb_drv->drvwrap.driver, + &driver_attr_new_id); + } } static void usb_free_dynids(struct usb_driver *usb_drv) @@ -180,22 +176,12 @@ static void usb_free_dynids(struct usb_driver *usb_drv) spin_unlock(&usb_drv->dynids.lock); } #else -static inline int usb_create_newid_file(struct usb_driver *usb_drv) -{ - return 0; -} - -static void usb_remove_newid_file(struct usb_driver *usb_drv) -{ -} - -static int -usb_create_removeid_file(struct usb_driver *drv) +static inline int usb_create_newid_files(struct usb_driver *usb_drv) { return 0; } -static void usb_remove_removeid_file(struct usb_driver *drv) +static void usb_remove_newid_files(struct usb_driver *usb_drv) { } @@ -872,22 +858,16 @@ int usb_register_driver(struct usb_driver *new_driver, struct module *owner, usbfs_update_special(); - retval = usb_create_newid_file(new_driver); + retval = usb_create_newid_files(new_driver); if (retval) goto out_newid; - retval = usb_create_removeid_file(new_driver); - if (retval) - goto out_removeid; - pr_info("%s: registered new interface driver %s\n", usbcore_name, new_driver->name); out: return retval; -out_removeid: - usb_remove_newid_file(new_driver); out_newid: driver_unregister(&new_driver->drvwrap.driver); @@ -914,10 +894,9 @@ void usb_deregister(struct usb_driver *driver) pr_info("%s: deregistering interface driver %s\n", usbcore_name, driver->name); - usb_remove_removeid_file(driver); - usb_remove_newid_file(driver); - usb_free_dynids(driver); + usb_remove_newid_files(driver); driver_unregister(&driver->drvwrap.driver); + usb_free_dynids(driver); usbfs_update_special(); } -- cgit v1.2.3-70-g09d2 From d4e33fac2408d37f7b52e80ca2a89f9fb482914f Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 26 Jan 2012 17:44:09 +0000 Subject: serial: Kill off NO_IRQ We transform the offenders into a test of irq <= 0 which will be ok while the ARM people get their platform sorted. Once that is done (or in a while if they don't do it anyway) then we will change them all to !irq checks. For arch specific drivers that are already using NO_IRQ = 0 we just test against zero so we don't need to re-review them later. Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/hvc/hvc_beat.c | 2 +- drivers/tty/hvc/hvc_rtas.c | 2 +- drivers/tty/hvc/hvc_udbg.c | 2 +- drivers/tty/hvc/hvc_xen.c | 2 +- drivers/tty/hvc/hvcs.c | 4 ++-- drivers/tty/hvc/hvsi.c | 2 +- drivers/tty/serial/21285.c | 4 ++-- drivers/tty/serial/8250.c | 21 +++++++-------------- drivers/tty/serial/m32r_sio.c | 11 ++--------- drivers/tty/serial/mpc52xx_uart.c | 4 ++-- drivers/tty/serial/mux.c | 2 +- drivers/tty/serial/pmac_zilog.c | 2 +- drivers/tty/serial/sunzilog.c | 10 +++++----- drivers/tty/serial/ucc_uart.c | 2 +- drivers/tty/serial/vr41xx_siu.c | 4 ++-- 15 files changed, 30 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/hvc/hvc_beat.c b/drivers/tty/hvc/hvc_beat.c index 5fe4631e2a6..1560d235449 100644 --- a/drivers/tty/hvc/hvc_beat.c +++ b/drivers/tty/hvc/hvc_beat.c @@ -113,7 +113,7 @@ static int __init hvc_beat_init(void) if (!firmware_has_feature(FW_FEATURE_BEAT)) return -ENODEV; - hp = hvc_alloc(0, NO_IRQ, &hvc_beat_get_put_ops, 16); + hp = hvc_alloc(0, 0, &hvc_beat_get_put_ops, 16); if (IS_ERR(hp)) return PTR_ERR(hp); hvc_beat_dev = hp; diff --git a/drivers/tty/hvc/hvc_rtas.c b/drivers/tty/hvc/hvc_rtas.c index 61c4a61558d..0069bb86ba4 100644 --- a/drivers/tty/hvc/hvc_rtas.c +++ b/drivers/tty/hvc/hvc_rtas.c @@ -94,7 +94,7 @@ static int __init hvc_rtas_init(void) /* Allocate an hvc_struct for the console device we instantiated * earlier. Save off hp so that we can return it on exit */ - hp = hvc_alloc(hvc_rtas_cookie, NO_IRQ, &hvc_rtas_get_put_ops, 16); + hp = hvc_alloc(hvc_rtas_cookie, 0, &hvc_rtas_get_put_ops, 16); if (IS_ERR(hp)) return PTR_ERR(hp); diff --git a/drivers/tty/hvc/hvc_udbg.c b/drivers/tty/hvc/hvc_udbg.c index b0957e61a7b..4c9b13e7748 100644 --- a/drivers/tty/hvc/hvc_udbg.c +++ b/drivers/tty/hvc/hvc_udbg.c @@ -69,7 +69,7 @@ static int __init hvc_udbg_init(void) BUG_ON(hvc_udbg_dev); - hp = hvc_alloc(0, NO_IRQ, &hvc_udbg_ops, 16); + hp = hvc_alloc(0, 0, &hvc_udbg_ops, 16); if (IS_ERR(hp)) return PTR_ERR(hp); diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index 52fdf60bdbe..a1b0a75c3ea 100644 --- a/drivers/tty/hvc/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c @@ -176,7 +176,7 @@ static int __init xen_hvc_init(void) xencons_irq = bind_evtchn_to_irq(xen_start_info->console.domU.evtchn); } if (xencons_irq < 0) - xencons_irq = 0; /* NO_IRQ */ + xencons_irq = 0; else irq_set_noprobe(xencons_irq); diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index b9040bec36b..df7e7a0a5e6 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c @@ -1203,7 +1203,7 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp) { struct hvcs_struct *hvcsd; unsigned long flags; - int irq = NO_IRQ; + int irq; /* * Is someone trying to close the file associated with this device after @@ -1264,7 +1264,7 @@ static void hvcs_hangup(struct tty_struct * tty) struct hvcs_struct *hvcsd = tty->driver_data; unsigned long flags; int temp_open_count; - int irq = NO_IRQ; + int irq; spin_lock_irqsave(&hvcsd->lock, flags); /* Preserve this so that we know how many kref refs to put */ diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c index cdfa3e02d62..1b5f28bd793 100644 --- a/drivers/tty/hvc/hvsi.c +++ b/drivers/tty/hvc/hvsi.c @@ -1237,7 +1237,7 @@ static int __init hvsi_console_init(void) hp->state = HVSI_CLOSED; hp->vtermno = *vtermno; hp->virq = irq_create_mapping(NULL, irq[0]); - if (hp->virq == NO_IRQ) { + if (hp->virq == 0) { printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n", __func__, irq[0]); continue; diff --git a/drivers/tty/serial/21285.c b/drivers/tty/serial/21285.c index 1b37626e8f1..f899996b436 100644 --- a/drivers/tty/serial/21285.c +++ b/drivers/tty/serial/21285.c @@ -331,7 +331,7 @@ static int serial21285_verify_port(struct uart_port *port, struct serial_struct int ret = 0; if (ser->type != PORT_UNKNOWN && ser->type != PORT_21285) ret = -EINVAL; - if (ser->irq != NO_IRQ) + if (ser->irq <= 0) ret = -EINVAL; if (ser->baud_base != port->uartclk / 16) ret = -EINVAL; @@ -360,7 +360,7 @@ static struct uart_ops serial21285_ops = { static struct uart_port serial21285_port = { .mapbase = 0x42000160, .iotype = UPIO_MEM, - .irq = NO_IRQ, + .irq = 0, .fifosize = 16, .ops = &serial21285_ops, .flags = UPF_BOOT_AUTOCONF, diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c index 9f50c4e3c2b..b0eb9613932 100644 --- a/drivers/tty/serial/8250.c +++ b/drivers/tty/serial/8250.c @@ -86,13 +86,6 @@ static unsigned int skip_txen_test; /* force skip of txen test at init time */ #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) -/* - * We default to IRQ0 for the "no irq" hack. Some - * machine types want others as well - they're free - * to redefine this in their header file. - */ -#define is_real_interrupt(irq) ((irq) != 0) - #ifdef CONFIG_SERIAL_8250_DETECT_IRQ #define CONFIG_SERIAL_DETECT_IRQ 1 #endif @@ -1750,7 +1743,7 @@ static void serial8250_backup_timeout(unsigned long data) * Must disable interrupts or else we risk racing with the interrupt * based handler. */ - if (is_real_interrupt(up->port.irq)) { + if (up->port.irq) { ier = serial_in(up, UART_IER); serial_out(up, UART_IER, 0); } @@ -1775,7 +1768,7 @@ static void serial8250_backup_timeout(unsigned long data) if (!(iir & UART_IIR_NO_INT)) serial8250_tx_chars(up); - if (is_real_interrupt(up->port.irq)) + if (up->port.irq) serial_out(up, UART_IER, ier); spin_unlock_irqrestore(&up->port.lock, flags); @@ -2028,7 +2021,7 @@ static int serial8250_startup(struct uart_port *port) serial_outp(up, UART_LCR, 0); } - if (is_real_interrupt(up->port.irq)) { + if (up->port.irq) { unsigned char iir1; /* * Test for UARTs that do not reassert THRE when the @@ -2083,7 +2076,7 @@ static int serial8250_startup(struct uart_port *port) * hardware interrupt, we use a timer-based system. The original * driver used to do this with IRQ0. */ - if (!is_real_interrupt(up->port.irq)) { + if (!up->port.irq) { up->timer.data = (unsigned long)up; mod_timer(&up->timer, jiffies + uart_poll_timeout(port)); } else { @@ -2099,13 +2092,13 @@ static int serial8250_startup(struct uart_port *port) spin_lock_irqsave(&up->port.lock, flags); if (up->port.flags & UPF_FOURPORT) { - if (!is_real_interrupt(up->port.irq)) + if (!up->port.irq) up->port.mctrl |= TIOCM_OUT1; } else /* * Most PC uarts need OUT2 raised to enable interrupts. */ - if (is_real_interrupt(up->port.irq)) + if (up->port.irq) up->port.mctrl |= TIOCM_OUT2; serial8250_set_mctrl(&up->port, up->port.mctrl); @@ -2223,7 +2216,7 @@ static void serial8250_shutdown(struct uart_port *port) del_timer_sync(&up->timer); up->timer.function = serial8250_timeout; - if (is_real_interrupt(up->port.irq)) + if (up->port.irq) serial_unlink_irq_chain(up); } diff --git a/drivers/tty/serial/m32r_sio.c b/drivers/tty/serial/m32r_sio.c index 94a6792bf97..e465dda63ed 100644 --- a/drivers/tty/serial/m32r_sio.c +++ b/drivers/tty/serial/m32r_sio.c @@ -70,13 +70,6 @@ #define PASS_LIMIT 256 -/* - * We default to IRQ0 for the "no irq" hack. Some - * machine types want others as well - they're free - * to redefine this in their header file. - */ -#define is_real_interrupt(irq) ((irq) != 0) - #define BASE_BAUD 115200 /* Standard COM flags */ @@ -640,7 +633,7 @@ static int m32r_sio_startup(struct uart_port *port) * hardware interrupt, we use a timer-based system. The original * driver used to do this with IRQ0. */ - if (!is_real_interrupt(up->port.irq)) { + if (!up->port.irq) { unsigned int timeout = up->port.timeout; timeout = timeout > 6 ? (timeout / 2 - 2) : 1; @@ -687,7 +680,7 @@ static void m32r_sio_shutdown(struct uart_port *port) sio_init(); - if (!is_real_interrupt(up->port.irq)) + if (!up->port.irq) del_timer_sync(&up->timer); else serial_unlink_irq_chain(up); diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index 1093a88a1fe..e9a770d77a6 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c @@ -507,7 +507,7 @@ static int __init mpc512x_psc_fifoc_init(void) psc_fifoc_irq = irq_of_parse_and_map(np, 0); of_node_put(np); - if (psc_fifoc_irq == NO_IRQ) { + if (psc_fifoc_irq == 0) { pr_err("%s: Can't get FIFOC irq\n", __func__); iounmap(psc_fifoc); return -ENODEV; @@ -1354,7 +1354,7 @@ static int __devinit mpc52xx_uart_of_probe(struct platform_device *op) } psc_ops->get_irq(port, op->dev.of_node); - if (port->irq == NO_IRQ) { + if (port->irq == 0) { dev_dbg(&op->dev, "Could not get irq\n"); return -EINVAL; } diff --git a/drivers/tty/serial/mux.c b/drivers/tty/serial/mux.c index 06f6aefd5ba..c61d950e07c 100644 --- a/drivers/tty/serial/mux.c +++ b/drivers/tty/serial/mux.c @@ -499,7 +499,7 @@ static int __init mux_probe(struct parisc_device *dev) port->membase = ioremap_nocache(port->mapbase, MUX_LINE_OFFSET); port->iotype = UPIO_MEM; port->type = PORT_MUX; - port->irq = NO_IRQ; + port->irq = 0; port->uartclk = 0; port->fifosize = MUX_FIFO_SIZE; port->ops = &mux_pops; diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index e9c2dfe471a..08ebe901bb5 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c @@ -1506,7 +1506,7 @@ no_dma: * fixed up interrupt info, but we use the device-tree directly * here due to early probing so we need the fixup too. */ - if (uap->port.irq == NO_IRQ && + if (uap->port.irq == 0 && np->parent && np->parent->parent && of_device_is_compatible(np->parent->parent, "gatwick")) { /* IRQs on gatwick are offset by 64 */ diff --git a/drivers/tty/serial/sunzilog.c b/drivers/tty/serial/sunzilog.c index 8e916e76b7b..5a47d1b196d 100644 --- a/drivers/tty/serial/sunzilog.c +++ b/drivers/tty/serial/sunzilog.c @@ -1397,7 +1397,7 @@ static void __devinit sunzilog_init_hw(struct uart_sunzilog_port *up) #endif } -static int zilog_irq = -1; +static int zilog_irq; static int __devinit zs_probe(struct platform_device *op) { @@ -1425,7 +1425,7 @@ static int __devinit zs_probe(struct platform_device *op) rp = sunzilog_chip_regs[inst]; - if (zilog_irq == -1) + if (!zilog_irq) zilog_irq = op->archdata.irqs[0]; up = &sunzilog_port_table[inst * 2]; @@ -1580,7 +1580,7 @@ static int __init sunzilog_init(void) if (err) goto out_unregister_uart; - if (zilog_irq != -1) { + if (!zilog_irq) { struct uart_sunzilog_port *up = sunzilog_irq_chain; err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED, "zs", sunzilog_irq_chain); @@ -1621,7 +1621,7 @@ static void __exit sunzilog_exit(void) { platform_driver_unregister(&zs_driver); - if (zilog_irq != -1) { + if (!zilog_irq) { struct uart_sunzilog_port *up = sunzilog_irq_chain; /* Disable Interrupts */ @@ -1637,7 +1637,7 @@ static void __exit sunzilog_exit(void) } free_irq(zilog_irq, sunzilog_irq_chain); - zilog_irq = -1; + zilog_irq = 0; } if (sunzilog_reg.nr) { diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index 2ebe606a2db..f99b0c965f8 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c @@ -1360,7 +1360,7 @@ static int ucc_uart_probe(struct platform_device *ofdev) } qe_port->port.irq = irq_of_parse_and_map(np, 0); - if (qe_port->port.irq == NO_IRQ) { + if (qe_port->port.irq == 0) { dev_err(&ofdev->dev, "could not map IRQ for UCC%u\n", qe_port->ucc_num + 1); ret = -EINVAL; diff --git a/drivers/tty/serial/vr41xx_siu.c b/drivers/tty/serial/vr41xx_siu.c index 83148e79ca1..cf0d9485ec0 100644 --- a/drivers/tty/serial/vr41xx_siu.c +++ b/drivers/tty/serial/vr41xx_siu.c @@ -61,7 +61,7 @@ static struct uart_port siu_uart_ports[SIU_PORTS_MAX] = { [0 ... SIU_PORTS_MAX-1] = { .lock = __SPIN_LOCK_UNLOCKED(siu_uart_ports->lock), - .irq = -1, + .irq = 0, }, }; @@ -171,7 +171,7 @@ static inline unsigned int siu_check_type(struct uart_port *port) { if (port->line == 0) return PORT_VR41XX_SIU; - if (port->line == 1 && port->irq != -1) + if (port->line == 1 && port->irq) return PORT_VR41XX_DSIU; return PORT_UNKNOWN; -- cgit v1.2.3-70-g09d2 From 79d4e9087a6ecd6bf2103bf378bf8e0d79278b5a Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:46:27 +0000 Subject: e1000e: disable Early Receive DMA on ICH LOMs Internal stress testing with jumbo frames shows the reliability of ICH9 and ICH10D devices is improved in certain corner cases by disabling the Early Receive feature. To reduce the performance impact caused by disabling this feature, the packet buffer sizes and relevant flow control settings are modified accordingly. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/e1000.h | 2 +- drivers/net/ethernet/intel/e1000e/ich8lan.c | 2 - drivers/net/ethernet/intel/e1000e/netdev.c | 60 ++++++++++++----------------- 3 files changed, 25 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index 4b3a27670a6..70bc9e90273 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -420,7 +420,7 @@ struct e1000_info { #define FLAG_HAS_FLASH (1 << 1) #define FLAG_HAS_HW_VLAN_FILTER (1 << 2) #define FLAG_HAS_WOL (1 << 3) -#define FLAG_HAS_ERT (1 << 4) +/* reserved bit4 */ #define FLAG_HAS_CTRLEXT_ON_LOAD (1 << 5) #define FLAG_HAS_SWSM_ON_LOAD (1 << 6) #define FLAG_HAS_JUMBO_FRAMES (1 << 7) diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 1b69c2d6b41..e446e058250 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -4110,7 +4110,6 @@ const struct e1000_info e1000_ich9_info = { | FLAG_HAS_WOL | FLAG_HAS_CTRLEXT_ON_LOAD | FLAG_HAS_AMT - | FLAG_HAS_ERT | FLAG_HAS_FLASH | FLAG_APME_IN_WUC, .pba = 10, @@ -4128,7 +4127,6 @@ const struct e1000_info e1000_ich10_info = { | FLAG_HAS_WOL | FLAG_HAS_CTRLEXT_ON_LOAD | FLAG_HAS_AMT - | FLAG_HAS_ERT | FLAG_HAS_FLASH | FLAG_APME_IN_WUC, .pba = 10, diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 89af6c02623..49b5ded2632 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -2947,8 +2947,7 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) * per packet. */ pages = PAGE_USE_COUNT(adapter->netdev->mtu); - if (!(adapter->flags & FLAG_HAS_ERT) && (pages <= 3) && - (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE)) + if ((pages <= 3) && (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE)) adapter->rx_ps_pages = pages; else adapter->rx_ps_pages = 0; @@ -3095,23 +3094,14 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) } ew32(RXCSUM, rxcsum); - /* - * Enable early receives on supported devices, only takes effect when - * packet size is equal or larger than the specified value (in 8 byte - * units), e.g. using jumbo frames when setting to E1000_ERT_2048 - */ - if ((adapter->flags & FLAG_HAS_ERT) || - (adapter->hw.mac.type == e1000_pch2lan)) { + if (adapter->hw.mac.type == e1000_pch2lan) { + /* + * With jumbo frames, excessive C-state transition + * latencies result in dropped transactions. + */ if (adapter->netdev->mtu > ETH_DATA_LEN) { u32 rxdctl = er32(RXDCTL(0)); ew32(RXDCTL(0), rxdctl | 0x3); - if (adapter->flags & FLAG_HAS_ERT) - ew32(ERT, E1000_ERT_2048 | (1 << 13)); - /* - * With jumbo frames and early-receive enabled, - * excessive C-state transition latencies result in - * dropped transactions. - */ pm_qos_update_request(&adapter->netdev->pm_qos_req, 55); } else { pm_qos_update_request(&adapter->netdev->pm_qos_req, @@ -3422,9 +3412,7 @@ void e1000e_reset(struct e1000_adapter *adapter) * if short on Rx space, Rx wins and must trump Tx * adjustment or use Early Receive if available */ - if ((pba < min_rx_space) && - (!(adapter->flags & FLAG_HAS_ERT))) - /* ERT enabled in e1000_configure_rx */ + if (pba < min_rx_space) pba = min_rx_space; } @@ -3438,8 +3426,6 @@ void e1000e_reset(struct e1000_adapter *adapter) * (or the size used for early receive) above it in the Rx FIFO. * Set it to the lower of: * - 90% of the Rx FIFO size, and - * - the full Rx FIFO size minus the early receive size (for parts - * with ERT support assuming ERT set to E1000_ERT_2048), or * - the full Rx FIFO size minus one full frame */ if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME) @@ -3450,14 +3436,19 @@ void e1000e_reset(struct e1000_adapter *adapter) fc->current_mode = fc->requested_mode; switch (hw->mac.type) { + case e1000_ich9lan: + case e1000_ich10lan: + if (adapter->netdev->mtu > ETH_DATA_LEN) { + pba = 14; + ew32(PBA, pba); + fc->high_water = 0x2800; + fc->low_water = fc->high_water - 8; + break; + } + /* fall-through */ default: - if ((adapter->flags & FLAG_HAS_ERT) && - (adapter->netdev->mtu > ETH_DATA_LEN)) - hwm = min(((pba << 10) * 9 / 10), - ((pba << 10) - (E1000_ERT_2048 << 3))); - else - hwm = min(((pba << 10) * 9 / 10), - ((pba << 10) - adapter->max_frame_size)); + hwm = min(((pba << 10) * 9 / 10), + ((pba << 10) - adapter->max_frame_size)); fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */ fc->low_water = fc->high_water - 8; @@ -3490,11 +3481,10 @@ void e1000e_reset(struct e1000_adapter *adapter) /* * Disable Adaptive Interrupt Moderation if 2 full packets cannot - * fit in receive buffer and early-receive not supported. + * fit in receive buffer. */ if (adapter->itr_setting & 0x3) { - if (((adapter->max_frame_size * 2) > (pba << 10)) && - !(adapter->flags & FLAG_HAS_ERT)) { + if ((adapter->max_frame_size * 2) > (pba << 10)) { if (!(adapter->flags2 & FLAG2_DISABLE_AIM)) { dev_info(&adapter->pdev->dev, "Interrupt Throttle Rate turned off\n"); @@ -3862,9 +3852,8 @@ static int e1000_open(struct net_device *netdev) E1000_MNG_DHCP_COOKIE_STATUS_VLAN)) e1000_update_mng_vlan(adapter); - /* DMA latency requirement to workaround early-receive/jumbo issue */ - if ((adapter->flags & FLAG_HAS_ERT) || - (adapter->hw.mac.type == e1000_pch2lan)) + /* DMA latency requirement to workaround jumbo issue */ + if (adapter->hw.mac.type == e1000_pch2lan) pm_qos_add_request(&adapter->netdev->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); @@ -3975,8 +3964,7 @@ static int e1000_close(struct net_device *netdev) !test_bit(__E1000_TESTING, &adapter->state)) e1000e_release_hw_control(adapter); - if ((adapter->flags & FLAG_HAS_ERT) || - (adapter->hw.mac.type == e1000_pch2lan)) + if (adapter->hw.mac.type == e1000_pch2lan) pm_qos_remove_request(&adapter->netdev->pm_qos_req); pm_runtime_put_sync(&pdev->dev); -- cgit v1.2.3-70-g09d2 From 90b82984a4ce689d7b1d7132e50bc61ac6f8b74f Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:46:33 +0000 Subject: e1000e: update workaround for 82579 intermittently disabled during S0->Sx The workaround which toggles the LANPHYPC (LAN PHY Power Control) value bit to force the MAC-Phy interconnect into PCIe mode from SMBus mode during driver load and resume should always be done except if PHY resets are blocked by the Manageability Engine (ME). Previously, the toggle was done only if PHY resets are blocked and the ME was disabled. The rest of the patch is just indentation changes as a consequence of the updated workaround. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/ich8lan.c | 103 +++++++++++++--------------- 1 file changed, 49 insertions(+), 54 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index e446e058250..50a61fcf75c 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -306,7 +306,6 @@ static void e1000_toggle_lanphypc_value_ich8lan(struct e1000_hw *hw) static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; - u32 fwsm; s32 ret_val = 0; phy->addr = 1; @@ -325,14 +324,14 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) phy->ops.power_down = e1000_power_down_phy_copper_ich8lan; phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; - /* - * The MAC-PHY interconnect may still be in SMBus mode - * after Sx->S0. If the manageability engine (ME) is - * disabled, then toggle the LANPHYPC Value bit to force - * the interconnect to PCIe mode. - */ - fwsm = er32(FWSM); - if (!(fwsm & E1000_ICH_FWSM_FW_VALID) && !e1000_check_reset_block(hw)) { + if (!e1000_check_reset_block(hw)) { + u32 fwsm = er32(FWSM); + + /* + * The MAC-PHY interconnect may still be in SMBus mode after + * Sx->S0. If resetting the PHY is not blocked, toggle the + * LANPHYPC Value bit to force the interconnect to PCIe mode. + */ e1000_toggle_lanphypc_value_ich8lan(hw); msleep(50); @@ -340,25 +339,26 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) * Gate automatic PHY configuration by hardware on * non-managed 82579 */ - if (hw->mac.type == e1000_pch2lan) + if ((hw->mac.type == e1000_pch2lan) && + !(fwsm & E1000_ICH_FWSM_FW_VALID)) e1000_gate_hw_phy_config_ich8lan(hw, true); - } - /* - * Reset the PHY before any access to it. Doing so, ensures that - * the PHY is in a known good state before we read/write PHY registers. - * The generic reset is sufficient here, because we haven't determined - * the PHY type yet. - */ - ret_val = e1000e_phy_hw_reset_generic(hw); - if (ret_val) - goto out; + /* + * Reset the PHY before any access to it. Doing so, ensures + * that the PHY is in a known good state before we read/write + * PHY registers. The generic reset is sufficient here, + * because we haven't determined the PHY type yet. + */ + ret_val = e1000e_phy_hw_reset_generic(hw); + if (ret_val) + goto out; - /* Ungate automatic PHY configuration on non-managed 82579 */ - if ((hw->mac.type == e1000_pch2lan) && - !(fwsm & E1000_ICH_FWSM_FW_VALID)) { - usleep_range(10000, 20000); - e1000_gate_hw_phy_config_ich8lan(hw, false); + /* Ungate automatic PHY configuration on non-managed 82579 */ + if ((hw->mac.type == e1000_pch2lan) && + !(fwsm & E1000_ICH_FWSM_FW_VALID)) { + usleep_range(10000, 20000); + e1000_gate_hw_phy_config_ich8lan(hw, false); + } } phy->id = e1000_phy_unknown; @@ -3736,42 +3736,37 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw) **/ void e1000_resume_workarounds_pchlan(struct e1000_hw *hw) { - u32 fwsm; + u16 phy_id1, phy_id2; + s32 ret_val; - if (hw->mac.type != e1000_pch2lan) + if ((hw->mac.type != e1000_pch2lan) || e1000_check_reset_block(hw)) return; - fwsm = er32(FWSM); - if (!(fwsm & E1000_ICH_FWSM_FW_VALID) || !e1000_check_reset_block(hw)) { - u16 phy_id1, phy_id2; - s32 ret_val; - - ret_val = hw->phy.ops.acquire(hw); - if (ret_val) { - e_dbg("Failed to acquire PHY semaphore in resume\n"); - return; - } + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) { + e_dbg("Failed to acquire PHY semaphore in resume\n"); + return; + } - /* Test access to the PHY registers by reading the ID regs */ - ret_val = hw->phy.ops.read_reg_locked(hw, PHY_ID1, &phy_id1); - if (ret_val) - goto release; - ret_val = hw->phy.ops.read_reg_locked(hw, PHY_ID2, &phy_id2); - if (ret_val) - goto release; + /* Test access to the PHY registers by reading the ID regs */ + ret_val = hw->phy.ops.read_reg_locked(hw, PHY_ID1, &phy_id1); + if (ret_val) + goto release; + ret_val = hw->phy.ops.read_reg_locked(hw, PHY_ID2, &phy_id2); + if (ret_val) + goto release; - if (hw->phy.id == ((u32)(phy_id1 << 16) | - (u32)(phy_id2 & PHY_REVISION_MASK))) - goto release; + if (hw->phy.id == ((u32)(phy_id1 << 16) | + (u32)(phy_id2 & PHY_REVISION_MASK))) + goto release; - e1000_toggle_lanphypc_value_ich8lan(hw); + e1000_toggle_lanphypc_value_ich8lan(hw); - hw->phy.ops.release(hw); - msleep(50); - e1000_phy_hw_reset(hw); - msleep(50); - return; - } + hw->phy.ops.release(hw); + msleep(50); + e1000_phy_hw_reset(hw); + msleep(50); + return; release: hw->phy.ops.release(hw); -- cgit v1.2.3-70-g09d2 From c077a9065b8d4612e4d55bd53c3563ca10d5c944 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:46:38 +0000 Subject: e1000e: ICHx/PCHx LOMs should use LPLU setting in NVM when going to Sx When going to Sx with an ICHx/PCH device, the default Low Power Link Up (LPLU, a.k.a. reverse auto-negotiation) behavior should be whatever is set in the NVM. However, the function e1000_suspend_workarounds_ich8lan() called when going to Sx always enabled LPLU in all power states. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/ich8lan.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 50a61fcf75c..00b5e34fcfa 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -3698,9 +3698,10 @@ void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw) * * During S0 to Sx transition, it is possible the link remains at gig * instead of negotiating to a lower speed. Before going to Sx, set - * 'LPLU Enabled' and 'Gig Disable' to force link speed negotiation - * to a lower speed. For PCH and newer parts, the OEM bits PHY register - * (LED, GbE disable and LPLU configurations) also needs to be written. + * 'Gig Disable' to force link speed negotiation to a lower speed based on + * the LPLU setting in the NVM or custom setting. For PCH and newer parts, + * the OEM bits PHY register (LED, GbE disable and LPLU configurations) also + * needs to be written. **/ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw) { @@ -3708,7 +3709,7 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw) s32 ret_val; phy_ctrl = er32(PHY_CTRL); - phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU | E1000_PHY_CTRL_GBE_DISABLE; + phy_ctrl |= E1000_PHY_CTRL_GBE_DISABLE; ew32(PHY_CTRL, phy_ctrl); if (hw->mac.type == e1000_ich8lan) -- cgit v1.2.3-70-g09d2 From 7f1557e1422a4cc842af641c6716714751c06865 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:46:43 +0000 Subject: e1000e: increase Rx PBA to prevent dropping received packets on 82566/82567 During bi-directional stress on some 82566/82567 devices, some received packets were dropped. Increasing the Receive Packet Buffer Allocation resolves this. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/ich8lan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 00b5e34fcfa..d99548ce4da 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -4108,7 +4108,7 @@ const struct e1000_info e1000_ich9_info = { | FLAG_HAS_AMT | FLAG_HAS_FLASH | FLAG_APME_IN_WUC, - .pba = 10, + .pba = 18, .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_ich8lan, .mac_ops = &ich8_mac_ops, @@ -4125,7 +4125,7 @@ const struct e1000_info e1000_ich10_info = { | FLAG_HAS_AMT | FLAG_HAS_FLASH | FLAG_APME_IN_WUC, - .pba = 10, + .pba = 18, .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_ich8lan, .mac_ops = &ich8_mac_ops, -- cgit v1.2.3-70-g09d2 From 464c85e37e6b2d2ad4f3bea23a59408c5595db15 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:46:49 +0000 Subject: e1000e: conditionally restart autoneg on 82577/8/9 when setting LPLU state When setting the Low Power Link Up (LPLU, a.k.a. reverse auto-negotiation) on 82577/8278/82579, do not restart auto-negotiation if reset of the Phy is blocked by the Manageability Engine. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/ich8lan.c | 4 +++- 1 file changed, 3 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 d99548ce4da..6a6e6f6d9e7 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -1921,7 +1921,9 @@ static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active) else oem_reg &= ~HV_OEM_BITS_LPLU; - oem_reg |= HV_OEM_BITS_RESTART_AN; + if (!e1000_check_reset_block(hw)) + oem_reg |= HV_OEM_BITS_RESTART_AN; + ret_val = e1e_wphy(hw, HV_OEM_BITS, oem_reg); out: -- cgit v1.2.3-70-g09d2 From 434f1392ae3a3934a33d2d16987d857c97951c3d Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:46:54 +0000 Subject: e1000e: concatenate long debug strings which span multiple lines To ease searching for debug message strings, concatenate strings that span multiple lines even if the resulting line exceeds 80 columns; these will not cause checkpatch warnings. Also, add '\n' and remove unnecessary '\r' from a few debug strings. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/80003es2lan.c | 3 +-- drivers/net/ethernet/intel/e1000e/ich8lan.c | 15 +++++---------- drivers/net/ethernet/intel/e1000e/lib.c | 20 ++++++++------------ drivers/net/ethernet/intel/e1000e/phy.c | 3 +-- 4 files changed, 15 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/80003es2lan.c b/drivers/net/ethernet/intel/e1000e/80003es2lan.c index b3a235c8ed8..f323ce507f5 100644 --- a/drivers/net/ethernet/intel/e1000e/80003es2lan.c +++ b/drivers/net/ethernet/intel/e1000e/80003es2lan.c @@ -667,8 +667,7 @@ static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw) udelay(1); if (hw->phy.autoneg_wait_to_complete) { - e_dbg("Waiting for forced speed/duplex link " - "on GG82563 phy.\n"); + e_dbg("Waiting for forced speed/duplex link on GG82563 phy.\n"); ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT, 100000, &link); diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 6a6e6f6d9e7..53e5447cbbc 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -902,8 +902,7 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) } if (!timeout) { - e_dbg("Failed to acquire the semaphore, FW or HW has it: " - "FWSM=0x%8.8x EXTCNF_CTRL=0x%8.8x)\n", + e_dbg("Failed to acquire the semaphore, FW or HW has it: FWSM=0x%8.8x EXTCNF_CTRL=0x%8.8x)\n", er32(FWSM), extcnf_ctrl); extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; ew32(EXTCNF_CTRL, extcnf_ctrl); @@ -2132,8 +2131,7 @@ static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank) return 0; } - e_dbg("Unable to determine valid NVM bank via EEC - " - "reading flash signature\n"); + e_dbg("Unable to determine valid NVM bank via EEC - reading flash signature\n"); /* fall-thru */ default: /* set bank to 0 in case flash read fails */ @@ -2245,8 +2243,7 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw) /* Check if the flash descriptor is valid */ if (hsfsts.hsf_status.fldesvalid == 0) { - e_dbg("Flash descriptor invalid. " - "SW Sequencing must be used.\n"); + e_dbg("Flash descriptor invalid. SW Sequencing must be used.\n"); return -E1000_ERR_NVM; } @@ -2446,8 +2443,7 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, /* Repeat for some time before giving up. */ continue; } else if (hsfsts.hsf_status.flcdone == 0) { - e_dbg("Timeout error - flash cycle " - "did not complete.\n"); + e_dbg("Timeout error - flash cycle did not complete.\n"); break; } } @@ -2798,8 +2794,7 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, /* Repeat for some time before giving up. */ continue; if (hsfsts.hsf_status.flcdone == 0) { - e_dbg("Timeout error - flash cycle " - "did not complete."); + e_dbg("Timeout error - flash cycle did not complete.\n"); break; } } while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT); diff --git a/drivers/net/ethernet/intel/e1000e/lib.c b/drivers/net/ethernet/intel/e1000e/lib.c index 78e3f4c0c36..e2678bda859 100644 --- a/drivers/net/ethernet/intel/e1000e/lib.c +++ b/drivers/net/ethernet/intel/e1000e/lib.c @@ -653,12 +653,10 @@ s32 e1000e_check_for_serdes_link(struct e1000_hw *hw) if (rxcw & E1000_RXCW_SYNCH) { if (!(rxcw & E1000_RXCW_IV)) { mac->serdes_has_link = true; - e_dbg("SERDES: Link up - autoneg " - "completed successfully.\n"); + e_dbg("SERDES: Link up - autoneg completed successfully.\n"); } else { mac->serdes_has_link = false; - e_dbg("SERDES: Link down - invalid" - "codewords detected in autoneg.\n"); + e_dbg("SERDES: Link down - invalid codewords detected in autoneg.\n"); } } else { mac->serdes_has_link = false; @@ -1118,8 +1116,7 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw) return ret_val; if (!(mii_status_reg & MII_SR_AUTONEG_COMPLETE)) { - e_dbg("Copper PHY and Auto Neg " - "has not completed.\n"); + e_dbg("Copper PHY and Auto Neg has not completed.\n"); return ret_val; } @@ -1183,11 +1180,10 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw) */ if (hw->fc.requested_mode == e1000_fc_full) { hw->fc.current_mode = e1000_fc_full; - e_dbg("Flow Control = FULL.\r\n"); + e_dbg("Flow Control = FULL.\n"); } else { hw->fc.current_mode = e1000_fc_rx_pause; - e_dbg("Flow Control = " - "Rx PAUSE frames only.\r\n"); + e_dbg("Flow Control = Rx PAUSE frames only.\n"); } } /* @@ -1203,7 +1199,7 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw) (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { hw->fc.current_mode = e1000_fc_tx_pause; - e_dbg("Flow Control = Tx PAUSE frames only.\r\n"); + e_dbg("Flow Control = Tx PAUSE frames only.\n"); } /* * For transmitting PAUSE frames ONLY. @@ -1218,14 +1214,14 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw) !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { hw->fc.current_mode = e1000_fc_rx_pause; - e_dbg("Flow Control = Rx PAUSE frames only.\r\n"); + e_dbg("Flow Control = Rx PAUSE frames only.\n"); } else { /* * Per the IEEE spec, at this point flow control * should be disabled. */ hw->fc.current_mode = e1000_fc_none; - e_dbg("Flow Control = NONE.\r\n"); + e_dbg("Flow Control = NONE.\n"); } /* diff --git a/drivers/net/ethernet/intel/e1000e/phy.c b/drivers/net/ethernet/intel/e1000e/phy.c index 8666476cb9b..ed70d08db5b 100644 --- a/drivers/net/ethernet/intel/e1000e/phy.c +++ b/drivers/net/ethernet/intel/e1000e/phy.c @@ -1136,8 +1136,7 @@ static s32 e1000_copper_link_autoneg(struct e1000_hw *hw) if (phy->autoneg_wait_to_complete) { ret_val = e1000_wait_autoneg(hw); if (ret_val) { - e_dbg("Error while waiting for " - "autoneg to complete\n"); + e_dbg("Error while waiting for autoneg to complete\n"); return ret_val; } } -- cgit v1.2.3-70-g09d2 From f2315bf1d1c6e9e0e05262b7910a8f1491d2d60e Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:46:59 +0000 Subject: e1000e: convert final strncpy() to strlcpy() Convert the last instances of strncpy() to the preferred strlcpy(). Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/netdev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 49b5ded2632..d6b451f9a09 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -5947,7 +5947,7 @@ static void e1000_print_device_info(struct e1000_adapter *adapter) ret_val = e1000_read_pba_string_generic(hw, pba_str, E1000_PBANUM_LENGTH); if (ret_val) - strncpy((char *)pba_str, "Unknown", sizeof(pba_str) - 1); + strlcpy((char *)pba_str, "Unknown", sizeof(pba_str)); e_info("MAC: %d, PHY: %d, PBA No: %s\n", hw->mac.type, hw->phy.type, pba_str); } @@ -6139,7 +6139,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, e1000e_set_ethtool_ops(netdev); netdev->watchdog_timeo = 5 * HZ; netif_napi_add(netdev, &adapter->napi, e1000_clean, 64); - strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1); + strlcpy(netdev->name, pci_name(pdev), sizeof(netdev->name)); netdev->mem_start = mmio_start; netdev->mem_end = mmio_start + mmio_len; @@ -6321,7 +6321,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, if (!(adapter->flags & FLAG_HAS_AMT)) e1000e_get_hw_control(adapter); - strncpy(netdev->name, "eth%d", sizeof(netdev->name) - 1); + strlcpy(netdev->name, "eth%d", sizeof(netdev->name)); err = register_netdev(netdev); if (err) goto err_register; -- cgit v1.2.3-70-g09d2 From 058e8edd11fb2c694c3c6c9fd8407439eb3eb954 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:47:04 +0000 Subject: e1000e: increase version number Signed-off-by: Bruce Allan 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 d6b451f9a09..210d27ddd8c 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -56,7 +56,7 @@ #define DRV_EXTRAVERSION "-k" -#define DRV_VERSION "1.5.1" DRV_EXTRAVERSION +#define DRV_VERSION "1.9.5" DRV_EXTRAVERSION char e1000e_driver_name[] = "e1000e"; const char e1000e_driver_version[] = DRV_VERSION; -- cgit v1.2.3-70-g09d2 From c8243ee0488d9bc12995ca7ea02f651db820622e Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Sat, 17 Dec 2011 08:32:57 +0000 Subject: e1000e: call er16flash() instead of __er16flash() __er16flash() is not meant to be called directly. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/ich8lan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 53e5447cbbc..070a90f78aa 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -2279,7 +2279,7 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw) * cycle has a chance to end before giving up. */ for (i = 0; i < ICH_FLASH_READ_COMMAND_TIMEOUT; i++) { - hsfsts.regval = __er16flash(hw, ICH_FLASH_HSFSTS); + hsfsts.regval = er16flash(ICH_FLASH_HSFSTS); if (hsfsts.hsf_status.flcinprog == 0) { ret_val = 0; break; -- cgit v1.2.3-70-g09d2 From fe2ddfb510f9d305a6654c7538c5c8faf326a16c Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 21 Dec 2011 09:47:10 +0000 Subject: e1000e: split lib.c into three more-appropriate files The generic lib.c file contains code relative to the various MACs, NVM and Manageability supported by the driver. This patch splits the file into three which are specific to those areas similar to how the PHY-specific code is in phy.c and code specific to the 80003es2lan, 8257x, and ichX MAC families are in their own files. The generic code that is applicable to all MAC/PHY parts supported by the driver remains in netdev.c, param.c and ethtool.c files. No change in functionality, just moving code around for ease of maintenance, with some whitespace and other checkpatch cleanups. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/Makefile | 3 +- drivers/net/ethernet/intel/e1000e/lib.c | 2686 ---------------------------- drivers/net/ethernet/intel/e1000e/mac.c | 1717 ++++++++++++++++++ drivers/net/ethernet/intel/e1000e/manage.c | 377 ++++ drivers/net/ethernet/intel/e1000e/nvm.c | 647 +++++++ 5 files changed, 2743 insertions(+), 2687 deletions(-) delete mode 100644 drivers/net/ethernet/intel/e1000e/lib.c create mode 100644 drivers/net/ethernet/intel/e1000e/mac.c create mode 100644 drivers/net/ethernet/intel/e1000e/manage.c create mode 100644 drivers/net/ethernet/intel/e1000e/nvm.c (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/Makefile b/drivers/net/ethernet/intel/e1000e/Makefile index 948c05db5d6..8b888e5f6a0 100644 --- a/drivers/net/ethernet/intel/e1000e/Makefile +++ b/drivers/net/ethernet/intel/e1000e/Makefile @@ -33,5 +33,6 @@ obj-$(CONFIG_E1000E) += e1000e.o e1000e-objs := 82571.o ich8lan.o 80003es2lan.o \ - lib.o phy.o param.o ethtool.o netdev.o + mac.o manage.o nvm.o phy.o \ + param.o ethtool.o netdev.o diff --git a/drivers/net/ethernet/intel/e1000e/lib.c b/drivers/net/ethernet/intel/e1000e/lib.c deleted file mode 100644 index e2678bda859..00000000000 --- a/drivers/net/ethernet/intel/e1000e/lib.c +++ /dev/null @@ -1,2686 +0,0 @@ -/******************************************************************************* - - Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. - - This program is free software; you can redistribute it and/or modify it - under the terms and conditions of the GNU General Public License, - version 2, as published by the Free Software Foundation. - - This program is distributed in the hope it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - - The full GNU General Public License is included in this distribution in - the file called "COPYING". - - Contact Information: - Linux NICS - e1000-devel Mailing List - Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - -*******************************************************************************/ - -#include "e1000.h" - -enum e1000_mng_mode { - e1000_mng_mode_none = 0, - e1000_mng_mode_asf, - e1000_mng_mode_pt, - e1000_mng_mode_ipmi, - e1000_mng_mode_host_if_only -}; - -#define E1000_FACTPS_MNGCG 0x20000000 - -/* Intel(R) Active Management Technology signature */ -#define E1000_IAMT_SIGNATURE 0x544D4149 - -/** - * e1000e_get_bus_info_pcie - Get PCIe bus information - * @hw: pointer to the HW structure - * - * Determines and stores the system bus information for a particular - * network interface. The following bus information is determined and stored: - * bus speed, bus width, type (PCIe), and PCIe function. - **/ -s32 e1000e_get_bus_info_pcie(struct e1000_hw *hw) -{ - struct e1000_mac_info *mac = &hw->mac; - struct e1000_bus_info *bus = &hw->bus; - struct e1000_adapter *adapter = hw->adapter; - u16 pcie_link_status, cap_offset; - - cap_offset = adapter->pdev->pcie_cap; - if (!cap_offset) { - bus->width = e1000_bus_width_unknown; - } else { - pci_read_config_word(adapter->pdev, - cap_offset + PCIE_LINK_STATUS, - &pcie_link_status); - bus->width = (enum e1000_bus_width)((pcie_link_status & - PCIE_LINK_WIDTH_MASK) >> - PCIE_LINK_WIDTH_SHIFT); - } - - mac->ops.set_lan_id(hw); - - return 0; -} - -/** - * e1000_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices - * - * @hw: pointer to the HW structure - * - * Determines the LAN function id by reading memory-mapped registers - * and swaps the port value if requested. - **/ -void e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw) -{ - struct e1000_bus_info *bus = &hw->bus; - u32 reg; - - /* - * The status register reports the correct function number - * for the device regardless of function swap state. - */ - reg = er32(STATUS); - bus->func = (reg & E1000_STATUS_FUNC_MASK) >> E1000_STATUS_FUNC_SHIFT; -} - -/** - * e1000_set_lan_id_single_port - Set LAN id for a single port device - * @hw: pointer to the HW structure - * - * Sets the LAN function id to zero for a single port device. - **/ -void e1000_set_lan_id_single_port(struct e1000_hw *hw) -{ - struct e1000_bus_info *bus = &hw->bus; - - bus->func = 0; -} - -/** - * e1000_clear_vfta_generic - Clear VLAN filter table - * @hw: pointer to the HW structure - * - * Clears the register array which contains the VLAN filter table by - * setting all the values to 0. - **/ -void e1000_clear_vfta_generic(struct e1000_hw *hw) -{ - u32 offset; - - for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) { - E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, 0); - e1e_flush(); - } -} - -/** - * e1000_write_vfta_generic - Write value to VLAN filter table - * @hw: pointer to the HW structure - * @offset: register offset in VLAN filter table - * @value: register value written to VLAN filter table - * - * Writes value at the given offset in the register array which stores - * the VLAN filter table. - **/ -void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value) -{ - E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value); - e1e_flush(); -} - -/** - * e1000e_init_rx_addrs - Initialize receive address's - * @hw: pointer to the HW structure - * @rar_count: receive address registers - * - * Setup the receive address registers by setting the base receive address - * register to the devices MAC address and clearing all the other receive - * address registers to 0. - **/ -void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count) -{ - u32 i; - u8 mac_addr[ETH_ALEN] = {0}; - - /* Setup the receive address */ - e_dbg("Programming MAC Address into RAR[0]\n"); - - e1000e_rar_set(hw, hw->mac.addr, 0); - - /* Zero out the other (rar_entry_count - 1) receive addresses */ - e_dbg("Clearing RAR[1-%u]\n", rar_count-1); - for (i = 1; i < rar_count; i++) - e1000e_rar_set(hw, mac_addr, i); -} - -/** - * e1000_check_alt_mac_addr_generic - Check for alternate MAC addr - * @hw: pointer to the HW structure - * - * Checks the nvm for an alternate MAC address. An alternate MAC address - * can be setup by pre-boot software and must be treated like a permanent - * address and must override the actual permanent MAC address. If an - * alternate MAC address is found it is programmed into RAR0, replacing - * the permanent address that was installed into RAR0 by the Si on reset. - * This function will return SUCCESS unless it encounters an error while - * reading the EEPROM. - **/ -s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) -{ - u32 i; - s32 ret_val = 0; - u16 offset, nvm_alt_mac_addr_offset, nvm_data; - u8 alt_mac_addr[ETH_ALEN]; - - ret_val = e1000_read_nvm(hw, NVM_COMPAT, 1, &nvm_data); - if (ret_val) - goto out; - - /* not supported on older hardware or 82573 */ - if ((hw->mac.type < e1000_82571) || (hw->mac.type == e1000_82573)) - goto out; - - ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1, - &nvm_alt_mac_addr_offset); - if (ret_val) { - e_dbg("NVM Read Error\n"); - goto out; - } - - if ((nvm_alt_mac_addr_offset == 0xFFFF) || - (nvm_alt_mac_addr_offset == 0x0000)) - /* There is no Alternate MAC Address */ - goto out; - - if (hw->bus.func == E1000_FUNC_1) - nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN1; - for (i = 0; i < ETH_ALEN; i += 2) { - offset = nvm_alt_mac_addr_offset + (i >> 1); - ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data); - if (ret_val) { - e_dbg("NVM Read Error\n"); - goto out; - } - - alt_mac_addr[i] = (u8)(nvm_data & 0xFF); - alt_mac_addr[i + 1] = (u8)(nvm_data >> 8); - } - - /* if multicast bit is set, the alternate address will not be used */ - if (is_multicast_ether_addr(alt_mac_addr)) { - e_dbg("Ignoring Alternate Mac Address with MC bit set\n"); - goto out; - } - - /* - * We have a valid alternate MAC address, and we want to treat it the - * same as the normal permanent MAC address stored by the HW into the - * RAR. Do this by mapping this address into RAR0. - */ - e1000e_rar_set(hw, alt_mac_addr, 0); - -out: - return ret_val; -} - -/** - * e1000e_rar_set - Set receive address register - * @hw: pointer to the HW structure - * @addr: pointer to the receive address - * @index: receive address array register - * - * Sets the receive address array register at index to the address passed - * in by addr. - **/ -void e1000e_rar_set(struct e1000_hw *hw, u8 *addr, u32 index) -{ - u32 rar_low, rar_high; - - /* - * HW expects these in little endian so we reverse the byte order - * from network order (big endian) to little endian - */ - rar_low = ((u32) addr[0] | - ((u32) addr[1] << 8) | - ((u32) addr[2] << 16) | ((u32) addr[3] << 24)); - - rar_high = ((u32) addr[4] | ((u32) addr[5] << 8)); - - /* If MAC address zero, no need to set the AV bit */ - if (rar_low || rar_high) - rar_high |= E1000_RAH_AV; - - /* - * Some bridges will combine consecutive 32-bit writes into - * a single burst write, which will malfunction on some parts. - * The flushes avoid this. - */ - ew32(RAL(index), rar_low); - e1e_flush(); - ew32(RAH(index), rar_high); - e1e_flush(); -} - -/** - * e1000_hash_mc_addr - Generate a multicast hash value - * @hw: pointer to the HW structure - * @mc_addr: pointer to a multicast address - * - * Generates a multicast address hash value which is used to determine - * the multicast filter table array address and new table value. See - * e1000_mta_set_generic() - **/ -static u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr) -{ - u32 hash_value, hash_mask; - u8 bit_shift = 0; - - /* Register count multiplied by bits per register */ - hash_mask = (hw->mac.mta_reg_count * 32) - 1; - - /* - * For a mc_filter_type of 0, bit_shift is the number of left-shifts - * where 0xFF would still fall within the hash mask. - */ - while (hash_mask >> bit_shift != 0xFF) - bit_shift++; - - /* - * The portion of the address that is used for the hash table - * is determined by the mc_filter_type setting. - * The algorithm is such that there is a total of 8 bits of shifting. - * The bit_shift for a mc_filter_type of 0 represents the number of - * left-shifts where the MSB of mc_addr[5] would still fall within - * the hash_mask. Case 0 does this exactly. Since there are a total - * of 8 bits of shifting, then mc_addr[4] will shift right the - * remaining number of bits. Thus 8 - bit_shift. The rest of the - * cases are a variation of this algorithm...essentially raising the - * number of bits to shift mc_addr[5] left, while still keeping the - * 8-bit shifting total. - * - * For example, given the following Destination MAC Address and an - * mta register count of 128 (thus a 4096-bit vector and 0xFFF mask), - * we can see that the bit_shift for case 0 is 4. These are the hash - * values resulting from each mc_filter_type... - * [0] [1] [2] [3] [4] [5] - * 01 AA 00 12 34 56 - * LSB MSB - * - * case 0: hash_value = ((0x34 >> 4) | (0x56 << 4)) & 0xFFF = 0x563 - * case 1: hash_value = ((0x34 >> 3) | (0x56 << 5)) & 0xFFF = 0xAC6 - * case 2: hash_value = ((0x34 >> 2) | (0x56 << 6)) & 0xFFF = 0x163 - * case 3: hash_value = ((0x34 >> 0) | (0x56 << 8)) & 0xFFF = 0x634 - */ - switch (hw->mac.mc_filter_type) { - default: - case 0: - break; - case 1: - bit_shift += 1; - break; - case 2: - bit_shift += 2; - break; - case 3: - bit_shift += 4; - break; - } - - hash_value = hash_mask & (((mc_addr[4] >> (8 - bit_shift)) | - (((u16) mc_addr[5]) << bit_shift))); - - return hash_value; -} - -/** - * e1000e_update_mc_addr_list_generic - Update Multicast addresses - * @hw: pointer to the HW structure - * @mc_addr_list: array of multicast addresses to program - * @mc_addr_count: number of multicast addresses to program - * - * Updates entire Multicast Table Array. - * The caller must have a packed mc_addr_list of multicast addresses. - **/ -void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw, - u8 *mc_addr_list, u32 mc_addr_count) -{ - u32 hash_value, hash_bit, hash_reg; - int i; - - /* clear mta_shadow */ - memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow)); - - /* update mta_shadow from mc_addr_list */ - for (i = 0; (u32) i < mc_addr_count; i++) { - hash_value = e1000_hash_mc_addr(hw, mc_addr_list); - - hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1); - hash_bit = hash_value & 0x1F; - - hw->mac.mta_shadow[hash_reg] |= (1 << hash_bit); - mc_addr_list += (ETH_ALEN); - } - - /* replace the entire MTA table */ - for (i = hw->mac.mta_reg_count - 1; i >= 0; i--) - E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, hw->mac.mta_shadow[i]); - e1e_flush(); -} - -/** - * e1000e_clear_hw_cntrs_base - Clear base hardware counters - * @hw: pointer to the HW structure - * - * Clears the base hardware counters by reading the counter registers. - **/ -void e1000e_clear_hw_cntrs_base(struct e1000_hw *hw) -{ - er32(CRCERRS); - er32(SYMERRS); - er32(MPC); - er32(SCC); - er32(ECOL); - er32(MCC); - er32(LATECOL); - er32(COLC); - er32(DC); - er32(SEC); - er32(RLEC); - er32(XONRXC); - er32(XONTXC); - er32(XOFFRXC); - er32(XOFFTXC); - er32(FCRUC); - er32(GPRC); - er32(BPRC); - er32(MPRC); - er32(GPTC); - er32(GORCL); - er32(GORCH); - er32(GOTCL); - er32(GOTCH); - er32(RNBC); - er32(RUC); - er32(RFC); - er32(ROC); - er32(RJC); - er32(TORL); - er32(TORH); - er32(TOTL); - er32(TOTH); - er32(TPR); - er32(TPT); - er32(MPTC); - er32(BPTC); -} - -/** - * e1000e_check_for_copper_link - Check for link (Copper) - * @hw: pointer to the HW structure - * - * Checks to see of the link status of the hardware has changed. If a - * change in link status has been detected, then we read the PHY registers - * to get the current speed/duplex if link exists. - **/ -s32 e1000e_check_for_copper_link(struct e1000_hw *hw) -{ - struct e1000_mac_info *mac = &hw->mac; - s32 ret_val; - bool link; - - /* - * We only want to go out to the PHY registers to see if Auto-Neg - * has completed and/or if our link status has changed. The - * get_link_status flag is set upon receiving a Link Status - * Change or Rx Sequence Error interrupt. - */ - if (!mac->get_link_status) - return 0; - - /* - * First we want to see if the MII Status Register reports - * link. If so, then we want to get the current speed/duplex - * of the PHY. - */ - ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link); - if (ret_val) - return ret_val; - - if (!link) - return ret_val; /* No link detected */ - - mac->get_link_status = false; - - /* - * Check if there was DownShift, must be checked - * immediately after link-up - */ - e1000e_check_downshift(hw); - - /* - * If we are forcing speed/duplex, then we simply return since - * we have already determined whether we have link or not. - */ - if (!mac->autoneg) { - ret_val = -E1000_ERR_CONFIG; - return ret_val; - } - - /* - * Auto-Neg is enabled. Auto Speed Detection takes care - * of MAC speed/duplex configuration. So we only need to - * configure Collision Distance in the MAC. - */ - e1000e_config_collision_dist(hw); - - /* - * Configure Flow Control now that Auto-Neg has completed. - * First, we need to restore the desired flow control - * settings because we may have had to re-autoneg with a - * different link partner. - */ - ret_val = e1000e_config_fc_after_link_up(hw); - if (ret_val) - e_dbg("Error configuring flow control\n"); - - return ret_val; -} - -/** - * e1000e_check_for_fiber_link - Check for link (Fiber) - * @hw: pointer to the HW structure - * - * Checks for link up on the hardware. If link is not up and we have - * a signal, then we need to force link up. - **/ -s32 e1000e_check_for_fiber_link(struct e1000_hw *hw) -{ - struct e1000_mac_info *mac = &hw->mac; - u32 rxcw; - u32 ctrl; - u32 status; - s32 ret_val; - - ctrl = er32(CTRL); - status = er32(STATUS); - rxcw = er32(RXCW); - - /* - * If we don't have link (auto-negotiation failed or link partner - * cannot auto-negotiate), the cable is plugged in (we have signal), - * and our link partner is not trying to auto-negotiate with us (we - * are receiving idles or data), we need to force link up. We also - * need to give auto-negotiation time to complete, in case the cable - * was just plugged in. The autoneg_failed flag does this. - */ - /* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */ - if ((ctrl & E1000_CTRL_SWDPIN1) && (!(status & E1000_STATUS_LU)) && - (!(rxcw & E1000_RXCW_C))) { - if (mac->autoneg_failed == 0) { - mac->autoneg_failed = 1; - return 0; - } - e_dbg("NOT Rx'ing /C/, disable AutoNeg and force link.\n"); - - /* Disable auto-negotiation in the TXCW register */ - ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE)); - - /* Force link-up and also force full-duplex. */ - ctrl = er32(CTRL); - ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD); - ew32(CTRL, ctrl); - - /* Configure Flow Control after forcing link up. */ - ret_val = e1000e_config_fc_after_link_up(hw); - if (ret_val) { - e_dbg("Error configuring flow control\n"); - return ret_val; - } - } else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) { - /* - * If we are forcing link and we are receiving /C/ ordered - * sets, re-enable auto-negotiation in the TXCW register - * and disable forced link in the Device Control register - * in an attempt to auto-negotiate with our link partner. - */ - e_dbg("Rx'ing /C/, enable AutoNeg and stop forcing link.\n"); - ew32(TXCW, mac->txcw); - ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); - - mac->serdes_has_link = true; - } - - return 0; -} - -/** - * e1000e_check_for_serdes_link - Check for link (Serdes) - * @hw: pointer to the HW structure - * - * Checks for link up on the hardware. If link is not up and we have - * a signal, then we need to force link up. - **/ -s32 e1000e_check_for_serdes_link(struct e1000_hw *hw) -{ - struct e1000_mac_info *mac = &hw->mac; - u32 rxcw; - u32 ctrl; - u32 status; - s32 ret_val; - - ctrl = er32(CTRL); - status = er32(STATUS); - rxcw = er32(RXCW); - - /* - * If we don't have link (auto-negotiation failed or link partner - * cannot auto-negotiate), and our link partner is not trying to - * auto-negotiate with us (we are receiving idles or data), - * we need to force link up. We also need to give auto-negotiation - * time to complete. - */ - /* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */ - if ((!(status & E1000_STATUS_LU)) && (!(rxcw & E1000_RXCW_C))) { - if (mac->autoneg_failed == 0) { - mac->autoneg_failed = 1; - return 0; - } - e_dbg("NOT Rx'ing /C/, disable AutoNeg and force link.\n"); - - /* Disable auto-negotiation in the TXCW register */ - ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE)); - - /* Force link-up and also force full-duplex. */ - ctrl = er32(CTRL); - ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD); - ew32(CTRL, ctrl); - - /* Configure Flow Control after forcing link up. */ - ret_val = e1000e_config_fc_after_link_up(hw); - if (ret_val) { - e_dbg("Error configuring flow control\n"); - return ret_val; - } - } else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) { - /* - * If we are forcing link and we are receiving /C/ ordered - * sets, re-enable auto-negotiation in the TXCW register - * and disable forced link in the Device Control register - * in an attempt to auto-negotiate with our link partner. - */ - e_dbg("Rx'ing /C/, enable AutoNeg and stop forcing link.\n"); - ew32(TXCW, mac->txcw); - ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); - - mac->serdes_has_link = true; - } else if (!(E1000_TXCW_ANE & er32(TXCW))) { - /* - * If we force link for non-auto-negotiation switch, check - * link status based on MAC synchronization for internal - * serdes media type. - */ - /* SYNCH bit and IV bit are sticky. */ - udelay(10); - rxcw = er32(RXCW); - if (rxcw & E1000_RXCW_SYNCH) { - if (!(rxcw & E1000_RXCW_IV)) { - mac->serdes_has_link = true; - e_dbg("SERDES: Link up - forced.\n"); - } - } else { - mac->serdes_has_link = false; - e_dbg("SERDES: Link down - force failed.\n"); - } - } - - if (E1000_TXCW_ANE & er32(TXCW)) { - status = er32(STATUS); - if (status & E1000_STATUS_LU) { - /* SYNCH bit and IV bit are sticky, so reread rxcw. */ - udelay(10); - rxcw = er32(RXCW); - if (rxcw & E1000_RXCW_SYNCH) { - if (!(rxcw & E1000_RXCW_IV)) { - mac->serdes_has_link = true; - e_dbg("SERDES: Link up - autoneg completed successfully.\n"); - } else { - mac->serdes_has_link = false; - e_dbg("SERDES: Link down - invalid codewords detected in autoneg.\n"); - } - } else { - mac->serdes_has_link = false; - e_dbg("SERDES: Link down - no sync.\n"); - } - } else { - mac->serdes_has_link = false; - e_dbg("SERDES: Link down - autoneg failed\n"); - } - } - - return 0; -} - -/** - * e1000_set_default_fc_generic - Set flow control default values - * @hw: pointer to the HW structure - * - * Read the EEPROM for the default values for flow control and store the - * values. - **/ -static s32 e1000_set_default_fc_generic(struct e1000_hw *hw) -{ - s32 ret_val; - u16 nvm_data; - - /* - * Read and store word 0x0F of the EEPROM. This word contains bits - * that determine the hardware's default PAUSE (flow control) mode, - * a bit that determines whether the HW defaults to enabling or - * disabling auto-negotiation, and the direction of the - * SW defined pins. If there is no SW over-ride of the flow - * control setting, then the variable hw->fc will - * be initialized based on a value in the EEPROM. - */ - ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data); - - if (ret_val) { - e_dbg("NVM Read Error\n"); - return ret_val; - } - - if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == 0) - hw->fc.requested_mode = e1000_fc_none; - else if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == - NVM_WORD0F_ASM_DIR) - hw->fc.requested_mode = e1000_fc_tx_pause; - else - hw->fc.requested_mode = e1000_fc_full; - - return 0; -} - -/** - * e1000e_setup_link - Setup flow control and link settings - * @hw: pointer to the HW structure - * - * Determines which flow control settings to use, then configures flow - * control. Calls the appropriate media-specific link configuration - * function. Assuming the adapter has a valid link partner, a valid link - * should be established. Assumes the hardware has previously been reset - * and the transmitter and receiver are not enabled. - **/ -s32 e1000e_setup_link(struct e1000_hw *hw) -{ - struct e1000_mac_info *mac = &hw->mac; - s32 ret_val; - - /* - * In the case of the phy reset being blocked, we already have a link. - * We do not need to set it up again. - */ - if (e1000_check_reset_block(hw)) - return 0; - - /* - * If requested flow control is set to default, set flow control - * based on the EEPROM flow control settings. - */ - if (hw->fc.requested_mode == e1000_fc_default) { - ret_val = e1000_set_default_fc_generic(hw); - if (ret_val) - return ret_val; - } - - /* - * Save off the requested flow control mode for use later. Depending - * on the link partner's capabilities, we may or may not use this mode. - */ - hw->fc.current_mode = hw->fc.requested_mode; - - e_dbg("After fix-ups FlowControl is now = %x\n", - hw->fc.current_mode); - - /* Call the necessary media_type subroutine to configure the link. */ - ret_val = mac->ops.setup_physical_interface(hw); - if (ret_val) - return ret_val; - - /* - * Initialize the flow control address, type, and PAUSE timer - * registers to their default values. This is done even if flow - * control is disabled, because it does not hurt anything to - * initialize these registers. - */ - e_dbg("Initializing the Flow Control address, type and timer regs\n"); - ew32(FCT, FLOW_CONTROL_TYPE); - ew32(FCAH, FLOW_CONTROL_ADDRESS_HIGH); - ew32(FCAL, FLOW_CONTROL_ADDRESS_LOW); - - ew32(FCTTV, hw->fc.pause_time); - - return e1000e_set_fc_watermarks(hw); -} - -/** - * e1000_commit_fc_settings_generic - Configure flow control - * @hw: pointer to the HW structure - * - * Write the flow control settings to the Transmit Config Word Register (TXCW) - * base on the flow control settings in e1000_mac_info. - **/ -static s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw) -{ - struct e1000_mac_info *mac = &hw->mac; - u32 txcw; - - /* - * Check for a software override of the flow control settings, and - * setup the device accordingly. If auto-negotiation is enabled, then - * software will have to set the "PAUSE" bits to the correct value in - * the Transmit Config Word Register (TXCW) and re-start auto- - * negotiation. However, if auto-negotiation is disabled, then - * software will have to manually configure the two flow control enable - * bits in the CTRL register. - * - * The possible values of the "fc" parameter are: - * 0: Flow control is completely disabled - * 1: Rx flow control is enabled (we can receive pause frames, - * but not send pause frames). - * 2: Tx flow control is enabled (we can send pause frames but we - * do not support receiving pause frames). - * 3: Both Rx and Tx flow control (symmetric) are enabled. - */ - switch (hw->fc.current_mode) { - case e1000_fc_none: - /* Flow control completely disabled by a software over-ride. */ - txcw = (E1000_TXCW_ANE | E1000_TXCW_FD); - break; - case e1000_fc_rx_pause: - /* - * Rx Flow control is enabled and Tx Flow control is disabled - * by a software over-ride. Since there really isn't a way to - * advertise that we are capable of Rx Pause ONLY, we will - * advertise that we support both symmetric and asymmetric Rx - * PAUSE. Later, we will disable the adapter's ability to send - * PAUSE frames. - */ - txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK); - break; - case e1000_fc_tx_pause: - /* - * Tx Flow control is enabled, and Rx Flow control is disabled, - * by a software over-ride. - */ - txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR); - break; - case e1000_fc_full: - /* - * Flow control (both Rx and Tx) is enabled by a software - * over-ride. - */ - txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK); - break; - default: - e_dbg("Flow control param set incorrectly\n"); - return -E1000_ERR_CONFIG; - break; - } - - ew32(TXCW, txcw); - mac->txcw = txcw; - - return 0; -} - -/** - * e1000_poll_fiber_serdes_link_generic - Poll for link up - * @hw: pointer to the HW structure - * - * Polls for link up by reading the status register, if link fails to come - * up with auto-negotiation, then the link is forced if a signal is detected. - **/ -static s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw) -{ - struct e1000_mac_info *mac = &hw->mac; - u32 i, status; - s32 ret_val; - - /* - * If we have a signal (the cable is plugged in, or assumed true for - * serdes media) then poll for a "Link-Up" indication in the Device - * Status Register. Time-out if a link isn't seen in 500 milliseconds - * seconds (Auto-negotiation should complete in less than 500 - * milliseconds even if the other end is doing it in SW). - */ - for (i = 0; i < FIBER_LINK_UP_LIMIT; i++) { - usleep_range(10000, 20000); - status = er32(STATUS); - if (status & E1000_STATUS_LU) - break; - } - if (i == FIBER_LINK_UP_LIMIT) { - e_dbg("Never got a valid link from auto-neg!!!\n"); - mac->autoneg_failed = 1; - /* - * AutoNeg failed to achieve a link, so we'll call - * mac->check_for_link. This routine will force the - * link up if we detect a signal. This will allow us to - * communicate with non-autonegotiating link partners. - */ - ret_val = mac->ops.check_for_link(hw); - if (ret_val) { - e_dbg("Error while checking for link\n"); - return ret_val; - } - mac->autoneg_failed = 0; - } else { - mac->autoneg_failed = 0; - e_dbg("Valid Link Found\n"); - } - - return 0; -} - -/** - * e1000e_setup_fiber_serdes_link - Setup link for fiber/serdes - * @hw: pointer to the HW structure - * - * Configures collision distance and flow control for fiber and serdes - * links. Upon successful setup, poll for link. - **/ -s32 e1000e_setup_fiber_serdes_link(struct e1000_hw *hw) -{ - u32 ctrl; - s32 ret_val; - - ctrl = er32(CTRL); - - /* Take the link out of reset */ - ctrl &= ~E1000_CTRL_LRST; - - e1000e_config_collision_dist(hw); - - ret_val = e1000_commit_fc_settings_generic(hw); - if (ret_val) - return ret_val; - - /* - * Since auto-negotiation is enabled, take the link out of reset (the - * link will be in reset, because we previously reset the chip). This - * will restart auto-negotiation. If auto-negotiation is successful - * then the link-up status bit will be set and the flow control enable - * bits (RFCE and TFCE) will be set according to their negotiated value. - */ - e_dbg("Auto-negotiation enabled\n"); - - ew32(CTRL, ctrl); - e1e_flush(); - usleep_range(1000, 2000); - - /* - * For these adapters, the SW definable pin 1 is set when the optics - * detect a signal. If we have a signal, then poll for a "Link-Up" - * indication. - */ - if (hw->phy.media_type == e1000_media_type_internal_serdes || - (er32(CTRL) & E1000_CTRL_SWDPIN1)) { - ret_val = e1000_poll_fiber_serdes_link_generic(hw); - } else { - e_dbg("No signal detected\n"); - } - - return 0; -} - -/** - * e1000e_config_collision_dist - Configure collision distance - * @hw: pointer to the HW structure - * - * Configures the collision distance to the default value and is used - * during link setup. Currently no func pointer exists and all - * implementations are handled in the generic version of this function. - **/ -void e1000e_config_collision_dist(struct e1000_hw *hw) -{ - u32 tctl; - - tctl = er32(TCTL); - - tctl &= ~E1000_TCTL_COLD; - tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT; - - ew32(TCTL, tctl); - e1e_flush(); -} - -/** - * e1000e_set_fc_watermarks - Set flow control high/low watermarks - * @hw: pointer to the HW structure - * - * Sets the flow control high/low threshold (watermark) registers. If - * flow control XON frame transmission is enabled, then set XON frame - * transmission as well. - **/ -s32 e1000e_set_fc_watermarks(struct e1000_hw *hw) -{ - u32 fcrtl = 0, fcrth = 0; - - /* - * Set the flow control receive threshold registers. Normally, - * these registers will be set to a default threshold that may be - * adjusted later by the driver's runtime code. However, if the - * ability to transmit pause frames is not enabled, then these - * registers will be set to 0. - */ - if (hw->fc.current_mode & e1000_fc_tx_pause) { - /* - * We need to set up the Receive Threshold high and low water - * marks as well as (optionally) enabling the transmission of - * XON frames. - */ - fcrtl = hw->fc.low_water; - fcrtl |= E1000_FCRTL_XONE; - fcrth = hw->fc.high_water; - } - ew32(FCRTL, fcrtl); - ew32(FCRTH, fcrth); - - return 0; -} - -/** - * e1000e_force_mac_fc - Force the MAC's flow control settings - * @hw: pointer to the HW structure - * - * Force the MAC's flow control settings. Sets the TFCE and RFCE bits in the - * device control register to reflect the adapter settings. TFCE and RFCE - * need to be explicitly set by software when a copper PHY is used because - * autonegotiation is managed by the PHY rather than the MAC. Software must - * also configure these bits when link is forced on a fiber connection. - **/ -s32 e1000e_force_mac_fc(struct e1000_hw *hw) -{ - u32 ctrl; - - ctrl = er32(CTRL); - - /* - * Because we didn't get link via the internal auto-negotiation - * mechanism (we either forced link or we got link via PHY - * auto-neg), we have to manually enable/disable transmit an - * receive flow control. - * - * The "Case" statement below enables/disable flow control - * according to the "hw->fc.current_mode" parameter. - * - * The possible values of the "fc" parameter are: - * 0: Flow control is completely disabled - * 1: Rx flow control is enabled (we can receive pause - * frames but not send pause frames). - * 2: Tx flow control is enabled (we can send pause frames - * frames but we do not receive pause frames). - * 3: Both Rx and Tx flow control (symmetric) is enabled. - * other: No other values should be possible at this point. - */ - e_dbg("hw->fc.current_mode = %u\n", hw->fc.current_mode); - - switch (hw->fc.current_mode) { - case e1000_fc_none: - ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE)); - break; - case e1000_fc_rx_pause: - ctrl &= (~E1000_CTRL_TFCE); - ctrl |= E1000_CTRL_RFCE; - break; - case e1000_fc_tx_pause: - ctrl &= (~E1000_CTRL_RFCE); - ctrl |= E1000_CTRL_TFCE; - break; - case e1000_fc_full: - ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE); - break; - default: - e_dbg("Flow control param set incorrectly\n"); - return -E1000_ERR_CONFIG; - } - - ew32(CTRL, ctrl); - - return 0; -} - -/** - * e1000e_config_fc_after_link_up - Configures flow control after link - * @hw: pointer to the HW structure - * - * Checks the status of auto-negotiation after link up to ensure that the - * speed and duplex were not forced. If the link needed to be forced, then - * flow control needs to be forced also. If auto-negotiation is enabled - * and did not fail, then we configure flow control based on our link - * partner. - **/ -s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw) -{ - struct e1000_mac_info *mac = &hw->mac; - s32 ret_val = 0; - u16 mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg; - u16 speed, duplex; - - /* - * Check for the case where we have fiber media and auto-neg failed - * so we had to force link. In this case, we need to force the - * configuration of the MAC to match the "fc" parameter. - */ - if (mac->autoneg_failed) { - if (hw->phy.media_type == e1000_media_type_fiber || - hw->phy.media_type == e1000_media_type_internal_serdes) - ret_val = e1000e_force_mac_fc(hw); - } else { - if (hw->phy.media_type == e1000_media_type_copper) - ret_val = e1000e_force_mac_fc(hw); - } - - if (ret_val) { - e_dbg("Error forcing flow control settings\n"); - return ret_val; - } - - /* - * Check for the case where we have copper media and auto-neg is - * enabled. In this case, we need to check and see if Auto-Neg - * has completed, and if so, how the PHY and link partner has - * flow control configured. - */ - if ((hw->phy.media_type == e1000_media_type_copper) && mac->autoneg) { - /* - * Read the MII Status Register and check to see if AutoNeg - * has completed. We read this twice because this reg has - * some "sticky" (latched) bits. - */ - ret_val = e1e_rphy(hw, PHY_STATUS, &mii_status_reg); - if (ret_val) - return ret_val; - ret_val = e1e_rphy(hw, PHY_STATUS, &mii_status_reg); - if (ret_val) - return ret_val; - - if (!(mii_status_reg & MII_SR_AUTONEG_COMPLETE)) { - e_dbg("Copper PHY and Auto Neg has not completed.\n"); - return ret_val; - } - - /* - * The AutoNeg process has completed, so we now need to - * read both the Auto Negotiation Advertisement - * Register (Address 4) and the Auto_Negotiation Base - * Page Ability Register (Address 5) to determine how - * flow control was negotiated. - */ - ret_val = e1e_rphy(hw, PHY_AUTONEG_ADV, &mii_nway_adv_reg); - if (ret_val) - return ret_val; - ret_val = - e1e_rphy(hw, PHY_LP_ABILITY, &mii_nway_lp_ability_reg); - if (ret_val) - return ret_val; - - /* - * Two bits in the Auto Negotiation Advertisement Register - * (Address 4) and two bits in the Auto Negotiation Base - * Page Ability Register (Address 5) determine flow control - * for both the PHY and the link partner. The following - * table, taken out of the IEEE 802.3ab/D6.0 dated March 25, - * 1999, describes these PAUSE resolution bits and how flow - * control is determined based upon these settings. - * NOTE: DC = Don't Care - * - * LOCAL DEVICE | LINK PARTNER - * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution - *-------|---------|-------|---------|-------------------- - * 0 | 0 | DC | DC | e1000_fc_none - * 0 | 1 | 0 | DC | e1000_fc_none - * 0 | 1 | 1 | 0 | e1000_fc_none - * 0 | 1 | 1 | 1 | e1000_fc_tx_pause - * 1 | 0 | 0 | DC | e1000_fc_none - * 1 | DC | 1 | DC | e1000_fc_full - * 1 | 1 | 0 | 0 | e1000_fc_none - * 1 | 1 | 0 | 1 | e1000_fc_rx_pause - * - * Are both PAUSE bits set to 1? If so, this implies - * Symmetric Flow Control is enabled at both ends. The - * ASM_DIR bits are irrelevant per the spec. - * - * For Symmetric Flow Control: - * - * LOCAL DEVICE | LINK PARTNER - * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result - *-------|---------|-------|---------|-------------------- - * 1 | DC | 1 | DC | E1000_fc_full - * - */ - if ((mii_nway_adv_reg & NWAY_AR_PAUSE) && - (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) { - /* - * Now we need to check if the user selected Rx ONLY - * of pause frames. In this case, we had to advertise - * FULL flow control because we could not advertise Rx - * ONLY. Hence, we must now check to see if we need to - * turn OFF the TRANSMISSION of PAUSE frames. - */ - if (hw->fc.requested_mode == e1000_fc_full) { - hw->fc.current_mode = e1000_fc_full; - e_dbg("Flow Control = FULL.\n"); - } else { - hw->fc.current_mode = e1000_fc_rx_pause; - e_dbg("Flow Control = Rx PAUSE frames only.\n"); - } - } - /* - * For receiving PAUSE frames ONLY. - * - * LOCAL DEVICE | LINK PARTNER - * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result - *-------|---------|-------|---------|-------------------- - * 0 | 1 | 1 | 1 | e1000_fc_tx_pause - */ - else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) && - (mii_nway_adv_reg & NWAY_AR_ASM_DIR) && - (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && - (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { - hw->fc.current_mode = e1000_fc_tx_pause; - e_dbg("Flow Control = Tx PAUSE frames only.\n"); - } - /* - * For transmitting PAUSE frames ONLY. - * - * LOCAL DEVICE | LINK PARTNER - * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result - *-------|---------|-------|---------|-------------------- - * 1 | 1 | 0 | 1 | e1000_fc_rx_pause - */ - else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) && - (mii_nway_adv_reg & NWAY_AR_ASM_DIR) && - !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && - (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { - hw->fc.current_mode = e1000_fc_rx_pause; - e_dbg("Flow Control = Rx PAUSE frames only.\n"); - } else { - /* - * Per the IEEE spec, at this point flow control - * should be disabled. - */ - hw->fc.current_mode = e1000_fc_none; - e_dbg("Flow Control = NONE.\n"); - } - - /* - * Now we need to do one last check... If we auto- - * negotiated to HALF DUPLEX, flow control should not be - * enabled per IEEE 802.3 spec. - */ - ret_val = mac->ops.get_link_up_info(hw, &speed, &duplex); - if (ret_val) { - e_dbg("Error getting link speed and duplex\n"); - return ret_val; - } - - if (duplex == HALF_DUPLEX) - hw->fc.current_mode = e1000_fc_none; - - /* - * Now we call a subroutine to actually force the MAC - * controller to use the correct flow control settings. - */ - ret_val = e1000e_force_mac_fc(hw); - if (ret_val) { - e_dbg("Error forcing flow control settings\n"); - return ret_val; - } - } - - return 0; -} - -/** - * e1000e_get_speed_and_duplex_copper - Retrieve current speed/duplex - * @hw: pointer to the HW structure - * @speed: stores the current speed - * @duplex: stores the current duplex - * - * Read the status register for the current speed/duplex and store the current - * speed and duplex for copper connections. - **/ -s32 e1000e_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed, u16 *duplex) -{ - u32 status; - - status = er32(STATUS); - if (status & E1000_STATUS_SPEED_1000) - *speed = SPEED_1000; - else if (status & E1000_STATUS_SPEED_100) - *speed = SPEED_100; - else - *speed = SPEED_10; - - if (status & E1000_STATUS_FD) - *duplex = FULL_DUPLEX; - else - *duplex = HALF_DUPLEX; - - e_dbg("%u Mbps, %s Duplex\n", - *speed == SPEED_1000 ? 1000 : *speed == SPEED_100 ? 100 : 10, - *duplex == FULL_DUPLEX ? "Full" : "Half"); - - return 0; -} - -/** - * e1000e_get_speed_and_duplex_fiber_serdes - Retrieve current speed/duplex - * @hw: pointer to the HW structure - * @speed: stores the current speed - * @duplex: stores the current duplex - * - * Sets the speed and duplex to gigabit full duplex (the only possible option) - * for fiber/serdes links. - **/ -s32 e1000e_get_speed_and_duplex_fiber_serdes(struct e1000_hw *hw, u16 *speed, u16 *duplex) -{ - *speed = SPEED_1000; - *duplex = FULL_DUPLEX; - - return 0; -} - -/** - * e1000e_get_hw_semaphore - Acquire hardware semaphore - * @hw: pointer to the HW structure - * - * Acquire the HW semaphore to access the PHY or NVM - **/ -s32 e1000e_get_hw_semaphore(struct e1000_hw *hw) -{ - u32 swsm; - s32 timeout = hw->nvm.word_size + 1; - s32 i = 0; - - /* Get the SW semaphore */ - while (i < timeout) { - swsm = er32(SWSM); - if (!(swsm & E1000_SWSM_SMBI)) - break; - - udelay(50); - i++; - } - - if (i == timeout) { - e_dbg("Driver can't access device - SMBI bit is set.\n"); - return -E1000_ERR_NVM; - } - - /* Get the FW semaphore. */ - for (i = 0; i < timeout; i++) { - swsm = er32(SWSM); - ew32(SWSM, swsm | E1000_SWSM_SWESMBI); - - /* Semaphore acquired if bit latched */ - if (er32(SWSM) & E1000_SWSM_SWESMBI) - break; - - udelay(50); - } - - if (i == timeout) { - /* Release semaphores */ - e1000e_put_hw_semaphore(hw); - e_dbg("Driver can't access the NVM\n"); - return -E1000_ERR_NVM; - } - - return 0; -} - -/** - * e1000e_put_hw_semaphore - Release hardware semaphore - * @hw: pointer to the HW structure - * - * Release hardware semaphore used to access the PHY or NVM - **/ -void e1000e_put_hw_semaphore(struct e1000_hw *hw) -{ - u32 swsm; - - swsm = er32(SWSM); - swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI); - ew32(SWSM, swsm); -} - -/** - * e1000e_get_auto_rd_done - Check for auto read completion - * @hw: pointer to the HW structure - * - * Check EEPROM for Auto Read done bit. - **/ -s32 e1000e_get_auto_rd_done(struct e1000_hw *hw) -{ - s32 i = 0; - - while (i < AUTO_READ_DONE_TIMEOUT) { - if (er32(EECD) & E1000_EECD_AUTO_RD) - break; - usleep_range(1000, 2000); - i++; - } - - if (i == AUTO_READ_DONE_TIMEOUT) { - e_dbg("Auto read by HW from NVM has not completed.\n"); - return -E1000_ERR_RESET; - } - - return 0; -} - -/** - * e1000e_valid_led_default - Verify a valid default LED config - * @hw: pointer to the HW structure - * @data: pointer to the NVM (EEPROM) - * - * Read the EEPROM for the current default LED configuration. If the - * LED configuration is not valid, set to a valid LED configuration. - **/ -s32 e1000e_valid_led_default(struct e1000_hw *hw, u16 *data) -{ - s32 ret_val; - - ret_val = e1000_read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data); - if (ret_val) { - e_dbg("NVM Read Error\n"); - return ret_val; - } - - if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) - *data = ID_LED_DEFAULT; - - return 0; -} - -/** - * e1000e_id_led_init - - * @hw: pointer to the HW structure - * - **/ -s32 e1000e_id_led_init(struct e1000_hw *hw) -{ - struct e1000_mac_info *mac = &hw->mac; - s32 ret_val; - const u32 ledctl_mask = 0x000000FF; - const u32 ledctl_on = E1000_LEDCTL_MODE_LED_ON; - const u32 ledctl_off = E1000_LEDCTL_MODE_LED_OFF; - u16 data, i, temp; - const u16 led_mask = 0x0F; - - ret_val = hw->nvm.ops.valid_led_default(hw, &data); - if (ret_val) - return ret_val; - - mac->ledctl_default = er32(LEDCTL); - mac->ledctl_mode1 = mac->ledctl_default; - mac->ledctl_mode2 = mac->ledctl_default; - - for (i = 0; i < 4; i++) { - temp = (data >> (i << 2)) & led_mask; - switch (temp) { - case ID_LED_ON1_DEF2: - case ID_LED_ON1_ON2: - case ID_LED_ON1_OFF2: - mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3)); - mac->ledctl_mode1 |= ledctl_on << (i << 3); - break; - case ID_LED_OFF1_DEF2: - case ID_LED_OFF1_ON2: - case ID_LED_OFF1_OFF2: - mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3)); - mac->ledctl_mode1 |= ledctl_off << (i << 3); - break; - default: - /* Do nothing */ - break; - } - switch (temp) { - case ID_LED_DEF1_ON2: - case ID_LED_ON1_ON2: - case ID_LED_OFF1_ON2: - mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3)); - mac->ledctl_mode2 |= ledctl_on << (i << 3); - break; - case ID_LED_DEF1_OFF2: - case ID_LED_ON1_OFF2: - case ID_LED_OFF1_OFF2: - mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3)); - mac->ledctl_mode2 |= ledctl_off << (i << 3); - break; - default: - /* Do nothing */ - break; - } - } - - return 0; -} - -/** - * e1000e_setup_led_generic - Configures SW controllable LED - * @hw: pointer to the HW structure - * - * This prepares the SW controllable LED for use and saves the current state - * of the LED so it can be later restored. - **/ -s32 e1000e_setup_led_generic(struct e1000_hw *hw) -{ - u32 ledctl; - - if (hw->mac.ops.setup_led != e1000e_setup_led_generic) - return -E1000_ERR_CONFIG; - - if (hw->phy.media_type == e1000_media_type_fiber) { - ledctl = er32(LEDCTL); - hw->mac.ledctl_default = ledctl; - /* Turn off LED0 */ - ledctl &= ~(E1000_LEDCTL_LED0_IVRT | - E1000_LEDCTL_LED0_BLINK | - E1000_LEDCTL_LED0_MODE_MASK); - ledctl |= (E1000_LEDCTL_MODE_LED_OFF << - E1000_LEDCTL_LED0_MODE_SHIFT); - ew32(LEDCTL, ledctl); - } else if (hw->phy.media_type == e1000_media_type_copper) { - ew32(LEDCTL, hw->mac.ledctl_mode1); - } - - return 0; -} - -/** - * e1000e_cleanup_led_generic - Set LED config to default operation - * @hw: pointer to the HW structure - * - * Remove the current LED configuration and set the LED configuration - * to the default value, saved from the EEPROM. - **/ -s32 e1000e_cleanup_led_generic(struct e1000_hw *hw) -{ - ew32(LEDCTL, hw->mac.ledctl_default); - return 0; -} - -/** - * e1000e_blink_led_generic - Blink LED - * @hw: pointer to the HW structure - * - * Blink the LEDs which are set to be on. - **/ -s32 e1000e_blink_led_generic(struct e1000_hw *hw) -{ - u32 ledctl_blink = 0; - u32 i; - - if (hw->phy.media_type == e1000_media_type_fiber) { - /* always blink LED0 for PCI-E fiber */ - ledctl_blink = E1000_LEDCTL_LED0_BLINK | - (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED0_MODE_SHIFT); - } else { - /* - * set the blink bit for each LED that's "on" (0x0E) - * in ledctl_mode2 - */ - ledctl_blink = hw->mac.ledctl_mode2; - for (i = 0; i < 4; i++) - if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) == - E1000_LEDCTL_MODE_LED_ON) - ledctl_blink |= (E1000_LEDCTL_LED0_BLINK << - (i * 8)); - } - - ew32(LEDCTL, ledctl_blink); - - return 0; -} - -/** - * e1000e_led_on_generic - Turn LED on - * @hw: pointer to the HW structure - * - * Turn LED on. - **/ -s32 e1000e_led_on_generic(struct e1000_hw *hw) -{ - u32 ctrl; - - switch (hw->phy.media_type) { - case e1000_media_type_fiber: - ctrl = er32(CTRL); - ctrl &= ~E1000_CTRL_SWDPIN0; - ctrl |= E1000_CTRL_SWDPIO0; - ew32(CTRL, ctrl); - break; - case e1000_media_type_copper: - ew32(LEDCTL, hw->mac.ledctl_mode2); - break; - default: - break; - } - - return 0; -} - -/** - * e1000e_led_off_generic - Turn LED off - * @hw: pointer to the HW structure - * - * Turn LED off. - **/ -s32 e1000e_led_off_generic(struct e1000_hw *hw) -{ - u32 ctrl; - - switch (hw->phy.media_type) { - case e1000_media_type_fiber: - ctrl = er32(CTRL); - ctrl |= E1000_CTRL_SWDPIN0; - ctrl |= E1000_CTRL_SWDPIO0; - ew32(CTRL, ctrl); - break; - case e1000_media_type_copper: - ew32(LEDCTL, hw->mac.ledctl_mode1); - break; - default: - break; - } - - return 0; -} - -/** - * e1000e_set_pcie_no_snoop - Set PCI-express capabilities - * @hw: pointer to the HW structure - * @no_snoop: bitmap of snoop events - * - * Set the PCI-express register to snoop for events enabled in 'no_snoop'. - **/ -void e1000e_set_pcie_no_snoop(struct e1000_hw *hw, u32 no_snoop) -{ - u32 gcr; - - if (no_snoop) { - gcr = er32(GCR); - gcr &= ~(PCIE_NO_SNOOP_ALL); - gcr |= no_snoop; - ew32(GCR, gcr); - } -} - -/** - * e1000e_disable_pcie_master - Disables PCI-express master access - * @hw: pointer to the HW structure - * - * Returns 0 if successful, else returns -10 - * (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not caused - * the master requests to be disabled. - * - * Disables PCI-Express master access and verifies there are no pending - * requests. - **/ -s32 e1000e_disable_pcie_master(struct e1000_hw *hw) -{ - u32 ctrl; - s32 timeout = MASTER_DISABLE_TIMEOUT; - - ctrl = er32(CTRL); - ctrl |= E1000_CTRL_GIO_MASTER_DISABLE; - ew32(CTRL, ctrl); - - while (timeout) { - if (!(er32(STATUS) & - E1000_STATUS_GIO_MASTER_ENABLE)) - break; - udelay(100); - timeout--; - } - - if (!timeout) { - e_dbg("Master requests are pending.\n"); - return -E1000_ERR_MASTER_REQUESTS_PENDING; - } - - return 0; -} - -/** - * e1000e_reset_adaptive - Reset Adaptive Interframe Spacing - * @hw: pointer to the HW structure - * - * Reset the Adaptive Interframe Spacing throttle to default values. - **/ -void e1000e_reset_adaptive(struct e1000_hw *hw) -{ - struct e1000_mac_info *mac = &hw->mac; - - if (!mac->adaptive_ifs) { - e_dbg("Not in Adaptive IFS mode!\n"); - goto out; - } - - mac->current_ifs_val = 0; - mac->ifs_min_val = IFS_MIN; - mac->ifs_max_val = IFS_MAX; - mac->ifs_step_size = IFS_STEP; - mac->ifs_ratio = IFS_RATIO; - - mac->in_ifs_mode = false; - ew32(AIT, 0); -out: - return; -} - -/** - * e1000e_update_adaptive - Update Adaptive Interframe Spacing - * @hw: pointer to the HW structure - * - * Update the Adaptive Interframe Spacing Throttle value based on the - * time between transmitted packets and time between collisions. - **/ -void e1000e_update_adaptive(struct e1000_hw *hw) -{ - struct e1000_mac_info *mac = &hw->mac; - - if (!mac->adaptive_ifs) { - e_dbg("Not in Adaptive IFS mode!\n"); - goto out; - } - - if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) { - if (mac->tx_packet_delta > MIN_NUM_XMITS) { - mac->in_ifs_mode = true; - if (mac->current_ifs_val < mac->ifs_max_val) { - if (!mac->current_ifs_val) - mac->current_ifs_val = mac->ifs_min_val; - else - mac->current_ifs_val += - mac->ifs_step_size; - ew32(AIT, mac->current_ifs_val); - } - } - } else { - if (mac->in_ifs_mode && - (mac->tx_packet_delta <= MIN_NUM_XMITS)) { - mac->current_ifs_val = 0; - mac->in_ifs_mode = false; - ew32(AIT, 0); - } - } -out: - return; -} - -/** - * e1000_raise_eec_clk - Raise EEPROM clock - * @hw: pointer to the HW structure - * @eecd: pointer to the EEPROM - * - * Enable/Raise the EEPROM clock bit. - **/ -static void e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd) -{ - *eecd = *eecd | E1000_EECD_SK; - ew32(EECD, *eecd); - e1e_flush(); - udelay(hw->nvm.delay_usec); -} - -/** - * e1000_lower_eec_clk - Lower EEPROM clock - * @hw: pointer to the HW structure - * @eecd: pointer to the EEPROM - * - * Clear/Lower the EEPROM clock bit. - **/ -static void e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd) -{ - *eecd = *eecd & ~E1000_EECD_SK; - ew32(EECD, *eecd); - e1e_flush(); - udelay(hw->nvm.delay_usec); -} - -/** - * e1000_shift_out_eec_bits - Shift data bits our to the EEPROM - * @hw: pointer to the HW structure - * @data: data to send to the EEPROM - * @count: number of bits to shift out - * - * We need to shift 'count' bits out to the EEPROM. So, the value in the - * "data" parameter will be shifted out to the EEPROM one bit at a time. - * In order to do this, "data" must be broken down into bits. - **/ -static void e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count) -{ - struct e1000_nvm_info *nvm = &hw->nvm; - u32 eecd = er32(EECD); - u32 mask; - - mask = 0x01 << (count - 1); - if (nvm->type == e1000_nvm_eeprom_spi) - eecd |= E1000_EECD_DO; - - do { - eecd &= ~E1000_EECD_DI; - - if (data & mask) - eecd |= E1000_EECD_DI; - - ew32(EECD, eecd); - e1e_flush(); - - udelay(nvm->delay_usec); - - e1000_raise_eec_clk(hw, &eecd); - e1000_lower_eec_clk(hw, &eecd); - - mask >>= 1; - } while (mask); - - eecd &= ~E1000_EECD_DI; - ew32(EECD, eecd); -} - -/** - * e1000_shift_in_eec_bits - Shift data bits in from the EEPROM - * @hw: pointer to the HW structure - * @count: number of bits to shift in - * - * In order to read a register from the EEPROM, we need to shift 'count' bits - * in from the EEPROM. Bits are "shifted in" by raising the clock input to - * the EEPROM (setting the SK bit), and then reading the value of the data out - * "DO" bit. During this "shifting in" process the data in "DI" bit should - * always be clear. - **/ -static u16 e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count) -{ - u32 eecd; - u32 i; - u16 data; - - eecd = er32(EECD); - - eecd &= ~(E1000_EECD_DO | E1000_EECD_DI); - data = 0; - - for (i = 0; i < count; i++) { - data <<= 1; - e1000_raise_eec_clk(hw, &eecd); - - eecd = er32(EECD); - - eecd &= ~E1000_EECD_DI; - if (eecd & E1000_EECD_DO) - data |= 1; - - e1000_lower_eec_clk(hw, &eecd); - } - - return data; -} - -/** - * e1000e_poll_eerd_eewr_done - Poll for EEPROM read/write completion - * @hw: pointer to the HW structure - * @ee_reg: EEPROM flag for polling - * - * Polls the EEPROM status bit for either read or write completion based - * upon the value of 'ee_reg'. - **/ -s32 e1000e_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg) -{ - u32 attempts = 100000; - u32 i, reg = 0; - - for (i = 0; i < attempts; i++) { - if (ee_reg == E1000_NVM_POLL_READ) - reg = er32(EERD); - else - reg = er32(EEWR); - - if (reg & E1000_NVM_RW_REG_DONE) - return 0; - - udelay(5); - } - - return -E1000_ERR_NVM; -} - -/** - * e1000e_acquire_nvm - Generic request for access to EEPROM - * @hw: pointer to the HW structure - * - * Set the EEPROM access request bit and wait for EEPROM access grant bit. - * Return successful if access grant bit set, else clear the request for - * EEPROM access and return -E1000_ERR_NVM (-1). - **/ -s32 e1000e_acquire_nvm(struct e1000_hw *hw) -{ - u32 eecd = er32(EECD); - s32 timeout = E1000_NVM_GRANT_ATTEMPTS; - - ew32(EECD, eecd | E1000_EECD_REQ); - eecd = er32(EECD); - - while (timeout) { - if (eecd & E1000_EECD_GNT) - break; - udelay(5); - eecd = er32(EECD); - timeout--; - } - - if (!timeout) { - eecd &= ~E1000_EECD_REQ; - ew32(EECD, eecd); - e_dbg("Could not acquire NVM grant\n"); - return -E1000_ERR_NVM; - } - - return 0; -} - -/** - * e1000_standby_nvm - Return EEPROM to standby state - * @hw: pointer to the HW structure - * - * Return the EEPROM to a standby state. - **/ -static void e1000_standby_nvm(struct e1000_hw *hw) -{ - struct e1000_nvm_info *nvm = &hw->nvm; - u32 eecd = er32(EECD); - - if (nvm->type == e1000_nvm_eeprom_spi) { - /* Toggle CS to flush commands */ - eecd |= E1000_EECD_CS; - ew32(EECD, eecd); - e1e_flush(); - udelay(nvm->delay_usec); - eecd &= ~E1000_EECD_CS; - ew32(EECD, eecd); - e1e_flush(); - udelay(nvm->delay_usec); - } -} - -/** - * e1000_stop_nvm - Terminate EEPROM command - * @hw: pointer to the HW structure - * - * Terminates the current command by inverting the EEPROM's chip select pin. - **/ -static void e1000_stop_nvm(struct e1000_hw *hw) -{ - u32 eecd; - - eecd = er32(EECD); - if (hw->nvm.type == e1000_nvm_eeprom_spi) { - /* Pull CS high */ - eecd |= E1000_EECD_CS; - e1000_lower_eec_clk(hw, &eecd); - } -} - -/** - * e1000e_release_nvm - Release exclusive access to EEPROM - * @hw: pointer to the HW structure - * - * Stop any current commands to the EEPROM and clear the EEPROM request bit. - **/ -void e1000e_release_nvm(struct e1000_hw *hw) -{ - u32 eecd; - - e1000_stop_nvm(hw); - - eecd = er32(EECD); - eecd &= ~E1000_EECD_REQ; - ew32(EECD, eecd); -} - -/** - * e1000_ready_nvm_eeprom - Prepares EEPROM for read/write - * @hw: pointer to the HW structure - * - * Setups the EEPROM for reading and writing. - **/ -static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw) -{ - struct e1000_nvm_info *nvm = &hw->nvm; - u32 eecd = er32(EECD); - u8 spi_stat_reg; - - if (nvm->type == e1000_nvm_eeprom_spi) { - u16 timeout = NVM_MAX_RETRY_SPI; - - /* Clear SK and CS */ - eecd &= ~(E1000_EECD_CS | E1000_EECD_SK); - ew32(EECD, eecd); - e1e_flush(); - udelay(1); - - /* - * Read "Status Register" repeatedly until the LSB is cleared. - * The EEPROM will signal that the command has been completed - * by clearing bit 0 of the internal status register. If it's - * not cleared within 'timeout', then error out. - */ - while (timeout) { - e1000_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI, - hw->nvm.opcode_bits); - spi_stat_reg = (u8)e1000_shift_in_eec_bits(hw, 8); - if (!(spi_stat_reg & NVM_STATUS_RDY_SPI)) - break; - - udelay(5); - e1000_standby_nvm(hw); - timeout--; - } - - if (!timeout) { - e_dbg("SPI NVM Status error\n"); - return -E1000_ERR_NVM; - } - } - - return 0; -} - -/** - * e1000e_read_nvm_eerd - Reads EEPROM using EERD register - * @hw: pointer to the HW structure - * @offset: offset of word in the EEPROM to read - * @words: number of words to read - * @data: word read from the EEPROM - * - * Reads a 16 bit word from the EEPROM using the EERD register. - **/ -s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) -{ - struct e1000_nvm_info *nvm = &hw->nvm; - u32 i, eerd = 0; - s32 ret_val = 0; - - /* - * A check for invalid values: offset too large, too many words, - * too many words for the offset, and not enough words. - */ - if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || - (words == 0)) { - e_dbg("nvm parameter(s) out of bounds\n"); - return -E1000_ERR_NVM; - } - - for (i = 0; i < words; i++) { - eerd = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) + - E1000_NVM_RW_REG_START; - - ew32(EERD, eerd); - ret_val = e1000e_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ); - if (ret_val) - break; - - data[i] = (er32(EERD) >> E1000_NVM_RW_REG_DATA); - } - - return ret_val; -} - -/** - * e1000e_write_nvm_spi - Write to EEPROM using SPI - * @hw: pointer to the HW structure - * @offset: offset within the EEPROM to be written to - * @words: number of words to write - * @data: 16 bit word(s) to be written to the EEPROM - * - * Writes data to EEPROM at offset using SPI interface. - * - * If e1000e_update_nvm_checksum is not called after this function , the - * EEPROM will most likely contain an invalid checksum. - **/ -s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) -{ - struct e1000_nvm_info *nvm = &hw->nvm; - s32 ret_val; - u16 widx = 0; - - /* - * A check for invalid values: offset too large, too many words, - * and not enough words. - */ - if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || - (words == 0)) { - e_dbg("nvm parameter(s) out of bounds\n"); - return -E1000_ERR_NVM; - } - - ret_val = nvm->ops.acquire(hw); - if (ret_val) - return ret_val; - - while (widx < words) { - u8 write_opcode = NVM_WRITE_OPCODE_SPI; - - ret_val = e1000_ready_nvm_eeprom(hw); - if (ret_val) { - nvm->ops.release(hw); - return ret_val; - } - - e1000_standby_nvm(hw); - - /* Send the WRITE ENABLE command (8 bit opcode) */ - e1000_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI, - nvm->opcode_bits); - - e1000_standby_nvm(hw); - - /* - * Some SPI eeproms use the 8th address bit embedded in the - * opcode - */ - if ((nvm->address_bits == 8) && (offset >= 128)) - write_opcode |= NVM_A8_OPCODE_SPI; - - /* Send the Write command (8-bit opcode + addr) */ - e1000_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits); - e1000_shift_out_eec_bits(hw, (u16)((offset + widx) * 2), - nvm->address_bits); - - /* Loop to allow for up to whole page write of eeprom */ - while (widx < words) { - u16 word_out = data[widx]; - word_out = (word_out >> 8) | (word_out << 8); - e1000_shift_out_eec_bits(hw, word_out, 16); - widx++; - - if ((((offset + widx) * 2) % nvm->page_size) == 0) { - e1000_standby_nvm(hw); - break; - } - } - } - - usleep_range(10000, 20000); - nvm->ops.release(hw); - return 0; -} - -/** - * e1000_read_pba_string_generic - Read device part number - * @hw: pointer to the HW structure - * @pba_num: pointer to device part number - * @pba_num_size: size of part number buffer - * - * Reads the product board assembly (PBA) number from the EEPROM and stores - * the value in pba_num. - **/ -s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num, - u32 pba_num_size) -{ - s32 ret_val; - u16 nvm_data; - u16 pba_ptr; - u16 offset; - u16 length; - - if (pba_num == NULL) { - e_dbg("PBA string buffer was null\n"); - ret_val = E1000_ERR_INVALID_ARGUMENT; - goto out; - } - - ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data); - if (ret_val) { - e_dbg("NVM Read Error\n"); - goto out; - } - - ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr); - if (ret_val) { - e_dbg("NVM Read Error\n"); - goto out; - } - - /* - * if nvm_data is not ptr guard the PBA must be in legacy format which - * means pba_ptr is actually our second data word for the PBA number - * and we can decode it into an ascii string - */ - if (nvm_data != NVM_PBA_PTR_GUARD) { - e_dbg("NVM PBA number is not stored as string\n"); - - /* we will need 11 characters to store the PBA */ - if (pba_num_size < 11) { - e_dbg("PBA string buffer too small\n"); - return E1000_ERR_NO_SPACE; - } - - /* extract hex string from data and pba_ptr */ - pba_num[0] = (nvm_data >> 12) & 0xF; - pba_num[1] = (nvm_data >> 8) & 0xF; - pba_num[2] = (nvm_data >> 4) & 0xF; - pba_num[3] = nvm_data & 0xF; - pba_num[4] = (pba_ptr >> 12) & 0xF; - pba_num[5] = (pba_ptr >> 8) & 0xF; - pba_num[6] = '-'; - pba_num[7] = 0; - pba_num[8] = (pba_ptr >> 4) & 0xF; - pba_num[9] = pba_ptr & 0xF; - - /* put a null character on the end of our string */ - pba_num[10] = '\0'; - - /* switch all the data but the '-' to hex char */ - for (offset = 0; offset < 10; offset++) { - if (pba_num[offset] < 0xA) - pba_num[offset] += '0'; - else if (pba_num[offset] < 0x10) - pba_num[offset] += 'A' - 0xA; - } - - goto out; - } - - ret_val = e1000_read_nvm(hw, pba_ptr, 1, &length); - if (ret_val) { - e_dbg("NVM Read Error\n"); - goto out; - } - - if (length == 0xFFFF || length == 0) { - e_dbg("NVM PBA number section invalid length\n"); - ret_val = E1000_ERR_NVM_PBA_SECTION; - goto out; - } - /* check if pba_num buffer is big enough */ - if (pba_num_size < (((u32)length * 2) - 1)) { - e_dbg("PBA string buffer too small\n"); - ret_val = E1000_ERR_NO_SPACE; - goto out; - } - - /* trim pba length from start of string */ - pba_ptr++; - length--; - - for (offset = 0; offset < length; offset++) { - ret_val = e1000_read_nvm(hw, pba_ptr + offset, 1, &nvm_data); - if (ret_val) { - e_dbg("NVM Read Error\n"); - goto out; - } - pba_num[offset * 2] = (u8)(nvm_data >> 8); - pba_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF); - } - pba_num[offset * 2] = '\0'; - -out: - return ret_val; -} - -/** - * e1000_read_mac_addr_generic - Read device MAC address - * @hw: pointer to the HW structure - * - * Reads the device MAC address from the EEPROM and stores the value. - * Since devices with two ports use the same EEPROM, we increment the - * last bit in the MAC address for the second port. - **/ -s32 e1000_read_mac_addr_generic(struct e1000_hw *hw) -{ - u32 rar_high; - u32 rar_low; - u16 i; - - rar_high = er32(RAH(0)); - rar_low = er32(RAL(0)); - - for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++) - hw->mac.perm_addr[i] = (u8)(rar_low >> (i*8)); - - for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++) - hw->mac.perm_addr[i+4] = (u8)(rar_high >> (i*8)); - - for (i = 0; i < ETH_ALEN; i++) - hw->mac.addr[i] = hw->mac.perm_addr[i]; - - return 0; -} - -/** - * e1000e_validate_nvm_checksum_generic - Validate EEPROM checksum - * @hw: pointer to the HW structure - * - * Calculates the EEPROM checksum by reading/adding each word of the EEPROM - * and then verifies that the sum of the EEPROM is equal to 0xBABA. - **/ -s32 e1000e_validate_nvm_checksum_generic(struct e1000_hw *hw) -{ - s32 ret_val; - u16 checksum = 0; - u16 i, nvm_data; - - for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) { - ret_val = e1000_read_nvm(hw, i, 1, &nvm_data); - if (ret_val) { - e_dbg("NVM Read Error\n"); - return ret_val; - } - checksum += nvm_data; - } - - if (checksum != (u16) NVM_SUM) { - e_dbg("NVM Checksum Invalid\n"); - return -E1000_ERR_NVM; - } - - return 0; -} - -/** - * e1000e_update_nvm_checksum_generic - Update EEPROM checksum - * @hw: pointer to the HW structure - * - * Updates the EEPROM checksum by reading/adding each word of the EEPROM - * up to the checksum. Then calculates the EEPROM checksum and writes the - * value to the EEPROM. - **/ -s32 e1000e_update_nvm_checksum_generic(struct e1000_hw *hw) -{ - s32 ret_val; - u16 checksum = 0; - u16 i, nvm_data; - - for (i = 0; i < NVM_CHECKSUM_REG; i++) { - ret_val = e1000_read_nvm(hw, i, 1, &nvm_data); - if (ret_val) { - e_dbg("NVM Read Error while updating checksum.\n"); - return ret_val; - } - checksum += nvm_data; - } - checksum = (u16) NVM_SUM - checksum; - ret_val = e1000_write_nvm(hw, NVM_CHECKSUM_REG, 1, &checksum); - if (ret_val) - e_dbg("NVM Write Error while updating checksum.\n"); - - return ret_val; -} - -/** - * e1000e_reload_nvm - Reloads EEPROM - * @hw: pointer to the HW structure - * - * Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the - * extended control register. - **/ -void e1000e_reload_nvm(struct e1000_hw *hw) -{ - u32 ctrl_ext; - - udelay(10); - ctrl_ext = er32(CTRL_EXT); - ctrl_ext |= E1000_CTRL_EXT_EE_RST; - ew32(CTRL_EXT, ctrl_ext); - e1e_flush(); -} - -/** - * e1000_calculate_checksum - Calculate checksum for buffer - * @buffer: pointer to EEPROM - * @length: size of EEPROM to calculate a checksum for - * - * Calculates the checksum for some buffer on a specified length. The - * checksum calculated is returned. - **/ -static u8 e1000_calculate_checksum(u8 *buffer, u32 length) -{ - u32 i; - u8 sum = 0; - - if (!buffer) - return 0; - - for (i = 0; i < length; i++) - sum += buffer[i]; - - return (u8) (0 - sum); -} - -/** - * e1000_mng_enable_host_if - Checks host interface is enabled - * @hw: pointer to the HW structure - * - * Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND - * - * This function checks whether the HOST IF is enabled for command operation - * and also checks whether the previous command is completed. It busy waits - * in case of previous command is not completed. - **/ -static s32 e1000_mng_enable_host_if(struct e1000_hw *hw) -{ - u32 hicr; - u8 i; - - if (!(hw->mac.arc_subsystem_valid)) { - e_dbg("ARC subsystem not valid.\n"); - return -E1000_ERR_HOST_INTERFACE_COMMAND; - } - - /* Check that the host interface is enabled. */ - hicr = er32(HICR); - if ((hicr & E1000_HICR_EN) == 0) { - e_dbg("E1000_HOST_EN bit disabled.\n"); - return -E1000_ERR_HOST_INTERFACE_COMMAND; - } - /* check the previous command is completed */ - for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) { - hicr = er32(HICR); - if (!(hicr & E1000_HICR_C)) - break; - mdelay(1); - } - - if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) { - e_dbg("Previous command timeout failed .\n"); - return -E1000_ERR_HOST_INTERFACE_COMMAND; - } - - return 0; -} - -/** - * e1000e_check_mng_mode_generic - check management mode - * @hw: pointer to the HW structure - * - * Reads the firmware semaphore register and returns true (>0) if - * manageability is enabled, else false (0). - **/ -bool e1000e_check_mng_mode_generic(struct e1000_hw *hw) -{ - u32 fwsm = er32(FWSM); - - return (fwsm & E1000_FWSM_MODE_MASK) == - (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT); -} - -/** - * e1000e_enable_tx_pkt_filtering - Enable packet filtering on Tx - * @hw: pointer to the HW structure - * - * Enables packet filtering on transmit packets if manageability is enabled - * and host interface is enabled. - **/ -bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw) -{ - struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie; - u32 *buffer = (u32 *)&hw->mng_cookie; - u32 offset; - s32 ret_val, hdr_csum, csum; - u8 i, len; - - hw->mac.tx_pkt_filtering = true; - - /* No manageability, no filtering */ - if (!e1000e_check_mng_mode(hw)) { - hw->mac.tx_pkt_filtering = false; - goto out; - } - - /* - * If we can't read from the host interface for whatever - * reason, disable filtering. - */ - ret_val = e1000_mng_enable_host_if(hw); - if (ret_val) { - hw->mac.tx_pkt_filtering = false; - goto out; - } - - /* Read in the header. Length and offset are in dwords. */ - len = E1000_MNG_DHCP_COOKIE_LENGTH >> 2; - offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2; - for (i = 0; i < len; i++) - *(buffer + i) = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF, offset + i); - hdr_csum = hdr->checksum; - hdr->checksum = 0; - csum = e1000_calculate_checksum((u8 *)hdr, - E1000_MNG_DHCP_COOKIE_LENGTH); - /* - * If either the checksums or signature don't match, then - * the cookie area isn't considered valid, in which case we - * take the safe route of assuming Tx filtering is enabled. - */ - if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) { - hw->mac.tx_pkt_filtering = true; - goto out; - } - - /* Cookie area is valid, make the final check for filtering. */ - if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) { - hw->mac.tx_pkt_filtering = false; - goto out; - } - -out: - return hw->mac.tx_pkt_filtering; -} - -/** - * e1000_mng_write_cmd_header - Writes manageability command header - * @hw: pointer to the HW structure - * @hdr: pointer to the host interface command header - * - * Writes the command header after does the checksum calculation. - **/ -static s32 e1000_mng_write_cmd_header(struct e1000_hw *hw, - struct e1000_host_mng_command_header *hdr) -{ - u16 i, length = sizeof(struct e1000_host_mng_command_header); - - /* Write the whole command header structure with new checksum. */ - - hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length); - - length >>= 2; - /* Write the relevant command block into the ram area. */ - for (i = 0; i < length; i++) { - E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, i, - *((u32 *) hdr + i)); - e1e_flush(); - } - - return 0; -} - -/** - * e1000_mng_host_if_write - Write to the manageability host interface - * @hw: pointer to the HW structure - * @buffer: pointer to the host interface buffer - * @length: size of the buffer - * @offset: location in the buffer to write to - * @sum: sum of the data (not checksum) - * - * This function writes the buffer content at the offset given on the host if. - * It also does alignment considerations to do the writes in most efficient - * way. Also fills up the sum of the buffer in *buffer parameter. - **/ -static s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer, - u16 length, u16 offset, u8 *sum) -{ - u8 *tmp; - u8 *bufptr = buffer; - u32 data = 0; - u16 remaining, i, j, prev_bytes; - - /* sum = only sum of the data and it is not checksum */ - - if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) - return -E1000_ERR_PARAM; - - tmp = (u8 *)&data; - prev_bytes = offset & 0x3; - offset >>= 2; - - if (prev_bytes) { - data = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF, offset); - for (j = prev_bytes; j < sizeof(u32); j++) { - *(tmp + j) = *bufptr++; - *sum += *(tmp + j); - } - E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset, data); - length -= j - prev_bytes; - offset++; - } - - remaining = length & 0x3; - length -= remaining; - - /* Calculate length in DWORDs */ - length >>= 2; - - /* - * The device driver writes the relevant command block into the - * ram area. - */ - for (i = 0; i < length; i++) { - for (j = 0; j < sizeof(u32); j++) { - *(tmp + j) = *bufptr++; - *sum += *(tmp + j); - } - - E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data); - } - if (remaining) { - for (j = 0; j < sizeof(u32); j++) { - if (j < remaining) - *(tmp + j) = *bufptr++; - else - *(tmp + j) = 0; - - *sum += *(tmp + j); - } - E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data); - } - - return 0; -} - -/** - * e1000e_mng_write_dhcp_info - Writes DHCP info to host interface - * @hw: pointer to the HW structure - * @buffer: pointer to the host interface - * @length: size of the buffer - * - * Writes the DHCP information to the host interface. - **/ -s32 e1000e_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length) -{ - struct e1000_host_mng_command_header hdr; - s32 ret_val; - u32 hicr; - - hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD; - hdr.command_length = length; - hdr.reserved1 = 0; - hdr.reserved2 = 0; - hdr.checksum = 0; - - /* Enable the host interface */ - ret_val = e1000_mng_enable_host_if(hw); - if (ret_val) - return ret_val; - - /* Populate the host interface with the contents of "buffer". */ - ret_val = e1000_mng_host_if_write(hw, buffer, length, - sizeof(hdr), &(hdr.checksum)); - if (ret_val) - return ret_val; - - /* Write the manageability command header */ - ret_val = e1000_mng_write_cmd_header(hw, &hdr); - if (ret_val) - return ret_val; - - /* Tell the ARC a new command is pending. */ - hicr = er32(HICR); - ew32(HICR, hicr | E1000_HICR_C); - - return 0; -} - -/** - * e1000e_enable_mng_pass_thru - Check if management passthrough is needed - * @hw: pointer to the HW structure - * - * Verifies the hardware needs to leave interface enabled so that frames can - * be directed to and from the management interface. - **/ -bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw) -{ - u32 manc; - u32 fwsm, factps; - bool ret_val = false; - - manc = er32(MANC); - - if (!(manc & E1000_MANC_RCV_TCO_EN)) - goto out; - - if (hw->mac.has_fwsm) { - fwsm = er32(FWSM); - factps = er32(FACTPS); - - if (!(factps & E1000_FACTPS_MNGCG) && - ((fwsm & E1000_FWSM_MODE_MASK) == - (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) { - ret_val = true; - goto out; - } - } else if ((hw->mac.type == e1000_82574) || - (hw->mac.type == e1000_82583)) { - u16 data; - - factps = er32(FACTPS); - e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data); - - if (!(factps & E1000_FACTPS_MNGCG) && - ((data & E1000_NVM_INIT_CTRL2_MNGM) == - (e1000_mng_mode_pt << 13))) { - ret_val = true; - goto out; - } - } else if ((manc & E1000_MANC_SMBUS_EN) && - !(manc & E1000_MANC_ASF_EN)) { - ret_val = true; - goto out; - } - -out: - return ret_val; -} diff --git a/drivers/net/ethernet/intel/e1000e/mac.c b/drivers/net/ethernet/intel/e1000e/mac.c new file mode 100644 index 00000000000..64b6f439338 --- /dev/null +++ b/drivers/net/ethernet/intel/e1000e/mac.c @@ -0,0 +1,1717 @@ +/******************************************************************************* + + Intel PRO/1000 Linux driver + Copyright(c) 1999 - 2011 Intel Corporation. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + Linux NICS + e1000-devel Mailing List + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + +*******************************************************************************/ + +#include "e1000.h" + +/** + * e1000e_get_bus_info_pcie - Get PCIe bus information + * @hw: pointer to the HW structure + * + * Determines and stores the system bus information for a particular + * network interface. The following bus information is determined and stored: + * bus speed, bus width, type (PCIe), and PCIe function. + **/ +s32 e1000e_get_bus_info_pcie(struct e1000_hw *hw) +{ + struct e1000_mac_info *mac = &hw->mac; + struct e1000_bus_info *bus = &hw->bus; + struct e1000_adapter *adapter = hw->adapter; + u16 pcie_link_status, cap_offset; + + cap_offset = adapter->pdev->pcie_cap; + if (!cap_offset) { + bus->width = e1000_bus_width_unknown; + } else { + pci_read_config_word(adapter->pdev, + cap_offset + PCIE_LINK_STATUS, + &pcie_link_status); + bus->width = (enum e1000_bus_width)((pcie_link_status & + PCIE_LINK_WIDTH_MASK) >> + PCIE_LINK_WIDTH_SHIFT); + } + + mac->ops.set_lan_id(hw); + + return 0; +} + +/** + * e1000_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices + * + * @hw: pointer to the HW structure + * + * Determines the LAN function id by reading memory-mapped registers + * and swaps the port value if requested. + **/ +void e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw) +{ + struct e1000_bus_info *bus = &hw->bus; + u32 reg; + + /* + * The status register reports the correct function number + * for the device regardless of function swap state. + */ + reg = er32(STATUS); + bus->func = (reg & E1000_STATUS_FUNC_MASK) >> E1000_STATUS_FUNC_SHIFT; +} + +/** + * e1000_set_lan_id_single_port - Set LAN id for a single port device + * @hw: pointer to the HW structure + * + * Sets the LAN function id to zero for a single port device. + **/ +void e1000_set_lan_id_single_port(struct e1000_hw *hw) +{ + struct e1000_bus_info *bus = &hw->bus; + + bus->func = 0; +} + +/** + * e1000_clear_vfta_generic - Clear VLAN filter table + * @hw: pointer to the HW structure + * + * Clears the register array which contains the VLAN filter table by + * setting all the values to 0. + **/ +void e1000_clear_vfta_generic(struct e1000_hw *hw) +{ + u32 offset; + + for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) { + E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, 0); + e1e_flush(); + } +} + +/** + * e1000_write_vfta_generic - Write value to VLAN filter table + * @hw: pointer to the HW structure + * @offset: register offset in VLAN filter table + * @value: register value written to VLAN filter table + * + * Writes value at the given offset in the register array which stores + * the VLAN filter table. + **/ +void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value) +{ + E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value); + e1e_flush(); +} + +/** + * e1000e_init_rx_addrs - Initialize receive address's + * @hw: pointer to the HW structure + * @rar_count: receive address registers + * + * Setup the receive address registers by setting the base receive address + * register to the devices MAC address and clearing all the other receive + * address registers to 0. + **/ +void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count) +{ + u32 i; + u8 mac_addr[ETH_ALEN] = { 0 }; + + /* Setup the receive address */ + e_dbg("Programming MAC Address into RAR[0]\n"); + + e1000e_rar_set(hw, hw->mac.addr, 0); + + /* Zero out the other (rar_entry_count - 1) receive addresses */ + e_dbg("Clearing RAR[1-%u]\n", rar_count - 1); + for (i = 1; i < rar_count; i++) + e1000e_rar_set(hw, mac_addr, i); +} + +/** + * e1000_check_alt_mac_addr_generic - Check for alternate MAC addr + * @hw: pointer to the HW structure + * + * Checks the nvm for an alternate MAC address. An alternate MAC address + * can be setup by pre-boot software and must be treated like a permanent + * address and must override the actual permanent MAC address. If an + * alternate MAC address is found it is programmed into RAR0, replacing + * the permanent address that was installed into RAR0 by the Si on reset. + * This function will return SUCCESS unless it encounters an error while + * reading the EEPROM. + **/ +s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) +{ + u32 i; + s32 ret_val = 0; + u16 offset, nvm_alt_mac_addr_offset, nvm_data; + u8 alt_mac_addr[ETH_ALEN]; + + ret_val = e1000_read_nvm(hw, NVM_COMPAT, 1, &nvm_data); + if (ret_val) + goto out; + + /* not supported on older hardware or 82573 */ + if ((hw->mac.type < e1000_82571) || (hw->mac.type == e1000_82573)) + goto out; + + ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1, + &nvm_alt_mac_addr_offset); + if (ret_val) { + e_dbg("NVM Read Error\n"); + goto out; + } + + if ((nvm_alt_mac_addr_offset == 0xFFFF) || + (nvm_alt_mac_addr_offset == 0x0000)) + /* There is no Alternate MAC Address */ + goto out; + + if (hw->bus.func == E1000_FUNC_1) + nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN1; + for (i = 0; i < ETH_ALEN; i += 2) { + offset = nvm_alt_mac_addr_offset + (i >> 1); + ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data); + if (ret_val) { + e_dbg("NVM Read Error\n"); + goto out; + } + + alt_mac_addr[i] = (u8)(nvm_data & 0xFF); + alt_mac_addr[i + 1] = (u8)(nvm_data >> 8); + } + + /* if multicast bit is set, the alternate address will not be used */ + if (is_multicast_ether_addr(alt_mac_addr)) { + e_dbg("Ignoring Alternate Mac Address with MC bit set\n"); + goto out; + } + + /* + * We have a valid alternate MAC address, and we want to treat it the + * same as the normal permanent MAC address stored by the HW into the + * RAR. Do this by mapping this address into RAR0. + */ + e1000e_rar_set(hw, alt_mac_addr, 0); + +out: + return ret_val; +} + +/** + * e1000e_rar_set - Set receive address register + * @hw: pointer to the HW structure + * @addr: pointer to the receive address + * @index: receive address array register + * + * Sets the receive address array register at index to the address passed + * in by addr. + **/ +void e1000e_rar_set(struct e1000_hw *hw, u8 *addr, u32 index) +{ + u32 rar_low, rar_high; + + /* + * HW expects these in little endian so we reverse the byte order + * from network order (big endian) to little endian + */ + rar_low = ((u32)addr[0] | ((u32)addr[1] << 8) | + ((u32)addr[2] << 16) | ((u32)addr[3] << 24)); + + rar_high = ((u32)addr[4] | ((u32)addr[5] << 8)); + + /* If MAC address zero, no need to set the AV bit */ + if (rar_low || rar_high) + rar_high |= E1000_RAH_AV; + + /* + * Some bridges will combine consecutive 32-bit writes into + * a single burst write, which will malfunction on some parts. + * The flushes avoid this. + */ + ew32(RAL(index), rar_low); + e1e_flush(); + ew32(RAH(index), rar_high); + e1e_flush(); +} + +/** + * e1000_hash_mc_addr - Generate a multicast hash value + * @hw: pointer to the HW structure + * @mc_addr: pointer to a multicast address + * + * Generates a multicast address hash value which is used to determine + * the multicast filter table array address and new table value. See + * e1000_mta_set_generic() + **/ +static u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr) +{ + u32 hash_value, hash_mask; + u8 bit_shift = 0; + + /* Register count multiplied by bits per register */ + hash_mask = (hw->mac.mta_reg_count * 32) - 1; + + /* + * For a mc_filter_type of 0, bit_shift is the number of left-shifts + * where 0xFF would still fall within the hash mask. + */ + while (hash_mask >> bit_shift != 0xFF) + bit_shift++; + + /* + * The portion of the address that is used for the hash table + * is determined by the mc_filter_type setting. + * The algorithm is such that there is a total of 8 bits of shifting. + * The bit_shift for a mc_filter_type of 0 represents the number of + * left-shifts where the MSB of mc_addr[5] would still fall within + * the hash_mask. Case 0 does this exactly. Since there are a total + * of 8 bits of shifting, then mc_addr[4] will shift right the + * remaining number of bits. Thus 8 - bit_shift. The rest of the + * cases are a variation of this algorithm...essentially raising the + * number of bits to shift mc_addr[5] left, while still keeping the + * 8-bit shifting total. + * + * For example, given the following Destination MAC Address and an + * mta register count of 128 (thus a 4096-bit vector and 0xFFF mask), + * we can see that the bit_shift for case 0 is 4. These are the hash + * values resulting from each mc_filter_type... + * [0] [1] [2] [3] [4] [5] + * 01 AA 00 12 34 56 + * LSB MSB + * + * case 0: hash_value = ((0x34 >> 4) | (0x56 << 4)) & 0xFFF = 0x563 + * case 1: hash_value = ((0x34 >> 3) | (0x56 << 5)) & 0xFFF = 0xAC6 + * case 2: hash_value = ((0x34 >> 2) | (0x56 << 6)) & 0xFFF = 0x163 + * case 3: hash_value = ((0x34 >> 0) | (0x56 << 8)) & 0xFFF = 0x634 + */ + switch (hw->mac.mc_filter_type) { + default: + case 0: + break; + case 1: + bit_shift += 1; + break; + case 2: + bit_shift += 2; + break; + case 3: + bit_shift += 4; + break; + } + + hash_value = hash_mask & (((mc_addr[4] >> (8 - bit_shift)) | + (((u16)mc_addr[5]) << bit_shift))); + + return hash_value; +} + +/** + * e1000e_update_mc_addr_list_generic - Update Multicast addresses + * @hw: pointer to the HW structure + * @mc_addr_list: array of multicast addresses to program + * @mc_addr_count: number of multicast addresses to program + * + * Updates entire Multicast Table Array. + * The caller must have a packed mc_addr_list of multicast addresses. + **/ +void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw, + u8 *mc_addr_list, u32 mc_addr_count) +{ + u32 hash_value, hash_bit, hash_reg; + int i; + + /* clear mta_shadow */ + memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow)); + + /* update mta_shadow from mc_addr_list */ + for (i = 0; (u32)i < mc_addr_count; i++) { + hash_value = e1000_hash_mc_addr(hw, mc_addr_list); + + hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1); + hash_bit = hash_value & 0x1F; + + hw->mac.mta_shadow[hash_reg] |= (1 << hash_bit); + mc_addr_list += (ETH_ALEN); + } + + /* replace the entire MTA table */ + for (i = hw->mac.mta_reg_count - 1; i >= 0; i--) + E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, hw->mac.mta_shadow[i]); + e1e_flush(); +} + +/** + * e1000e_clear_hw_cntrs_base - Clear base hardware counters + * @hw: pointer to the HW structure + * + * Clears the base hardware counters by reading the counter registers. + **/ +void e1000e_clear_hw_cntrs_base(struct e1000_hw *hw) +{ + er32(CRCERRS); + er32(SYMERRS); + er32(MPC); + er32(SCC); + er32(ECOL); + er32(MCC); + er32(LATECOL); + er32(COLC); + er32(DC); + er32(SEC); + er32(RLEC); + er32(XONRXC); + er32(XONTXC); + er32(XOFFRXC); + er32(XOFFTXC); + er32(FCRUC); + er32(GPRC); + er32(BPRC); + er32(MPRC); + er32(GPTC); + er32(GORCL); + er32(GORCH); + er32(GOTCL); + er32(GOTCH); + er32(RNBC); + er32(RUC); + er32(RFC); + er32(ROC); + er32(RJC); + er32(TORL); + er32(TORH); + er32(TOTL); + er32(TOTH); + er32(TPR); + er32(TPT); + er32(MPTC); + er32(BPTC); +} + +/** + * e1000e_check_for_copper_link - Check for link (Copper) + * @hw: pointer to the HW structure + * + * Checks to see of the link status of the hardware has changed. If a + * change in link status has been detected, then we read the PHY registers + * to get the current speed/duplex if link exists. + **/ +s32 e1000e_check_for_copper_link(struct e1000_hw *hw) +{ + struct e1000_mac_info *mac = &hw->mac; + s32 ret_val; + bool link; + + /* + * We only want to go out to the PHY registers to see if Auto-Neg + * has completed and/or if our link status has changed. The + * get_link_status flag is set upon receiving a Link Status + * Change or Rx Sequence Error interrupt. + */ + if (!mac->get_link_status) + return 0; + + /* + * First we want to see if the MII Status Register reports + * link. If so, then we want to get the current speed/duplex + * of the PHY. + */ + ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link); + if (ret_val) + return ret_val; + + if (!link) + return ret_val; /* No link detected */ + + mac->get_link_status = false; + + /* + * Check if there was DownShift, must be checked + * immediately after link-up + */ + e1000e_check_downshift(hw); + + /* + * If we are forcing speed/duplex, then we simply return since + * we have already determined whether we have link or not. + */ + if (!mac->autoneg) { + ret_val = -E1000_ERR_CONFIG; + return ret_val; + } + + /* + * Auto-Neg is enabled. Auto Speed Detection takes care + * of MAC speed/duplex configuration. So we only need to + * configure Collision Distance in the MAC. + */ + e1000e_config_collision_dist(hw); + + /* + * Configure Flow Control now that Auto-Neg has completed. + * First, we need to restore the desired flow control + * settings because we may have had to re-autoneg with a + * different link partner. + */ + ret_val = e1000e_config_fc_after_link_up(hw); + if (ret_val) + e_dbg("Error configuring flow control\n"); + + return ret_val; +} + +/** + * e1000e_check_for_fiber_link - Check for link (Fiber) + * @hw: pointer to the HW structure + * + * Checks for link up on the hardware. If link is not up and we have + * a signal, then we need to force link up. + **/ +s32 e1000e_check_for_fiber_link(struct e1000_hw *hw) +{ + struct e1000_mac_info *mac = &hw->mac; + u32 rxcw; + u32 ctrl; + u32 status; + s32 ret_val; + + ctrl = er32(CTRL); + status = er32(STATUS); + rxcw = er32(RXCW); + + /* + * If we don't have link (auto-negotiation failed or link partner + * cannot auto-negotiate), the cable is plugged in (we have signal), + * and our link partner is not trying to auto-negotiate with us (we + * are receiving idles or data), we need to force link up. We also + * need to give auto-negotiation time to complete, in case the cable + * was just plugged in. The autoneg_failed flag does this. + */ + /* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */ + if ((ctrl & E1000_CTRL_SWDPIN1) && (!(status & E1000_STATUS_LU)) && + (!(rxcw & E1000_RXCW_C))) { + if (mac->autoneg_failed == 0) { + mac->autoneg_failed = 1; + return 0; + } + e_dbg("NOT Rx'ing /C/, disable AutoNeg and force link.\n"); + + /* Disable auto-negotiation in the TXCW register */ + ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE)); + + /* Force link-up and also force full-duplex. */ + ctrl = er32(CTRL); + ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD); + ew32(CTRL, ctrl); + + /* Configure Flow Control after forcing link up. */ + ret_val = e1000e_config_fc_after_link_up(hw); + if (ret_val) { + e_dbg("Error configuring flow control\n"); + return ret_val; + } + } else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) { + /* + * If we are forcing link and we are receiving /C/ ordered + * sets, re-enable auto-negotiation in the TXCW register + * and disable forced link in the Device Control register + * in an attempt to auto-negotiate with our link partner. + */ + e_dbg("Rx'ing /C/, enable AutoNeg and stop forcing link.\n"); + ew32(TXCW, mac->txcw); + ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); + + mac->serdes_has_link = true; + } + + return 0; +} + +/** + * e1000e_check_for_serdes_link - Check for link (Serdes) + * @hw: pointer to the HW structure + * + * Checks for link up on the hardware. If link is not up and we have + * a signal, then we need to force link up. + **/ +s32 e1000e_check_for_serdes_link(struct e1000_hw *hw) +{ + struct e1000_mac_info *mac = &hw->mac; + u32 rxcw; + u32 ctrl; + u32 status; + s32 ret_val; + + ctrl = er32(CTRL); + status = er32(STATUS); + rxcw = er32(RXCW); + + /* + * If we don't have link (auto-negotiation failed or link partner + * cannot auto-negotiate), and our link partner is not trying to + * auto-negotiate with us (we are receiving idles or data), + * we need to force link up. We also need to give auto-negotiation + * time to complete. + */ + /* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */ + if ((!(status & E1000_STATUS_LU)) && (!(rxcw & E1000_RXCW_C))) { + if (mac->autoneg_failed == 0) { + mac->autoneg_failed = 1; + return 0; + } + e_dbg("NOT Rx'ing /C/, disable AutoNeg and force link.\n"); + + /* Disable auto-negotiation in the TXCW register */ + ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE)); + + /* Force link-up and also force full-duplex. */ + ctrl = er32(CTRL); + ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD); + ew32(CTRL, ctrl); + + /* Configure Flow Control after forcing link up. */ + ret_val = e1000e_config_fc_after_link_up(hw); + if (ret_val) { + e_dbg("Error configuring flow control\n"); + return ret_val; + } + } else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) { + /* + * If we are forcing link and we are receiving /C/ ordered + * sets, re-enable auto-negotiation in the TXCW register + * and disable forced link in the Device Control register + * in an attempt to auto-negotiate with our link partner. + */ + e_dbg("Rx'ing /C/, enable AutoNeg and stop forcing link.\n"); + ew32(TXCW, mac->txcw); + ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); + + mac->serdes_has_link = true; + } else if (!(E1000_TXCW_ANE & er32(TXCW))) { + /* + * If we force link for non-auto-negotiation switch, check + * link status based on MAC synchronization for internal + * serdes media type. + */ + /* SYNCH bit and IV bit are sticky. */ + udelay(10); + rxcw = er32(RXCW); + if (rxcw & E1000_RXCW_SYNCH) { + if (!(rxcw & E1000_RXCW_IV)) { + mac->serdes_has_link = true; + e_dbg("SERDES: Link up - forced.\n"); + } + } else { + mac->serdes_has_link = false; + e_dbg("SERDES: Link down - force failed.\n"); + } + } + + if (E1000_TXCW_ANE & er32(TXCW)) { + status = er32(STATUS); + if (status & E1000_STATUS_LU) { + /* SYNCH bit and IV bit are sticky, so reread rxcw. */ + udelay(10); + rxcw = er32(RXCW); + if (rxcw & E1000_RXCW_SYNCH) { + if (!(rxcw & E1000_RXCW_IV)) { + mac->serdes_has_link = true; + e_dbg("SERDES: Link up - autoneg completed successfully.\n"); + } else { + mac->serdes_has_link = false; + e_dbg("SERDES: Link down - invalid codewords detected in autoneg.\n"); + } + } else { + mac->serdes_has_link = false; + e_dbg("SERDES: Link down - no sync.\n"); + } + } else { + mac->serdes_has_link = false; + e_dbg("SERDES: Link down - autoneg failed\n"); + } + } + + return 0; +} + +/** + * e1000_set_default_fc_generic - Set flow control default values + * @hw: pointer to the HW structure + * + * Read the EEPROM for the default values for flow control and store the + * values. + **/ +static s32 e1000_set_default_fc_generic(struct e1000_hw *hw) +{ + s32 ret_val; + u16 nvm_data; + + /* + * Read and store word 0x0F of the EEPROM. This word contains bits + * that determine the hardware's default PAUSE (flow control) mode, + * a bit that determines whether the HW defaults to enabling or + * disabling auto-negotiation, and the direction of the + * SW defined pins. If there is no SW over-ride of the flow + * control setting, then the variable hw->fc will + * be initialized based on a value in the EEPROM. + */ + ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data); + + if (ret_val) { + e_dbg("NVM Read Error\n"); + return ret_val; + } + + if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == 0) + hw->fc.requested_mode = e1000_fc_none; + else if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == NVM_WORD0F_ASM_DIR) + hw->fc.requested_mode = e1000_fc_tx_pause; + else + hw->fc.requested_mode = e1000_fc_full; + + return 0; +} + +/** + * e1000e_setup_link - Setup flow control and link settings + * @hw: pointer to the HW structure + * + * Determines which flow control settings to use, then configures flow + * control. Calls the appropriate media-specific link configuration + * function. Assuming the adapter has a valid link partner, a valid link + * should be established. Assumes the hardware has previously been reset + * and the transmitter and receiver are not enabled. + **/ +s32 e1000e_setup_link(struct e1000_hw *hw) +{ + struct e1000_mac_info *mac = &hw->mac; + s32 ret_val; + + /* + * In the case of the phy reset being blocked, we already have a link. + * We do not need to set it up again. + */ + if (e1000_check_reset_block(hw)) + return 0; + + /* + * If requested flow control is set to default, set flow control + * based on the EEPROM flow control settings. + */ + if (hw->fc.requested_mode == e1000_fc_default) { + ret_val = e1000_set_default_fc_generic(hw); + if (ret_val) + return ret_val; + } + + /* + * Save off the requested flow control mode for use later. Depending + * on the link partner's capabilities, we may or may not use this mode. + */ + hw->fc.current_mode = hw->fc.requested_mode; + + e_dbg("After fix-ups FlowControl is now = %x\n", hw->fc.current_mode); + + /* Call the necessary media_type subroutine to configure the link. */ + ret_val = mac->ops.setup_physical_interface(hw); + if (ret_val) + return ret_val; + + /* + * Initialize the flow control address, type, and PAUSE timer + * registers to their default values. This is done even if flow + * control is disabled, because it does not hurt anything to + * initialize these registers. + */ + e_dbg("Initializing the Flow Control address, type and timer regs\n"); + ew32(FCT, FLOW_CONTROL_TYPE); + ew32(FCAH, FLOW_CONTROL_ADDRESS_HIGH); + ew32(FCAL, FLOW_CONTROL_ADDRESS_LOW); + + ew32(FCTTV, hw->fc.pause_time); + + return e1000e_set_fc_watermarks(hw); +} + +/** + * e1000_commit_fc_settings_generic - Configure flow control + * @hw: pointer to the HW structure + * + * Write the flow control settings to the Transmit Config Word Register (TXCW) + * base on the flow control settings in e1000_mac_info. + **/ +static s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw) +{ + struct e1000_mac_info *mac = &hw->mac; + u32 txcw; + + /* + * Check for a software override of the flow control settings, and + * setup the device accordingly. If auto-negotiation is enabled, then + * software will have to set the "PAUSE" bits to the correct value in + * the Transmit Config Word Register (TXCW) and re-start auto- + * negotiation. However, if auto-negotiation is disabled, then + * software will have to manually configure the two flow control enable + * bits in the CTRL register. + * + * The possible values of the "fc" parameter are: + * 0: Flow control is completely disabled + * 1: Rx flow control is enabled (we can receive pause frames, + * but not send pause frames). + * 2: Tx flow control is enabled (we can send pause frames but we + * do not support receiving pause frames). + * 3: Both Rx and Tx flow control (symmetric) are enabled. + */ + switch (hw->fc.current_mode) { + case e1000_fc_none: + /* Flow control completely disabled by a software over-ride. */ + txcw = (E1000_TXCW_ANE | E1000_TXCW_FD); + break; + case e1000_fc_rx_pause: + /* + * Rx Flow control is enabled and Tx Flow control is disabled + * by a software over-ride. Since there really isn't a way to + * advertise that we are capable of Rx Pause ONLY, we will + * advertise that we support both symmetric and asymmetric Rx + * PAUSE. Later, we will disable the adapter's ability to send + * PAUSE frames. + */ + txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK); + break; + case e1000_fc_tx_pause: + /* + * Tx Flow control is enabled, and Rx Flow control is disabled, + * by a software over-ride. + */ + txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR); + break; + case e1000_fc_full: + /* + * Flow control (both Rx and Tx) is enabled by a software + * over-ride. + */ + txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK); + break; + default: + e_dbg("Flow control param set incorrectly\n"); + return -E1000_ERR_CONFIG; + break; + } + + ew32(TXCW, txcw); + mac->txcw = txcw; + + return 0; +} + +/** + * e1000_poll_fiber_serdes_link_generic - Poll for link up + * @hw: pointer to the HW structure + * + * Polls for link up by reading the status register, if link fails to come + * up with auto-negotiation, then the link is forced if a signal is detected. + **/ +static s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw) +{ + struct e1000_mac_info *mac = &hw->mac; + u32 i, status; + s32 ret_val; + + /* + * If we have a signal (the cable is plugged in, or assumed true for + * serdes media) then poll for a "Link-Up" indication in the Device + * Status Register. Time-out if a link isn't seen in 500 milliseconds + * seconds (Auto-negotiation should complete in less than 500 + * milliseconds even if the other end is doing it in SW). + */ + for (i = 0; i < FIBER_LINK_UP_LIMIT; i++) { + usleep_range(10000, 20000); + status = er32(STATUS); + if (status & E1000_STATUS_LU) + break; + } + if (i == FIBER_LINK_UP_LIMIT) { + e_dbg("Never got a valid link from auto-neg!!!\n"); + mac->autoneg_failed = 1; + /* + * AutoNeg failed to achieve a link, so we'll call + * mac->check_for_link. This routine will force the + * link up if we detect a signal. This will allow us to + * communicate with non-autonegotiating link partners. + */ + ret_val = mac->ops.check_for_link(hw); + if (ret_val) { + e_dbg("Error while checking for link\n"); + return ret_val; + } + mac->autoneg_failed = 0; + } else { + mac->autoneg_failed = 0; + e_dbg("Valid Link Found\n"); + } + + return 0; +} + +/** + * e1000e_setup_fiber_serdes_link - Setup link for fiber/serdes + * @hw: pointer to the HW structure + * + * Configures collision distance and flow control for fiber and serdes + * links. Upon successful setup, poll for link. + **/ +s32 e1000e_setup_fiber_serdes_link(struct e1000_hw *hw) +{ + u32 ctrl; + s32 ret_val; + + ctrl = er32(CTRL); + + /* Take the link out of reset */ + ctrl &= ~E1000_CTRL_LRST; + + e1000e_config_collision_dist(hw); + + ret_val = e1000_commit_fc_settings_generic(hw); + if (ret_val) + return ret_val; + + /* + * Since auto-negotiation is enabled, take the link out of reset (the + * link will be in reset, because we previously reset the chip). This + * will restart auto-negotiation. If auto-negotiation is successful + * then the link-up status bit will be set and the flow control enable + * bits (RFCE and TFCE) will be set according to their negotiated value. + */ + e_dbg("Auto-negotiation enabled\n"); + + ew32(CTRL, ctrl); + e1e_flush(); + usleep_range(1000, 2000); + + /* + * For these adapters, the SW definable pin 1 is set when the optics + * detect a signal. If we have a signal, then poll for a "Link-Up" + * indication. + */ + if (hw->phy.media_type == e1000_media_type_internal_serdes || + (er32(CTRL) & E1000_CTRL_SWDPIN1)) { + ret_val = e1000_poll_fiber_serdes_link_generic(hw); + } else { + e_dbg("No signal detected\n"); + } + + return 0; +} + +/** + * e1000e_config_collision_dist - Configure collision distance + * @hw: pointer to the HW structure + * + * Configures the collision distance to the default value and is used + * during link setup. Currently no func pointer exists and all + * implementations are handled in the generic version of this function. + **/ +void e1000e_config_collision_dist(struct e1000_hw *hw) +{ + u32 tctl; + + tctl = er32(TCTL); + + tctl &= ~E1000_TCTL_COLD; + tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT; + + ew32(TCTL, tctl); + e1e_flush(); +} + +/** + * e1000e_set_fc_watermarks - Set flow control high/low watermarks + * @hw: pointer to the HW structure + * + * Sets the flow control high/low threshold (watermark) registers. If + * flow control XON frame transmission is enabled, then set XON frame + * transmission as well. + **/ +s32 e1000e_set_fc_watermarks(struct e1000_hw *hw) +{ + u32 fcrtl = 0, fcrth = 0; + + /* + * Set the flow control receive threshold registers. Normally, + * these registers will be set to a default threshold that may be + * adjusted later by the driver's runtime code. However, if the + * ability to transmit pause frames is not enabled, then these + * registers will be set to 0. + */ + if (hw->fc.current_mode & e1000_fc_tx_pause) { + /* + * We need to set up the Receive Threshold high and low water + * marks as well as (optionally) enabling the transmission of + * XON frames. + */ + fcrtl = hw->fc.low_water; + fcrtl |= E1000_FCRTL_XONE; + fcrth = hw->fc.high_water; + } + ew32(FCRTL, fcrtl); + ew32(FCRTH, fcrth); + + return 0; +} + +/** + * e1000e_force_mac_fc - Force the MAC's flow control settings + * @hw: pointer to the HW structure + * + * Force the MAC's flow control settings. Sets the TFCE and RFCE bits in the + * device control register to reflect the adapter settings. TFCE and RFCE + * need to be explicitly set by software when a copper PHY is used because + * autonegotiation is managed by the PHY rather than the MAC. Software must + * also configure these bits when link is forced on a fiber connection. + **/ +s32 e1000e_force_mac_fc(struct e1000_hw *hw) +{ + u32 ctrl; + + ctrl = er32(CTRL); + + /* + * Because we didn't get link via the internal auto-negotiation + * mechanism (we either forced link or we got link via PHY + * auto-neg), we have to manually enable/disable transmit an + * receive flow control. + * + * The "Case" statement below enables/disable flow control + * according to the "hw->fc.current_mode" parameter. + * + * The possible values of the "fc" parameter are: + * 0: Flow control is completely disabled + * 1: Rx flow control is enabled (we can receive pause + * frames but not send pause frames). + * 2: Tx flow control is enabled (we can send pause frames + * frames but we do not receive pause frames). + * 3: Both Rx and Tx flow control (symmetric) is enabled. + * other: No other values should be possible at this point. + */ + e_dbg("hw->fc.current_mode = %u\n", hw->fc.current_mode); + + switch (hw->fc.current_mode) { + case e1000_fc_none: + ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE)); + break; + case e1000_fc_rx_pause: + ctrl &= (~E1000_CTRL_TFCE); + ctrl |= E1000_CTRL_RFCE; + break; + case e1000_fc_tx_pause: + ctrl &= (~E1000_CTRL_RFCE); + ctrl |= E1000_CTRL_TFCE; + break; + case e1000_fc_full: + ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE); + break; + default: + e_dbg("Flow control param set incorrectly\n"); + return -E1000_ERR_CONFIG; + } + + ew32(CTRL, ctrl); + + return 0; +} + +/** + * e1000e_config_fc_after_link_up - Configures flow control after link + * @hw: pointer to the HW structure + * + * Checks the status of auto-negotiation after link up to ensure that the + * speed and duplex were not forced. If the link needed to be forced, then + * flow control needs to be forced also. If auto-negotiation is enabled + * and did not fail, then we configure flow control based on our link + * partner. + **/ +s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw) +{ + struct e1000_mac_info *mac = &hw->mac; + s32 ret_val = 0; + u16 mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg; + u16 speed, duplex; + + /* + * Check for the case where we have fiber media and auto-neg failed + * so we had to force link. In this case, we need to force the + * configuration of the MAC to match the "fc" parameter. + */ + if (mac->autoneg_failed) { + if (hw->phy.media_type == e1000_media_type_fiber || + hw->phy.media_type == e1000_media_type_internal_serdes) + ret_val = e1000e_force_mac_fc(hw); + } else { + if (hw->phy.media_type == e1000_media_type_copper) + ret_val = e1000e_force_mac_fc(hw); + } + + if (ret_val) { + e_dbg("Error forcing flow control settings\n"); + return ret_val; + } + + /* + * Check for the case where we have copper media and auto-neg is + * enabled. In this case, we need to check and see if Auto-Neg + * has completed, and if so, how the PHY and link partner has + * flow control configured. + */ + if ((hw->phy.media_type == e1000_media_type_copper) && mac->autoneg) { + /* + * Read the MII Status Register and check to see if AutoNeg + * has completed. We read this twice because this reg has + * some "sticky" (latched) bits. + */ + ret_val = e1e_rphy(hw, PHY_STATUS, &mii_status_reg); + if (ret_val) + return ret_val; + ret_val = e1e_rphy(hw, PHY_STATUS, &mii_status_reg); + if (ret_val) + return ret_val; + + if (!(mii_status_reg & MII_SR_AUTONEG_COMPLETE)) { + e_dbg("Copper PHY and Auto Neg has not completed.\n"); + return ret_val; + } + + /* + * The AutoNeg process has completed, so we now need to + * read both the Auto Negotiation Advertisement + * Register (Address 4) and the Auto_Negotiation Base + * Page Ability Register (Address 5) to determine how + * flow control was negotiated. + */ + ret_val = e1e_rphy(hw, PHY_AUTONEG_ADV, &mii_nway_adv_reg); + if (ret_val) + return ret_val; + ret_val = + e1e_rphy(hw, PHY_LP_ABILITY, &mii_nway_lp_ability_reg); + if (ret_val) + return ret_val; + + /* + * Two bits in the Auto Negotiation Advertisement Register + * (Address 4) and two bits in the Auto Negotiation Base + * Page Ability Register (Address 5) determine flow control + * for both the PHY and the link partner. The following + * table, taken out of the IEEE 802.3ab/D6.0 dated March 25, + * 1999, describes these PAUSE resolution bits and how flow + * control is determined based upon these settings. + * NOTE: DC = Don't Care + * + * LOCAL DEVICE | LINK PARTNER + * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution + *-------|---------|-------|---------|-------------------- + * 0 | 0 | DC | DC | e1000_fc_none + * 0 | 1 | 0 | DC | e1000_fc_none + * 0 | 1 | 1 | 0 | e1000_fc_none + * 0 | 1 | 1 | 1 | e1000_fc_tx_pause + * 1 | 0 | 0 | DC | e1000_fc_none + * 1 | DC | 1 | DC | e1000_fc_full + * 1 | 1 | 0 | 0 | e1000_fc_none + * 1 | 1 | 0 | 1 | e1000_fc_rx_pause + * + * Are both PAUSE bits set to 1? If so, this implies + * Symmetric Flow Control is enabled at both ends. The + * ASM_DIR bits are irrelevant per the spec. + * + * For Symmetric Flow Control: + * + * LOCAL DEVICE | LINK PARTNER + * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result + *-------|---------|-------|---------|-------------------- + * 1 | DC | 1 | DC | E1000_fc_full + * + */ + if ((mii_nway_adv_reg & NWAY_AR_PAUSE) && + (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) { + /* + * Now we need to check if the user selected Rx ONLY + * of pause frames. In this case, we had to advertise + * FULL flow control because we could not advertise Rx + * ONLY. Hence, we must now check to see if we need to + * turn OFF the TRANSMISSION of PAUSE frames. + */ + if (hw->fc.requested_mode == e1000_fc_full) { + hw->fc.current_mode = e1000_fc_full; + e_dbg("Flow Control = FULL.\n"); + } else { + hw->fc.current_mode = e1000_fc_rx_pause; + e_dbg("Flow Control = Rx PAUSE frames only.\n"); + } + } + /* + * For receiving PAUSE frames ONLY. + * + * LOCAL DEVICE | LINK PARTNER + * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result + *-------|---------|-------|---------|-------------------- + * 0 | 1 | 1 | 1 | e1000_fc_tx_pause + */ + else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) && + (mii_nway_adv_reg & NWAY_AR_ASM_DIR) && + (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && + (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { + hw->fc.current_mode = e1000_fc_tx_pause; + e_dbg("Flow Control = Tx PAUSE frames only.\n"); + } + /* + * For transmitting PAUSE frames ONLY. + * + * LOCAL DEVICE | LINK PARTNER + * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result + *-------|---------|-------|---------|-------------------- + * 1 | 1 | 0 | 1 | e1000_fc_rx_pause + */ + else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) && + (mii_nway_adv_reg & NWAY_AR_ASM_DIR) && + !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && + (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { + hw->fc.current_mode = e1000_fc_rx_pause; + e_dbg("Flow Control = Rx PAUSE frames only.\n"); + } else { + /* + * Per the IEEE spec, at this point flow control + * should be disabled. + */ + hw->fc.current_mode = e1000_fc_none; + e_dbg("Flow Control = NONE.\n"); + } + + /* + * Now we need to do one last check... If we auto- + * negotiated to HALF DUPLEX, flow control should not be + * enabled per IEEE 802.3 spec. + */ + ret_val = mac->ops.get_link_up_info(hw, &speed, &duplex); + if (ret_val) { + e_dbg("Error getting link speed and duplex\n"); + return ret_val; + } + + if (duplex == HALF_DUPLEX) + hw->fc.current_mode = e1000_fc_none; + + /* + * Now we call a subroutine to actually force the MAC + * controller to use the correct flow control settings. + */ + ret_val = e1000e_force_mac_fc(hw); + if (ret_val) { + e_dbg("Error forcing flow control settings\n"); + return ret_val; + } + } + + return 0; +} + +/** + * e1000e_get_speed_and_duplex_copper - Retrieve current speed/duplex + * @hw: pointer to the HW structure + * @speed: stores the current speed + * @duplex: stores the current duplex + * + * Read the status register for the current speed/duplex and store the current + * speed and duplex for copper connections. + **/ +s32 e1000e_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed, + u16 *duplex) +{ + u32 status; + + status = er32(STATUS); + if (status & E1000_STATUS_SPEED_1000) + *speed = SPEED_1000; + else if (status & E1000_STATUS_SPEED_100) + *speed = SPEED_100; + else + *speed = SPEED_10; + + if (status & E1000_STATUS_FD) + *duplex = FULL_DUPLEX; + else + *duplex = HALF_DUPLEX; + + e_dbg("%u Mbps, %s Duplex\n", + *speed == SPEED_1000 ? 1000 : *speed == SPEED_100 ? 100 : 10, + *duplex == FULL_DUPLEX ? "Full" : "Half"); + + return 0; +} + +/** + * e1000e_get_speed_and_duplex_fiber_serdes - Retrieve current speed/duplex + * @hw: pointer to the HW structure + * @speed: stores the current speed + * @duplex: stores the current duplex + * + * Sets the speed and duplex to gigabit full duplex (the only possible option) + * for fiber/serdes links. + **/ +s32 e1000e_get_speed_and_duplex_fiber_serdes(struct e1000_hw *hw, u16 *speed, + u16 *duplex) +{ + *speed = SPEED_1000; + *duplex = FULL_DUPLEX; + + return 0; +} + +/** + * e1000e_get_hw_semaphore - Acquire hardware semaphore + * @hw: pointer to the HW structure + * + * Acquire the HW semaphore to access the PHY or NVM + **/ +s32 e1000e_get_hw_semaphore(struct e1000_hw *hw) +{ + u32 swsm; + s32 timeout = hw->nvm.word_size + 1; + s32 i = 0; + + /* Get the SW semaphore */ + while (i < timeout) { + swsm = er32(SWSM); + if (!(swsm & E1000_SWSM_SMBI)) + break; + + udelay(50); + i++; + } + + if (i == timeout) { + e_dbg("Driver can't access device - SMBI bit is set.\n"); + return -E1000_ERR_NVM; + } + + /* Get the FW semaphore. */ + for (i = 0; i < timeout; i++) { + swsm = er32(SWSM); + ew32(SWSM, swsm | E1000_SWSM_SWESMBI); + + /* Semaphore acquired if bit latched */ + if (er32(SWSM) & E1000_SWSM_SWESMBI) + break; + + udelay(50); + } + + if (i == timeout) { + /* Release semaphores */ + e1000e_put_hw_semaphore(hw); + e_dbg("Driver can't access the NVM\n"); + return -E1000_ERR_NVM; + } + + return 0; +} + +/** + * e1000e_put_hw_semaphore - Release hardware semaphore + * @hw: pointer to the HW structure + * + * Release hardware semaphore used to access the PHY or NVM + **/ +void e1000e_put_hw_semaphore(struct e1000_hw *hw) +{ + u32 swsm; + + swsm = er32(SWSM); + swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI); + ew32(SWSM, swsm); +} + +/** + * e1000e_get_auto_rd_done - Check for auto read completion + * @hw: pointer to the HW structure + * + * Check EEPROM for Auto Read done bit. + **/ +s32 e1000e_get_auto_rd_done(struct e1000_hw *hw) +{ + s32 i = 0; + + while (i < AUTO_READ_DONE_TIMEOUT) { + if (er32(EECD) & E1000_EECD_AUTO_RD) + break; + usleep_range(1000, 2000); + i++; + } + + if (i == AUTO_READ_DONE_TIMEOUT) { + e_dbg("Auto read by HW from NVM has not completed.\n"); + return -E1000_ERR_RESET; + } + + return 0; +} + +/** + * e1000e_valid_led_default - Verify a valid default LED config + * @hw: pointer to the HW structure + * @data: pointer to the NVM (EEPROM) + * + * Read the EEPROM for the current default LED configuration. If the + * LED configuration is not valid, set to a valid LED configuration. + **/ +s32 e1000e_valid_led_default(struct e1000_hw *hw, u16 *data) +{ + s32 ret_val; + + ret_val = e1000_read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data); + if (ret_val) { + e_dbg("NVM Read Error\n"); + return ret_val; + } + + if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) + *data = ID_LED_DEFAULT; + + return 0; +} + +/** + * e1000e_id_led_init - + * @hw: pointer to the HW structure + * + **/ +s32 e1000e_id_led_init(struct e1000_hw *hw) +{ + struct e1000_mac_info *mac = &hw->mac; + s32 ret_val; + const u32 ledctl_mask = 0x000000FF; + const u32 ledctl_on = E1000_LEDCTL_MODE_LED_ON; + const u32 ledctl_off = E1000_LEDCTL_MODE_LED_OFF; + u16 data, i, temp; + const u16 led_mask = 0x0F; + + ret_val = hw->nvm.ops.valid_led_default(hw, &data); + if (ret_val) + return ret_val; + + mac->ledctl_default = er32(LEDCTL); + mac->ledctl_mode1 = mac->ledctl_default; + mac->ledctl_mode2 = mac->ledctl_default; + + for (i = 0; i < 4; i++) { + temp = (data >> (i << 2)) & led_mask; + switch (temp) { + case ID_LED_ON1_DEF2: + case ID_LED_ON1_ON2: + case ID_LED_ON1_OFF2: + mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3)); + mac->ledctl_mode1 |= ledctl_on << (i << 3); + break; + case ID_LED_OFF1_DEF2: + case ID_LED_OFF1_ON2: + case ID_LED_OFF1_OFF2: + mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3)); + mac->ledctl_mode1 |= ledctl_off << (i << 3); + break; + default: + /* Do nothing */ + break; + } + switch (temp) { + case ID_LED_DEF1_ON2: + case ID_LED_ON1_ON2: + case ID_LED_OFF1_ON2: + mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3)); + mac->ledctl_mode2 |= ledctl_on << (i << 3); + break; + case ID_LED_DEF1_OFF2: + case ID_LED_ON1_OFF2: + case ID_LED_OFF1_OFF2: + mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3)); + mac->ledctl_mode2 |= ledctl_off << (i << 3); + break; + default: + /* Do nothing */ + break; + } + } + + return 0; +} + +/** + * e1000e_setup_led_generic - Configures SW controllable LED + * @hw: pointer to the HW structure + * + * This prepares the SW controllable LED for use and saves the current state + * of the LED so it can be later restored. + **/ +s32 e1000e_setup_led_generic(struct e1000_hw *hw) +{ + u32 ledctl; + + if (hw->mac.ops.setup_led != e1000e_setup_led_generic) + return -E1000_ERR_CONFIG; + + if (hw->phy.media_type == e1000_media_type_fiber) { + ledctl = er32(LEDCTL); + hw->mac.ledctl_default = ledctl; + /* Turn off LED0 */ + ledctl &= ~(E1000_LEDCTL_LED0_IVRT | E1000_LEDCTL_LED0_BLINK | + E1000_LEDCTL_LED0_MODE_MASK); + ledctl |= (E1000_LEDCTL_MODE_LED_OFF << + E1000_LEDCTL_LED0_MODE_SHIFT); + ew32(LEDCTL, ledctl); + } else if (hw->phy.media_type == e1000_media_type_copper) { + ew32(LEDCTL, hw->mac.ledctl_mode1); + } + + return 0; +} + +/** + * e1000e_cleanup_led_generic - Set LED config to default operation + * @hw: pointer to the HW structure + * + * Remove the current LED configuration and set the LED configuration + * to the default value, saved from the EEPROM. + **/ +s32 e1000e_cleanup_led_generic(struct e1000_hw *hw) +{ + ew32(LEDCTL, hw->mac.ledctl_default); + return 0; +} + +/** + * e1000e_blink_led_generic - Blink LED + * @hw: pointer to the HW structure + * + * Blink the LEDs which are set to be on. + **/ +s32 e1000e_blink_led_generic(struct e1000_hw *hw) +{ + u32 ledctl_blink = 0; + u32 i; + + if (hw->phy.media_type == e1000_media_type_fiber) { + /* always blink LED0 for PCI-E fiber */ + ledctl_blink = E1000_LEDCTL_LED0_BLINK | + (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED0_MODE_SHIFT); + } else { + /* + * set the blink bit for each LED that's "on" (0x0E) + * in ledctl_mode2 + */ + ledctl_blink = hw->mac.ledctl_mode2; + for (i = 0; i < 4; i++) + if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) == + E1000_LEDCTL_MODE_LED_ON) + ledctl_blink |= (E1000_LEDCTL_LED0_BLINK << + (i * 8)); + } + + ew32(LEDCTL, ledctl_blink); + + return 0; +} + +/** + * e1000e_led_on_generic - Turn LED on + * @hw: pointer to the HW structure + * + * Turn LED on. + **/ +s32 e1000e_led_on_generic(struct e1000_hw *hw) +{ + u32 ctrl; + + switch (hw->phy.media_type) { + case e1000_media_type_fiber: + ctrl = er32(CTRL); + ctrl &= ~E1000_CTRL_SWDPIN0; + ctrl |= E1000_CTRL_SWDPIO0; + ew32(CTRL, ctrl); + break; + case e1000_media_type_copper: + ew32(LEDCTL, hw->mac.ledctl_mode2); + break; + default: + break; + } + + return 0; +} + +/** + * e1000e_led_off_generic - Turn LED off + * @hw: pointer to the HW structure + * + * Turn LED off. + **/ +s32 e1000e_led_off_generic(struct e1000_hw *hw) +{ + u32 ctrl; + + switch (hw->phy.media_type) { + case e1000_media_type_fiber: + ctrl = er32(CTRL); + ctrl |= E1000_CTRL_SWDPIN0; + ctrl |= E1000_CTRL_SWDPIO0; + ew32(CTRL, ctrl); + break; + case e1000_media_type_copper: + ew32(LEDCTL, hw->mac.ledctl_mode1); + break; + default: + break; + } + + return 0; +} + +/** + * e1000e_set_pcie_no_snoop - Set PCI-express capabilities + * @hw: pointer to the HW structure + * @no_snoop: bitmap of snoop events + * + * Set the PCI-express register to snoop for events enabled in 'no_snoop'. + **/ +void e1000e_set_pcie_no_snoop(struct e1000_hw *hw, u32 no_snoop) +{ + u32 gcr; + + if (no_snoop) { + gcr = er32(GCR); + gcr &= ~(PCIE_NO_SNOOP_ALL); + gcr |= no_snoop; + ew32(GCR, gcr); + } +} + +/** + * e1000e_disable_pcie_master - Disables PCI-express master access + * @hw: pointer to the HW structure + * + * Returns 0 if successful, else returns -10 + * (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not caused + * the master requests to be disabled. + * + * Disables PCI-Express master access and verifies there are no pending + * requests. + **/ +s32 e1000e_disable_pcie_master(struct e1000_hw *hw) +{ + u32 ctrl; + s32 timeout = MASTER_DISABLE_TIMEOUT; + + ctrl = er32(CTRL); + ctrl |= E1000_CTRL_GIO_MASTER_DISABLE; + ew32(CTRL, ctrl); + + while (timeout) { + if (!(er32(STATUS) & E1000_STATUS_GIO_MASTER_ENABLE)) + break; + udelay(100); + timeout--; + } + + if (!timeout) { + e_dbg("Master requests are pending.\n"); + return -E1000_ERR_MASTER_REQUESTS_PENDING; + } + + return 0; +} + +/** + * e1000e_reset_adaptive - Reset Adaptive Interframe Spacing + * @hw: pointer to the HW structure + * + * Reset the Adaptive Interframe Spacing throttle to default values. + **/ +void e1000e_reset_adaptive(struct e1000_hw *hw) +{ + struct e1000_mac_info *mac = &hw->mac; + + if (!mac->adaptive_ifs) { + e_dbg("Not in Adaptive IFS mode!\n"); + goto out; + } + + mac->current_ifs_val = 0; + mac->ifs_min_val = IFS_MIN; + mac->ifs_max_val = IFS_MAX; + mac->ifs_step_size = IFS_STEP; + mac->ifs_ratio = IFS_RATIO; + + mac->in_ifs_mode = false; + ew32(AIT, 0); +out: + return; +} + +/** + * e1000e_update_adaptive - Update Adaptive Interframe Spacing + * @hw: pointer to the HW structure + * + * Update the Adaptive Interframe Spacing Throttle value based on the + * time between transmitted packets and time between collisions. + **/ +void e1000e_update_adaptive(struct e1000_hw *hw) +{ + struct e1000_mac_info *mac = &hw->mac; + + if (!mac->adaptive_ifs) { + e_dbg("Not in Adaptive IFS mode!\n"); + goto out; + } + + if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) { + if (mac->tx_packet_delta > MIN_NUM_XMITS) { + mac->in_ifs_mode = true; + if (mac->current_ifs_val < mac->ifs_max_val) { + if (!mac->current_ifs_val) + mac->current_ifs_val = mac->ifs_min_val; + else + mac->current_ifs_val += + mac->ifs_step_size; + ew32(AIT, mac->current_ifs_val); + } + } + } else { + if (mac->in_ifs_mode && + (mac->tx_packet_delta <= MIN_NUM_XMITS)) { + mac->current_ifs_val = 0; + mac->in_ifs_mode = false; + ew32(AIT, 0); + } + } +out: + return; +} diff --git a/drivers/net/ethernet/intel/e1000e/manage.c b/drivers/net/ethernet/intel/e1000e/manage.c new file mode 100644 index 00000000000..3dae2655ec7 --- /dev/null +++ b/drivers/net/ethernet/intel/e1000e/manage.c @@ -0,0 +1,377 @@ +/******************************************************************************* + + Intel PRO/1000 Linux driver + Copyright(c) 1999 - 2011 Intel Corporation. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + Linux NICS + e1000-devel Mailing List + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + +*******************************************************************************/ + +#include "e1000.h" + +enum e1000_mng_mode { + e1000_mng_mode_none = 0, + e1000_mng_mode_asf, + e1000_mng_mode_pt, + e1000_mng_mode_ipmi, + e1000_mng_mode_host_if_only +}; + +#define E1000_FACTPS_MNGCG 0x20000000 + +/* Intel(R) Active Management Technology signature */ +#define E1000_IAMT_SIGNATURE 0x544D4149 + +/** + * e1000_calculate_checksum - Calculate checksum for buffer + * @buffer: pointer to EEPROM + * @length: size of EEPROM to calculate a checksum for + * + * Calculates the checksum for some buffer on a specified length. The + * checksum calculated is returned. + **/ +static u8 e1000_calculate_checksum(u8 *buffer, u32 length) +{ + u32 i; + u8 sum = 0; + + if (!buffer) + return 0; + + for (i = 0; i < length; i++) + sum += buffer[i]; + + return (u8)(0 - sum); +} + +/** + * e1000_mng_enable_host_if - Checks host interface is enabled + * @hw: pointer to the HW structure + * + * Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND + * + * This function checks whether the HOST IF is enabled for command operation + * and also checks whether the previous command is completed. It busy waits + * in case of previous command is not completed. + **/ +static s32 e1000_mng_enable_host_if(struct e1000_hw *hw) +{ + u32 hicr; + u8 i; + + if (!(hw->mac.arc_subsystem_valid)) { + e_dbg("ARC subsystem not valid.\n"); + return -E1000_ERR_HOST_INTERFACE_COMMAND; + } + + /* Check that the host interface is enabled. */ + hicr = er32(HICR); + if ((hicr & E1000_HICR_EN) == 0) { + e_dbg("E1000_HOST_EN bit disabled.\n"); + return -E1000_ERR_HOST_INTERFACE_COMMAND; + } + /* check the previous command is completed */ + for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) { + hicr = er32(HICR); + if (!(hicr & E1000_HICR_C)) + break; + mdelay(1); + } + + if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) { + e_dbg("Previous command timeout failed .\n"); + return -E1000_ERR_HOST_INTERFACE_COMMAND; + } + + return 0; +} + +/** + * e1000e_check_mng_mode_generic - check management mode + * @hw: pointer to the HW structure + * + * Reads the firmware semaphore register and returns true (>0) if + * manageability is enabled, else false (0). + **/ +bool e1000e_check_mng_mode_generic(struct e1000_hw *hw) +{ + u32 fwsm = er32(FWSM); + + return (fwsm & E1000_FWSM_MODE_MASK) == + (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT); +} + +/** + * e1000e_enable_tx_pkt_filtering - Enable packet filtering on Tx + * @hw: pointer to the HW structure + * + * Enables packet filtering on transmit packets if manageability is enabled + * and host interface is enabled. + **/ +bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw) +{ + struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie; + u32 *buffer = (u32 *)&hw->mng_cookie; + u32 offset; + s32 ret_val, hdr_csum, csum; + u8 i, len; + + hw->mac.tx_pkt_filtering = true; + + /* No manageability, no filtering */ + if (!e1000e_check_mng_mode(hw)) { + hw->mac.tx_pkt_filtering = false; + goto out; + } + + /* + * If we can't read from the host interface for whatever + * reason, disable filtering. + */ + ret_val = e1000_mng_enable_host_if(hw); + if (ret_val) { + hw->mac.tx_pkt_filtering = false; + goto out; + } + + /* Read in the header. Length and offset are in dwords. */ + len = E1000_MNG_DHCP_COOKIE_LENGTH >> 2; + offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2; + for (i = 0; i < len; i++) + *(buffer + i) = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF, + offset + i); + hdr_csum = hdr->checksum; + hdr->checksum = 0; + csum = e1000_calculate_checksum((u8 *)hdr, + E1000_MNG_DHCP_COOKIE_LENGTH); + /* + * If either the checksums or signature don't match, then + * the cookie area isn't considered valid, in which case we + * take the safe route of assuming Tx filtering is enabled. + */ + if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) { + hw->mac.tx_pkt_filtering = true; + goto out; + } + + /* Cookie area is valid, make the final check for filtering. */ + if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) { + hw->mac.tx_pkt_filtering = false; + goto out; + } + +out: + return hw->mac.tx_pkt_filtering; +} + +/** + * e1000_mng_write_cmd_header - Writes manageability command header + * @hw: pointer to the HW structure + * @hdr: pointer to the host interface command header + * + * Writes the command header after does the checksum calculation. + **/ +static s32 e1000_mng_write_cmd_header(struct e1000_hw *hw, + struct e1000_host_mng_command_header *hdr) +{ + u16 i, length = sizeof(struct e1000_host_mng_command_header); + + /* Write the whole command header structure with new checksum. */ + + hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length); + + length >>= 2; + /* Write the relevant command block into the ram area. */ + for (i = 0; i < length; i++) { + E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, i, *((u32 *)hdr + i)); + e1e_flush(); + } + + return 0; +} + +/** + * e1000_mng_host_if_write - Write to the manageability host interface + * @hw: pointer to the HW structure + * @buffer: pointer to the host interface buffer + * @length: size of the buffer + * @offset: location in the buffer to write to + * @sum: sum of the data (not checksum) + * + * This function writes the buffer content at the offset given on the host if. + * It also does alignment considerations to do the writes in most efficient + * way. Also fills up the sum of the buffer in *buffer parameter. + **/ +static s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer, + u16 length, u16 offset, u8 *sum) +{ + u8 *tmp; + u8 *bufptr = buffer; + u32 data = 0; + u16 remaining, i, j, prev_bytes; + + /* sum = only sum of the data and it is not checksum */ + + if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) + return -E1000_ERR_PARAM; + + tmp = (u8 *)&data; + prev_bytes = offset & 0x3; + offset >>= 2; + + if (prev_bytes) { + data = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF, offset); + for (j = prev_bytes; j < sizeof(u32); j++) { + *(tmp + j) = *bufptr++; + *sum += *(tmp + j); + } + E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset, data); + length -= j - prev_bytes; + offset++; + } + + remaining = length & 0x3; + length -= remaining; + + /* Calculate length in DWORDs */ + length >>= 2; + + /* + * The device driver writes the relevant command block into the + * ram area. + */ + for (i = 0; i < length; i++) { + for (j = 0; j < sizeof(u32); j++) { + *(tmp + j) = *bufptr++; + *sum += *(tmp + j); + } + + E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data); + } + if (remaining) { + for (j = 0; j < sizeof(u32); j++) { + if (j < remaining) + *(tmp + j) = *bufptr++; + else + *(tmp + j) = 0; + + *sum += *(tmp + j); + } + E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data); + } + + return 0; +} + +/** + * e1000e_mng_write_dhcp_info - Writes DHCP info to host interface + * @hw: pointer to the HW structure + * @buffer: pointer to the host interface + * @length: size of the buffer + * + * Writes the DHCP information to the host interface. + **/ +s32 e1000e_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length) +{ + struct e1000_host_mng_command_header hdr; + s32 ret_val; + u32 hicr; + + hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD; + hdr.command_length = length; + hdr.reserved1 = 0; + hdr.reserved2 = 0; + hdr.checksum = 0; + + /* Enable the host interface */ + ret_val = e1000_mng_enable_host_if(hw); + if (ret_val) + return ret_val; + + /* Populate the host interface with the contents of "buffer". */ + ret_val = e1000_mng_host_if_write(hw, buffer, length, + sizeof(hdr), &(hdr.checksum)); + if (ret_val) + return ret_val; + + /* Write the manageability command header */ + ret_val = e1000_mng_write_cmd_header(hw, &hdr); + if (ret_val) + return ret_val; + + /* Tell the ARC a new command is pending. */ + hicr = er32(HICR); + ew32(HICR, hicr | E1000_HICR_C); + + return 0; +} + +/** + * e1000e_enable_mng_pass_thru - Check if management passthrough is needed + * @hw: pointer to the HW structure + * + * Verifies the hardware needs to leave interface enabled so that frames can + * be directed to and from the management interface. + **/ +bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw) +{ + u32 manc; + u32 fwsm, factps; + bool ret_val = false; + + manc = er32(MANC); + + if (!(manc & E1000_MANC_RCV_TCO_EN)) + goto out; + + if (hw->mac.has_fwsm) { + fwsm = er32(FWSM); + factps = er32(FACTPS); + + if (!(factps & E1000_FACTPS_MNGCG) && + ((fwsm & E1000_FWSM_MODE_MASK) == + (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) { + ret_val = true; + goto out; + } + } else if ((hw->mac.type == e1000_82574) || + (hw->mac.type == e1000_82583)) { + u16 data; + + factps = er32(FACTPS); + e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data); + + if (!(factps & E1000_FACTPS_MNGCG) && + ((data & E1000_NVM_INIT_CTRL2_MNGM) == + (e1000_mng_mode_pt << 13))) { + ret_val = true; + goto out; + } + } else if ((manc & E1000_MANC_SMBUS_EN) && + !(manc & E1000_MANC_ASF_EN)) { + ret_val = true; + goto out; + } + +out: + return ret_val; +} diff --git a/drivers/net/ethernet/intel/e1000e/nvm.c b/drivers/net/ethernet/intel/e1000e/nvm.c new file mode 100644 index 00000000000..dbdaa0052b1 --- /dev/null +++ b/drivers/net/ethernet/intel/e1000e/nvm.c @@ -0,0 +1,647 @@ +/******************************************************************************* + + Intel PRO/1000 Linux driver + Copyright(c) 1999 - 2011 Intel Corporation. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + Linux NICS + e1000-devel Mailing List + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + +*******************************************************************************/ + +#include "e1000.h" + +/** + * e1000_raise_eec_clk - Raise EEPROM clock + * @hw: pointer to the HW structure + * @eecd: pointer to the EEPROM + * + * Enable/Raise the EEPROM clock bit. + **/ +static void e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd) +{ + *eecd = *eecd | E1000_EECD_SK; + ew32(EECD, *eecd); + e1e_flush(); + udelay(hw->nvm.delay_usec); +} + +/** + * e1000_lower_eec_clk - Lower EEPROM clock + * @hw: pointer to the HW structure + * @eecd: pointer to the EEPROM + * + * Clear/Lower the EEPROM clock bit. + **/ +static void e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd) +{ + *eecd = *eecd & ~E1000_EECD_SK; + ew32(EECD, *eecd); + e1e_flush(); + udelay(hw->nvm.delay_usec); +} + +/** + * e1000_shift_out_eec_bits - Shift data bits our to the EEPROM + * @hw: pointer to the HW structure + * @data: data to send to the EEPROM + * @count: number of bits to shift out + * + * We need to shift 'count' bits out to the EEPROM. So, the value in the + * "data" parameter will be shifted out to the EEPROM one bit at a time. + * In order to do this, "data" must be broken down into bits. + **/ +static void e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count) +{ + struct e1000_nvm_info *nvm = &hw->nvm; + u32 eecd = er32(EECD); + u32 mask; + + mask = 0x01 << (count - 1); + if (nvm->type == e1000_nvm_eeprom_spi) + eecd |= E1000_EECD_DO; + + do { + eecd &= ~E1000_EECD_DI; + + if (data & mask) + eecd |= E1000_EECD_DI; + + ew32(EECD, eecd); + e1e_flush(); + + udelay(nvm->delay_usec); + + e1000_raise_eec_clk(hw, &eecd); + e1000_lower_eec_clk(hw, &eecd); + + mask >>= 1; + } while (mask); + + eecd &= ~E1000_EECD_DI; + ew32(EECD, eecd); +} + +/** + * e1000_shift_in_eec_bits - Shift data bits in from the EEPROM + * @hw: pointer to the HW structure + * @count: number of bits to shift in + * + * In order to read a register from the EEPROM, we need to shift 'count' bits + * in from the EEPROM. Bits are "shifted in" by raising the clock input to + * the EEPROM (setting the SK bit), and then reading the value of the data out + * "DO" bit. During this "shifting in" process the data in "DI" bit should + * always be clear. + **/ +static u16 e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count) +{ + u32 eecd; + u32 i; + u16 data; + + eecd = er32(EECD); + + eecd &= ~(E1000_EECD_DO | E1000_EECD_DI); + data = 0; + + for (i = 0; i < count; i++) { + data <<= 1; + e1000_raise_eec_clk(hw, &eecd); + + eecd = er32(EECD); + + eecd &= ~E1000_EECD_DI; + if (eecd & E1000_EECD_DO) + data |= 1; + + e1000_lower_eec_clk(hw, &eecd); + } + + return data; +} + +/** + * e1000e_poll_eerd_eewr_done - Poll for EEPROM read/write completion + * @hw: pointer to the HW structure + * @ee_reg: EEPROM flag for polling + * + * Polls the EEPROM status bit for either read or write completion based + * upon the value of 'ee_reg'. + **/ +s32 e1000e_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg) +{ + u32 attempts = 100000; + u32 i, reg = 0; + + for (i = 0; i < attempts; i++) { + if (ee_reg == E1000_NVM_POLL_READ) + reg = er32(EERD); + else + reg = er32(EEWR); + + if (reg & E1000_NVM_RW_REG_DONE) + return 0; + + udelay(5); + } + + return -E1000_ERR_NVM; +} + +/** + * e1000e_acquire_nvm - Generic request for access to EEPROM + * @hw: pointer to the HW structure + * + * Set the EEPROM access request bit and wait for EEPROM access grant bit. + * Return successful if access grant bit set, else clear the request for + * EEPROM access and return -E1000_ERR_NVM (-1). + **/ +s32 e1000e_acquire_nvm(struct e1000_hw *hw) +{ + u32 eecd = er32(EECD); + s32 timeout = E1000_NVM_GRANT_ATTEMPTS; + + ew32(EECD, eecd | E1000_EECD_REQ); + eecd = er32(EECD); + + while (timeout) { + if (eecd & E1000_EECD_GNT) + break; + udelay(5); + eecd = er32(EECD); + timeout--; + } + + if (!timeout) { + eecd &= ~E1000_EECD_REQ; + ew32(EECD, eecd); + e_dbg("Could not acquire NVM grant\n"); + return -E1000_ERR_NVM; + } + + return 0; +} + +/** + * e1000_standby_nvm - Return EEPROM to standby state + * @hw: pointer to the HW structure + * + * Return the EEPROM to a standby state. + **/ +static void e1000_standby_nvm(struct e1000_hw *hw) +{ + struct e1000_nvm_info *nvm = &hw->nvm; + u32 eecd = er32(EECD); + + if (nvm->type == e1000_nvm_eeprom_spi) { + /* Toggle CS to flush commands */ + eecd |= E1000_EECD_CS; + ew32(EECD, eecd); + e1e_flush(); + udelay(nvm->delay_usec); + eecd &= ~E1000_EECD_CS; + ew32(EECD, eecd); + e1e_flush(); + udelay(nvm->delay_usec); + } +} + +/** + * e1000_stop_nvm - Terminate EEPROM command + * @hw: pointer to the HW structure + * + * Terminates the current command by inverting the EEPROM's chip select pin. + **/ +static void e1000_stop_nvm(struct e1000_hw *hw) +{ + u32 eecd; + + eecd = er32(EECD); + if (hw->nvm.type == e1000_nvm_eeprom_spi) { + /* Pull CS high */ + eecd |= E1000_EECD_CS; + e1000_lower_eec_clk(hw, &eecd); + } +} + +/** + * e1000e_release_nvm - Release exclusive access to EEPROM + * @hw: pointer to the HW structure + * + * Stop any current commands to the EEPROM and clear the EEPROM request bit. + **/ +void e1000e_release_nvm(struct e1000_hw *hw) +{ + u32 eecd; + + e1000_stop_nvm(hw); + + eecd = er32(EECD); + eecd &= ~E1000_EECD_REQ; + ew32(EECD, eecd); +} + +/** + * e1000_ready_nvm_eeprom - Prepares EEPROM for read/write + * @hw: pointer to the HW structure + * + * Setups the EEPROM for reading and writing. + **/ +static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw) +{ + struct e1000_nvm_info *nvm = &hw->nvm; + u32 eecd = er32(EECD); + u8 spi_stat_reg; + + if (nvm->type == e1000_nvm_eeprom_spi) { + u16 timeout = NVM_MAX_RETRY_SPI; + + /* Clear SK and CS */ + eecd &= ~(E1000_EECD_CS | E1000_EECD_SK); + ew32(EECD, eecd); + e1e_flush(); + udelay(1); + + /* + * Read "Status Register" repeatedly until the LSB is cleared. + * The EEPROM will signal that the command has been completed + * by clearing bit 0 of the internal status register. If it's + * not cleared within 'timeout', then error out. + */ + while (timeout) { + e1000_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI, + hw->nvm.opcode_bits); + spi_stat_reg = (u8)e1000_shift_in_eec_bits(hw, 8); + if (!(spi_stat_reg & NVM_STATUS_RDY_SPI)) + break; + + udelay(5); + e1000_standby_nvm(hw); + timeout--; + } + + if (!timeout) { + e_dbg("SPI NVM Status error\n"); + return -E1000_ERR_NVM; + } + } + + return 0; +} + +/** + * e1000e_read_nvm_eerd - Reads EEPROM using EERD register + * @hw: pointer to the HW structure + * @offset: offset of word in the EEPROM to read + * @words: number of words to read + * @data: word read from the EEPROM + * + * Reads a 16 bit word from the EEPROM using the EERD register. + **/ +s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) +{ + struct e1000_nvm_info *nvm = &hw->nvm; + u32 i, eerd = 0; + s32 ret_val = 0; + + /* + * A check for invalid values: offset too large, too many words, + * too many words for the offset, and not enough words. + */ + if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || + (words == 0)) { + e_dbg("nvm parameter(s) out of bounds\n"); + return -E1000_ERR_NVM; + } + + for (i = 0; i < words; i++) { + eerd = ((offset + i) << E1000_NVM_RW_ADDR_SHIFT) + + E1000_NVM_RW_REG_START; + + ew32(EERD, eerd); + ret_val = e1000e_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ); + if (ret_val) + break; + + data[i] = (er32(EERD) >> E1000_NVM_RW_REG_DATA); + } + + return ret_val; +} + +/** + * e1000e_write_nvm_spi - Write to EEPROM using SPI + * @hw: pointer to the HW structure + * @offset: offset within the EEPROM to be written to + * @words: number of words to write + * @data: 16 bit word(s) to be written to the EEPROM + * + * Writes data to EEPROM at offset using SPI interface. + * + * If e1000e_update_nvm_checksum is not called after this function , the + * EEPROM will most likely contain an invalid checksum. + **/ +s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) +{ + struct e1000_nvm_info *nvm = &hw->nvm; + s32 ret_val; + u16 widx = 0; + + /* + * A check for invalid values: offset too large, too many words, + * and not enough words. + */ + if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || + (words == 0)) { + e_dbg("nvm parameter(s) out of bounds\n"); + return -E1000_ERR_NVM; + } + + ret_val = nvm->ops.acquire(hw); + if (ret_val) + return ret_val; + + while (widx < words) { + u8 write_opcode = NVM_WRITE_OPCODE_SPI; + + ret_val = e1000_ready_nvm_eeprom(hw); + if (ret_val) { + nvm->ops.release(hw); + return ret_val; + } + + e1000_standby_nvm(hw); + + /* Send the WRITE ENABLE command (8 bit opcode) */ + e1000_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI, + nvm->opcode_bits); + + e1000_standby_nvm(hw); + + /* + * Some SPI eeproms use the 8th address bit embedded in the + * opcode + */ + if ((nvm->address_bits == 8) && (offset >= 128)) + write_opcode |= NVM_A8_OPCODE_SPI; + + /* Send the Write command (8-bit opcode + addr) */ + e1000_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits); + e1000_shift_out_eec_bits(hw, (u16)((offset + widx) * 2), + nvm->address_bits); + + /* Loop to allow for up to whole page write of eeprom */ + while (widx < words) { + u16 word_out = data[widx]; + word_out = (word_out >> 8) | (word_out << 8); + e1000_shift_out_eec_bits(hw, word_out, 16); + widx++; + + if ((((offset + widx) * 2) % nvm->page_size) == 0) { + e1000_standby_nvm(hw); + break; + } + } + } + + usleep_range(10000, 20000); + nvm->ops.release(hw); + return 0; +} + +/** + * e1000_read_pba_string_generic - Read device part number + * @hw: pointer to the HW structure + * @pba_num: pointer to device part number + * @pba_num_size: size of part number buffer + * + * Reads the product board assembly (PBA) number from the EEPROM and stores + * the value in pba_num. + **/ +s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num, + u32 pba_num_size) +{ + s32 ret_val; + u16 nvm_data; + u16 pba_ptr; + u16 offset; + u16 length; + + if (pba_num == NULL) { + e_dbg("PBA string buffer was null\n"); + ret_val = E1000_ERR_INVALID_ARGUMENT; + goto out; + } + + ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data); + if (ret_val) { + e_dbg("NVM Read Error\n"); + goto out; + } + + ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr); + if (ret_val) { + e_dbg("NVM Read Error\n"); + goto out; + } + + /* + * if nvm_data is not ptr guard the PBA must be in legacy format which + * means pba_ptr is actually our second data word for the PBA number + * and we can decode it into an ascii string + */ + if (nvm_data != NVM_PBA_PTR_GUARD) { + e_dbg("NVM PBA number is not stored as string\n"); + + /* we will need 11 characters to store the PBA */ + if (pba_num_size < 11) { + e_dbg("PBA string buffer too small\n"); + return E1000_ERR_NO_SPACE; + } + + /* extract hex string from data and pba_ptr */ + pba_num[0] = (nvm_data >> 12) & 0xF; + pba_num[1] = (nvm_data >> 8) & 0xF; + pba_num[2] = (nvm_data >> 4) & 0xF; + pba_num[3] = nvm_data & 0xF; + pba_num[4] = (pba_ptr >> 12) & 0xF; + pba_num[5] = (pba_ptr >> 8) & 0xF; + pba_num[6] = '-'; + pba_num[7] = 0; + pba_num[8] = (pba_ptr >> 4) & 0xF; + pba_num[9] = pba_ptr & 0xF; + + /* put a null character on the end of our string */ + pba_num[10] = '\0'; + + /* switch all the data but the '-' to hex char */ + for (offset = 0; offset < 10; offset++) { + if (pba_num[offset] < 0xA) + pba_num[offset] += '0'; + else if (pba_num[offset] < 0x10) + pba_num[offset] += 'A' - 0xA; + } + + goto out; + } + + ret_val = e1000_read_nvm(hw, pba_ptr, 1, &length); + if (ret_val) { + e_dbg("NVM Read Error\n"); + goto out; + } + + if (length == 0xFFFF || length == 0) { + e_dbg("NVM PBA number section invalid length\n"); + ret_val = E1000_ERR_NVM_PBA_SECTION; + goto out; + } + /* check if pba_num buffer is big enough */ + if (pba_num_size < (((u32)length * 2) - 1)) { + e_dbg("PBA string buffer too small\n"); + ret_val = E1000_ERR_NO_SPACE; + goto out; + } + + /* trim pba length from start of string */ + pba_ptr++; + length--; + + for (offset = 0; offset < length; offset++) { + ret_val = e1000_read_nvm(hw, pba_ptr + offset, 1, &nvm_data); + if (ret_val) { + e_dbg("NVM Read Error\n"); + goto out; + } + pba_num[offset * 2] = (u8)(nvm_data >> 8); + pba_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF); + } + pba_num[offset * 2] = '\0'; + +out: + return ret_val; +} + +/** + * e1000_read_mac_addr_generic - Read device MAC address + * @hw: pointer to the HW structure + * + * Reads the device MAC address from the EEPROM and stores the value. + * Since devices with two ports use the same EEPROM, we increment the + * last bit in the MAC address for the second port. + **/ +s32 e1000_read_mac_addr_generic(struct e1000_hw *hw) +{ + u32 rar_high; + u32 rar_low; + u16 i; + + rar_high = er32(RAH(0)); + rar_low = er32(RAL(0)); + + for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++) + hw->mac.perm_addr[i] = (u8)(rar_low >> (i * 8)); + + for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++) + hw->mac.perm_addr[i + 4] = (u8)(rar_high >> (i * 8)); + + for (i = 0; i < ETH_ALEN; i++) + hw->mac.addr[i] = hw->mac.perm_addr[i]; + + return 0; +} + +/** + * e1000e_validate_nvm_checksum_generic - Validate EEPROM checksum + * @hw: pointer to the HW structure + * + * Calculates the EEPROM checksum by reading/adding each word of the EEPROM + * and then verifies that the sum of the EEPROM is equal to 0xBABA. + **/ +s32 e1000e_validate_nvm_checksum_generic(struct e1000_hw *hw) +{ + s32 ret_val; + u16 checksum = 0; + u16 i, nvm_data; + + for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) { + ret_val = e1000_read_nvm(hw, i, 1, &nvm_data); + if (ret_val) { + e_dbg("NVM Read Error\n"); + return ret_val; + } + checksum += nvm_data; + } + + if (checksum != (u16)NVM_SUM) { + e_dbg("NVM Checksum Invalid\n"); + return -E1000_ERR_NVM; + } + + return 0; +} + +/** + * e1000e_update_nvm_checksum_generic - Update EEPROM checksum + * @hw: pointer to the HW structure + * + * Updates the EEPROM checksum by reading/adding each word of the EEPROM + * up to the checksum. Then calculates the EEPROM checksum and writes the + * value to the EEPROM. + **/ +s32 e1000e_update_nvm_checksum_generic(struct e1000_hw *hw) +{ + s32 ret_val; + u16 checksum = 0; + u16 i, nvm_data; + + for (i = 0; i < NVM_CHECKSUM_REG; i++) { + ret_val = e1000_read_nvm(hw, i, 1, &nvm_data); + if (ret_val) { + e_dbg("NVM Read Error while updating checksum.\n"); + return ret_val; + } + checksum += nvm_data; + } + checksum = (u16)NVM_SUM - checksum; + ret_val = e1000_write_nvm(hw, NVM_CHECKSUM_REG, 1, &checksum); + if (ret_val) + e_dbg("NVM Write Error while updating checksum.\n"); + + return ret_val; +} + +/** + * e1000e_reload_nvm - Reloads EEPROM + * @hw: pointer to the HW structure + * + * Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the + * extended control register. + **/ +void e1000e_reload_nvm(struct e1000_hw *hw) +{ + u32 ctrl_ext; + + udelay(10); + ctrl_ext = er32(CTRL_EXT); + ctrl_ext |= E1000_CTRL_EXT_EE_RST; + ew32(CTRL_EXT, ctrl_ext); + e1e_flush(); +} -- cgit v1.2.3-70-g09d2 From f5e261e626eb3fe07adf484aaad2ecfc757feba3 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Sun, 1 Jan 2012 16:00:03 +0000 Subject: e1000e: update copyright year Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/80003es2lan.c | 2 +- drivers/net/ethernet/intel/e1000e/82571.c | 2 +- drivers/net/ethernet/intel/e1000e/Makefile | 2 +- drivers/net/ethernet/intel/e1000e/defines.h | 2 +- drivers/net/ethernet/intel/e1000e/e1000.h | 2 +- drivers/net/ethernet/intel/e1000e/ethtool.c | 2 +- drivers/net/ethernet/intel/e1000e/hw.h | 2 +- drivers/net/ethernet/intel/e1000e/ich8lan.c | 2 +- drivers/net/ethernet/intel/e1000e/mac.c | 2 +- drivers/net/ethernet/intel/e1000e/manage.c | 2 +- drivers/net/ethernet/intel/e1000e/netdev.c | 4 ++-- drivers/net/ethernet/intel/e1000e/nvm.c | 2 +- drivers/net/ethernet/intel/e1000e/param.c | 2 +- drivers/net/ethernet/intel/e1000e/phy.c | 2 +- 14 files changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/80003es2lan.c b/drivers/net/ethernet/intel/e1000e/80003es2lan.c index f323ce507f5..82a5d87c90c 100644 --- a/drivers/net/ethernet/intel/e1000e/80003es2lan.c +++ b/drivers/net/ethernet/intel/e1000e/80003es2lan.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. + Copyright(c) 1999 - 2012 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ethernet/intel/e1000e/82571.c b/drivers/net/ethernet/intel/e1000e/82571.c index 0609ac69bb3..844907da8aa 100644 --- a/drivers/net/ethernet/intel/e1000e/82571.c +++ b/drivers/net/ethernet/intel/e1000e/82571.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. + Copyright(c) 1999 - 2012 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ethernet/intel/e1000e/Makefile b/drivers/net/ethernet/intel/e1000e/Makefile index 8b888e5f6a0..591b7132450 100644 --- a/drivers/net/ethernet/intel/e1000e/Makefile +++ b/drivers/net/ethernet/intel/e1000e/Makefile @@ -1,7 +1,7 @@ ################################################################################ # # Intel PRO/1000 Linux driver -# Copyright(c) 1999 - 2011 Intel Corporation. +# Copyright(c) 1999 - 2012 Intel Corporation. # # This program is free software; you can redistribute it and/or modify it # under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ethernet/intel/e1000e/defines.h b/drivers/net/ethernet/intel/e1000e/defines.h index c73795f4653..1af30b967a4 100644 --- a/drivers/net/ethernet/intel/e1000e/defines.h +++ b/drivers/net/ethernet/intel/e1000e/defines.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. + Copyright(c) 1999 - 2012 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index 70bc9e90273..45e5ae8a9fb 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. + Copyright(c) 1999 - 2012 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index 1ea317f1adc..92d5b627895 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. + Copyright(c) 1999 - 2012 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ethernet/intel/e1000e/hw.h b/drivers/net/ethernet/intel/e1000e/hw.h index a15da4712f8..197059bb9ab 100644 --- a/drivers/net/ethernet/intel/e1000e/hw.h +++ b/drivers/net/ethernet/intel/e1000e/hw.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. + Copyright(c) 1999 - 2012 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 070a90f78aa..907b17b2e66 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. + Copyright(c) 1999 - 2012 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ethernet/intel/e1000e/mac.c b/drivers/net/ethernet/intel/e1000e/mac.c index 64b6f439338..e1cf1072f31 100644 --- a/drivers/net/ethernet/intel/e1000e/mac.c +++ b/drivers/net/ethernet/intel/e1000e/mac.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. + Copyright(c) 1999 - 2012 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ethernet/intel/e1000e/manage.c b/drivers/net/ethernet/intel/e1000e/manage.c index 3dae2655ec7..6594dbf248b 100644 --- a/drivers/net/ethernet/intel/e1000e/manage.c +++ b/drivers/net/ethernet/intel/e1000e/manage.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. + Copyright(c) 1999 - 2012 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 210d27ddd8c..1a8dd2f0e60 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. + Copyright(c) 1999 - 2012 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -6538,7 +6538,7 @@ static int __init e1000_init_module(void) int ret; pr_info("Intel(R) PRO/1000 Network Driver - %s\n", e1000e_driver_version); - pr_info("Copyright(c) 1999 - 2011 Intel Corporation.\n"); + pr_info("Copyright(c) 1999 - 2012 Intel Corporation.\n"); ret = pci_register_driver(&e1000_driver); return ret; diff --git a/drivers/net/ethernet/intel/e1000e/nvm.c b/drivers/net/ethernet/intel/e1000e/nvm.c index dbdaa0052b1..f6fb7a768ba 100644 --- a/drivers/net/ethernet/intel/e1000e/nvm.c +++ b/drivers/net/ethernet/intel/e1000e/nvm.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. + Copyright(c) 1999 - 2012 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ethernet/intel/e1000e/param.c b/drivers/net/ethernet/intel/e1000e/param.c index 40664f5bfbd..9c6a56d804a 100644 --- a/drivers/net/ethernet/intel/e1000e/param.c +++ b/drivers/net/ethernet/intel/e1000e/param.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. + Copyright(c) 1999 - 2012 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ethernet/intel/e1000e/phy.c b/drivers/net/ethernet/intel/e1000e/phy.c index ed70d08db5b..8dd2ff03f1f 100644 --- a/drivers/net/ethernet/intel/e1000e/phy.c +++ b/drivers/net/ethernet/intel/e1000e/phy.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. + Copyright(c) 1999 - 2012 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, -- cgit v1.2.3-70-g09d2 From 36f21f1ce419a552227b32d445e40c2d99286275 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 12 Jan 2012 10:55:15 +0100 Subject: clocksource: cyclone: Add missing iounmap Add missing iounmap in error handling code, in a case where the function already preforms iounmap on some other execution path. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression e; statement S,S1; int ret; @@ e = \(ioremap\|ioremap_nocache\)(...) ... when != iounmap(e) if (<+...e...+>) S ... when any when != iounmap(e) *if (...) { ... when != iounmap(e) return ...; } ... when any iounmap(e); // Signed-off-by: Julia Lawall [fixed up subject -jstultz] Signed-off-by: John Stultz --- drivers/clocksource/cyclone.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clocksource/cyclone.c b/drivers/clocksource/cyclone.c index 72f811f73e9..9e0998f2288 100644 --- a/drivers/clocksource/cyclone.c +++ b/drivers/clocksource/cyclone.c @@ -55,11 +55,11 @@ static int __init init_cyclone_clocksource(void) } /* even on 64bit systems, this is only 32bits: */ base = readl(reg); + iounmap(reg); if (!base) { printk(KERN_ERR "Summit chipset: Could not find valid CBAR value.\n"); return -ENODEV; } - iounmap(reg); /* setup PMCC: */ offset = base + CYCLONE_PMCC_OFFSET; -- cgit v1.2.3-70-g09d2 From bd729d72b428261f2975360e0c117d7d7a2cd6e8 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Thu, 5 Jan 2012 15:21:19 -0800 Subject: rtc: Avoid setting alarm to a time in the past In some cases at boot up, the RTC alarm may be set in the past, but still have the enabled flag on. This was causing problems, because we would then enqueue the alarm into the timerqueue, but it would never fire. This would clog up the timerqueue and keep other alarms from working. The fix is to check the alarm against the current rtc time at boot and avoid enqueueing the alarm if it is in the past. Reported-by: NeilBrown Tested-by: NeilBrown Tested-by: Sander Eikelenboom Signed-off-by: John Stultz --- drivers/rtc/interface.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 8a1c031391d..c55a16041b6 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -380,18 +380,27 @@ EXPORT_SYMBOL_GPL(rtc_set_alarm); int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) { int err; + struct rtc_time now; err = rtc_valid_tm(&alarm->time); if (err != 0) return err; + err = rtc_read_time(rtc, &now); + if (err) + return err; + err = mutex_lock_interruptible(&rtc->ops_lock); if (err) return err; rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time); rtc->aie_timer.period = ktime_set(0, 0); - if (alarm->enabled) { + + /* Alarm has to be enabled & in the futrure for us to enqueue it */ + if (alarm->enabled && (rtc_tm_to_ktime(now).tv64 < + rtc->aie_timer.node.expires.tv64)) { + rtc->aie_timer.enabled = 1; timerqueue_add(&rtc->timerqueue, &rtc->aie_timer.node); } -- cgit v1.2.3-70-g09d2 From 5f9679d29c7959445d4af1eb85ee55e4ebad4a93 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 9 Dec 2011 09:39:15 +1100 Subject: rtc: Expire alarms after the time is set. (v2) If the alarm time programming in the rtc is ever in the past, it won't fire, and any other alarm will be queued after it so they won't fire either. So any time that the alarm might be in the past, we need to trigger the irq handler to ensure the old alarm is cleared and the timer queue is fully in the future. This is done whenever the RTC clock is set. This is the second revision of this patch, which was earlier reverted. This version avoids the initialization problem, which is handled by a different patch. Tested-by: Sander Eikelenboom Signed-off-by: NeilBrown [Remove problematic initialization change, update commit log, also catch set_mmss case -jstultz] Signed-off-by: John Stultz --- drivers/rtc/interface.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index c55a16041b6..167e68a9ffd 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -73,6 +73,8 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) err = -EINVAL; mutex_unlock(&rtc->ops_lock); + /* A timer might have just expired */ + schedule_work(&rtc->irqwork); return err; } EXPORT_SYMBOL_GPL(rtc_set_time); @@ -112,6 +114,8 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs) err = -EINVAL; mutex_unlock(&rtc->ops_lock); + /* A timer might have just expired */ + schedule_work(&rtc->irqwork); return err; } -- cgit v1.2.3-70-g09d2 From 41c7f7424259ff11009449f87c95656f69f9b186 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Tue, 22 Nov 2011 11:03:14 +0100 Subject: rtc: Disable the alarm in the hardware (v2) Currently, the RTC code does not disable the alarm in the hardware. This means that after a sequence such as the one below (the files are in the RTC sysfs), the box will boot up after 2 minutes even though we've asked for the alarm to be turned off. # echo $((`cat since_epoch`)+120) > wakealarm # echo 0 > wakealarm # poweroff Fix this by disabling the alarm when there are no timers to run. The original version of this patch was reverted. This version disables the irq directly instead of setting a disabled timer in the future. Cc: stable@kernel.org Cc: John Stultz Signed-off-by: Rabin Vincent [Merged in the second revision from Rabin] Signed-off-by: John Stultz --- drivers/rtc/interface.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 167e68a9ffd..dc87eda6581 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -776,6 +776,14 @@ static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) return 0; } +static void rtc_alarm_disable(struct rtc_device *rtc) +{ + if (!rtc->ops || !rtc->ops->alarm_irq_enable) + return; + + rtc->ops->alarm_irq_enable(rtc->dev.parent, false); +} + /** * rtc_timer_remove - Removes a rtc_timer from the rtc_device timerqueue * @rtc rtc device @@ -797,8 +805,10 @@ static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer) struct rtc_wkalrm alarm; int err; next = timerqueue_getnext(&rtc->timerqueue); - if (!next) + if (!next) { + rtc_alarm_disable(rtc); return; + } alarm.time = rtc_ktime_to_tm(next->expires); alarm.enabled = 1; err = __rtc_set_alarm(rtc, &alarm); @@ -860,7 +870,8 @@ again: err = __rtc_set_alarm(rtc, &alarm); if (err == -ETIME) goto again; - } + } else + rtc_alarm_disable(rtc); mutex_unlock(&rtc->ops_lock); } -- cgit v1.2.3-70-g09d2 From c8aa130b74cc5b112cb2b119d3b477abaaf6e5b2 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Fri, 27 Jan 2012 15:22:07 +0900 Subject: PM / Domains: Add OF support A device node pointer is added to generic pm domain structure to associate the domain with a node in the device tree. The platform code parses the device tree to find available nodes representing the generic power domain, instantiates the available domains and initializes them by calling pm_genpd_init(). Nodes representing the devices include a phandle of the power domain to which it belongs. As these devices get instantiated, the driver code checkes for availability of a power domain phandle, converts the phandle to a device node and uses the new pm_genpd_of_add_device() api to associate the device with a power domain. pm_genpd_of_add_device() runs through its list of registered power domains and matches the OF node of the domain with the one specified as the parameter. If a match is found, the device is associated with the matched domain. Cc: Rob Herring Cc: Grant Likely Signed-off-by: Thomas Abraham Acked-by: Rafael J. Wysocki Signed-off-by: Kukjin Kim --- drivers/base/power/domain.c | 32 ++++++++++++++++++++++++++++++++ include/linux/pm_domain.h | 12 ++++++++++++ 2 files changed, 44 insertions(+) (limited to 'drivers') diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 978bbf7ac6a..939109b75c9 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -1170,6 +1170,38 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, return ret; } +/** + * __pm_genpd_of_add_device - Add a device to an I/O PM domain. + * @genpd_node: Device tree node pointer representing a PM domain to which the + * the device is added to. + * @dev: Device to be added. + * @td: Set of PM QoS timing parameters to attach to the device. + */ +int __pm_genpd_of_add_device(struct device_node *genpd_node, struct device *dev, + struct gpd_timing_data *td) +{ + struct generic_pm_domain *genpd = NULL, *gpd; + + dev_dbg(dev, "%s()\n", __func__); + + if (IS_ERR_OR_NULL(genpd_node) || IS_ERR_OR_NULL(dev)) + return -EINVAL; + + mutex_lock(&gpd_list_lock); + list_for_each_entry(gpd, &gpd_list, gpd_list_node) { + if (gpd->of_node == genpd_node) { + genpd = gpd; + break; + } + } + mutex_unlock(&gpd_list_lock); + + if (!genpd) + return -EINVAL; + + return __pm_genpd_add_device(genpd, dev, td); +} + /** * pm_genpd_remove_device - Remove a device from an I/O PM domain. * @genpd: PM domain to remove the device from. diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index a03a0ad998b..e3ff87550ee 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -11,6 +11,7 @@ #include #include +#include enum gpd_status { GPD_STATE_ACTIVE = 0, /* PM domain is active */ @@ -70,6 +71,7 @@ struct generic_pm_domain { s64 break_even_ns; /* Power break even for the entire domain. */ s64 max_off_time_ns; /* Maximum allowed "suspended" time. */ ktime_t power_off_time; + struct device_node *of_node; /* Node in device tree */ }; static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd) @@ -117,12 +119,22 @@ extern int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, struct gpd_timing_data *td); +extern int __pm_genpd_of_add_device(struct device_node *genpd_node, + struct device *dev, + struct gpd_timing_data *td); + static inline int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev) { return __pm_genpd_add_device(genpd, dev, NULL); } +static inline int pm_genpd_of_add_device(struct device_node *genpd_node, + struct device *dev) +{ + return __pm_genpd_of_add_device(genpd_node, dev, NULL); +} + extern int pm_genpd_remove_device(struct generic_pm_domain *genpd, struct device *dev); extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, -- cgit v1.2.3-70-g09d2 From 4512ff9f361a2786a18cb805d1f64b8d8719f121 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Thu, 22 Dec 2011 18:59:37 +0100 Subject: r8169: remove hardcoded PCIe registers accesses. Signed-off-by: Francois Romieu --- drivers/net/ethernet/realtek/r8169.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 7a0c800b50a..ca86e67a33a 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -3824,23 +3824,21 @@ static void r8168dp_hw_jumbo_disable(struct rtl8169_private *tp) static void r8168e_hw_jumbo_enable(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; - struct pci_dev *pdev = tp->pci_dev; RTL_W8(MaxTxPacketSize, 0x3f); RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0); RTL_W8(Config4, RTL_R8(Config4) | 0x01); - pci_write_config_byte(pdev, 0x79, 0x20); + rtl_tx_performance_tweak(tp->pci_dev, 0x2 << MAX_READ_REQUEST_SHIFT); } static void r8168e_hw_jumbo_disable(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; - struct pci_dev *pdev = tp->pci_dev; RTL_W8(MaxTxPacketSize, 0x0c); RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0); RTL_W8(Config4, RTL_R8(Config4) & ~0x01); - pci_write_config_byte(pdev, 0x79, 0x50); + rtl_tx_performance_tweak(tp->pci_dev, 0x5 << MAX_READ_REQUEST_SHIFT); } static void r8168b_0_hw_jumbo_enable(struct rtl8169_private *tp) -- cgit v1.2.3-70-g09d2 From 209e5ac83b4d038ffb52cabc793f75031602a031 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Thu, 26 Jan 2012 09:59:50 +0100 Subject: r8169: remove rtl8169_reinit_task. I see no good reason to keep both rtl8169_reinit_task and rtl8169_reset_task: - rtl8169_reinit_task adds a software failure point which does relate to any hardware state - they handle hardware the same. Remember that rtl8169_reinit_task was introduced in the 8169 only era to handle PCI errors way before the 8168 asked for pll and firmware ops and compare : rtl8169_reinit_task | rtl8169_reset_task ----------------------------+-------------------------- rtl8169_wait_for_quiescence | rtl8169_hw_reset rtl8169_update_counters | rtl8169_wait_for_quiescence rtl8169_hw_reset | rtl_hw_start rtl8169_rx_missed | rtl8169_check_link_status rtl_pll_power_down | rtl_request_firmware | rtl8169_init_phy | rtl_pll_power_up | rtl_hw_start | rtl8169_check_link_status | Signed-off-by: Francois Romieu Cc: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 34 +++------------------------------- 1 file changed, 3 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index ca86e67a33a..4f0856b8fab 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -5353,34 +5353,6 @@ static void rtl8169_wait_for_quiescence(struct net_device *dev) napi_enable(&tp->napi); } -static void rtl8169_reinit_task(struct work_struct *work) -{ - struct rtl8169_private *tp = - container_of(work, struct rtl8169_private, task.work); - struct net_device *dev = tp->dev; - int ret; - - rtnl_lock(); - - if (!netif_running(dev)) - goto out_unlock; - - rtl8169_wait_for_quiescence(dev); - rtl8169_close(dev); - - ret = rtl8169_open(dev); - if (unlikely(ret < 0)) { - if (net_ratelimit()) - netif_err(tp, drv, dev, - "reinit failure (status = %d). Rescheduling\n", - ret); - rtl8169_schedule_work(dev, rtl8169_reinit_task); - } - -out_unlock: - rtnl_unlock(); -} - static void rtl8169_reset_task(struct work_struct *work) { struct rtl8169_private *tp = @@ -5616,7 +5588,7 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev) rtl8169_hw_reset(tp); - rtl8169_schedule_work(dev, rtl8169_reinit_task); + rtl8169_schedule_work(dev, rtl8169_reset_task); } static void rtl8169_tx_interrupt(struct net_device *dev, @@ -5923,8 +5895,8 @@ static void rtl8169_down(struct net_device *dev) rtl8169_hw_reset(tp); /* * At this point device interrupts can not be enabled in any function, - * as netif_running is not true (rtl8169_interrupt, rtl8169_reset_task, - * rtl8169_reinit_task) and napi is disabled (rtl8169_poll). + * as netif_running is not true (rtl8169_interrupt, rtl8169_reset_task) + * and napi is disabled (rtl8169_poll). */ rtl8169_rx_missed(dev, ioaddr); -- cgit v1.2.3-70-g09d2 From 4422bcd4907d1bbb9f63e049e3c3819132c047a1 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Thu, 26 Jan 2012 11:23:32 +0100 Subject: r8169: stop delaying workqueue. Though motivated by the move of the driver to a single work queue of sequential events and removal of hard irq processing, it looks safe as a standalone change. Signed-off-by: Francois Romieu Cc: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 37 +++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 4f0856b8fab..6d74931049f 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -714,7 +714,11 @@ struct rtl8169_private { unsigned int (*phy_reset_pending)(struct rtl8169_private *tp); unsigned int (*link_ok)(void __iomem *); int (*do_ioctl)(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd); - struct delayed_work task; + + struct { + struct work_struct work; + } wk; + unsigned features; struct mii_if_info mii; @@ -4194,7 +4198,7 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) rtl8168_driver_stop(tp); } - cancel_delayed_work_sync(&tp->task); + cancel_work_sync(&tp->wk.work); unregister_netdev(dev); @@ -4255,6 +4259,8 @@ static void rtl_request_firmware(struct rtl8169_private *tp) rtl_request_uncached_firmware(tp); } +static void rtl_task(struct work_struct *); + static int rtl8169_open(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -4282,7 +4288,7 @@ static int rtl8169_open(struct net_device *dev) if (retval < 0) goto err_free_rx_1; - INIT_DELAYED_WORK(&tp->task, NULL); + INIT_WORK(&tp->wk.work, rtl_task); smp_mb(); @@ -5328,12 +5334,11 @@ static void rtl8169_tx_clear(struct rtl8169_private *tp) tp->cur_tx = tp->dirty_tx = 0; } -static void rtl8169_schedule_work(struct net_device *dev, work_func_t task) +static void rtl8169_schedule_work(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); - PREPARE_DELAYED_WORK(&tp->task, task); - schedule_delayed_work(&tp->task, 4); + schedule_work(&tp->wk.work); } static void rtl8169_wait_for_quiescence(struct net_device *dev) @@ -5353,10 +5358,8 @@ static void rtl8169_wait_for_quiescence(struct net_device *dev) napi_enable(&tp->napi); } -static void rtl8169_reset_task(struct work_struct *work) +static void rtl_reset_work(struct rtl8169_private *tp) { - struct rtl8169_private *tp = - container_of(work, struct rtl8169_private, task.work); struct net_device *dev = tp->dev; int i; @@ -5385,7 +5388,7 @@ out_unlock: static void rtl8169_tx_timeout(struct net_device *dev) { - rtl8169_schedule_work(dev, rtl8169_reset_task); + rtl8169_schedule_work(dev); } static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, @@ -5588,7 +5591,7 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev) rtl8169_hw_reset(tp); - rtl8169_schedule_work(dev, rtl8169_reset_task); + rtl8169_schedule_work(dev); } static void rtl8169_tx_interrupt(struct net_device *dev, @@ -5707,7 +5710,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev, if (status & RxCRC) dev->stats.rx_crc_errors++; if (status & RxFOVF) { - rtl8169_schedule_work(dev, rtl8169_reset_task); + rtl8169_schedule_work(dev); dev->stats.rx_fifo_errors++; } rtl8169_mark_to_asic(desc, rx_buf_sz); @@ -5840,6 +5843,14 @@ done: return IRQ_RETVAL(handled); } +static void rtl_task(struct work_struct *work) +{ + struct rtl8169_private *tp = + container_of(work, struct rtl8169_private, wk.work); + + rtl_reset_work(tp); +} + static int rtl8169_poll(struct napi_struct *napi, int budget) { struct rtl8169_private *tp = container_of(napi, struct rtl8169_private, napi); @@ -6046,7 +6057,7 @@ static void __rtl8169_resume(struct net_device *dev) rtl_pll_power_up(tp); - rtl8169_schedule_work(dev, rtl8169_reset_task); + rtl8169_schedule_work(dev); } static int rtl8169_resume(struct device *device) -- cgit v1.2.3-70-g09d2 From 3e990ff5f119c2f9b142f3e2548dc90ca9b7dfa1 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Thu, 26 Jan 2012 12:50:01 +0100 Subject: r8169: factor out IntrMask writes. Signed-off-by: Francois Romieu Cc: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 6d74931049f..9f9abb5d01a 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -1184,6 +1184,13 @@ static u8 rtl8168d_efuse_read(void __iomem *ioaddr, int reg_addr) return value; } +static void rtl_irq_enable(struct rtl8169_private *tp, u16 bits) +{ + void __iomem *ioaddr = tp->mmio_addr; + + RTL_W16(IntrMask, bits); +} + static void rtl8169_irq_mask_and_ack(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; @@ -4383,6 +4390,8 @@ static void rtl_hw_start(struct net_device *dev) tp->hw_start(dev); + rtl_irq_enable(tp, tp->intr_event); + netif_start_queue(dev); } @@ -4510,9 +4519,6 @@ static void rtl_hw_start_8169(struct net_device *dev) /* no early-rx interrupts */ RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); - - /* Enable all known interrupts by setting the interrupt mask. */ - RTL_W16(IntrMask, tp->intr_event); } static void rtl_csi_access_enable(void __iomem *ioaddr, u32 bits) @@ -4981,8 +4987,6 @@ static void rtl_hw_start_8168(struct net_device *dev) RTL_W8(Cfg9346, Cfg9346_Lock); RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); - - RTL_W16(IntrMask, tp->intr_event); } #define R810X_CPCMD_QUIRK_MASK (\ @@ -5140,8 +5144,6 @@ static void rtl_hw_start_8101(struct net_device *dev) rtl_set_rx_mode(dev); RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xf000); - - RTL_W16(IntrMask, tp->intr_event); } static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) -- cgit v1.2.3-70-g09d2 From 9085cdfa2f9f04d8678465748e2cced6e3f02e26 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Thu, 26 Jan 2012 12:59:08 +0100 Subject: r8169: irq mask helpers. Signed-off-by: Francois Romieu Cc: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 37 +++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 9f9abb5d01a..610f4b3655c 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -1184,6 +1184,29 @@ static u8 rtl8168d_efuse_read(void __iomem *ioaddr, int reg_addr) return value; } +static u16 rtl_get_events(struct rtl8169_private *tp) +{ + void __iomem *ioaddr = tp->mmio_addr; + + return RTL_R16(IntrStatus); +} + +static void rtl_ack_events(struct rtl8169_private *tp, u16 bits) +{ + void __iomem *ioaddr = tp->mmio_addr; + + RTL_W16(IntrStatus, bits); + mmiowb(); +} + +static void rtl_irq_disable(struct rtl8169_private *tp) +{ + void __iomem *ioaddr = tp->mmio_addr; + + RTL_W16(IntrMask, 0); + mmiowb(); +} + static void rtl_irq_enable(struct rtl8169_private *tp, u16 bits) { void __iomem *ioaddr = tp->mmio_addr; @@ -1195,8 +1218,8 @@ static void rtl8169_irq_mask_and_ack(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; - RTL_W16(IntrMask, 0x0000); - RTL_W16(IntrStatus, tp->intr_event); + rtl_irq_disable(tp); + rtl_ack_events(tp, tp->intr_event); RTL_R8(ChipCmd); } @@ -4057,11 +4080,11 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) rtl_init_rxcfg(tp); - RTL_W16(IntrMask, 0x0000); + rtl_irq_disable(tp); rtl_hw_reset(tp); - RTL_W16(IntrStatus, 0xffff); + rtl_ack_events(tp, 0xffff); pci_set_master(pdev); @@ -5775,12 +5798,12 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; int handled = 0; - int status; + u16 status; /* loop handling interrupts until we have no new ones or * we hit a invalid/hotplug case. */ - status = RTL_R16(IntrStatus); + status = rtl_get_events(tp); while (status && status != 0xffff) { status &= tp->intr_event; if (!status) @@ -5839,7 +5862,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) */ RTL_W16(IntrStatus, (status & RxFIFOOver) ? (status | RxOverflow) : status); - status = RTL_R16(IntrStatus); + status = rtl_get_events(tp); } done: return IRQ_RETVAL(handled); -- cgit v1.2.3-70-g09d2 From 9aa507505cdcd10b7390398790f013374ee74a26 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 27 Jan 2012 16:10:22 +0100 Subject: regmap: Add support for 2/6 register formating Signed-off-by: Wolfram Sang Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 2d71aeae310..b4475d87f4a 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -76,6 +76,14 @@ static bool regmap_volatile_range(struct regmap *map, unsigned int reg, return true; } +static void regmap_format_2_6_write(struct regmap *map, + unsigned int reg, unsigned int val) +{ + u8 *out = map->work_buf; + + *out = (reg << 6) | val; +} + static void regmap_format_4_12_write(struct regmap *map, unsigned int reg, unsigned int val) { @@ -180,6 +188,16 @@ struct regmap *regmap_init(struct device *dev, } switch (config->reg_bits) { + case 2: + switch (config->val_bits) { + case 6: + map->format.format_write = regmap_format_2_6_write; + break; + default: + goto err_map; + } + break; + case 4: switch (config->val_bits) { case 12: -- cgit v1.2.3-70-g09d2 From 1e874e041fc7c222cbd85b20c4406070be1f687a Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Fri, 27 Jan 2012 15:05:38 +0100 Subject: r8169: missing barriers. Signed-off-by: Francois Romieu Cc: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 610f4b3655c..8dd13f5a920 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -5552,7 +5552,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) { netif_stop_queue(dev); - smp_rmb(); + smp_mb(); if (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS) netif_wake_queue(dev); } @@ -5653,7 +5653,7 @@ static void rtl8169_tx_interrupt(struct net_device *dev, if (tp->dirty_tx != dirty_tx) { tp->dirty_tx = dirty_tx; - smp_wmb(); + smp_mb(); if (netif_queue_stopped(dev) && (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS)) { netif_wake_queue(dev); @@ -5664,7 +5664,6 @@ static void rtl8169_tx_interrupt(struct net_device *dev, * of start_xmit activity is detected (if it is not detected, * it is slow enough). -- FR */ - smp_rmb(); if (tp->cur_tx != dirty_tx) RTL_W8(TxPoll, NPQ); } -- cgit v1.2.3-70-g09d2 From c1288b1278d00169e12495eb53ad128e09560b69 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 19 Jan 2012 09:29:57 +0100 Subject: mac80211: make beacon filtering per virtual interface Due to firmware limitations, we may not be able to support beacon filtering on all virtual interfaces. To allow this in mac80211, introduce per-interface driver capability flags that the driver sets when an interface is added. Signed-off-by: Johannes Berg Acked-by: Luciano Coelho Signed-off-by: John W. Linville --- drivers/net/wireless/p54/main.c | 3 ++- drivers/net/wireless/rtlwifi/base.c | 1 - drivers/net/wireless/rtlwifi/core.c | 2 ++ drivers/net/wireless/wl1251/main.c | 3 ++- drivers/net/wireless/wl12xx/main.c | 3 ++- include/net/mac80211.h | 29 ++++++++++++++++++++--------- net/mac80211/debugfs.c | 2 -- net/mac80211/mlme.c | 2 +- 8 files changed, 29 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index af2ca1a9c7d..40f4eb7da7b 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c @@ -228,6 +228,8 @@ static int p54_add_interface(struct ieee80211_hw *dev, { struct p54_common *priv = dev->priv; + vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; + mutex_lock(&priv->conf_mutex); if (priv->mode != NL80211_IFTYPE_MONITOR) { mutex_unlock(&priv->conf_mutex); @@ -734,7 +736,6 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_PS_NULLFUNC_STACK | - IEEE80211_HW_BEACON_FILTER | IEEE80211_HW_REPORTS_TX_ACK_STATUS; dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index 6f80142580f..ff3e393bc10 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -309,7 +309,6 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw) /* <5> set hw caps */ hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_RX_INCLUDES_FCS | - IEEE80211_HW_BEACON_FILTER | IEEE80211_HW_AMPDU_AGGREGATION | IEEE80211_HW_CONNECTION_MONITOR | /* IEEE80211_HW_SUPPORTS_CQM_RSSI | */ diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index d6e37e6a1d5..0ee01ab2e4f 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -112,6 +112,8 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); int err = 0; + vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; + if (mac->vif) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "vif has been set!! mac->vif = 0x%p\n", mac->vif); diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c index ba3268ea81f..86540db6f1a 100644 --- a/drivers/net/wireless/wl1251/main.c +++ b/drivers/net/wireless/wl1251/main.c @@ -514,6 +514,8 @@ static int wl1251_op_add_interface(struct ieee80211_hw *hw, struct wl1251 *wl = hw->priv; int ret = 0; + vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; + wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", vif->type, vif->addr); @@ -1338,7 +1340,6 @@ int wl1251_init_ieee80211(struct wl1251 *wl) wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SUPPORTS_PS | - IEEE80211_HW_BEACON_FILTER | IEEE80211_HW_SUPPORTS_UAPSD | IEEE80211_HW_SUPPORTS_CQM_RSSI; diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index d5f55a149de..afc5381f287 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -2060,6 +2060,8 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, u8 role_type; bool booted = false; + vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; + wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", ieee80211_vif_type_p2p(vif), vif->addr); @@ -4898,7 +4900,6 @@ static int wl1271_init_ieee80211(struct wl1271 *wl) wl->hw->max_listen_interval = wl->conf.conn.max_listen_interval; wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | - IEEE80211_HW_BEACON_FILTER | IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_UAPSD | IEEE80211_HW_HAS_RATE_CONTROL | diff --git a/include/net/mac80211.h b/include/net/mac80211.h index d49928ba5d0..ae8db247bde 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -851,6 +851,16 @@ struct ieee80211_channel_switch { u8 count; }; +/** + * enum ieee80211_vif_flags - virtual interface flags + * + * @IEEE80211_VIF_BEACON_FILTER: the device performs beacon filtering + * on this virtual interface to avoid unnecessary CPU wakeups + */ +enum ieee80211_vif_flags { + IEEE80211_VIF_BEACON_FILTER = BIT(0), +}; + /** * struct ieee80211_vif - per-interface data * @@ -863,6 +873,10 @@ struct ieee80211_channel_switch { * @addr: address of this interface * @p2p: indicates whether this AP or STA interface is a p2p * interface, i.e. a GO or p2p-sta respectively + * @driver_flags: flags/capabilities the driver has for this interface, + * these need to be set (or cleared) when the interface is added + * or, if supported by the driver, the interface type is changed + * at runtime, mac80211 will never touch this field * @drv_priv: data area for driver use, will always be aligned to * sizeof(void *). */ @@ -871,6 +885,7 @@ struct ieee80211_vif { struct ieee80211_bss_conf bss_conf; u8 addr[ETH_ALEN]; bool p2p; + u32 driver_flags; /* must be last */ u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *)))); }; @@ -1079,10 +1094,6 @@ enum sta_notify_cmd { * @IEEE80211_HW_MFP_CAPABLE: * Hardware supports management frame protection (MFP, IEEE 802.11w). * - * @IEEE80211_HW_BEACON_FILTER: - * Hardware supports dropping of irrelevant beacon frames to - * avoid waking up cpu. - * * @IEEE80211_HW_SUPPORTS_STATIC_SMPS: * Hardware supports static spatial multiplexing powersave, * ie. can turn off all but one chain even on HT connections @@ -1150,7 +1161,7 @@ enum ieee80211_hw_flags { IEEE80211_HW_PS_NULLFUNC_STACK = 1<<11, IEEE80211_HW_SUPPORTS_DYNAMIC_PS = 1<<12, IEEE80211_HW_MFP_CAPABLE = 1<<13, - IEEE80211_HW_BEACON_FILTER = 1<<14, + /* reuse bit 14 */ IEEE80211_HW_SUPPORTS_STATIC_SMPS = 1<<15, IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS = 1<<16, IEEE80211_HW_SUPPORTS_UAPSD = 1<<17, @@ -1446,8 +1457,8 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb); * way the host will only receive beacons where some relevant information * (for example ERP protection or WMM settings) have changed. * - * Beacon filter support is advertised with the %IEEE80211_HW_BEACON_FILTER - * hardware capability. The driver needs to enable beacon filter support + * Beacon filter support is advertised with the %IEEE80211_VIF_BEACON_FILTER + * interface capability. The driver needs to enable beacon filter support * whenever power save is enabled, that is %IEEE80211_CONF_PS is set. When * power save is enabled, the stack will not check for beacon loss and the * driver needs to notify about loss of beacons with ieee80211_beacon_loss(). @@ -3316,7 +3327,7 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw, * * @vif: &struct ieee80211_vif pointer from the add_interface callback. * - * When beacon filtering is enabled with %IEEE80211_HW_BEACON_FILTER and + * When beacon filtering is enabled with %IEEE80211_VIF_BEACON_FILTER and * %IEEE80211_CONF_PS is set, the driver needs to inform whenever the * hardware is not receiving beacons with this function. */ @@ -3327,7 +3338,7 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif); * * @vif: &struct ieee80211_vif pointer from the add_interface callback. * - * When beacon filtering is enabled with %IEEE80211_HW_BEACON_FILTER, and + * When beacon filtering is enabled with %IEEE80211_VIF_BEACON_FILTER, and * %IEEE80211_CONF_PS and %IEEE80211_HW_CONNECTION_MONITOR are set, the driver * needs to inform if the connection to the AP has been lost. * diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 90baea53e7c..e8868dae1c0 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -247,8 +247,6 @@ static ssize_t hwflags_read(struct file *file, char __user *user_buf, sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_DYNAMIC_PS\n"); if (local->hw.flags & IEEE80211_HW_MFP_CAPABLE) sf += snprintf(buf + sf, mxln - sf, "MFP_CAPABLE\n"); - if (local->hw.flags & IEEE80211_HW_BEACON_FILTER) - sf += snprintf(buf + sf, mxln - sf, "BEACON_FILTER\n"); if (local->hw.flags & IEEE80211_HW_SUPPORTS_STATIC_SMPS) sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_STATIC_SMPS\n"); if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 95d3964fc08..b51eb49d852 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -127,7 +127,7 @@ static void run_again(struct ieee80211_if_managed *ifmgd, void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata) { - if (sdata->local->hw.flags & IEEE80211_HW_BEACON_FILTER) + if (sdata->vif.driver_flags & IEEE80211_VIF_BEACON_FILTER) return; mod_timer(&sdata->u.mgd.bcn_mon_timer, -- cgit v1.2.3-70-g09d2 From ea086359a63bd0dd85c1d784d0425340649613fa Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 19 Jan 2012 09:29:58 +0100 Subject: mac80211: make CQM RSSI support per virtual interface Similar to the previous beacon filtering patch, make CQM RSSI support depend on the flags that the driver set for virtual interfaces. Signed-off-by: Johannes Berg Acked-by: Luciano Coelho Signed-off-by: John W. Linville --- drivers/net/wireless/wl1251/main.c | 6 +++--- drivers/net/wireless/wl12xx/main.c | 4 ++-- include/net/mac80211.h | 14 +++++++------- net/mac80211/cfg.c | 10 ++-------- net/mac80211/debugfs.c | 2 -- net/mac80211/mlme.c | 4 ++-- 6 files changed, 16 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c index 86540db6f1a..41302c7b1ad 100644 --- a/drivers/net/wireless/wl1251/main.c +++ b/drivers/net/wireless/wl1251/main.c @@ -514,7 +514,8 @@ static int wl1251_op_add_interface(struct ieee80211_hw *hw, struct wl1251 *wl = hw->priv; int ret = 0; - vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; + vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | + IEEE80211_VIF_SUPPORTS_CQM_RSSI; wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", vif->type, vif->addr); @@ -1340,8 +1341,7 @@ int wl1251_init_ieee80211(struct wl1251 *wl) wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SUPPORTS_PS | - IEEE80211_HW_SUPPORTS_UAPSD | - IEEE80211_HW_SUPPORTS_CQM_RSSI; + IEEE80211_HW_SUPPORTS_UAPSD; wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index afc5381f287..f8748cedbae 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -2060,7 +2060,8 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, u8 role_type; bool booted = false; - vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; + vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | + IEEE80211_VIF_SUPPORTS_CQM_RSSI; wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", ieee80211_vif_type_p2p(vif), vif->addr); @@ -4904,7 +4905,6 @@ static int wl1271_init_ieee80211(struct wl1271 *wl) IEEE80211_HW_SUPPORTS_UAPSD | IEEE80211_HW_HAS_RATE_CONTROL | IEEE80211_HW_CONNECTION_MONITOR | - IEEE80211_HW_SUPPORTS_CQM_RSSI | IEEE80211_HW_REPORTS_TX_ACK_STATUS | IEEE80211_HW_SPECTRUM_MGMT | IEEE80211_HW_AP_LINK_PS | diff --git a/include/net/mac80211.h b/include/net/mac80211.h index ae8db247bde..65018587684 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -856,9 +856,14 @@ struct ieee80211_channel_switch { * * @IEEE80211_VIF_BEACON_FILTER: the device performs beacon filtering * on this virtual interface to avoid unnecessary CPU wakeups + * @IEEE80211_VIF_SUPPORTS_CQM_RSSI: the device can do connection quality + * monitoring on this virtual interface -- i.e. it can monitor + * connection quality related parameters, such as the RSSI level and + * provide notifications if configured trigger levels are reached. */ enum ieee80211_vif_flags { IEEE80211_VIF_BEACON_FILTER = BIT(0), + IEEE80211_VIF_SUPPORTS_CQM_RSSI = BIT(1), }; /** @@ -1119,11 +1124,6 @@ enum sta_notify_cmd { * When this flag is set, signaling beacon-loss will cause an immediate * change to disassociated state. * - * @IEEE80211_HW_SUPPORTS_CQM_RSSI: - * Hardware can do connection quality monitoring - i.e. it can monitor - * connection quality related parameters, such as the RSSI level and - * provide notifications if configured trigger levels are reached. - * * @IEEE80211_HW_NEED_DTIM_PERIOD: * This device needs to know the DTIM period for the BSS before * associating. @@ -1167,7 +1167,7 @@ enum ieee80211_hw_flags { IEEE80211_HW_SUPPORTS_UAPSD = 1<<17, IEEE80211_HW_REPORTS_TX_ACK_STATUS = 1<<18, IEEE80211_HW_CONNECTION_MONITOR = 1<<19, - IEEE80211_HW_SUPPORTS_CQM_RSSI = 1<<20, + /* reuse bit 20 */ IEEE80211_HW_SUPPORTS_PER_STA_GTK = 1<<21, IEEE80211_HW_AP_LINK_PS = 1<<22, IEEE80211_HW_TX_AMPDU_SETUP_IN_HW = 1<<23, @@ -3408,7 +3408,7 @@ void ieee80211_enable_dyn_ps(struct ieee80211_vif *vif); * @rssi_event: the RSSI trigger event type * @gfp: context flags * - * When the %IEEE80211_HW_SUPPORTS_CQM_RSSI is set, and a connection quality + * When the %IEEE80211_VIF_SUPPORTS_CQM_RSSI is set, and a connection quality * monitoring is configured with an rssi threshold, the driver will inform * whenever the rssi level reaches the threshold. */ diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index d86730fe75c..74c9301681e 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1873,7 +1873,6 @@ static int ieee80211_set_cqm_rssi_config(struct wiphy *wiphy, s32 rssi_thold, u32 rssi_hyst) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_vif *vif = &sdata->vif; struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; @@ -1884,14 +1883,9 @@ static int ieee80211_set_cqm_rssi_config(struct wiphy *wiphy, bss_conf->cqm_rssi_thold = rssi_thold; bss_conf->cqm_rssi_hyst = rssi_hyst; - if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) { - if (sdata->vif.type != NL80211_IFTYPE_STATION) - return -EOPNOTSUPP; - return 0; - } - /* tell the driver upon association, unless already associated */ - if (sdata->u.mgd.associated) + if (sdata->u.mgd.associated && + sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI) ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_CQM); return 0; diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index e8868dae1c0..affe64be909 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -257,8 +257,6 @@ static ssize_t hwflags_read(struct file *file, char __user *user_buf, sf += snprintf(buf + sf, mxln - sf, "REPORTS_TX_ACK_STATUS\n"); if (local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) sf += snprintf(buf + sf, mxln - sf, "CONNECTION_MONITOR\n"); - if (local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI) - sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_CQM_RSSI\n"); if (local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK) sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_PER_STA_GTK\n"); if (local->hw.flags & IEEE80211_HW_AP_LINK_PS) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index b51eb49d852..de3268c7be1 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1043,7 +1043,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, bss_info_changed |= BSS_CHANGED_BSSID; /* Tell the driver to monitor connection quality (if supported) */ - if ((local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI) && + if (sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI && bss_conf->cqm_rssi_thold) bss_info_changed |= BSS_CHANGED_CQM; @@ -1882,7 +1882,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, if (bss_conf->cqm_rssi_thold && ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT && - !(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) { + !(sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI)) { int sig = ifmgd->ave_beacon_signal / 16; int last_event = ifmgd->last_cqm_event_signal; int thold = bss_conf->cqm_rssi_thold; -- cgit v1.2.3-70-g09d2 From 67e43de6dbc9caf52fa7bcf4c813fd088ba6fbfc Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 21 Jan 2012 16:59:10 +0100 Subject: carl9170: allow users to lower output power level This patch implements a simple way of reducing the output power of the device by a configurable upper limit. Requested-by: Harshal Chhaya Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/carl9170.h | 1 + drivers/net/wireless/ath/carl9170/mac.c | 35 +++++++++++++++++++++++++++ drivers/net/wireless/ath/carl9170/main.c | 11 +++++---- drivers/net/wireless/ath/carl9170/phy.c | 36 +++++----------------------- drivers/net/wireless/ath/carl9170/tx.c | 2 ++ 5 files changed, 50 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h index f0f44c30b2f..0cea20e3e25 100644 --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h @@ -559,6 +559,7 @@ int carl9170_set_hwretry_limit(struct ar9170 *ar, const u32 max_retry); int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac, const u8 ktype, const u8 keyidx, const u8 *keydata, const int keylen); int carl9170_disable_key(struct ar9170 *ar, const u8 id); +int carl9170_set_mac_tpc(struct ar9170 *ar, struct ieee80211_channel *channel); /* RX */ void carl9170_rx(struct ar9170 *ar, void *buf, unsigned int len); diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c index dfda9197099..53415bfd8be 100644 --- a/drivers/net/wireless/ath/carl9170/mac.c +++ b/drivers/net/wireless/ath/carl9170/mac.c @@ -485,3 +485,38 @@ int carl9170_disable_key(struct ar9170 *ar, const u8 id) return carl9170_exec_cmd(ar, CARL9170_CMD_DKEY, sizeof(key), (u8 *)&key, 0, NULL); } + +int carl9170_set_mac_tpc(struct ar9170 *ar, struct ieee80211_channel *channel) +{ + unsigned int power, chains; + + if (ar->eeprom.tx_mask != 1) + chains = AR9170_TX_PHY_TXCHAIN_2; + else + chains = AR9170_TX_PHY_TXCHAIN_1; + + switch (channel->band) { + case IEEE80211_BAND_2GHZ: + power = ar->power_2G_ofdm[0] & 0x3f; + break; + case IEEE80211_BAND_5GHZ: + power = ar->power_5G_leg[0] & 0x3f; + break; + default: + BUG_ON(1); + } + + power = min_t(unsigned int, power, ar->hw->conf.power_level * 2); + + carl9170_regwrite_begin(ar); + carl9170_regwrite(AR9170_MAC_REG_ACK_TPC, + 0x3c1e | power << 20 | chains << 26); + carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_TPC, + power << 5 | chains << 11 | + power << 21 | chains << 27); + carl9170_regwrite(AR9170_MAC_REG_CFEND_QOSNULL_TPC, + power << 5 | chains << 11 | + power << 21 | chains << 27); + carl9170_regwrite_finish(); + return carl9170_regwrite_result(); +} diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 6ee7c55f75a..8d2523b3f72 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -853,11 +853,6 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed) goto out; } - if (changed & IEEE80211_CONF_CHANGE_POWER) { - /* TODO */ - err = 0; - } - if (changed & IEEE80211_CONF_CHANGE_SMPS) { /* TODO */ err = 0; @@ -891,6 +886,12 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed) goto out; } + if (changed & IEEE80211_CONF_CHANGE_POWER) { + err = carl9170_set_mac_tpc(ar, ar->hw->conf.channel); + if (err) + goto out; + } + out: mutex_unlock(&ar->mutex); return err; diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c index 472efc7e340..b72c09cf43a 100644 --- a/drivers/net/wireless/ath/carl9170/phy.c +++ b/drivers/net/wireless/ath/carl9170/phy.c @@ -1426,15 +1426,15 @@ static void carl9170_calc_ctl(struct ar9170 *ar, u32 freq, enum carl9170_bw bw) #undef EDGES } -static int carl9170_set_power_cal(struct ar9170 *ar, u32 freq, - enum carl9170_bw bw) +static void carl9170_set_power_cal(struct ar9170 *ar, u32 freq, + enum carl9170_bw bw) { struct ar9170_calibration_target_power_legacy *ctpl; struct ar9170_calibration_target_power_ht *ctph; u8 *ctpres; int ntargets; int idx, i, n; - u8 ackpower, ackchains, f; + u8 f; u8 pwr_freqs[AR5416_MAX_NUM_TGT_PWRS]; if (freq < 3000) @@ -1523,32 +1523,6 @@ static int carl9170_set_power_cal(struct ar9170 *ar, u32 freq, /* calc. conformance test limits and apply to ar->power*[] */ carl9170_calc_ctl(ar, freq, bw); - - /* set ACK/CTS TX power */ - carl9170_regwrite_begin(ar); - - if (ar->eeprom.tx_mask != 1) - ackchains = AR9170_TX_PHY_TXCHAIN_2; - else - ackchains = AR9170_TX_PHY_TXCHAIN_1; - - if (freq < 3000) - ackpower = ar->power_2G_ofdm[0] & 0x3f; - else - ackpower = ar->power_5G_leg[0] & 0x3f; - - carl9170_regwrite(AR9170_MAC_REG_ACK_TPC, - 0x3c1e | ackpower << 20 | ackchains << 26); - carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_TPC, - ackpower << 5 | ackchains << 11 | - ackpower << 21 | ackchains << 27); - - carl9170_regwrite(AR9170_MAC_REG_CFEND_QOSNULL_TPC, - ackpower << 5 | ackchains << 11 | - ackpower << 21 | ackchains << 27); - - carl9170_regwrite_finish(); - return carl9170_regwrite_result(); } int carl9170_get_noisefloor(struct ar9170 *ar) @@ -1712,7 +1686,9 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, if (err) return err; - err = carl9170_set_power_cal(ar, channel->center_freq, bw); + carl9170_set_power_cal(ar, channel->center_freq, bw); + + err = carl9170_set_mac_tpc(ar, channel); if (err) return err; diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index d19a9ee9d05..771e1a9294c 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c @@ -719,6 +719,8 @@ static void carl9170_tx_rate_tpc_chains(struct ar9170 *ar, else *chains = AR9170_TX_PHY_TXCHAIN_2; } + + *tpc = min_t(unsigned int, *tpc, ar->hw->conf.power_level * 2); } static __le32 carl9170_tx_physet(struct ar9170 *ar, -- cgit v1.2.3-70-g09d2 From 0c17cf962d716ea7557d18679cc98b3a43efb46d Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 24 Jan 2012 14:09:06 +0100 Subject: rt2800usb: initialize H2M_INT_SRC register Ralink USB driver initialize H2M_INT_SRC to 0 after firmware load, and never touch this register later. It is not touched at all by Ralink PCI driver. Acked-by: Helmut Schaa Acked-by: Ivo van Doorn Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 22a1a8fc6e0..3e194b7e9bb 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -448,6 +448,8 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, */ rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); + if (rt2x00_is_usb(rt2x00dev)) + rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0); msleep(1); return 0; -- cgit v1.2.3-70-g09d2 From 4ed1dd2a7ec880b301beb61cbc1e08811ec340e4 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 24 Jan 2012 14:09:07 +0100 Subject: rt2800: disable DMA after firmware load We can receive frames just after firmware load with current code, so disable DMA just after firmware is loaded, not before. Acked-by: Ivo van Doorn Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 3e194b7e9bb..165535cc507 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -411,18 +411,6 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002); } - /* - * Disable DMA, will be reenabled later when enabling - * the radio. - */ - rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); - rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_DMA_BUSY, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_RX_DMA_BUSY, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); - rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); - /* * Write firmware to the device. */ @@ -443,6 +431,15 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, return -EBUSY; } + /* + * Disable DMA, will be reenabled later when enabling + * the radio. + */ + rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); + rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); + rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); + rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); + /* * Initialize firmware. */ -- cgit v1.2.3-70-g09d2 From 2a48e8ae113be506a7169d50c0b8fcb3ab0c462a Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 24 Jan 2012 14:09:08 +0100 Subject: rt2800: zero MAC_SYS_CTRL bits during BBP and MAC reset Zero all other bits than RESET_CSR and RESET_BBP when want to do the reset, that the vendor driver behaviour. Acked-by: Helmut Schaa Acked-by: Ivo van Doorn Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800pci.c | 2 +- drivers/net/wireless/rt2x00/rt2800usb.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index dc88baefa72..4e985026985 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -489,7 +489,7 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00pci_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); - rt2x00pci_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + reg = 0; rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, reg); diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 262ee9eefb6..425267af610 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -228,7 +228,7 @@ static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00usb_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); - rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + reg = 0; rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg); -- cgit v1.2.3-70-g09d2 From 10ef6a8f1567739192c29f11375556ce0d53ec74 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 24 Jan 2012 14:09:09 +0100 Subject: rt2800usb: remove PWR_PIN_CFG=0x3 during init This seems to be only needed as workaround for hardware problem on PCI devices. Acked-by: Helmut Schaa Acked-by: Ivo van Doorn Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 425267af610..f0074bcee7c 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -226,8 +226,6 @@ static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00usb_register_read(rt2x00dev, PBF_SYS_CTRL, ®); rt2x00usb_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000); - rt2x00usb_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); - reg = 0; rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); -- cgit v1.2.3-70-g09d2 From 2690e1bb35e97a3b15f0064e9176cd2ec61c2511 Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Tue, 24 Jan 2012 20:50:24 -0800 Subject: mwifiex: pass priv pointer instead of adapter Pass mwifiex_private pointer directly to wmm_add_buf_txqueue() instead of passing adapter and then deriving priv again in mwifiex_get_priv_by_id(). This reduces a 'for' loop in TX path. Signed-off-by: Avinash Patil Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/main.c | 2 +- drivers/net/wireless/mwifiex/wmm.c | 6 ++---- drivers/net/wireless/mwifiex/wmm.h | 4 ++-- 3 files changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 1a0775d19ad..80e44566bf6 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -462,7 +462,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) tx_info->bss_type = priv->bss_type; mwifiex_fill_buffer(skb); - mwifiex_wmm_add_buf_txqueue(priv->adapter, skb); + mwifiex_wmm_add_buf_txqueue(priv, skb); atomic_inc(&priv->adapter->tx_pending); if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) { diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index e6a2cb127d2..75f79ef9f6c 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -599,12 +599,10 @@ mwifiex_is_ralist_valid(struct mwifiex_private *priv, * is queued at the list tail. */ void -mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter, +mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, struct sk_buff *skb) { - struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb); - struct mwifiex_private *priv = mwifiex_get_priv_by_id(adapter, - tx_info->bss_num, tx_info->bss_type); + struct mwifiex_adapter *adapter = priv->adapter; u32 tid; struct mwifiex_ra_list_tbl *ra_list; u8 ra[ETH_ALEN], tid_down; diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h index fcea1f68792..ec839952d2e 100644 --- a/drivers/net/wireless/mwifiex/wmm.h +++ b/drivers/net/wireless/mwifiex/wmm.h @@ -80,8 +80,8 @@ mwifiex_wmm_is_ra_list_empty(struct list_head *ra_list_hhead) return true; } -void mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter, - struct sk_buff *skb); +void mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, + struct sk_buff *skb); void mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra); int mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter); -- cgit v1.2.3-70-g09d2 From c4f3b9725ed476adbcaf1c49d882ab541bc4214c Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Tue, 24 Jan 2012 20:50:25 -0800 Subject: mwifiex: update BSS parameters in dump_station_info() This enables user to check beacon interval, DTIM period, short slot time and short preamble information using "iw dev mlan0 link" command when station is in connected state. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 17 +++++++++++++++++ drivers/net/wireless/mwifiex/main.h | 1 + drivers/net/wireless/mwifiex/scan.c | 6 ++++++ 3 files changed, 24 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 00f10059ecb..6fef4925d13 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -557,6 +557,23 @@ mwifiex_dump_station_info(struct mwifiex_private *priv, /* bit rate is in 500 kb/s units. Convert it to 100kb/s units */ sinfo->txrate.legacy = rate.rate * 5; + if (priv->bss_mode == NL80211_IFTYPE_STATION) { + sinfo->filled |= STATION_INFO_BSS_PARAM; + sinfo->bss_param.flags = 0; + if (priv->curr_bss_params.bss_descriptor.cap_info_bitmap & + WLAN_CAPABILITY_SHORT_PREAMBLE) + sinfo->bss_param.flags |= + BSS_PARAM_FLAGS_SHORT_PREAMBLE; + if (priv->curr_bss_params.bss_descriptor.cap_info_bitmap & + WLAN_CAPABILITY_SHORT_SLOT_TIME) + sinfo->bss_param.flags |= + BSS_PARAM_FLAGS_SHORT_SLOT_TIME; + sinfo->bss_param.dtim_period = + priv->curr_bss_params.bss_descriptor.dtim_period; + sinfo->bss_param.beacon_interval = + priv->curr_bss_params.bss_descriptor.beacon_period; + } + return ret; } diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 6712ea89ef7..3dc0f721c1d 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -249,6 +249,7 @@ struct mwifiex_bssdescriptor { u32 channel; u32 freq; u16 beacon_period; + u8 dtim_period; u8 erp_flags; u32 bss_mode; u8 supported_rates[MWIFIEX_SUPPORTED_RATES]; diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 98f1ca9cd6d..135208596af 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -1086,6 +1086,7 @@ mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, struct ieee_types_vendor_specific *vendor_ie; const u8 wpa_oui[4] = { 0x00, 0x50, 0xf2, 0x01 }; const u8 wmm_oui[4] = { 0x00, 0x50, 0xf2, 0x02 }; + struct ieee80211_tim_ie *tim_ie; found_data_rate_ie = false; rate_size = 0; @@ -1258,6 +1259,11 @@ mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, sizeof(struct ieee_types_header) - bss_entry->beacon_buf); break; + case WLAN_EID_TIM: + tim_ie = (void *) (current_ptr + + sizeof(struct ieee_types_header)); + bss_entry->dtim_period = tim_ie->dtim_period; + break; default: break; } -- cgit v1.2.3-70-g09d2 From ff7e9f99f7effb385a9be2f7198743c1ad2bb126 Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Fri, 27 Jan 2012 16:08:27 +0530 Subject: mwl8k: Configuring correct MAC address in broadcast key While configuring the broadcast key in the hardware, in multi-BSS environment, BSSes other than first were incorrectly configured with the MAC address of first BSS. Fixing it with correct MAC addresses. Signed-off-by: Yogesh Ashok Powar Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index dd5aeaff44b..fd125473be7 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -4093,7 +4093,7 @@ static int mwl8k_set_key(struct ieee80211_hw *hw, return -EOPNOTSUPP; if (sta == NULL) - addr = hw->wiphy->perm_addr; + addr = vif->addr; else addr = sta->addr; -- cgit v1.2.3-70-g09d2 From da78dbff2e05630921c551dbbc70a4b7981a8fff Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Thu, 26 Jan 2012 14:18:23 +0100 Subject: r8169: remove work from irq handler. The irq handler was a mess. See 7ab87ff4c770eed71e3777936299292739fcd0fe ("via-rhine: move work from irq handler to softirq and beyond") for similar changes. One can notice: - all non-napi tasks are explicitely scheduled trough a single work queue. - hiding software tx queue start behind the rtl_hw_start method is mildly natural. Move it in the caller where needed. - as can be seen from the heavy use of bh disabling locks, the driver is not safe for irq context messages with netconsole. It is still quite usable for general messaging though. Tested ok with concurrent registers dump (ethtool -d) + background traffic + "echo t > /proc/sysrq-trigger". Tested with old PCI chipset, PCIe 8168 and 810x: - XID 0c900800 RTL8168evl/8111evl - XID 18000000 RTL8168b/8111b - XID 98000000 RTL8169sc/8110sc - XID 083000c0 RTL8168d/8111d - XID 081000c0 RTL8168d/8111d - XID 00b00000 RTL8105e - XID 04a00000 RTL8102e As a side note, the comments in f11a377b3f4e897d11f0e8d1fc688667e2f19708 ("r8169: avoid losing MSI interrupts") does not seem completely clear: if I hack the driver further to stop acking the irq link event bit, MSI interrupts keep being delivered (RTL8168b/8111b, XID 18000000). Signed-off-by: Francois Romieu Cc: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 449 ++++++++++++++++++----------------- 1 file changed, 231 insertions(+), 218 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 8dd13f5a920..d039d39963a 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -667,6 +667,13 @@ struct rtl8169_counters { __le16 tx_underun; }; +enum rtl_flag { + RTL_FLAG_TASK_SLOW_PENDING, + RTL_FLAG_TASK_RESET_PENDING, + RTL_FLAG_TASK_PHY_PENDING, + RTL_FLAG_MAX +}; + struct rtl8169_private { void __iomem *mmio_addr; /* memory map physical address */ struct pci_dev *pci_dev; @@ -688,9 +695,8 @@ struct rtl8169_private { struct ring_info tx_skb[NUM_TX_DESC]; /* Tx data buffers */ struct timer_list timer; u16 cp_cmd; - u16 intr_event; - u16 napi_event; - u16 intr_mask; + + u16 event_slow; struct mdio_ops { void (*write)(void __iomem *, int, int); @@ -716,7 +722,10 @@ struct rtl8169_private { int (*do_ioctl)(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd); struct { + DECLARE_BITMAP(flags, RTL_FLAG_MAX); + struct mutex mutex; struct work_struct work; + bool enabled; } wk; unsigned features; @@ -768,13 +777,20 @@ static int rtl8169_close(struct net_device *dev); static void rtl_set_rx_mode(struct net_device *dev); static void rtl8169_tx_timeout(struct net_device *dev); static struct net_device_stats *rtl8169_get_stats(struct net_device *dev); -static int rtl8169_rx_interrupt(struct net_device *, struct rtl8169_private *, - void __iomem *, u32 budget); static int rtl8169_change_mtu(struct net_device *dev, int new_mtu); -static void rtl8169_down(struct net_device *dev); static void rtl8169_rx_clear(struct rtl8169_private *tp); static int rtl8169_poll(struct napi_struct *napi, int budget); +static void rtl_lock_work(struct rtl8169_private *tp) +{ + mutex_lock(&tp->wk.mutex); +} + +static void rtl_unlock_work(struct rtl8169_private *tp) +{ + mutex_unlock(&tp->wk.mutex); +} + static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force) { int cap = pci_pcie_cap(pdev); @@ -1214,12 +1230,21 @@ static void rtl_irq_enable(struct rtl8169_private *tp, u16 bits) RTL_W16(IntrMask, bits); } +#define RTL_EVENT_NAPI_RX (RxOK | RxErr) +#define RTL_EVENT_NAPI_TX (TxOK | TxErr) +#define RTL_EVENT_NAPI (RTL_EVENT_NAPI_RX | RTL_EVENT_NAPI_TX) + +static void rtl_irq_enable_all(struct rtl8169_private *tp) +{ + rtl_irq_enable(tp, RTL_EVENT_NAPI | tp->event_slow); +} + static void rtl8169_irq_mask_and_ack(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; rtl_irq_disable(tp); - rtl_ack_events(tp, tp->intr_event); + rtl_ack_events(tp, RTL_EVENT_NAPI | tp->event_slow); RTL_R8(ChipCmd); } @@ -1310,9 +1335,6 @@ static void __rtl8169_check_link_status(struct net_device *dev, struct rtl8169_private *tp, void __iomem *ioaddr, bool pm) { - unsigned long flags; - - spin_lock_irqsave(&tp->lock, flags); if (tp->link_ok(ioaddr)) { rtl_link_chg_patch(tp); /* This is to cancel a scheduled suspend if there's one. */ @@ -1327,7 +1349,6 @@ static void __rtl8169_check_link_status(struct net_device *dev, if (pm) pm_schedule_suspend(&tp->pci_dev->dev, 5000); } - spin_unlock_irqrestore(&tp->lock, flags); } static void rtl8169_check_link_status(struct net_device *dev, @@ -1370,12 +1391,12 @@ static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct rtl8169_private *tp = netdev_priv(dev); - spin_lock_irq(&tp->lock); + rtl_lock_work(tp); wol->supported = WAKE_ANY; wol->wolopts = __rtl8169_get_wol(tp); - spin_unlock_irq(&tp->lock); + rtl_unlock_work(tp); } static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts) @@ -1412,14 +1433,15 @@ static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct rtl8169_private *tp = netdev_priv(dev); - spin_lock_irq(&tp->lock); + rtl_lock_work(tp); if (wol->wolopts) tp->features |= RTL_FEATURE_WOL; else tp->features &= ~RTL_FEATURE_WOL; __rtl8169_set_wol(tp, wol->wolopts); - spin_unlock_irq(&tp->lock); + + rtl_unlock_work(tp); device_set_wakeup_enable(&tp->pci_dev->dev, wol->wolopts); @@ -1574,15 +1596,14 @@ out: static int rtl8169_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct rtl8169_private *tp = netdev_priv(dev); - unsigned long flags; int ret; del_timer_sync(&tp->timer); - spin_lock_irqsave(&tp->lock, flags); + rtl_lock_work(tp); ret = rtl8169_set_speed(dev, cmd->autoneg, ethtool_cmd_speed(cmd), cmd->duplex, cmd->advertising); - spin_unlock_irqrestore(&tp->lock, flags); + rtl_unlock_work(tp); return ret; } @@ -1602,14 +1623,12 @@ static netdev_features_t rtl8169_fix_features(struct net_device *dev, return features; } -static int rtl8169_set_features(struct net_device *dev, - netdev_features_t features) +static void __rtl8169_set_features(struct net_device *dev, + netdev_features_t features) { struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; - unsigned long flags; - spin_lock_irqsave(&tp->lock, flags); + void __iomem *ioaddr = tp->mmio_addr; if (features & NETIF_F_RXCSUM) tp->cp_cmd |= RxChkSum; @@ -1623,12 +1642,21 @@ static int rtl8169_set_features(struct net_device *dev, RTL_W16(CPlusCmd, tp->cp_cmd); RTL_R16(CPlusCmd); +} - spin_unlock_irqrestore(&tp->lock, flags); +static int rtl8169_set_features(struct net_device *dev, + netdev_features_t features) +{ + struct rtl8169_private *tp = netdev_priv(dev); + + rtl_lock_work(tp); + __rtl8169_set_features(dev, features); + rtl_unlock_work(tp); return 0; } + static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp, struct sk_buff *skb) { @@ -1677,14 +1705,12 @@ static int rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd) static int rtl8169_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct rtl8169_private *tp = netdev_priv(dev); - unsigned long flags; int rc; - spin_lock_irqsave(&tp->lock, flags); - + rtl_lock_work(tp); rc = tp->get_settings(dev, cmd); + rtl_unlock_work(tp); - spin_unlock_irqrestore(&tp->lock, flags); return rc; } @@ -1692,14 +1718,15 @@ static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) { struct rtl8169_private *tp = netdev_priv(dev); - unsigned long flags; if (regs->len > R8169_REGS_SIZE) regs->len = R8169_REGS_SIZE; - spin_lock_irqsave(&tp->lock, flags); + rtl_lock_work(tp); + spin_lock_bh(&tp->lock); memcpy_fromio(p, tp->mmio_addr, regs->len); - spin_unlock_irqrestore(&tp->lock, flags); + spin_unlock_bh(&tp->lock); + rtl_unlock_work(tp); } static u32 rtl8169_get_msglevel(struct net_device *dev) @@ -3216,18 +3243,14 @@ static void rtl_hw_phy_config(struct net_device *dev) } } -static void rtl8169_phy_timer(unsigned long __opaque) +static void rtl_phy_work(struct rtl8169_private *tp) { - struct net_device *dev = (struct net_device *)__opaque; - struct rtl8169_private *tp = netdev_priv(dev); struct timer_list *timer = &tp->timer; void __iomem *ioaddr = tp->mmio_addr; unsigned long timeout = RTL8169_PHY_TIMEOUT; assert(tp->mac_version > RTL_GIGA_MAC_VER_01); - spin_lock_irq(&tp->lock); - if (tp->phy_reset_pending(tp)) { /* * A busy loop could burn quite a few cycles on nowadays CPU. @@ -3238,32 +3261,45 @@ static void rtl8169_phy_timer(unsigned long __opaque) } if (tp->link_ok(ioaddr)) - goto out_unlock; + return; - netif_warn(tp, link, dev, "PHY reset until link up\n"); + netif_warn(tp, link, tp->dev, "PHY reset until link up\n"); tp->phy_reset_enable(tp); out_mod_timer: mod_timer(timer, jiffies + timeout); -out_unlock: - spin_unlock_irq(&tp->lock); +} + +static void rtl_schedule_task(struct rtl8169_private *tp, enum rtl_flag flag) +{ + spin_lock(&tp->lock); + if (!test_and_set_bit(flag, tp->wk.flags)) + schedule_work(&tp->wk.work); + spin_unlock(&tp->lock); +} + +static void rtl_schedule_task_bh(struct rtl8169_private *tp, enum rtl_flag flag) +{ + local_bh_disable(); + rtl_schedule_task(tp, flag); + local_bh_enable(); +} + +static void rtl8169_phy_timer(unsigned long __opaque) +{ + struct net_device *dev = (struct net_device *)__opaque; + struct rtl8169_private *tp = netdev_priv(dev); + + rtl_schedule_task_bh(tp, RTL_FLAG_TASK_PHY_PENDING); } #ifdef CONFIG_NET_POLL_CONTROLLER -/* - * Polling 'interrupt' - used by things like netconsole to send skbs - * without having to re-enable interrupts. It's not called while - * the interrupt routine is executing. - */ static void rtl8169_netpoll(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); - struct pci_dev *pdev = tp->pci_dev; - disable_irq(pdev->irq); - rtl8169_interrupt(pdev->irq, dev); - enable_irq(pdev->irq); + rtl8169_interrupt(tp->pci_dev->irq, dev); } #endif @@ -3344,7 +3380,7 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr) low = addr[0] | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24); high = addr[4] | (addr[5] << 8); - spin_lock_irq(&tp->lock); + rtl_lock_work(tp); RTL_W8(Cfg9346, Cfg9346_Unlock); @@ -3368,7 +3404,7 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr) RTL_W8(Cfg9346, Cfg9346_Lock); - spin_unlock_irq(&tp->lock); + rtl_unlock_work(tp); } static int rtl_set_mac_address(struct net_device *dev, void *p) @@ -3422,8 +3458,7 @@ static const struct rtl_cfg_info { void (*hw_start)(struct net_device *); unsigned int region; unsigned int align; - u16 intr_event; - u16 napi_event; + u16 event_slow; unsigned features; u8 default_ver; } rtl_cfg_infos [] = { @@ -3431,9 +3466,7 @@ static const struct rtl_cfg_info { .hw_start = rtl_hw_start_8169, .region = 1, .align = 0, - .intr_event = SYSErr | LinkChg | RxOverflow | - RxFIFOOver | TxErr | TxOK | RxOK | RxErr, - .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow, + .event_slow = SYSErr | LinkChg | RxOverflow | RxFIFOOver, .features = RTL_FEATURE_GMII, .default_ver = RTL_GIGA_MAC_VER_01, }, @@ -3441,9 +3474,7 @@ static const struct rtl_cfg_info { .hw_start = rtl_hw_start_8168, .region = 2, .align = 8, - .intr_event = SYSErr | LinkChg | RxOverflow | - TxErr | TxOK | RxOK | RxErr, - .napi_event = TxErr | TxOK | RxOK | RxOverflow, + .event_slow = SYSErr | LinkChg | RxOverflow, .features = RTL_FEATURE_GMII | RTL_FEATURE_MSI, .default_ver = RTL_GIGA_MAC_VER_11, }, @@ -3451,9 +3482,8 @@ static const struct rtl_cfg_info { .hw_start = rtl_hw_start_8101, .region = 2, .align = 8, - .intr_event = SYSErr | LinkChg | RxOverflow | PCSTimeout | - RxFIFOOver | TxErr | TxOK | RxOK | RxErr, - .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow, + .event_slow = SYSErr | LinkChg | RxOverflow | RxFIFOOver | + PCSTimeout, .features = RTL_FEATURE_MSI, .default_ver = RTL_GIGA_MAC_VER_13, } @@ -4131,6 +4161,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) } spin_lock_init(&tp->lock); + mutex_init(&tp->wk.mutex); /* Get MAC address */ for (i = 0; i < ETH_ALEN; i++) @@ -4158,10 +4189,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) /* 8110SCd requires hardware Rx VLAN - disallow toggling */ dev->hw_features &= ~NETIF_F_HW_VLAN_RX; - tp->intr_mask = 0xffff; tp->hw_start = cfg->hw_start; - tp->intr_event = cfg->intr_event; - tp->napi_event = cfg->napi_event; + tp->event_slow = cfg->event_slow; tp->opts1_mask = (tp->mac_version != RTL_GIGA_MAC_VER_01) ? ~(RxBOVF | RxFOVF) : ~0; @@ -4330,16 +4359,24 @@ static int rtl8169_open(struct net_device *dev) if (retval < 0) goto err_release_fw_2; + rtl_lock_work(tp); + + tp->wk.enabled = true; + napi_enable(&tp->napi); rtl8169_init_phy(dev, tp); - rtl8169_set_features(dev, dev->features); + __rtl8169_set_features(dev, dev->features); rtl_pll_power_up(tp); rtl_hw_start(dev); + netif_start_queue(dev); + + rtl_unlock_work(tp); + tp->saved_wolopts = 0; pm_runtime_put_noidle(&pdev->dev); @@ -4413,9 +4450,7 @@ static void rtl_hw_start(struct net_device *dev) tp->hw_start(dev); - rtl_irq_enable(tp, tp->intr_event); - - netif_start_queue(dev); + rtl_irq_enable_all(tp); } static void rtl_set_rx_tx_desc_registers(struct rtl8169_private *tp, @@ -4921,8 +4956,8 @@ static void rtl_hw_start_8168(struct net_device *dev) /* Work around for RxFIFO overflow. */ if (tp->mac_version == RTL_GIGA_MAC_VER_11) { - tp->intr_event |= RxFIFOOver | PCSTimeout; - tp->intr_event &= ~RxOverflow; + tp->event_slow |= RxFIFOOver | PCSTimeout; + tp->event_slow &= ~RxOverflow; } rtl_set_rx_tx_desc_registers(tp, ioaddr); @@ -5108,10 +5143,8 @@ static void rtl_hw_start_8101(struct net_device *dev) void __iomem *ioaddr = tp->mmio_addr; struct pci_dev *pdev = tp->pci_dev; - if (tp->mac_version >= RTL_GIGA_MAC_VER_30) { - tp->intr_event &= ~RxFIFOOver; - tp->napi_event &= ~RxFIFOOver; - } + if (tp->mac_version >= RTL_GIGA_MAC_VER_30) + tp->event_slow &= ~RxFIFOOver; if (tp->mac_version == RTL_GIGA_MAC_VER_13 || tp->mac_version == RTL_GIGA_MAC_VER_16) { @@ -5359,61 +5392,34 @@ static void rtl8169_tx_clear(struct rtl8169_private *tp) tp->cur_tx = tp->dirty_tx = 0; } -static void rtl8169_schedule_work(struct net_device *dev) -{ - struct rtl8169_private *tp = netdev_priv(dev); - - schedule_work(&tp->wk.work); -} - -static void rtl8169_wait_for_quiescence(struct net_device *dev) -{ - struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; - - synchronize_irq(dev->irq); - - /* Wait for any pending NAPI task to complete */ - napi_disable(&tp->napi); - - rtl8169_irq_mask_and_ack(tp); - - tp->intr_mask = 0xffff; - RTL_W16(IntrMask, tp->intr_event); - napi_enable(&tp->napi); -} - static void rtl_reset_work(struct rtl8169_private *tp) { struct net_device *dev = tp->dev; int i; - rtnl_lock(); - - if (!netif_running(dev)) - goto out_unlock; + napi_disable(&tp->napi); + netif_stop_queue(dev); + synchronize_sched(); rtl8169_hw_reset(tp); - rtl8169_wait_for_quiescence(dev); - for (i = 0; i < NUM_RX_DESC; i++) rtl8169_mark_to_asic(tp->RxDescArray + i, rx_buf_sz); rtl8169_tx_clear(tp); rtl8169_init_ring_indexes(tp); + napi_enable(&tp->napi); rtl_hw_start(dev); netif_wake_queue(dev); rtl8169_check_link_status(dev, tp, tp->mmio_addr); - -out_unlock: - rtnl_unlock(); } static void rtl8169_tx_timeout(struct net_device *dev) { - rtl8169_schedule_work(dev); + struct rtl8169_private *tp = netdev_priv(dev); + + rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); } static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, @@ -5550,6 +5556,8 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, RTL_W8(TxPoll, NPQ); + mmiowb(); + if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) { netif_stop_queue(dev); smp_mb(); @@ -5616,12 +5624,10 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev) rtl8169_hw_reset(tp); - rtl8169_schedule_work(dev); + rtl_schedule_task_bh(tp, RTL_FLAG_TASK_RESET_PENDING); } -static void rtl8169_tx_interrupt(struct net_device *dev, - struct rtl8169_private *tp, - void __iomem *ioaddr) +static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp) { unsigned int dirty_tx, tx_left; @@ -5664,8 +5670,11 @@ static void rtl8169_tx_interrupt(struct net_device *dev, * of start_xmit activity is detected (if it is not detected, * it is slow enough). -- FR */ - if (tp->cur_tx != dirty_tx) + if (tp->cur_tx != dirty_tx) { + void __iomem *ioaddr = tp->mmio_addr; + RTL_W8(TxPoll, NPQ); + } } } @@ -5704,9 +5713,7 @@ static struct sk_buff *rtl8169_try_rx_copy(void *data, return skb; } -static int rtl8169_rx_interrupt(struct net_device *dev, - struct rtl8169_private *tp, - void __iomem *ioaddr, u32 budget) +static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, u32 budget) { unsigned int cur_rx, rx_left; unsigned int count; @@ -5734,7 +5741,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev, if (status & RxCRC) dev->stats.rx_crc_errors++; if (status & RxFOVF) { - rtl8169_schedule_work(dev); + rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); dev->stats.rx_fifo_errors++; } rtl8169_mark_to_asic(desc, rx_buf_sz); @@ -5795,109 +5802,120 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) { struct net_device *dev = dev_instance; struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; int handled = 0; u16 status; - /* loop handling interrupts until we have no new ones or - * we hit a invalid/hotplug case. - */ status = rtl_get_events(tp); - while (status && status != 0xffff) { - status &= tp->intr_event; - if (!status) - break; - - handled = 1; + if (status && status != 0xffff) { + status &= RTL_EVENT_NAPI | tp->event_slow; + if (status) { + handled = 1; - /* Handle all of the error cases first. These will reset - * the chip, so just exit the loop. - */ - if (unlikely(!netif_running(dev))) { - rtl8169_hw_reset(tp); - break; + rtl_irq_disable(tp); + napi_schedule(&tp->napi); } + } + return IRQ_RETVAL(handled); +} - if (unlikely(status & RxFIFOOver)) { - switch (tp->mac_version) { - /* Work around for rx fifo overflow */ - case RTL_GIGA_MAC_VER_11: - netif_stop_queue(dev); - rtl8169_tx_timeout(dev); - goto done; - default: - break; - } - } +/* + * Workqueue context. + */ +static void rtl_slow_event_work(struct rtl8169_private *tp) +{ + struct net_device *dev = tp->dev; + u16 status; + + status = rtl_get_events(tp) & tp->event_slow; + rtl_ack_events(tp, status); - if (unlikely(status & SYSErr)) { - rtl8169_pcierr_interrupt(dev); + if (unlikely(status & RxFIFOOver)) { + switch (tp->mac_version) { + /* Work around for rx fifo overflow */ + case RTL_GIGA_MAC_VER_11: + netif_stop_queue(dev); + rtl_schedule_task_bh(tp, RTL_FLAG_TASK_RESET_PENDING); + default: break; } + } - if (status & LinkChg) - __rtl8169_check_link_status(dev, tp, ioaddr, true); + if (unlikely(status & SYSErr)) + rtl8169_pcierr_interrupt(dev); - /* We need to see the lastest version of tp->intr_mask to - * avoid ignoring an MSI interrupt and having to wait for - * another event which may never come. - */ - smp_rmb(); - if (status & tp->intr_mask & tp->napi_event) { - RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event); - tp->intr_mask = ~tp->napi_event; - - if (likely(napi_schedule_prep(&tp->napi))) - __napi_schedule(&tp->napi); - else - netif_info(tp, intr, dev, - "interrupt %04x in poll\n", status); - } + if (status & LinkChg) + __rtl8169_check_link_status(dev, tp, tp->mmio_addr, true); - /* We only get a new MSI interrupt when all active irq - * sources on the chip have been acknowledged. So, ack - * everything we've seen and check if new sources have become - * active to avoid blocking all interrupts from the chip. - */ - RTL_W16(IntrStatus, - (status & RxFIFOOver) ? (status | RxOverflow) : status); - status = rtl_get_events(tp); - } -done: - return IRQ_RETVAL(handled); + napi_disable(&tp->napi); + rtl_irq_disable(tp); + + napi_enable(&tp->napi); + napi_schedule(&tp->napi); } static void rtl_task(struct work_struct *work) { + static const struct { + int bitnr; + void (*action)(struct rtl8169_private *); + } rtl_work[] = { + { RTL_FLAG_TASK_SLOW_PENDING, rtl_slow_event_work }, + { RTL_FLAG_TASK_RESET_PENDING, rtl_reset_work }, + { RTL_FLAG_TASK_PHY_PENDING, rtl_phy_work } + }; struct rtl8169_private *tp = container_of(work, struct rtl8169_private, wk.work); + struct net_device *dev = tp->dev; + int i; + + rtl_lock_work(tp); + + if (!netif_running(dev) || !tp->wk.enabled) + goto out_unlock; + + for (i = 0; i < ARRAY_SIZE(rtl_work); i++) { + bool pending; + + spin_lock_bh(&tp->lock); + pending = test_and_clear_bit(rtl_work[i].bitnr, tp->wk.flags); + spin_unlock_bh(&tp->lock); + + if (pending) + rtl_work[i].action(tp); + } - rtl_reset_work(tp); +out_unlock: + rtl_unlock_work(tp); } static int rtl8169_poll(struct napi_struct *napi, int budget) { struct rtl8169_private *tp = container_of(napi, struct rtl8169_private, napi); struct net_device *dev = tp->dev; - void __iomem *ioaddr = tp->mmio_addr; - int work_done; + u16 enable_mask = RTL_EVENT_NAPI | tp->event_slow; + int work_done= 0; + u16 status; + + status = rtl_get_events(tp); + rtl_ack_events(tp, status & ~tp->event_slow); + + if (status & RTL_EVENT_NAPI_RX) + work_done = rtl_rx(dev, tp, (u32) budget); + + if (status & RTL_EVENT_NAPI_TX) + rtl_tx(dev, tp); - work_done = rtl8169_rx_interrupt(dev, tp, ioaddr, (u32) budget); - rtl8169_tx_interrupt(dev, tp, ioaddr); + if (status & tp->event_slow) { + enable_mask &= ~tp->event_slow; + + rtl_schedule_task(tp, RTL_FLAG_TASK_SLOW_PENDING); + } if (work_done < budget) { napi_complete(napi); - /* We need for force the visibility of tp->intr_mask - * for other CPUs, as we can loose an MSI interrupt - * and potentially wait for a retransmit timeout if we don't. - * The posted write to IntrMask is safe, as it will - * eventually make it to the chip and we won't loose anything - * until it does. - */ - tp->intr_mask = 0xffff; - wmb(); - RTL_W16(IntrMask, tp->intr_event); + rtl_irq_enable(tp, enable_mask); + mmiowb(); } return work_done; @@ -5921,11 +5939,8 @@ static void rtl8169_down(struct net_device *dev) del_timer_sync(&tp->timer); - netif_stop_queue(dev); - napi_disable(&tp->napi); - - spin_lock_irq(&tp->lock); + netif_stop_queue(dev); rtl8169_hw_reset(tp); /* @@ -5935,12 +5950,8 @@ static void rtl8169_down(struct net_device *dev) */ rtl8169_rx_missed(dev, ioaddr); - spin_unlock_irq(&tp->lock); - - synchronize_irq(dev->irq); - /* Give a racing hard_start_xmit a few cycles to complete. */ - synchronize_sched(); /* FIXME: should this be synchronize_irq()? */ + synchronize_sched(); rtl8169_tx_clear(tp); @@ -5959,7 +5970,11 @@ static int rtl8169_close(struct net_device *dev) /* Update counters before going down */ rtl8169_update_counters(dev); + rtl_lock_work(tp); + tp->wk.enabled = false; + rtl8169_down(dev); + rtl_unlock_work(tp); free_irq(dev->irq, dev); @@ -5979,7 +5994,6 @@ static void rtl_set_rx_mode(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; - unsigned long flags; u32 mc_filter[2]; /* Multicast hash filter */ int rx_mode; u32 tmp = 0; @@ -6008,7 +6022,7 @@ static void rtl_set_rx_mode(struct net_device *dev) } } - spin_lock_irqsave(&tp->lock, flags); + spin_lock_bh(&tp->lock); tmp = (RTL_R32(RxConfig) & ~RX_CONFIG_ACCEPT_MASK) | rx_mode; @@ -6024,7 +6038,7 @@ static void rtl_set_rx_mode(struct net_device *dev) RTL_W32(RxConfig, tmp); - spin_unlock_irqrestore(&tp->lock, flags); + spin_unlock_bh(&tp->lock); } /** @@ -6037,13 +6051,9 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; - unsigned long flags; - if (netif_running(dev)) { - spin_lock_irqsave(&tp->lock, flags); + if (netif_running(dev)) rtl8169_rx_missed(dev, ioaddr); - spin_unlock_irqrestore(&tp->lock, flags); - } return &dev->stats; } @@ -6055,10 +6065,15 @@ static void rtl8169_net_suspend(struct net_device *dev) if (!netif_running(dev)) return; - rtl_pll_power_down(tp); - netif_device_detach(dev); netif_stop_queue(dev); + + rtl_lock_work(tp); + napi_disable(&tp->napi); + tp->wk.enabled = false; + rtl_unlock_work(tp); + + rtl_pll_power_down(tp); } #ifdef CONFIG_PM @@ -6081,7 +6096,9 @@ static void __rtl8169_resume(struct net_device *dev) rtl_pll_power_up(tp); - rtl8169_schedule_work(dev); + tp->wk.enabled = true; + + rtl_schedule_task_bh(tp, RTL_FLAG_TASK_RESET_PENDING); } static int rtl8169_resume(struct device *device) @@ -6107,10 +6124,10 @@ static int rtl8169_runtime_suspend(struct device *device) if (!tp->TxDescArray) return 0; - spin_lock_irq(&tp->lock); + rtl_lock_work(tp); tp->saved_wolopts = __rtl8169_get_wol(tp); __rtl8169_set_wol(tp, WAKE_ANY); - spin_unlock_irq(&tp->lock); + rtl_unlock_work(tp); rtl8169_net_suspend(dev); @@ -6126,10 +6143,10 @@ static int rtl8169_runtime_resume(struct device *device) if (!tp->TxDescArray) return 0; - spin_lock_irq(&tp->lock); + rtl_lock_work(tp); __rtl8169_set_wol(tp, tp->saved_wolopts); tp->saved_wolopts = 0; - spin_unlock_irq(&tp->lock); + rtl_unlock_work(tp); rtl8169_init_phy(dev, tp); @@ -6197,12 +6214,8 @@ static void rtl_shutdown(struct pci_dev *pdev) /* Restore original MAC address */ rtl_rar_set(tp, dev->perm_addr); - spin_lock_irq(&tp->lock); - rtl8169_hw_reset(tp); - spin_unlock_irq(&tp->lock); - if (system_state == SYSTEM_POWER_OFF) { if (__rtl8169_get_wol(tp) & WAKE_ANY) { rtl_wol_suspend_quirk(tp); -- cgit v1.2.3-70-g09d2 From 07d251460bbf9752c6532af8c1a68328c199dd70 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 27 Jan 2012 10:24:40 -0500 Subject: PCI/XEN: Fix bug introduced by a recent change This patch (as1516) fixes a bug introduced during the removal of put_driver() and get_driver() from drivers/pci/xen-pcifront.c. Reported-by: Stephen Rothwell Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/pci/xen-pcifront.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c index 6f819988a8d..98387caf59b 100644 --- a/drivers/pci/xen-pcifront.c +++ b/drivers/pci/xen-pcifront.c @@ -593,7 +593,7 @@ static pci_ers_result_t pcifront_common_process(int cmd, } pdrv = pcidev->driver; - if (pdrv->driver) { + if (pdrv) { if (pdrv->err_handler && pdrv->err_handler->error_detected) { dev_dbg(&pcidev->dev, "trying to call AER service\n"); -- cgit v1.2.3-70-g09d2 From 7aff0fe33033fc75b61446ba29d38b1b1354af9f Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Mon, 12 Dec 2011 09:25:58 -0700 Subject: of: Add of_property_match_string() to find index into a string list Add a helper function for finding the index of a string in a string list property. This helper is useful for bindings that use a separate *-name property for attaching names to tuples in another property such as 'reg' or 'gpios'. Signed-off-by: Grant Likely --- arch/arm/boot/dts/testcases/tests-phandle.dtsi | 2 ++ drivers/of/base.c | 36 ++++++++++++++++++++++++++ drivers/of/selftest.c | 29 +++++++++++++++++++++ include/linux/of.h | 3 +++ 4 files changed, 70 insertions(+) (limited to 'drivers') diff --git a/arch/arm/boot/dts/testcases/tests-phandle.dtsi b/arch/arm/boot/dts/testcases/tests-phandle.dtsi index ec0c4e6212c..0007d3cd7dc 100644 --- a/arch/arm/boot/dts/testcases/tests-phandle.dtsi +++ b/arch/arm/boot/dts/testcases/tests-phandle.dtsi @@ -31,6 +31,8 @@ phandle-list-bad-phandle = <12345678 0 0>; phandle-list-bad-args = <&provider2 1 0>, <&provider3 0>; + empty-property; + unterminated-string = [40 41 42 43]; }; }; }; diff --git a/drivers/of/base.c b/drivers/of/base.c index 133908a6fd8..13ba72875e2 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -761,6 +761,42 @@ int of_property_read_string_index(struct device_node *np, const char *propname, } EXPORT_SYMBOL_GPL(of_property_read_string_index); +/** + * of_property_match_string() - Find string in a list and return index + * @np: pointer to node containing string list property + * @propname: string list property name + * @string: pointer to string to search for in string list + * + * This function searches a string list property and returns the index + * of a specific string value. + */ +int of_property_match_string(struct device_node *np, const char *propname, + const char *string) +{ + struct property *prop = of_find_property(np, propname, NULL); + size_t l; + int i; + const char *p, *end; + + if (!prop) + return -EINVAL; + if (!prop->value) + return -ENODATA; + + p = prop->value; + end = p + prop->length; + + for (i = 0; p < end; i++, p += l) { + l = strlen(p) + 1; + if (p + l > end) + return -EILSEQ; + pr_debug("comparing %s with %s\n", string, p); + if (strcmp(string, p) == 0) + return i; /* Found it; return index */ + } + return -ENODATA; +} +EXPORT_SYMBOL_GPL(of_property_match_string); /** * of_property_count_strings - Find and return the number of strings from a diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c index 9d2b4803a9d..f24ffd7088d 100644 --- a/drivers/of/selftest.c +++ b/drivers/of/selftest.c @@ -120,6 +120,34 @@ static void __init of_selftest_parse_phandle_with_args(void) pr_info("end - %s\n", passed_all ? "PASS" : "FAIL"); } +static void __init of_selftest_property_match_string(void) +{ + struct device_node *np; + int rc; + + pr_info("start\n"); + np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); + if (!np) { + pr_err("No testcase data in device tree\n"); + return; + } + + rc = of_property_match_string(np, "phandle-list-names", "first"); + selftest(rc == 0, "first expected:0 got:%i\n", rc); + rc = of_property_match_string(np, "phandle-list-names", "second"); + selftest(rc == 1, "second expected:0 got:%i\n", rc); + rc = of_property_match_string(np, "phandle-list-names", "third"); + selftest(rc == 2, "third expected:0 got:%i\n", rc); + rc = of_property_match_string(np, "phandle-list-names", "fourth"); + selftest(rc == -ENODATA, "unmatched string; rc=%i", rc); + rc = of_property_match_string(np, "missing-property", "blah"); + selftest(rc == -EINVAL, "missing property; rc=%i", rc); + rc = of_property_match_string(np, "empty-property", "blah"); + selftest(rc == -ENODATA, "empty property; rc=%i", rc); + rc = of_property_match_string(np, "unterminated-string", "blah"); + selftest(rc == -EILSEQ, "unterminated string; rc=%i", rc); +} + static int __init of_selftest(void) { struct device_node *np; @@ -133,6 +161,7 @@ static int __init of_selftest(void) pr_info("start of selftest - you will see error messages\n"); of_selftest_parse_phandle_with_args(); + of_selftest_property_match_string(); pr_info("end of selftest - %s\n", selftest_passed ? "PASS" : "FAIL"); return 0; } diff --git a/include/linux/of.h b/include/linux/of.h index a75a831e205..5a4a3adb17e 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -217,6 +217,9 @@ extern int of_property_read_string(struct device_node *np, extern int of_property_read_string_index(struct device_node *np, const char *propname, int index, const char **output); +extern int of_property_match_string(struct device_node *np, + const char *propname, + const char *string); extern int of_property_count_strings(struct device_node *np, const char *propname); extern int of_device_is_compatible(const struct device_node *device, -- cgit v1.2.3-70-g09d2 From 787f9fd23283d7103c65371f7b108ecf1020cddf Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Thu, 13 Oct 2011 16:52:50 +0200 Subject: atmel_lcdfb: support 16bit BGR:565 mode, remove unsupported 15bit modes Allow framebuffer to be configured in 16bit mode when panel is wired in (the default) BGR configuration, and don't claim to support 15bit input modes, which the LCD controller cannot handle. Signed-off-by: Peter Korsgaard Acked-by: Nicolas Ferre Signed-off-by: Florian Tobias Schandinat --- drivers/video/atmel_lcdfb.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index e40c00f2c2b..d99505b1637 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -421,24 +421,18 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var, var->red.length = var->green.length = var->blue.length = var->bits_per_pixel; break; - case 15: case 16: if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) { /* RGB:565 mode */ var->red.offset = 11; var->blue.offset = 0; - var->green.length = 6; - } else if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB555) { - var->red.offset = 10; - var->blue.offset = 0; - var->green.length = 5; } else { - /* BGR:555 mode */ + /* BGR:565 mode */ var->red.offset = 0; - var->blue.offset = 10; - var->green.length = 5; + var->blue.offset = 11; } var->green.offset = 5; + var->green.length = 6; var->red.length = var->blue.length = 5; break; case 32: -- cgit v1.2.3-70-g09d2 From f820917abae4a019b0357d3fe72b22c22a11b775 Mon Sep 17 00:00:00 2001 From: "Manjunathappa, Prakash" Date: Tue, 3 Jan 2012 18:10:51 +0530 Subject: video: da8xx-fb: reset LCDC only if functional clock changes with DVFS LCDC functional clock may or may not be derived from CPU/MPU DPLL, For example, AM335x => Separate independent DPLL for LCDC Davinci => Same DPLL as MPU So, on platforms where LCDC functional clock is not derived from CPU/MPU PLL it is not required to reset LCDC module as its functional clock does not change with DVFS. This patch adds check to do reset only if functional clock changes between pre and post notifier callbacks with DVFS. Signed-off-by: Manjunathappa, Prakash Signed-off-by: Florian Tobias Schandinat --- drivers/video/da8xx-fb.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 29577bf1f55..9ecc30744c6 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -161,6 +161,7 @@ struct da8xx_fb_par { int vsync_timeout; #ifdef CONFIG_CPU_FREQ struct notifier_block freq_transition; + unsigned int lcd_fck_rate; #endif void (*panel_power_ctrl)(int); }; @@ -840,11 +841,13 @@ static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb, struct da8xx_fb_par *par; par = container_of(nb, struct da8xx_fb_par, freq_transition); - if (val == CPUFREQ_PRECHANGE) { - lcd_disable_raster(); - } else if (val == CPUFREQ_POSTCHANGE) { - lcd_calc_clk_divider(par); - lcd_enable_raster(); + if (val == CPUFREQ_POSTCHANGE) { + if (par->lcd_fck_rate != clk_get_rate(par->lcdc_clk)) { + par->lcd_fck_rate = clk_get_rate(par->lcdc_clk); + lcd_disable_raster(); + lcd_calc_clk_divider(par); + lcd_enable_raster(); + } } return 0; @@ -1137,6 +1140,9 @@ static int __devinit fb_probe(struct platform_device *device) par = da8xx_fb_info->par; par->lcdc_clk = fb_clk; +#ifdef CONFIG_CPU_FREQ + par->lcd_fck_rate = clk_get_rate(fb_clk); +#endif par->pxl_clk = lcdc_info->pxl_clk; if (fb_pdata->panel_power_ctrl) { par->panel_power_ctrl = fb_pdata->panel_power_ctrl; -- cgit v1.2.3-70-g09d2 From 857a8df9467a6dfe5d3aa309d9bdef31dc817647 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 21 Jan 2012 13:11:49 +0000 Subject: video: s3c-fb: Convert to devm style allocation Saves some code, especially useful as the code saved is mostly in the infrequently tested error paths. Signed-off-by: Mark Brown Acked-by: Jingoo Han Signed-off-by: Florian Tobias Schandinat --- drivers/video/s3c-fb.c | 32 +++++--------------------------- 1 file changed, 5 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c index 0c63b69b634..7c5158dda0b 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c @@ -186,7 +186,6 @@ struct s3c_fb_vsync { * struct s3c_fb - overall hardware state of the hardware * @slock: The spinlock protection for this data sturcture. * @dev: The device that we bound to, for printing, etc. - * @regs_res: The resource we claimed for the IO registers. * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk. * @lcd_clk: The clk (sclk) feeding pixclk. * @regs: The mapped hardware registers. @@ -202,7 +201,6 @@ struct s3c_fb_vsync { struct s3c_fb { spinlock_t slock; struct device *dev; - struct resource *regs_res; struct clk *bus_clk; struct clk *lcd_clk; void __iomem *regs; @@ -1361,7 +1359,7 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev) return -EINVAL; } - sfb = kzalloc(sizeof(struct s3c_fb), GFP_KERNEL); + sfb = devm_kzalloc(dev, sizeof(struct s3c_fb), GFP_KERNEL); if (!sfb) { dev_err(dev, "no memory for framebuffers\n"); return -ENOMEM; @@ -1404,33 +1402,25 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev) goto err_lcd_clk; } - sfb->regs_res = request_mem_region(res->start, resource_size(res), - dev_name(dev)); - if (!sfb->regs_res) { - dev_err(dev, "failed to claim register region\n"); - ret = -ENOENT; - goto err_lcd_clk; - } - - sfb->regs = ioremap(res->start, resource_size(res)); + sfb->regs = devm_request_and_ioremap(dev, res); if (!sfb->regs) { dev_err(dev, "failed to map registers\n"); ret = -ENXIO; - goto err_req_region; + goto err_lcd_clk; } res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { dev_err(dev, "failed to acquire irq resource\n"); ret = -ENOENT; - goto err_ioremap; + goto err_lcd_clk; } sfb->irq_no = res->start; ret = request_irq(sfb->irq_no, s3c_fb_irq, 0, "s3c_fb", sfb); if (ret) { dev_err(dev, "irq request failed\n"); - goto err_ioremap; + goto err_lcd_clk; } dev_dbg(dev, "got resources (regs %p), probing windows\n", sfb->regs); @@ -1486,12 +1476,6 @@ err_pm_runtime: pm_runtime_put_sync(sfb->dev); free_irq(sfb->irq_no, sfb); -err_ioremap: - iounmap(sfb->regs); - -err_req_region: - release_mem_region(sfb->regs_res->start, resource_size(sfb->regs_res)); - err_lcd_clk: pm_runtime_disable(sfb->dev); @@ -1505,7 +1489,6 @@ err_bus_clk: clk_put(sfb->bus_clk); err_sfb: - kfree(sfb); return ret; } @@ -1529,8 +1512,6 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev) free_irq(sfb->irq_no, sfb); - iounmap(sfb->regs); - if (!sfb->variant.has_clksel) { clk_disable(sfb->lcd_clk); clk_put(sfb->lcd_clk); @@ -1539,12 +1520,9 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev) clk_disable(sfb->bus_clk); clk_put(sfb->bus_clk); - release_mem_region(sfb->regs_res->start, resource_size(sfb->regs_res)); - pm_runtime_put_sync(sfb->dev); pm_runtime_disable(sfb->dev); - kfree(sfb); return 0; } -- cgit v1.2.3-70-g09d2 From 92a9c19a89af2ca219fbb040a0059f414a4b7223 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 28 Jan 2012 19:57:46 +0000 Subject: udlfb: remove sysfs framebuffer device with USB .disconnect() The USB graphics card driver delays the unregistering of the framebuffer device to a workqueue, which breaks the userspace visible remove uevent sequence. Recent userspace tools started to support USB graphics card hotplug out-of-the-box and rely on proper events sent by the kernel. The framebuffer device is a direct child of the USB interface which is removed immediately after the USB .disconnect() callback. But the fb device in /sys stays around until its final cleanup, at a time where all the parent devices have been removed already. To work around that, we remove the sysfs fb device directly in the USB .disconnect() callback and leave only the cleanup of the internal fb data to the delayed work. Before: add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb) add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb) add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/graphics/fb0 (graphics) remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb) remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb) remove /2-1.2:1.0/graphics/fb0 (graphics) After: add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb) add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb) add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/graphics/fb1 (graphics) remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/graphics/fb1 (graphics) remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb) remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb) Cc: stable@vger.kernel.org Tested-by: Bernie Thompson Acked-by: Bernie Thompson Signed-off-by: Kay Sievers Signed-off-by: Florian Tobias Schandinat --- drivers/video/fbmem.c | 18 +++++++++++++++++- drivers/video/udlfb.c | 2 +- include/linux/fb.h | 1 + 3 files changed, 19 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index ac9141b8535..c6ce416ab58 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -1665,6 +1665,7 @@ static int do_unregister_framebuffer(struct fb_info *fb_info) if (ret) return -EINVAL; + unlink_framebuffer(fb_info); if (fb_info->pixmap.addr && (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT)) kfree(fb_info->pixmap.addr); @@ -1672,7 +1673,6 @@ static int do_unregister_framebuffer(struct fb_info *fb_info) registered_fb[i] = NULL; num_registered_fb--; fb_cleanup_device(fb_info); - device_destroy(fb_class, MKDEV(FB_MAJOR, i)); event.info = fb_info; fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); @@ -1681,6 +1681,22 @@ static int do_unregister_framebuffer(struct fb_info *fb_info) return 0; } +int unlink_framebuffer(struct fb_info *fb_info) +{ + int i; + + i = fb_info->node; + if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info) + return -EINVAL; + + if (fb_info->dev) { + device_destroy(fb_class, MKDEV(FB_MAJOR, i)); + fb_info->dev = NULL; + } + return 0; +} +EXPORT_SYMBOL(unlink_framebuffer); + void remove_conflicting_framebuffers(struct apertures_struct *a, const char *name, bool primary) { diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c index a19773149bd..a40c05ebbdc 100644 --- a/drivers/video/udlfb.c +++ b/drivers/video/udlfb.c @@ -1739,7 +1739,7 @@ static void dlfb_usb_disconnect(struct usb_interface *interface) for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++) device_remove_file(info->dev, &fb_device_attrs[i]); device_remove_bin_file(info->dev, &edid_attr); - + unlink_framebuffer(info); usb_set_intfdata(interface, NULL); /* if clients still have us open, will be freed on last close */ diff --git a/include/linux/fb.h b/include/linux/fb.h index c18122f4054..a395b8c7699 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -1003,6 +1003,7 @@ extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf, /* drivers/video/fbmem.c */ extern int register_framebuffer(struct fb_info *fb_info); extern int unregister_framebuffer(struct fb_info *fb_info); +extern int unlink_framebuffer(struct fb_info *fb_info); extern void remove_conflicting_framebuffers(struct apertures_struct *a, const char *name, bool primary); extern int fb_prepare_logo(struct fb_info *fb_info, int rotate); -- cgit v1.2.3-70-g09d2 From 1c16697bf9d5b206cb0d2b905a54de5e077296be Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 21 Jan 2012 16:01:58 +0100 Subject: drivers/video/au*fb.c: use devm_ functions The various devm_ functions allocate memory that is released when a driver detaches. This patch uses these functions for data that is allocated in the probe function of a platform device and is only freed in the remove function. In au1100fb.c, the probe function now returns -ENODEV on failure. Signed-off-by: Julia Lawall Acked-by: Manuel Lauss Signed-off-by: Florian Tobias Schandinat --- drivers/video/au1100fb.c | 32 ++++++++++++-------------------- drivers/video/au1200fb.c | 9 +-------- 2 files changed, 13 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c index de9da6774fd..befcbd8ef01 100644 --- a/drivers/video/au1100fb.c +++ b/drivers/video/au1100fb.c @@ -477,7 +477,8 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev) u32 sys_clksrc; /* Allocate new device private */ - fbdev = kzalloc(sizeof(struct au1100fb_device), GFP_KERNEL); + fbdev = devm_kzalloc(&dev->dev, sizeof(struct au1100fb_device), + GFP_KERNEL); if (!fbdev) { print_err("fail to allocate device private record"); return -ENOMEM; @@ -498,8 +499,9 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev) au1100fb_fix.mmio_start = regs_res->start; au1100fb_fix.mmio_len = resource_size(regs_res); - if (!request_mem_region(au1100fb_fix.mmio_start, au1100fb_fix.mmio_len, - DRIVER_NAME)) { + if (!devm_request_mem_region(au1100fb_fix.mmio_start, + au1100fb_fix.mmio_len, + DRIVER_NAME)) { print_err("fail to lock memory region at 0x%08lx", au1100fb_fix.mmio_start); return -EBUSY; @@ -514,8 +516,9 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev) fbdev->fb_len = fbdev->panel->xres * fbdev->panel->yres * (fbdev->panel->bpp >> 3) * AU1100FB_NBR_VIDEO_BUFFERS; - fbdev->fb_mem = dma_alloc_coherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len), - &fbdev->fb_phys, GFP_KERNEL); + fbdev->fb_mem = dmam_alloc_coherent(&dev->dev, &dev->dev, + PAGE_ALIGN(fbdev->fb_len), + &fbdev->fb_phys, GFP_KERNEL); if (!fbdev->fb_mem) { print_err("fail to allocate frambuffer (size: %dK))", fbdev->fb_len / 1024); @@ -557,14 +560,14 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev) fbdev->info.fbops = &au1100fb_ops; fbdev->info.fix = au1100fb_fix; - if (!(fbdev->info.pseudo_palette = kzalloc(sizeof(u32) * 16, GFP_KERNEL))) { + fbdev->info.pseudo_palette = + devm_kzalloc(&dev->dev, sizeof(u32) * 16, GFP_KERNEL); + if (!fbdev->info.pseudo_palette) return -ENOMEM; - } if (fb_alloc_cmap(&fbdev->info.cmap, AU1100_LCD_NBR_PALETTE_ENTRIES, 0) < 0) { print_err("Fail to allocate colormap (%d entries)", AU1100_LCD_NBR_PALETTE_ENTRIES); - kfree(fbdev->info.pseudo_palette); return -EFAULT; } @@ -582,9 +585,6 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev) return 0; failed: - if (fbdev->regs) { - release_mem_region(fbdev->regs_phys, fbdev->regs_len); - } if (fbdev->fb_mem) { dma_free_noncoherent(&dev->dev, fbdev->fb_len, fbdev->fb_mem, fbdev->fb_phys); @@ -592,10 +592,9 @@ failed: if (fbdev->info.cmap.len != 0) { fb_dealloc_cmap(&fbdev->info.cmap); } - kfree(fbdev); platform_set_drvdata(dev, NULL); - return 0; + return -ENODEV; } int au1100fb_drv_remove(struct platform_device *dev) @@ -615,14 +614,7 @@ int au1100fb_drv_remove(struct platform_device *dev) /* Clean up all probe data */ unregister_framebuffer(&fbdev->info); - release_mem_region(fbdev->regs_phys, fbdev->regs_len); - - dma_free_coherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len), fbdev->fb_mem, - fbdev->fb_phys); - fb_dealloc_cmap(&fbdev->info.cmap); - kfree(fbdev->info.pseudo_palette); - kfree((void*)fbdev); return 0; } diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c index 04e4479d5af..3e9a773db09 100644 --- a/drivers/video/au1200fb.c +++ b/drivers/video/au1200fb.c @@ -1724,7 +1724,7 @@ static int __devinit au1200fb_drv_probe(struct platform_device *dev) /* Allocate the framebuffer to the maximum screen size */ fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8; - fbdev->fb_mem = dma_alloc_noncoherent(&dev->dev, + fbdev->fb_mem = dmam_alloc_noncoherent(&dev->dev, &dev->dev, PAGE_ALIGN(fbdev->fb_len), &fbdev->fb_phys, GFP_KERNEL); if (!fbdev->fb_mem) { @@ -1788,9 +1788,6 @@ static int __devinit au1200fb_drv_probe(struct platform_device *dev) failed: /* NOTE: This only does the current plane/window that failed; others are still active */ - if (fbdev->fb_mem) - dma_free_noncoherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len), - fbdev->fb_mem, fbdev->fb_phys); if (fbi) { if (fbi->cmap.len != 0) fb_dealloc_cmap(&fbi->cmap); @@ -1817,10 +1814,6 @@ static int __devexit au1200fb_drv_remove(struct platform_device *dev) /* Clean up all probe data */ unregister_framebuffer(fbi); - if (fbdev->fb_mem) - dma_free_noncoherent(&dev->dev, - PAGE_ALIGN(fbdev->fb_len), - fbdev->fb_mem, fbdev->fb_phys); if (fbi->cmap.len != 0) fb_dealloc_cmap(&fbi->cmap); kfree(fbi->pseudo_palette); -- cgit v1.2.3-70-g09d2 From f8bd493456c3da372ae81ed8f6b903f6207b9d98 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 26 Jan 2012 19:32:34 +0900 Subject: video: use gpio_request_one Using gpio_request_one can make the code simpler because it can set the direction and initial value in one shot. Signed-off-by: Jingoo Han Acked-by: Tomi Valkeinen Cc: Michael Hennerich Cc: Pavel Machek Signed-off-by: Florian Tobias Schandinat --- drivers/video/bf537-lq035.c | 12 +++--------- drivers/video/bf54x-lq043fb.c | 4 +--- drivers/video/bfin-lq035q1-fb.c | 8 ++++---- drivers/video/bfin_adv7393fb.c | 5 +++-- drivers/video/msm/mddi_client_nt35399.c | 7 +------ drivers/video/msm/mddi_client_toshiba.c | 7 +------ drivers/video/omap/lcd_inn1610.c | 10 ++++------ drivers/video/omap2/displays/panel-taal.c | 4 +--- drivers/video/omap2/displays/panel-tpo-td043mtea1.c | 11 ++--------- 9 files changed, 20 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/video/bf537-lq035.c b/drivers/video/bf537-lq035.c index bea53c1a495..befbc80d11f 100644 --- a/drivers/video/bf537-lq035.c +++ b/drivers/video/bf537-lq035.c @@ -383,23 +383,19 @@ static int __devinit request_ports(void) } #if (defined(UD) && defined(LBR)) - if (gpio_request(UD, KBUILD_MODNAME)) { + if (gpio_request_one(UD, GPIOF_OUT_INIT_LOW, KBUILD_MODNAME)) { pr_err("requesting GPIO %d failed\n", UD); return -EBUSY; } - if (gpio_request(LBR, KBUILD_MODNAME)) { + if (gpio_request_one(LBR, GPIOF_OUT_INIT_HIGH, KBUILD_MODNAME)) { pr_err("requesting GPIO %d failed\n", LBR); gpio_free(UD); return -EBUSY; } - - gpio_direction_output(UD, 0); - gpio_direction_output(LBR, 1); - #endif - if (gpio_request(MOD, KBUILD_MODNAME)) { + if (gpio_request_one(MOD, GPIOF_OUT_INIT_HIGH, KBUILD_MODNAME)) { pr_err("requesting GPIO %d failed\n", MOD); #if (defined(UD) && defined(LBR)) gpio_free(LBR); @@ -408,8 +404,6 @@ static int __devinit request_ports(void) return -EBUSY; } - gpio_direction_output(MOD, 1); - SSYNC(); return 0; } diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c index 46b03f53985..dc2f0047769 100644 --- a/drivers/video/bf54x-lq043fb.c +++ b/drivers/video/bf54x-lq043fb.c @@ -240,7 +240,7 @@ static int request_ports(struct bfin_bf54xfb_info *fbi) u16 eppi_req_18[] = EPPI0_18; u16 disp = fbi->mach_info->disp; - if (gpio_request(disp, DRIVER_NAME)) { + if (gpio_request_one(disp, GPIOF_OUT_INIT_HIGH, DRIVER_NAME)) { printk(KERN_ERR "Requesting GPIO %d failed\n", disp); return -EFAULT; } @@ -263,8 +263,6 @@ static int request_ports(struct bfin_bf54xfb_info *fbi) } } - gpio_direction_output(disp, 1); - return 0; } diff --git a/drivers/video/bfin-lq035q1-fb.c b/drivers/video/bfin-lq035q1-fb.c index c633068372c..86922ac8441 100644 --- a/drivers/video/bfin-lq035q1-fb.c +++ b/drivers/video/bfin-lq035q1-fb.c @@ -365,10 +365,10 @@ static int __devinit bfin_lq035q1_request_ports(struct platform_device *pdev, * Drive PPI_FS3 Low */ if (ANOMALY_05000400) { - int ret = gpio_request(P_IDENT(P_PPI0_FS3), "PPI_FS3"); + int ret = gpio_request_one(P_IDENT(P_PPI0_FS3), + GPIOF_OUT_INIT_LOW, "PPI_FS3"); if (ret) return ret; - gpio_direction_output(P_IDENT(P_PPI0_FS3), 0); } if (ppi16) @@ -716,14 +716,14 @@ static int __devinit bfin_lq035q1_probe(struct platform_device *pdev) } if (info->disp_info->use_bl) { - ret = gpio_request(info->disp_info->gpio_bl, "LQ035 Backlight"); + ret = gpio_request_one(info->disp_info->gpio_bl, + GPIOF_OUT_INIT_LOW, "LQ035 Backlight"); if (ret) { dev_err(&pdev->dev, "failed to request GPIO %d\n", info->disp_info->gpio_bl); goto out9; } - gpio_direction_output(info->disp_info->gpio_bl, 0); } ret = register_framebuffer(fbinfo); diff --git a/drivers/video/bfin_adv7393fb.c b/drivers/video/bfin_adv7393fb.c index 811dd7f6aa4..c9928142921 100644 --- a/drivers/video/bfin_adv7393fb.c +++ b/drivers/video/bfin_adv7393fb.c @@ -411,12 +411,13 @@ static int __devinit bfin_adv7393_fb_probe(struct i2c_client *client, /* Workaround "PPI Does Not Start Properly In Specific Mode" */ if (ANOMALY_05000400) { - if (gpio_request(P_IDENT(P_PPI0_FS3), "PPI0_FS3")) { + ret = gpio_request_one(P_IDENT(P_PPI0_FS3), GPIOF_OUT_INIT_LOW, + "PPI0_FS3") + if (ret) { dev_err(&client->dev, "PPI0_FS3 GPIO request failed\n"); ret = -EBUSY; goto out_8; } - gpio_direction_output(P_IDENT(P_PPI0_FS3), 0); } if (peripheral_request_list(ppi_pins, DRIVER_NAME)) { diff --git a/drivers/video/msm/mddi_client_nt35399.c b/drivers/video/msm/mddi_client_nt35399.c index f239f4a25e0..7fcd67e132b 100644 --- a/drivers/video/msm/mddi_client_nt35399.c +++ b/drivers/video/msm/mddi_client_nt35399.c @@ -155,14 +155,10 @@ static int setup_vsync(struct panel_info *panel, int init) ret = 0; goto uninit; } - ret = gpio_request(gpio, "vsync"); + ret = gpio_request_one(gpio, GPIOF_IN, "vsync"); if (ret) goto err_request_gpio_failed; - ret = gpio_direction_input(gpio); - if (ret) - goto err_gpio_direction_input_failed; - ret = irq = gpio_to_irq(gpio); if (ret < 0) goto err_get_irq_num_failed; @@ -180,7 +176,6 @@ uninit: free_irq(gpio_to_irq(gpio), panel->client_data); err_request_irq_failed: err_get_irq_num_failed: -err_gpio_direction_input_failed: gpio_free(gpio); err_request_gpio_failed: return ret; diff --git a/drivers/video/msm/mddi_client_toshiba.c b/drivers/video/msm/mddi_client_toshiba.c index f9bc932ac46..053eb687733 100644 --- a/drivers/video/msm/mddi_client_toshiba.c +++ b/drivers/video/msm/mddi_client_toshiba.c @@ -186,14 +186,10 @@ static int setup_vsync(struct panel_info *panel, ret = 0; goto uninit; } - ret = gpio_request(gpio, "vsync"); + ret = gpio_request_one(gpio, GPIOF_IN, "vsync"); if (ret) goto err_request_gpio_failed; - ret = gpio_direction_input(gpio); - if (ret) - goto err_gpio_direction_input_failed; - ret = irq = gpio_to_irq(gpio); if (ret < 0) goto err_get_irq_num_failed; @@ -210,7 +206,6 @@ uninit: free_irq(gpio_to_irq(gpio), panel); err_request_irq_failed: err_get_irq_num_failed: -err_gpio_direction_input_failed: gpio_free(gpio); err_request_gpio_failed: return ret; diff --git a/drivers/video/omap/lcd_inn1610.c b/drivers/video/omap/lcd_inn1610.c index 7e8bd8e08a9..e3d3d135aa4 100644 --- a/drivers/video/omap/lcd_inn1610.c +++ b/drivers/video/omap/lcd_inn1610.c @@ -22,7 +22,7 @@ #include #include -#include +#include #include "omapfb.h" #define MODULE_NAME "omapfb-lcd_h3" @@ -32,20 +32,18 @@ static int innovator1610_panel_init(struct lcd_panel *panel, { int r = 0; - if (gpio_request(14, "lcd_en0")) { + /* configure GPIO(14, 15) as outputs */ + if (gpio_request_one(14, GPIOF_OUT_INIT_LOW, "lcd_en0")) { pr_err(MODULE_NAME ": can't request GPIO 14\n"); r = -1; goto exit; } - if (gpio_request(15, "lcd_en1")) { + if (gpio_request_one(15, GPIOF_OUT_INIT_LOW, "lcd_en1")) { pr_err(MODULE_NAME ": can't request GPIO 15\n"); gpio_free(14); r = -1; goto exit; } - /* configure GPIO(14, 15) as outputs */ - gpio_direction_output(14, 0); - gpio_direction_output(15, 0); exit: return r; } diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index 00c5c615585..0f21fa5a16a 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -1019,14 +1019,12 @@ static int taal_probe(struct omap_dss_device *dssdev) if (panel_data->use_ext_te) { int gpio = panel_data->ext_te_gpio; - r = gpio_request(gpio, "taal irq"); + r = gpio_request_one(gpio, GPIOF_IN, "taal irq"); if (r) { dev_err(&dssdev->dev, "GPIO request failed\n"); goto err_gpio; } - gpio_direction_input(gpio); - r = request_irq(gpio_to_irq(gpio), taal_te_isr, IRQF_TRIGGER_RISING, "taal vsync", dssdev); diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c index e6649aa8959..880c313d6bc 100644 --- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c +++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c @@ -408,17 +408,12 @@ static int tpo_td043_probe(struct omap_dss_device *dssdev) } if (gpio_is_valid(nreset_gpio)) { - ret = gpio_request(nreset_gpio, "lcd reset"); + ret = gpio_request_one(nreset_gpio, GPIOF_OUT_INIT_LOW, + "lcd reset"); if (ret < 0) { dev_err(&dssdev->dev, "couldn't request reset GPIO\n"); goto fail_gpio_req; } - - ret = gpio_direction_output(nreset_gpio, 0); - if (ret < 0) { - dev_err(&dssdev->dev, "couldn't set GPIO direction\n"); - goto fail_gpio_direction; - } } ret = sysfs_create_group(&dssdev->dev.kobj, &tpo_td043_attr_group); @@ -427,8 +422,6 @@ static int tpo_td043_probe(struct omap_dss_device *dssdev) return 0; -fail_gpio_direction: - gpio_free(nreset_gpio); fail_gpio_req: regulator_put(tpo_td043->vcc_reg); fail_regulator: -- cgit v1.2.3-70-g09d2 From 05e52b4bfba0d1fa4195abbc4ac29c24033c8e96 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 26 Jan 2012 19:38:45 +0900 Subject: video: s3c-fb: fix checkpatch error This patch fixes the checkpatch error listed below: ERROR: trailing statements should be on next line Signed-off-by: Jingoo Han Signed-off-by: Florian Tobias Schandinat --- drivers/video/s3c-fb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c index 7c5158dda0b..389189a9e77 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c @@ -48,7 +48,8 @@ #undef writel #define writel(v, r) do { \ printk(KERN_DEBUG "%s: %08x => %p\n", __func__, (unsigned int)v, r); \ - __raw_writel(v, r); } while (0) + __raw_writel(v, r); \ +} while (0) #endif /* FB_S3C_DEBUG_REGWRITE */ /* irq_flags bits */ -- cgit v1.2.3-70-g09d2 From f7f31e505aa79d91b979a38789b1608744361bdc Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Fri, 27 Jan 2012 14:47:22 +0900 Subject: video: s3c-fb: add alpha value width setting This patch adds alpha value width setting according to transparency value of each window format, using BLENDCON register. When alpha value is 8 bits, BLENDCON will set alpha value width as 8 bits. Signed-off-by: Jingoo Han Signed-off-by: Florian Tobias Schandinat --- arch/arm/plat-samsung/include/plat/regs-fb.h | 6 ++++++ drivers/video/s3c-fb.c | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) (limited to 'drivers') diff --git a/arch/arm/plat-samsung/include/plat/regs-fb.h b/arch/arm/plat-samsung/include/plat/regs-fb.h index 8f39aa5b26e..6bf68ed0196 100644 --- a/arch/arm/plat-samsung/include/plat/regs-fb.h +++ b/arch/arm/plat-samsung/include/plat/regs-fb.h @@ -384,3 +384,9 @@ #define WPALCON_W0PAL_16BPP_A555 (0x5 << 0) #define WPALCON_W0PAL_16BPP_565 (0x6 << 0) +/* Blending equation control */ +#define BLENDCON (0x260) +#define BLENDCON_NEW_MASK (1 << 0) +#define BLENDCON_NEW_8BIT_ALPHA_VALUE (1 << 0) +#define BLENDCON_NEW_4BIT_ALPHA_VALUE (0 << 0) + diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c index 389189a9e77..9af6c1849c2 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c @@ -82,6 +82,7 @@ struct s3c_fb; * @palette: Address of palette memory, or 0 if none. * @has_prtcon: Set if has PRTCON register. * @has_shadowcon: Set if has SHADOWCON register. + * @has_blendcon: Set if has BLENDCON register. * @has_clksel: Set if VIDCON0 register has CLKSEL bit. */ struct s3c_fb_variant { @@ -100,6 +101,7 @@ struct s3c_fb_variant { unsigned int has_prtcon:1; unsigned int has_shadowcon:1; + unsigned int has_blendcon:1; unsigned int has_clksel:1; }; @@ -691,6 +693,17 @@ static int s3c_fb_set_par(struct fb_info *info) writel(data, regs + sfb->variant.wincon + (win_no * 4)); writel(0x0, regs + sfb->variant.winmap + (win_no * 4)); + /* Set alpha value width */ + if (sfb->variant.has_blendcon) { + data = readl(sfb->regs + BLENDCON); + data &= ~BLENDCON_NEW_MASK; + if (var->transp.length > 4) + data |= BLENDCON_NEW_8BIT_ALPHA_VALUE; + else + data |= BLENDCON_NEW_4BIT_ALPHA_VALUE; + writel(data, sfb->regs + BLENDCON); + } + shadow_protect_win(win, 0); pm_runtime_put_sync(sfb->dev); @@ -1798,6 +1811,7 @@ static struct s3c_fb_driverdata s3c_fb_data_s5pc100 = { }, .has_prtcon = 1, + .has_blendcon = 1, .has_clksel = 1, }, .win[0] = &s3c_fb_data_s5p_wins[0], @@ -1829,6 +1843,7 @@ static struct s3c_fb_driverdata s3c_fb_data_s5pv210 = { }, .has_shadowcon = 1, + .has_blendcon = 1, .has_clksel = 1, }, .win[0] = &s3c_fb_data_s5p_wins[0], @@ -1860,6 +1875,7 @@ static struct s3c_fb_driverdata s3c_fb_data_exynos4 = { }, .has_shadowcon = 1, + .has_blendcon = 1, }, .win[0] = &s3c_fb_data_s5p_wins[0], .win[1] = &s3c_fb_data_s5p_wins[1], @@ -1923,6 +1939,8 @@ static struct s3c_fb_driverdata s3c_fb_data_s5p64x0 = { [1] = 0x2800, [2] = 0x2c00, }, + + .has_blendcon = 1, }, .win[0] = &s3c_fb_data_s5p_wins[0], .win[1] = &s3c_fb_data_s5p_wins[1], -- cgit v1.2.3-70-g09d2 From d8b97db4c8e40e49985fa5802be914292add64f6 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Fri, 27 Jan 2012 14:47:55 +0900 Subject: video: s3c-fb: add video clock running at data under-flow This patch adds video clock running at data under-flow. It means that the pixel clock is continuously provided to lcd module, even when under-run occurs. Signed-off-by: Jingoo Han Signed-off-by: Florian Tobias Schandinat --- arch/arm/plat-samsung/include/plat/regs-fb.h | 3 +++ drivers/video/s3c-fb.c | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+) (limited to 'drivers') diff --git a/arch/arm/plat-samsung/include/plat/regs-fb.h b/arch/arm/plat-samsung/include/plat/regs-fb.h index 6bf68ed0196..bbb16e0aa1f 100644 --- a/arch/arm/plat-samsung/include/plat/regs-fb.h +++ b/arch/arm/plat-samsung/include/plat/regs-fb.h @@ -91,6 +91,9 @@ #define VIDCON1_VSTATUS_BACKPORCH (0x1 << 13) #define VIDCON1_VSTATUS_ACTIVE (0x2 << 13) #define VIDCON1_VSTATUS_FRONTPORCH (0x0 << 13) +#define VIDCON1_VCLK_MASK (0x3 << 9) +#define VIDCON1_VCLK_HOLD (0x0 << 9) +#define VIDCON1_VCLK_RUN (0x1 << 9) #define VIDCON1_INV_VCLK (1 << 7) #define VIDCON1_INV_HSYNC (1 << 6) diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c index 9af6c1849c2..e22bf9ddf28 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c @@ -84,6 +84,7 @@ struct s3c_fb; * @has_shadowcon: Set if has SHADOWCON register. * @has_blendcon: Set if has BLENDCON register. * @has_clksel: Set if VIDCON0 register has CLKSEL bit. + * @has_fixvclk: Set if VIDCON1 register has FIXVCLK bits. */ struct s3c_fb_variant { unsigned int is_2443:1; @@ -103,6 +104,7 @@ struct s3c_fb_variant { unsigned int has_shadowcon:1; unsigned int has_blendcon:1; unsigned int has_clksel:1; + unsigned int has_fixvclk:1; }; /** @@ -1358,6 +1360,7 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev) struct resource *res; int win; int ret = 0; + u32 reg; platid = platform_get_device_id(pdev); fbdrv = (struct s3c_fb_driverdata *)platid->driver_data; @@ -1448,6 +1451,14 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev) writel(pd->vidcon1, sfb->regs + VIDCON1); + /* set video clock running at under-run */ + if (sfb->variant.has_fixvclk) { + reg = readl(sfb->regs + VIDCON1); + reg &= ~VIDCON1_VCLK_MASK; + reg |= VIDCON1_VCLK_RUN; + writel(reg, sfb->regs + VIDCON1); + } + /* zero all windows before we do anything */ for (win = 0; win < fbdrv->variant.nr_windows; win++) @@ -1571,6 +1582,7 @@ static int s3c_fb_resume(struct device *dev) struct s3c_fb_platdata *pd = sfb->pdata; struct s3c_fb_win *win; int win_no; + u32 reg; clk_enable(sfb->bus_clk); @@ -1581,6 +1593,14 @@ static int s3c_fb_resume(struct device *dev) pd->setup_gpio(); writel(pd->vidcon1, sfb->regs + VIDCON1); + /* set video clock running at under-run */ + if (sfb->variant.has_fixvclk) { + reg = readl(sfb->regs + VIDCON1); + reg &= ~VIDCON1_VCLK_MASK; + reg |= VIDCON1_VCLK_RUN; + writel(reg, sfb->regs + VIDCON1); + } + /* zero all windows before we do anything */ for (win_no = 0; win_no < sfb->variant.nr_windows; win_no++) s3c_fb_clear_win(sfb, win_no); @@ -1845,6 +1865,7 @@ static struct s3c_fb_driverdata s3c_fb_data_s5pv210 = { .has_shadowcon = 1, .has_blendcon = 1, .has_clksel = 1, + .has_fixvclk = 1, }, .win[0] = &s3c_fb_data_s5p_wins[0], .win[1] = &s3c_fb_data_s5p_wins[1], @@ -1876,6 +1897,7 @@ static struct s3c_fb_driverdata s3c_fb_data_exynos4 = { .has_shadowcon = 1, .has_blendcon = 1, + .has_fixvclk = 1, }, .win[0] = &s3c_fb_data_s5p_wins[0], .win[1] = &s3c_fb_data_s5p_wins[1], @@ -1941,6 +1963,7 @@ static struct s3c_fb_driverdata s3c_fb_data_s5p64x0 = { }, .has_blendcon = 1, + .has_fixvclk = 1, }, .win[0] = &s3c_fb_data_s5p_wins[0], .win[1] = &s3c_fb_data_s5p_wins[1], -- cgit v1.2.3-70-g09d2 From c6d242aa64d27ebd258a12aa0a5da068e25e01f5 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 27 Jan 2012 16:02:54 +0800 Subject: video: convert drivers/video/* to use module_spi_driver() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch converts the drivers in drivers/video/* to use the module_spi_driver() macro which makes the code smaller and a bit simpler. Signed-off-by: Axel Lin Cc: Imre Deak Cc: Roger Quadros Cc: Steve Sakoman Cc: Erik Gilling Cc: Gražvydas Ignotas Signed-off-by: Florian Tobias Schandinat --- drivers/video/omap/lcd_mipid.c | 14 +------------- drivers/video/omap2/displays/panel-acx565akm.c | 13 +------------ drivers/video/omap2/displays/panel-lgphilips-lb035q02.c | 12 +----------- drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c | 12 +----------- drivers/video/omap2/displays/panel-tpo-td043mtea1.c | 13 +------------ 5 files changed, 5 insertions(+), 59 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap/lcd_mipid.c b/drivers/video/omap/lcd_mipid.c index 8d546dd55e8..e3880c4a0bb 100644 --- a/drivers/video/omap/lcd_mipid.c +++ b/drivers/video/omap/lcd_mipid.c @@ -609,19 +609,7 @@ static struct spi_driver mipid_spi_driver = { .remove = __devexit_p(mipid_spi_remove), }; -static int __init mipid_drv_init(void) -{ - spi_register_driver(&mipid_spi_driver); - - return 0; -} -module_init(mipid_drv_init); - -static void __exit mipid_drv_cleanup(void) -{ - spi_unregister_driver(&mipid_spi_driver); -} -module_exit(mipid_drv_cleanup); +module_spi_driver(mipid_spi_driver); MODULE_DESCRIPTION("MIPI display driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c index 51a87e149e2..d26f37ac69d 100644 --- a/drivers/video/omap2/displays/panel-acx565akm.c +++ b/drivers/video/omap2/displays/panel-acx565akm.c @@ -809,18 +809,7 @@ static struct spi_driver acx565akm_spi_driver = { .remove = __devexit_p(acx565akm_spi_remove), }; -static int __init acx565akm_init(void) -{ - return spi_register_driver(&acx565akm_spi_driver); -} - -static void __exit acx565akm_exit(void) -{ - spi_unregister_driver(&acx565akm_spi_driver); -} - -module_init(acx565akm_init); -module_exit(acx565akm_exit); +module_spi_driver(acx565akm_spi_driver); MODULE_AUTHOR("Nokia Corporation"); MODULE_DESCRIPTION("acx565akm LCD Driver"); diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c index e0eb35be303..0841cc2b3f7 100644 --- a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c +++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c @@ -264,16 +264,6 @@ static struct spi_driver lb035q02_spi_driver = { .remove = __devexit_p(lb035q02_panel_spi_remove), }; -static int __init lb035q02_panel_drv_init(void) -{ - return spi_register_driver(&lb035q02_spi_driver); -} - -static void __exit lb035q02_panel_drv_exit(void) -{ - spi_unregister_driver(&lb035q02_spi_driver); -} +module_spi_driver(lb035q02_spi_driver); -module_init(lb035q02_panel_drv_init); -module_exit(lb035q02_panel_drv_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c index 0eb31caddca..8b38b39213f 100644 --- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c +++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c @@ -350,18 +350,8 @@ static struct spi_driver nec_8048_spi_driver = { }, }; -static int __init nec_8048_lcd_init(void) -{ - return spi_register_driver(&nec_8048_spi_driver); -} - -static void __exit nec_8048_lcd_exit(void) -{ - return spi_unregister_driver(&nec_8048_spi_driver); -} +module_spi_driver(nec_8048_spi_driver); -module_init(nec_8048_lcd_init); -module_exit(nec_8048_lcd_exit); MODULE_AUTHOR("Erik Gilling "); MODULE_DESCRIPTION("NEC-nl8048hl11-01b Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c index 880c313d6bc..0ca9644f9ea 100644 --- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c +++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c @@ -511,18 +511,7 @@ static struct spi_driver tpo_td043_spi_driver = { .remove = __devexit_p(tpo_td043_spi_remove), }; -static int __init tpo_td043_init(void) -{ - return spi_register_driver(&tpo_td043_spi_driver); -} - -static void __exit tpo_td043_exit(void) -{ - spi_unregister_driver(&tpo_td043_spi_driver); -} - -module_init(tpo_td043_init); -module_exit(tpo_td043_exit); +module_spi_driver(tpo_td043_spi_driver); MODULE_AUTHOR("Gražvydas Ignotas "); MODULE_DESCRIPTION("TPO TD043MTEA1 LCD Driver"); -- cgit v1.2.3-70-g09d2 From b6daa025b1e1aebf276508eb2a5a9f730391aa84 Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Fri, 6 Jan 2012 14:41:31 -0600 Subject: drm/i915: set AUD_CONFIG N_value_index for DisplayPort It should be programmed to "0" for HDMI or "1" for DisplayPort. This enables DisplayPort audio for - HP EliteBook 8460p (whose BIOS does not set the N_value_index bit for us) - DisplayPort monitor hot plugged after boot (otherwise most BIOS will fill the N_value_index bit for us) Tested-by: Robert Lemaire Reviewed-by: Keith Packard Signed-off-by: Wu Fengguang Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 12 ++++++++++++ drivers/gpu/drm/i915/intel_display.c | 8 +++++++- 2 files changed, 19 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index bbad7885348..f4daa6e60b6 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3742,4 +3742,16 @@ */ #define GEN7_SO_WRITE_OFFSET(n) (0x5280 + (n) * 4) +#define IBX_AUD_CONFIG_A 0xe2000 +#define CPT_AUD_CONFIG_A 0xe5000 +#define AUD_CONFIG_N_VALUE_INDEX (1 << 29) +#define AUD_CONFIG_N_PROG_ENABLE (1 << 28) +#define AUD_CONFIG_UPPER_N_SHIFT 20 +#define AUD_CONFIG_UPPER_N_VALUE (0xff << 20) +#define AUD_CONFIG_LOWER_N_SHIFT 4 +#define AUD_CONFIG_LOWER_N_VALUE (0xfff << 4) +#define AUD_CONFIG_PIXEL_CLOCK_HDMI_SHIFT 16 +#define AUD_CONFIG_PIXEL_CLOCK_HDMI (0xf << 16) +#define AUD_CONFIG_DISABLE_NCTS (1 << 3) + #endif /* _I915_REG_H_ */ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ebb34524490..0770671fa8a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6141,15 +6141,18 @@ static void ironlake_write_eld(struct drm_connector *connector, uint32_t i; int len; int hdmiw_hdmiedid; + int aud_config; int aud_cntl_st; int aud_cntrl_st2; if (HAS_PCH_IBX(connector->dev)) { hdmiw_hdmiedid = IBX_HDMIW_HDMIEDID_A; + aud_config = IBX_AUD_CONFIG_A; aud_cntl_st = IBX_AUD_CNTL_ST_A; aud_cntrl_st2 = IBX_AUD_CNTL_ST2; } else { hdmiw_hdmiedid = CPT_HDMIW_HDMIEDID_A; + aud_config = CPT_AUD_CONFIG_A; aud_cntl_st = CPT_AUD_CNTL_ST_A; aud_cntrl_st2 = CPT_AUD_CNTRL_ST2; } @@ -6157,6 +6160,7 @@ static void ironlake_write_eld(struct drm_connector *connector, i = to_intel_crtc(crtc)->pipe; hdmiw_hdmiedid += i * 0x100; aud_cntl_st += i * 0x100; + aud_config += i * 0x100; DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(i)); @@ -6176,7 +6180,9 @@ static void ironlake_write_eld(struct drm_connector *connector, if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n"); eld[5] |= (1 << 2); /* Conn_Type, 0x1 = DisplayPort */ - } + I915_WRITE(aud_config, AUD_CONFIG_N_VALUE_INDEX); /* 0x1 = DP */ + } else + I915_WRITE(aud_config, 0); if (intel_eld_uptodate(connector, aud_cntrl_st2, eldv, -- cgit v1.2.3-70-g09d2 From 96154f2faba540281073243d61108d1705d19c6d Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:00 +0100 Subject: drm/i915: switch ring->id to be a real id ... and add a helpr function for the places where we want a flag. This way we can use ring->id to index into arrays. v2: Resurrect the missing beautification-space Chris Wilson noted. I'm moving this space around because I'll reuse ring_str in the next patch. Reviewed-by: Chris Wilson Reviewed-by: Ben Widawsky Reviewed-by: Eugeni Dodonov Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 9 +++++---- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 4 ++-- drivers/gpu/drm/i915/i915_irq.c | 2 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 14 +++++++------- drivers/gpu/drm/i915/intel_ringbuffer.h | 20 ++++++++++---------- 5 files changed, 25 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 6c3be86274e..9c5db4edd68 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -669,9 +669,9 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) static const char *ring_str(int ring) { switch (ring) { - case RING_RENDER: return " render"; - case RING_BSD: return " bsd"; - case RING_BLT: return " blt"; + case RCS: return "render"; + case VCS: return "bsd"; + case BCS: return "blt"; default: return ""; } } @@ -714,7 +714,7 @@ static void print_error_buffers(struct seq_file *m, seq_printf(m, "%s [%d]:\n", name, count); while (count--) { - seq_printf(m, " %08x %8u %04x %04x %08x%s%s%s%s%s%s", + seq_printf(m, " %08x %8u %04x %04x %08x%s%s%s%s%s%s%s", err->gtt_offset, err->size, err->read_domains, @@ -724,6 +724,7 @@ static void print_error_buffers(struct seq_file *m, tiling_flag(err->tiling), dirty_flag(err->dirty), purgeable_flag(err->purgeable), + err->ring != -1 ? " " : "", ring_str(err->ring), cache_level_str(err->cache_level)); diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index c649e0f255b..49b3ebc0e7a 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -203,9 +203,9 @@ i915_gem_object_set_to_gpu_domain(struct drm_i915_gem_object *obj, cd->invalidate_domains |= invalidate_domains; cd->flush_domains |= flush_domains; if (flush_domains & I915_GEM_GPU_DOMAINS) - cd->flush_rings |= obj->ring->id; + cd->flush_rings |= intel_ring_flag(obj->ring); if (invalidate_domains & I915_GEM_GPU_DOMAINS) - cd->flush_rings |= ring->id; + cd->flush_rings |= intel_ring_flag(ring); } struct eb_objects { diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 275ab6fecbd..ab53edb9f29 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -804,7 +804,7 @@ static u32 capture_bo_list(struct drm_i915_error_buffer *err, err->tiling = obj->tiling_mode; err->dirty = obj->dirty; err->purgeable = obj->madv != I915_MADV_WILLNEED; - err->ring = obj->ring ? obj->ring->id : 0; + err->ring = obj->ring ? obj->ring->id : -1; err->cache_level = obj->cache_level; if (++i == count) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index b3da17af899..48042f3b0ea 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -729,13 +729,13 @@ void intel_ring_setup_status_page(struct intel_ring_buffer *ring) */ if (IS_GEN7(dev)) { switch (ring->id) { - case RING_RENDER: + case RCS: mmio = RENDER_HWS_PGA_GEN7; break; - case RING_BLT: + case BCS: mmio = BLT_HWS_PGA_GEN7; break; - case RING_BSD: + case VCS: mmio = BSD_HWS_PGA_GEN7; break; } @@ -1199,7 +1199,7 @@ void intel_ring_advance(struct intel_ring_buffer *ring) static const struct intel_ring_buffer render_ring = { .name = "render ring", - .id = RING_RENDER, + .id = RCS, .mmio_base = RENDER_RING_BASE, .size = 32 * PAGE_SIZE, .init = init_render_ring, @@ -1222,7 +1222,7 @@ static const struct intel_ring_buffer render_ring = { static const struct intel_ring_buffer bsd_ring = { .name = "bsd ring", - .id = RING_BSD, + .id = VCS, .mmio_base = BSD_RING_BASE, .size = 32 * PAGE_SIZE, .init = init_ring_common, @@ -1332,7 +1332,7 @@ gen6_bsd_ring_put_irq(struct intel_ring_buffer *ring) /* ring buffer for Video Codec for Gen6+ */ static const struct intel_ring_buffer gen6_bsd_ring = { .name = "gen6 bsd ring", - .id = RING_BSD, + .id = VCS, .mmio_base = GEN6_BSD_RING_BASE, .size = 32 * PAGE_SIZE, .init = init_ring_common, @@ -1467,7 +1467,7 @@ static void blt_ring_cleanup(struct intel_ring_buffer *ring) static const struct intel_ring_buffer gen6_blt_ring = { .name = "blt ring", - .id = RING_BLT, + .id = BCS, .mmio_base = BLT_RING_BASE, .size = 32 * PAGE_SIZE, .init = blt_ring_init, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 68281c96c55..c8b9cc0cd0d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -1,13 +1,6 @@ #ifndef _INTEL_RINGBUFFER_H_ #define _INTEL_RINGBUFFER_H_ -enum { - RCS = 0x0, - VCS, - BCS, - I915_NUM_RINGS, -}; - struct intel_hw_status_page { u32 __iomem *page_addr; unsigned int gfx_addr; @@ -36,10 +29,11 @@ struct intel_hw_status_page { struct intel_ring_buffer { const char *name; enum intel_ring_id { - RING_RENDER = 0x1, - RING_BSD = 0x2, - RING_BLT = 0x4, + RCS = 0x0, + VCS, + BCS, } id; +#define I915_NUM_RINGS 3 u32 mmio_base; void __iomem *virtual_start; struct drm_device *dev; @@ -119,6 +113,12 @@ struct intel_ring_buffer { void *private; }; +static inline unsigned +intel_ring_flag(struct intel_ring_buffer *ring) +{ + return 1 << ring->id; +} + static inline u32 intel_ring_sync_index(struct intel_ring_buffer *ring, struct intel_ring_buffer *other) -- cgit v1.2.3-70-g09d2 From d27b1e0ec2a0a04770b2ebf70a2e01281ef93562 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:01 +0100 Subject: drm/i915: refactor ring error state capture to use arrays The code already got unwieldy and we want to dump more per-ring registers. Only functional change is that we now also capture the video ring registers on ilk. v2: fixup a refactor fumble spotted by Chris Wilson. Reviewed-by: Eugeni Dodonov Reviewed-by: Chris Wilson Signed-off-by: Ben Widawsky Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 55 +++++++++++++++-------------- drivers/gpu/drm/i915/i915_drv.h | 20 +++-------- drivers/gpu/drm/i915/i915_irq.c | 70 +++++++++++++++++++------------------ drivers/gpu/drm/i915/i915_reg.h | 11 ++---- 4 files changed, 73 insertions(+), 83 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 9c5db4edd68..4002846d56a 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -738,6 +738,26 @@ static void print_error_buffers(struct seq_file *m, } } +static void i915_ring_error_state(struct seq_file *m, + struct drm_device *dev, + struct drm_i915_error_state *error, + unsigned ring) +{ + seq_printf(m, "%s command stream:\n", ring_str(ring)); + seq_printf(m, " ACTHD: 0x%08x\n", error->acthd[ring]); + seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir[ring]); + seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr[ring]); + seq_printf(m, " INSTDONE: 0x%08x\n", error->instdone[ring]); + if (ring == RCS) { + if (INTEL_INFO(dev)->gen >= 4) { + seq_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1); + seq_printf(m, " INSTPS: 0x%08x\n", error->instps); + } + seq_printf(m, " INSTPM: 0x%08x\n", error->instpm); + } + seq_printf(m, " seqno: 0x%08x\n", error->seqno[ring]); +} + static int i915_error_state(struct seq_file *m, void *unused) { struct drm_info_node *node = (struct drm_info_node *) m->private; @@ -760,36 +780,19 @@ static int i915_error_state(struct seq_file *m, void *unused) seq_printf(m, "PCI ID: 0x%04x\n", dev->pci_device); seq_printf(m, "EIR: 0x%08x\n", error->eir); seq_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er); - if (INTEL_INFO(dev)->gen >= 6) { - seq_printf(m, "ERROR: 0x%08x\n", error->error); - seq_printf(m, "Blitter command stream:\n"); - seq_printf(m, " ACTHD: 0x%08x\n", error->bcs_acthd); - seq_printf(m, " IPEIR: 0x%08x\n", error->bcs_ipeir); - seq_printf(m, " IPEHR: 0x%08x\n", error->bcs_ipehr); - seq_printf(m, " INSTDONE: 0x%08x\n", error->bcs_instdone); - seq_printf(m, " seqno: 0x%08x\n", error->bcs_seqno); - seq_printf(m, "Video (BSD) command stream:\n"); - seq_printf(m, " ACTHD: 0x%08x\n", error->vcs_acthd); - seq_printf(m, " IPEIR: 0x%08x\n", error->vcs_ipeir); - seq_printf(m, " IPEHR: 0x%08x\n", error->vcs_ipehr); - seq_printf(m, " INSTDONE: 0x%08x\n", error->vcs_instdone); - seq_printf(m, " seqno: 0x%08x\n", error->vcs_seqno); - } - seq_printf(m, "Render command stream:\n"); - seq_printf(m, " ACTHD: 0x%08x\n", error->acthd); - seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir); - seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr); - seq_printf(m, " INSTDONE: 0x%08x\n", error->instdone); - if (INTEL_INFO(dev)->gen >= 4) { - seq_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1); - seq_printf(m, " INSTPS: 0x%08x\n", error->instps); - } - seq_printf(m, " INSTPM: 0x%08x\n", error->instpm); - seq_printf(m, " seqno: 0x%08x\n", error->seqno); for (i = 0; i < dev_priv->num_fence_regs; i++) seq_printf(m, " fence[%d] = %08llx\n", i, error->fence[i]); + if (INTEL_INFO(dev)->gen >= 6) + seq_printf(m, "ERROR: 0x%08x\n", error->error); + + i915_ring_error_state(m, dev, error, RCS); + if (HAS_BLT(dev)) + i915_ring_error_state(m, dev, error, BCS); + if (HAS_BSD(dev)) + i915_ring_error_state(m, dev, error, VCS); + if (error->active_bo) print_error_buffers(m, "Active", error->active_bo, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 1d10b8c26c9..766ef1c10ce 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -152,25 +152,15 @@ struct drm_i915_error_state { u32 eir; u32 pgtbl_er; u32 pipestat[I915_MAX_PIPES]; - u32 ipeir; - u32 ipehr; - u32 instdone; - u32 acthd; + u32 ipeir[I915_NUM_RINGS]; + u32 ipehr[I915_NUM_RINGS]; + u32 instdone[I915_NUM_RINGS]; + u32 acthd[I915_NUM_RINGS]; u32 error; /* gen6+ */ - u32 bcs_acthd; /* gen6+ blt engine */ - u32 bcs_ipehr; - u32 bcs_ipeir; - u32 bcs_instdone; - u32 bcs_seqno; - u32 vcs_acthd; /* gen6+ bsd engine */ - u32 vcs_ipehr; - u32 vcs_ipeir; - u32 vcs_instdone; - u32 vcs_seqno; u32 instpm; u32 instps; u32 instdone1; - u32 seqno; + u32 seqno[I915_NUM_RINGS]; u64 bbaddr; u64 fence[I915_MAX_NUM_FENCES]; struct timeval time; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index ab53edb9f29..dffeef870b3 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -876,6 +876,32 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv, return NULL; } +static void i915_record_ring_state(struct drm_device *dev, + struct drm_i915_error_state *error, + struct intel_ring_buffer *ring) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + if (INTEL_INFO(dev)->gen >= 4) { + error->ipeir[ring->id] = I915_READ(RING_IPEIR(ring->mmio_base)); + error->ipehr[ring->id] = I915_READ(RING_IPEHR(ring->mmio_base)); + error->instdone[ring->id] = I915_READ(RING_INSTDONE(ring->mmio_base)); + if (ring->id == RCS) { + error->instps = I915_READ(INSTPS); + error->instdone1 = I915_READ(INSTDONE1); + error->bbaddr = I915_READ64(BB_ADDR); + } + } else { + error->ipeir[ring->id] = I915_READ(IPEIR); + error->ipehr[ring->id] = I915_READ(IPEHR); + error->instdone[ring->id] = I915_READ(INSTDONE); + error->bbaddr = 0; + } + + error->seqno[ring->id] = ring->get_seqno(ring); + error->acthd[ring->id] = intel_ring_get_active_head(ring); +} + /** * i915_capture_error_state - capture an error record for later analysis * @dev: drm device @@ -909,47 +935,23 @@ static void i915_capture_error_state(struct drm_device *dev) DRM_INFO("capturing error event; look for more information in /debug/dri/%d/i915_error_state\n", dev->primary->index); - error->seqno = dev_priv->ring[RCS].get_seqno(&dev_priv->ring[RCS]); error->eir = I915_READ(EIR); error->pgtbl_er = I915_READ(PGTBL_ER); for_each_pipe(pipe) error->pipestat[pipe] = I915_READ(PIPESTAT(pipe)); error->instpm = I915_READ(INSTPM); - error->error = 0; - if (INTEL_INFO(dev)->gen >= 6) { + + if (INTEL_INFO(dev)->gen >= 6) error->error = I915_READ(ERROR_GEN6); + else + error->error = 0; + + i915_record_ring_state(dev, error, &dev_priv->ring[RCS]); + if (HAS_BLT(dev)) + i915_record_ring_state(dev, error, &dev_priv->ring[BCS]); + if (HAS_BSD(dev)) + i915_record_ring_state(dev, error, &dev_priv->ring[VCS]); - error->bcs_acthd = I915_READ(BCS_ACTHD); - error->bcs_ipehr = I915_READ(BCS_IPEHR); - error->bcs_ipeir = I915_READ(BCS_IPEIR); - error->bcs_instdone = I915_READ(BCS_INSTDONE); - error->bcs_seqno = 0; - if (dev_priv->ring[BCS].get_seqno) - error->bcs_seqno = dev_priv->ring[BCS].get_seqno(&dev_priv->ring[BCS]); - - error->vcs_acthd = I915_READ(VCS_ACTHD); - error->vcs_ipehr = I915_READ(VCS_IPEHR); - error->vcs_ipeir = I915_READ(VCS_IPEIR); - error->vcs_instdone = I915_READ(VCS_INSTDONE); - error->vcs_seqno = 0; - if (dev_priv->ring[VCS].get_seqno) - error->vcs_seqno = dev_priv->ring[VCS].get_seqno(&dev_priv->ring[VCS]); - } - if (INTEL_INFO(dev)->gen >= 4) { - error->ipeir = I915_READ(IPEIR_I965); - error->ipehr = I915_READ(IPEHR_I965); - error->instdone = I915_READ(INSTDONE_I965); - error->instps = I915_READ(INSTPS); - error->instdone1 = I915_READ(INSTDONE1); - error->acthd = I915_READ(ACTHD_I965); - error->bbaddr = I915_READ64(BB_ADDR); - } else { - error->ipeir = I915_READ(IPEIR); - error->ipehr = I915_READ(IPEHR); - error->instdone = I915_READ(INSTDONE); - error->acthd = I915_READ(ACTHD); - error->bbaddr = 0; - } i915_gem_record_fences(dev, error); /* Record the active batch and ring buffers */ diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f4daa6e60b6..80febc55a0c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -352,6 +352,9 @@ #define IPEIR_I965 0x02064 #define IPEHR_I965 0x02068 #define INSTDONE_I965 0x0206c +#define RING_IPEIR(base) ((base)+0x64) +#define RING_IPEHR(base) ((base)+0x68) +#define RING_INSTDONE(base) ((base)+0x6c) #define INSTPS 0x02070 /* 965+ only */ #define INSTDONE1 0x0207c /* 965+ only */ #define ACTHD_I965 0x02074 @@ -365,14 +368,6 @@ #define INSTDONE 0x02090 #define NOPID 0x02094 #define HWSTAM 0x02098 -#define VCS_INSTDONE 0x1206C -#define VCS_IPEIR 0x12064 -#define VCS_IPEHR 0x12068 -#define VCS_ACTHD 0x12074 -#define BCS_INSTDONE 0x2206C -#define BCS_IPEIR 0x22064 -#define BCS_IPEHR 0x22068 -#define BCS_ACTHD 0x22074 #define ERROR_GEN6 0x040a0 -- cgit v1.2.3-70-g09d2 From c1cd90ed7957d1dd8aa6138468d71003fbc095ce Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:02 +0100 Subject: drm/i915: collect more per ring error state Based on a patch by Ben Widawsky, but with different colors for the bikeshed. In contrast to Ben's patch this one doesn't add the fault regs. Afaics they're for the optional page fault support which - we're not enabling - and which seems to be unsupported by the hw team. Recent bspec lacks tons of information about this that the public docs released half a year back still contain. Also dump ring HEAD/TAIL registers - I've recently seen a few error_state where just guessing these is not good enough. v2: Also dump INSTPM for every ring. v3: Fix a few really silly goof-ups spotted by Chris Wilson. Reviewed-by: Eugeni Dodonov Reviewed-by: Chris Wilson Signed-off-by: Ben Widawsky Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 16 ++++++++++------ drivers/gpu/drm/i915/i915_drv.h | 7 +++++-- drivers/gpu/drm/i915/i915_irq.c | 9 +++++++-- drivers/gpu/drm/i915/i915_reg.h | 3 +++ 4 files changed, 25 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 4002846d56a..5aa256861df 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -744,17 +744,21 @@ static void i915_ring_error_state(struct seq_file *m, unsigned ring) { seq_printf(m, "%s command stream:\n", ring_str(ring)); + seq_printf(m, " HEAD: 0x%08x\n", error->head[ring]); + seq_printf(m, " TAIL: 0x%08x\n", error->tail[ring]); seq_printf(m, " ACTHD: 0x%08x\n", error->acthd[ring]); seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir[ring]); seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr[ring]); seq_printf(m, " INSTDONE: 0x%08x\n", error->instdone[ring]); - if (ring == RCS) { - if (INTEL_INFO(dev)->gen >= 4) { - seq_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1); - seq_printf(m, " INSTPS: 0x%08x\n", error->instps); - } - seq_printf(m, " INSTPM: 0x%08x\n", error->instpm); + if (ring == RCS && INTEL_INFO(dev)->gen >= 4) { + seq_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1); + seq_printf(m, " BBADDR: 0x%08llx\n", error->bbaddr); } + if (INTEL_INFO(dev)->gen >= 4) + seq_printf(m, " INSTPS: 0x%08x\n", error->instps[ring]); + seq_printf(m, " INSTPM: 0x%08x\n", error->instpm[ring]); + if (INTEL_INFO(dev)->gen >= 6) + seq_printf(m, " FADDR: 0x%08x\n", error->faddr[ring]); seq_printf(m, " seqno: 0x%08x\n", error->seqno[ring]); } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 766ef1c10ce..733f5f57bab 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -152,16 +152,19 @@ struct drm_i915_error_state { u32 eir; u32 pgtbl_er; u32 pipestat[I915_MAX_PIPES]; + u32 tail[I915_NUM_RINGS]; + u32 head[I915_NUM_RINGS]; u32 ipeir[I915_NUM_RINGS]; u32 ipehr[I915_NUM_RINGS]; u32 instdone[I915_NUM_RINGS]; u32 acthd[I915_NUM_RINGS]; u32 error; /* gen6+ */ - u32 instpm; - u32 instps; + u32 instpm[I915_NUM_RINGS]; + u32 instps[I915_NUM_RINGS]; u32 instdone1; u32 seqno[I915_NUM_RINGS]; u64 bbaddr; + u32 faddr[I915_NUM_RINGS]; u64 fence[I915_MAX_NUM_FENCES]; struct timeval time; struct drm_i915_error_object { diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index dffeef870b3..1e75c44af56 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -882,12 +882,15 @@ static void i915_record_ring_state(struct drm_device *dev, { struct drm_i915_private *dev_priv = dev->dev_private; + if (INTEL_INFO(dev)->gen >= 6) + error->faddr[ring->id] = I915_READ(RING_DMA_FADD(ring->mmio_base)); + if (INTEL_INFO(dev)->gen >= 4) { error->ipeir[ring->id] = I915_READ(RING_IPEIR(ring->mmio_base)); error->ipehr[ring->id] = I915_READ(RING_IPEHR(ring->mmio_base)); error->instdone[ring->id] = I915_READ(RING_INSTDONE(ring->mmio_base)); + error->instps[ring->id] = I915_READ(RING_INSTPS(ring->mmio_base)); if (ring->id == RCS) { - error->instps = I915_READ(INSTPS); error->instdone1 = I915_READ(INSTDONE1); error->bbaddr = I915_READ64(BB_ADDR); } @@ -898,8 +901,11 @@ static void i915_record_ring_state(struct drm_device *dev, error->bbaddr = 0; } + error->instpm[ring->id] = I915_READ(RING_INSTPM(ring->mmio_base)); error->seqno[ring->id] = ring->get_seqno(ring); error->acthd[ring->id] = intel_ring_get_active_head(ring); + error->head[ring->id] = I915_READ_HEAD(ring); + error->tail[ring->id] = I915_READ_TAIL(ring); } /** @@ -939,7 +945,6 @@ static void i915_capture_error_state(struct drm_device *dev) error->pgtbl_er = I915_READ(PGTBL_ER); for_each_pipe(pipe) error->pipestat[pipe] = I915_READ(PIPESTAT(pipe)); - error->instpm = I915_READ(INSTPM); if (INTEL_INFO(dev)->gen >= 6) error->error = I915_READ(ERROR_GEN6); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 80febc55a0c..d107a1d756a 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -355,6 +355,9 @@ #define RING_IPEIR(base) ((base)+0x64) #define RING_IPEHR(base) ((base)+0x68) #define RING_INSTDONE(base) ((base)+0x6c) +#define RING_INSTPS(base) ((base)+0x70) +#define RING_DMA_FADD(base) ((base)+0x78) +#define RING_INSTPM(base) ((base)+0xc0) #define INSTPS 0x02070 /* 965+ only */ #define INSTDONE1 0x0207c /* 965+ only */ #define ACTHD_I965 0x02074 -- cgit v1.2.3-70-g09d2 From 6a233c78878d8795517d716544d045d5675b3061 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:07 +0100 Subject: drm/i915/ringbuffer: kill snb blt workaround This was just to facilitate product enablement with pre-production hw. Allows us to kill quite a bit of cruft. Signed-off-by: Kenneth Graunke Reviewed-by: Eric Anholt Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ringbuffer.c | 81 +-------------------------------- 1 file changed, 2 insertions(+), 79 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 48042f3b0ea..6e80f836835 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1368,79 +1368,13 @@ blt_ring_put_irq(struct intel_ring_buffer *ring) GEN6_BLITTER_USER_INTERRUPT); } - -/* Workaround for some stepping of SNB, - * each time when BLT engine ring tail moved, - * the first command in the ring to be parsed - * should be MI_BATCH_BUFFER_START - */ -#define NEED_BLT_WORKAROUND(dev) \ - (IS_GEN6(dev) && (dev->pdev->revision < 8)) - -static inline struct drm_i915_gem_object * -to_blt_workaround(struct intel_ring_buffer *ring) -{ - return ring->private; -} - -static int blt_ring_init(struct intel_ring_buffer *ring) -{ - if (NEED_BLT_WORKAROUND(ring->dev)) { - struct drm_i915_gem_object *obj; - u32 *ptr; - int ret; - - obj = i915_gem_alloc_object(ring->dev, 4096); - if (obj == NULL) - return -ENOMEM; - - ret = i915_gem_object_pin(obj, 4096, true); - if (ret) { - drm_gem_object_unreference(&obj->base); - return ret; - } - - ptr = kmap(obj->pages[0]); - *ptr++ = MI_BATCH_BUFFER_END; - *ptr++ = MI_NOOP; - kunmap(obj->pages[0]); - - ret = i915_gem_object_set_to_gtt_domain(obj, false); - if (ret) { - i915_gem_object_unpin(obj); - drm_gem_object_unreference(&obj->base); - return ret; - } - - ring->private = obj; - } - - return init_ring_common(ring); -} - -static int blt_ring_begin(struct intel_ring_buffer *ring, - int num_dwords) -{ - if (ring->private) { - int ret = intel_ring_begin(ring, num_dwords+2); - if (ret) - return ret; - - intel_ring_emit(ring, MI_BATCH_BUFFER_START); - intel_ring_emit(ring, to_blt_workaround(ring)->gtt_offset); - - return 0; - } else - return intel_ring_begin(ring, 4); -} - static int blt_ring_flush(struct intel_ring_buffer *ring, u32 invalidate, u32 flush) { uint32_t cmd; int ret; - ret = blt_ring_begin(ring, 4); + ret = intel_ring_begin(ring, 4); if (ret) return ret; @@ -1455,22 +1389,12 @@ static int blt_ring_flush(struct intel_ring_buffer *ring, return 0; } -static void blt_ring_cleanup(struct intel_ring_buffer *ring) -{ - if (!ring->private) - return; - - i915_gem_object_unpin(ring->private); - drm_gem_object_unreference(ring->private); - ring->private = NULL; -} - static const struct intel_ring_buffer gen6_blt_ring = { .name = "blt ring", .id = BCS, .mmio_base = BLT_RING_BASE, .size = 32 * PAGE_SIZE, - .init = blt_ring_init, + .init = init_ring_common, .write_tail = ring_write_tail, .flush = blt_ring_flush, .add_request = gen6_add_request, @@ -1478,7 +1402,6 @@ static const struct intel_ring_buffer gen6_blt_ring = { .irq_get = blt_ring_get_irq, .irq_put = blt_ring_put_irq, .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, - .cleanup = blt_ring_cleanup, .sync_to = gen6_blt_ring_sync_to, .semaphore_register = {MI_SEMAPHORE_SYNC_BR, MI_SEMAPHORE_SYNC_BV, -- cgit v1.2.3-70-g09d2 From 1690e1eb7a9021826853e181baa48dd77090da28 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 14 Dec 2011 13:57:08 +0100 Subject: drm/i915: Separate fence pin counting from normal bind pin counting In order to correctly account for reserving space in the GTT and fences for a batch buffer, we need to independently track whether the fence is pinned due to a fenced GPU access in the batch or whether the buffer is pinned in the aperture. Currently we count the fenced as pinned if the buffer has already been seen in the execbuffer. This leads to a false accounting of available fence registers, causing frequent mass evictions. Worse, if coupled with the change to make i915_gem_object_get_fence() report EDADLK upon fence starvation, the batchbuffer can fail with only one fence required... Fixes intel-gpu-tools/tests/gem_fenced_exec_thrash Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=38735 Signed-off-by: Chris Wilson Reviewed-by: Daniel Vetter Tested-by: Paul Neumann [danvet: Resolve the functional conflict with Jesse Barnes sprite patches, acked by Chris Wilson on irc.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 19 ++++ drivers/gpu/drm/i915/i915_gem.c | 7 +- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 139 +++++++++++++++++++---------- drivers/gpu/drm/i915/intel_display.c | 16 +++- drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_sprite.c | 4 +- 6 files changed, 129 insertions(+), 57 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 733f5f57bab..12e8cce7928 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -135,6 +135,7 @@ struct drm_i915_fence_reg { struct list_head lru_list; struct drm_i915_gem_object *obj; uint32_t setup_seqno; + int pin_count; }; struct sdvo_device_mapping { @@ -1159,6 +1160,24 @@ int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj, struct intel_ring_buffer *pipelined); int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj); +static inline void +i915_gem_object_pin_fence(struct drm_i915_gem_object *obj) +{ + if (obj->fence_reg != I915_FENCE_REG_NONE) { + struct drm_i915_private *dev_priv = obj->base.dev->dev_private; + dev_priv->fence_regs[obj->fence_reg].pin_count++; + } +} + +static inline void +i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj) +{ + if (obj->fence_reg != I915_FENCE_REG_NONE) { + struct drm_i915_private *dev_priv = obj->base.dev->dev_private; + dev_priv->fence_regs[obj->fence_reg].pin_count--; + } +} + void i915_gem_retire_requests(struct drm_device *dev); void i915_gem_reset(struct drm_device *dev); void i915_gem_clflush_object(struct drm_i915_gem_object *obj); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index ff3066c4c76..c78930ed2e8 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2435,6 +2435,8 @@ i915_gem_object_put_fence(struct drm_i915_gem_object *obj) if (obj->fence_reg != I915_FENCE_REG_NONE) { struct drm_i915_private *dev_priv = obj->base.dev->dev_private; + + WARN_ON(dev_priv->fence_regs[obj->fence_reg].pin_count); i915_gem_clear_fence_reg(obj->base.dev, &dev_priv->fence_regs[obj->fence_reg]); @@ -2459,7 +2461,7 @@ i915_find_fence_reg(struct drm_device *dev, if (!reg->obj) return reg; - if (!reg->obj->pin_count) + if (!reg->pin_count) avail = reg; } @@ -2469,7 +2471,7 @@ i915_find_fence_reg(struct drm_device *dev, /* None available, try to steal one or wait for a user to finish */ avail = first = NULL; list_for_each_entry(reg, &dev_priv->mm.fence_list, lru_list) { - if (reg->obj->pin_count) + if (reg->pin_count) continue; if (first == NULL) @@ -2664,6 +2666,7 @@ i915_gem_clear_fence_reg(struct drm_device *dev, list_del_init(®->lru_list); reg->obj = NULL; reg->setup_seqno = 0; + reg->pin_count = 0; } /** diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 49b3ebc0e7a..4a43ef5dba3 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -461,6 +461,54 @@ i915_gem_execbuffer_relocate(struct drm_device *dev, return ret; } +#define __EXEC_OBJECT_HAS_FENCE (1<<31) + +static int +pin_and_fence_object(struct drm_i915_gem_object *obj, + struct intel_ring_buffer *ring) +{ + struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; + bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4; + bool need_fence, need_mappable; + int ret; + + need_fence = + has_fenced_gpu_access && + entry->flags & EXEC_OBJECT_NEEDS_FENCE && + obj->tiling_mode != I915_TILING_NONE; + need_mappable = + entry->relocation_count ? true : need_fence; + + ret = i915_gem_object_pin(obj, entry->alignment, need_mappable); + if (ret) + return ret; + + if (has_fenced_gpu_access) { + if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) { + if (obj->tiling_mode) { + ret = i915_gem_object_get_fence(obj, ring); + if (ret) + goto err_unpin; + + entry->flags |= __EXEC_OBJECT_HAS_FENCE; + i915_gem_object_pin_fence(obj); + } else { + ret = i915_gem_object_put_fence(obj); + if (ret) + goto err_unpin; + } + } + obj->pending_fenced_gpu_access = need_fence; + } + + entry->offset = obj->gtt_offset; + return 0; + +err_unpin: + i915_gem_object_unpin(obj); + return ret; +} + static int i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, struct drm_file *file, @@ -518,6 +566,7 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, list_for_each_entry(obj, objects, exec_list) { struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; bool need_fence, need_mappable; + if (!obj->gtt_space) continue; @@ -532,58 +581,47 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, (need_mappable && !obj->map_and_fenceable)) ret = i915_gem_object_unbind(obj); else - ret = i915_gem_object_pin(obj, - entry->alignment, - need_mappable); + ret = pin_and_fence_object(obj, ring); if (ret) goto err; - - entry++; } /* Bind fresh objects */ list_for_each_entry(obj, objects, exec_list) { - struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; - bool need_fence; - - need_fence = - has_fenced_gpu_access && - entry->flags & EXEC_OBJECT_NEEDS_FENCE && - obj->tiling_mode != I915_TILING_NONE; - - if (!obj->gtt_space) { - bool need_mappable = - entry->relocation_count ? true : need_fence; - - ret = i915_gem_object_pin(obj, - entry->alignment, - need_mappable); - if (ret) - break; - } + if (obj->gtt_space) + continue; - if (has_fenced_gpu_access) { - if (need_fence) { - ret = i915_gem_object_get_fence(obj, ring); - if (ret) - break; - } else if (entry->flags & EXEC_OBJECT_NEEDS_FENCE && - obj->tiling_mode == I915_TILING_NONE) { - /* XXX pipelined! */ - ret = i915_gem_object_put_fence(obj); - if (ret) - break; - } - obj->pending_fenced_gpu_access = need_fence; + ret = pin_and_fence_object(obj, ring); + if (ret) { + int ret_ignore; + + /* This can potentially raise a harmless + * -EINVAL if we failed to bind in the above + * call. It cannot raise -EINTR since we know + * that the bo is freshly bound and so will + * not need to be flushed or waited upon. + */ + ret_ignore = i915_gem_object_unbind(obj); + (void)ret_ignore; + WARN_ON(obj->gtt_space); + break; } - - entry->offset = obj->gtt_offset; } /* Decrement pin count for bound objects */ list_for_each_entry(obj, objects, exec_list) { - if (obj->gtt_space) - i915_gem_object_unpin(obj); + struct drm_i915_gem_exec_object2 *entry; + + if (!obj->gtt_space) + continue; + + entry = obj->exec_entry; + if (entry->flags & __EXEC_OBJECT_HAS_FENCE) { + i915_gem_object_unpin_fence(obj); + entry->flags &= ~__EXEC_OBJECT_HAS_FENCE; + } + + i915_gem_object_unpin(obj); } if (ret != -ENOSPC || retry > 1) @@ -600,16 +638,19 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, } while (1); err: - obj = list_entry(obj->exec_list.prev, - struct drm_i915_gem_object, - exec_list); - while (objects != &obj->exec_list) { - if (obj->gtt_space) - i915_gem_object_unpin(obj); + list_for_each_entry_continue_reverse(obj, objects, exec_list) { + struct drm_i915_gem_exec_object2 *entry; + + if (!obj->gtt_space) + continue; + + entry = obj->exec_entry; + if (entry->flags & __EXEC_OBJECT_HAS_FENCE) { + i915_gem_object_unpin_fence(obj); + entry->flags &= ~__EXEC_OBJECT_HAS_FENCE; + } - obj = list_entry(obj->exec_list.prev, - struct drm_i915_gem_object, - exec_list); + i915_gem_object_unpin(obj); } return ret; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0770671fa8a..fc9bc19f6db 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2041,6 +2041,8 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, ret = i915_gem_object_get_fence(obj, pipelined); if (ret) goto err_unpin; + + i915_gem_object_pin_fence(obj); } dev_priv->mm.interruptible = true; @@ -2053,6 +2055,12 @@ err_interruptible: return ret; } +void intel_unpin_fb_obj(struct drm_i915_gem_object *obj) +{ + i915_gem_object_unpin_fence(obj); + i915_gem_object_unpin(obj); +} + static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb, int x, int y) { @@ -2284,7 +2292,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y, LEAVE_ATOMIC_MODE_SET); if (ret) { - i915_gem_object_unpin(to_intel_framebuffer(crtc->fb)->obj); + intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj); mutex_unlock(&dev->struct_mutex); DRM_ERROR("failed to update base address\n"); return ret; @@ -2292,7 +2300,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, if (old_fb) { intel_wait_for_vblank(dev, intel_crtc->pipe); - i915_gem_object_unpin(to_intel_framebuffer(old_fb)->obj); + intel_unpin_fb_obj(to_intel_framebuffer(old_fb)->obj); } mutex_unlock(&dev->struct_mutex); @@ -3355,7 +3363,7 @@ static void intel_crtc_disable(struct drm_crtc *crtc) if (crtc->fb) { mutex_lock(&dev->struct_mutex); - i915_gem_object_unpin(to_intel_framebuffer(crtc->fb)->obj); + intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj); mutex_unlock(&dev->struct_mutex); } } @@ -7158,7 +7166,7 @@ static void intel_unpin_work_fn(struct work_struct *__work) container_of(__work, struct intel_unpin_work, work); mutex_lock(&work->dev->struct_mutex); - i915_gem_object_unpin(work->old_fb_obj); + intel_unpin_fb_obj(work->old_fb_obj); drm_gem_object_unreference(&work->pending_flip_obj->base); drm_gem_object_unreference(&work->old_fb_obj->base); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 1348705faf6..9cec6c3937f 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -374,6 +374,7 @@ extern void intel_init_emon(struct drm_device *dev); extern int intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_i915_gem_object *obj, struct intel_ring_buffer *pipelined); +extern void intel_unpin_fb_obj(struct drm_i915_gem_object *obj); extern int intel_framebuffer_init(struct drm_device *dev, struct intel_framebuffer *ifb, diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index d13989fda50..ad3bd929aec 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -503,7 +503,7 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe); mutex_lock(&dev->struct_mutex); } - i915_gem_object_unpin(old_obj); + intel_unpin_fb_obj(old_obj); } out_unlock: @@ -530,7 +530,7 @@ intel_disable_plane(struct drm_plane *plane) goto out; mutex_lock(&dev->struct_mutex); - i915_gem_object_unpin(intel_plane->obj); + intel_unpin_fb_obj(intel_plane->obj); intel_plane->obj = NULL; mutex_unlock(&dev->struct_mutex); out: -- cgit v1.2.3-70-g09d2 From 39965b376601314ba374b8fa3944f5957d4ff2de Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:09 +0100 Subject: drm/i915: don't trash the gtt when running out of fences With the fence accounting fixed up in the previous commit not finding enough fences is a fatal error and userspace bug. Trashing the entire gtt is not gonna turn up that missing fence, so don't to this by returning another error thatn ENOSPC. This has the added benefit that it's easier to distinguish fence accounting errors from gtt space accounting issues. TTM serves as precendence for the EDEADLK error code - it returns it when the reservation code needs resources already blocked by the current reservation. Reviewed-by: Chris Wilson Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c78930ed2e8..721924150d0 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2566,7 +2566,7 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj, reg = i915_find_fence_reg(dev, pipelined); if (reg == NULL) - return -ENOSPC; + return -EDEADLK; ret = i915_gem_object_flush_fence(obj, pipelined); if (ret) -- cgit v1.2.3-70-g09d2 From 08e14e80d0229262063139a95209fa0dc354feaa Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:10 +0100 Subject: drm/i915: refactor debugfs open function Only forcewake has an open with special semantics, the other r/w debugfs only assign the file private pointer. Reviewed-by: Ben Widawsky Reviewed-by: Kenneth Graunke Reviewed-by: Chris Wilson Reviewed-by: Eugeni Dodonov Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 5aa256861df..37740429600 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1415,8 +1415,8 @@ static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data) } static int -i915_wedged_open(struct inode *inode, - struct file *filp) +i915_debugfs_common_open(struct inode *inode, + struct file *filp) { filp->private_data = inode->i_private; return 0; @@ -1472,20 +1472,12 @@ i915_wedged_write(struct file *filp, static const struct file_operations i915_wedged_fops = { .owner = THIS_MODULE, - .open = i915_wedged_open, + .open = i915_debugfs_common_open, .read = i915_wedged_read, .write = i915_wedged_write, .llseek = default_llseek, }; -static int -i915_max_freq_open(struct inode *inode, - struct file *filp) -{ - filp->private_data = inode->i_private; - return 0; -} - static ssize_t i915_max_freq_read(struct file *filp, char __user *ubuf, @@ -1542,20 +1534,12 @@ i915_max_freq_write(struct file *filp, static const struct file_operations i915_max_freq_fops = { .owner = THIS_MODULE, - .open = i915_max_freq_open, + .open = i915_debugfs_common_open, .read = i915_max_freq_read, .write = i915_max_freq_write, .llseek = default_llseek, }; -static int -i915_cache_sharing_open(struct inode *inode, - struct file *filp) -{ - filp->private_data = inode->i_private; - return 0; -} - static ssize_t i915_cache_sharing_read(struct file *filp, char __user *ubuf, @@ -1621,7 +1605,7 @@ i915_cache_sharing_write(struct file *filp, static const struct file_operations i915_cache_sharing_fops = { .owner = THIS_MODULE, - .open = i915_cache_sharing_open, + .open = i915_debugfs_common_open, .read = i915_cache_sharing_read, .write = i915_cache_sharing_write, .llseek = default_llseek, -- cgit v1.2.3-70-g09d2 From 6a9c308de0332b873720c629cb88f58d154b4f1d Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:11 +0100 Subject: drm/i915: refactor debugfs create functions All r/w debugfs files are created equal. v2: Add some newlines to make the code easier on the eyes as requested by Ben Widawsky. Reviewed-by: Ben Widawsky Reviewed-by: Kenneth Graunke Reviewed-by: Eugeni Dodonov Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 55 ++++++++++++------------------------- 1 file changed, 18 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 37740429600..9a2f3fcd220 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1637,21 +1637,6 @@ drm_add_fake_info_node(struct drm_minor *minor, return 0; } -static int i915_wedged_create(struct dentry *root, struct drm_minor *minor) -{ - struct drm_device *dev = minor->dev; - struct dentry *ent; - - ent = debugfs_create_file("i915_wedged", - S_IRUGO | S_IWUSR, - root, dev, - &i915_wedged_fops); - if (IS_ERR(ent)) - return PTR_ERR(ent); - - return drm_add_fake_info_node(minor, ent, &i915_wedged_fops); -} - static int i915_forcewake_open(struct inode *inode, struct file *file) { struct drm_device *dev = inode->i_private; @@ -1713,34 +1698,22 @@ static int i915_forcewake_create(struct dentry *root, struct drm_minor *minor) return drm_add_fake_info_node(minor, ent, &i915_forcewake_fops); } -static int i915_max_freq_create(struct dentry *root, struct drm_minor *minor) -{ - struct drm_device *dev = minor->dev; - struct dentry *ent; - - ent = debugfs_create_file("i915_max_freq", - S_IRUGO | S_IWUSR, - root, dev, - &i915_max_freq_fops); - if (IS_ERR(ent)) - return PTR_ERR(ent); - - return drm_add_fake_info_node(minor, ent, &i915_max_freq_fops); -} - -static int i915_cache_sharing_create(struct dentry *root, struct drm_minor *minor) +static int i915_debugfs_create(struct dentry *root, + struct drm_minor *minor, + const char *name, + const struct file_operations *fops) { struct drm_device *dev = minor->dev; struct dentry *ent; - ent = debugfs_create_file("i915_cache_sharing", + ent = debugfs_create_file(name, S_IRUGO | S_IWUSR, root, dev, - &i915_cache_sharing_fops); + fops); if (IS_ERR(ent)) return PTR_ERR(ent); - return drm_add_fake_info_node(minor, ent, &i915_cache_sharing_fops); + return drm_add_fake_info_node(minor, ent, fops); } static struct drm_info_list i915_debugfs_list[] = { @@ -1789,17 +1762,25 @@ int i915_debugfs_init(struct drm_minor *minor) { int ret; - ret = i915_wedged_create(minor->debugfs_root, minor); + ret = i915_debugfs_create(minor->debugfs_root, minor, + "i915_wedged", + &i915_wedged_fops); if (ret) return ret; ret = i915_forcewake_create(minor->debugfs_root, minor); if (ret) return ret; - ret = i915_max_freq_create(minor->debugfs_root, minor); + + ret = i915_debugfs_create(minor->debugfs_root, minor, + "i915_max_freq", + &i915_max_freq_fops); if (ret) return ret; - ret = i915_cache_sharing_create(minor->debugfs_root, minor); + + ret = i915_debugfs_create(minor->debugfs_root, minor, + "i915_cache_sharing", + &i915_cache_sharing_fops); if (ret) return ret; -- cgit v1.2.3-70-g09d2 From 653d7bed26a0c298dee7d60f6ab4bb442acf8b82 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:21 +0100 Subject: drm/i915: capture error_state also for stuck rings Since quite a while we also the basic output configuration in the error_state, so it should contain enough information to diagnose these MI_WAIT hangs. Reviewed-and-tested-by: Chris Wilson Reviewed-by: Eugeni Dodonov Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 1e75c44af56..4dedb314806 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1706,6 +1706,7 @@ void i915_hangcheck_elapsed(unsigned long data) dev_priv->last_instdone1 == instdone1) { if (dev_priv->hangcheck_count++ > 1) { DRM_ERROR("Hangcheck timer elapsed... GPU hung\n"); + i915_handle_error(dev, true); if (!IS_GEN2(dev)) { /* Is the chip hanging on a WAIT_FOR_EVENT? @@ -1713,7 +1714,6 @@ void i915_hangcheck_elapsed(unsigned long data) * and break the hang. This should work on * all but the second generation chipsets. */ - if (kick_ring(&dev_priv->ring[RCS])) goto repeat; @@ -1726,7 +1726,6 @@ void i915_hangcheck_elapsed(unsigned long data) goto repeat; } - i915_handle_error(dev, true); return; } } else { -- cgit v1.2.3-70-g09d2 From ff865f79764ca43bc601ff5a2499738451fc96dd Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:26 +0100 Subject: drm/i915: remove the i915_batchbuffer_info debugfs file With the error_state facility in place, this has outlived it's usefulness. It also oopses with the lates llc-reloc patches because it directly access objects through the gtt without any checks. Reviewed-by: Chris Wilson Reviewed-by: Eugeni Dodonov Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 40 ------------------------------------- 1 file changed, 40 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 9a2f3fcd220..f0486059e44 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -564,45 +564,6 @@ static int i915_hws_info(struct seq_file *m, void *data) return 0; } -static void i915_dump_object(struct seq_file *m, - struct io_mapping *mapping, - struct drm_i915_gem_object *obj) -{ - int page, page_count, i; - - page_count = obj->base.size / PAGE_SIZE; - for (page = 0; page < page_count; page++) { - u32 *mem = io_mapping_map_wc(mapping, - obj->gtt_offset + page * PAGE_SIZE); - for (i = 0; i < PAGE_SIZE; i += 4) - seq_printf(m, "%08x : %08x\n", i, mem[i / 4]); - io_mapping_unmap(mem); - } -} - -static int i915_batchbuffer_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj; - int ret; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) { - if (obj->base.read_domains & I915_GEM_DOMAIN_COMMAND) { - seq_printf(m, "--- gtt_offset = 0x%08x\n", obj->gtt_offset); - i915_dump_object(m, dev_priv->mm.gtt_mapping, obj); - } - } - - mutex_unlock(&dev->struct_mutex); - return 0; -} - static int i915_ringbuffer_data(struct seq_file *m, void *data) { struct drm_info_node *node = (struct drm_info_node *) m->private; @@ -1739,7 +1700,6 @@ static struct drm_info_list i915_debugfs_list[] = { {"i915_bsd_ringbuffer_info", i915_ringbuffer_info, 0, (void *)VCS}, {"i915_blt_ringbuffer_data", i915_ringbuffer_data, 0, (void *)BCS}, {"i915_blt_ringbuffer_info", i915_ringbuffer_info, 0, (void *)BCS}, - {"i915_batchbuffers", i915_batchbuffer_info, 0}, {"i915_error_state", i915_error_state, 0}, {"i915_rstdby_delays", i915_rstdby_delays, 0}, {"i915_cur_delayinfo", i915_cur_delayinfo, 0}, -- cgit v1.2.3-70-g09d2 From 4ca4a250ac93d5538a2a5c98ee2bcf9195f38be4 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:27 +0100 Subject: drm/i915: reject GTT domain in relocations This confuses our domain tracking and can (for gtt write domains) lead to a subsequent oops. Tested by tests/gem_exec_bad_domains from i-g-t. Reviewed-by: Eric Anholt Reviewed-by: Chris Wilson Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 5 +++-- 1 file changed, 3 insertions(+), 2 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 4a43ef5dba3..123c51445a8 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -303,8 +303,9 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, reloc->write_domain); return ret; } - if (unlikely((reloc->write_domain | reloc->read_domains) & I915_GEM_DOMAIN_CPU)) { - DRM_ERROR("reloc with read/write CPU domains: " + if (unlikely((reloc->write_domain | reloc->read_domains) + & ~I915_GEM_GPU_DOMAINS)) { + DRM_ERROR("reloc with read/write non-GPU domains: " "obj %p target %d offset %d " "read %08x write %08x", obj, reloc->target_handle, -- cgit v1.2.3-70-g09d2 From cf579dfb82550e34de7ccf3ef090d8b834ccd3a9 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 29 Jan 2012 20:38:29 +0100 Subject: PM / Sleep: Introduce "late suspend" and "early resume" of devices The current device suspend/resume phases during system-wide power transitions appear to be insufficient for some platforms that want to use the same callback routines for saving device states and related operations during runtime suspend/resume as well as during system suspend/resume. In principle, they could point their .suspend_noirq() and .resume_noirq() to the same callback routines as their .runtime_suspend() and .runtime_resume(), respectively, but at least some of them require device interrupts to be enabled while the code in those routines is running. It also makes sense to have device suspend-resume callbacks that will be executed with runtime PM disabled and with device interrupts enabled in case someone needs to run some special code in that context during system-wide power transitions. Apart from this, .suspend_noirq() and .resume_noirq() were introduced as a workaround for drivers using shared interrupts and failing to prevent their interrupt handlers from accessing suspended hardware. It appears to be better not to use them for other porposes, or we may have to deal with some serious confusion (which seems to be happening already). For the above reasons, introduce new device suspend/resume phases, "late suspend" and "early resume" (and analogously for hibernation) whose callback will be executed with runtime PM disabled and with device interrupts enabled and whose callback pointers generally may point to runtime suspend/resume routines. Signed-off-by: Rafael J. Wysocki Reviewed-by: Mark Brown Reviewed-by: Kevin Hilman --- Documentation/power/devices.txt | 93 +++++++++------ arch/x86/kernel/apm_32.c | 11 +- drivers/base/power/main.c | 247 ++++++++++++++++++++++++++++++++++++---- drivers/xen/manage.c | 6 +- include/linux/pm.h | 43 +++++-- include/linux/suspend.h | 4 + kernel/kexec.c | 8 +- kernel/power/hibernate.c | 24 ++-- kernel/power/main.c | 8 +- kernel/power/suspend.c | 4 +- 10 files changed, 357 insertions(+), 91 deletions(-) (limited to 'drivers') diff --git a/Documentation/power/devices.txt b/Documentation/power/devices.txt index 20af7def23c..872815cd41d 100644 --- a/Documentation/power/devices.txt +++ b/Documentation/power/devices.txt @@ -96,6 +96,12 @@ struct dev_pm_ops { int (*thaw)(struct device *dev); int (*poweroff)(struct device *dev); int (*restore)(struct device *dev); + int (*suspend_late)(struct device *dev); + int (*resume_early)(struct device *dev); + int (*freeze_late)(struct device *dev); + int (*thaw_early)(struct device *dev); + int (*poweroff_late)(struct device *dev); + int (*restore_early)(struct device *dev); int (*suspend_noirq)(struct device *dev); int (*resume_noirq)(struct device *dev); int (*freeze_noirq)(struct device *dev); @@ -305,7 +311,7 @@ Entering System Suspend ----------------------- When the system goes into the standby or memory sleep state, the phases are: - prepare, suspend, suspend_noirq. + prepare, suspend, suspend_late, suspend_noirq. 1. The prepare phase is meant to prevent races by preventing new devices from being registered; the PM core would never know that all the @@ -324,7 +330,12 @@ When the system goes into the standby or memory sleep state, the phases are: appropriate low-power state, depending on the bus type the device is on, and they may enable wakeup events. - 3. The suspend_noirq phase occurs after IRQ handlers have been disabled, + 3 For a number of devices it is convenient to split suspend into the + "quiesce device" and "save device state" phases, in which cases + suspend_late is meant to do the latter. It is always executed after + runtime power management has been disabled for all devices. + + 4. The suspend_noirq phase occurs after IRQ handlers have been disabled, which means that the driver's interrupt handler will not be called while the callback method is running. The methods should save the values of the device's registers that weren't saved previously and finally put the @@ -359,7 +370,7 @@ Leaving System Suspend ---------------------- When resuming from standby or memory sleep, the phases are: - resume_noirq, resume, complete. + resume_noirq, resume_early, resume, complete. 1. The resume_noirq callback methods should perform any actions needed before the driver's interrupt handlers are invoked. This generally @@ -375,14 +386,18 @@ When resuming from standby or memory sleep, the phases are: device driver's ->pm.resume_noirq() method to perform device-specific actions. - 2. The resume methods should bring the the device back to its operating + 2. The resume_early methods should prepare devices for the execution of + the resume methods. This generally involves undoing the actions of the + preceding suspend_late phase. + + 3 The resume methods should bring the the device back to its operating state, so that it can perform normal I/O. This generally involves undoing the actions of the suspend phase. - 3. The complete phase uses only a bus callback. The method should undo the - actions of the prepare phase. Note, however, that new children may be - registered below the device as soon as the resume callbacks occur; it's - not necessary to wait until the complete phase. + 4. The complete phase should undo the actions of the prepare phase. Note, + however, that new children may be registered below the device as soon as + the resume callbacks occur; it's not necessary to wait until the + complete phase. At the end of these phases, drivers should be as functional as they were before suspending: I/O can be performed using DMA and IRQs, and the relevant clocks are @@ -429,8 +444,8 @@ an image of the system memory while everything is stable, reactivate all devices (thaw), write the image to permanent storage, and finally shut down the system (poweroff). The phases used to accomplish this are: - prepare, freeze, freeze_noirq, thaw_noirq, thaw, complete, - prepare, poweroff, poweroff_noirq + prepare, freeze, freeze_late, freeze_noirq, thaw_noirq, thaw_early, + thaw, complete, prepare, poweroff, poweroff_late, poweroff_noirq 1. The prepare phase is discussed in the "Entering System Suspend" section above. @@ -441,7 +456,11 @@ system (poweroff). The phases used to accomplish this are: save time it's best not to do so. Also, the device should not be prepared to generate wakeup events. - 3. The freeze_noirq phase is analogous to the suspend_noirq phase discussed + 3. The freeze_late phase is analogous to the suspend_late phase described + above, except that the device should not be put in a low-power state and + should not be allowed to generate wakeup events by it. + + 4. The freeze_noirq phase is analogous to the suspend_noirq phase discussed above, except again that the device should not be put in a low-power state and should not be allowed to generate wakeup events. @@ -449,15 +468,19 @@ At this point the system image is created. All devices should be inactive and the contents of memory should remain undisturbed while this happens, so that the image forms an atomic snapshot of the system state. - 4. The thaw_noirq phase is analogous to the resume_noirq phase discussed + 5. The thaw_noirq phase is analogous to the resume_noirq phase discussed above. The main difference is that its methods can assume the device is in the same state as at the end of the freeze_noirq phase. - 5. The thaw phase is analogous to the resume phase discussed above. Its + 6. The thaw_early phase is analogous to the resume_early phase described + above. Its methods should undo the actions of the preceding + freeze_late, if necessary. + + 7. The thaw phase is analogous to the resume phase discussed above. Its methods should bring the device back to an operating state, so that it can be used for saving the image if necessary. - 6. The complete phase is discussed in the "Leaving System Suspend" section + 8. The complete phase is discussed in the "Leaving System Suspend" section above. At this point the system image is saved, and the devices then need to be @@ -465,16 +488,19 @@ prepared for the upcoming system shutdown. This is much like suspending them before putting the system into the standby or memory sleep state, and the phases are similar. - 7. The prepare phase is discussed above. + 9. The prepare phase is discussed above. + + 10. The poweroff phase is analogous to the suspend phase. - 8. The poweroff phase is analogous to the suspend phase. + 11. The poweroff_late phase is analogous to the suspend_late phase. - 9. The poweroff_noirq phase is analogous to the suspend_noirq phase. + 12. The poweroff_noirq phase is analogous to the suspend_noirq phase. -The poweroff and poweroff_noirq callbacks should do essentially the same things -as the suspend and suspend_noirq callbacks. The only notable difference is that -they need not store the device register values, because the registers should -already have been stored during the freeze or freeze_noirq phases. +The poweroff, poweroff_late and poweroff_noirq callbacks should do essentially +the same things as the suspend, suspend_late and suspend_noirq callbacks, +respectively. The only notable difference is that they need not store the +device register values, because the registers should already have been stored +during the freeze, freeze_late or freeze_noirq phases. Leaving Hibernation @@ -518,22 +544,25 @@ To achieve this, the image kernel must restore the devices' pre-hibernation functionality. The operation is much like waking up from the memory sleep state, although it involves different phases: - restore_noirq, restore, complete + restore_noirq, restore_early, restore, complete 1. The restore_noirq phase is analogous to the resume_noirq phase. - 2. The restore phase is analogous to the resume phase. + 2. The restore_early phase is analogous to the resume_early phase. + + 3. The restore phase is analogous to the resume phase. - 3. The complete phase is discussed above. + 4. The complete phase is discussed above. -The main difference from resume[_noirq] is that restore[_noirq] must assume the -device has been accessed and reconfigured by the boot loader or the boot kernel. -Consequently the state of the device may be different from the state remembered -from the freeze and freeze_noirq phases. The device may even need to be reset -and completely re-initialized. In many cases this difference doesn't matter, so -the resume[_noirq] and restore[_norq] method pointers can be set to the same -routines. Nevertheless, different callback pointers are used in case there is a -situation where it actually matters. +The main difference from resume[_early|_noirq] is that restore[_early|_noirq] +must assume the device has been accessed and reconfigured by the boot loader or +the boot kernel. Consequently the state of the device may be different from the +state remembered from the freeze, freeze_late and freeze_noirq phases. The +device may even need to be reset and completely re-initialized. In many cases +this difference doesn't matter, so the resume[_early|_noirq] and +restore[_early|_norq] method pointers can be set to the same routines. +Nevertheless, different callback pointers are used in case there is a situation +where it actually does matter. Device Power Management Domains diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index f76623cbe26..5d56931a15b 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c @@ -1234,8 +1234,7 @@ static int suspend(int vetoable) struct apm_user *as; dpm_suspend_start(PMSG_SUSPEND); - - dpm_suspend_noirq(PMSG_SUSPEND); + dpm_suspend_end(PMSG_SUSPEND); local_irq_disable(); syscore_suspend(); @@ -1259,9 +1258,9 @@ static int suspend(int vetoable) syscore_resume(); local_irq_enable(); - dpm_resume_noirq(PMSG_RESUME); - + dpm_resume_start(PMSG_RESUME); dpm_resume_end(PMSG_RESUME); + queue_event(APM_NORMAL_RESUME, NULL); spin_lock(&user_list_lock); for (as = user_list; as != NULL; as = as->next) { @@ -1277,7 +1276,7 @@ static void standby(void) { int err; - dpm_suspend_noirq(PMSG_SUSPEND); + dpm_suspend_end(PMSG_SUSPEND); local_irq_disable(); syscore_suspend(); @@ -1291,7 +1290,7 @@ static void standby(void) syscore_resume(); local_irq_enable(); - dpm_resume_noirq(PMSG_RESUME); + dpm_resume_start(PMSG_RESUME); } static apm_event_t get_event(void) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index e2cc3d2e0ec..b462c0e341c 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -47,6 +47,7 @@ typedef int (*pm_callback_t)(struct device *); LIST_HEAD(dpm_list); LIST_HEAD(dpm_prepared_list); LIST_HEAD(dpm_suspended_list); +LIST_HEAD(dpm_late_early_list); LIST_HEAD(dpm_noirq_list); struct suspend_stats suspend_stats; @@ -245,6 +246,40 @@ static pm_callback_t pm_op(const struct dev_pm_ops *ops, pm_message_t state) return NULL; } +/** + * pm_late_early_op - Return the PM operation appropriate for given PM event. + * @ops: PM operations to choose from. + * @state: PM transition of the system being carried out. + * + * Runtime PM is disabled for @dev while this function is being executed. + */ +static pm_callback_t pm_late_early_op(const struct dev_pm_ops *ops, + pm_message_t state) +{ + switch (state.event) { +#ifdef CONFIG_SUSPEND + case PM_EVENT_SUSPEND: + return ops->suspend_late; + case PM_EVENT_RESUME: + return ops->resume_early; +#endif /* CONFIG_SUSPEND */ +#ifdef CONFIG_HIBERNATE_CALLBACKS + case PM_EVENT_FREEZE: + case PM_EVENT_QUIESCE: + return ops->freeze_late; + case PM_EVENT_HIBERNATE: + return ops->poweroff_late; + case PM_EVENT_THAW: + case PM_EVENT_RECOVER: + return ops->thaw_early; + case PM_EVENT_RESTORE: + return ops->restore_early; +#endif /* CONFIG_HIBERNATE_CALLBACKS */ + } + + return NULL; +} + /** * pm_noirq_op - Return the PM operation appropriate for given PM event. * @ops: PM operations to choose from. @@ -374,21 +409,21 @@ static int device_resume_noirq(struct device *dev, pm_message_t state) TRACE_RESUME(0); if (dev->pm_domain) { - info = "EARLY power domain "; + info = "noirq power domain "; callback = pm_noirq_op(&dev->pm_domain->ops, state); } else if (dev->type && dev->type->pm) { - info = "EARLY type "; + info = "noirq type "; callback = pm_noirq_op(dev->type->pm, state); } else if (dev->class && dev->class->pm) { - info = "EARLY class "; + info = "noirq class "; callback = pm_noirq_op(dev->class->pm, state); } else if (dev->bus && dev->bus->pm) { - info = "EARLY bus "; + info = "noirq bus "; callback = pm_noirq_op(dev->bus->pm, state); } if (!callback && dev->driver && dev->driver->pm) { - info = "EARLY driver "; + info = "noirq driver "; callback = pm_noirq_op(dev->driver->pm, state); } @@ -399,13 +434,13 @@ static int device_resume_noirq(struct device *dev, pm_message_t state) } /** - * dpm_resume_noirq - Execute "early resume" callbacks for non-sysdev devices. + * dpm_resume_noirq - Execute "noirq resume" callbacks for all devices. * @state: PM transition of the system being carried out. * - * Call the "noirq" resume handlers for all devices marked as DPM_OFF_IRQ and + * Call the "noirq" resume handlers for all devices in dpm_noirq_list and * enable device drivers to receive interrupts. */ -void dpm_resume_noirq(pm_message_t state) +static void dpm_resume_noirq(pm_message_t state) { ktime_t starttime = ktime_get(); @@ -415,7 +450,7 @@ void dpm_resume_noirq(pm_message_t state) int error; get_device(dev); - list_move_tail(&dev->power.entry, &dpm_suspended_list); + list_move_tail(&dev->power.entry, &dpm_late_early_list); mutex_unlock(&dpm_list_mtx); error = device_resume_noirq(dev, state); @@ -423,6 +458,80 @@ void dpm_resume_noirq(pm_message_t state) suspend_stats.failed_resume_noirq++; dpm_save_failed_step(SUSPEND_RESUME_NOIRQ); dpm_save_failed_dev(dev_name(dev)); + pm_dev_err(dev, state, " noirq", error); + } + + mutex_lock(&dpm_list_mtx); + put_device(dev); + } + mutex_unlock(&dpm_list_mtx); + dpm_show_time(starttime, state, "noirq"); + resume_device_irqs(); +} + +/** + * device_resume_early - Execute an "early resume" callback for given device. + * @dev: Device to handle. + * @state: PM transition of the system being carried out. + * + * Runtime PM is disabled for @dev while this function is being executed. + */ +static int device_resume_early(struct device *dev, pm_message_t state) +{ + pm_callback_t callback = NULL; + char *info = NULL; + int error = 0; + + TRACE_DEVICE(dev); + TRACE_RESUME(0); + + if (dev->pm_domain) { + info = "early power domain "; + callback = pm_late_early_op(&dev->pm_domain->ops, state); + } else if (dev->type && dev->type->pm) { + info = "early type "; + callback = pm_late_early_op(dev->type->pm, state); + } else if (dev->class && dev->class->pm) { + info = "early class "; + callback = pm_late_early_op(dev->class->pm, state); + } else if (dev->bus && dev->bus->pm) { + info = "early bus "; + callback = pm_late_early_op(dev->bus->pm, state); + } + + if (!callback && dev->driver && dev->driver->pm) { + info = "early driver "; + callback = pm_late_early_op(dev->driver->pm, state); + } + + error = dpm_run_callback(callback, dev, state, info); + + TRACE_RESUME(error); + return error; +} + +/** + * dpm_resume_early - Execute "early resume" callbacks for all devices. + * @state: PM transition of the system being carried out. + */ +static void dpm_resume_early(pm_message_t state) +{ + ktime_t starttime = ktime_get(); + + mutex_lock(&dpm_list_mtx); + while (!list_empty(&dpm_late_early_list)) { + struct device *dev = to_device(dpm_late_early_list.next); + int error; + + get_device(dev); + list_move_tail(&dev->power.entry, &dpm_suspended_list); + mutex_unlock(&dpm_list_mtx); + + error = device_resume_early(dev, state); + if (error) { + suspend_stats.failed_resume_early++; + dpm_save_failed_step(SUSPEND_RESUME_EARLY); + dpm_save_failed_dev(dev_name(dev)); pm_dev_err(dev, state, " early", error); } @@ -431,9 +540,18 @@ void dpm_resume_noirq(pm_message_t state) } mutex_unlock(&dpm_list_mtx); dpm_show_time(starttime, state, "early"); - resume_device_irqs(); } -EXPORT_SYMBOL_GPL(dpm_resume_noirq); + +/** + * dpm_resume_start - Execute "noirq" and "early" device callbacks. + * @state: PM transition of the system being carried out. + */ +void dpm_resume_start(pm_message_t state) +{ + dpm_resume_noirq(state); + dpm_resume_early(state); +} +EXPORT_SYMBOL_GPL(dpm_resume_start); /** * device_resume - Execute "resume" callbacks for given device. @@ -716,21 +834,21 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state) char *info = NULL; if (dev->pm_domain) { - info = "LATE power domain "; + info = "noirq power domain "; callback = pm_noirq_op(&dev->pm_domain->ops, state); } else if (dev->type && dev->type->pm) { - info = "LATE type "; + info = "noirq type "; callback = pm_noirq_op(dev->type->pm, state); } else if (dev->class && dev->class->pm) { - info = "LATE class "; + info = "noirq class "; callback = pm_noirq_op(dev->class->pm, state); } else if (dev->bus && dev->bus->pm) { - info = "LATE bus "; + info = "noirq bus "; callback = pm_noirq_op(dev->bus->pm, state); } if (!callback && dev->driver && dev->driver->pm) { - info = "LATE driver "; + info = "noirq driver "; callback = pm_noirq_op(dev->driver->pm, state); } @@ -738,21 +856,21 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state) } /** - * dpm_suspend_noirq - Execute "late suspend" callbacks for non-sysdev devices. + * dpm_suspend_noirq - Execute "noirq suspend" callbacks for all devices. * @state: PM transition of the system being carried out. * * Prevent device drivers from receiving interrupts and call the "noirq" suspend * handlers for all non-sysdev devices. */ -int dpm_suspend_noirq(pm_message_t state) +static int dpm_suspend_noirq(pm_message_t state) { ktime_t starttime = ktime_get(); int error = 0; suspend_device_irqs(); mutex_lock(&dpm_list_mtx); - while (!list_empty(&dpm_suspended_list)) { - struct device *dev = to_device(dpm_suspended_list.prev); + while (!list_empty(&dpm_late_early_list)) { + struct device *dev = to_device(dpm_late_early_list.prev); get_device(dev); mutex_unlock(&dpm_list_mtx); @@ -761,7 +879,7 @@ int dpm_suspend_noirq(pm_message_t state) mutex_lock(&dpm_list_mtx); if (error) { - pm_dev_err(dev, state, " late", error); + pm_dev_err(dev, state, " noirq", error); suspend_stats.failed_suspend_noirq++; dpm_save_failed_step(SUSPEND_SUSPEND_NOIRQ); dpm_save_failed_dev(dev_name(dev)); @@ -775,11 +893,96 @@ int dpm_suspend_noirq(pm_message_t state) mutex_unlock(&dpm_list_mtx); if (error) dpm_resume_noirq(resume_event(state)); + else + dpm_show_time(starttime, state, "noirq"); + return error; +} + +/** + * device_suspend_late - Execute a "late suspend" callback for given device. + * @dev: Device to handle. + * @state: PM transition of the system being carried out. + * + * Runtime PM is disabled for @dev while this function is being executed. + */ +static int device_suspend_late(struct device *dev, pm_message_t state) +{ + pm_callback_t callback = NULL; + char *info = NULL; + + if (dev->pm_domain) { + info = "late power domain "; + callback = pm_late_early_op(&dev->pm_domain->ops, state); + } else if (dev->type && dev->type->pm) { + info = "late type "; + callback = pm_late_early_op(dev->type->pm, state); + } else if (dev->class && dev->class->pm) { + info = "late class "; + callback = pm_late_early_op(dev->class->pm, state); + } else if (dev->bus && dev->bus->pm) { + info = "late bus "; + callback = pm_late_early_op(dev->bus->pm, state); + } + + if (!callback && dev->driver && dev->driver->pm) { + info = "late driver "; + callback = pm_late_early_op(dev->driver->pm, state); + } + + return dpm_run_callback(callback, dev, state, info); +} + +/** + * dpm_suspend_late - Execute "late suspend" callbacks for all devices. + * @state: PM transition of the system being carried out. + */ +static int dpm_suspend_late(pm_message_t state) +{ + ktime_t starttime = ktime_get(); + int error = 0; + + mutex_lock(&dpm_list_mtx); + while (!list_empty(&dpm_suspended_list)) { + struct device *dev = to_device(dpm_suspended_list.prev); + + get_device(dev); + mutex_unlock(&dpm_list_mtx); + + error = device_suspend_late(dev, state); + + mutex_lock(&dpm_list_mtx); + if (error) { + pm_dev_err(dev, state, " late", error); + suspend_stats.failed_suspend_late++; + dpm_save_failed_step(SUSPEND_SUSPEND_LATE); + dpm_save_failed_dev(dev_name(dev)); + put_device(dev); + break; + } + if (!list_empty(&dev->power.entry)) + list_move(&dev->power.entry, &dpm_late_early_list); + put_device(dev); + } + mutex_unlock(&dpm_list_mtx); + if (error) + dpm_resume_early(resume_event(state)); else dpm_show_time(starttime, state, "late"); + return error; } -EXPORT_SYMBOL_GPL(dpm_suspend_noirq); + +/** + * dpm_suspend_end - Execute "late" and "noirq" device suspend callbacks. + * @state: PM transition of the system being carried out. + */ +int dpm_suspend_end(pm_message_t state) +{ + int error = dpm_suspend_late(state); + + return error ? : dpm_suspend_noirq(state); +} +EXPORT_SYMBOL_GPL(dpm_suspend_end); /** * legacy_suspend - Execute a legacy (bus or class) suspend callback for device. diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index ce4fa083186..9e14ae6cd49 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -129,9 +129,9 @@ static void do_suspend(void) printk(KERN_DEBUG "suspending xenstore...\n"); xs_suspend(); - err = dpm_suspend_noirq(PMSG_FREEZE); + err = dpm_suspend_end(PMSG_FREEZE); if (err) { - printk(KERN_ERR "dpm_suspend_noirq failed: %d\n", err); + printk(KERN_ERR "dpm_suspend_end failed: %d\n", err); goto out_resume; } @@ -149,7 +149,7 @@ static void do_suspend(void) err = stop_machine(xen_suspend, &si, cpumask_of(0)); - dpm_resume_noirq(si.cancelled ? PMSG_THAW : PMSG_RESTORE); + dpm_resume_start(si.cancelled ? PMSG_THAW : PMSG_RESTORE); if (err) { printk(KERN_ERR "failed to start xen_suspend: %d\n", err); diff --git a/include/linux/pm.h b/include/linux/pm.h index e4982ac3fbb..c68e1f22ac9 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -110,6 +110,10 @@ typedef struct pm_message { * Subsystem-level @suspend() is executed for all devices after invoking * subsystem-level @prepare() for all of them. * + * @suspend_late: Continue operations started by @suspend(). For a number of + * devices @suspend_late() may point to the same callback routine as the + * runtime suspend callback. + * * @resume: Executed after waking the system up from a sleep state in which the * contents of main memory were preserved. The exact action to perform * depends on the device's subsystem, but generally the driver is expected @@ -122,6 +126,10 @@ typedef struct pm_message { * Subsystem-level @resume() is executed for all devices after invoking * subsystem-level @resume_noirq() for all of them. * + * @resume_early: Prepare to execute @resume(). For a number of devices + * @resume_early() may point to the same callback routine as the runtime + * resume callback. + * * @freeze: Hibernation-specific, executed before creating a hibernation image. * Analogous to @suspend(), but it should not enable the device to signal * wakeup events or change its power state. The majority of subsystems @@ -131,6 +139,10 @@ typedef struct pm_message { * Subsystem-level @freeze() is executed for all devices after invoking * subsystem-level @prepare() for all of them. * + * @freeze_late: Continue operations started by @freeze(). Analogous to + * @suspend_late(), but it should not enable the device to signal wakeup + * events or change its power state. + * * @thaw: Hibernation-specific, executed after creating a hibernation image OR * if the creation of an image has failed. Also executed after a failing * attempt to restore the contents of main memory from such an image. @@ -140,15 +152,23 @@ typedef struct pm_message { * subsystem-level @thaw_noirq() for all of them. It also may be executed * directly after @freeze() in case of a transition error. * + * @thaw_early: Prepare to execute @thaw(). Undo the changes made by the + * preceding @freeze_late(). + * * @poweroff: Hibernation-specific, executed after saving a hibernation image. * Analogous to @suspend(), but it need not save the device's settings in * memory. * Subsystem-level @poweroff() is executed for all devices after invoking * subsystem-level @prepare() for all of them. * + * @poweroff_late: Continue operations started by @poweroff(). Analogous to + * @suspend_late(), but it need not save the device's settings in memory. + * * @restore: Hibernation-specific, executed after restoring the contents of main * memory from a hibernation image, analogous to @resume(). * + * @restore_early: Prepare to execute @restore(), analogous to @resume_early(). + * * @suspend_noirq: Complete the actions started by @suspend(). Carry out any * additional operations required for suspending the device that might be * racing with its driver's interrupt handler, which is guaranteed not to @@ -158,9 +178,10 @@ typedef struct pm_message { * @suspend_noirq() has returned successfully. If the device can generate * system wakeup signals and is enabled to wake up the system, it should be * configured to do so at that time. However, depending on the platform - * and device's subsystem, @suspend() may be allowed to put the device into - * the low-power state and configure it to generate wakeup signals, in - * which case it generally is not necessary to define @suspend_noirq(). + * and device's subsystem, @suspend() or @suspend_late() may be allowed to + * put the device into the low-power state and configure it to generate + * wakeup signals, in which case it generally is not necessary to define + * @suspend_noirq(). * * @resume_noirq: Prepare for the execution of @resume() by carrying out any * operations required for resuming the device that might be racing with @@ -171,9 +192,9 @@ typedef struct pm_message { * additional operations required for freezing the device that might be * racing with its driver's interrupt handler, which is guaranteed not to * run while @freeze_noirq() is being executed. - * The power state of the device should not be changed by either @freeze() - * or @freeze_noirq() and it should not be configured to signal system - * wakeup by any of these callbacks. + * The power state of the device should not be changed by either @freeze(), + * or @freeze_late(), or @freeze_noirq() and it should not be configured to + * signal system wakeup by any of these callbacks. * * @thaw_noirq: Prepare for the execution of @thaw() by carrying out any * operations required for thawing the device that might be racing with its @@ -249,6 +270,12 @@ struct dev_pm_ops { int (*thaw)(struct device *dev); int (*poweroff)(struct device *dev); int (*restore)(struct device *dev); + int (*suspend_late)(struct device *dev); + int (*resume_early)(struct device *dev); + int (*freeze_late)(struct device *dev); + int (*thaw_early)(struct device *dev); + int (*poweroff_late)(struct device *dev); + int (*restore_early)(struct device *dev); int (*suspend_noirq)(struct device *dev); int (*resume_noirq)(struct device *dev); int (*freeze_noirq)(struct device *dev); @@ -584,13 +611,13 @@ struct dev_pm_domain { #ifdef CONFIG_PM_SLEEP extern void device_pm_lock(void); -extern void dpm_resume_noirq(pm_message_t state); +extern void dpm_resume_start(pm_message_t state); extern void dpm_resume_end(pm_message_t state); extern void dpm_resume(pm_message_t state); extern void dpm_complete(pm_message_t state); extern void device_pm_unlock(void); -extern int dpm_suspend_noirq(pm_message_t state); +extern int dpm_suspend_end(pm_message_t state); extern int dpm_suspend_start(pm_message_t state); extern int dpm_suspend(pm_message_t state); extern int dpm_prepare(pm_message_t state); diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 91784a4f860..ac1c114c499 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -42,8 +42,10 @@ enum suspend_stat_step { SUSPEND_FREEZE = 1, SUSPEND_PREPARE, SUSPEND_SUSPEND, + SUSPEND_SUSPEND_LATE, SUSPEND_SUSPEND_NOIRQ, SUSPEND_RESUME_NOIRQ, + SUSPEND_RESUME_EARLY, SUSPEND_RESUME }; @@ -53,8 +55,10 @@ struct suspend_stats { int failed_freeze; int failed_prepare; int failed_suspend; + int failed_suspend_late; int failed_suspend_noirq; int failed_resume; + int failed_resume_early; int failed_resume_noirq; #define REC_FAILED_NUM 2 int last_failed_dev; diff --git a/kernel/kexec.c b/kernel/kexec.c index 7b088678670..a6a675cb981 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -1546,13 +1546,13 @@ int kernel_kexec(void) if (error) goto Resume_console; /* At this point, dpm_suspend_start() has been called, - * but *not* dpm_suspend_noirq(). We *must* call - * dpm_suspend_noirq() now. Otherwise, drivers for + * but *not* dpm_suspend_end(). We *must* call + * dpm_suspend_end() now. Otherwise, drivers for * some devices (e.g. interrupt controllers) become * desynchronized with the actual state of the * hardware at resume time, and evil weirdness ensues. */ - error = dpm_suspend_noirq(PMSG_FREEZE); + error = dpm_suspend_end(PMSG_FREEZE); if (error) goto Resume_devices; error = disable_nonboot_cpus(); @@ -1579,7 +1579,7 @@ int kernel_kexec(void) local_irq_enable(); Enable_cpus: enable_nonboot_cpus(); - dpm_resume_noirq(PMSG_RESTORE); + dpm_resume_start(PMSG_RESTORE); Resume_devices: dpm_resume_end(PMSG_RESTORE); Resume_console: diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index 6d6d2887033..a5d4cf0aa03 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -245,8 +245,8 @@ void swsusp_show_speed(struct timeval *start, struct timeval *stop, * create_image - Create a hibernation image. * @platform_mode: Whether or not to use the platform driver. * - * Execute device drivers' .freeze_noirq() callbacks, create a hibernation image - * and execute the drivers' .thaw_noirq() callbacks. + * Execute device drivers' "late" and "noirq" freeze callbacks, create a + * hibernation image and run the drivers' "noirq" and "early" thaw callbacks. * * Control reappears in this routine after the subsequent restore. */ @@ -254,7 +254,7 @@ static int create_image(int platform_mode) { int error; - error = dpm_suspend_noirq(PMSG_FREEZE); + error = dpm_suspend_end(PMSG_FREEZE); if (error) { printk(KERN_ERR "PM: Some devices failed to power down, " "aborting hibernation\n"); @@ -306,7 +306,7 @@ static int create_image(int platform_mode) Platform_finish: platform_finish(platform_mode); - dpm_resume_noirq(in_suspend ? + dpm_resume_start(in_suspend ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); return error; @@ -394,16 +394,16 @@ int hibernation_snapshot(int platform_mode) * resume_target_kernel - Restore system state from a hibernation image. * @platform_mode: Whether or not to use the platform driver. * - * Execute device drivers' .freeze_noirq() callbacks, restore the contents of - * highmem that have not been restored yet from the image and run the low-level - * code that will restore the remaining contents of memory and switch to the - * just restored target kernel. + * Execute device drivers' "noirq" and "late" freeze callbacks, restore the + * contents of highmem that have not been restored yet from the image and run + * the low-level code that will restore the remaining contents of memory and + * switch to the just restored target kernel. */ static int resume_target_kernel(bool platform_mode) { int error; - error = dpm_suspend_noirq(PMSG_QUIESCE); + error = dpm_suspend_end(PMSG_QUIESCE); if (error) { printk(KERN_ERR "PM: Some devices failed to power down, " "aborting resume\n"); @@ -460,7 +460,7 @@ static int resume_target_kernel(bool platform_mode) Cleanup: platform_restore_cleanup(platform_mode); - dpm_resume_noirq(PMSG_RECOVER); + dpm_resume_start(PMSG_RECOVER); return error; } @@ -518,7 +518,7 @@ int hibernation_platform_enter(void) goto Resume_devices; } - error = dpm_suspend_noirq(PMSG_HIBERNATE); + error = dpm_suspend_end(PMSG_HIBERNATE); if (error) goto Resume_devices; @@ -549,7 +549,7 @@ int hibernation_platform_enter(void) Platform_finish: hibernation_ops->finish(); - dpm_resume_noirq(PMSG_RESTORE); + dpm_resume_start(PMSG_RESTORE); Resume_devices: entering_platform_hibernation = false; diff --git a/kernel/power/main.c b/kernel/power/main.c index 9824b41e5a1..8c5014a4e05 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -165,16 +165,20 @@ static int suspend_stats_show(struct seq_file *s, void *unused) last_errno %= REC_FAILED_NUM; last_step = suspend_stats.last_failed_step + REC_FAILED_NUM - 1; last_step %= REC_FAILED_NUM; - seq_printf(s, "%s: %d\n%s: %d\n%s: %d\n%s: %d\n" - "%s: %d\n%s: %d\n%s: %d\n%s: %d\n", + seq_printf(s, "%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %d\n" + "%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %d\n", "success", suspend_stats.success, "fail", suspend_stats.fail, "failed_freeze", suspend_stats.failed_freeze, "failed_prepare", suspend_stats.failed_prepare, "failed_suspend", suspend_stats.failed_suspend, + "failed_suspend_late", + suspend_stats.failed_suspend_late, "failed_suspend_noirq", suspend_stats.failed_suspend_noirq, "failed_resume", suspend_stats.failed_resume, + "failed_resume_early", + suspend_stats.failed_resume_early, "failed_resume_noirq", suspend_stats.failed_resume_noirq); seq_printf(s, "failures:\n last_failed_dev:\t%-s\n", diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index 4fd51beed87..560a639614a 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -147,7 +147,7 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) goto Platform_finish; } - error = dpm_suspend_noirq(PMSG_SUSPEND); + error = dpm_suspend_end(PMSG_SUSPEND); if (error) { printk(KERN_ERR "PM: Some devices failed to power down\n"); goto Platform_finish; @@ -189,7 +189,7 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) if (suspend_ops->wake) suspend_ops->wake(); - dpm_resume_noirq(PMSG_RESUME); + dpm_resume_start(PMSG_RESUME); Platform_finish: if (suspend_ops->finish) -- cgit v1.2.3-70-g09d2 From e470d06655e00749f6f9372e4fa4f20cea7ed7c5 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 29 Jan 2012 20:38:41 +0100 Subject: PM / Sleep: Introduce generic callbacks for new device PM phases Introduce generic subsystem callbacks for the new phases of device suspend/resume during system power transitions: "late suspend", "early resume", "late freeze", "early thaw", "late poweroff", "early restore". Signed-off-by: Rafael J. Wysocki --- drivers/base/power/generic_ops.c | 157 ++++++++++++++++++++++++++------------- include/linux/pm.h | 6 ++ 2 files changed, 110 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/base/power/generic_ops.c b/drivers/base/power/generic_ops.c index 10bdd793f0b..d03d290f31c 100644 --- a/drivers/base/power/generic_ops.c +++ b/drivers/base/power/generic_ops.c @@ -92,59 +92,28 @@ int pm_generic_prepare(struct device *dev) } /** - * __pm_generic_call - Generic suspend/freeze/poweroff/thaw subsystem callback. - * @dev: Device to handle. - * @event: PM transition of the system under way. - * @bool: Whether or not this is the "noirq" stage. - * - * Execute the PM callback corresponding to @event provided by the driver of - * @dev, if defined, and return its error code. Return 0 if the callback is - * not present. + * pm_generic_suspend_noirq - Generic suspend_noirq callback for subsystems. + * @dev: Device to suspend. */ -static int __pm_generic_call(struct device *dev, int event, bool noirq) +int pm_generic_suspend_noirq(struct device *dev) { const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - int (*callback)(struct device *); - - if (!pm) - return 0; - - switch (event) { - case PM_EVENT_SUSPEND: - callback = noirq ? pm->suspend_noirq : pm->suspend; - break; - case PM_EVENT_FREEZE: - callback = noirq ? pm->freeze_noirq : pm->freeze; - break; - case PM_EVENT_HIBERNATE: - callback = noirq ? pm->poweroff_noirq : pm->poweroff; - break; - case PM_EVENT_RESUME: - callback = noirq ? pm->resume_noirq : pm->resume; - break; - case PM_EVENT_THAW: - callback = noirq ? pm->thaw_noirq : pm->thaw; - break; - case PM_EVENT_RESTORE: - callback = noirq ? pm->restore_noirq : pm->restore; - break; - default: - callback = NULL; - break; - } - return callback ? callback(dev) : 0; + return pm && pm->suspend_noirq ? pm->suspend_noirq(dev) : 0; } +EXPORT_SYMBOL_GPL(pm_generic_suspend_noirq); /** - * pm_generic_suspend_noirq - Generic suspend_noirq callback for subsystems. + * pm_generic_suspend_late - Generic suspend_late callback for subsystems. * @dev: Device to suspend. */ -int pm_generic_suspend_noirq(struct device *dev) +int pm_generic_suspend_late(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_SUSPEND, true); + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->suspend_late ? pm->suspend_late(dev) : 0; } -EXPORT_SYMBOL_GPL(pm_generic_suspend_noirq); +EXPORT_SYMBOL_GPL(pm_generic_suspend_late); /** * pm_generic_suspend - Generic suspend callback for subsystems. @@ -152,7 +121,9 @@ EXPORT_SYMBOL_GPL(pm_generic_suspend_noirq); */ int pm_generic_suspend(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_SUSPEND, false); + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->suspend ? pm->suspend(dev) : 0; } EXPORT_SYMBOL_GPL(pm_generic_suspend); @@ -162,17 +133,33 @@ EXPORT_SYMBOL_GPL(pm_generic_suspend); */ int pm_generic_freeze_noirq(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_FREEZE, true); + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->freeze_noirq ? pm->freeze_noirq(dev) : 0; } EXPORT_SYMBOL_GPL(pm_generic_freeze_noirq); +/** + * pm_generic_freeze_late - Generic freeze_late callback for subsystems. + * @dev: Device to freeze. + */ +int pm_generic_freeze_late(struct device *dev) +{ + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->freeze_late ? pm->freeze_late(dev) : 0; +} +EXPORT_SYMBOL_GPL(pm_generic_freeze_late); + /** * pm_generic_freeze - Generic freeze callback for subsystems. * @dev: Device to freeze. */ int pm_generic_freeze(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_FREEZE, false); + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->freeze ? pm->freeze(dev) : 0; } EXPORT_SYMBOL_GPL(pm_generic_freeze); @@ -182,17 +169,33 @@ EXPORT_SYMBOL_GPL(pm_generic_freeze); */ int pm_generic_poweroff_noirq(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_HIBERNATE, true); + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->poweroff_noirq ? pm->poweroff_noirq(dev) : 0; } EXPORT_SYMBOL_GPL(pm_generic_poweroff_noirq); +/** + * pm_generic_poweroff_late - Generic poweroff_late callback for subsystems. + * @dev: Device to handle. + */ +int pm_generic_poweroff_late(struct device *dev) +{ + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->poweroff_late ? pm->poweroff_late(dev) : 0; +} +EXPORT_SYMBOL_GPL(pm_generic_poweroff_late); + /** * pm_generic_poweroff - Generic poweroff callback for subsystems. * @dev: Device to handle. */ int pm_generic_poweroff(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_HIBERNATE, false); + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->poweroff ? pm->poweroff(dev) : 0; } EXPORT_SYMBOL_GPL(pm_generic_poweroff); @@ -202,17 +205,33 @@ EXPORT_SYMBOL_GPL(pm_generic_poweroff); */ int pm_generic_thaw_noirq(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_THAW, true); + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->thaw_noirq ? pm->thaw_noirq(dev) : 0; } EXPORT_SYMBOL_GPL(pm_generic_thaw_noirq); +/** + * pm_generic_thaw_early - Generic thaw_early callback for subsystems. + * @dev: Device to thaw. + */ +int pm_generic_thaw_early(struct device *dev) +{ + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->thaw_early ? pm->thaw_early(dev) : 0; +} +EXPORT_SYMBOL_GPL(pm_generic_thaw_early); + /** * pm_generic_thaw - Generic thaw callback for subsystems. * @dev: Device to thaw. */ int pm_generic_thaw(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_THAW, false); + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->thaw ? pm->thaw(dev) : 0; } EXPORT_SYMBOL_GPL(pm_generic_thaw); @@ -222,17 +241,33 @@ EXPORT_SYMBOL_GPL(pm_generic_thaw); */ int pm_generic_resume_noirq(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_RESUME, true); + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->resume_noirq ? pm->resume_noirq(dev) : 0; } EXPORT_SYMBOL_GPL(pm_generic_resume_noirq); +/** + * pm_generic_resume_early - Generic resume_early callback for subsystems. + * @dev: Device to resume. + */ +int pm_generic_resume_early(struct device *dev) +{ + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->resume_early ? pm->resume_early(dev) : 0; +} +EXPORT_SYMBOL_GPL(pm_generic_resume_early); + /** * pm_generic_resume - Generic resume callback for subsystems. * @dev: Device to resume. */ int pm_generic_resume(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_RESUME, false); + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->resume ? pm->resume(dev) : 0; } EXPORT_SYMBOL_GPL(pm_generic_resume); @@ -242,17 +277,33 @@ EXPORT_SYMBOL_GPL(pm_generic_resume); */ int pm_generic_restore_noirq(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_RESTORE, true); + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->restore_noirq ? pm->restore_noirq(dev) : 0; } EXPORT_SYMBOL_GPL(pm_generic_restore_noirq); +/** + * pm_generic_restore_early - Generic restore_early callback for subsystems. + * @dev: Device to resume. + */ +int pm_generic_restore_early(struct device *dev) +{ + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->restore_early ? pm->restore_early(dev) : 0; +} +EXPORT_SYMBOL_GPL(pm_generic_restore_early); + /** * pm_generic_restore - Generic restore callback for subsystems. * @dev: Device to restore. */ int pm_generic_restore(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_RESTORE, false); + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->restore ? pm->restore(dev) : 0; } EXPORT_SYMBOL_GPL(pm_generic_restore); diff --git a/include/linux/pm.h b/include/linux/pm.h index c68e1f22ac9..73c610573a7 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -632,17 +632,23 @@ extern void __suspend_report_result(const char *function, void *fn, int ret); extern int device_pm_wait_for_dev(struct device *sub, struct device *dev); extern int pm_generic_prepare(struct device *dev); +extern int pm_generic_suspend_late(struct device *dev); extern int pm_generic_suspend_noirq(struct device *dev); extern int pm_generic_suspend(struct device *dev); +extern int pm_generic_resume_early(struct device *dev); extern int pm_generic_resume_noirq(struct device *dev); extern int pm_generic_resume(struct device *dev); extern int pm_generic_freeze_noirq(struct device *dev); +extern int pm_generic_freeze_late(struct device *dev); extern int pm_generic_freeze(struct device *dev); extern int pm_generic_thaw_noirq(struct device *dev); +extern int pm_generic_thaw_early(struct device *dev); extern int pm_generic_thaw(struct device *dev); extern int pm_generic_restore_noirq(struct device *dev); +extern int pm_generic_restore_early(struct device *dev); extern int pm_generic_restore(struct device *dev); extern int pm_generic_poweroff_noirq(struct device *dev); +extern int pm_generic_poweroff_late(struct device *dev); extern int pm_generic_poweroff(struct device *dev); extern void pm_generic_complete(struct device *dev); -- cgit v1.2.3-70-g09d2 From 0496c8ae366724a0a2136cec09a2e277e782c126 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 29 Jan 2012 20:39:02 +0100 Subject: PM / Domains: Run late/early device suspend callbacks at the right time After the introduction of the late/early phases of device suspend/resume during system-wide power transitions it is possible to make the generic PM domains code execute its default late/early device suspend/resume callbacks during those phases instead of the corresponding _noirq phases. The _noirq device suspend/resume phases were only used for executing those callbacks, because this was the only way it could be done, but now we can do better. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/domain.c | 157 +++++++++++++++++++++++++++++++------------- 1 file changed, 111 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 978bbf7ac6a..12a03afe530 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -820,17 +820,16 @@ static int pm_genpd_suspend(struct device *dev) } /** - * pm_genpd_suspend_noirq - Late suspend of a device from an I/O PM domain. + * pm_genpd_suspend_late - Late suspend of a device from an I/O PM domain. * @dev: Device to suspend. * * Carry out a late suspend of a device under the assumption that its * pm_domain field points to the domain member of an object of type * struct generic_pm_domain representing a PM domain consisting of I/O devices. */ -static int pm_genpd_suspend_noirq(struct device *dev) +static int pm_genpd_suspend_late(struct device *dev) { struct generic_pm_domain *genpd; - int ret; dev_dbg(dev, "%s()\n", __func__); @@ -838,14 +837,28 @@ static int pm_genpd_suspend_noirq(struct device *dev) if (IS_ERR(genpd)) return -EINVAL; - if (genpd->suspend_power_off) - return 0; + return genpd->suspend_power_off ? 0 : genpd_suspend_late(genpd, dev); +} - ret = genpd_suspend_late(genpd, dev); - if (ret) - return ret; +/** + * pm_genpd_suspend_noirq - Completion of suspend of device in an I/O PM domain. + * @dev: Device to suspend. + * + * Stop the device and remove power from the domain if all devices in it have + * been stopped. + */ +static int pm_genpd_suspend_noirq(struct device *dev) +{ + struct generic_pm_domain *genpd; + + dev_dbg(dev, "%s()\n", __func__); + + genpd = dev_to_genpd(dev); + if (IS_ERR(genpd)) + return -EINVAL; - if (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev)) + if (genpd->suspend_power_off + || (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev))) return 0; genpd_stop_dev(genpd, dev); @@ -862,13 +875,10 @@ static int pm_genpd_suspend_noirq(struct device *dev) } /** - * pm_genpd_resume_noirq - Early resume of a device from an I/O power domain. + * pm_genpd_resume_noirq - Start of resume of device in an I/O PM domain. * @dev: Device to resume. * - * Carry out an early resume of a device under the assumption that its - * pm_domain field points to the domain member of an object of type - * struct generic_pm_domain representing a power domain consisting of I/O - * devices. + * Restore power to the device's PM domain, if necessary, and start the device. */ static int pm_genpd_resume_noirq(struct device *dev) { @@ -890,13 +900,34 @@ static int pm_genpd_resume_noirq(struct device *dev) */ pm_genpd_poweron(genpd); genpd->suspended_count--; - genpd_start_dev(genpd, dev); - return genpd_resume_early(genpd, dev); + return genpd_start_dev(genpd, dev); } /** - * pm_genpd_resume - Resume a device belonging to an I/O power domain. + * pm_genpd_resume_early - Early resume of a device in an I/O PM domain. + * @dev: Device to resume. + * + * Carry out an early resume of a device under the assumption that its + * pm_domain field points to the domain member of an object of type + * struct generic_pm_domain representing a power domain consisting of I/O + * devices. + */ +static int pm_genpd_resume_early(struct device *dev) +{ + struct generic_pm_domain *genpd; + + dev_dbg(dev, "%s()\n", __func__); + + genpd = dev_to_genpd(dev); + if (IS_ERR(genpd)) + return -EINVAL; + + return genpd->suspend_power_off ? 0 : genpd_resume_early(genpd, dev); +} + +/** + * pm_genpd_resume - Resume of device in an I/O PM domain. * @dev: Device to resume. * * Resume a device under the assumption that its pm_domain field points to the @@ -917,7 +948,7 @@ static int pm_genpd_resume(struct device *dev) } /** - * pm_genpd_freeze - Freeze a device belonging to an I/O power domain. + * pm_genpd_freeze - Freezing a device in an I/O PM domain. * @dev: Device to freeze. * * Freeze a device under the assumption that its pm_domain field points to the @@ -938,7 +969,29 @@ static int pm_genpd_freeze(struct device *dev) } /** - * pm_genpd_freeze_noirq - Late freeze of a device from an I/O power domain. + * pm_genpd_freeze_late - Late freeze of a device in an I/O PM domain. + * @dev: Device to freeze. + * + * Carry out a late freeze of a device under the assumption that its + * pm_domain field points to the domain member of an object of type + * struct generic_pm_domain representing a power domain consisting of I/O + * devices. + */ +static int pm_genpd_freeze_late(struct device *dev) +{ + struct generic_pm_domain *genpd; + + dev_dbg(dev, "%s()\n", __func__); + + genpd = dev_to_genpd(dev); + if (IS_ERR(genpd)) + return -EINVAL; + + return genpd->suspend_power_off ? 0 : genpd_freeze_late(genpd, dev); +} + +/** + * pm_genpd_freeze_noirq - Completion of freezing a device in an I/O PM domain. * @dev: Device to freeze. * * Carry out a late freeze of a device under the assumption that its @@ -949,7 +1002,6 @@ static int pm_genpd_freeze(struct device *dev) static int pm_genpd_freeze_noirq(struct device *dev) { struct generic_pm_domain *genpd; - int ret; dev_dbg(dev, "%s()\n", __func__); @@ -957,20 +1009,31 @@ static int pm_genpd_freeze_noirq(struct device *dev) if (IS_ERR(genpd)) return -EINVAL; - if (genpd->suspend_power_off) - return 0; + return genpd->suspend_power_off ? 0 : genpd_stop_dev(genpd, dev); +} - ret = genpd_freeze_late(genpd, dev); - if (ret) - return ret; +/** + * pm_genpd_thaw_noirq - Early thaw of device in an I/O PM domain. + * @dev: Device to thaw. + * + * Start the device, unless power has been removed from the domain already + * before the system transition. + */ +static int pm_genpd_thaw_noirq(struct device *dev) +{ + struct generic_pm_domain *genpd; - genpd_stop_dev(genpd, dev); + dev_dbg(dev, "%s()\n", __func__); - return 0; + genpd = dev_to_genpd(dev); + if (IS_ERR(genpd)) + return -EINVAL; + + return genpd->suspend_power_off ? 0 : genpd_start_dev(genpd, dev); } /** - * pm_genpd_thaw_noirq - Early thaw of a device from an I/O power domain. + * pm_genpd_thaw_early - Early thaw of device in an I/O PM domain. * @dev: Device to thaw. * * Carry out an early thaw of a device under the assumption that its @@ -978,7 +1041,7 @@ static int pm_genpd_freeze_noirq(struct device *dev) * struct generic_pm_domain representing a power domain consisting of I/O * devices. */ -static int pm_genpd_thaw_noirq(struct device *dev) +static int pm_genpd_thaw_early(struct device *dev) { struct generic_pm_domain *genpd; @@ -988,12 +1051,7 @@ static int pm_genpd_thaw_noirq(struct device *dev) if (IS_ERR(genpd)) return -EINVAL; - if (genpd->suspend_power_off) - return 0; - - genpd_start_dev(genpd, dev); - - return genpd_thaw_early(genpd, dev); + return genpd->suspend_power_off ? 0 : genpd_thaw_early(genpd, dev); } /** @@ -1018,13 +1076,11 @@ static int pm_genpd_thaw(struct device *dev) } /** - * pm_genpd_restore_noirq - Early restore of a device from an I/O power domain. + * pm_genpd_restore_noirq - Start of restore of device in an I/O PM domain. * @dev: Device to resume. * - * Carry out an early restore of a device under the assumption that its - * pm_domain field points to the domain member of an object of type - * struct generic_pm_domain representing a power domain consisting of I/O - * devices. + * Make sure the domain will be in the same power state as before the + * hibernation the system is resuming from and start the device if necessary. */ static int pm_genpd_restore_noirq(struct device *dev) { @@ -1054,9 +1110,8 @@ static int pm_genpd_restore_noirq(struct device *dev) pm_genpd_poweron(genpd); genpd->suspended_count--; - genpd_start_dev(genpd, dev); - return genpd_resume_early(genpd, dev); + return genpd_start_dev(genpd, dev); } /** @@ -1099,11 +1154,15 @@ static void pm_genpd_complete(struct device *dev) #define pm_genpd_prepare NULL #define pm_genpd_suspend NULL +#define pm_genpd_suspend_late NULL #define pm_genpd_suspend_noirq NULL +#define pm_genpd_resume_early NULL #define pm_genpd_resume_noirq NULL #define pm_genpd_resume NULL #define pm_genpd_freeze NULL +#define pm_genpd_freeze_late NULL #define pm_genpd_freeze_noirq NULL +#define pm_genpd_thaw_early NULL #define pm_genpd_thaw_noirq NULL #define pm_genpd_thaw NULL #define pm_genpd_restore_noirq NULL @@ -1450,7 +1509,7 @@ static int pm_genpd_default_suspend_late(struct device *dev) { int (*cb)(struct device *__dev) = dev_gpd_data(dev)->ops.suspend_late; - return cb ? cb(dev) : pm_generic_suspend_noirq(dev); + return cb ? cb(dev) : pm_generic_suspend_late(dev); } /** @@ -1461,7 +1520,7 @@ static int pm_genpd_default_resume_early(struct device *dev) { int (*cb)(struct device *__dev) = dev_gpd_data(dev)->ops.resume_early; - return cb ? cb(dev) : pm_generic_resume_noirq(dev); + return cb ? cb(dev) : pm_generic_resume_early(dev); } /** @@ -1494,7 +1553,7 @@ static int pm_genpd_default_freeze_late(struct device *dev) { int (*cb)(struct device *__dev) = dev_gpd_data(dev)->ops.freeze_late; - return cb ? cb(dev) : pm_generic_freeze_noirq(dev); + return cb ? cb(dev) : pm_generic_freeze_late(dev); } /** @@ -1505,7 +1564,7 @@ static int pm_genpd_default_thaw_early(struct device *dev) { int (*cb)(struct device *__dev) = dev_gpd_data(dev)->ops.thaw_early; - return cb ? cb(dev) : pm_generic_thaw_noirq(dev); + return cb ? cb(dev) : pm_generic_thaw_early(dev); } /** @@ -1564,16 +1623,22 @@ void pm_genpd_init(struct generic_pm_domain *genpd, genpd->domain.ops.runtime_idle = pm_generic_runtime_idle; genpd->domain.ops.prepare = pm_genpd_prepare; genpd->domain.ops.suspend = pm_genpd_suspend; + genpd->domain.ops.suspend_late = pm_genpd_suspend_late; genpd->domain.ops.suspend_noirq = pm_genpd_suspend_noirq; genpd->domain.ops.resume_noirq = pm_genpd_resume_noirq; + genpd->domain.ops.resume_early = pm_genpd_resume_early; genpd->domain.ops.resume = pm_genpd_resume; genpd->domain.ops.freeze = pm_genpd_freeze; + genpd->domain.ops.freeze_late = pm_genpd_freeze_late; genpd->domain.ops.freeze_noirq = pm_genpd_freeze_noirq; genpd->domain.ops.thaw_noirq = pm_genpd_thaw_noirq; + genpd->domain.ops.thaw_early = pm_genpd_thaw_early; genpd->domain.ops.thaw = pm_genpd_thaw; genpd->domain.ops.poweroff = pm_genpd_suspend; + genpd->domain.ops.poweroff_late = pm_genpd_suspend_late; genpd->domain.ops.poweroff_noirq = pm_genpd_suspend_noirq; genpd->domain.ops.restore_noirq = pm_genpd_restore_noirq; + genpd->domain.ops.restore_early = pm_genpd_resume_early; genpd->domain.ops.restore = pm_genpd_resume; genpd->domain.ops.complete = pm_genpd_complete; genpd->dev_ops.save_state = pm_genpd_default_save_state; -- cgit v1.2.3-70-g09d2 From c212acccc368a087a53559aac2b7d3be941b1252 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sat, 28 Jan 2012 02:16:41 +0100 Subject: regmap: Properly round reg_bytes and val_bytes For the upcoming 2/6-format, we don't see debugfs output otherwise, since the current division results in 0. I'd think 10/14 is broken currently, too. Signed-off-by: Wolfram Sang Signed-off-by: Mark Brown --- 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 b4475d87f4a..3c34526091d 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -167,9 +167,9 @@ struct regmap *regmap_init(struct device *dev, mutex_init(&map->lock); map->format.buf_size = (config->reg_bits + config->val_bits) / 8; - map->format.reg_bytes = config->reg_bits / 8; + map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8); map->format.pad_bytes = config->pad_bits / 8; - map->format.val_bytes = config->val_bits / 8; + map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8); map->format.buf_size += map->format.pad_bytes; map->dev = dev; map->bus = bus; -- cgit v1.2.3-70-g09d2 From 33f3f518fbb65d86f163083b74823e8bbe561bfc Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:39 +0100 Subject: drm/i915: add per-ring fault reg to error_state This was pretty handy when figuring out what exactly went wrong with ppgtt and it might also be useful when we stop filling the entire gart with scratch page entries. Also add the gen6+ DONE reg while at it. v2: Chris Wilson suggested to allocate the error_state with kzalloc for better paranoia. Also kill existing spurious clears of the error_state while at it. Reviewed-by: Ben Widawsky Reviewed-by: Eugeni Dodonov Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 8 ++++++-- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_irq.c | 13 +++++++------ drivers/gpu/drm/i915/i915_reg.h | 2 ++ 4 files changed, 17 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index f0486059e44..d4104904e58 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -718,8 +718,10 @@ static void i915_ring_error_state(struct seq_file *m, if (INTEL_INFO(dev)->gen >= 4) seq_printf(m, " INSTPS: 0x%08x\n", error->instps[ring]); seq_printf(m, " INSTPM: 0x%08x\n", error->instpm[ring]); - if (INTEL_INFO(dev)->gen >= 6) + if (INTEL_INFO(dev)->gen >= 6) { seq_printf(m, " FADDR: 0x%08x\n", error->faddr[ring]); + seq_printf(m, " FAULT_REG: 0x%08x\n", error->fault_reg[ring]); + } seq_printf(m, " seqno: 0x%08x\n", error->seqno[ring]); } @@ -749,8 +751,10 @@ static int i915_error_state(struct seq_file *m, void *unused) for (i = 0; i < dev_priv->num_fence_regs; i++) seq_printf(m, " fence[%d] = %08llx\n", i, error->fence[i]); - if (INTEL_INFO(dev)->gen >= 6) + if (INTEL_INFO(dev)->gen >= 6) { seq_printf(m, "ERROR: 0x%08x\n", error->error); + seq_printf(m, "DONE_REG: 0x%08x\n", error->done_reg); + } i915_ring_error_state(m, dev, error, RCS); if (HAS_BLT(dev)) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 12e8cce7928..865de800756 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -165,6 +165,8 @@ struct drm_i915_error_state { u32 instdone1; u32 seqno[I915_NUM_RINGS]; u64 bbaddr; + u32 fault_reg[I915_NUM_RINGS]; + u32 done_reg; u32 faddr[I915_NUM_RINGS]; u64 fence[I915_MAX_NUM_FENCES]; struct timeval time; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 4dedb314806..64bb2127911 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -882,8 +882,10 @@ static void i915_record_ring_state(struct drm_device *dev, { struct drm_i915_private *dev_priv = dev->dev_private; - if (INTEL_INFO(dev)->gen >= 6) + if (INTEL_INFO(dev)->gen >= 6) { error->faddr[ring->id] = I915_READ(RING_DMA_FADD(ring->mmio_base)); + error->fault_reg[ring->id] = I915_READ(RING_FAULT_REG(ring)); + } if (INTEL_INFO(dev)->gen >= 4) { error->ipeir[ring->id] = I915_READ(RING_IPEIR(ring->mmio_base)); @@ -898,7 +900,6 @@ static void i915_record_ring_state(struct drm_device *dev, error->ipeir[ring->id] = I915_READ(IPEIR); error->ipehr[ring->id] = I915_READ(IPEHR); error->instdone[ring->id] = I915_READ(INSTDONE); - error->bbaddr = 0; } error->instpm[ring->id] = I915_READ(RING_INSTPM(ring->mmio_base)); @@ -932,7 +933,7 @@ static void i915_capture_error_state(struct drm_device *dev) return; /* Account for pipe specific data like PIPE*STAT */ - error = kmalloc(sizeof(*error), GFP_ATOMIC); + error = kzalloc(sizeof(*error), GFP_ATOMIC); if (!error) { DRM_DEBUG_DRIVER("out of memory, not capturing error state\n"); return; @@ -946,10 +947,10 @@ static void i915_capture_error_state(struct drm_device *dev) for_each_pipe(pipe) error->pipestat[pipe] = I915_READ(PIPESTAT(pipe)); - if (INTEL_INFO(dev)->gen >= 6) + if (INTEL_INFO(dev)->gen >= 6) { error->error = I915_READ(ERROR_GEN6); - else - error->error = 0; + error->done_reg = I915_READ(DONE_REG); + } i915_record_ring_state(dev, error, &dev_priv->ring[RCS]); if (HAS_BLT(dev)) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index d107a1d756a..f9607387c00 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -319,6 +319,8 @@ #define RING_HWS_PGA(base) ((base)+0x80) #define RING_HWS_PGA_GEN6(base) ((base)+0x2080) #define RENDER_HWS_PGA_GEN7 (0x04080) +#define RING_FAULT_REG(ring) (0x4094 + 0x100*(ring)->id) +#define DONE_REG 0x40b0 #define BSD_HWS_PGA_GEN7 (0x04180) #define BLT_HWS_PGA_GEN7 (0x04280) #define RING_ACTHD(base) ((base)+0x74) -- cgit v1.2.3-70-g09d2 From d11519adc214c243ec606f186316f2667b677694 Mon Sep 17 00:00:00 2001 From: Praveena Nadahally Date: Wed, 25 Jan 2012 11:02:03 +0100 Subject: usb: gadget: Add Interface Association Descriptor to ECM Add IAD to bind the two interfaces of ECM so that it works properly in composite gadget mode. Signed-off-by: Thirupathi Signed-off-by: Praveena Nadahally Signed-off-by: Linus Walleij Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_ecm.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c index 11c07cb7d33..30b908f2a53 100644 --- a/drivers/usb/gadget/f_ecm.c +++ b/drivers/usb/gadget/f_ecm.c @@ -97,6 +97,20 @@ static inline unsigned ecm_bitrate(struct usb_gadget *g) /* interface descriptor: */ +static struct usb_interface_assoc_descriptor +ecm_iad_descriptor = { + .bLength = sizeof ecm_iad_descriptor, + .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, + + /* .bFirstInterface = DYNAMIC, */ + .bInterfaceCount = 2, /* control + data */ + .bFunctionClass = USB_CLASS_COMM, + .bFunctionSubClass = USB_CDC_SUBCLASS_ETHERNET, + .bFunctionProtocol = USB_CDC_PROTO_NONE, + /* .iFunction = DYNAMIC */ +}; + + static struct usb_interface_descriptor ecm_control_intf = { .bLength = sizeof ecm_control_intf, .bDescriptorType = USB_DT_INTERFACE, @@ -199,6 +213,7 @@ static struct usb_endpoint_descriptor fs_ecm_out_desc = { static struct usb_descriptor_header *ecm_fs_function[] = { /* CDC ECM control descriptors */ + (struct usb_descriptor_header *) &ecm_iad_descriptor, (struct usb_descriptor_header *) &ecm_control_intf, (struct usb_descriptor_header *) &ecm_header_desc, (struct usb_descriptor_header *) &ecm_union_desc, @@ -247,6 +262,7 @@ static struct usb_endpoint_descriptor hs_ecm_out_desc = { static struct usb_descriptor_header *ecm_hs_function[] = { /* CDC ECM control descriptors */ + (struct usb_descriptor_header *) &ecm_iad_descriptor, (struct usb_descriptor_header *) &ecm_control_intf, (struct usb_descriptor_header *) &ecm_header_desc, (struct usb_descriptor_header *) &ecm_union_desc, @@ -339,6 +355,7 @@ static struct usb_string ecm_string_defs[] = { [0].s = "CDC Ethernet Control Model (ECM)", [1].s = NULL /* DYNAMIC */, [2].s = "CDC Ethernet Data", + [3].s = "CDC ECM", { } /* end of list */ }; @@ -674,6 +691,7 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f) if (status < 0) goto fail; ecm->ctrl_id = status; + ecm_iad_descriptor.bFirstInterface = status; ecm_control_intf.bInterfaceNumber = status; ecm_union_desc.bMasterInterface0 = status; @@ -864,6 +882,13 @@ ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]) return status; ecm_string_defs[1].id = status; ecm_desc.iMACAddress = status; + + /* IAD label */ + status = usb_string_id(c->cdev); + if (status < 0) + return status; + ecm_string_defs[3].id = status; + ecm_iad_descriptor.iFunction = status; } /* allocate and initialize one new instance */ -- cgit v1.2.3-70-g09d2 From 1e0c66f49762fa1866ab20b1feb6e86a9aa4838f Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Sat, 28 Jan 2012 15:07:57 +0530 Subject: regulator: tps65910: Sleep control through external inputs Add support for sleep controls of different regulator through external inputs EN1, EN2 or EN3. Each regulator's output will be active when its external input is high and turns to OFF/Low power mode when its external input is low. The configuration parameters for sleep control is provided through board specific platform data. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/tps65910-regulator.c | 206 +++++++++++++++++++++++++++++++++ include/linux/mfd/tps65910.h | 8 ++ 2 files changed, 214 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 1d13cf997af..9092b7f998c 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -26,6 +26,9 @@ #include #define TPS65910_SUPPLY_STATE_ENABLED 0x1 +#define EXT_SLEEP_CONTROL (TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1 | \ + TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2 | \ + TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3) /* supported VIO voltages in milivolts */ static const u16 VIO_VSEL_table[] = { @@ -252,6 +255,39 @@ static struct tps_info tps65911_regs[] = { }, }; +#define EXT_CONTROL_REG_BITS(id, regs_offs, bits) (((regs_offs) << 8) | (bits)) +static unsigned int tps65910_ext_sleep_control[] = { + 0, + EXT_CONTROL_REG_BITS(VIO, 1, 0), + EXT_CONTROL_REG_BITS(VDD1, 1, 1), + EXT_CONTROL_REG_BITS(VDD2, 1, 2), + EXT_CONTROL_REG_BITS(VDD3, 1, 3), + EXT_CONTROL_REG_BITS(VDIG1, 0, 1), + EXT_CONTROL_REG_BITS(VDIG2, 0, 2), + EXT_CONTROL_REG_BITS(VPLL, 0, 6), + EXT_CONTROL_REG_BITS(VDAC, 0, 7), + EXT_CONTROL_REG_BITS(VAUX1, 0, 3), + EXT_CONTROL_REG_BITS(VAUX2, 0, 4), + EXT_CONTROL_REG_BITS(VAUX33, 0, 5), + EXT_CONTROL_REG_BITS(VMMC, 0, 0), +}; + +static unsigned int tps65911_ext_sleep_control[] = { + 0, + EXT_CONTROL_REG_BITS(VIO, 1, 0), + EXT_CONTROL_REG_BITS(VDD1, 1, 1), + EXT_CONTROL_REG_BITS(VDD2, 1, 2), + EXT_CONTROL_REG_BITS(VDDCTRL, 1, 3), + EXT_CONTROL_REG_BITS(LDO1, 0, 1), + EXT_CONTROL_REG_BITS(LDO2, 0, 2), + EXT_CONTROL_REG_BITS(LDO3, 0, 7), + EXT_CONTROL_REG_BITS(LDO4, 0, 6), + EXT_CONTROL_REG_BITS(LDO5, 0, 3), + EXT_CONTROL_REG_BITS(LDO6, 0, 0), + EXT_CONTROL_REG_BITS(LDO7, 0, 5), + EXT_CONTROL_REG_BITS(LDO8, 0, 4), +}; + struct tps65910_reg { struct regulator_desc *desc; struct tps65910 *mfd; @@ -261,6 +297,8 @@ struct tps65910_reg { int num_regulators; int mode; int (*get_ctrl_reg)(int); + unsigned int *ext_sleep_control; + unsigned int board_ext_control[TPS65910_NUM_REGS]; }; static inline int tps65910_read(struct tps65910_reg *pmic, u8 reg) @@ -861,6 +899,131 @@ static struct regulator_ops tps65911_ops = { .list_voltage = tps65911_list_voltage, }; +static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic, + int id, int ext_sleep_config) +{ + struct tps65910 *mfd = pmic->mfd; + u8 regoffs = (pmic->ext_sleep_control[id] >> 8) & 0xFF; + u8 bit_pos = (1 << pmic->ext_sleep_control[id] & 0xFF); + int ret; + + /* + * Regulator can not be control from multiple external input EN1, EN2 + * and EN3 together. + */ + if (ext_sleep_config & EXT_SLEEP_CONTROL) { + int en_count; + en_count = ((ext_sleep_config & + TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1) != 0); + en_count += ((ext_sleep_config & + TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2) != 0); + en_count += ((ext_sleep_config & + TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3) != 0); + if (en_count > 1) { + dev_err(mfd->dev, + "External sleep control flag is not proper\n"); + return -EINVAL; + } + } + + pmic->board_ext_control[id] = ext_sleep_config; + + /* External EN1 control */ + if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1) + ret = tps65910_set_bits(mfd, + TPS65910_EN1_LDO_ASS + regoffs, bit_pos); + else + ret = tps65910_clear_bits(mfd, + TPS65910_EN1_LDO_ASS + regoffs, bit_pos); + if (ret < 0) { + dev_err(mfd->dev, + "Error in configuring external control EN1\n"); + return ret; + } + + /* External EN2 control */ + if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2) + ret = tps65910_set_bits(mfd, + TPS65910_EN2_LDO_ASS + regoffs, bit_pos); + else + ret = tps65910_clear_bits(mfd, + TPS65910_EN2_LDO_ASS + regoffs, bit_pos); + if (ret < 0) { + dev_err(mfd->dev, + "Error in configuring external control EN2\n"); + return ret; + } + + /* External EN3 control for TPS65910 LDO only */ + if ((tps65910_chip_id(mfd) == TPS65910) && + (id >= TPS65910_REG_VDIG1)) { + if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3) + ret = tps65910_set_bits(mfd, + TPS65910_EN3_LDO_ASS + regoffs, bit_pos); + else + ret = tps65910_clear_bits(mfd, + TPS65910_EN3_LDO_ASS + regoffs, bit_pos); + if (ret < 0) { + dev_err(mfd->dev, + "Error in configuring external control EN3\n"); + return ret; + } + } + + /* Return if no external control is selected */ + if (!(ext_sleep_config & EXT_SLEEP_CONTROL)) { + /* Clear all sleep controls */ + ret = tps65910_clear_bits(mfd, + TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos); + if (!ret) + ret = tps65910_clear_bits(mfd, + TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos); + if (ret < 0) + dev_err(mfd->dev, + "Error in configuring SLEEP register\n"); + return ret; + } + + /* + * For regulator that has separate operational and sleep register make + * sure that operational is used and clear sleep register to turn + * regulator off when external control is inactive + */ + if ((id == TPS65910_REG_VDD1) || + (id == TPS65910_REG_VDD2) || + ((id == TPS65911_REG_VDDCTRL) && + (tps65910_chip_id(mfd) == TPS65911))) { + int op_reg_add = pmic->get_ctrl_reg(id) + 1; + int sr_reg_add = pmic->get_ctrl_reg(id) + 2; + int opvsel = tps65910_reg_read(pmic, op_reg_add); + int srvsel = tps65910_reg_read(pmic, sr_reg_add); + if (opvsel & VDD1_OP_CMD_MASK) { + u8 reg_val = srvsel & VDD1_OP_SEL_MASK; + ret = tps65910_reg_write(pmic, op_reg_add, reg_val); + if (ret < 0) { + dev_err(mfd->dev, + "Error in configuring op register\n"); + return ret; + } + } + ret = tps65910_reg_write(pmic, sr_reg_add, 0); + if (ret < 0) { + dev_err(mfd->dev, "Error in settting sr register\n"); + return ret; + } + } + + ret = tps65910_clear_bits(mfd, + TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos); + if (!ret) + ret = tps65910_set_bits(mfd, + TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos); + if (ret < 0) + dev_err(mfd->dev, + "Error in configuring SLEEP register\n"); + return ret; +} + static __devinit int tps65910_probe(struct platform_device *pdev) { struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); @@ -891,11 +1054,13 @@ static __devinit int tps65910_probe(struct platform_device *pdev) case TPS65910: pmic->get_ctrl_reg = &tps65910_get_ctrl_register; pmic->num_regulators = ARRAY_SIZE(tps65910_regs); + pmic->ext_sleep_control = tps65910_ext_sleep_control; info = tps65910_regs; break; case TPS65911: pmic->get_ctrl_reg = &tps65911_get_ctrl_register; pmic->num_regulators = ARRAY_SIZE(tps65911_regs); + pmic->ext_sleep_control = tps65911_ext_sleep_control; info = tps65911_regs; break; default: @@ -958,6 +1123,16 @@ static __devinit int tps65910_probe(struct platform_device *pdev) pmic->desc[i].ops = &tps65911_ops; } + err = tps65910_set_ext_sleep_config(pmic, i, + pmic_plat_data->regulator_ext_sleep_control[i]); + /* + * Failing on regulator for configuring externally control + * is not a serious issue, just throw warning. + */ + if (err < 0) + dev_warn(tps65910->dev, + "Failed to initialise ext control config\n"); + pmic->desc[i].type = REGULATOR_VOLTAGE; pmic->desc[i].owner = THIS_MODULE; @@ -1004,6 +1179,36 @@ static int __devexit tps65910_remove(struct platform_device *pdev) return 0; } +static void tps65910_shutdown(struct platform_device *pdev) +{ + struct tps65910_reg *pmic = platform_get_drvdata(pdev); + int i; + + /* + * Before bootloader jumps to kernel, it makes sure that required + * external control signals are in desired state so that given rails + * can be configure accordingly. + * If rails are configured to be controlled from external control + * then before shutting down/rebooting the system, the external + * control configuration need to be remove from the rails so that + * its output will be available as per register programming even + * if external controls are removed. This is require when the POR + * value of the control signals are not in active state and before + * bootloader initializes it, the system requires the rail output + * to be active for booting. + */ + for (i = 0; i < pmic->num_regulators; i++) { + int err; + if (!pmic->rdev[i]) + continue; + + err = tps65910_set_ext_sleep_config(pmic, i, 0); + if (err < 0) + dev_err(&pdev->dev, + "Error in clearing external control\n"); + } +} + static struct platform_driver tps65910_driver = { .driver = { .name = "tps65910-pmic", @@ -1011,6 +1216,7 @@ static struct platform_driver tps65910_driver = { }, .probe = tps65910_probe, .remove = __devexit_p(tps65910_remove), + .shutdown = tps65910_shutdown, }; static int __init tps65910_init(void) diff --git a/include/linux/mfd/tps65910.h b/include/linux/mfd/tps65910.h index d0cb12eba40..fa6c6bf7a54 100644 --- a/include/linux/mfd/tps65910.h +++ b/include/linux/mfd/tps65910.h @@ -768,6 +768,13 @@ /* Max number of TPS65910/11 regulators */ #define TPS65910_NUM_REGS 13 +/* External sleep controls through EN1/EN2/EN3 inputs*/ +#define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1 0x1 +#define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2 0x2 +#define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3 0x4 +/* TPS65911 names the EN3 signal as SLEEP */ +#define TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP 0x4 + /** * struct tps65910_board * Board platform data may be used to initialize regulators. @@ -779,6 +786,7 @@ struct tps65910_board { int irq_base; int vmbch_threshold; int vmbch2_threshold; + unsigned long regulator_ext_sleep_control[TPS65910_NUM_REGS]; struct regulator_init_data *tps65910_pmic_init_data[TPS65910_NUM_REGS]; }; -- cgit v1.2.3-70-g09d2 From 41b2d62702730b0c6bc5a40722e423bb0338311a Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 30 Jan 2012 10:53:55 -0500 Subject: ath9k: use WARN_ON_ONCE in ath_rc_get_highest_rix The device seems to survive the issue, so no need to flood the logs about it... Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/rc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index b3c3798fe51..635b592ad96 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -694,7 +694,7 @@ static u8 ath_rc_get_highest_rix(struct ath_softc *sc, return rate; /* This should not happen */ - WARN_ON(1); + WARN_ON_ONCE(1); rate = ath_rc_priv->valid_rate_index[0]; -- cgit v1.2.3-70-g09d2 From 4191f19792bf91267835eb090d970e9cd6277a65 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 30 Jan 2012 15:08:16 +0100 Subject: regmap: if format_write is used, declare all registers as "unreadable" Using .format_write means, we have a custom function to write to the chip, but not to read back. Also, mark registers as "not precious" and "not volatile" which is implicit because we cannot read them. Make those functions use 'regmap_readable' to reuse the checks done there. Signed-off-by: Wolfram Sang Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 3c34526091d..b7198f57b69 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -36,6 +36,9 @@ bool regmap_readable(struct regmap *map, unsigned int reg) if (map->max_register && reg > map->max_register) return false; + if (map->format.format_write) + return false; + if (map->readable_reg) return map->readable_reg(map->dev, reg); @@ -44,7 +47,7 @@ bool regmap_readable(struct regmap *map, unsigned int reg) bool regmap_volatile(struct regmap *map, unsigned int reg) { - if (map->max_register && reg > map->max_register) + if (!regmap_readable(map, reg)) return false; if (map->volatile_reg) @@ -55,7 +58,7 @@ bool regmap_volatile(struct regmap *map, unsigned int reg) bool regmap_precious(struct regmap *map, unsigned int reg) { - if (map->max_register && reg > map->max_register) + if (!regmap_readable(map, reg)) return false; if (map->precious_reg) -- cgit v1.2.3-70-g09d2 From 8b1c36b357153f491ddea5363fdd397109c3326f Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 30 Jan 2012 16:53:37 +0000 Subject: sfc: MTD: Leave the DEBUG macro alone no longer defines DEBUG so we do not need to un-define it here. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/mtd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/mtd.c b/drivers/net/ethernet/sfc/mtd.c index eff49da458e..79c19227204 100644 --- a/drivers/net/ethernet/sfc/mtd.c +++ b/drivers/net/ethernet/sfc/mtd.c @@ -10,7 +10,6 @@ #include #include -#undef DEBUG /* has its own use for DEBUG */ #include #include #include -- cgit v1.2.3-70-g09d2 From 068c6ff1cbbfc09eed2b892dd7b0572dd6737785 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 29 Jan 2012 16:52:05 +0000 Subject: drm/i915: Remove the upper limit on the bo size for mapping into the CPU domain The original intention of comparing the bo against the mappable GTT limits was to prevent a subsequent faulting of the bo into the GTT from clearing the entire GTT in vain. However, that was clearly a cut'n'paste mistake as a CPU mapping never binds the bo into the aperture. Whilst there may be some merit to limiting the maximum size of the bo to something that can be utilized by the GPU, that limit itself does not belong as a safeguard to mmapping the bo, so remove the check entirely. Signed-off-by: Chris Wilson Reviewed-by: Eric Anholt Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 721924150d0..df23c627341 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1141,7 +1141,6 @@ int i915_gem_mmap_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { - struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_mmap *args = data; struct drm_gem_object *obj; unsigned long addr; @@ -1153,11 +1152,6 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, if (obj == NULL) return -ENOENT; - if (obj->size > dev_priv->mm.gtt_mappable_end) { - drm_gem_object_unreference_unlocked(obj); - return -E2BIG; - } - down_write(¤t->mm->mmap_sem); addr = do_mmap(obj->filp, 0, args->size, PROT_READ | PROT_WRITE, MAP_SHARED, -- cgit v1.2.3-70-g09d2 From 06e63c57acbb1df7c35ebe846ae416a8b88dfafa Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 30 Jan 2012 16:55:05 +0000 Subject: sfc: Use a more sensible cast in efx_rx_buf_offset() This function returns the page offset of the buffer, which can be calculated based on either its DMA address or its virtual address. It used to use the virtual address and we would cast that to unsigned long, as anything smaller would result in a compiler warning. Now that it's using the DMA address we should use unsigned int, matching the return type. It is also unnecessary to use __force. 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 a33aef25ead..1dfda5e2791 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -98,7 +98,7 @@ static inline unsigned int efx_rx_buf_offset(struct efx_nic *efx, /* Offset is always within one page, so we don't need to consider * the page order. */ - return ((__force unsigned long) buf->dma_addr & (PAGE_SIZE - 1)) + + return ((unsigned int) buf->dma_addr & (PAGE_SIZE - 1)) + efx->type->rx_buffer_hash_size; } static inline unsigned int efx_rx_buf_size(struct efx_nic *efx) -- cgit v1.2.3-70-g09d2 From 3396c7823efb3a5b8630388c464e1034ea031ced Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Fri, 27 Jan 2012 13:36:01 +0000 Subject: drivers/net: fix up stale paths from driver reorg The reorganization of the driver layout in drivers/net left behind some stale paths in comments and in Kconfig help text. Bring them up to date. No actual change to any code takes place here. Signed-off-by: Paul Gortmaker CC: Jeff Kirsher Signed-off-by: David S. Miller --- Documentation/magic-number.txt | 2 +- Documentation/networking/phy.txt | 3 ++- Documentation/zh_CN/magic-number.txt | 2 +- drivers/net/can/slcan.c | 2 +- drivers/net/ethernet/3com/Kconfig | 2 +- drivers/net/ethernet/8390/ax88796.c | 2 +- drivers/net/ethernet/8390/axnet_cs.c | 2 +- drivers/net/ethernet/8390/pcnet_cs.c | 2 +- drivers/net/ethernet/amd/Kconfig | 2 +- drivers/net/ethernet/amd/am79c961a.c | 2 +- drivers/net/ethernet/amd/am79c961a.h | 2 +- drivers/net/ethernet/dec/tulip/21142.c | 2 +- drivers/net/ethernet/dec/tulip/eeprom.c | 2 +- drivers/net/ethernet/dec/tulip/interrupt.c | 2 +- drivers/net/ethernet/dec/tulip/media.c | 2 +- drivers/net/ethernet/dec/tulip/pnic.c | 2 +- drivers/net/ethernet/dec/tulip/pnic2.c | 2 +- drivers/net/ethernet/dec/tulip/timer.c | 2 +- drivers/net/ethernet/dec/tulip/tulip.h | 2 +- drivers/net/ethernet/ethoc.c | 2 +- drivers/net/ethernet/freescale/fec_mpc52xx.h | 2 +- drivers/net/ethernet/freescale/gianfar.c | 2 +- drivers/net/ethernet/freescale/gianfar.h | 2 +- drivers/net/ethernet/freescale/gianfar_ethtool.c | 2 +- drivers/net/ethernet/freescale/gianfar_sysfs.c | 2 +- drivers/net/ethernet/ibm/ehea/ehea.h | 2 +- drivers/net/ethernet/ibm/ehea/ehea_ethtool.c | 2 +- drivers/net/ethernet/ibm/ehea/ehea_hw.h | 2 +- drivers/net/ethernet/ibm/ehea/ehea_main.c | 2 +- drivers/net/ethernet/ibm/ehea/ehea_phyp.c | 2 +- drivers/net/ethernet/ibm/ehea/ehea_phyp.h | 2 +- drivers/net/ethernet/ibm/ehea/ehea_qmr.c | 2 +- drivers/net/ethernet/ibm/ehea/ehea_qmr.h | 2 +- drivers/net/ethernet/ibm/emac/core.c | 2 +- drivers/net/ethernet/ibm/emac/core.h | 2 +- drivers/net/ethernet/ibm/emac/debug.c | 2 +- drivers/net/ethernet/ibm/emac/debug.h | 2 +- drivers/net/ethernet/ibm/emac/emac.h | 2 +- drivers/net/ethernet/ibm/emac/mal.c | 2 +- drivers/net/ethernet/ibm/emac/mal.h | 2 +- drivers/net/ethernet/ibm/emac/phy.c | 2 +- drivers/net/ethernet/ibm/emac/phy.h | 2 +- drivers/net/ethernet/ibm/emac/rgmii.c | 2 +- drivers/net/ethernet/ibm/emac/rgmii.h | 2 +- drivers/net/ethernet/ibm/emac/tah.c | 2 +- drivers/net/ethernet/ibm/emac/tah.h | 2 +- drivers/net/ethernet/ibm/emac/zmii.c | 2 +- drivers/net/ethernet/ibm/emac/zmii.h | 2 +- drivers/net/ethernet/micrel/ks8851.c | 2 +- drivers/net/ethernet/micrel/ks8851.h | 2 +- drivers/net/ethernet/micrel/ks8851_mll.c | 2 +- drivers/net/ethernet/micrel/ksz884x.c | 2 +- drivers/net/ethernet/netx-eth.c | 2 +- drivers/net/ethernet/realtek/Kconfig | 10 +++++----- 54 files changed, 59 insertions(+), 58 deletions(-) (limited to 'drivers') diff --git a/Documentation/magic-number.txt b/Documentation/magic-number.txt index abf481f780e..82761a31d64 100644 --- a/Documentation/magic-number.txt +++ b/Documentation/magic-number.txt @@ -89,7 +89,7 @@ TTY_DRIVER_MAGIC 0x5402 tty_driver include/linux/tty_driver.h MGSLPC_MAGIC 0x5402 mgslpc_info drivers/char/pcmcia/synclink_cs.c TTY_LDISC_MAGIC 0x5403 tty_ldisc include/linux/tty_ldisc.h USB_SERIAL_MAGIC 0x6702 usb_serial drivers/usb/serial/usb-serial.h -FULL_DUPLEX_MAGIC 0x6969 drivers/net/tulip/de2104x.c +FULL_DUPLEX_MAGIC 0x6969 drivers/net/ethernet/dec/tulip/de2104x.c USB_BLUETOOTH_MAGIC 0x6d02 usb_bluetooth drivers/usb/class/bluetty.c RFCOMM_TTY_MAGIC 0x6d02 net/bluetooth/rfcomm/tty.c USB_SERIAL_PORT_MAGIC 0x7301 usb_serial_port drivers/usb/serial/usb-serial.h diff --git a/Documentation/networking/phy.txt b/Documentation/networking/phy.txt index 9eb1ba52013..95e5f5985a2 100644 --- a/Documentation/networking/phy.txt +++ b/Documentation/networking/phy.txt @@ -62,7 +62,8 @@ The MDIO bus 5) The bus must also be declared somewhere as a device, and registered. As an example for how one driver implemented an mdio bus driver, see - drivers/net/gianfar_mii.c and arch/ppc/syslib/mpc85xx_devices.c + drivers/net/ethernet/freescale/fsl_pq_mdio.c and an associated DTS file + for one of the users. (e.g. "git grep fsl,.*-mdio arch/powerpc/boot/dts/") Connecting to a PHY diff --git a/Documentation/zh_CN/magic-number.txt b/Documentation/zh_CN/magic-number.txt index c278f412dc6..f606ba8598c 100644 --- a/Documentation/zh_CN/magic-number.txt +++ b/Documentation/zh_CN/magic-number.txt @@ -89,7 +89,7 @@ TTY_DRIVER_MAGIC 0x5402 tty_driver include/linux/tty_driver.h MGSLPC_MAGIC 0x5402 mgslpc_info drivers/char/pcmcia/synclink_cs.c TTY_LDISC_MAGIC 0x5403 tty_ldisc include/linux/tty_ldisc.h USB_SERIAL_MAGIC 0x6702 usb_serial drivers/usb/serial/usb-serial.h -FULL_DUPLEX_MAGIC 0x6969 drivers/net/tulip/de2104x.c +FULL_DUPLEX_MAGIC 0x6969 drivers/net/ethernet/dec/tulip/de2104x.c USB_BLUETOOTH_MAGIC 0x6d02 usb_bluetooth drivers/usb/class/bluetty.c RFCOMM_TTY_MAGIC 0x6d02 net/bluetooth/rfcomm/tty.c USB_SERIAL_PORT_MAGIC 0x7301 usb_serial_port drivers/usb/serial/usb-serial.h diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index 3f1ebcc2cb8..579e7fca644 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -1,7 +1,7 @@ /* * slcan.c - serial line CAN interface driver (using tty line discipline) * - * This file is derived from linux/drivers/net/slip.c + * This file is derived from linux/drivers/net/slip/slip.c * * slip.c Authors : Laurence Culhane * Fred N. van Kempen diff --git a/drivers/net/ethernet/3com/Kconfig b/drivers/net/ethernet/3com/Kconfig index a8bb30cf512..bad4fa6815c 100644 --- a/drivers/net/ethernet/3com/Kconfig +++ b/drivers/net/ethernet/3com/Kconfig @@ -97,7 +97,7 @@ config VORTEX available from . More specific information is in and in the comments at - the beginning of . + the beginning of . To compile this support as a module, choose M here. diff --git a/drivers/net/ethernet/8390/ax88796.c b/drivers/net/ethernet/8390/ax88796.c index 0f92e3567f6..c30adcc9828 100644 --- a/drivers/net/ethernet/8390/ax88796.c +++ b/drivers/net/ethernet/8390/ax88796.c @@ -1,4 +1,4 @@ -/* drivers/net/ax88796.c +/* drivers/net/ethernet/8390/ax88796.c * * Copyright 2005,2007 Simtec Electronics * Ben Dooks diff --git a/drivers/net/ethernet/8390/axnet_cs.c b/drivers/net/ethernet/8390/axnet_cs.c index bba51cdc74a..5de394368ff 100644 --- a/drivers/net/ethernet/8390/axnet_cs.c +++ b/drivers/net/ethernet/8390/axnet_cs.c @@ -192,7 +192,7 @@ static int get_prom(struct pcmcia_device *link) unsigned int ioaddr = dev->base_addr; int i, j; - /* This is based on drivers/net/ne.c */ + /* This is based on drivers/net/ethernet/8390/ne.c */ struct { u_char value, offset; } program_seq[] = { diff --git a/drivers/net/ethernet/8390/pcnet_cs.c b/drivers/net/ethernet/8390/pcnet_cs.c index 053b2551a72..f2a4e5de18c 100644 --- a/drivers/net/ethernet/8390/pcnet_cs.c +++ b/drivers/net/ethernet/8390/pcnet_cs.c @@ -326,7 +326,7 @@ static hw_info_t *get_prom(struct pcmcia_device *link) u_char prom[32]; int i, j; - /* This is lifted straight from drivers/net/ne.c */ + /* This is lifted straight from drivers/net/ethernet/8390/ne.c */ struct { u_char value, offset; } program_seq[] = { diff --git a/drivers/net/ethernet/amd/Kconfig b/drivers/net/ethernet/amd/Kconfig index 238b537b68f..8350f4b37a8 100644 --- a/drivers/net/ethernet/amd/Kconfig +++ b/drivers/net/ethernet/amd/Kconfig @@ -113,7 +113,7 @@ config DEPCA If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available from as well as - . + . To compile this driver as a module, choose M here. The module will be called depca. diff --git a/drivers/net/ethernet/amd/am79c961a.c b/drivers/net/ethernet/amd/am79c961a.c index 7d5ded80d2d..216ae87b945 100644 --- a/drivers/net/ethernet/amd/am79c961a.c +++ b/drivers/net/ethernet/amd/am79c961a.c @@ -1,5 +1,5 @@ /* - * linux/drivers/net/am79c961.c + * linux/drivers/net/ethernet/amd/am79c961a.c * * by Russell King 1995-2001. * diff --git a/drivers/net/ethernet/amd/am79c961a.h b/drivers/net/ethernet/amd/am79c961a.h index fd634d32756..9f384b79507 100644 --- a/drivers/net/ethernet/amd/am79c961a.h +++ b/drivers/net/ethernet/amd/am79c961a.h @@ -1,5 +1,5 @@ /* - * linux/drivers/net/arm/am79c961a.h + * linux/drivers/net/ethernet/amd/am79c961a.h * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/drivers/net/ethernet/dec/tulip/21142.c b/drivers/net/ethernet/dec/tulip/21142.c index 25b8deedbef..36985827265 100644 --- a/drivers/net/ethernet/dec/tulip/21142.c +++ b/drivers/net/ethernet/dec/tulip/21142.c @@ -1,5 +1,5 @@ /* - drivers/net/tulip/21142.c + drivers/net/ethernet/dec/tulip/21142.c Copyright 2000,2001 The Linux Kernel Team Written/copyright 1994-2001 by Donald Becker. diff --git a/drivers/net/ethernet/dec/tulip/eeprom.c b/drivers/net/ethernet/dec/tulip/eeprom.c index 14d5b611783..ed7d1dcd956 100644 --- a/drivers/net/ethernet/dec/tulip/eeprom.c +++ b/drivers/net/ethernet/dec/tulip/eeprom.c @@ -1,5 +1,5 @@ /* - drivers/net/tulip/eeprom.c + drivers/net/ethernet/dec/tulip/eeprom.c Copyright 2000,2001 The Linux Kernel Team Written/copyright 1994-2001 by Donald Becker. diff --git a/drivers/net/ethernet/dec/tulip/interrupt.c b/drivers/net/ethernet/dec/tulip/interrupt.c index 4fb8c8c0a42..feaee7424bd 100644 --- a/drivers/net/ethernet/dec/tulip/interrupt.c +++ b/drivers/net/ethernet/dec/tulip/interrupt.c @@ -1,5 +1,5 @@ /* - drivers/net/tulip/interrupt.c + drivers/net/ethernet/dec/tulip/interrupt.c Copyright 2000,2001 The Linux Kernel Team Written/copyright 1994-2001 by Donald Becker. diff --git a/drivers/net/ethernet/dec/tulip/media.c b/drivers/net/ethernet/dec/tulip/media.c index beeb17b52ad..ae937c6749e 100644 --- a/drivers/net/ethernet/dec/tulip/media.c +++ b/drivers/net/ethernet/dec/tulip/media.c @@ -1,5 +1,5 @@ /* - drivers/net/tulip/media.c + drivers/net/ethernet/dec/tulip/media.c Copyright 2000,2001 The Linux Kernel Team Written/copyright 1994-2001 by Donald Becker. diff --git a/drivers/net/ethernet/dec/tulip/pnic.c b/drivers/net/ethernet/dec/tulip/pnic.c index 9c16e4ad02a..5364563c437 100644 --- a/drivers/net/ethernet/dec/tulip/pnic.c +++ b/drivers/net/ethernet/dec/tulip/pnic.c @@ -1,5 +1,5 @@ /* - drivers/net/tulip/pnic.c + drivers/net/ethernet/dec/tulip/pnic.c Copyright 2000,2001 The Linux Kernel Team Written/copyright 1994-2001 by Donald Becker. diff --git a/drivers/net/ethernet/dec/tulip/pnic2.c b/drivers/net/ethernet/dec/tulip/pnic2.c index 04a7e477eaf..5895fc43f6e 100644 --- a/drivers/net/ethernet/dec/tulip/pnic2.c +++ b/drivers/net/ethernet/dec/tulip/pnic2.c @@ -1,5 +1,5 @@ /* - drivers/net/tulip/pnic2.c + drivers/net/ethernet/dec/tulip/pnic2.c Copyright 2000,2001 The Linux Kernel Team Written/copyright 1994-2001 by Donald Becker. diff --git a/drivers/net/ethernet/dec/tulip/timer.c b/drivers/net/ethernet/dec/tulip/timer.c index 19078d28ffb..768379b8aee 100644 --- a/drivers/net/ethernet/dec/tulip/timer.c +++ b/drivers/net/ethernet/dec/tulip/timer.c @@ -1,5 +1,5 @@ /* - drivers/net/tulip/timer.c + drivers/net/ethernet/dec/tulip/timer.c Copyright 2000,2001 The Linux Kernel Team Written/copyright 1994-2001 by Donald Becker. diff --git a/drivers/net/ethernet/dec/tulip/tulip.h b/drivers/net/ethernet/dec/tulip/tulip.h index fb3887c18dc..38431a155f0 100644 --- a/drivers/net/ethernet/dec/tulip/tulip.h +++ b/drivers/net/ethernet/dec/tulip/tulip.h @@ -1,5 +1,5 @@ /* - drivers/net/tulip/tulip.h + drivers/net/ethernet/dec/tulip/tulip.h Copyright 2000,2001 The Linux Kernel Team Written/copyright 1994-2001 by Donald Becker. diff --git a/drivers/net/ethernet/ethoc.c b/drivers/net/ethernet/ethoc.c index 60f0e788cc2..388c592b5ef 100644 --- a/drivers/net/ethernet/ethoc.c +++ b/drivers/net/ethernet/ethoc.c @@ -1,5 +1,5 @@ /* - * linux/drivers/net/ethoc.c + * linux/drivers/net/ethernet/ethoc.c * * Copyright (C) 2007-2008 Avionic Design Development GmbH * Copyright (C) 2008-2009 Avionic Design GmbH diff --git a/drivers/net/ethernet/freescale/fec_mpc52xx.h b/drivers/net/ethernet/freescale/fec_mpc52xx.h index 41d2dffde55..10afa54dd06 100644 --- a/drivers/net/ethernet/freescale/fec_mpc52xx.h +++ b/drivers/net/ethernet/freescale/fec_mpc52xx.h @@ -1,5 +1,5 @@ /* - * drivers/drivers/net/fec_mpc52xx/fec.h + * drivers/net/ethernet/freescale/fec_mpc52xx.h * * Driver for the MPC5200 Fast Ethernet Controller * diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 39d160d353a..adb0ae4e419 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -1,5 +1,5 @@ /* - * drivers/net/gianfar.c + * drivers/net/ethernet/freescale/gianfar.c * * Gianfar Ethernet Driver * This driver is designed for the non-CPM ethernet controllers diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h index 40c33a7554c..4fe0f342ace 100644 --- a/drivers/net/ethernet/freescale/gianfar.h +++ b/drivers/net/ethernet/freescale/gianfar.h @@ -1,5 +1,5 @@ /* - * drivers/net/gianfar.h + * drivers/net/ethernet/freescale/gianfar.h * * Gianfar Ethernet Driver * Driver for FEC on MPC8540 and TSEC on MPC8540/MPC8560 diff --git a/drivers/net/ethernet/freescale/gianfar_ethtool.c b/drivers/net/ethernet/freescale/gianfar_ethtool.c index 5a3b2e5b288..5a78d55f46e 100644 --- a/drivers/net/ethernet/freescale/gianfar_ethtool.c +++ b/drivers/net/ethernet/freescale/gianfar_ethtool.c @@ -1,5 +1,5 @@ /* - * drivers/net/gianfar_ethtool.c + * drivers/net/ethernet/freescale/gianfar_ethtool.c * * Gianfar Ethernet Driver * Ethtool support for Gianfar Enet diff --git a/drivers/net/ethernet/freescale/gianfar_sysfs.c b/drivers/net/ethernet/freescale/gianfar_sysfs.c index 64f4094ac7f..cd14a4d449c 100644 --- a/drivers/net/ethernet/freescale/gianfar_sysfs.c +++ b/drivers/net/ethernet/freescale/gianfar_sysfs.c @@ -1,5 +1,5 @@ /* - * drivers/net/gianfar_sysfs.c + * drivers/net/ethernet/freescale/gianfar_sysfs.c * * Gianfar Ethernet Driver * This driver is designed for the non-CPM ethernet controllers diff --git a/drivers/net/ethernet/ibm/ehea/ehea.h b/drivers/net/ethernet/ibm/ehea/ehea.h index 6650068c996..b8e46cc31e5 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea.h +++ b/drivers/net/ethernet/ibm/ehea/ehea.h @@ -1,5 +1,5 @@ /* - * linux/drivers/net/ehea/ehea.h + * linux/drivers/net/ethernet/ibm/ehea/ehea.h * * eHEA ethernet device driver for IBM eServer System p * diff --git a/drivers/net/ethernet/ibm/ehea/ehea_ethtool.c b/drivers/net/ethernet/ibm/ehea/ehea_ethtool.c index 6bdd8e36e56..95837b99a46 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_ethtool.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_ethtool.c @@ -1,5 +1,5 @@ /* - * linux/drivers/net/ehea/ehea_ethtool.c + * linux/drivers/net/ethernet/ibm/ehea/ehea_ethtool.c * * eHEA ethernet device driver for IBM eServer System p * diff --git a/drivers/net/ethernet/ibm/ehea/ehea_hw.h b/drivers/net/ethernet/ibm/ehea/ehea_hw.h index 1a2fe4dc3eb..180d4128a71 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_hw.h +++ b/drivers/net/ethernet/ibm/ehea/ehea_hw.h @@ -1,5 +1,5 @@ /* - * linux/drivers/net/ehea/ehea_hw.h + * linux/drivers/net/ethernet/ibm/ehea/ehea_hw.h * * eHEA ethernet device driver for IBM eServer System p * diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c index 5d5fb262718..14507d1e78c 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_main.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c @@ -1,5 +1,5 @@ /* - * linux/drivers/net/ehea/ehea_main.c + * linux/drivers/net/ethernet/ibm/ehea/ehea_main.c * * eHEA ethernet device driver for IBM eServer System p * diff --git a/drivers/net/ethernet/ibm/ehea/ehea_phyp.c b/drivers/net/ethernet/ibm/ehea/ehea_phyp.c index 0506967b904..30f903332e9 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_phyp.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_phyp.c @@ -1,5 +1,5 @@ /* - * linux/drivers/net/ehea/ehea_phyp.c + * linux/drivers/net/ethernet/ibm/ehea/ehea_phyp.c * * eHEA ethernet device driver for IBM eServer System p * diff --git a/drivers/net/ethernet/ibm/ehea/ehea_phyp.h b/drivers/net/ethernet/ibm/ehea/ehea_phyp.h index 2f8174c248b..52c456ec4d6 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_phyp.h +++ b/drivers/net/ethernet/ibm/ehea/ehea_phyp.h @@ -1,5 +1,5 @@ /* - * linux/drivers/net/ehea/ehea_phyp.h + * linux/drivers/net/ethernet/ibm/ehea/ehea_phyp.h * * eHEA ethernet device driver for IBM eServer System p * diff --git a/drivers/net/ethernet/ibm/ehea/ehea_qmr.c b/drivers/net/ethernet/ibm/ehea/ehea_qmr.c index c25b05b94da..4fb47f14dbf 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_qmr.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_qmr.c @@ -1,5 +1,5 @@ /* - * linux/drivers/net/ehea/ehea_qmr.c + * linux/drivers/net/ethernet/ibm/ehea/ehea_qmr.c * * eHEA ethernet device driver for IBM eServer System p * diff --git a/drivers/net/ethernet/ibm/ehea/ehea_qmr.h b/drivers/net/ethernet/ibm/ehea/ehea_qmr.h index 337a47ecf4a..8e4a70c20ab 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_qmr.h +++ b/drivers/net/ethernet/ibm/ehea/ehea_qmr.h @@ -1,5 +1,5 @@ /* - * linux/drivers/net/ehea/ehea_qmr.h + * linux/drivers/net/ethernet/ibm/ehea/ehea_qmr.h * * eHEA ethernet device driver for IBM eServer System p * diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c index 2abce965c7b..d47c16e02d0 100644 --- a/drivers/net/ethernet/ibm/emac/core.c +++ b/drivers/net/ethernet/ibm/emac/core.c @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/core.c + * drivers/net/ethernet/ibm/emac/core.c * * Driver for PowerPC 4xx on-chip ethernet controller. * diff --git a/drivers/net/ethernet/ibm/emac/core.h b/drivers/net/ethernet/ibm/emac/core.h index fa3ec57935f..bade29690c7 100644 --- a/drivers/net/ethernet/ibm/emac/core.h +++ b/drivers/net/ethernet/ibm/emac/core.h @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/core.h + * drivers/net/ethernet/ibm/emac/core.h * * Driver for PowerPC 4xx on-chip ethernet controller. * diff --git a/drivers/net/ethernet/ibm/emac/debug.c b/drivers/net/ethernet/ibm/emac/debug.c index 8c6c1e2a875..b16b4828b64 100644 --- a/drivers/net/ethernet/ibm/emac/debug.c +++ b/drivers/net/ethernet/ibm/emac/debug.c @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/debug.c + * drivers/net/ethernet/ibm/emac/debug.c * * Driver for PowerPC 4xx on-chip ethernet controller, debug print routines. * diff --git a/drivers/net/ethernet/ibm/emac/debug.h b/drivers/net/ethernet/ibm/emac/debug.h index 90477fe69d0..59a92d5870b 100644 --- a/drivers/net/ethernet/ibm/emac/debug.h +++ b/drivers/net/ethernet/ibm/emac/debug.h @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/debug.h + * drivers/net/ethernet/ibm/emac/debug.h * * Driver for PowerPC 4xx on-chip ethernet controller, debug print routines. * diff --git a/drivers/net/ethernet/ibm/emac/emac.h b/drivers/net/ethernet/ibm/emac/emac.h index 1568278d759..b44bd243fb5 100644 --- a/drivers/net/ethernet/ibm/emac/emac.h +++ b/drivers/net/ethernet/ibm/emac/emac.h @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/emac.h + * drivers/net/ethernet/ibm/emac/emac.h * * Register definitions for PowerPC 4xx on-chip ethernet contoller * diff --git a/drivers/net/ethernet/ibm/emac/mal.c b/drivers/net/ethernet/ibm/emac/mal.c index f3c50b97ec6..479e43e2f1e 100644 --- a/drivers/net/ethernet/ibm/emac/mal.c +++ b/drivers/net/ethernet/ibm/emac/mal.c @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/mal.c + * drivers/net/ethernet/ibm/emac/mal.c * * Memory Access Layer (MAL) support * diff --git a/drivers/net/ethernet/ibm/emac/mal.h b/drivers/net/ethernet/ibm/emac/mal.h index d06f985bda3..e431a32e3d6 100644 --- a/drivers/net/ethernet/ibm/emac/mal.h +++ b/drivers/net/ethernet/ibm/emac/mal.h @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/mal.h + * drivers/net/ethernet/ibm/emac/mal.h * * Memory Access Layer (MAL) support * diff --git a/drivers/net/ethernet/ibm/emac/phy.c b/drivers/net/ethernet/ibm/emac/phy.c index ab4e5969fe6..d3b9d103353 100644 --- a/drivers/net/ethernet/ibm/emac/phy.c +++ b/drivers/net/ethernet/ibm/emac/phy.c @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/phy.c + * drivers/net/ethernet/ibm/emac/phy.c * * Driver for PowerPC 4xx on-chip ethernet controller, PHY support. * Borrowed from sungem_phy.c, though I only kept the generic MII diff --git a/drivers/net/ethernet/ibm/emac/phy.h b/drivers/net/ethernet/ibm/emac/phy.h index 5d2bf4cbe50..d7e41ec3746 100644 --- a/drivers/net/ethernet/ibm/emac/phy.h +++ b/drivers/net/ethernet/ibm/emac/phy.h @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/phy.h + * drivers/net/ethernet/ibm/emac/phy.h * * Driver for PowerPC 4xx on-chip ethernet controller, PHY support * diff --git a/drivers/net/ethernet/ibm/emac/rgmii.c b/drivers/net/ethernet/ibm/emac/rgmii.c index 4fa53f3def6..05484f918ee 100644 --- a/drivers/net/ethernet/ibm/emac/rgmii.c +++ b/drivers/net/ethernet/ibm/emac/rgmii.c @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/rgmii.c + * drivers/net/ethernet/ibm/emac/rgmii.c * * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge support. * diff --git a/drivers/net/ethernet/ibm/emac/rgmii.h b/drivers/net/ethernet/ibm/emac/rgmii.h index 9296b6c5f92..668bceeff4a 100644 --- a/drivers/net/ethernet/ibm/emac/rgmii.h +++ b/drivers/net/ethernet/ibm/emac/rgmii.h @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/rgmii.h + * drivers/net/ethernet/ibm/emac/rgmii.h * * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge support. * diff --git a/drivers/net/ethernet/ibm/emac/tah.c b/drivers/net/ethernet/ibm/emac/tah.c index 5f51bf7c9dc..0d9881efe2f 100644 --- a/drivers/net/ethernet/ibm/emac/tah.c +++ b/drivers/net/ethernet/ibm/emac/tah.c @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/tah.c + * drivers/net/ethernet/ibm/emac/tah.c * * Driver for PowerPC 4xx on-chip ethernet controller, TAH support. * diff --git a/drivers/net/ethernet/ibm/emac/tah.h b/drivers/net/ethernet/ibm/emac/tah.h index 3437ab4964c..350b7096a04 100644 --- a/drivers/net/ethernet/ibm/emac/tah.h +++ b/drivers/net/ethernet/ibm/emac/tah.h @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/tah.h + * drivers/net/ethernet/ibm/emac/tah.h * * Driver for PowerPC 4xx on-chip ethernet controller, TAH support. * diff --git a/drivers/net/ethernet/ibm/emac/zmii.c b/drivers/net/ethernet/ibm/emac/zmii.c index 97449e786d6..e799a6116ba 100644 --- a/drivers/net/ethernet/ibm/emac/zmii.c +++ b/drivers/net/ethernet/ibm/emac/zmii.c @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/zmii.c + * drivers/net/ethernet/ibm/emac/zmii.c * * Driver for PowerPC 4xx on-chip ethernet controller, ZMII bridge support. * diff --git a/drivers/net/ethernet/ibm/emac/zmii.h b/drivers/net/ethernet/ibm/emac/zmii.h index ceaed823a83..455bfb08549 100644 --- a/drivers/net/ethernet/ibm/emac/zmii.h +++ b/drivers/net/ethernet/ibm/emac/zmii.h @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/zmii.h + * drivers/net/ethernet/ibm/emac/zmii.h * * Driver for PowerPC 4xx on-chip ethernet controller, ZMII bridge support. * diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index 6b35e7da9a9..134c4d07936 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -1,4 +1,4 @@ -/* drivers/net/ks8851.c +/* drivers/net/ethernet/micrel/ks8851.c * * Copyright 2009 Simtec Electronics * http://www.simtec.co.uk/ diff --git a/drivers/net/ethernet/micrel/ks8851.h b/drivers/net/ethernet/micrel/ks8851.h index b0fae86aaca..852256ef1f2 100644 --- a/drivers/net/ethernet/micrel/ks8851.h +++ b/drivers/net/ethernet/micrel/ks8851.h @@ -1,4 +1,4 @@ -/* drivers/net/ks8851.h +/* drivers/net/ethernet/micrel/ks8851.h * * Copyright 2009 Simtec Electronics * Ben Dooks diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c index e58e78e5c93..a37264e61a2 100644 --- a/drivers/net/ethernet/micrel/ks8851_mll.c +++ b/drivers/net/ethernet/micrel/ks8851_mll.c @@ -1,5 +1,5 @@ /** - * drivers/net/ks8851_mll.c + * drivers/net/ethernet/micrel/ks8851_mll.c * Copyright (c) 2009 Micrel Inc. * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index e52cd310ae7..2725d693c3c 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c @@ -1,5 +1,5 @@ /** - * drivers/net/ksx884x.c - Micrel KSZ8841/2 PCI Ethernet driver + * drivers/net/ethernet/micrel/ksx884x.c - Micrel KSZ8841/2 PCI Ethernet driver * * Copyright (c) 2009-2010 Micrel, Inc. * Tristram Ha diff --git a/drivers/net/ethernet/netx-eth.c b/drivers/net/ethernet/netx-eth.c index 8d288af16fc..a18bb10b4f0 100644 --- a/drivers/net/ethernet/netx-eth.c +++ b/drivers/net/ethernet/netx-eth.c @@ -1,5 +1,5 @@ /* - * drivers/net/netx-eth.c + * drivers/net/ethernet/netx-eth.c * * Copyright (c) 2005 Sascha Hauer , Pengutronix * diff --git a/drivers/net/ethernet/realtek/Kconfig b/drivers/net/ethernet/realtek/Kconfig index 0578859a3c7..5821966f9f2 100644 --- a/drivers/net/ethernet/realtek/Kconfig +++ b/drivers/net/ethernet/realtek/Kconfig @@ -24,11 +24,11 @@ config ATP select CRC32 ---help--- This is a network (Ethernet) device which attaches to your parallel - port. Read as well as the Ethernet-HOWTO, - available from , if you - want to use this. If you intend to use this driver, you should have - said N to the "Parallel printer support", because the two drivers - don't like each other. + port. Read as well as the + Ethernet-HOWTO, available from , + if you want to use this. If you intend to use this driver, you + should have said N to the "Parallel printer support", because the two + drivers don't like each other. To compile this driver as a module, choose M here: the module will be called atp. -- cgit v1.2.3-70-g09d2 From 5e6bbedd8238edbfee03d2950369edb08773cd3c Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Fri, 27 Jan 2012 13:55:46 +0000 Subject: drivers/net: strip unused module code from sun3_82586.c This code is clearly unused, since it has a #error right in it. Given the vintage of sun3 hardware, it is probably safe to assume that there is little interest in adding new functionality to the driver now, so just delete the unused block of code. Signed-off-by: Paul Gortmaker Signed-off-by: Sam Creasey Signed-off-by: David S. Miller --- drivers/net/ethernet/i825xx/sun3_82586.c | 25 ------------------------- 1 file changed, 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/i825xx/sun3_82586.c b/drivers/net/ethernet/i825xx/sun3_82586.c index 6ef5e11d1c8..296cf8a0ee5 100644 --- a/drivers/net/ethernet/i825xx/sun3_82586.c +++ b/drivers/net/ethernet/i825xx/sun3_82586.c @@ -28,7 +28,6 @@ static int automatic_resume = 0; /* experimental .. better should be zero */ static int rfdadd = 0; /* rfdadd=1 may be better for 8K MEM cards */ static int fifo=0x8; /* don't change */ -#include #include #include #include @@ -1151,28 +1150,6 @@ static void set_multicast_list(struct net_device *dev) netif_wake_queue(dev); } -#ifdef MODULE -#error This code is not currently supported as a module -static struct net_device *dev_sun3_82586; - -int init_module(void) -{ - dev_sun3_82586 = sun3_82586_probe(-1); - if (IS_ERR(dev_sun3_82586)) - return PTR_ERR(dev_sun3_82586); - return 0; -} - -void cleanup_module(void) -{ - unsigned long ioaddr = dev_sun3_82586->base_addr; - unregister_netdev(dev_sun3_82586); - release_region(ioaddr, SUN3_82586_TOTAL_SIZE); - iounmap((void *)ioaddr); - free_netdev(dev_sun3_82586); -} -#endif /* MODULE */ - #if 0 /* * DUMP .. we expect a not running CMD unit and enough space @@ -1209,5 +1186,3 @@ void sun3_82586_dump(struct net_device *dev,void *ptr) printk("\n"); } #endif - -MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From 5f1127ffbae3029fde5dc1464ec3c26cdf34cb80 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 24 Jan 2012 13:50:16 +0200 Subject: ath6kl: fix testmode when fw-2.bin or fw-3.bin is used Testmode (TCMD and ART) was not enabled when fw-2.bin or fw-3.bin files were available, fix that by fetching testmode file just after the board file but before rest of the firmware files are fetched. I also added testmode field to struct ath6kl and moved the module parameter to core.c. Now all module parameters are grouped in one place. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/core.c | 4 ++ drivers/net/wireless/ath/ath6kl/core.h | 1 + drivers/net/wireless/ath/ath6kl/init.c | 74 +++++++++++++++++++++------------- 3 files changed, 51 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c index 0d92e7179f8..2a5198185d5 100644 --- a/drivers/net/wireless/ath/ath6kl/core.c +++ b/drivers/net/wireless/ath/ath6kl/core.c @@ -28,11 +28,13 @@ unsigned int debug_mask; static bool suspend_cutpower; static unsigned int uart_debug; static unsigned int ath6kl_p2p; +static unsigned int testmode; module_param(debug_mask, uint, 0644); module_param(suspend_cutpower, bool, 0444); module_param(uart_debug, uint, 0644); module_param(ath6kl_p2p, uint, 0644); +module_param(testmode, uint, 0644); int ath6kl_core_init(struct ath6kl *ar) { @@ -76,6 +78,8 @@ int ath6kl_core_init(struct ath6kl *ar) goto err_power_off; } + ar->testmode = testmode; + ret = ath6kl_init_fetch_firmwares(ar); if (ret) goto err_htc_cleanup; diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index ed9fcc11b5f..7f1869d00d7 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -532,6 +532,7 @@ struct ath6kl { struct wiphy *wiphy; enum ath6kl_state state; + unsigned int testmode; struct ath6kl_bmi bmi; const struct ath6kl_hif_ops *hif_ops; diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 4d8eb1cca6e..bf56e5f1761 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -27,10 +27,6 @@ #include "debug.h" #include "hif-ops.h" -static unsigned int testmode; - -module_param(testmode, uint, 0644); - static const struct ath6kl_hw hw_list[] = { { .id = AR6003_HW_2_0_VERSION, @@ -731,39 +727,54 @@ static int ath6kl_fetch_otp_file(struct ath6kl *ar) return 0; } -static int ath6kl_fetch_fw_file(struct ath6kl *ar) +static int ath6kl_fetch_testmode_file(struct ath6kl *ar) { char filename[100]; int ret; - if (ar->fw != NULL) + if (ar->testmode == 0) return 0; - if (testmode) { - ath6kl_dbg(ATH6KL_DBG_BOOT, "testmode %d\n", - testmode); - if (testmode == 2) { - if (ar->hw.fw.utf == NULL) { - ath6kl_warn("testmode 2 not supported\n"); - return -EOPNOTSUPP; - } + ath6kl_dbg(ATH6KL_DBG_BOOT, "testmode %d\n", ar->testmode); - snprintf(filename, sizeof(filename), "%s/%s", - ar->hw.fw.dir, ar->hw.fw.utf); - } else { - if (ar->hw.fw.tcmd == NULL) { - ath6kl_warn("testmode 1 not supported\n"); - return -EOPNOTSUPP; - } + if (ar->testmode == 2) { + if (ar->hw.fw.utf == NULL) { + ath6kl_warn("testmode 2 not supported\n"); + return -EOPNOTSUPP; + } - snprintf(filename, sizeof(filename), "%s/%s", - ar->hw.fw.dir, ar->hw.fw.tcmd); + snprintf(filename, sizeof(filename), "%s/%s", + ar->hw.fw.dir, ar->hw.fw.utf); + } else { + if (ar->hw.fw.tcmd == NULL) { + ath6kl_warn("testmode 1 not supported\n"); + return -EOPNOTSUPP; } - set_bit(TESTMODE, &ar->flag); - goto get_fw; + snprintf(filename, sizeof(filename), "%s/%s", + ar->hw.fw.dir, ar->hw.fw.tcmd); } + set_bit(TESTMODE, &ar->flag); + + ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len); + if (ret) { + ath6kl_err("Failed to get testmode %d firmware file %s: %d\n", + ar->testmode, filename, ret); + return ret; + } + + return 0; +} + +static int ath6kl_fetch_fw_file(struct ath6kl *ar) +{ + char filename[100]; + int ret; + + if (ar->fw != NULL) + return 0; + /* FIXME: remove WARN_ON() as we won't support FW API 1 for long */ if (WARN_ON(ar->hw.fw.fw == NULL)) return -EINVAL; @@ -771,7 +782,6 @@ static int ath6kl_fetch_fw_file(struct ath6kl *ar) snprintf(filename, sizeof(filename), "%s/%s", ar->hw.fw.dir, ar->hw.fw.fw); -get_fw: ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len); if (ret) { ath6kl_err("Failed to get firmware file %s: %d\n", @@ -812,7 +822,7 @@ static int ath6kl_fetch_testscript_file(struct ath6kl *ar) char filename[100]; int ret; - if (testmode != 2) + if (ar->testmode != 2) return 0; if (ar->fw_testscript != NULL) @@ -927,6 +937,10 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name) ath6kl_dbg(ATH6KL_DBG_BOOT, "found fw image ie (%zd B)\n", ie_len); + /* in testmode we already might have a fw file */ + if (ar->fw != NULL) + break; + ar->fw = kmemdup(data, ie_len, GFP_KERNEL); if (ar->fw == NULL) { @@ -1038,6 +1052,10 @@ int ath6kl_init_fetch_firmwares(struct ath6kl *ar) if (ret) return ret; + ret = ath6kl_fetch_testmode_file(ar); + if (ret) + return ret; + ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API3_FILE); if (ret == 0) { ar->fw_api = 3; @@ -1283,7 +1301,7 @@ static int ath6kl_upload_testscript(struct ath6kl *ar) u32 address, param; int ret; - if (testmode != 2) + if (ar->testmode != 2) return 0; if (ar->fw_testscript == NULL) -- cgit v1.2.3-70-g09d2 From c86515412f0c364f2d45029b45d5909614087af3 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Thu, 26 Jan 2012 13:17:18 +0530 Subject: ath6kl: Fix kernel panic during rx aggregation "ath6kl: Define a structure for connection specific aggregation information" introduces this. In aggr_conn_init(), vif->aggr_cntxt is assigned to aggr_conn->aggr_info, but vif->aggr_cntxt is not initialized at this point, this would end up accessing an invalid pointer in aggregation receive path. Fix this by passing the correct aggr_info to aggr_conn_init(). The panic trace would look like. [] panic+0xa1/0x1c6 [] ? kmsg_dump+0xfd/0x160 [] oops_end+0xea/0xf0 [] no_context+0x11d/0x2d0 [] __bad_area_nosemaphore+0x14d/0x230 [] ? do_page_fault+0x30d/0x520 [] bad_area_nosemaphore+0x13/0x20 [] do_page_fault+0x3bd/0x520 [] ? __lock_acquire+0x320/0x1680 [] ? trace_hardirqs_off_thunk+0x3a/0x3c [] page_fault+0x25/0x30 [] ? aggr_slice_amsdu+0xdf/0x170 [ath6kl_core] [] aggr_deque_frms+0xbc/0x190 [ath6kl_core] [] ath6kl_rx+0x3e4/0xae0 [ath6kl_core] [] ath6kl_htc_rxmsg_pending_handler+0x8b7/0xf10 [ath6kl_core] [] ? mmc_do_release_host+0x70/0x90 [mmc_core] [] ? mmc_release_host+0x2a/0x50 [mmc_core] [] ? ath6kl_alloc_amsdu_rxbuf+0x140/0x140 [ath6kl_core] [] ath6kl_hif_intr_bh_handler+0x362/0x510 [ath6kl_core] [] ath6kl_sdio_irq_handler+0x60/0xb0 [ath6kl_sdio] [] sdio_irq_thread+0xec/0x320 [mmc_core] [] ? sdio_claim_irq+0x220/0x220 [mmc_core] [] ? sdio_claim_irq+0x220/0x220 [mmc_core] [] kthread+0xbe/0xd0 [] kernel_thread_helper+0x4/0x10 [] ? retint_restore_args+0x13/0x13 [] ? __init_kthread_worker+0x70/0x70 [] ? gs_change+0x13/0x13 Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/core.h | 3 ++- drivers/net/wireless/ath/ath6kl/main.c | 2 +- drivers/net/wireless/ath/ath6kl/txrx.c | 7 ++++--- 3 files changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 7f1869d00d7..426f269e8ab 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -715,7 +715,8 @@ void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie); int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev); struct aggr_info *aggr_init(struct ath6kl_vif *vif); -void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info_conn *aggr_conn); +void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info *aggr_info, + struct aggr_info_conn *aggr_conn); void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint); void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count); diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index 39da1f98da8..b96d01a7919 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -74,7 +74,7 @@ static void ath6kl_add_new_sta(struct ath6kl_vif *vif, u8 *mac, u16 aid, ar->sta_list_index = ar->sta_list_index | (1 << free_slot); ar->ap_stats.sta[free_slot].aid = cpu_to_le32(aid); - aggr_conn_init(vif, sta->aggr_conn); + aggr_conn_init(vif, vif->aggr_cntxt, sta->aggr_conn); } static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i) diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index 62c12102e14..a3dc6943c7f 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -1674,7 +1674,8 @@ void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid_mux, u16 seq_no, rxtid->aggr = true; } -void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info_conn *aggr_conn) +void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info *aggr_info, + struct aggr_info_conn *aggr_conn) { struct rxtid *rxtid; u8 i; @@ -1684,7 +1685,7 @@ void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info_conn *aggr_conn) init_timer(&aggr_conn->timer); aggr_conn->timer.function = aggr_timeout; aggr_conn->timer.data = (unsigned long) aggr_conn; - aggr_conn->aggr_info = vif->aggr_cntxt; + aggr_conn->aggr_info = aggr_info; aggr_conn->timer_scheduled = false; @@ -1716,7 +1717,7 @@ struct aggr_info *aggr_init(struct ath6kl_vif *vif) return NULL; } - aggr_conn_init(vif, p_aggr->aggr_conn); + aggr_conn_init(vif, p_aggr, p_aggr->aggr_conn); skb_queue_head_init(&p_aggr->rx_amsdu_freeq); ath6kl_alloc_netbufs(&p_aggr->rx_amsdu_freeq, AGGR_NUM_OF_FREE_NETBUFS); -- cgit v1.2.3-70-g09d2 From e390af779dc671551800514d391928f5a798089a Mon Sep 17 00:00:00 2001 From: Raja Mani Date: Mon, 30 Jan 2012 17:13:09 +0530 Subject: ath6kl: Re-architect suspend mode handling in ath6kl_sdio_suspend Using this patch, the user can bypass existing auto suspend mode selection logic and force ath6kl to enter into the suspend mode what he/she wants. If the user doesn't choose any suspend mode while doing insmod of the driver, auto suspend mode selection logic will kick in and choose suspend mode based on the host SDIO controller capability. Generic module parameter is required to specify suspend mode including Deep Sleep and WOW while doing insmod. Renaming existing mod param variable suspend_cutpower would be sufficient to meet this requirement. New module parameter suspend_mode can take any one of the below suspend state, 1. cut power 2. deep sleep 3. wow Signed-off-by: Raja Mani Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/core.c | 12 +++-- drivers/net/wireless/ath/ath6kl/core.h | 4 +- drivers/net/wireless/ath/ath6kl/sdio.c | 86 +++++++++++++++++++++------------- 3 files changed, 64 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c index 2a5198185d5..722ca59b88c 100644 --- a/drivers/net/wireless/ath/ath6kl/core.c +++ b/drivers/net/wireless/ath/ath6kl/core.c @@ -25,13 +25,13 @@ #include "cfg80211.h" unsigned int debug_mask; -static bool suspend_cutpower; +static unsigned int suspend_mode; static unsigned int uart_debug; static unsigned int ath6kl_p2p; static unsigned int testmode; module_param(debug_mask, uint, 0644); -module_param(suspend_cutpower, bool, 0444); +module_param(suspend_mode, uint, 0644); module_param(uart_debug, uint, 0644); module_param(ath6kl_p2p, uint, 0644); module_param(testmode, uint, 0644); @@ -147,8 +147,12 @@ int ath6kl_core_init(struct ath6kl *ar) ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER | ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST; - if (suspend_cutpower) - ar->conf_flags |= ATH6KL_CONF_SUSPEND_CUTPOWER; + if (suspend_mode && + suspend_mode >= WLAN_POWER_STATE_CUT_PWR && + suspend_mode <= WLAN_POWER_STATE_WOW) + ar->suspend_mode = suspend_mode; + else + ar->suspend_mode = 0; if (uart_debug) ar->conf_flags |= ATH6KL_CONF_UART_DEBUG; diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 426f269e8ab..ce572c04b92 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -196,8 +196,7 @@ struct ath6kl_fw_ie { #define ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN BIT(1) #define ATH6KL_CONF_ENABLE_11N BIT(2) #define ATH6KL_CONF_ENABLE_TX_BURST BIT(3) -#define ATH6KL_CONF_SUSPEND_CUTPOWER BIT(4) -#define ATH6KL_CONF_UART_DEBUG BIT(5) +#define ATH6KL_CONF_UART_DEBUG BIT(4) enum wlan_low_pwr_state { WLAN_POWER_STATE_ON, @@ -619,6 +618,7 @@ struct ath6kl { } hw; u16 conf_flags; + u16 suspend_mode; wait_queue_head_t event_wq; struct ath6kl_mbox_info mbox_info; diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index d9f55914b89..07dcf00ca1a 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -779,7 +779,7 @@ out: return ret; } -static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) +static int ath6kl_set_sdio_pm_caps(struct ath6kl *ar) { struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); struct sdio_func *func = ar_sdio->func; @@ -790,60 +790,82 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sdio suspend pm_caps 0x%x\n", flags); - if (!(flags & MMC_PM_KEEP_POWER) || - (ar->conf_flags & ATH6KL_CONF_SUSPEND_CUTPOWER)) { - /* as host doesn't support keep power we need to cut power */ - return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_CUTPOWER, - NULL); - } + if (!(flags & MMC_PM_WAKE_SDIO_IRQ) || + !(flags & MMC_PM_KEEP_POWER)) + return -EINVAL; ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); if (ret) { - printk(KERN_ERR "ath6kl: set sdio pm flags failed: %d\n", - ret); + ath6kl_err("set sdio keep pwr flag failed: %d\n", ret); return ret; } - if (!(flags & MMC_PM_WAKE_SDIO_IRQ)) - goto deepsleep; - /* sdio irq wakes up host */ + ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ); + if (ret) + ath6kl_err("set sdio wake irq flag failed: %d\n", ret); + + return ret; +} + +static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) +{ + struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); + struct sdio_func *func = ar_sdio->func; + mmc_pm_flag_t flags; + int ret; if (ar->state == ATH6KL_STATE_SCHED_SCAN) { + ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sched scan is in progress\n"); + + ret = ath6kl_set_sdio_pm_caps(ar); + if (ret) + goto cut_pwr; + ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_SCHED_SCAN, NULL); - if (ret) { - ath6kl_warn("Schedule scan suspend failed: %d", ret); - return ret; - } - - ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ); if (ret) - ath6kl_warn("set sdio wake irq flag failed: %d\n", ret); + goto cut_pwr; - return ret; + return 0; } - if (wow) { - /* - * The host sdio controller is capable of keep power and - * sdio irq wake up at this point. It's fine to continue - * wow suspend operation. - */ + if (ar->suspend_mode == WLAN_POWER_STATE_WOW || + (!ar->suspend_mode && wow)) { + + ret = ath6kl_set_sdio_pm_caps(ar); + if (ret) + goto cut_pwr; + ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_WOW, wow); if (ret) - return ret; + goto cut_pwr; + + return 0; + } + + if (ar->suspend_mode == WLAN_POWER_STATE_DEEP_SLEEP || + !ar->suspend_mode) { - ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ); + flags = sdio_get_host_pm_caps(func); + if (!(flags & MMC_PM_KEEP_POWER)) + goto cut_pwr; + + ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); if (ret) - ath6kl_err("set sdio wake irq flag failed: %d\n", ret); + goto cut_pwr; - return ret; + ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_DEEPSLEEP, + NULL); + if (ret) + goto cut_pwr; + + return 0; } -deepsleep: - return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_DEEPSLEEP, NULL); +cut_pwr: + return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_CUTPOWER, NULL); } static int ath6kl_sdio_resume(struct ath6kl *ar) -- cgit v1.2.3-70-g09d2 From d91e8eee046e0d4ae7a8a585616b5ce800f54568 Mon Sep 17 00:00:00 2001 From: Raja Mani Date: Mon, 30 Jan 2012 17:13:10 +0530 Subject: ath6kl: Configure WOW patterns while going to wow_suspend First preference is given to the user configured WOW patterns. If the user doesn't configure any patterns (for ex, via iw command), the default patterns will be configured based on the current mode (vif->nw_type) while going to WOW suspend. Summary of changes: * ath6kl_wow_ap() is added to configure the below default patterns when the system enters into WOW suspend in AP mode. + Unicast IP, EAPOL-like and ARP packet pattern + ARP packet pattern + mDNS/SSDP/LLMNR pattern + DHCP broadcast pattern * ath6kl_wow_sta() is added to configure the below default patterns when the system enters into WOW suspend in STA mode. + Unicast packet pattern + mDNS/SSDP/LLMNR pattern * Move the user provided WOW patterns configuration code from ath6kl_wow_suspend() to a separate function called ath6kl_wow_usr(). * Two argument variable's ('filter' and 'mask) data type in ath6kl_wmi_add_wow_pattern_cmd() are changed from 'u8 *' to 'const u8 *'. This is needed to make all pattern and mask arrays to be 'static const u8' in the caller function. * New conditional check is added to make sure user configured pattern count is within the limit (WOW_MAX_FILTERS_PER_LIST). Signed-off-by: Raja Mani Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 231 +++++++++++++++++++++++------ drivers/net/wireless/ath/ath6kl/wmi.c | 3 +- drivers/net/wireless/ath/ath6kl/wmi.h | 3 +- 3 files changed, 193 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index fed7b8077f5..e676cfccedf 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -1723,32 +1723,14 @@ static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) return 0; } -static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) +static int ath6kl_wow_usr(struct ath6kl *ar, struct ath6kl_vif *vif, + struct cfg80211_wowlan *wow, u32 *filter) { - struct in_device *in_dev; - struct in_ifaddr *ifa; - struct ath6kl_vif *vif; - int ret, pos, left; - u32 filter = 0; + int ret, pos; + u8 mask[WOW_MASK_SIZE]; u16 i; - u8 mask[WOW_MASK_SIZE], index = 0; - __be32 ips[MAX_IP_ADDRS]; - - vif = ath6kl_vif_first(ar); - if (!vif) - return -EIO; - - if (!ath6kl_cfg80211_ready(vif)) - return -EIO; - - if (!test_bit(CONNECTED, &vif->flags)) - return -EINVAL; - /* Clear existing WOW patterns */ - for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++) - ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx, - WOW_LIST_ID, i); - /* Configure new WOW patterns */ + /* Configure the patterns that we received from the user. */ for (i = 0; i < wow->n_patterns; i++) { /* @@ -1771,14 +1753,194 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) * matched from the first byte of received pkt in the firmware. */ ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi, - vif->fw_vif_idx, WOW_LIST_ID, - wow->patterns[i].pattern_len, - 0 /* pattern offset */, - wow->patterns[i].pattern, mask); + vif->fw_vif_idx, WOW_LIST_ID, + wow->patterns[i].pattern_len, + 0 /* pattern offset */, + wow->patterns[i].pattern, mask); if (ret) return ret; } + if (wow->disconnect) + *filter |= WOW_FILTER_OPTION_NWK_DISASSOC; + + if (wow->magic_pkt) + *filter |= WOW_FILTER_OPTION_MAGIC_PACKET; + + if (wow->gtk_rekey_failure) + *filter |= WOW_FILTER_OPTION_GTK_ERROR; + + if (wow->eap_identity_req) + *filter |= WOW_FILTER_OPTION_EAP_REQ; + + if (wow->four_way_handshake) + *filter |= WOW_FILTER_OPTION_8021X_4WAYHS; + + return 0; +} + +static int ath6kl_wow_ap(struct ath6kl *ar, struct ath6kl_vif *vif) +{ + static const u8 unicst_pattern[] = { 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08 }; + static const u8 unicst_mask[] = { 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f }; + u8 unicst_offset = 0; + static const u8 arp_pattern[] = { 0x08, 0x06 }; + static const u8 arp_mask[] = { 0xff, 0xff }; + u8 arp_offset = 20; + static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 }; + static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 }; + u8 discvr_offset = 38; + static const u8 dhcp_pattern[] = { 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 /* port 67 */ }; + static const u8 dhcp_mask[] = { 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff /* port 67 */ }; + u8 dhcp_offset = 0; + int ret; + + /* Setup unicast IP, EAPOL-like and ARP pkt pattern */ + ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi, + vif->fw_vif_idx, WOW_LIST_ID, + sizeof(unicst_pattern), unicst_offset, + unicst_pattern, unicst_mask); + if (ret) { + ath6kl_err("failed to add WOW unicast IP pattern\n"); + return ret; + } + + /* Setup all ARP pkt pattern */ + ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi, + vif->fw_vif_idx, WOW_LIST_ID, + sizeof(arp_pattern), arp_offset, + arp_pattern, arp_mask); + if (ret) { + ath6kl_err("failed to add WOW ARP pattern\n"); + return ret; + } + + /* + * Setup multicast pattern for mDNS 224.0.0.251, + * SSDP 239.255.255.250 and LLMNR 224.0.0.252 + */ + ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi, + vif->fw_vif_idx, WOW_LIST_ID, + sizeof(discvr_pattern), discvr_offset, + discvr_pattern, discvr_mask); + if (ret) { + ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n"); + return ret; + } + + /* Setup all DHCP broadcast pkt pattern */ + ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi, + vif->fw_vif_idx, WOW_LIST_ID, + sizeof(dhcp_pattern), dhcp_offset, + dhcp_pattern, dhcp_mask); + if (ret) { + ath6kl_err("failed to add WOW DHCP broadcast pattern\n"); + return ret; + } + + return 0; +} + +static int ath6kl_wow_sta(struct ath6kl *ar, struct ath6kl_vif *vif) +{ + struct net_device *ndev = vif->ndev; + static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 }; + static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 }; + u8 discvr_offset = 38; + u8 mac_mask[ETH_ALEN]; + int ret; + + /* Setup unicast pkt pattern */ + memset(mac_mask, 0xff, ETH_ALEN); + ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi, + vif->fw_vif_idx, WOW_LIST_ID, + ETH_ALEN, 0, ndev->dev_addr, + mac_mask); + if (ret) { + ath6kl_err("failed to add WOW unicast pattern\n"); + return ret; + } + + /* + * Setup multicast pattern for mDNS 224.0.0.251, + * SSDP 239.255.255.250 and LLMNR 224.0.0.252 + */ + if ((ndev->flags & IFF_ALLMULTI) || + (ndev->flags & IFF_MULTICAST && netdev_mc_count(ndev) > 0)) { + ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi, + vif->fw_vif_idx, WOW_LIST_ID, + sizeof(discvr_pattern), discvr_offset, + discvr_pattern, discvr_mask); + if (ret) { + ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR " + "pattern\n"); + return ret; + } + } + + return 0; +} + +static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) +{ + struct in_device *in_dev; + struct in_ifaddr *ifa; + struct ath6kl_vif *vif; + int ret, left; + u32 filter = 0; + u16 i; + u8 index = 0; + __be32 ips[MAX_IP_ADDRS]; + + vif = ath6kl_vif_first(ar); + if (!vif) + return -EIO; + + if (!ath6kl_cfg80211_ready(vif)) + return -EIO; + + if (!test_bit(CONNECTED, &vif->flags)) + return -EINVAL; + + if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST)) + return -EINVAL; + + /* Clear existing WOW patterns */ + for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++) + ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx, + WOW_LIST_ID, i); + + /* + * Skip the default WOW pattern configuration + * if the driver receives any WOW patterns from + * the user. + */ + if (wow) + ret = ath6kl_wow_usr(ar, vif, wow, &filter); + else if (vif->nw_type == AP_NETWORK) + ret = ath6kl_wow_ap(ar, vif); + else + ret = ath6kl_wow_sta(ar, vif); + + if (ret) + return ret; + /* Setup own IP addr for ARP agent. */ in_dev = __in_dev_get_rtnl(vif->ndev); if (!in_dev) @@ -1806,21 +1968,6 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) } skip_arp: - if (wow->disconnect) - filter |= WOW_FILTER_OPTION_NWK_DISASSOC; - - if (wow->magic_pkt) - filter |= WOW_FILTER_OPTION_MAGIC_PACKET; - - if (wow->gtk_rekey_failure) - filter |= WOW_FILTER_OPTION_GTK_ERROR; - - if (wow->eap_identity_req) - filter |= WOW_FILTER_OPTION_EAP_REQ; - - if (wow->four_way_handshake) - filter |= WOW_FILTER_OPTION_8021X_4WAYHS; - ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx, ATH6KL_WOW_MODE_ENABLE, filter, diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 5d678bf372d..9c8e4dfbfa0 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -2620,7 +2620,8 @@ int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx, int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, u8 list_id, u8 filter_size, - u8 filter_offset, u8 *filter, u8 *mask) + u8 filter_offset, const u8 *filter, + const u8 *mask) { struct sk_buff *skb; struct wmi_add_wow_pattern_cmd *cmd; diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index 48e9d2641d6..85698ef2dd8 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -2461,7 +2461,8 @@ int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx, u32 filter, u16 host_req_delay); int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, u8 list_id, u8 filter_size, - u8 filter_offset, u8 *filter, u8 *mask); + u8 filter_offset, const u8 *filter, + const u8 *mask); int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, u16 list_id, u16 filter_id); int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi); -- cgit v1.2.3-70-g09d2 From 081c7a84e969453716e2a7bd315417067c3643ad Mon Sep 17 00:00:00 2001 From: Raja Mani Date: Mon, 30 Jan 2012 17:13:11 +0530 Subject: ath6kl: Wait for host sleep mode cmd processed event during WOW suspend For every WMI_SET_HOST_SLEEP_MODE_CMDID command (send from the host), the firmware sends WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID as an acknowledgement to the host. In order to being sync with the firmware, the host has to wait for WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENT event before going to the suspend state. This patch ensures ath6kl_wow_suspend() waits until it gets this event after sending set host sleep mode command. This patch adds, * New command WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID in WMI event table. * New WMI function ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx() to process the event. * New flag HOST_SLEEP_MODE_CMD_PROCESSED in VIF flags to record the arrival of the event. Signed-off-by: Raja Mani Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 15 +++++++++++++++ drivers/net/wireless/ath/ath6kl/core.h | 1 + drivers/net/wireless/ath/ath6kl/wmi.c | 17 +++++++++++++++++ drivers/net/wireless/ath/ath6kl/wmi.h | 2 ++ 4 files changed, 35 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index e676cfccedf..1902e2fa1a6 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -1975,11 +1975,26 @@ skip_arp: if (ret) return ret; + clear_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags); + ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, ATH6KL_HOST_MODE_ASLEEP); if (ret) return ret; + left = wait_event_interruptible_timeout(ar->event_wq, + test_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags), + WMI_TIMEOUT); + if (left == 0) { + ath6kl_warn("timeout, didn't get host sleep cmd " + "processed event\n"); + ret = -ETIMEDOUT; + } else if (left < 0) { + ath6kl_warn("error while waiting for host sleep cmd " + "processed event %d\n", left); + ret = left; + } + if (ar->tx_pending[ar->ctrl_ep]) { left = wait_event_interruptible_timeout(ar->event_wq, ar->tx_pending[ar->ctrl_ep] == 0, WMI_TIMEOUT); diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index ce572c04b92..c4d66e066dc 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -451,6 +451,7 @@ enum ath6kl_vif_state { DTIM_PERIOD_AVAIL, WLAN_ENABLED, STATS_UPDATE_PEND, + HOST_SLEEP_MODE_CMD_PROCESSED, }; struct ath6kl_vif { diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 9c8e4dfbfa0..18fa9aa8af9 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -2590,6 +2590,18 @@ int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx, return ret; } +/* This command has zero length payload */ +static int ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx(struct wmi *wmi, + struct ath6kl_vif *vif) +{ + struct ath6kl *ar = wmi->parent_dev; + + set_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags); + wake_up(&ar->event_wq); + + return 0; +} + int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx, enum ath6kl_wow_mode wow_mode, u32 filter, u16 host_req_delay) @@ -3556,6 +3568,11 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_COMPLETE_EVENTID\n"); ret = ath6kl_wmi_tx_complete_event_rx(datap, len); break; + case WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, + "WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID"); + ret = ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx(wmi, vif); + break; case WMI_REMAIN_ON_CHNL_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REMAIN_ON_CHNL_EVENTID\n"); ret = ath6kl_wmi_remain_on_chnl_event_rx(wmi, datap, len, vif); diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index 85698ef2dd8..e7919869725 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -1357,6 +1357,8 @@ enum wmi_event_id { WMI_P2P_START_SDPD_EVENTID, WMI_P2P_SDPD_RX_EVENTID, + WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID = 0x1047, + WMI_THIN_RESERVED_START_EVENTID = 0x8000, /* Events in this range are reserved for thinmode */ WMI_THIN_RESERVED_END_EVENTID = 0x8fff, -- cgit v1.2.3-70-g09d2 From 3c411a434414f4320ce926bee3733e34ba0ea407 Mon Sep 17 00:00:00 2001 From: Raja Mani Date: Mon, 30 Jan 2012 17:13:12 +0530 Subject: ath6kl: Return a proper error code when not in connected state Error code ENOTCONN is more suitable than EINVAL to report when the driver is not in connected state in ath6kl_wow_suspend(). I found this during code review. Signed-off-by: Raja Mani Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 1902e2fa1a6..5934e40ee55 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -1916,7 +1916,7 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) return -EIO; if (!test_bit(CONNECTED, &vif->flags)) - return -EINVAL; + return -ENOTCONN; if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST)) return -EINVAL; -- cgit v1.2.3-70-g09d2 From c9c4b6f6c28354f1df9bd288dc33ba7ae0e66aaa Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:15 +0100 Subject: drm/i915: fix swizzle detection for gen3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It looks like the desktop variants of i915 and i945 also have the DCC register to control dram channel interleave and cpu side bit6 swizzling. Unfortunately internal Cspec/ConfigDB documentation for these ancient chips have already been dropped and there seem to be no archives. Also somebody thought the swizzling behaviour is surely a worthy secret to keep and redacted any mention of these fields from the published Intel datasheets. I suspect the hw engineers were really proud of the page coloring they've achieved in their first dual channel dram controller with bit17 - after all Bspec explains in great length the optimal layout of page frame numbers modulo 4 for the color and depth buffers, too. Later on when they've started to work on VT-d they shamefully discoverd their stupidity and tried to cover the tracks ... Tested-by: Daniel Vetter (i915g) Tested-by: Pavel Ondračka (i945g) Tested-by: Chris Wilson Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=42625 Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_tiling.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 31d334d9d9d..861223bf394 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -107,10 +107,10 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) */ swizzle_x = I915_BIT_6_SWIZZLE_NONE; swizzle_y = I915_BIT_6_SWIZZLE_NONE; - } else if (IS_MOBILE(dev)) { + } else if (IS_MOBILE(dev) || (IS_GEN3(dev) && !IS_G33(dev))) { uint32_t dcc; - /* On mobile 9xx chipsets, channel interleave by the CPU is + /* On 9xx chipsets, channel interleave by the CPU is * determined by DCC. For single-channel, neither the CPU * nor the GPU do swizzling. For dual channel interleaved, * the GPU's interleave is bit 9 and 10 for X tiled, and bit -- cgit v1.2.3-70-g09d2 From ea16a3cdb9218a2389fafc804356c1914c157654 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:16 +0100 Subject: drm/i915: add debugfs file for swizzling information This will also come handy for the gen6+ swizzling support, where the driver is supposed to control swizzling depending upon dram configuration. v2: CxDRB3 are 16 bit regs! Noticed by Chris Wilson. Reviewed-by: Chris Wilson Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 50 +++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index d4104904e58..681cbe4e6e2 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1379,6 +1379,55 @@ static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data) return 0; } +static const char *swizzle_string(unsigned swizzle) +{ + switch(swizzle) { + case I915_BIT_6_SWIZZLE_NONE: + return "none"; + case I915_BIT_6_SWIZZLE_9: + return "bit9"; + case I915_BIT_6_SWIZZLE_9_10: + return "bit9/bit10"; + case I915_BIT_6_SWIZZLE_9_11: + return "bit9/bit11"; + case I915_BIT_6_SWIZZLE_9_10_11: + return "bit9/bit10/bit11"; + case I915_BIT_6_SWIZZLE_9_17: + return "bit9/bit17"; + case I915_BIT_6_SWIZZLE_9_10_17: + return "bit9/bit10/bit17"; + case I915_BIT_6_SWIZZLE_UNKNOWN: + return "unkown"; + } + + return "bug"; +} + +static int i915_swizzle_info(struct seq_file *m, void *data) +{ + struct drm_info_node *node = (struct drm_info_node *) m->private; + struct drm_device *dev = node->minor->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + mutex_lock(&dev->struct_mutex); + seq_printf(m, "bit6 swizzle for X-tiling = %s\n", + swizzle_string(dev_priv->mm.bit_6_swizzle_x)); + seq_printf(m, "bit6 swizzle for Y-tiling = %s\n", + swizzle_string(dev_priv->mm.bit_6_swizzle_y)); + + if (IS_GEN3(dev) || IS_GEN4(dev)) { + seq_printf(m, "DDC = 0x%08x\n", + I915_READ(DCC)); + seq_printf(m, "C0DRB3 = 0x%04x\n", + I915_READ16(C0DRB3)); + seq_printf(m, "C1DRB3 = 0x%04x\n", + I915_READ16(C1DRB3)); + } + mutex_unlock(&dev->struct_mutex); + + return 0; +} + static int i915_debugfs_common_open(struct inode *inode, struct file *filp) @@ -1719,6 +1768,7 @@ static struct drm_info_list i915_debugfs_list[] = { {"i915_gem_framebuffer", i915_gem_framebuffer_info, 0}, {"i915_context_status", i915_context_status, 0}, {"i915_gen6_forcewake_count", i915_gen6_forcewake_count_info, 0}, + {"i915_swizzle_info", i915_swizzle_info, 0}, }; #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) -- cgit v1.2.3-70-g09d2 From d273bb20c00340748e3ca9730f87524ec5abbd64 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 27 Jan 2012 13:59:25 -0600 Subject: rtlwifi: Move pr_fmt macros to a single location Although the rtlwifi family of devices contains 11 copies of the pr_fmt macro, the macro is not defined for all routines that need it. By moving the macro to wifi.h, a single copy is available for all routines. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/base.c | 7 +++---- drivers/net/wireless/rtlwifi/cam.c | 2 -- drivers/net/wireless/rtlwifi/core.h | 2 -- drivers/net/wireless/rtlwifi/debug.c | 2 ++ drivers/net/wireless/rtlwifi/pci.c | 4 ++-- drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | 5 +---- drivers/net/wireless/rtlwifi/rtl8192c/main.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | 5 ++--- drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 2 -- drivers/net/wireless/rtlwifi/rtl8192cu/mac.c | 6 ++---- drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | 1 - drivers/net/wireless/rtlwifi/rtl8192de/sw.c | 7 ++----- drivers/net/wireless/rtlwifi/rtl8192se/hw.c | 2 -- drivers/net/wireless/rtlwifi/rtl8192se/phy.c | 2 -- drivers/net/wireless/rtlwifi/rtl8192se/rf.c | 2 -- drivers/net/wireless/rtlwifi/rtl8192se/sw.c | 7 ++----- drivers/net/wireless/rtlwifi/usb.c | 7 ++----- drivers/net/wireless/rtlwifi/usb.h | 1 - drivers/net/wireless/rtlwifi/wifi.h | 2 ++ 19 files changed, 21 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index ff3e393bc10..7a95a544a9b 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -27,10 +27,6 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include #include "wifi.h" #include "rc.h" #include "base.h" @@ -39,6 +35,9 @@ #include "ps.h" #include "regd.h" +#include +#include + /* *NOTICE!!!: This file will be very big, we hsould *keep it clear under follwing roles: diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c index 8fd820d85ee..5c7d57947d2 100644 --- a/drivers/net/wireless/rtlwifi/cam.c +++ b/drivers/net/wireless/rtlwifi/cam.c @@ -27,8 +27,6 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include "wifi.h" #include "cam.h" diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h index a45c3892e36..57569e0e3d4 100644 --- a/drivers/net/wireless/rtlwifi/core.h +++ b/drivers/net/wireless/rtlwifi/core.h @@ -30,8 +30,6 @@ #ifndef __RTL_CORE_H__ #define __RTL_CORE_H__ -#include - #define RTL_SUPPORTED_FILTERS \ (FIF_PROMISC_IN_BSS | \ FIF_ALLMULTI | FIF_CONTROL | \ diff --git a/drivers/net/wireless/rtlwifi/debug.c b/drivers/net/wireless/rtlwifi/debug.c index 67dcbcdfaa7..bdda9b2fffe 100644 --- a/drivers/net/wireless/rtlwifi/debug.c +++ b/drivers/net/wireless/rtlwifi/debug.c @@ -28,6 +28,8 @@ #include "wifi.h" +#include + void rtl_dbgp_flag_init(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 4326fd1e319..e4d1dcfe829 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -27,13 +27,13 @@ * *****************************************************************************/ -#include -#include "core.h" #include "wifi.h" +#include "core.h" #include "pci.h" #include "base.h" #include "ps.h" #include "efuse.h" +#include static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = { PCI_VENDOR_ID_INTEL, diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index 75be221fde4..82bbc8384ac 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c @@ -27,16 +27,13 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include #include "../wifi.h" #include "../pci.h" #include "../base.h" #include "../rtl8192ce/reg.h" #include "../rtl8192ce/def.h" #include "fw_common.h" +#include static void _rtl92c_enable_fw_download(struct ieee80211_hw *hw, bool enable) { diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/main.c b/drivers/net/wireless/rtlwifi/rtl8192c/main.c index 8ae65b57612..918b1d129e7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/main.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/main.c @@ -27,8 +27,8 @@ * *****************************************************************************/ -#include #include "../wifi.h" +#include MODULE_AUTHOR("lizhaoming "); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index 7e59b689bff..460dc925b4e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c @@ -27,9 +27,6 @@ * *****************************************************************************/ -#include -#include - #include "../wifi.h" #include "../core.h" #include "../pci.h" @@ -43,6 +40,8 @@ #include "trx.h" #include "led.h" +#include + static void rtl92c_init_aspm_vars(struct ieee80211_hw *hw) { struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index edb52987f5e..7f171682d3d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -27,8 +27,6 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include "../wifi.h" #include "../efuse.h" #include "../base.h" diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c index d028f6f2199..025bdc2eba4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c @@ -27,10 +27,6 @@ * ****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include - #include "../wifi.h" #include "../pci.h" #include "../usb.h" @@ -44,6 +40,8 @@ #include "mac.h" #include "trx.h" +#include + /* macro to shorten lines */ #define LINK_Q ui_link_quality diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index aec8cae733a..c04c3be5bd4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -41,7 +41,6 @@ #include "trx.h" #include "led.h" #include "hw.h" -#include #include MODULE_AUTHOR("Georgia "); diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c index b8d7fe39e5a..bf625f9e632 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c @@ -27,11 +27,6 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include - #include "../wifi.h" #include "../core.h" #include "../pci.h" @@ -44,6 +39,8 @@ #include "trx.h" #include "led.h" +#include + static void rtl92d_init_aspm_vars(struct ieee80211_hw *hw) { struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index 625c9eb0a11..cbaf1f345c6 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c @@ -27,8 +27,6 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include "../wifi.h" #include "../efuse.h" #include "../base.h" diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c index adfac569b67..05b4e2790e9 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c @@ -27,8 +27,6 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include "../wifi.h" #include "../pci.h" #include "../ps.h" diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c index 46be4cc8ba9..ad51906124d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c @@ -27,8 +27,6 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include "../wifi.h" #include "reg.h" #include "def.h" diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c index 3bc0128deea..0c47310b39b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c @@ -27,11 +27,6 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include - #include "../wifi.h" #include "../core.h" #include "../pci.h" @@ -45,6 +40,8 @@ #include "trx.h" #include "led.h" +#include + static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw) { struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index 78194e30fcd..e7a7ea96f42 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -25,16 +25,13 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include "core.h" #include "wifi.h" +#include "core.h" #include "usb.h" #include "base.h" #include "ps.h" #include "rtl8192c/fw_common.h" +#include #define REALTEK_USB_VENQT_READ 0xC0 #define REALTEK_USB_VENQT_WRITE 0x40 diff --git a/drivers/net/wireless/rtlwifi/usb.h b/drivers/net/wireless/rtlwifi/usb.h index cdad7c2507e..43846b32915 100644 --- a/drivers/net/wireless/rtlwifi/usb.h +++ b/drivers/net/wireless/rtlwifi/usb.h @@ -28,7 +28,6 @@ #ifndef __RTL_USB_H__ #define __RTL_USB_H__ -#include #include #define RTL_RX_DESC_SIZE 24 diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index b2d98548500..1e5fffb2db0 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -30,6 +30,8 @@ #ifndef __RTL_WIFI_H__ #define __RTL_WIFI_H__ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include -- cgit v1.2.3-70-g09d2 From 0a79bb57d46c7ee93de0e262cebb46f6f6f6a1a7 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sat, 28 Jan 2012 08:30:49 -0800 Subject: iwlwifi: fix typo Fix few places of typo Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-testmode.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h index 185b69ef753..f97d06169b4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h @@ -111,17 +111,17 @@ * * @IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32: * @IWL_TM_CMD_APP2DEV_INDIRECT_REG_WRITE32: - * commands from user applicaiton to indirectly access peripheral register + * commands from user application to indirectly access peripheral register * * @IWL_TM_CMD_APP2DEV_READ_SRAM: * @IWL_TM_CMD_APP2DEV_DUMP_SRAM: - * commands from user applicaiton to read data in sram + * commands from user application to read data in sram * - * @IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: load Weak On Wireless LAN uCode image + * @IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: load Wake On Wireless LAN uCode image * @IWL_TM_CMD_APP2DEV_GET_FW_VERSION: retrieve uCode version * @IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: retrieve ID information in device * @IWL_TM_CMD_APP2DEV_GET_FW_INFO: - * retrieve informration of existing loaded uCode image + * retrieve information of existing loaded uCode image * */ enum iwl_tm_cmd_t { -- cgit v1.2.3-70-g09d2 From 2b2db58d65edcab4bcc9d6fdd2770bb0275cdac4 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 28 Jan 2012 08:30:50 -0800 Subject: iwlwifi: fix uCode event tracing Fix multiple bugs in event tracing: 1) If you enable uCode tracing with the device down, it will still attempt to access the device and continuously log "MAC is in deep sleep!" errors. Fix this by only starting logging when the device is actually alive. 2) Now you can set the flag when the device is down, but logging doesn't happen when you bring it up. To fix that, start logging when the device comes alive. This means we don't log before -- we could do that but I don't need it right now. 3) For some reason we read the error instead of the event log -- use the right pointer. 4) Optimise SRAM reading of event log header. 5) Fix reading write pointer == capacity, which can happen due to racy SRAM access 6) Most importantly: fix an error where we would try to read WAY too many events (like 2^32-300) when we read the wrap counter before it is updated by the uCode -- this does happen in practice and will cause the driver to hang the machine. 7) Finally, change the timer to 10ms instead of 100ms as 100ms is too slow to capture all data with a normal event log and with 100ms the log will wrap multiple times before we have a chance to read it. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 99 +++++++++++++++++++++--------- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 7 ++- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 +- 3 files changed, 76 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 7321e7d3140..3e429a3e518 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -315,7 +315,7 @@ static void iwl_bg_statistics_periodic(unsigned long data) static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, u32 start_idx, u32 num_events, - u32 mode) + u32 capacity, u32 mode) { u32 i; u32 ptr; /* SRAM byte address of log data */ @@ -338,6 +338,15 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, iwl_write32(bus(priv), HBUS_TARG_MEM_RADDR, ptr); rmb(); + /* + * Refuse to read more than would have fit into the log from + * the current start_idx. This used to happen due to the race + * described below, but now WARN because the code below should + * prevent it from happening here. + */ + if (WARN_ON(num_events > capacity - start_idx)) + num_events = capacity - start_idx; + /* * "time" is actually "data" for mode 0 (no timestamp). * place event id # at far right for easier visual parsing. @@ -346,12 +355,11 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, ev = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); time = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); if (mode == 0) { - trace_iwlwifi_dev_ucode_cont_event(priv, - 0, time, ev); + trace_iwlwifi_dev_ucode_cont_event(priv, 0, time, ev); } else { data = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); - trace_iwlwifi_dev_ucode_cont_event(priv, - time, data, ev); + trace_iwlwifi_dev_ucode_cont_event(priv, time, + data, ev); } } /* Allow device to power down */ @@ -362,53 +370,83 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, static void iwl_continuous_event_trace(struct iwl_priv *priv) { u32 capacity; /* event log capacity in # entries */ + struct { + u32 capacity; + u32 mode; + u32 wrap_counter; + u32 write_counter; + } __packed read; u32 base; /* SRAM byte address of event log header */ u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */ u32 num_wraps; /* # times uCode wrapped to top of log */ u32 next_entry; /* index of next entry to be written by uCode */ - base = priv->shrd->device_pointers.error_event_table; + base = priv->shrd->device_pointers.log_event_table; if (iwlagn_hw_valid_rtc_data_addr(base)) { - capacity = iwl_read_targ_mem(bus(priv), base); - num_wraps = iwl_read_targ_mem(bus(priv), - base + (2 * sizeof(u32))); - mode = iwl_read_targ_mem(bus(priv), base + (1 * sizeof(u32))); - next_entry = iwl_read_targ_mem(bus(priv), - base + (3 * sizeof(u32))); + iwl_read_targ_mem_words(bus(priv), base, &read, sizeof(read)); + + capacity = read.capacity; + mode = read.mode; + num_wraps = read.wrap_counter; + next_entry = read.write_counter; } else return; + /* + * Unfortunately, the uCode doesn't use temporary variables. + * Therefore, it can happen that we read next_entry == capacity, + * which really means next_entry == 0. + */ + if (unlikely(next_entry == capacity)) + next_entry = 0; + /* + * Additionally, the uCode increases the write pointer before + * the wraps counter, so if the write pointer is smaller than + * the old write pointer (wrap occurred) but we read that no + * wrap occurred, we actually read between the next_entry and + * num_wraps update (this does happen in practice!!) -- take + * that into account by increasing num_wraps. + */ + if (unlikely(next_entry < priv->event_log.next_entry && + num_wraps == priv->event_log.num_wraps)) + num_wraps++; + if (num_wraps == priv->event_log.num_wraps) { - iwl_print_cont_event_trace(priv, - base, priv->event_log.next_entry, - next_entry - priv->event_log.next_entry, - mode); + iwl_print_cont_event_trace( + priv, base, priv->event_log.next_entry, + next_entry - priv->event_log.next_entry, + capacity, mode); + priv->event_log.non_wraps_count++; } else { - if ((num_wraps - priv->event_log.num_wraps) > 1) + if (num_wraps - priv->event_log.num_wraps > 1) priv->event_log.wraps_more_count++; else priv->event_log.wraps_once_count++; + trace_iwlwifi_dev_ucode_wrap_event(priv, num_wraps - priv->event_log.num_wraps, next_entry, priv->event_log.next_entry); + if (next_entry < priv->event_log.next_entry) { - iwl_print_cont_event_trace(priv, base, - priv->event_log.next_entry, - capacity - priv->event_log.next_entry, - mode); + iwl_print_cont_event_trace( + priv, base, priv->event_log.next_entry, + capacity - priv->event_log.next_entry, + capacity, mode); - iwl_print_cont_event_trace(priv, base, 0, - next_entry, mode); + iwl_print_cont_event_trace( + priv, base, 0, next_entry, capacity, mode); } else { - iwl_print_cont_event_trace(priv, base, - next_entry, capacity - next_entry, - mode); + iwl_print_cont_event_trace( + priv, base, next_entry, + capacity - next_entry, + capacity, mode); - iwl_print_cont_event_trace(priv, base, 0, - next_entry, mode); + iwl_print_cont_event_trace( + priv, base, 0, next_entry, capacity, mode); } } + priv->event_log.num_wraps = num_wraps; priv->event_log.next_entry = next_entry; } @@ -1219,6 +1257,11 @@ int iwl_alive_start(struct iwl_priv *priv) if (iwl_is_rfkill(priv->shrd)) return -ERFKILL; + if (priv->event_log.ucode_trace) { + /* start collecting data now */ + mod_timer(&priv->ucode_trace, jiffies); + } + /* download priority table before any calibration request */ if (cfg(priv)->bt_params && cfg(priv)->bt_params->advanced_bt_coexist) { diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index f837f32bb71..978a1d4c6a0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -2131,9 +2131,10 @@ static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file, if (trace) { priv->event_log.ucode_trace = true; - /* schedule the ucode timer to occur in UCODE_TRACE_PERIOD */ - mod_timer(&priv->ucode_trace, - jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD)); + if (iwl_is_alive(priv->shrd)) { + /* start collecting data now */ + mod_timer(&priv->ucode_trace, jiffies); + } } else { priv->event_log.ucode_trace = false; del_timer_sync(&priv->ucode_trace); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 4579d61da25..af846002150 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -661,7 +661,7 @@ struct traffic_stats { * schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds * to perform continuous uCode event logging operation if enabled */ -#define UCODE_TRACE_PERIOD (100) +#define UCODE_TRACE_PERIOD (10) /* * iwl_event_log: current uCode event log position -- cgit v1.2.3-70-g09d2 From dcc3ec04c14d6d840fdcc5be0ddd752a7daf7ec4 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sat, 28 Jan 2012 08:30:51 -0800 Subject: iwlwifi: add option to disalbe LED Led has no use for some platform. Add additional module parameter option to disable LED Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl-led.c | 4 ++++ drivers/net/wireless/iwlwifi/iwl-shared.h | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 3e429a3e518..90315c69cdf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2097,7 +2097,7 @@ MODULE_PARM_DESC(bt_coex_active, "enable wifi/bt co-exist (default: enable)"); module_param_named(led_mode, iwlagn_mod_params.led_mode, int, S_IRUGO); MODULE_PARM_DESC(led_mode, "0=system default, " - "1=On(RF On)/Off(RF Off), 2=blinking (default: 0)"); + "1=On(RF On)/Off(RF Off), 2=blinking, 3=Off (default: 0)"); module_param_named(power_save, iwlagn_mod_params.power_save, bool, S_IRUGO); diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index eca79087afb..8761438f153 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -177,6 +177,10 @@ void iwl_leds_init(struct iwl_priv *priv) int mode = iwlagn_mod_params.led_mode; int ret; + if (mode == IWL_LED_DISABLE) { + IWL_INFO(priv, "Led disabled\n"); + return; + } if (mode == IWL_LED_DEFAULT) mode = cfg(priv)->led_mode; diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index e406d49f418..04975b7b65b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -264,11 +264,13 @@ enum iwl_pa_type { * LED ON = RF ON * LED OFF = RF OFF * IWL_LED_BLINK: adjust led blink rate based on blink table + * IWL_LED_DISABLE: led disabled */ enum iwl_led_mode { IWL_LED_DEFAULT, IWL_LED_RF_STATE, IWL_LED_BLINK, + IWL_LED_DISABLE, }; /** -- cgit v1.2.3-70-g09d2 From 2ed81710ccc0ccebe177481b8d4ac584f9c2b569 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 28 Jan 2012 08:30:52 -0800 Subject: iwlwifi: always restrict scan dwell in P2P Whenever the PAN (P2P) context is active, it has timers in the uCode that prevent sleep, so scanning can't be out of channel for more than the beacon interval programmed into the device. Before this patch, a full scan including any passive channels when P2P was active would stall forever because it wouldn't find time to execute the passive requests (for default beacon intervals of 100 TU.) Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-scan.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 2aea20bf0f1..7f2e3a1c80e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -414,10 +414,25 @@ static u16 iwl_limit_dwell(struct iwl_priv *priv, u16 dwell_time) for_each_context(priv, ctx) { u16 value; - if (!iwl_is_associated_ctx(ctx)) - continue; - if (ctx->staging.dev_type == RXON_DEV_TYPE_P2P) + switch (ctx->staging.dev_type) { + case RXON_DEV_TYPE_P2P: + /* no timing constraints */ continue; + case RXON_DEV_TYPE_ESS: + default: + /* timing constraints if associated */ + if (!iwl_is_associated_ctx(ctx)) + continue; + break; + case RXON_DEV_TYPE_CP: + case RXON_DEV_TYPE_2STA: + /* + * These seem to always have timers for TBTT + * active in uCode even when not associated yet. + */ + break; + } + value = ctx->beacon_int; if (!value) value = IWL_PASSIVE_DWELL_BASE; -- cgit v1.2.3-70-g09d2 From 0ed7b93e307fd02188a33b80897069d3acc76485 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 30 Jan 2012 14:17:18 +0530 Subject: ath9k_htc: Load firmware asynchronously This patch modifies ath9k_htc to load the needed firmware in an asynchronous manner, fixing timeouts that were introduced with the new udev changes. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 154 ++++++++++++++++++++----------- drivers/net/wireless/ath/ath9k/hif_usb.h | 3 +- 2 files changed, 101 insertions(+), 56 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 77c8ded8de5..f317515d8bf 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -968,8 +968,7 @@ static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) ath9k_hif_usb_dealloc_rx_urbs(hif_dev); } -static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev, - u32 drv_info) +static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) { int transfer, err; const void *data = hif_dev->firmware->data; @@ -1000,7 +999,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev, } kfree(buf); - if (IS_AR7010_DEVICE(drv_info)) + if (IS_AR7010_DEVICE(hif_dev->usb_device_id->driver_info)) firm_offset = AR7010_FIRMWARE_TEXT; else firm_offset = AR9271_FIRMWARE_TEXT; @@ -1021,28 +1020,18 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev, return 0; } -static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, u32 drv_info) +static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev) { - int ret, idx; struct usb_host_interface *alt = &hif_dev->interface->altsetting[0]; struct usb_endpoint_descriptor *endp; + int ret, idx; - /* Request firmware */ - ret = request_firmware(&hif_dev->firmware, hif_dev->fw_name, - &hif_dev->udev->dev); - if (ret) { - dev_err(&hif_dev->udev->dev, - "ath9k_htc: Firmware - %s not found\n", hif_dev->fw_name); - goto err_fw_req; - } - - /* Download firmware */ - ret = ath9k_hif_usb_download_fw(hif_dev, drv_info); + ret = ath9k_hif_usb_download_fw(hif_dev); if (ret) { dev_err(&hif_dev->udev->dev, "ath9k_htc: Firmware - %s download failed\n", hif_dev->fw_name); - goto err_fw_download; + return ret; } /* On downloading the firmware to the target, the USB descriptor of EP4 @@ -1064,23 +1053,84 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, u32 drv_info) if (ret) { dev_err(&hif_dev->udev->dev, "ath9k_htc: Unable to allocate URBs\n"); - goto err_fw_download; + return ret; } return 0; - -err_fw_download: - release_firmware(hif_dev->firmware); -err_fw_req: - hif_dev->firmware = NULL; - return ret; } static void ath9k_hif_usb_dev_deinit(struct hif_device_usb *hif_dev) { ath9k_hif_usb_dealloc_urbs(hif_dev); - if (hif_dev->firmware) - release_firmware(hif_dev->firmware); +} + +/* + * If initialization fails or the FW cannot be retrieved, + * detach the device. + */ +static void ath9k_hif_usb_firmware_fail(struct hif_device_usb *hif_dev) +{ + struct device *parent = hif_dev->udev->dev.parent; + + complete(&hif_dev->fw_done); + + if (parent) + device_lock(parent); + + device_release_driver(&hif_dev->udev->dev); + + if (parent) + device_unlock(parent); +} + +static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context) +{ + struct hif_device_usb *hif_dev = context; + int ret; + + if (!fw) { + dev_err(&hif_dev->udev->dev, + "ath9k_htc: Failed to get firmware %s\n", + hif_dev->fw_name); + goto err_fw; + } + + hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev, &hif_usb, + &hif_dev->udev->dev); + if (hif_dev->htc_handle == NULL) { + goto err_fw; + } + + hif_dev->firmware = fw; + + /* Proceed with initialization */ + + ret = ath9k_hif_usb_dev_init(hif_dev); + if (ret) + goto err_dev_init; + + ret = ath9k_htc_hw_init(hif_dev->htc_handle, + &hif_dev->interface->dev, + hif_dev->usb_device_id->idProduct, + hif_dev->udev->product, + hif_dev->usb_device_id->driver_info); + if (ret) { + ret = -EINVAL; + goto err_htc_hw_init; + } + + complete(&hif_dev->fw_done); + + return; + +err_htc_hw_init: + ath9k_hif_usb_dev_deinit(hif_dev); +err_dev_init: + ath9k_htc_hw_free(hif_dev->htc_handle); + release_firmware(fw); + hif_dev->firmware = NULL; +err_fw: + ath9k_hif_usb_firmware_fail(hif_dev); } /* @@ -1155,20 +1205,16 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, } usb_get_dev(udev); + hif_dev->udev = udev; hif_dev->interface = interface; - hif_dev->device_id = id->idProduct; + hif_dev->usb_device_id = id; #ifdef CONFIG_PM udev->reset_resume = 1; #endif usb_set_intfdata(interface, hif_dev); - hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev, &hif_usb, - &hif_dev->udev->dev); - if (hif_dev->htc_handle == NULL) { - ret = -ENOMEM; - goto err_htc_hw_alloc; - } + init_completion(&hif_dev->fw_done); /* Find out which firmware to load */ @@ -1177,29 +1223,22 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, else hif_dev->fw_name = FIRMWARE_AR9271; - ret = ath9k_hif_usb_dev_init(hif_dev, id->driver_info); - if (ret) { - ret = -EINVAL; - goto err_hif_init_usb; - } - - ret = ath9k_htc_hw_init(hif_dev->htc_handle, - &interface->dev, hif_dev->device_id, - hif_dev->udev->product, id->driver_info); + ret = request_firmware_nowait(THIS_MODULE, true, hif_dev->fw_name, + &hif_dev->udev->dev, GFP_KERNEL, + hif_dev, ath9k_hif_usb_firmware_cb); if (ret) { - ret = -EINVAL; - goto err_htc_hw_init; + dev_err(&hif_dev->udev->dev, + "ath9k_htc: Async request for firmware %s failed\n", + hif_dev->fw_name); + goto err_fw_req; } - dev_info(&hif_dev->udev->dev, "ath9k_htc: USB layer initialized\n"); + dev_info(&hif_dev->udev->dev, "ath9k_htc: Firmware %s requested\n", + hif_dev->fw_name); return 0; -err_htc_hw_init: - ath9k_hif_usb_dev_deinit(hif_dev); -err_hif_init_usb: - ath9k_htc_hw_free(hif_dev->htc_handle); -err_htc_hw_alloc: +err_fw_req: usb_set_intfdata(interface, NULL); kfree(hif_dev); usb_put_dev(udev); @@ -1234,9 +1273,15 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface) if (!hif_dev) return; - ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged); - ath9k_htc_hw_free(hif_dev->htc_handle); - ath9k_hif_usb_dev_deinit(hif_dev); + wait_for_completion(&hif_dev->fw_done); + + if (hif_dev->firmware) { + ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged); + ath9k_htc_hw_free(hif_dev->htc_handle); + ath9k_hif_usb_dev_deinit(hif_dev); + release_firmware(hif_dev->firmware); + } + usb_set_intfdata(interface, NULL); if (!unplugged && (hif_dev->flags & HIF_USB_START)) @@ -1276,8 +1321,7 @@ static int ath9k_hif_usb_resume(struct usb_interface *interface) return ret; if (hif_dev->firmware) { - ret = ath9k_hif_usb_download_fw(hif_dev, - htc_handle->drv_priv->ah->hw_version.usbdev); + ret = ath9k_hif_usb_download_fw(hif_dev); if (ret) goto fail_resume; } else { diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h index 794f63094e5..487ff658b4c 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.h +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h @@ -87,10 +87,11 @@ struct cmd_buf { #define HIF_USB_START BIT(0) struct hif_device_usb { - u16 device_id; struct usb_device *udev; struct usb_interface *interface; + const struct usb_device_id *usb_device_id; const struct firmware *firmware; + struct completion fw_done; struct htc_target *htc_handle; struct hif_usb_tx tx; struct usb_anchor regout_submitted; -- cgit v1.2.3-70-g09d2 From feced2012e665468258a5c89b7f2a90b4e5695a4 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 30 Jan 2012 14:21:42 +0530 Subject: ath9k: Print the correct channel mode channelFlags doesn't contain the operating HT mode. Use IS_CHAN_HT40 to determine if the current channel is in HT40 mode. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 4a00806e285..ec82e926bad 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -340,9 +340,7 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan, fastcc = false; ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n", - hchan->channel, !!(hchan->channelFlags & (CHANNEL_HT40MINUS | - CHANNEL_HT40PLUS)), - fastcc); + hchan->channel, IS_CHAN_HT40(hchan), fastcc); r = ath9k_hw_reset(ah, hchan, caldata, fastcc); if (r) { -- cgit v1.2.3-70-g09d2 From b0302aba812bcc39291cdab9ad7e37008f352a91 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Mon, 30 Jan 2012 09:54:49 -0600 Subject: rtlwifi: Convert to asynchronous firmware load This patch addresses a kernel bugzilla report and two recent mail threads. The kernel bugzilla report is https://bugzilla.kernel.org/show_bug.cgi?id=42632, which reports a udev timeout on boot. The first mail thread, which was on LKML (http://lkml.indiana.edu/hypermail/ linux/kernel/1112.3/00965.html) was for a WARNING that occurs after a suspend/resume cycle for rtl8192cu. The scond mail thread (http://marc.info/?l=linux-wireless&m=132655490826766&w=2) concerned changes in udev that break drivers that delay while firmware is loaded on modprobe. This patch converts all rtlwifi-based drivers to use the asynchronous firmware loading mechanism. Drivers rtl8192ce, rtl8192cu and rtl8192de share a common callback routine. Driver rtl8192se needs different handling of the firmware, thus it has its own code. Signed-off-by: Larry Finger Cc: Stable Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/base.c | 1 + drivers/net/wireless/rtlwifi/core.c | 46 +++++++++++++++- drivers/net/wireless/rtlwifi/core.h | 2 + drivers/net/wireless/rtlwifi/pci.c | 26 ++++----- drivers/net/wireless/rtlwifi/pci.h | 1 - drivers/net/wireless/rtlwifi/ps.c | 3 +- drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | 10 +--- drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 6 +-- drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | 24 +++------ drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 35 ++++++------ drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | 29 ++++------ drivers/net/wireless/rtlwifi/rtl8192de/fw.c | 8 +-- drivers/net/wireless/rtlwifi/rtl8192de/hw.c | 3 -- drivers/net/wireless/rtlwifi/rtl8192de/sw.c | 38 ++++++------- drivers/net/wireless/rtlwifi/rtl8192se/fw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/hw.c | 16 +++--- drivers/net/wireless/rtlwifi/rtl8192se/led.c | 5 +- drivers/net/wireless/rtlwifi/rtl8192se/sw.c | 65 +++++++++++++++++------ drivers/net/wireless/rtlwifi/usb.c | 34 +++++------- drivers/net/wireless/rtlwifi/wifi.h | 4 +- 20 files changed, 194 insertions(+), 164 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index 7a95a544a9b..df5655cc55c 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -410,6 +410,7 @@ void rtl_init_rfkill(struct ieee80211_hw *hw) wiphy_rfkill_start_polling(hw->wiphy); } +EXPORT_SYMBOL(rtl_init_rfkill); void rtl_deinit_rfkill(struct ieee80211_hw *hw) { diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index 0ee01ab2e4f..f231b918043 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -31,8 +31,50 @@ #include "core.h" #include "cam.h" #include "base.h" +#include "pci.h" #include "ps.h" +#include + +void rtl_fw_cb(const struct firmware *firmware, void *context) +{ + struct ieee80211_hw *hw = context; + struct rtl_priv *rtlpriv = rtl_priv(hw); + int err; + + RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, + "Firmware callback routine entered!\n"); + complete(&rtlpriv->firmware_loading_complete); + if (!firmware) { + pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name); + rtlpriv->max_fw_size = 0; + return; + } + if (firmware->size > rtlpriv->max_fw_size) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "Firmware is too big!\n"); + release_firmware(firmware); + return; + } + memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size); + rtlpriv->rtlhal.fwsize = firmware->size; + release_firmware(firmware); + + err = ieee80211_register_hw(hw); + if (err) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "Can't register mac80211 hw\n"); + return; + } else { + rtlpriv->mac80211.mac80211_registered = 1; + } + set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); + + /*init rfkill */ + rtl_init_rfkill(hw); +} +EXPORT_SYMBOL(rtl_fw_cb); + /*mutex for start & stop is must here. */ static int rtl_op_start(struct ieee80211_hw *hw) { @@ -254,10 +296,12 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) * because that will cause nullfunc send by mac80211 * fail, and cause pkt loss, we have tested that 5mA * is worked very well */ - if (!rtlpriv->psc.multi_buffered) + if (!rtlpriv->psc.multi_buffered) { queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_work, MSECS(5)); + pr_info("In section\n"); + } } else { rtl_swlps_rf_awake(hw); rtlpriv->psc.sw_ps_enabled = false; diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h index 57569e0e3d4..2fe46a1b4f1 100644 --- a/drivers/net/wireless/rtlwifi/core.h +++ b/drivers/net/wireless/rtlwifi/core.h @@ -40,4 +40,6 @@ #define RTL_SUPPORTED_CTRL_FILTER 0xFF extern const struct ieee80211_ops rtl_ops; +void rtl_fw_cb(const struct firmware *firmware, void *context); + #endif diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index e4d1dcfe829..5cb2199435d 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -1565,6 +1565,9 @@ static void rtl_pci_stop(struct ieee80211_hw *hw) rtlpci->driver_is_goingto_unload = true; rtlpriv->cfg->ops->hw_disable(hw); + /* some things are not needed if firmware not available */ + if (!rtlpriv->max_fw_size) + return; rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags); @@ -1779,6 +1782,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, rtlpriv = hw->priv; pcipriv = (void *)rtlpriv->priv; pcipriv->dev.pdev = pdev; + init_completion(&rtlpriv->firmware_loading_complete); /* init cfg & intf_ops */ rtlpriv->rtlhal.interface = INTF_PCI; @@ -1799,7 +1803,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, err = pci_request_regions(pdev, KBUILD_MODNAME); if (err) { RT_ASSERT(false, "Can't obtain PCI resources\n"); - return err; + goto fail2; } pmem_start = pci_resource_start(pdev, rtlpriv->cfg->bar_id); @@ -1862,15 +1866,6 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, goto fail3; } - err = ieee80211_register_hw(hw); - if (err) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Can't register mac80211 hw\n"); - goto fail3; - } else { - rtlpriv->mac80211.mac80211_registered = 1; - } - err = sysfs_create_group(&pdev->dev.kobj, &rtl_attribute_group); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, @@ -1878,9 +1873,6 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, goto fail3; } - /*init rfkill */ - rtl_init_rfkill(hw); - rtlpci = rtl_pcidev(pcipriv); err = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt, IRQF_SHARED, KBUILD_MODNAME, hw); @@ -1889,24 +1881,22 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, "%s: failed to register IRQ handler\n", wiphy_name(hw->wiphy)); goto fail3; - } else { - rtlpci->irq_alloc = 1; } + rtlpci->irq_alloc = 1; - set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); return 0; fail3: pci_set_drvdata(pdev, NULL); rtl_deinit_core(hw); _rtl_pci_io_handler_release(hw); - ieee80211_free_hw(hw); if (rtlpriv->io.pci_mem_start != 0) pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start); fail2: pci_release_regions(pdev); + complete(&rtlpriv->firmware_loading_complete); fail1: @@ -1925,6 +1915,8 @@ void rtl_pci_disconnect(struct pci_dev *pdev) struct rtl_pci *rtlpci = rtl_pcidev(pcipriv); struct rtl_mac *rtlmac = rtl_mac(rtlpriv); + /* just in case driver is removed before firmware callback */ + wait_for_completion(&rtlpriv->firmware_loading_complete); clear_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); sysfs_remove_group(&pdev->dev.kobj, &rtl_attribute_group); diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h index 99d81ede17b..241448fc9ed 100644 --- a/drivers/net/wireless/rtlwifi/pci.h +++ b/drivers/net/wireless/rtlwifi/pci.h @@ -239,7 +239,6 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, void rtl_pci_disconnect(struct pci_dev *pdev); int rtl_pci_suspend(struct device *dev); int rtl_pci_resume(struct device *dev); - static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr) { return readb((u8 __iomem *) rtlpriv->io.pci_mem_start + addr); diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index b151266ef9f..15f86eaa1cd 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c @@ -47,7 +47,8 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw) "Driver is already down!\n"); /*<2> Enable Adapter */ - rtlpriv->cfg->ops->hw_init(hw); + if (rtlpriv->cfg->ops->hw_init(hw)) + return 1; RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); /*<3> Enable Interrupt */ diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index 82bbc8384ac..c20b3c30f62 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c @@ -257,10 +257,9 @@ int rtl92c_download_fw(struct ieee80211_hw *hw) u32 fwsize; enum version_8192c version = rtlhal->version; - if (!rtlhal->pfirmware) + if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware) return 1; - pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name); pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware; pfwdata = (u8 *) rtlhal->pfirmware; fwsize = rtlhal->fwsize; @@ -512,15 +511,8 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, u32 cmd_len, u8 *p_cmdbuffer) { - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); u32 tmp_cmdbuf[2]; - if (rtlhal->fw_ready == false) { - RT_ASSERT(false, - "return H2C cmd because of Fw download fail!!!\n"); - return; - } - memset(tmp_cmdbuf, 0, 8); memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len); _rtl92c_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index c5aced459cd..48c7b5d3fc5 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -917,10 +917,7 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "Failed to download FW. Init HW without FW now..\n"); err = 1; - rtlhal->fw_ready = false; return err; - } else { - rtlhal->fw_ready = true; } rtlhal->last_hmeboxnum = 0; @@ -1193,7 +1190,6 @@ static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); u8 u1b_tmp; u32 u4b_tmp; @@ -1204,7 +1200,7 @@ static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE0); - if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->fw_ready) + if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) rtl92c_firmware_selfreset(hw); rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x51); rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index 460dc925b4e..2c3b73366cd 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c @@ -91,9 +91,7 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) int err; struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - const struct firmware *firmware; struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - char *fw_name = NULL; rtl8192ce_bt_reg_init(hw); @@ -165,26 +163,20 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) /* request fw */ if (IS_VENDOR_UMC_A_CUT(rtlhal->version) && !IS_92C_SERIAL(rtlhal->version)) - fw_name = "rtlwifi/rtl8192cfwU.bin"; + rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU.bin"; else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) - fw_name = "rtlwifi/rtl8192cfwU_B.bin"; - else - fw_name = rtlpriv->cfg->fw_name; - err = request_firmware(&firmware, fw_name, rtlpriv->io.dev); + rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU_B.bin"; + + rtlpriv->max_fw_size = 0x4000; + pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name); + err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Failed to request firmware!\n"); return 1; } - if (firmware->size > 0x4000) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Firmware is too big!\n"); - release_firmware(firmware); - return 1; - } - memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size); - rtlpriv->rtlhal.fwsize = firmware->size; - release_firmware(firmware); return 0; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 7f171682d3d..0c74d4f2eeb 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -997,10 +997,7 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "Failed to download FW. Init HW without FW now..\n"); err = 1; - rtlhal->fw_ready = false; return err; - } else { - rtlhal->fw_ready = true; } rtlhal->last_hmeboxnum = 0; /* h2c */ _rtl92cu_phy_param_tab_init(hw); @@ -1094,23 +1091,21 @@ static void _ResetDigitalProcedure1(struct ieee80211_hw *hw, bool bWithoutHWSM) if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(1)) { /* reset MCU ready status */ rtl_write_byte(rtlpriv, REG_MCUFWDL, 0); - if (rtlhal->fw_ready) { - /* 8051 reset by self */ - rtl_write_byte(rtlpriv, REG_HMETFR+3, 0x20); - while ((retry_cnts++ < 100) && - (FEN_CPUEN & rtl_read_word(rtlpriv, - REG_SYS_FUNC_EN))) { - udelay(50); - } - if (retry_cnts >= 100) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "#####=> 8051 reset failed!.........................\n"); - /* if 8051 reset fail, reset MAC. */ - rtl_write_byte(rtlpriv, - REG_SYS_FUNC_EN + 1, - 0x50); - udelay(100); - } + /* 8051 reset by self */ + rtl_write_byte(rtlpriv, REG_HMETFR+3, 0x20); + while ((retry_cnts++ < 100) && + (FEN_CPUEN & rtl_read_word(rtlpriv, + REG_SYS_FUNC_EN))) { + udelay(50); + } + if (retry_cnts >= 100) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "#####=> 8051 reset failed!.........................\n"); + /* if 8051 reset fail, reset MAC. */ + rtl_write_byte(rtlpriv, + REG_SYS_FUNC_EN + 1, + 0x50); + udelay(100); } } /* Reset MAC and Enable 8051 */ diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index c04c3be5bd4..82c85286ab2 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -53,7 +53,6 @@ MODULE_FIRMWARE("rtlwifi/rtl8192cufw.bin"); static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); - const struct firmware *firmware; int err; rtlpriv->dm.dm_initialgain_enable = true; @@ -61,29 +60,21 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->dm.disable_framebursting = false; rtlpriv->dm.thermalvalue = 0; rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug; - rtlpriv->rtlhal.pfirmware = vmalloc(0x4000); + + /* for firmware buf */ + rtlpriv->rtlhal.pfirmware = vzalloc(0x4000); if (!rtlpriv->rtlhal.pfirmware) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't alloc buffer for fw\n"); return 1; } - /* request fw */ - err = request_firmware(&firmware, rtlpriv->cfg->fw_name, - rtlpriv->io.dev); - if (err) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Failed to request firmware!\n"); - return 1; - } - if (firmware->size > 0x4000) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Firmware is too big!\n"); - release_firmware(firmware); - return 1; - } - memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size); - rtlpriv->rtlhal.fwsize = firmware->size; - release_firmware(firmware); + + pr_info("Loading firmware %s\n", rtlpriv->cfg->fw_name); + rtlpriv->max_fw_size = 0x4000; + err = request_firmware_nowait(THIS_MODULE, 1, + rtlpriv->cfg->fw_name, rtlpriv->io.dev, + GFP_KERNEL, hw, rtl_fw_cb); + return 0; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c index b59de75a364..f548a8d0068 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c @@ -253,7 +253,7 @@ int rtl92d_download_fw(struct ieee80211_hw *hw) bool fw_downloaded = false, fwdl_in_process = false; unsigned long flags; - if (!rtlhal->pfirmware) + if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware) return 1; fwsize = rtlhal->fwsize; pfwheader = (u8 *) rtlhal->pfirmware; @@ -532,14 +532,8 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw, void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, u32 cmd_len, u8 *cmdbuffer) { - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); u32 tmp_cmdbuf[2]; - if (rtlhal->fw_ready == false) { - RT_ASSERT(false, - "return H2C cmd because of Fw download fail!!!\n"); - return; - } memset(tmp_cmdbuf, 0, 8); memcpy(tmp_cmdbuf, cmdbuffer, cmd_len); _rtl92d_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf); diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c index 695bccb4375..7d877125db2 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c @@ -931,10 +931,7 @@ int rtl92de_hw_init(struct ieee80211_hw *hw) if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "Failed to download FW. Init HW without FW..\n"); - rtlhal->fw_ready = false; return 1; - } else { - rtlhal->fw_ready = true; } rtlhal->last_hmeboxnum = 0; rtlpriv->psc.fw_current_inpsmode = false; diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c index bf625f9e632..4898c502974 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c @@ -91,7 +91,6 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) u8 tid; struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - const struct firmware *firmware; static int header_print; rtlpriv->dm.dm_initialgain_enable = true; @@ -167,6 +166,15 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) else if (rtlpriv->psc.reg_fwctrl_lps == 3) rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE; + /* for early mode */ + rtlpriv->rtlhal.earlymode_enable = true; + for (tid = 0; tid < 8; tid++) + skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]); + + /* Only load firmware for first MAC */ + if (header_print) + return 0; + /* for firmware buf */ rtlpriv->rtlhal.pfirmware = vzalloc(0x8000); if (!rtlpriv->rtlhal.pfirmware) { @@ -175,33 +183,21 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) return 1; } - if (!header_print) { - pr_info("Driver for Realtek RTL8192DE WLAN interface\n"); - pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name); - header_print++; - } + rtlpriv->max_fw_size = 0x8000; + pr_info("Driver for Realtek RTL8192DE WLAN interface\n"); + pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name); + header_print++; + /* request fw */ - err = request_firmware(&firmware, rtlpriv->cfg->fw_name, - rtlpriv->io.dev); + err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Failed to request firmware!\n"); return 1; } - if (firmware->size > 0x8000) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Firmware is too big!\n"); - release_firmware(firmware); - return 1; - } - memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size); - rtlpriv->rtlhal.fwsize = firmware->size; - release_firmware(firmware); - /* for early mode */ - rtlpriv->rtlhal.earlymode_enable = true; - for (tid = 0; tid < 8; tid++) - skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]); return 0; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c index 595ecd22ffa..0d8bf565700 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c @@ -364,7 +364,7 @@ int rtl92s_download_fw(struct ieee80211_hw *hw) u8 fwstatus = FW_STATUS_INIT; bool rtstatus = true; - if (!rtlhal->pfirmware) + if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware) return 1; firmware = (struct rt_firmware *)rtlhal->pfirmware; diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index cbaf1f345c6..22098c2f38f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c @@ -949,10 +949,9 @@ int rtl92se_hw_init(struct ieee80211_hw *hw) rtstatus = rtl92s_download_fw(hw); if (!rtstatus) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "Failed to download FW. Init HW without FW now... Please copy FW into /lib/firmware/rtlwifi\n"); - rtlhal->fw_ready = false; - } else { - rtlhal->fw_ready = true; + "Failed to download FW. Init HW without FW now... " + "Please copy FW into /lib/firmware/rtlwifi\n"); + return 1; } /* After FW download, we have to reset MAC register */ @@ -1215,9 +1214,14 @@ void rtl92se_enable_interrupt(struct ieee80211_hw *hw) void rtl92se_disable_interrupt(struct ieee80211_hw *hw) { - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv; + struct rtl_pci *rtlpci; + rtlpriv = rtl_priv(hw); + /* if firmware not available, no interrupts */ + if (!rtlpriv || !rtlpriv->max_fw_size) + return; + rtlpci = rtl_pcidev(rtl_pcipriv(hw)); rtl_write_dword(rtlpriv, INTA_MASK, 0); rtl_write_dword(rtlpriv, INTA_MASK + 4, 0); diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/led.c b/drivers/net/wireless/rtlwifi/rtl8192se/led.c index ef4211bca58..44949b5cbb8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/led.c @@ -76,10 +76,13 @@ void rtl92se_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) void rtl92se_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) { - struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_priv *rtlpriv; struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); u8 ledcfg; + rtlpriv = rtl_priv(hw); + if (!rtlpriv || rtlpriv->max_fw_size) + return; RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", LEDCFG, pled->ledpin); diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c index 0c47310b39b..ca38dd9f356 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c @@ -30,6 +30,8 @@ #include "../wifi.h" #include "../core.h" #include "../pci.h" +#include "../base.h" +#include "../pci.h" #include "reg.h" #include "def.h" #include "phy.h" @@ -86,12 +88,53 @@ static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw) rtlpci->const_support_pciaspm = 2; } +static void rtl92se_fw_cb(const struct firmware *firmware, void *context) +{ + struct ieee80211_hw *hw = context; + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(pcipriv); + struct rt_firmware *pfirmware = NULL; + int err; + + RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, + "Firmware callback routine entered!\n"); + complete(&rtlpriv->firmware_loading_complete); + if (!firmware) { + pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name); + rtlpriv->max_fw_size = 0; + return; + } + if (firmware->size > rtlpriv->max_fw_size) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "Firmware is too big!\n"); + release_firmware(firmware); + return; + } + pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware; + memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size); + pfirmware->sz_fw_tmpbufferlen = firmware->size; + release_firmware(firmware); + + err = ieee80211_register_hw(hw); + if (err) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "Can't register mac80211 hw\n"); + return; + } else { + rtlpriv->mac80211.mac80211_registered = 1; + } + rtlpci->irq_alloc = 1; + set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); + + /*init rfkill */ + rtl_init_rfkill(hw); +} + static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - const struct firmware *firmware; - struct rt_firmware *pfirmware = NULL; int err = 0; u16 earlyrxthreshold = 7; @@ -189,27 +232,19 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) return 1; } + rtlpriv->max_fw_size = sizeof(struct rt_firmware); + pr_info("Driver for Realtek RTL8192SE/RTL8191SE\n" "Loading firmware %s\n", rtlpriv->cfg->fw_name); /* request fw */ - err = request_firmware(&firmware, rtlpriv->cfg->fw_name, - rtlpriv->io.dev); + err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl92se_fw_cb); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Failed to request firmware!\n"); return 1; } - if (firmware->size > sizeof(struct rt_firmware)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Firmware is too big!\n"); - release_firmware(firmware); - return 1; - } - - pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware; - memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size); - pfirmware->sz_fw_tmpbufferlen = firmware->size; - release_firmware(firmware); return err; } diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index e7a7ea96f42..ffcf89fe45e 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -664,15 +664,17 @@ static int rtl_usb_start(struct ieee80211_hw *hw) struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); err = rtlpriv->cfg->ops->hw_init(hw); - rtl_init_rx_config(hw); + if (!err) { + rtl_init_rx_config(hw); - /* Enable software */ - SET_USB_START(rtlusb); - /* should after adapter start and interrupt enable. */ - set_hal_start(rtlhal); + /* Enable software */ + SET_USB_START(rtlusb); + /* should after adapter start and interrupt enable. */ + set_hal_start(rtlhal); - /* Start bulk IN */ - _rtl_usb_receive(hw); + /* Start bulk IN */ + _rtl_usb_receive(hw); + } return err; } @@ -949,6 +951,7 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, return -ENOMEM; } rtlpriv = hw->priv; + init_completion(&rtlpriv->firmware_loading_complete); SET_IEEE80211_DEV(hw, &intf->dev); udev = interface_to_usbdev(intf); usb_get_dev(udev); @@ -982,24 +985,12 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, goto error_out; } - /*init rfkill */ - /* rtl_init_rfkill(hw); */ - - err = ieee80211_register_hw(hw); - if (err) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - "Can't register mac80211 hw\n"); - goto error_out; - } else { - rtlpriv->mac80211.mac80211_registered = 1; - } - set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); return 0; error_out: rtl_deinit_core(hw); _rtl_usb_io_handler_release(hw); - ieee80211_free_hw(hw); usb_put_dev(udev); + complete(&rtlpriv->firmware_loading_complete); return -ENODEV; } EXPORT_SYMBOL(rtl_usb_probe); @@ -1013,6 +1004,9 @@ void rtl_usb_disconnect(struct usb_interface *intf) if (unlikely(!rtlpriv)) return; + + /* just in case driver is removed before firmware callback */ + wait_for_completion(&rtlpriv->firmware_loading_complete); /*ieee80211_unregister_hw will call ops_stop */ if (rtlmac->mac80211_registered == 1) { ieee80211_unregister_hw(hw); diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 1e5fffb2db0..b591614c3b9 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -38,6 +38,7 @@ #include #include #include +#include #include "debug.h" #define RF_CHANGE_BY_INIT 0 @@ -1047,7 +1048,6 @@ struct rtl_hal { u16 fw_subversion; bool h2c_setinprogress; u8 last_hmeboxnum; - bool fw_ready; /*Reserve page start offset except beacon in TxQ. */ u8 fw_rsvdpage_startoffset; u8 h2c_txcmd_seq; @@ -1593,6 +1593,7 @@ struct rtl_debug { }; struct rtl_priv { + struct completion firmware_loading_complete; struct rtl_locks locks; struct rtl_works works; struct rtl_mac mac80211; @@ -1614,6 +1615,7 @@ struct rtl_priv { struct rtl_rate_priv *rate_priv; struct rtl_debug dbg; + int max_fw_size; /* *hal_cfg : for diff cards -- cgit v1.2.3-70-g09d2 From c0eb46766d395da8d62148bda2e59bad5e6ee2f2 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 30 Jan 2012 19:56:52 +0000 Subject: regmap: Implement managed regmap_init() Save error handling and unwinding code in drivers by providing managed versions of the regmap init functions, simplifying usage. Signed-off-by: Mark Brown --- drivers/base/regmap/regmap-i2c.c | 17 +++++++++++++++++ drivers/base/regmap/regmap-spi.c | 17 +++++++++++++++++ drivers/base/regmap/regmap.c | 39 +++++++++++++++++++++++++++++++++++++++ include/linux/regmap.h | 8 ++++++++ 4 files changed, 81 insertions(+) (limited to 'drivers') diff --git a/drivers/base/regmap/regmap-i2c.c b/drivers/base/regmap/regmap-i2c.c index 38621ec87c0..9a3a8c56438 100644 --- a/drivers/base/regmap/regmap-i2c.c +++ b/drivers/base/regmap/regmap-i2c.c @@ -111,4 +111,21 @@ struct regmap *regmap_init_i2c(struct i2c_client *i2c, } EXPORT_SYMBOL_GPL(regmap_init_i2c); +/** + * devm_regmap_init_i2c(): Initialise managed register map + * + * @i2c: Device that will be interacted with + * @config: Configuration for register map + * + * The return value will be an ERR_PTR() on error or a valid pointer + * to a struct regmap. The regmap will be automatically freed by the + * device management code. + */ +struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c, + const struct regmap_config *config) +{ + return devm_regmap_init(&i2c->dev, ®map_i2c, config); +} +EXPORT_SYMBOL_GPL(devm_regmap_init_i2c); + MODULE_LICENSE("GPL"); diff --git a/drivers/base/regmap/regmap-spi.c b/drivers/base/regmap/regmap-spi.c index 2560658de34..7c0c35a39c3 100644 --- a/drivers/base/regmap/regmap-spi.c +++ b/drivers/base/regmap/regmap-spi.c @@ -70,4 +70,21 @@ struct regmap *regmap_init_spi(struct spi_device *spi, } EXPORT_SYMBOL_GPL(regmap_init_spi); +/** + * devm_regmap_init_spi(): Initialise register map + * + * @spi: Device that will be interacted with + * @config: Configuration for register map + * + * The return value will be an ERR_PTR() on error or a valid pointer + * to a struct regmap. The map will be automatically freed by the + * device management code. + */ +struct regmap *devm_regmap_init_spi(struct spi_device *spi, + const struct regmap_config *config) +{ + return devm_regmap_init(&spi->dev, ®map_spi, config); +} +EXPORT_SYMBOL_GPL(devm_regmap_init_spi); + MODULE_LICENSE("GPL"); diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index be10a4ff660..839cc82bd17 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -258,6 +258,45 @@ err: } EXPORT_SYMBOL_GPL(regmap_init); +static void devm_regmap_release(struct device *dev, void *res) +{ + regmap_exit(*(struct regmap **)res); +} + +/** + * devm_regmap_init(): Initialise managed register map + * + * @dev: Device that will be interacted with + * @bus: Bus-specific callbacks to use with device + * @config: Configuration for register map + * + * The return value will be an ERR_PTR() on error or a valid pointer + * to a struct regmap. This function should generally not be called + * directly, it should be called by bus-specific init functions. The + * map will be automatically freed by the device management code. + */ +struct regmap *devm_regmap_init(struct device *dev, + const struct regmap_bus *bus, + const struct regmap_config *config) +{ + struct regmap **ptr, *regmap; + + ptr = devres_alloc(devm_regmap_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return ERR_PTR(-ENOMEM); + + regmap = regmap_init(dev, bus, config); + if (!IS_ERR(regmap)) { + *ptr = regmap; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return regmap; +} +EXPORT_SYMBOL_GPL(devm_regmap_init); + /** * regmap_reinit_cache(): Reinitialise the current register cache * diff --git a/include/linux/regmap.h b/include/linux/regmap.h index eb93921cdd3..195db51ec79 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -127,6 +127,14 @@ struct regmap *regmap_init_i2c(struct i2c_client *i2c, struct regmap *regmap_init_spi(struct spi_device *dev, const struct regmap_config *config); +struct regmap *devm_regmap_init(struct device *dev, + const struct regmap_bus *bus, + const struct regmap_config *config); +struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c, + const struct regmap_config *config); +struct regmap *devm_regmap_init_spi(struct spi_device *dev, + const struct regmap_config *config); + void regmap_exit(struct regmap *map); int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config); -- cgit v1.2.3-70-g09d2 From ff3d9c3c90c6edcb975c390db3671713899c2842 Mon Sep 17 00:00:00 2001 From: Mark Allyn Date: Wed, 28 Dec 2011 17:37:59 +0000 Subject: staging: sep: SEP update This is basically a rewrite so there isn't a nice easy to present way of providing this as a patch series. This patch is a pull of Mark's new driver into the upstream staging area. On top of that are a series of patches by Andy Shevchenko to make it build on the current tree, fix a few things and even get it passed sparse. The new driver supports the kernel crypto layer, passes the coding style checks, passes human taste checks and has proper kernel-doc formatted comments. I've then folded back in some later fixes it was missing that got applied to to the kernel tree. This should be ready for more serious review with a view to migration from the staging tree shortly. Signed-off-by: Mark Allyn [Forward port and some bug fixing] Signed-off-by: Andy Shevchenko [Fold and tweaks for 3.2] Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/Kconfig | 3 +- drivers/staging/sep/Makefile | 5 +- drivers/staging/sep/TODO | 5 +- drivers/staging/sep/sep_crypto.c | 3768 ++++++++++++++++++++++++++ drivers/staging/sep/sep_crypto.h | 348 +++ drivers/staging/sep/sep_dev.h | 99 +- drivers/staging/sep/sep_driver.c | 2932 -------------------- drivers/staging/sep/sep_driver_api.h | 280 +- drivers/staging/sep/sep_driver_config.h | 79 +- drivers/staging/sep/sep_driver_hw_defs.h | 182 +- drivers/staging/sep/sep_main.c | 4286 ++++++++++++++++++++++++++++++ drivers/staging/sep/sep_trace_events.h | 188 ++ 12 files changed, 8960 insertions(+), 3215 deletions(-) create mode 100644 drivers/staging/sep/sep_crypto.c create mode 100644 drivers/staging/sep/sep_crypto.h delete mode 100644 drivers/staging/sep/sep_driver.c create mode 100644 drivers/staging/sep/sep_main.c create mode 100644 drivers/staging/sep/sep_trace_events.h (limited to 'drivers') diff --git a/drivers/staging/sep/Kconfig b/drivers/staging/sep/Kconfig index 92bf16667d0..185b676d858 100644 --- a/drivers/staging/sep/Kconfig +++ b/drivers/staging/sep/Kconfig @@ -3,7 +3,8 @@ config DX_SEP depends on PCI help Discretix SEP driver; used for the security processor subsystem - on bard the Intel Mobile Internet Device. + on board the Intel Mobile Internet Device and adds SEP availability + to the kernel crypto infrastructure The driver's name is sep_driver. diff --git a/drivers/staging/sep/Makefile b/drivers/staging/sep/Makefile index 628d5f91941..e48a7959289 100644 --- a/drivers/staging/sep/Makefile +++ b/drivers/staging/sep/Makefile @@ -1,2 +1,3 @@ -obj-$(CONFIG_DX_SEP) := sep_driver.o - +ccflags-y += -I$(srctree)/$(src) +obj-$(CONFIG_DX_SEP) += sep_driver.o +sep_driver-objs := sep_crypto.o sep_main.o diff --git a/drivers/staging/sep/TODO b/drivers/staging/sep/TODO index 8f3b878ad8a..3524d0cf84b 100644 --- a/drivers/staging/sep/TODO +++ b/drivers/staging/sep/TODO @@ -1,4 +1,3 @@ Todo's so far (from Alan Cox) -- Check whether it can be plugged into any of the kernel crypto API - interfaces - Crypto API 'glue' is still not ready to submit -- Clean up un-needed debug prints - Started to work on this +- Clean up unused ioctls +- Clean up unused fields in ioctl structures diff --git a/drivers/staging/sep/sep_crypto.c b/drivers/staging/sep/sep_crypto.c new file mode 100644 index 00000000000..a6b0f8353bb --- /dev/null +++ b/drivers/staging/sep/sep_crypto.c @@ -0,0 +1,3768 @@ +/* + * + * sep_crypto.c - Crypto interface structures + * + * Copyright(c) 2009-2011 Intel Corporation. All rights reserved. + * Contributions(c) 2009-2010 Discretix. 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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * CONTACTS: + * + * Mark Allyn mark.a.allyn@intel.com + * Jayant Mangalampalli jayant.mangalampalli@intel.com + * + * CHANGES: + * + * 2009.06.26 Initial publish + * 2010.09.14 Upgrade to Medfield + * 2011.02.22 Enable Kernel Crypto + * + */ + +/* #define DEBUG */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sep_driver_hw_defs.h" +#include "sep_driver_config.h" +#include "sep_driver_api.h" +#include "sep_dev.h" +#include "sep_crypto.h" + +/* Globals for queuing */ +static spinlock_t queue_lock; +static struct crypto_queue sep_queue; + +/* Declare of dequeuer */ +static void sep_dequeuer(void *data); + +/* TESTING */ +/** + * crypto_sep_dump_message - dump the message that is pending + * @sep: SEP device + * This will only print dump if DEBUG is set; it does + * follow kernel debug print enabling + */ +static void crypto_sep_dump_message(struct sep_system_ctx *sctx) +{ +#if 0 + u32 *p; + u32 *i; + int count; + + p = sctx->sep_used->shared_addr; + i = (u32 *)sctx->msg; + for (count = 0; count < 40 * 4; count += 4) + dev_dbg(&sctx->sep_used->pdev->dev, + "[PID%d] Word %d of the message is %x (local)%x\n", + current->pid, count/4, *p++, *i++); +#endif +} + +/** + * sep_do_callback + * @work: pointer to work_struct + * This is what is called by the queue; it is generic so that it + * can be used by any type of operation as each different callback + * function can use the data parameter in its own way + */ +static void sep_do_callback(struct work_struct *work) +{ + struct sep_work_struct *sep_work = container_of(work, + struct sep_work_struct, work); + if (sep_work != NULL) { + (sep_work->callback)(sep_work->data); + kfree(sep_work); + } else { + pr_debug("sep crypto: do callback - NULL container\n"); + } +} + +/** + * sep_submit_work + * @work_queue: pointer to struct_workqueue + * @funct: pointer to function to execute + * @data: pointer to data; function will know + * how to use it + * This is a generic API to submit something to + * the queue. The callback function will depend + * on what operation is to be done + */ +static int sep_submit_work(struct workqueue_struct *work_queue, + void(*funct)(void *), + void *data) +{ + struct sep_work_struct *sep_work; + int result; + + sep_work = kmalloc(sizeof(struct sep_work_struct), GFP_ATOMIC); + + if (sep_work == NULL) { + pr_debug("sep crypto: cant allocate work structure\n"); + return -ENOMEM; + } + + sep_work->callback = funct; + sep_work->data = data; + INIT_WORK(&sep_work->work, sep_do_callback); + result = queue_work(work_queue, &sep_work->work); + if (!result) { + pr_debug("sep_crypto: queue_work failed\n"); + return -EINVAL; + } + return 0; +} + +/** + * sep_alloc_sg_buf - + * @sep: pointer to struct sep_device + * @size: total size of area + * @block_size: minimum size of chunks + * each page is minimum or modulo this size + * @returns: pointer to struct scatterlist for new + * buffer + **/ +static struct scatterlist *sep_alloc_sg_buf( + struct sep_device *sep, + size_t size, + size_t block_size) +{ + u32 nbr_pages; + u32 ct1; + void *buf; + size_t current_size; + size_t real_page_size; + + struct scatterlist *sg, *sg_temp; + + if (size == 0) + return NULL; + + dev_dbg(&sep->pdev->dev, "sep alloc sg buf\n"); + + current_size = 0; + nbr_pages = 0; + real_page_size = PAGE_SIZE - (PAGE_SIZE % block_size); + /** + * The size of each page must be modulo of the operation + * block size; increment by the modified page size until + * the total size is reached, then you have the number of + * pages + */ + while (current_size < size) { + current_size += real_page_size; + nbr_pages += 1; + } + + sg = kmalloc((sizeof(struct scatterlist) * nbr_pages), GFP_ATOMIC); + if (!sg) { + dev_warn(&sep->pdev->dev, "Cannot allocate page for new sg\n"); + return NULL; + } + + sg_init_table(sg, nbr_pages); + + current_size = 0; + sg_temp = sg; + for (ct1 = 0; ct1 < nbr_pages; ct1 += 1) { + buf = (void *)get_zeroed_page(GFP_ATOMIC); + if (!buf) { + dev_warn(&sep->pdev->dev, + "Cannot allocate page for new buffer\n"); + kfree(sg); + return NULL; + } + + sg_set_buf(sg_temp, buf, real_page_size); + if ((size - current_size) > real_page_size) { + sg_temp->length = real_page_size; + current_size += real_page_size; + } else { + sg_temp->length = (size - current_size); + current_size = size; + } + sg_temp = sg_next(sg); + } + return sg; +} + +/** + * sep_free_sg_buf - + * @sg: pointer to struct scatterlist; points to area to free + */ +static void sep_free_sg_buf(struct scatterlist *sg) +{ + struct scatterlist *sg_temp = sg; + while (sg_temp) { + free_page((unsigned long)sg_virt(sg_temp)); + sg_temp = sg_next(sg_temp); + } + kfree(sg); +} + +/** + * sep_copy_sg - + * @sep: pointer to struct sep_device + * @sg_src: pointer to struct scatterlist for source + * @sg_dst: pointer to struct scatterlist for destination + * @size: size (in bytes) of data to copy + * + * Copy data from one scatterlist to another; both must + * be the same size + */ +static void sep_copy_sg( + struct sep_device *sep, + struct scatterlist *sg_src, + struct scatterlist *sg_dst, + size_t size) +{ + u32 seg_size; + u32 in_offset, out_offset; + + u32 count = 0; + struct scatterlist *sg_src_tmp = sg_src; + struct scatterlist *sg_dst_tmp = sg_dst; + in_offset = 0; + out_offset = 0; + + dev_dbg(&sep->pdev->dev, "sep copy sg\n"); + + if ((sg_src == NULL) || (sg_dst == NULL) || (size == 0)) + return; + + dev_dbg(&sep->pdev->dev, "sep copy sg not null\n"); + + while (count < size) { + if ((sg_src_tmp->length - in_offset) > + (sg_dst_tmp->length - out_offset)) + seg_size = sg_dst_tmp->length - out_offset; + else + seg_size = sg_src_tmp->length - in_offset; + + if (seg_size > (size - count)) + seg_size = (size = count); + + memcpy(sg_virt(sg_dst_tmp) + out_offset, + sg_virt(sg_src_tmp) + in_offset, + seg_size); + + in_offset += seg_size; + out_offset += seg_size; + count += seg_size; + + if (in_offset >= sg_src_tmp->length) { + sg_src_tmp = sg_next(sg_src_tmp); + in_offset = 0; + } + + if (out_offset >= sg_dst_tmp->length) { + sg_dst_tmp = sg_next(sg_dst_tmp); + out_offset = 0; + } + } +} + +/** + * sep_oddball_pages - + * @sep: pointer to struct sep_device + * @sg: pointer to struct scatterlist - buffer to check + * @size: total data size + * @blocksize: minimum block size; must be multiples of this size + * @to_copy: 1 means do copy, 0 means do not copy + * @new_sg: pointer to location to put pointer to new sg area + * @returns: 1 if new scatterlist is needed; 0 if not needed; + * error value if operation failed + * + * The SEP device requires all pages to be multiples of the + * minimum block size appropriate for the operation + * This function check all pages; if any are oddball sizes + * (not multiple of block sizes), it creates a new scatterlist. + * If the to_copy parameter is set to 1, then a scatter list + * copy is performed. The pointer to the new scatterlist is + * put into the address supplied by the new_sg parameter; if + * no new scatterlist is needed, then a NULL is put into + * the location at new_sg. + * + */ +static int sep_oddball_pages( + struct sep_device *sep, + struct scatterlist *sg, + size_t data_size, + u32 block_size, + struct scatterlist **new_sg, + u32 do_copy) +{ + struct scatterlist *sg_temp; + u32 flag; + u32 nbr_pages, page_count; + + dev_dbg(&sep->pdev->dev, "sep oddball\n"); + if ((sg == NULL) || (data_size == 0) || (data_size < block_size)) + return 0; + + dev_dbg(&sep->pdev->dev, "sep oddball not null\n"); + flag = 0; + nbr_pages = 0; + page_count = 0; + sg_temp = sg; + + while (sg_temp) { + nbr_pages += 1; + sg_temp = sg_next(sg_temp); + } + + sg_temp = sg; + while ((sg_temp) && (flag == 0)) { + page_count += 1; + if (sg_temp->length % block_size) + flag = 1; + else + sg_temp = sg_next(sg_temp); + } + + /* Do not process if last (or only) page is oddball */ + if (nbr_pages == page_count) + flag = 0; + + if (flag) { + dev_dbg(&sep->pdev->dev, "sep oddball processing\n"); + *new_sg = sep_alloc_sg_buf(sep, data_size, block_size); + if (*new_sg == NULL) { + dev_warn(&sep->pdev->dev, "cannot allocate new sg\n"); + return -ENOMEM; + } + + if (do_copy) + sep_copy_sg(sep, sg, *new_sg, data_size); + + return 1; + } else { + return 0; + } +} + +/** + * sep_copy_offset_sg - + * @sep: pointer to struct sep_device; + * @sg: pointer to struct scatterlist + * @offset: offset into scatterlist memory + * @dst: place to put data + * @len: length of data + * @returns: number of bytes copies + * + * This copies data from scatterlist buffer + * offset from beginning - it is needed for + * handling tail data in hash + */ +static size_t sep_copy_offset_sg( + struct sep_device *sep, + struct scatterlist *sg, + u32 offset, + void *dst, + u32 len) +{ + size_t page_start; + size_t page_end; + size_t offset_within_page; + size_t length_within_page; + size_t length_remaining; + size_t current_offset; + + /* Find which page is beginning of segment */ + page_start = 0; + page_end = sg->length; + while ((sg) && (offset > page_end)) { + page_start += sg->length; + sg = sg_next(sg); + if (sg) + page_end += sg->length; + } + + if (sg == NULL) + return -ENOMEM; + + offset_within_page = offset - page_start; + if ((sg->length - offset_within_page) >= len) { + /* All within this page */ + memcpy(dst, sg_virt(sg) + offset_within_page, len); + return len; + } else { + /* Scattered multiple pages */ + current_offset = 0; + length_remaining = len; + while ((sg) && (current_offset < len)) { + length_within_page = sg->length - offset_within_page; + if (length_within_page >= length_remaining) { + memcpy(dst+current_offset, + sg_virt(sg) + offset_within_page, + length_remaining); + length_remaining = 0; + current_offset = len; + } else { + memcpy(dst+current_offset, + sg_virt(sg) + offset_within_page, + length_within_page); + length_remaining -= length_within_page; + current_offset += length_within_page; + offset_within_page = 0; + sg = sg_next(sg); + } + } + + if (sg == NULL) + return -ENOMEM; + } + return len; +} + +/** + * partial_overlap - + * @src_ptr: source pointer + * @dst_ptr: destination pointer + * @nbytes: number of bytes + * @returns: 0 for success; -1 for failure + * We cannot have any partial overlap. Total overlap + * where src is the same as dst is okay + */ +static int partial_overlap(void *src_ptr, void *dst_ptr, u32 nbytes) +{ + /* Check for partial overlap */ + if (src_ptr != dst_ptr) { + if (src_ptr < dst_ptr) { + if ((src_ptr + nbytes) > dst_ptr) + return -EINVAL; + } else { + if ((dst_ptr + nbytes) > src_ptr) + return -EINVAL; + } + } + + return 0; +} + +/* Debug - prints only if DEBUG is defined; follows kernel debug model */ +static void sep_dump(struct sep_device *sep, char *stg, void *start, int len) +{ +#if 0 + int ct1; + u8 *ptt; + + dev_dbg(&sep->pdev->dev, + "Dump of %s starting at %08lx for %08x bytes\n", + stg, (unsigned long)start, len); + for (ct1 = 0; ct1 < len; ct1 += 1) { + ptt = (u8 *)(start + ct1); + dev_dbg(&sep->pdev->dev, "%02x ", *ptt); + if (ct1 % 16 == 15) + dev_dbg(&sep->pdev->dev, "\n"); + } + dev_dbg(&sep->pdev->dev, "\n"); +#endif +} + +/* Debug - prints only if DEBUG is defined; follows kernel debug model */ +static void sep_dump_sg(struct sep_device *sep, char *stg, + struct scatterlist *sg) +{ +#if 0 + int ct1, ct2; + u8 *ptt; + + dev_dbg(&sep->pdev->dev, "Dump of scatterlist %s\n", stg); + + ct1 = 0; + while (sg) { + dev_dbg(&sep->pdev->dev, "page %x\n size %x", ct1, + sg->length); + dev_dbg(&sep->pdev->dev, "phys addr is %lx", + (unsigned long)sg_phys(sg)); + ptt = sg_virt(sg); + for (ct2 = 0; ct2 < sg->length; ct2 += 1) { + dev_dbg(&sep->pdev->dev, "byte %x is %02x\n", + ct2, (unsigned char)*(ptt + ct2)); + } + + ct1 += 1; + sg = sg_next(sg); + } + dev_dbg(&sep->pdev->dev, "\n"); +#endif +} + +/** + * RFC2451: Weak key check + * Returns: 1 (weak), 0 (not weak) + */ +static int sep_weak_key(const u8 *key, unsigned int keylen) +{ + static const u8 parity[] = { + 8, 1, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 2, 8, + 0, 8, 8, 0, 8, 0, 0, 8, 8, + 0, 0, 8, 0, 8, 8, 3, + 0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0, + 8, 0, 0, 8, 0, 8, 8, 0, 0, + 8, 8, 0, 8, 0, 0, 8, + 0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0, + 8, 0, 0, 8, 0, 8, 8, 0, 0, + 8, 8, 0, 8, 0, 0, 8, + 8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8, + 0, 8, 8, 0, 8, 0, 0, 8, 8, + 0, 0, 8, 0, 8, 8, 0, + 0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0, + 8, 0, 0, 8, 0, 8, 8, 0, 0, + 8, 8, 0, 8, 0, 0, 8, + 8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8, + 0, 8, 8, 0, 8, 0, 0, 8, 8, + 0, 0, 8, 0, 8, 8, 0, + 8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8, + 0, 8, 8, 0, 8, 0, 0, 8, 8, + 0, 0, 8, 0, 8, 8, 0, + 4, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0, + 8, 5, 0, 8, 0, 8, 8, 0, 0, + 8, 8, 0, 8, 0, 6, 8, + }; + + u32 n, w; + + n = parity[key[0]]; n <<= 4; + n |= parity[key[1]]; n <<= 4; + n |= parity[key[2]]; n <<= 4; + n |= parity[key[3]]; n <<= 4; + n |= parity[key[4]]; n <<= 4; + n |= parity[key[5]]; n <<= 4; + n |= parity[key[6]]; n <<= 4; + n |= parity[key[7]]; + w = 0x88888888L; + + /* 1 in 10^10 keys passes this test */ + if (!((n - (w >> 3)) & w)) { + if (n < 0x41415151) { + if (n < 0x31312121) { + if (n < 0x14141515) { + /* 01 01 01 01 01 01 01 01 */ + if (n == 0x11111111) + goto weak; + /* 01 1F 01 1F 01 0E 01 0E */ + if (n == 0x13131212) + goto weak; + } else { + /* 01 E0 01 E0 01 F1 01 F1 */ + if (n == 0x14141515) + goto weak; + /* 01 FE 01 FE 01 FE 01 FE */ + if (n == 0x16161616) + goto weak; + } + } else { + if (n < 0x34342525) { + /* 1F 01 1F 01 0E 01 0E 01 */ + if (n == 0x31312121) + goto weak; + /* 1F 1F 1F 1F 0E 0E 0E 0E (?) */ + if (n == 0x33332222) + goto weak; + } else { + /* 1F E0 1F E0 0E F1 0E F1 */ + if (n == 0x34342525) + goto weak; + /* 1F FE 1F FE 0E FE 0E FE */ + if (n == 0x36362626) + goto weak; + } + } + } else { + if (n < 0x61616161) { + if (n < 0x44445555) { + /* E0 01 E0 01 F1 01 F1 01 */ + if (n == 0x41415151) + goto weak; + /* E0 1F E0 1F F1 0E F1 0E */ + if (n == 0x43435252) + goto weak; + } else { + /* E0 E0 E0 E0 F1 F1 F1 F1 (?) */ + if (n == 0x44445555) + goto weak; + /* E0 FE E0 FE F1 FE F1 FE */ + if (n == 0x46465656) + goto weak; + } + } else { + if (n < 0x64646565) { + /* FE 01 FE 01 FE 01 FE 01 */ + if (n == 0x61616161) + goto weak; + /* FE 1F FE 1F FE 0E FE 0E */ + if (n == 0x63636262) + goto weak; + } else { + /* FE E0 FE E0 FE F1 FE F1 */ + if (n == 0x64646565) + goto weak; + /* FE FE FE FE FE FE FE FE */ + if (n == 0x66666666) + goto weak; + } + } + } + } + return 0; +weak: + return 1; +} +/** + * sep_sg_nents + */ +static u32 sep_sg_nents(struct scatterlist *sg) +{ + u32 ct1 = 0; + while (sg) { + ct1 += 1; + sg = sg_next(sg); + } + + return ct1; +} + +/** + * sep_start_msg - + * @sctx: pointer to struct sep_system_ctx + * @returns: offset to place for the next word in the message + * Set up pointer in message pool for new message + */ +static u32 sep_start_msg(struct sep_system_ctx *sctx) +{ + u32 *word_ptr; + sctx->msg_len_words = 2; + sctx->msgptr = sctx->msg; + memset(sctx->msg, 0, SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); + sctx->msgptr += sizeof(u32) * 2; + word_ptr = (u32 *)sctx->msgptr; + *word_ptr = SEP_START_MSG_TOKEN; + return sizeof(u32) * 2; +} + +/** + * sep_end_msg - + * @sctx: pointer to struct sep_system_ctx + * @messages_offset: current message offset + * Returns: 0 for success; <0 otherwise + * End message; set length and CRC; and + * send interrupt to the SEP + */ +static void sep_end_msg(struct sep_system_ctx *sctx, u32 msg_offset) +{ + u32 *word_ptr; + /* Msg size goes into msg after token */ + sctx->msg_len_words = msg_offset / sizeof(u32) + 1; + word_ptr = (u32 *)sctx->msgptr; + word_ptr += 1; + *word_ptr = sctx->msg_len_words; + + /* CRC (currently 0) goes at end of msg */ + word_ptr = (u32 *)(sctx->msgptr + msg_offset); + *word_ptr = 0; +} + +/** + * sep_start_inbound_msg - + * @sctx: pointer to struct sep_system_ctx + * @msg_offset: offset to place for the next word in the message + * @returns: 0 for success; error value for failure + * Set up pointer in message pool for inbound message + */ +static u32 sep_start_inbound_msg(struct sep_system_ctx *sctx, u32 *msg_offset) +{ + u32 *word_ptr; + u32 token; + u32 error = SEP_OK; + + *msg_offset = sizeof(u32) * 2; + word_ptr = (u32 *)sctx->msgptr; + token = *word_ptr; + sctx->msg_len_words = *(word_ptr + 1); + + if (token != SEP_START_MSG_TOKEN) { + error = SEP_INVALID_START; + goto end_function; + } + +end_function: + + return error; +} + +/** + * sep_write_msg - + * @sctx: pointer to struct sep_system_ctx + * @in_addr: pointer to start of parameter + * @size: size of parameter to copy (in bytes) + * @max_size: size to move up offset; SEP mesg is in word sizes + * @msg_offset: pointer to current offset (is updated) + * @byte_array: flag ti indicate wheter endian must be changed + * Copies data into the message area from caller + */ +static void sep_write_msg(struct sep_system_ctx *sctx, void *in_addr, + u32 size, u32 max_size, u32 *msg_offset, u32 byte_array) +{ + u32 *word_ptr; + void *void_ptr; + void_ptr = sctx->msgptr + *msg_offset; + word_ptr = (u32 *)void_ptr; + memcpy(void_ptr, in_addr, size); + *msg_offset += max_size; + + /* Do we need to manipulate endian? */ + if (byte_array) { + u32 i; + for (i = 0; i < ((size + 3) / 4); i += 1) + *(word_ptr + i) = CHG_ENDIAN(*(word_ptr + i)); + } +} + +/** + * sep_make_header + * @sctx: pointer to struct sep_system_ctx + * @msg_offset: pointer to current offset (is updated) + * @op_code: op code to put into message + * Puts op code into message and updates offset + */ +static void sep_make_header(struct sep_system_ctx *sctx, u32 *msg_offset, + u32 op_code) +{ + u32 *word_ptr; + + *msg_offset = sep_start_msg(sctx); + word_ptr = (u32 *)(sctx->msgptr + *msg_offset); + *word_ptr = op_code; + *msg_offset += sizeof(u32); +} + + + +/** + * sep_read_msg - + * @sctx: pointer to struct sep_system_ctx + * @in_addr: pointer to start of parameter + * @size: size of parameter to copy (in bytes) + * @max_size: size to move up offset; SEP mesg is in word sizes + * @msg_offset: pointer to current offset (is updated) + * @byte_array: flag ti indicate wheter endian must be changed + * Copies data out of the message area to caller + */ +static void sep_read_msg(struct sep_system_ctx *sctx, void *in_addr, + u32 size, u32 max_size, u32 *msg_offset, u32 byte_array) +{ + u32 *word_ptr; + void *void_ptr; + void_ptr = sctx->msgptr + *msg_offset; + word_ptr = (u32 *)void_ptr; + + /* Do we need to manipulate endian? */ + if (byte_array) { + u32 i; + for (i = 0; i < ((size + 3) / 4); i += 1) + *(word_ptr + i) = CHG_ENDIAN(*(word_ptr + i)); + } + + memcpy(in_addr, void_ptr, size); + *msg_offset += max_size; +} + +/** + * sep_verify_op - + * @sctx: pointer to struct sep_system_ctx + * @op_code: expected op_code + * @msg_offset: pointer to current offset (is updated) + * @returns: 0 for success; error for failure + */ +static u32 sep_verify_op(struct sep_system_ctx *sctx, u32 op_code, + u32 *msg_offset) +{ + u32 error; + u32 in_ary[2]; + + struct sep_device *sep = sctx->sep_used; + + dev_dbg(&sep->pdev->dev, "dumping return message\n"); + error = sep_start_inbound_msg(sctx, msg_offset); + if (error) { + dev_warn(&sep->pdev->dev, + "sep_start_inbound_msg error\n"); + return error; + } + + sep_read_msg(sctx, in_ary, sizeof(u32) * 2, sizeof(u32) * 2, + msg_offset, 0); + + if (in_ary[0] != op_code) { + dev_warn(&sep->pdev->dev, + "sep got back wrong opcode\n"); + dev_warn(&sep->pdev->dev, + "got back %x; expected %x\n", + in_ary[0], op_code); + return SEP_WRONG_OPCODE; + } + + if (in_ary[1] != SEP_OK) { + dev_warn(&sep->pdev->dev, + "sep execution error\n"); + dev_warn(&sep->pdev->dev, + "got back %x; expected %x\n", + in_ary[1], SEP_OK); + return in_ary[0]; + } + +return 0; +} + +/** + * sep_read_context - + * @sctx: pointer to struct sep_system_ctx + * @msg_offset: point to current place in SEP msg; is updated + * @dst: pointer to place to put the context + * @len: size of the context structure (differs for crypro/hash) + * This function reads the context from the msg area + * There is a special way the vendor needs to have the maximum + * length calculated so that the msg_offset is updated properly; + * it skips over some words in the msg area depending on the size + * of the context + */ +static void sep_read_context(struct sep_system_ctx *sctx, u32 *msg_offset, + void *dst, u32 len) +{ + u32 max_length = ((len + 3) / sizeof(u32)) * sizeof(u32); + sep_read_msg(sctx, dst, len, max_length, msg_offset, 0); +} + +/** + * sep_write_context - + * @sctx: pointer to struct sep_system_ctx + * @msg_offset: point to current place in SEP msg; is updated + * @src: pointer to the current context + * @len: size of the context structure (differs for crypro/hash) + * This function writes the context to the msg area + * There is a special way the vendor needs to have the maximum + * length calculated so that the msg_offset is updated properly; + * it skips over some words in the msg area depending on the size + * of the context + */ +static void sep_write_context(struct sep_system_ctx *sctx, u32 *msg_offset, + void *src, u32 len) +{ + u32 max_length = ((len + 3) / sizeof(u32)) * sizeof(u32); + sep_write_msg(sctx, src, len, max_length, msg_offset, 0); +} + +/** + * sep_clear_out - + * @sctx: pointer to struct sep_system_ctx + * Clear out crypto related values in sep device structure + * to enable device to be used by anyone; either kernel + * crypto or userspace app via middleware + */ +static void sep_clear_out(struct sep_system_ctx *sctx) +{ + if (sctx->src_sg_hold) { + sep_free_sg_buf(sctx->src_sg_hold); + sctx->src_sg_hold = NULL; + } + + if (sctx->dst_sg_hold) { + sep_free_sg_buf(sctx->dst_sg_hold); + sctx->dst_sg_hold = NULL; + } + + sctx->src_sg = NULL; + sctx->dst_sg = NULL; + + sep_free_dma_table_data_handler(sctx->sep_used, &sctx->dma_ctx); + + if (sctx->i_own_sep) { + /** + * The following unlocks the sep and makes it available + * to any other application + * First, null out crypto entries in sep before relesing it + */ + sctx->sep_used->current_hash_req = NULL; + sctx->sep_used->current_cypher_req = NULL; + sctx->sep_used->current_request = 0; + sctx->sep_used->current_hash_stage = 0; + sctx->sep_used->sctx = NULL; + sctx->sep_used->in_kernel = 0; + + sctx->call_status.status = 0; + + /* Remove anything confidentail */ + memset(sctx->sep_used->shared_addr, 0, + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); + + sep_queue_status_remove(sctx->sep_used, &sctx->queue_elem); + +#ifdef SEP_ENABLE_RUNTIME_PM + sctx->sep_used->in_use = 0; + pm_runtime_mark_last_busy(&sctx->sep_used->pdev->dev); + pm_runtime_put_autosuspend(&sctx->sep_used->pdev->dev); +#endif + + clear_bit(SEP_WORKING_LOCK_BIT, &sctx->sep_used->in_use_flags); + sctx->sep_used->pid_doing_transaction = 0; + + dev_dbg(&sctx->sep_used->pdev->dev, + "[PID%d] waking up next transaction\n", + current->pid); + + clear_bit(SEP_TRANSACTION_STARTED_LOCK_BIT, + &sctx->sep_used->in_use_flags); + wake_up(&sctx->sep_used->event_transactions); + + sctx->i_own_sep = 0; + } +} + +/** + * Release crypto infrastructure from EINPROGRESS and + * clear sep_dev so that SEP is available to anyone + */ +static void sep_crypto_release(struct sep_system_ctx *sctx, u32 error) +{ + struct ahash_request *hash_req = sctx->current_hash_req; + struct ablkcipher_request *cypher_req = + sctx->current_cypher_req; + struct sep_device *sep = sctx->sep_used; + + sep_clear_out(sctx); + + if (cypher_req != NULL) { + if (cypher_req->base.complete == NULL) { + dev_dbg(&sep->pdev->dev, + "release is null for cypher!"); + } else { + cypher_req->base.complete( + &cypher_req->base, error); + } + } + + if (hash_req != NULL) { + if (hash_req->base.complete == NULL) { + dev_dbg(&sep->pdev->dev, + "release is null for hash!"); + } else { + hash_req->base.complete( + &hash_req->base, error); + } + } +} + +/** + * This is where we grab the sep itself and tell it to do something. + * It will sleep if the sep is currently busy + * and it will return 0 if sep is now ours; error value if there + * were problems + */ +static int sep_crypto_take_sep(struct sep_system_ctx *sctx) +{ + struct sep_device *sep = sctx->sep_used; + int result; + struct sep_msgarea_hdr *my_msg_header; + + my_msg_header = (struct sep_msgarea_hdr *)sctx->msg; + + /* add to status queue */ + sctx->queue_elem = sep_queue_status_add(sep, my_msg_header->opcode, + sctx->nbytes, current->pid, + current->comm, sizeof(current->comm)); + + if (!sctx->queue_elem) { + dev_dbg(&sep->pdev->dev, "[PID%d] updating queue" + " status error\n", current->pid); + return -EINVAL; + } + + /* get the device; this can sleep */ + result = sep_wait_transaction(sep); + if (result) + return result; + + if (sep_dev->power_save_setup == 1) + pm_runtime_get_sync(&sep_dev->pdev->dev); + + /* Copy in the message */ + memcpy(sep->shared_addr, sctx->msg, + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); + + /* Copy in the dcb information if there is any */ + if (sctx->dcb_region) { + result = sep_activate_dcb_dmatables_context(sep, + &sctx->dcb_region, &sctx->dmatables_region, + sctx->dma_ctx); + if (result) + return result; + } + + /* Mark the device so we know how to finish the job in the tasklet */ + if (sctx->current_hash_req) + sep->current_hash_req = sctx->current_hash_req; + else + sep->current_cypher_req = sctx->current_cypher_req; + + sep->current_request = sctx->current_request; + sep->current_hash_stage = sctx->current_hash_stage; + sep->sctx = sctx; + sep->in_kernel = 1; + sctx->i_own_sep = 1; + + result = sep_send_command_handler(sep); + + dev_dbg(&sep->pdev->dev, "[PID%d]: sending command to the sep\n", + current->pid); + + if (!result) { + set_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET, + &sctx->call_status.status); + dev_dbg(&sep->pdev->dev, "[PID%d]: command sent okay\n", + current->pid); + } + + return result; +} + +/* This needs to be run as a work queue as it can be put asleep */ +static void sep_crypto_block(void *data) +{ + int int_error; + u32 msg_offset; + static u32 msg[10]; + void *src_ptr; + void *dst_ptr; + + static char small_buf[100]; + ssize_t copy_result; + int result; + + u32 max_length; + struct scatterlist *new_sg; + struct ablkcipher_request *req; + struct sep_block_ctx *bctx; + struct crypto_ablkcipher *tfm; + struct sep_system_ctx *sctx; + + req = (struct ablkcipher_request *)data; + bctx = ablkcipher_request_ctx(req); + tfm = crypto_ablkcipher_reqtfm(req); + sctx = crypto_ablkcipher_ctx(tfm); + + /* start the walk on scatterlists */ + ablkcipher_walk_init(&bctx->walk, req->src, req->dst, req->nbytes); + dev_dbg(&sctx->sep_used->pdev->dev, "sep crypto block data size of %x\n", + req->nbytes); + + int_error = ablkcipher_walk_phys(req, &bctx->walk); + if (int_error) { + dev_warn(&sctx->sep_used->pdev->dev, "walk phys error %x\n", + int_error); + sep_crypto_release(sctx, -ENOMEM); + return; + } + + /* check iv */ + if (bctx->des_opmode == SEP_DES_CBC) { + if (!bctx->walk.iv) { + dev_warn(&sctx->sep_used->pdev->dev, "no iv found\n"); + sep_crypto_release(sctx, -EINVAL); + return; + } + + memcpy(bctx->iv, bctx->walk.iv, SEP_DES_IV_SIZE_BYTES); + sep_dump(sctx->sep_used, "iv", bctx->iv, SEP_DES_IV_SIZE_BYTES); + } + + if (bctx->aes_opmode == SEP_AES_CBC) { + if (!bctx->walk.iv) { + dev_warn(&sctx->sep_used->pdev->dev, "no iv found\n"); + sep_crypto_release(sctx, -EINVAL); + return; + } + + memcpy(bctx->iv, bctx->walk.iv, SEP_AES_IV_SIZE_BYTES); + sep_dump(sctx->sep_used, "iv", bctx->iv, SEP_AES_IV_SIZE_BYTES); + } + + dev_dbg(&sctx->sep_used->pdev->dev, + "crypto block: src is %lx dst is %lx\n", + (unsigned long)req->src, (unsigned long)req->dst); + + /* Make sure all pages are even block */ + int_error = sep_oddball_pages(sctx->sep_used, req->src, + req->nbytes, bctx->walk.blocksize, &new_sg, 1); + + if (int_error < 0) { + dev_warn(&sctx->sep_used->pdev->dev, "oddball page eerror\n"); + sep_crypto_release(sctx, -ENOMEM); + return; + } else if (int_error == 1) { + sctx->src_sg = new_sg; + sctx->src_sg_hold = new_sg; + } else { + sctx->src_sg = req->src; + sctx->src_sg_hold = NULL; + } + + int_error = sep_oddball_pages(sctx->sep_used, req->dst, + req->nbytes, bctx->walk.blocksize, &new_sg, 0); + + if (int_error < 0) { + dev_warn(&sctx->sep_used->pdev->dev, "walk phys error %x\n", + int_error); + sep_crypto_release(sctx, -ENOMEM); + return; + } else if (int_error == 1) { + sctx->dst_sg = new_sg; + sctx->dst_sg_hold = new_sg; + } else { + sctx->dst_sg = req->dst; + sctx->dst_sg_hold = NULL; + } + + /* Do we need to perform init; ie; send key to sep? */ + if (sctx->key_sent == 0) { + + dev_dbg(&sctx->sep_used->pdev->dev, "sending key\n"); + + /* put together message to SEP */ + /* Start with op code */ + sep_make_header(sctx, &msg_offset, bctx->init_opcode); + + /* now deal with IV */ + if (bctx->init_opcode == SEP_DES_INIT_OPCODE) { + if (bctx->des_opmode == SEP_DES_CBC) { + sep_write_msg(sctx, bctx->iv, + SEP_DES_IV_SIZE_BYTES, sizeof(u32) * 4, + &msg_offset, 1); + sep_dump(sctx->sep_used, "initial IV", + bctx->walk.iv, SEP_DES_IV_SIZE_BYTES); + } else { + /* Skip if ECB */ + msg_offset += 4 * sizeof(u32); + } + } else { + max_length = ((SEP_AES_IV_SIZE_BYTES + 3) / + sizeof(u32)) * sizeof(u32); + if (bctx->aes_opmode == SEP_AES_CBC) { + sep_write_msg(sctx, bctx->iv, + SEP_AES_IV_SIZE_BYTES, max_length, + &msg_offset, 1); + sep_dump(sctx->sep_used, "initial IV", + bctx->walk.iv, SEP_AES_IV_SIZE_BYTES); + } else { + /* Skip if ECB */ + msg_offset += max_length; + } + } + + /* load the key */ + if (bctx->init_opcode == SEP_DES_INIT_OPCODE) { + sep_write_msg(sctx, (void *)&sctx->key.des.key1, + sizeof(u32) * 8, sizeof(u32) * 8, + &msg_offset, 1); + + msg[0] = (u32)sctx->des_nbr_keys; + msg[1] = (u32)bctx->des_encmode; + msg[2] = (u32)bctx->des_opmode; + + sep_write_msg(sctx, (void *)msg, + sizeof(u32) * 3, sizeof(u32) * 3, + &msg_offset, 0); + } else { + sep_write_msg(sctx, (void *)&sctx->key.aes, + sctx->keylen, + SEP_AES_MAX_KEY_SIZE_BYTES, + &msg_offset, 1); + + msg[0] = (u32)sctx->aes_key_size; + msg[1] = (u32)bctx->aes_encmode; + msg[2] = (u32)bctx->aes_opmode; + msg[3] = (u32)0; /* Secret key is not used */ + sep_write_msg(sctx, (void *)msg, + sizeof(u32) * 4, sizeof(u32) * 4, + &msg_offset, 0); + } + + } else { + + /* set nbytes for queue status */ + sctx->nbytes = req->nbytes; + + /* Key already done; this is for data */ + dev_dbg(&sctx->sep_used->pdev->dev, "sending data\n"); + + sep_dump_sg(sctx->sep_used, + "block sg in", sctx->src_sg); + + /* check for valid data and proper spacing */ + src_ptr = sg_virt(sctx->src_sg); + dst_ptr = sg_virt(sctx->dst_sg); + + if (!src_ptr || !dst_ptr || + (sctx->current_cypher_req->nbytes % + crypto_ablkcipher_blocksize(tfm))) { + + dev_warn(&sctx->sep_used->pdev->dev, + "cipher block size odd\n"); + dev_warn(&sctx->sep_used->pdev->dev, + "cipher block size is %x\n", + crypto_ablkcipher_blocksize(tfm)); + dev_warn(&sctx->sep_used->pdev->dev, + "cipher data size is %x\n", + sctx->current_cypher_req->nbytes); + sep_crypto_release(sctx, -EINVAL); + return; + } + + if (partial_overlap(src_ptr, dst_ptr, + sctx->current_cypher_req->nbytes)) { + dev_warn(&sctx->sep_used->pdev->dev, + "block partial overlap\n"); + sep_crypto_release(sctx, -EINVAL); + return; + } + + /* Put together the message */ + sep_make_header(sctx, &msg_offset, bctx->block_opcode); + + /* If des, and size is 1 block, put directly in msg */ + if ((bctx->block_opcode == SEP_DES_BLOCK_OPCODE) && + (req->nbytes == crypto_ablkcipher_blocksize(tfm))) { + + dev_dbg(&sctx->sep_used->pdev->dev, + "writing out one block des\n"); + + copy_result = sg_copy_to_buffer( + sctx->src_sg, sep_sg_nents(sctx->src_sg), + small_buf, crypto_ablkcipher_blocksize(tfm)); + + if (copy_result != crypto_ablkcipher_blocksize(tfm)) { + dev_warn(&sctx->sep_used->pdev->dev, + "des block copy faild\n"); + sep_crypto_release(sctx, -ENOMEM); + return; + } + + /* Put data into message */ + sep_write_msg(sctx, small_buf, + crypto_ablkcipher_blocksize(tfm), + crypto_ablkcipher_blocksize(tfm) * 2, + &msg_offset, 1); + + /* Put size into message */ + sep_write_msg(sctx, &req->nbytes, + sizeof(u32), sizeof(u32), &msg_offset, 0); + } else { + /* Otherwise, fill out dma tables */ + sctx->dcb_input_data.app_in_address = src_ptr; + sctx->dcb_input_data.data_in_size = req->nbytes; + sctx->dcb_input_data.app_out_address = dst_ptr; + sctx->dcb_input_data.block_size = + crypto_ablkcipher_blocksize(tfm); + sctx->dcb_input_data.tail_block_size = 0; + sctx->dcb_input_data.is_applet = 0; + sctx->dcb_input_data.src_sg = sctx->src_sg; + sctx->dcb_input_data.dst_sg = sctx->dst_sg; + + result = sep_create_dcb_dmatables_context_kernel( + sctx->sep_used, + &sctx->dcb_region, + &sctx->dmatables_region, + &sctx->dma_ctx, + &sctx->dcb_input_data, + 1); + if (result) { + dev_warn(&sctx->sep_used->pdev->dev, + "crypto dma table create failed\n"); + sep_crypto_release(sctx, -EINVAL); + return; + } + + /* Portion of msg is nulled (no data) */ + msg[0] = (u32)0; + msg[1] = (u32)0; + msg[2] = (u32)0; + msg[3] = (u32)0; + msg[4] = (u32)0; + sep_write_msg(sctx, (void *)msg, + sizeof(u32) * 5, + sizeof(u32) * 5, + &msg_offset, 0); + } + + /* Write context into message */ + if (bctx->block_opcode == SEP_DES_BLOCK_OPCODE) { + sep_write_context(sctx, &msg_offset, + &bctx->des_private_ctx, + sizeof(struct sep_des_private_context)); + sep_dump(sctx->sep_used, "ctx to block des", + &bctx->des_private_ctx, 40); + } else { + sep_write_context(sctx, &msg_offset, + &bctx->aes_private_ctx, + sizeof(struct sep_aes_private_context)); + sep_dump(sctx->sep_used, "ctx to block aes", + &bctx->aes_private_ctx, 20); + } + } + + /* conclude message and then tell sep to do its thing */ + sctx->done_with_transaction = 0; + + sep_end_msg(sctx, msg_offset); + result = sep_crypto_take_sep(sctx); + if (result) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_crypto_take_sep failed\n"); + sep_crypto_release(sctx, -EINVAL); + return; + } + + /** + * Sep is now working. Lets wait up to 5 seconds + * for completion. If it does not complete, we will do + * a crypto release with -EINVAL to release the + * kernel crypto infrastructure and let the system + * continue to boot up + * We have to wait this long because some crypto + * operations can take a while + */ + + dev_dbg(&sctx->sep_used->pdev->dev, + "waiting for done with transaction\n"); + + sctx->end_time = jiffies + (SEP_TRANSACTION_WAIT_TIME * HZ); + while ((time_before(jiffies, sctx->end_time)) && + (!sctx->done_with_transaction)) + schedule(); + + dev_dbg(&sctx->sep_used->pdev->dev, + "done waiting for done with transaction\n"); + + /* are we done? */ + if (!sctx->done_with_transaction) { + /* Nope, lets release and tell crypto no */ + dev_warn(&sctx->sep_used->pdev->dev, + "[PID%d] sep_crypto_block never finished\n", + current->pid); + sep_crypto_release(sctx, -EINVAL); + } +} + +/** + * Post operation (after interrupt) for crypto block + */ +static u32 crypto_post_op(struct sep_device *sep) +{ + /* HERE */ + int int_error; + u32 u32_error; + u32 msg_offset; + + ssize_t copy_result; + static char small_buf[100]; + + struct ablkcipher_request *req; + struct sep_block_ctx *bctx; + struct sep_system_ctx *sctx; + struct crypto_ablkcipher *tfm; + + if (!sep->current_cypher_req) + return -EINVAL; + + /* hold req since we need to submit work after clearing sep */ + req = sep->current_cypher_req; + + bctx = ablkcipher_request_ctx(sep->current_cypher_req); + tfm = crypto_ablkcipher_reqtfm(sep->current_cypher_req); + sctx = crypto_ablkcipher_ctx(tfm); + + dev_dbg(&sctx->sep_used->pdev->dev, "crypto post_op\n"); + dev_dbg(&sctx->sep_used->pdev->dev, "crypto post_op message dump\n"); + crypto_sep_dump_message(sctx); + + sctx->done_with_transaction = 1; + + /* first bring msg from shared area to local area */ + memcpy(sctx->msg, sep->shared_addr, + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); + + /* Is this the result of performing init (key to SEP */ + if (sctx->key_sent == 0) { + + /* Did SEP do it okay */ + u32_error = sep_verify_op(sctx, bctx->init_opcode, + &msg_offset); + if (u32_error) { + dev_warn(&sctx->sep_used->pdev->dev, + "aes init error %x\n", u32_error); + sep_crypto_release(sctx, u32_error); + return u32_error; + } + + /* Read Context */ + if (bctx->init_opcode == SEP_DES_INIT_OPCODE) { + sep_read_context(sctx, &msg_offset, + &bctx->des_private_ctx, + sizeof(struct sep_des_private_context)); + + sep_dump(sctx->sep_used, "ctx init des", + &bctx->des_private_ctx, 40); + } else { + sep_read_context(sctx, &msg_offset, + &bctx->aes_private_ctx, + sizeof(struct sep_des_private_context)); + + sep_dump(sctx->sep_used, "ctx init aes", + &bctx->aes_private_ctx, 20); + } + + /* We are done with init. Now send out the data */ + /* first release the sep */ + sctx->key_sent = 1; + sep_crypto_release(sctx, -EINPROGRESS); + + spin_lock_irq(&queue_lock); + int_error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((int_error != 0) && (int_error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "spe cypher post op cant queue\n"); + sep_crypto_release(sctx, int_error); + return int_error; + } + + /* schedule the data send */ + int_error = sep_submit_work(sep->workqueue, sep_dequeuer, + (void *)&sep_queue); + + if (int_error) { + dev_warn(&sep->pdev->dev, + "cant submit work sep_crypto_block\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + + } else { + + /** + * This is the result of a block request + */ + dev_dbg(&sctx->sep_used->pdev->dev, + "crypto_post_op block response\n"); + + u32_error = sep_verify_op(sctx, bctx->block_opcode, + &msg_offset); + + if (u32_error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep block error %x\n", u32_error); + sep_crypto_release(sctx, u32_error); + return -EINVAL; + } + + if (bctx->block_opcode == SEP_DES_BLOCK_OPCODE) { + + dev_dbg(&sctx->sep_used->pdev->dev, + "post op for DES\n"); + + /* special case for 1 block des */ + if (sep->current_cypher_req->nbytes == + crypto_ablkcipher_blocksize(tfm)) { + + sep_read_msg(sctx, small_buf, + crypto_ablkcipher_blocksize(tfm), + crypto_ablkcipher_blocksize(tfm) * 2, + &msg_offset, 1); + + dev_dbg(&sctx->sep_used->pdev->dev, + "reading in block des\n"); + + copy_result = sg_copy_from_buffer( + sctx->dst_sg, + sep_sg_nents(sctx->dst_sg), + small_buf, + crypto_ablkcipher_blocksize(tfm)); + + if (copy_result != + crypto_ablkcipher_blocksize(tfm)) { + + dev_warn(&sctx->sep_used->pdev->dev, + "des block copy faild\n"); + sep_crypto_release(sctx, -ENOMEM); + return -ENOMEM; + } + } + + /* Read Context */ + sep_read_context(sctx, &msg_offset, + &bctx->des_private_ctx, + sizeof(struct sep_des_private_context)); + } else { + + dev_dbg(&sctx->sep_used->pdev->dev, + "post op for AES\n"); + + /* Skip the MAC Output */ + msg_offset += (sizeof(u32) * 4); + + /* Read Context */ + sep_read_context(sctx, &msg_offset, + &bctx->aes_private_ctx, + sizeof(struct sep_aes_private_context)); + } + + sep_dump_sg(sctx->sep_used, + "block sg out", sctx->dst_sg); + + /* Copy to correct sg if this block had oddball pages */ + if (sctx->dst_sg_hold) + sep_copy_sg(sctx->sep_used, + sctx->dst_sg, + sctx->current_cypher_req->dst, + sctx->current_cypher_req->nbytes); + + /* finished, release everything */ + sep_crypto_release(sctx, 0); + } + return 0; +} + +static u32 hash_init_post_op(struct sep_device *sep) +{ + u32 u32_error; + u32 msg_offset; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(sep->current_hash_req); + struct sep_hash_ctx *ctx = ahash_request_ctx(sep->current_hash_req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, + "hash init post op\n"); + + sctx->done_with_transaction = 1; + + /* first bring msg from shared area to local area */ + memcpy(sctx->msg, sep->shared_addr, + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); + + u32_error = sep_verify_op(sctx, SEP_HASH_INIT_OPCODE, + &msg_offset); + + if (u32_error) { + dev_warn(&sctx->sep_used->pdev->dev, "hash init error %x\n", + u32_error); + sep_crypto_release(sctx, u32_error); + return u32_error; + } + + /* Read Context */ + sep_read_context(sctx, &msg_offset, + &ctx->hash_private_ctx, + sizeof(struct sep_hash_private_context)); + + /* Signal to crypto infrastructure and clear out */ + dev_dbg(&sctx->sep_used->pdev->dev, "hash init post op done\n"); + sep_crypto_release(sctx, 0); + return 0; +} + +static u32 hash_update_post_op(struct sep_device *sep) +{ + u32 u32_error; + u32 msg_offset; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(sep->current_hash_req); + struct sep_hash_ctx *ctx = ahash_request_ctx(sep->current_hash_req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, + "hash update post op\n"); + + sctx->done_with_transaction = 1; + + /* first bring msg from shared area to local area */ + memcpy(sctx->msg, sep->shared_addr, + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); + + u32_error = sep_verify_op(sctx, SEP_HASH_UPDATE_OPCODE, + &msg_offset); + + if (u32_error) { + dev_warn(&sctx->sep_used->pdev->dev, "hash init error %x\n", + u32_error); + sep_crypto_release(sctx, u32_error); + return u32_error; + } + + /* Read Context */ + sep_read_context(sctx, &msg_offset, + &ctx->hash_private_ctx, + sizeof(struct sep_hash_private_context)); + + sep_crypto_release(sctx, 0); + return 0; +} + +static u32 hash_final_post_op(struct sep_device *sep) +{ + int max_length; + u32 u32_error; + u32 msg_offset; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(sep->current_hash_req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, + "hash final post op\n"); + + sctx->done_with_transaction = 1; + + /* first bring msg from shared area to local area */ + memcpy(sctx->msg, sep->shared_addr, + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); + + u32_error = sep_verify_op(sctx, SEP_HASH_FINISH_OPCODE, + &msg_offset); + + if (u32_error) { + dev_warn(&sctx->sep_used->pdev->dev, "hash finish error %x\n", + u32_error); + sep_crypto_release(sctx, u32_error); + return u32_error; + } + + /* Grab the result */ + if (sctx->current_hash_req->result == NULL) { + /* Oops, null buffer; error out here */ + dev_warn(&sctx->sep_used->pdev->dev, + "hash finish null buffer\n"); + sep_crypto_release(sctx, (u32)-ENOMEM); + return -ENOMEM; + } + + max_length = (((SEP_HASH_RESULT_SIZE_WORDS * sizeof(u32)) + 3) / + sizeof(u32)) * sizeof(u32); + + sep_read_msg(sctx, + sctx->current_hash_req->result, + crypto_ahash_digestsize(tfm), max_length, + &msg_offset, 0); + + /* Signal to crypto infrastructure and clear out */ + dev_dbg(&sctx->sep_used->pdev->dev, "hash finish post op done\n"); + sep_crypto_release(sctx, 0); + return 0; +} + +static u32 hash_digest_post_op(struct sep_device *sep) +{ + int max_length; + u32 u32_error; + u32 msg_offset; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(sep->current_hash_req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, + "hash digest post op\n"); + + sctx->done_with_transaction = 1; + + /* first bring msg from shared area to local area */ + memcpy(sctx->msg, sep->shared_addr, + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); + + u32_error = sep_verify_op(sctx, SEP_HASH_SINGLE_OPCODE, + &msg_offset); + + if (u32_error) { + dev_warn(&sctx->sep_used->pdev->dev, + "hash digest finish error %x\n", u32_error); + + sep_crypto_release(sctx, u32_error); + return u32_error; + } + + /* Grab the result */ + if (sctx->current_hash_req->result == NULL) { + /* Oops, null buffer; error out here */ + dev_warn(&sctx->sep_used->pdev->dev, + "hash digest finish null buffer\n"); + sep_crypto_release(sctx, (u32)-ENOMEM); + return -ENOMEM; + } + + max_length = (((SEP_HASH_RESULT_SIZE_WORDS * sizeof(u32)) + 3) / + sizeof(u32)) * sizeof(u32); + + sep_read_msg(sctx, + sctx->current_hash_req->result, + crypto_ahash_digestsize(tfm), max_length, + &msg_offset, 0); + + /* Signal to crypto infrastructure and clear out */ + dev_dbg(&sctx->sep_used->pdev->dev, + "hash digest finish post op done\n"); + + sep_crypto_release(sctx, 0); + return 0; +} + +/** + * The sep_finish function is the function that is schedule (via tasket) + * by the interrupt service routine when the SEP sends and interrupt + * This is only called by the interrupt handler as a tasklet. + */ +static void sep_finish(unsigned long data) +{ + unsigned long flags; + struct sep_device *sep_dev; + int res; + + res = 0; + + if (data == 0) { + pr_debug("sep_finish called with null data\n"); + return; + } + + sep_dev = (struct sep_device *)data; + if (sep_dev == NULL) { + pr_debug("sep_finish; sep_dev is NULL\n"); + return; + } + + spin_lock_irqsave(&sep_dev->busy_lock, flags); + if (sep_dev->in_kernel == (u32)0) { + spin_unlock_irqrestore(&sep_dev->busy_lock, flags); + dev_warn(&sep_dev->pdev->dev, + "sep_finish; not in kernel operation\n"); + return; + } + spin_unlock_irqrestore(&sep_dev->busy_lock, flags); + + /* Did we really do a sep command prior to this? */ + if (0 == test_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET, + &sep_dev->sctx->call_status.status)) { + + dev_warn(&sep_dev->pdev->dev, "[PID%d] sendmsg not called\n", + current->pid); + return; + } + + if (sep_dev->send_ct != sep_dev->reply_ct) { + dev_warn(&sep_dev->pdev->dev, + "[PID%d] poll; no message came back\n", + current->pid); + return; + } + + /* Check for error (In case time ran out) */ + if ((res != 0x0) && (res != 0x8)) { + dev_warn(&sep_dev->pdev->dev, + "[PID%d] poll; poll error GPR3 is %x\n", + current->pid, res); + return; + } + + /* What kind of interrupt from sep was this? */ + res = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR2_REG_ADDR); + + dev_dbg(&sep_dev->pdev->dev, "[PID%d] GPR2 at crypto finish is %x\n", + current->pid, res); + + /* Print request? */ + if ((res >> 30) & 0x1) { + dev_dbg(&sep_dev->pdev->dev, "[PID%d] sep print req\n", + current->pid); + dev_dbg(&sep_dev->pdev->dev, "[PID%d] contents: %s\n", + current->pid, + (char *)(sep_dev->shared_addr + + SEP_DRIVER_PRINTF_OFFSET_IN_BYTES)); + return; + } + + /* Request for daemon (not currently in POR)? */ + if (res >> 31) { + dev_dbg(&sep_dev->pdev->dev, + "[PID%d] sep request; ignoring\n", + current->pid); + return; + } + + /* If we got here, then we have a replay to a sep command */ + + dev_dbg(&sep_dev->pdev->dev, + "[PID%d] sep reply to command; processing request: %x\n", + current->pid, sep_dev->current_request); + + switch (sep_dev->current_request) { + case AES_CBC: + case AES_ECB: + case DES_CBC: + case DES_ECB: + res = crypto_post_op(sep_dev); + break; + case SHA1: + case MD5: + case SHA224: + case SHA256: + switch (sep_dev->current_hash_stage) { + case HASH_INIT: + res = hash_init_post_op(sep_dev); + break; + case HASH_UPDATE: + res = hash_update_post_op(sep_dev); + break; + case HASH_FINISH: + res = hash_final_post_op(sep_dev); + break; + case HASH_DIGEST: + res = hash_digest_post_op(sep_dev); + break; + default: + dev_warn(&sep_dev->pdev->dev, + "invalid stage for hash finish\n"); + } + break; + default: + dev_warn(&sep_dev->pdev->dev, + "invalid request for finish\n"); + } + + if (res) { + dev_warn(&sep_dev->pdev->dev, + "finish returned error %x\n", res); + } +} + +static int sep_hash_cra_init(struct crypto_tfm *tfm) + { + struct sep_system_ctx *sctx = crypto_tfm_ctx(tfm); + const char *alg_name = crypto_tfm_alg_name(tfm); + + sctx->sep_used = sep_dev; + + dev_dbg(&sctx->sep_used->pdev->dev, + "sep_hash_cra_init name is %s\n", alg_name); + + crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), + sizeof(struct sep_hash_ctx)); + return 0; + } + +static void sep_hash_cra_exit(struct crypto_tfm *tfm) +{ + struct sep_system_ctx *sctx = crypto_tfm_ctx(tfm); + + dev_dbg(&sctx->sep_used->pdev->dev, + "sep_hash_cra_exit\n"); + sctx->sep_used = NULL; +} + +static void sep_hash_init(void *data) +{ + u32 msg_offset; + int result; + struct ahash_request *req; + struct crypto_ahash *tfm; + struct sep_hash_ctx *ctx; + struct sep_system_ctx *sctx; + + req = (struct ahash_request *)data; + tfm = crypto_ahash_reqtfm(req); + ctx = ahash_request_ctx(req); + sctx = crypto_ahash_ctx(tfm); + + dev_dbg(&sctx->sep_used->pdev->dev, + "sep_hash_init\n"); + sctx->current_hash_stage = HASH_INIT; + /* opcode and mode */ + sep_make_header(sctx, &msg_offset, SEP_HASH_INIT_OPCODE); + sep_write_msg(sctx, &ctx->hash_opmode, + sizeof(u32), sizeof(u32), &msg_offset, 0); + sep_end_msg(sctx, msg_offset); + + sctx->done_with_transaction = 0; + + result = sep_crypto_take_sep(sctx); + if (result) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_hash_init take sep failed\n"); + sep_crypto_release(sctx, -EINVAL); + } + + /** + * Sep is now working. Lets wait up to 5 seconds + * for completion. If it does not complete, we will do + * a crypto release with -EINVAL to release the + * kernel crypto infrastructure and let the system + * continue to boot up + * We have to wait this long because some crypto + * operations can take a while + */ + dev_dbg(&sctx->sep_used->pdev->dev, + "waiting for done with transaction\n"); + + sctx->end_time = jiffies + (SEP_TRANSACTION_WAIT_TIME * HZ); + while ((time_before(jiffies, sctx->end_time)) && + (!sctx->done_with_transaction)) + schedule(); + + dev_dbg(&sctx->sep_used->pdev->dev, + "done waiting for done with transaction\n"); + + /* are we done? */ + if (!sctx->done_with_transaction) { + /* Nope, lets release and tell crypto no */ + dev_warn(&sctx->sep_used->pdev->dev, + "[PID%d] sep_hash_init never finished\n", + current->pid); + sep_crypto_release(sctx, -EINVAL); + } +} + +static void sep_hash_update(void *data) +{ + int int_error; + u32 msg_offset; + u32 len; + struct sep_hash_internal_context *int_ctx; + u32 block_size; + u32 head_len; + u32 tail_len; + static u32 msg[10]; + static char small_buf[100]; + void *src_ptr; + struct scatterlist *new_sg; + ssize_t copy_result; + struct ahash_request *req; + struct crypto_ahash *tfm; + struct sep_hash_ctx *ctx; + struct sep_system_ctx *sctx; + + req = (struct ahash_request *)data; + tfm = crypto_ahash_reqtfm(req); + ctx = ahash_request_ctx(req); + sctx = crypto_ahash_ctx(tfm); + + /* length for queue status */ + sctx->nbytes = req->nbytes; + + dev_dbg(&sctx->sep_used->pdev->dev, + "sep_hash_update\n"); + sctx->current_hash_stage = HASH_UPDATE; + len = req->nbytes; + + block_size = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm)); + tail_len = req->nbytes % block_size; + dev_dbg(&sctx->sep_used->pdev->dev, "length is %x\n", len); + dev_dbg(&sctx->sep_used->pdev->dev, "block_size is %x\n", block_size); + dev_dbg(&sctx->sep_used->pdev->dev, "tail len is %x\n", tail_len); + + /* Compute header/tail sizes */ + int_ctx = (struct sep_hash_internal_context *)&ctx-> + hash_private_ctx.internal_context; + head_len = (block_size - int_ctx->prev_update_bytes) % block_size; + tail_len = (req->nbytes - head_len) % block_size; + + /* Make sure all pages are even block */ + int_error = sep_oddball_pages(sctx->sep_used, req->src, + req->nbytes, + block_size, &new_sg, 1); + + if (int_error < 0) { + dev_warn(&sctx->sep_used->pdev->dev, + "oddball pages error in crash update\n"); + sep_crypto_release(sctx, -ENOMEM); + return; + } else if (int_error == 1) { + sctx->src_sg = new_sg; + sctx->src_sg_hold = new_sg; + } else { + sctx->src_sg = req->src; + sctx->src_sg_hold = NULL; + } + + src_ptr = sg_virt(sctx->src_sg); + + if ((!req->nbytes) || (!ctx->sg)) { + /* null data */ + src_ptr = NULL; + } + + sep_dump_sg(sctx->sep_used, "hash block sg in", sctx->src_sg); + + sctx->dcb_input_data.app_in_address = src_ptr; + sctx->dcb_input_data.data_in_size = req->nbytes - (head_len + tail_len); + sctx->dcb_input_data.app_out_address = NULL; + sctx->dcb_input_data.block_size = block_size; + sctx->dcb_input_data.tail_block_size = 0; + sctx->dcb_input_data.is_applet = 0; + sctx->dcb_input_data.src_sg = sctx->src_sg; + sctx->dcb_input_data.dst_sg = NULL; + + int_error = sep_create_dcb_dmatables_context_kernel( + sctx->sep_used, + &sctx->dcb_region, + &sctx->dmatables_region, + &sctx->dma_ctx, + &sctx->dcb_input_data, + 1); + if (int_error) { + dev_warn(&sctx->sep_used->pdev->dev, + "hash update dma table create failed\n"); + sep_crypto_release(sctx, -EINVAL); + return; + } + + /* Construct message to SEP */ + sep_make_header(sctx, &msg_offset, SEP_HASH_UPDATE_OPCODE); + + msg[0] = (u32)0; + msg[1] = (u32)0; + msg[2] = (u32)0; + + sep_write_msg(sctx, msg, sizeof(u32) * 3, sizeof(u32) * 3, + &msg_offset, 0); + + /* Handle remainders */ + + /* Head */ + sep_write_msg(sctx, &head_len, sizeof(u32), + sizeof(u32), &msg_offset, 0); + + if (head_len) { + copy_result = sg_copy_to_buffer( + req->src, + sep_sg_nents(sctx->src_sg), + small_buf, head_len); + + if (copy_result != head_len) { + dev_warn(&sctx->sep_used->pdev->dev, + "sg head copy failure in hash block\n"); + sep_crypto_release(sctx, -ENOMEM); + return; + } + + sep_write_msg(sctx, small_buf, head_len, + sizeof(u32) * 32, &msg_offset, 1); + } else { + msg_offset += sizeof(u32) * 32; + } + + /* Tail */ + sep_write_msg(sctx, &tail_len, sizeof(u32), + sizeof(u32), &msg_offset, 0); + + if (tail_len) { + copy_result = sep_copy_offset_sg( + sctx->sep_used, + sctx->src_sg, + req->nbytes - tail_len, + small_buf, tail_len); + + if (copy_result != tail_len) { + dev_warn(&sctx->sep_used->pdev->dev, + "sg tail copy failure in hash block\n"); + sep_crypto_release(sctx, -ENOMEM); + return; + } + + sep_write_msg(sctx, small_buf, tail_len, + sizeof(u32) * 32, &msg_offset, 1); + } else { + msg_offset += sizeof(u32) * 32; + } + + /* Context */ + sep_write_context(sctx, &msg_offset, &ctx->hash_private_ctx, + sizeof(struct sep_hash_private_context)); + + sep_end_msg(sctx, msg_offset); + sctx->done_with_transaction = 0; + int_error = sep_crypto_take_sep(sctx); + if (int_error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_hash_update take sep failed\n"); + sep_crypto_release(sctx, -EINVAL); + } + + /** + * Sep is now working. Lets wait up to 5 seconds + * for completion. If it does not complete, we will do + * a crypto release with -EINVAL to release the + * kernel crypto infrastructure and let the system + * continue to boot up + * We have to wait this long because some crypto + * operations can take a while + */ + dev_dbg(&sctx->sep_used->pdev->dev, + "waiting for done with transaction\n"); + + sctx->end_time = jiffies + (SEP_TRANSACTION_WAIT_TIME * HZ); + while ((time_before(jiffies, sctx->end_time)) && + (!sctx->done_with_transaction)) + schedule(); + + dev_dbg(&sctx->sep_used->pdev->dev, + "done waiting for done with transaction\n"); + + /* are we done? */ + if (!sctx->done_with_transaction) { + /* Nope, lets release and tell crypto no */ + dev_warn(&sctx->sep_used->pdev->dev, + "[PID%d] sep_hash_update never finished\n", + current->pid); + sep_crypto_release(sctx, -EINVAL); + } +} + +static void sep_hash_final(void *data) +{ + u32 msg_offset; + struct ahash_request *req; + struct crypto_ahash *tfm; + struct sep_hash_ctx *ctx; + struct sep_system_ctx *sctx; + int result; + + req = (struct ahash_request *)data; + tfm = crypto_ahash_reqtfm(req); + ctx = ahash_request_ctx(req); + sctx = crypto_ahash_ctx(tfm); + + dev_dbg(&sctx->sep_used->pdev->dev, + "sep_hash_final\n"); + sctx->current_hash_stage = HASH_FINISH; + + /* opcode and mode */ + sep_make_header(sctx, &msg_offset, SEP_HASH_FINISH_OPCODE); + + /* Context */ + sep_write_context(sctx, &msg_offset, &ctx->hash_private_ctx, + sizeof(struct sep_hash_private_context)); + + sep_end_msg(sctx, msg_offset); + sctx->done_with_transaction = 0; + result = sep_crypto_take_sep(sctx); + if (result) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_hash_final take sep failed\n"); + sep_crypto_release(sctx, -EINVAL); + } + + /** + * Sep is now working. Lets wait up to 5 seconds + * for completion. If it does not complete, we will do + * a crypto release with -EINVAL to release the + * kernel crypto infrastructure and let the system + * continue to boot up + * We have to wait this long because some crypto + * operations can take a while + */ + dev_dbg(&sctx->sep_used->pdev->dev, + "waiting for done with transaction\n"); + + sctx->end_time = jiffies + (SEP_TRANSACTION_WAIT_TIME * HZ); + while ((time_before(jiffies, sctx->end_time)) && + (!sctx->done_with_transaction)) + schedule(); + + dev_dbg(&sctx->sep_used->pdev->dev, + "done waiting for done with transaction\n"); + + /* are we done? */ + if (!sctx->done_with_transaction) { + /* Nope, lets release and tell crypto no */ + dev_warn(&sctx->sep_used->pdev->dev, + "[PID%d] sep_hash_final never finished\n", + current->pid); + sep_crypto_release(sctx, -EINVAL); + } +} + +static void sep_hash_digest(void *data) +{ + int int_error; + u32 msg_offset; + u32 block_size; + u32 msg[10]; + size_t copy_result; + int result; + u32 tail_len; + static char small_buf[100]; + struct scatterlist *new_sg; + void *src_ptr; + + struct ahash_request *req; + struct crypto_ahash *tfm; + struct sep_hash_ctx *ctx; + struct sep_system_ctx *sctx; + + req = (struct ahash_request *)data; + tfm = crypto_ahash_reqtfm(req); + ctx = ahash_request_ctx(req); + sctx = crypto_ahash_ctx(tfm); + + dev_dbg(&sctx->sep_used->pdev->dev, + "sep_hash_digest\n"); + sctx->current_hash_stage = HASH_DIGEST; + + /* length for queue status */ + sctx->nbytes = req->nbytes; + + block_size = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm)); + tail_len = req->nbytes % block_size; + dev_dbg(&sctx->sep_used->pdev->dev, "length is %x\n", req->nbytes); + dev_dbg(&sctx->sep_used->pdev->dev, "block_size is %x\n", block_size); + dev_dbg(&sctx->sep_used->pdev->dev, "tail len is %x\n", tail_len); + + /* Make sure all pages are even block */ + int_error = sep_oddball_pages(sctx->sep_used, req->src, + req->nbytes, + block_size, &new_sg, 1); + + if (int_error < 0) { + dev_warn(&sctx->sep_used->pdev->dev, + "oddball pages error in crash update\n"); + sep_crypto_release(sctx, -ENOMEM); + return; + } else if (int_error == 1) { + sctx->src_sg = new_sg; + sctx->src_sg_hold = new_sg; + } else { + sctx->src_sg = req->src; + sctx->src_sg_hold = NULL; + } + + src_ptr = sg_virt(sctx->src_sg); + + if ((!req->nbytes) || (!ctx->sg)) { + /* null data */ + src_ptr = NULL; + } + + sep_dump_sg(sctx->sep_used, "hash block sg in", sctx->src_sg); + + sctx->dcb_input_data.app_in_address = src_ptr; + sctx->dcb_input_data.data_in_size = req->nbytes - tail_len; + sctx->dcb_input_data.app_out_address = NULL; + sctx->dcb_input_data.block_size = block_size; + sctx->dcb_input_data.tail_block_size = 0; + sctx->dcb_input_data.is_applet = 0; + sctx->dcb_input_data.src_sg = sctx->src_sg; + sctx->dcb_input_data.dst_sg = NULL; + + int_error = sep_create_dcb_dmatables_context_kernel( + sctx->sep_used, + &sctx->dcb_region, + &sctx->dmatables_region, + &sctx->dma_ctx, + &sctx->dcb_input_data, + 1); + if (int_error) { + dev_warn(&sctx->sep_used->pdev->dev, + "hash update dma table create failed\n"); + sep_crypto_release(sctx, -EINVAL); + return; + } + + /* Construct message to SEP */ + sep_make_header(sctx, &msg_offset, SEP_HASH_SINGLE_OPCODE); + sep_write_msg(sctx, &ctx->hash_opmode, + sizeof(u32), sizeof(u32), &msg_offset, 0); + + msg[0] = (u32)0; + msg[1] = (u32)0; + msg[2] = (u32)0; + + sep_write_msg(sctx, msg, sizeof(u32) * 3, sizeof(u32) * 3, + &msg_offset, 0); + + /* Tail */ + sep_write_msg(sctx, &tail_len, sizeof(u32), + sizeof(u32), &msg_offset, 0); + + if (tail_len) { + copy_result = sep_copy_offset_sg( + sctx->sep_used, + sctx->src_sg, + req->nbytes - tail_len, + small_buf, tail_len); + + if (copy_result != tail_len) { + dev_warn(&sctx->sep_used->pdev->dev, + "sg tail copy failure in hash block\n"); + sep_crypto_release(sctx, -ENOMEM); + return; + } + + sep_write_msg(sctx, small_buf, tail_len, + sizeof(u32) * 32, &msg_offset, 1); + } else { + msg_offset += sizeof(u32) * 32; + } + + sep_end_msg(sctx, msg_offset); + + sctx->done_with_transaction = 0; + + result = sep_crypto_take_sep(sctx); + if (result) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_hash_digest take sep failed\n"); + sep_crypto_release(sctx, -EINVAL); + } + + /** + * Sep is now working. Lets wait up to 5 seconds + * for completion. If it does not complete, we will do + * a crypto release with -EINVAL to release the + * kernel crypto infrastructure and let the system + * continue to boot up + * We have to wait this long because some crypto + * operations can take a while + */ + dev_dbg(&sctx->sep_used->pdev->dev, + "waiting for done with transaction\n"); + + sctx->end_time = jiffies + (SEP_TRANSACTION_WAIT_TIME * HZ); + while ((time_before(jiffies, sctx->end_time)) && + (!sctx->done_with_transaction)) + schedule(); + + dev_dbg(&sctx->sep_used->pdev->dev, + "done waiting for done with transaction\n"); + + /* are we done? */ + if (!sctx->done_with_transaction) { + /* Nope, lets release and tell crypto no */ + dev_warn(&sctx->sep_used->pdev->dev, + "[PID%d] sep_hash_digest never finished\n", + current->pid); + sep_crypto_release(sctx, -EINVAL); + } +} + +/** + * This is what is called by each of the API's provided + * in the kernel crypto descriptors. It is run in a process + * context using the kernel workqueues. Therefore it can + * be put to sleep. + */ +static void sep_dequeuer(void *data) +{ + struct crypto_queue *this_queue; + struct crypto_async_request *async_req; + struct crypto_async_request *backlog; + struct ablkcipher_request *cypher_req; + struct ahash_request *hash_req; + struct sep_system_ctx *sctx; + struct crypto_ahash *hash_tfm; + + + this_queue = (struct crypto_queue *)data; + + spin_lock_irq(&queue_lock); + backlog = crypto_get_backlog(this_queue); + async_req = crypto_dequeue_request(this_queue); + spin_unlock_irq(&queue_lock); + + if (!async_req) { + pr_debug("sep crypto queue is empty\n"); + return; + } + + if (backlog) { + pr_debug("sep crypto backlog set\n"); + if (backlog->complete) + backlog->complete(backlog, -EINPROGRESS); + backlog = NULL; + } + + if (!async_req->tfm) { + pr_debug("sep crypto queue null tfm\n"); + return; + } + + if (!async_req->tfm->__crt_alg) { + pr_debug("sep crypto queue null __crt_alg\n"); + return; + } + + if (!async_req->tfm->__crt_alg->cra_type) { + pr_debug("sep crypto queue null cra_type\n"); + return; + } + + /* we have stuff in the queue */ + if (async_req->tfm->__crt_alg->cra_type != + &crypto_ahash_type) { + /* This is for a cypher */ + pr_debug("sep crypto queue doing cipher\n"); + cypher_req = container_of(async_req, + struct ablkcipher_request, + base); + if (!cypher_req) { + pr_debug("sep crypto queue null cypher_req\n"); + return; + } + + sep_crypto_block((void *)cypher_req); + return; + } else { + /* This is a hash */ + pr_debug("sep crypto queue doing hash\n"); + /** + * This is a bit more complex than cipher; we + * need to figure out what type of operation + */ + hash_req = ahash_request_cast(async_req); + if (!hash_req) { + pr_debug("sep crypto queue null hash_req\n"); + return; + } + + hash_tfm = crypto_ahash_reqtfm(hash_req); + if (!hash_tfm) { + pr_debug("sep crypto queue null hash_tfm\n"); + return; + } + + + sctx = crypto_ahash_ctx(hash_tfm); + if (!sctx) { + pr_debug("sep crypto queue null sctx\n"); + return; + } + + if (sctx->current_hash_stage == HASH_INIT) { + pr_debug("sep crypto queue hash init\n"); + sep_hash_init((void *)hash_req); + return; + } else if (sctx->current_hash_stage == HASH_UPDATE) { + pr_debug("sep crypto queue hash update\n"); + sep_hash_update((void *)hash_req); + return; + } else if (sctx->current_hash_stage == HASH_FINISH) { + pr_debug("sep crypto queue hash final\n"); + sep_hash_final((void *)hash_req); + return; + } else if (sctx->current_hash_stage == HASH_DIGEST) { + pr_debug("sep crypto queue hash digest\n"); + sep_hash_digest((void *)hash_req); + return; + } else { + pr_debug("sep crypto queue hash oops nothing\n"); + return; + } + } +} + +static int sep_sha1_init(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + + dev_dbg(&sctx->sep_used->pdev->dev, "doing sha1 init\n"); + sctx->current_request = SHA1; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_SHA1; + sctx->current_hash_stage = HASH_INIT; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep sha1 init cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sha1 init cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_sha1_update(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + + dev_dbg(&sctx->sep_used->pdev->dev, "doing sha1 update\n"); + sctx->current_request = SHA1; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_SHA1; + sctx->current_hash_stage = HASH_INIT; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep sha1 update cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sha1 update cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_sha1_final(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, "doing sha1 final\n"); + + sctx->current_request = SHA1; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_SHA1; + sctx->current_hash_stage = HASH_FINISH; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep sha1 final cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sha1 final cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; + +} + +static int sep_sha1_digest(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, "doing sha1 digest\n"); + + sctx->current_request = SHA1; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_SHA1; + sctx->current_hash_stage = HASH_DIGEST; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep sha1 digest cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sha1 digest cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; + +} + +static int sep_md5_init(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, "doing md5 init\n"); + + sctx->current_request = MD5; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_MD5; + sctx->current_hash_stage = HASH_INIT; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep md5 init cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "md5 init cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; + +} + +static int sep_md5_update(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, "doing md5 update\n"); + + sctx->current_request = MD5; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_MD5; + sctx->current_hash_stage = HASH_UPDATE; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "md5 update cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "md5 update cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_md5_final(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, "doing md5 final\n"); + + sctx->current_request = MD5; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_MD5; + sctx->current_hash_stage = HASH_FINISH; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep md5 final cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "md5 final cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; + +} + +static int sep_md5_digest(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + + dev_dbg(&sctx->sep_used->pdev->dev, "doing md5 digest\n"); + sctx->current_request = MD5; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_MD5; + sctx->current_hash_stage = HASH_DIGEST; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep md5 digest cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "md5 digest cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_sha224_init(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, "doing sha224 init\n"); + + sctx->current_request = SHA224; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_SHA224; + sctx->current_hash_stage = HASH_INIT; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep sha224 init cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sha224 init cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_sha224_update(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, "doing sha224 update\n"); + + sctx->current_request = SHA224; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_SHA224; + sctx->current_hash_stage = HASH_UPDATE; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep sha224 update cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sha224 update cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_sha224_final(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, "doing sha224 final\n"); + + sctx->current_request = SHA224; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_SHA224; + sctx->current_hash_stage = HASH_FINISH; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep sha224 final cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sha224 final cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_sha224_digest(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + + dev_dbg(&sctx->sep_used->pdev->dev, "doing 224 digest\n"); + sctx->current_request = SHA224; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_SHA224; + sctx->current_hash_stage = HASH_DIGEST; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep sha224 digest cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sha256 digest cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_sha256_init(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, "doing sha256 init\n"); + + sctx->current_request = SHA256; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_SHA256; + sctx->current_hash_stage = HASH_INIT; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep sha256 init cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sha256 init cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_sha256_update(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, "doing sha256 update\n"); + + sctx->current_request = SHA256; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_SHA256; + sctx->current_hash_stage = HASH_UPDATE; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep sha256 update cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sha256 update cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_sha256_final(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, "doing sha256 final\n"); + + sctx->current_request = SHA256; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_SHA256; + sctx->current_hash_stage = HASH_FINISH; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep sha256 final cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sha256 final cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_sha256_digest(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + + dev_dbg(&sctx->sep_used->pdev->dev, "doing sha256 digest\n"); + sctx->current_request = SHA256; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_SHA256; + sctx->current_hash_stage = HASH_DIGEST; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep sha256 digest cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sha256 digest cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_crypto_init(struct crypto_tfm *tfm) +{ + struct sep_system_ctx *sctx = crypto_tfm_ctx(tfm); + const char *alg_name = crypto_tfm_alg_name(tfm); + + sctx->sep_used = sep_dev; + + if (alg_name == NULL) + dev_dbg(&sctx->sep_used->pdev->dev, "alg is NULL\n"); + else + dev_dbg(&sctx->sep_used->pdev->dev, "alg is %s\n", alg_name); + + tfm->crt_ablkcipher.reqsize = sizeof(struct sep_block_ctx); + dev_dbg(&sctx->sep_used->pdev->dev, "sep_crypto_init\n"); + return 0; +} + +static void sep_crypto_exit(struct crypto_tfm *tfm) +{ + struct sep_system_ctx *sctx = crypto_tfm_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, "sep_crypto_exit\n"); + sctx->sep_used = NULL; +} + +static int sep_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key, + unsigned int keylen) +{ + struct sep_system_ctx *sctx = crypto_ablkcipher_ctx(tfm); + + dev_dbg(&sctx->sep_used->pdev->dev, "sep aes setkey\n"); + + switch (keylen) { + case SEP_AES_KEY_128_SIZE: + sctx->aes_key_size = AES_128; + break; + case SEP_AES_KEY_192_SIZE: + sctx->aes_key_size = AES_192; + break; + case SEP_AES_KEY_256_SIZE: + sctx->aes_key_size = AES_256; + break; + case SEP_AES_KEY_512_SIZE: + sctx->aes_key_size = AES_512; + break; + default: + dev_warn(&sctx->sep_used->pdev->dev, "sep aes key size %x\n", + keylen); + return -EINVAL; + } + + memset(&sctx->key.aes, 0, sizeof(u32) * + SEP_AES_MAX_KEY_SIZE_WORDS); + memcpy(&sctx->key.aes, key, keylen); + sctx->keylen = keylen; + /* Indicate to encrypt/decrypt function to send key to SEP */ + sctx->key_sent = 0; + sctx->last_block = 0; + + return 0; +} + +static int sep_aes_ecb_encrypt(struct ablkcipher_request *req) +{ + int error; + struct sep_block_ctx *bctx = ablkcipher_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ablkcipher_ctx( + crypto_ablkcipher_reqtfm(req)); + + dev_dbg(&sctx->sep_used->pdev->dev, "sep aes ecb encrypt\n"); + sctx->current_request = AES_ECB; + sctx->current_hash_req = NULL; + sctx->current_cypher_req = req; + bctx->aes_encmode = SEP_AES_ENCRYPT; + bctx->aes_opmode = SEP_AES_ECB; + bctx->init_opcode = SEP_AES_INIT_OPCODE; + bctx->block_opcode = SEP_AES_BLOCK_OPCODE; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_aes_ecb_encrypt cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_aes_ecb_encrypt cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_aes_ecb_decrypt(struct ablkcipher_request *req) +{ + int error; + struct sep_block_ctx *bctx = ablkcipher_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ablkcipher_ctx( + crypto_ablkcipher_reqtfm(req)); + + dev_dbg(&sctx->sep_used->pdev->dev, "sep aes ecb decrypt\n"); + sctx->current_request = AES_ECB; + sctx->current_hash_req = NULL; + sctx->current_cypher_req = req; + bctx->aes_encmode = SEP_AES_DECRYPT; + bctx->aes_opmode = SEP_AES_ECB; + bctx->init_opcode = SEP_AES_INIT_OPCODE; + bctx->block_opcode = SEP_AES_BLOCK_OPCODE; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_aes_ecb_decrypt cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_aes_ecb_decrypt cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_aes_cbc_encrypt(struct ablkcipher_request *req) +{ + int error; + struct sep_block_ctx *bctx = ablkcipher_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ablkcipher_ctx( + crypto_ablkcipher_reqtfm(req)); + + dev_dbg(&sctx->sep_used->pdev->dev, "sep aes cbc encrypt\n"); + sctx->current_request = AES_CBC; + sctx->current_hash_req = NULL; + sctx->current_cypher_req = req; + bctx->aes_encmode = SEP_AES_ENCRYPT; + bctx->aes_opmode = SEP_AES_CBC; + bctx->init_opcode = SEP_AES_INIT_OPCODE; + bctx->block_opcode = SEP_AES_BLOCK_OPCODE; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_aes_cbc_encrypt cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_aes_cbc_encrypt cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_aes_cbc_decrypt(struct ablkcipher_request *req) +{ + int error; + struct sep_block_ctx *bctx = ablkcipher_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ablkcipher_ctx( + crypto_ablkcipher_reqtfm(req)); + + dev_dbg(&sctx->sep_used->pdev->dev, "sep aes cbc decrypt\n"); + sctx->current_request = AES_CBC; + sctx->current_hash_req = NULL; + sctx->current_cypher_req = req; + bctx->aes_encmode = SEP_AES_DECRYPT; + bctx->aes_opmode = SEP_AES_CBC; + bctx->init_opcode = SEP_AES_INIT_OPCODE; + bctx->block_opcode = SEP_AES_BLOCK_OPCODE; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_aes_cbc_decrypt cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_aes_cbc_decrypt cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key, + unsigned int keylen) +{ + struct sep_system_ctx *sctx = crypto_ablkcipher_ctx(tfm); + struct crypto_tfm *ctfm = crypto_ablkcipher_tfm(tfm); + u32 *flags = &ctfm->crt_flags; + + dev_dbg(&sctx->sep_used->pdev->dev, "sep des setkey\n"); + + switch (keylen) { + case DES_KEY_SIZE: + sctx->des_nbr_keys = DES_KEY_1; + break; + case DES_KEY_SIZE * 2: + sctx->des_nbr_keys = DES_KEY_2; + break; + case DES_KEY_SIZE * 3: + sctx->des_nbr_keys = DES_KEY_3; + break; + default: + dev_dbg(&sctx->sep_used->pdev->dev, "invalid key size %x\n", + keylen); + return -EINVAL; + } + + if ((*flags & CRYPTO_TFM_REQ_WEAK_KEY) && + (sep_weak_key(key, keylen))) { + + *flags |= CRYPTO_TFM_RES_WEAK_KEY; + dev_warn(&sctx->sep_used->pdev->dev, "weak key\n"); + return -EINVAL; + } + + memset(&sctx->key.des, 0, sizeof(struct sep_des_key)); + memcpy(&sctx->key.des.key1, key, keylen); + sctx->keylen = keylen; + /* Indicate to encrypt/decrypt function to send key to SEP */ + sctx->key_sent = 0; + sctx->last_block = 0; + + return 0; +} + +static int sep_des_ebc_encrypt(struct ablkcipher_request *req) +{ + int error; + struct sep_block_ctx *bctx = ablkcipher_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ablkcipher_ctx( + crypto_ablkcipher_reqtfm(req)); + + dev_dbg(&sctx->sep_used->pdev->dev, "sep des ecb encrypt\n"); + sctx->current_request = DES_ECB; + sctx->current_hash_req = NULL; + sctx->current_cypher_req = req; + bctx->des_encmode = SEP_DES_ENCRYPT; + bctx->des_opmode = SEP_DES_ECB; + bctx->init_opcode = SEP_DES_INIT_OPCODE; + bctx->block_opcode = SEP_DES_BLOCK_OPCODE; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_des_ecb_encrypt cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_des_ecb_encrypt cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_des_ebc_decrypt(struct ablkcipher_request *req) +{ + int error; + struct sep_block_ctx *bctx = ablkcipher_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ablkcipher_ctx( + crypto_ablkcipher_reqtfm(req)); + + dev_dbg(&sctx->sep_used->pdev->dev, "sep des ecb decrypt\n"); + sctx->current_request = DES_ECB; + sctx->current_hash_req = NULL; + sctx->current_cypher_req = req; + bctx->des_encmode = SEP_DES_DECRYPT; + bctx->des_opmode = SEP_DES_ECB; + bctx->init_opcode = SEP_DES_INIT_OPCODE; + bctx->block_opcode = SEP_DES_BLOCK_OPCODE; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_des_ecb_decrypt cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_des_ecb_decrypt cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_des_cbc_encrypt(struct ablkcipher_request *req) +{ + int error; + struct sep_block_ctx *bctx = ablkcipher_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ablkcipher_ctx( + crypto_ablkcipher_reqtfm(req)); + + dev_dbg(&sctx->sep_used->pdev->dev, "sep des cbc encrypt\n"); + sctx->current_request = DES_CBC; + sctx->current_hash_req = NULL; + sctx->current_cypher_req = req; + bctx->des_encmode = SEP_DES_ENCRYPT; + bctx->des_opmode = SEP_DES_CBC; + bctx->init_opcode = SEP_DES_INIT_OPCODE; + bctx->block_opcode = SEP_DES_BLOCK_OPCODE; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_des_cbc_encrypt cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_des_cbc_encrypt cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_des_cbc_decrypt(struct ablkcipher_request *req) +{ + int error; + struct sep_block_ctx *bctx = ablkcipher_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ablkcipher_ctx( + crypto_ablkcipher_reqtfm(req)); + + dev_dbg(&sctx->sep_used->pdev->dev, "sep des cbc decrypt\n"); + sctx->current_request = DES_CBC; + sctx->current_hash_req = NULL; + sctx->current_cypher_req = req; + bctx->des_encmode = SEP_DES_DECRYPT; + bctx->des_opmode = SEP_DES_CBC; + bctx->init_opcode = SEP_DES_INIT_OPCODE; + bctx->block_opcode = SEP_DES_BLOCK_OPCODE; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_des_cbc_decrypt cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_des_cbc_decrypt cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static struct ahash_alg hash_algs[] = { +{ + .init = sep_sha1_init, + .update = sep_sha1_update, + .final = sep_sha1_final, + .digest = sep_sha1_digest, + .halg = { + .digestsize = SHA1_DIGEST_SIZE, + .base = { + .cra_name = "sha1", + .cra_driver_name = "sha1-sep", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC, + .cra_blocksize = SHA1_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sep_system_ctx), + .cra_alignmask = 0, + .cra_module = THIS_MODULE, + .cra_init = sep_hash_cra_init, + .cra_exit = sep_hash_cra_exit, + } + } +}, +{ + .init = sep_md5_init, + .update = sep_md5_update, + .final = sep_md5_final, + .digest = sep_md5_digest, + .halg = { + .digestsize = MD5_DIGEST_SIZE, + .base = { + .cra_name = "md5", + .cra_driver_name = "md5-sep", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC, + .cra_blocksize = SHA1_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sep_system_ctx), + .cra_alignmask = 0, + .cra_module = THIS_MODULE, + .cra_init = sep_hash_cra_init, + .cra_exit = sep_hash_cra_exit, + } + } +}, +{ + .init = sep_sha224_init, + .update = sep_sha224_update, + .final = sep_sha224_final, + .digest = sep_sha224_digest, + .halg = { + .digestsize = SHA224_DIGEST_SIZE, + .base = { + .cra_name = "sha224", + .cra_driver_name = "sha224-sep", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC, + .cra_blocksize = SHA224_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sep_system_ctx), + .cra_alignmask = 0, + .cra_module = THIS_MODULE, + .cra_init = sep_hash_cra_init, + .cra_exit = sep_hash_cra_exit, + } + } +}, +{ + .init = sep_sha256_init, + .update = sep_sha256_update, + .final = sep_sha256_final, + .digest = sep_sha256_digest, + .halg = { + .digestsize = SHA256_DIGEST_SIZE, + .base = { + .cra_name = "sha256", + .cra_driver_name = "sha256-sep", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC, + .cra_blocksize = SHA256_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sep_system_ctx), + .cra_alignmask = 0, + .cra_module = THIS_MODULE, + .cra_init = sep_hash_cra_init, + .cra_exit = sep_hash_cra_exit, + } + } +} +}; + +static struct crypto_alg crypto_algs[] = { +{ + .cra_name = "ecb(aes)", + .cra_driver_name = "ecb-aes-sep", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sep_system_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_init = sep_crypto_init, + .cra_exit = sep_crypto_exit, + .cra_u.ablkcipher = { + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .setkey = sep_aes_setkey, + .encrypt = sep_aes_ecb_encrypt, + .decrypt = sep_aes_ecb_decrypt, + } +}, +{ + .cra_name = "cbc(aes)", + .cra_driver_name = "cbc-aes-sep", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sep_system_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_init = sep_crypto_init, + .cra_exit = sep_crypto_exit, + .cra_u.ablkcipher = { + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .setkey = sep_aes_setkey, + .encrypt = sep_aes_cbc_encrypt, + .decrypt = sep_aes_cbc_decrypt, + } +}, +{ + .cra_name = "ebc(des)", + .cra_driver_name = "ebc-des-sep", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = DES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sep_system_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_init = sep_crypto_init, + .cra_exit = sep_crypto_exit, + .cra_u.ablkcipher = { + .min_keysize = DES_KEY_SIZE, + .max_keysize = DES_KEY_SIZE, + .setkey = sep_des_setkey, + .encrypt = sep_des_ebc_encrypt, + .decrypt = sep_des_ebc_decrypt, + } +}, +{ + .cra_name = "cbc(des)", + .cra_driver_name = "cbc-des-sep", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = DES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sep_system_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_init = sep_crypto_init, + .cra_exit = sep_crypto_exit, + .cra_u.ablkcipher = { + .min_keysize = DES_KEY_SIZE, + .max_keysize = DES_KEY_SIZE, + .setkey = sep_des_setkey, + .encrypt = sep_des_cbc_encrypt, + .decrypt = sep_des_cbc_decrypt, + } +}, +{ + .cra_name = "ebc(des3-ede)", + .cra_driver_name = "ebc-des3-ede-sep", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = DES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sep_system_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_init = sep_crypto_init, + .cra_exit = sep_crypto_exit, + .cra_u.ablkcipher = { + .min_keysize = DES3_EDE_KEY_SIZE, + .max_keysize = DES3_EDE_KEY_SIZE, + .setkey = sep_des_setkey, + .encrypt = sep_des_ebc_encrypt, + .decrypt = sep_des_ebc_decrypt, + } +}, +{ + .cra_name = "cbc(des3-ede)", + .cra_driver_name = "cbc-des3--ede-sep", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = DES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sep_system_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_init = sep_crypto_init, + .cra_exit = sep_crypto_exit, + .cra_u.ablkcipher = { + .min_keysize = DES3_EDE_KEY_SIZE, + .max_keysize = DES3_EDE_KEY_SIZE, + .setkey = sep_des_setkey, + .encrypt = sep_des_cbc_encrypt, + .decrypt = sep_des_cbc_decrypt, + } +} +}; + +int sep_crypto_setup(void) +{ + int err, i, j, k; + tasklet_init(&sep_dev->finish_tasklet, sep_finish, + (unsigned long)sep_dev); + + crypto_init_queue(&sep_queue, SEP_QUEUE_LENGTH); + + sep_dev->workqueue = create_workqueue("sep_crypto_workqueue"); + if (!sep_dev->workqueue) { + dev_warn(&sep_dev->pdev->dev, "cant create workqueue\n"); + return -ENOMEM; + } + + i = 0; + j = 0; + + spin_lock_init(&sep_dev->busy_lock); + spin_lock_init(&queue_lock); + + err = 0; + + for (i = 0; i < ARRAY_SIZE(hash_algs); i++) { + err = crypto_register_ahash(&hash_algs[i]); + if (err) + goto err_algs; + } + + err = 0; + for (j = 0; j < ARRAY_SIZE(crypto_algs); j++) { + err = crypto_register_alg(&crypto_algs[j]); + if (err) + goto err_crypto_algs; + } + + return err; + +err_algs: + for (k = 0; k < i; k++) + crypto_unregister_ahash(&hash_algs[k]); + return err; + +err_crypto_algs: + for (k = 0; k < j; k++) + crypto_unregister_alg(&crypto_algs[k]); + goto err_algs; +} + +void sep_crypto_takedown(void) +{ + + int i; + + for (i = 0; i < ARRAY_SIZE(hash_algs); i++) + crypto_unregister_ahash(&hash_algs[i]); + for (i = 0; i < ARRAY_SIZE(crypto_algs); i++) + crypto_unregister_alg(&crypto_algs[i]); + + tasklet_kill(&sep_dev->finish_tasklet); +} diff --git a/drivers/staging/sep/sep_crypto.h b/drivers/staging/sep/sep_crypto.h new file mode 100644 index 00000000000..52c58c483c5 --- /dev/null +++ b/drivers/staging/sep/sep_crypto.h @@ -0,0 +1,348 @@ +/* + * + * sep_crypto.h - Crypto interface structures + * + * Copyright(c) 2009-2011 Intel Corporation. All rights reserved. + * Contributions(c) 2009-2010 Discretix. 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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * CONTACTS: + * + * Mark Allyn mark.a.allyn@intel.com + * Jayant Mangalampalli jayant.mangalampalli@intel.com + * + * CHANGES: + * + * 2009.06.26 Initial publish + * 2011.02.22 Enable Kernel Crypto + * + */ + +/* Constants for SEP (from vendor) */ +#define SEP_START_MSG_TOKEN 0x02558808 + +#define SEP_DES_IV_SIZE_WORDS 2 +#define SEP_DES_IV_SIZE_BYTES (SEP_DES_IV_SIZE_WORDS * \ + sizeof(u32)) +#define SEP_DES_KEY_SIZE_WORDS 2 +#define SEP_DES_KEY_SIZE_BYTES (SEP_DES_KEY_SIZE_WORDS * \ + sizeof(u32)) +#define SEP_DES_BLOCK_SIZE 8 +#define SEP_DES_DUMMY_SIZE 16 + +#define SEP_DES_INIT_OPCODE 0x10 +#define SEP_DES_BLOCK_OPCODE 0x11 + +#define SEP_AES_BLOCK_SIZE_WORDS 4 +#define SEP_AES_BLOCK_SIZE_BYTES \ + (SEP_AES_BLOCK_SIZE_WORDS * sizeof(u32)) + +#define SEP_AES_DUMMY_BLOCK_SIZE 16 +#define SEP_AES_IV_SIZE_WORDS SEP_AES_BLOCK_SIZE_WORDS +#define SEP_AES_IV_SIZE_BYTES \ + (SEP_AES_IV_SIZE_WORDS * sizeof(u32)) + +#define SEP_AES_KEY_128_SIZE 16 +#define SEP_AES_KEY_192_SIZE 24 +#define SEP_AES_KEY_256_SIZE 32 +#define SEP_AES_KEY_512_SIZE 64 +#define SEP_AES_MAX_KEY_SIZE_WORDS 16 +#define SEP_AES_MAX_KEY_SIZE_BYTES \ + (SEP_AES_MAX_KEY_SIZE_WORDS * sizeof(u32)) + +#define SEP_AES_WRAP_MIN_SIZE 8 +#define SEP_AES_WRAP_MAX_SIZE 0x10000000 + +#define SEP_AES_WRAP_BLOCK_SIZE_WORDS 2 +#define SEP_AES_WRAP_BLOCK_SIZE_BYTES \ + (SEP_AES_WRAP_BLOCK_SIZE_WORDS * sizeof(u32)) + +#define SEP_AES_SECRET_RKEK1 0x1 +#define SEP_AES_SECRET_RKEK2 0x2 + +#define SEP_AES_INIT_OPCODE 0x2 +#define SEP_AES_BLOCK_OPCODE 0x3 +#define SEP_AES_FINISH_OPCODE 0x4 +#define SEP_AES_WRAP_OPCODE 0x6 +#define SEP_AES_UNWRAP_OPCODE 0x7 +#define SEP_AES_XTS_FINISH_OPCODE 0x8 + +#define SEP_HASH_RESULT_SIZE_WORDS 16 +#define SEP_MD5_DIGEST_SIZE_WORDS 4 +#define SEP_MD5_DIGEST_SIZE_BYTES \ + (SEP_MD5_DIGEST_SIZE_WORDS * sizeof(u32)) +#define SEP_SHA1_DIGEST_SIZE_WORDS 5 +#define SEP_SHA1_DIGEST_SIZE_BYTES \ + (SEP_SHA1_DIGEST_SIZE_WORDS * sizeof(u32)) +#define SEP_SHA224_DIGEST_SIZE_WORDS 7 +#define SEP_SHA224_DIGEST_SIZE_BYTES \ + (SEP_SHA224_DIGEST_SIZE_WORDS * sizeof(u32)) +#define SEP_SHA256_DIGEST_SIZE_WORDS 8 +#define SEP_SHA256_DIGEST_SIZE_BYTES \ + (SEP_SHA256_DIGEST_SIZE_WORDS * sizeof(u32)) +#define SEP_SHA384_DIGEST_SIZE_WORDS 12 +#define SEP_SHA384_DIGEST_SIZE_BYTES \ + (SEP_SHA384_DIGEST_SIZE_WORDS * sizeof(u32)) +#define SEP_SHA512_DIGEST_SIZE_WORDS 16 +#define SEP_SHA512_DIGEST_SIZE_BYTES \ + (SEP_SHA512_DIGEST_SIZE_WORDS * sizeof(u32)) +#define SEP_HASH_BLOCK_SIZE_WORDS 16 +#define SEP_HASH_BLOCK_SIZE_BYTES \ + (SEP_HASH_BLOCK_SIZE_WORDS * sizeof(u32)) +#define SEP_SHA2_BLOCK_SIZE_WORDS 32 +#define SEP_SHA2_BLOCK_SIZE_BYTES \ + (SEP_SHA2_BLOCK_SIZE_WORDS * sizeof(u32)) + +#define SEP_HASH_INIT_OPCODE 0x20 +#define SEP_HASH_UPDATE_OPCODE 0x21 +#define SEP_HASH_FINISH_OPCODE 0x22 +#define SEP_HASH_SINGLE_OPCODE 0x23 + +#define SEP_HOST_ERROR 0x0b000000 +#define SEP_OK 0x0 +#define SEP_INVALID_START (SEP_HOST_ERROR + 0x3) +#define SEP_WRONG_OPCODE (SEP_HOST_ERROR + 0x1) + +#define SEP_TRANSACTION_WAIT_TIME 5 + +#define SEP_QUEUE_LENGTH 10 +/* Macros */ +#ifndef __LITTLE_ENDIAN +#define CHG_ENDIAN(val) \ + (((val) >> 24) | \ + (((val) & 0x00FF0000) >> 8) | \ + (((val) & 0x0000FF00) << 8) | \ + (((val) & 0x000000FF) << 24)) +#else +#define CHG_ENDIAN(val) val +#endif +/* Enums for SEP (from vendor) */ +enum des_numkey { + DES_KEY_1 = 1, + DES_KEY_2 = 2, + DES_KEY_3 = 3, + SEP_NUMKEY_OPTIONS, + SEP_NUMKEY_LAST = 0x7fffffff, +}; + +enum des_enc_mode { + SEP_DES_ENCRYPT = 0, + SEP_DES_DECRYPT = 1, + SEP_DES_ENC_OPTIONS, + SEP_DES_ENC_LAST = 0x7fffffff, +}; + +enum des_op_mode { + SEP_DES_ECB = 0, + SEP_DES_CBC = 1, + SEP_OP_OPTIONS, + SEP_OP_LAST = 0x7fffffff, +}; + +enum aes_keysize { + AES_128 = 0, + AES_192 = 1, + AES_256 = 2, + AES_512 = 3, + AES_SIZE_OPTIONS, + AEA_SIZE_LAST = 0x7FFFFFFF, +}; + +enum aes_enc_mode { + SEP_AES_ENCRYPT = 0, + SEP_AES_DECRYPT = 1, + SEP_AES_ENC_OPTIONS, + SEP_AES_ENC_LAST = 0x7FFFFFFF, +}; + +enum aes_op_mode { + SEP_AES_ECB = 0, + SEP_AES_CBC = 1, + SEP_AES_MAC = 2, + SEP_AES_CTR = 3, + SEP_AES_XCBC = 4, + SEP_AES_CMAC = 5, + SEP_AES_XTS = 6, + SEP_AES_OP_OPTIONS, + SEP_AES_OP_LAST = 0x7FFFFFFF, +}; + +enum hash_op_mode { + SEP_HASH_SHA1 = 0, + SEP_HASH_SHA224 = 1, + SEP_HASH_SHA256 = 2, + SEP_HASH_SHA384 = 3, + SEP_HASH_SHA512 = 4, + SEP_HASH_MD5 = 5, + SEP_HASH_OPTIONS, + SEP_HASH_LAST_MODE = 0x7FFFFFFF, +}; + +/* Structures for SEP (from vendor) */ +struct sep_des_internal_key { + u32 key1[SEP_DES_KEY_SIZE_WORDS]; + u32 key2[SEP_DES_KEY_SIZE_WORDS]; + u32 key3[SEP_DES_KEY_SIZE_WORDS]; +}; + +struct sep_des_internal_context { + u32 iv_context[SEP_DES_IV_SIZE_WORDS]; + struct sep_des_internal_key context_key; + enum des_numkey nbr_keys; + enum des_enc_mode encryption; + enum des_op_mode operation; + u8 dummy_block[SEP_DES_DUMMY_SIZE]; +}; + +struct sep_des_private_context { + u32 valid_tag; + u32 iv; + u8 ctx_buf[sizeof(struct sep_des_internal_context)]; +}; + +/* This is the structure passed to SEP via msg area */ +struct sep_des_key { + u32 key1[SEP_DES_KEY_SIZE_WORDS]; + u32 key2[SEP_DES_KEY_SIZE_WORDS]; + u32 key3[SEP_DES_KEY_SIZE_WORDS]; + u32 pad[SEP_DES_KEY_SIZE_WORDS]; +}; + +struct sep_aes_internal_context { + u32 aes_ctx_iv[SEP_AES_IV_SIZE_WORDS]; + u32 aes_ctx_key[SEP_AES_MAX_KEY_SIZE_WORDS / 2]; + enum aes_keysize keysize; + enum aes_enc_mode encmode; + enum aes_op_mode opmode; + u8 secret_key; + u32 no_add_blocks; + u32 last_block_size; + u32 last_block[SEP_AES_BLOCK_SIZE_WORDS]; + u32 prev_iv[SEP_AES_BLOCK_SIZE_WORDS]; + u32 remaining_size; + union { + struct { + u32 dkey1[SEP_AES_BLOCK_SIZE_WORDS]; + u32 dkey2[SEP_AES_BLOCK_SIZE_WORDS]; + u32 dkey3[SEP_AES_BLOCK_SIZE_WORDS]; + } cmac_data; + struct { + u32 xts_key[SEP_AES_MAX_KEY_SIZE_WORDS / 2]; + u32 temp1[SEP_AES_BLOCK_SIZE_WORDS]; + u32 temp2[SEP_AES_BLOCK_SIZE_WORDS]; + } xtx_data; + } s_data; + u8 dummy_block[SEP_AES_DUMMY_BLOCK_SIZE]; +}; + +struct sep_aes_private_context { + u32 valid_tag; + u32 aes_iv; + u32 op_mode; + u8 cbuff[sizeof(struct sep_aes_internal_context)]; +}; + +struct sep_hash_internal_context { + u32 hash_result[SEP_HASH_RESULT_SIZE_WORDS]; + enum hash_op_mode hash_opmode; + u32 previous_data[SEP_SHA2_BLOCK_SIZE_WORDS]; + u16 prev_update_bytes; + u32 total_proc_128bit[4]; + u16 op_mode_block_size; + u8 dummy_aes_block[SEP_AES_DUMMY_BLOCK_SIZE]; +}; + +struct sep_hash_private_context { + u32 valid_tag; + u32 iv; + u8 internal_context[sizeof(struct sep_hash_internal_context)]; +}; + +/* Context structures for crypto API */ +struct sep_block_ctx { + struct sep_device *sep; + u32 done; + unsigned char iv[100]; + enum des_enc_mode des_encmode; + enum des_op_mode des_opmode; + enum aes_enc_mode aes_encmode; + enum aes_op_mode aes_opmode; + u32 init_opcode; + u32 block_opcode; + size_t data_length; + size_t ivlen; + struct ablkcipher_walk walk; + struct sep_des_private_context des_private_ctx; + struct sep_aes_private_context aes_private_ctx; + }; + +struct sep_hash_ctx { + u32 done; + unsigned char *buf; + size_t buflen; + unsigned char *dgst; + int digest_size_words; + int digest_size_bytes; + int block_size_words; + int block_size_bytes; + struct scatterlist *sg; + enum hash_op_mode hash_opmode; + struct sep_hash_private_context hash_private_ctx; + }; + +struct sep_system_ctx { + struct sep_device *sep_used; + union key_t { + struct sep_des_key des; + u32 aes[SEP_AES_MAX_KEY_SIZE_WORDS]; + } key; + int i_own_sep; /* Do I have custody of the sep? */ + size_t keylen; + enum des_numkey des_nbr_keys; + enum aes_keysize aes_key_size; + u32 key_sent; /* Indicate if key is sent to sep */ + u32 last_block; /* Indicate that this is the final block */ + struct sep_call_status call_status; + struct build_dcb_struct_kernel dcb_input_data; + struct sep_dma_context *dma_ctx; + void *dmatables_region; + size_t nbytes; + struct sep_dcblock *dcb_region; + struct sep_queue_info *queue_elem; + int msg_len_words; + unsigned char msg[SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES]; + void *msgptr; + struct scatterlist *src_sg; + struct scatterlist *dst_sg; + struct scatterlist *src_sg_hold; + struct scatterlist *dst_sg_hold; + struct ahash_request *current_hash_req; + struct ablkcipher_request *current_cypher_req; + enum type_of_request current_request; + enum hash_stage current_hash_stage; + int done_with_transaction; + unsigned long end_time; + }; + +/* work queue structures */ +struct sep_work_struct { + struct work_struct work; + void (*callback)(void *); + void *data; + }; + +/* Functions */ +int sep_crypto_setup(void); +void sep_crypto_takedown(void); diff --git a/drivers/staging/sep/sep_dev.h b/drivers/staging/sep/sep_dev.h index 696ab0dd2b7..66d8e95523b 100644 --- a/drivers/staging/sep/sep_dev.h +++ b/drivers/staging/sep/sep_dev.h @@ -5,8 +5,8 @@ * * sep_dev.h - Security Processor Device Structures * - * Copyright(c) 2009,2010 Intel Corporation. All rights reserved. - * Contributions(c) 2009,2010 Discretix. All rights reserved. + * Copyright(c) 2009-2011 Intel Corporation. All rights reserved. + * Contributions(c) 2009-2011 Discretix. 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 @@ -28,6 +28,7 @@ * * CHANGES * 2010.09.14 upgrade to Medfield + * 2011.02.22 enable kernel crypto */ struct sep_device { @@ -36,33 +37,21 @@ struct sep_device { /* character device file */ struct cdev sep_cdev; - struct cdev sep_daemon_cdev; - struct cdev sep_singleton_cdev; /* devices (using misc dev) */ struct miscdevice miscdev_sep; - struct miscdevice miscdev_singleton; - struct miscdevice miscdev_daemon; /* major / minor numbers of device */ dev_t sep_devno; - dev_t sep_daemon_devno; - dev_t sep_singleton_devno; - - struct mutex sep_mutex; - struct mutex ioctl_mutex; + /* guards command sent counter */ spinlock_t snd_rply_lck; + /* guards driver memory usage in fastcall if */ + struct semaphore sep_doublebuf; /* flags to indicate use and lock status of sep */ u32 pid_doing_transaction; unsigned long in_use_flags; - /* request daemon alread open */ - unsigned long request_daemon_open; - - /* 1 = Moorestown; 0 = Medfield */ - int mrst; - /* address of the shared memory allocated during init for SEP driver (coherent alloc) */ dma_addr_t shared_bus; @@ -74,36 +63,78 @@ struct sep_device { dma_addr_t reg_physical_end; void __iomem *reg_addr; - /* wait queue head (event) of the driver */ - wait_queue_head_t event; - wait_queue_head_t event_request_daemon; - wait_queue_head_t event_mmap; + /* wait queue heads of the driver */ + wait_queue_head_t event_interrupt; + wait_queue_head_t event_transactions; - struct sep_caller_id_entry - caller_id_table[SEP_CALLER_ID_TABLE_NUM_ENTRIES]; + struct list_head sep_queue_status; + u32 sep_queue_num; + spinlock_t sep_queue_lock; - /* access flag for singleton device */ - unsigned long singleton_access_flag; + /* Is this in use? */ + u32 in_use; + + /* indicates whether power save is set up */ + u32 power_save_setup; + + /* Power state */ + u32 power_state; /* transaction counter that coordinates the transactions between SEP and HOST */ unsigned long send_ct; /* counter for the messages from sep */ unsigned long reply_ct; - /* counter for the number of bytes allocated in the pool for the - current transaction */ - long data_pool_bytes_allocated; - u32 num_of_data_allocations; + /* The following are used for kernel crypto client requests */ + u32 in_kernel; /* Set for kernel client request */ + struct tasklet_struct finish_tasklet; + enum type_of_request current_request; + enum hash_stage current_hash_stage; + struct ahash_request *current_hash_req; + struct ablkcipher_request *current_cypher_req; + struct sep_system_ctx *sctx; + spinlock_t busy_lock; + struct workqueue_struct *workqueue; +}; - /* number of the lli tables created in the current transaction */ - u32 num_lli_tables_created; +extern struct sep_device *sep_dev; - /* number of data control blocks */ - u32 nr_dcb_creat; +/** + * SEP message header for a transaction + * @reserved: reserved memory (two words) + * @token: SEP message token + * @msg_len: message length + * @opcpde: message opcode + */ +struct sep_msgarea_hdr { + u32 reserved[2]; + u32 token; + u32 msg_len; + u32 opcode; +}; - struct sep_dma_resource dma_res_arr[SEP_MAX_NUM_SYNC_DMA_OPS]; +/** + * sep_queue_data - data to be maintained in status queue for a transaction + * @opcode : transaction opcode + * @size : message size + * @pid: owner process + * @name: owner process name + */ +struct sep_queue_data { + u32 opcode; + u32 size; + s32 pid; + u8 name[TASK_COMM_LEN]; +}; +/** sep_queue_info - maintains status info of all transactions + * @list: head of list + * @sep_queue_data : data for transaction + */ +struct sep_queue_info { + struct list_head list; + struct sep_queue_data data; }; static inline void sep_write_reg(struct sep_device *dev, int reg, u32 value) diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c deleted file mode 100644 index 6b3d156d414..00000000000 --- a/drivers/staging/sep/sep_driver.c +++ /dev/null @@ -1,2932 +0,0 @@ -/* - * - * sep_driver.c - Security Processor Driver main group of functions - * - * Copyright(c) 2009,2010 Intel Corporation. All rights reserved. - * Contributions(c) 2009,2010 Discretix. 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; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * CONTACTS: - * - * Mark Allyn mark.a.allyn@intel.com - * Jayant Mangalampalli jayant.mangalampalli@intel.com - * - * CHANGES: - * - * 2009.06.26 Initial publish - * 2010.09.14 Upgrade to Medfield - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sep_driver_hw_defs.h" -#include "sep_driver_config.h" -#include "sep_driver_api.h" -#include "sep_dev.h" - -/*---------------------------------------- - DEFINES ------------------------------------------*/ - -#define SEP_RAR_IO_MEM_REGION_SIZE 0x40000 - -/*-------------------------------------------- - GLOBAL variables ---------------------------------------------*/ - -/* Keep this a single static object for now to keep the conversion easy */ - -static struct sep_device *sep_dev; - -/** - * sep_dump_message - dump the message that is pending - * @sep: SEP device - */ -static void sep_dump_message(struct sep_device *sep) -{ - int count; - u32 *p = sep->shared_addr; - for (count = 0; count < 12 * 4; count += 4) - dev_dbg(&sep->pdev->dev, "Word %d of the message is %x\n", - count, *p++); -} - -/** - * sep_map_and_alloc_shared_area - allocate shared block - * @sep: security processor - * @size: size of shared area - */ -static int sep_map_and_alloc_shared_area(struct sep_device *sep) -{ - sep->shared_addr = dma_alloc_coherent(&sep->pdev->dev, - sep->shared_size, - &sep->shared_bus, GFP_KERNEL); - - if (!sep->shared_addr) { - dev_warn(&sep->pdev->dev, - "shared memory dma_alloc_coherent failed\n"); - return -ENOMEM; - } - dev_dbg(&sep->pdev->dev, - "shared_addr %zx bytes @%p (bus %llx)\n", - sep->shared_size, sep->shared_addr, - (unsigned long long)sep->shared_bus); - return 0; -} - -/** - * sep_unmap_and_free_shared_area - free shared block - * @sep: security processor - */ -static void sep_unmap_and_free_shared_area(struct sep_device *sep) -{ - dma_free_coherent(&sep->pdev->dev, sep->shared_size, - sep->shared_addr, sep->shared_bus); -} - -/** - * sep_shared_bus_to_virt - convert bus/virt addresses - * @sep: pointer to struct sep_device - * @bus_address: address to convert - * - * Returns virtual address inside the shared area according - * to the bus address. - */ -static void *sep_shared_bus_to_virt(struct sep_device *sep, - dma_addr_t bus_address) -{ - return sep->shared_addr + (bus_address - sep->shared_bus); -} - -/** - * open function for the singleton driver - * @inode_ptr struct inode * - * @file_ptr struct file * - * - * Called when the user opens the singleton device interface - */ -static int sep_singleton_open(struct inode *inode_ptr, struct file *file_ptr) -{ - struct sep_device *sep; - - /* - * Get the SEP device structure and use it for the - * private_data field in filp for other methods - */ - sep = sep_dev; - - file_ptr->private_data = sep; - - if (test_and_set_bit(0, &sep->singleton_access_flag)) - return -EBUSY; - return 0; -} - -/** - * sep_open - device open method - * @inode: inode of SEP device - * @filp: file handle to SEP device - * - * Open method for the SEP device. Called when userspace opens - * the SEP device node. - * - * Returns zero on success otherwise an error code. - */ -static int sep_open(struct inode *inode, struct file *filp) -{ - struct sep_device *sep; - - /* - * Get the SEP device structure and use it for the - * private_data field in filp for other methods - */ - sep = sep_dev; - filp->private_data = sep; - - /* Anyone can open; locking takes place at transaction level */ - return 0; -} - -/** - * sep_singleton_release - close a SEP singleton device - * @inode: inode of SEP device - * @filp: file handle being closed - * - * Called on the final close of a SEP device. As the open protects against - * multiple simultaenous opens that means this method is called when the - * final reference to the open handle is dropped. - */ -static int sep_singleton_release(struct inode *inode, struct file *filp) -{ - struct sep_device *sep = filp->private_data; - - clear_bit(0, &sep->singleton_access_flag); - return 0; -} - -/** - * sep_request_daemon_open - request daemon open method - * @inode: inode of SEP device - * @filp: file handle to SEP device - * - * Open method for the SEP request daemon. Called when - * request daemon in userspace opens the SEP device node. - * - * Returns zero on success otherwise an error code. - */ -static int sep_request_daemon_open(struct inode *inode, struct file *filp) -{ - struct sep_device *sep = sep_dev; - int error = 0; - - filp->private_data = sep; - - /* There is supposed to be only one request daemon */ - if (test_and_set_bit(0, &sep->request_daemon_open)) - error = -EBUSY; - return error; -} - -/** - * sep_request_daemon_release - close a SEP daemon - * @inode: inode of SEP device - * @filp: file handle being closed - * - * Called on the final close of a SEP daemon. - */ -static int sep_request_daemon_release(struct inode *inode, struct file *filp) -{ - struct sep_device *sep = filp->private_data; - - dev_dbg(&sep->pdev->dev, "Request daemon release for pid %d\n", - current->pid); - - /* Clear the request_daemon_open flag */ - clear_bit(0, &sep->request_daemon_open); - return 0; -} - -/** - * sep_req_daemon_send_reply_command_handler - poke the SEP - * @sep: struct sep_device * - * - * This function raises interrupt to SEPm that signals that is has a - * new command from HOST - */ -static int sep_req_daemon_send_reply_command_handler(struct sep_device *sep) -{ - unsigned long lck_flags; - - sep_dump_message(sep); - - /* Counters are lockable region */ - spin_lock_irqsave(&sep->snd_rply_lck, lck_flags); - sep->send_ct++; - sep->reply_ct++; - - /* Send the interrupt to SEP */ - sep_write_reg(sep, HW_HOST_HOST_SEP_GPR2_REG_ADDR, sep->send_ct); - sep->send_ct++; - - spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); - - dev_dbg(&sep->pdev->dev, - "sep_req_daemon_send_reply send_ct %lx reply_ct %lx\n", - sep->send_ct, sep->reply_ct); - - return 0; -} - - -/** - * sep_free_dma_table_data_handler - free DMA table - * @sep: pointere to struct sep_device - * - * Handles the request to free DMA table for synchronic actions - */ -static int sep_free_dma_table_data_handler(struct sep_device *sep) -{ - int count; - int dcb_counter; - /* Pointer to the current dma_resource struct */ - struct sep_dma_resource *dma; - - for (dcb_counter = 0; dcb_counter < sep->nr_dcb_creat; dcb_counter++) { - dma = &sep->dma_res_arr[dcb_counter]; - - /* Unmap and free input map array */ - if (dma->in_map_array) { - for (count = 0; count < dma->in_num_pages; count++) { - dma_unmap_page(&sep->pdev->dev, - dma->in_map_array[count].dma_addr, - dma->in_map_array[count].size, - DMA_TO_DEVICE); - } - kfree(dma->in_map_array); - } - - /* Unmap output map array, DON'T free it yet */ - if (dma->out_map_array) { - for (count = 0; count < dma->out_num_pages; count++) { - dma_unmap_page(&sep->pdev->dev, - dma->out_map_array[count].dma_addr, - dma->out_map_array[count].size, - DMA_FROM_DEVICE); - } - kfree(dma->out_map_array); - } - - /* Free page cache for output */ - if (dma->in_page_array) { - for (count = 0; count < dma->in_num_pages; count++) { - flush_dcache_page(dma->in_page_array[count]); - page_cache_release(dma->in_page_array[count]); - } - kfree(dma->in_page_array); - } - - if (dma->out_page_array) { - for (count = 0; count < dma->out_num_pages; count++) { - if (!PageReserved(dma->out_page_array[count])) - SetPageDirty(dma->out_page_array[count]); - flush_dcache_page(dma->out_page_array[count]); - page_cache_release(dma->out_page_array[count]); - } - kfree(dma->out_page_array); - } - - /* Reset all the values */ - dma->in_page_array = NULL; - dma->out_page_array = NULL; - dma->in_num_pages = 0; - dma->out_num_pages = 0; - dma->in_map_array = NULL; - dma->out_map_array = NULL; - dma->in_map_num_entries = 0; - dma->out_map_num_entries = 0; - } - - sep->nr_dcb_creat = 0; - sep->num_lli_tables_created = 0; - - return 0; -} - -/** - * sep_request_daemon_mmap - maps the shared area to user space - * @filp: pointer to struct file - * @vma: pointer to vm_area_struct - * - * Called by the kernel when the daemon attempts an mmap() syscall - * using our handle. - */ -static int sep_request_daemon_mmap(struct file *filp, - struct vm_area_struct *vma) -{ - struct sep_device *sep = filp->private_data; - dma_addr_t bus_address; - int error = 0; - - if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) { - error = -EINVAL; - goto end_function; - } - - /* Get physical address */ - bus_address = sep->shared_bus; - - if (remap_pfn_range(vma, vma->vm_start, bus_address >> PAGE_SHIFT, - vma->vm_end - vma->vm_start, vma->vm_page_prot)) { - - dev_warn(&sep->pdev->dev, "remap_page_range failed\n"); - error = -EAGAIN; - goto end_function; - } - -end_function: - return error; -} - -/** - * sep_request_daemon_poll - poll implementation - * @sep: struct sep_device * for current SEP device - * @filp: struct file * for open file - * @wait: poll_table * for poll - * - * Called when our device is part of a poll() or select() syscall - */ -static unsigned int sep_request_daemon_poll(struct file *filp, - poll_table *wait) -{ - u32 mask = 0; - /* GPR2 register */ - u32 retval2; - unsigned long lck_flags; - struct sep_device *sep = filp->private_data; - - poll_wait(filp, &sep->event_request_daemon, wait); - - dev_dbg(&sep->pdev->dev, "daemon poll: send_ct is %lx reply ct is %lx\n", - sep->send_ct, sep->reply_ct); - - spin_lock_irqsave(&sep->snd_rply_lck, lck_flags); - /* Check if the data is ready */ - if (sep->send_ct == sep->reply_ct) { - spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); - - retval2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); - dev_dbg(&sep->pdev->dev, - "daemon poll: data check (GPR2) is %x\n", retval2); - - /* Check if PRINT request */ - if ((retval2 >> 30) & 0x1) { - dev_dbg(&sep->pdev->dev, "daemon poll: PRINTF request in\n"); - mask |= POLLIN; - goto end_function; - } - /* Check if NVS request */ - if (retval2 >> 31) { - dev_dbg(&sep->pdev->dev, "daemon poll: NVS request in\n"); - mask |= POLLPRI | POLLWRNORM; - } - } else { - spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); - dev_dbg(&sep->pdev->dev, - "daemon poll: no reply received; returning 0\n"); - mask = 0; - } -end_function: - return mask; -} - -/** - * sep_release - close a SEP device - * @inode: inode of SEP device - * @filp: file handle being closed - * - * Called on the final close of a SEP device. - */ -static int sep_release(struct inode *inode, struct file *filp) -{ - struct sep_device *sep = filp->private_data; - - dev_dbg(&sep->pdev->dev, "Release for pid %d\n", current->pid); - - mutex_lock(&sep->sep_mutex); - /* Is this the process that has a transaction open? - * If so, lets reset pid_doing_transaction to 0 and - * clear the in use flags, and then wake up sep_event - * so that other processes can do transactions - */ - if (sep->pid_doing_transaction == current->pid) { - clear_bit(SEP_MMAP_LOCK_BIT, &sep->in_use_flags); - clear_bit(SEP_SEND_MSG_LOCK_BIT, &sep->in_use_flags); - sep_free_dma_table_data_handler(sep); - wake_up(&sep->event); - sep->pid_doing_transaction = 0; - } - - mutex_unlock(&sep->sep_mutex); - return 0; -} - -/** - * sep_mmap - maps the shared area to user space - * @filp: pointer to struct file - * @vma: pointer to vm_area_struct - * - * Called on an mmap of our space via the normal SEP device - */ -static int sep_mmap(struct file *filp, struct vm_area_struct *vma) -{ - dma_addr_t bus_addr; - struct sep_device *sep = filp->private_data; - unsigned long error = 0; - - /* Set the transaction busy (own the device) */ - wait_event_interruptible(sep->event, - test_and_set_bit(SEP_MMAP_LOCK_BIT, - &sep->in_use_flags) == 0); - - if (signal_pending(current)) { - error = -EINTR; - goto end_function_with_error; - } - /* - * The pid_doing_transaction indicates that this process - * now owns the facilities to performa a transaction with - * the SEP. While this process is performing a transaction, - * no other process who has the SEP device open can perform - * any transactions. This method allows more than one process - * to have the device open at any given time, which provides - * finer granularity for device utilization by multiple - * processes. - */ - mutex_lock(&sep->sep_mutex); - sep->pid_doing_transaction = current->pid; - mutex_unlock(&sep->sep_mutex); - - /* Zero the pools and the number of data pool alocation pointers */ - sep->data_pool_bytes_allocated = 0; - sep->num_of_data_allocations = 0; - - /* - * Check that the size of the mapped range is as the size of the message - * shared area - */ - if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) { - error = -EINVAL; - goto end_function_with_error; - } - - dev_dbg(&sep->pdev->dev, "shared_addr is %p\n", sep->shared_addr); - - /* Get bus address */ - bus_addr = sep->shared_bus; - - if (remap_pfn_range(vma, vma->vm_start, bus_addr >> PAGE_SHIFT, - vma->vm_end - vma->vm_start, vma->vm_page_prot)) { - dev_warn(&sep->pdev->dev, "remap_page_range failed\n"); - error = -EAGAIN; - goto end_function_with_error; - } - goto end_function; - -end_function_with_error: - /* Clear the bit */ - clear_bit(SEP_MMAP_LOCK_BIT, &sep->in_use_flags); - mutex_lock(&sep->sep_mutex); - sep->pid_doing_transaction = 0; - mutex_unlock(&sep->sep_mutex); - - /* Raise event for stuck contextes */ - - wake_up(&sep->event); - -end_function: - return error; -} - -/** - * sep_poll - poll handler - * @filp: pointer to struct file - * @wait: pointer to poll_table - * - * Called by the OS when the kernel is asked to do a poll on - * a SEP file handle. - */ -static unsigned int sep_poll(struct file *filp, poll_table *wait) -{ - u32 mask = 0; - u32 retval = 0; - u32 retval2 = 0; - unsigned long lck_flags; - - struct sep_device *sep = filp->private_data; - - /* Am I the process that owns the transaction? */ - mutex_lock(&sep->sep_mutex); - if (current->pid != sep->pid_doing_transaction) { - dev_dbg(&sep->pdev->dev, "poll; wrong pid\n"); - mask = POLLERR; - mutex_unlock(&sep->sep_mutex); - goto end_function; - } - mutex_unlock(&sep->sep_mutex); - - /* Check if send command or send_reply were activated previously */ - if (!test_bit(SEP_SEND_MSG_LOCK_BIT, &sep->in_use_flags)) { - mask = POLLERR; - goto end_function; - } - - /* Add the event to the polling wait table */ - dev_dbg(&sep->pdev->dev, "poll: calling wait sep_event\n"); - - poll_wait(filp, &sep->event, wait); - - dev_dbg(&sep->pdev->dev, "poll: send_ct is %lx reply ct is %lx\n", - sep->send_ct, sep->reply_ct); - - /* Check if error occurred during poll */ - retval2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); - if (retval2 != 0x0) { - dev_warn(&sep->pdev->dev, "poll; poll error %x\n", retval2); - mask |= POLLERR; - goto end_function; - } - - spin_lock_irqsave(&sep->snd_rply_lck, lck_flags); - - if (sep->send_ct == sep->reply_ct) { - spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); - retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); - dev_dbg(&sep->pdev->dev, "poll: data ready check (GPR2) %x\n", - retval); - - /* Check if printf request */ - if ((retval >> 30) & 0x1) { - dev_dbg(&sep->pdev->dev, "poll: SEP printf request\n"); - wake_up(&sep->event_request_daemon); - goto end_function; - } - - /* Check if the this is SEP reply or request */ - if (retval >> 31) { - dev_dbg(&sep->pdev->dev, "poll: SEP request\n"); - wake_up(&sep->event_request_daemon); - } else { - dev_dbg(&sep->pdev->dev, "poll: normal return\n"); - /* In case it is again by send_reply_comand */ - clear_bit(SEP_SEND_MSG_LOCK_BIT, &sep->in_use_flags); - sep_dump_message(sep); - dev_dbg(&sep->pdev->dev, - "poll; SEP reply POLLIN | POLLRDNORM\n"); - mask |= POLLIN | POLLRDNORM; - } - } else { - spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); - dev_dbg(&sep->pdev->dev, - "poll; no reply received; returning mask of 0\n"); - mask = 0; - } - -end_function: - return mask; -} - -/** - * sep_time_address - address in SEP memory of time - * @sep: SEP device we want the address from - * - * Return the address of the two dwords in memory used for time - * setting. - */ -static u32 *sep_time_address(struct sep_device *sep) -{ - return sep->shared_addr + SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES; -} - -/** - * sep_set_time - set the SEP time - * @sep: the SEP we are setting the time for - * - * Calculates time and sets it at the predefined address. - * Called with the SEP mutex held. - */ -static unsigned long sep_set_time(struct sep_device *sep) -{ - struct timeval time; - u32 *time_addr; /* Address of time as seen by the kernel */ - - - do_gettimeofday(&time); - - /* Set value in the SYSTEM MEMORY offset */ - time_addr = sep_time_address(sep); - - time_addr[0] = SEP_TIME_VAL_TOKEN; - time_addr[1] = time.tv_sec; - - dev_dbg(&sep->pdev->dev, "time.tv_sec is %lu\n", time.tv_sec); - dev_dbg(&sep->pdev->dev, "time_addr is %p\n", time_addr); - dev_dbg(&sep->pdev->dev, "sep->shared_addr is %p\n", sep->shared_addr); - - return time.tv_sec; -} - -/** - * sep_set_caller_id_handler - insert caller id entry - * @sep: SEP device - * @arg: pointer to struct caller_id_struct - * - * Inserts the data into the caller id table. Note that this function - * falls under the ioctl lock - */ -static int sep_set_caller_id_handler(struct sep_device *sep, unsigned long arg) -{ - void __user *hash; - int error = 0; - int i; - struct caller_id_struct command_args; - - for (i = 0; i < SEP_CALLER_ID_TABLE_NUM_ENTRIES; i++) { - if (sep->caller_id_table[i].pid == 0) - break; - } - - if (i == SEP_CALLER_ID_TABLE_NUM_ENTRIES) { - dev_dbg(&sep->pdev->dev, "no more caller id entries left\n"); - dev_dbg(&sep->pdev->dev, "maximum number is %d\n", - SEP_CALLER_ID_TABLE_NUM_ENTRIES); - error = -EUSERS; - goto end_function; - } - - /* Copy the data */ - if (copy_from_user(&command_args, (void __user *)arg, - sizeof(command_args))) { - error = -EFAULT; - goto end_function; - } - - hash = (void __user *)(unsigned long)command_args.callerIdAddress; - - if (!command_args.pid || !command_args.callerIdSizeInBytes) { - error = -EINVAL; - goto end_function; - } - - dev_dbg(&sep->pdev->dev, "pid is %x\n", command_args.pid); - dev_dbg(&sep->pdev->dev, "callerIdSizeInBytes is %x\n", - command_args.callerIdSizeInBytes); - - if (command_args.callerIdSizeInBytes > - SEP_CALLER_ID_HASH_SIZE_IN_BYTES) { - error = -EMSGSIZE; - goto end_function; - } - - sep->caller_id_table[i].pid = command_args.pid; - - if (copy_from_user(sep->caller_id_table[i].callerIdHash, - hash, command_args.callerIdSizeInBytes)) - error = -EFAULT; -end_function: - return error; -} - -/** - * sep_set_current_caller_id - set the caller id - * @sep: pointer to struct_sep_device - * - * Set the caller ID (if it exists) to the SEP. Note that this - * function falls under the ioctl lock - */ -static int sep_set_current_caller_id(struct sep_device *sep) -{ - int i; - u32 *hash_buf_ptr; - - /* Zero the previous value */ - memset(sep->shared_addr + SEP_CALLER_ID_OFFSET_BYTES, - 0, SEP_CALLER_ID_HASH_SIZE_IN_BYTES); - - for (i = 0; i < SEP_CALLER_ID_TABLE_NUM_ENTRIES; i++) { - if (sep->caller_id_table[i].pid == current->pid) { - dev_dbg(&sep->pdev->dev, "Caller Id found\n"); - - memcpy(sep->shared_addr + SEP_CALLER_ID_OFFSET_BYTES, - (void *)(sep->caller_id_table[i].callerIdHash), - SEP_CALLER_ID_HASH_SIZE_IN_BYTES); - break; - } - } - /* Ensure data is in little endian */ - hash_buf_ptr = (u32 *)sep->shared_addr + - SEP_CALLER_ID_OFFSET_BYTES; - - for (i = 0; i < SEP_CALLER_ID_HASH_SIZE_IN_WORDS; i++) - hash_buf_ptr[i] = cpu_to_le32(hash_buf_ptr[i]); - - return 0; -} - -/** - * sep_send_command_handler - kick off a command - * @sep: SEP being signalled - * - * This function raises interrupt to SEP that signals that is has a new - * command from the host - * - * Note that this function does fall under the ioctl lock - */ -static int sep_send_command_handler(struct sep_device *sep) -{ - unsigned long lck_flags; - int error = 0; - - if (test_and_set_bit(SEP_SEND_MSG_LOCK_BIT, &sep->in_use_flags)) { - error = -EPROTO; - goto end_function; - } - sep_set_time(sep); - - sep_set_current_caller_id(sep); - - sep_dump_message(sep); - - /* Update counter */ - spin_lock_irqsave(&sep->snd_rply_lck, lck_flags); - sep->send_ct++; - spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); - - dev_dbg(&sep->pdev->dev, - "sep_send_command_handler send_ct %lx reply_ct %lx\n", - sep->send_ct, sep->reply_ct); - - /* Send interrupt to SEP */ - sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2); - -end_function: - return error; -} - -/** - * sep_allocate_data_pool_memory_handler -allocate pool memory - * @sep: pointer to struct sep_device - * @arg: pointer to struct alloc_struct - * - * This function handles the allocate data pool memory request - * This function returns calculates the bus address of the - * allocated memory, and the offset of this area from the mapped address. - * Therefore, the FVOs in user space can calculate the exact virtual - * address of this allocated memory - */ -static int sep_allocate_data_pool_memory_handler(struct sep_device *sep, - unsigned long arg) -{ - int error = 0; - struct alloc_struct command_args; - - /* Holds the allocated buffer address in the system memory pool */ - u32 *token_addr; - - if (copy_from_user(&command_args, (void __user *)arg, - sizeof(struct alloc_struct))) { - error = -EFAULT; - goto end_function; - } - - /* Allocate memory */ - if ((sep->data_pool_bytes_allocated + command_args.num_bytes) > - SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) { - error = -ENOMEM; - goto end_function; - } - - dev_dbg(&sep->pdev->dev, - "data pool bytes_allocated: %x\n", (int)sep->data_pool_bytes_allocated); - dev_dbg(&sep->pdev->dev, - "offset: %x\n", SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES); - /* Set the virtual and bus address */ - command_args.offset = SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + - sep->data_pool_bytes_allocated; - - /* Place in the shared area that is known by the SEP */ - token_addr = (u32 *)(sep->shared_addr + - SEP_DRIVER_DATA_POOL_ALLOCATION_OFFSET_IN_BYTES + - (sep->num_of_data_allocations)*2*sizeof(u32)); - - token_addr[0] = SEP_DATA_POOL_POINTERS_VAL_TOKEN; - token_addr[1] = (u32)sep->shared_bus + - SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + - sep->data_pool_bytes_allocated; - - /* Write the memory back to the user space */ - error = copy_to_user((void *)arg, (void *)&command_args, - sizeof(struct alloc_struct)); - if (error) { - error = -EFAULT; - goto end_function; - } - - /* Update the allocation */ - sep->data_pool_bytes_allocated += command_args.num_bytes; - sep->num_of_data_allocations += 1; - -end_function: - return error; -} - -/** - * sep_lock_kernel_pages - map kernel pages for DMA - * @sep: pointer to struct sep_device - * @kernel_virt_addr: address of data buffer in kernel - * @data_size: size of data - * @lli_array_ptr: lli array - * @in_out_flag: input into device or output from device - * - * This function locks all the physical pages of the kernel virtual buffer - * and construct a basic lli array, where each entry holds the physical - * page address and the size that application data holds in this page - * This function is used only during kernel crypto mod calls from within - * the kernel (when ioctl is not used) - */ -static int sep_lock_kernel_pages(struct sep_device *sep, - unsigned long kernel_virt_addr, - u32 data_size, - struct sep_lli_entry **lli_array_ptr, - int in_out_flag) - -{ - int error = 0; - /* Array of lli */ - struct sep_lli_entry *lli_array; - /* Map array */ - struct sep_dma_map *map_array; - - dev_dbg(&sep->pdev->dev, "lock kernel pages kernel_virt_addr is %08lx\n", - (unsigned long)kernel_virt_addr); - dev_dbg(&sep->pdev->dev, "data_size is %x\n", data_size); - - lli_array = kmalloc(sizeof(struct sep_lli_entry), GFP_ATOMIC); - if (!lli_array) { - error = -ENOMEM; - goto end_function; - } - map_array = kmalloc(sizeof(struct sep_dma_map), GFP_ATOMIC); - if (!map_array) { - error = -ENOMEM; - goto end_function_with_error; - } - - map_array[0].dma_addr = - dma_map_single(&sep->pdev->dev, (void *)kernel_virt_addr, - data_size, DMA_BIDIRECTIONAL); - map_array[0].size = data_size; - - - /* - * Set the start address of the first page - app data may start not at - * the beginning of the page - */ - lli_array[0].bus_address = (u32)map_array[0].dma_addr; - lli_array[0].block_size = map_array[0].size; - - dev_dbg(&sep->pdev->dev, - "lli_array[0].bus_address is %08lx, lli_array[0].block_size is %x\n", - (unsigned long)lli_array[0].bus_address, - lli_array[0].block_size); - - /* Set the output parameters */ - if (in_out_flag == SEP_DRIVER_IN_FLAG) { - *lli_array_ptr = lli_array; - sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages = 1; - sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = NULL; - sep->dma_res_arr[sep->nr_dcb_creat].in_map_array = map_array; - sep->dma_res_arr[sep->nr_dcb_creat].in_map_num_entries = 1; - } else { - *lli_array_ptr = lli_array; - sep->dma_res_arr[sep->nr_dcb_creat].out_num_pages = 1; - sep->dma_res_arr[sep->nr_dcb_creat].out_page_array = NULL; - sep->dma_res_arr[sep->nr_dcb_creat].out_map_array = map_array; - sep->dma_res_arr[sep->nr_dcb_creat].out_map_num_entries = 1; - } - goto end_function; - -end_function_with_error: - kfree(lli_array); - -end_function: - return error; -} - -/** - * sep_lock_user_pages - lock and map user pages for DMA - * @sep: pointer to struct sep_device - * @app_virt_addr: user memory data buffer - * @data_size: size of data buffer - * @lli_array_ptr: lli array - * @in_out_flag: input or output to device - * - * This function locks all the physical pages of the application - * virtual buffer and construct a basic lli array, where each entry - * holds the physical page address and the size that application - * data holds in this physical pages - */ -static int sep_lock_user_pages(struct sep_device *sep, - u32 app_virt_addr, - u32 data_size, - struct sep_lli_entry **lli_array_ptr, - int in_out_flag) - -{ - int error = 0; - u32 count; - int result; - /* The the page of the end address of the user space buffer */ - u32 end_page; - /* The page of the start address of the user space buffer */ - u32 start_page; - /* The range in pages */ - u32 num_pages; - /* Array of pointers to page */ - struct page **page_array; - /* Array of lli */ - struct sep_lli_entry *lli_array; - /* Map array */ - struct sep_dma_map *map_array; - /* Direction of the DMA mapping for locked pages */ - enum dma_data_direction dir; - - /* Set start and end pages and num pages */ - end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT; - start_page = app_virt_addr >> PAGE_SHIFT; - num_pages = end_page - start_page + 1; - - dev_dbg(&sep->pdev->dev, "lock user pages app_virt_addr is %x\n", app_virt_addr); - dev_dbg(&sep->pdev->dev, "data_size is %x\n", data_size); - dev_dbg(&sep->pdev->dev, "start_page is %x\n", start_page); - dev_dbg(&sep->pdev->dev, "end_page is %x\n", end_page); - dev_dbg(&sep->pdev->dev, "num_pages is %x\n", num_pages); - - /* Allocate array of pages structure pointers */ - page_array = kmalloc(sizeof(struct page *) * num_pages, GFP_ATOMIC); - if (!page_array) { - error = -ENOMEM; - goto end_function; - } - map_array = kmalloc(sizeof(struct sep_dma_map) * num_pages, GFP_ATOMIC); - if (!map_array) { - dev_warn(&sep->pdev->dev, "kmalloc for map_array failed\n"); - error = -ENOMEM; - goto end_function_with_error1; - } - - lli_array = kmalloc(sizeof(struct sep_lli_entry) * num_pages, - GFP_ATOMIC); - - if (!lli_array) { - dev_warn(&sep->pdev->dev, "kmalloc for lli_array failed\n"); - error = -ENOMEM; - goto end_function_with_error2; - } - - /* Convert the application virtual address into a set of physical */ - down_read(¤t->mm->mmap_sem); - result = get_user_pages(current, current->mm, app_virt_addr, - num_pages, - ((in_out_flag == SEP_DRIVER_IN_FLAG) ? 0 : 1), - 0, page_array, NULL); - - up_read(¤t->mm->mmap_sem); - - /* Check the number of pages locked - if not all then exit with error */ - if (result != num_pages) { - dev_warn(&sep->pdev->dev, - "not all pages locked by get_user_pages\n"); - error = -ENOMEM; - goto end_function_with_error3; - } - - dev_dbg(&sep->pdev->dev, "get_user_pages succeeded\n"); - - /* Set direction */ - if (in_out_flag == SEP_DRIVER_IN_FLAG) - dir = DMA_TO_DEVICE; - else - dir = DMA_FROM_DEVICE; - - /* - * Fill the array using page array data and - * map the pages - this action will also flush the cache as needed - */ - for (count = 0; count < num_pages; count++) { - /* Fill the map array */ - map_array[count].dma_addr = - dma_map_page(&sep->pdev->dev, page_array[count], - 0, PAGE_SIZE, /*dir*/DMA_BIDIRECTIONAL); - - map_array[count].size = PAGE_SIZE; - - /* Fill the lli array entry */ - lli_array[count].bus_address = (u32)map_array[count].dma_addr; - lli_array[count].block_size = PAGE_SIZE; - - dev_warn(&sep->pdev->dev, "lli_array[%x].bus_address is %08lx, lli_array[%x].block_size is %x\n", - count, (unsigned long)lli_array[count].bus_address, - count, lli_array[count].block_size); - } - - /* Check the offset for the first page */ - lli_array[0].bus_address = - lli_array[0].bus_address + (app_virt_addr & (~PAGE_MASK)); - - /* Check that not all the data is in the first page only */ - if ((PAGE_SIZE - (app_virt_addr & (~PAGE_MASK))) >= data_size) - lli_array[0].block_size = data_size; - else - lli_array[0].block_size = - PAGE_SIZE - (app_virt_addr & (~PAGE_MASK)); - - dev_dbg(&sep->pdev->dev, - "lli_array[0].bus_address is %08lx, lli_array[0].block_size is %x\n", - (unsigned long)lli_array[count].bus_address, - lli_array[count].block_size); - - /* Check the size of the last page */ - if (num_pages > 1) { - lli_array[num_pages - 1].block_size = - (app_virt_addr + data_size) & (~PAGE_MASK); - if (lli_array[num_pages - 1].block_size == 0) - lli_array[num_pages - 1].block_size = PAGE_SIZE; - - dev_warn(&sep->pdev->dev, - "lli_array[%x].bus_address is " - "%08lx, lli_array[%x].block_size is %x\n", - num_pages - 1, - (unsigned long)lli_array[num_pages - 1].bus_address, - num_pages - 1, - lli_array[num_pages - 1].block_size); - } - - /* Set output params according to the in_out flag */ - if (in_out_flag == SEP_DRIVER_IN_FLAG) { - *lli_array_ptr = lli_array; - sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages = num_pages; - sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = page_array; - sep->dma_res_arr[sep->nr_dcb_creat].in_map_array = map_array; - sep->dma_res_arr[sep->nr_dcb_creat].in_map_num_entries = - num_pages; - } else { - *lli_array_ptr = lli_array; - sep->dma_res_arr[sep->nr_dcb_creat].out_num_pages = num_pages; - sep->dma_res_arr[sep->nr_dcb_creat].out_page_array = - page_array; - sep->dma_res_arr[sep->nr_dcb_creat].out_map_array = map_array; - sep->dma_res_arr[sep->nr_dcb_creat].out_map_num_entries = - num_pages; - } - goto end_function; - -end_function_with_error3: - /* Free lli array */ - kfree(lli_array); - -end_function_with_error2: - kfree(map_array); - -end_function_with_error1: - /* Free page array */ - kfree(page_array); - -end_function: - return error; -} - -/** - * u32 sep_calculate_lli_table_max_size - size the LLI table - * @sep: pointer to struct sep_device - * @lli_in_array_ptr - * @num_array_entries - * @last_table_flag - * - * This function calculates the size of data that can be inserted into - * the lli table from this array, such that either the table is full - * (all entries are entered), or there are no more entries in the - * lli array - */ -static u32 sep_calculate_lli_table_max_size(struct sep_device *sep, - struct sep_lli_entry *lli_in_array_ptr, - u32 num_array_entries, - u32 *last_table_flag) -{ - u32 counter; - /* Table data size */ - u32 table_data_size = 0; - /* Data size for the next table */ - u32 next_table_data_size; - - *last_table_flag = 0; - - /* - * Calculate the data in the out lli table till we fill the whole - * table or till the data has ended - */ - for (counter = 0; - (counter < (SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP - 1)) && - (counter < num_array_entries); counter++) - table_data_size += lli_in_array_ptr[counter].block_size; - - /* - * Check if we reached the last entry, - * meaning this ia the last table to build, - * and no need to check the block alignment - */ - if (counter == num_array_entries) { - /* Set the last table flag */ - *last_table_flag = 1; - goto end_function; - } - - /* - * Calculate the data size of the next table. - * Stop if no entries left or if data size is more the DMA restriction - */ - next_table_data_size = 0; - for (; counter < num_array_entries; counter++) { - next_table_data_size += lli_in_array_ptr[counter].block_size; - if (next_table_data_size >= SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE) - break; - } - - /* - * Check if the next table data size is less then DMA rstriction. - * if it is - recalculate the current table size, so that the next - * table data size will be adaquete for DMA - */ - if (next_table_data_size && - next_table_data_size < SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE) - - table_data_size -= (SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE - - next_table_data_size); - -end_function: - return table_data_size; -} - -/** - * sep_build_lli_table - build an lli array for the given table - * @sep: pointer to struct sep_device - * @lli_array_ptr: pointer to lli array - * @lli_table_ptr: pointer to lli table - * @num_processed_entries_ptr: pointer to number of entries - * @num_table_entries_ptr: pointer to number of tables - * @table_data_size: total data size - * - * Builds ant lli table from the lli_array according to - * the given size of data - */ -static void sep_build_lli_table(struct sep_device *sep, - struct sep_lli_entry *lli_array_ptr, - struct sep_lli_entry *lli_table_ptr, - u32 *num_processed_entries_ptr, - u32 *num_table_entries_ptr, - u32 table_data_size) -{ - /* Current table data size */ - u32 curr_table_data_size; - /* Counter of lli array entry */ - u32 array_counter; - - /* Init current table data size and lli array entry counter */ - curr_table_data_size = 0; - array_counter = 0; - *num_table_entries_ptr = 1; - - dev_dbg(&sep->pdev->dev, "build lli table table_data_size is %x\n", table_data_size); - - /* Fill the table till table size reaches the needed amount */ - while (curr_table_data_size < table_data_size) { - /* Update the number of entries in table */ - (*num_table_entries_ptr)++; - - lli_table_ptr->bus_address = - cpu_to_le32(lli_array_ptr[array_counter].bus_address); - - lli_table_ptr->block_size = - cpu_to_le32(lli_array_ptr[array_counter].block_size); - - curr_table_data_size += lli_array_ptr[array_counter].block_size; - - dev_dbg(&sep->pdev->dev, "lli_table_ptr is %p\n", - lli_table_ptr); - dev_dbg(&sep->pdev->dev, "lli_table_ptr->bus_address is %08lx\n", - (unsigned long)lli_table_ptr->bus_address); - dev_dbg(&sep->pdev->dev, "lli_table_ptr->block_size is %x\n", - lli_table_ptr->block_size); - - /* Check for overflow of the table data */ - if (curr_table_data_size > table_data_size) { - dev_dbg(&sep->pdev->dev, - "curr_table_data_size too large\n"); - - /* Update the size of block in the table */ - lli_table_ptr->block_size -= - cpu_to_le32((curr_table_data_size - table_data_size)); - - /* Update the physical address in the lli array */ - lli_array_ptr[array_counter].bus_address += - cpu_to_le32(lli_table_ptr->block_size); - - /* Update the block size left in the lli array */ - lli_array_ptr[array_counter].block_size = - (curr_table_data_size - table_data_size); - } else - /* Advance to the next entry in the lli_array */ - array_counter++; - - dev_dbg(&sep->pdev->dev, - "lli_table_ptr->bus_address is %08lx\n", - (unsigned long)lli_table_ptr->bus_address); - dev_dbg(&sep->pdev->dev, - "lli_table_ptr->block_size is %x\n", - lli_table_ptr->block_size); - - /* Move to the next entry in table */ - lli_table_ptr++; - } - - /* Set the info entry to default */ - lli_table_ptr->bus_address = 0xffffffff; - lli_table_ptr->block_size = 0; - - /* Set the output parameter */ - *num_processed_entries_ptr += array_counter; - -} - -/** - * sep_shared_area_virt_to_bus - map shared area to bus address - * @sep: pointer to struct sep_device - * @virt_address: virtual address to convert - * - * This functions returns the physical address inside shared area according - * to the virtual address. It can be either on the externa RAM device - * (ioremapped), or on the system RAM - * This implementation is for the external RAM - */ -static dma_addr_t sep_shared_area_virt_to_bus(struct sep_device *sep, - void *virt_address) -{ - dev_dbg(&sep->pdev->dev, "sh virt to phys v %p\n", virt_address); - dev_dbg(&sep->pdev->dev, "sh virt to phys p %08lx\n", - (unsigned long) - sep->shared_bus + (virt_address - sep->shared_addr)); - - return sep->shared_bus + (size_t)(virt_address - sep->shared_addr); -} - -/** - * sep_shared_area_bus_to_virt - map shared area bus address to kernel - * @sep: pointer to struct sep_device - * @bus_address: bus address to convert - * - * This functions returns the virtual address inside shared area - * according to the physical address. It can be either on the - * externa RAM device (ioremapped), or on the system RAM - * This implementation is for the external RAM - */ -static void *sep_shared_area_bus_to_virt(struct sep_device *sep, - dma_addr_t bus_address) -{ - dev_dbg(&sep->pdev->dev, "shared bus to virt b=%lx v=%lx\n", - (unsigned long)bus_address, (unsigned long)(sep->shared_addr + - (size_t)(bus_address - sep->shared_bus))); - - return sep->shared_addr + (size_t)(bus_address - sep->shared_bus); -} - -/** - * sep_debug_print_lli_tables - dump LLI table - * @sep: pointer to struct sep_device - * @lli_table_ptr: pointer to sep_lli_entry - * @num_table_entries: number of entries - * @table_data_size: total data size - * - * Walk the the list of the print created tables and print all the data - */ -static void sep_debug_print_lli_tables(struct sep_device *sep, - struct sep_lli_entry *lli_table_ptr, - unsigned long num_table_entries, - unsigned long table_data_size) -{ - unsigned long table_count = 1; - unsigned long entries_count = 0; - - dev_dbg(&sep->pdev->dev, "sep_debug_print_lli_tables start\n"); - - while ((unsigned long) lli_table_ptr->bus_address != 0xffffffff) { - dev_dbg(&sep->pdev->dev, - "lli table %08lx, table_data_size is %lu\n", - table_count, table_data_size); - dev_dbg(&sep->pdev->dev, "num_table_entries is %lu\n", - num_table_entries); - - /* Print entries of the table (without info entry) */ - for (entries_count = 0; entries_count < num_table_entries; - entries_count++, lli_table_ptr++) { - - dev_dbg(&sep->pdev->dev, - "lli_table_ptr address is %08lx\n", - (unsigned long) lli_table_ptr); - - dev_dbg(&sep->pdev->dev, - "phys address is %08lx block size is %x\n", - (unsigned long)lli_table_ptr->bus_address, - lli_table_ptr->block_size); - } - /* Point to the info entry */ - lli_table_ptr--; - - dev_dbg(&sep->pdev->dev, - "phys lli_table_ptr->block_size is %x\n", - lli_table_ptr->block_size); - - dev_dbg(&sep->pdev->dev, - "phys lli_table_ptr->physical_address is %08lu\n", - (unsigned long)lli_table_ptr->bus_address); - - - table_data_size = lli_table_ptr->block_size & 0xffffff; - num_table_entries = (lli_table_ptr->block_size >> 24) & 0xff; - - dev_dbg(&sep->pdev->dev, - "phys table_data_size is %lu num_table_entries is" - " %lu bus_address is%lu\n", table_data_size, - num_table_entries, (unsigned long)lli_table_ptr->bus_address); - - if ((unsigned long)lli_table_ptr->bus_address != 0xffffffff) - lli_table_ptr = (struct sep_lli_entry *) - sep_shared_bus_to_virt(sep, - (unsigned long)lli_table_ptr->bus_address); - - table_count++; - } - dev_dbg(&sep->pdev->dev, "sep_debug_print_lli_tables end\n"); -} - - -/** - * sep_prepare_empty_lli_table - create a blank LLI table - * @sep: pointer to struct sep_device - * @lli_table_addr_ptr: pointer to lli table - * @num_entries_ptr: pointer to number of entries - * @table_data_size_ptr: point to table data size - * - * This function creates empty lli tables when there is no data - */ -static void sep_prepare_empty_lli_table(struct sep_device *sep, - dma_addr_t *lli_table_addr_ptr, - u32 *num_entries_ptr, - u32 *table_data_size_ptr) -{ - struct sep_lli_entry *lli_table_ptr; - - /* Find the area for new table */ - lli_table_ptr = - (struct sep_lli_entry *)(sep->shared_addr + - SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + - sep->num_lli_tables_created * sizeof(struct sep_lli_entry) * - SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); - - lli_table_ptr->bus_address = 0; - lli_table_ptr->block_size = 0; - - lli_table_ptr++; - lli_table_ptr->bus_address = 0xFFFFFFFF; - lli_table_ptr->block_size = 0; - - /* Set the output parameter value */ - *lli_table_addr_ptr = sep->shared_bus + - SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + - sep->num_lli_tables_created * - sizeof(struct sep_lli_entry) * - SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; - - /* Set the num of entries and table data size for empty table */ - *num_entries_ptr = 2; - *table_data_size_ptr = 0; - - /* Update the number of created tables */ - sep->num_lli_tables_created++; -} - -/** - * sep_prepare_input_dma_table - prepare input DMA mappings - * @sep: pointer to struct sep_device - * @data_size: - * @block_size: - * @lli_table_ptr: - * @num_entries_ptr: - * @table_data_size_ptr: - * @is_kva: set for kernel data (kernel cryptio call) - * - * This function prepares only input DMA table for synhronic symmetric - * operations (HASH) - * Note that all bus addresses that are passed to the SEP - * are in 32 bit format; the SEP is a 32 bit device - */ -static int sep_prepare_input_dma_table(struct sep_device *sep, - unsigned long app_virt_addr, - u32 data_size, - u32 block_size, - dma_addr_t *lli_table_ptr, - u32 *num_entries_ptr, - u32 *table_data_size_ptr, - bool is_kva) -{ - int error = 0; - /* Pointer to the info entry of the table - the last entry */ - struct sep_lli_entry *info_entry_ptr; - /* Array of pointers to page */ - struct sep_lli_entry *lli_array_ptr; - /* Points to the first entry to be processed in the lli_in_array */ - u32 current_entry = 0; - /* Num entries in the virtual buffer */ - u32 sep_lli_entries = 0; - /* Lli table pointer */ - struct sep_lli_entry *in_lli_table_ptr; - /* The total data in one table */ - u32 table_data_size = 0; - /* Flag for last table */ - u32 last_table_flag = 0; - /* Number of entries in lli table */ - u32 num_entries_in_table = 0; - /* Next table address */ - void *lli_table_alloc_addr = 0; - - dev_dbg(&sep->pdev->dev, "prepare intput dma table data_size is %x\n", data_size); - dev_dbg(&sep->pdev->dev, "block_size is %x\n", block_size); - - /* Initialize the pages pointers */ - sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = NULL; - sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages = 0; - - /* Set the kernel address for first table to be allocated */ - lli_table_alloc_addr = (void *)(sep->shared_addr + - SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + - sep->num_lli_tables_created * sizeof(struct sep_lli_entry) * - SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); - - if (data_size == 0) { - /* Special case - create meptu table - 2 entries, zero data */ - sep_prepare_empty_lli_table(sep, lli_table_ptr, - num_entries_ptr, table_data_size_ptr); - goto update_dcb_counter; - } - - /* Check if the pages are in Kernel Virtual Address layout */ - if (is_kva == true) - /* Lock the pages in the kernel */ - error = sep_lock_kernel_pages(sep, app_virt_addr, - data_size, &lli_array_ptr, SEP_DRIVER_IN_FLAG); - else - /* - * Lock the pages of the user buffer - * and translate them to pages - */ - error = sep_lock_user_pages(sep, app_virt_addr, - data_size, &lli_array_ptr, SEP_DRIVER_IN_FLAG); - - if (error) - goto end_function; - - dev_dbg(&sep->pdev->dev, "output sep_in_num_pages is %x\n", - sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages); - - current_entry = 0; - info_entry_ptr = NULL; - - sep_lli_entries = sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages; - - /* Loop till all the entries in in array are not processed */ - while (current_entry < sep_lli_entries) { - - /* Set the new input and output tables */ - in_lli_table_ptr = - (struct sep_lli_entry *)lli_table_alloc_addr; - - lli_table_alloc_addr += sizeof(struct sep_lli_entry) * - SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; - - if (lli_table_alloc_addr > - ((void *)sep->shared_addr + - SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + - SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES)) { - - error = -ENOMEM; - goto end_function_error; - - } - - /* Update the number of created tables */ - sep->num_lli_tables_created++; - - /* Calculate the maximum size of data for input table */ - table_data_size = sep_calculate_lli_table_max_size(sep, - &lli_array_ptr[current_entry], - (sep_lli_entries - current_entry), - &last_table_flag); - - /* - * If this is not the last table - - * then align it to the block size - */ - if (!last_table_flag) - table_data_size = - (table_data_size / block_size) * block_size; - - dev_dbg(&sep->pdev->dev, "output table_data_size is %x\n", - table_data_size); - - /* Construct input lli table */ - sep_build_lli_table(sep, &lli_array_ptr[current_entry], - in_lli_table_ptr, - ¤t_entry, &num_entries_in_table, table_data_size); - - if (info_entry_ptr == NULL) { - - /* Set the output parameters to physical addresses */ - *lli_table_ptr = sep_shared_area_virt_to_bus(sep, - in_lli_table_ptr); - *num_entries_ptr = num_entries_in_table; - *table_data_size_ptr = table_data_size; - - dev_dbg(&sep->pdev->dev, - "output lli_table_in_ptr is %08lx\n", - (unsigned long)*lli_table_ptr); - - } else { - /* Update the info entry of the previous in table */ - info_entry_ptr->bus_address = - sep_shared_area_virt_to_bus(sep, - in_lli_table_ptr); - info_entry_ptr->block_size = - ((num_entries_in_table) << 24) | - (table_data_size); - } - /* Save the pointer to the info entry of the current tables */ - info_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1; - } - /* Print input tables */ - sep_debug_print_lli_tables(sep, (struct sep_lli_entry *) - sep_shared_area_bus_to_virt(sep, *lli_table_ptr), - *num_entries_ptr, *table_data_size_ptr); - /* The array of the pages */ - kfree(lli_array_ptr); - -update_dcb_counter: - /* Update DCB counter */ - sep->nr_dcb_creat++; - goto end_function; - -end_function_error: - /* Free all the allocated resources */ - kfree(sep->dma_res_arr[sep->nr_dcb_creat].in_map_array); - kfree(lli_array_ptr); - kfree(sep->dma_res_arr[sep->nr_dcb_creat].in_page_array); - -end_function: - return error; - -} -/** - * sep_construct_dma_tables_from_lli - prepare AES/DES mappings - * @sep: pointer to struct sep_device - * @lli_in_array: - * @sep_in_lli_entries: - * @lli_out_array: - * @sep_out_lli_entries - * @block_size - * @lli_table_in_ptr - * @lli_table_out_ptr - * @in_num_entries_ptr - * @out_num_entries_ptr - * @table_data_size_ptr - * - * This function creates the input and output DMA tables for - * symmetric operations (AES/DES) according to the block - * size from LLI arays - * Note that all bus addresses that are passed to the SEP - * are in 32 bit format; the SEP is a 32 bit device - */ -static int sep_construct_dma_tables_from_lli( - struct sep_device *sep, - struct sep_lli_entry *lli_in_array, - u32 sep_in_lli_entries, - struct sep_lli_entry *lli_out_array, - u32 sep_out_lli_entries, - u32 block_size, - dma_addr_t *lli_table_in_ptr, - dma_addr_t *lli_table_out_ptr, - u32 *in_num_entries_ptr, - u32 *out_num_entries_ptr, - u32 *table_data_size_ptr) -{ - /* Points to the area where next lli table can be allocated */ - void *lli_table_alloc_addr = 0; - /* Input lli table */ - struct sep_lli_entry *in_lli_table_ptr = NULL; - /* Output lli table */ - struct sep_lli_entry *out_lli_table_ptr = NULL; - /* Pointer to the info entry of the table - the last entry */ - struct sep_lli_entry *info_in_entry_ptr = NULL; - /* Pointer to the info entry of the table - the last entry */ - struct sep_lli_entry *info_out_entry_ptr = NULL; - /* Points to the first entry to be processed in the lli_in_array */ - u32 current_in_entry = 0; - /* Points to the first entry to be processed in the lli_out_array */ - u32 current_out_entry = 0; - /* Max size of the input table */ - u32 in_table_data_size = 0; - /* Max size of the output table */ - u32 out_table_data_size = 0; - /* Flag te signifies if this is the last tables build */ - u32 last_table_flag = 0; - /* The data size that should be in table */ - u32 table_data_size = 0; - /* Number of etnries in the input table */ - u32 num_entries_in_table = 0; - /* Number of etnries in the output table */ - u32 num_entries_out_table = 0; - - /* Initiate to point after the message area */ - lli_table_alloc_addr = (void *)(sep->shared_addr + - SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + - (sep->num_lli_tables_created * - (sizeof(struct sep_lli_entry) * - SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP))); - - /* Loop till all the entries in in array are not processed */ - while (current_in_entry < sep_in_lli_entries) { - /* Set the new input and output tables */ - in_lli_table_ptr = - (struct sep_lli_entry *)lli_table_alloc_addr; - - lli_table_alloc_addr += sizeof(struct sep_lli_entry) * - SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; - - /* Set the first output tables */ - out_lli_table_ptr = - (struct sep_lli_entry *)lli_table_alloc_addr; - - /* Check if the DMA table area limit was overrun */ - if ((lli_table_alloc_addr + sizeof(struct sep_lli_entry) * - SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP) > - ((void *)sep->shared_addr + - SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + - SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES)) { - - dev_warn(&sep->pdev->dev, "dma table limit overrun\n"); - return -ENOMEM; - } - - /* Update the number of the lli tables created */ - sep->num_lli_tables_created += 2; - - lli_table_alloc_addr += sizeof(struct sep_lli_entry) * - SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; - - /* Calculate the maximum size of data for input table */ - in_table_data_size = - sep_calculate_lli_table_max_size(sep, - &lli_in_array[current_in_entry], - (sep_in_lli_entries - current_in_entry), - &last_table_flag); - - /* Calculate the maximum size of data for output table */ - out_table_data_size = - sep_calculate_lli_table_max_size(sep, - &lli_out_array[current_out_entry], - (sep_out_lli_entries - current_out_entry), - &last_table_flag); - - dev_dbg(&sep->pdev->dev, - "construct tables from lli in_table_data_size is %x\n", - in_table_data_size); - - dev_dbg(&sep->pdev->dev, - "construct tables from lli out_table_data_size is %x\n", - out_table_data_size); - - table_data_size = in_table_data_size; - - if (!last_table_flag) { - /* - * If this is not the last table, - * then must check where the data is smallest - * and then align it to the block size - */ - if (table_data_size > out_table_data_size) - table_data_size = out_table_data_size; - - /* - * Now calculate the table size so that - * it will be module block size - */ - table_data_size = (table_data_size / block_size) * - block_size; - } - - /* Construct input lli table */ - sep_build_lli_table(sep, &lli_in_array[current_in_entry], - in_lli_table_ptr, - ¤t_in_entry, - &num_entries_in_table, - table_data_size); - - /* Construct output lli table */ - sep_build_lli_table(sep, &lli_out_array[current_out_entry], - out_lli_table_ptr, - ¤t_out_entry, - &num_entries_out_table, - table_data_size); - - /* If info entry is null - this is the first table built */ - if (info_in_entry_ptr == NULL) { - /* Set the output parameters to physical addresses */ - *lli_table_in_ptr = - sep_shared_area_virt_to_bus(sep, in_lli_table_ptr); - - *in_num_entries_ptr = num_entries_in_table; - - *lli_table_out_ptr = - sep_shared_area_virt_to_bus(sep, - out_lli_table_ptr); - - *out_num_entries_ptr = num_entries_out_table; - *table_data_size_ptr = table_data_size; - - dev_dbg(&sep->pdev->dev, - "output lli_table_in_ptr is %08lx\n", - (unsigned long)*lli_table_in_ptr); - dev_dbg(&sep->pdev->dev, - "output lli_table_out_ptr is %08lx\n", - (unsigned long)*lli_table_out_ptr); - } else { - /* Update the info entry of the previous in table */ - info_in_entry_ptr->bus_address = - sep_shared_area_virt_to_bus(sep, - in_lli_table_ptr); - - info_in_entry_ptr->block_size = - ((num_entries_in_table) << 24) | - (table_data_size); - - /* Update the info entry of the previous in table */ - info_out_entry_ptr->bus_address = - sep_shared_area_virt_to_bus(sep, - out_lli_table_ptr); - - info_out_entry_ptr->block_size = - ((num_entries_out_table) << 24) | - (table_data_size); - - dev_dbg(&sep->pdev->dev, - "output lli_table_in_ptr:%08lx %08x\n", - (unsigned long)info_in_entry_ptr->bus_address, - info_in_entry_ptr->block_size); - - dev_dbg(&sep->pdev->dev, - "output lli_table_out_ptr:%08lx %08x\n", - (unsigned long)info_out_entry_ptr->bus_address, - info_out_entry_ptr->block_size); - } - - /* Save the pointer to the info entry of the current tables */ - info_in_entry_ptr = in_lli_table_ptr + - num_entries_in_table - 1; - info_out_entry_ptr = out_lli_table_ptr + - num_entries_out_table - 1; - - dev_dbg(&sep->pdev->dev, - "output num_entries_out_table is %x\n", - (u32)num_entries_out_table); - dev_dbg(&sep->pdev->dev, - "output info_in_entry_ptr is %lx\n", - (unsigned long)info_in_entry_ptr); - dev_dbg(&sep->pdev->dev, - "output info_out_entry_ptr is %lx\n", - (unsigned long)info_out_entry_ptr); - } - - /* Print input tables */ - sep_debug_print_lli_tables(sep, - (struct sep_lli_entry *) - sep_shared_area_bus_to_virt(sep, *lli_table_in_ptr), - *in_num_entries_ptr, - *table_data_size_ptr); - - /* Print output tables */ - sep_debug_print_lli_tables(sep, - (struct sep_lli_entry *) - sep_shared_area_bus_to_virt(sep, *lli_table_out_ptr), - *out_num_entries_ptr, - *table_data_size_ptr); - - return 0; -} - -/** - * sep_prepare_input_output_dma_table - prepare DMA I/O table - * @app_virt_in_addr: - * @app_virt_out_addr: - * @data_size: - * @block_size: - * @lli_table_in_ptr: - * @lli_table_out_ptr: - * @in_num_entries_ptr: - * @out_num_entries_ptr: - * @table_data_size_ptr: - * @is_kva: set for kernel data; used only for kernel crypto module - * - * This function builds input and output DMA tables for synhronic - * symmetric operations (AES, DES, HASH). It also checks that each table - * is of the modular block size - * Note that all bus addresses that are passed to the SEP - * are in 32 bit format; the SEP is a 32 bit device - */ -static int sep_prepare_input_output_dma_table(struct sep_device *sep, - unsigned long app_virt_in_addr, - unsigned long app_virt_out_addr, - u32 data_size, - u32 block_size, - dma_addr_t *lli_table_in_ptr, - dma_addr_t *lli_table_out_ptr, - u32 *in_num_entries_ptr, - u32 *out_num_entries_ptr, - u32 *table_data_size_ptr, - bool is_kva) - -{ - int error = 0; - /* Array of pointers of page */ - struct sep_lli_entry *lli_in_array; - /* Array of pointers of page */ - struct sep_lli_entry *lli_out_array; - - if (data_size == 0) { - /* Prepare empty table for input and output */ - sep_prepare_empty_lli_table(sep, lli_table_in_ptr, - in_num_entries_ptr, table_data_size_ptr); - - sep_prepare_empty_lli_table(sep, lli_table_out_ptr, - out_num_entries_ptr, table_data_size_ptr); - - goto update_dcb_counter; - } - - /* Initialize the pages pointers */ - sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = NULL; - sep->dma_res_arr[sep->nr_dcb_creat].out_page_array = NULL; - - /* Lock the pages of the buffer and translate them to pages */ - if (is_kva == true) { - error = sep_lock_kernel_pages(sep, app_virt_in_addr, - data_size, &lli_in_array, SEP_DRIVER_IN_FLAG); - - if (error) { - dev_warn(&sep->pdev->dev, - "lock kernel for in failed\n"); - goto end_function; - } - - error = sep_lock_kernel_pages(sep, app_virt_out_addr, - data_size, &lli_out_array, SEP_DRIVER_OUT_FLAG); - - if (error) { - dev_warn(&sep->pdev->dev, - "lock kernel for out failed\n"); - goto end_function; - } - } - - else { - error = sep_lock_user_pages(sep, app_virt_in_addr, - data_size, &lli_in_array, SEP_DRIVER_IN_FLAG); - if (error) { - dev_warn(&sep->pdev->dev, - "sep_lock_user_pages for input virtual buffer failed\n"); - goto end_function; - } - - error = sep_lock_user_pages(sep, app_virt_out_addr, - data_size, &lli_out_array, SEP_DRIVER_OUT_FLAG); - - if (error) { - dev_warn(&sep->pdev->dev, - "sep_lock_user_pages for output virtual buffer failed\n"); - goto end_function_free_lli_in; - } - } - - dev_dbg(&sep->pdev->dev, "prep input output dma table sep_in_num_pages is %x\n", - sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages); - dev_dbg(&sep->pdev->dev, "sep_out_num_pages is %x\n", - sep->dma_res_arr[sep->nr_dcb_creat].out_num_pages); - dev_dbg(&sep->pdev->dev, "SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP is %x\n", - SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); - - /* Call the function that creates table from the lli arrays */ - error = sep_construct_dma_tables_from_lli(sep, lli_in_array, - sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages, - lli_out_array, - sep->dma_res_arr[sep->nr_dcb_creat].out_num_pages, - block_size, lli_table_in_ptr, lli_table_out_ptr, - in_num_entries_ptr, out_num_entries_ptr, table_data_size_ptr); - - if (error) { - dev_warn(&sep->pdev->dev, - "sep_construct_dma_tables_from_lli failed\n"); - goto end_function_with_error; - } - - kfree(lli_out_array); - kfree(lli_in_array); - -update_dcb_counter: - /* Update DCB counter */ - sep->nr_dcb_creat++; - - goto end_function; - -end_function_with_error: - kfree(sep->dma_res_arr[sep->nr_dcb_creat].out_map_array); - kfree(sep->dma_res_arr[sep->nr_dcb_creat].out_page_array); - kfree(lli_out_array); - - -end_function_free_lli_in: - kfree(sep->dma_res_arr[sep->nr_dcb_creat].in_map_array); - kfree(sep->dma_res_arr[sep->nr_dcb_creat].in_page_array); - kfree(lli_in_array); - -end_function: - - return error; - -} - -/** - * sep_prepare_input_output_dma_table_in_dcb - prepare control blocks - * @app_in_address: unsigned long; for data buffer in (user space) - * @app_out_address: unsigned long; for data buffer out (user space) - * @data_in_size: u32; for size of data - * @block_size: u32; for block size - * @tail_block_size: u32; for size of tail block - * @isapplet: bool; to indicate external app - * @is_kva: bool; kernel buffer; only used for kernel crypto module - * - * This function prepares the linked DMA tables and puts the - * address for the linked list of tables inta a DCB (data control - * block) the address of which is known by the SEP hardware - * Note that all bus addresses that are passed to the SEP - * are in 32 bit format; the SEP is a 32 bit device - */ -static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, - unsigned long app_in_address, - unsigned long app_out_address, - u32 data_in_size, - u32 block_size, - u32 tail_block_size, - bool isapplet, - bool is_kva) -{ - int error = 0; - /* Size of tail */ - u32 tail_size = 0; - /* Address of the created DCB table */ - struct sep_dcblock *dcb_table_ptr = NULL; - /* The physical address of the first input DMA table */ - dma_addr_t in_first_mlli_address = 0; - /* Number of entries in the first input DMA table */ - u32 in_first_num_entries = 0; - /* The physical address of the first output DMA table */ - dma_addr_t out_first_mlli_address = 0; - /* Number of entries in the first output DMA table */ - u32 out_first_num_entries = 0; - /* Data in the first input/output table */ - u32 first_data_size = 0; - - if (sep->nr_dcb_creat == SEP_MAX_NUM_SYNC_DMA_OPS) { - /* No more DCBs to allocate */ - dev_warn(&sep->pdev->dev, "no more DCBs available\n"); - error = -ENOSPC; - goto end_function; - } - - /* Allocate new DCB */ - dcb_table_ptr = (struct sep_dcblock *)(sep->shared_addr + - SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES + - (sep->nr_dcb_creat * sizeof(struct sep_dcblock))); - - /* Set the default values in the DCB */ - dcb_table_ptr->input_mlli_address = 0; - dcb_table_ptr->input_mlli_num_entries = 0; - dcb_table_ptr->input_mlli_data_size = 0; - dcb_table_ptr->output_mlli_address = 0; - dcb_table_ptr->output_mlli_num_entries = 0; - dcb_table_ptr->output_mlli_data_size = 0; - dcb_table_ptr->tail_data_size = 0; - dcb_table_ptr->out_vr_tail_pt = 0; - - if (isapplet == true) { - - /* Check if there is enough data for DMA operation */ - if (data_in_size < SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE) { - if (is_kva == true) { - memcpy(dcb_table_ptr->tail_data, - (void *)app_in_address, data_in_size); - } else { - if (copy_from_user(dcb_table_ptr->tail_data, - (void __user *)app_in_address, - data_in_size)) { - error = -EFAULT; - goto end_function; - } - } - - dcb_table_ptr->tail_data_size = data_in_size; - - /* Set the output user-space address for mem2mem op */ - if (app_out_address) - dcb_table_ptr->out_vr_tail_pt = - (aligned_u64)app_out_address; - - /* - * Update both data length parameters in order to avoid - * second data copy and allow building of empty mlli - * tables - */ - tail_size = 0x0; - data_in_size = 0x0; - - } else { - if (!app_out_address) { - tail_size = data_in_size % block_size; - if (!tail_size) { - if (tail_block_size == block_size) - tail_size = block_size; - } - } else { - tail_size = 0; - } - } - if (tail_size) { - if (tail_size > sizeof(dcb_table_ptr->tail_data)) - return -EINVAL; - if (is_kva == true) { - memcpy(dcb_table_ptr->tail_data, - (void *)(app_in_address + data_in_size - - tail_size), tail_size); - } else { - /* We have tail data - copy it to DCB */ - if (copy_from_user(dcb_table_ptr->tail_data, - (void *)(app_in_address + - data_in_size - tail_size), tail_size)) { - error = -EFAULT; - goto end_function; - } - } - if (app_out_address) - /* - * Calculate the output address - * according to tail data size - */ - dcb_table_ptr->out_vr_tail_pt = - (aligned_u64)app_out_address + data_in_size - - tail_size; - - /* Save the real tail data size */ - dcb_table_ptr->tail_data_size = tail_size; - /* - * Update the data size without the tail - * data size AKA data for the dma - */ - data_in_size = (data_in_size - tail_size); - } - } - /* Check if we need to build only input table or input/output */ - if (app_out_address) { - /* Prepare input/output tables */ - error = sep_prepare_input_output_dma_table(sep, - app_in_address, - app_out_address, - data_in_size, - block_size, - &in_first_mlli_address, - &out_first_mlli_address, - &in_first_num_entries, - &out_first_num_entries, - &first_data_size, - is_kva); - } else { - /* Prepare input tables */ - error = sep_prepare_input_dma_table(sep, - app_in_address, - data_in_size, - block_size, - &in_first_mlli_address, - &in_first_num_entries, - &first_data_size, - is_kva); - } - - if (error) { - dev_warn(&sep->pdev->dev, "prepare DMA table call failed from prepare DCB call\n"); - goto end_function; - } - - /* Set the DCB values */ - dcb_table_ptr->input_mlli_address = in_first_mlli_address; - dcb_table_ptr->input_mlli_num_entries = in_first_num_entries; - dcb_table_ptr->input_mlli_data_size = first_data_size; - dcb_table_ptr->output_mlli_address = out_first_mlli_address; - dcb_table_ptr->output_mlli_num_entries = out_first_num_entries; - dcb_table_ptr->output_mlli_data_size = first_data_size; - -end_function: - return error; - -} - -/** - * sep_free_dma_tables_and_dcb - free DMA tables and DCBs - * @sep: pointer to struct sep_device - * @isapplet: indicates external application (used for kernel access) - * @is_kva: indicates kernel addresses (only used for kernel crypto) - * - * This function frees the DMA tables and DCB - */ -static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet, - bool is_kva) -{ - int i = 0; - int error = 0; - int error_temp = 0; - struct sep_dcblock *dcb_table_ptr; - unsigned long pt_hold; - void *tail_pt; - - if (isapplet == true) { - /* Set pointer to first DCB table */ - dcb_table_ptr = (struct sep_dcblock *) - (sep->shared_addr + - SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES); - - /* Go over each DCB and see if tail pointer must be updated */ - for (i = 0; i < sep->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; - tail_pt = (void *)pt_hold; - if (is_kva == true) { - memcpy(tail_pt, - dcb_table_ptr->tail_data, - dcb_table_ptr->tail_data_size); - } else { - error_temp = copy_to_user( - tail_pt, - dcb_table_ptr->tail_data, - dcb_table_ptr->tail_data_size); - } - if (error_temp) { - /* Release the DMA resource */ - error = -EFAULT; - break; - } - } - } - } - /* Free the output pages, if any */ - sep_free_dma_table_data_handler(sep); - - return error; -} - -/** - * sep_get_static_pool_addr_handler - get static pool address - * @sep: pointer to struct sep_device - * - * This function sets the bus and virtual addresses of the static pool - */ -static int sep_get_static_pool_addr_handler(struct sep_device *sep) -{ - u32 *static_pool_addr = NULL; - - static_pool_addr = (u32 *)(sep->shared_addr + - SEP_DRIVER_SYSTEM_RAR_MEMORY_OFFSET_IN_BYTES); - - static_pool_addr[0] = SEP_STATIC_POOL_VAL_TOKEN; - static_pool_addr[1] = (u32)sep->shared_bus + - SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES; - - dev_dbg(&sep->pdev->dev, "static pool segment: physical %x\n", - (u32)static_pool_addr[1]); - - return 0; -} - -/** - * sep_end_transaction_handler - end transaction - * @sep: pointer to struct sep_device - * - * This API handles the end transaction request - */ -static int sep_end_transaction_handler(struct sep_device *sep) -{ - /* Clear the data pool pointers Token */ - memset((void *)(sep->shared_addr + - SEP_DRIVER_DATA_POOL_ALLOCATION_OFFSET_IN_BYTES), - 0, sep->num_of_data_allocations*2*sizeof(u32)); - - /* Check that all the DMA resources were freed */ - sep_free_dma_table_data_handler(sep); - - clear_bit(SEP_MMAP_LOCK_BIT, &sep->in_use_flags); - - /* - * We are now through with the transaction. Let's - * allow other processes who have the device open - * to perform transactions - */ - mutex_lock(&sep->sep_mutex); - sep->pid_doing_transaction = 0; - mutex_unlock(&sep->sep_mutex); - /* Raise event for stuck contextes */ - wake_up(&sep->event); - - return 0; -} - -/** - * sep_prepare_dcb_handler - prepare a control block - * @sep: pointer to struct sep_device - * @arg: pointer to user parameters - * - * This function will retrieve the RAR buffer physical addresses, type - * & size corresponding to the RAR handles provided in the buffers vector. - */ -static int sep_prepare_dcb_handler(struct sep_device *sep, unsigned long arg) -{ - int error; - /* Command arguments */ - struct build_dcb_struct command_args; - - /* Get the command arguments */ - if (copy_from_user(&command_args, (void __user *)arg, - sizeof(struct build_dcb_struct))) { - error = -EFAULT; - goto end_function; - } - - dev_dbg(&sep->pdev->dev, "prep dcb handler app_in_address is %08llx\n", - command_args.app_in_address); - dev_dbg(&sep->pdev->dev, "app_out_address is %08llx\n", - command_args.app_out_address); - dev_dbg(&sep->pdev->dev, "data_size is %x\n", - command_args.data_in_size); - dev_dbg(&sep->pdev->dev, "block_size is %x\n", - command_args.block_size); - dev_dbg(&sep->pdev->dev, "tail block_size is %x\n", - command_args.tail_block_size); - - error = sep_prepare_input_output_dma_table_in_dcb(sep, - (unsigned long)command_args.app_in_address, - (unsigned long)command_args.app_out_address, - command_args.data_in_size, command_args.block_size, - command_args.tail_block_size, true, false); - -end_function: - return error; - -} - -/** - * sep_free_dcb_handler - free control block resources - * @sep: pointer to struct sep_device - * - * This function frees the DCB resources and updates the needed - * user-space buffers. - */ -static int sep_free_dcb_handler(struct sep_device *sep) -{ - return sep_free_dma_tables_and_dcb(sep, false, false); -} - -/** - * sep_rar_prepare_output_msg_handler - prepare an output message - * @sep: pointer to struct sep_device - * @arg: pointer to user parameters - * - * This function will retrieve the RAR buffer physical addresses, type - * & size corresponding to the RAR handles provided in the buffers vector. - */ -static int sep_rar_prepare_output_msg_handler(struct sep_device *sep, - unsigned long arg) -{ - int error = 0; - /* Command args */ - struct rar_hndl_to_bus_struct command_args; - /* Bus address */ - dma_addr_t rar_bus = 0; - /* Holds the RAR address in the system memory offset */ - u32 *rar_addr; - - /* Copy the data */ - if (copy_from_user(&command_args, (void __user *)arg, - sizeof(command_args))) { - error = -EFAULT; - goto end_function; - } - - /* Call to translation function only if user handle is not NULL */ - if (command_args.rar_handle) - return -EOPNOTSUPP; - dev_dbg(&sep->pdev->dev, "rar msg; rar_addr_bus = %x\n", (u32)rar_bus); - - /* Set value in the SYSTEM MEMORY offset */ - rar_addr = (u32 *)(sep->shared_addr + - SEP_DRIVER_SYSTEM_RAR_MEMORY_OFFSET_IN_BYTES); - - /* Copy the physical address to the System Area for the SEP */ - rar_addr[0] = SEP_RAR_VAL_TOKEN; - rar_addr[1] = rar_bus; - -end_function: - return error; -} - -/** - * sep_ioctl - ioctl api - * @filp: pointer to struct file - * @cmd: command - * @arg: pointer to argument structure - * - * Implement the ioctl methods available on the SEP device. - */ -static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - int error = 0; - struct sep_device *sep = filp->private_data; - - /* Make sure we own this device */ - mutex_lock(&sep->sep_mutex); - if ((current->pid != sep->pid_doing_transaction) && - (sep->pid_doing_transaction != 0)) { - dev_dbg(&sep->pdev->dev, "ioctl pid is not owner\n"); - error = -EACCES; - } - mutex_unlock(&sep->sep_mutex); - - if (error) - return error; - - if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER) - return -ENOTTY; - - /* Lock to prevent the daemon to interfere with operation */ - mutex_lock(&sep->ioctl_mutex); - - switch (cmd) { - case SEP_IOCSENDSEPCOMMAND: - /* Send command to SEP */ - error = sep_send_command_handler(sep); - break; - case SEP_IOCALLOCDATAPOLL: - /* Allocate data pool */ - error = sep_allocate_data_pool_memory_handler(sep, arg); - break; - case SEP_IOCGETSTATICPOOLADDR: - /* Inform the SEP the bus address of the static pool */ - error = sep_get_static_pool_addr_handler(sep); - break; - case SEP_IOCENDTRANSACTION: - error = sep_end_transaction_handler(sep); - break; - case SEP_IOCRARPREPAREMESSAGE: - error = sep_rar_prepare_output_msg_handler(sep, arg); - break; - case SEP_IOCPREPAREDCB: - error = sep_prepare_dcb_handler(sep, arg); - break; - case SEP_IOCFREEDCB: - error = sep_free_dcb_handler(sep); - break; - default: - error = -ENOTTY; - break; - } - - mutex_unlock(&sep->ioctl_mutex); - return error; -} - -/** - * sep_singleton_ioctl - ioctl api for singleton interface - * @filp: pointer to struct file - * @cmd: command - * @arg: pointer to argument structure - * - * Implement the additional ioctls for the singleton device - */ -static long sep_singleton_ioctl(struct file *filp, u32 cmd, unsigned long arg) -{ - long error = 0; - struct sep_device *sep = filp->private_data; - - /* Check that the command is for the SEP device */ - if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER) - return -ENOTTY; - - /* Make sure we own this device */ - mutex_lock(&sep->sep_mutex); - if ((current->pid != sep->pid_doing_transaction) && - (sep->pid_doing_transaction != 0)) { - dev_dbg(&sep->pdev->dev, "singleton ioctl pid is not owner\n"); - mutex_unlock(&sep->sep_mutex); - return -EACCES; - } - - mutex_unlock(&sep->sep_mutex); - - switch (cmd) { - case SEP_IOCTLSETCALLERID: - mutex_lock(&sep->ioctl_mutex); - error = sep_set_caller_id_handler(sep, arg); - mutex_unlock(&sep->ioctl_mutex); - break; - default: - error = sep_ioctl(filp, cmd, arg); - break; - } - return error; -} - -/** - * sep_request_daemon_ioctl - ioctl for daemon - * @filp: pointer to struct file - * @cmd: command - * @arg: pointer to argument structure - * - * Called by the request daemon to perform ioctls on the daemon device - */ -static long sep_request_daemon_ioctl(struct file *filp, u32 cmd, - unsigned long arg) -{ - - long error; - struct sep_device *sep = filp->private_data; - - /* Check that the command is for SEP device */ - if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER) - return -ENOTTY; - - /* Only one process can access ioctl at any given time */ - mutex_lock(&sep->ioctl_mutex); - - switch (cmd) { - case SEP_IOCSENDSEPRPLYCOMMAND: - /* Send reply command to SEP */ - error = sep_req_daemon_send_reply_command_handler(sep); - break; - case SEP_IOCENDTRANSACTION: - /* - * End req daemon transaction, do nothing - * will be removed upon update in middleware - * API library - */ - error = 0; - break; - default: - error = -ENOTTY; - } - mutex_unlock(&sep->ioctl_mutex); - return error; -} - -/** - * sep_inthandler - interrupt handler - * @irq: interrupt - * @dev_id: device id - */ -static irqreturn_t sep_inthandler(int irq, void *dev_id) -{ - irqreturn_t int_error = IRQ_HANDLED; - unsigned long lck_flags; - u32 reg_val, reg_val2 = 0; - struct sep_device *sep = dev_id; - - /* Read the IRR register to check if this is SEP interrupt */ - reg_val = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR); - - if (reg_val & (0x1 << 13)) { - /* Lock and update the counter of reply messages */ - spin_lock_irqsave(&sep->snd_rply_lck, lck_flags); - sep->reply_ct++; - spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); - - dev_dbg(&sep->pdev->dev, "sep int: send_ct %lx reply_ct %lx\n", - sep->send_ct, sep->reply_ct); - - /* Is this printf or daemon request? */ - reg_val2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); - dev_dbg(&sep->pdev->dev, - "SEP Interrupt - reg2 is %08x\n", reg_val2); - - if ((reg_val2 >> 30) & 0x1) { - dev_dbg(&sep->pdev->dev, "int: printf request\n"); - wake_up(&sep->event_request_daemon); - } else if (reg_val2 >> 31) { - dev_dbg(&sep->pdev->dev, "int: daemon request\n"); - wake_up(&sep->event_request_daemon); - } else { - dev_dbg(&sep->pdev->dev, "int: SEP reply\n"); - wake_up(&sep->event); - } - } else { - dev_dbg(&sep->pdev->dev, "int: not SEP interrupt\n"); - int_error = IRQ_NONE; - } - if (int_error == IRQ_HANDLED) - sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, reg_val); - - return int_error; -} - -/** - * sep_reconfig_shared_area - reconfigure shared area - * @sep: pointer to struct sep_device - * - * Reconfig the shared area between HOST and SEP - needed in case - * the DX_CC_Init function was called before OS loading. - */ -static int sep_reconfig_shared_area(struct sep_device *sep) -{ - int ret_val; - - /* use to limit waiting for SEP */ - unsigned long end_time; - - /* Send the new SHARED MESSAGE AREA to the SEP */ - dev_dbg(&sep->pdev->dev, "reconfig shared; sending %08llx to sep\n", - (unsigned long long)sep->shared_bus); - - sep_write_reg(sep, HW_HOST_HOST_SEP_GPR1_REG_ADDR, sep->shared_bus); - - /* Poll for SEP response */ - ret_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR); - - end_time = jiffies + (WAIT_TIME * HZ); - - while ((time_before(jiffies, end_time)) && (ret_val != 0xffffffff) && - (ret_val != sep->shared_bus)) - ret_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR); - - /* Check the return value (register) */ - if (ret_val != sep->shared_bus) { - dev_warn(&sep->pdev->dev, "could not reconfig shared area\n"); - dev_warn(&sep->pdev->dev, "result was %x\n", ret_val); - ret_val = -ENOMEM; - } else - ret_val = 0; - - dev_dbg(&sep->pdev->dev, "reconfig shared area end\n"); - return ret_val; -} - -/* File operation for singleton SEP operations */ -static const struct file_operations singleton_file_operations = { - .owner = THIS_MODULE, - .unlocked_ioctl = sep_singleton_ioctl, - .poll = sep_poll, - .open = sep_singleton_open, - .release = sep_singleton_release, - .mmap = sep_mmap, -}; - -/* File operation for daemon operations */ -static const struct file_operations daemon_file_operations = { - .owner = THIS_MODULE, - .unlocked_ioctl = sep_request_daemon_ioctl, - .poll = sep_request_daemon_poll, - .open = sep_request_daemon_open, - .release = sep_request_daemon_release, - .mmap = sep_request_daemon_mmap, -}; - -/* The files operations structure of the driver */ -static const struct file_operations sep_file_operations = { - .owner = THIS_MODULE, - .unlocked_ioctl = sep_ioctl, - .poll = sep_poll, - .open = sep_open, - .release = sep_release, - .mmap = sep_mmap, -}; - -/** - * sep_register_driver_with_fs - register misc devices - * @sep: pointer to struct sep_device - * - * This function registers the driver with the file system - */ -static int sep_register_driver_with_fs(struct sep_device *sep) -{ - int ret_val; - - sep->miscdev_sep.minor = MISC_DYNAMIC_MINOR; - sep->miscdev_sep.name = SEP_DEV_NAME; - sep->miscdev_sep.fops = &sep_file_operations; - - sep->miscdev_singleton.minor = MISC_DYNAMIC_MINOR; - sep->miscdev_singleton.name = SEP_DEV_SINGLETON; - sep->miscdev_singleton.fops = &singleton_file_operations; - - sep->miscdev_daemon.minor = MISC_DYNAMIC_MINOR; - sep->miscdev_daemon.name = SEP_DEV_DAEMON; - sep->miscdev_daemon.fops = &daemon_file_operations; - - ret_val = misc_register(&sep->miscdev_sep); - if (ret_val) { - dev_warn(&sep->pdev->dev, "misc reg fails for SEP %x\n", - ret_val); - return ret_val; - } - - ret_val = misc_register(&sep->miscdev_singleton); - if (ret_val) { - dev_warn(&sep->pdev->dev, "misc reg fails for sing %x\n", - ret_val); - misc_deregister(&sep->miscdev_sep); - return ret_val; - } - - ret_val = misc_register(&sep->miscdev_daemon); - if (ret_val) { - dev_warn(&sep->pdev->dev, "misc reg fails for dmn %x\n", - ret_val); - misc_deregister(&sep->miscdev_sep); - misc_deregister(&sep->miscdev_singleton); - - return ret_val; - } - return ret_val; -} - - -/** - * sep_probe - probe a matching PCI device - * @pdev: pci_device - * @end: pci_device_id - * - * Attempt to set up and configure a SEP device that has been - * discovered by the PCI layer. - */ -static int __devinit sep_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - int error = 0; - struct sep_device *sep; - - if (sep_dev != NULL) { - dev_warn(&pdev->dev, "only one SEP supported.\n"); - return -EBUSY; - } - - /* Enable the device */ - error = pci_enable_device(pdev); - if (error) { - dev_warn(&pdev->dev, "error enabling pci device\n"); - goto end_function; - } - - /* Allocate the sep_device structure for this device */ - sep_dev = kzalloc(sizeof(struct sep_device), GFP_ATOMIC); - if (sep_dev == NULL) { - dev_warn(&pdev->dev, - "can't kmalloc the sep_device structure\n"); - error = -ENOMEM; - goto end_function_disable_device; - } - - /* - * We're going to use another variable for actually - * working with the device; this way, if we have - * multiple devices in the future, it would be easier - * to make appropriate changes - */ - sep = sep_dev; - - sep->pdev = pci_dev_get(pdev); - - init_waitqueue_head(&sep->event); - init_waitqueue_head(&sep->event_request_daemon); - spin_lock_init(&sep->snd_rply_lck); - mutex_init(&sep->sep_mutex); - mutex_init(&sep->ioctl_mutex); - - dev_dbg(&sep->pdev->dev, "sep probe: PCI obtained, device being prepared\n"); - dev_dbg(&sep->pdev->dev, "revision is %d\n", sep->pdev->revision); - - /* Set up our register area */ - sep->reg_physical_addr = pci_resource_start(sep->pdev, 0); - if (!sep->reg_physical_addr) { - dev_warn(&sep->pdev->dev, "Error getting register start\n"); - error = -ENODEV; - goto end_function_free_sep_dev; - } - - sep->reg_physical_end = pci_resource_end(sep->pdev, 0); - if (!sep->reg_physical_end) { - dev_warn(&sep->pdev->dev, "Error getting register end\n"); - error = -ENODEV; - goto end_function_free_sep_dev; - } - - sep->reg_addr = ioremap_nocache(sep->reg_physical_addr, - (size_t)(sep->reg_physical_end - sep->reg_physical_addr + 1)); - if (!sep->reg_addr) { - dev_warn(&sep->pdev->dev, "Error getting register virtual\n"); - error = -ENODEV; - goto end_function_free_sep_dev; - } - - dev_dbg(&sep->pdev->dev, - "Register area start %llx end %llx virtual %p\n", - (unsigned long long)sep->reg_physical_addr, - (unsigned long long)sep->reg_physical_end, - sep->reg_addr); - - /* Allocate the shared area */ - sep->shared_size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES + - SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES + - SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES + - SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES + - SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES; - - if (sep_map_and_alloc_shared_area(sep)) { - error = -ENOMEM; - /* Allocation failed */ - goto end_function_error; - } - - /* Clear ICR register */ - sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF); - - /* Set the IMR register - open only GPR 2 */ - sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13))); - - /* Read send/receive counters from SEP */ - sep->reply_ct = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); - sep->reply_ct &= 0x3FFFFFFF; - sep->send_ct = sep->reply_ct; - - /* Get the interrupt line */ - error = request_irq(pdev->irq, sep_inthandler, IRQF_SHARED, - "sep_driver", sep); - - if (error) - goto end_function_deallocate_sep_shared_area; - - /* The new chip requires a shared area reconfigure */ - if (sep->pdev->revision == 4) { /* Only for new chip */ - error = sep_reconfig_shared_area(sep); - if (error) - goto end_function_free_irq; - } - /* Finally magic up the device nodes */ - /* Register driver with the fs */ - error = sep_register_driver_with_fs(sep); - if (error == 0) - /* Success */ - return 0; - -end_function_free_irq: - free_irq(pdev->irq, sep); - -end_function_deallocate_sep_shared_area: - /* De-allocate shared area */ - sep_unmap_and_free_shared_area(sep); - -end_function_error: - iounmap(sep->reg_addr); - -end_function_free_sep_dev: - pci_dev_put(sep_dev->pdev); - kfree(sep_dev); - sep_dev = NULL; - -end_function_disable_device: - pci_disable_device(pdev); - -end_function: - return error; -} - -static void sep_remove(struct pci_dev *pdev) -{ - struct sep_device *sep = sep_dev; - - /* Unregister from fs */ - misc_deregister(&sep->miscdev_sep); - misc_deregister(&sep->miscdev_singleton); - misc_deregister(&sep->miscdev_daemon); - - /* Free the irq */ - free_irq(sep->pdev->irq, sep); - - /* Free the shared area */ - sep_unmap_and_free_shared_area(sep_dev); - iounmap((void *) sep_dev->reg_addr); -} - -static DEFINE_PCI_DEVICE_TABLE(sep_pci_id_tbl) = { - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MFLD_PCI_DEVICE_ID)}, - {0} -}; - -MODULE_DEVICE_TABLE(pci, sep_pci_id_tbl); - -/* Field for registering driver to PCI device */ -static struct pci_driver sep_pci_driver = { - .name = "sep_sec_driver", - .id_table = sep_pci_id_tbl, - .probe = sep_probe, - .remove = sep_remove -}; - - -/** - * sep_init - init function - * - * Module load time. Register the PCI device driver. - */ -static int __init sep_init(void) -{ - return pci_register_driver(&sep_pci_driver); -} - - -/** - * sep_exit - called to unload driver - * - * Drop the misc devices then remove and unmap the various resources - * that are not released by the driver remove method. - */ -static void __exit sep_exit(void) -{ - pci_unregister_driver(&sep_pci_driver); -} - - -module_init(sep_init); -module_exit(sep_exit); - -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/sep/sep_driver_api.h b/drivers/staging/sep/sep_driver_api.h index c3aacfcc8ac..78a4b69d3fd 100644 --- a/drivers/staging/sep/sep_driver_api.h +++ b/drivers/staging/sep/sep_driver_api.h @@ -2,8 +2,8 @@ * * sep_driver_api.h - Security Processor Driver api definitions * - * Copyright(c) 2009,2010 Intel Corporation. All rights reserved. - * Contributions(c) 2009,2010 Discretix. All rights reserved. + * Copyright(c) 2009-2011 Intel Corporation. All rights reserved. + * Contributions(c) 2009-2011 Discretix. 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 @@ -26,6 +26,7 @@ * CHANGES: * * 2010.09.14 Upgrade to Medfield + * 2011.02.22 Enable kernel crypto * */ @@ -37,26 +38,30 @@ #define SEP_DRIVER_SRC_REQ 2 #define SEP_DRIVER_SRC_PRINTF 3 - -/*------------------------------------------- - TYPEDEFS -----------------------------------------------*/ - -struct alloc_struct { - /* offset from start of shared pool area */ - u32 offset; - /* number of bytes to allocate */ - u32 num_bytes; -}; - -/* command struct for getting caller id value and address */ -struct caller_id_struct { - /* pid of the process */ - u32 pid; - /* virtual address of the caller id hash */ - aligned_u64 callerIdAddress; - /* caller id hash size in bytes */ - u32 callerIdSizeInBytes; +/* Power state */ +#define SEP_DRIVER_POWERON 1 +#define SEP_DRIVER_POWEROFF 2 + +/* Following enums are used only for kernel crypto api */ +enum type_of_request { + NO_REQUEST, + AES_CBC, + AES_ECB, + DES_CBC, + DES_ECB, + DES3_ECB, + DES3_CBC, + SHA1, + MD5, + SHA224, + SHA256 + }; + +enum hash_stage { + HASH_INIT, + HASH_UPDATE, + HASH_FINISH, + HASH_DIGEST }; /* @@ -83,11 +88,6 @@ struct sep_dcblock { u8 tail_data[68]; }; -struct sep_caller_id_entry { - int pid; - unsigned char callerIdHash[SEP_CALLER_ID_HASH_SIZE_IN_BYTES]; -}; - /* command structure for building dcb block (currently for ext app only */ @@ -104,6 +104,33 @@ struct build_dcb_struct { /* the size of the block of the operation - if needed, every table will be modulo this parameter */ u32 tail_block_size; + + /* which application calls the driver DX or applet */ + u32 is_applet; +}; + +/* + command structure for building dcb block for kernel crypto +*/ +struct build_dcb_struct_kernel { + /* address value of the data in */ + void *app_in_address; + /* size of data in */ + ssize_t data_in_size; + /* address of the data out */ + void *app_out_address; + /* the size of the block of the operation - if needed, + every table will be modulo this parameter */ + u32 block_size; + /* the size of the block of the operation - if needed, + every table will be modulo this parameter */ + u32 tail_block_size; + + /* which application calls the driver DX or applet */ + u32 is_applet; + + struct scatterlist *src_sg; + struct scatterlist *dst_sg; }; /** @@ -147,6 +174,10 @@ struct sep_dma_resource { /* number of entries of the output mapp array */ u32 out_map_num_entries; + + /* Scatter list for kernel operations */ + struct scatterlist *src_sg; + struct scatterlist *dst_sg; }; @@ -169,47 +200,190 @@ struct sep_lli_entry { u32 block_size; }; -/*---------------------------------------------------------------- - IOCTL command defines - -----------------------------------------------------------------*/ +/* + * header format for each fastcall write operation + */ +struct sep_fastcall_hdr { + u32 magic; + u32 msg_len; + u32 num_dcbs; +}; -/* magic number 1 of the sep IOCTL command */ -#define SEP_IOC_MAGIC_NUMBER 's' +/* + * structure used in file pointer's private data field + * to track the status of the calls to the various + * driver interface + */ +struct sep_call_status { + unsigned long status; +}; -/* sends interrupt to sep that message is ready */ -#define SEP_IOCSENDSEPCOMMAND \ - _IO(SEP_IOC_MAGIC_NUMBER, 0) +/* + * format of dma context buffer used to store all DMA-related + * context information of a particular transaction + */ +struct sep_dma_context { + /* number of data control blocks */ + u32 nr_dcb_creat; + /* number of the lli tables created in the current transaction */ + u32 num_lli_tables_created; + /* size of currently allocated dma tables region */ + u32 dmatables_len; + /* size of input data */ + u32 input_data_len; + struct sep_dma_resource dma_res_arr[SEP_MAX_NUM_SYNC_DMA_OPS]; + /* Scatter gather for kernel crypto */ + struct scatterlist *src_sg; + struct scatterlist *dst_sg; +}; -/* sends interrupt to sep that message is ready */ -#define SEP_IOCSENDSEPRPLYCOMMAND \ - _IO(SEP_IOC_MAGIC_NUMBER, 1) +/* + * format for file pointer's private_data field + */ +struct sep_private_data { + struct sep_queue_info *my_queue_elem; + struct sep_device *device; + struct sep_call_status call_status; + struct sep_dma_context *dma_ctx; +}; + + +/* Functions used by sep_crypto */ + +/** + * sep_queue_status_remove - Removes transaction from status queue + * @sep: SEP device + * @sep_queue_info: pointer to status queue + * + * This function will removes information about transaction from the queue. + */ +void sep_queue_status_remove(struct sep_device *sep, + struct sep_queue_info **queue_elem); +/** + * sep_queue_status_add - Adds transaction to status queue + * @sep: SEP device + * @opcode: transaction opcode + * @size: input data size + * @pid: pid of current process + * @name: current process name + * @name_len: length of name (current process) + * + * This function adds information about about transaction started to the status + * queue. + */ +struct sep_queue_info *sep_queue_status_add( + struct sep_device *sep, + u32 opcode, + u32 size, + u32 pid, + u8 *name, size_t name_len); -/* allocate memory in data pool */ -#define SEP_IOCALLOCDATAPOLL \ - _IOW(SEP_IOC_MAGIC_NUMBER, 2, struct alloc_struct) +/** + * sep_create_dcb_dmatables_context_kernel - Creates DCB & MLLI/DMA table context + * for kernel crypto + * @sep: SEP device + * @dcb_region: DCB region buf to create for current transaction + * @dmatables_region: MLLI/DMA tables buf to create for current transaction + * @dma_ctx: DMA context buf to create for current transaction + * @user_dcb_args: User arguments for DCB/MLLI creation + * @num_dcbs: Number of DCBs to create + */ +int sep_create_dcb_dmatables_context_kernel(struct sep_device *sep, + struct sep_dcblock **dcb_region, + void **dmatables_region, + struct sep_dma_context **dma_ctx, + const struct build_dcb_struct_kernel *dcb_data, + const u32 num_dcbs); -/* free dynamic data aalocated during table creation */ -#define SEP_IOCFREEDMATABLEDATA \ - _IO(SEP_IOC_MAGIC_NUMBER, 7) +/** + * sep_activate_dcb_dmatables_context - Takes DCB & DMA tables + * contexts into use + * @sep: SEP device + * @dcb_region: DCB region copy + * @dmatables_region: MLLI/DMA tables copy + * @dma_ctx: DMA context for current transaction + */ +ssize_t sep_activate_dcb_dmatables_context(struct sep_device *sep, + struct sep_dcblock **dcb_region, + void **dmatables_region, + struct sep_dma_context *dma_ctx); -/* get the static pool area addersses (physical and virtual) */ -#define SEP_IOCGETSTATICPOOLADDR \ - _IO(SEP_IOC_MAGIC_NUMBER, 8) +/** + * sep_prepare_input_output_dma_table_in_dcb - prepare control blocks + * @app_in_address: unsigned long; for data buffer in (user space) + * @app_out_address: unsigned long; for data buffer out (user space) + * @data_in_size: u32; for size of data + * @block_size: u32; for block size + * @tail_block_size: u32; for size of tail block + * @isapplet: bool; to indicate external app + * @is_kva: bool; kernel buffer; only used for kernel crypto module + * + * This function prepares the linked DMA tables and puts the + * address for the linked list of tables inta a DCB (data control + * block) the address of which is known by the SEP hardware + * Note that all bus addresses that are passed to the SEP + * are in 32 bit format; the SEP is a 32 bit device + */ +int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, + unsigned long app_in_address, + unsigned long app_out_address, + u32 data_in_size, + u32 block_size, + u32 tail_block_size, + bool isapplet, + bool is_kva, + struct sep_dcblock *dcb_region, + void **dmatables_region, + struct sep_dma_context **dma_ctx, + struct scatterlist *src_sg, + struct scatterlist *dst_sg); + +/** + * sep_free_dma_table_data_handler - free DMA table + * @sep: pointere to struct sep_device + * @dma_ctx: dma context + * + * Handles the request to free DMA table for synchronic actions + */ +int sep_free_dma_table_data_handler(struct sep_device *sep, + struct sep_dma_context **dma_ctx); +/** + * sep_send_command_handler - kick off a command + * @sep: SEP being signalled + * + * This function raises interrupt to SEP that signals that is has a new + * command from the host + * + * Note that this function does fall under the ioctl lock + */ +int sep_send_command_handler(struct sep_device *sep); + +/** + * sep_wait_transaction - Used for synchronizing transactions + * @sep: SEP device + */ +int sep_wait_transaction(struct sep_device *sep); + +/** + * IOCTL command defines + */ +/* magic number 1 of the sep IOCTL command */ +#define SEP_IOC_MAGIC_NUMBER 's' + +/* sends interrupt to sep that message is ready */ +#define SEP_IOCSENDSEPCOMMAND \ + _IO(SEP_IOC_MAGIC_NUMBER, 0) /* end transaction command */ #define SEP_IOCENDTRANSACTION \ _IO(SEP_IOC_MAGIC_NUMBER, 15) -#define SEP_IOCRARPREPAREMESSAGE \ - _IOW(SEP_IOC_MAGIC_NUMBER, 20, struct rar_hndl_to_bus_struct) - -#define SEP_IOCTLSETCALLERID \ - _IOW(SEP_IOC_MAGIC_NUMBER, 34, struct caller_id_struct) - #define SEP_IOCPREPAREDCB \ _IOW(SEP_IOC_MAGIC_NUMBER, 35, struct build_dcb_struct) #define SEP_IOCFREEDCB \ _IO(SEP_IOC_MAGIC_NUMBER, 36) +struct sep_device; + #endif diff --git a/drivers/staging/sep/sep_driver_config.h b/drivers/staging/sep/sep_driver_config.h index d6bfd245522..fa7c0d09bfa 100644 --- a/drivers/staging/sep/sep_driver_config.h +++ b/drivers/staging/sep/sep_driver_config.h @@ -2,8 +2,8 @@ * * sep_driver_config.h - Security Processor Driver configuration * - * Copyright(c) 2009,2010 Intel Corporation. All rights reserved. - * Contributions(c) 2009,2010 Discretix. All rights reserved. + * Copyright(c) 2009-2011 Intel Corporation. All rights reserved. + * Contributions(c) 2009-2011 Discretix. 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 @@ -26,6 +26,7 @@ * CHANGES: * * 2010.06.26 Upgrade to Medfield + * 2011.02.22 Enable kernel crypto * */ @@ -48,6 +49,8 @@ /* the mode for running on the ARM1172 Evaluation platform (flag is 1) */ #define SEP_DRIVER_ARM_DEBUG_MODE 0 +/* Critical message area contents for sanity checking */ +#define SEP_START_MSG_TOKEN 0x02558808 /*------------------------------------------- INTERNAL DATA CONFIGURATION -------------------------------------------*/ @@ -65,21 +68,17 @@ #define SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE 16 /* flag that signifies tah the lock is -currently held by the process (struct file) */ +currently held by the proccess (struct file) */ #define SEP_DRIVER_OWN_LOCK_FLAG 1 /* flag that signifies tah the lock is currently NOT -held by the process (struct file) */ +held by the proccess (struct file) */ #define SEP_DRIVER_DISOWN_LOCK_FLAG 0 /* indicates whether driver has mapped/unmapped shared area */ #define SEP_REQUEST_DAEMON_MAPPED 1 #define SEP_REQUEST_DAEMON_UNMAPPED 0 -#define SEP_DEV_NAME "sep_sec_driver" -#define SEP_DEV_SINGLETON "sep_sec_singleton_driver" -#define SEP_DEV_DAEMON "sep_req_daemon_driver" - /*-------------------------------------------------------- SHARED AREA memory total size is 36K it is divided is following: @@ -90,7 +89,7 @@ held by the process (struct file) */ } DATA_POOL_AREA 12K } - SYNCHRONIC_DMA_TABLES_AREA 5K + SYNCHRONIC_DMA_TABLES_AREA 29K placeholder until drver changes FLOW_DMA_TABLES_AREA 4K @@ -108,6 +107,12 @@ held by the process (struct file) */ #define SEP_DEV_DAEMON "sep_req_daemon_driver" +/* + the minimum length of the message - includes 2 reserved fields + at the start, then token, message size and opcode fields. all dwords +*/ +#define SEP_DRIVER_MIN_MESSAGE_SIZE_IN_BYTES (5*sizeof(u32)) + /* the maximum length of the message - the rest of the message shared area will be dedicated to the dma lli tables @@ -124,7 +129,7 @@ held by the process (struct file) */ #define SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES (16 * 1024) /* the size of the message shared area in pages */ -#define SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES (1024 * 5) +#define SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES (1024 * 29) /* Placeholder until driver changes */ #define SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES (1024 * 4) @@ -132,6 +137,9 @@ held by the process (struct file) */ /* system data (time, caller id etc') pool */ #define SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES (1024 * 3) +/* Offset of the sep printf buffer in the message area */ +#define SEP_DRIVER_PRINTF_OFFSET_IN_BYTES (5888) + /* the size in bytes of the time memory */ #define SEP_DRIVER_TIME_MEMORY_SIZE_IN_BYTES 8 @@ -223,10 +231,10 @@ held by the process (struct file) */ #define SEP_ALREADY_INITIALIZED_ERR 12 /* bit that locks access to the shared area */ -#define SEP_MMAP_LOCK_BIT 0 +#define SEP_TRANSACTION_STARTED_LOCK_BIT 0 /* bit that lock access to the poll - after send_command */ -#define SEP_SEND_MSG_LOCK_BIT 1 +#define SEP_WORKING_LOCK_BIT 1 /* the token that defines the static pool address address */ #define SEP_STATIC_POOL_VAL_TOKEN 0xABBAABBA @@ -240,4 +248,51 @@ held by the process (struct file) */ /* Time limit for SEP to finish */ #define WAIT_TIME 10 +/* Delay for pm runtime suspend (reduces pm thrashing with bursty traffic */ +#define SUSPEND_DELAY 10 + +/* Number of delays to wait until scu boots after runtime resume */ +#define SCU_DELAY_MAX 50 + +/* Delay for each iteration (usec) wait for scu boots after runtime resume */ +#define SCU_DELAY_ITERATION 10 + + +/* + * Bits used in struct sep_call_status to check that + * driver's APIs are called in valid order + */ + +/* Bit offset which indicates status of sep_write() */ +#define SEP_FASTCALL_WRITE_DONE_OFFSET 0 + +/* Bit offset which indicates status of sep_mmap() */ +#define SEP_LEGACY_MMAP_DONE_OFFSET 1 + +/* Bit offset which indicates status of the SEP_IOCSENDSEPCOMMAND ioctl */ +#define SEP_LEGACY_SENDMSG_DONE_OFFSET 2 + +/* Bit offset which indicates status of sep_poll() */ +#define SEP_LEGACY_POLL_DONE_OFFSET 3 + +/* Bit offset which indicates status of the SEP_IOCENDTRANSACTION ioctl */ +#define SEP_LEGACY_ENDTRANSACTION_DONE_OFFSET 4 + +/* + * Used to limit number of concurrent processes + * allowed to allocte dynamic buffers in fastcall + * interface. + */ +#define SEP_DOUBLEBUF_USERS_LIMIT 3 + +/* Identifier for valid fastcall header */ +#define SEP_FC_MAGIC 0xFFAACCAA + +/* + * Used for enabling driver runtime power management. + * Useful for enabling/disabling it during performance + * testing + */ +#define SEP_ENABLE_RUNTIME_PM + #endif /* SEP DRIVER CONFIG */ diff --git a/drivers/staging/sep/sep_driver_hw_defs.h b/drivers/staging/sep/sep_driver_hw_defs.h index 300f90963de..c48e49a741b 100644 --- a/drivers/staging/sep/sep_driver_hw_defs.h +++ b/drivers/staging/sep/sep_driver_hw_defs.h @@ -2,8 +2,8 @@ * * sep_driver_hw_defs.h - Security Processor Driver hardware definitions * - * Copyright(c) 2009,2010 Intel Corporation. All rights reserved. - * Contributions(c) 2009,2010 Discretix. All rights reserved. + * Copyright(c) 2009-2011 Intel Corporation. All rights reserved. + * Contributions(c) 2009-2011 Discretix. 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 @@ -26,6 +26,7 @@ * CHANGES: * * 2010.09.20 Upgrade to Medfield + * 2011.02.22 Enable kernel crypto * */ @@ -42,181 +43,9 @@ /* cf registers */ -#define HW_R0B_ADDR_0_REG_ADDR 0x0000UL -#define HW_R0B_ADDR_1_REG_ADDR 0x0004UL -#define HW_R0B_ADDR_2_REG_ADDR 0x0008UL -#define HW_R0B_ADDR_3_REG_ADDR 0x000cUL -#define HW_R0B_ADDR_4_REG_ADDR 0x0010UL -#define HW_R0B_ADDR_5_REG_ADDR 0x0014UL -#define HW_R0B_ADDR_6_REG_ADDR 0x0018UL -#define HW_R0B_ADDR_7_REG_ADDR 0x001cUL -#define HW_R0B_ADDR_8_REG_ADDR 0x0020UL -#define HW_R2B_ADDR_0_REG_ADDR 0x0080UL -#define HW_R2B_ADDR_1_REG_ADDR 0x0084UL -#define HW_R2B_ADDR_2_REG_ADDR 0x0088UL -#define HW_R2B_ADDR_3_REG_ADDR 0x008cUL -#define HW_R2B_ADDR_4_REG_ADDR 0x0090UL -#define HW_R2B_ADDR_5_REG_ADDR 0x0094UL -#define HW_R2B_ADDR_6_REG_ADDR 0x0098UL -#define HW_R2B_ADDR_7_REG_ADDR 0x009cUL -#define HW_R2B_ADDR_8_REG_ADDR 0x00a0UL -#define HW_R3B_REG_ADDR 0x00C0UL -#define HW_R4B_REG_ADDR 0x0100UL -#define HW_CSA_ADDR_0_REG_ADDR 0x0140UL -#define HW_CSA_ADDR_1_REG_ADDR 0x0144UL -#define HW_CSA_ADDR_2_REG_ADDR 0x0148UL -#define HW_CSA_ADDR_3_REG_ADDR 0x014cUL -#define HW_CSA_ADDR_4_REG_ADDR 0x0150UL -#define HW_CSA_ADDR_5_REG_ADDR 0x0154UL -#define HW_CSA_ADDR_6_REG_ADDR 0x0158UL -#define HW_CSA_ADDR_7_REG_ADDR 0x015cUL -#define HW_CSA_ADDR_8_REG_ADDR 0x0160UL -#define HW_CSA_REG_ADDR 0x0140UL -#define HW_SINB_REG_ADDR 0x0180UL -#define HW_SOUTB_REG_ADDR 0x0184UL -#define HW_PKI_CONTROL_REG_ADDR 0x01C0UL -#define HW_PKI_STATUS_REG_ADDR 0x01C4UL -#define HW_PKI_BUSY_REG_ADDR 0x01C8UL -#define HW_PKI_A_1025_REG_ADDR 0x01CCUL -#define HW_PKI_SDMA_CTL_REG_ADDR 0x01D0UL -#define HW_PKI_SDMA_OFFSET_REG_ADDR 0x01D4UL -#define HW_PKI_SDMA_POINTERS_REG_ADDR 0x01D8UL -#define HW_PKI_SDMA_DLENG_REG_ADDR 0x01DCUL -#define HW_PKI_SDMA_EXP_POINTERS_REG_ADDR 0x01E0UL -#define HW_PKI_SDMA_RES_POINTERS_REG_ADDR 0x01E4UL -#define HW_PKI_CLR_REG_ADDR 0x01E8UL -#define HW_PKI_SDMA_BUSY_REG_ADDR 0x01E8UL -#define HW_PKI_SDMA_FIRST_EXP_N_REG_ADDR 0x01ECUL -#define HW_PKI_SDMA_MUL_BY1_REG_ADDR 0x01F0UL -#define HW_PKI_SDMA_RMUL_SEL_REG_ADDR 0x01F4UL -#define HW_DES_KEY_0_REG_ADDR 0x0208UL -#define HW_DES_KEY_1_REG_ADDR 0x020CUL -#define HW_DES_KEY_2_REG_ADDR 0x0210UL -#define HW_DES_KEY_3_REG_ADDR 0x0214UL -#define HW_DES_KEY_4_REG_ADDR 0x0218UL -#define HW_DES_KEY_5_REG_ADDR 0x021CUL -#define HW_DES_CONTROL_0_REG_ADDR 0x0220UL -#define HW_DES_CONTROL_1_REG_ADDR 0x0224UL -#define HW_DES_IV_0_REG_ADDR 0x0228UL -#define HW_DES_IV_1_REG_ADDR 0x022CUL -#define HW_AES_KEY_0_ADDR_0_REG_ADDR 0x0400UL -#define HW_AES_KEY_0_ADDR_1_REG_ADDR 0x0404UL -#define HW_AES_KEY_0_ADDR_2_REG_ADDR 0x0408UL -#define HW_AES_KEY_0_ADDR_3_REG_ADDR 0x040cUL -#define HW_AES_KEY_0_ADDR_4_REG_ADDR 0x0410UL -#define HW_AES_KEY_0_ADDR_5_REG_ADDR 0x0414UL -#define HW_AES_KEY_0_ADDR_6_REG_ADDR 0x0418UL -#define HW_AES_KEY_0_ADDR_7_REG_ADDR 0x041cUL -#define HW_AES_KEY_0_REG_ADDR 0x0400UL -#define HW_AES_IV_0_ADDR_0_REG_ADDR 0x0440UL -#define HW_AES_IV_0_ADDR_1_REG_ADDR 0x0444UL -#define HW_AES_IV_0_ADDR_2_REG_ADDR 0x0448UL -#define HW_AES_IV_0_ADDR_3_REG_ADDR 0x044cUL -#define HW_AES_IV_0_REG_ADDR 0x0440UL -#define HW_AES_CTR1_ADDR_0_REG_ADDR 0x0460UL -#define HW_AES_CTR1_ADDR_1_REG_ADDR 0x0464UL -#define HW_AES_CTR1_ADDR_2_REG_ADDR 0x0468UL -#define HW_AES_CTR1_ADDR_3_REG_ADDR 0x046cUL -#define HW_AES_CTR1_REG_ADDR 0x0460UL -#define HW_AES_SK_REG_ADDR 0x0478UL -#define HW_AES_MAC_OK_REG_ADDR 0x0480UL -#define HW_AES_PREV_IV_0_ADDR_0_REG_ADDR 0x0490UL -#define HW_AES_PREV_IV_0_ADDR_1_REG_ADDR 0x0494UL -#define HW_AES_PREV_IV_0_ADDR_2_REG_ADDR 0x0498UL -#define HW_AES_PREV_IV_0_ADDR_3_REG_ADDR 0x049cUL -#define HW_AES_PREV_IV_0_REG_ADDR 0x0490UL -#define HW_AES_CONTROL_REG_ADDR 0x04C0UL -#define HW_HASH_H0_REG_ADDR 0x0640UL -#define HW_HASH_H1_REG_ADDR 0x0644UL -#define HW_HASH_H2_REG_ADDR 0x0648UL -#define HW_HASH_H3_REG_ADDR 0x064CUL -#define HW_HASH_H4_REG_ADDR 0x0650UL -#define HW_HASH_H5_REG_ADDR 0x0654UL -#define HW_HASH_H6_REG_ADDR 0x0658UL -#define HW_HASH_H7_REG_ADDR 0x065CUL -#define HW_HASH_H8_REG_ADDR 0x0660UL -#define HW_HASH_H9_REG_ADDR 0x0664UL -#define HW_HASH_H10_REG_ADDR 0x0668UL -#define HW_HASH_H11_REG_ADDR 0x066CUL -#define HW_HASH_H12_REG_ADDR 0x0670UL -#define HW_HASH_H13_REG_ADDR 0x0674UL -#define HW_HASH_H14_REG_ADDR 0x0678UL -#define HW_HASH_H15_REG_ADDR 0x067CUL -#define HW_HASH_CONTROL_REG_ADDR 0x07C0UL -#define HW_HASH_PAD_EN_REG_ADDR 0x07C4UL -#define HW_HASH_PAD_CFG_REG_ADDR 0x07C8UL -#define HW_HASH_CUR_LEN_0_REG_ADDR 0x07CCUL -#define HW_HASH_CUR_LEN_1_REG_ADDR 0x07D0UL -#define HW_HASH_CUR_LEN_2_REG_ADDR 0x07D4UL -#define HW_HASH_CUR_LEN_3_REG_ADDR 0x07D8UL -#define HW_HASH_PARAM_REG_ADDR 0x07DCUL -#define HW_HASH_INT_BUSY_REG_ADDR 0x07E0UL -#define HW_HASH_SW_RESET_REG_ADDR 0x07E4UL -#define HW_HASH_ENDIANESS_REG_ADDR 0x07E8UL -#define HW_HASH_DATA_REG_ADDR 0x07ECUL -#define HW_DRNG_CONTROL_REG_ADDR 0x0800UL -#define HW_DRNG_VALID_REG_ADDR 0x0804UL -#define HW_DRNG_DATA_REG_ADDR 0x0808UL -#define HW_RND_SRC_EN_REG_ADDR 0x080CUL -#define HW_AES_CLK_ENABLE_REG_ADDR 0x0810UL -#define HW_DES_CLK_ENABLE_REG_ADDR 0x0814UL -#define HW_HASH_CLK_ENABLE_REG_ADDR 0x0818UL -#define HW_PKI_CLK_ENABLE_REG_ADDR 0x081CUL -#define HW_CLK_STATUS_REG_ADDR 0x0824UL -#define HW_CLK_ENABLE_REG_ADDR 0x0828UL -#define HW_DRNG_SAMPLE_REG_ADDR 0x0850UL -#define HW_RND_SRC_CTL_REG_ADDR 0x0858UL -#define HW_CRYPTO_CTL_REG_ADDR 0x0900UL -#define HW_CRYPTO_STATUS_REG_ADDR 0x090CUL -#define HW_CRYPTO_BUSY_REG_ADDR 0x0910UL -#define HW_AES_BUSY_REG_ADDR 0x0914UL -#define HW_DES_BUSY_REG_ADDR 0x0918UL -#define HW_HASH_BUSY_REG_ADDR 0x091CUL -#define HW_CONTENT_REG_ADDR 0x0924UL -#define HW_VERSION_REG_ADDR 0x0928UL -#define HW_CONTEXT_ID_REG_ADDR 0x0930UL -#define HW_DIN_BUFFER_REG_ADDR 0x0C00UL -#define HW_DIN_MEM_DMA_BUSY_REG_ADDR 0x0c20UL -#define HW_SRC_LLI_MEM_ADDR_REG_ADDR 0x0c24UL -#define HW_SRC_LLI_WORD0_REG_ADDR 0x0C28UL -#define HW_SRC_LLI_WORD1_REG_ADDR 0x0C2CUL -#define HW_SRAM_SRC_ADDR_REG_ADDR 0x0c30UL -#define HW_DIN_SRAM_BYTES_LEN_REG_ADDR 0x0c34UL -#define HW_DIN_SRAM_DMA_BUSY_REG_ADDR 0x0C38UL -#define HW_WRITE_ALIGN_REG_ADDR 0x0C3CUL -#define HW_OLD_DATA_REG_ADDR 0x0C48UL -#define HW_WRITE_ALIGN_LAST_REG_ADDR 0x0C4CUL -#define HW_DOUT_BUFFER_REG_ADDR 0x0C00UL -#define HW_DST_LLI_WORD0_REG_ADDR 0x0D28UL -#define HW_DST_LLI_WORD1_REG_ADDR 0x0D2CUL -#define HW_DST_LLI_MEM_ADDR_REG_ADDR 0x0D24UL -#define HW_DOUT_MEM_DMA_BUSY_REG_ADDR 0x0D20UL -#define HW_SRAM_DEST_ADDR_REG_ADDR 0x0D30UL -#define HW_DOUT_SRAM_BYTES_LEN_REG_ADDR 0x0D34UL -#define HW_DOUT_SRAM_DMA_BUSY_REG_ADDR 0x0D38UL -#define HW_READ_ALIGN_REG_ADDR 0x0D3CUL -#define HW_READ_LAST_DATA_REG_ADDR 0x0D44UL -#define HW_RC4_THRU_CPU_REG_ADDR 0x0D4CUL -#define HW_AHB_SINGLE_REG_ADDR 0x0E00UL -#define HW_SRAM_DATA_REG_ADDR 0x0F00UL -#define HW_SRAM_ADDR_REG_ADDR 0x0F04UL -#define HW_SRAM_DATA_READY_REG_ADDR 0x0F08UL #define HW_HOST_IRR_REG_ADDR 0x0A00UL #define HW_HOST_IMR_REG_ADDR 0x0A04UL #define HW_HOST_ICR_REG_ADDR 0x0A08UL -#define HW_HOST_SEP_SRAM_THRESHOLD_REG_ADDR 0x0A10UL -#define HW_HOST_SEP_BUSY_REG_ADDR 0x0A14UL -#define HW_HOST_SEP_LCS_REG_ADDR 0x0A18UL -#define HW_HOST_CC_SW_RST_REG_ADDR 0x0A40UL -#define HW_HOST_SEP_SW_RST_REG_ADDR 0x0A44UL -#define HW_HOST_FLOW_DMA_SW_INT0_REG_ADDR 0x0A80UL -#define HW_HOST_FLOW_DMA_SW_INT1_REG_ADDR 0x0A84UL -#define HW_HOST_FLOW_DMA_SW_INT2_REG_ADDR 0x0A88UL -#define HW_HOST_FLOW_DMA_SW_INT3_REG_ADDR 0x0A8cUL -#define HW_HOST_FLOW_DMA_SW_INT4_REG_ADDR 0x0A90UL -#define HW_HOST_FLOW_DMA_SW_INT5_REG_ADDR 0x0A94UL -#define HW_HOST_FLOW_DMA_SW_INT6_REG_ADDR 0x0A98UL -#define HW_HOST_FLOW_DMA_SW_INT7_REG_ADDR 0x0A9cUL #define HW_HOST_SEP_HOST_GPR0_REG_ADDR 0x0B00UL #define HW_HOST_SEP_HOST_GPR1_REG_ADDR 0x0B04UL #define HW_HOST_SEP_HOST_GPR2_REG_ADDR 0x0B08UL @@ -225,9 +54,6 @@ #define HW_HOST_HOST_SEP_GPR1_REG_ADDR 0x0B84UL #define HW_HOST_HOST_SEP_GPR2_REG_ADDR 0x0B88UL #define HW_HOST_HOST_SEP_GPR3_REG_ADDR 0x0B8CUL -#define HW_HOST_HOST_ENDIAN_REG_ADDR 0x0B90UL -#define HW_HOST_HOST_COMM_CLK_EN_REG_ADDR 0x0B94UL -#define HW_CLR_SRAM_BUSY_REG_REG_ADDR 0x0F0CUL -#define HW_CC_SRAM_BASE_ADDRESS 0x5800UL +#define HW_SRAM_DATA_READY_REG_ADDR 0x0F08UL #endif /* ifndef HW_DEFS */ diff --git a/drivers/staging/sep/sep_main.c b/drivers/staging/sep/sep_main.c new file mode 100644 index 00000000000..0defb0ad4c8 --- /dev/null +++ b/drivers/staging/sep/sep_main.c @@ -0,0 +1,4286 @@ +/* + * + * sep_main.c - Security Processor Driver main group of functions + * + * Copyright(c) 2009-2011 Intel Corporation. All rights reserved. + * Contributions(c) 2009-2011 Discretix. 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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * CONTACTS: + * + * Mark Allyn mark.a.allyn@intel.com + * Jayant Mangalampalli jayant.mangalampalli@intel.com + * + * CHANGES: + * + * 2009.06.26 Initial publish + * 2010.09.14 Upgrade to Medfield + * 2011.01.21 Move to sep_main.c to allow for sep_crypto.c + * 2011.02.22 Enable kernel crypto operation + * + * Please note that this driver is based on information in the Discretix + * CryptoCell 5.2 Driver Implementation Guide; the Discretix CryptoCell 5.2 + * Integration Intel Medfield appendix; the Discretix CryptoCell 5.2 + * Linux Driver Integration Guide; and the Discretix CryptoCell 5.2 System + * Overview and Integration Guide. + */ +/* #define DEBUG */ +/* #define SEP_PERF_DEBUG */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sep_driver_hw_defs.h" +#include "sep_driver_config.h" +#include "sep_driver_api.h" +#include "sep_dev.h" +#include "sep_crypto.h" + +#define CREATE_TRACE_POINTS +#include "sep_trace_events.h" + +/* + * Let's not spend cycles iterating over message + * area contents if debugging not enabled + */ +#ifdef DEBUG +#define sep_dump_message(sep) _sep_dump_message(sep) +#else +#define sep_dump_message(sep) +#endif + +/** + * Currenlty, there is only one SEP device per platform; + * In event platforms in the future have more than one SEP + * device, this will be a linked list + */ + +struct sep_device *sep_dev; + +/** + * sep_queue_status_remove - Removes transaction from status queue + * @sep: SEP device + * @sep_queue_info: pointer to status queue + * + * This function will removes information about transaction from the queue. + */ +void sep_queue_status_remove(struct sep_device *sep, + struct sep_queue_info **queue_elem) +{ + unsigned long lck_flags; + + dev_dbg(&sep->pdev->dev, "[PID%d] sep_queue_status_remove\n", + current->pid); + + if (!queue_elem || !(*queue_elem)) { + dev_dbg(&sep->pdev->dev, "PID%d %s null\n", + current->pid, __func__); + return; + } + + spin_lock_irqsave(&sep->sep_queue_lock, lck_flags); + list_del(&(*queue_elem)->list); + sep->sep_queue_num--; + spin_unlock_irqrestore(&sep->sep_queue_lock, lck_flags); + + kfree(*queue_elem); + *queue_elem = NULL; + + dev_dbg(&sep->pdev->dev, "[PID%d] sep_queue_status_remove return\n", + current->pid); + return; +} + +/** + * sep_queue_status_add - Adds transaction to status queue + * @sep: SEP device + * @opcode: transaction opcode + * @size: input data size + * @pid: pid of current process + * @name: current process name + * @name_len: length of name (current process) + * + * This function adds information about about transaction started to the status + * queue. + */ +struct sep_queue_info *sep_queue_status_add( + struct sep_device *sep, + u32 opcode, + u32 size, + u32 pid, + u8 *name, size_t name_len) +{ + unsigned long lck_flags; + struct sep_queue_info *my_elem = NULL; + + my_elem = kzalloc(sizeof(struct sep_queue_info), GFP_KERNEL); + + if (!my_elem) + return NULL; + + dev_dbg(&sep->pdev->dev, "[PID%d] kzalloc ok\n", current->pid); + + my_elem->data.opcode = opcode; + my_elem->data.size = size; + my_elem->data.pid = pid; + + if (name_len > TASK_COMM_LEN) + name_len = TASK_COMM_LEN; + + memcpy(&my_elem->data.name, name, name_len); + + spin_lock_irqsave(&sep->sep_queue_lock, lck_flags); + + list_add_tail(&my_elem->list, &sep->sep_queue_status); + sep->sep_queue_num++; + + spin_unlock_irqrestore(&sep->sep_queue_lock, lck_flags); + + return my_elem; +} + +/** + * sep_allocate_dmatables_region - Allocates buf for the MLLI/DMA tables + * @sep: SEP device + * @dmatables_region: Destination pointer for the buffer + * @dma_ctx: DMA context for the transaction + * @table_count: Number of MLLI/DMA tables to create + * The buffer created will not work as-is for DMA operations, + * it needs to be copied over to the appropriate place in the + * shared area. + */ +static int sep_allocate_dmatables_region(struct sep_device *sep, + void **dmatables_region, + struct sep_dma_context *dma_ctx, + const u32 table_count) +{ + const size_t new_len = table_count * + sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; + void *tmp_region = NULL; + + dev_dbg(&sep->pdev->dev, "[PID%d] dma_ctx = 0x%p\n", + current->pid, dma_ctx); + dev_dbg(&sep->pdev->dev, "[PID%d] dmatables_region = 0x%p\n", + current->pid, dmatables_region); + + if (!dma_ctx || !dmatables_region) { + dev_warn(&sep->pdev->dev, + "[PID%d] dma context/region uninitialized\n", + current->pid); + return -EINVAL; + } + + dev_dbg(&sep->pdev->dev, "[PID%d] newlen = 0x%08X\n", + current->pid, new_len); + dev_dbg(&sep->pdev->dev, "[PID%d] oldlen = 0x%08X\n", current->pid, + dma_ctx->dmatables_len); + tmp_region = kzalloc(new_len + dma_ctx->dmatables_len, GFP_KERNEL); + if (!tmp_region) { + dev_warn(&sep->pdev->dev, + "[PID%d] no mem for dma tables region\n", + current->pid); + return -ENOMEM; + } + + /* Were there any previous tables that need to be preserved ? */ + if (*dmatables_region) { + memcpy(tmp_region, *dmatables_region, dma_ctx->dmatables_len); + kfree(*dmatables_region); + } + + *dmatables_region = tmp_region; + + dma_ctx->dmatables_len += new_len; + + return 0; +} + +/** + * sep_wait_transaction - Used for synchronizing transactions + * @sep: SEP device + */ +int sep_wait_transaction(struct sep_device *sep) +{ + int error = 0; + DEFINE_WAIT(wait); + + if (0 == test_and_set_bit(SEP_TRANSACTION_STARTED_LOCK_BIT, + &sep->in_use_flags)) { + dev_dbg(&sep->pdev->dev, + "[PID%d] no transactions, returning\n", + current->pid); + goto end_function_setpid; + } + + /* + * Looping needed even for exclusive waitq entries + * due to process wakeup latencies, previous process + * might have already created another transaction. + */ + for (;;) { + /* + * Exclusive waitq entry, so that only one process is + * woken up from the queue at a time. + */ + prepare_to_wait_exclusive(&sep->event_transactions, + &wait, + TASK_INTERRUPTIBLE); + if (0 == test_and_set_bit(SEP_TRANSACTION_STARTED_LOCK_BIT, + &sep->in_use_flags)) { + dev_dbg(&sep->pdev->dev, + "[PID%d] no transactions, breaking\n", + current->pid); + break; + } + dev_dbg(&sep->pdev->dev, + "[PID%d] transactions ongoing, sleeping\n", + current->pid); + schedule(); + dev_dbg(&sep->pdev->dev, "[PID%d] woken up\n", current->pid); + + if (signal_pending(current)) { + dev_dbg(&sep->pdev->dev, "[PID%d] received signal\n", + current->pid); + error = -EINTR; + goto end_function; + } + } +end_function_setpid: + /* + * The pid_doing_transaction indicates that this process + * now owns the facilities to performa a transaction with + * the SEP. While this process is performing a transaction, + * no other process who has the SEP device open can perform + * any transactions. This method allows more than one process + * to have the device open at any given time, which provides + * finer granularity for device utilization by multiple + * processes. + */ + /* Only one process is able to progress here at a time */ + sep->pid_doing_transaction = current->pid; + +end_function: + finish_wait(&sep->event_transactions, &wait); + + return error; +} + +/** + * sep_check_transaction_owner - Checks if current process owns transaction + * @sep: SEP device + */ +static inline int sep_check_transaction_owner(struct sep_device *sep) +{ + dev_dbg(&sep->pdev->dev, "[PID%d] transaction pid = %d\n", + current->pid, + sep->pid_doing_transaction); + + if ((sep->pid_doing_transaction == 0) || + (current->pid != sep->pid_doing_transaction)) { + return -EACCES; + } + + /* We own the transaction */ + return 0; +} + +#ifdef DEBUG + +/** + * sep_dump_message - dump the message that is pending + * @sep: SEP device + * This will only print dump if DEBUG is set; it does + * follow kernel debug print enabling + */ +static void _sep_dump_message(struct sep_device *sep) +{ + int count; + + u32 *p = sep->shared_addr; + + for (count = 0; count < 40 * 4; count += 4) + dev_dbg(&sep->pdev->dev, + "[PID%d] Word %d of the message is %x\n", + current->pid, count/4, *p++); +} +#endif + +/** + * sep_map_and_alloc_shared_area -allocate shared block + * @sep: security processor + * @size: size of shared area + */ +static int sep_map_and_alloc_shared_area(struct sep_device *sep) +{ + sep->shared_addr = dma_alloc_coherent(&sep->pdev->dev, + sep->shared_size, + &sep->shared_bus, GFP_KERNEL); + + if (!sep->shared_addr) { + dev_dbg(&sep->pdev->dev, + "[PID%d] shared memory dma_alloc_coherent failed\n", + current->pid); + return -ENOMEM; + } + dev_dbg(&sep->pdev->dev, + "[PID%d] shared_addr %zx bytes @%p (bus %llx)\n", + current->pid, + sep->shared_size, sep->shared_addr, + (unsigned long long)sep->shared_bus); + return 0; +} + +/** + * sep_unmap_and_free_shared_area - free shared block + * @sep: security processor + */ +static void sep_unmap_and_free_shared_area(struct sep_device *sep) +{ + dma_free_coherent(&sep->pdev->dev, sep->shared_size, + sep->shared_addr, sep->shared_bus); +} + +/** + * sep_shared_bus_to_virt - convert bus/virt addresses + * @sep: pointer to struct sep_device + * @bus_address: address to convert + * + * Returns virtual address inside the shared area according + * to the bus address. + */ +static void *sep_shared_bus_to_virt(struct sep_device *sep, + dma_addr_t bus_address) +{ + return sep->shared_addr + (bus_address - sep->shared_bus); +} + +/** + * sep_open - device open method + * @inode: inode of SEP device + * @filp: file handle to SEP device + * + * Open method for the SEP device. Called when userspace opens + * the SEP device node. + * + * Returns zero on success otherwise an error code. + */ +static int sep_open(struct inode *inode, struct file *filp) +{ + struct sep_device *sep; + struct sep_private_data *priv; + + dev_dbg(&sep_dev->pdev->dev, "[PID%d] open\n", current->pid); + + if (filp->f_flags & O_NONBLOCK) + return -ENOTSUPP; + + /* + * Get the SEP device structure and use it for the + * private_data field in filp for other methods + */ + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + sep = sep_dev; + priv->device = sep; + filp->private_data = priv; + + dev_dbg(&sep_dev->pdev->dev, "[PID%d] priv is 0x%p\n", + current->pid, priv); + + /* Anyone can open; locking takes place at transaction level */ + return 0; +} + +/** + * sep_free_dma_table_data_handler - free DMA table + * @sep: pointere to struct sep_device + * @dma_ctx: dma context + * + * Handles the request to free DMA table for synchronic actions + */ +int sep_free_dma_table_data_handler(struct sep_device *sep, + struct sep_dma_context **dma_ctx) +{ + int count; + int dcb_counter; + /* Pointer to the current dma_resource struct */ + struct sep_dma_resource *dma; + + dev_dbg(&sep->pdev->dev, + "[PID%d] sep_free_dma_table_data_handler\n", + current->pid); + + if (!dma_ctx || !(*dma_ctx)) { + /* No context or context already freed */ + dev_dbg(&sep->pdev->dev, + "[PID%d] no DMA context or context already freed\n", + current->pid); + + return 0; + } + + dev_dbg(&sep->pdev->dev, "[PID%d] (*dma_ctx)->nr_dcb_creat 0x%x\n", + current->pid, + (*dma_ctx)->nr_dcb_creat); + + for (dcb_counter = 0; + dcb_counter < (*dma_ctx)->nr_dcb_creat; dcb_counter++) { + dma = &(*dma_ctx)->dma_res_arr[dcb_counter]; + + /* Unmap and free input map array */ + if (dma->in_map_array) { + for (count = 0; count < dma->in_num_pages; count++) { + dma_unmap_page(&sep->pdev->dev, + dma->in_map_array[count].dma_addr, + dma->in_map_array[count].size, + DMA_TO_DEVICE); + } + kfree(dma->in_map_array); + } + + /* Unmap output map array, DON'T free it yet */ + if (dma->out_map_array) { + for (count = 0; count < dma->out_num_pages; count++) { + dma_unmap_page(&sep->pdev->dev, + dma->out_map_array[count].dma_addr, + dma->out_map_array[count].size, + DMA_FROM_DEVICE); + } + kfree(dma->out_map_array); + } + + /* Free page cache for output */ + if (dma->in_page_array) { + for (count = 0; count < dma->in_num_pages; count++) { + flush_dcache_page(dma->in_page_array[count]); + page_cache_release(dma->in_page_array[count]); + } + kfree(dma->in_page_array); + } + + if (dma->out_page_array) { + for (count = 0; count < dma->out_num_pages; count++) { + if (!PageReserved(dma->out_page_array[count])) + + SetPageDirty(dma-> + out_page_array[count]); + + flush_dcache_page(dma->out_page_array[count]); + page_cache_release(dma->out_page_array[count]); + } + kfree(dma->out_page_array); + } + + /** + * Note that here we use in_map_num_entries because we + * don't have a page array; the page array is generated + * only in the lock_user_pages, which is not called + * for kernel crypto, which is what the sg (scatter gather + * is used for exclusively + */ + if (dma->src_sg) { + dma_unmap_sg(&sep->pdev->dev, dma->src_sg, + dma->in_map_num_entries, DMA_TO_DEVICE); + dma->src_sg = NULL; + } + + if (dma->dst_sg) { + dma_unmap_sg(&sep->pdev->dev, dma->dst_sg, + dma->in_map_num_entries, DMA_FROM_DEVICE); + dma->dst_sg = NULL; + } + + /* Reset all the values */ + dma->in_page_array = NULL; + dma->out_page_array = NULL; + dma->in_num_pages = 0; + dma->out_num_pages = 0; + dma->in_map_array = NULL; + dma->out_map_array = NULL; + dma->in_map_num_entries = 0; + dma->out_map_num_entries = 0; + } + + (*dma_ctx)->nr_dcb_creat = 0; + (*dma_ctx)->num_lli_tables_created = 0; + + kfree(*dma_ctx); + *dma_ctx = NULL; + + dev_dbg(&sep->pdev->dev, + "[PID%d] sep_free_dma_table_data_handler end\n", + current->pid); + + return 0; +} + +/** + * sep_end_transaction_handler - end transaction + * @sep: pointer to struct sep_device + * @dma_ctx: DMA context + * @call_status: Call status + * + * This API handles the end transaction request. + */ +static int sep_end_transaction_handler(struct sep_device *sep, + struct sep_dma_context **dma_ctx, + struct sep_call_status *call_status, + struct sep_queue_info **my_queue_elem) +{ + dev_dbg(&sep->pdev->dev, "[PID%d] ending transaction\n", current->pid); + + /* + * Extraneous transaction clearing would mess up PM + * device usage counters and SEP would get suspended + * just before we send a command to SEP in the next + * transaction + * */ + if (sep_check_transaction_owner(sep)) { + dev_dbg(&sep->pdev->dev, "[PID%d] not transaction owner\n", + current->pid); + return 0; + } + + /* Update queue status */ + sep_queue_status_remove(sep, my_queue_elem); + + /* Check that all the DMA resources were freed */ + if (dma_ctx) + sep_free_dma_table_data_handler(sep, dma_ctx); + + /* Reset call status for next transaction */ + if (call_status) + call_status->status = 0; + + /* Clear the message area to avoid next transaction reading + * sensitive results from previous transaction */ + memset(sep->shared_addr, 0, + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); + + /* start suspend delay */ +#ifdef SEP_ENABLE_RUNTIME_PM + if (sep->in_use) { + sep->in_use = 0; + pm_runtime_mark_last_busy(&sep->pdev->dev); + pm_runtime_put_autosuspend(&sep->pdev->dev); + } +#endif + + clear_bit(SEP_WORKING_LOCK_BIT, &sep->in_use_flags); + sep->pid_doing_transaction = 0; + + /* Now it's safe for next process to proceed */ + dev_dbg(&sep->pdev->dev, "[PID%d] waking up next transaction\n", + current->pid); + clear_bit(SEP_TRANSACTION_STARTED_LOCK_BIT, &sep->in_use_flags); + wake_up(&sep->event_transactions); + + return 0; +} + + +/** + * sep_release - close a SEP device + * @inode: inode of SEP device + * @filp: file handle being closed + * + * Called on the final close of a SEP device. + */ +static int sep_release(struct inode *inode, struct file *filp) +{ + struct sep_private_data * const private_data = filp->private_data; + struct sep_call_status *call_status = &private_data->call_status; + struct sep_device *sep = private_data->device; + struct sep_dma_context **dma_ctx = &private_data->dma_ctx; + struct sep_queue_info **my_queue_elem = &private_data->my_queue_elem; + + dev_dbg(&sep->pdev->dev, "[PID%d] release\n", current->pid); + + sep_end_transaction_handler(sep, dma_ctx, call_status, + my_queue_elem); + + kfree(filp->private_data); + + return 0; +} + +/** + * sep_mmap - maps the shared area to user space + * @filp: pointer to struct file + * @vma: pointer to vm_area_struct + * + * Called on an mmap of our space via the normal SEP device + */ +static int sep_mmap(struct file *filp, struct vm_area_struct *vma) +{ + struct sep_private_data * const private_data = filp->private_data; + struct sep_call_status *call_status = &private_data->call_status; + struct sep_device *sep = private_data->device; + struct sep_queue_info **my_queue_elem = &private_data->my_queue_elem; + dma_addr_t bus_addr; + unsigned long error = 0; + + dev_dbg(&sep->pdev->dev, "[PID%d] sep_mmap\n", current->pid); + + /* Set the transaction busy (own the device) */ + /* + * Problem for multithreaded applications is that here we're + * possibly going to sleep while holding a write lock on + * current->mm->mmap_sem, which will cause deadlock for ongoing + * transaction trying to create DMA tables + */ + error = sep_wait_transaction(sep); + if (error) + /* Interrupted by signal, don't clear transaction */ + goto end_function; + + /* Clear the message area to avoid next transaction reading + * sensitive results from previous transaction */ + memset(sep->shared_addr, 0, + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); + + /* + * Check that the size of the mapped range is as the size of the message + * shared area + */ + if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) { + error = -EINVAL; + goto end_function_with_error; + } + + dev_dbg(&sep->pdev->dev, "[PID%d] shared_addr is %p\n", + current->pid, sep->shared_addr); + + /* Get bus address */ + bus_addr = sep->shared_bus; + + if (remap_pfn_range(vma, vma->vm_start, bus_addr >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, vma->vm_page_prot)) { + dev_dbg(&sep->pdev->dev, "[PID%d] remap_page_range failed\n", + current->pid); + error = -EAGAIN; + goto end_function_with_error; + } + + /* Update call status */ + set_bit(SEP_LEGACY_MMAP_DONE_OFFSET, &call_status->status); + + goto end_function; + +end_function_with_error: + /* Clear our transaction */ + sep_end_transaction_handler(sep, NULL, call_status, + my_queue_elem); + +end_function: + return error; +} + +/** + * sep_poll - poll handler + * @filp: pointer to struct file + * @wait: pointer to poll_table + * + * Called by the OS when the kernel is asked to do a poll on + * a SEP file handle. + */ +static unsigned int sep_poll(struct file *filp, poll_table *wait) +{ + struct sep_private_data * const private_data = filp->private_data; + struct sep_call_status *call_status = &private_data->call_status; + struct sep_device *sep = private_data->device; + u32 mask = 0; + u32 retval = 0; + u32 retval2 = 0; + unsigned long lock_irq_flag; + + /* Am I the process that owns the transaction? */ + if (sep_check_transaction_owner(sep)) { + dev_dbg(&sep->pdev->dev, "[PID%d] poll pid not owner\n", + current->pid); + mask = POLLERR; + goto end_function; + } + + /* Check if send command or send_reply were activated previously */ + if (0 == test_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET, + &call_status->status)) { + dev_warn(&sep->pdev->dev, "[PID%d] sendmsg not called\n", + current->pid); + mask = POLLERR; + goto end_function; + } + + + /* Add the event to the polling wait table */ + dev_dbg(&sep->pdev->dev, "[PID%d] poll: calling wait sep_event\n", + current->pid); + + poll_wait(filp, &sep->event_interrupt, wait); + + dev_dbg(&sep->pdev->dev, + "[PID%d] poll: send_ct is %lx reply ct is %lx\n", + current->pid, sep->send_ct, sep->reply_ct); + + /* Check if error occured during poll */ + retval2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); + if ((retval2 != 0x0) && (retval2 != 0x8)) { + dev_dbg(&sep->pdev->dev, "[PID%d] poll; poll error %x\n", + current->pid, retval2); + mask |= POLLERR; + goto end_function; + } + + spin_lock_irqsave(&sep->snd_rply_lck, lock_irq_flag); + + if (sep->send_ct == sep->reply_ct) { + spin_unlock_irqrestore(&sep->snd_rply_lck, lock_irq_flag); + retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); + dev_dbg(&sep->pdev->dev, + "[PID%d] poll: data ready check (GPR2) %x\n", + current->pid, retval); + + /* Check if printf request */ + if ((retval >> 30) & 0x1) { + dev_dbg(&sep->pdev->dev, + "[PID%d] poll: SEP printf request\n", + current->pid); + goto end_function; + } + + /* Check if the this is SEP reply or request */ + if (retval >> 31) { + dev_dbg(&sep->pdev->dev, + "[PID%d] poll: SEP request\n", + current->pid); + } else { + dev_dbg(&sep->pdev->dev, + "[PID%d] poll: normal return\n", + current->pid); + sep_dump_message(sep); + dev_dbg(&sep->pdev->dev, + "[PID%d] poll; SEP reply POLLIN|POLLRDNORM\n", + current->pid); + mask |= POLLIN | POLLRDNORM; + } + set_bit(SEP_LEGACY_POLL_DONE_OFFSET, &call_status->status); + } else { + spin_unlock_irqrestore(&sep->snd_rply_lck, lock_irq_flag); + dev_dbg(&sep->pdev->dev, + "[PID%d] poll; no reply; returning mask of 0\n", + current->pid); + mask = 0; + } + +end_function: + return mask; +} + +/** + * sep_time_address - address in SEP memory of time + * @sep: SEP device we want the address from + * + * Return the address of the two dwords in memory used for time + * setting. + */ +static u32 *sep_time_address(struct sep_device *sep) +{ + return sep->shared_addr + + SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES; +} + +/** + * sep_set_time - set the SEP time + * @sep: the SEP we are setting the time for + * + * Calculates time and sets it at the predefined address. + * Called with the SEP mutex held. + */ +static unsigned long sep_set_time(struct sep_device *sep) +{ + struct timeval time; + u32 *time_addr; /* Address of time as seen by the kernel */ + + + do_gettimeofday(&time); + + /* Set value in the SYSTEM MEMORY offset */ + time_addr = sep_time_address(sep); + + time_addr[0] = SEP_TIME_VAL_TOKEN; + time_addr[1] = time.tv_sec; + + dev_dbg(&sep->pdev->dev, "[PID%d] time.tv_sec is %lu\n", + current->pid, time.tv_sec); + dev_dbg(&sep->pdev->dev, "[PID%d] time_addr is %p\n", + current->pid, time_addr); + dev_dbg(&sep->pdev->dev, "[PID%d] sep->shared_addr is %p\n", + current->pid, sep->shared_addr); + + return time.tv_sec; +} + +/** + * sep_send_command_handler - kick off a command + * @sep: SEP being signalled + * + * This function raises interrupt to SEP that signals that is has a new + * command from the host + * + * Note that this function does fall under the ioctl lock + */ +int sep_send_command_handler(struct sep_device *sep) +{ + unsigned long lock_irq_flag; + u32 *msg_pool; + int error = 0; + + /* Basic sanity check; set msg pool to start of shared area */ + msg_pool = (u32 *)sep->shared_addr; + msg_pool += 2; + + /* Look for start msg token */ + if (*msg_pool != SEP_START_MSG_TOKEN) { + dev_warn(&sep->pdev->dev, "start message token not present\n"); + error = -EPROTO; + goto end_function; + } + + /* Do we have a reasonable size? */ + msg_pool += 1; + if ((*msg_pool < 2) || + (*msg_pool > SEP_DRIVER_MAX_MESSAGE_SIZE_IN_BYTES)) { + + dev_warn(&sep->pdev->dev, "invalid message size\n"); + error = -EPROTO; + goto end_function; + } + + /* Does the command look reasonable? */ + msg_pool += 1; + if (*msg_pool < 2) { + dev_warn(&sep->pdev->dev, "invalid message opcode\n"); + error = -EPROTO; + goto end_function; + } + +#if defined(CONFIG_PM_RUNTIME) && defined(SEP_ENABLE_RUNTIME_PM) + dev_dbg(&sep->pdev->dev, "[PID%d] before pm sync status 0x%X\n", + current->pid, + sep->pdev->dev.power.runtime_status); + sep->in_use = 1; /* device is about to be used */ + pm_runtime_get_sync(&sep->pdev->dev); +#endif + + if (test_and_set_bit(SEP_WORKING_LOCK_BIT, &sep->in_use_flags)) { + error = -EPROTO; + goto end_function; + } + sep->in_use = 1; /* device is about to be used */ + sep_set_time(sep); + + sep_dump_message(sep); + + /* Update counter */ + spin_lock_irqsave(&sep->snd_rply_lck, lock_irq_flag); + sep->send_ct++; + spin_unlock_irqrestore(&sep->snd_rply_lck, lock_irq_flag); + + dev_dbg(&sep->pdev->dev, + "[PID%d] sep_send_command_handler send_ct %lx reply_ct %lx\n", + current->pid, sep->send_ct, sep->reply_ct); + + /* Send interrupt to SEP */ + sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2); + +end_function: + return error; +} + +/** + * sep_crypto_dma - + * @sep: pointer to struct sep_device + * @sg: pointer to struct scatterlist + * @direction: + * @dma_maps: pointer to place a pointer to array of dma maps + * This is filled in; anything previous there will be lost + * The structure for dma maps is sep_dma_map + * @returns number of dma maps on success; negative on error + * + * This creates the dma table from the scatterlist + * It is used only for kernel crypto as it works with scatterlists + * representation of data buffers + * + */ +static int sep_crypto_dma( + struct sep_device *sep, + struct scatterlist *sg, + struct sep_dma_map **dma_maps, + enum dma_data_direction direction) +{ + struct scatterlist *temp_sg; + + u32 count_segment; + u32 count_mapped; + struct sep_dma_map *sep_dma; + int ct1; + + if (sg->length == 0) + return 0; + + /* Count the segments */ + temp_sg = sg; + count_segment = 0; + while (temp_sg) { + count_segment += 1; + temp_sg = scatterwalk_sg_next(temp_sg); + } + dev_dbg(&sep->pdev->dev, + "There are (hex) %x segments in sg\n", count_segment); + + /* DMA map segments */ + count_mapped = dma_map_sg(&sep->pdev->dev, sg, + count_segment, direction); + + dev_dbg(&sep->pdev->dev, + "There are (hex) %x maps in sg\n", count_mapped); + + if (count_mapped == 0) { + dev_dbg(&sep->pdev->dev, "Cannot dma_map_sg\n"); + return -ENOMEM; + } + + sep_dma = kmalloc(sizeof(struct sep_dma_map) * + count_mapped, GFP_ATOMIC); + + if (sep_dma == NULL) { + dev_dbg(&sep->pdev->dev, "Cannot allocate dma_maps\n"); + return -ENOMEM; + } + + for_each_sg(sg, temp_sg, count_mapped, ct1) { + sep_dma[ct1].dma_addr = sg_dma_address(temp_sg); + sep_dma[ct1].size = sg_dma_len(temp_sg); + dev_dbg(&sep->pdev->dev, "(all hex) map %x dma %lx len %lx\n", + ct1, (unsigned long)sep_dma[ct1].dma_addr, + (unsigned long)sep_dma[ct1].size); + } + + *dma_maps = sep_dma; + return count_mapped; + +} + +/** + * sep_crypto_lli - + * @sep: pointer to struct sep_device + * @sg: pointer to struct scatterlist + * @data_size: total data size + * @direction: + * @dma_maps: pointer to place a pointer to array of dma maps + * This is filled in; anything previous there will be lost + * The structure for dma maps is sep_dma_map + * @lli_maps: pointer to place a pointer to array of lli maps + * This is filled in; anything previous there will be lost + * The structure for dma maps is sep_dma_map + * @returns number of dma maps on success; negative on error + * + * This creates the LLI table from the scatterlist + * It is only used for kernel crypto as it works exclusively + * with scatterlists (struct scatterlist) representation of + * data buffers + */ +static int sep_crypto_lli( + struct sep_device *sep, + struct scatterlist *sg, + struct sep_dma_map **maps, + struct sep_lli_entry **llis, + u32 data_size, + enum dma_data_direction direction) +{ + + int ct1; + struct sep_lli_entry *sep_lli; + struct sep_dma_map *sep_map; + + int nbr_ents; + + nbr_ents = sep_crypto_dma(sep, sg, maps, direction); + if (nbr_ents <= 0) { + dev_dbg(&sep->pdev->dev, "crypto_dma failed %x\n", + nbr_ents); + return nbr_ents; + } + + sep_map = *maps; + + sep_lli = kmalloc(sizeof(struct sep_lli_entry) * nbr_ents, GFP_ATOMIC); + + if (sep_lli == NULL) { + dev_dbg(&sep->pdev->dev, "Cannot allocate lli_maps\n"); + + kfree(*maps); + *maps = NULL; + return -ENOMEM; + } + + for (ct1 = 0; ct1 < nbr_ents; ct1 += 1) { + sep_lli[ct1].bus_address = (u32)sep_map[ct1].dma_addr; + + /* Maximum for page is total data size */ + if (sep_map[ct1].size > data_size) + sep_map[ct1].size = data_size; + + sep_lli[ct1].block_size = (u32)sep_map[ct1].size; + } + + *llis = sep_lli; + return nbr_ents; +} + +/** + * sep_lock_kernel_pages - map kernel pages for DMA + * @sep: pointer to struct sep_device + * @kernel_virt_addr: address of data buffer in kernel + * @data_size: size of data + * @lli_array_ptr: lli array + * @in_out_flag: input into device or output from device + * + * This function locks all the physical pages of the kernel virtual buffer + * and construct a basic lli array, where each entry holds the physical + * page address and the size that application data holds in this page + * This function is used only during kernel crypto mod calls from within + * the kernel (when ioctl is not used) + * + * This is used only for kernel crypto. Kernel pages + * are handled differently as they are done via + * scatter gather lists (struct scatterlist) + */ +static int sep_lock_kernel_pages(struct sep_device *sep, + unsigned long kernel_virt_addr, + u32 data_size, + struct sep_lli_entry **lli_array_ptr, + int in_out_flag, + struct sep_dma_context *dma_ctx) + +{ + u32 num_pages; + struct scatterlist *sg; + + /* Array of lli */ + struct sep_lli_entry *lli_array; + /* Map array */ + struct sep_dma_map *map_array; + + enum dma_data_direction direction; + + lli_array = NULL; + map_array = NULL; + + if (in_out_flag == SEP_DRIVER_IN_FLAG) { + direction = DMA_TO_DEVICE; + sg = dma_ctx->src_sg; + } else { + direction = DMA_FROM_DEVICE; + sg = dma_ctx->dst_sg; + } + + num_pages = sep_crypto_lli(sep, sg, &map_array, &lli_array, + data_size, direction); + + if (num_pages <= 0) { + dev_dbg(&sep->pdev->dev, "sep_crypto_lli returned error %x\n", + num_pages); + return -ENOMEM; + } + + /* Put mapped kernel sg into kernel resource array */ + + /* Set output params acording to the in_out flag */ + if (in_out_flag == SEP_DRIVER_IN_FLAG) { + *lli_array_ptr = lli_array; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages = + num_pages; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array = + NULL; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array = + map_array; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_num_entries = + num_pages; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].src_sg = + dma_ctx->src_sg; + } else { + *lli_array_ptr = lli_array; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_num_pages = + num_pages; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_page_array = + NULL; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_map_array = + map_array; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat]. + out_map_num_entries = num_pages; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].dst_sg = + dma_ctx->dst_sg; + } + + return 0; +} + +/** + * sep_lock_user_pages - lock and map user pages for DMA + * @sep: pointer to struct sep_device + * @app_virt_addr: user memory data buffer + * @data_size: size of data buffer + * @lli_array_ptr: lli array + * @in_out_flag: input or output to device + * + * This function locks all the physical pages of the application + * virtual buffer and construct a basic lli array, where each entry + * holds the physical page address and the size that application + * data holds in this physical pages + */ +static int sep_lock_user_pages(struct sep_device *sep, + u32 app_virt_addr, + u32 data_size, + struct sep_lli_entry **lli_array_ptr, + int in_out_flag, + struct sep_dma_context *dma_ctx) + +{ + int error = 0; + u32 count; + int result; + /* The the page of the end address of the user space buffer */ + u32 end_page; + /* The page of the start address of the user space buffer */ + u32 start_page; + /* The range in pages */ + u32 num_pages; + /* Array of pointers to page */ + struct page **page_array; + /* Array of lli */ + struct sep_lli_entry *lli_array; + /* Map array */ + struct sep_dma_map *map_array; + + /* Set start and end pages and num pages */ + end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT; + start_page = app_virt_addr >> PAGE_SHIFT; + num_pages = end_page - start_page + 1; + + dev_dbg(&sep->pdev->dev, + "[PID%d] lock user pages app_virt_addr is %x\n", + current->pid, app_virt_addr); + + dev_dbg(&sep->pdev->dev, "[PID%d] data_size is (hex) %x\n", + current->pid, data_size); + dev_dbg(&sep->pdev->dev, "[PID%d] start_page is (hex) %x\n", + current->pid, start_page); + dev_dbg(&sep->pdev->dev, "[PID%d] end_page is (hex) %x\n", + current->pid, end_page); + dev_dbg(&sep->pdev->dev, "[PID%d] num_pages is (hex) %x\n", + current->pid, num_pages); + + /* Allocate array of pages structure pointers */ + page_array = kmalloc(sizeof(struct page *) * num_pages, GFP_ATOMIC); + if (!page_array) { + error = -ENOMEM; + goto end_function; + } + map_array = kmalloc(sizeof(struct sep_dma_map) * num_pages, GFP_ATOMIC); + if (!map_array) { + dev_warn(&sep->pdev->dev, + "[PID%d] kmalloc for map_array failed\n", + current->pid); + error = -ENOMEM; + goto end_function_with_error1; + } + + lli_array = kmalloc(sizeof(struct sep_lli_entry) * num_pages, + GFP_ATOMIC); + + if (!lli_array) { + dev_warn(&sep->pdev->dev, + "[PID%d] kmalloc for lli_array failed\n", + current->pid); + error = -ENOMEM; + goto end_function_with_error2; + } + + /* Convert the application virtual address into a set of physical */ + down_read(¤t->mm->mmap_sem); + result = get_user_pages(current, current->mm, app_virt_addr, + num_pages, + ((in_out_flag == SEP_DRIVER_IN_FLAG) ? 0 : 1), + 0, page_array, NULL); + + up_read(¤t->mm->mmap_sem); + + /* Check the number of pages locked - if not all then exit with error */ + if (result != num_pages) { + dev_warn(&sep->pdev->dev, + "[PID%d] not all pages locked by get_user_pages, " + "result 0x%X, num_pages 0x%X\n", + current->pid, result, num_pages); + error = -ENOMEM; + goto end_function_with_error3; + } + + dev_dbg(&sep->pdev->dev, "[PID%d] get_user_pages succeeded\n", + current->pid); + + /* + * Fill the array using page array data and + * map the pages - this action will also flush the cache as needed + */ + for (count = 0; count < num_pages; count++) { + /* Fill the map array */ + map_array[count].dma_addr = + dma_map_page(&sep->pdev->dev, page_array[count], + 0, PAGE_SIZE, DMA_BIDIRECTIONAL); + + map_array[count].size = PAGE_SIZE; + + /* Fill the lli array entry */ + lli_array[count].bus_address = (u32)map_array[count].dma_addr; + lli_array[count].block_size = PAGE_SIZE; + + dev_dbg(&sep->pdev->dev, + "[PID%d] lli_array[%x].bus_address is %08lx, " + "lli_array[%x].block_size is (hex) %x\n", current->pid, + count, (unsigned long)lli_array[count].bus_address, + count, lli_array[count].block_size); + } + + /* Check the offset for the first page */ + lli_array[0].bus_address = + lli_array[0].bus_address + (app_virt_addr & (~PAGE_MASK)); + + /* Check that not all the data is in the first page only */ + if ((PAGE_SIZE - (app_virt_addr & (~PAGE_MASK))) >= data_size) + lli_array[0].block_size = data_size; + else + lli_array[0].block_size = + PAGE_SIZE - (app_virt_addr & (~PAGE_MASK)); + + dev_dbg(&sep->pdev->dev, + "[PID%d] After check if page 0 has all data\n", + current->pid); + dev_dbg(&sep->pdev->dev, + "[PID%d] lli_array[0].bus_address is (hex) %08lx, " + "lli_array[0].block_size is (hex) %x\n", + current->pid, + (unsigned long)lli_array[0].bus_address, + lli_array[0].block_size); + + + /* Check the size of the last page */ + if (num_pages > 1) { + lli_array[num_pages - 1].block_size = + (app_virt_addr + data_size) & (~PAGE_MASK); + if (lli_array[num_pages - 1].block_size == 0) + lli_array[num_pages - 1].block_size = PAGE_SIZE; + + dev_dbg(&sep->pdev->dev, + "[PID%d] After last page size adjustment\n", + current->pid); + dev_dbg(&sep->pdev->dev, + "[PID%d] lli_array[%x].bus_address is (hex) %08lx, " + "lli_array[%x].block_size is (hex) %x\n", + current->pid, + num_pages - 1, + (unsigned long)lli_array[num_pages - 1].bus_address, + num_pages - 1, + lli_array[num_pages - 1].block_size); + } + + /* Set output params acording to the in_out flag */ + if (in_out_flag == SEP_DRIVER_IN_FLAG) { + *lli_array_ptr = lli_array; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages = + num_pages; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array = + page_array; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array = + map_array; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_num_entries = + num_pages; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].src_sg = NULL; + } else { + *lli_array_ptr = lli_array; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_num_pages = + num_pages; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_page_array = + page_array; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_map_array = + map_array; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat]. + out_map_num_entries = num_pages; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].dst_sg = NULL; + } + goto end_function; + +end_function_with_error3: + /* Free lli array */ + kfree(lli_array); + +end_function_with_error2: + kfree(map_array); + +end_function_with_error1: + /* Free page array */ + kfree(page_array); + +end_function: + return error; +} + +/** + * sep_calculate_lli_table_max_size - size the LLI table + * @sep: pointer to struct sep_device + * @lli_in_array_ptr + * @num_array_entries + * @last_table_flag + * + * This function calculates the size of data that can be inserted into + * the lli table from this array, such that either the table is full + * (all entries are entered), or there are no more entries in the + * lli array + */ +static u32 sep_calculate_lli_table_max_size(struct sep_device *sep, + struct sep_lli_entry *lli_in_array_ptr, + u32 num_array_entries, + u32 *last_table_flag) +{ + u32 counter; + /* Table data size */ + u32 table_data_size = 0; + /* Data size for the next table */ + u32 next_table_data_size; + + *last_table_flag = 0; + + /* + * Calculate the data in the out lli table till we fill the whole + * table or till the data has ended + */ + for (counter = 0; + (counter < (SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP - 1)) && + (counter < num_array_entries); counter++) + table_data_size += lli_in_array_ptr[counter].block_size; + + /* + * Check if we reached the last entry, + * meaning this ia the last table to build, + * and no need to check the block alignment + */ + if (counter == num_array_entries) { + /* Set the last table flag */ + *last_table_flag = 1; + goto end_function; + } + + /* + * Calculate the data size of the next table. + * Stop if no entries left or if data size is more the DMA restriction + */ + next_table_data_size = 0; + for (; counter < num_array_entries; counter++) { + next_table_data_size += lli_in_array_ptr[counter].block_size; + if (next_table_data_size >= SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE) + break; + } + + /* + * Check if the next table data size is less then DMA rstriction. + * if it is - recalculate the current table size, so that the next + * table data size will be adaquete for DMA + */ + if (next_table_data_size && + next_table_data_size < SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE) + + table_data_size -= (SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE - + next_table_data_size); + +end_function: + return table_data_size; +} + +/** + * sep_build_lli_table - build an lli array for the given table + * @sep: pointer to struct sep_device + * @lli_array_ptr: pointer to lli array + * @lli_table_ptr: pointer to lli table + * @num_processed_entries_ptr: pointer to number of entries + * @num_table_entries_ptr: pointer to number of tables + * @table_data_size: total data size + * + * Builds ant lli table from the lli_array according to + * the given size of data + */ +static void sep_build_lli_table(struct sep_device *sep, + struct sep_lli_entry *lli_array_ptr, + struct sep_lli_entry *lli_table_ptr, + u32 *num_processed_entries_ptr, + u32 *num_table_entries_ptr, + u32 table_data_size) +{ + /* Current table data size */ + u32 curr_table_data_size; + /* Counter of lli array entry */ + u32 array_counter; + + /* Init current table data size and lli array entry counter */ + curr_table_data_size = 0; + array_counter = 0; + *num_table_entries_ptr = 1; + + dev_dbg(&sep->pdev->dev, + "[PID%d] build lli table table_data_size: (hex) %x\n", + current->pid, table_data_size); + + /* Fill the table till table size reaches the needed amount */ + while (curr_table_data_size < table_data_size) { + /* Update the number of entries in table */ + (*num_table_entries_ptr)++; + + lli_table_ptr->bus_address = + cpu_to_le32(lli_array_ptr[array_counter].bus_address); + + lli_table_ptr->block_size = + cpu_to_le32(lli_array_ptr[array_counter].block_size); + + curr_table_data_size += lli_array_ptr[array_counter].block_size; + + dev_dbg(&sep->pdev->dev, + "[PID%d] lli_table_ptr is %p\n", + current->pid, lli_table_ptr); + dev_dbg(&sep->pdev->dev, + "[PID%d] lli_table_ptr->bus_address: %08lx\n", + current->pid, + (unsigned long)lli_table_ptr->bus_address); + + dev_dbg(&sep->pdev->dev, + "[PID%d] lli_table_ptr->block_size is (hex) %x\n", + current->pid, lli_table_ptr->block_size); + + /* Check for overflow of the table data */ + if (curr_table_data_size > table_data_size) { + dev_dbg(&sep->pdev->dev, + "[PID%d] curr_table_data_size too large\n", + current->pid); + + /* Update the size of block in the table */ + lli_table_ptr->block_size = + cpu_to_le32(lli_table_ptr->block_size) - + (curr_table_data_size - table_data_size); + + /* Update the physical address in the lli array */ + lli_array_ptr[array_counter].bus_address += + cpu_to_le32(lli_table_ptr->block_size); + + /* Update the block size left in the lli array */ + lli_array_ptr[array_counter].block_size = + (curr_table_data_size - table_data_size); + } else + /* Advance to the next entry in the lli_array */ + array_counter++; + + dev_dbg(&sep->pdev->dev, + "[PID%d] lli_table_ptr->bus_address is %08lx\n", + current->pid, + (unsigned long)lli_table_ptr->bus_address); + dev_dbg(&sep->pdev->dev, + "[PID%d] lli_table_ptr->block_size is (hex) %x\n", + current->pid, + lli_table_ptr->block_size); + + /* Move to the next entry in table */ + lli_table_ptr++; + } + + /* Set the info entry to default */ + lli_table_ptr->bus_address = 0xffffffff; + lli_table_ptr->block_size = 0; + + /* Set the output parameter */ + *num_processed_entries_ptr += array_counter; + +} + +/** + * sep_shared_area_virt_to_bus - map shared area to bus address + * @sep: pointer to struct sep_device + * @virt_address: virtual address to convert + * + * This functions returns the physical address inside shared area according + * to the virtual address. It can be either on the externa RAM device + * (ioremapped), or on the system RAM + * This implementation is for the external RAM + */ +static dma_addr_t sep_shared_area_virt_to_bus(struct sep_device *sep, + void *virt_address) +{ + dev_dbg(&sep->pdev->dev, "[PID%d] sh virt to phys v %p\n", + current->pid, virt_address); + dev_dbg(&sep->pdev->dev, "[PID%d] sh virt to phys p %08lx\n", + current->pid, + (unsigned long) + sep->shared_bus + (virt_address - sep->shared_addr)); + + return sep->shared_bus + (size_t)(virt_address - sep->shared_addr); +} + +/** + * sep_shared_area_bus_to_virt - map shared area bus address to kernel + * @sep: pointer to struct sep_device + * @bus_address: bus address to convert + * + * This functions returns the virtual address inside shared area + * according to the physical address. It can be either on the + * externa RAM device (ioremapped), or on the system RAM + * This implementation is for the external RAM + */ +static void *sep_shared_area_bus_to_virt(struct sep_device *sep, + dma_addr_t bus_address) +{ + dev_dbg(&sep->pdev->dev, "[PID%d] shared bus to virt b=%lx v=%lx\n", + current->pid, + (unsigned long)bus_address, (unsigned long)(sep->shared_addr + + (size_t)(bus_address - sep->shared_bus))); + + return sep->shared_addr + (size_t)(bus_address - sep->shared_bus); +} + +/** + * sep_debug_print_lli_tables - dump LLI table + * @sep: pointer to struct sep_device + * @lli_table_ptr: pointer to sep_lli_entry + * @num_table_entries: number of entries + * @table_data_size: total data size + * + * Walk the the list of the print created tables and print all the data + */ +static void sep_debug_print_lli_tables(struct sep_device *sep, + struct sep_lli_entry *lli_table_ptr, + unsigned long num_table_entries, + unsigned long table_data_size) +{ + unsigned long table_count = 1; + unsigned long entries_count = 0; + + dev_dbg(&sep->pdev->dev, "[PID%d] sep_debug_print_lli_tables start\n", + current->pid); + if (num_table_entries == 0) { + dev_dbg(&sep->pdev->dev, "[PID%d] no table to print\n", + current->pid); + return; + } + + while ((unsigned long) lli_table_ptr->bus_address != 0xffffffff) { + dev_dbg(&sep->pdev->dev, + "[PID%d] lli table %08lx, " + "table_data_size is (hex) %lx\n", + current->pid, table_count, table_data_size); + dev_dbg(&sep->pdev->dev, + "[PID%d] num_table_entries is (hex) %lx\n", + current->pid, num_table_entries); + + /* Print entries of the table (without info entry) */ + for (entries_count = 0; entries_count < num_table_entries; + entries_count++, lli_table_ptr++) { + + dev_dbg(&sep->pdev->dev, + "[PID%d] lli_table_ptr address is %08lx\n", + current->pid, + (unsigned long) lli_table_ptr); + + dev_dbg(&sep->pdev->dev, + "[PID%d] phys address is %08lx " + "block size is (hex) %x\n", current->pid, + (unsigned long)lli_table_ptr->bus_address, + lli_table_ptr->block_size); + } + + /* Point to the info entry */ + lli_table_ptr--; + + dev_dbg(&sep->pdev->dev, + "[PID%d] phys lli_table_ptr->block_size " + "is (hex) %x\n", + current->pid, + lli_table_ptr->block_size); + + dev_dbg(&sep->pdev->dev, + "[PID%d] phys lli_table_ptr->physical_address " + "is %08lx\n", + current->pid, + (unsigned long)lli_table_ptr->bus_address); + + + table_data_size = lli_table_ptr->block_size & 0xffffff; + num_table_entries = (lli_table_ptr->block_size >> 24) & 0xff; + + dev_dbg(&sep->pdev->dev, + "[PID%d] phys table_data_size is " + "(hex) %lx num_table_entries is" + " %lx bus_address is%lx\n", + current->pid, + table_data_size, + num_table_entries, + (unsigned long)lli_table_ptr->bus_address); + + if ((unsigned long)lli_table_ptr->bus_address != 0xffffffff) + lli_table_ptr = (struct sep_lli_entry *) + sep_shared_bus_to_virt(sep, + (unsigned long)lli_table_ptr->bus_address); + + table_count++; + } + dev_dbg(&sep->pdev->dev, "[PID%d] sep_debug_print_lli_tables end\n", + current->pid); +} + + +/** + * sep_prepare_empty_lli_table - create a blank LLI table + * @sep: pointer to struct sep_device + * @lli_table_addr_ptr: pointer to lli table + * @num_entries_ptr: pointer to number of entries + * @table_data_size_ptr: point to table data size + * @dmatables_region: Optional buffer for DMA tables + * @dma_ctx: DMA context + * + * This function creates empty lli tables when there is no data + */ +static void sep_prepare_empty_lli_table(struct sep_device *sep, + dma_addr_t *lli_table_addr_ptr, + u32 *num_entries_ptr, + u32 *table_data_size_ptr, + void **dmatables_region, + struct sep_dma_context *dma_ctx) +{ + struct sep_lli_entry *lli_table_ptr; + + /* Find the area for new table */ + lli_table_ptr = + (struct sep_lli_entry *)(sep->shared_addr + + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + + dma_ctx->num_lli_tables_created * sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); + + if (dmatables_region && *dmatables_region) + lli_table_ptr = *dmatables_region; + + lli_table_ptr->bus_address = 0; + lli_table_ptr->block_size = 0; + + lli_table_ptr++; + lli_table_ptr->bus_address = 0xFFFFFFFF; + lli_table_ptr->block_size = 0; + + /* Set the output parameter value */ + *lli_table_addr_ptr = sep->shared_bus + + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + + dma_ctx->num_lli_tables_created * + sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; + + /* Set the num of entries and table data size for empty table */ + *num_entries_ptr = 2; + *table_data_size_ptr = 0; + + /* Update the number of created tables */ + dma_ctx->num_lli_tables_created++; +} + +/** + * sep_prepare_input_dma_table - prepare input DMA mappings + * @sep: pointer to struct sep_device + * @data_size: + * @block_size: + * @lli_table_ptr: + * @num_entries_ptr: + * @table_data_size_ptr: + * @is_kva: set for kernel data (kernel cryptio call) + * + * This function prepares only input DMA table for synhronic symmetric + * operations (HASH) + * Note that all bus addresses that are passed to the SEP + * are in 32 bit format; the SEP is a 32 bit device + */ +static int sep_prepare_input_dma_table(struct sep_device *sep, + unsigned long app_virt_addr, + u32 data_size, + u32 block_size, + dma_addr_t *lli_table_ptr, + u32 *num_entries_ptr, + u32 *table_data_size_ptr, + bool is_kva, + void **dmatables_region, + struct sep_dma_context *dma_ctx +) +{ + int error = 0; + /* Pointer to the info entry of the table - the last entry */ + struct sep_lli_entry *info_entry_ptr; + /* Array of pointers to page */ + struct sep_lli_entry *lli_array_ptr; + /* Points to the first entry to be processed in the lli_in_array */ + u32 current_entry = 0; + /* Num entries in the virtual buffer */ + u32 sep_lli_entries = 0; + /* Lli table pointer */ + struct sep_lli_entry *in_lli_table_ptr; + /* The total data in one table */ + u32 table_data_size = 0; + /* Flag for last table */ + u32 last_table_flag = 0; + /* Number of entries in lli table */ + u32 num_entries_in_table = 0; + /* Next table address */ + void *lli_table_alloc_addr = NULL; + void *dma_lli_table_alloc_addr = NULL; + void *dma_in_lli_table_ptr = NULL; + + dev_dbg(&sep->pdev->dev, "[PID%d] prepare intput dma " + "tbl data size: (hex) %x\n", + current->pid, data_size); + + dev_dbg(&sep->pdev->dev, "[PID%d] block_size is (hex) %x\n", + current->pid, block_size); + + /* Initialize the pages pointers */ + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array = NULL; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages = 0; + + /* Set the kernel address for first table to be allocated */ + lli_table_alloc_addr = (void *)(sep->shared_addr + + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + + dma_ctx->num_lli_tables_created * sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); + + if (data_size == 0) { + if (dmatables_region) { + error = sep_allocate_dmatables_region(sep, + dmatables_region, + dma_ctx, + 1); + if (error) + return error; + } + /* Special case - create meptu table - 2 entries, zero data */ + sep_prepare_empty_lli_table(sep, lli_table_ptr, + num_entries_ptr, table_data_size_ptr, + dmatables_region, dma_ctx); + goto update_dcb_counter; + } + + /* Check if the pages are in Kernel Virtual Address layout */ + if (is_kva == true) + error = sep_lock_kernel_pages(sep, app_virt_addr, + data_size, &lli_array_ptr, SEP_DRIVER_IN_FLAG, + dma_ctx); + else + /* + * Lock the pages of the user buffer + * and translate them to pages + */ + error = sep_lock_user_pages(sep, app_virt_addr, + data_size, &lli_array_ptr, SEP_DRIVER_IN_FLAG, + dma_ctx); + + if (error) + goto end_function; + + dev_dbg(&sep->pdev->dev, + "[PID%d] output sep_in_num_pages is (hex) %x\n", + current->pid, + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages); + + current_entry = 0; + info_entry_ptr = NULL; + + sep_lli_entries = + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages; + + dma_lli_table_alloc_addr = lli_table_alloc_addr; + if (dmatables_region) { + error = sep_allocate_dmatables_region(sep, + dmatables_region, + dma_ctx, + sep_lli_entries); + if (error) + return error; + lli_table_alloc_addr = *dmatables_region; + } + + /* Loop till all the entries in in array are processed */ + while (current_entry < sep_lli_entries) { + + /* Set the new input and output tables */ + in_lli_table_ptr = + (struct sep_lli_entry *)lli_table_alloc_addr; + dma_in_lli_table_ptr = + (struct sep_lli_entry *)dma_lli_table_alloc_addr; + + lli_table_alloc_addr += sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; + dma_lli_table_alloc_addr += sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; + + if (dma_lli_table_alloc_addr > + ((void *)sep->shared_addr + + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + + SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES)) { + + error = -ENOMEM; + goto end_function_error; + + } + + /* Update the number of created tables */ + dma_ctx->num_lli_tables_created++; + + /* Calculate the maximum size of data for input table */ + table_data_size = sep_calculate_lli_table_max_size(sep, + &lli_array_ptr[current_entry], + (sep_lli_entries - current_entry), + &last_table_flag); + + /* + * If this is not the last table - + * then allign it to the block size + */ + if (!last_table_flag) + table_data_size = + (table_data_size / block_size) * block_size; + + dev_dbg(&sep->pdev->dev, + "[PID%d] output table_data_size is (hex) %x\n", + current->pid, + table_data_size); + + /* Construct input lli table */ + sep_build_lli_table(sep, &lli_array_ptr[current_entry], + in_lli_table_ptr, + ¤t_entry, &num_entries_in_table, table_data_size); + + if (info_entry_ptr == NULL) { + + /* Set the output parameters to physical addresses */ + *lli_table_ptr = sep_shared_area_virt_to_bus(sep, + dma_in_lli_table_ptr); + *num_entries_ptr = num_entries_in_table; + *table_data_size_ptr = table_data_size; + + dev_dbg(&sep->pdev->dev, + "[PID%d] output lli_table_in_ptr is %08lx\n", + current->pid, + (unsigned long)*lli_table_ptr); + + } else { + /* Update the info entry of the previous in table */ + info_entry_ptr->bus_address = + sep_shared_area_virt_to_bus(sep, + dma_in_lli_table_ptr); + info_entry_ptr->block_size = + ((num_entries_in_table) << 24) | + (table_data_size); + } + /* Save the pointer to the info entry of the current tables */ + info_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1; + } + /* Print input tables */ + if (!dmatables_region) { + sep_debug_print_lli_tables(sep, (struct sep_lli_entry *) + sep_shared_area_bus_to_virt(sep, *lli_table_ptr), + *num_entries_ptr, *table_data_size_ptr); + } + + /* The array of the pages */ + kfree(lli_array_ptr); + +update_dcb_counter: + /* Update DCB counter */ + dma_ctx->nr_dcb_creat++; + goto end_function; + +end_function_error: + /* Free all the allocated resources */ + kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array); + kfree(lli_array_ptr); + kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array); + +end_function: + return error; + +} + +/** + * sep_construct_dma_tables_from_lli - prepare AES/DES mappings + * @sep: pointer to struct sep_device + * @lli_in_array: + * @sep_in_lli_entries: + * @lli_out_array: + * @sep_out_lli_entries + * @block_size + * @lli_table_in_ptr + * @lli_table_out_ptr + * @in_num_entries_ptr + * @out_num_entries_ptr + * @table_data_size_ptr + * + * This function creates the input and output DMA tables for + * symmetric operations (AES/DES) according to the block + * size from LLI arays + * Note that all bus addresses that are passed to the SEP + * are in 32 bit format; the SEP is a 32 bit device + */ +static int sep_construct_dma_tables_from_lli( + struct sep_device *sep, + struct sep_lli_entry *lli_in_array, + u32 sep_in_lli_entries, + struct sep_lli_entry *lli_out_array, + u32 sep_out_lli_entries, + u32 block_size, + dma_addr_t *lli_table_in_ptr, + dma_addr_t *lli_table_out_ptr, + u32 *in_num_entries_ptr, + u32 *out_num_entries_ptr, + u32 *table_data_size_ptr, + void **dmatables_region, + struct sep_dma_context *dma_ctx) +{ + /* Points to the area where next lli table can be allocated */ + void *lli_table_alloc_addr = NULL; + /* + * Points to the area in shared region where next lli table + * can be allocated + */ + void *dma_lli_table_alloc_addr = NULL; + /* Input lli table in dmatables_region or shared region */ + struct sep_lli_entry *in_lli_table_ptr = NULL; + /* Input lli table location in the shared region */ + struct sep_lli_entry *dma_in_lli_table_ptr = NULL; + /* Output lli table in dmatables_region or shared region */ + struct sep_lli_entry *out_lli_table_ptr = NULL; + /* Output lli table location in the shared region */ + struct sep_lli_entry *dma_out_lli_table_ptr = NULL; + /* Pointer to the info entry of the table - the last entry */ + struct sep_lli_entry *info_in_entry_ptr = NULL; + /* Pointer to the info entry of the table - the last entry */ + struct sep_lli_entry *info_out_entry_ptr = NULL; + /* Points to the first entry to be processed in the lli_in_array */ + u32 current_in_entry = 0; + /* Points to the first entry to be processed in the lli_out_array */ + u32 current_out_entry = 0; + /* Max size of the input table */ + u32 in_table_data_size = 0; + /* Max size of the output table */ + u32 out_table_data_size = 0; + /* Flag te signifies if this is the last tables build */ + u32 last_table_flag = 0; + /* The data size that should be in table */ + u32 table_data_size = 0; + /* Number of etnries in the input table */ + u32 num_entries_in_table = 0; + /* Number of etnries in the output table */ + u32 num_entries_out_table = 0; + + if (!dma_ctx) { + dev_warn(&sep->pdev->dev, "DMA context uninitialized\n"); + return -EINVAL; + } + + /* Initiate to point after the message area */ + lli_table_alloc_addr = (void *)(sep->shared_addr + + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + + (dma_ctx->num_lli_tables_created * + (sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP))); + dma_lli_table_alloc_addr = lli_table_alloc_addr; + + if (dmatables_region) { + /* 2 for both in+out table */ + if (sep_allocate_dmatables_region(sep, + dmatables_region, + dma_ctx, + 2*sep_in_lli_entries)) + return -ENOMEM; + lli_table_alloc_addr = *dmatables_region; + } + + /* Loop till all the entries in in array are not processed */ + while (current_in_entry < sep_in_lli_entries) { + /* Set the new input and output tables */ + in_lli_table_ptr = + (struct sep_lli_entry *)lli_table_alloc_addr; + dma_in_lli_table_ptr = + (struct sep_lli_entry *)dma_lli_table_alloc_addr; + + lli_table_alloc_addr += sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; + dma_lli_table_alloc_addr += sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; + + /* Set the first output tables */ + out_lli_table_ptr = + (struct sep_lli_entry *)lli_table_alloc_addr; + dma_out_lli_table_ptr = + (struct sep_lli_entry *)dma_lli_table_alloc_addr; + + /* Check if the DMA table area limit was overrun */ + if ((dma_lli_table_alloc_addr + sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP) > + ((void *)sep->shared_addr + + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + + SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES)) { + + dev_warn(&sep->pdev->dev, "dma table limit overrun\n"); + return -ENOMEM; + } + + /* Update the number of the lli tables created */ + dma_ctx->num_lli_tables_created += 2; + + lli_table_alloc_addr += sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; + dma_lli_table_alloc_addr += sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; + + /* Calculate the maximum size of data for input table */ + in_table_data_size = + sep_calculate_lli_table_max_size(sep, + &lli_in_array[current_in_entry], + (sep_in_lli_entries - current_in_entry), + &last_table_flag); + + /* Calculate the maximum size of data for output table */ + out_table_data_size = + sep_calculate_lli_table_max_size(sep, + &lli_out_array[current_out_entry], + (sep_out_lli_entries - current_out_entry), + &last_table_flag); + + if (!last_table_flag) { + in_table_data_size = (in_table_data_size / + block_size) * block_size; + out_table_data_size = (out_table_data_size / + block_size) * block_size; + } + + table_data_size = in_table_data_size; + if (table_data_size > out_table_data_size) + table_data_size = out_table_data_size; + + dev_dbg(&sep->pdev->dev, + "[PID%d] construct tables from lli" + " in_table_data_size is (hex) %x\n", current->pid, + in_table_data_size); + + dev_dbg(&sep->pdev->dev, + "[PID%d] construct tables from lli" + "out_table_data_size is (hex) %x\n", current->pid, + out_table_data_size); + + /* Construct input lli table */ + sep_build_lli_table(sep, &lli_in_array[current_in_entry], + in_lli_table_ptr, + ¤t_in_entry, + &num_entries_in_table, + table_data_size); + + /* Construct output lli table */ + sep_build_lli_table(sep, &lli_out_array[current_out_entry], + out_lli_table_ptr, + ¤t_out_entry, + &num_entries_out_table, + table_data_size); + + /* If info entry is null - this is the first table built */ + if (info_in_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); + + *in_num_entries_ptr = num_entries_in_table; + + *lli_table_out_ptr = + sep_shared_area_virt_to_bus(sep, + dma_out_lli_table_ptr); + + *out_num_entries_ptr = num_entries_out_table; + *table_data_size_ptr = table_data_size; + + dev_dbg(&sep->pdev->dev, + "[PID%d] output lli_table_in_ptr is %08lx\n", + current->pid, + (unsigned long)*lli_table_in_ptr); + dev_dbg(&sep->pdev->dev, + "[PID%d] output lli_table_out_ptr is %08lx\n", + current->pid, + (unsigned long)*lli_table_out_ptr); + } else { + /* Update the info entry of the previous in table */ + info_in_entry_ptr->bus_address = + sep_shared_area_virt_to_bus(sep, + dma_in_lli_table_ptr); + + info_in_entry_ptr->block_size = + ((num_entries_in_table) << 24) | + (table_data_size); + + /* Update the info entry of the previous in table */ + info_out_entry_ptr->bus_address = + sep_shared_area_virt_to_bus(sep, + dma_out_lli_table_ptr); + + info_out_entry_ptr->block_size = + ((num_entries_out_table) << 24) | + (table_data_size); + + dev_dbg(&sep->pdev->dev, + "[PID%d] output lli_table_in_ptr:%08lx %08x\n", + current->pid, + (unsigned long)info_in_entry_ptr->bus_address, + info_in_entry_ptr->block_size); + + dev_dbg(&sep->pdev->dev, + "[PID%d] output lli_table_out_ptr:" + "%08lx %08x\n", + current->pid, + (unsigned long)info_out_entry_ptr->bus_address, + info_out_entry_ptr->block_size); + } + + /* Save the pointer to the info entry of the current tables */ + info_in_entry_ptr = in_lli_table_ptr + + num_entries_in_table - 1; + info_out_entry_ptr = out_lli_table_ptr + + num_entries_out_table - 1; + + dev_dbg(&sep->pdev->dev, + "[PID%d] output num_entries_out_table is %x\n", + current->pid, + (u32)num_entries_out_table); + dev_dbg(&sep->pdev->dev, + "[PID%d] output info_in_entry_ptr is %lx\n", + current->pid, + (unsigned long)info_in_entry_ptr); + dev_dbg(&sep->pdev->dev, + "[PID%d] output info_out_entry_ptr is %lx\n", + current->pid, + (unsigned long)info_out_entry_ptr); + } + + /* Print input tables */ + if (!dmatables_region) { + sep_debug_print_lli_tables( + sep, + (struct sep_lli_entry *) + sep_shared_area_bus_to_virt(sep, *lli_table_in_ptr), + *in_num_entries_ptr, + *table_data_size_ptr); + } + + /* Print output tables */ + if (!dmatables_region) { + sep_debug_print_lli_tables( + sep, + (struct sep_lli_entry *) + sep_shared_area_bus_to_virt(sep, *lli_table_out_ptr), + *out_num_entries_ptr, + *table_data_size_ptr); + } + + return 0; +} + +/** + * sep_prepare_input_output_dma_table - prepare DMA I/O table + * @app_virt_in_addr: + * @app_virt_out_addr: + * @data_size: + * @block_size: + * @lli_table_in_ptr: + * @lli_table_out_ptr: + * @in_num_entries_ptr: + * @out_num_entries_ptr: + * @table_data_size_ptr: + * @is_kva: set for kernel data; used only for kernel crypto module + * + * This function builds input and output DMA tables for synhronic + * symmetric operations (AES, DES, HASH). It also checks that each table + * is of the modular block size + * Note that all bus addresses that are passed to the SEP + * are in 32 bit format; the SEP is a 32 bit device + */ +static int sep_prepare_input_output_dma_table(struct sep_device *sep, + unsigned long app_virt_in_addr, + unsigned long app_virt_out_addr, + u32 data_size, + u32 block_size, + dma_addr_t *lli_table_in_ptr, + dma_addr_t *lli_table_out_ptr, + u32 *in_num_entries_ptr, + u32 *out_num_entries_ptr, + u32 *table_data_size_ptr, + bool is_kva, + void **dmatables_region, + struct sep_dma_context *dma_ctx) + +{ + int error = 0; + /* Array of pointers of page */ + struct sep_lli_entry *lli_in_array; + /* Array of pointers of page */ + struct sep_lli_entry *lli_out_array; + + if (!dma_ctx) { + error = -EINVAL; + goto end_function; + } + + if (data_size == 0) { + /* Prepare empty table for input and output */ + if (dmatables_region) { + error = sep_allocate_dmatables_region( + sep, + dmatables_region, + dma_ctx, + 2); + if (error) + goto end_function; + } + sep_prepare_empty_lli_table(sep, lli_table_in_ptr, + in_num_entries_ptr, table_data_size_ptr, + dmatables_region, dma_ctx); + + sep_prepare_empty_lli_table(sep, lli_table_out_ptr, + out_num_entries_ptr, table_data_size_ptr, + dmatables_region, dma_ctx); + + goto update_dcb_counter; + } + + /* Initialize the pages pointers */ + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array = NULL; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_page_array = NULL; + + /* Lock the pages of the buffer and translate them to pages */ + if (is_kva == true) { + dev_dbg(&sep->pdev->dev, "[PID%d] Locking kernel input pages\n", + current->pid); + error = sep_lock_kernel_pages(sep, app_virt_in_addr, + data_size, &lli_in_array, SEP_DRIVER_IN_FLAG, + dma_ctx); + if (error) { + dev_warn(&sep->pdev->dev, + "[PID%d] sep_lock_kernel_pages for input " + "virtual buffer failed\n", current->pid); + + goto end_function; + } + + dev_dbg(&sep->pdev->dev, "[PID%d] Locking kernel output pages\n", + current->pid); + error = sep_lock_kernel_pages(sep, app_virt_out_addr, + data_size, &lli_out_array, SEP_DRIVER_OUT_FLAG, + dma_ctx); + + if (error) { + dev_warn(&sep->pdev->dev, + "[PID%d] sep_lock_kernel_pages for output " + "virtual buffer failed\n", current->pid); + + goto end_function_free_lli_in; + } + + } + + else { + dev_dbg(&sep->pdev->dev, "[PID%d] Locking user input pages\n", + current->pid); + error = sep_lock_user_pages(sep, app_virt_in_addr, + data_size, &lli_in_array, SEP_DRIVER_IN_FLAG, + dma_ctx); + if (error) { + dev_warn(&sep->pdev->dev, + "[PID%d] sep_lock_user_pages for input " + "virtual buffer failed\n", current->pid); + + goto end_function; + } + + dev_dbg(&sep->pdev->dev, "[PID%d] Locking user output pages\n", + current->pid); + + error = sep_lock_user_pages(sep, app_virt_out_addr, + data_size, &lli_out_array, SEP_DRIVER_OUT_FLAG, + dma_ctx); + + if (error) { + dev_warn(&sep->pdev->dev, + "[PID%d] sep_lock_user_pages" + " for output virtual buffer failed\n", + current->pid); + + goto end_function_free_lli_in; + } + } + + dev_dbg(&sep->pdev->dev, "[PID%d] After lock; prep input output dma " + "table sep_in_num_pages is (hex) %x\n", current->pid, + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages); + + dev_dbg(&sep->pdev->dev, "[PID%d] sep_out_num_pages is (hex) %x\n", + current->pid, + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_num_pages); + + dev_dbg(&sep->pdev->dev, "[PID%d] SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP" + " is (hex) %x\n", current->pid, + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); + + /* Call the fucntion that creates table from the lli arrays */ + dev_dbg(&sep->pdev->dev, "[PID%d] calling create table from lli\n", + current->pid); + error = sep_construct_dma_tables_from_lli( + sep, lli_in_array, + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat]. + in_num_pages, + lli_out_array, + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat]. + out_num_pages, + block_size, lli_table_in_ptr, lli_table_out_ptr, + in_num_entries_ptr, out_num_entries_ptr, + table_data_size_ptr, dmatables_region, dma_ctx); + + if (error) { + dev_warn(&sep->pdev->dev, + "[PID%d] sep_construct_dma_tables_from_lli failed\n", + current->pid); + goto end_function_with_error; + } + + kfree(lli_out_array); + kfree(lli_in_array); + +update_dcb_counter: + /* Update DCB counter */ + dma_ctx->nr_dcb_creat++; + + goto end_function; + +end_function_with_error: + kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_map_array); + kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_page_array); + kfree(lli_out_array); + + +end_function_free_lli_in: + kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array); + kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array); + kfree(lli_in_array); + +end_function: + + return error; + +} + +/** + * sep_prepare_input_output_dma_table_in_dcb - prepare control blocks + * @app_in_address: unsigned long; for data buffer in (user space) + * @app_out_address: unsigned long; for data buffer out (user space) + * @data_in_size: u32; for size of data + * @block_size: u32; for block size + * @tail_block_size: u32; for size of tail block + * @isapplet: bool; to indicate external app + * @is_kva: bool; kernel buffer; only used for kernel crypto module + * + * This function prepares the linked DMA tables and puts the + * address for the linked list of tables inta a DCB (data control + * block) the address of which is known by the SEP hardware + * Note that all bus addresses that are passed to the SEP + * are in 32 bit format; the SEP is a 32 bit device + */ +int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, + unsigned long app_in_address, + unsigned long app_out_address, + u32 data_in_size, + u32 block_size, + u32 tail_block_size, + bool isapplet, + bool is_kva, + struct sep_dcblock *dcb_region, + void **dmatables_region, + struct sep_dma_context **dma_ctx, + struct scatterlist *src_sg, + struct scatterlist *dst_sg) +{ + int error = 0; + /* Size of tail */ + u32 tail_size = 0; + /* Address of the created DCB table */ + struct sep_dcblock *dcb_table_ptr = NULL; + /* The physical address of the first input DMA table */ + dma_addr_t in_first_mlli_address = 0; + /* Number of entries in the first input DMA table */ + u32 in_first_num_entries = 0; + /* The physical address of the first output DMA table */ + dma_addr_t out_first_mlli_address = 0; + /* Number of entries in the first output DMA table */ + u32 out_first_num_entries = 0; + /* Data in the first input/output table */ + u32 first_data_size = 0; + + dev_dbg(&sep->pdev->dev, "[PID%d] app_in_address %lx\n", + current->pid, app_in_address); + + dev_dbg(&sep->pdev->dev, "[PID%d] app_out_address %lx\n", + current->pid, app_out_address); + + dev_dbg(&sep->pdev->dev, "[PID%d] data_in_size %x\n", + current->pid, data_in_size); + + dev_dbg(&sep->pdev->dev, "[PID%d] block_size %x\n", + current->pid, block_size); + + dev_dbg(&sep->pdev->dev, "[PID%d] tail_block_size %x\n", + current->pid, tail_block_size); + + dev_dbg(&sep->pdev->dev, "[PID%d] isapplet %x\n", + current->pid, isapplet); + + dev_dbg(&sep->pdev->dev, "[PID%d] is_kva %x\n", + current->pid, is_kva); + + dev_dbg(&sep->pdev->dev, "[PID%d] src_sg %p\n", + current->pid, src_sg); + + dev_dbg(&sep->pdev->dev, "[PID%d] dst_sg %p\n", + current->pid, dst_sg); + + if (!dma_ctx) { + dev_warn(&sep->pdev->dev, "[PID%d] no DMA context pointer\n", + current->pid); + error = -EINVAL; + goto end_function; + } + + if (*dma_ctx) { + /* In case there are multiple DCBs for this transaction */ + dev_dbg(&sep->pdev->dev, "[PID%d] DMA context already set\n", + current->pid); + } else { + *dma_ctx = kzalloc(sizeof(**dma_ctx), GFP_KERNEL); + if (!(*dma_ctx)) { + dev_dbg(&sep->pdev->dev, + "[PID%d] Not enough memory for DMA context\n", + current->pid); + error = -ENOMEM; + goto end_function; + } + dev_dbg(&sep->pdev->dev, + "[PID%d] Created DMA context addr at 0x%p\n", + current->pid, *dma_ctx); + } + + /* these are for kernel crypto only */ + (*dma_ctx)->src_sg = src_sg; + (*dma_ctx)->dst_sg = dst_sg; + + if ((*dma_ctx)->nr_dcb_creat == SEP_MAX_NUM_SYNC_DMA_OPS) { + /* No more DCBs to allocate */ + dev_dbg(&sep->pdev->dev, "[PID%d] no more DCBs available\n", + current->pid); + error = -ENOSPC; + goto end_function_error; + } + + /* Allocate new DCB */ + if (dcb_region) { + dcb_table_ptr = dcb_region; + } else { + dcb_table_ptr = (struct sep_dcblock *)(sep->shared_addr + + SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES + + ((*dma_ctx)->nr_dcb_creat * + sizeof(struct sep_dcblock))); + } + + /* Set the default values in the DCB */ + dcb_table_ptr->input_mlli_address = 0; + dcb_table_ptr->input_mlli_num_entries = 0; + dcb_table_ptr->input_mlli_data_size = 0; + dcb_table_ptr->output_mlli_address = 0; + dcb_table_ptr->output_mlli_num_entries = 0; + dcb_table_ptr->output_mlli_data_size = 0; + dcb_table_ptr->tail_data_size = 0; + dcb_table_ptr->out_vr_tail_pt = 0; + + if (isapplet == true) { + + /* Check if there is enough data for DMA operation */ + if (data_in_size < SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE) { + if (is_kva == true) { + error = -ENODEV; + goto end_function_error; + } else { + if (copy_from_user(dcb_table_ptr->tail_data, + (void __user *)app_in_address, + data_in_size)) { + error = -EFAULT; + goto end_function_error; + } + } + + dcb_table_ptr->tail_data_size = data_in_size; + + /* Set the output user-space address for mem2mem op */ + if (app_out_address) + dcb_table_ptr->out_vr_tail_pt = + (aligned_u64)app_out_address; + + /* + * Update both data length parameters in order to avoid + * second data copy and allow building of empty mlli + * tables + */ + tail_size = 0x0; + data_in_size = 0x0; + + } else { + if (!app_out_address) { + tail_size = data_in_size % block_size; + if (!tail_size) { + if (tail_block_size == block_size) + tail_size = block_size; + } + } else { + tail_size = 0; + } + } + if (tail_size) { + if (tail_size > sizeof(dcb_table_ptr->tail_data)) + return -EINVAL; + if (is_kva == true) { + error = -ENODEV; + goto end_function_error; + } else { + /* We have tail data - copy it to DCB */ + if (copy_from_user(dcb_table_ptr->tail_data, + (void __user *)(app_in_address + + data_in_size - tail_size), tail_size)) { + error = -EFAULT; + goto end_function_error; + } + } + if (app_out_address) + /* + * Calculate the output address + * according to tail data size + */ + dcb_table_ptr->out_vr_tail_pt = + (aligned_u64)app_out_address + + data_in_size - tail_size; + + /* Save the real tail data size */ + dcb_table_ptr->tail_data_size = tail_size; + /* + * Update the data size without the tail + * data size AKA data for the dma + */ + data_in_size = (data_in_size - tail_size); + } + } + /* Check if we need to build only input table or input/output */ + if (app_out_address) { + /* Prepare input/output tables */ + error = sep_prepare_input_output_dma_table(sep, + app_in_address, + app_out_address, + data_in_size, + block_size, + &in_first_mlli_address, + &out_first_mlli_address, + &in_first_num_entries, + &out_first_num_entries, + &first_data_size, + is_kva, + dmatables_region, + *dma_ctx); + } else { + /* Prepare input tables */ + error = sep_prepare_input_dma_table(sep, + app_in_address, + data_in_size, + block_size, + &in_first_mlli_address, + &in_first_num_entries, + &first_data_size, + is_kva, + dmatables_region, + *dma_ctx); + } + + if (error) { + dev_warn(&sep->pdev->dev, + "prepare DMA table call failed " + "from prepare DCB call\n"); + goto end_function_error; + } + + /* Set the DCB values */ + dcb_table_ptr->input_mlli_address = in_first_mlli_address; + dcb_table_ptr->input_mlli_num_entries = in_first_num_entries; + dcb_table_ptr->input_mlli_data_size = first_data_size; + dcb_table_ptr->output_mlli_address = out_first_mlli_address; + dcb_table_ptr->output_mlli_num_entries = out_first_num_entries; + dcb_table_ptr->output_mlli_data_size = first_data_size; + + goto end_function; + +end_function_error: + kfree(*dma_ctx); + +end_function: + return error; + +} + + +/** + * sep_free_dma_tables_and_dcb - free DMA tables and DCBs + * @sep: pointer to struct sep_device + * @isapplet: indicates external application (used for kernel access) + * @is_kva: indicates kernel addresses (only used for kernel crypto) + * + * This function frees the DMA tables and DCB + */ +static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet, + bool is_kva, struct sep_dma_context **dma_ctx) +{ + struct sep_dcblock *dcb_table_ptr; + unsigned long pt_hold; + void *tail_pt; + + int i = 0; + int error = 0; + int error_temp = 0; + + dev_dbg(&sep->pdev->dev, "[PID%d] sep_free_dma_tables_and_dcb\n", + current->pid); + + if (isapplet == true) { + /* Set pointer to first DCB table */ + dcb_table_ptr = (struct sep_dcblock *) + (sep->shared_addr + + SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES); + + /* Go over each DCB and see if tail pointer must be updated */ + 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; + tail_pt = (void *)pt_hold; + if (is_kva == true) { + error = -ENODEV; + break; + } else { + error_temp = copy_to_user( + (void __user *)tail_pt, + dcb_table_ptr->tail_data, + dcb_table_ptr->tail_data_size); + } + if (error_temp) { + /* Release the DMA resource */ + error = -EFAULT; + break; + } + } + } + } + /* Free the output pages, if any */ + sep_free_dma_table_data_handler(sep, dma_ctx); + + dev_dbg(&sep->pdev->dev, "[PID%d] sep_free_dma_tables_and_dcb end\n", + current->pid); + + return error; +} + +/** + * sep_prepare_dcb_handler - prepare a control block + * @sep: pointer to struct sep_device + * @arg: pointer to user parameters + * + * This function will retrieve the RAR buffer physical addresses, type + * & size corresponding to the RAR handles provided in the buffers vector. + */ +static int sep_prepare_dcb_handler(struct sep_device *sep, unsigned long arg, + struct sep_dma_context **dma_ctx) +{ + int error; + /* Command arguments */ + static struct build_dcb_struct command_args; + + /* Get the command arguments */ + if (copy_from_user(&command_args, (void __user *)arg, + sizeof(struct build_dcb_struct))) { + error = -EFAULT; + goto end_function; + } + + dev_dbg(&sep->pdev->dev, + "[PID%d] prep dcb handler app_in_address is %08llx\n", + current->pid, command_args.app_in_address); + dev_dbg(&sep->pdev->dev, + "[PID%d] app_out_address is %08llx\n", + current->pid, command_args.app_out_address); + dev_dbg(&sep->pdev->dev, + "[PID%d] data_size is %x\n", + current->pid, command_args.data_in_size); + dev_dbg(&sep->pdev->dev, + "[PID%d] block_size is %x\n", + current->pid, command_args.block_size); + dev_dbg(&sep->pdev->dev, + "[PID%d] tail block_size is %x\n", + current->pid, command_args.tail_block_size); + dev_dbg(&sep->pdev->dev, + "[PID%d] is_applet is %x\n", + current->pid, command_args.is_applet); + + if (!command_args.app_in_address) { + dev_warn(&sep->pdev->dev, + "[PID%d] null app_in_address\n", current->pid); + error = -EINVAL; + goto end_function; + } + + error = sep_prepare_input_output_dma_table_in_dcb(sep, + (unsigned long)command_args.app_in_address, + (unsigned long)command_args.app_out_address, + command_args.data_in_size, command_args.block_size, + command_args.tail_block_size, + command_args.is_applet, false, + NULL, NULL, dma_ctx, NULL, NULL); + +end_function: + return error; + +} + +/** + * sep_free_dcb_handler - free control block resources + * @sep: pointer to struct sep_device + * + * This function frees the DCB resources and updates the needed + * user-space buffers. + */ +static int sep_free_dcb_handler(struct sep_device *sep, + struct sep_dma_context **dma_ctx) +{ + int error = 0; + + if (!dma_ctx || !(*dma_ctx)) { + dev_dbg(&sep->pdev->dev, "[PID%d] no dma context defined, nothing to free\n", + current->pid); + return error; + } + + dev_dbg(&sep->pdev->dev, "[PID%d] free dcbs num of DCBs %x\n", + current->pid, + (*dma_ctx)->nr_dcb_creat); + + error = sep_free_dma_tables_and_dcb(sep, false, false, dma_ctx); + + return error; +} + +/** + * sep_ioctl - ioctl handler for sep device + * @filp: pointer to struct file + * @cmd: command + * @arg: pointer to argument structure + * + * Implement the ioctl methods availble on the SEP device. + */ +static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct sep_private_data * const private_data = filp->private_data; + struct sep_call_status *call_status = &private_data->call_status; + struct sep_device *sep = private_data->device; + struct sep_dma_context **dma_ctx = &private_data->dma_ctx; + struct sep_queue_info **my_queue_elem = &private_data->my_queue_elem; + int error = 0; + + dev_dbg(&sep->pdev->dev, "[PID%d] ioctl cmd 0x%x\n", + current->pid, cmd); + dev_dbg(&sep->pdev->dev, "[PID%d] dma context addr 0x%p\n", + current->pid, *dma_ctx); + + /* Make sure we own this device */ + error = sep_check_transaction_owner(sep); + if (error) { + dev_dbg(&sep->pdev->dev, "[PID%d] ioctl pid is not owner\n", + current->pid); + goto end_function; + } + + /* Check that sep_mmap has been called before */ + if (0 == test_bit(SEP_LEGACY_MMAP_DONE_OFFSET, + &call_status->status)) { + dev_dbg(&sep->pdev->dev, + "[PID%d] mmap not called\n", current->pid); + error = -EPROTO; + goto end_function; + } + + /* Check that the command is for SEP device */ + if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER) { + error = -ENOTTY; + goto end_function; + } + + switch (cmd) { + case SEP_IOCSENDSEPCOMMAND: + if (1 == test_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET, + &call_status->status)) { + dev_dbg(&sep->pdev->dev, "[PID%d] send msg already done\n", + current->pid); + error = -EPROTO; + goto end_function; + } + /* Send command to SEP */ + error = sep_send_command_handler(sep); + if (!error) + set_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET, + &call_status->status); + dev_dbg(&sep->pdev->dev, "[PID%d] SEP_IOCSENDSEPCOMMAND end\n", + current->pid); + break; + case SEP_IOCENDTRANSACTION: + error = sep_end_transaction_handler(sep, dma_ctx, call_status, + my_queue_elem); + dev_dbg(&sep->pdev->dev, "[PID%d] SEP_IOCENDTRANSACTION end\n", + current->pid); + break; + case SEP_IOCPREPAREDCB: + if (1 == test_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET, + &call_status->status)) { + dev_dbg(&sep->pdev->dev, + "[PID%d] dcb preparation needed before send msg\n", + current->pid); + error = -EPROTO; + goto end_function; + } + + if (!arg) { + dev_dbg(&sep->pdev->dev, + "[PID%d] dcb prep null arg\n", current->pid); + error = -EINVAL; + goto end_function; + } + + error = sep_prepare_dcb_handler(sep, arg, dma_ctx); + dev_dbg(&sep->pdev->dev, "[PID%d] SEP_IOCPREPAREDCB end\n", + current->pid); + break; + case SEP_IOCFREEDCB: + error = sep_free_dcb_handler(sep, dma_ctx); + dev_dbg(&sep->pdev->dev, "[PID%d] SEP_IOCFREEDCB end\n", + current->pid); + break; + default: + error = -ENOTTY; + dev_dbg(&sep->pdev->dev, "[PID%d] default end\n", + current->pid); + break; + } + +end_function: + dev_dbg(&sep->pdev->dev, "[PID%d] ioctl end\n", current->pid); + + return error; +} + +/** + * sep_inthandler - interrupt handler for sep device + * @irq: interrupt + * @dev_id: device id + */ +static irqreturn_t sep_inthandler(int irq, void *dev_id) +{ + unsigned long lock_irq_flag; + u32 reg_val, reg_val2 = 0; + struct sep_device *sep = dev_id; + irqreturn_t int_error = IRQ_HANDLED; + + /* Are we in power save? */ +#if defined(CONFIG_PM_RUNTIME) && defined(SEP_ENABLE_RUNTIME_PM) + if (sep->pdev->dev.power.runtime_status != RPM_ACTIVE) { + dev_dbg(&sep->pdev->dev, "interrupt during pwr save\n"); + return IRQ_NONE; + } +#endif + + if (test_bit(SEP_WORKING_LOCK_BIT, &sep->in_use_flags) == 0) { + dev_dbg(&sep->pdev->dev, "interrupt while nobody using sep\n"); + return IRQ_NONE; + } + + /* Read the IRR register to check if this is SEP interrupt */ + reg_val = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR); + + dev_dbg(&sep->pdev->dev, "sep int: IRR REG val: %x\n", reg_val); + + if (reg_val & (0x1 << 13)) { + + /* Lock and update the counter of reply messages */ + spin_lock_irqsave(&sep->snd_rply_lck, lock_irq_flag); + sep->reply_ct++; + spin_unlock_irqrestore(&sep->snd_rply_lck, lock_irq_flag); + + dev_dbg(&sep->pdev->dev, "sep int: send_ct %lx reply_ct %lx\n", + sep->send_ct, sep->reply_ct); + + /* Is this a kernel client request */ + if (sep->in_kernel) { + tasklet_schedule(&sep->finish_tasklet); + goto finished_interrupt; + } + + /* Is this printf or daemon request? */ + reg_val2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); + dev_dbg(&sep->pdev->dev, + "SEP Interrupt - GPR2 is %08x\n", reg_val2); + + clear_bit(SEP_WORKING_LOCK_BIT, &sep->in_use_flags); + + if ((reg_val2 >> 30) & 0x1) { + dev_dbg(&sep->pdev->dev, "int: printf request\n"); + } else if (reg_val2 >> 31) { + dev_dbg(&sep->pdev->dev, "int: daemon request\n"); + } else { + dev_dbg(&sep->pdev->dev, "int: SEP reply\n"); + wake_up(&sep->event_interrupt); + } + } else { + dev_dbg(&sep->pdev->dev, "int: not SEP interrupt\n"); + int_error = IRQ_NONE; + } + +finished_interrupt: + + if (int_error == IRQ_HANDLED) + sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, reg_val); + + return int_error; +} + +/** + * sep_reconfig_shared_area - reconfigure shared area + * @sep: pointer to struct sep_device + * + * Reconfig the shared area between HOST and SEP - needed in case + * the DX_CC_Init function was called before OS loading. + */ +static int sep_reconfig_shared_area(struct sep_device *sep) +{ + int ret_val; + + /* use to limit waiting for SEP */ + unsigned long end_time; + + /* Send the new SHARED MESSAGE AREA to the SEP */ + dev_dbg(&sep->pdev->dev, "reconfig shared; sending %08llx to sep\n", + (unsigned long long)sep->shared_bus); + + sep_write_reg(sep, HW_HOST_HOST_SEP_GPR1_REG_ADDR, sep->shared_bus); + + /* Poll for SEP response */ + ret_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR); + + end_time = jiffies + (WAIT_TIME * HZ); + + while ((time_before(jiffies, end_time)) && (ret_val != 0xffffffff) && + (ret_val != sep->shared_bus)) + ret_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR); + + /* Check the return value (register) */ + if (ret_val != sep->shared_bus) { + dev_warn(&sep->pdev->dev, "could not reconfig shared area\n"); + dev_warn(&sep->pdev->dev, "result was %x\n", ret_val); + ret_val = -ENOMEM; + } else + ret_val = 0; + + dev_dbg(&sep->pdev->dev, "reconfig shared area end\n"); + + return ret_val; +} + +/** + * sep_activate_dcb_dmatables_context - Takes DCB & DMA tables + * contexts into use + * @sep: SEP device + * @dcb_region: DCB region copy + * @dmatables_region: MLLI/DMA tables copy + * @dma_ctx: DMA context for current transaction + */ +ssize_t sep_activate_dcb_dmatables_context(struct sep_device *sep, + struct sep_dcblock **dcb_region, + void **dmatables_region, + struct sep_dma_context *dma_ctx) +{ + void *dmaregion_free_start = NULL; + void *dmaregion_free_end = NULL; + void *dcbregion_free_start = NULL; + void *dcbregion_free_end = NULL; + ssize_t error = 0; + + dev_dbg(&sep->pdev->dev, "[PID%d] activating dcb/dma region\n", + current->pid); + + if (1 > dma_ctx->nr_dcb_creat) { + dev_warn(&sep->pdev->dev, + "[PID%d] invalid number of dcbs to activate 0x%08X\n", + current->pid, dma_ctx->nr_dcb_creat); + error = -EINVAL; + goto end_function; + } + + dmaregion_free_start = sep->shared_addr + + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES; + dmaregion_free_end = dmaregion_free_start + + SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES - 1; + + if (dmaregion_free_start + + dma_ctx->dmatables_len > dmaregion_free_end) { + error = -ENOMEM; + goto end_function; + } + memcpy(dmaregion_free_start, + *dmatables_region, + dma_ctx->dmatables_len); + /* Free MLLI table copy */ + kfree(*dmatables_region); + *dmatables_region = NULL; + + /* Copy thread's DCB table copy to DCB table region */ + dcbregion_free_start = sep->shared_addr + + SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES; + dcbregion_free_end = dcbregion_free_start + + (SEP_MAX_NUM_SYNC_DMA_OPS * + sizeof(struct sep_dcblock)) - 1; + + if (dcbregion_free_start + + (dma_ctx->nr_dcb_creat * sizeof(struct sep_dcblock)) + > dcbregion_free_end) { + error = -ENOMEM; + goto end_function; + } + + memcpy(dcbregion_free_start, + *dcb_region, + dma_ctx->nr_dcb_creat * sizeof(struct sep_dcblock)); + + /* Print the tables */ + dev_dbg(&sep->pdev->dev, "activate: input table\n"); + sep_debug_print_lli_tables(sep, + (struct sep_lli_entry *)sep_shared_area_bus_to_virt(sep, + (*dcb_region)->input_mlli_address), + (*dcb_region)->input_mlli_num_entries, + (*dcb_region)->input_mlli_data_size); + + dev_dbg(&sep->pdev->dev, "activate: output table\n"); + sep_debug_print_lli_tables(sep, + (struct sep_lli_entry *)sep_shared_area_bus_to_virt(sep, + (*dcb_region)->output_mlli_address), + (*dcb_region)->output_mlli_num_entries, + (*dcb_region)->output_mlli_data_size); + + dev_dbg(&sep->pdev->dev, + "[PID%d] printing activated tables\n", current->pid); + +end_function: + kfree(*dmatables_region); + *dmatables_region = NULL; + + kfree(*dcb_region); + *dcb_region = NULL; + + return error; +} + +/** + * sep_create_dcb_dmatables_context - Creates DCB & MLLI/DMA table context + * @sep: SEP device + * @dcb_region: DCB region buf to create for current transaction + * @dmatables_region: MLLI/DMA tables buf to create for current transaction + * @dma_ctx: DMA context buf to create for current transaction + * @user_dcb_args: User arguments for DCB/MLLI creation + * @num_dcbs: Number of DCBs to create + */ +static ssize_t sep_create_dcb_dmatables_context(struct sep_device *sep, + struct sep_dcblock **dcb_region, + void **dmatables_region, + struct sep_dma_context **dma_ctx, + const struct build_dcb_struct __user *user_dcb_args, + const u32 num_dcbs) +{ + int error = 0; + int i = 0; + struct build_dcb_struct *dcb_args = NULL; + + dev_dbg(&sep->pdev->dev, "[PID%d] creating dcb/dma region\n", + current->pid); + + if (!dcb_region || !dma_ctx || !dmatables_region || !user_dcb_args) { + error = -EINVAL; + goto end_function; + } + + if (SEP_MAX_NUM_SYNC_DMA_OPS < num_dcbs) { + dev_warn(&sep->pdev->dev, + "[PID%d] invalid number of dcbs 0x%08X\n", + current->pid, num_dcbs); + error = -EINVAL; + goto end_function; + } + + dcb_args = kzalloc(num_dcbs * sizeof(struct build_dcb_struct), + GFP_KERNEL); + if (!dcb_args) { + dev_warn(&sep->pdev->dev, "[PID%d] no memory for dcb args\n", + current->pid); + error = -ENOMEM; + goto end_function; + } + + if (copy_from_user(dcb_args, + user_dcb_args, + num_dcbs * sizeof(struct build_dcb_struct))) { + error = -EINVAL; + goto end_function; + } + + /* Allocate thread-specific memory for DCB */ + *dcb_region = kzalloc(num_dcbs * sizeof(struct sep_dcblock), + GFP_KERNEL); + if (!(*dcb_region)) { + error = -ENOMEM; + goto end_function; + } + + /* Prepare DCB and MLLI table into the allocated regions */ + for (i = 0; i < num_dcbs; i++) { + error = sep_prepare_input_output_dma_table_in_dcb(sep, + (unsigned long)dcb_args[i].app_in_address, + (unsigned long)dcb_args[i].app_out_address, + dcb_args[i].data_in_size, + dcb_args[i].block_size, + dcb_args[i].tail_block_size, + dcb_args[i].is_applet, + false, + *dcb_region, dmatables_region, + dma_ctx, + NULL, + NULL); + if (error) { + dev_warn(&sep->pdev->dev, + "[PID%d] dma table creation failed\n", + current->pid); + goto end_function; + } + } + +end_function: + kfree(dcb_args); + return error; + +} + +/** + * sep_create_dcb_dmatables_context_kernel - Creates DCB & MLLI/DMA table context + * for kernel crypto + * @sep: SEP device + * @dcb_region: DCB region buf to create for current transaction + * @dmatables_region: MLLI/DMA tables buf to create for current transaction + * @dma_ctx: DMA context buf to create for current transaction + * @user_dcb_args: User arguments for DCB/MLLI creation + * @num_dcbs: Number of DCBs to create + * This does that same thing as sep_create_dcb_dmatables_context + * except that it is used only for the kernel crypto operation. It is + * separate because there is no user data involved; the dcb data structure + * is specific for kernel crypto (build_dcb_struct_kernel) + */ +int sep_create_dcb_dmatables_context_kernel(struct sep_device *sep, + struct sep_dcblock **dcb_region, + void **dmatables_region, + struct sep_dma_context **dma_ctx, + const struct build_dcb_struct_kernel *dcb_data, + const u32 num_dcbs) +{ + int error = 0; + int i = 0; + + dev_dbg(&sep->pdev->dev, "[PID%d] creating dcb/dma region\n", + current->pid); + + if (!dcb_region || !dma_ctx || !dmatables_region || !dcb_data) { + error = -EINVAL; + goto end_function; + } + + if (SEP_MAX_NUM_SYNC_DMA_OPS < num_dcbs) { + dev_warn(&sep->pdev->dev, + "[PID%d] invalid number of dcbs 0x%08X\n", + current->pid, num_dcbs); + error = -EINVAL; + goto end_function; + } + + dev_dbg(&sep->pdev->dev, "[PID%d] num_dcbs is %d\n", + current->pid, num_dcbs); + + /* Allocate thread-specific memory for DCB */ + *dcb_region = kzalloc(num_dcbs * sizeof(struct sep_dcblock), + GFP_KERNEL); + if (!(*dcb_region)) { + error = -ENOMEM; + goto end_function; + } + + /* Prepare DCB and MLLI table into the allocated regions */ + for (i = 0; i < num_dcbs; i++) { + error = sep_prepare_input_output_dma_table_in_dcb(sep, + (unsigned long)dcb_data->app_in_address, + (unsigned long)dcb_data->app_out_address, + dcb_data->data_in_size, + dcb_data->block_size, + dcb_data->tail_block_size, + dcb_data->is_applet, + true, + *dcb_region, dmatables_region, + dma_ctx, + dcb_data->src_sg, + dcb_data->dst_sg); + if (error) { + dev_warn(&sep->pdev->dev, + "[PID%d] dma table creation failed\n", + current->pid); + goto end_function; + } + } + +end_function: + return error; + +} + +/** + * sep_activate_msgarea_context - Takes the message area context into use + * @sep: SEP device + * @msg_region: Message area context buf + * @msg_len: Message area context buffer size + */ +static ssize_t sep_activate_msgarea_context(struct sep_device *sep, + void **msg_region, + const size_t msg_len) +{ + dev_dbg(&sep->pdev->dev, "[PID%d] activating msg region\n", + current->pid); + + if (!msg_region || !(*msg_region) || + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES < msg_len) { + dev_warn(&sep->pdev->dev, + "[PID%d] invalid act msgarea len 0x%08X\n", + current->pid, msg_len); + return -EINVAL; + } + + memcpy(sep->shared_addr, *msg_region, msg_len); + + return 0; +} + +/** + * sep_create_msgarea_context - Creates message area context + * @sep: SEP device + * @msg_region: Msg area region buf to create for current transaction + * @msg_user: Content for msg area region from user + * @msg_len: Message area size + */ +static ssize_t sep_create_msgarea_context(struct sep_device *sep, + void **msg_region, + const void __user *msg_user, + const size_t msg_len) +{ + int error = 0; + + dev_dbg(&sep->pdev->dev, "[PID%d] creating msg region\n", + current->pid); + + if (!msg_region || + !msg_user || + SEP_DRIVER_MAX_MESSAGE_SIZE_IN_BYTES < msg_len || + SEP_DRIVER_MIN_MESSAGE_SIZE_IN_BYTES > msg_len) { + dev_warn(&sep->pdev->dev, + "[PID%d] invalid creat msgarea len 0x%08X\n", + current->pid, msg_len); + error = -EINVAL; + goto end_function; + } + + /* Allocate thread-specific memory for message buffer */ + *msg_region = kzalloc(msg_len, GFP_KERNEL); + if (!(*msg_region)) { + dev_warn(&sep->pdev->dev, + "[PID%d] no mem for msgarea context\n", + current->pid); + error = -ENOMEM; + goto end_function; + } + + /* Copy input data to write() to allocated message buffer */ + if (copy_from_user(*msg_region, msg_user, msg_len)) { + error = -EINVAL; + goto end_function; + } + +end_function: + if (error && msg_region) { + kfree(*msg_region); + *msg_region = NULL; + } + + return error; +} + + +/** + * sep_read - Returns results of an operation for fastcall interface + * @filp: File pointer + * @buf_user: User buffer for storing results + * @count_user: User buffer size + * @offset: File offset, not supported + * + * The implementation does not support reading in chunks, all data must be + * consumed during a single read system call. + */ +static ssize_t sep_read(struct file *filp, + char __user *buf_user, size_t count_user, + loff_t *offset) +{ + struct sep_private_data * const private_data = filp->private_data; + struct sep_call_status *call_status = &private_data->call_status; + struct sep_device *sep = private_data->device; + struct sep_dma_context **dma_ctx = &private_data->dma_ctx; + struct sep_queue_info **my_queue_elem = &private_data->my_queue_elem; + ssize_t error = 0, error_tmp = 0; + + /* Am I the process that owns the transaction? */ + error = sep_check_transaction_owner(sep); + if (error) { + dev_dbg(&sep->pdev->dev, "[PID%d] read pid is not owner\n", + current->pid); + goto end_function; + } + + /* Checks that user has called necessarry apis */ + if (0 == test_bit(SEP_FASTCALL_WRITE_DONE_OFFSET, + &call_status->status)) { + dev_warn(&sep->pdev->dev, + "[PID%d] fastcall write not called\n", + current->pid); + error = -EPROTO; + goto end_function_error; + } + + if (!buf_user) { + dev_warn(&sep->pdev->dev, + "[PID%d] null user buffer\n", + current->pid); + error = -EINVAL; + goto end_function_error; + } + + + /* Wait for SEP to finish */ + wait_event(sep->event_interrupt, + test_bit(SEP_WORKING_LOCK_BIT, + &sep->in_use_flags) == 0); + + sep_dump_message(sep); + + dev_dbg(&sep->pdev->dev, "[PID%d] count_user = 0x%08X\n", + current->pid, count_user); + + /* In case user has allocated bigger buffer */ + if (count_user > SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES) + count_user = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES; + + if (copy_to_user(buf_user, sep->shared_addr, count_user)) { + error = -EFAULT; + goto end_function_error; + } + + dev_dbg(&sep->pdev->dev, "[PID%d] read succeeded\n", current->pid); + error = count_user; + +end_function_error: + /* Copy possible tail data to user and free DCB and MLLIs */ + error_tmp = sep_free_dcb_handler(sep, dma_ctx); + if (error_tmp) + dev_warn(&sep->pdev->dev, "[PID%d] dcb free failed\n", + current->pid); + + /* End the transaction, wakeup pending ones */ + error_tmp = sep_end_transaction_handler(sep, dma_ctx, call_status, + my_queue_elem); + if (error_tmp) + dev_warn(&sep->pdev->dev, + "[PID%d] ending transaction failed\n", + current->pid); + +end_function: + return error; +} + +/** + * sep_fastcall_args_get - Gets fastcall params from user + * sep: SEP device + * @args: Parameters buffer + * @buf_user: User buffer for operation parameters + * @count_user: User buffer size + */ +static inline ssize_t sep_fastcall_args_get(struct sep_device *sep, + struct sep_fastcall_hdr *args, + const char __user *buf_user, + const size_t count_user) +{ + ssize_t error = 0; + size_t actual_count = 0; + + if (!buf_user) { + dev_warn(&sep->pdev->dev, + "[PID%d] null user buffer\n", + current->pid); + error = -EINVAL; + goto end_function; + } + + if (count_user < sizeof(struct sep_fastcall_hdr)) { + dev_warn(&sep->pdev->dev, + "[PID%d] too small message size 0x%08X\n", + current->pid, count_user); + error = -EINVAL; + goto end_function; + } + + + if (copy_from_user(args, buf_user, sizeof(struct sep_fastcall_hdr))) { + error = -EFAULT; + goto end_function; + } + + if (SEP_FC_MAGIC != args->magic) { + dev_warn(&sep->pdev->dev, + "[PID%d] invalid fastcall magic 0x%08X\n", + current->pid, args->magic); + error = -EINVAL; + goto end_function; + } + + dev_dbg(&sep->pdev->dev, "[PID%d] fastcall hdr num of DCBs 0x%08X\n", + current->pid, args->num_dcbs); + dev_dbg(&sep->pdev->dev, "[PID%d] fastcall hdr msg len 0x%08X\n", + current->pid, args->msg_len); + + if (SEP_DRIVER_MAX_MESSAGE_SIZE_IN_BYTES < args->msg_len || + SEP_DRIVER_MIN_MESSAGE_SIZE_IN_BYTES > args->msg_len) { + dev_warn(&sep->pdev->dev, + "[PID%d] invalid message length\n", + current->pid); + error = -EINVAL; + goto end_function; + } + + actual_count = sizeof(struct sep_fastcall_hdr) + + args->msg_len + + (args->num_dcbs * sizeof(struct build_dcb_struct)); + + if (actual_count != count_user) { + dev_warn(&sep->pdev->dev, + "[PID%d] inconsistent message " + "sizes 0x%08X vs 0x%08X\n", + current->pid, actual_count, count_user); + error = -EMSGSIZE; + goto end_function; + } + +end_function: + return error; +} + +/** + * sep_write - Starts an operation for fastcall interface + * @filp: File pointer + * @buf_user: User buffer for operation parameters + * @count_user: User buffer size + * @offset: File offset, not supported + * + * The implementation does not support writing in chunks, + * all data must be given during a single write system call. + */ +static ssize_t sep_write(struct file *filp, + const char __user *buf_user, size_t count_user, + loff_t *offset) +{ + struct sep_private_data * const private_data = filp->private_data; + struct sep_call_status *call_status = &private_data->call_status; + struct sep_device *sep = private_data->device; + struct sep_dma_context *dma_ctx = NULL; + struct sep_fastcall_hdr call_hdr = {0}; + void *msg_region = NULL; + void *dmatables_region = NULL; + struct sep_dcblock *dcb_region = NULL; + ssize_t error = 0; + struct sep_queue_info *my_queue_elem = NULL; + + dev_dbg(&sep->pdev->dev, "[PID%d] sep dev is 0x%p\n", + current->pid, sep); + dev_dbg(&sep->pdev->dev, "[PID%d] private_data is 0x%p\n", + current->pid, private_data); + + error = sep_fastcall_args_get(sep, &call_hdr, buf_user, count_user); + if (error) + goto end_function; + + buf_user += sizeof(struct sep_fastcall_hdr); + + /* + * Controlling driver memory usage by limiting amount of + * buffers created. Only SEP_DOUBLEBUF_USERS_LIMIT number + * of threads can progress further at a time + */ + dev_dbg(&sep->pdev->dev, "[PID%d] waiting for double buffering " + "region access\n", current->pid); + error = down_interruptible(&sep->sep_doublebuf); + dev_dbg(&sep->pdev->dev, "[PID%d] double buffering region start\n", + current->pid); + if (error) { + /* Signal received */ + goto end_function_error; + } + + + /* + * Prepare contents of the shared area regions for + * the operation into temporary buffers + */ + if (0 < call_hdr.num_dcbs) { + error = sep_create_dcb_dmatables_context(sep, + &dcb_region, + &dmatables_region, + &dma_ctx, + (const struct build_dcb_struct __user *) + buf_user, + call_hdr.num_dcbs); + if (error) + goto end_function_error_doublebuf; + + buf_user += call_hdr.num_dcbs * sizeof(struct build_dcb_struct); + } + + error = sep_create_msgarea_context(sep, + &msg_region, + buf_user, + call_hdr.msg_len); + if (error) + goto end_function_error_doublebuf; + + dev_dbg(&sep->pdev->dev, "[PID%d] updating queue status\n", + current->pid); + my_queue_elem = sep_queue_status_add(sep, + ((struct sep_msgarea_hdr *)msg_region)->opcode, + (dma_ctx) ? dma_ctx->input_data_len : 0, + current->pid, + current->comm, sizeof(current->comm)); + + if (!my_queue_elem) { + dev_dbg(&sep->pdev->dev, "[PID%d] updating queue" + "status error\n", current->pid); + error = -ENOMEM; + goto end_function_error_doublebuf; + } + + /* Wait until current process gets the transaction */ + error = sep_wait_transaction(sep); + + if (error) { + /* Interrupted by signal, don't clear transaction */ + dev_dbg(&sep->pdev->dev, "[PID%d] interrupted by signal\n", + current->pid); + sep_queue_status_remove(sep, &my_queue_elem); + goto end_function_error_doublebuf; + } + + dev_dbg(&sep->pdev->dev, "[PID%d] saving queue element\n", + current->pid); + private_data->my_queue_elem = my_queue_elem; + + /* Activate shared area regions for the transaction */ + error = sep_activate_msgarea_context(sep, &msg_region, + call_hdr.msg_len); + if (error) + goto end_function_error_clear_transact; + + sep_dump_message(sep); + + if (0 < call_hdr.num_dcbs) { + error = sep_activate_dcb_dmatables_context(sep, + &dcb_region, + &dmatables_region, + dma_ctx); + if (error) + goto end_function_error_clear_transact; + } + + /* Send command to SEP */ + error = sep_send_command_handler(sep); + if (error) + goto end_function_error_clear_transact; + + /* Store DMA context for the transaction */ + private_data->dma_ctx = dma_ctx; + /* Update call status */ + set_bit(SEP_FASTCALL_WRITE_DONE_OFFSET, &call_status->status); + error = count_user; + + up(&sep->sep_doublebuf); + dev_dbg(&sep->pdev->dev, "[PID%d] double buffering region end\n", + current->pid); + + goto end_function; + +end_function_error_clear_transact: + sep_end_transaction_handler(sep, &dma_ctx, call_status, + &private_data->my_queue_elem); + +end_function_error_doublebuf: + up(&sep->sep_doublebuf); + dev_dbg(&sep->pdev->dev, "[PID%d] double buffering region end\n", + current->pid); + +end_function_error: + if (dma_ctx) + sep_free_dma_table_data_handler(sep, &dma_ctx); + +end_function: + kfree(dcb_region); + kfree(dmatables_region); + kfree(msg_region); + + return error; +} +/** + * sep_seek - Handler for seek system call + * @filp: File pointer + * @offset: File offset + * @origin: Options for offset + * + * Fastcall interface does not support seeking, all reads + * and writes are from/to offset zero + */ +static loff_t sep_seek(struct file *filp, loff_t offset, int origin) +{ + return -ENOSYS; +} + + + +/** + * sep_file_operations - file operation on sep device + * @sep_ioctl: ioctl handler from user space call + * @sep_poll: poll handler + * @sep_open: handles sep device open request + * @sep_release:handles sep device release request + * @sep_mmap: handles memory mapping requests + * @sep_read: handles read request on sep device + * @sep_write: handles write request on sep device + * @sep_seek: handles seek request on sep device + */ +static const struct file_operations sep_file_operations = { + .owner = THIS_MODULE, + .unlocked_ioctl = sep_ioctl, + .poll = sep_poll, + .open = sep_open, + .release = sep_release, + .mmap = sep_mmap, + .read = sep_read, + .write = sep_write, + .llseek = sep_seek, +}; + +/** + * sep_sysfs_read - read sysfs entry per gives arguments + * @filp: file pointer + * @kobj: kobject pointer + * @attr: binary file attributes + * @buf: read to this buffer + * @pos: offset to read + * @count: amount of data to read + * + * This function is to read sysfs entries for sep driver per given arguments. + */ +static ssize_t +sep_sysfs_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t pos, size_t count) +{ + unsigned long lck_flags; + size_t nleft = count; + struct sep_device *sep = sep_dev; + struct sep_queue_info *queue_elem = NULL; + u32 queue_num = 0; + u32 i = 1; + + spin_lock_irqsave(&sep->sep_queue_lock, lck_flags); + + queue_num = sep->sep_queue_num; + if (queue_num > SEP_DOUBLEBUF_USERS_LIMIT) + queue_num = SEP_DOUBLEBUF_USERS_LIMIT; + + + if (count < sizeof(queue_num) + + (queue_num * sizeof(struct sep_queue_data))) { + spin_unlock_irqrestore(&sep->sep_queue_lock, lck_flags); + return -EINVAL; + } + + memcpy(buf, &queue_num, sizeof(queue_num)); + buf += sizeof(queue_num); + nleft -= sizeof(queue_num); + + list_for_each_entry(queue_elem, &sep->sep_queue_status, list) { + if (i++ > queue_num) + break; + + memcpy(buf, &queue_elem->data, sizeof(queue_elem->data)); + nleft -= sizeof(queue_elem->data); + buf += sizeof(queue_elem->data); + } + spin_unlock_irqrestore(&sep->sep_queue_lock, lck_flags); + + return count - nleft; +} + +/** + * bin_attributes - defines attributes for queue_status + * @attr: attributes (name & permissions) + * @read: function pointer to read this file + * @size: maxinum size of binary attribute + */ +static const struct bin_attribute queue_status = { + .attr = {.name = "queue_status", .mode = 0444}, + .read = sep_sysfs_read, + .size = sizeof(u32) + + (SEP_DOUBLEBUF_USERS_LIMIT * sizeof(struct sep_queue_data)), +}; + +/** + * sep_register_driver_with_fs - register misc devices + * @sep: pointer to struct sep_device + * + * This function registers the driver with the file system + */ +static int sep_register_driver_with_fs(struct sep_device *sep) +{ + int ret_val; + + sep->miscdev_sep.minor = MISC_DYNAMIC_MINOR; + sep->miscdev_sep.name = SEP_DEV_NAME; + sep->miscdev_sep.fops = &sep_file_operations; + + ret_val = misc_register(&sep->miscdev_sep); + if (ret_val) { + dev_warn(&sep->pdev->dev, "misc reg fails for SEP %x\n", + ret_val); + return ret_val; + } + + ret_val = device_create_bin_file(sep->miscdev_sep.this_device, + &queue_status); + if (ret_val) { + dev_warn(&sep->pdev->dev, "sysfs attribute1 fails for SEP %x\n", + ret_val); + return ret_val; + } + + return ret_val; +} + + +/** + *sep_probe - probe a matching PCI device + *@pdev: pci_device + *@ent: pci_device_id + * + *Attempt to set up and configure a SEP device that has been + *discovered by the PCI layer. Allocates all required resources. + */ +static int __devinit sep_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + int error = 0; + struct sep_device *sep = NULL; + + if (sep_dev != NULL) { + dev_dbg(&pdev->dev, "only one SEP supported.\n"); + return -EBUSY; + } + + /* Enable the device */ + error = pci_enable_device(pdev); + if (error) { + dev_warn(&pdev->dev, "error enabling pci device\n"); + goto end_function; + } + + /* Allocate the sep_device structure for this device */ + sep_dev = kzalloc(sizeof(struct sep_device), GFP_ATOMIC); + if (sep_dev == NULL) { + dev_warn(&pdev->dev, + "can't kmalloc the sep_device structure\n"); + error = -ENOMEM; + goto end_function_disable_device; + } + + /* + * We're going to use another variable for actually + * working with the device; this way, if we have + * multiple devices in the future, it would be easier + * to make appropriate changes + */ + sep = sep_dev; + + sep->pdev = pci_dev_get(pdev); + + init_waitqueue_head(&sep->event_transactions); + init_waitqueue_head(&sep->event_interrupt); + spin_lock_init(&sep->snd_rply_lck); + spin_lock_init(&sep->sep_queue_lock); + sema_init(&sep->sep_doublebuf, SEP_DOUBLEBUF_USERS_LIMIT); + + INIT_LIST_HEAD(&sep->sep_queue_status); + + dev_dbg(&sep->pdev->dev, "sep probe: PCI obtained, " + "device being prepared\n"); + dev_dbg(&sep->pdev->dev, "revision is %d\n", sep->pdev->revision); + + /* Set up our register area */ + sep->reg_physical_addr = pci_resource_start(sep->pdev, 0); + if (!sep->reg_physical_addr) { + dev_warn(&sep->pdev->dev, "Error getting register start\n"); + error = -ENODEV; + goto end_function_free_sep_dev; + } + + sep->reg_physical_end = pci_resource_end(sep->pdev, 0); + if (!sep->reg_physical_end) { + dev_warn(&sep->pdev->dev, "Error getting register end\n"); + error = -ENODEV; + goto end_function_free_sep_dev; + } + + sep->reg_addr = ioremap_nocache(sep->reg_physical_addr, + (size_t)(sep->reg_physical_end - sep->reg_physical_addr + 1)); + if (!sep->reg_addr) { + dev_warn(&sep->pdev->dev, "Error getting register virtual\n"); + error = -ENODEV; + goto end_function_free_sep_dev; + } + + dev_dbg(&sep->pdev->dev, + "Register area start %llx end %llx virtual %p\n", + (unsigned long long)sep->reg_physical_addr, + (unsigned long long)sep->reg_physical_end, + sep->reg_addr); + + /* Allocate the shared area */ + sep->shared_size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES + + SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES + + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES + + SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES + + SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES; + + if (sep_map_and_alloc_shared_area(sep)) { + error = -ENOMEM; + /* Allocation failed */ + goto end_function_error; + } + + /* Clear ICR register */ + sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF); + + /* Set the IMR register - open only GPR 2 */ + sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13))); + + /* Read send/receive counters from SEP */ + sep->reply_ct = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); + sep->reply_ct &= 0x3FFFFFFF; + sep->send_ct = sep->reply_ct; + + /* Get the interrupt line */ + error = request_irq(pdev->irq, sep_inthandler, IRQF_SHARED, + "sep_driver", sep); + + if (error) + goto end_function_deallocate_sep_shared_area; + + /* The new chip requires a shared area reconfigure */ + if (sep->pdev->revision != 0) { /* Only for new chip */ + error = sep_reconfig_shared_area(sep); + if (error) + goto end_function_free_irq; + } + + sep->in_use = 1; + + /* Finally magic up the device nodes */ + /* Register driver with the fs */ + error = sep_register_driver_with_fs(sep); + if (error) + goto end_function_free_irq; + +#ifdef SEP_ENABLE_RUNTIME_PM + pm_runtime_put_noidle(&sep->pdev->dev); + pm_runtime_allow(&sep->pdev->dev); + pm_runtime_set_autosuspend_delay(&sep->pdev->dev, + SUSPEND_DELAY); + pm_runtime_use_autosuspend(&sep->pdev->dev); + sep->power_save_setup = 1; +#endif + + sep->in_use = 0; + + /* register kernel crypto driver */ + error = sep_crypto_setup(); + if (error) { + dev_dbg(&sep->pdev->dev, "crypto setup fail\n"); + goto end_function_free_irq; + } + + goto end_function; + +end_function_free_irq: + free_irq(pdev->irq, sep); + +end_function_deallocate_sep_shared_area: + /* De-allocate shared area */ + sep_unmap_and_free_shared_area(sep); + +end_function_error: + iounmap(sep->reg_addr); + +end_function_free_sep_dev: + pci_dev_put(sep_dev->pdev); + kfree(sep_dev); + sep_dev = NULL; + +end_function_disable_device: + pci_disable_device(pdev); + +end_function: + return error; +} + +/** + * sep_remove - handles removing device from pci subsystem + * @pdev: pointer to pci device + * + * This function will handle removing our sep device from pci subsystem on exit + * or unloading this module. It should free up all used resources, and unmap if + * any memory regions mapped. + */ +static void sep_remove(struct pci_dev *pdev) +{ + struct sep_device *sep = sep_dev; + + /* Unregister from fs */ + misc_deregister(&sep->miscdev_sep); + + /* Unregister from kernel crypto */ + sep_crypto_takedown(); + + /* Free the irq */ + free_irq(sep->pdev->irq, sep); + + /* Free the shared area */ + sep_unmap_and_free_shared_area(sep_dev); + iounmap((void __iomem *)sep_dev->reg_addr); + +#ifdef SEP_ENABLE_RUNTIME_PM + if (sep->in_use) { + sep->in_use = 0; + pm_runtime_forbid(&sep->pdev->dev); + pm_runtime_get_noresume(&sep->pdev->dev); + } +#endif + pci_dev_put(sep_dev->pdev); + kfree(sep_dev); + sep_dev = NULL; +} + +/* Initialize struct pci_device_id for our driver */ +static DEFINE_PCI_DEVICE_TABLE(sep_pci_id_tbl) = { + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MFLD_PCI_DEVICE_ID)}, + {0} +}; + +/* Export our pci_device_id structure to user space */ +MODULE_DEVICE_TABLE(pci, sep_pci_id_tbl); + +#ifdef SEP_ENABLE_RUNTIME_PM + +/** + * sep_pm_resume - rsume routine while waking up from S3 state + * @dev: pointer to sep device + * + * This function is to be used to wake up sep driver while system awakes from S3 + * state i.e. suspend to ram. The RAM in intact. + * Notes - revisit with more understanding of pm, ICR/IMR & counters. + */ +static int sep_pci_resume(struct device *dev) +{ + struct sep_device *sep = sep_dev; + + dev_dbg(&sep->pdev->dev, "pci resume called\n"); + + if (sep->power_state == SEP_DRIVER_POWERON) + return 0; + + /* Clear ICR register */ + sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF); + + /* Set the IMR register - open only GPR 2 */ + sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13))); + + /* Read send/receive counters from SEP */ + sep->reply_ct = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); + sep->reply_ct &= 0x3FFFFFFF; + sep->send_ct = sep->reply_ct; + + sep->power_state = SEP_DRIVER_POWERON; + + return 0; +} + +/** + * sep_pm_suspend - suspend routine while going to S3 state + * @dev: pointer to sep device + * + * This function is to be used to suspend sep driver while system goes to S3 + * state i.e. suspend to ram. The RAM in intact and ON during this suspend. + * Notes - revisit with more understanding of pm, ICR/IMR + */ +static int sep_pci_suspend(struct device *dev) +{ + struct sep_device *sep = sep_dev; + + dev_dbg(&sep->pdev->dev, "pci suspend called\n"); + if (sep->in_use == 1) + return -EAGAIN; + + sep->power_state = SEP_DRIVER_POWEROFF; + + /* Clear ICR register */ + sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF); + + /* Set the IMR to block all */ + sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, 0xFFFFFFFF); + + return 0; +} + +/** + * sep_pm_runtime_resume - runtime resume routine + * @dev: pointer to sep device + * + * Notes - revisit with more understanding of pm, ICR/IMR & counters + */ +static int sep_pm_runtime_resume(struct device *dev) +{ + + u32 retval2; + u32 delay_count; + struct sep_device *sep = sep_dev; + + dev_dbg(&sep->pdev->dev, "pm runtime resume called\n"); + + /** + * Wait until the SCU boot is ready + * This is done by iterating SCU_DELAY_ITERATION (10 + * microseconds each) up to SCU_DELAY_MAX (50) times. + * This bit can be set in a random time that is less + * than 500 microseconds after each power resume + */ + retval2 = 0; + delay_count = 0; + while ((!retval2) && (delay_count < SCU_DELAY_MAX)) { + retval2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); + retval2 &= 0x00000008; + if (!retval2) { + udelay(SCU_DELAY_ITERATION); + delay_count += 1; + } + } + + if (!retval2) { + dev_warn(&sep->pdev->dev, "scu boot bit not set at resume\n"); + return -EINVAL; + } + + /* Clear ICR register */ + sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF); + + /* Set the IMR register - open only GPR 2 */ + sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13))); + + /* Read send/receive counters from SEP */ + sep->reply_ct = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); + sep->reply_ct &= 0x3FFFFFFF; + sep->send_ct = sep->reply_ct; + + return 0; +} + +/** + * sep_pm_runtime_suspend - runtime suspend routine + * @dev: pointer to sep device + * + * Notes - revisit with more understanding of pm + */ +static int sep_pm_runtime_suspend(struct device *dev) +{ + struct sep_device *sep = sep_dev; + + dev_dbg(&sep->pdev->dev, "pm runtime suspend called\n"); + + /* Clear ICR register */ + sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF); + return 0; +} + +/** + * sep_pm - power management for sep driver + * @sep_pm_runtime_resume: resume- no communication with cpu & main memory + * @sep_pm_runtime_suspend: suspend- no communication with cpu & main memory + * @sep_pci_suspend: suspend - main memory is still ON + * @sep_pci_resume: resume - main meory is still ON + */ +static const struct dev_pm_ops sep_pm = { + .runtime_resume = sep_pm_runtime_resume, + .runtime_suspend = sep_pm_runtime_suspend, + .resume = sep_pci_resume, + .suspend = sep_pci_suspend, +}; +#endif /* SEP_ENABLE_RUNTIME_PM */ + +/** + * sep_pci_driver - registers this device with pci subsystem + * @name: name identifier for this driver + * @sep_pci_id_tbl: pointer to struct pci_device_id table + * @sep_probe: pointer to probe function in PCI driver + * @sep_remove: pointer to remove function in PCI driver + */ +static struct pci_driver sep_pci_driver = { +#ifdef SEP_ENABLE_RUNTIME_PM + .driver = { + .pm = &sep_pm, + }, +#endif + .name = "sep_sec_driver", + .id_table = sep_pci_id_tbl, + .probe = sep_probe, + .remove = sep_remove +}; + +/** + * sep_init - init function + * + * Module load time. Register the PCI device driver. + */ + +static int __init sep_init(void) +{ + return pci_register_driver(&sep_pci_driver); +} + + +/** + * sep_exit - called to unload driver + * + * Unregister the driver The device will perform all the cleanup required. + */ +static void __exit sep_exit(void) +{ + pci_unregister_driver(&sep_pci_driver); +} + + +module_init(sep_init); +module_exit(sep_exit); + +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/sep/sep_trace_events.h b/drivers/staging/sep/sep_trace_events.h new file mode 100644 index 00000000000..2b053a93afe --- /dev/null +++ b/drivers/staging/sep/sep_trace_events.h @@ -0,0 +1,188 @@ +/* + * If TRACE_SYSTEM is defined, that will be the directory created + * in the ftrace directory under /sys/kernel/debug/tracing/events/ + * + * The define_trace.h below will also look for a file name of + * TRACE_SYSTEM.h where TRACE_SYSTEM is what is defined here. + * In this case, it would look for sample.h + * + * If the header name will be different than the system name + * (as in this case), then you can override the header name that + * define_trace.h will look up by defining TRACE_INCLUDE_FILE + * + * This file is called trace-events-sample.h but we want the system + * to be called "sample". Therefore we must define the name of this + * file: + * + * #define TRACE_INCLUDE_FILE trace-events-sample + * + * As we do an the bottom of this file. + * + * Notice that TRACE_SYSTEM should be defined outside of #if + * protection, just like TRACE_INCLUDE_FILE. + */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM sep + +/* + * Notice that this file is not protected like a normal header. + * We also must allow for rereading of this file. The + * + * || defined(TRACE_HEADER_MULTI_READ) + * + * serves this purpose. + */ +#if !defined(_TRACE_SEP_EVENTS_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SEP_EVENTS_H + +#ifdef SEP_PERF_DEBUG +#define SEP_TRACE_FUNC_IN() trace_sep_func_start(__func__, 0) +#define SEP_TRACE_FUNC_OUT(branch) trace_sep_func_end(__func__, branch) +#define SEP_TRACE_EVENT(branch) trace_sep_misc_event(__func__, branch) +#else +#define SEP_TRACE_FUNC_IN() +#define SEP_TRACE_FUNC_OUT(branch) +#define SEP_TRACE_EVENT(branch) +#endif + + +/* + * All trace headers should include tracepoint.h, until we finally + * make it into a standard header. + */ +#include + +/* + * The TRACE_EVENT macro is broken up into 5 parts. + * + * name: name of the trace point. This is also how to enable the tracepoint. + * A function called trace_foo_bar() will be created. + * + * proto: the prototype of the function trace_foo_bar() + * Here it is trace_foo_bar(char *foo, int bar). + * + * args: must match the arguments in the prototype. + * Here it is simply "foo, bar". + * + * struct: This defines the way the data will be stored in the ring buffer. + * There are currently two types of elements. __field and __array. + * a __field is broken up into (type, name). Where type can be any + * type but an array. + * For an array. there are three fields. (type, name, size). The + * type of elements in the array, the name of the field and the size + * of the array. + * + * __array( char, foo, 10) is the same as saying char foo[10]. + * + * fast_assign: This is a C like function that is used to store the items + * into the ring buffer. + * + * printk: This is a way to print out the data in pretty print. This is + * useful if the system crashes and you are logging via a serial line, + * the data can be printed to the console using this "printk" method. + * + * Note, that for both the assign and the printk, __entry is the handler + * to the data structure in the ring buffer, and is defined by the + * TP_STRUCT__entry. + */ +TRACE_EVENT(sep_func_start, + + TP_PROTO(const char *name, int branch), + + TP_ARGS(name, branch), + + TP_STRUCT__entry( + __array(char, name, 20) + __field(int, branch) + ), + + TP_fast_assign( + strncpy(__entry->name, name, 20); + __entry->branch = branch; + ), + + TP_printk("func_start %s %d", __entry->name, __entry->branch) +); + +TRACE_EVENT(sep_func_end, + + TP_PROTO(const char *name, int branch), + + TP_ARGS(name, branch), + + TP_STRUCT__entry( + __array(char, name, 20) + __field(int, branch) + ), + + TP_fast_assign( + strncpy(__entry->name, name, 20); + __entry->branch = branch; + ), + + TP_printk("func_end %s %d", __entry->name, __entry->branch) +); + +TRACE_EVENT(sep_misc_event, + + TP_PROTO(const char *name, int branch), + + TP_ARGS(name, branch), + + TP_STRUCT__entry( + __array(char, name, 20) + __field(int, branch) + ), + + TP_fast_assign( + strncpy(__entry->name, name, 20); + __entry->branch = branch; + ), + + TP_printk("misc_event %s %d", __entry->name, __entry->branch) +); + + +#endif + +/***** NOTICE! The #if protection ends here. *****/ + + +/* + * There are several ways I could have done this. If I left out the + * TRACE_INCLUDE_PATH, then it would default to the kernel source + * include/trace/events directory. + * + * I could specify a path from the define_trace.h file back to this + * file. + * + * #define TRACE_INCLUDE_PATH ../../samples/trace_events + * + * But the safest and easiest way to simply make it use the directory + * that the file is in is to add in the Makefile: + * + * CFLAGS_trace-events-sample.o := -I$(src) + * + * This will make sure the current path is part of the include + * structure for our file so that define_trace.h can find it. + * + * I could have made only the top level directory the include: + * + * CFLAGS_trace-events-sample.o := -I$(PWD) + * + * And then let the path to this directory be the TRACE_INCLUDE_PATH: + * + * #define TRACE_INCLUDE_PATH samples/trace_events + * + * But then if something defines "samples" or "trace_events" as a macro + * then we could risk that being converted too, and give us an unexpected + * result. + */ +#undef TRACE_INCLUDE_PATH +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_PATH . +/* + * TRACE_INCLUDE_FILE is not needed if the filename and TRACE_SYSTEM are equal + */ +#define TRACE_INCLUDE_FILE sep_trace_events +#include -- cgit v1.2.3-70-g09d2 From 5c0480f21f9896c443b0e65d779c8e09a695da7b Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:30 +0100 Subject: drm/i915: fall through pwrite_gtt_slow to the shmem slow path The gtt_pwrite slowpath grabs the userspace memory with get_user_pages. This will not work for non-page backed memory, like a gtt mmapped gem object. Hence fall throuh to the shmem paths if we hit -EFAULT in the gtt paths. Now the shmem paths have exactly the same problem, but this way we only need to rearrange the code in one write path. v2: v1 accidentaly falls back to shmem pwrite for phys objects. Fixed. v3: Make the codeflow around phys_pwrite cleara as suggested by Chris Wilson. Reviewed-by: Chris Wilson Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index df23c627341..7bb32ecc13c 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -996,10 +996,13 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, * pread/pwrite currently are reading and writing from the CPU * perspective, requiring manual detiling by the client. */ - if (obj->phys_obj) + if (obj->phys_obj) { ret = i915_gem_phys_pwrite(dev, obj, args, file); - else if (obj->gtt_space && - obj->base.write_domain != I915_GEM_DOMAIN_CPU) { + goto out; + } + + if (obj->gtt_space && + obj->base.write_domain != I915_GEM_DOMAIN_CPU) { ret = i915_gem_object_pin(obj, 0, true); if (ret) goto out; @@ -1018,18 +1021,24 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, out_unpin: i915_gem_object_unpin(obj); - } else { - ret = i915_gem_object_set_to_cpu_domain(obj, 1); - if (ret) - goto out; - ret = -EFAULT; - if (!i915_gem_object_needs_bit17_swizzle(obj)) - ret = i915_gem_shmem_pwrite_fast(dev, obj, args, file); - if (ret == -EFAULT) - ret = i915_gem_shmem_pwrite_slow(dev, obj, args, file); + if (ret != -EFAULT) + goto out; + /* Fall through to the shmfs paths because the gtt paths might + * fail with non-page-backed user pointers (e.g. gtt mappings + * when moving data between textures). */ } + ret = i915_gem_object_set_to_cpu_domain(obj, 1); + if (ret) + goto out; + + ret = -EFAULT; + if (!i915_gem_object_needs_bit17_swizzle(obj)) + ret = i915_gem_shmem_pwrite_fast(dev, obj, args, file); + if (ret == -EFAULT) + ret = i915_gem_shmem_pwrite_slow(dev, obj, args, file); + out: drm_gem_object_unreference(&obj->base); unlock: -- cgit v1.2.3-70-g09d2 From 8c59967c448af5d77fe5189d0e73f32cd3dbe439 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:31 +0100 Subject: drm/i915: rewrite shmem_pwrite_slow to use copy_from_user ... instead of get_user_pages, because that fails on non page-backed user addresses like e.g. a gtt mapping of a bo. To get there essentially copy the vfs read path into pagecache. We can't call that right away because we have to take care of bit17 swizzling. To not deadlock with our own pagefault handler we need to completely drop struct_mutex, reducing the atomicty-guarantees of our userspace abi. Implications for racing with other gem ioctl: - execbuf, pwrite, pread: Due to -EFAULT fallback to slow paths there's already the risk of the pwrite call not being atomic, no degration. - read/write access to mmaps: already fully racy, no degration. - set_tiling: Calling set_tiling while reading/writing is already pretty much undefined, now it just got a bit worse. set_tiling is only called by libdrm on unused/new bos, so no problem. - set_domain: When changing to the gtt domain while copying (without any read/write access, e.g. for synchronization), we might leave unflushed data in the cpu caches. The clflush_object at the end of pwrite_slow takes care of this problem. - truncating of purgeable objects: the shmem_read_mapping_page call could reinstate backing storage for truncated objects. The check at the end of pwrite_slow takes care of this. v2: - add missing intel_gtt_chipset_flush - add __ to copy_from_user_swizzled as suggest by Chris Wilson. v3: Fixup bit17 swizzling, it swizzled the wrong pages. Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 127 ++++++++++++++++++++-------------------- 1 file changed, 65 insertions(+), 62 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 7bb32ecc13c..3f391aa76d3 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -58,6 +58,7 @@ static void i915_gem_free_object_tail(struct drm_i915_gem_object *obj); static int i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc); +static void i915_gem_object_truncate(struct drm_i915_gem_object *obj); /* some bookkeeping */ static void i915_gem_info_add_obj(struct drm_i915_private *dev_priv, @@ -385,6 +386,32 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, return 0; } +static inline int +__copy_from_user_swizzled(char __user *gpu_vaddr, int gpu_offset, + const char *cpu_vaddr, + int length) +{ + int ret, cpu_offset = 0; + + while (length > 0) { + int cacheline_end = ALIGN(gpu_offset + 1, 64); + int this_length = min(cacheline_end - gpu_offset, length); + int swizzled_gpu_offset = gpu_offset ^ 64; + + ret = __copy_from_user(gpu_vaddr + swizzled_gpu_offset, + cpu_vaddr + cpu_offset, + this_length); + if (ret) + return ret + length; + + cpu_offset += this_length; + gpu_offset += this_length; + length -= this_length; + } + + return 0; +} + /** * This is the fallback shmem pread path, which allocates temporary storage * in kernel space to copy_to_user into outside of the struct_mutex, so we @@ -841,71 +868,36 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_file *file) { struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; - struct mm_struct *mm = current->mm; - struct page **user_pages; ssize_t remain; - loff_t offset, pinned_pages, i; - loff_t first_data_page, last_data_page, num_pages; - int shmem_page_offset; - int data_page_index, data_page_offset; - int page_length; - int ret; - uint64_t data_ptr = args->data_ptr; - int do_bit17_swizzling; + loff_t offset; + char __user *user_data; + int shmem_page_offset, page_length, ret; + int obj_do_bit17_swizzling, page_do_bit17_swizzling; + user_data = (char __user *) (uintptr_t) args->data_ptr; remain = args->size; - /* Pin the user pages containing the data. We can't fault while - * holding the struct mutex, and all of the pwrite implementations - * want to hold it while dereferencing the user data. - */ - first_data_page = data_ptr / PAGE_SIZE; - last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE; - num_pages = last_data_page - first_data_page + 1; - - user_pages = drm_malloc_ab(num_pages, sizeof(struct page *)); - if (user_pages == NULL) - return -ENOMEM; - - mutex_unlock(&dev->struct_mutex); - down_read(&mm->mmap_sem); - pinned_pages = get_user_pages(current, mm, (uintptr_t)args->data_ptr, - num_pages, 0, 0, user_pages, NULL); - up_read(&mm->mmap_sem); - mutex_lock(&dev->struct_mutex); - if (pinned_pages < num_pages) { - ret = -EFAULT; - goto out; - } - - ret = i915_gem_object_set_to_cpu_domain(obj, 1); - if (ret) - goto out; - - do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); + obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); offset = args->offset; obj->dirty = 1; + mutex_unlock(&dev->struct_mutex); + while (remain > 0) { struct page *page; + char *vaddr; /* Operation in this page * * shmem_page_offset = offset within page in shmem file - * data_page_index = page number in get_user_pages return - * data_page_offset = offset with data_page_index page. * page_length = bytes to copy for this page */ shmem_page_offset = offset_in_page(offset); - data_page_index = data_ptr / PAGE_SIZE - first_data_page; - data_page_offset = offset_in_page(data_ptr); page_length = remain; if ((shmem_page_offset + page_length) > PAGE_SIZE) page_length = PAGE_SIZE - shmem_page_offset; - if ((data_page_offset + page_length) > PAGE_SIZE) - page_length = PAGE_SIZE - data_page_offset; page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT); if (IS_ERR(page)) { @@ -913,34 +905,45 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, goto out; } - if (do_bit17_swizzling) { - slow_shmem_bit17_copy(page, - shmem_page_offset, - user_pages[data_page_index], - data_page_offset, - page_length, - 0); - } else { - slow_shmem_copy(page, - shmem_page_offset, - user_pages[data_page_index], - data_page_offset, - page_length); - } + page_do_bit17_swizzling = obj_do_bit17_swizzling && + (page_to_phys(page) & (1 << 17)) != 0; + + vaddr = kmap(page); + if (page_do_bit17_swizzling) + ret = __copy_from_user_swizzled(vaddr, shmem_page_offset, + user_data, + page_length); + else + ret = __copy_from_user(vaddr + shmem_page_offset, + user_data, + page_length); + kunmap(page); set_page_dirty(page); mark_page_accessed(page); page_cache_release(page); + if (ret) { + ret = -EFAULT; + goto out; + } + remain -= page_length; - data_ptr += page_length; + user_data += page_length; offset += page_length; } out: - for (i = 0; i < pinned_pages; i++) - page_cache_release(user_pages[i]); - drm_free_large(user_pages); + mutex_lock(&dev->struct_mutex); + /* Fixup: Kill any reinstated backing storage pages */ + if (obj->madv == __I915_MADV_PURGED) + i915_gem_object_truncate(obj); + /* and flush dirty cachelines in case the object isn't in the cpu write + * domain anymore. */ + if (obj->base.write_domain != I915_GEM_DOMAIN_CPU) { + i915_gem_clflush_object(obj); + intel_gtt_chipset_flush(); + } return ret; } -- cgit v1.2.3-70-g09d2 From 8461d2267726dddcb9b5d6ae6b32769b38a326cc Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:32 +0100 Subject: drm/i915: rewrite shmem_pread_slow to use copy_to_user Like for shmem_pwrite_slow. The only difference is that because we read data, we can leave the fetched cachelines in the cpu: In the case that the object isn't in the cpu read domain anymore, the clflush for the next cpu read domain invalidation will simply drop these cachelines. slow_shmem_bit17_copy is now ununsed, so kill it. With this patch tests/gem_mmap_gtt now actually works. v2: add __ to copy_to_user_swizzled as suggested by Chris Wilson. v3: Fixup the swizzling logic, it swizzled the wrong pages. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=38115 Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 191 ++++++++++++---------------------------- 1 file changed, 57 insertions(+), 134 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 3f391aa76d3..51a2b0c2a30 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -259,73 +259,6 @@ static int i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj) obj->tiling_mode != I915_TILING_NONE; } -static inline void -slow_shmem_copy(struct page *dst_page, - int dst_offset, - struct page *src_page, - int src_offset, - int length) -{ - char *dst_vaddr, *src_vaddr; - - dst_vaddr = kmap(dst_page); - src_vaddr = kmap(src_page); - - memcpy(dst_vaddr + dst_offset, src_vaddr + src_offset, length); - - kunmap(src_page); - kunmap(dst_page); -} - -static inline void -slow_shmem_bit17_copy(struct page *gpu_page, - int gpu_offset, - struct page *cpu_page, - int cpu_offset, - int length, - int is_read) -{ - char *gpu_vaddr, *cpu_vaddr; - - /* Use the unswizzled path if this page isn't affected. */ - if ((page_to_phys(gpu_page) & (1 << 17)) == 0) { - if (is_read) - return slow_shmem_copy(cpu_page, cpu_offset, - gpu_page, gpu_offset, length); - else - return slow_shmem_copy(gpu_page, gpu_offset, - cpu_page, cpu_offset, length); - } - - gpu_vaddr = kmap(gpu_page); - cpu_vaddr = kmap(cpu_page); - - /* Copy the data, XORing A6 with A17 (1). The user already knows he's - * XORing with the other bits (A9 for Y, A9 and A10 for X) - */ - while (length > 0) { - int cacheline_end = ALIGN(gpu_offset + 1, 64); - int this_length = min(cacheline_end - gpu_offset, length); - int swizzled_gpu_offset = gpu_offset ^ 64; - - if (is_read) { - memcpy(cpu_vaddr + cpu_offset, - gpu_vaddr + swizzled_gpu_offset, - this_length); - } else { - memcpy(gpu_vaddr + swizzled_gpu_offset, - cpu_vaddr + cpu_offset, - this_length); - } - cpu_offset += this_length; - gpu_offset += this_length; - length -= this_length; - } - - kunmap(cpu_page); - kunmap(gpu_page); -} - /** * This is the fast shmem pread path, which attempts to copy_from_user directly * from the backing pages of the object to the user's address space. On a @@ -386,6 +319,32 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, return 0; } +static inline int +__copy_to_user_swizzled(char __user *cpu_vaddr, + const char *gpu_vaddr, int gpu_offset, + int length) +{ + int ret, cpu_offset = 0; + + while (length > 0) { + int cacheline_end = ALIGN(gpu_offset + 1, 64); + int this_length = min(cacheline_end - gpu_offset, length); + int swizzled_gpu_offset = gpu_offset ^ 64; + + ret = __copy_to_user(cpu_vaddr + cpu_offset, + gpu_vaddr + swizzled_gpu_offset, + this_length); + if (ret) + return ret + length; + + cpu_offset += this_length; + gpu_offset += this_length; + length -= this_length; + } + + return 0; +} + static inline int __copy_from_user_swizzled(char __user *gpu_vaddr, int gpu_offset, const char *cpu_vaddr, @@ -425,72 +384,34 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_file *file) { struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; - struct mm_struct *mm = current->mm; - struct page **user_pages; + char __user *user_data; ssize_t remain; - loff_t offset, pinned_pages, i; - loff_t first_data_page, last_data_page, num_pages; - int shmem_page_offset; - int data_page_index, data_page_offset; - int page_length; - int ret; - uint64_t data_ptr = args->data_ptr; - int do_bit17_swizzling; + loff_t offset; + int shmem_page_offset, page_length, ret; + int obj_do_bit17_swizzling, page_do_bit17_swizzling; + user_data = (char __user *) (uintptr_t) args->data_ptr; remain = args->size; - /* Pin the user pages containing the data. We can't fault while - * holding the struct mutex, yet we want to hold it while - * dereferencing the user data. - */ - first_data_page = data_ptr / PAGE_SIZE; - last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE; - num_pages = last_data_page - first_data_page + 1; + obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); - user_pages = drm_malloc_ab(num_pages, sizeof(struct page *)); - if (user_pages == NULL) - return -ENOMEM; + offset = args->offset; mutex_unlock(&dev->struct_mutex); - down_read(&mm->mmap_sem); - pinned_pages = get_user_pages(current, mm, (uintptr_t)args->data_ptr, - num_pages, 1, 0, user_pages, NULL); - up_read(&mm->mmap_sem); - mutex_lock(&dev->struct_mutex); - if (pinned_pages < num_pages) { - ret = -EFAULT; - goto out; - } - - ret = i915_gem_object_set_cpu_read_domain_range(obj, - args->offset, - args->size); - if (ret) - goto out; - - do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); - - offset = args->offset; while (remain > 0) { struct page *page; + char *vaddr; /* Operation in this page * * shmem_page_offset = offset within page in shmem file - * data_page_index = page number in get_user_pages return - * data_page_offset = offset with data_page_index page. * page_length = bytes to copy for this page */ shmem_page_offset = offset_in_page(offset); - data_page_index = data_ptr / PAGE_SIZE - first_data_page; - data_page_offset = offset_in_page(data_ptr); - page_length = remain; if ((shmem_page_offset + page_length) > PAGE_SIZE) page_length = PAGE_SIZE - shmem_page_offset; - if ((data_page_offset + page_length) > PAGE_SIZE) - page_length = PAGE_SIZE - data_page_offset; page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT); if (IS_ERR(page)) { @@ -498,36 +419,38 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, goto out; } - if (do_bit17_swizzling) { - slow_shmem_bit17_copy(page, - shmem_page_offset, - user_pages[data_page_index], - data_page_offset, - page_length, - 1); - } else { - slow_shmem_copy(user_pages[data_page_index], - data_page_offset, - page, - shmem_page_offset, - page_length); - } + page_do_bit17_swizzling = obj_do_bit17_swizzling && + (page_to_phys(page) & (1 << 17)) != 0; + + vaddr = kmap(page); + if (page_do_bit17_swizzling) + ret = __copy_to_user_swizzled(user_data, + vaddr, shmem_page_offset, + page_length); + else + ret = __copy_to_user(user_data, + vaddr + shmem_page_offset, + page_length); + kunmap(page); mark_page_accessed(page); page_cache_release(page); + if (ret) { + ret = -EFAULT; + goto out; + } + remain -= page_length; - data_ptr += page_length; + user_data += page_length; offset += page_length; } out: - for (i = 0; i < pinned_pages; i++) { - SetPageDirty(user_pages[i]); - mark_page_accessed(user_pages[i]); - page_cache_release(user_pages[i]); - } - drm_free_large(user_pages); + mutex_lock(&dev->struct_mutex); + /* Fixup: Kill any reinstated backing storage pages */ + if (obj->madv == __I915_MADV_PURGED) + i915_gem_object_truncate(obj); return ret; } -- cgit v1.2.3-70-g09d2 From 393f9ffb7956c0ab8edb971d2c98d94aad9eeef8 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Tue, 31 Jan 2012 00:07:33 -0800 Subject: Input: pcf8574_keypad - fix typo in Kconfig Correct spelling "connetced" to "connected" in pcf8574_keypad description in drivers/input/misc/Kconfig. Signed-off-by: Masanari Iida Signed-off-by: Dmitry Torokhov --- drivers/input/misc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 7b46781c30c..c528deadd63 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -415,7 +415,7 @@ config INPUT_PCF8574 tristate "PCF8574 Keypad input device" depends on I2C && EXPERIMENTAL help - Say Y here if you want to support a keypad connetced via I2C + Say Y here if you want to support a keypad connected via I2C with a PCF8574. To compile this driver as a module, choose M here: the -- cgit v1.2.3-70-g09d2 From 8b4a0c1fe3b03c0cfe829413481d69c2e6fd844c Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Tue, 31 Jan 2012 00:07:33 -0800 Subject: Input: wacom - use BTN_TOOL_FINGER to indicate touch device type Tested-by: Chris Bagwell Reviewed-by: Chris Bagwell Signed-off-by: Ping Cheng Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_sys.c | 6 +----- drivers/input/tablet/wacom_wac.c | 4 ++-- 2 files changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 7e63183a6c6..c9588eececf 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -176,7 +176,7 @@ static int wacom_parse_logical_collection(unsigned char *report, /* Logical collection is only used by 3rd gen Bamboo Touch */ features->pktlen = WACOM_PKGLEN_BBTOUCH3; - features->device_type = BTN_TOOL_DOUBLETAP; + features->device_type = BTN_TOOL_FINGER; /* * Stylus and Touch have same active area @@ -286,12 +286,10 @@ static int wacom_parse_hid(struct usb_interface *intf, if (features->type == TABLETPC2FG) { /* need to reset back */ features->pktlen = WACOM_PKGLEN_TPC2FG; - features->device_type = BTN_TOOL_DOUBLETAP; } if (features->type == BAMBOO_PT) { /* need to reset back */ features->pktlen = WACOM_PKGLEN_BBTOUCH; - features->device_type = BTN_TOOL_DOUBLETAP; features->x_phy = get_unaligned_le16(&report[i + 5]); features->x_max = @@ -325,7 +323,6 @@ static int wacom_parse_hid(struct usb_interface *intf, if (features->type == TABLETPC2FG) { /* need to reset back */ features->pktlen = WACOM_PKGLEN_TPC2FG; - features->device_type = BTN_TOOL_DOUBLETAP; features->y_max = get_unaligned_le16(&report[i + 3]); features->y_phy = @@ -334,7 +331,6 @@ static int wacom_parse_hid(struct usb_interface *intf, } else if (features->type == BAMBOO_PT) { /* need to reset back */ features->pktlen = WACOM_PKGLEN_BBTOUCH; - features->device_type = BTN_TOOL_DOUBLETAP; features->y_phy = get_unaligned_le16(&report[i + 3]); features->y_max = diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index a22e7789d91..e18f3623268 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -1317,7 +1317,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, break; case TABLETPC2FG: - if (features->device_type == BTN_TOOL_DOUBLETAP) { + if (features->device_type == BTN_TOOL_FINGER) { input_mt_init_slots(input_dev, 2); input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE, @@ -1366,7 +1366,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, __set_bit(INPUT_PROP_POINTER, input_dev->propbit); - if (features->device_type == BTN_TOOL_DOUBLETAP) { + if (features->device_type == BTN_TOOL_FINGER) { __set_bit(BTN_LEFT, input_dev->keybit); __set_bit(BTN_FORWARD, input_dev->keybit); __set_bit(BTN_BACK, input_dev->keybit); -- cgit v1.2.3-70-g09d2 From 31175a8348af76aea2f557857c90467d13632dc3 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Tue, 31 Jan 2012 00:07:33 -0800 Subject: Input: wacom - use switch statement for wacom_tpc_irq() And add two new data formats. Tested-by: Chris Bagwell Reviewed-by: Chris Bagwell Signed-off-by: Ping Cheng Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_wac.c | 24 ++++++++++++++++++------ drivers/input/tablet/wacom_wac.h | 2 ++ 2 files changed, 20 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index e18f3623268..9283507b13a 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -832,12 +832,24 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) dbg("wacom_tpc_irq: received report #%d", data[0]); - if (len == WACOM_PKGLEN_TPC1FG || data[0] == WACOM_REPORT_TPC1FG) - return wacom_tpc_single_touch(wacom, len); - else if (data[0] == WACOM_REPORT_TPC2FG) - return wacom_tpc_mt_touch(wacom); - else if (data[0] == WACOM_REPORT_PENABLED) - return wacom_tpc_pen(wacom); + switch (len) { + case WACOM_PKGLEN_TPC1FG: + return wacom_tpc_single_touch(wacom, len); + + case WACOM_PKGLEN_TPC2FG: + return wacom_tpc_mt_touch(wacom); + + default: + switch (data[0]) { + case WACOM_REPORT_TPC1FG: + case WACOM_REPORT_TPCHID: + case WACOM_REPORT_TPCST: + return wacom_tpc_single_touch(wacom, len); + + case WACOM_REPORT_PENABLED: + return wacom_tpc_pen(wacom); + } + } return 0; } diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index 050acaefee7..4f0ba21b019 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h @@ -39,6 +39,8 @@ #define WACOM_REPORT_INTUOSPAD 12 #define WACOM_REPORT_TPC1FG 6 #define WACOM_REPORT_TPC2FG 13 +#define WACOM_REPORT_TPCHID 15 +#define WACOM_REPORT_TPCST 16 /* device quirks */ #define WACOM_QUIRK_MULTI_INPUT 0x0001 -- cgit v1.2.3-70-g09d2 From 4065d1e7b2164cff4af57b58fac887df2fe75d2a Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Tue, 31 Jan 2012 00:18:00 -0800 Subject: Input: add Cypress TTSP capacitive multi-touch screen support Cypress TrueTouch(tm) Standard Product controllers are found in a wide range of embedded devices. This driver add support for a variety of TTSP controllers. Since the hardware is capable of tracking identifiable contacts, multi-touch protocol type B (stateful) is used to report contact information. The driver is composed of a core driver that process the data sent by the contacts and a set of bus specific interface modules. This patch adds the base core TTSP driver. Signed-off-by: Javier Martinez Canillas Reviewed-by: Henrik Rydberg Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/Kconfig | 32 +- drivers/input/touchscreen/Makefile | 5 +- drivers/input/touchscreen/cyttsp_core.c | 625 ++++++++++++++++++++++++++++++++ drivers/input/touchscreen/cyttsp_core.h | 149 ++++++++ drivers/input/touchscreen/cyttsp_i2c.c | 146 ++++++++ drivers/input/touchscreen/cyttsp_spi.c | 210 +++++++++++ include/linux/input/cyttsp.h | 58 +++ 7 files changed, 1223 insertions(+), 2 deletions(-) create mode 100644 drivers/input/touchscreen/cyttsp_core.c create mode 100644 drivers/input/touchscreen/cyttsp_core.h create mode 100644 drivers/input/touchscreen/cyttsp_i2c.c create mode 100644 drivers/input/touchscreen/cyttsp_spi.c create mode 100644 include/linux/input/cyttsp.h (limited to 'drivers') diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 4af2a18eb3b..2b21a7066d3 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -139,7 +139,6 @@ config TOUCHSCREEN_CY8CTMG110 tristate "cy8ctmg110 touchscreen" depends on I2C depends on GPIOLIB - help Say Y here if you have a cy8ctmg110 capacitive touchscreen on an AAVA device. @@ -149,6 +148,37 @@ config TOUCHSCREEN_CY8CTMG110 To compile this driver as a module, choose M here: the module will be called cy8ctmg110_ts. +config TOUCHSCREEN_CYTTSP_CORE + tristate "Cypress TTSP touchscreen" + help + Say Y here if you have a touchscreen using controller from + the Cypress TrueTouch(tm) Standard Product family connected + to your system. You will also need to select appropriate + bus connection below. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called cyttsp_core. + +config TOUCHSCREEN_CYTTSP_I2C + tristate "support I2C bus connection" + depends on TOUCHSCREEN_CYTTSP_CORE && I2C + help + Say Y here if the touchscreen is connected via I2C bus. + + To compile this driver as a module, choose M here: the + module will be called cyttsp_i2c. + +config TOUCHSCREEN_CYTTSP_SPI + tristate "support SPI bus connection" + depends on TOUCHSCREEN_CYTTSP_CORE && SPI_MASTER + help + Say Y here if the touchscreen is connected via SPI bus. + + To compile this driver as a module, choose M here: the + module will be called cyttsp_spi. + config TOUCHSCREEN_DA9034 tristate "Touchscreen support for Dialog Semiconductor DA9034" depends on PMIC_DA903X diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 496091e8846..d9acbdcda3d 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -16,8 +16,11 @@ obj-$(CONFIG_TOUCHSCREEN_ATMEL_MXT) += atmel_mxt_ts.o obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o obj-$(CONFIG_TOUCHSCREEN_AUO_PIXCIR) += auo-pixcir-ts.o obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o -obj-$(CONFIG_TOUCHSCREEN_BU21013) += bu21013_ts.o +obj-$(CONFIG_TOUCHSCREEN_BU21013) += bu21013_ts.o obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110) += cy8ctmg110_ts.o +obj-$(CONFIG_TOUCHSCREEN_CYTTSP_CORE) += cyttsp_core.o +obj-$(CONFIG_TOUCHSCREEN_CYTTSP_I2C) += cyttsp_i2c.o +obj-$(CONFIG_TOUCHSCREEN_CYTTSP_SPI) += cyttsp_spi.o obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += hampshire.o diff --git a/drivers/input/touchscreen/cyttsp_core.c b/drivers/input/touchscreen/cyttsp_core.c new file mode 100644 index 00000000000..8be22479b41 --- /dev/null +++ b/drivers/input/touchscreen/cyttsp_core.c @@ -0,0 +1,625 @@ +/* + * Core Source for: + * Cypress TrueTouch(TM) Standard Product (TTSP) touchscreen drivers. + * For use with Cypress Txx3xx parts. + * Supported parts include: + * CY8CTST341 + * CY8CTMA340 + * + * Copyright (C) 2009, 2010, 2011 Cypress Semiconductor, Inc. + * Copyright (C) 2012 Javier Martinez Canillas + * + * 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. + * + * Contact Cypress Semiconductor at www.cypress.com + * + */ + +#include +#include +#include +#include +#include +#include + +#include "cyttsp_core.h" + +/* Bootloader number of command keys */ +#define CY_NUM_BL_KEYS 8 + +/* helpers */ +#define GET_NUM_TOUCHES(x) ((x) & 0x0F) +#define IS_LARGE_AREA(x) (((x) & 0x10) >> 4) +#define IS_BAD_PKT(x) ((x) & 0x20) +#define IS_VALID_APP(x) ((x) & 0x01) +#define IS_OPERATIONAL_ERR(x) ((x) & 0x3F) +#define GET_HSTMODE(reg) (((reg) & 0x70) >> 4) +#define GET_BOOTLOADERMODE(reg) (((reg) & 0x10) >> 4) + +#define CY_REG_BASE 0x00 +#define CY_REG_ACT_DIST 0x1E +#define CY_REG_ACT_INTRVL 0x1D +#define CY_REG_TCH_TMOUT (CY_REG_ACT_INTRVL + 1) +#define CY_REG_LP_INTRVL (CY_REG_TCH_TMOUT + 1) +#define CY_MAXZ 255 +#define CY_DELAY_DFLT 20 /* ms */ +#define CY_DELAY_MAX 500 +#define CY_ACT_DIST_DFLT 0xF8 +#define CY_HNDSHK_BIT 0x80 +/* device mode bits */ +#define CY_OPERATE_MODE 0x00 +#define CY_SYSINFO_MODE 0x10 +/* power mode select bits */ +#define CY_SOFT_RESET_MODE 0x01 /* return to Bootloader mode */ +#define CY_DEEP_SLEEP_MODE 0x02 +#define CY_LOW_POWER_MODE 0x04 + +/* Slots management */ +#define CY_MAX_FINGER 4 +#define CY_MAX_ID 16 + +static const u8 bl_command[] = { + 0x00, /* file offset */ + 0xFF, /* command */ + 0xA5, /* exit bootloader command */ + 0, 1, 2, 3, 4, 5, 6, 7 /* default keys */ +}; + +static int ttsp_read_block_data(struct cyttsp *ts, u8 command, + u8 length, void *buf) +{ + int error; + int tries; + + for (tries = 0; tries < CY_NUM_RETRY; tries++) { + error = ts->bus_ops->read(ts, command, length, buf); + if (!error) + return 0; + + msleep(CY_DELAY_DFLT); + } + + return -EIO; +} + +static int ttsp_write_block_data(struct cyttsp *ts, u8 command, + u8 length, void *buf) +{ + int error; + int tries; + + for (tries = 0; tries < CY_NUM_RETRY; tries++) { + error = ts->bus_ops->write(ts, command, length, buf); + if (!error) + return 0; + + msleep(CY_DELAY_DFLT); + } + + return -EIO; +} + +static int ttsp_send_command(struct cyttsp *ts, u8 cmd) +{ + return ttsp_write_block_data(ts, CY_REG_BASE, sizeof(cmd), &cmd); +} + +static int cyttsp_load_bl_regs(struct cyttsp *ts) +{ + memset(&ts->bl_data, 0, sizeof(ts->bl_data)); + ts->bl_data.bl_status = 0x10; + + return ttsp_read_block_data(ts, CY_REG_BASE, + sizeof(ts->bl_data), &ts->bl_data); +} + +static int cyttsp_exit_bl_mode(struct cyttsp *ts) +{ + int error; + u8 bl_cmd[sizeof(bl_command)]; + + memcpy(bl_cmd, bl_command, sizeof(bl_command)); + if (ts->pdata->bl_keys) + memcpy(&bl_cmd[sizeof(bl_command) - CY_NUM_BL_KEYS], + ts->pdata->bl_keys, sizeof(bl_command)); + + error = ttsp_write_block_data(ts, CY_REG_BASE, + sizeof(bl_cmd), bl_cmd); + if (error) + return error; + + /* wait for TTSP Device to complete the operation */ + msleep(CY_DELAY_DFLT); + + error = cyttsp_load_bl_regs(ts); + if (error) + return error; + + if (GET_BOOTLOADERMODE(ts->bl_data.bl_status)) + return -EIO; + + return 0; +} + +static int cyttsp_set_operational_mode(struct cyttsp *ts) +{ + int error; + + error = ttsp_send_command(ts, CY_OPERATE_MODE); + if (error) + return error; + + /* wait for TTSP Device to complete switch to Operational mode */ + error = ttsp_read_block_data(ts, CY_REG_BASE, + sizeof(ts->xy_data), &ts->xy_data); + if (error) + return error; + + return ts->xy_data.act_dist == CY_ACT_DIST_DFLT ? -EIO : 0; +} + +static int cyttsp_set_sysinfo_mode(struct cyttsp *ts) +{ + int error; + + memset(&ts->sysinfo_data, 0, sizeof(ts->sysinfo_data)); + + /* switch to sysinfo mode */ + error = ttsp_send_command(ts, CY_SYSINFO_MODE); + if (error) + return error; + + /* read sysinfo registers */ + msleep(CY_DELAY_DFLT); + error = ttsp_read_block_data(ts, CY_REG_BASE, sizeof(ts->sysinfo_data), + &ts->sysinfo_data); + if (error) + return error; + + if (!ts->sysinfo_data.tts_verh && !ts->sysinfo_data.tts_verl) + return -EIO; + + return 0; +} + +static int cyttsp_set_sysinfo_regs(struct cyttsp *ts) +{ + int retval = 0; + + if (ts->pdata->act_intrvl != CY_ACT_INTRVL_DFLT || + ts->pdata->tch_tmout != CY_TCH_TMOUT_DFLT || + ts->pdata->lp_intrvl != CY_LP_INTRVL_DFLT) { + + u8 intrvl_ray[] = { + ts->pdata->act_intrvl, + ts->pdata->tch_tmout, + ts->pdata->lp_intrvl + }; + + /* set intrvl registers */ + retval = ttsp_write_block_data(ts, CY_REG_ACT_INTRVL, + sizeof(intrvl_ray), intrvl_ray); + msleep(CY_DELAY_DFLT); + } + + return retval; +} + +static int cyttsp_soft_reset(struct cyttsp *ts) +{ + unsigned long timeout; + int retval; + + /* wait for interrupt to set ready completion */ + INIT_COMPLETION(ts->bl_ready); + ts->state = CY_BL_STATE; + + enable_irq(ts->irq); + + retval = ttsp_send_command(ts, CY_SOFT_RESET_MODE); + if (retval) + goto out; + + timeout = wait_for_completion_timeout(&ts->bl_ready, + msecs_to_jiffies(CY_DELAY_DFLT * CY_DELAY_MAX)); + retval = timeout ? 0 : -EIO; + +out: + ts->state = CY_IDLE_STATE; + disable_irq(ts->irq); + return retval; +} + +static int cyttsp_act_dist_setup(struct cyttsp *ts) +{ + u8 act_dist_setup = ts->pdata->act_dist; + + /* Init gesture; active distance setup */ + return ttsp_write_block_data(ts, CY_REG_ACT_DIST, + sizeof(act_dist_setup), &act_dist_setup); +} + +static void cyttsp_extract_track_ids(struct cyttsp_xydata *xy_data, int *ids) +{ + ids[0] = xy_data->touch12_id >> 4; + ids[1] = xy_data->touch12_id & 0xF; + ids[2] = xy_data->touch34_id >> 4; + ids[3] = xy_data->touch34_id & 0xF; +} + +static const struct cyttsp_tch *cyttsp_get_tch(struct cyttsp_xydata *xy_data, + int idx) +{ + switch (idx) { + case 0: + return &xy_data->tch1; + case 1: + return &xy_data->tch2; + case 2: + return &xy_data->tch3; + case 3: + return &xy_data->tch4; + default: + return NULL; + } +} + +static void cyttsp_report_tchdata(struct cyttsp *ts) +{ + struct cyttsp_xydata *xy_data = &ts->xy_data; + struct input_dev *input = ts->input; + int num_tch = GET_NUM_TOUCHES(xy_data->tt_stat); + const struct cyttsp_tch *tch; + int ids[CY_MAX_ID]; + int i; + DECLARE_BITMAP(used, CY_MAX_ID); + + if (IS_LARGE_AREA(xy_data->tt_stat) == 1) { + /* terminate all active tracks */ + num_tch = 0; + dev_dbg(ts->dev, "%s: Large area detected\n", __func__); + } else if (num_tch > CY_MAX_FINGER) { + /* terminate all active tracks */ + num_tch = 0; + dev_dbg(ts->dev, "%s: Num touch error detected\n", __func__); + } else if (IS_BAD_PKT(xy_data->tt_mode)) { + /* terminate all active tracks */ + num_tch = 0; + dev_dbg(ts->dev, "%s: Invalid buffer detected\n", __func__); + } + + cyttsp_extract_track_ids(xy_data, ids); + + bitmap_zero(used, CY_MAX_ID); + + for (i = 0; i < num_tch; i++) { + tch = cyttsp_get_tch(xy_data, i); + + input_mt_slot(input, ids[i]); + input_mt_report_slot_state(input, MT_TOOL_FINGER, true); + input_report_abs(input, ABS_MT_POSITION_X, be16_to_cpu(tch->x)); + input_report_abs(input, ABS_MT_POSITION_Y, be16_to_cpu(tch->y)); + input_report_abs(input, ABS_MT_TOUCH_MAJOR, tch->z); + + __set_bit(ids[i], used); + } + + for (i = 0; i < CY_MAX_ID; i++) { + if (test_bit(i, used)) + continue; + + input_mt_slot(input, i); + input_mt_report_slot_state(input, MT_TOOL_FINGER, false); + } + + input_sync(input); +} + +static irqreturn_t cyttsp_irq(int irq, void *handle) +{ + struct cyttsp *ts = handle; + int error; + + if (unlikely(ts->state == CY_BL_STATE)) { + complete(&ts->bl_ready); + goto out; + } + + /* Get touch data from CYTTSP device */ + error = ttsp_read_block_data(ts, CY_REG_BASE, + sizeof(struct cyttsp_xydata), &ts->xy_data); + if (error) + goto out; + + /* provide flow control handshake */ + if (ts->pdata->use_hndshk) { + error = ttsp_send_command(ts, + ts->xy_data.hst_mode ^ CY_HNDSHK_BIT); + if (error) + goto out; + } + + if (unlikely(ts->state == CY_IDLE_STATE)) + goto out; + + if (GET_BOOTLOADERMODE(ts->xy_data.tt_mode)) { + /* + * TTSP device has reset back to bootloader mode. + * Restore to operational mode. + */ + error = cyttsp_exit_bl_mode(ts); + if (error) { + dev_err(ts->dev, + "Could not return to operational mode, err: %d\n", + error); + ts->state = CY_IDLE_STATE; + } + } else { + cyttsp_report_tchdata(ts); + } + +out: + return IRQ_HANDLED; +} + +static int cyttsp_power_on(struct cyttsp *ts) +{ + int error; + + error = cyttsp_soft_reset(ts); + if (error) + return error; + + error = cyttsp_load_bl_regs(ts); + if (error) + return error; + + if (GET_BOOTLOADERMODE(ts->bl_data.bl_status) && + IS_VALID_APP(ts->bl_data.bl_status)) { + error = cyttsp_exit_bl_mode(ts); + if (error) + return error; + } + + if (GET_HSTMODE(ts->bl_data.bl_file) != CY_OPERATE_MODE || + IS_OPERATIONAL_ERR(ts->bl_data.bl_status)) { + return -ENODEV; + } + + error = cyttsp_set_sysinfo_mode(ts); + if (error) + return error; + + error = cyttsp_set_sysinfo_regs(ts); + if (error) + return error; + + error = cyttsp_set_operational_mode(ts); + if (error) + return error; + + /* init active distance */ + error = cyttsp_act_dist_setup(ts); + if (error) + return error; + + ts->state = CY_ACTIVE_STATE; + + return 0; +} + +static int cyttsp_enable(struct cyttsp *ts) +{ + int error; + + /* + * The device firmware can wake on an I2C or SPI memory slave + * address match. So just reading a register is sufficient to + * wake up the device. The first read attempt will fail but it + * will wake it up making the second read attempt successful. + */ + error = ttsp_read_block_data(ts, CY_REG_BASE, + sizeof(ts->xy_data), &ts->xy_data); + if (error) + return error; + + if (GET_HSTMODE(ts->xy_data.hst_mode)) + return -EIO; + + enable_irq(ts->irq); + + return 0; +} + +static int cyttsp_disable(struct cyttsp *ts) +{ + int error; + + error = ttsp_send_command(ts, CY_LOW_POWER_MODE); + if (error) + return error; + + disable_irq(ts->irq); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int cyttsp_suspend(struct device *dev) +{ + struct cyttsp *ts = dev_get_drvdata(dev); + int retval = 0; + + mutex_lock(&ts->input->mutex); + + if (ts->input->users) { + retval = cyttsp_disable(ts); + if (retval == 0) + ts->suspended = true; + } + + mutex_unlock(&ts->input->mutex); + + return retval; +} + +static int cyttsp_resume(struct device *dev) +{ + struct cyttsp *ts = dev_get_drvdata(dev); + + mutex_lock(&ts->input->mutex); + + if (ts->input->users) + cyttsp_enable(ts); + + ts->suspended = false; + + mutex_unlock(&ts->input->mutex); + + return 0; +} + +#endif + +SIMPLE_DEV_PM_OPS(cyttsp_pm_ops, cyttsp_suspend, cyttsp_resume); +EXPORT_SYMBOL_GPL(cyttsp_pm_ops); + +static int cyttsp_open(struct input_dev *dev) +{ + struct cyttsp *ts = input_get_drvdata(dev); + int retval = 0; + + if (!ts->suspended) + retval = cyttsp_enable(ts); + + return retval; +} + +static void cyttsp_close(struct input_dev *dev) +{ + struct cyttsp *ts = input_get_drvdata(dev); + + if (!ts->suspended) + cyttsp_disable(ts); +} + +struct cyttsp *cyttsp_probe(const struct cyttsp_bus_ops *bus_ops, + struct device *dev, int irq, size_t xfer_buf_size) +{ + const struct cyttsp_platform_data *pdata = dev->platform_data; + struct cyttsp *ts; + struct input_dev *input_dev; + int error; + + if (!dev || !bus_ops || !pdata || !pdata->name || irq <= 0) { + error = -EINVAL; + goto err_out; + } + + ts = kzalloc(sizeof(*ts) + xfer_buf_size, GFP_KERNEL); + input_dev = input_allocate_device(); + if (!ts || !input_dev) { + error = -ENOMEM; + goto err_free_mem; + } + + ts->dev = dev; + ts->input = input_dev; + ts->pdata = dev->platform_data; + ts->bus_ops = bus_ops; + ts->irq = irq; + + init_completion(&ts->bl_ready); + snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(dev)); + + if (pdata->init) { + error = pdata->init(); + if (error) { + dev_err(ts->dev, "platform init failed, err: %d\n", + error); + goto err_free_mem; + } + } + + input_dev->name = pdata->name; + input_dev->phys = ts->phys; + input_dev->id.bustype = bus_ops->bustype; + input_dev->dev.parent = ts->dev; + + input_dev->open = cyttsp_open; + input_dev->close = cyttsp_close; + + input_set_drvdata(input_dev, ts); + + __set_bit(EV_ABS, input_dev->evbit); + input_set_abs_params(input_dev, ABS_MT_POSITION_X, + 0, pdata->maxx, 0, 0); + input_set_abs_params(input_dev, ABS_MT_POSITION_Y, + 0, pdata->maxy, 0, 0); + input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, + 0, CY_MAXZ, 0, 0); + + input_mt_init_slots(input_dev, CY_MAX_ID); + + error = request_threaded_irq(ts->irq, NULL, cyttsp_irq, + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + pdata->name, ts); + if (error) { + dev_err(ts->dev, "failed to request IRQ %d, err: %d\n", + ts->irq, error); + goto err_platform_exit; + } + + disable_irq(ts->irq); + + error = cyttsp_power_on(ts); + if (error) + goto err_free_irq; + + error = input_register_device(input_dev); + if (error) { + dev_err(ts->dev, "failed to register input device: %d\n", + error); + goto err_free_irq; + } + + return ts; + +err_free_irq: + free_irq(ts->irq, ts); +err_platform_exit: + if (pdata->exit) + pdata->exit(); +err_free_mem: + input_free_device(input_dev); + kfree(ts); +err_out: + return ERR_PTR(error); +} +EXPORT_SYMBOL_GPL(cyttsp_probe); + +void cyttsp_remove(struct cyttsp *ts) +{ + free_irq(ts->irq, ts); + input_unregister_device(ts->input); + if (ts->pdata->exit) + ts->pdata->exit(); + kfree(ts); +} +EXPORT_SYMBOL_GPL(cyttsp_remove); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Cypress TrueTouch(R) Standard touchscreen driver core"); +MODULE_AUTHOR("Cypress"); diff --git a/drivers/input/touchscreen/cyttsp_core.h b/drivers/input/touchscreen/cyttsp_core.h new file mode 100644 index 00000000000..1aa3c6967e7 --- /dev/null +++ b/drivers/input/touchscreen/cyttsp_core.h @@ -0,0 +1,149 @@ +/* + * Header file for: + * Cypress TrueTouch(TM) Standard Product (TTSP) touchscreen drivers. + * For use with Cypress Txx3xx parts. + * Supported parts include: + * CY8CTST341 + * CY8CTMA340 + * + * Copyright (C) 2009, 2010, 2011 Cypress Semiconductor, Inc. + * Copyright (C) 2012 Javier Martinez Canillas + * + * 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. + * + * Contact Cypress Semiconductor at www.cypress.com + * + */ + + +#ifndef __CYTTSP_CORE_H__ +#define __CYTTSP_CORE_H__ + +#include +#include +#include +#include +#include +#include + +#define CY_NUM_RETRY 16 /* max number of retries for read ops */ + +struct cyttsp_tch { + __be16 x, y; + u8 z; +} __packed; + +/* TrueTouch Standard Product Gen3 interface definition */ +struct cyttsp_xydata { + u8 hst_mode; + u8 tt_mode; + u8 tt_stat; + struct cyttsp_tch tch1; + u8 touch12_id; + struct cyttsp_tch tch2; + u8 gest_cnt; + u8 gest_id; + struct cyttsp_tch tch3; + u8 touch34_id; + struct cyttsp_tch tch4; + u8 tt_undef[3]; + u8 act_dist; + u8 tt_reserved; +} __packed; + + +/* TTSP System Information interface definition */ +struct cyttsp_sysinfo_data { + u8 hst_mode; + u8 mfg_cmd; + u8 mfg_stat; + u8 cid[3]; + u8 tt_undef1; + u8 uid[8]; + u8 bl_verh; + u8 bl_verl; + u8 tts_verh; + u8 tts_verl; + u8 app_idh; + u8 app_idl; + u8 app_verh; + u8 app_verl; + u8 tt_undef[5]; + u8 scn_typ; + u8 act_intrvl; + u8 tch_tmout; + u8 lp_intrvl; +}; + +/* TTSP Bootloader Register Map interface definition */ +#define CY_BL_CHKSUM_OK 0x01 +struct cyttsp_bootloader_data { + u8 bl_file; + u8 bl_status; + u8 bl_error; + u8 blver_hi; + u8 blver_lo; + u8 bld_blver_hi; + u8 bld_blver_lo; + u8 ttspver_hi; + u8 ttspver_lo; + u8 appid_hi; + u8 appid_lo; + u8 appver_hi; + u8 appver_lo; + u8 cid_0; + u8 cid_1; + u8 cid_2; +}; + +struct cyttsp; + +struct cyttsp_bus_ops { + u16 bustype; + int (*write)(struct cyttsp *ts, + u8 addr, u8 length, const void *values); + int (*read)(struct cyttsp *ts, u8 addr, u8 length, void *values); +}; + +enum cyttsp_state { + CY_IDLE_STATE, + CY_ACTIVE_STATE, + CY_BL_STATE, +}; + +struct cyttsp { + struct device *dev; + int irq; + struct input_dev *input; + char phys[32]; + const struct cyttsp_platform_data *pdata; + const struct cyttsp_bus_ops *bus_ops; + struct cyttsp_bootloader_data bl_data; + struct cyttsp_sysinfo_data sysinfo_data; + struct cyttsp_xydata xy_data; + struct completion bl_ready; + enum cyttsp_state state; + bool suspended; + + u8 xfer_buf[] ____cacheline_aligned; +}; + +struct cyttsp *cyttsp_probe(const struct cyttsp_bus_ops *bus_ops, + struct device *dev, int irq, size_t xfer_buf_size); +void cyttsp_remove(struct cyttsp *ts); + +extern const struct dev_pm_ops cyttsp_pm_ops; + +#endif /* __CYTTSP_CORE_H__ */ diff --git a/drivers/input/touchscreen/cyttsp_i2c.c b/drivers/input/touchscreen/cyttsp_i2c.c new file mode 100644 index 00000000000..c7110cc06b9 --- /dev/null +++ b/drivers/input/touchscreen/cyttsp_i2c.c @@ -0,0 +1,146 @@ +/* + * Source for: + * Cypress TrueTouch(TM) Standard Product (TTSP) I2C touchscreen driver. + * For use with Cypress Txx3xx parts. + * Supported parts include: + * CY8CTST341 + * CY8CTMA340 + * + * Copyright (C) 2009, 2010, 2011 Cypress Semiconductor, Inc. + * Copyright (C) 2012 Javier Martinez Canillas + * + * 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. + * + * Contact Cypress Semiconductor at www.cypress.com + * + */ + +#include "cyttsp_core.h" + +#include +#include + +#define CY_I2C_DATA_SIZE 128 + +static int cyttsp_i2c_read_block_data(struct cyttsp *ts, + u8 addr, u8 length, void *values) +{ + struct i2c_client *client = to_i2c_client(ts->dev); + struct i2c_msg msgs[] = { + { + .addr = client->addr, + .flags = 0, + .len = 1, + .buf = &addr, + }, + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = length, + .buf = values, + }, + }; + int retval; + + retval = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); + if (retval < 0) + return retval; + + return retval != ARRAY_SIZE(msgs) ? -EIO : 0; +} + +static int cyttsp_i2c_write_block_data(struct cyttsp *ts, + u8 addr, u8 length, const void *values) +{ + struct i2c_client *client = to_i2c_client(ts->dev); + int retval; + + ts->xfer_buf[0] = addr; + memcpy(&ts->xfer_buf[1], values, length); + + retval = i2c_master_send(client, ts->xfer_buf, length + 1); + + return retval < 0 ? retval : 0; +} + +static const struct cyttsp_bus_ops cyttsp_i2c_bus_ops = { + .bustype = BUS_I2C, + .write = cyttsp_i2c_write_block_data, + .read = cyttsp_i2c_read_block_data, +}; + +static int __devinit cyttsp_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct cyttsp *ts; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + dev_err(&client->dev, "I2C functionality not Supported\n"); + return -EIO; + } + + ts = cyttsp_probe(&cyttsp_i2c_bus_ops, &client->dev, client->irq, + CY_I2C_DATA_SIZE); + + if (IS_ERR(ts)) + return PTR_ERR(ts); + + i2c_set_clientdata(client, ts); + + return 0; +} + +static int __devexit cyttsp_i2c_remove(struct i2c_client *client) +{ + struct cyttsp *ts = i2c_get_clientdata(client); + + cyttsp_remove(ts); + + return 0; +} + +static const struct i2c_device_id cyttsp_i2c_id[] = { + { CY_I2C_NAME, 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, cyttsp_i2c_id); + +static struct i2c_driver cyttsp_i2c_driver = { + .driver = { + .name = CY_I2C_NAME, + .owner = THIS_MODULE, + .pm = &cyttsp_pm_ops, + }, + .probe = cyttsp_i2c_probe, + .remove = __devexit_p(cyttsp_i2c_remove), + .id_table = cyttsp_i2c_id, +}; + +static int __init cyttsp_i2c_init(void) +{ + return i2c_add_driver(&cyttsp_i2c_driver); +} +module_init(cyttsp_i2c_init); + +static void __exit cyttsp_i2c_exit(void) +{ + return i2c_del_driver(&cyttsp_i2c_driver); +} +module_exit(cyttsp_i2c_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Cypress TrueTouch(R) Standard Product (TTSP) I2C driver"); +MODULE_AUTHOR("Cypress"); +MODULE_ALIAS("i2c:cyttsp"); diff --git a/drivers/input/touchscreen/cyttsp_spi.c b/drivers/input/touchscreen/cyttsp_spi.c new file mode 100644 index 00000000000..9db5f8754d1 --- /dev/null +++ b/drivers/input/touchscreen/cyttsp_spi.c @@ -0,0 +1,210 @@ +/* + * Source for: + * Cypress TrueTouch(TM) Standard Product (TTSP) SPI touchscreen driver. + * For use with Cypress Txx3xx parts. + * Supported parts include: + * CY8CTST341 + * CY8CTMA340 + * + * Copyright (C) 2009, 2010, 2011 Cypress Semiconductor, Inc. + * Copyright (C) 2012 Javier Martinez Canillas + * + * 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. + * + * Contact Cypress Semiconductor at www.cypress.com + * + */ + +#include "cyttsp_core.h" + +#include +#include +#include + +#define CY_SPI_WR_OP 0x00 /* r/~w */ +#define CY_SPI_RD_OP 0x01 +#define CY_SPI_CMD_BYTES 4 +#define CY_SPI_SYNC_BYTE 2 +#define CY_SPI_SYNC_ACK1 0x62 /* from protocol v.2 */ +#define CY_SPI_SYNC_ACK2 0x9D /* from protocol v.2 */ +#define CY_SPI_DATA_SIZE 128 +#define CY_SPI_DATA_BUF_SIZE (CY_SPI_CMD_BYTES + CY_SPI_DATA_SIZE) +#define CY_SPI_BITS_PER_WORD 8 + +static int cyttsp_spi_xfer(struct cyttsp *ts, + u8 op, u8 reg, u8 *buf, int length) +{ + struct spi_device *spi = to_spi_device(ts->dev); + struct spi_message msg; + struct spi_transfer xfer[2]; + u8 *wr_buf = &ts->xfer_buf[0]; + u8 *rd_buf = &ts->xfer_buf[CY_SPI_DATA_BUF_SIZE]; + int retval; + int i; + + if (length > CY_SPI_DATA_SIZE) { + dev_err(ts->dev, "%s: length %d is too big.\n", + __func__, length); + return -EINVAL; + } + + memset(wr_buf, 0, CY_SPI_DATA_BUF_SIZE); + memset(rd_buf, 0, CY_SPI_DATA_BUF_SIZE); + + wr_buf[0] = 0x00; /* header byte 0 */ + wr_buf[1] = 0xFF; /* header byte 1 */ + wr_buf[2] = reg; /* reg index */ + wr_buf[3] = op; /* r/~w */ + if (op == CY_SPI_WR_OP) + memcpy(wr_buf + CY_SPI_CMD_BYTES, buf, length); + + memset(xfer, 0, sizeof(xfer)); + spi_message_init(&msg); + + /* + We set both TX and RX buffers because Cypress TTSP + requires full duplex operation. + */ + xfer[0].tx_buf = wr_buf; + xfer[0].rx_buf = rd_buf; + switch (op) { + case CY_SPI_WR_OP: + xfer[0].len = length + CY_SPI_CMD_BYTES; + spi_message_add_tail(&xfer[0], &msg); + break; + + case CY_SPI_RD_OP: + xfer[0].len = CY_SPI_CMD_BYTES; + spi_message_add_tail(&xfer[0], &msg); + + xfer[1].rx_buf = buf; + xfer[1].len = length; + spi_message_add_tail(&xfer[1], &msg); + break; + + default: + dev_err(ts->dev, "%s: bad operation code=%d\n", __func__, op); + return -EINVAL; + } + + retval = spi_sync(spi, &msg); + if (retval < 0) { + dev_dbg(ts->dev, "%s: spi_sync() error %d, len=%d, op=%d\n", + __func__, retval, xfer[1].len, op); + + /* + * do not return here since was a bad ACK sequence + * let the following ACK check handle any errors and + * allow silent retries + */ + } + + if (rd_buf[CY_SPI_SYNC_BYTE] != CY_SPI_SYNC_ACK1 || + rd_buf[CY_SPI_SYNC_BYTE + 1] != CY_SPI_SYNC_ACK2) { + + dev_dbg(ts->dev, "%s: operation %d failed\n", __func__, op); + + for (i = 0; i < CY_SPI_CMD_BYTES; i++) + dev_dbg(ts->dev, "%s: test rd_buf[%d]:0x%02x\n", + __func__, i, rd_buf[i]); + for (i = 0; i < length; i++) + dev_dbg(ts->dev, "%s: test buf[%d]:0x%02x\n", + __func__, i, buf[i]); + + return -EIO; + } + + return 0; +} + +static int cyttsp_spi_read_block_data(struct cyttsp *ts, + u8 addr, u8 length, void *data) +{ + return cyttsp_spi_xfer(ts, CY_SPI_RD_OP, addr, data, length); +} + +static int cyttsp_spi_write_block_data(struct cyttsp *ts, + u8 addr, u8 length, const void *data) +{ + return cyttsp_spi_xfer(ts, CY_SPI_WR_OP, addr, (void *)data, length); +} + +static const struct cyttsp_bus_ops cyttsp_spi_bus_ops = { + .bustype = BUS_SPI, + .write = cyttsp_spi_write_block_data, + .read = cyttsp_spi_read_block_data, +}; + +static int __devinit cyttsp_spi_probe(struct spi_device *spi) +{ + struct cyttsp *ts; + int error; + + /* Set up SPI*/ + spi->bits_per_word = CY_SPI_BITS_PER_WORD; + spi->mode = SPI_MODE_0; + error = spi_setup(spi); + if (error < 0) { + dev_err(&spi->dev, "%s: SPI setup error %d\n", + __func__, error); + return error; + } + + ts = cyttsp_probe(&cyttsp_spi_bus_ops, &spi->dev, spi->irq, + CY_SPI_DATA_BUF_SIZE * 2); + if (IS_ERR(ts)) + return PTR_ERR(ts); + + spi_set_drvdata(spi, ts); + + return 0; +} + +static int __devexit cyttsp_spi_remove(struct spi_device *spi) +{ + struct cyttsp *ts = spi_get_drvdata(spi); + + cyttsp_remove(ts); + + return 0; +} + +static struct spi_driver cyttsp_spi_driver = { + .driver = { + .name = CY_SPI_NAME, + .owner = THIS_MODULE, + .pm = &cyttsp_pm_ops, + }, + .probe = cyttsp_spi_probe, + .remove = __devexit_p(cyttsp_spi_remove), +}; + +static int __init cyttsp_spi_init(void) +{ + return spi_register_driver(&cyttsp_spi_driver); +} +module_init(cyttsp_spi_init); + +static void __exit cyttsp_spi_exit(void) +{ + spi_unregister_driver(&cyttsp_spi_driver); +} +module_exit(cyttsp_spi_exit); + +MODULE_ALIAS("spi:cyttsp"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Cypress TrueTouch(R) Standard Product (TTSP) SPI driver"); +MODULE_AUTHOR("Cypress"); +MODULE_ALIAS("spi:cyttsp"); diff --git a/include/linux/input/cyttsp.h b/include/linux/input/cyttsp.h new file mode 100644 index 00000000000..5af7c66f1fc --- /dev/null +++ b/include/linux/input/cyttsp.h @@ -0,0 +1,58 @@ +/* + * Header file for: + * Cypress TrueTouch(TM) Standard Product (TTSP) touchscreen drivers. + * For use with Cypress Txx3xx parts. + * Supported parts include: + * CY8CTST341 + * CY8CTMA340 + * + * Copyright (C) 2009, 2010, 2011 Cypress Semiconductor, Inc. + * Copyright (C) 2012 Javier Martinez Canillas + * + * 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. + * + * Contact Cypress Semiconductor at www.cypress.com (kev@cypress.com) + * + */ +#ifndef _CYTTSP_H_ +#define _CYTTSP_H_ + +#define CY_SPI_NAME "cyttsp-spi" +#define CY_I2C_NAME "cyttsp-i2c" +/* Active Power state scanning/processing refresh interval */ +#define CY_ACT_INTRVL_DFLT 0x00 /* ms */ +/* touch timeout for the Active power */ +#define CY_TCH_TMOUT_DFLT 0xFF /* ms */ +/* Low Power state scanning/processing refresh interval */ +#define CY_LP_INTRVL_DFLT 0x0A /* ms */ +/* Active distance in pixels for a gesture to be reported */ +#define CY_ACT_DIST_DFLT 0xF8 /* pixels */ + +struct cyttsp_platform_data { + u32 maxx; + u32 maxy; + bool use_hndshk; + u8 act_dist; /* Active distance */ + u8 act_intrvl; /* Active refresh interval; ms */ + u8 tch_tmout; /* Active touch timeout; ms */ + u8 lp_intrvl; /* Low power refresh interval; ms */ + int (*init)(void); + void (*exit)(void); + char *name; + s16 irq_gpio; + u8 *bl_keys; +}; + +#endif /* _CYTTSP_H_ */ -- cgit v1.2.3-70-g09d2 From aa795d129246cb4c973076e3242b8a2eb374f1ef Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 31 Jan 2012 11:48:18 +0800 Subject: regmap: Remove incorrect unreachable comment in regcache_set_val() regcache_set_val() returns false if cache[idx] != val. Thus it actually is not unreachable. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/base/regmap/regcache.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 99beccfad4d..7e18d1e70f1 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -375,7 +375,6 @@ bool regcache_set_val(void *base, unsigned int idx, default: BUG(); } - /* unreachable */ return false; } -- cgit v1.2.3-70-g09d2 From e9e8c85e69310141d78daaecd6a56138700ac317 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 26 Jan 2012 12:40:23 +0200 Subject: usb: musb: make modules behave better There's really no point in doing all that initcall trickery when we can safely let udev handle module probing for us. Remove all of that trickery, by moving everybody to module_init() and making proper use of platform_device_register() rather than platform_device_probe(). Tested-by: Rajashekhara, Sudhakar Tested-by: Tasslehoff Kjappfot Signed-off-by: Felipe Balbi --- drivers/usb/musb/am35x.c | 11 ++++----- drivers/usb/musb/blackfin.c | 9 ++++---- drivers/usb/musb/da8xx.c | 11 ++++----- drivers/usb/musb/davinci.c | 11 ++++----- drivers/usb/musb/musb_core.c | 49 +++++++++++++++++++---------------------- drivers/usb/musb/musb_debugfs.c | 2 +- drivers/usb/musb/musb_gadget.c | 6 ++--- drivers/usb/musb/omap2430.c | 11 ++++----- drivers/usb/musb/tusb6010.c | 11 ++++----- drivers/usb/musb/ux500.c | 11 ++++----- 10 files changed, 68 insertions(+), 64 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index e233d2b7d33..5285bda1dc4 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c @@ -456,7 +456,7 @@ static const struct musb_platform_ops am35x_ops = { static u64 am35x_dmamask = DMA_BIT_MASK(32); -static int __init am35x_probe(struct platform_device *pdev) +static int __devinit am35x_probe(struct platform_device *pdev) { struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct platform_device *musb; @@ -561,7 +561,7 @@ err0: return ret; } -static int __exit am35x_remove(struct platform_device *pdev) +static int __devexit am35x_remove(struct platform_device *pdev) { struct am35x_glue *glue = platform_get_drvdata(pdev); @@ -630,7 +630,8 @@ static struct dev_pm_ops am35x_pm_ops = { #endif static struct platform_driver am35x_driver = { - .remove = __exit_p(am35x_remove), + .probe = am35x_probe, + .remove = __devexit_p(am35x_remove), .driver = { .name = "musb-am35x", .pm = DEV_PM_OPS, @@ -643,9 +644,9 @@ MODULE_LICENSE("GPL v2"); static int __init am35x_init(void) { - return platform_driver_probe(&am35x_driver, am35x_probe); + return platform_driver_register(&am35x_driver); } -subsys_initcall(am35x_init); +module_init(am35x_init); static void __exit am35x_exit(void) { diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index 5e7cfba5b07..261af3487b5 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -463,7 +463,7 @@ static const struct musb_platform_ops bfin_ops = { static u64 bfin_dmamask = DMA_BIT_MASK(32); -static int __init bfin_probe(struct platform_device *pdev) +static int __devinit bfin_probe(struct platform_device *pdev) { struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct platform_device *musb; @@ -525,7 +525,7 @@ err0: return ret; } -static int __exit bfin_remove(struct platform_device *pdev) +static int __devexit bfin_remove(struct platform_device *pdev) { struct bfin_glue *glue = platform_get_drvdata(pdev); @@ -575,6 +575,7 @@ static struct dev_pm_ops bfin_pm_ops = { #endif static struct platform_driver bfin_driver = { + .probe = bfin_probe, .remove = __exit_p(bfin_remove), .driver = { .name = "musb-blackfin", @@ -588,9 +589,9 @@ MODULE_LICENSE("GPL v2"); static int __init bfin_init(void) { - return platform_driver_probe(&bfin_driver, bfin_probe); + return platform_driver_register(&bfin_driver); } -subsys_initcall(bfin_init); +module_init(bfin_init); static void __exit bfin_exit(void) { diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 2613bfdb09b..01c8f2ece08 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -478,7 +478,7 @@ static const struct musb_platform_ops da8xx_ops = { static u64 da8xx_dmamask = DMA_BIT_MASK(32); -static int __init da8xx_probe(struct platform_device *pdev) +static int __devinit da8xx_probe(struct platform_device *pdev) { struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct platform_device *musb; @@ -562,7 +562,7 @@ err0: return ret; } -static int __exit da8xx_remove(struct platform_device *pdev) +static int __devexit da8xx_remove(struct platform_device *pdev) { struct da8xx_glue *glue = platform_get_drvdata(pdev); @@ -576,7 +576,8 @@ static int __exit da8xx_remove(struct platform_device *pdev) } static struct platform_driver da8xx_driver = { - .remove = __exit_p(da8xx_remove), + .probe = da8xx_probe, + .remove = __devexit_p(da8xx_remove), .driver = { .name = "musb-da8xx", }, @@ -588,9 +589,9 @@ MODULE_LICENSE("GPL v2"); static int __init da8xx_init(void) { - return platform_driver_probe(&da8xx_driver, da8xx_probe); + return platform_driver_register(&da8xx_driver); } -subsys_initcall(da8xx_init); +module_init(da8xx_init); static void __exit da8xx_exit(void) { diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index f9a3f62a83b..7802c7ec43f 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -514,7 +514,7 @@ static const struct musb_platform_ops davinci_ops = { static u64 davinci_dmamask = DMA_BIT_MASK(32); -static int __init davinci_probe(struct platform_device *pdev) +static int __devinit davinci_probe(struct platform_device *pdev) { struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct platform_device *musb; @@ -597,7 +597,7 @@ err0: return ret; } -static int __exit davinci_remove(struct platform_device *pdev) +static int __devexit davinci_remove(struct platform_device *pdev) { struct davinci_glue *glue = platform_get_drvdata(pdev); @@ -611,7 +611,8 @@ static int __exit davinci_remove(struct platform_device *pdev) } static struct platform_driver davinci_driver = { - .remove = __exit_p(davinci_remove), + .probe = davinci_probe, + .remove = __devexit_p(davinci_remove), .driver = { .name = "musb-davinci", }, @@ -623,9 +624,9 @@ MODULE_LICENSE("GPL v2"); static int __init davinci_init(void) { - return platform_driver_probe(&davinci_driver, davinci_probe); + return platform_driver_register(&davinci_driver); } -subsys_initcall(davinci_init); +module_init(davinci_init); static void __exit davinci_exit(void) { diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 6a929859b55..d6134b39e8f 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1014,12 +1014,12 @@ static void musb_shutdown(struct platform_device *pdev) || defined(CONFIG_USB_MUSB_OMAP2PLUS_MODULE) \ || defined(CONFIG_USB_MUSB_AM35X) \ || defined(CONFIG_USB_MUSB_AM35X_MODULE) -static ushort __initdata fifo_mode = 4; +static ushort __devinitdata fifo_mode = 4; #elif defined(CONFIG_USB_MUSB_UX500) \ || defined(CONFIG_USB_MUSB_UX500_MODULE) -static ushort __initdata fifo_mode = 5; +static ushort __devinitdata fifo_mode = 5; #else -static ushort __initdata fifo_mode = 2; +static ushort __devinitdata fifo_mode = 2; #endif /* "modprobe ... fifo_mode=1" etc */ @@ -1032,7 +1032,7 @@ MODULE_PARM_DESC(fifo_mode, "initial endpoint configuration"); */ /* mode 0 - fits in 2KB */ -static struct musb_fifo_cfg __initdata mode_0_cfg[] = { +static struct musb_fifo_cfg __devinitdata mode_0_cfg[] = { { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, }, { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, }, { .hw_ep_num = 2, .style = FIFO_RXTX, .maxpacket = 512, }, @@ -1041,7 +1041,7 @@ static struct musb_fifo_cfg __initdata mode_0_cfg[] = { }; /* mode 1 - fits in 4KB */ -static struct musb_fifo_cfg __initdata mode_1_cfg[] = { +static struct musb_fifo_cfg __devinitdata mode_1_cfg[] = { { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, .mode = BUF_DOUBLE, }, { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, .mode = BUF_DOUBLE, }, { .hw_ep_num = 2, .style = FIFO_RXTX, .maxpacket = 512, .mode = BUF_DOUBLE, }, @@ -1050,7 +1050,7 @@ static struct musb_fifo_cfg __initdata mode_1_cfg[] = { }; /* mode 2 - fits in 4KB */ -static struct musb_fifo_cfg __initdata mode_2_cfg[] = { +static struct musb_fifo_cfg __devinitdata mode_2_cfg[] = { { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, }, { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, }, { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, }, @@ -1060,7 +1060,7 @@ static struct musb_fifo_cfg __initdata mode_2_cfg[] = { }; /* mode 3 - fits in 4KB */ -static struct musb_fifo_cfg __initdata mode_3_cfg[] = { +static struct musb_fifo_cfg __devinitdata mode_3_cfg[] = { { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, .mode = BUF_DOUBLE, }, { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, .mode = BUF_DOUBLE, }, { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, }, @@ -1070,7 +1070,7 @@ static struct musb_fifo_cfg __initdata mode_3_cfg[] = { }; /* mode 4 - fits in 16KB */ -static struct musb_fifo_cfg __initdata mode_4_cfg[] = { +static struct musb_fifo_cfg __devinitdata mode_4_cfg[] = { { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, }, { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, }, { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, }, @@ -1101,7 +1101,7 @@ static struct musb_fifo_cfg __initdata mode_4_cfg[] = { }; /* mode 5 - fits in 8KB */ -static struct musb_fifo_cfg __initdata mode_5_cfg[] = { +static struct musb_fifo_cfg __devinitdata mode_5_cfg[] = { { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, }, { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, }, { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, }, @@ -1137,7 +1137,7 @@ static struct musb_fifo_cfg __initdata mode_5_cfg[] = { * * returns negative errno or offset for next fifo. */ -static int __init +static int __devinit fifo_setup(struct musb *musb, struct musb_hw_ep *hw_ep, const struct musb_fifo_cfg *cfg, u16 offset) { @@ -1208,11 +1208,11 @@ fifo_setup(struct musb *musb, struct musb_hw_ep *hw_ep, return offset + (maxpacket << ((c_size & MUSB_FIFOSZ_DPB) ? 1 : 0)); } -static struct musb_fifo_cfg __initdata ep0_cfg = { +static struct musb_fifo_cfg __devinitdata ep0_cfg = { .style = FIFO_RXTX, .maxpacket = 64, }; -static int __init ep_config_from_table(struct musb *musb) +static int __devinit ep_config_from_table(struct musb *musb) { const struct musb_fifo_cfg *cfg; unsigned i, n; @@ -1303,7 +1303,7 @@ done: * ep_config_from_hw - when MUSB_C_DYNFIFO_DEF is false * @param musb the controller */ -static int __init ep_config_from_hw(struct musb *musb) +static int __devinit ep_config_from_hw(struct musb *musb) { u8 epnum = 0; struct musb_hw_ep *hw_ep; @@ -1350,7 +1350,7 @@ enum { MUSB_CONTROLLER_MHDRC, MUSB_CONTROLLER_HDRC, }; /* Initialize MUSB (M)HDRC part of the USB hardware subsystem; * configure endpoints, or take their config from silicon */ -static int __init musb_core_init(u16 musb_type, struct musb *musb) +static int __devinit musb_core_init(u16 musb_type, struct musb *musb) { u8 reg; char *type; @@ -1586,7 +1586,7 @@ irqreturn_t musb_interrupt(struct musb *musb) EXPORT_SYMBOL_GPL(musb_interrupt); #ifndef CONFIG_MUSB_PIO_ONLY -static bool __initdata use_dma = 1; +static bool __devinitdata use_dma = 1; /* "modprobe ... use_dma=0" etc */ module_param(use_dma, bool, 0); @@ -1774,7 +1774,7 @@ static void musb_irq_work(struct work_struct *data) * Init support */ -static struct musb *__init +static struct musb *__devinit allocate_instance(struct device *dev, struct musb_hdrc_config *config, void __iomem *mbase) { @@ -1852,7 +1852,7 @@ static void musb_free(struct musb *musb) * @mregs: virtual address of controller registers, * not yet corrected for platform-specific offsets */ -static int __init +static int __devinit musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) { int status; @@ -2072,7 +2072,7 @@ fail0: static u64 *orig_dma_mask; #endif -static int __init musb_probe(struct platform_device *pdev) +static int __devinit musb_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; int irq = platform_get_irq_byname(pdev, "mc"); @@ -2101,7 +2101,7 @@ static int __init musb_probe(struct platform_device *pdev) return status; } -static int __exit musb_remove(struct platform_device *pdev) +static int __devexit musb_remove(struct platform_device *pdev) { struct musb *musb = dev_to_musb(&pdev->dev); void __iomem *ctrl_base = musb->ctrl_base; @@ -2361,7 +2361,8 @@ static struct platform_driver musb_driver = { .owner = THIS_MODULE, .pm = MUSB_DEV_PM_OPS, }, - .remove = __exit_p(musb_remove), + .probe = musb_probe, + .remove = __devexit_p(musb_remove), .shutdown = musb_shutdown, }; @@ -2377,13 +2378,9 @@ static int __init musb_init(void) ", " "otg (peripheral+host)", musb_driver_name); - return platform_driver_probe(&musb_driver, musb_probe); + return platform_driver_register(&musb_driver); } - -/* make us init after usbcore and i2c (transceivers, regulators, etc) - * and before usb gadget and host-side drivers start to register - */ -fs_initcall(musb_init); +module_init(musb_init); static void __exit musb_cleanup(void) { diff --git a/drivers/usb/musb/musb_debugfs.c b/drivers/usb/musb/musb_debugfs.c index 13d9af9bf92..219d0fba584 100644 --- a/drivers/usb/musb/musb_debugfs.c +++ b/drivers/usb/musb/musb_debugfs.c @@ -235,7 +235,7 @@ static const struct file_operations musb_test_mode_fops = { .release = single_release, }; -int __init musb_init_debugfs(struct musb *musb) +int __devinit musb_init_debugfs(struct musb *musb) { struct dentry *root; struct dentry *file; diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index ac3d2eec20f..59ab98f08e9 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1762,7 +1762,7 @@ static void musb_gadget_release(struct device *dev) } -static void __init +static void __devinit init_peripheral_ep(struct musb *musb, struct musb_ep *ep, u8 epnum, int is_in) { struct musb_hw_ep *hw_ep = musb->endpoints + epnum; @@ -1799,7 +1799,7 @@ init_peripheral_ep(struct musb *musb, struct musb_ep *ep, u8 epnum, int is_in) * Initialize the endpoints exposed to peripheral drivers, with backlinks * to the rest of the driver state. */ -static inline void __init musb_g_init_endpoints(struct musb *musb) +static inline void __devinit musb_g_init_endpoints(struct musb *musb) { u8 epnum; struct musb_hw_ep *hw_ep; @@ -1832,7 +1832,7 @@ static inline void __init musb_g_init_endpoints(struct musb *musb) /* called once during driver setup to initialize and link into * the driver model; memory is zeroed. */ -int __init musb_gadget_setup(struct musb *musb) +int __devinit musb_gadget_setup(struct musb *musb) { int status; diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index c27bbbf32b5..b254173e7e8 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -408,7 +408,7 @@ static const struct musb_platform_ops omap2430_ops = { static u64 omap2430_dmamask = DMA_BIT_MASK(32); -static int __init omap2430_probe(struct platform_device *pdev) +static int __devinit omap2430_probe(struct platform_device *pdev) { struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct platform_device *musb; @@ -471,7 +471,7 @@ err0: return ret; } -static int __exit omap2430_remove(struct platform_device *pdev) +static int __devexit omap2430_remove(struct platform_device *pdev) { struct omap2430_glue *glue = platform_get_drvdata(pdev); @@ -524,7 +524,8 @@ static struct dev_pm_ops omap2430_pm_ops = { #endif static struct platform_driver omap2430_driver = { - .remove = __exit_p(omap2430_remove), + .probe = omap2430_probe, + .remove = __devexit_p(omap2430_remove), .driver = { .name = "musb-omap2430", .pm = DEV_PM_OPS, @@ -537,9 +538,9 @@ MODULE_LICENSE("GPL v2"); static int __init omap2430_init(void) { - return platform_driver_probe(&omap2430_driver, omap2430_probe); + return platform_driver_register(&omap2430_driver); } -subsys_initcall(omap2430_init); +module_init(omap2430_init); static void __exit omap2430_exit(void) { diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 1f405616e6c..b387f12d05b 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -1165,7 +1165,7 @@ static const struct musb_platform_ops tusb_ops = { static u64 tusb_dmamask = DMA_BIT_MASK(32); -static int __init tusb_probe(struct platform_device *pdev) +static int __devinit tusb_probe(struct platform_device *pdev) { struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct platform_device *musb; @@ -1227,7 +1227,7 @@ err0: return ret; } -static int __exit tusb_remove(struct platform_device *pdev) +static int __devexit tusb_remove(struct platform_device *pdev) { struct tusb6010_glue *glue = platform_get_drvdata(pdev); @@ -1239,7 +1239,8 @@ static int __exit tusb_remove(struct platform_device *pdev) } static struct platform_driver tusb_driver = { - .remove = __exit_p(tusb_remove), + .probe = tusb_probe, + .remove = __devexit_p(tusb_remove), .driver = { .name = "musb-tusb", }, @@ -1251,9 +1252,9 @@ MODULE_LICENSE("GPL v2"); static int __init tusb_init(void) { - return platform_driver_probe(&tusb_driver, tusb_probe); + return platform_driver_register(&tusb_driver); } -subsys_initcall(tusb_init); +module_init(tusb_init); static void __exit tusb_exit(void) { diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index f7e04bf34a1..bcfc48f4854 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -58,7 +58,7 @@ static const struct musb_platform_ops ux500_ops = { .exit = ux500_musb_exit, }; -static int __init ux500_probe(struct platform_device *pdev) +static int __devinit ux500_probe(struct platform_device *pdev) { struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct platform_device *musb; @@ -141,7 +141,7 @@ err0: return ret; } -static int __exit ux500_remove(struct platform_device *pdev) +static int __devexit ux500_remove(struct platform_device *pdev) { struct ux500_glue *glue = platform_get_drvdata(pdev); @@ -194,7 +194,8 @@ static const struct dev_pm_ops ux500_pm_ops = { #endif static struct platform_driver ux500_driver = { - .remove = __exit_p(ux500_remove), + .probe = ux500_probe, + .remove = __devexit_p(ux500_remove), .driver = { .name = "musb-ux500", .pm = DEV_PM_OPS, @@ -207,9 +208,9 @@ MODULE_LICENSE("GPL v2"); static int __init ux500_init(void) { - return platform_driver_probe(&ux500_driver, ux500_probe); + return platform_driver_register(&ux500_driver); } -subsys_initcall(ux500_init); +module_init(ux500_init); static void __exit ux500_exit(void) { -- cgit v1.2.3-70-g09d2 From ae1f23fb433ac0aaff8aeaa5a7b14348e9aa8277 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Tue, 31 Jan 2012 00:00:19 +0100 Subject: r8169: fix early queue wake-up. With infinite gratitude to Eric Dumazet for allowing me to identify the error. Signed-off-by: Francois Romieu Acked-by: Eric Dumazet Cc: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index d039d39963a..859554a03a0 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -5559,7 +5559,18 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, mmiowb(); if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) { + /* Avoid wrongly optimistic queue wake-up: rtl_tx thread must + * not miss a ring update when it notices a stopped queue. + */ + smp_wmb(); netif_stop_queue(dev); + /* Sync with rtl_tx: + * - publish queue status and cur_tx ring index (write barrier) + * - refresh dirty_tx ring index (read barrier). + * May the current thread have a pessimistic view of the ring + * status and forget to wake up queue, a racing rtl_tx thread + * can't. + */ smp_mb(); if (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS) netif_wake_queue(dev); @@ -5659,6 +5670,13 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp) if (tp->dirty_tx != dirty_tx) { tp->dirty_tx = dirty_tx; + /* Sync with rtl8169_start_xmit: + * - publish dirty_tx ring index (write barrier) + * - refresh cur_tx ring index and queue status (read barrier) + * May the current thread miss the stopped queue condition, + * a racing xmit thread can only have a right view of the + * ring status. + */ smp_mb(); if (netif_queue_stopped(dev) && (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS)) { -- cgit v1.2.3-70-g09d2 From 98ddf986fca17840e46e070354b7e2cd2169da15 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Tue, 31 Jan 2012 10:47:34 +0100 Subject: r8169: bh locking redux and task scheduling. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - atomic bit operations are globally visible - pending status is always cleared before execution - scheduled works are either idempotent or only required to happen once after a series of originating events, say link events for instance Signed-off-by: Francois Romieu Suggested-by: Michał Mirosław Cc: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 859554a03a0..118f6f6fcef 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -3273,17 +3273,8 @@ out_mod_timer: static void rtl_schedule_task(struct rtl8169_private *tp, enum rtl_flag flag) { - spin_lock(&tp->lock); if (!test_and_set_bit(flag, tp->wk.flags)) schedule_work(&tp->wk.work); - spin_unlock(&tp->lock); -} - -static void rtl_schedule_task_bh(struct rtl8169_private *tp, enum rtl_flag flag) -{ - local_bh_disable(); - rtl_schedule_task(tp, flag); - local_bh_enable(); } static void rtl8169_phy_timer(unsigned long __opaque) @@ -3291,7 +3282,7 @@ static void rtl8169_phy_timer(unsigned long __opaque) struct net_device *dev = (struct net_device *)__opaque; struct rtl8169_private *tp = netdev_priv(dev); - rtl_schedule_task_bh(tp, RTL_FLAG_TASK_PHY_PENDING); + rtl_schedule_task(tp, RTL_FLAG_TASK_PHY_PENDING); } #ifdef CONFIG_NET_POLL_CONTROLLER @@ -5635,7 +5626,7 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev) rtl8169_hw_reset(tp); - rtl_schedule_task_bh(tp, RTL_FLAG_TASK_RESET_PENDING); + rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); } static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp) @@ -5852,7 +5843,7 @@ static void rtl_slow_event_work(struct rtl8169_private *tp) /* Work around for rx fifo overflow */ case RTL_GIGA_MAC_VER_11: netif_stop_queue(dev); - rtl_schedule_task_bh(tp, RTL_FLAG_TASK_RESET_PENDING); + rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); default: break; } @@ -5894,10 +5885,7 @@ static void rtl_task(struct work_struct *work) for (i = 0; i < ARRAY_SIZE(rtl_work); i++) { bool pending; - spin_lock_bh(&tp->lock); pending = test_and_clear_bit(rtl_work[i].bitnr, tp->wk.flags); - spin_unlock_bh(&tp->lock); - if (pending) rtl_work[i].action(tp); } @@ -6116,7 +6104,7 @@ static void __rtl8169_resume(struct net_device *dev) tp->wk.enabled = true; - rtl_schedule_task_bh(tp, RTL_FLAG_TASK_RESET_PENDING); + rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); } static int rtl8169_resume(struct device *device) -- cgit v1.2.3-70-g09d2 From 6c4a70c5f286077e78b294b3f3a93dc45c40db89 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Tue, 31 Jan 2012 10:56:44 +0100 Subject: r8169: move task enable boolean to bitfield. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simpler, more consistent, with negligible cost in non-critical paths. Signed-off-by: Francois Romieu Suggested-by: Michał Mirosław Cc: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 118f6f6fcef..679711e4c3c 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -668,6 +668,7 @@ struct rtl8169_counters { }; enum rtl_flag { + RTL_FLAG_TASK_ENABLED, RTL_FLAG_TASK_SLOW_PENDING, RTL_FLAG_TASK_RESET_PENDING, RTL_FLAG_TASK_PHY_PENDING, @@ -725,7 +726,6 @@ struct rtl8169_private { DECLARE_BITMAP(flags, RTL_FLAG_MAX); struct mutex mutex; struct work_struct work; - bool enabled; } wk; unsigned features; @@ -4352,7 +4352,7 @@ static int rtl8169_open(struct net_device *dev) rtl_lock_work(tp); - tp->wk.enabled = true; + set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags); napi_enable(&tp->napi); @@ -5879,7 +5879,8 @@ static void rtl_task(struct work_struct *work) rtl_lock_work(tp); - if (!netif_running(dev) || !tp->wk.enabled) + if (!netif_running(dev) || + !test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags)) goto out_unlock; for (i = 0; i < ARRAY_SIZE(rtl_work); i++) { @@ -5977,7 +5978,7 @@ static int rtl8169_close(struct net_device *dev) rtl8169_update_counters(dev); rtl_lock_work(tp); - tp->wk.enabled = false; + clear_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags); rtl8169_down(dev); rtl_unlock_work(tp); @@ -6076,7 +6077,7 @@ static void rtl8169_net_suspend(struct net_device *dev) rtl_lock_work(tp); napi_disable(&tp->napi); - tp->wk.enabled = false; + clear_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags); rtl_unlock_work(tp); rtl_pll_power_down(tp); @@ -6102,7 +6103,7 @@ static void __rtl8169_resume(struct net_device *dev) rtl_pll_power_up(tp); - tp->wk.enabled = true; + set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags); rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); } -- cgit v1.2.3-70-g09d2 From 934714d088f35b81edafdce89397969baf77fb8a Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Tue, 31 Jan 2012 11:09:21 +0100 Subject: r8169: avoid a useless work scheduling. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Francois Romieu Suggested-by: Michał Mirosław Cc: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 679711e4c3c..0377ffaa8be 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -5843,7 +5843,8 @@ static void rtl_slow_event_work(struct rtl8169_private *tp) /* Work around for rx fifo overflow */ case RTL_GIGA_MAC_VER_11: netif_stop_queue(dev); - rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); + /* XXX - Hack alert. See rtl_task(). */ + set_bit(RTL_FLAG_TASK_RESET_PENDING, tp->wk.flags); default: break; } @@ -5868,6 +5869,7 @@ static void rtl_task(struct work_struct *work) int bitnr; void (*action)(struct rtl8169_private *); } rtl_work[] = { + /* XXX - keep rtl_slow_event_work() as first element. */ { RTL_FLAG_TASK_SLOW_PENDING, rtl_slow_event_work }, { RTL_FLAG_TASK_RESET_PENDING, rtl_reset_work }, { RTL_FLAG_TASK_PHY_PENDING, rtl_phy_work } -- cgit v1.2.3-70-g09d2 From 6c05d25267ebb371c4311de6904f740342e82f7c Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Tue, 31 Jan 2012 11:20:34 +0100 Subject: r8169: spinlock redux. rtl8169_get_regs operates under RTNL and rtl task mutex whereas rtl_set_rx_mode is either called under RTNL or rtl task mutex protection. Signed-off-by: Francois Romieu Cc: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 0377ffaa8be..707742207c7 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -680,7 +680,6 @@ struct rtl8169_private { struct pci_dev *pci_dev; struct net_device *dev; struct napi_struct napi; - spinlock_t lock; u32 msg_enable; u16 txd_version; u16 mac_version; @@ -1723,9 +1722,7 @@ static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs, regs->len = R8169_REGS_SIZE; rtl_lock_work(tp); - spin_lock_bh(&tp->lock); memcpy_fromio(p, tp->mmio_addr, regs->len); - spin_unlock_bh(&tp->lock); rtl_unlock_work(tp); } @@ -4151,7 +4148,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) tp->do_ioctl = rtl_xmii_ioctl; } - spin_lock_init(&tp->lock); mutex_init(&tp->wk.mutex); /* Get MAC address */ @@ -6031,8 +6027,6 @@ static void rtl_set_rx_mode(struct net_device *dev) } } - spin_lock_bh(&tp->lock); - tmp = (RTL_R32(RxConfig) & ~RX_CONFIG_ACCEPT_MASK) | rx_mode; if (tp->mac_version > RTL_GIGA_MAC_VER_06) { @@ -6046,8 +6040,6 @@ static void rtl_set_rx_mode(struct net_device *dev) RTL_W32(MAR0 + 0, mc_filter[0]); RTL_W32(RxConfig, tmp); - - spin_unlock_bh(&tp->lock); } /** -- cgit v1.2.3-70-g09d2 From 5f356a67ae14033d734f73b79b926f8949300e83 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 31 Jan 2012 16:56:48 +0000 Subject: staging: sep: Fix warnings caused by sizeof() types Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_main.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/sep/sep_main.c b/drivers/staging/sep/sep_main.c index 0defb0ad4c8..7f8362cab7a 100644 --- a/drivers/staging/sep/sep_main.c +++ b/drivers/staging/sep/sep_main.c @@ -214,7 +214,7 @@ static int sep_allocate_dmatables_region(struct sep_device *sep, return -EINVAL; } - dev_dbg(&sep->pdev->dev, "[PID%d] newlen = 0x%08X\n", + dev_dbg(&sep->pdev->dev, "[PID%d] newlen = 0x%08zX\n", current->pid, new_len); dev_dbg(&sep->pdev->dev, "[PID%d] oldlen = 0x%08X\n", current->pid, dma_ctx->dmatables_len); @@ -3344,7 +3344,7 @@ static ssize_t sep_activate_msgarea_context(struct sep_device *sep, if (!msg_region || !(*msg_region) || SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES < msg_len) { dev_warn(&sep->pdev->dev, - "[PID%d] invalid act msgarea len 0x%08X\n", + "[PID%d] invalid act msgarea len 0x%08zX\n", current->pid, msg_len); return -EINVAL; } @@ -3376,7 +3376,7 @@ static ssize_t sep_create_msgarea_context(struct sep_device *sep, SEP_DRIVER_MAX_MESSAGE_SIZE_IN_BYTES < msg_len || SEP_DRIVER_MIN_MESSAGE_SIZE_IN_BYTES > msg_len) { dev_warn(&sep->pdev->dev, - "[PID%d] invalid creat msgarea len 0x%08X\n", + "[PID%d] invalid creat msgarea len 0x%08zX\n", current->pid, msg_len); error = -EINVAL; goto end_function; @@ -3463,7 +3463,7 @@ static ssize_t sep_read(struct file *filp, sep_dump_message(sep); - dev_dbg(&sep->pdev->dev, "[PID%d] count_user = 0x%08X\n", + dev_dbg(&sep->pdev->dev, "[PID%d] count_user = 0x%08zX\n", current->pid, count_user); /* In case user has allocated bigger buffer */ @@ -3522,7 +3522,7 @@ static inline ssize_t sep_fastcall_args_get(struct sep_device *sep, if (count_user < sizeof(struct sep_fastcall_hdr)) { dev_warn(&sep->pdev->dev, - "[PID%d] too small message size 0x%08X\n", + "[PID%d] too small message size 0x%08zX\n", current->pid, count_user); error = -EINVAL; goto end_function; @@ -3563,7 +3563,7 @@ static inline ssize_t sep_fastcall_args_get(struct sep_device *sep, if (actual_count != count_user) { dev_warn(&sep->pdev->dev, "[PID%d] inconsistent message " - "sizes 0x%08X vs 0x%08X\n", + "sizes 0x%08zX vs 0x%08zX\n", current->pid, actual_count, count_user); error = -EMSGSIZE; goto end_function; -- cgit v1.2.3-70-g09d2 From d1b5342c1f5946c2219e4e5bd770b1c1fc186272 Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Mon, 26 Dec 2011 17:57:32 +0100 Subject: staging: nvec: ps2: add suspend/resume functions This adds suspend and resume functions to the nvec_ps2 mouse driver. During suspend the nvec sends a "Cancel all mouse events" command. If this is missed, there will be still some bytes in the received buffer after resume which make the mouse go out of sync. Signed-off-by: Marc Dietrich Signed-off-by: Julian Andres Klode Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec_ps2.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c index 742f5ccfe76..4410dfb3e33 100644 --- a/drivers/staging/nvec/nvec_ps2.c +++ b/drivers/staging/nvec/nvec_ps2.c @@ -111,8 +111,27 @@ static int __devinit nvec_mouse_probe(struct platform_device *pdev) return 0; } +static int nvec_mouse_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); + + /* send cancel autoreceive */ + nvec_write_async(nvec, "\x06\x04", 2); + + return 0; +} + +static int nvec_mouse_resume(struct platform_device *pdev) +{ + ps2_startstreaming(ps2_dev.ser_dev); + + return 0; +} + static struct platform_driver nvec_mouse_driver = { .probe = nvec_mouse_probe, + .suspend = nvec_mouse_suspend, + .resume = nvec_mouse_resume, .driver = { .name = "nvec-mouse", .owner = THIS_MODULE, -- cgit v1.2.3-70-g09d2 From 34ba143b9d1daf2eb7ea06b05c24b71faff82512 Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Mon, 26 Dec 2011 17:57:33 +0100 Subject: staging: nvec: ps2: let the start/stop streaming commands be called by the start/stop functions of serio Instead of executing these commands during open/close, the start/stop event of the serio device seem to be more appropiete. Signed-off-by: Marc Dietrich Signed-off-by: Julian Andres Klode Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec_ps2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c index 4410dfb3e33..f15283468c5 100644 --- a/drivers/staging/nvec/nvec_ps2.c +++ b/drivers/staging/nvec/nvec_ps2.c @@ -92,8 +92,8 @@ static int __devinit nvec_mouse_probe(struct platform_device *pdev) ser_dev->id.type = SERIO_8042; ser_dev->write = ps2_sendcommand; - ser_dev->open = ps2_startstreaming; - ser_dev->close = ps2_stopstreaming; + ser_dev->start = ps2_startstreaming; + ser_dev->stop = ps2_stopstreaming; strlcpy(ser_dev->name, "nvec mouse", sizeof(ser_dev->name)); strlcpy(ser_dev->phys, "nvec", sizeof(ser_dev->phys)); -- cgit v1.2.3-70-g09d2 From 4b625c3abe91fca5b5a7f05681c10105af957e4f Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Mon, 26 Dec 2011 17:57:34 +0100 Subject: staging: nvec: ps2: tell nvec to send 6 byte long messages This packet size used on most modern touchpads. Ideally, this should be configurable or autodetected. Signed-off-by: Marc Dietrich Signed-off-by: Julian Andres Klode Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec_ps2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c index f15283468c5..8bfaccd04ac 100644 --- a/drivers/staging/nvec/nvec_ps2.c +++ b/drivers/staging/nvec/nvec_ps2.c @@ -21,7 +21,7 @@ #include "nvec.h" -#define START_STREAMING {'\x06', '\x03', '\x04'} +#define START_STREAMING {'\x06', '\x03', '\x06'} #define STOP_STREAMING {'\x06', '\x04'} #define SEND_COMMAND {'\x06', '\x01', '\xf4', '\x01'} -- cgit v1.2.3-70-g09d2 From 0eedab704ed93d03b1ac392fd329f7ed20ab2279 Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Mon, 26 Dec 2011 17:57:35 +0100 Subject: staging: nvec: ps2: add some more debug functions This can print the mouse traffic which goes over the i2c bus. Make mouse debugging messages configurable and disable them by default. Signed-off-by: Marc Dietrich Signed-off-by: Julian Andres Klode Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec_ps2.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c index 8bfaccd04ac..7f470ba1160 100644 --- a/drivers/staging/nvec/nvec_ps2.c +++ b/drivers/staging/nvec/nvec_ps2.c @@ -25,6 +25,14 @@ #define STOP_STREAMING {'\x06', '\x04'} #define SEND_COMMAND {'\x06', '\x01', '\xf4', '\x01'} +#ifdef NVEC_PS2_DEBUG +#define NVEC_PHD(str, buf, len) \ + print_hex_dump(KERN_DEBUG, str, DUMP_PREFIX_NONE, \ + 16, 1, buf, len, false) +#else +#define NVEC_PHD(str, buf, len) +#endif + static const unsigned char MOUSE_RESET[] = {'\x06', '\x01', '\xff', '\x03'}; struct nvec_ps2 { @@ -67,18 +75,18 @@ static int nvec_ps2_notifier(struct notifier_block *nb, case NVEC_PS2_EVT: for (i = 0; i < msg[1]; i++) serio_interrupt(ps2_dev.ser_dev, msg[2 + i], 0); + NVEC_PHD("ps/2 mouse event: ", &msg[2], msg[1]); return NOTIFY_STOP; case NVEC_PS2: - if (msg[2] == 1) + if (msg[2] == 1) { for (i = 0; i < (msg[1] - 2); i++) serio_interrupt(ps2_dev.ser_dev, msg[i + 4], 0); - else if (msg[1] != 2) { /* !ack */ - print_hex_dump(KERN_WARNING, "unhandled mouse event: ", - DUMP_PREFIX_NONE, 16, 1, - msg, msg[1] + 2, true); + NVEC_PHD("ps/2 mouse reply: ", &msg[4], msg[1] - 2); } + else if (msg[1] != 2) /* !ack */ + NVEC_PHD("unhandled mouse event: ", msg, msg[1] + 2); return NOTIFY_STOP; } -- cgit v1.2.3-70-g09d2 From a573298b81ffd05856ddaa222826471eabf3953b Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Mon, 26 Dec 2011 17:57:36 +0100 Subject: staging: nvec: ps2: disable/enable mouse on suspend/resume This change makes the touchpad buttons work after suspend/resume. Signed-off-by: Marc Dietrich Signed-off-by: Julian Andres Klode Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec_ps2.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c index 7f470ba1160..4be3d220a63 100644 --- a/drivers/staging/nvec/nvec_ps2.c +++ b/drivers/staging/nvec/nvec_ps2.c @@ -123,6 +123,9 @@ static int nvec_mouse_suspend(struct platform_device *pdev, pm_message_t state) { struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); + /* disable mouse */ + nvec_write_async(nvec, "\x06\xf4", 2); + /* send cancel autoreceive */ nvec_write_async(nvec, "\x06\x04", 2); @@ -131,8 +134,13 @@ static int nvec_mouse_suspend(struct platform_device *pdev, pm_message_t state) static int nvec_mouse_resume(struct platform_device *pdev) { + struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); + ps2_startstreaming(ps2_dev.ser_dev); + /* enable mouse */ + nvec_write_async(nvec, "\x06\xf5", 2); + return 0; } -- cgit v1.2.3-70-g09d2 From 36b30d6138f4677514aca35ab76c20c1604baaad Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Mon, 26 Dec 2011 17:57:37 +0100 Subject: staging: nvec: ps2: change serio type to passthrough This changes the serio type of the nvec_ps2 mouse port to passthrough. The old 8042 type seems appropiete for keyboards only. Signed-off-by: Marc Dietrich Signed-off-by: Julian Andres Klode Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec_ps2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c index 4be3d220a63..14a6f687cf7 100644 --- a/drivers/staging/nvec/nvec_ps2.c +++ b/drivers/staging/nvec/nvec_ps2.c @@ -98,7 +98,7 @@ static int __devinit nvec_mouse_probe(struct platform_device *pdev) struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); struct serio *ser_dev = kzalloc(sizeof(struct serio), GFP_KERNEL); - ser_dev->id.type = SERIO_8042; + ser_dev->id.type = SERIO_PS_PSTHRU; ser_dev->write = ps2_sendcommand; ser_dev->start = ps2_startstreaming; ser_dev->stop = ps2_stopstreaming; -- cgit v1.2.3-70-g09d2 From d3f862aec400dd831a4bdbea107fd85419bddab1 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 26 Dec 2011 17:57:38 +0100 Subject: staging: nvec: Fix typo s/I2C_SL_NEWL/I2C_SL_NEWSL/ The constant I2C_SL_NEWL meant "new slave", but the S was missing. Signed-off-by: Julian Andres Klode Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index fafdfa25e13..b6108afb909 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -49,7 +49,7 @@ #define I2C_CNFG_DEBOUNCE_CNT_SHIFT 12 #define I2C_SL_CNFG 0x20 -#define I2C_SL_NEWL (1<<2) +#define I2C_SL_NEWSL (1<<2) #define I2C_SL_NACK (1<<1) #define I2C_SL_RESP (1<<0) #define I2C_SL_IRQ (1<<3) @@ -687,7 +687,7 @@ static void tegra_init_i2c_slave(struct nvec_chip *nvec) clk_set_rate(nvec->i2c_clk, 8 * 80000); - writel(I2C_SL_NEWL, nvec->base + I2C_SL_CNFG); + writel(I2C_SL_NEWSL, nvec->base + I2C_SL_CNFG); writel(0x1E, nvec->base + I2C_SL_DELAY_COUNT); writel(nvec->i2c_addr>>1, nvec->base + I2C_SL_ADDR1); @@ -701,7 +701,7 @@ static void tegra_init_i2c_slave(struct nvec_chip *nvec) static void nvec_disable_i2c_slave(struct nvec_chip *nvec) { disable_irq(nvec->irq); - writel(I2C_SL_NEWL | I2C_SL_NACK, nvec->base + I2C_SL_CNFG); + writel(I2C_SL_NEWSL | I2C_SL_NACK, nvec->base + I2C_SL_CNFG); clk_disable(nvec->i2c_clk); } -- cgit v1.2.3-70-g09d2 From aed92bbcf4ce760c4d7848013a0db3bdd4ae9492 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 26 Dec 2011 17:57:39 +0100 Subject: staging: nvec: Use gpio_request_one() instead of gpio_request() This saves us some calls and thus makes the code shorter and nicer. Signed-off-by: Julian Andres Klode Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index b6108afb909..3c60088871e 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -784,11 +784,6 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev) nvec->i2c_clk = i2c_clk; nvec->rx = &nvec->msg_pool[0]; - /* Set the gpio to low when we've got something to say */ - err = gpio_request(nvec->gpio, "nvec gpio"); - if (err < 0) - dev_err(nvec->dev, "couldn't request gpio\n"); - ATOMIC_INIT_NOTIFIER_HEAD(&nvec->notifier_list); init_completion(&nvec->sync_write); @@ -802,6 +797,12 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev) INIT_WORK(&nvec->tx_work, nvec_request_master); nvec->wq = alloc_workqueue("nvec", WQ_NON_REENTRANT, 2); + err = gpio_request_one(nvec->gpio, GPIOF_OUT_INIT_HIGH, "nvec gpio"); + if (err < 0) { + dev_err(nvec->dev, "couldn't request gpio\n"); + goto failed; + } + err = request_irq(nvec->irq, nvec_interrupt, 0, "nvec", nvec); if (err) { dev_err(nvec->dev, "couldn't request irq\n"); @@ -813,8 +814,6 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev) clk_enable(i2c_clk); - gpio_direction_output(nvec->gpio, 1); - gpio_set_value(nvec->gpio, 1); /* enable event reporting */ nvec_write_async(nvec, EC_ENABLE_EVENT_REPORTING, -- cgit v1.2.3-70-g09d2 From e96045a7c837200e65c9fa8f8a94020bc2107931 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 26 Dec 2011 17:57:40 +0100 Subject: staging: nvec: Fix Kconfig dependencies nvec modules do not require other stuff to be build in, nor does nvec_ps2 require mouse support, only generic serio support. Signed-off-by: Julian Andres Klode Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/nvec/Kconfig b/drivers/staging/nvec/Kconfig index 86a8b8c418c..731301f524a 100644 --- a/drivers/staging/nvec/Kconfig +++ b/drivers/staging/nvec/Kconfig @@ -7,21 +7,21 @@ config MFD_NVEC config KEYBOARD_NVEC bool "Keyboard on nVidia compliant EC" - depends on MFD_NVEC && INPUT=y + depends on MFD_NVEC && INPUT help Say Y here to enable support for a keyboard connected to a nVidia compliant embedded controller. config SERIO_NVEC_PS2 bool "PS2 on nVidia EC" - depends on MFD_NVEC && MOUSE_PS2 + depends on MFD_NVEC && SERIO help Say Y here to enable support for a Touchpad / Mouse connected to a nVidia compliant embedded controller. config NVEC_POWER bool "NVEC charger and battery" - depends on MFD_NVEC && POWER_SUPPLY=y + depends on MFD_NVEC && POWER_SUPPLY help Say Y to enable support for battery and charger interface for nVidia compliant embedded controllers. -- cgit v1.2.3-70-g09d2 From cca4d5adcff515b4bf5402dc23792f5123872906 Mon Sep 17 00:00:00 2001 From: Santosh Sajjan Date: Mon, 30 Jan 2012 22:02:26 +0200 Subject: ath6kl: Workaround to support Deep Sleep with MSM. Set the host pm flag MMC_PM_WAKE_SDIO_IRQ to allow host to disable the sdc2_clk and sdc2_h_clk,so that the MSM device enter into TCXO shutdown. Signed-off-by: Santosh Sajjan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/sdio.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index 07dcf00ca1a..4febee72349 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -856,6 +856,19 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) if (ret) goto cut_pwr; + /* + * Workaround to support Deep Sleep with MSM, set the host pm + * flag as MMC_PM_WAKE_SDIO_IRQ to allow SDCC deiver to disable + * the sdc2_clock and internally allows MSM to enter + * TCXO shutdown properly. + */ + if ((flags & MMC_PM_WAKE_SDIO_IRQ)) { + ret = sdio_set_host_pm_flags(func, + MMC_PM_WAKE_SDIO_IRQ); + if (ret) + goto cut_pwr; + } + ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_DEEPSLEEP, NULL); if (ret) -- cgit v1.2.3-70-g09d2 From 172975aa746e155533cb386c7159c2d6510e2bc8 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 14 Dec 2011 13:57:25 +0100 Subject: drm/i915: Handle unmappable buffers during error state capture As the buffer is not necessarily accessible through the GTT at the time of a GPU hang, and capturing some of its contents is far more valuable than skipping it, provide a clflushed fallback read path. We still prefer to read through the GTT as that is more consistent with the GPU access of the same buffer. So example it will demonstrate any errorneous tiling or swizzling of the command buffer as seen by the GPU. This becomes necessary with use of CPU relocations and lazy GTT binding, but could potentially happen anyway as a result of a pathological error. Signed-off-by: Chris Wilson Reviewed-by: Daniel Vetter Reviewed-by: Eugeni Dodonov Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 64bb2127911..8ea1ca4158a 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -720,7 +720,6 @@ i915_error_object_create(struct drm_i915_private *dev_priv, reloc_offset = src->gtt_offset; for (page = 0; page < page_count; page++) { unsigned long flags; - void __iomem *s; void *d; d = kmalloc(PAGE_SIZE, GFP_ATOMIC); @@ -728,10 +727,29 @@ i915_error_object_create(struct drm_i915_private *dev_priv, goto unwind; local_irq_save(flags); - s = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, - reloc_offset); - memcpy_fromio(d, s, PAGE_SIZE); - io_mapping_unmap_atomic(s); + if (reloc_offset < dev_priv->mm.gtt_mappable_end) { + void __iomem *s; + + /* Simply ignore tiling or any overlapping fence. + * It's part of the error state, and this hopefully + * captures what the GPU read. + */ + + s = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, + reloc_offset); + memcpy_fromio(d, s, PAGE_SIZE); + io_mapping_unmap_atomic(s); + } else { + void *s; + + drm_clflush_pages(&src->pages[page], 1); + + s = kmap_atomic(src->pages[page]); + memcpy(d, s, PAGE_SIZE); + kunmap_atomic(s); + + drm_clflush_pages(&src->pages[page], 1); + } local_irq_restore(flags); dst->pages[page] = d; -- cgit v1.2.3-70-g09d2 From e404decb0fb017be80552adee894b35307b6c7b4 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 29 Jan 2012 12:56:23 +0000 Subject: drivers/net: Remove unnecessary k.alloc/v.alloc OOM messages alloc failures use dump_stack so emitting an additional out-of-memory message is an unnecessary duplication. Remove the allocation failure messages. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/bonding/bond_alb.c | 12 ++++-------- drivers/net/can/slcan.c | 4 +--- drivers/net/ethernet/amd/ni65.c | 4 +--- drivers/net/ethernet/apple/bmac.c | 4 +--- drivers/net/ethernet/apple/mace.c | 4 +--- drivers/net/ethernet/broadcom/bnx2.c | 4 +--- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 4 +--- drivers/net/ethernet/brocade/bna/bnad_debugfs.c | 21 +++------------------ drivers/net/ethernet/cisco/enic/enic_main.c | 1 - drivers/net/ethernet/cisco/enic/vnic_rq.c | 4 +--- drivers/net/ethernet/cisco/enic/vnic_wq.c | 4 +--- drivers/net/ethernet/i825xx/lp486e.c | 2 -- drivers/net/ethernet/ibm/emac/rgmii.c | 5 +---- drivers/net/ethernet/ibm/emac/tah.c | 5 +---- drivers/net/ethernet/ibm/emac/zmii.c | 5 +---- drivers/net/ethernet/intel/e1000/e1000_main.c | 4 +--- drivers/net/ethernet/intel/ixgb/ixgb_main.c | 4 +--- drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 6 +----- drivers/net/ethernet/korina.c | 1 - drivers/net/ethernet/marvell/pxa168_eth.c | 10 ++++------ drivers/net/ethernet/mellanox/mlx4/en_rx.c | 5 ++--- drivers/net/ethernet/mellanox/mlx4/en_tx.c | 6 ++---- drivers/net/ethernet/micrel/ks8851_mll.c | 4 +--- .../net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c | 9 +++------ .../net/ethernet/qlogic/netxen/netxen_nic_init.c | 12 +++--------- drivers/net/ethernet/qlogic/qlge/qlge_dbg.c | 4 +--- drivers/net/ethernet/sis/sis900.c | 1 - drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 ++--- drivers/net/ethernet/sun/cassini.c | 1 - drivers/net/ethernet/sun/sunvnet.c | 9 +++------ drivers/net/ethernet/toshiba/ps3_gelic_wireless.c | 5 ++--- drivers/net/hamradio/yam.c | 1 - drivers/net/hippi/rrunner.c | 8 +------- drivers/net/irda/donauboe.c | 2 -- drivers/net/netconsole.c | 8 ++------ drivers/net/ppp/pptp.c | 4 +--- drivers/net/slip/slip.c | 4 +--- drivers/net/tokenring/3c359.c | 4 ---- drivers/net/tokenring/madgemc.c | 1 - drivers/net/vmxnet3/vmxnet3_drv.c | 15 +++------------ drivers/net/wan/c101.c | 4 +--- drivers/net/wan/dscc4.c | 8 ++------ drivers/net/wan/lmc/lmc_main.c | 1 - drivers/net/wan/n2.c | 4 +--- drivers/net/wan/pc300too.c | 1 - drivers/net/wan/pci200syn.c | 1 - drivers/net/wan/wanxl.c | 1 - drivers/net/wan/x25_asy.c | 4 +--- drivers/net/wireless/ath/ath9k/htc_hst.c | 5 +---- drivers/net/wireless/hostap/hostap_hw.c | 18 ++++++------------ drivers/net/wireless/ipw2x00/ipw2100.c | 5 +---- drivers/net/wireless/libertas/if_cs.c | 5 ++--- drivers/net/wireless/libertas/if_usb.c | 4 +--- drivers/net/wireless/libertas_tf/if_usb.c | 4 +--- drivers/net/wireless/mwifiex/pcie.c | 4 +--- drivers/net/wireless/mwifiex/sdio.c | 4 +--- drivers/net/wireless/orinoco/main.c | 6 ++---- drivers/net/wireless/prism54/islpci_mgt.c | 6 ++---- drivers/net/wireless/rtlwifi/rtl8192se/sw.c | 5 +---- drivers/net/xen-netback/netback.c | 4 +--- 60 files changed, 77 insertions(+), 233 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index f820b26b9db..9abfde47931 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -180,11 +180,9 @@ static int tlb_initialize(struct bonding *bond) int i; new_hashtbl = kzalloc(size, GFP_KERNEL); - if (!new_hashtbl) { - pr_err("%s: Error: Failed to allocate TLB hash table\n", - bond->dev->name); + if (!new_hashtbl) return -1; - } + _lock_tx_hashtbl_bh(bond); bond_info->tx_hashtbl = new_hashtbl; @@ -784,11 +782,9 @@ static int rlb_initialize(struct bonding *bond) int i; new_hashtbl = kmalloc(size, GFP_KERNEL); - if (!new_hashtbl) { - pr_err("%s: Error: Failed to allocate RLB hash table\n", - bond->dev->name); + if (!new_hashtbl) return -1; - } + _lock_rx_hashtbl_bh(bond); bond_info->rx_hashtbl = new_hashtbl; diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index 579e7fca644..98a5a7d867f 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -639,10 +639,8 @@ static int __init slcan_init(void) printk(KERN_INFO "slcan: %d dynamic interface channels.\n", maxdev); slcan_devs = kzalloc(sizeof(struct net_device *)*maxdev, GFP_KERNEL); - if (!slcan_devs) { - printk(KERN_ERR "slcan: can't allocate slcan device array!\n"); + if (!slcan_devs) return -ENOMEM; - } /* Fill in our line protocol discipline, and register it */ status = tty_register_ldisc(N_SLCAN, &slc_ldisc); diff --git a/drivers/net/ethernet/amd/ni65.c b/drivers/net/ethernet/amd/ni65.c index 6e6aa7213aa..735c213798b 100644 --- a/drivers/net/ethernet/amd/ni65.c +++ b/drivers/net/ethernet/amd/ni65.c @@ -621,10 +621,8 @@ static void *ni65_alloc_mem(struct net_device *dev,char *what,int size,int type) } else { ret = ptr = kmalloc(T_BUF_SIZE,GFP_KERNEL | GFP_DMA); - if(!ret) { - printk(KERN_WARNING "%s: unable to allocate %s memory.\n",dev->name,what); + if(!ret) return NULL; - } } if( (u32) virt_to_phys(ptr+size) > 0x1000000) { printk(KERN_WARNING "%s: unable to allocate %s memory in lower 16MB!\n",dev->name,what); diff --git a/drivers/net/ethernet/apple/bmac.c b/drivers/net/ethernet/apple/bmac.c index d070b229dbf..4108ac800cf 100644 --- a/drivers/net/ethernet/apple/bmac.c +++ b/drivers/net/ethernet/apple/bmac.c @@ -1660,10 +1660,8 @@ static int __init bmac_init(void) { if (bmac_emergency_rxbuf == NULL) { bmac_emergency_rxbuf = kmalloc(RX_BUFLEN, GFP_KERNEL); - if (bmac_emergency_rxbuf == NULL) { - printk(KERN_ERR "BMAC: can't allocate emergency RX buffer\n"); + if (bmac_emergency_rxbuf == NULL) return -ENOMEM; - } } return macio_register_driver(&bmac_driver); diff --git a/drivers/net/ethernet/apple/mace.c b/drivers/net/ethernet/apple/mace.c index bec87bd9195..45ba18ee3d6 100644 --- a/drivers/net/ethernet/apple/mace.c +++ b/drivers/net/ethernet/apple/mace.c @@ -136,10 +136,8 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i */ if (dummy_buf == NULL) { dummy_buf = kmalloc(RX_BUFLEN+2, GFP_KERNEL); - if (dummy_buf == NULL) { - printk(KERN_ERR "MACE: couldn't allocate dummy buffer\n"); + if (dummy_buf == NULL) return -ENOMEM; - } } if (macio_request_resources(mdev, "mace")) { diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index 021fb818007..0a4c5405dcf 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -2625,10 +2625,8 @@ bnx2_alloc_bad_rbuf(struct bnx2 *bp) u32 val; good_mbuf = kmalloc(512 * sizeof(u16), GFP_KERNEL); - if (good_mbuf == NULL) { - pr_err("Failed to allocate memory in %s\n", __func__); + if (good_mbuf == NULL) return -ENOMEM; - } REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS, BNX2_MISC_ENABLE_SET_BITS_RX_MBUF_ENABLE); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index fea96150539..582cbcf5f9f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -10894,10 +10894,8 @@ static inline void be16_to_cpu_n(const u8 *_source, u8 *_target, u32 n) do { \ u32 len = be32_to_cpu(fw_hdr->arr.len); \ bp->arr = kmalloc(len, GFP_KERNEL); \ - if (!bp->arr) { \ - pr_err("Failed to allocate %d bytes for "#arr"\n", len); \ + if (!bp->arr) \ goto lbl; \ - } \ func(bp->firmware->data + be32_to_cpu(fw_hdr->arr.offset), \ (u8 *)bp->arr, len); \ } while (0) diff --git a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c index 592ad3929f5..c9fdceb135f 100644 --- a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c +++ b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c @@ -62,8 +62,6 @@ bnad_debugfs_open_fwtrc(struct inode *inode, struct file *file) if (!fw_debug->debug_buffer) { kfree(fw_debug); fw_debug = NULL; - pr_warn("bna %s: Failed to allocate fwtrc buffer\n", - pci_name(bnad->pcidev)); return -ENOMEM; } @@ -105,8 +103,6 @@ bnad_debugfs_open_fwsave(struct inode *inode, struct file *file) if (!fw_debug->debug_buffer) { kfree(fw_debug); fw_debug = NULL; - pr_warn("bna %s: Failed to allocate fwsave buffer\n", - pci_name(bnad->pcidev)); return -ENOMEM; } @@ -208,8 +204,6 @@ bnad_debugfs_open_drvinfo(struct inode *inode, struct file *file) if (!drv_info->debug_buffer) { kfree(drv_info); drv_info = NULL; - pr_warn("bna %s: Failed to allocate drv info buffer\n", - pci_name(bnad->pcidev)); return -ENOMEM; } @@ -348,11 +342,8 @@ bnad_debugfs_write_regrd(struct file *file, const char __user *buf, /* Allocate memory to store the user space buf */ kern_buf = kzalloc(nbytes, GFP_KERNEL); - if (!kern_buf) { - pr_warn("bna %s: Failed to allocate user buffer\n", - pci_name(bnad->pcidev)); + if (!kern_buf) return -ENOMEM; - } if (copy_from_user(kern_buf, (void __user *)buf, nbytes)) { kfree(kern_buf); @@ -373,11 +364,8 @@ bnad_debugfs_write_regrd(struct file *file, const char __user *buf, bnad->reglen = 0; bnad->regdata = kzalloc(len << 2, GFP_KERNEL); - if (!bnad->regdata) { - pr_warn("bna %s: Failed to allocate regrd buffer\n", - pci_name(bnad->pcidev)); + if (!bnad->regdata) return -ENOMEM; - } bnad->reglen = len << 2; rb = bfa_ioc_bar0(ioc); @@ -421,11 +409,8 @@ bnad_debugfs_write_regwr(struct file *file, const char __user *buf, /* Allocate memory to store the user space buf */ kern_buf = kzalloc(nbytes, GFP_KERNEL); - if (!kern_buf) { - pr_warn("bna %s: Failed to allocate user buffer\n", - pci_name(bnad->pcidev)); + if (!kern_buf) return -ENOMEM; - } if (copy_from_user(kern_buf, (void __user *)buf, nbytes)) { kfree(kern_buf); diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index ab3f67f980d..07df13745c4 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c @@ -2388,7 +2388,6 @@ static int __devinit enic_probe(struct pci_dev *pdev, /* Allocate structure for port profiles */ enic->pp = kcalloc(num_pps, sizeof(*enic->pp), GFP_KERNEL); if (!enic->pp) { - pr_err("port profile alloc failed, aborting\n"); err = -ENOMEM; goto err_out_disable_sriov_pp; } diff --git a/drivers/net/ethernet/cisco/enic/vnic_rq.c b/drivers/net/ethernet/cisco/enic/vnic_rq.c index 34105e0951a..7e1488fc8ab 100644 --- a/drivers/net/ethernet/cisco/enic/vnic_rq.c +++ b/drivers/net/ethernet/cisco/enic/vnic_rq.c @@ -38,10 +38,8 @@ static int vnic_rq_alloc_bufs(struct vnic_rq *rq) for (i = 0; i < blks; i++) { rq->bufs[i] = kzalloc(VNIC_RQ_BUF_BLK_SZ(count), GFP_ATOMIC); - if (!rq->bufs[i]) { - pr_err("Failed to alloc rq_bufs\n"); + if (!rq->bufs[i]) return -ENOMEM; - } } for (i = 0; i < blks; i++) { diff --git a/drivers/net/ethernet/cisco/enic/vnic_wq.c b/drivers/net/ethernet/cisco/enic/vnic_wq.c index df61bd932ea..5e0d7a2be9b 100644 --- a/drivers/net/ethernet/cisco/enic/vnic_wq.c +++ b/drivers/net/ethernet/cisco/enic/vnic_wq.c @@ -38,10 +38,8 @@ static int vnic_wq_alloc_bufs(struct vnic_wq *wq) for (i = 0; i < blks; i++) { wq->bufs[i] = kzalloc(VNIC_WQ_BUF_BLK_SZ(count), GFP_ATOMIC); - if (!wq->bufs[i]) { - pr_err("Failed to alloc wq_bufs\n"); + if (!wq->bufs[i]) return -ENOMEM; - } } for (i = 0; i < blks; i++) { diff --git a/drivers/net/ethernet/i825xx/lp486e.c b/drivers/net/ethernet/i825xx/lp486e.c index 414044b3cb1..02df5f5accb 100644 --- a/drivers/net/ethernet/i825xx/lp486e.c +++ b/drivers/net/ethernet/i825xx/lp486e.c @@ -454,8 +454,6 @@ init_rx_bufs(struct net_device *dev, int num) { } rfd->rbd = rbd; - } else { - printk("Could not kmalloc rbd\n"); } } lp->rbd_tail->next = rfd->rbd; diff --git a/drivers/net/ethernet/ibm/emac/rgmii.c b/drivers/net/ethernet/ibm/emac/rgmii.c index 05484f918ee..d3123282e18 100644 --- a/drivers/net/ethernet/ibm/emac/rgmii.c +++ b/drivers/net/ethernet/ibm/emac/rgmii.c @@ -237,11 +237,8 @@ static int __devinit rgmii_probe(struct platform_device *ofdev) rc = -ENOMEM; dev = kzalloc(sizeof(struct rgmii_instance), GFP_KERNEL); - if (dev == NULL) { - printk(KERN_ERR "%s: could not allocate RGMII device!\n", - np->full_name); + if (dev == NULL) goto err_gone; - } mutex_init(&dev->lock); dev->ofdev = ofdev; diff --git a/drivers/net/ethernet/ibm/emac/tah.c b/drivers/net/ethernet/ibm/emac/tah.c index 0d9881efe2f..872912ef518 100644 --- a/drivers/net/ethernet/ibm/emac/tah.c +++ b/drivers/net/ethernet/ibm/emac/tah.c @@ -96,11 +96,8 @@ static int __devinit tah_probe(struct platform_device *ofdev) rc = -ENOMEM; dev = kzalloc(sizeof(struct tah_instance), GFP_KERNEL); - if (dev == NULL) { - printk(KERN_ERR "%s: could not allocate TAH device!\n", - np->full_name); + if (dev == NULL) goto err_gone; - } mutex_init(&dev->lock); dev->ofdev = ofdev; diff --git a/drivers/net/ethernet/ibm/emac/zmii.c b/drivers/net/ethernet/ibm/emac/zmii.c index e799a6116ba..415e9b4d540 100644 --- a/drivers/net/ethernet/ibm/emac/zmii.c +++ b/drivers/net/ethernet/ibm/emac/zmii.c @@ -240,11 +240,8 @@ static int __devinit zmii_probe(struct platform_device *ofdev) rc = -ENOMEM; dev = kzalloc(sizeof(struct zmii_instance), GFP_KERNEL); - if (dev == NULL) { - printk(KERN_ERR "%s: could not allocate ZMII device!\n", - np->full_name); + if (dev == NULL) goto err_gone; - } mutex_init(&dev->lock); dev->ofdev = ofdev; diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 669ca3800c0..363fd395c75 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -730,10 +730,8 @@ static void e1000_dump_eeprom(struct e1000_adapter *adapter) eeprom.offset = 0; data = kmalloc(eeprom.len, GFP_KERNEL); - if (!data) { - pr_err("Unable to allocate memory to dump EEPROM data\n"); + if (!data) return; - } ops->get_eeprom(netdev, &eeprom, data); diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_main.c b/drivers/net/ethernet/intel/ixgb/ixgb_main.c index 9bd5faf64a8..002478801a1 100644 --- a/drivers/net/ethernet/intel/ixgb/ixgb_main.c +++ b/drivers/net/ethernet/intel/ixgb/ixgb_main.c @@ -1136,10 +1136,8 @@ ixgb_set_multi(struct net_device *netdev) u8 *mta = kmalloc(IXGB_MAX_NUM_MULTICAST_ADDRESSES * ETH_ALEN, GFP_ATOMIC); u8 *addr; - if (!mta) { - pr_err("allocation of multicast memory failed\n"); + if (!mta) goto alloc_failed; - } IXGB_WRITE_REG(hw, RCTL, rctl); diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index bed411bada2..f3bc9333a08 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -2517,12 +2517,8 @@ int ixgbevf_setup_rx_resources(struct ixgbevf_adapter *adapter, size = sizeof(struct ixgbevf_rx_buffer) * rx_ring->count; rx_ring->rx_buffer_info = vzalloc(size); - if (!rx_ring->rx_buffer_info) { - hw_dbg(&adapter->hw, - "Unable to vmalloc buffer memory for " - "the receive descriptor ring\n"); + if (!rx_ring->rx_buffer_info) goto alloc_failed; - } /* Round up to nearest 4K */ rx_ring->size = rx_ring->count * sizeof(union ixgbe_adv_rx_desc); diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c index 6ad094f176f..341d10130dc 100644 --- a/drivers/net/ethernet/korina.c +++ b/drivers/net/ethernet/korina.c @@ -1150,7 +1150,6 @@ static int korina_probe(struct platform_device *pdev) lp->td_ring = kmalloc(TD_RING_SIZE + RD_RING_SIZE, GFP_KERNEL); if (!lp->td_ring) { - printk(KERN_ERR DRV_NAME ": cannot allocate descriptors\n"); rc = -ENXIO; goto probe_err_td_ring; } diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c index 953ba5851f7..92b4b4e68e3 100644 --- a/drivers/net/ethernet/marvell/pxa168_eth.c +++ b/drivers/net/ethernet/marvell/pxa168_eth.c @@ -1017,10 +1017,9 @@ static int rxq_init(struct net_device *dev) /* Allocate RX skb rings */ pep->rx_skb = kmalloc(sizeof(*pep->rx_skb) * pep->rx_ring_size, GFP_KERNEL); - if (!pep->rx_skb) { - printk(KERN_ERR "%s: Cannot alloc RX skb ring\n", dev->name); + if (!pep->rx_skb) return -ENOMEM; - } + /* Allocate RX ring */ pep->rx_desc_count = 0; size = pep->rx_ring_size * sizeof(struct rx_desc); @@ -1081,10 +1080,9 @@ static int txq_init(struct net_device *dev) pep->tx_skb = kmalloc(sizeof(*pep->tx_skb) * pep->tx_ring_size, GFP_KERNEL); - if (!pep->tx_skb) { - printk(KERN_ERR "%s: Cannot alloc TX skb ring\n", dev->name); + if (!pep->tx_skb) return -ENOMEM; - } + /* Allocate TX ring */ pep->tx_desc_count = 0; size = pep->tx_ring_size * sizeof(struct tx_desc); diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index 971d4b6b8df..f61d0e08f52 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -281,10 +281,9 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv, tmp = size * roundup_pow_of_two(MLX4_EN_MAX_RX_FRAGS * sizeof(struct skb_frag_struct)); ring->rx_info = vmalloc(tmp); - if (!ring->rx_info) { - en_err(priv, "Failed allocating rx_info ring\n"); + if (!ring->rx_info) return -ENOMEM; - } + en_dbg(DRV, priv, "Allocated rx_info ring at addr:%p size:%d\n", ring->rx_info, tmp); diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index 9ef9038d062..ff325058658 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c @@ -71,16 +71,14 @@ int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv, tmp = size * sizeof(struct mlx4_en_tx_info); ring->tx_info = vmalloc(tmp); - if (!ring->tx_info) { - en_err(priv, "Failed allocating tx_info ring\n"); + if (!ring->tx_info) return -ENOMEM; - } + en_dbg(DRV, priv, "Allocated tx_info ring at addr:%p size:%d\n", ring->tx_info, tmp); ring->bounce_buf = kmalloc(MAX_DESC_SIZE, GFP_KERNEL); if (!ring->bounce_buf) { - en_err(priv, "Failed allocating bounce buffer\n"); err = -ENOMEM; goto err_tx; } diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c index a37264e61a2..4a9d57fb9fb 100644 --- a/drivers/net/ethernet/micrel/ks8851_mll.c +++ b/drivers/net/ethernet/micrel/ks8851_mll.c @@ -1501,10 +1501,8 @@ static int ks_hw_init(struct ks_net *ks) ks->mcast_lst_size = 0; ks->frame_head_info = kmalloc(MHEADER_SIZE, GFP_KERNEL); - if (!ks->frame_head_info) { - pr_err("Error: Fail to allocate frame memory\n"); + if (!ks->frame_head_info) return false; - } ks_set_mac(ks, KS_DEFAULT_MAC_ADDRESS); return true; diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c index 3ead111111e..0217991fede 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c @@ -1587,10 +1587,8 @@ int pch_gbe_setup_tx_resources(struct pch_gbe_adapter *adapter, size = (int)sizeof(struct pch_gbe_buffer) * tx_ring->count; tx_ring->buffer_info = vzalloc(size); - if (!tx_ring->buffer_info) { - pr_err("Unable to allocate memory for the buffer information\n"); + if (!tx_ring->buffer_info) return -ENOMEM; - } tx_ring->size = tx_ring->count * (int)sizeof(struct pch_gbe_tx_desc); @@ -1636,10 +1634,9 @@ int pch_gbe_setup_rx_resources(struct pch_gbe_adapter *adapter, size = (int)sizeof(struct pch_gbe_buffer) * rx_ring->count; rx_ring->buffer_info = vzalloc(size); - if (!rx_ring->buffer_info) { - pr_err("Unable to allocate memory for the receive descriptor ring\n"); + if (!rx_ring->buffer_info) return -ENOMEM; - } + rx_ring->size = rx_ring->count * (int)sizeof(struct pch_gbe_rx_desc); rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size, &rx_ring->dma, GFP_KERNEL); diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c index a8259cc19a6..094d26c5181 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c @@ -280,13 +280,10 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) } rds_ring->rx_buf_arr = vzalloc(RCV_BUFF_RINGSIZE(rds_ring)); - if (rds_ring->rx_buf_arr == NULL) { - printk(KERN_ERR "%s: Failed to allocate " - "rx buffer ring %d\n", - netdev->name, ring); + if (rds_ring->rx_buf_arr == NULL) /* free whatever was already allocated */ goto err_out; - } + INIT_LIST_HEAD(&rds_ring->free_list); /* * Now go through all of them, set reference handles @@ -480,11 +477,8 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter) } buf = kcalloc(n, sizeof(struct crb_addr_pair), GFP_KERNEL); - if (buf == NULL) { - printk("%s: netxen_pinit_from_rom: Unable to calloc memory.\n", - netxen_nic_driver_name); + if (buf == NULL) return -ENOMEM; - } for (i = 0; i < n; i++) { if (netxen_rom_fast_read(adapter, 8*i + 4*offset, &val) != 0 || diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c index fca804f36d6..58185b604b7 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c @@ -1824,10 +1824,8 @@ void ql_dump_hw_cb(struct ql_adapter *qdev, int size, u32 bit, u16 q_id) pr_err("%s: Enter\n", __func__); ptr = kmalloc(size, GFP_ATOMIC); - if (ptr == NULL) { - pr_err("%s: Couldn't allocate a buffer\n", __func__); + if (ptr == NULL) return; - } if (ql_write_cfg(qdev, ptr, size, bit, q_id)) { pr_err("%s: Failed to upload control block!\n", __func__); diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c index c8efc708c79..91c44688bc3 100644 --- a/drivers/net/ethernet/sis/sis900.c +++ b/drivers/net/ethernet/sis/sis900.c @@ -619,7 +619,6 @@ static int __devinit sis900_mii_probe(struct net_device * net_dev) } if ((mii_phy = kmalloc(sizeof(struct mii_phy), GFP_KERNEL)) == NULL) { - printk(KERN_WARNING "Cannot allocate mem for struct mii_phy\n"); mii_phy = sis_priv->first_mii; while (mii_phy) { struct mii_phy *phy; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 96fa2da3076..ffc7581879b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -954,10 +954,9 @@ static int stmmac_open(struct net_device *dev) #ifdef CONFIG_STMMAC_TIMER priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL); - if (unlikely(priv->tm == NULL)) { - pr_err("%s: ERROR: timer memory alloc failed\n", __func__); + if (unlikely(priv->tm == NULL)) return -ENOMEM; - } + priv->tm->freq = tmrate; /* Test if the external timer can be actually used. diff --git a/drivers/net/ethernet/sun/cassini.c b/drivers/net/ethernet/sun/cassini.c index f10665f594c..46d84abe553 100644 --- a/drivers/net/ethernet/sun/cassini.c +++ b/drivers/net/ethernet/sun/cassini.c @@ -835,7 +835,6 @@ static int cas_saturn_firmware_init(struct cas *cp) cp->fw_data = vmalloc(cp->fw_size); if (!cp->fw_data) { err = -ENOMEM; - pr_err("\"%s\" Failed %d\n", fw_name, err); goto out; } memcpy(cp->fw_data, &fw->data[2], cp->fw_size); diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index 8c6c059f348..2896f6e9672 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c @@ -949,10 +949,9 @@ static int __devinit vnet_port_alloc_tx_bufs(struct vnet_port *port) int map_len = (ETH_FRAME_LEN + 7) & ~7; err = -ENOMEM; - if (!buf) { - pr_err("TX buffer allocation failure\n"); + if (!buf) goto err_out; - } + err = -EFAULT; if ((unsigned long)buf & (8UL - 1)) { pr_err("TX buffer misaligned\n"); @@ -1165,10 +1164,8 @@ static int __devinit vnet_port_probe(struct vio_dev *vdev, port = kzalloc(sizeof(*port), GFP_KERNEL); err = -ENOMEM; - if (!port) { - pr_err("Cannot allocate vnet_port\n"); + if (!port) goto err_out_put_mdesc; - } for (i = 0; i < ETH_ALEN; i++) port->raddr[i] = (*rmac >> (5 - i) * 8) & 0xff; diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c index fd4ed7f8cfa..5c14f82c495 100644 --- a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c +++ b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c @@ -1621,10 +1621,9 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl) kfree(target->hwinfo); target->hwinfo = kzalloc(be16_to_cpu(scan_info->size), GFP_KERNEL); - if (!target->hwinfo) { - pr_info("%s: kzalloc failed\n", __func__); + if (!target->hwinfo) continue; - } + /* copy hw scan info */ memcpy(target->hwinfo, scan_info, scan_info->size); target->essid_len = strnlen(scan_info->essid, diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c index 96a98d2ff15..696327773fb 100644 --- a/drivers/net/hamradio/yam.c +++ b/drivers/net/hamradio/yam.c @@ -403,7 +403,6 @@ static unsigned char *add_mcs(unsigned char *bits, int bitrate, /* Allocate a new mcs */ if ((p = kmalloc(sizeof(struct yam_mcs), GFP_KERNEL)) == NULL) { - printk(KERN_WARNING "YAM: no memory to allocate mcs\n"); release_firmware(fw); return NULL; } diff --git a/drivers/net/hippi/rrunner.c b/drivers/net/hippi/rrunner.c index e68c941926f..2a51363d9fe 100644 --- a/drivers/net/hippi/rrunner.c +++ b/drivers/net/hippi/rrunner.c @@ -1600,12 +1600,8 @@ static int rr_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } image = kmalloc(EEPROM_WORDS * sizeof(u32), GFP_KERNEL); - if (!image){ - printk(KERN_ERR "%s: Unable to allocate memory " - "for EEPROM image\n", dev->name); + if (!image) return -ENOMEM; - } - if (rrpriv->fw_running){ printk("%s: Firmware already running\n", dev->name); @@ -1637,8 +1633,6 @@ static int rr_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) image = kmalloc(EEPROM_WORDS * sizeof(u32), GFP_KERNEL); oldimage = kmalloc(EEPROM_WORDS * sizeof(u32), GFP_KERNEL); if (!image || !oldimage) { - printk(KERN_ERR "%s: Unable to allocate memory " - "for EEPROM image\n", dev->name); error = -ENOMEM; goto wf_out; } diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c index 64f403da101..617a446d126 100644 --- a/drivers/net/irda/donauboe.c +++ b/drivers/net/irda/donauboe.c @@ -1608,7 +1608,6 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid) self->ringbuf = kmalloc(OBOE_RING_LEN << 1, GFP_KERNEL); if (!self->ringbuf) { - printk (KERN_ERR DRIVER_NAME ": can't allocate DMA buffers\n"); err = -ENOMEM; goto freeregion; } @@ -1647,7 +1646,6 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid) if (!ok) { - printk (KERN_ERR DRIVER_NAME ": can't allocate rx/tx buffers\n"); err = -ENOMEM; goto freebufs; } diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index e8882023576..f9347ea3d38 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -169,10 +169,8 @@ static struct netconsole_target *alloc_param_target(char *target_config) * Note that these targets get their config_item fields zeroed-out. */ nt = kzalloc(sizeof(*nt), GFP_KERNEL); - if (!nt) { - printk(KERN_ERR "netconsole: failed to allocate memory\n"); + if (!nt) goto fail; - } nt->np.name = "netconsole"; strlcpy(nt->np.dev_name, "eth0", IFNAMSIZ); @@ -551,10 +549,8 @@ static struct config_item *make_netconsole_target(struct config_group *group, * Target is disabled at creation (enabled == 0). */ nt = kzalloc(sizeof(*nt), GFP_KERNEL); - if (!nt) { - printk(KERN_ERR "netconsole: failed to allocate memory\n"); + if (!nt) return ERR_PTR(-ENOMEM); - } nt->np.name = "netconsole"; strlcpy(nt->np.dev_name, "eth0", IFNAMSIZ); diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c index df884dde2a5..234cd9d87ed 100644 --- a/drivers/net/ppp/pptp.c +++ b/drivers/net/ppp/pptp.c @@ -670,10 +670,8 @@ static int __init pptp_init_module(void) pr_info("PPTP driver version " PPTP_DRIVER_VERSION "\n"); callid_sock = vzalloc((MAX_CALLID + 1) * sizeof(void *)); - if (!callid_sock) { - pr_err("PPTP: cann't allocate memory\n"); + if (!callid_sock) return -ENOMEM; - } err = gre_add_protocol(&gre_pptp_protocol, GREPROTO_PPTP); if (err) { diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c index ba08341fb92..69345dfae0f 100644 --- a/drivers/net/slip/slip.c +++ b/drivers/net/slip/slip.c @@ -1296,10 +1296,8 @@ static int __init slip_init(void) slip_devs = kzalloc(sizeof(struct net_device *)*slip_maxdev, GFP_KERNEL); - if (!slip_devs) { - printk(KERN_ERR "SLIP: Can't allocate slip devices array.\n"); + if (!slip_devs) return -ENOMEM; - } /* Fill in our line protocol discipline, and register it */ status = tty_register_ldisc(N_SLIP, &sl_ldisc); diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c index ef9fdf3652f..d7c292aa76b 100644 --- a/drivers/net/tokenring/3c359.c +++ b/drivers/net/tokenring/3c359.c @@ -674,15 +674,11 @@ static int xl_open(struct net_device *dev) /* These MUST be on 8 byte boundaries */ xl_priv->xl_tx_ring = kzalloc((sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE) + 7, GFP_DMA | GFP_KERNEL); if (xl_priv->xl_tx_ring == NULL) { - printk(KERN_WARNING "%s: Not enough memory to allocate tx buffers.\n", - dev->name); free_irq(dev->irq,dev); return -ENOMEM; } xl_priv->xl_rx_ring = kzalloc((sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE) +7, GFP_DMA | GFP_KERNEL); if (xl_priv->xl_rx_ring == NULL) { - printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers.\n", - dev->name); free_irq(dev->irq,dev); kfree(xl_priv->xl_tx_ring); return -ENOMEM; diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c index 6153cfd696b..1cdc034f6ae 100644 --- a/drivers/net/tokenring/madgemc.c +++ b/drivers/net/tokenring/madgemc.c @@ -171,7 +171,6 @@ static int __devinit madgemc_probe(struct device *device) card = kmalloc(sizeof(struct card_info), GFP_KERNEL); if (card==NULL) { - printk("madgemc: unable to allocate card struct\n"); ret = -ENOMEM; goto getout1; } diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index be6aa353f6a..87c0b586f11 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -537,11 +537,8 @@ vmxnet3_tq_create(struct vmxnet3_tx_queue *tq, tq->buf_info = kcalloc(tq->tx_ring.size, sizeof(tq->buf_info[0]), GFP_KERNEL); - if (!tq->buf_info) { - printk(KERN_ERR "%s: failed to allocate tx bufinfo\n", - adapter->netdev->name); + if (!tq->buf_info) goto err; - } return 0; @@ -1519,11 +1516,9 @@ vmxnet3_rq_create(struct vmxnet3_rx_queue *rq, struct vmxnet3_adapter *adapter) sz = sizeof(struct vmxnet3_rx_buf_info) * (rq->rx_ring[0].size + rq->rx_ring[1].size); bi = kzalloc(sz, GFP_KERNEL); - if (!bi) { - printk(KERN_ERR "%s: failed to allocate rx bufinfo\n", - adapter->netdev->name); + if (!bi) goto err; - } + rq->buf_info[0] = bi; rq->buf_info[1] = bi + rq->rx_ring[0].size; @@ -2964,8 +2959,6 @@ vmxnet3_probe_device(struct pci_dev *pdev, adapter->pm_conf = kmalloc(sizeof(struct Vmxnet3_PMConf), GFP_KERNEL); if (adapter->pm_conf == NULL) { - printk(KERN_ERR "Failed to allocate memory for %s\n", - pci_name(pdev)); err = -ENOMEM; goto err_alloc_pm; } @@ -2974,8 +2967,6 @@ vmxnet3_probe_device(struct pci_dev *pdev, adapter->rss_conf = kmalloc(sizeof(struct UPT1_RSSConf), GFP_KERNEL); if (adapter->rss_conf == NULL) { - printk(KERN_ERR "Failed to allocate memory for %s\n", - pci_name(pdev)); err = -ENOMEM; goto err_alloc_rss; } diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c index 54f995f4a5a..09a50751763 100644 --- a/drivers/net/wan/c101.c +++ b/drivers/net/wan/c101.c @@ -325,10 +325,8 @@ static int __init c101_run(unsigned long irq, unsigned long winbase) } card = kzalloc(sizeof(card_t), GFP_KERNEL); - if (card == NULL) { - pr_err("unable to allocate memory\n"); + if (card == NULL) return -ENOBUFS; - } card->dev = alloc_hdlcdev(card); if (!card->dev) { diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c index 058e1697c17..fe8d060d8ff 100644 --- a/drivers/net/wan/dscc4.c +++ b/drivers/net/wan/dscc4.c @@ -903,10 +903,8 @@ static int dscc4_found1(struct pci_dev *pdev, void __iomem *ioaddr) int i, ret = -ENOMEM; root = kcalloc(dev_per_card, sizeof(*root), GFP_KERNEL); - if (!root) { - pr_err("can't allocate data\n"); + if (!root) goto err_out; - } for (i = 0; i < dev_per_card; i++) { root[i].dev = alloc_hdlcdev(root + i); @@ -915,10 +913,8 @@ static int dscc4_found1(struct pci_dev *pdev, void __iomem *ioaddr) } ppriv = kzalloc(sizeof(*ppriv), GFP_KERNEL); - if (!ppriv) { - pr_err("can't allocate private data\n"); + if (!ppriv) goto err_free_dev; - } ppriv->root = root; spin_lock_init(&ppriv->lock); diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c index b7f2358d23b..76a8a4a522e 100644 --- a/drivers/net/wan/lmc/lmc_main.c +++ b/drivers/net/wan/lmc/lmc_main.c @@ -497,7 +497,6 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ data = kmalloc(xc.len, GFP_KERNEL); if (!data) { - printk(KERN_WARNING "%s: Failed to allocate memory for copy\n", dev->name); ret = -ENOMEM; break; } diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c index 5129ad514d2..315bf09d6a2 100644 --- a/drivers/net/wan/n2.c +++ b/drivers/net/wan/n2.c @@ -358,10 +358,8 @@ static int __init n2_run(unsigned long io, unsigned long irq, } card = kzalloc(sizeof(card_t), GFP_KERNEL); - if (card == NULL) { - pr_err("unable to allocate memory\n"); + if (card == NULL) return -ENOBUFS; - } card->ports[0].dev = alloc_hdlcdev(&card->ports[0]); card->ports[1].dev = alloc_hdlcdev(&card->ports[1]); diff --git a/drivers/net/wan/pc300too.c b/drivers/net/wan/pc300too.c index c49c1b3c7aa..5fe246e060d 100644 --- a/drivers/net/wan/pc300too.c +++ b/drivers/net/wan/pc300too.c @@ -320,7 +320,6 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev, card = kzalloc(sizeof(card_t), GFP_KERNEL); if (card == NULL) { - pr_err("unable to allocate memory\n"); pci_release_regions(pdev); pci_disable_device(pdev); return -ENOBUFS; diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c index 1ce21163c77..9659fcaa34e 100644 --- a/drivers/net/wan/pci200syn.c +++ b/drivers/net/wan/pci200syn.c @@ -299,7 +299,6 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev, card = kzalloc(sizeof(card_t), GFP_KERNEL); if (card == NULL) { - pr_err("unable to allocate memory\n"); pci_release_regions(pdev); pci_disable_device(pdev); return -ENOBUFS; diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c index 44b70719725..feb7541b33f 100644 --- a/drivers/net/wan/wanxl.c +++ b/drivers/net/wan/wanxl.c @@ -604,7 +604,6 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, alloc_size = sizeof(card_t) + ports * sizeof(port_t); card = kzalloc(alloc_size, GFP_KERNEL); if (card == NULL) { - pr_err("%s: unable to allocate memory\n", pci_name(pdev)); pci_release_regions(pdev); pci_disable_device(pdev); return -ENOBUFS; diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index 8a10bb730d5..e862369b4a6 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c @@ -786,10 +786,8 @@ static int __init init_x25_asy(void) x25_asy_devs = kcalloc(x25_asy_maxdev, sizeof(struct net_device *), GFP_KERNEL); - if (!x25_asy_devs) { - pr_warn("Can't allocate x25_asy_ctrls[] array! Uaargh! (-> No X.25 available)\n"); + if (!x25_asy_devs) return -ENOMEM; - } return tty_register_ldisc(N_X25, &x25_ldisc); } diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index 1b90ed8795c..c25226a32dd 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -431,11 +431,8 @@ struct htc_target *ath9k_htc_hw_alloc(void *hif_handle, struct htc_target *target; target = kzalloc(sizeof(struct htc_target), GFP_KERNEL); - if (!target) { - printk(KERN_ERR "Unable to allocate memory for" - "target device\n"); + if (!target) return NULL; - } init_completion(&target->target_wait); init_completion(&target->cmd_wait); diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index a8bddd81b4d..aa15cc4269a 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c @@ -347,11 +347,9 @@ static int hfa384x_cmd(struct net_device *dev, u16 cmd, u16 param0, return -EINTR; entry = kzalloc(sizeof(*entry), GFP_ATOMIC); - if (entry == NULL) { - printk(KERN_DEBUG "%s: hfa384x_cmd - kmalloc failed\n", - dev->name); + if (entry == NULL) return -ENOMEM; - } + atomic_set(&entry->usecnt, 1); entry->type = CMD_SLEEP; entry->cmd = cmd; @@ -515,11 +513,9 @@ static int hfa384x_cmd_callback(struct net_device *dev, u16 cmd, u16 param0, } entry = kzalloc(sizeof(*entry), GFP_ATOMIC); - if (entry == NULL) { - printk(KERN_DEBUG "%s: hfa384x_cmd_callback - kmalloc " - "failed\n", dev->name); + if (entry == NULL) return -ENOMEM; - } + atomic_set(&entry->usecnt, 1); entry->type = CMD_CALLBACK; entry->cmd = cmd; @@ -2978,11 +2974,9 @@ static int prism2_set_tim(struct net_device *dev, int aid, int set) local = iface->local; new_entry = kzalloc(sizeof(*new_entry), GFP_ATOMIC); - if (new_entry == NULL) { - printk(KERN_DEBUG "%s: prism2_set_tim: kmalloc failed\n", - local->dev->name); + if (new_entry == NULL) return -ENOMEM; - } + new_entry->aid = aid; new_entry->set = set; diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index a0e5c21d365..e847737ccc9 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c @@ -3464,11 +3464,8 @@ static int ipw2100_msg_allocate(struct ipw2100_priv *priv) priv->msg_buffers = kmalloc(IPW_COMMAND_POOL_SIZE * sizeof(struct ipw2100_tx_packet), GFP_KERNEL); - if (!priv->msg_buffers) { - printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for msg " - "buffers.\n", priv->net_dev->name); + if (!priv->msg_buffers) return -ENOMEM; - } for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++) { v = pci_alloc_consistent(priv->pci_dev, diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index 3f7bf4d912b..234ee88dec9 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c @@ -815,10 +815,9 @@ static int if_cs_probe(struct pcmcia_device *p_dev) lbs_deb_enter(LBS_DEB_CS); card = kzalloc(sizeof(struct if_cs_card), GFP_KERNEL); - if (!card) { - pr_err("error in kzalloc\n"); + if (!card) goto out; - } + card->p_dev = p_dev; p_dev->priv = card; diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index b5fbbc7947d..74da5f1ea24 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c @@ -261,10 +261,8 @@ static int if_usb_probe(struct usb_interface *intf, udev = interface_to_usbdev(intf); cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL); - if (!cardp) { - pr_err("Out of memory allocating private data\n"); + if (!cardp) goto error; - } setup_timer(&cardp->fw_timeout, if_usb_fw_timeo, (unsigned long)cardp); init_waitqueue_head(&cardp->fw_wq); diff --git a/drivers/net/wireless/libertas_tf/if_usb.c b/drivers/net/wireless/libertas_tf/if_usb.c index aff8b5743af..7ced130f4f9 100644 --- a/drivers/net/wireless/libertas_tf/if_usb.c +++ b/drivers/net/wireless/libertas_tf/if_usb.c @@ -153,10 +153,8 @@ static int if_usb_probe(struct usb_interface *intf, udev = interface_to_usbdev(intf); cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL); - if (!cardp) { - pr_err("Out of memory allocating private data.\n"); + if (!cardp) goto error; - } setup_timer(&cardp->fw_timeout, if_usb_fw_timeo, (unsigned long)cardp); init_waitqueue_head(&cardp->fw_wq); diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 405350940a4..f4fbad95d3e 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c @@ -86,10 +86,8 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev, pdev->vendor, pdev->device, pdev->revision); card = kzalloc(sizeof(struct pcie_service_card), GFP_KERNEL); - if (!card) { - pr_err("%s: failed to alloc memory\n", __func__); + if (!card) return -ENOMEM; - } card->dev = pdev; diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index d39d8457f25..83590275023 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c @@ -70,10 +70,8 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) func->vendor, func->device, func->class, func->num); card = kzalloc(sizeof(struct sdio_mmc_card), GFP_KERNEL); - if (!card) { - pr_err("%s: failed to alloc memory\n", __func__); + if (!card) return -ENOMEM; - } card->func = func; diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c index 9fb77d0319f..dd6c64ac406 100644 --- a/drivers/net/wireless/orinoco/main.c +++ b/drivers/net/wireless/orinoco/main.c @@ -941,11 +941,9 @@ void __orinoco_ev_rx(struct net_device *dev, struct hermes *hw) /* Add desc and skb to rx queue */ rx_data = kzalloc(sizeof(*rx_data), GFP_ATOMIC); - if (!rx_data) { - printk(KERN_WARNING "%s: Can't allocate RX packet\n", - dev->name); + if (!rx_data) goto drop; - } + rx_data->desc = desc; rx_data->skb = skb; list_add_tail(&rx_data->list, &priv->rx_list); diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c index a5224f6160e..851fa10241e 100644 --- a/drivers/net/wireless/prism54/islpci_mgt.c +++ b/drivers/net/wireless/prism54/islpci_mgt.c @@ -192,11 +192,9 @@ islpci_mgt_transmit(struct net_device *ndev, int operation, unsigned long oid, err = -ENOMEM; p = buf.mem = kmalloc(frag_len, GFP_KERNEL); - if (!buf.mem) { - printk(KERN_DEBUG "%s: cannot allocate mgmt frame\n", - ndev->name); + if (!buf.mem) goto error; - } + buf.size = frag_len; /* create the header directly in the fragment data area */ diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c index 78723cf5949..36140ccf2ab 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c @@ -186,11 +186,8 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) /* for firmware buf */ rtlpriv->rtlhal.pfirmware = vzalloc(sizeof(struct rt_firmware)); - if (!rtlpriv->rtlhal.pfirmware) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't alloc buffer for fw.\n")); + if (!rtlpriv->rtlhal.pfirmware) return 1; - } pr_info("Driver for Realtek RTL8192SE/RTL8191SE\n" "Loading firmware %s\n", rtlpriv->cfg->fw_name); diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 59effac15f3..2596401308a 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -1639,10 +1639,8 @@ static int __init netback_init(void) xen_netbk_group_nr = num_online_cpus(); xen_netbk = vzalloc(sizeof(struct xen_netbk) * xen_netbk_group_nr); - if (!xen_netbk) { - printk(KERN_ALERT "%s: out of memory\n", __func__); + if (!xen_netbk) return -ENOMEM; - } for (group = 0; group < xen_netbk_group_nr; group++) { struct xen_netbk *netbk = &xen_netbk[group]; -- cgit v1.2.3-70-g09d2 From 41de8d4cff21a2e81e3d9ff66f5f7c903f9c3ab1 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 29 Jan 2012 13:47:52 +0000 Subject: drivers/net: Remove alloc_etherdev error messages alloc_etherdev has a generic OOM/unable to alloc message. Remove the duplicative messages after alloc_etherdev calls. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/ethernet/3com/3c59x.c | 5 ++--- drivers/net/ethernet/adaptec/starfire.c | 5 ++--- drivers/net/ethernet/adi/bfin_mac.c | 4 +--- drivers/net/ethernet/alteon/acenic.c | 5 +---- drivers/net/ethernet/amd/amd8111e.c | 1 - drivers/net/ethernet/amd/au1000_eth.c | 1 - drivers/net/ethernet/amd/declance.c | 2 -- drivers/net/ethernet/amd/pcnet32.c | 2 -- drivers/net/ethernet/apple/bmac.c | 4 +--- drivers/net/ethernet/apple/mace.c | 1 - drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 1 - drivers/net/ethernet/atheros/atl1e/atl1e_main.c | 1 - drivers/net/ethernet/broadcom/b44.c | 1 - drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 4 +--- drivers/net/ethernet/broadcom/sb1250-mac.c | 2 -- drivers/net/ethernet/broadcom/tg3.c | 1 - drivers/net/ethernet/brocade/bna/bnad.c | 1 - drivers/net/ethernet/cadence/macb.c | 4 +--- drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | 2 -- drivers/net/ethernet/cisco/enic/enic_main.c | 4 +--- drivers/net/ethernet/davicom/dm9000.c | 4 +--- drivers/net/ethernet/dec/tulip/tulip_core.c | 4 +--- drivers/net/ethernet/dec/tulip/xircom_cb.c | 5 ++--- drivers/net/ethernet/dnet.c | 4 +--- drivers/net/ethernet/ethoc.c | 1 - drivers/net/ethernet/hp/hp100.c | 1 - drivers/net/ethernet/ibm/ehea/ehea_main.c | 1 - drivers/net/ethernet/ibm/emac/core.c | 6 ++---- drivers/net/ethernet/ibm/iseries_veth.c | 4 +--- drivers/net/ethernet/icplus/ipg.c | 1 - drivers/net/ethernet/intel/e100.c | 5 +---- drivers/net/ethernet/jme.c | 1 - drivers/net/ethernet/korina.c | 5 ++--- drivers/net/ethernet/lantiq_etop.c | 4 ++++ drivers/net/ethernet/marvell/skge.c | 4 +--- drivers/net/ethernet/marvell/sky2.c | 4 +--- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 4 +--- drivers/net/ethernet/micrel/ks8695net.c | 4 +--- drivers/net/ethernet/micrel/ks8851.c | 4 +--- drivers/net/ethernet/microchip/enc28j60.c | 3 --- drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 4 +--- drivers/net/ethernet/neterion/s2io.c | 1 - drivers/net/ethernet/netx-eth.c | 1 - drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c | 2 -- drivers/net/ethernet/packetengines/yellowfin.c | 5 ++--- drivers/net/ethernet/pasemi/pasemi_mac.c | 2 -- drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c | 1 - drivers/net/ethernet/qlogic/qla3xxx.c | 1 - drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 1 - drivers/net/ethernet/rdc/r6040.c | 1 - drivers/net/ethernet/realtek/8139too.c | 5 ++--- drivers/net/ethernet/realtek/r8169.c | 2 -- drivers/net/ethernet/renesas/sh_eth.c | 1 - drivers/net/ethernet/s6gmac.c | 6 +++--- drivers/net/ethernet/seeq/sgiseeq.c | 1 - drivers/net/ethernet/sis/sis190.c | 2 -- drivers/net/ethernet/smsc/epic100.c | 5 ++--- drivers/net/ethernet/smsc/smc911x.c | 1 - drivers/net/ethernet/smsc/smc91x.c | 1 - drivers/net/ethernet/smsc/smsc911x.c | 1 - drivers/net/ethernet/smsc/smsc9420.c | 4 +--- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 +--- drivers/net/ethernet/sun/cassini.c | 1 - drivers/net/ethernet/sun/niu.c | 4 +--- drivers/net/ethernet/sun/sungem.c | 1 - drivers/net/ethernet/sun/sunvnet.c | 4 +--- drivers/net/ethernet/tehuti/tehuti.c | 1 - drivers/net/ethernet/ti/cpmac.c | 5 +---- drivers/net/ethernet/ti/davinci_emac.c | 1 - drivers/net/ethernet/ti/tlan.c | 1 - drivers/net/ethernet/toshiba/tc35815.c | 5 ++--- drivers/net/ethernet/tundra/tsi108_eth.c | 4 +--- drivers/net/ethernet/via/via-rhine.c | 1 - drivers/net/ethernet/via/via-velocity.c | 4 +--- drivers/net/ethernet/xilinx/ll_temac_main.c | 5 ++--- drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 4 +--- drivers/net/ethernet/xilinx/xilinx_emaclite.c | 4 +--- drivers/net/plip/plip.c | 4 +--- drivers/net/rionet.c | 2 -- drivers/net/usb/pegasus.c | 4 +--- drivers/net/usb/rtl8150.c | 4 +--- drivers/net/usb/usbnet.c | 4 +--- drivers/net/vmxnet3/vmxnet3_drv.c | 5 +---- drivers/net/wireless/atmel.c | 5 ++--- drivers/net/wireless/ipw2x00/libipw_module.c | 5 ++--- drivers/net/xen-netfront.c | 5 +---- 86 files changed, 63 insertions(+), 192 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c index 8153a3e0a1a..dc51d9218e6 100644 --- a/drivers/net/ethernet/3com/3c59x.c +++ b/drivers/net/ethernet/3com/3c59x.c @@ -1121,10 +1121,9 @@ static int __devinit vortex_probe1(struct device *gendev, dev = alloc_etherdev(sizeof(*vp)); retval = -ENOMEM; - if (!dev) { - pr_err(PFX "unable to allocate etherdev, aborting\n"); + if (!dev) goto out; - } + SET_NETDEV_DEV(dev, gendev); vp = netdev_priv(dev); diff --git a/drivers/net/ethernet/adaptec/starfire.c b/drivers/net/ethernet/adaptec/starfire.c index cb4f38a17f2..11fc2eccb0f 100644 --- a/drivers/net/ethernet/adaptec/starfire.c +++ b/drivers/net/ethernet/adaptec/starfire.c @@ -686,10 +686,9 @@ static int __devinit starfire_init_one(struct pci_dev *pdev, } dev = alloc_etherdev(sizeof(*np)); - if (!dev) { - printk(KERN_ERR DRV_NAME " %d: cannot alloc etherdev, aborting\n", card_idx); + if (!dev) return -ENOMEM; - } + SET_NETDEV_DEV(dev, &pdev->dev); irq = pdev->irq; diff --git a/drivers/net/ethernet/adi/bfin_mac.c b/drivers/net/ethernet/adi/bfin_mac.c index d812a103e03..525a9768bb5 100644 --- a/drivers/net/ethernet/adi/bfin_mac.c +++ b/drivers/net/ethernet/adi/bfin_mac.c @@ -1467,10 +1467,8 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev) int rc; ndev = alloc_etherdev(sizeof(struct bfin_mac_local)); - if (!ndev) { - dev_err(&pdev->dev, "Cannot allocate net device!\n"); + if (!ndev) return -ENOMEM; - } SET_NETDEV_DEV(ndev, &pdev->dev); platform_set_drvdata(pdev, ndev); diff --git a/drivers/net/ethernet/alteon/acenic.c b/drivers/net/ethernet/alteon/acenic.c index f872748ab4e..6c3b1c0adaa 100644 --- a/drivers/net/ethernet/alteon/acenic.c +++ b/drivers/net/ethernet/alteon/acenic.c @@ -463,11 +463,8 @@ static int __devinit acenic_probe_one(struct pci_dev *pdev, static int boards_found; dev = alloc_etherdev(sizeof(struct ace_private)); - if (dev == NULL) { - printk(KERN_ERR "acenic: Unable to allocate " - "net_device structure!\n"); + if (dev == NULL) return -ENOMEM; - } SET_NETDEV_DEV(dev, &pdev->dev); diff --git a/drivers/net/ethernet/amd/amd8111e.c b/drivers/net/ethernet/amd/amd8111e.c index 33e0a8c20f6..b8306a58955 100644 --- a/drivers/net/ethernet/amd/amd8111e.c +++ b/drivers/net/ethernet/amd/amd8111e.c @@ -1859,7 +1859,6 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev, dev = alloc_etherdev(sizeof(struct amd8111e_priv)); if (!dev) { - printk(KERN_ERR "amd8111e: Etherdev alloc failed, exiting.\n"); err = -ENOMEM; goto err_free_reg; } diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c index 8b95dd31425..a81c871aeac 100644 --- a/drivers/net/ethernet/amd/au1000_eth.c +++ b/drivers/net/ethernet/amd/au1000_eth.c @@ -1077,7 +1077,6 @@ static int __devinit au1000_probe(struct platform_device *pdev) dev = alloc_etherdev(sizeof(struct au1000_private)); if (!dev) { - dev_err(&pdev->dev, "alloc_etherdev failed\n"); err = -ENOMEM; goto err_alloc; } diff --git a/drivers/net/ethernet/amd/declance.c b/drivers/net/ethernet/amd/declance.c index 73f8d4fa682..dd82ee2f8d2 100644 --- a/drivers/net/ethernet/amd/declance.c +++ b/drivers/net/ethernet/amd/declance.c @@ -1052,8 +1052,6 @@ static int __devinit dec_lance_probe(struct device *bdev, const int type) dev = alloc_etherdev(sizeof(struct lance_private)); if (!dev) { - printk(KERN_ERR "%s: Unable to allocate etherdev, aborting.\n", - name); ret = -ENOMEM; goto err_out; } diff --git a/drivers/net/ethernet/amd/pcnet32.c b/drivers/net/ethernet/amd/pcnet32.c index 20e6dab0186..1bb388f62e5 100644 --- a/drivers/net/ethernet/amd/pcnet32.c +++ b/drivers/net/ethernet/amd/pcnet32.c @@ -1649,8 +1649,6 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) dev = alloc_etherdev(sizeof(*lp)); if (!dev) { - if (pcnet32_debug & NETIF_MSG_PROBE) - pr_err("Memory allocation failed\n"); ret = -ENOMEM; goto err_release_region; } diff --git a/drivers/net/ethernet/apple/bmac.c b/drivers/net/ethernet/apple/bmac.c index 4108ac800cf..ebc0dba5ba3 100644 --- a/drivers/net/ethernet/apple/bmac.c +++ b/drivers/net/ethernet/apple/bmac.c @@ -1269,10 +1269,8 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i memcpy(addr, prop_addr, sizeof(addr)); dev = alloc_etherdev(PRIV_BYTES); - if (!dev) { - printk(KERN_ERR "BMAC: alloc_etherdev failed, out of memory\n"); + if (!dev) return -ENOMEM; - } bp = netdev_priv(dev); SET_NETDEV_DEV(dev, &mdev->ofdev.dev); diff --git a/drivers/net/ethernet/apple/mace.c b/drivers/net/ethernet/apple/mace.c index 45ba18ee3d6..bd5555dbe02 100644 --- a/drivers/net/ethernet/apple/mace.c +++ b/drivers/net/ethernet/apple/mace.c @@ -147,7 +147,6 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i dev = alloc_etherdev(PRIV_BYTES); if (!dev) { - printk(KERN_ERR "MACE: can't allocate ethernet device !\n"); rc = -ENOMEM; goto err_release; } diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c index b8591246eb4..7ee4aacb01a 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c @@ -2689,7 +2689,6 @@ static int __devinit atl1c_probe(struct pci_dev *pdev, netdev = alloc_etherdev(sizeof(struct atl1c_adapter)); if (netdev == NULL) { err = -ENOMEM; - dev_err(&pdev->dev, "etherdev alloc failed\n"); goto err_alloc_etherdev; } diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c index c915c087381..93ff2b23128 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c @@ -2300,7 +2300,6 @@ static int __devinit atl1e_probe(struct pci_dev *pdev, netdev = alloc_etherdev(sizeof(struct atl1e_adapter)); if (netdev == NULL) { err = -ENOMEM; - dev_err(&pdev->dev, "etherdev alloc failed\n"); goto err_alloc_etherdev; } diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c index 3fb66d09ece..66f53c797e3 100644 --- a/drivers/net/ethernet/broadcom/b44.c +++ b/drivers/net/ethernet/broadcom/b44.c @@ -2138,7 +2138,6 @@ static int __devinit b44_init_one(struct ssb_device *sdev, dev = alloc_etherdev(sizeof(*bp)); if (!dev) { - dev_err(sdev->dev, "Etherdev alloc failed, aborting\n"); err = -ENOMEM; goto out; } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 582cbcf5f9f..ff19c3cf440 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -11133,10 +11133,8 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, /* dev zeroed in init_etherdev */ dev = alloc_etherdev_mqs(sizeof(*bp), tx_count, rx_count); - if (!dev) { - dev_err(&pdev->dev, "Cannot allocate net device\n"); + if (!dev) return -ENOMEM; - } bp = netdev_priv(dev); diff --git a/drivers/net/ethernet/broadcom/sb1250-mac.c b/drivers/net/ethernet/broadcom/sb1250-mac.c index 084904ceaa3..49e7a258da8 100644 --- a/drivers/net/ethernet/broadcom/sb1250-mac.c +++ b/drivers/net/ethernet/broadcom/sb1250-mac.c @@ -2623,8 +2623,6 @@ static int __devinit sbmac_probe(struct platform_device *pldev) */ dev = alloc_etherdev(sizeof(struct sbmac_softc)); if (!dev) { - printk(KERN_ERR "%s: unable to allocate etherdev\n", - dev_name(&pldev->dev)); err = -ENOMEM; goto out_unmap; } diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index a1f2e0fed78..3bf3adca369 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -15471,7 +15471,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, dev = alloc_etherdev_mq(sizeof(*tp), TG3_IRQ_MAX_VECS); if (!dev) { - dev_err(&pdev->dev, "Etherdev alloc failed, aborting\n"); err = -ENOMEM; goto err_out_power_down; } diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c index be7d91e4b78..ff78f770dec 100644 --- a/drivers/net/ethernet/brocade/bna/bnad.c +++ b/drivers/net/ethernet/brocade/bna/bnad.c @@ -3284,7 +3284,6 @@ bnad_pci_probe(struct pci_dev *pdev, */ netdev = alloc_etherdev(sizeof(struct bnad)); if (!netdev) { - dev_err(&pdev->dev, "netdev allocation failed\n"); err = -ENOMEM; return err; } diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index 23200680d4c..3c315f46859 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -1308,10 +1308,8 @@ static int __init macb_probe(struct platform_device *pdev) err = -ENOMEM; dev = alloc_etherdev(sizeof(*bp)); - if (!dev) { - dev_err(&pdev->dev, "etherdev alloc failed, aborting.\n"); + if (!dev) goto err_out; - } SET_NETDEV_DEV(dev, &pdev->dev); diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index e53365a7148..9045a451d4a 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -2596,8 +2596,6 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, netdev = alloc_etherdev_mq(sizeof(struct port_info), MAX_PORT_QSETS); if (netdev == NULL) { - dev_err(&pdev->dev, "cannot allocate netdev for" - " port %d\n", port_id); t4vf_free_vi(adapter, viid); err = -ENOMEM; goto err_free_dev; diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index 07df13745c4..2838891a94e 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c @@ -2280,10 +2280,8 @@ static int __devinit enic_probe(struct pci_dev *pdev, */ netdev = alloc_etherdev(sizeof(struct enic)); - if (!netdev) { - pr_err("Etherdev alloc failed, aborting\n"); + if (!netdev) return -ENOMEM; - } pci_set_drvdata(pdev, netdev); diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c index f801754c71a..493cc620208 100644 --- a/drivers/net/ethernet/davicom/dm9000.c +++ b/drivers/net/ethernet/davicom/dm9000.c @@ -1373,10 +1373,8 @@ dm9000_probe(struct platform_device *pdev) /* Init network device */ ndev = alloc_etherdev(sizeof(struct board_info)); - if (!ndev) { - dev_err(&pdev->dev, "could not allocate device.\n"); + if (!ndev) return -ENOMEM; - } SET_NETDEV_DEV(ndev, &pdev->dev); diff --git a/drivers/net/ethernet/dec/tulip/tulip_core.c b/drivers/net/ethernet/dec/tulip/tulip_core.c index 4eb0d76145c..17ecb18341c 100644 --- a/drivers/net/ethernet/dec/tulip/tulip_core.c +++ b/drivers/net/ethernet/dec/tulip/tulip_core.c @@ -1424,10 +1424,8 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, /* alloc_etherdev ensures aligned and zeroed private structures */ dev = alloc_etherdev (sizeof (*tp)); - if (!dev) { - pr_err("ether device alloc failed, aborting\n"); + if (!dev) return -ENOMEM; - } SET_NETDEV_DEV(dev, &pdev->dev); if (pci_resource_len (pdev, 0) < tulip_tbl[chip_idx].io_size) { diff --git a/drivers/net/ethernet/dec/tulip/xircom_cb.c b/drivers/net/ethernet/dec/tulip/xircom_cb.c index 988b8eb24d3..b7c73eefb54 100644 --- a/drivers/net/ethernet/dec/tulip/xircom_cb.c +++ b/drivers/net/ethernet/dec/tulip/xircom_cb.c @@ -222,10 +222,9 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_ is available. */ dev = alloc_etherdev(sizeof(struct xircom_private)); - if (!dev) { - pr_err("%s: failed to allocate etherdev\n", __func__); + if (!dev) goto device_fail; - } + private = netdev_priv(dev); /* Allocate the send/receive buffers */ diff --git a/drivers/net/ethernet/dnet.c b/drivers/net/ethernet/dnet.c index 925c9bafc9b..fe48cb7dde2 100644 --- a/drivers/net/ethernet/dnet.c +++ b/drivers/net/ethernet/dnet.c @@ -854,10 +854,8 @@ static int __devinit dnet_probe(struct platform_device *pdev) err = -ENOMEM; dev = alloc_etherdev(sizeof(*bp)); - if (!dev) { - dev_err(&pdev->dev, "etherdev alloc failed, aborting.\n"); + if (!dev) goto err_out_release_mem; - } /* TODO: Actually, we have some interesting features... */ dev->features |= 0; diff --git a/drivers/net/ethernet/ethoc.c b/drivers/net/ethernet/ethoc.c index 388c592b5ef..0b723ff2294 100644 --- a/drivers/net/ethernet/ethoc.c +++ b/drivers/net/ethernet/ethoc.c @@ -913,7 +913,6 @@ static int __devinit ethoc_probe(struct platform_device *pdev) /* allocate networking device */ netdev = alloc_etherdev(sizeof(struct ethoc)); if (!netdev) { - dev_err(&pdev->dev, "cannot allocate network device\n"); ret = -ENOMEM; goto out; } diff --git a/drivers/net/ethernet/hp/hp100.c b/drivers/net/ethernet/hp/hp100.c index 6a5ee0776b2..3598c5408e7 100644 --- a/drivers/net/ethernet/hp/hp100.c +++ b/drivers/net/ethernet/hp/hp100.c @@ -2992,7 +2992,6 @@ static int __init hp100_isa_init(void) for (i = 0; i < HP100_DEVICES && hp100_port[i] != -1; ++i) { dev = alloc_etherdev(sizeof(struct hp100_private)); if (!dev) { - printk(KERN_WARNING "hp100: no memory for network device\n"); while (cards > 0) cleanup_dev(hp100_devlist[--cards]); diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c index 14507d1e78c..8b73dd47247 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_main.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c @@ -2980,7 +2980,6 @@ static struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, dev = alloc_etherdev_mq(sizeof(struct ehea_port), EHEA_MAX_PORT_RES); if (!dev) { - pr_err("no mem for net_device\n"); ret = -ENOMEM; goto out_err; } diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c index d47c16e02d0..dac7ffb4eaf 100644 --- a/drivers/net/ethernet/ibm/emac/core.c +++ b/drivers/net/ethernet/ibm/emac/core.c @@ -2706,11 +2706,9 @@ static int __devinit emac_probe(struct platform_device *ofdev) /* Allocate our net_device structure */ err = -ENOMEM; ndev = alloc_etherdev(sizeof(struct emac_instance)); - if (!ndev) { - printk(KERN_ERR "%s: could not allocate ethernet device!\n", - np->full_name); + if (!ndev) goto err_gone; - } + dev = netdev_priv(ndev); dev->ndev = ndev; dev->ofdev = ofdev; diff --git a/drivers/net/ethernet/ibm/iseries_veth.c b/drivers/net/ethernet/ibm/iseries_veth.c index acc31af6594..1cafa6562a0 100644 --- a/drivers/net/ethernet/ibm/iseries_veth.c +++ b/drivers/net/ethernet/ibm/iseries_veth.c @@ -1032,10 +1032,8 @@ static struct net_device *veth_probe_one(int vlan, } dev = alloc_etherdev(sizeof (struct veth_port)); - if (! dev) { - veth_error("Unable to allocate net_device structure!\n"); + if (!dev) return NULL; - } port = netdev_priv(dev); diff --git a/drivers/net/ethernet/icplus/ipg.c b/drivers/net/ethernet/icplus/ipg.c index 075451d0207..3c636f16a3c 100644 --- a/drivers/net/ethernet/icplus/ipg.c +++ b/drivers/net/ethernet/icplus/ipg.c @@ -2233,7 +2233,6 @@ static int __devinit ipg_probe(struct pci_dev *pdev, */ dev = alloc_etherdev(sizeof(struct ipg_nic_private)); if (!dev) { - pr_err("%s: alloc_etherdev failed\n", pci_name(pdev)); rc = -ENOMEM; goto err_disable_0; } diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c index 9436397e572..485ab8cdac4 100644 --- a/drivers/net/ethernet/intel/e100.c +++ b/drivers/net/ethernet/intel/e100.c @@ -2751,11 +2751,8 @@ static int __devinit e100_probe(struct pci_dev *pdev, struct nic *nic; int err; - if (!(netdev = alloc_etherdev(sizeof(struct nic)))) { - if (((1 << debug) - 1) & NETIF_MSG_PROBE) - pr_err("Etherdev alloc failed, aborting\n"); + if (!(netdev = alloc_etherdev(sizeof(struct nic)))) return -ENOMEM; - } netdev->netdev_ops = &e100_netdev_ops; SET_ETHTOOL_OPS(netdev, &e100_ethtool_ops); diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c index 27d651a80f3..1b86d0b45f3 100644 --- a/drivers/net/ethernet/jme.c +++ b/drivers/net/ethernet/jme.c @@ -2999,7 +2999,6 @@ jme_init_one(struct pci_dev *pdev, */ netdev = alloc_etherdev(sizeof(*jme)); if (!netdev) { - pr_err("Cannot allocate netdev structure\n"); rc = -ENOMEM; goto err_out_release_regions; } diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c index 341d10130dc..f30db1c4660 100644 --- a/drivers/net/ethernet/korina.c +++ b/drivers/net/ethernet/korina.c @@ -1108,10 +1108,9 @@ static int korina_probe(struct platform_device *pdev) int rc; dev = alloc_etherdev(sizeof(struct korina_private)); - if (!dev) { - printk(KERN_ERR DRV_NAME ": alloc_etherdev failed\n"); + if (!dev) return -ENOMEM; - } + SET_NETDEV_DEV(dev, &pdev->dev); lp = netdev_priv(dev); diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c index 85e2c6cd970..86d2fe6e053 100644 --- a/drivers/net/ethernet/lantiq_etop.c +++ b/drivers/net/ethernet/lantiq_etop.c @@ -731,6 +731,10 @@ ltq_etop_probe(struct platform_device *pdev) } dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4); + if (!dev) { + err = -ENOMEM; + goto err_out; + } strcpy(dev->name, "eth%d"); dev->netdev_ops = <q_eth_netdev_ops; dev->ethtool_ops = <q_etop_ethtool_ops; diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c index edb9bda55d5..1d61eaac858 100644 --- a/drivers/net/ethernet/marvell/skge.c +++ b/drivers/net/ethernet/marvell/skge.c @@ -3852,10 +3852,8 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, struct skge_port *skge; struct net_device *dev = alloc_etherdev(sizeof(*skge)); - if (!dev) { - dev_err(&hw->pdev->dev, "etherdev alloc failed\n"); + if (!dev) return NULL; - } SET_NETDEV_DEV(dev, &hw->pdev->dev); dev->netdev_ops = &skge_netdev_ops; diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c index 760c2b17dfd..82c2c86a195 100644 --- a/drivers/net/ethernet/marvell/sky2.c +++ b/drivers/net/ethernet/marvell/sky2.c @@ -4700,10 +4700,8 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, struct sky2_port *sky2; struct net_device *dev = alloc_etherdev(sizeof(*sky2)); - if (!dev) { - dev_err(&hw->pdev->dev, "etherdev alloc failed\n"); + if (!dev) return NULL; - } SET_NETDEV_DEV(dev, &hw->pdev->dev); dev->irq = hw->pdev->irq; diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 467ae582487..25e6480479d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -1047,10 +1047,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, dev = alloc_etherdev_mqs(sizeof(struct mlx4_en_priv), prof->tx_ring_num, prof->rx_ring_num); - if (dev == NULL) { - mlx4_err(mdev, "Net device allocation failed\n"); + if (dev == NULL) return -ENOMEM; - } SET_NETDEV_DEV(dev, &mdev->dev->pdev->dev); dev->dev_id = port - 1; diff --git a/drivers/net/ethernet/micrel/ks8695net.c b/drivers/net/ethernet/micrel/ks8695net.c index ab81c0dc96e..7c717276502 100644 --- a/drivers/net/ethernet/micrel/ks8695net.c +++ b/drivers/net/ethernet/micrel/ks8695net.c @@ -1362,10 +1362,8 @@ ks8695_probe(struct platform_device *pdev) /* Initialise a net_device */ ndev = alloc_etherdev(sizeof(struct ks8695_priv)); - if (!ndev) { - dev_err(&pdev->dev, "could not allocate device.\n"); + if (!ndev) return -ENOMEM; - } SET_NETDEV_DEV(ndev, &pdev->dev); diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index 134c4d07936..4b551feae4c 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -1419,10 +1419,8 @@ static int __devinit ks8851_probe(struct spi_device *spi) int ret; ndev = alloc_etherdev(sizeof(struct ks8851_net)); - if (!ndev) { - dev_err(&spi->dev, "failed to alloc ethernet device\n"); + if (!ndev) return -ENOMEM; - } spi->bits_per_word = 8; diff --git a/drivers/net/ethernet/microchip/enc28j60.c b/drivers/net/ethernet/microchip/enc28j60.c index 50055e0282e..c813e5d8db9 100644 --- a/drivers/net/ethernet/microchip/enc28j60.c +++ b/drivers/net/ethernet/microchip/enc28j60.c @@ -1553,9 +1553,6 @@ static int __devinit enc28j60_probe(struct spi_device *spi) dev = alloc_etherdev(sizeof(struct enc28j60_net)); if (!dev) { - if (netif_msg_drv(&debug)) - dev_err(&spi->dev, DRV_NAME - ": unable to alloc new ethernet\n"); ret = -ENOMEM; goto error_alloc; } diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c index 20b72ecb020..27273ae1a6e 100644 --- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c @@ -3910,10 +3910,8 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) static int board_number; netdev = alloc_etherdev_mq(sizeof(*mgp), MYRI10GE_MAX_SLICES); - if (netdev == NULL) { - dev_err(dev, "Could not allocate ethernet device\n"); + if (netdev == NULL) return -ENOMEM; - } SET_NETDEV_DEV(netdev, &pdev->dev); diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c index 97f63e12d86..13858460880 100644 --- a/drivers/net/ethernet/neterion/s2io.c +++ b/drivers/net/ethernet/neterion/s2io.c @@ -7760,7 +7760,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) else dev = alloc_etherdev(sizeof(struct s2io_nic)); if (dev == NULL) { - DBG_PRINT(ERR_DBG, "Device allocation failed\n"); pci_disable_device(pdev); pci_release_regions(pdev); return -ENODEV; diff --git a/drivers/net/ethernet/netx-eth.c b/drivers/net/ethernet/netx-eth.c index a18bb10b4f0..5a12276f810 100644 --- a/drivers/net/ethernet/netx-eth.c +++ b/drivers/net/ethernet/netx-eth.c @@ -383,7 +383,6 @@ static int netx_eth_drv_probe(struct platform_device *pdev) ndev = alloc_etherdev(sizeof (struct netx_eth_priv)); if (!ndev) { - printk("%s: could not allocate device.\n", CARDNAME); ret = -ENOMEM; goto exit; } diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c index 0217991fede..bdbec7e04a4 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c @@ -2419,8 +2419,6 @@ static int pch_gbe_probe(struct pci_dev *pdev, netdev = alloc_etherdev((int)sizeof(struct pch_gbe_adapter)); if (!netdev) { ret = -ENOMEM; - dev_err(&pdev->dev, - "ERR: Can't allocate and set up an Ethernet device\n"); goto err_release_pci; } SET_NETDEV_DEV(netdev, &pdev->dev); diff --git a/drivers/net/ethernet/packetengines/yellowfin.c b/drivers/net/ethernet/packetengines/yellowfin.c index db44e9af03c..4a5774271bd 100644 --- a/drivers/net/ethernet/packetengines/yellowfin.c +++ b/drivers/net/ethernet/packetengines/yellowfin.c @@ -397,10 +397,9 @@ static int __devinit yellowfin_init_one(struct pci_dev *pdev, if (i) return i; dev = alloc_etherdev(sizeof(*np)); - if (!dev) { - pr_err("cannot allocate ethernet device\n"); + if (!dev) return -ENOMEM; - } + SET_NETDEV_DEV(dev, &pdev->dev); np = netdev_priv(dev); diff --git a/drivers/net/ethernet/pasemi/pasemi_mac.c b/drivers/net/ethernet/pasemi/pasemi_mac.c index 49b549ff2c7..3bb725ed270 100644 --- a/drivers/net/ethernet/pasemi/pasemi_mac.c +++ b/drivers/net/ethernet/pasemi/pasemi_mac.c @@ -1740,8 +1740,6 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev = alloc_etherdev(sizeof(struct pasemi_mac)); if (dev == NULL) { - dev_err(&pdev->dev, - "pasemi_mac: Could not allocate ethernet device.\n"); err = -ENOMEM; goto out_disable_device; } diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index 7dd9a4b107e..64aa44d5dab 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c @@ -1403,7 +1403,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netdev = alloc_etherdev(sizeof(struct netxen_adapter)); if(!netdev) { - dev_err(&pdev->dev, "failed to allocate net_device\n"); err = -ENOMEM; goto err_out_free_res; } diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c index 7931531c3a4..d49f6dac51f 100644 --- a/drivers/net/ethernet/qlogic/qla3xxx.c +++ b/drivers/net/ethernet/qlogic/qla3xxx.c @@ -3805,7 +3805,6 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev, ndev = alloc_etherdev(sizeof(struct ql3_adapter)); if (!ndev) { - pr_err("%s could not alloc etherdev\n", pci_name(pdev)); err = -ENOMEM; goto err_out_free_regions; } diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 69b8e4ef14d..7bfdf57f4b7 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -1576,7 +1576,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netdev = alloc_etherdev(sizeof(struct qlcnic_adapter)); if (!netdev) { - dev_err(&pdev->dev, "failed to allocate net_device\n"); err = -ENOMEM; goto err_out_free_res; } diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c index cb0eca80785..76cab284876 100644 --- a/drivers/net/ethernet/rdc/r6040.c +++ b/drivers/net/ethernet/rdc/r6040.c @@ -1107,7 +1107,6 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, dev = alloc_etherdev(sizeof(struct r6040_private)); if (!dev) { - dev_err(&pdev->dev, "Failed to allocate etherdev\n"); err = -ENOMEM; goto err_out; } diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c index a8779bedb3d..1c3feb0116b 100644 --- a/drivers/net/ethernet/realtek/8139too.c +++ b/drivers/net/ethernet/realtek/8139too.c @@ -754,10 +754,9 @@ static __devinit struct net_device * rtl8139_init_board (struct pci_dev *pdev) /* dev and priv zeroed in alloc_etherdev */ dev = alloc_etherdev (sizeof (*tp)); - if (dev == NULL) { - dev_err(&pdev->dev, "Unable to alloc new net device\n"); + if (dev == NULL) return ERR_PTR(-ENOMEM); - } + SET_NETDEV_DEV(dev, &pdev->dev); tp = netdev_priv(dev); diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 707742207c7..5eb6858ed0a 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -4008,8 +4008,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dev = alloc_etherdev(sizeof (*tp)); if (!dev) { - if (netif_msg_drv(&debug)) - dev_err(&pdev->dev, "unable to alloc new ethernet\n"); rc = -ENOMEM; goto out; } diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 813d41c4a84..1cb5a34d577 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1792,7 +1792,6 @@ static int sh_eth_drv_probe(struct platform_device *pdev) ndev = alloc_etherdev(sizeof(struct sh_eth_private)); if (!ndev) { - dev_err(&pdev->dev, "Could not allocate device.\n"); ret = -ENOMEM; goto out; } diff --git a/drivers/net/ethernet/s6gmac.c b/drivers/net/ethernet/s6gmac.c index 22e9c0181ce..bee97033167 100644 --- a/drivers/net/ethernet/s6gmac.c +++ b/drivers/net/ethernet/s6gmac.c @@ -960,11 +960,11 @@ static int __devinit s6gmac_probe(struct platform_device *pdev) int res; unsigned long i; struct mii_bus *mb; + dev = alloc_etherdev(sizeof(*pd)); - if (!dev) { - printk(KERN_ERR DRV_PRMT "etherdev alloc failed, aborting.\n"); + if (!dev) return -ENOMEM; - } + dev->open = s6gmac_open; dev->stop = s6gmac_stop; dev->hard_start_xmit = s6gmac_tx; diff --git a/drivers/net/ethernet/seeq/sgiseeq.c b/drivers/net/ethernet/seeq/sgiseeq.c index f955a19eb22..bb8c8222122 100644 --- a/drivers/net/ethernet/seeq/sgiseeq.c +++ b/drivers/net/ethernet/seeq/sgiseeq.c @@ -733,7 +733,6 @@ static int __devinit sgiseeq_probe(struct platform_device *pdev) dev = alloc_etherdev(sizeof (struct sgiseeq_private)); if (!dev) { - printk(KERN_ERR "Sgiseeq: Etherdev alloc failed, aborting.\n"); err = -ENOMEM; goto err_out; } diff --git a/drivers/net/ethernet/sis/sis190.c b/drivers/net/ethernet/sis/sis190.c index 5b118cd5bf9..a9deda8eaf6 100644 --- a/drivers/net/ethernet/sis/sis190.c +++ b/drivers/net/ethernet/sis/sis190.c @@ -1462,8 +1462,6 @@ static struct net_device * __devinit sis190_init_board(struct pci_dev *pdev) dev = alloc_etherdev(sizeof(*tp)); if (!dev) { - if (netif_msg_drv(&debug)) - pr_err("unable to alloc new ethernet\n"); rc = -ENOMEM; goto err_out_0; } diff --git a/drivers/net/ethernet/smsc/epic100.c b/drivers/net/ethernet/smsc/epic100.c index 2c077ce0b6d..11dcb38b99f 100644 --- a/drivers/net/ethernet/smsc/epic100.c +++ b/drivers/net/ethernet/smsc/epic100.c @@ -363,10 +363,9 @@ static int __devinit epic_init_one (struct pci_dev *pdev, ret = -ENOMEM; dev = alloc_etherdev(sizeof (*ep)); - if (!dev) { - dev_err(&pdev->dev, "no memory for eth device\n"); + if (!dev) goto err_out_free_res; - } + SET_NETDEV_DEV(dev, &pdev->dev); #ifdef USE_IO_OPS diff --git a/drivers/net/ethernet/smsc/smc911x.c b/drivers/net/ethernet/smsc/smc911x.c index 313ba3b32ab..c28230148ef 100644 --- a/drivers/net/ethernet/smsc/smc911x.c +++ b/drivers/net/ethernet/smsc/smc911x.c @@ -2065,7 +2065,6 @@ static int __devinit smc911x_drv_probe(struct platform_device *pdev) ndev = alloc_etherdev(sizeof(struct smc911x_local)); if (!ndev) { - printk("%s: could not allocate device.\n", CARDNAME); ret = -ENOMEM; goto release_1; } diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c index 64ad3ed7449..24104a1ee6a 100644 --- a/drivers/net/ethernet/smsc/smc91x.c +++ b/drivers/net/ethernet/smsc/smc91x.c @@ -2223,7 +2223,6 @@ static int __devinit smc_drv_probe(struct platform_device *pdev) ndev = alloc_etherdev(sizeof(struct smc_local)); if (!ndev) { - printk("%s: could not allocate device.\n", CARDNAME); ret = -ENOMEM; goto out; } diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index 24d2df068d7..6a1cd236081 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -2374,7 +2374,6 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) dev = alloc_etherdev(sizeof(struct smsc911x_data)); if (!dev) { - pr_warn("Could not allocate device\n"); retval = -ENOMEM; goto out_release_io_1; } diff --git a/drivers/net/ethernet/smsc/smsc9420.c b/drivers/net/ethernet/smsc/smsc9420.c index a9efbdfe530..595f9881e09 100644 --- a/drivers/net/ethernet/smsc/smsc9420.c +++ b/drivers/net/ethernet/smsc/smsc9420.c @@ -1598,10 +1598,8 @@ smsc9420_probe(struct pci_dev *pdev, const struct pci_device_id *id) pci_set_master(pdev); dev = alloc_etherdev(sizeof(*pd)); - if (!dev) { - printk(KERN_ERR "ether device alloc failed\n"); + if (!dev) goto out_disable_pci_device_1; - } SET_NETDEV_DEV(dev, &pdev->dev); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index ffc7581879b..166fc95e5ba 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1801,10 +1801,8 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, struct stmmac_priv *priv; ndev = alloc_etherdev(sizeof(struct stmmac_priv)); - if (!ndev) { - pr_err("%s: ERROR: allocating the device\n", __func__); + if (!ndev) return NULL; - } SET_NETDEV_DEV(ndev, device); diff --git a/drivers/net/ethernet/sun/cassini.c b/drivers/net/ethernet/sun/cassini.c index 46d84abe553..45292760fce 100644 --- a/drivers/net/ethernet/sun/cassini.c +++ b/drivers/net/ethernet/sun/cassini.c @@ -4946,7 +4946,6 @@ static int __devinit cas_init_one(struct pci_dev *pdev, dev = alloc_etherdev(sizeof(*cp)); if (!dev) { - dev_err(&pdev->dev, "Etherdev alloc failed, aborting\n"); err = -ENOMEM; goto err_out_disable_pdev; } diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c index cf433931304..d83c5081671 100644 --- a/drivers/net/ethernet/sun/niu.c +++ b/drivers/net/ethernet/sun/niu.c @@ -9685,10 +9685,8 @@ static struct net_device * __devinit niu_alloc_and_init( struct niu *np; dev = alloc_etherdev_mq(sizeof(struct niu), NIU_NUM_TXCHAN); - if (!dev) { - dev_err(gen_dev, "Etherdev alloc failed, aborting\n"); + if (!dev) return NULL; - } SET_NETDEV_DEV(dev, gen_dev); diff --git a/drivers/net/ethernet/sun/sungem.c b/drivers/net/ethernet/sun/sungem.c index 31441a870b0..ba041596e04 100644 --- a/drivers/net/ethernet/sun/sungem.c +++ b/drivers/net/ethernet/sun/sungem.c @@ -2885,7 +2885,6 @@ static int __devinit gem_init_one(struct pci_dev *pdev, dev = alloc_etherdev(sizeof(*gp)); if (!dev) { - pr_err("Etherdev alloc failed, aborting\n"); err = -ENOMEM; goto err_disable_device; } diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index 2896f6e9672..92a037a8228 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c @@ -1026,10 +1026,8 @@ static struct vnet * __devinit vnet_new(const u64 *local_mac) int err, i; dev = alloc_etherdev(sizeof(*vp)); - if (!dev) { - pr_err("Etherdev alloc failed, aborting\n"); + if (!dev) return ERR_PTR(-ENOMEM); - } for (i = 0; i < ETH_ALEN; i++) dev->dev_addr[i] = (*local_mac >> (5 - i) * 8) & 0xff; diff --git a/drivers/net/ethernet/tehuti/tehuti.c b/drivers/net/ethernet/tehuti/tehuti.c index 4b19e9b0606..df7febba9ea 100644 --- a/drivers/net/ethernet/tehuti/tehuti.c +++ b/drivers/net/ethernet/tehuti/tehuti.c @@ -1978,7 +1978,6 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ndev = alloc_etherdev(sizeof(struct bdx_priv)); if (!ndev) { err = -ENOMEM; - pr_err("alloc_etherdev failed\n"); goto err_out_iomap; } diff --git a/drivers/net/ethernet/ti/cpmac.c b/drivers/net/ethernet/ti/cpmac.c index 4d9a28ffd3c..97e1df330a1 100644 --- a/drivers/net/ethernet/ti/cpmac.c +++ b/drivers/net/ethernet/ti/cpmac.c @@ -1143,11 +1143,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev) } dev = alloc_etherdev_mq(sizeof(*priv), CPMAC_QUEUES); - - if (!dev) { - printk(KERN_ERR "cpmac: Unable to allocate net_device\n"); + if (!dev) return -ENOMEM; - } platform_set_drvdata(pdev, dev); priv = netdev_priv(dev); diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index 794ac30a577..efd4f3ee1a2 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c @@ -1789,7 +1789,6 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) ndev = alloc_etherdev(sizeof(struct emac_priv)); if (!ndev) { - dev_err(&pdev->dev, "error allocating net_device\n"); rc = -ENOMEM; goto free_clk; } diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c index 9c0dd6b8d6c..817ad3bc495 100644 --- a/drivers/net/ethernet/ti/tlan.c +++ b/drivers/net/ethernet/ti/tlan.c @@ -486,7 +486,6 @@ static int __devinit tlan_probe1(struct pci_dev *pdev, dev = alloc_etherdev(sizeof(struct tlan_priv)); if (dev == NULL) { - pr_err("Could not allocate memory for device\n"); rc = -ENOMEM; goto err_out_regions; } diff --git a/drivers/net/ethernet/toshiba/tc35815.c b/drivers/net/ethernet/toshiba/tc35815.c index 71b785cd756..f5ac603d560 100644 --- a/drivers/net/ethernet/toshiba/tc35815.c +++ b/drivers/net/ethernet/toshiba/tc35815.c @@ -808,10 +808,9 @@ static int __devinit tc35815_init_one(struct pci_dev *pdev, /* dev zeroed in alloc_etherdev */ dev = alloc_etherdev(sizeof(*lp)); - if (dev == NULL) { - dev_err(&pdev->dev, "unable to alloc new ethernet\n"); + if (dev == NULL) return -ENOMEM; - } + SET_NETDEV_DEV(dev, &pdev->dev); lp = netdev_priv(dev); lp->dev = dev; diff --git a/drivers/net/ethernet/tundra/tsi108_eth.c b/drivers/net/ethernet/tundra/tsi108_eth.c index 164fb775d7b..fc5521c9c08 100644 --- a/drivers/net/ethernet/tundra/tsi108_eth.c +++ b/drivers/net/ethernet/tundra/tsi108_eth.c @@ -1582,10 +1582,8 @@ tsi108_init_one(struct platform_device *pdev) /* Create an ethernet device instance */ dev = alloc_etherdev(sizeof(struct tsi108_prv_data)); - if (!dev) { - printk("tsi108_eth: Could not allocate a device structure\n"); + if (!dev) return -ENOMEM; - } printk("tsi108_eth%d: probe...\n", pdev->id); data = netdev_priv(dev); diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c index 10b18eb63d2..1b95daa372c 100644 --- a/drivers/net/ethernet/via/via-rhine.c +++ b/drivers/net/ethernet/via/via-rhine.c @@ -927,7 +927,6 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, dev = alloc_etherdev(sizeof(struct rhine_private)); if (!dev) { rc = -ENOMEM; - dev_err(&pdev->dev, "alloc_etherdev failed\n"); goto err_out; } SET_NETDEV_DEV(dev, &pdev->dev); diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c index 4128d6b8cc2..2776bbc6793 100644 --- a/drivers/net/ethernet/via/via-velocity.c +++ b/drivers/net/ethernet/via/via-velocity.c @@ -2733,10 +2733,8 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi } dev = alloc_etherdev(sizeof(struct velocity_info)); - if (!dev) { - dev_err(&pdev->dev, "allocate net device failed.\n"); + if (!dev) goto out; - } /* Chain it all together */ diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c index f21addb1db9..d8eb9c9e3ee 100644 --- a/drivers/net/ethernet/xilinx/ll_temac_main.c +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c @@ -1011,10 +1011,9 @@ static int __devinit temac_of_probe(struct platform_device *op) /* Init network device structure */ ndev = alloc_etherdev(sizeof(*lp)); - if (!ndev) { - dev_err(&op->dev, "could not allocate device.\n"); + if (!ndev) return -ENOMEM; - } + ether_setup(ndev); dev_set_drvdata(&op->dev, ndev); SET_NETDEV_DEV(ndev, &op->dev); diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index ea50caf8925..a7cf00438a3 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -1486,10 +1486,8 @@ static int __devinit axienet_of_probe(struct platform_device *op) const void *addr; ndev = alloc_etherdev(sizeof(*lp)); - if (!ndev) { - dev_err(&op->dev, "could not allocate device.\n"); + if (!ndev) return -ENOMEM; - } ether_setup(ndev); dev_set_drvdata(&op->dev, ndev); diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c index 79013e5731a..90e611a6f6c 100644 --- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c +++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c @@ -1136,10 +1136,8 @@ static int __devinit xemaclite_of_probe(struct platform_device *ofdev) /* Create an ethernet device instance */ ndev = alloc_etherdev(sizeof(struct net_local)); - if (!ndev) { - dev_err(dev, "Could not allocate network device\n"); + if (!ndev) return -ENOMEM; - } dev_set_drvdata(dev, ndev); SET_NETDEV_DEV(ndev, &ofdev->dev); diff --git a/drivers/net/plip/plip.c b/drivers/net/plip/plip.c index a9e9ca8a86e..1a5a316cc96 100644 --- a/drivers/net/plip/plip.c +++ b/drivers/net/plip/plip.c @@ -1260,10 +1260,8 @@ static void plip_attach (struct parport *port) sprintf(name, "plip%d", unit); dev = alloc_etherdev(sizeof(struct net_local)); - if (!dev) { - printk(KERN_ERR "plip: memory squeeze\n"); + if (!dev) return; - } strcpy(dev->name, name); diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c index 7145714a5ec..a57f05726b5 100644 --- a/drivers/net/rionet.c +++ b/drivers/net/rionet.c @@ -497,8 +497,6 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id) /* Allocate our net_device structure */ ndev = alloc_etherdev(sizeof(struct rionet_private)); if (ndev == NULL) { - printk(KERN_INFO "%s: could not allocate ethernet device.\n", - DRV_NAME); rc = -ENOMEM; goto out; } diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index 5d99b8cacd7..75239309232 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c @@ -1332,10 +1332,8 @@ static int pegasus_probe(struct usb_interface *intf, usb_get_dev(dev); net = alloc_etherdev(sizeof(struct pegasus)); - if (!net) { - dev_err(&intf->dev, "can't allocate %s\n", "device"); + if (!net) goto out; - } pegasus = netdev_priv(net); pegasus->dev_index = dev_index; diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c index 0710b4ca925..6dda2fe5b15 100644 --- a/drivers/net/usb/rtl8150.c +++ b/drivers/net/usb/rtl8150.c @@ -894,10 +894,8 @@ static int rtl8150_probe(struct usb_interface *intf, struct net_device *netdev; netdev = alloc_etherdev(sizeof(rtl8150_t)); - if (!netdev) { - err("Out of memory"); + if (!netdev) return -ENOMEM; - } dev = netdev_priv(netdev); diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index fae0fbd8bc8..b924f46c963 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1334,10 +1334,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) // set up our own records net = alloc_etherdev(sizeof(*dev)); - if (!net) { - dbg ("can't kmalloc dev"); + if (!net) goto out; - } /* netdev_printk() needs this so do it as early as possible */ SET_NETDEV_DEV(net, &udev->dev); diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 87c0b586f11..482cfa891f8 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -2918,11 +2918,8 @@ vmxnet3_probe_device(struct pci_dev *pdev, printk(KERN_INFO "# of Tx queues : %d, # of Rx queues : %d\n", num_tx_queues, num_rx_queues); - if (!netdev) { - printk(KERN_ERR "Failed to alloc ethernet device for adapter " - "%s\n", pci_name(pdev)); + if (!netdev) return -ENOMEM; - } pci_set_drvdata(pdev, netdev); adapter = netdev_priv(netdev); diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index 7e45ca2e78e..3010cee7b95 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c @@ -1533,10 +1533,9 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port, /* Create the network device object. */ dev = alloc_etherdev(sizeof(*priv)); - if (!dev) { - printk(KERN_ERR "atmel: Couldn't alloc_etherdev\n"); + if (!dev) return NULL; - } + if (dev_alloc_name(dev, dev->name) < 0) { printk(KERN_ERR "atmel: Couldn't get name!\n"); goto err_out_free; diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c index d5ef696298e..3adb24021a2 100644 --- a/drivers/net/wireless/ipw2x00/libipw_module.c +++ b/drivers/net/wireless/ipw2x00/libipw_module.c @@ -150,10 +150,9 @@ struct net_device *alloc_libipw(int sizeof_priv, int monitor) LIBIPW_DEBUG_INFO("Initializing...\n"); dev = alloc_etherdev(sizeof(struct libipw_device) + sizeof_priv); - if (!dev) { - LIBIPW_ERROR("Unable to allocate network device.\n"); + if (!dev) goto failed; - } + ieee = netdev_priv(dev); ieee->dev = dev; diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index db638b4454e..168102e6ff6 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1279,11 +1279,8 @@ static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev struct netfront_info *np; netdev = alloc_etherdev(sizeof(struct netfront_info)); - if (!netdev) { - printk(KERN_WARNING "%s> alloc_etherdev failed.\n", - __func__); + if (!netdev) return ERR_PTR(-ENOMEM); - } np = netdev_priv(netdev); np->xbdev = dev; -- cgit v1.2.3-70-g09d2 From 6c2abcdd4f8e21ce686a26697de0ce198a16eaed Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 31 Jan 2012 14:19:00 +0200 Subject: usb: musb: debugfs: fix error check debugfs will return NULL on failure, so we must check for !ptr instead of IS_ERR(ptr). Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_debugfs.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_debugfs.c b/drivers/usb/musb/musb_debugfs.c index 219d0fba584..40a37c91cc1 100644 --- a/drivers/usb/musb/musb_debugfs.c +++ b/drivers/usb/musb/musb_debugfs.c @@ -242,22 +242,22 @@ int __devinit musb_init_debugfs(struct musb *musb) int ret; root = debugfs_create_dir("musb", NULL); - if (IS_ERR(root)) { - ret = PTR_ERR(root); + if (!root) { + ret = -ENOMEM; goto err0; } file = debugfs_create_file("regdump", S_IRUGO, root, musb, &musb_regdump_fops); - if (IS_ERR(file)) { - ret = PTR_ERR(file); + if (!file) { + ret = -ENOMEM; goto err1; } file = debugfs_create_file("testmode", S_IRUGO | S_IWUSR, root, musb, &musb_test_mode_fops); - if (IS_ERR(file)) { - ret = PTR_ERR(file); + if (!file) { + ret = -ENOMEM; goto err1; } -- cgit v1.2.3-70-g09d2 From 9dfac4fd7f8cdcdf734dff2ccc7ca467f53f1cfd Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 1 Feb 2012 18:02:47 +0100 Subject: pinctrl: delete raw device pointers in pinmux maps After discussion with Mark Brown in an unrelated thread about ADC lookups, it came to my knowledge that the ability to pass a struct device * in the regulator consumers is just a historical artifact, and not really recommended. Since there are no in-kernel users of these pointers, we just kill them right now, before someone starts to use them. Reviewed-by: Mark Brown Signed-off-by: Linus Walleij --- Documentation/pinctrl.txt | 5 +---- drivers/pinctrl/core.c | 22 +++++++--------------- drivers/pinctrl/core.h | 3 +-- drivers/pinctrl/pinconf.c | 8 ++++---- drivers/pinctrl/pinmux.c | 27 ++++++++------------------- include/linux/pinctrl/machine.h | 12 ++---------- 6 files changed, 23 insertions(+), 54 deletions(-) (limited to 'drivers') diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index 150fd3833d0..14aecd2b2db 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -805,10 +805,7 @@ must match a function provided by the pinmux driver handling this pin range. As you can see we may have several pin controllers on the system and thus we need to specify which one of them that contain the functions we wish -to map. The map can also use struct device * directly, so there is no -inherent need to use strings to specify .dev_name or .ctrl_dev_name, these -are for the situation where you do not have a handle to the struct device *, -for example if they are not yet instantiated or cumbersome to obtain. +to map. You register this pinmux mapping to the pinmux subsystem by simply: diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 894cd5e103d..4f10476cc1f 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -48,31 +48,23 @@ void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev) EXPORT_SYMBOL_GPL(pinctrl_dev_get_drvdata); /** - * get_pinctrl_dev_from_dev() - look up pin controller device - * @dev: a device pointer, this may be NULL but then devname needs to be - * defined instead - * @devname: the name of a device instance, as returned by dev_name(), this - * may be NULL but then dev needs to be defined instead + * get_pinctrl_dev_from_devname() - look up pin controller device + * @devname: the name of a device instance, as returned by dev_name() * * Looks up a pin control device matching a certain device name or pure device * pointer, the pure device pointer will take precedence. */ -struct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev, - const char *devname) +struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *devname) { struct pinctrl_dev *pctldev = NULL; bool found = false; + if (!devname) + return NULL; + mutex_lock(&pinctrldev_list_mutex); list_for_each_entry(pctldev, &pinctrldev_list, node) { - if (dev && pctldev->dev == dev) { - /* Matched on device pointer */ - found = true; - break; - } - - if (devname && - !strcmp(dev_name(pctldev->dev), devname)) { + if (!strcmp(dev_name(pctldev->dev), devname)) { /* Matched on device name */ found = true; break; diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index cfa86da6b4b..8a8b02e9c18 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -72,8 +72,7 @@ struct pin_desc { #endif }; -struct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev, - const char *dev_name); +struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *dev_name); struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, unsigned int pin); int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name); int pinctrl_get_device_gpio_range(unsigned gpio, diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c index 9fb75456824..b74f64af192 100644 --- a/drivers/pinctrl/pinconf.c +++ b/drivers/pinctrl/pinconf.c @@ -51,7 +51,7 @@ int pin_config_get(const char *dev_name, const char *name, struct pinctrl_dev *pctldev; int pin; - pctldev = get_pinctrl_dev_from_dev(NULL, dev_name); + pctldev = get_pinctrl_dev_from_devname(dev_name); if (!pctldev) return -EINVAL; @@ -99,7 +99,7 @@ int pin_config_set(const char *dev_name, const char *name, struct pinctrl_dev *pctldev; int pin; - pctldev = get_pinctrl_dev_from_dev(NULL, dev_name); + pctldev = get_pinctrl_dev_from_devname(dev_name); if (!pctldev) return -EINVAL; @@ -118,7 +118,7 @@ int pin_config_group_get(const char *dev_name, const char *pin_group, const struct pinconf_ops *ops; int selector; - pctldev = get_pinctrl_dev_from_dev(NULL, dev_name); + pctldev = get_pinctrl_dev_from_devname(dev_name); if (!pctldev) return -EINVAL; ops = pctldev->desc->confops; @@ -151,7 +151,7 @@ int pin_config_group_set(const char *dev_name, const char *pin_group, int ret; int i; - pctldev = get_pinctrl_dev_from_dev(NULL, dev_name); + pctldev = get_pinctrl_dev_from_devname(dev_name); if (!pctldev) return -EINVAL; ops = pctldev->desc->confops; diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 7c3193f7a04..1311f1d2200 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -354,7 +354,7 @@ int __init pinmux_register_mappings(struct pinmux_map const *maps, return -EINVAL; } - if (!maps[i].ctrl_dev && !maps[i].ctrl_dev_name) { + if (!maps[i].ctrl_dev_name) { pr_err("failed to register map %s (%d): no pin control device given\n", maps[i].name, i); return -EINVAL; @@ -366,7 +366,7 @@ int __init pinmux_register_mappings(struct pinmux_map const *maps, return -EINVAL; } - if (!maps[i].dev && !maps[i].dev_name) + if (!maps[i].dev_name) pr_debug("add system map %s function %s with no device\n", maps[i].name, maps[i].function); @@ -721,20 +721,12 @@ struct pinmux *pinmux_get(struct device *dev, const char *name) /* * First, try to find the pctldev given in the map */ - pctldev = get_pinctrl_dev_from_dev(map->ctrl_dev, - map->ctrl_dev_name); + pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name); if (!pctldev) { - const char *devname = NULL; - - if (map->ctrl_dev) - devname = dev_name(map->ctrl_dev); - else if (map->ctrl_dev_name) - devname = map->ctrl_dev_name; - pr_warning("could not find a pinctrl device for pinmux function %s, fishy, they shall all have one\n", map->function); pr_warning("given pinctrl device name: %s", - devname ? devname : "UNDEFINED"); + map->ctrl_dev_name); /* Continue to check the other mappings anyway... */ continue; @@ -925,7 +917,7 @@ static int pinmux_hog_map(struct pinctrl_dev *pctldev, struct pinmux *pmx; int ret; - if (map->dev || map->dev_name) { + if (map->dev_name) { /* * TODO: the day we have device tree support, we can * traverse the device tree and hog to specific device nodes @@ -996,9 +988,8 @@ int pinmux_hog_maps(struct pinctrl_dev *pctldev) if (!map->hog_on_boot) continue; - if ((map->ctrl_dev == dev) || - (map->ctrl_dev_name && - !strcmp(map->ctrl_dev_name, devname))) { + if (map->ctrl_dev_name && + !strcmp(map->ctrl_dev_name, devname)) { /* OK time to hog! */ ret = pinmux_hog_map(pctldev, map); if (ret) @@ -1156,14 +1147,12 @@ static int pinmux_maps_show(struct seq_file *s, void *what) struct pinmux_map const *map = &pinmux_maps[i]; seq_printf(s, "%s:\n", map->name); - if (map->dev || map->dev_name) + if (map->dev_name) seq_printf(s, " device: %s\n", - map->dev ? dev_name(map->dev) : map->dev_name); else seq_printf(s, " SYSTEM MUX\n"); seq_printf(s, " controlling device %s\n", - map->ctrl_dev ? dev_name(map->ctrl_dev) : map->ctrl_dev_name); seq_printf(s, " function: %s\n", map->function); seq_printf(s, " group: %s\n", map->group ? map->group : diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index d0aecb7f6fb..f8593fdc646 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -17,22 +17,16 @@ * @name: the name of this specific map entry for the particular machine. * This is the second parameter passed to pinmux_get() when you want * to have several mappings to the same device - * @ctrl_dev: the pin control device to be used by this mapping, may be NULL - * if you provide .ctrl_dev_name instead (this is more common) * @ctrl_dev_name: the name of the device controlling this specific mapping, - * the name must be the same as in your struct device*, may be NULL if - * you provide .ctrl_dev instead + * the name must be the same as in your struct device* * @function: a function in the driver to use for this mapping, the driver * will lookup the function referenced by this ID on the specified * pin control device * @group: sometimes a function can map to different pin groups, so this * selects a certain specific pin group to activate for the function, if * left as NULL, the first applicable group will be used - * @dev: the device using this specific mapping, may be NULL if you provide - * .dev_name instead (this is more common) * @dev_name: the name of the device using this specific mapping, the name - * must be the same as in your struct device*, may be NULL if you - * provide .dev instead + * must be the same as in your struct device* * @hog_on_boot: if this is set to true, the pin control subsystem will itself * hog the mappings as the pinmux device drivers are attached, so this is * typically used with system maps (mux mappings without an assigned @@ -42,11 +36,9 @@ */ struct pinmux_map { const char *name; - struct device *ctrl_dev; const char *ctrl_dev_name; const char *function; const char *group; - struct device *dev; const char *dev_name; bool hog_on_boot; }; -- cgit v1.2.3-70-g09d2 From f4e66983293f78e177bb210d19a46f083f5e8197 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Wed, 4 Jan 2012 10:26:33 +0800 Subject: pinctrl: enable pinmux for mmp series Support PXA168/PXA910/MMP2 pinmux. Now only support function switch. Signed-off-by: Haojian Zhuang [Rebase and fix some whitespace issues] Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 22 + drivers/pinctrl/Makefile | 4 + drivers/pinctrl/pinctrl-mmp2.c | 722 +++++++++++++++++++++++++++ drivers/pinctrl/pinctrl-pxa168.c | 651 ++++++++++++++++++++++++ drivers/pinctrl/pinctrl-pxa3xx.c | 244 +++++++++ drivers/pinctrl/pinctrl-pxa3xx.h | 264 ++++++++++ drivers/pinctrl/pinctrl-pxa910.c | 1007 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 2914 insertions(+) create mode 100644 drivers/pinctrl/pinctrl-mmp2.c create mode 100644 drivers/pinctrl/pinctrl-pxa168.c create mode 100644 drivers/pinctrl/pinctrl-pxa3xx.c create mode 100644 drivers/pinctrl/pinctrl-pxa3xx.h create mode 100644 drivers/pinctrl/pinctrl-pxa910.c (limited to 'drivers') diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index afaf8855812..3bea79fc35d 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -23,6 +23,28 @@ config DEBUG_PINCTRL help Say Y here to add some extra checks and diagnostics to PINCTRL calls. +config PINCTRL_PXA3xx + bool + select PINMUX + +config PINCTRL_MMP2 + bool "MMP2 pin controller driver" + depends on ARCH_MMP + select PINCTRL_PXA3xx + select PINCONF + +config PINCTRL_PXA168 + bool "PXA168 pin controller driver" + depends on ARCH_MMP + select PINCTRL_PXA3xx + select PINCONF + +config PINCTRL_PXA910 + bool "PXA910 pin controller driver" + depends on ARCH_MMP + select PINCTRL_PXA3xx + select PINCONF + config PINCTRL_SIRF bool "CSR SiRFprimaII pin controller driver" depends on ARCH_PRIMA2 diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 827601cc68f..c95d91e87b5 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -5,6 +5,10 @@ ccflags-$(CONFIG_DEBUG_PINCTRL) += -DDEBUG obj-$(CONFIG_PINCTRL) += core.o obj-$(CONFIG_PINMUX) += pinmux.o obj-$(CONFIG_PINCONF) += pinconf.o +obj-$(CONFIG_PINCTRL_PXA3xx) += pinctrl-pxa3xx.o +obj-$(CONFIG_PINCTRL_MMP2) += pinctrl-mmp2.o +obj-$(CONFIG_PINCTRL_PXA168) += pinctrl-pxa168.o +obj-$(CONFIG_PINCTRL_PXA910) += pinctrl-pxa910.o obj-$(CONFIG_PINCTRL_SIRF) += pinctrl-sirf.o obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o diff --git a/drivers/pinctrl/pinctrl-mmp2.c b/drivers/pinctrl/pinctrl-mmp2.c new file mode 100644 index 00000000000..2cfed552bbe --- /dev/null +++ b/drivers/pinctrl/pinctrl-mmp2.c @@ -0,0 +1,722 @@ +/* + * linux/drivers/pinctrl/pinmux-mmp2.c + * + * 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 + * publishhed by the Free Software Foundation. + * + * Copyright (C) 2011, Marvell Technology Group Ltd. + * + * Author: Haojian Zhuang + * + */ + +#include +#include +#include +#include +#include "pinctrl-pxa3xx.h" + +#define MMP2_DS_MASK 0x1800 +#define MMP2_DS_SHIFT 11 +#define MMP2_SLEEP_MASK 0x38 +#define MMP2_SLEEP_SELECT (1 << 9) +#define MMP2_SLEEP_DATA (1 << 8) +#define MMP2_SLEEP_DIR (1 << 7) + +#define MFPR_MMP2(a, r, f0, f1, f2, f3, f4, f5, f6, f7) \ + { \ + .name = #a, \ + .pin = a, \ + .mfpr = r, \ + .func = { \ + MMP2_MUX_##f0, \ + MMP2_MUX_##f1, \ + MMP2_MUX_##f2, \ + MMP2_MUX_##f3, \ + MMP2_MUX_##f4, \ + MMP2_MUX_##f5, \ + MMP2_MUX_##f6, \ + MMP2_MUX_##f7, \ + }, \ + } + +#define GRP_MMP2(a, m, p) \ + { .name = a, .mux = MMP2_MUX_##m, .pins = p, .npins = ARRAY_SIZE(p), } + +/* 174 pins */ +enum mmp2_pin_list { + /* 0~168: GPIO0~GPIO168 */ + TWSI4_SCL = 169, + TWSI4_SDA, /* 170 */ + G_CLKREQ, + VCXO_REQ, + VCXO_OUT, +}; + +enum mmp2_mux { + /* PXA3xx_MUX_GPIO = 0 (predefined in pinctrl-pxa3xx.h) */ + MMP2_MUX_GPIO = 0, + MMP2_MUX_G_CLKREQ, + MMP2_MUX_VCXO_REQ, + MMP2_MUX_VCXO_OUT, + MMP2_MUX_KP_MK, + MMP2_MUX_KP_DK, + MMP2_MUX_CCIC1, + MMP2_MUX_CCIC2, + MMP2_MUX_SPI, + MMP2_MUX_SSPA2, + MMP2_MUX_ROT, + MMP2_MUX_I2S, + MMP2_MUX_TB, + MMP2_MUX_CAM2, + MMP2_MUX_HDMI, + MMP2_MUX_TWSI2, + MMP2_MUX_TWSI3, + MMP2_MUX_TWSI4, + MMP2_MUX_TWSI5, + MMP2_MUX_TWSI6, + MMP2_MUX_UART1, + MMP2_MUX_UART2, + MMP2_MUX_UART3, + MMP2_MUX_UART4, + MMP2_MUX_SSP1_RX, + MMP2_MUX_SSP1_FRM, + MMP2_MUX_SSP1_TXRX, + MMP2_MUX_SSP2_RX, + MMP2_MUX_SSP2_FRM, + MMP2_MUX_SSP1, + MMP2_MUX_SSP2, + MMP2_MUX_SSP3, + MMP2_MUX_SSP4, + MMP2_MUX_MMC1, + MMP2_MUX_MMC2, + MMP2_MUX_MMC3, + MMP2_MUX_MMC4, + MMP2_MUX_ULPI, + MMP2_MUX_AC, + MMP2_MUX_CA, + MMP2_MUX_PWM, + MMP2_MUX_USIM, + MMP2_MUX_TIPU, + MMP2_MUX_PLL, + MMP2_MUX_NAND, + MMP2_MUX_FSIC, + MMP2_MUX_SLEEP_IND, + MMP2_MUX_EXT_DMA, + MMP2_MUX_ONE_WIRE, + MMP2_MUX_LCD, + MMP2_MUX_SMC, + MMP2_MUX_SMC_INT, + MMP2_MUX_MSP, + MMP2_MUX_G_CLKOUT, + MMP2_MUX_32K_CLKOUT, + MMP2_MUX_PRI_JTAG, + MMP2_MUX_AAS_JTAG, + MMP2_MUX_AAS_GPIO, + MMP2_MUX_AAS_SPI, + MMP2_MUX_AAS_TWSI, + MMP2_MUX_AAS_DEU_EX, + MMP2_MUX_NONE = 0xffff, +}; + +static struct pinctrl_pin_desc mmp2_pads[] = { + /* + * The name indicates function 0 of this pin. + * After reset, function 0 is the default function of pin. + */ + PINCTRL_PIN(GPIO0, "GPIO0"), + PINCTRL_PIN(GPIO1, "GPIO1"), + PINCTRL_PIN(GPIO2, "GPIO2"), + PINCTRL_PIN(GPIO3, "GPIO3"), + PINCTRL_PIN(GPIO4, "GPIO4"), + PINCTRL_PIN(GPIO5, "GPIO5"), + PINCTRL_PIN(GPIO6, "GPIO6"), + PINCTRL_PIN(GPIO7, "GPIO7"), + PINCTRL_PIN(GPIO8, "GPIO8"), + PINCTRL_PIN(GPIO9, "GPIO9"), + PINCTRL_PIN(GPIO10, "GPIO10"), + PINCTRL_PIN(GPIO11, "GPIO11"), + PINCTRL_PIN(GPIO12, "GPIO12"), + PINCTRL_PIN(GPIO13, "GPIO13"), + PINCTRL_PIN(GPIO14, "GPIO14"), + PINCTRL_PIN(GPIO15, "GPIO15"), + PINCTRL_PIN(GPIO16, "GPIO16"), + PINCTRL_PIN(GPIO17, "GPIO17"), + PINCTRL_PIN(GPIO18, "GPIO18"), + PINCTRL_PIN(GPIO19, "GPIO19"), + PINCTRL_PIN(GPIO20, "GPIO20"), + PINCTRL_PIN(GPIO21, "GPIO21"), + PINCTRL_PIN(GPIO22, "GPIO22"), + PINCTRL_PIN(GPIO23, "GPIO23"), + PINCTRL_PIN(GPIO24, "GPIO24"), + PINCTRL_PIN(GPIO25, "GPIO25"), + PINCTRL_PIN(GPIO26, "GPIO26"), + PINCTRL_PIN(GPIO27, "GPIO27"), + PINCTRL_PIN(GPIO28, "GPIO28"), + PINCTRL_PIN(GPIO29, "GPIO29"), + PINCTRL_PIN(GPIO30, "GPIO30"), + PINCTRL_PIN(GPIO31, "GPIO31"), + PINCTRL_PIN(GPIO32, "GPIO32"), + PINCTRL_PIN(GPIO33, "GPIO33"), + PINCTRL_PIN(GPIO34, "GPIO34"), + PINCTRL_PIN(GPIO35, "GPIO35"), + PINCTRL_PIN(GPIO36, "GPIO36"), + PINCTRL_PIN(GPIO37, "GPIO37"), + PINCTRL_PIN(GPIO38, "GPIO38"), + PINCTRL_PIN(GPIO39, "GPIO39"), + PINCTRL_PIN(GPIO40, "GPIO40"), + PINCTRL_PIN(GPIO41, "GPIO41"), + PINCTRL_PIN(GPIO42, "GPIO42"), + PINCTRL_PIN(GPIO43, "GPIO43"), + PINCTRL_PIN(GPIO44, "GPIO44"), + PINCTRL_PIN(GPIO45, "GPIO45"), + PINCTRL_PIN(GPIO46, "GPIO46"), + PINCTRL_PIN(GPIO47, "GPIO47"), + PINCTRL_PIN(GPIO48, "GPIO48"), + PINCTRL_PIN(GPIO49, "GPIO49"), + PINCTRL_PIN(GPIO50, "GPIO50"), + PINCTRL_PIN(GPIO51, "GPIO51"), + PINCTRL_PIN(GPIO52, "GPIO52"), + PINCTRL_PIN(GPIO53, "GPIO53"), + PINCTRL_PIN(GPIO54, "GPIO54"), + PINCTRL_PIN(GPIO55, "GPIO55"), + PINCTRL_PIN(GPIO56, "GPIO56"), + PINCTRL_PIN(GPIO57, "GPIO57"), + PINCTRL_PIN(GPIO58, "GPIO58"), + PINCTRL_PIN(GPIO59, "GPIO59"), + PINCTRL_PIN(GPIO60, "GPIO60"), + PINCTRL_PIN(GPIO61, "GPIO61"), + PINCTRL_PIN(GPIO62, "GPIO62"), + PINCTRL_PIN(GPIO63, "GPIO63"), + PINCTRL_PIN(GPIO64, "GPIO64"), + PINCTRL_PIN(GPIO65, "GPIO65"), + PINCTRL_PIN(GPIO66, "GPIO66"), + PINCTRL_PIN(GPIO67, "GPIO67"), + PINCTRL_PIN(GPIO68, "GPIO68"), + PINCTRL_PIN(GPIO69, "GPIO69"), + PINCTRL_PIN(GPIO70, "GPIO70"), + PINCTRL_PIN(GPIO71, "GPIO71"), + PINCTRL_PIN(GPIO72, "GPIO72"), + PINCTRL_PIN(GPIO73, "GPIO73"), + PINCTRL_PIN(GPIO74, "GPIO74"), + PINCTRL_PIN(GPIO75, "GPIO75"), + PINCTRL_PIN(GPIO76, "GPIO76"), + PINCTRL_PIN(GPIO77, "GPIO77"), + PINCTRL_PIN(GPIO78, "GPIO78"), + PINCTRL_PIN(GPIO79, "GPIO79"), + PINCTRL_PIN(GPIO80, "GPIO80"), + PINCTRL_PIN(GPIO81, "GPIO81"), + PINCTRL_PIN(GPIO82, "GPIO82"), + PINCTRL_PIN(GPIO83, "GPIO83"), + PINCTRL_PIN(GPIO84, "GPIO84"), + PINCTRL_PIN(GPIO85, "GPIO85"), + PINCTRL_PIN(GPIO86, "GPIO86"), + PINCTRL_PIN(GPIO87, "GPIO87"), + PINCTRL_PIN(GPIO88, "GPIO88"), + PINCTRL_PIN(GPIO89, "GPIO89"), + PINCTRL_PIN(GPIO90, "GPIO90"), + PINCTRL_PIN(GPIO91, "GPIO91"), + PINCTRL_PIN(GPIO92, "GPIO92"), + PINCTRL_PIN(GPIO93, "GPIO93"), + PINCTRL_PIN(GPIO94, "GPIO94"), + PINCTRL_PIN(GPIO95, "GPIO95"), + PINCTRL_PIN(GPIO96, "GPIO96"), + PINCTRL_PIN(GPIO97, "GPIO97"), + PINCTRL_PIN(GPIO98, "GPIO98"), + PINCTRL_PIN(GPIO99, "GPIO99"), + PINCTRL_PIN(GPIO100, "GPIO100"), + PINCTRL_PIN(GPIO101, "GPIO101"), + PINCTRL_PIN(GPIO102, "GPIO102"), + PINCTRL_PIN(GPIO103, "GPIO103"), + PINCTRL_PIN(GPIO104, "GPIO104"), + PINCTRL_PIN(GPIO105, "GPIO105"), + PINCTRL_PIN(GPIO106, "GPIO106"), + PINCTRL_PIN(GPIO107, "GPIO107"), + PINCTRL_PIN(GPIO108, "GPIO108"), + PINCTRL_PIN(GPIO109, "GPIO109"), + PINCTRL_PIN(GPIO110, "GPIO110"), + PINCTRL_PIN(GPIO111, "GPIO111"), + PINCTRL_PIN(GPIO112, "GPIO112"), + PINCTRL_PIN(GPIO113, "GPIO113"), + PINCTRL_PIN(GPIO114, "GPIO114"), + PINCTRL_PIN(GPIO115, "GPIO115"), + PINCTRL_PIN(GPIO116, "GPIO116"), + PINCTRL_PIN(GPIO117, "GPIO117"), + PINCTRL_PIN(GPIO118, "GPIO118"), + PINCTRL_PIN(GPIO119, "GPIO119"), + PINCTRL_PIN(GPIO120, "GPIO120"), + PINCTRL_PIN(GPIO121, "GPIO121"), + PINCTRL_PIN(GPIO122, "GPIO122"), + PINCTRL_PIN(GPIO123, "GPIO123"), + PINCTRL_PIN(GPIO124, "GPIO124"), + PINCTRL_PIN(GPIO125, "GPIO125"), + PINCTRL_PIN(GPIO126, "GPIO126"), + PINCTRL_PIN(GPIO127, "GPIO127"), + PINCTRL_PIN(GPIO128, "GPIO128"), + PINCTRL_PIN(GPIO129, "GPIO129"), + PINCTRL_PIN(GPIO130, "GPIO130"), + PINCTRL_PIN(GPIO131, "GPIO131"), + PINCTRL_PIN(GPIO132, "GPIO132"), + PINCTRL_PIN(GPIO133, "GPIO133"), + PINCTRL_PIN(GPIO134, "GPIO134"), + PINCTRL_PIN(GPIO135, "GPIO135"), + PINCTRL_PIN(GPIO136, "GPIO136"), + PINCTRL_PIN(GPIO137, "GPIO137"), + PINCTRL_PIN(GPIO138, "GPIO138"), + PINCTRL_PIN(GPIO139, "GPIO139"), + PINCTRL_PIN(GPIO140, "GPIO140"), + PINCTRL_PIN(GPIO141, "GPIO141"), + PINCTRL_PIN(GPIO142, "GPIO142"), + PINCTRL_PIN(GPIO143, "GPIO143"), + PINCTRL_PIN(GPIO144, "GPIO144"), + PINCTRL_PIN(GPIO145, "GPIO145"), + PINCTRL_PIN(GPIO146, "GPIO146"), + PINCTRL_PIN(GPIO147, "GPIO147"), + PINCTRL_PIN(GPIO148, "GPIO148"), + PINCTRL_PIN(GPIO149, "GPIO149"), + PINCTRL_PIN(GPIO150, "GPIO150"), + PINCTRL_PIN(GPIO151, "GPIO151"), + PINCTRL_PIN(GPIO152, "GPIO152"), + PINCTRL_PIN(GPIO153, "GPIO153"), + PINCTRL_PIN(GPIO154, "GPIO154"), + PINCTRL_PIN(GPIO155, "GPIO155"), + PINCTRL_PIN(GPIO156, "GPIO156"), + PINCTRL_PIN(GPIO157, "GPIO157"), + PINCTRL_PIN(GPIO158, "GPIO158"), + PINCTRL_PIN(GPIO159, "GPIO159"), + PINCTRL_PIN(GPIO160, "GPIO160"), + PINCTRL_PIN(GPIO161, "GPIO161"), + PINCTRL_PIN(GPIO162, "GPIO162"), + PINCTRL_PIN(GPIO163, "GPIO163"), + PINCTRL_PIN(GPIO164, "GPIO164"), + PINCTRL_PIN(GPIO165, "GPIO165"), + PINCTRL_PIN(GPIO166, "GPIO166"), + PINCTRL_PIN(GPIO167, "GPIO167"), + PINCTRL_PIN(GPIO168, "GPIO168"), + PINCTRL_PIN(TWSI4_SCL, "TWSI4_SCL"), + PINCTRL_PIN(TWSI4_SDA, "TWSI4_SDA"), + PINCTRL_PIN(G_CLKREQ, "G_CLKREQ"), + PINCTRL_PIN(VCXO_REQ, "VCXO_REQ"), + PINCTRL_PIN(VCXO_OUT, "VCXO_OUT"), +}; + +struct pxa3xx_mfp_pin mmp2_mfp[] = { + /* pin offs f0 f1 f2 f3 f4 f5 f6 f7 */ + MFPR_MMP2(GPIO0, 0x054, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO1, 0x058, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO2, 0x05C, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO3, 0x060, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO4, 0x064, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO5, 0x068, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO6, 0x06C, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO7, 0x070, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO8, 0x074, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO9, 0x078, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO10, 0x07C, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO11, 0x080, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO12, 0x084, GPIO, KP_MK, NONE, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO13, 0x088, GPIO, KP_MK, NONE, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO14, 0x08C, GPIO, KP_MK, NONE, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO15, 0x090, GPIO, KP_MK, KP_DK, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO16, 0x094, GPIO, KP_DK, ROT, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO17, 0x098, GPIO, KP_DK, ROT, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO18, 0x09C, GPIO, KP_DK, ROT, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO19, 0x0A0, GPIO, KP_DK, ROT, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO20, 0x0A4, GPIO, KP_DK, TB, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO21, 0x0A8, GPIO, KP_DK, TB, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO22, 0x0AC, GPIO, KP_DK, TB, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO23, 0x0B0, GPIO, KP_DK, TB, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO24, 0x0B4, GPIO, I2S, VCXO_OUT, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO25, 0x0B8, GPIO, I2S, HDMI, SSPA2, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO26, 0x0BC, GPIO, I2S, HDMI, SSPA2, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO27, 0x0C0, GPIO, I2S, HDMI, SSPA2, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO28, 0x0C4, GPIO, I2S, NONE, SSPA2, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO29, 0x0C8, GPIO, UART1, KP_MK, NONE, NONE, NONE, AAS_SPI, NONE), + MFPR_MMP2(GPIO30, 0x0CC, GPIO, UART1, KP_MK, NONE, NONE, NONE, AAS_SPI, NONE), + MFPR_MMP2(GPIO31, 0x0D0, GPIO, UART1, KP_MK, NONE, NONE, NONE, AAS_SPI, NONE), + MFPR_MMP2(GPIO32, 0x0D4, GPIO, UART1, KP_MK, NONE, NONE, NONE, AAS_SPI, NONE), + MFPR_MMP2(GPIO33, 0x0D8, GPIO, SSPA2, I2S, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO34, 0x0DC, GPIO, SSPA2, I2S, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO35, 0x0E0, GPIO, SSPA2, I2S, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO36, 0x0E4, GPIO, SSPA2, I2S, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO37, 0x0E8, GPIO, MMC2, SSP1, TWSI2, UART2, UART3, AAS_SPI, AAS_TWSI), + MFPR_MMP2(GPIO38, 0x0EC, GPIO, MMC2, SSP1, TWSI2, UART2, UART3, AAS_SPI, AAS_TWSI), + MFPR_MMP2(GPIO39, 0x0F0, GPIO, MMC2, SSP1, TWSI2, UART2, UART3, AAS_SPI, AAS_TWSI), + MFPR_MMP2(GPIO40, 0x0F4, GPIO, MMC2, SSP1, TWSI2, UART2, UART3, AAS_SPI, AAS_TWSI), + MFPR_MMP2(GPIO41, 0x0F8, GPIO, MMC2, TWSI5, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO42, 0x0FC, GPIO, MMC2, TWSI5, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO43, 0x100, GPIO, TWSI2, UART4, SSP1, UART2, UART3, NONE, AAS_TWSI), + MFPR_MMP2(GPIO44, 0x104, GPIO, TWSI2, UART4, SSP1, UART2, UART3, NONE, AAS_TWSI), + MFPR_MMP2(GPIO45, 0x108, GPIO, UART1, UART4, SSP1, UART2, UART3, NONE, NONE), + MFPR_MMP2(GPIO46, 0x10C, GPIO, UART1, UART4, SSP1, UART2, UART3, NONE, NONE), + MFPR_MMP2(GPIO47, 0x110, GPIO, UART2, SSP2, TWSI6, CAM2, AAS_SPI, AAS_GPIO, NONE), + MFPR_MMP2(GPIO48, 0x114, GPIO, UART2, SSP2, TWSI6, CAM2, AAS_SPI, AAS_GPIO, NONE), + MFPR_MMP2(GPIO49, 0x118, GPIO, UART2, SSP2, PWM, CCIC2, AAS_SPI, NONE, NONE), + MFPR_MMP2(GPIO50, 0x11C, GPIO, UART2, SSP2, PWM, CCIC2, AAS_SPI, NONE, NONE), + MFPR_MMP2(GPIO51, 0x120, GPIO, UART3, ROT, AAS_GPIO, PWM, NONE, NONE, NONE), + MFPR_MMP2(GPIO52, 0x124, GPIO, UART3, ROT, AAS_GPIO, PWM, NONE, NONE, NONE), + MFPR_MMP2(GPIO53, 0x128, GPIO, UART3, TWSI2, VCXO_REQ, NONE, PWM, NONE, AAS_TWSI), + MFPR_MMP2(GPIO54, 0x12C, GPIO, UART3, TWSI2, VCXO_OUT, HDMI, PWM, NONE, AAS_TWSI), + MFPR_MMP2(GPIO55, 0x130, GPIO, SSP2, SSP1, UART2, ROT, TWSI2, SSP3, AAS_TWSI), + MFPR_MMP2(GPIO56, 0x134, GPIO, SSP2, SSP1, UART2, ROT, TWSI2, KP_DK, AAS_TWSI), + MFPR_MMP2(GPIO57, 0x138, GPIO, SSP2_RX, SSP1_TXRX, SSP2_FRM, SSP1_RX, VCXO_REQ, KP_DK, NONE), + MFPR_MMP2(GPIO58, 0x13C, GPIO, SSP2, SSP1_RX, SSP1_FRM, SSP1_TXRX, VCXO_REQ, KP_DK, NONE), + MFPR_MMP2(GPIO59, 0x280, GPIO, CCIC1, ULPI, MMC3, CCIC2, UART3, UART4, NONE), + MFPR_MMP2(GPIO60, 0x284, GPIO, CCIC1, ULPI, MMC3, CCIC2, UART3, UART4, NONE), + MFPR_MMP2(GPIO61, 0x288, GPIO, CCIC1, ULPI, MMC3, CCIC2, UART3, HDMI, NONE), + MFPR_MMP2(GPIO62, 0x28C, GPIO, CCIC1, ULPI, MMC3, CCIC2, UART3, NONE, NONE), + MFPR_MMP2(GPIO63, 0x290, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, UART4, NONE), + MFPR_MMP2(GPIO64, 0x294, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, UART4, NONE), + MFPR_MMP2(GPIO65, 0x298, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, UART4, NONE), + MFPR_MMP2(GPIO66, 0x29C, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, UART4, NONE), + MFPR_MMP2(GPIO67, 0x2A0, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, NONE, NONE), + MFPR_MMP2(GPIO68, 0x2A4, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, LCD, NONE), + MFPR_MMP2(GPIO69, 0x2A8, GPIO, CCIC1, ULPI, MMC3, CCIC2, NONE, LCD, NONE), + MFPR_MMP2(GPIO70, 0x2AC, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, LCD, NONE), + MFPR_MMP2(GPIO71, 0x2B0, GPIO, TWSI3, NONE, PWM, NONE, NONE, LCD, AAS_TWSI), + MFPR_MMP2(GPIO72, 0x2B4, GPIO, TWSI3, HDMI, PWM, NONE, NONE, LCD, AAS_TWSI), + MFPR_MMP2(GPIO73, 0x2B8, GPIO, VCXO_REQ, 32K_CLKOUT, PWM, VCXO_OUT, NONE, LCD, NONE), + MFPR_MMP2(GPIO74, 0x170, GPIO, LCD, SMC, MMC4, SSP3, UART2, UART4, TIPU), + MFPR_MMP2(GPIO75, 0x174, GPIO, LCD, SMC, MMC4, SSP3, UART2, UART4, TIPU), + MFPR_MMP2(GPIO76, 0x178, GPIO, LCD, SMC, MMC4, SSP3, UART2, UART4, TIPU), + MFPR_MMP2(GPIO77, 0x17C, GPIO, LCD, SMC, MMC4, SSP3, UART2, UART4, TIPU), + MFPR_MMP2(GPIO78, 0x180, GPIO, LCD, HDMI, MMC4, NONE, SSP4, AAS_SPI, TIPU), + MFPR_MMP2(GPIO79, 0x184, GPIO, LCD, AAS_GPIO, MMC4, NONE, SSP4, AAS_SPI, TIPU), + MFPR_MMP2(GPIO80, 0x188, GPIO, LCD, AAS_GPIO, MMC4, NONE, SSP4, AAS_SPI, TIPU), + MFPR_MMP2(GPIO81, 0x18C, GPIO, LCD, AAS_GPIO, MMC4, NONE, SSP4, AAS_SPI, TIPU), + MFPR_MMP2(GPIO82, 0x190, GPIO, LCD, NONE, MMC4, NONE, NONE, CCIC2, TIPU), + MFPR_MMP2(GPIO83, 0x194, GPIO, LCD, NONE, MMC4, NONE, NONE, CCIC2, TIPU), + MFPR_MMP2(GPIO84, 0x198, GPIO, LCD, SMC, MMC2, NONE, TWSI5, AAS_TWSI, TIPU), + MFPR_MMP2(GPIO85, 0x19C, GPIO, LCD, SMC, MMC2, NONE, TWSI5, AAS_TWSI, TIPU), + MFPR_MMP2(GPIO86, 0x1A0, GPIO, LCD, SMC, MMC2, NONE, TWSI6, CCIC2, TIPU), + MFPR_MMP2(GPIO87, 0x1A4, GPIO, LCD, SMC, MMC2, NONE, TWSI6, CCIC2, TIPU), + MFPR_MMP2(GPIO88, 0x1A8, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU), + MFPR_MMP2(GPIO89, 0x1AC, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU), + MFPR_MMP2(GPIO90, 0x1B0, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU), + MFPR_MMP2(GPIO91, 0x1B4, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU), + MFPR_MMP2(GPIO92, 0x1B8, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU), + MFPR_MMP2(GPIO93, 0x1BC, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU), + MFPR_MMP2(GPIO94, 0x1C0, GPIO, LCD, AAS_GPIO, SPI, NONE, AAS_SPI, CCIC2, TIPU), + MFPR_MMP2(GPIO95, 0x1C4, GPIO, LCD, TWSI3, SPI, AAS_DEU_EX, AAS_SPI, CCIC2, TIPU), + MFPR_MMP2(GPIO96, 0x1C8, GPIO, LCD, TWSI3, SPI, AAS_DEU_EX, AAS_SPI, NONE, TIPU), + MFPR_MMP2(GPIO97, 0x1CC, GPIO, LCD, TWSI6, SPI, AAS_DEU_EX, AAS_SPI, NONE, TIPU), + MFPR_MMP2(GPIO98, 0x1D0, GPIO, LCD, TWSI6, SPI, ONE_WIRE, NONE, NONE, TIPU), + MFPR_MMP2(GPIO99, 0x1D4, GPIO, LCD, SMC, SPI, TWSI5, NONE, NONE, TIPU), + MFPR_MMP2(GPIO100, 0x1D8, GPIO, LCD, SMC, SPI, TWSI5, NONE, NONE, TIPU), + MFPR_MMP2(GPIO101, 0x1DC, GPIO, LCD, SMC, SPI, NONE, NONE, NONE, TIPU), + MFPR_MMP2(GPIO102, 0x000, USIM, GPIO, FSIC, KP_DK, LCD, NONE, NONE, NONE), + MFPR_MMP2(GPIO103, 0x004, USIM, GPIO, FSIC, KP_DK, LCD, NONE, NONE, NONE), + MFPR_MMP2(GPIO104, 0x1FC, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO105, 0x1F8, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO106, 0x1F4, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO107, 0x1F0, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO108, 0x21C, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO109, 0x218, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO110, 0x214, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO111, 0x200, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO112, 0x244, NAND, GPIO, MMC3, SMC, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO113, 0x25C, SMC, GPIO, EXT_DMA, MMC3, SMC, HDMI, NONE, NONE), + MFPR_MMP2(GPIO114, 0x164, G_CLKOUT, 32K_CLKOUT, HDMI, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO115, 0x260, GPIO, NONE, AC, UART4, UART3, SSP1, NONE, NONE), + MFPR_MMP2(GPIO116, 0x264, GPIO, NONE, AC, UART4, UART3, SSP1, NONE, NONE), + MFPR_MMP2(GPIO117, 0x268, GPIO, NONE, AC, UART4, UART3, SSP1, NONE, NONE), + MFPR_MMP2(GPIO118, 0x26C, GPIO, NONE, AC, UART4, UART3, SSP1, NONE, NONE), + MFPR_MMP2(GPIO119, 0x270, GPIO, NONE, CA, SSP3, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO120, 0x274, GPIO, NONE, CA, SSP3, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO121, 0x278, GPIO, NONE, CA, SSP3, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO122, 0x27C, GPIO, NONE, CA, SSP3, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO123, 0x148, GPIO, SLEEP_IND, ONE_WIRE, 32K_CLKOUT, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO124, 0x00C, GPIO, MMC1, LCD, MMC3, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO125, 0x010, GPIO, MMC1, LCD, MMC3, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO126, 0x014, GPIO, MMC1, LCD, MMC3, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO127, 0x018, GPIO, NONE, LCD, MMC3, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO128, 0x01C, GPIO, NONE, LCD, MMC3, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO129, 0x020, GPIO, MMC1, LCD, MMC3, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO130, 0x024, GPIO, MMC1, LCD, MMC3, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO131, 0x028, GPIO, MMC1, NONE, MSP, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO132, 0x02C, GPIO, MMC1, PRI_JTAG, MSP, SSP3, AAS_JTAG, NONE, NONE), + MFPR_MMP2(GPIO133, 0x030, GPIO, MMC1, PRI_JTAG, MSP, SSP3, AAS_JTAG, NONE, NONE), + MFPR_MMP2(GPIO134, 0x034, GPIO, MMC1, PRI_JTAG, MSP, SSP3, AAS_JTAG, NONE, NONE), + MFPR_MMP2(GPIO135, 0x038, GPIO, NONE, LCD, MMC3, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO136, 0x03C, GPIO, MMC1, PRI_JTAG, MSP, SSP3, AAS_JTAG, NONE, NONE), + MFPR_MMP2(GPIO137, 0x040, GPIO, HDMI, LCD, MSP, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO138, 0x044, GPIO, NONE, LCD, MMC3, SMC, NONE, NONE, NONE), + MFPR_MMP2(GPIO139, 0x048, GPIO, MMC1, PRI_JTAG, MSP, NONE, AAS_JTAG, NONE, NONE), + MFPR_MMP2(GPIO140, 0x04C, GPIO, MMC1, LCD, NONE, NONE, UART2, UART1, NONE), + MFPR_MMP2(GPIO141, 0x050, GPIO, MMC1, LCD, NONE, NONE, UART2, UART1, NONE), + MFPR_MMP2(GPIO142, 0x008, USIM, GPIO, FSIC, KP_DK, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO143, 0x220, NAND, GPIO, SMC, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO144, 0x224, NAND, GPIO, SMC_INT, SMC, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO145, 0x228, SMC, GPIO, NONE, NONE, SMC, NONE, NONE, NONE), + MFPR_MMP2(GPIO146, 0x22C, SMC, GPIO, NONE, NONE, SMC, NONE, NONE, NONE), + MFPR_MMP2(GPIO147, 0x230, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO148, 0x234, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO149, 0x238, NAND, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO150, 0x23C, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO151, 0x240, SMC, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO152, 0x248, SMC, GPIO, NONE, NONE, SMC, NONE, NONE, NONE), + MFPR_MMP2(GPIO153, 0x24C, SMC, GPIO, NONE, NONE, SMC, NONE, NONE, NONE), + MFPR_MMP2(GPIO154, 0x254, SMC_INT, GPIO, SMC, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO155, 0x258, EXT_DMA, GPIO, SMC, NONE, EXT_DMA, NONE, NONE, NONE), + MFPR_MMP2(GPIO156, 0x14C, PRI_JTAG, GPIO, PWM, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO157, 0x150, PRI_JTAG, GPIO, PWM, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO158, 0x154, PRI_JTAG, GPIO, PWM, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO159, 0x158, PRI_JTAG, GPIO, PWM, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO160, 0x250, NAND, GPIO, SMC, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO161, 0x210, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO162, 0x20C, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO163, 0x208, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO164, 0x204, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO165, 0x1EC, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO166, 0x1E8, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO167, 0x1E4, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO168, 0x1E0, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(TWSI4_SCL, 0x2BC, TWSI4, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(TWSI4_SDA, 0x2C0, TWSI4, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(G_CLKREQ, 0x160, G_CLKREQ, ONE_WIRE, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(VCXO_REQ, 0x168, VCXO_REQ, ONE_WIRE, PLL, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(VCXO_OUT, 0x16C, VCXO_OUT, 32K_CLKOUT, NONE, NONE, NONE, NONE, NONE, NONE), +}; + +static const unsigned mmp2_uart1_pin1[] = {GPIO29, GPIO30, GPIO31, GPIO32}; +static const unsigned mmp2_uart1_pin2[] = {GPIO45, GPIO46}; +static const unsigned mmp2_uart1_pin3[] = {GPIO140, GPIO141}; +static const unsigned mmp2_uart2_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40}; +static const unsigned mmp2_uart2_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned mmp2_uart2_pin3[] = {GPIO47, GPIO48, GPIO49, GPIO50}; +static const unsigned mmp2_uart2_pin4[] = {GPIO74, GPIO75, GPIO76, GPIO77}; +static const unsigned mmp2_uart2_pin5[] = {GPIO55, GPIO56}; +static const unsigned mmp2_uart2_pin6[] = {GPIO140, GPIO141}; +static const unsigned mmp2_uart3_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40}; +static const unsigned mmp2_uart3_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned mmp2_uart3_pin3[] = {GPIO51, GPIO52, GPIO53, GPIO54}; +static const unsigned mmp2_uart3_pin4[] = {GPIO59, GPIO60, GPIO61, GPIO62}; +static const unsigned mmp2_uart3_pin5[] = {GPIO115, GPIO116, GPIO117, GPIO118}; +static const unsigned mmp2_uart3_pin6[] = {GPIO51, GPIO52}; +static const unsigned mmp2_uart4_pin1[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned mmp2_uart4_pin2[] = {GPIO63, GPIO64, GPIO65, GPIO66}; +static const unsigned mmp2_uart4_pin3[] = {GPIO74, GPIO75, GPIO76, GPIO77}; +static const unsigned mmp2_uart4_pin4[] = {GPIO115, GPIO116, GPIO117, GPIO118}; +static const unsigned mmp2_uart4_pin5[] = {GPIO59, GPIO60}; +static const unsigned mmp2_kpdk_pin1[] = {GPIO16, GPIO17, GPIO18, GPIO19}; +static const unsigned mmp2_kpdk_pin2[] = {GPIO16, GPIO17}; +static const unsigned mmp2_twsi2_pin1[] = {GPIO37, GPIO38}; +static const unsigned mmp2_twsi2_pin2[] = {GPIO39, GPIO40}; +static const unsigned mmp2_twsi2_pin3[] = {GPIO43, GPIO44}; +static const unsigned mmp2_twsi2_pin4[] = {GPIO53, GPIO54}; +static const unsigned mmp2_twsi2_pin5[] = {GPIO55, GPIO56}; +static const unsigned mmp2_twsi3_pin1[] = {GPIO71, GPIO72}; +static const unsigned mmp2_twsi3_pin2[] = {GPIO95, GPIO96}; +static const unsigned mmp2_twsi4_pin1[] = {TWSI4_SCL, TWSI4_SDA}; +static const unsigned mmp2_twsi5_pin1[] = {GPIO41, GPIO42}; +static const unsigned mmp2_twsi5_pin2[] = {GPIO84, GPIO85}; +static const unsigned mmp2_twsi5_pin3[] = {GPIO99, GPIO100}; +static const unsigned mmp2_twsi6_pin1[] = {GPIO47, GPIO48}; +static const unsigned mmp2_twsi6_pin2[] = {GPIO86, GPIO87}; +static const unsigned mmp2_twsi6_pin3[] = {GPIO97, GPIO98}; +static const unsigned mmp2_ccic1_pin1[] = {GPIO12, GPIO13, GPIO14, GPIO15, + GPIO16, GPIO17, GPIO18, GPIO19, GPIO20, GPIO21, GPIO22, GPIO23}; +static const unsigned mmp2_ccic1_pin2[] = {GPIO59, GPIO60, GPIO61, GPIO62, + GPIO63, GPIO64, GPIO65, GPIO66, GPIO67, GPIO68, GPIO69, GPIO70}; +static const unsigned mmp2_ccic2_pin1[] = {GPIO59, GPIO60, GPIO61, GPIO62, + GPIO63, GPIO64, GPIO65, GPIO66, GPIO67, GPIO68, GPIO69, GPIO70}; +static const unsigned mmp2_ccic2_pin2[] = {GPIO82, GPIO83, GPIO86, GPIO87, + GPIO88, GPIO89, GPIO90, GPIO91, GPIO92, GPIO93, GPIO94, GPIO95}; +static const unsigned mmp2_ulpi_pin1[] = {GPIO59, GPIO60, GPIO61, GPIO62, + GPIO63, GPIO64, GPIO65, GPIO66, GPIO67, GPIO68, GPIO69, GPIO70}; +static const unsigned mmp2_ro_pin1[] = {GPIO16, GPIO17}; +static const unsigned mmp2_ro_pin2[] = {GPIO18, GPIO19}; +static const unsigned mmp2_ro_pin3[] = {GPIO51, GPIO52}; +static const unsigned mmp2_ro_pin4[] = {GPIO55, GPIO56}; +static const unsigned mmp2_i2s_pin1[] = {GPIO24, GPIO25, GPIO26, GPIO27, + GPIO28}; +static const unsigned mmp2_i2s_pin2[] = {GPIO33, GPIO34, GPIO35, GPIO36}; +static const unsigned mmp2_ssp1_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40}; +static const unsigned mmp2_ssp1_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned mmp2_ssp1_pin3[] = {GPIO115, GPIO116, GPIO117, GPIO118}; +static const unsigned mmp2_ssp2_pin1[] = {GPIO47, GPIO48, GPIO49, GPIO50}; +static const unsigned mmp2_ssp3_pin1[] = {GPIO119, GPIO120, GPIO121, GPIO122}; +static const unsigned mmp2_ssp3_pin2[] = {GPIO132, GPIO133, GPIO133, GPIO136}; +static const unsigned mmp2_sspa2_pin1[] = {GPIO25, GPIO26, GPIO27, GPIO28}; +static const unsigned mmp2_sspa2_pin2[] = {GPIO33, GPIO34, GPIO35, GPIO36}; +static const unsigned mmp2_mmc1_pin1[] = {GPIO131, GPIO132, GPIO133, GPIO134, + GPIO136, GPIO139, GPIO140, GPIO141}; +static const unsigned mmp2_mmc2_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40, + GPIO41, GPIO42}; +static const unsigned mmp2_mmc3_pin1[] = {GPIO111, GPIO112, GPIO151, GPIO162, + GPIO163, GPIO164, GPIO165, GPIO166, GPIO167, GPIO168}; + +static struct pxa3xx_pin_group mmp2_grps[] = { + GRP_MMP2("uart1 4p1", UART1, mmp2_uart1_pin1), + GRP_MMP2("uart1 2p2", UART1, mmp2_uart1_pin2), + GRP_MMP2("uart1 2p3", UART1, mmp2_uart1_pin3), + GRP_MMP2("uart2 4p1", UART2, mmp2_uart2_pin1), + GRP_MMP2("uart2 4p2", UART2, mmp2_uart2_pin2), + GRP_MMP2("uart2 4p3", UART2, mmp2_uart2_pin3), + GRP_MMP2("uart2 4p4", UART2, mmp2_uart2_pin4), + GRP_MMP2("uart2 2p5", UART2, mmp2_uart2_pin5), + GRP_MMP2("uart2 2p6", UART2, mmp2_uart2_pin6), + GRP_MMP2("uart3 4p1", UART3, mmp2_uart3_pin1), + GRP_MMP2("uart3 4p2", UART3, mmp2_uart3_pin2), + GRP_MMP2("uart3 4p3", UART3, mmp2_uart3_pin3), + GRP_MMP2("uart3 4p4", UART3, mmp2_uart3_pin4), + GRP_MMP2("uart3 4p5", UART3, mmp2_uart3_pin5), + GRP_MMP2("uart3 2p6", UART3, mmp2_uart3_pin6), + GRP_MMP2("uart4 4p1", UART4, mmp2_uart4_pin1), + GRP_MMP2("uart4 4p2", UART4, mmp2_uart4_pin2), + GRP_MMP2("uart4 4p3", UART4, mmp2_uart4_pin3), + GRP_MMP2("uart4 4p4", UART4, mmp2_uart4_pin4), + GRP_MMP2("uart4 2p5", UART4, mmp2_uart4_pin5), + GRP_MMP2("kpdk 4p1", KP_DK, mmp2_kpdk_pin1), + GRP_MMP2("kpdk 4p2", KP_DK, mmp2_kpdk_pin2), + GRP_MMP2("twsi2-1", TWSI2, mmp2_twsi2_pin1), + GRP_MMP2("twsi2-2", TWSI2, mmp2_twsi2_pin2), + GRP_MMP2("twsi2-3", TWSI2, mmp2_twsi2_pin3), + GRP_MMP2("twsi2-4", TWSI2, mmp2_twsi2_pin4), + GRP_MMP2("twsi2-5", TWSI2, mmp2_twsi2_pin5), + GRP_MMP2("twsi3-1", TWSI3, mmp2_twsi3_pin1), + GRP_MMP2("twsi3-2", TWSI3, mmp2_twsi3_pin2), + GRP_MMP2("twsi4", TWSI4, mmp2_twsi4_pin1), + GRP_MMP2("twsi5-1", TWSI5, mmp2_twsi5_pin1), + GRP_MMP2("twsi5-2", TWSI5, mmp2_twsi5_pin2), + GRP_MMP2("twsi5-3", TWSI5, mmp2_twsi5_pin3), + GRP_MMP2("twsi6-1", TWSI6, mmp2_twsi6_pin1), + GRP_MMP2("twsi6-2", TWSI6, mmp2_twsi6_pin2), + GRP_MMP2("twsi6-3", TWSI6, mmp2_twsi6_pin3), + GRP_MMP2("ccic1-1", CCIC1, mmp2_ccic1_pin1), + GRP_MMP2("ccic1-2", CCIC1, mmp2_ccic1_pin2), + GRP_MMP2("ccic2-1", CCIC2, mmp2_ccic2_pin1), + GRP_MMP2("ccic2-1", CCIC2, mmp2_ccic2_pin2), + GRP_MMP2("ulpi", ULPI, mmp2_ulpi_pin1), + GRP_MMP2("ro-1", ROT, mmp2_ro_pin1), + GRP_MMP2("ro-2", ROT, mmp2_ro_pin2), + GRP_MMP2("ro-3", ROT, mmp2_ro_pin3), + GRP_MMP2("ro-4", ROT, mmp2_ro_pin4), + GRP_MMP2("i2s 5p1", I2S, mmp2_i2s_pin1), + GRP_MMP2("i2s 4p2", I2S, mmp2_i2s_pin2), + GRP_MMP2("ssp1 4p1", SSP1, mmp2_ssp1_pin1), + GRP_MMP2("ssp1 4p2", SSP1, mmp2_ssp1_pin2), + GRP_MMP2("ssp1 4p3", SSP1, mmp2_ssp1_pin3), + GRP_MMP2("ssp2 4p1", SSP2, mmp2_ssp2_pin1), + GRP_MMP2("ssp3 4p1", SSP3, mmp2_ssp3_pin1), + GRP_MMP2("ssp3 4p2", SSP3, mmp2_ssp3_pin2), + GRP_MMP2("sspa2 4p1", SSPA2, mmp2_sspa2_pin1), + GRP_MMP2("sspa2 4p2", SSPA2, mmp2_sspa2_pin2), + GRP_MMP2("mmc1 8p1", MMC1, mmp2_mmc1_pin1), + GRP_MMP2("mmc2 6p1", MMC2, mmp2_mmc2_pin1), + GRP_MMP2("mmc3 10p1", MMC3, mmp2_mmc3_pin1), +}; + +static const char * const mmp2_uart1_grps[] = {"uart1 4p1", "uart1 2p2", + "uart1 2p3"}; +static const char * const mmp2_uart2_grps[] = {"uart2 4p1", "uart2 4p2", + "uart2 4p3", "uart2 4p4", "uart2 4p5", "uart2 4p6"}; +static const char * const mmp2_uart3_grps[] = {"uart3 4p1", "uart3 4p2", + "uart3 4p3", "uart3 4p4", "uart3 4p5", "uart3 2p6"}; +static const char * const mmp2_uart4_grps[] = {"uart4 4p1", "uart4 4p2", + "uart4 4p3", "uart4 4p4", "uart4 2p5"}; +static const char * const mmp2_kpdk_grps[] = {"kpdk 4p1", "kpdk 4p2"}; +static const char * const mmp2_twsi2_grps[] = {"twsi2-1", "twsi2-2", + "twsi2-3", "twsi2-4", "twsi2-5"}; +static const char * const mmp2_twsi3_grps[] = {"twsi3-1", "twsi3-2"}; +static const char * const mmp2_twsi4_grps[] = {"twsi4"}; +static const char * const mmp2_twsi5_grps[] = {"twsi5-1", "twsi5-2", + "twsi5-3"}; +static const char * const mmp2_twsi6_grps[] = {"twsi6-1", "twsi6-2", + "twsi6-3"}; +static const char * const mmp2_ccic1_grps[] = {"ccic1-1", "ccic1-2"}; +static const char * const mmp2_ccic2_grps[] = {"ccic2-1", "ccic2-2"}; +static const char * const mmp2_ulpi_grps[] = {"ulpi"}; +static const char * const mmp2_ro_grps[] = {"ro-1", "ro-2", "ro-3", "ro-4"}; +static const char * const mmp2_i2s_grps[] = {"i2s 5p1", "i2s 4p2"}; +static const char * const mmp2_ssp1_grps[] = {"ssp1 4p1", "ssp1 4p2", + "ssp1 4p3"}; +static const char * const mmp2_ssp2_grps[] = {"ssp2 4p1"}; +static const char * const mmp2_ssp3_grps[] = {"ssp3 4p1", "ssp3 4p2"}; +static const char * const mmp2_sspa2_grps[] = {"sspa2 4p1", "sspa2 4p2"}; +static const char * const mmp2_mmc1_grps[] = {"mmc1 8p1"}; +static const char * const mmp2_mmc2_grps[] = {"mmc2 6p1"}; +static const char * const mmp2_mmc3_grps[] = {"mmc3 10p1"}; + +static struct pxa3xx_pmx_func mmp2_funcs[] = { + {"uart1", ARRAY_AND_SIZE(mmp2_uart1_grps)}, + {"uart2", ARRAY_AND_SIZE(mmp2_uart2_grps)}, + {"uart3", ARRAY_AND_SIZE(mmp2_uart3_grps)}, + {"uart4", ARRAY_AND_SIZE(mmp2_uart4_grps)}, + {"kpdk", ARRAY_AND_SIZE(mmp2_kpdk_grps)}, + {"twsi2", ARRAY_AND_SIZE(mmp2_twsi2_grps)}, + {"twsi3", ARRAY_AND_SIZE(mmp2_twsi3_grps)}, + {"twsi4", ARRAY_AND_SIZE(mmp2_twsi4_grps)}, + {"twsi5", ARRAY_AND_SIZE(mmp2_twsi5_grps)}, + {"twsi6", ARRAY_AND_SIZE(mmp2_twsi6_grps)}, + {"ccic1", ARRAY_AND_SIZE(mmp2_ccic1_grps)}, + {"ccic2", ARRAY_AND_SIZE(mmp2_ccic2_grps)}, + {"ulpi", ARRAY_AND_SIZE(mmp2_ulpi_grps)}, + {"ro", ARRAY_AND_SIZE(mmp2_ro_grps)}, + {"i2s", ARRAY_AND_SIZE(mmp2_i2s_grps)}, + {"ssp1", ARRAY_AND_SIZE(mmp2_ssp1_grps)}, + {"ssp2", ARRAY_AND_SIZE(mmp2_ssp2_grps)}, + {"ssp3", ARRAY_AND_SIZE(mmp2_ssp3_grps)}, + {"sspa2", ARRAY_AND_SIZE(mmp2_sspa2_grps)}, + {"mmc1", ARRAY_AND_SIZE(mmp2_mmc1_grps)}, + {"mmc2", ARRAY_AND_SIZE(mmp2_mmc2_grps)}, + {"mmc3", ARRAY_AND_SIZE(mmp2_mmc3_grps)}, +}; + +static struct pinctrl_desc mmp2_pctrl_desc = { + .name = "mmp2-pinctrl", + .owner = THIS_MODULE, +}; + +static struct pxa3xx_pinmux_info mmp2_info = { + .mfp = mmp2_mfp, + .num_mfp = ARRAY_SIZE(mmp2_mfp), + .grps = mmp2_grps, + .num_grps = ARRAY_SIZE(mmp2_grps), + .funcs = mmp2_funcs, + .num_funcs = ARRAY_SIZE(mmp2_funcs), + .num_gpio = 169, + .desc = &mmp2_pctrl_desc, + .pads = mmp2_pads, + .num_pads = ARRAY_SIZE(mmp2_pads), + + .cputype = PINCTRL_MMP2, + .ds_mask = MMP2_DS_MASK, + .ds_shift = MMP2_DS_SHIFT, +}; + +static int __devinit mmp2_pinmux_probe(struct platform_device *pdev) +{ + return pxa3xx_pinctrl_register(pdev, &mmp2_info); +} + +static int __devexit mmp2_pinmux_remove(struct platform_device *pdev) +{ + return pxa3xx_pinctrl_unregister(pdev); +} + +static struct platform_driver mmp2_pinmux_driver = { + .driver = { + .name = "mmp2-pinmux", + .owner = THIS_MODULE, + }, + .probe = mmp2_pinmux_probe, + .remove = __devexit_p(mmp2_pinmux_remove), +}; + +static int __init mmp2_pinmux_init(void) +{ + return platform_driver_register(&mmp2_pinmux_driver); +} +core_initcall_sync(mmp2_pinmux_init); + +static void __exit mmp2_pinmux_exit(void) +{ + platform_driver_unregister(&mmp2_pinmux_driver); +} +module_exit(mmp2_pinmux_exit); + +MODULE_AUTHOR("Haojian Zhuang "); +MODULE_DESCRIPTION("PXA3xx pin control driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/pinctrl-pxa168.c b/drivers/pinctrl/pinctrl-pxa168.c new file mode 100644 index 00000000000..c1997fa7f28 --- /dev/null +++ b/drivers/pinctrl/pinctrl-pxa168.c @@ -0,0 +1,651 @@ +/* + * linux/drivers/pinctrl/pinmux-pxa168.c + * + * 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 + * publishhed by the Free Software Foundation. + * + * Copyright (C) 2011, Marvell Technology Group Ltd. + * + * Author: Haojian Zhuang + * + */ + +#include +#include +#include +#include +#include "pinctrl-pxa3xx.h" + +#define PXA168_DS_MASK 0x1800 +#define PXA168_DS_SHIFT 11 +#define PXA168_SLEEP_MASK 0x38 +#define PXA168_SLEEP_SELECT (1 << 9) +#define PXA168_SLEEP_DATA (1 << 8) +#define PXA168_SLEEP_DIR (1 << 7) + +#define MFPR_168(a, r, f0, f1, f2, f3, f4, f5, f6, f7) \ + { \ + .name = #a, \ + .pin = a, \ + .mfpr = r, \ + .func = { \ + PXA168_MUX_##f0, \ + PXA168_MUX_##f1, \ + PXA168_MUX_##f2, \ + PXA168_MUX_##f3, \ + PXA168_MUX_##f4, \ + PXA168_MUX_##f5, \ + PXA168_MUX_##f6, \ + PXA168_MUX_##f7, \ + }, \ + } + +#define GRP_168(a, m, p) \ + { .name = a, .mux = PXA168_MUX_##m, .pins = p, .npins = ARRAY_SIZE(p), } + +/* 131 pins */ +enum pxa168_pin_list { + /* 0~122: GPIO0~GPIO122 */ + PWR_SCL = 123, + PWR_SDA, + TDI, + TMS, + TCK, + TDO, + TRST, + WAKEUP = 130, +}; + +enum pxa168_mux { + /* PXA3xx_MUX_GPIO = 0 (predefined in pinctrl-pxa3xx.h) */ + PXA168_MUX_GPIO = 0, + PXA168_MUX_DFIO, + PXA168_MUX_NAND, + PXA168_MUX_SMC, + PXA168_MUX_SMC_CS0, + PXA168_MUX_SMC_CS1, + PXA168_MUX_SMC_INT, + PXA168_MUX_SMC_RDY, + PXA168_MUX_MMC1, + PXA168_MUX_MMC2, + PXA168_MUX_MMC2_CMD, + PXA168_MUX_MMC2_CLK, + PXA168_MUX_MMC3, + PXA168_MUX_MMC3_CMD, + PXA168_MUX_MMC3_CLK, + PXA168_MUX_MMC4, + PXA168_MUX_MSP, + PXA168_MUX_MSP_DAT3, + PXA168_MUX_MSP_INS, + PXA168_MUX_I2C, + PXA168_MUX_PWRI2C, + PXA168_MUX_AC97, + PXA168_MUX_AC97_SYSCLK, + PXA168_MUX_PWM, + PXA168_MUX_PWM1, + PXA168_MUX_XD, + PXA168_MUX_XP, + PXA168_MUX_LCD, + PXA168_MUX_CCIC, + PXA168_MUX_CF, + PXA168_MUX_CF_RDY, + PXA168_MUX_CF_nINPACK, + PXA168_MUX_CF_nWAIT, + PXA168_MUX_KP_MKOUT, + PXA168_MUX_KP_MKIN, + PXA168_MUX_KP_DK, + PXA168_MUX_ETH, + PXA168_MUX_ETH_TX, + PXA168_MUX_ETH_RX, + PXA168_MUX_ONE_WIRE, + PXA168_MUX_UART1, + PXA168_MUX_UART1_TX, + PXA168_MUX_UART1_CTS, + PXA168_MUX_UART1_nRI, + PXA168_MUX_UART1_DTR, + PXA168_MUX_UART2, + PXA168_MUX_UART2_TX, + PXA168_MUX_UART3, + PXA168_MUX_UART3_TX, + PXA168_MUX_UART3_CTS, + PXA168_MUX_SSP1, + PXA168_MUX_SSP1_TX, + PXA168_MUX_SSP2, + PXA168_MUX_SSP2_TX, + PXA168_MUX_SSP3, + PXA168_MUX_SSP3_TX, + PXA168_MUX_SSP4, + PXA168_MUX_SSP4_TX, + PXA168_MUX_SSP5, + PXA168_MUX_SSP5_TX, + PXA168_MUX_USB, + PXA168_MUX_JTAG, + PXA168_MUX_RESET, + PXA168_MUX_WAKEUP, + PXA168_MUX_EXT_32K_IN, + PXA168_MUX_NONE = 0xffff, +}; + +static struct pinctrl_pin_desc pxa168_pads[] = { + PINCTRL_PIN(GPIO0, "GPIO0"), + PINCTRL_PIN(GPIO1, "GPIO1"), + PINCTRL_PIN(GPIO2, "GPIO2"), + PINCTRL_PIN(GPIO3, "GPIO3"), + PINCTRL_PIN(GPIO4, "GPIO4"), + PINCTRL_PIN(GPIO5, "GPIO5"), + PINCTRL_PIN(GPIO6, "GPIO6"), + PINCTRL_PIN(GPIO7, "GPIO7"), + PINCTRL_PIN(GPIO8, "GPIO8"), + PINCTRL_PIN(GPIO9, "GPIO9"), + PINCTRL_PIN(GPIO10, "GPIO10"), + PINCTRL_PIN(GPIO11, "GPIO11"), + PINCTRL_PIN(GPIO12, "GPIO12"), + PINCTRL_PIN(GPIO13, "GPIO13"), + PINCTRL_PIN(GPIO14, "GPIO14"), + PINCTRL_PIN(GPIO15, "GPIO15"), + PINCTRL_PIN(GPIO16, "GPIO16"), + PINCTRL_PIN(GPIO17, "GPIO17"), + PINCTRL_PIN(GPIO18, "GPIO18"), + PINCTRL_PIN(GPIO19, "GPIO19"), + PINCTRL_PIN(GPIO20, "GPIO20"), + PINCTRL_PIN(GPIO21, "GPIO21"), + PINCTRL_PIN(GPIO22, "GPIO22"), + PINCTRL_PIN(GPIO23, "GPIO23"), + PINCTRL_PIN(GPIO24, "GPIO24"), + PINCTRL_PIN(GPIO25, "GPIO25"), + PINCTRL_PIN(GPIO26, "GPIO26"), + PINCTRL_PIN(GPIO27, "GPIO27"), + PINCTRL_PIN(GPIO28, "GPIO28"), + PINCTRL_PIN(GPIO29, "GPIO29"), + PINCTRL_PIN(GPIO30, "GPIO30"), + PINCTRL_PIN(GPIO31, "GPIO31"), + PINCTRL_PIN(GPIO32, "GPIO32"), + PINCTRL_PIN(GPIO33, "GPIO33"), + PINCTRL_PIN(GPIO34, "GPIO34"), + PINCTRL_PIN(GPIO35, "GPIO35"), + PINCTRL_PIN(GPIO36, "GPIO36"), + PINCTRL_PIN(GPIO37, "GPIO37"), + PINCTRL_PIN(GPIO38, "GPIO38"), + PINCTRL_PIN(GPIO39, "GPIO39"), + PINCTRL_PIN(GPIO40, "GPIO40"), + PINCTRL_PIN(GPIO41, "GPIO41"), + PINCTRL_PIN(GPIO42, "GPIO42"), + PINCTRL_PIN(GPIO43, "GPIO43"), + PINCTRL_PIN(GPIO44, "GPIO44"), + PINCTRL_PIN(GPIO45, "GPIO45"), + PINCTRL_PIN(GPIO46, "GPIO46"), + PINCTRL_PIN(GPIO47, "GPIO47"), + PINCTRL_PIN(GPIO48, "GPIO48"), + PINCTRL_PIN(GPIO49, "GPIO49"), + PINCTRL_PIN(GPIO50, "GPIO50"), + PINCTRL_PIN(GPIO51, "GPIO51"), + PINCTRL_PIN(GPIO52, "GPIO52"), + PINCTRL_PIN(GPIO53, "GPIO53"), + PINCTRL_PIN(GPIO54, "GPIO54"), + PINCTRL_PIN(GPIO55, "GPIO55"), + PINCTRL_PIN(GPIO56, "GPIO56"), + PINCTRL_PIN(GPIO57, "GPIO57"), + PINCTRL_PIN(GPIO58, "GPIO58"), + PINCTRL_PIN(GPIO59, "GPIO59"), + PINCTRL_PIN(GPIO60, "GPIO60"), + PINCTRL_PIN(GPIO61, "GPIO61"), + PINCTRL_PIN(GPIO62, "GPIO62"), + PINCTRL_PIN(GPIO63, "GPIO63"), + PINCTRL_PIN(GPIO64, "GPIO64"), + PINCTRL_PIN(GPIO65, "GPIO65"), + PINCTRL_PIN(GPIO66, "GPIO66"), + PINCTRL_PIN(GPIO67, "GPIO67"), + PINCTRL_PIN(GPIO68, "GPIO68"), + PINCTRL_PIN(GPIO69, "GPIO69"), + PINCTRL_PIN(GPIO70, "GPIO70"), + PINCTRL_PIN(GPIO71, "GPIO71"), + PINCTRL_PIN(GPIO72, "GPIO72"), + PINCTRL_PIN(GPIO73, "GPIO73"), + PINCTRL_PIN(GPIO74, "GPIO74"), + PINCTRL_PIN(GPIO75, "GPIO75"), + PINCTRL_PIN(GPIO76, "GPIO76"), + PINCTRL_PIN(GPIO77, "GPIO77"), + PINCTRL_PIN(GPIO78, "GPIO78"), + PINCTRL_PIN(GPIO79, "GPIO79"), + PINCTRL_PIN(GPIO80, "GPIO80"), + PINCTRL_PIN(GPIO81, "GPIO81"), + PINCTRL_PIN(GPIO82, "GPIO82"), + PINCTRL_PIN(GPIO83, "GPIO83"), + PINCTRL_PIN(GPIO84, "GPIO84"), + PINCTRL_PIN(GPIO85, "GPIO85"), + PINCTRL_PIN(GPIO86, "GPIO86"), + PINCTRL_PIN(GPIO87, "GPIO87"), + PINCTRL_PIN(GPIO88, "GPIO88"), + PINCTRL_PIN(GPIO89, "GPIO89"), + PINCTRL_PIN(GPIO90, "GPIO90"), + PINCTRL_PIN(GPIO91, "GPIO91"), + PINCTRL_PIN(GPIO92, "GPIO92"), + PINCTRL_PIN(GPIO93, "GPIO93"), + PINCTRL_PIN(GPIO94, "GPIO94"), + PINCTRL_PIN(GPIO95, "GPIO95"), + PINCTRL_PIN(GPIO96, "GPIO96"), + PINCTRL_PIN(GPIO97, "GPIO97"), + PINCTRL_PIN(GPIO98, "GPIO98"), + PINCTRL_PIN(GPIO99, "GPIO99"), + PINCTRL_PIN(GPIO100, "GPIO100"), + PINCTRL_PIN(GPIO101, "GPIO101"), + PINCTRL_PIN(GPIO102, "GPIO102"), + PINCTRL_PIN(GPIO103, "GPIO103"), + PINCTRL_PIN(GPIO104, "GPIO104"), + PINCTRL_PIN(GPIO105, "GPIO105"), + PINCTRL_PIN(GPIO106, "GPIO106"), + PINCTRL_PIN(GPIO107, "GPIO107"), + PINCTRL_PIN(GPIO108, "GPIO108"), + PINCTRL_PIN(GPIO109, "GPIO109"), + PINCTRL_PIN(GPIO110, "GPIO110"), + PINCTRL_PIN(GPIO111, "GPIO111"), + PINCTRL_PIN(GPIO112, "GPIO112"), + PINCTRL_PIN(GPIO113, "GPIO113"), + PINCTRL_PIN(GPIO114, "GPIO114"), + PINCTRL_PIN(GPIO115, "GPIO115"), + PINCTRL_PIN(GPIO116, "GPIO116"), + PINCTRL_PIN(GPIO117, "GPIO117"), + PINCTRL_PIN(GPIO118, "GPIO118"), + PINCTRL_PIN(GPIO119, "GPIO119"), + PINCTRL_PIN(GPIO120, "GPIO120"), + PINCTRL_PIN(GPIO121, "GPIO121"), + PINCTRL_PIN(GPIO122, "GPIO122"), + PINCTRL_PIN(PWR_SCL, "PWR_SCL"), + PINCTRL_PIN(PWR_SDA, "PWR_SDA"), + PINCTRL_PIN(TDI, "TDI"), + PINCTRL_PIN(TMS, "TMS"), + PINCTRL_PIN(TCK, "TCK"), + PINCTRL_PIN(TDO, "TDO"), + PINCTRL_PIN(TRST, "TRST"), + PINCTRL_PIN(WAKEUP, "WAKEUP"), +}; + +struct pxa3xx_mfp_pin pxa168_mfp[] = { + /* pin offs f0 f1 f2 f3 f4 f5 f6 f7 */ + MFPR_168(GPIO0, 0x04C, DFIO, NONE, NONE, MSP, MMC3_CMD, GPIO, MMC3, NONE), + MFPR_168(GPIO1, 0x050, DFIO, NONE, NONE, MSP, MMC3_CLK, GPIO, MMC3, NONE), + MFPR_168(GPIO2, 0x054, DFIO, NONE, NONE, MSP, NONE, GPIO, MMC3, NONE), + MFPR_168(GPIO3, 0x058, DFIO, NONE, NONE, NONE, NONE, GPIO, MMC3, NONE), + MFPR_168(GPIO4, 0x05C, DFIO, NONE, NONE, MSP_DAT3, NONE, GPIO, MMC3, NONE), + MFPR_168(GPIO5, 0x060, DFIO, NONE, NONE, MSP, NONE, GPIO, MMC3, NONE), + MFPR_168(GPIO6, 0x064, DFIO, NONE, NONE, MSP, NONE, GPIO, MMC3, NONE), + MFPR_168(GPIO7, 0x068, DFIO, NONE, NONE, MSP, NONE, GPIO, MMC3, NONE), + MFPR_168(GPIO8, 0x06C, DFIO, MMC2, UART3_TX, NONE, MMC2_CMD, GPIO, MMC3_CLK, NONE), + MFPR_168(GPIO9, 0x070, DFIO, MMC2, UART3, NONE, MMC2_CLK, GPIO, MMC3_CMD, NONE), + MFPR_168(GPIO10, 0x074, DFIO, MMC2, UART3, NONE, NONE, GPIO, MSP_DAT3, NONE), + MFPR_168(GPIO11, 0x078, DFIO, MMC2, UART3, NONE, NONE, GPIO, MSP, NONE), + MFPR_168(GPIO12, 0x07C, DFIO, MMC2, UART3, NONE, NONE, GPIO, MSP, NONE), + MFPR_168(GPIO13, 0x080, DFIO, MMC2, UART3, NONE, NONE, GPIO, MSP, NONE), + MFPR_168(GPIO14, 0x084, DFIO, MMC2, NONE, NONE, NONE, GPIO, MSP, NONE), + MFPR_168(GPIO15, 0x088, DFIO, MMC2, NONE, NONE, NONE, GPIO, MSP, NONE), + MFPR_168(GPIO16, 0x08C, GPIO, NAND, SMC_CS0, SMC_CS1, NONE, NONE, MMC3, NONE), + MFPR_168(GPIO17, 0x090, NAND, NONE, NONE, NONE, NONE, GPIO, MSP, NONE), + MFPR_168(GPIO18, 0x094, GPIO, NAND, SMC_CS1, SMC_CS0, NONE, NONE, NONE, NONE), + MFPR_168(GPIO19, 0x098, SMC_CS0, NONE, NONE, CF, NONE, GPIO, NONE, NONE), + MFPR_168(GPIO20, 0x09C, GPIO, NONE, SMC_CS1, CF, CF_RDY, NONE, NONE, NONE), + MFPR_168(GPIO21, 0x0A0, NAND, MMC2_CLK, NONE, NONE, NONE, GPIO, NONE, NONE), + MFPR_168(GPIO22, 0x0A4, NAND, MMC2_CMD, NONE, NONE, NONE, GPIO, NONE, NONE), + MFPR_168(GPIO23, 0x0A8, SMC, NAND, NONE, CF, NONE, GPIO, NONE, NONE), + MFPR_168(GPIO24, 0x0AC, NAND, NONE, NONE, NONE, NONE, GPIO, NONE, NONE), + MFPR_168(GPIO25, 0x0B0, SMC, NAND, NONE, CF, NONE, GPIO, NONE, NONE), + MFPR_168(GPIO26, 0x0B4, GPIO, NAND, NONE, NONE, CF, NONE, NONE, NONE), + MFPR_168(GPIO27, 0x0B8, SMC_INT, NAND, SMC, NONE, SMC_RDY, GPIO, NONE, NONE), + MFPR_168(GPIO28, 0x0BC, SMC_RDY, MMC4, SMC, CF_RDY, NONE, GPIO, MMC2_CMD, NONE), + MFPR_168(GPIO29, 0x0C0, SMC, MMC4, NONE, CF, NONE, GPIO, MMC2_CLK, KP_DK), + MFPR_168(GPIO30, 0x0C4, SMC, MMC4, UART3_TX, CF, NONE, GPIO, MMC2, KP_DK), + MFPR_168(GPIO31, 0x0C8, SMC, MMC4, UART3, CF, NONE, GPIO, MMC2, KP_DK), + MFPR_168(GPIO32, 0x0CC, SMC, MMC4, UART3, CF, NONE, GPIO, MMC2, KP_DK), + MFPR_168(GPIO33, 0x0D0, SMC, MMC4, UART3, CF, CF_nINPACK, GPIO, MMC2, KP_DK), + MFPR_168(GPIO34, 0x0D4, GPIO, NONE, SMC_CS1, CF, CF_nWAIT, NONE, MMC3, KP_DK), + MFPR_168(GPIO35, 0x0D8, GPIO, NONE, SMC, CF_nINPACK, NONE, NONE, MMC3_CMD, KP_DK), + MFPR_168(GPIO36, 0x0DC, GPIO, NONE, SMC, CF_nWAIT, NONE, NONE, MMC3_CLK, KP_DK), + MFPR_168(GPIO37, 0x000, GPIO, MMC1, NONE, KP_MKOUT, CCIC, XP, KP_MKIN, KP_DK), + MFPR_168(GPIO38, 0x004, GPIO, MMC1, NONE, KP_MKOUT, CCIC, XP, KP_MKIN, KP_DK), + MFPR_168(GPIO39, 0x008, GPIO, NONE, NONE, KP_MKOUT, CCIC, XP, KP_MKIN, KP_DK), + MFPR_168(GPIO40, 0x00C, GPIO, MMC1, MSP, KP_MKOUT, CCIC, XP, KP_MKIN, KP_DK), + MFPR_168(GPIO41, 0x010, GPIO, MMC1, MSP, NONE, CCIC, XP, KP_MKIN, KP_DK), + MFPR_168(GPIO42, 0x014, GPIO, I2C, NONE, MSP, CCIC, XP, KP_MKIN, KP_DK), + MFPR_168(GPIO43, 0x018, GPIO, MMC1, MSP, MSP_INS, NONE, NONE, KP_MKIN, KP_DK), + MFPR_168(GPIO44, 0x01C, GPIO, MMC1, MSP_DAT3, MSP, CCIC, XP, KP_MKIN, KP_DK), + MFPR_168(GPIO45, 0x020, GPIO, NONE, NONE, MSP, CCIC, XP, NONE, KP_DK), + MFPR_168(GPIO46, 0x024, GPIO, MMC1, MSP_INS, MSP, CCIC, NONE, KP_MKOUT, KP_DK), + MFPR_168(GPIO47, 0x028, GPIO, NONE, NONE, MSP_INS, NONE, XP, NONE, KP_DK), + MFPR_168(GPIO48, 0x02C, GPIO, MMC1, NONE, MSP_DAT3, CCIC, NONE, NONE, KP_DK), + MFPR_168(GPIO49, 0x030, GPIO, MMC1, NONE, MSP, NONE, XD, KP_MKOUT, NONE), + MFPR_168(GPIO50, 0x034, GPIO, I2C, NONE, MSP, CCIC, XD, KP_MKOUT, NONE), + MFPR_168(GPIO51, 0x038, GPIO, MMC1, NONE, MSP, NONE, XD, KP_MKOUT, NONE), + MFPR_168(GPIO52, 0x03C, GPIO, MMC1, NONE, MSP, NONE, XD, KP_MKOUT, NONE), + MFPR_168(GPIO53, 0x040, GPIO, MMC1, NONE, NONE, NONE, XD, KP_MKOUT, NONE), + MFPR_168(GPIO54, 0x044, GPIO, MMC1, NONE, NONE, CCIC, XD, KP_MKOUT, NONE), + MFPR_168(GPIO55, 0x048, GPIO, NONE, NONE, MSP, CCIC, XD, KP_MKOUT, NONE), + MFPR_168(GPIO56, 0x0E0, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO57, 0x0E4, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO58, 0x0E8, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO59, 0x0EC, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO60, 0x0F0, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO61, 0x0F4, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO62, 0x0F8, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO63, 0x0FC, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO64, 0x100, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO65, 0x104, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO66, 0x108, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO67, 0x10C, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO68, 0x110, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE), + MFPR_168(GPIO69, 0x114, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE), + MFPR_168(GPIO70, 0x118, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE), + MFPR_168(GPIO71, 0x11C, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE), + MFPR_168(GPIO72, 0x120, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE), + MFPR_168(GPIO73, 0x124, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE), + MFPR_168(GPIO74, 0x128, GPIO, LCD, PWM, XD, NONE, NONE, NONE, NONE), + MFPR_168(GPIO75, 0x12C, GPIO, LCD, PWM, XD, ONE_WIRE, NONE, NONE, NONE), + MFPR_168(GPIO76, 0x130, GPIO, LCD, PWM, I2C, NONE, NONE, MSP_INS, NONE), + MFPR_168(GPIO77, 0x134, GPIO, LCD, PWM1, I2C, ONE_WIRE, NONE, XD, NONE), + MFPR_168(GPIO78, 0x138, GPIO, LCD, NONE, NONE, NONE, MMC4, NONE, NONE), + MFPR_168(GPIO79, 0x13C, GPIO, LCD, NONE, NONE, ONE_WIRE, MMC4, NONE, NONE), + MFPR_168(GPIO80, 0x140, GPIO, LCD, NONE, I2C, NONE, MMC4, NONE, NONE), + MFPR_168(GPIO81, 0x144, GPIO, LCD, NONE, I2C, ONE_WIRE, MMC4, NONE, NONE), + MFPR_168(GPIO82, 0x148, GPIO, LCD, PWM, NONE, NONE, MMC4, NONE, NONE), + MFPR_168(GPIO83, 0x14C, GPIO, LCD, PWM, NONE, RESET, MMC4, NONE, NONE), + MFPR_168(GPIO84, 0x150, GPIO, NONE, PWM, ONE_WIRE, PWM1, NONE, NONE, EXT_32K_IN), + MFPR_168(GPIO85, 0x154, GPIO, NONE, PWM1, NONE, NONE, NONE, NONE, USB), + MFPR_168(GPIO86, 0x158, GPIO, MMC2, UART2, NONE, JTAG, ETH_TX, SSP5_TX, SSP5), + MFPR_168(GPIO87, 0x15C, GPIO, MMC2, UART2, NONE, JTAG, ETH_TX, SSP5, SSP5_TX), + MFPR_168(GPIO88, 0x160, GPIO, MMC2, UART2, UART2_TX, JTAG, ETH_TX, ETH_RX, SSP5), + MFPR_168(GPIO89, 0x164, GPIO, MMC2, UART2_TX, UART2, JTAG, ETH_TX, ETH_RX, SSP5), + MFPR_168(GPIO90, 0x168, GPIO, MMC2, NONE, SSP3, JTAG, ETH_TX, ETH_RX, NONE), + MFPR_168(GPIO91, 0x16C, GPIO, MMC2, NONE, SSP3, SSP4, ETH_TX, ETH_RX, NONE), + MFPR_168(GPIO92, 0x170, GPIO, MMC2, NONE, SSP3, SSP3_TX, ETH, NONE, NONE), + MFPR_168(GPIO93, 0x174, GPIO, MMC2, NONE, SSP3_TX, SSP3, ETH, NONE, NONE), + MFPR_168(GPIO94, 0x178, GPIO, MMC2_CMD, SSP3, AC97_SYSCLK, AC97, ETH, NONE, NONE), + MFPR_168(GPIO95, 0x17C, GPIO, MMC2_CLK, NONE, NONE, AC97, ETH, NONE, NONE), + MFPR_168(GPIO96, 0x180, GPIO, PWM, NONE, MMC2, NONE, ETH_RX, ETH_TX, NONE), + MFPR_168(GPIO97, 0x184, GPIO, PWM, ONE_WIRE, NONE, NONE, ETH_RX, ETH_TX, NONE), + MFPR_168(GPIO98, 0x188, GPIO, PWM1, UART3_TX, UART3, NONE, ETH_RX, ETH_TX, NONE), + MFPR_168(GPIO99, 0x18C, GPIO, ONE_WIRE, UART3, UART3_TX, NONE, ETH_RX, ETH_TX, NONE), + MFPR_168(GPIO100, 0x190, GPIO, NONE, UART3_CTS, UART3, NONE, ETH, NONE, NONE), + MFPR_168(GPIO101, 0x194, GPIO, NONE, UART3, UART3_CTS, NONE, ETH, NONE, NONE), + MFPR_168(GPIO102, 0x198, GPIO, I2C, UART3, SSP4, NONE, NONE, NONE, NONE), + MFPR_168(GPIO103, 0x19C, GPIO, I2C, UART3, SSP4, SSP2, ETH, NONE, NONE), + MFPR_168(GPIO104, 0x1A0, GPIO, PWM, UART1, SSP4, SSP4_TX, AC97, KP_MKOUT, NONE), + MFPR_168(GPIO105, 0x1A4, GPIO, I2C, UART1, SSP4_TX, SSP4, AC97, KP_MKOUT, NONE), + MFPR_168(GPIO106, 0x1A8, GPIO, I2C, PWM1, AC97_SYSCLK, MMC2, NONE, KP_MKOUT, NONE), + MFPR_168(GPIO107, 0x1AC, GPIO, UART1_TX, UART1, NONE, SSP2, MSP_DAT3, NONE, KP_MKIN), + MFPR_168(GPIO108, 0x1B0, GPIO, UART1, UART1_TX, NONE, SSP2_TX, MSP, NONE, KP_MKIN), + MFPR_168(GPIO109, 0x1B4, GPIO, UART1_CTS, UART1, NONE, AC97_SYSCLK, MSP, NONE, KP_MKIN), + MFPR_168(GPIO110, 0x1B8, GPIO, UART1, UART1_CTS, NONE, SMC_RDY, MSP, NONE, KP_MKIN), + MFPR_168(GPIO111, 0x1BC, GPIO, UART1_nRI, UART1, SSP3, SSP2, MSP, XD, KP_MKOUT), + MFPR_168(GPIO112, 0x1C0, GPIO, UART1_DTR, UART1, ONE_WIRE, SSP2, MSP, XD, KP_MKOUT), + MFPR_168(GPIO113, 0x1C4, GPIO, NONE, NONE, NONE, NONE, NONE, AC97_SYSCLK, NONE), + MFPR_168(GPIO114, 0x1C8, GPIO, SSP1, NONE, NONE, NONE, NONE, AC97, NONE), + MFPR_168(GPIO115, 0x1CC, GPIO, SSP1, NONE, NONE, NONE, NONE, AC97, NONE), + MFPR_168(GPIO116, 0x1D0, GPIO, SSP1_TX, SSP1, NONE, NONE, NONE, AC97, NONE), + MFPR_168(GPIO117, 0x1D4, GPIO, SSP1, SSP1_TX, NONE, MMC2_CMD, NONE, AC97, NONE), + MFPR_168(GPIO118, 0x1D8, GPIO, SSP2, NONE, NONE, MMC2_CLK, NONE, AC97, KP_MKIN), + MFPR_168(GPIO119, 0x1DC, GPIO, SSP2, NONE, NONE, MMC2, NONE, AC97, KP_MKIN), + MFPR_168(GPIO120, 0x1E0, GPIO, SSP2, SSP2_TX, NONE, MMC2, NONE, NONE, KP_MKIN), + MFPR_168(GPIO121, 0x1E4, GPIO, SSP2_TX, SSP2, NONE, MMC2, NONE, NONE, KP_MKIN), + MFPR_168(GPIO122, 0x1E8, GPIO, AC97_SYSCLK, SSP2, PWM, MMC2, NONE, NONE, NONE), + MFPR_168(PWR_SCL, 0x1EC, PWRI2C, NONE, NONE, NONE, NONE, NONE, GPIO, MMC4), + MFPR_168(PWR_SDA, 0x1F0, PWRI2C, NONE, NONE, NONE, NONE, NONE, GPIO, NONE), + MFPR_168(TDI, 0x1F4, JTAG, PWM1, UART2, MMC4, SSP5, NONE, XD, MMC4), + MFPR_168(TMS, 0x1F8, JTAG, PWM, UART2, NONE, SSP5, NONE, XD, MMC4), + MFPR_168(TCK, 0x1FC, JTAG, PWM, UART2, UART2_TX, SSP5, NONE, XD, MMC4), + MFPR_168(TDO, 0x200, JTAG, PWM, UART2_TX, UART2, SSP5_TX, NONE, XD, MMC4), + MFPR_168(TRST, 0x204, JTAG, ONE_WIRE, SSP2, SSP3, AC97_SYSCLK, NONE, XD, MMC4), + MFPR_168(WAKEUP, 0x208, WAKEUP, ONE_WIRE, PWM1, PWM, SSP2, NONE, GPIO, MMC4), +}; + +static const unsigned p168_jtag_pin1[] = {TDI, TMS, TCK, TDO, TRST}; +static const unsigned p168_wakeup_pin1[] = {WAKEUP}; +static const unsigned p168_ssp1rx_pin1[] = {GPIO114, GPIO115, GPIO116}; +static const unsigned p168_ssp1tx_pin1[] = {GPIO117}; +static const unsigned p168_ssp4rx_pin1[] = {GPIO102, GPIO103, GPIO104}; +static const unsigned p168_ssp4tx_pin1[] = {GPIO105}; +static const unsigned p168_ssp5rx_pin1[] = {GPIO86, GPIO88, GPIO89}; +static const unsigned p168_ssp5tx_pin1[] = {GPIO87}; +static const unsigned p168_i2c_pin1[] = {GPIO105, GPIO106}; +static const unsigned p168_pwri2c_pin1[] = {PWR_SCL, PWR_SDA}; +static const unsigned p168_mmc1_pin1[] = {GPIO40, GPIO41, GPIO43, GPIO46, + GPIO49, GPIO51, GPIO52, GPIO53}; +static const unsigned p168_mmc2_data_pin1[] = {GPIO90, GPIO91, GPIO92, GPIO93}; +static const unsigned p168_mmc2_cmd_pin1[] = {GPIO94}; +static const unsigned p168_mmc2_clk_pin1[] = {GPIO95}; +static const unsigned p168_mmc3_data_pin1[] = {GPIO0, GPIO1, GPIO2, GPIO3, + GPIO4, GPIO5, GPIO6, GPIO7}; +static const unsigned p168_mmc3_cmd_pin1[] = {GPIO9}; +static const unsigned p168_mmc3_clk_pin1[] = {GPIO8}; +static const unsigned p168_eth_pin1[] = {GPIO92, GPIO93, GPIO100, GPIO101, + GPIO103}; +static const unsigned p168_ethtx_pin1[] = {GPIO86, GPIO87, GPIO88, GPIO89, + GPIO90, GPIO91}; +static const unsigned p168_ethrx_pin1[] = {GPIO94, GPIO95, GPIO96, GPIO97, + GPIO98, GPIO99}; +static const unsigned p168_uart1rx_pin1[] = {GPIO107}; +static const unsigned p168_uart1tx_pin1[] = {GPIO108}; +static const unsigned p168_uart3rx_pin1[] = {GPIO98, GPIO100, GPIO101}; +static const unsigned p168_uart3tx_pin1[] = {GPIO99}; +static const unsigned p168_msp_pin1[] = {GPIO40, GPIO41, GPIO42, GPIO43, + GPIO44, GPIO50}; +static const unsigned p168_ccic_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40, + GPIO41, GPIO42, GPIO44, GPIO45, GPIO46, GPIO48, GPIO54, GPIO55}; +static const unsigned p168_xd_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40, + GPIO41, GPIO42, GPIO44, GPIO45, GPIO47, GPIO48, GPIO49, GPIO50, + GPIO51, GPIO52}; +static const unsigned p168_lcd_pin1[] = {GPIO56, GPIO57, GPIO58, GPIO59, + GPIO60, GPIO61, GPIO62, GPIO63, GPIO64, GPIO65, GPIO66, GPIO67, + GPIO68, GPIO69, GPIO70, GPIO71, GPIO72, GPIO73, GPIO74, GPIO75, + GPIO76, GPIO77, GPIO78, GPIO79, GPIO80, GPIO81, GPIO82, GPIO83}; +static const unsigned p168_dfio_pin1[] = {GPIO0, GPIO1, GPIO2, GPIO3, + GPIO4, GPIO5, GPIO6, GPIO7, GPIO8, GPIO9, GPIO10, GPIO11, GPIO12, + GPIO13, GPIO14, GPIO15}; +static const unsigned p168_nand_pin1[] = {GPIO16, GPIO17, GPIO21, GPIO22, + GPIO24, GPIO26}; +static const unsigned p168_smc_pin1[] = {GPIO23, GPIO25, GPIO29, GPIO35, + GPIO36}; +static const unsigned p168_smccs0_pin1[] = {GPIO18}; +static const unsigned p168_smccs1_pin1[] = {GPIO34}; +static const unsigned p168_smcrdy_pin1[] = {GPIO28}; +static const unsigned p168_ac97sysclk_pin1[] = {GPIO113}; +static const unsigned p168_ac97_pin1[] = {GPIO114, GPIO115, GPIO117, GPIO118, + GPIO119}; +static const unsigned p168_cf_pin1[] = {GPIO19, GPIO20, GPIO23, GPIO25, + GPIO28, GPIO29, GPIO30, GPIO31, GPIO32, GPIO33, GPIO34, GPIO35, + GPIO36}; +static const unsigned p168_kpmkin_pin1[] = {GPIO109, GPIO110, GPIO121}; +static const unsigned p168_kpmkout_pin1[] = {GPIO111, GPIO112}; +static const unsigned p168_gpio86_pin1[] = {WAKEUP}; +static const unsigned p168_gpio86_pin2[] = {GPIO86}; +static const unsigned p168_gpio87_pin1[] = {GPIO87}; +static const unsigned p168_gpio87_pin2[] = {PWR_SDA}; +static const unsigned p168_gpio88_pin1[] = {GPIO88}; +static const unsigned p168_gpio88_pin2[] = {PWR_SCL}; + +static struct pxa3xx_pin_group pxa168_grps[] = { + GRP_168("uart1rx-1", UART1, p168_uart1rx_pin1), + GRP_168("uart1tx-1", UART1_TX, p168_uart1tx_pin1), + GRP_168("uart3rx-1", UART3, p168_uart3rx_pin1), + GRP_168("uart3tx-1", UART3_TX, p168_uart3tx_pin1), + GRP_168("ssp1rx-1", SSP1, p168_ssp1rx_pin1), + GRP_168("ssp1tx-1", SSP1_TX, p168_ssp1tx_pin1), + GRP_168("ssp4rx-1", SSP4, p168_ssp4rx_pin1), + GRP_168("ssp4tx-1", SSP4_TX, p168_ssp4tx_pin1), + GRP_168("ssp5rx-1", SSP5, p168_ssp5rx_pin1), + GRP_168("ssp5tx-1", SSP5_TX, p168_ssp5tx_pin1), + GRP_168("jtag", JTAG, p168_jtag_pin1), + GRP_168("wakeup", WAKEUP, p168_wakeup_pin1), + GRP_168("i2c", I2C, p168_i2c_pin1), + GRP_168("pwri2c", PWRI2C, p168_pwri2c_pin1), + GRP_168("mmc1 8p1", MMC1, p168_mmc1_pin1), + GRP_168("mmc2 4p1", MMC2, p168_mmc2_data_pin1), + GRP_168("mmc2 cmd1", MMC2_CMD, p168_mmc2_cmd_pin1), + GRP_168("mmc2 clk1", MMC2_CLK, p168_mmc2_clk_pin1), + GRP_168("mmc3 8p1", MMC3, p168_mmc3_data_pin1), + GRP_168("mmc3 cmd1", MMC3_CMD, p168_mmc3_cmd_pin1), + GRP_168("mmc3 clk1", MMC3_CLK, p168_mmc3_clk_pin1), + GRP_168("eth", ETH, p168_eth_pin1), + GRP_168("eth rx", ETH_RX, p168_ethrx_pin1), + GRP_168("eth tx", ETH_TX, p168_ethtx_pin1), + GRP_168("msp", MSP, p168_msp_pin1), + GRP_168("ccic", CCIC, p168_ccic_pin1), + GRP_168("xd", XD, p168_xd_pin1), + GRP_168("lcd", LCD, p168_lcd_pin1), + GRP_168("dfio", DFIO, p168_dfio_pin1), + GRP_168("nand", NAND, p168_nand_pin1), + GRP_168("smc", SMC, p168_smc_pin1), + GRP_168("smc cs0", SMC_CS0, p168_smccs0_pin1), + GRP_168("smc cs1", SMC_CS1, p168_smccs1_pin1), + GRP_168("smc rdy", SMC_RDY, p168_smcrdy_pin1), + GRP_168("ac97 sysclk", AC97_SYSCLK, p168_ac97sysclk_pin1), + GRP_168("ac97", AC97, p168_ac97_pin1), + GRP_168("cf", CF, p168_cf_pin1), + GRP_168("kp mkin 3p1", KP_MKIN, p168_kpmkin_pin1), + GRP_168("kp mkout 2p1", KP_MKOUT, p168_kpmkout_pin1), + GRP_168("gpio86-1", GPIO, p168_gpio86_pin1), + GRP_168("gpio86-2", GPIO, p168_gpio86_pin2), + GRP_168("gpio87-1", GPIO, p168_gpio87_pin1), + GRP_168("gpio87-2", GPIO, p168_gpio87_pin2), + GRP_168("gpio88-1", GPIO, p168_gpio88_pin1), + GRP_168("gpio88-2", GPIO, p168_gpio88_pin2), +}; + +static const char * const p168_uart1rx_grps[] = {"uart1rx-1"}; +static const char * const p168_uart1tx_grps[] = {"uart1tx-1"}; +static const char * const p168_uart3rx_grps[] = {"uart3rx-1"}; +static const char * const p168_uart3tx_grps[] = {"uart3tx-1"}; +static const char * const p168_ssp1rx_grps[] = {"ssp1rx-1"}; +static const char * const p168_ssp1tx_grps[] = {"ssp1tx-1"}; +static const char * const p168_ssp4rx_grps[] = {"ssp4rx-1"}; +static const char * const p168_ssp4tx_grps[] = {"ssp4tx-1"}; +static const char * const p168_ssp5rx_grps[] = {"ssp5rx-1"}; +static const char * const p168_ssp5tx_grps[] = {"ssp5tx-1"}; +static const char * const p168_i2c_grps[] = {"i2c"}; +static const char * const p168_pwri2c_grps[] = {"pwri2c"}; +static const char * const p168_mmc1_grps[] = {"mmc1 8p1"}; +static const char * const p168_mmc2_data_grps[] = {"mmc2 4p1"}; +static const char * const p168_mmc2_cmd_grps[] = {"mmc2 cmd1"}; +static const char * const p168_mmc2_clk_grps[] = {"mmc2 clk1"}; +static const char * const p168_mmc3_data_grps[] = {"mmc3 8p1"}; +static const char * const p168_mmc3_cmd_grps[] = {"mmc3 cmd1"}; +static const char * const p168_mmc3_clk_grps[] = {"mmc3 clk1"}; +static const char * const p168_eth_grps[] = {"eth"}; +static const char * const p168_ethrx_grps[] = {"eth rx"}; +static const char * const p168_ethtx_grps[] = {"eth tx"}; +static const char * const p168_msp_grps[] = {"msp"}; +static const char * const p168_ccic_grps[] = {"ccic"}; +static const char * const p168_xd_grps[] = {"xd"}; +static const char * const p168_lcd_grps[] = {"lcd"}; +static const char * const p168_dfio_grps[] = {"dfio"}; +static const char * const p168_nand_grps[] = {"nand"}; +static const char * const p168_smc_grps[] = {"smc"}; +static const char * const p168_smccs0_grps[] = {"smc cs0"}; +static const char * const p168_smccs1_grps[] = {"smc cs1"}; +static const char * const p168_smcrdy_grps[] = {"smc rdy"}; +static const char * const p168_ac97sysclk_grps[] = {"ac97 sysclk"}; +static const char * const p168_ac97_grps[] = {"ac97"}; +static const char * const p168_cf_grps[] = {"cf"}; +static const char * const p168_kpmkin_grps[] = {"kp mkin 3p1"}; +static const char * const p168_kpmkout_grps[] = {"kp mkout 2p1"}; +static const char * const p168_gpio86_grps[] = {"gpio86-1", "gpio86-2"}; +static const char * const p168_gpio87_grps[] = {"gpio87-1", "gpio87-2"}; +static const char * const p168_gpio88_grps[] = {"gpio88-1", "gpio88-2"}; + +static struct pxa3xx_pmx_func pxa168_funcs[] = { + {"uart1 rx", ARRAY_AND_SIZE(p168_uart1rx_grps)}, + {"uart1 tx", ARRAY_AND_SIZE(p168_uart1tx_grps)}, + {"uart3 rx", ARRAY_AND_SIZE(p168_uart3rx_grps)}, + {"uart3 tx", ARRAY_AND_SIZE(p168_uart3tx_grps)}, + {"ssp1 rx", ARRAY_AND_SIZE(p168_ssp1rx_grps)}, + {"ssp1 tx", ARRAY_AND_SIZE(p168_ssp1tx_grps)}, + {"ssp4 rx", ARRAY_AND_SIZE(p168_ssp4rx_grps)}, + {"ssp4 tx", ARRAY_AND_SIZE(p168_ssp4tx_grps)}, + {"ssp5 rx", ARRAY_AND_SIZE(p168_ssp5rx_grps)}, + {"ssp5 tx", ARRAY_AND_SIZE(p168_ssp5tx_grps)}, + {"i2c", ARRAY_AND_SIZE(p168_i2c_grps)}, + {"pwri2c", ARRAY_AND_SIZE(p168_pwri2c_grps)}, + {"mmc1", ARRAY_AND_SIZE(p168_mmc1_grps)}, + {"mmc2", ARRAY_AND_SIZE(p168_mmc2_data_grps)}, + {"mmc2 cmd", ARRAY_AND_SIZE(p168_mmc2_cmd_grps)}, + {"mmc2 clk", ARRAY_AND_SIZE(p168_mmc2_clk_grps)}, + {"mmc3", ARRAY_AND_SIZE(p168_mmc3_data_grps)}, + {"mmc3 cmd", ARRAY_AND_SIZE(p168_mmc3_cmd_grps)}, + {"mmc3 clk", ARRAY_AND_SIZE(p168_mmc3_clk_grps)}, + {"eth", ARRAY_AND_SIZE(p168_eth_grps)}, + {"eth rx", ARRAY_AND_SIZE(p168_ethrx_grps)}, + {"eth tx", ARRAY_AND_SIZE(p168_ethtx_grps)}, + {"msp", ARRAY_AND_SIZE(p168_msp_grps)}, + {"ccic", ARRAY_AND_SIZE(p168_ccic_grps)}, + {"xd", ARRAY_AND_SIZE(p168_xd_grps)}, + {"lcd", ARRAY_AND_SIZE(p168_lcd_grps)}, + {"dfio", ARRAY_AND_SIZE(p168_dfio_grps)}, + {"nand", ARRAY_AND_SIZE(p168_nand_grps)}, + {"smc", ARRAY_AND_SIZE(p168_smc_grps)}, + {"smc cs0", ARRAY_AND_SIZE(p168_smccs0_grps)}, + {"smc cs1", ARRAY_AND_SIZE(p168_smccs1_grps)}, + {"smc rdy", ARRAY_AND_SIZE(p168_smcrdy_grps)}, + {"ac97", ARRAY_AND_SIZE(p168_ac97_grps)}, + {"ac97 sysclk", ARRAY_AND_SIZE(p168_ac97sysclk_grps)}, + {"cf", ARRAY_AND_SIZE(p168_cf_grps)}, + {"kpmkin", ARRAY_AND_SIZE(p168_kpmkin_grps)}, + {"kpmkout", ARRAY_AND_SIZE(p168_kpmkout_grps)}, + {"gpio86", ARRAY_AND_SIZE(p168_gpio86_grps)}, + {"gpio87", ARRAY_AND_SIZE(p168_gpio87_grps)}, + {"gpio88", ARRAY_AND_SIZE(p168_gpio88_grps)}, +}; + +static struct pinctrl_desc pxa168_pctrl_desc = { + .name = "pxa168-pinctrl", + .owner = THIS_MODULE, +}; + +static struct pxa3xx_pinmux_info pxa168_info = { + .mfp = pxa168_mfp, + .num_mfp = ARRAY_SIZE(pxa168_mfp), + .grps = pxa168_grps, + .num_grps = ARRAY_SIZE(pxa168_grps), + .funcs = pxa168_funcs, + .num_funcs = ARRAY_SIZE(pxa168_funcs), + .num_gpio = 128, + .desc = &pxa168_pctrl_desc, + .pads = pxa168_pads, + .num_pads = ARRAY_SIZE(pxa168_pads), + + .cputype = PINCTRL_PXA168, + .ds_mask = PXA168_DS_MASK, + .ds_shift = PXA168_DS_SHIFT, +}; + +static int __devinit pxa168_pinmux_probe(struct platform_device *pdev) +{ + return pxa3xx_pinctrl_register(pdev, &pxa168_info); +} + +static int __devexit pxa168_pinmux_remove(struct platform_device *pdev) +{ + return pxa3xx_pinctrl_unregister(pdev); +} + +static struct platform_driver pxa168_pinmux_driver = { + .driver = { + .name = "pxa168-pinmux", + .owner = THIS_MODULE, + }, + .probe = pxa168_pinmux_probe, + .remove = __devexit_p(pxa168_pinmux_remove), +}; + +static int __init pxa168_pinmux_init(void) +{ + return platform_driver_register(&pxa168_pinmux_driver); +} +core_initcall_sync(pxa168_pinmux_init); + +static void __exit pxa168_pinmux_exit(void) +{ + platform_driver_unregister(&pxa168_pinmux_driver); +} +module_exit(pxa168_pinmux_exit); + +MODULE_AUTHOR("Haojian Zhuang "); +MODULE_DESCRIPTION("PXA3xx pin control driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/pinctrl-pxa3xx.c b/drivers/pinctrl/pinctrl-pxa3xx.c new file mode 100644 index 00000000000..079dce0e93e --- /dev/null +++ b/drivers/pinctrl/pinctrl-pxa3xx.c @@ -0,0 +1,244 @@ +/* + * linux/drivers/pinctrl/pinctrl-pxa3xx.c + * + * 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 + * publishhed by the Free Software Foundation. + * + * Copyright (C) 2011, Marvell Technology Group Ltd. + * + * Author: Haojian Zhuang + * + */ + +#include +#include +#include +#include +#include +#include "pinctrl-pxa3xx.h" + +static struct pinctrl_gpio_range pxa3xx_pinctrl_gpio_range = { + .name = "PXA3xx GPIO", + .id = 0, + .base = 0, + .pin_base = 0, +}; + +static int pxa3xx_list_groups(struct pinctrl_dev *pctrldev, unsigned selector) +{ + struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); + if (selector >= info->num_grps) + return -EINVAL; + return 0; +} + +static const char *pxa3xx_get_group_name(struct pinctrl_dev *pctrldev, + unsigned selector) +{ + struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); + if (selector >= info->num_grps) + return NULL; + return info->grps[selector].name; +} + +static int pxa3xx_get_group_pins(struct pinctrl_dev *pctrldev, + unsigned selector, + const unsigned **pins, + unsigned *num_pins) +{ + struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); + if (selector >= info->num_grps) + return -EINVAL; + *pins = info->grps[selector].pins; + *num_pins = info->grps[selector].npins; + return 0; +} + +static struct pinctrl_ops pxa3xx_pctrl_ops = { + .list_groups = pxa3xx_list_groups, + .get_group_name = pxa3xx_get_group_name, + .get_group_pins = pxa3xx_get_group_pins, +}; + +static int pxa3xx_pmx_list_func(struct pinctrl_dev *pctrldev, unsigned func) +{ + struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); + if (func >= info->num_funcs) + return -EINVAL; + return 0; +} + +static const char *pxa3xx_pmx_get_func_name(struct pinctrl_dev *pctrldev, + unsigned func) +{ + struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); + return info->funcs[func].name; +} + +static int pxa3xx_pmx_get_groups(struct pinctrl_dev *pctrldev, unsigned func, + const char * const **groups, + unsigned * const num_groups) +{ + struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); + *groups = info->funcs[func].groups; + *num_groups = info->funcs[func].num_groups; + return 0; +} + +/* Return function number. If failure, return negative value. */ +static int match_mux(struct pxa3xx_mfp_pin *mfp, unsigned mux) +{ + int i; + for (i = 0; i < PXA3xx_MAX_MUX; i++) { + if (mfp->func[i] == mux) + break; + } + if (i >= PXA3xx_MAX_MUX) + return -EINVAL; + return i; +} + +/* check whether current pin configuration is valid. Negative for failure */ +static int match_group_mux(struct pxa3xx_pin_group *grp, + struct pxa3xx_pinmux_info *info, + unsigned mux) +{ + int i, pin, ret = 0; + for (i = 0; i < grp->npins; i++) { + pin = grp->pins[i]; + ret = match_mux(&info->mfp[pin], mux); + if (ret < 0) { + dev_err(info->dev, "Can't find mux %d on pin%d\n", + mux, pin); + break; + } + } + return ret; +} + +static int pxa3xx_pmx_enable(struct pinctrl_dev *pctrldev, unsigned func, + unsigned group) +{ + struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); + struct pxa3xx_pin_group *pin_grp = &info->grps[group]; + unsigned int data; + int i, mfpr, pin, pin_func; + + if (!pin_grp->npins || + (match_group_mux(pin_grp, info, pin_grp->mux) < 0)) { + dev_err(info->dev, "Failed to set the pin group: %d\n", group); + return -EINVAL; + } + for (i = 0; i < pin_grp->npins; i++) { + pin = pin_grp->pins[i]; + pin_func = match_mux(&info->mfp[pin], pin_grp->mux); + mfpr = info->mfp[pin].mfpr; + data = readl_relaxed(info->virt_base + mfpr); + data &= ~MFPR_FUNC_MASK; + data |= pin_func; + writel_relaxed(data, info->virt_base + mfpr); + } + return 0; +} + +static void pxa3xx_pmx_disable(struct pinctrl_dev *pctrldev, unsigned func, + unsigned group) +{ +} + +static int pxa3xx_pmx_request_gpio(struct pinctrl_dev *pctrldev, + struct pinctrl_gpio_range *range, + unsigned pin) +{ + struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); + unsigned int data; + int pin_func, mfpr; + + pin_func = match_mux(&info->mfp[pin], PXA3xx_MUX_GPIO); + if (pin_func < 0) { + dev_err(info->dev, "No GPIO function on pin%d (%s)\n", + pin, info->pads[pin].name); + return -EINVAL; + } + mfpr = info->mfp[pin].mfpr; + /* write gpio function into mfpr register */ + data = readl_relaxed(info->virt_base + mfpr) & ~MFPR_FUNC_MASK; + data |= pin_func; + writel_relaxed(data, info->virt_base + mfpr); + return 0; +} + +static struct pinmux_ops pxa3xx_pmx_ops = { + .list_functions = pxa3xx_pmx_list_func, + .get_function_name = pxa3xx_pmx_get_func_name, + .get_function_groups = pxa3xx_pmx_get_groups, + .enable = pxa3xx_pmx_enable, + .disable = pxa3xx_pmx_disable, + .gpio_request_enable = pxa3xx_pmx_request_gpio, +}; + +int pxa3xx_pinctrl_register(struct platform_device *pdev, + struct pxa3xx_pinmux_info *info) +{ + struct pinctrl_desc *desc; + struct resource *res; + int ret = 0; + + if (!info || !info->cputype) + return -EINVAL; + desc = info->desc; + desc->pins = info->pads; + desc->npins = info->num_pads; + desc->pctlops = &pxa3xx_pctrl_ops; + desc->pmxops = &pxa3xx_pmx_ops; + info->dev = &pdev->dev; + pxa3xx_pinctrl_gpio_range.npins = info->num_gpio; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENOENT; + info->phy_base = res->start; + info->phy_size = resource_size(res); + info->virt_base = ioremap(info->phy_base, info->phy_size); + if (!info->virt_base) + return -ENOMEM; + info->pctrl = pinctrl_register(desc, &pdev->dev, info); + if (!info->pctrl) { + dev_err(&pdev->dev, "failed to register PXA pinmux driver\n"); + ret = -EINVAL; + goto err; + } + pinctrl_add_gpio_range(info->pctrl, &pxa3xx_pinctrl_gpio_range); + platform_set_drvdata(pdev, info); + return 0; +err: + iounmap(info->virt_base); + return ret; +} + +int pxa3xx_pinctrl_unregister(struct platform_device *pdev) +{ + struct pxa3xx_pinmux_info *info = platform_get_drvdata(pdev); + + pinctrl_unregister(info->pctrl); + iounmap(info->virt_base); + platform_set_drvdata(pdev, NULL); + return 0; +} + +static int __init pxa3xx_pinctrl_init(void) +{ + pr_info("pxa3xx-pinctrl: PXA3xx pinctrl driver initializing\n"); + return 0; +} +core_initcall_sync(pxa3xx_pinctrl_init); + +static void __exit pxa3xx_pinctrl_exit(void) +{ +} +module_exit(pxa3xx_pinctrl_exit); + +MODULE_AUTHOR("Haojian Zhuang "); +MODULE_DESCRIPTION("PXA3xx pin control driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/pinctrl-pxa3xx.h b/drivers/pinctrl/pinctrl-pxa3xx.h new file mode 100644 index 00000000000..8135744d659 --- /dev/null +++ b/drivers/pinctrl/pinctrl-pxa3xx.h @@ -0,0 +1,264 @@ +/* + * linux/drivers/pinctrl/pinctrl-pxa3xx.h + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + * + * Copyright (C) 2011, Marvell Technology Group Ltd. + * + * Author: Haojian Zhuang + * + */ + +#ifndef __PINCTRL_PXA3XX_H + +#include +#include + +#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) + +#define PXA3xx_MUX_GPIO 0 + +#define PXA3xx_MAX_MUX 8 +#define MFPR_FUNC_MASK 0x7 + +enum pxa_cpu_type { + PINCTRL_INVALID = 0, + PINCTRL_PXA300, + PINCTRL_PXA310, + PINCTRL_PXA320, + PINCTRL_PXA168, + PINCTRL_PXA910, + PINCTRL_PXA930, + PINCTRL_PXA955, + PINCTRL_MMP2, + PINCTRL_MAX, +}; + +struct pxa3xx_mfp_pin { + const char *name; + const unsigned int pin; + const unsigned int mfpr; /* register offset */ + const unsigned short func[8]; +}; + +struct pxa3xx_pin_group { + const char *name; + const unsigned mux; + const unsigned *pins; + const unsigned npins; +}; + +struct pxa3xx_pmx_func { + const char *name; + const char * const * groups; + const unsigned num_groups; +}; + +struct pxa3xx_pinmux_info { + struct device *dev; + struct pinctrl_dev *pctrl; + enum pxa_cpu_type cputype; + unsigned int phy_base; + unsigned int phy_size; + void __iomem *virt_base; + + struct pxa3xx_mfp_pin *mfp; + unsigned int num_mfp; + struct pxa3xx_pin_group *grps; + unsigned int num_grps; + struct pxa3xx_pmx_func *funcs; + unsigned int num_funcs; + unsigned int num_gpio; + struct pinctrl_desc *desc; + struct pinctrl_pin_desc *pads; + unsigned int num_pads; + + unsigned ds_mask; /* drive strength mask */ + unsigned ds_shift; /* drive strength shift */ + unsigned slp_mask; /* sleep mask */ + unsigned slp_input_low; + unsigned slp_input_high; + unsigned slp_output_low; + unsigned slp_output_high; + unsigned slp_float; +}; + +enum pxa3xx_pin_list { + GPIO0 = 0, + GPIO1, + GPIO2, + GPIO3, + GPIO4, + GPIO5, + GPIO6, + GPIO7, + GPIO8, + GPIO9, + GPIO10, /* 10 */ + GPIO11, + GPIO12, + GPIO13, + GPIO14, + GPIO15, + GPIO16, + GPIO17, + GPIO18, + GPIO19, + GPIO20, /* 20 */ + GPIO21, + GPIO22, + GPIO23, + GPIO24, + GPIO25, + GPIO26, + GPIO27, + GPIO28, + GPIO29, + GPIO30, /* 30 */ + GPIO31, + GPIO32, + GPIO33, + GPIO34, + GPIO35, + GPIO36, + GPIO37, + GPIO38, + GPIO39, + GPIO40, /* 40 */ + GPIO41, + GPIO42, + GPIO43, + GPIO44, + GPIO45, + GPIO46, + GPIO47, + GPIO48, + GPIO49, + GPIO50, /* 50 */ + GPIO51, + GPIO52, + GPIO53, + GPIO54, + GPIO55, + GPIO56, + GPIO57, + GPIO58, + GPIO59, + GPIO60, /* 60 */ + GPIO61, + GPIO62, + GPIO63, + GPIO64, + GPIO65, + GPIO66, + GPIO67, + GPIO68, + GPIO69, + GPIO70, /* 70 */ + GPIO71, + GPIO72, + GPIO73, + GPIO74, + GPIO75, + GPIO76, + GPIO77, + GPIO78, + GPIO79, + GPIO80, /* 80 */ + GPIO81, + GPIO82, + GPIO83, + GPIO84, + GPIO85, + GPIO86, + GPIO87, + GPIO88, + GPIO89, + GPIO90, /* 90 */ + GPIO91, + GPIO92, + GPIO93, + GPIO94, + GPIO95, + GPIO96, + GPIO97, + GPIO98, + GPIO99, + GPIO100, /* 100 */ + GPIO101, + GPIO102, + GPIO103, + GPIO104, + GPIO105, + GPIO106, + GPIO107, + GPIO108, + GPIO109, + GPIO110, /* 110 */ + GPIO111, + GPIO112, + GPIO113, + GPIO114, + GPIO115, + GPIO116, + GPIO117, + GPIO118, + GPIO119, + GPIO120, /* 120 */ + GPIO121, + GPIO122, + GPIO123, + GPIO124, + GPIO125, + GPIO126, + GPIO127, + GPIO128, + GPIO129, + GPIO130, /* 130 */ + GPIO131, + GPIO132, + GPIO133, + GPIO134, + GPIO135, + GPIO136, + GPIO137, + GPIO138, + GPIO139, + GPIO140, /* 140 */ + GPIO141, + GPIO142, + GPIO143, + GPIO144, + GPIO145, + GPIO146, + GPIO147, + GPIO148, + GPIO149, + GPIO150, /* 150 */ + GPIO151, + GPIO152, + GPIO153, + GPIO154, + GPIO155, + GPIO156, + GPIO157, + GPIO158, + GPIO159, + GPIO160, /* 160 */ + GPIO161, + GPIO162, + GPIO163, + GPIO164, + GPIO165, + GPIO166, + GPIO167, + GPIO168, + GPIO169, +}; + +extern int pxa3xx_pinctrl_register(struct platform_device *pdev, + struct pxa3xx_pinmux_info *info); +extern int pxa3xx_pinctrl_unregister(struct platform_device *pdev); +#endif /* __PINCTRL_PXA3XX_H */ diff --git a/drivers/pinctrl/pinctrl-pxa910.c b/drivers/pinctrl/pinctrl-pxa910.c new file mode 100644 index 00000000000..c72ab4b9cc8 --- /dev/null +++ b/drivers/pinctrl/pinctrl-pxa910.c @@ -0,0 +1,1007 @@ +/* + * linux/drivers/pinctrl/pinmux-pxa910.c + * + * 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 + * publishhed by the Free Software Foundation. + * + * Copyright (C) 2011, Marvell Technology Group Ltd. + * + * Author: Haojian Zhuang + * + */ + +#include +#include +#include +#include +#include "pinctrl-pxa3xx.h" + +#define PXA910_DS_MASK 0x1800 +#define PXA910_DS_SHIFT 11 +#define PXA910_SLEEP_MASK 0x38 +#define PXA910_SLEEP_SELECT (1 << 9) +#define PXA910_SLEEP_DATA (1 << 8) +#define PXA910_SLEEP_DIR (1 << 7) + +#define MFPR_910(a, r, f0, f1, f2, f3, f4, f5, f6, f7) \ + { \ + .name = #a, \ + .pin = a, \ + .mfpr = r, \ + .func = { \ + PXA910_MUX_##f0, \ + PXA910_MUX_##f1, \ + PXA910_MUX_##f2, \ + PXA910_MUX_##f3, \ + PXA910_MUX_##f4, \ + PXA910_MUX_##f5, \ + PXA910_MUX_##f6, \ + PXA910_MUX_##f7, \ + }, \ + } + +#define GRP_910(a, m, p) \ + { .name = a, .mux = PXA910_MUX_##m, .pins = p, .npins = ARRAY_SIZE(p), } + +/* 170 pins */ +enum pxa910_pin_list { + /* 0~127: GPIO0~GPIO127 */ + ND_IO15 = 128, + ND_IO14, + ND_IO13, /* 130 */ + ND_IO12, + ND_IO11, + ND_IO10, + ND_IO9, + ND_IO8, + ND_IO7, + ND_IO6, + ND_IO5, + ND_IO4, + ND_IO3, /* 140 */ + ND_IO2, + ND_IO1, + ND_IO0, + ND_NCS0, + ND_NCS1, + SM_NCS0, + SM_NCS1, + ND_NWE, + ND_NRE, + ND_CLE, /* 150 */ + ND_ALE, + SM_SCLK, + ND_RDY0, + SM_ADV, + ND_RDY1, + SM_ADVMUX, + SM_RDY, + MMC1_DAT7, + MMC1_DAT6, + MMC1_DAT5, /* 160 */ + MMC1_DAT4, + MMC1_DAT3, + MMC1_DAT2, + MMC1_DAT1, + MMC1_DAT0, + MMC1_CMD, + MMC1_CLK, + MMC1_CD, + VCXO_OUT, +}; + +enum pxa910_mux { + /* PXA3xx_MUX_GPIO = 0 (predefined in pinctrl-pxa3xx.h) */ + PXA910_MUX_GPIO = 0, + PXA910_MUX_NAND, + PXA910_MUX_USIM2, + PXA910_MUX_EXT_DMA, + PXA910_MUX_EXT_INT, + PXA910_MUX_MMC1, + PXA910_MUX_MMC2, + PXA910_MUX_MMC3, + PXA910_MUX_SM_INT, + PXA910_MUX_PRI_JTAG, + PXA910_MUX_SEC1_JTAG, + PXA910_MUX_SEC2_JTAG, + PXA910_MUX_RESET, /* SLAVE RESET OUT */ + PXA910_MUX_CLK_REQ, + PXA910_MUX_VCXO_REQ, + PXA910_MUX_VCXO_OUT, + PXA910_MUX_VCXO_REQ2, + PXA910_MUX_VCXO_OUT2, + PXA910_MUX_SPI, + PXA910_MUX_SPI2, + PXA910_MUX_GSSP, + PXA910_MUX_SSP0, + PXA910_MUX_SSP1, + PXA910_MUX_SSP2, + PXA910_MUX_DSSP2, + PXA910_MUX_DSSP3, + PXA910_MUX_UART0, + PXA910_MUX_UART1, + PXA910_MUX_UART2, + PXA910_MUX_TWSI, + PXA910_MUX_CCIC, + PXA910_MUX_PWM0, + PXA910_MUX_PWM1, + PXA910_MUX_PWM2, + PXA910_MUX_PWM3, + PXA910_MUX_HSL, + PXA910_MUX_ONE_WIRE, + PXA910_MUX_LCD, + PXA910_MUX_DAC_ST23, + PXA910_MUX_ULPI, + PXA910_MUX_TB, + PXA910_MUX_KP_MK, + PXA910_MUX_KP_DK, + PXA910_MUX_TCU_GPOA, + PXA910_MUX_TCU_GPOB, + PXA910_MUX_ROT, + PXA910_MUX_TDS, + PXA910_MUX_32K_CLK, /* 32KHz CLK OUT */ + PXA910_MUX_MN_CLK, /* MN CLK OUT */ + PXA910_MUX_SMC, + PXA910_MUX_SM_ADDR18, + PXA910_MUX_SM_ADDR19, + PXA910_MUX_SM_ADDR20, + PXA910_MUX_NONE = 0xffff, +}; + + +static struct pinctrl_pin_desc pxa910_pads[] = { + PINCTRL_PIN(GPIO0, "GPIO0"), + PINCTRL_PIN(GPIO1, "GPIO1"), + PINCTRL_PIN(GPIO2, "GPIO2"), + PINCTRL_PIN(GPIO3, "GPIO3"), + PINCTRL_PIN(GPIO4, "GPIO4"), + PINCTRL_PIN(GPIO5, "GPIO5"), + PINCTRL_PIN(GPIO6, "GPIO6"), + PINCTRL_PIN(GPIO7, "GPIO7"), + PINCTRL_PIN(GPIO8, "GPIO8"), + PINCTRL_PIN(GPIO9, "GPIO9"), + PINCTRL_PIN(GPIO10, "GPIO10"), + PINCTRL_PIN(GPIO11, "GPIO11"), + PINCTRL_PIN(GPIO12, "GPIO12"), + PINCTRL_PIN(GPIO13, "GPIO13"), + PINCTRL_PIN(GPIO14, "GPIO14"), + PINCTRL_PIN(GPIO15, "GPIO15"), + PINCTRL_PIN(GPIO16, "GPIO16"), + PINCTRL_PIN(GPIO17, "GPIO17"), + PINCTRL_PIN(GPIO18, "GPIO18"), + PINCTRL_PIN(GPIO19, "GPIO19"), + PINCTRL_PIN(GPIO20, "GPIO20"), + PINCTRL_PIN(GPIO21, "GPIO21"), + PINCTRL_PIN(GPIO22, "GPIO22"), + PINCTRL_PIN(GPIO23, "GPIO23"), + PINCTRL_PIN(GPIO24, "GPIO24"), + PINCTRL_PIN(GPIO25, "GPIO25"), + PINCTRL_PIN(GPIO26, "GPIO26"), + PINCTRL_PIN(GPIO27, "GPIO27"), + PINCTRL_PIN(GPIO28, "GPIO28"), + PINCTRL_PIN(GPIO29, "GPIO29"), + PINCTRL_PIN(GPIO30, "GPIO30"), + PINCTRL_PIN(GPIO31, "GPIO31"), + PINCTRL_PIN(GPIO32, "GPIO32"), + PINCTRL_PIN(GPIO33, "GPIO33"), + PINCTRL_PIN(GPIO34, "GPIO34"), + PINCTRL_PIN(GPIO35, "GPIO35"), + PINCTRL_PIN(GPIO36, "GPIO36"), + PINCTRL_PIN(GPIO37, "GPIO37"), + PINCTRL_PIN(GPIO38, "GPIO38"), + PINCTRL_PIN(GPIO39, "GPIO39"), + PINCTRL_PIN(GPIO40, "GPIO40"), + PINCTRL_PIN(GPIO41, "GPIO41"), + PINCTRL_PIN(GPIO42, "GPIO42"), + PINCTRL_PIN(GPIO43, "GPIO43"), + PINCTRL_PIN(GPIO44, "GPIO44"), + PINCTRL_PIN(GPIO45, "GPIO45"), + PINCTRL_PIN(GPIO46, "GPIO46"), + PINCTRL_PIN(GPIO47, "GPIO47"), + PINCTRL_PIN(GPIO48, "GPIO48"), + PINCTRL_PIN(GPIO49, "GPIO49"), + PINCTRL_PIN(GPIO50, "GPIO50"), + PINCTRL_PIN(GPIO51, "GPIO51"), + PINCTRL_PIN(GPIO52, "GPIO52"), + PINCTRL_PIN(GPIO53, "GPIO53"), + PINCTRL_PIN(GPIO54, "GPIO54"), + PINCTRL_PIN(GPIO55, "GPIO55"), + PINCTRL_PIN(GPIO56, "GPIO56"), + PINCTRL_PIN(GPIO57, "GPIO57"), + PINCTRL_PIN(GPIO58, "GPIO58"), + PINCTRL_PIN(GPIO59, "GPIO59"), + PINCTRL_PIN(GPIO60, "GPIO60"), + PINCTRL_PIN(GPIO61, "GPIO61"), + PINCTRL_PIN(GPIO62, "GPIO62"), + PINCTRL_PIN(GPIO63, "GPIO63"), + PINCTRL_PIN(GPIO64, "GPIO64"), + PINCTRL_PIN(GPIO65, "GPIO65"), + PINCTRL_PIN(GPIO66, "GPIO66"), + PINCTRL_PIN(GPIO67, "GPIO67"), + PINCTRL_PIN(GPIO68, "GPIO68"), + PINCTRL_PIN(GPIO69, "GPIO69"), + PINCTRL_PIN(GPIO70, "GPIO70"), + PINCTRL_PIN(GPIO71, "GPIO71"), + PINCTRL_PIN(GPIO72, "GPIO72"), + PINCTRL_PIN(GPIO73, "GPIO73"), + PINCTRL_PIN(GPIO74, "GPIO74"), + PINCTRL_PIN(GPIO75, "GPIO75"), + PINCTRL_PIN(GPIO76, "GPIO76"), + PINCTRL_PIN(GPIO77, "GPIO77"), + PINCTRL_PIN(GPIO78, "GPIO78"), + PINCTRL_PIN(GPIO79, "GPIO79"), + PINCTRL_PIN(GPIO80, "GPIO80"), + PINCTRL_PIN(GPIO81, "GPIO81"), + PINCTRL_PIN(GPIO82, "GPIO82"), + PINCTRL_PIN(GPIO83, "GPIO83"), + PINCTRL_PIN(GPIO84, "GPIO84"), + PINCTRL_PIN(GPIO85, "GPIO85"), + PINCTRL_PIN(GPIO86, "GPIO86"), + PINCTRL_PIN(GPIO87, "GPIO87"), + PINCTRL_PIN(GPIO88, "GPIO88"), + PINCTRL_PIN(GPIO89, "GPIO89"), + PINCTRL_PIN(GPIO90, "GPIO90"), + PINCTRL_PIN(GPIO91, "GPIO91"), + PINCTRL_PIN(GPIO92, "GPIO92"), + PINCTRL_PIN(GPIO93, "GPIO93"), + PINCTRL_PIN(GPIO94, "GPIO94"), + PINCTRL_PIN(GPIO95, "GPIO95"), + PINCTRL_PIN(GPIO96, "GPIO96"), + PINCTRL_PIN(GPIO97, "GPIO97"), + PINCTRL_PIN(GPIO98, "GPIO98"), + PINCTRL_PIN(GPIO99, "GPIO99"), + PINCTRL_PIN(GPIO100, "GPIO100"), + PINCTRL_PIN(GPIO101, "GPIO101"), + PINCTRL_PIN(GPIO102, "GPIO102"), + PINCTRL_PIN(GPIO103, "GPIO103"), + PINCTRL_PIN(GPIO104, "GPIO104"), + PINCTRL_PIN(GPIO105, "GPIO105"), + PINCTRL_PIN(GPIO106, "GPIO106"), + PINCTRL_PIN(GPIO107, "GPIO107"), + PINCTRL_PIN(GPIO108, "GPIO108"), + PINCTRL_PIN(GPIO109, "GPIO109"), + PINCTRL_PIN(GPIO110, "GPIO110"), + PINCTRL_PIN(GPIO111, "GPIO111"), + PINCTRL_PIN(GPIO112, "GPIO112"), + PINCTRL_PIN(GPIO113, "GPIO113"), + PINCTRL_PIN(GPIO114, "GPIO114"), + PINCTRL_PIN(GPIO115, "GPIO115"), + PINCTRL_PIN(GPIO116, "GPIO116"), + PINCTRL_PIN(GPIO117, "GPIO117"), + PINCTRL_PIN(GPIO118, "GPIO118"), + PINCTRL_PIN(GPIO119, "GPIO119"), + PINCTRL_PIN(GPIO120, "GPIO120"), + PINCTRL_PIN(GPIO121, "GPIO121"), + PINCTRL_PIN(GPIO122, "GPIO122"), + PINCTRL_PIN(GPIO123, "GPIO123"), + PINCTRL_PIN(GPIO124, "GPIO124"), + PINCTRL_PIN(GPIO125, "GPIO125"), + PINCTRL_PIN(GPIO126, "GPIO126"), + PINCTRL_PIN(GPIO127, "GPIO127"), + PINCTRL_PIN(ND_IO15, "ND_IO15"), + PINCTRL_PIN(ND_IO14, "ND_IO14"), + PINCTRL_PIN(ND_IO13, "ND_IO13"), + PINCTRL_PIN(ND_IO12, "ND_IO12"), + PINCTRL_PIN(ND_IO11, "ND_IO11"), + PINCTRL_PIN(ND_IO10, "ND_IO10"), + PINCTRL_PIN(ND_IO9, "ND_IO9"), + PINCTRL_PIN(ND_IO8, "ND_IO8"), + PINCTRL_PIN(ND_IO7, "ND_IO7"), + PINCTRL_PIN(ND_IO6, "ND_IO6"), + PINCTRL_PIN(ND_IO5, "ND_IO5"), + PINCTRL_PIN(ND_IO4, "ND_IO4"), + PINCTRL_PIN(ND_IO3, "ND_IO3"), + PINCTRL_PIN(ND_IO2, "ND_IO2"), + PINCTRL_PIN(ND_IO1, "ND_IO1"), + PINCTRL_PIN(ND_IO0, "ND_IO0"), + PINCTRL_PIN(ND_NCS0, "ND_NCS0_SM_NCS2"), + PINCTRL_PIN(ND_NCS1, "ND_NCS1_SM_NCS3"), + PINCTRL_PIN(SM_NCS0, "SM_NCS0"), + PINCTRL_PIN(SM_NCS1, "SM_NCS1"), + PINCTRL_PIN(ND_NWE, "ND_NWE"), + PINCTRL_PIN(ND_NRE, "ND_NRE"), + PINCTRL_PIN(ND_CLE, "ND_CLE_SM_NOE"), + PINCTRL_PIN(ND_ALE, "ND_ALE_SM_NWE"), + PINCTRL_PIN(SM_SCLK, "SM_SCLK"), + PINCTRL_PIN(ND_RDY0, "ND_RDY0"), + PINCTRL_PIN(SM_ADV, "SM_ADV"), + PINCTRL_PIN(ND_RDY1, "ND_RDY1"), + PINCTRL_PIN(SM_RDY, "SM_RDY"), + PINCTRL_PIN(MMC1_DAT7, "MMC1_DAT7"), + PINCTRL_PIN(MMC1_DAT6, "MMC1_DAT6"), + PINCTRL_PIN(MMC1_DAT5, "MMC1_DAT5"), + PINCTRL_PIN(MMC1_DAT4, "MMC1_DAT4"), + PINCTRL_PIN(MMC1_DAT3, "MMC1_DAT3"), + PINCTRL_PIN(MMC1_DAT2, "MMC1_DAT2"), + PINCTRL_PIN(MMC1_DAT1, "MMC1_DAT1"), + PINCTRL_PIN(MMC1_DAT0, "MMC1_DAT0"), + PINCTRL_PIN(MMC1_CMD, "MMC1 CMD"), + PINCTRL_PIN(MMC1_CLK, "MMC1 CLK"), + PINCTRL_PIN(MMC1_CD, "MMC1 CD"), + PINCTRL_PIN(VCXO_OUT, "VCXO_OUT"), +}; + +struct pxa3xx_mfp_pin pxa910_mfp[] = { + /* pin offs f0 f1 f2 f3 f4 f5 f6 f7 */ + MFPR_910(GPIO0, 0x0DC, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO1, 0x0E0, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO2, 0x0E4, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO3, 0x0E8, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO4, 0x0EC, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO5, 0x0F0, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO6, 0x0F4, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO7, 0x0F8, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO8, 0x0FC, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO9, 0x100, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO10, 0x104, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO11, 0x108, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO12, 0x10C, GPIO, KP_MK, NONE, NONE, KP_DK, NONE, NONE, NONE), + MFPR_910(GPIO13, 0x110, GPIO, KP_MK, NONE, NONE, KP_DK, NONE, NONE, NONE), + MFPR_910(GPIO14, 0x114, GPIO, KP_MK, NONE, NONE, KP_DK, TB, NONE, NONE), + MFPR_910(GPIO15, 0x118, GPIO, KP_MK, NONE, NONE, KP_DK, TB, NONE, NONE), + MFPR_910(GPIO16, 0x11C, GPIO, KP_DK, NONE, NONE, NONE, TB, NONE, NONE), + MFPR_910(GPIO17, 0x120, GPIO, KP_DK, NONE, NONE, NONE, TB, NONE, NONE), + MFPR_910(GPIO18, 0x124, GPIO, KP_DK, NONE, NONE, ROT, NONE, NONE, NONE), + MFPR_910(GPIO19, 0x128, GPIO, KP_DK, NONE, NONE, ROT, NONE, NONE, NONE), + MFPR_910(GPIO20, 0x12C, GPIO, SSP1, NONE, NONE, VCXO_OUT, NONE, NONE, NONE), + MFPR_910(GPIO21, 0x130, GPIO, SSP1, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO22, 0x134, GPIO, SSP1, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO23, 0x138, GPIO, SSP1, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO24, 0x13C, GPIO, SSP1, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO25, 0x140, GPIO, GSSP, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO26, 0x144, GPIO, GSSP, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO27, 0x148, GPIO, GSSP, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO28, 0x14C, GPIO, GSSP, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO29, 0x150, GPIO, UART0, NONE, NONE, UART1, NONE, NONE, NONE), + MFPR_910(GPIO30, 0x154, GPIO, UART0, NONE, NONE, UART1, NONE, NONE, NONE), + MFPR_910(GPIO31, 0x158, GPIO, UART0, NONE, NONE, UART1, NONE, NONE, NONE), + MFPR_910(GPIO32, 0x15C, GPIO, UART0, DAC_ST23, NONE, UART1, NONE, NONE, NONE), + MFPR_910(GPIO33, 0x160, GPIO, MMC2, SSP0, SSP2, NONE, SPI, NONE, MMC3), + MFPR_910(GPIO34, 0x164, GPIO, MMC2, SSP0, SSP2, NONE, SPI, NONE, MMC3), + MFPR_910(GPIO35, 0x168, GPIO, MMC2, SSP0, SSP2, NONE, SPI, NONE, MMC3), + MFPR_910(GPIO36, 0x16C, GPIO, MMC2, SSP0, SSP2, NONE, SPI, NONE, MMC3), + MFPR_910(GPIO37, 0x170, GPIO, MMC2, NONE, NONE, NONE, SPI, HSL, NONE), + MFPR_910(GPIO38, 0x174, GPIO, MMC2, NONE, NONE, NONE, NONE, HSL, NONE), + MFPR_910(GPIO39, 0x178, GPIO, MMC2, NONE, NONE, NONE, NONE, HSL, NONE), + MFPR_910(GPIO40, 0x17C, GPIO, MMC2, NONE, NONE, NONE, NONE, HSL, NONE), + MFPR_910(GPIO41, 0x180, GPIO, MMC2, NONE, NONE, NONE, NONE, HSL, NONE), + MFPR_910(GPIO42, 0x184, GPIO, MMC2, NONE, NONE, NONE, NONE, HSL, NONE), + MFPR_910(GPIO43, 0x188, GPIO, UART1, NONE, DAC_ST23, NONE, DSSP2, SPI, UART2), + MFPR_910(GPIO44, 0x18C, GPIO, UART1, NONE, EXT_INT, NONE, DSSP2, SPI, UART2), + MFPR_910(GPIO45, 0x190, GPIO, UART1, NONE, EXT_INT, NONE, DSSP2, SPI, UART2), + MFPR_910(GPIO46, 0x194, GPIO, UART1, NONE, EXT_INT, NONE, DSSP2, SPI, UART2), + MFPR_910(GPIO47, 0x198, GPIO, SSP0, NONE, NONE, NONE, SSP2, UART1, NONE), + MFPR_910(GPIO48, 0x19C, GPIO, SSP0, NONE, NONE, NONE, SSP2, UART1, NONE), + MFPR_910(GPIO49, 0x1A0, GPIO, SSP0, UART0, VCXO_REQ, NONE, SSP2, NONE, MMC3), + MFPR_910(GPIO50, 0x1A4, GPIO, SSP0, UART0, VCXO_OUT, NONE, SSP2, NONE, MMC3), + MFPR_910(GPIO51, 0x1A8, GPIO, UART2, PWM1, TWSI, SSP0, NONE, DSSP3, NONE), + MFPR_910(GPIO52, 0x1AC, GPIO, UART2, DAC_ST23, TWSI, SSP0, NONE, DSSP3, NONE), + MFPR_910(GPIO53, 0x1B0, GPIO, UART2, TWSI, NONE, SSP0, NONE, DSSP3, NONE), + MFPR_910(GPIO54, 0x1B4, GPIO, UART2, TWSI, SSP0, NONE, NONE, DSSP3, NONE), + MFPR_910(GPIO55, 0x2F0, TDS, GPIO, TB, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO56, 0x2F4, TDS, GPIO, TB, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO57, 0x2F8, TDS, GPIO, TB, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO58, 0x2FC, TDS, GPIO, TB, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO59, 0x300, TDS, GPIO, TCU_GPOA, TCU_GPOB, ONE_WIRE, NONE, NONE, NONE), + MFPR_910(GPIO60, 0x304, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO61, 0x308, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, HSL), + MFPR_910(GPIO62, 0x30C, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, HSL), + MFPR_910(GPIO63, 0x310, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, HSL), + MFPR_910(GPIO64, 0x314, GPIO, SPI2, NONE, NONE, NONE, NONE, NONE, HSL), + MFPR_910(GPIO65, 0x318, GPIO, SPI2, NONE, NONE, NONE, NONE, ONE_WIRE, HSL), + MFPR_910(GPIO66, 0x31C, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, HSL), + MFPR_910(GPIO67, 0x1B8, GPIO, CCIC, SPI, NONE, NONE, ULPI, NONE, USIM2), + MFPR_910(GPIO68, 0x1BC, GPIO, CCIC, SPI, NONE, NONE, ULPI, NONE, USIM2), + MFPR_910(GPIO69, 0x1C0, GPIO, CCIC, SPI, NONE, NONE, ULPI, NONE, USIM2), + MFPR_910(GPIO70, 0x1C4, GPIO, CCIC, SPI, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO71, 0x1C8, GPIO, CCIC, SPI, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO72, 0x1CC, GPIO, CCIC, EXT_DMA, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO73, 0x1D0, GPIO, CCIC, EXT_DMA, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO74, 0x1D4, GPIO, CCIC, EXT_DMA, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO75, 0x1D8, GPIO, CCIC, NONE, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO76, 0x1DC, GPIO, CCIC, NONE, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO77, 0x1E0, GPIO, CCIC, NONE, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO78, 0x1E4, GPIO, CCIC, NONE, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO79, 0x1E8, GPIO, TWSI, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO80, 0x1EC, GPIO, TWSI, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO81, 0x1F0, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO82, 0x1F4, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO83, 0x1F8, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO84, 0x1FC, GPIO, LCD, VCXO_REQ2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO85, 0x200, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO86, 0x204, GPIO, LCD, VCXO_OUT2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO87, 0x208, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO88, 0x20C, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO89, 0x210, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO90, 0x214, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO91, 0x218, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO92, 0x21C, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO93, 0x220, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO94, 0x224, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO95, 0x228, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO96, 0x22C, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO97, 0x230, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO98, 0x234, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO99, 0x0B0, MMC1, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO100, 0x238, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO101, 0x23C, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO102, 0x240, GPIO, LCD, DSSP2, SPI, NONE, NONE, NONE, SPI2), + MFPR_910(GPIO103, 0x244, GPIO, LCD, DSSP2, SPI, NONE, NONE, NONE, SPI2), + MFPR_910(GPIO104, 0x248, GPIO, LCD, DSSP2, SPI, NONE, NONE, NONE, NONE), + MFPR_910(GPIO105, 0x24C, GPIO, LCD, DSSP2, SPI, NONE, NONE, NONE, NONE), + MFPR_910(GPIO106, 0x250, GPIO, LCD, DSSP3, ONE_WIRE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO107, 0x254, GPIO, LCD, DSSP3, SPI, NONE, NONE, NONE, NONE), + MFPR_910(GPIO108, 0x258, GPIO, LCD, DSSP3, SPI, NONE, NONE, NONE, NONE), + MFPR_910(GPIO109, 0x25C, GPIO, LCD, DSSP3, SPI, NONE, NONE, NONE, NONE), + MFPR_910(GPIO110, 0x298, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO111, 0x29C, GPIO, NONE, DSSP2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO112, 0x2A0, GPIO, NONE, DSSP2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO113, 0x2A4, GPIO, NONE, DSSP2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO114, 0x2A8, GPIO, NONE, DSSP3, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO115, 0x2AC, GPIO, NONE, DSSP3, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO116, 0x2B0, GPIO, NONE, DSSP3, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO117, 0x0B4, PRI_JTAG, GPIO, PWM0, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO118, 0x0B8, PRI_JTAG, GPIO, PWM1, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO119, 0x0BC, PRI_JTAG, GPIO, PWM2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO120, 0x0C0, PRI_JTAG, GPIO, PWM3, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO121, 0x32C, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO122, 0x0C8, RESET, GPIO, 32K_CLK, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO123, 0x0CC, CLK_REQ, GPIO, ONE_WIRE, EXT_DMA, NONE, NONE, NONE, NONE), + MFPR_910(GPIO124, 0x0D0, GPIO, MN_CLK, DAC_ST23, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO125, 0x0D4, VCXO_REQ, GPIO, NONE, EXT_INT, NONE, NONE, NONE, NONE), + MFPR_910(GPIO126, 0x06C, GPIO, SMC, NONE, SM_ADDR18, NONE, EXT_DMA, NONE, NONE), + MFPR_910(GPIO127, 0x070, GPIO, SMC, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO15, 0x004, NAND, GPIO, USIM2, EXT_DMA, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO14, 0x008, NAND, GPIO, USIM2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO13, 0x00C, NAND, GPIO, USIM2, EXT_INT, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO12, 0x010, NAND, GPIO, SSP2, EXT_INT, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO11, 0x014, NAND, GPIO, SSP2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO10, 0x018, NAND, GPIO, SSP2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO9, 0x01C, NAND, GPIO, SSP2, NONE, VCXO_OUT2, NONE, NONE, NONE), + MFPR_910(ND_IO8, 0x020, NAND, GPIO, NONE, NONE, PWM3, NONE, NONE, NONE), + MFPR_910(ND_IO7, 0x024, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO6, 0x028, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO5, 0x02C, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO4, 0x030, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO3, 0x034, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO2, 0x038, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO1, 0x03C, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO0, 0x040, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_NCS0, 0x044, NAND, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_NCS1, 0x048, NAND, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(SM_NCS0, 0x04C, SMC, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(SM_NCS1, 0x050, SMC, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_NWE, 0x054, GPIO, NAND, NONE, SM_ADDR20, NONE, SMC, NONE, NONE), + MFPR_910(ND_NRE, 0x058, GPIO, NAND, NONE, SMC, NONE, EXT_DMA, NONE, NONE), + MFPR_910(ND_CLE, 0x05C, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_ALE, 0x060, GPIO, NAND, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(SM_SCLK, 0x064, MMC3, NONE, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_RDY0, 0x068, NAND, GPIO, NONE, SMC, NONE, NONE, NONE, NONE), + MFPR_910(SM_ADV, 0x074, SMC, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_RDY1, 0x078, NAND, GPIO, NONE, SMC, NONE, NONE, NONE, NONE), + MFPR_910(SM_ADVMUX, 0x07C, SMC, GPIO, NONE, SM_ADDR19, NONE, NONE, NONE, NONE), + MFPR_910(SM_RDY, 0x080, SMC, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_DAT7, 0x084, MMC1, GPIO, SEC1_JTAG, TB, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_DAT6, 0x088, MMC1, GPIO, SEC1_JTAG, TB, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_DAT5, 0x08C, MMC1, GPIO, SEC1_JTAG, TB, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_DAT4, 0x090, MMC1, GPIO, NONE, TB, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_DAT3, 0x094, MMC1, HSL, SEC2_JTAG, SSP0, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_DAT2, 0x098, MMC1, HSL, SEC2_JTAG, SSP2, SSP0, NONE, NONE, NONE), + MFPR_910(MMC1_DAT1, 0x09C, MMC1, HSL, SEC2_JTAG, SSP2, SSP0, NONE, NONE, NONE), + MFPR_910(MMC1_DAT0, 0x0A0, MMC1, HSL, SEC2_JTAG, SSP2, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_CMD, 0x0A4, MMC1, HSL, SEC1_JTAG, SSP2, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_CLK, 0x0A8, MMC1, HSL, SEC2_JTAG, SSP0, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_CD, 0x0AC, MMC1, GPIO, SEC1_JTAG, NONE, NONE, NONE, NONE, NONE), + MFPR_910(VCXO_OUT, 0x0D8, VCXO_OUT, PWM3, NONE, NONE, NONE, NONE, NONE, NONE), +}; + + +static const unsigned p910_usim2_pin1[] = {GPIO67, GPIO68, GPIO69}; +static const unsigned p910_usim2_pin2[] = {ND_IO15, ND_IO14, ND_IO13}; +static const unsigned p910_mmc1_pin1[] = {MMC1_DAT7, MMC1_DAT6, MMC1_DAT5, + MMC1_DAT4, MMC1_DAT3, MMC1_DAT2, MMC1_DAT1, MMC1_DAT0, MMC1_CMD, + MMC1_CLK, MMC1_CD, GPIO99}; +static const unsigned p910_mmc2_pin1[] = {GPIO33, GPIO34, GPIO35, GPIO36, + GPIO37, GPIO38, GPIO39, GPIO40, GPIO41, GPIO42}; +static const unsigned p910_mmc3_pin1[] = {GPIO33, GPIO34, GPIO35, GPIO36, + GPIO49, GPIO50}; +static const unsigned p910_mmc3_pin2[] = {ND_IO7, ND_IO6, ND_IO5, ND_IO4, + ND_IO3, ND_IO2, ND_IO1, ND_IO0, ND_CLE, SM_SCLK}; +static const unsigned p910_uart0_pin1[] = {GPIO29, GPIO30, GPIO31, GPIO32}; +static const unsigned p910_uart1_pin1[] = {GPIO47, GPIO48}; +static const unsigned p910_uart1_pin2[] = {GPIO31, GPIO32}; +static const unsigned p910_uart1_pin3[] = {GPIO45, GPIO46}; +static const unsigned p910_uart1_pin4[] = {GPIO29, GPIO30, GPIO31, GPIO32}; +static const unsigned p910_uart1_pin5[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned p910_uart2_pin1[] = {GPIO43, GPIO44}; +static const unsigned p910_uart2_pin2[] = {GPIO51, GPIO52}; +static const unsigned p910_uart2_pin3[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned p910_uart2_pin4[] = {GPIO51, GPIO52, GPIO53, GPIO54}; +static const unsigned p910_twsi_pin1[] = {GPIO51, GPIO52}; +static const unsigned p910_twsi_pin2[] = {GPIO53, GPIO54}; +static const unsigned p910_twsi_pin3[] = {GPIO79, GPIO80}; +static const unsigned p910_ccic_pin1[] = {GPIO67, GPIO68, GPIO69, GPIO70, + GPIO71, GPIO72, GPIO73, GPIO74, GPIO75, GPIO76, GPIO77, GPIO78}; +static const unsigned p910_lcd_pin1[] = {GPIO81, GPIO82, GPIO83, GPIO84, + GPIO85, GPIO86, GPIO87, GPIO88, GPIO89, GPIO90, GPIO91, GPIO92, + GPIO93, GPIO94, GPIO95, GPIO96, GPIO97, GPIO98, GPIO100, GPIO101, + GPIO102, GPIO103}; +static const unsigned p910_spi_pin1[] = {GPIO104, GPIO105, GPIO107, GPIO108}; +static const unsigned p910_spi_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned p910_spi_pin3[] = {GPIO33, GPIO34, GPIO35, GPIO36, + GPIO37}; +static const unsigned p910_spi_pin4[] = {GPIO67, GPIO68, GPIO69, GPIO70, + GPIO71}; +static const unsigned p910_spi2_pin1[] = {GPIO64, GPIO65}; +static const unsigned p910_spi2_pin2[] = {GPIO102, GPIO103}; +static const unsigned p910_dssp2_pin1[] = {GPIO102, GPIO103, GPIO104, GPIO105}; +static const unsigned p910_dssp2_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned p910_dssp2_pin3[] = {GPIO111, GPIO112, GPIO113}; +static const unsigned p910_dssp3_pin1[] = {GPIO106, GPIO107, GPIO108, GPIO109}; +static const unsigned p910_dssp3_pin2[] = {GPIO51, GPIO52, GPIO53, GPIO54}; +static const unsigned p910_dssp3_pin3[] = {GPIO114, GPIO115, GPIO116}; +static const unsigned p910_ssp0_pin1[] = {MMC1_DAT3, MMC1_DAT2, MMC1_DAT1, + MMC1_CLK}; +static const unsigned p910_ssp0_pin2[] = {GPIO33, GPIO34, GPIO35, GPIO36}; +static const unsigned p910_ssp0_pin3[] = {GPIO47, GPIO48, GPIO49, GPIO50}; +static const unsigned p910_ssp0_pin4[] = {GPIO51, GPIO52, GPIO53, GPIO54}; +static const unsigned p910_ssp1_pin1[] = {GPIO21, GPIO22, GPIO23, GPIO24}; +static const unsigned p910_ssp1_pin2[] = {GPIO20, GPIO21, GPIO22, GPIO23, + GPIO24}; +static const unsigned p910_ssp2_pin1[] = {MMC1_DAT2, MMC1_DAT1, MMC1_DAT0, + MMC1_CMD}; +static const unsigned p910_ssp2_pin2[] = {GPIO33, GPIO34, GPIO35, GPIO36}; +static const unsigned p910_ssp2_pin3[] = {GPIO47, GPIO48, GPIO49, GPIO50}; +static const unsigned p910_ssp2_pin4[] = {ND_IO12, ND_IO11, ND_IO10, ND_IO9}; +static const unsigned p910_gssp_pin1[] = {GPIO25, GPIO26, GPIO27, GPIO28}; +static const unsigned p910_pwm0_pin1[] = {GPIO117}; +static const unsigned p910_pwm1_pin1[] = {GPIO118}; +static const unsigned p910_pwm1_pin2[] = {GPIO51}; +static const unsigned p910_pwm2_pin1[] = {GPIO119}; +static const unsigned p910_pwm3_pin1[] = {GPIO120}; +static const unsigned p910_pwm3_pin2[] = {ND_IO8}; +static const unsigned p910_pwm3_pin3[] = {VCXO_OUT}; +static const unsigned p910_pri_jtag_pin1[] = {GPIO117, GPIO118, GPIO119, + GPIO120}; +static const unsigned p910_sec1_jtag_pin1[] = {MMC1_DAT7, MMC1_DAT6, MMC1_DAT5, + MMC1_CMD, MMC1_CD}; +static const unsigned p910_sec2_jtag_pin1[] = {MMC1_DAT3, MMC1_DAT2, MMC1_DAT1, + MMC1_DAT0, MMC1_CLK}; +static const unsigned p910_hsl_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40, + GPIO41, GPIO42}; +static const unsigned p910_hsl_pin2[] = {GPIO61, GPIO62, GPIO63, GPIO64, + GPIO65, GPIO66}; +static const unsigned p910_hsl_pin3[] = {MMC1_DAT3, MMC1_DAT2, MMC1_DAT1, + MMC1_DAT0, MMC1_CMD, MMC1_CLK}; +static const unsigned p910_w1_pin1[] = {GPIO59}; +static const unsigned p910_w1_pin2[] = {GPIO65}; +static const unsigned p910_w1_pin3[] = {GPIO106}; +static const unsigned p910_w1_pin4[] = {GPIO123}; +static const unsigned p910_kpmk_pin1[] = {GPIO0, GPIO1, GPIO2, GPIO3, GPIO4, + GPIO5, GPIO6, GPIO7, GPIO8, GPIO9, GPIO10, GPIO11, GPIO12, GPIO13, + GPIO14, GPIO15}; +static const unsigned p910_kpmk_pin2[] = {GPIO0, GPIO1, GPIO2, GPIO3, GPIO4, + GPIO5, GPIO6, GPIO7, GPIO8, GPIO9, GPIO12}; +static const unsigned p910_kpdk_pin1[] = {GPIO12, GPIO13, GPIO14, GPIO15, + GPIO16, GPIO17, GPIO18, GPIO19}; +static const unsigned p910_tds_pin1[] = {GPIO55, GPIO56, GPIO57, GPIO58, + GPIO59}; +static const unsigned p910_tds_pin2[] = {GPIO55, GPIO57, GPIO58, GPIO59}; +static const unsigned p910_tb_pin1[] = {GPIO14, GPIO15, GPIO16, GPIO17}; +static const unsigned p910_tb_pin2[] = {GPIO55, GPIO56, GPIO57, GPIO58}; +static const unsigned p910_tb_pin3[] = {MMC1_DAT7, MMC1_DAT6, MMC1_DAT5, + MMC1_DAT4}; +static const unsigned p910_ext_dma0_pin1[] = {GPIO72}; +static const unsigned p910_ext_dma0_pin2[] = {ND_IO15}; +static const unsigned p910_ext_dma0_pin3[] = {ND_NRE}; +static const unsigned p910_ext_dma1_pin1[] = {GPIO73}; +static const unsigned p910_ext_dma1_pin2[] = {GPIO123}; +static const unsigned p910_ext_dma1_pin3[] = {GPIO126}; +static const unsigned p910_ext_dma2_pin1[] = {GPIO74}; +static const unsigned p910_ext0_int_pin1[] = {GPIO44}; +static const unsigned p910_ext0_int_pin2[] = {ND_IO13}; +static const unsigned p910_ext1_int_pin1[] = {GPIO45}; +static const unsigned p910_ext1_int_pin2[] = {ND_IO12}; +static const unsigned p910_ext2_int_pin1[] = {GPIO46}; +static const unsigned p910_ext2_int_pin2[] = {GPIO125}; +static const unsigned p910_dac_st23_pin1[] = {GPIO32}; +static const unsigned p910_dac_st23_pin2[] = {GPIO43}; +static const unsigned p910_dac_st23_pin3[] = {GPIO52}; +static const unsigned p910_dac_st23_pin4[] = {GPIO124}; +static const unsigned p910_vcxo_out_pin1[] = {GPIO50}; +static const unsigned p910_vcxo_out_pin2[] = {VCXO_OUT}; +static const unsigned p910_vcxo_out_pin3[] = {GPIO20}; +static const unsigned p910_vcxo_req_pin1[] = {GPIO49}; +static const unsigned p910_vcxo_req_pin2[] = {GPIO125}; +static const unsigned p910_vcxo_out2_pin1[] = {GPIO86}; +static const unsigned p910_vcxo_out2_pin2[] = {ND_IO9}; +static const unsigned p910_vcxo_req2_pin1[] = {GPIO84}; +static const unsigned p910_ulpi_pin1[] = {GPIO67, GPIO68, GPIO69, GPIO70, + GPIO71, GPIO72, GPIO73, GPIO74, GPIO75, GPIO76, GPIO77, GPIO78}; +static const unsigned p910_nand_pin1[] = {ND_IO15, ND_IO14, ND_IO13, ND_IO12, + ND_IO11, ND_IO10, ND_IO9, ND_IO8, ND_IO7, ND_IO6, ND_IO5, ND_IO4, + ND_IO3, ND_IO2, ND_IO1, ND_IO0, ND_NCS0, ND_NWE, ND_NRE, ND_CLE, + ND_ALE, ND_RDY0}; +static const unsigned p910_gpio0_pin1[] = {GPIO0}; +static const unsigned p910_gpio0_pin2[] = {SM_ADV}; +static const unsigned p910_gpio1_pin1[] = {GPIO1}; +static const unsigned p910_gpio1_pin2[] = {ND_RDY1}; +static const unsigned p910_gpio2_pin1[] = {GPIO2}; +static const unsigned p910_gpio2_pin2[] = {SM_ADVMUX}; +static const unsigned p910_gpio3_pin1[] = {GPIO3}; +static const unsigned p910_gpio3_pin2[] = {SM_RDY}; +static const unsigned p910_gpio20_pin1[] = {GPIO20}; +static const unsigned p910_gpio20_pin2[] = {ND_IO15}; +static const unsigned p910_gpio20_pin3[] = {MMC1_DAT6}; +static const unsigned p910_gpio21_pin1[] = {GPIO21}; +static const unsigned p910_gpio21_pin2[] = {ND_IO14}; +static const unsigned p910_gpio21_pin3[] = {MMC1_DAT5}; +static const unsigned p910_gpio22_pin1[] = {GPIO22}; +static const unsigned p910_gpio22_pin2[] = {ND_IO13}; +static const unsigned p910_gpio22_pin3[] = {MMC1_DAT4}; +static const unsigned p910_gpio23_pin1[] = {GPIO23}; +static const unsigned p910_gpio23_pin2[] = {ND_IO12}; +static const unsigned p910_gpio23_pin3[] = {MMC1_CD}; +static const unsigned p910_gpio24_pin1[] = {GPIO24}; +static const unsigned p910_gpio24_pin2[] = {ND_IO11}; +static const unsigned p910_gpio24_pin3[] = {MMC1_DAT7}; +static const unsigned p910_gpio25_pin1[] = {GPIO25}; +static const unsigned p910_gpio25_pin2[] = {ND_IO10}; +static const unsigned p910_gpio26_pin1[] = {GPIO26}; +static const unsigned p910_gpio26_pin2[] = {ND_IO9}; +static const unsigned p910_gpio27_pin1[] = {GPIO27}; +static const unsigned p910_gpio27_pin2[] = {ND_IO8}; +static const unsigned p910_gpio85_pin1[] = {GPIO85}; +static const unsigned p910_gpio85_pin2[] = {ND_NCS0}; +static const unsigned p910_gpio86_pin1[] = {GPIO86}; +static const unsigned p910_gpio86_pin2[] = {ND_NCS1}; +static const unsigned p910_gpio87_pin1[] = {GPIO87}; +static const unsigned p910_gpio87_pin2[] = {SM_NCS0}; +static const unsigned p910_gpio88_pin1[] = {GPIO88}; +static const unsigned p910_gpio88_pin2[] = {SM_NCS1}; +static const unsigned p910_gpio89_pin1[] = {GPIO89}; +static const unsigned p910_gpio89_pin2[] = {ND_NWE}; +static const unsigned p910_gpio90_pin1[] = {GPIO90}; +static const unsigned p910_gpio90_pin2[] = {ND_NRE}; +static const unsigned p910_gpio91_pin1[] = {GPIO91}; +static const unsigned p910_gpio91_pin2[] = {ND_ALE}; +static const unsigned p910_gpio92_pin1[] = {GPIO92}; +static const unsigned p910_gpio92_pin2[] = {ND_RDY0}; + +static struct pxa3xx_pin_group pxa910_grps[] = { + GRP_910("usim2 3p1", USIM2, p910_usim2_pin1), + GRP_910("usim2 3p2", USIM2, p910_usim2_pin2), + GRP_910("mmc1 12p", MMC1, p910_mmc1_pin1), + GRP_910("mmc2 10p", MMC2, p910_mmc2_pin1), + GRP_910("mmc3 6p", MMC3, p910_mmc3_pin1), + GRP_910("mmc3 10p", MMC3, p910_mmc3_pin2), + GRP_910("uart0 4p", UART0, p910_uart0_pin1), + GRP_910("uart1 2p1", UART1, p910_uart1_pin1), + GRP_910("uart1 2p2", UART1, p910_uart1_pin2), + GRP_910("uart1 2p3", UART1, p910_uart1_pin3), + GRP_910("uart1 4p4", UART1, p910_uart1_pin4), + GRP_910("uart1 4p5", UART1, p910_uart1_pin5), + GRP_910("uart2 2p1", UART2, p910_uart2_pin1), + GRP_910("uart2 2p2", UART2, p910_uart2_pin2), + GRP_910("uart2 4p3", UART2, p910_uart2_pin3), + GRP_910("uart2 4p4", UART2, p910_uart2_pin4), + GRP_910("twsi 2p1", TWSI, p910_twsi_pin1), + GRP_910("twsi 2p2", TWSI, p910_twsi_pin2), + GRP_910("twsi 2p3", TWSI, p910_twsi_pin3), + GRP_910("ccic", CCIC, p910_ccic_pin1), + GRP_910("lcd", LCD, p910_lcd_pin1), + GRP_910("spi 4p1", SPI, p910_spi_pin1), + GRP_910("spi 4p2", SPI, p910_spi_pin2), + GRP_910("spi 5p3", SPI, p910_spi_pin3), + GRP_910("spi 5p4", SPI, p910_spi_pin4), + GRP_910("dssp2 4p1", DSSP2, p910_dssp2_pin1), + GRP_910("dssp2 4p2", DSSP2, p910_dssp2_pin2), + GRP_910("dssp2 3p3", DSSP2, p910_dssp2_pin3), + GRP_910("dssp3 4p1", DSSP3, p910_dssp3_pin1), + GRP_910("dssp3 4p2", DSSP3, p910_dssp3_pin2), + GRP_910("dssp3 3p3", DSSP3, p910_dssp3_pin3), + GRP_910("ssp0 4p1", SSP0, p910_ssp0_pin1), + GRP_910("ssp0 4p2", SSP0, p910_ssp0_pin2), + GRP_910("ssp0 4p3", SSP0, p910_ssp0_pin3), + GRP_910("ssp0 4p4", SSP0, p910_ssp0_pin4), + GRP_910("ssp1 4p1", SSP1, p910_ssp1_pin1), + GRP_910("ssp1 5p2", SSP1, p910_ssp1_pin2), + GRP_910("ssp2 4p1", SSP2, p910_ssp2_pin1), + GRP_910("ssp2 4p2", SSP2, p910_ssp2_pin2), + GRP_910("ssp2 4p3", SSP2, p910_ssp2_pin3), + GRP_910("ssp2 4p4", SSP2, p910_ssp2_pin4), + GRP_910("gssp", GSSP, p910_gssp_pin1), + GRP_910("pwm0", PWM0, p910_pwm0_pin1), + GRP_910("pwm1-1", PWM1, p910_pwm1_pin1), + GRP_910("pwm1-2", PWM1, p910_pwm1_pin2), + GRP_910("pwm2", PWM2, p910_pwm2_pin1), + GRP_910("pwm3-1", PWM3, p910_pwm3_pin1), + GRP_910("pwm3-2", PWM3, p910_pwm3_pin2), + GRP_910("pwm3-3", PWM3, p910_pwm3_pin3), + GRP_910("pri jtag", PRI_JTAG, p910_pri_jtag_pin1), + GRP_910("sec1 jtag", SEC1_JTAG, p910_sec1_jtag_pin1), + GRP_910("sec2 jtag", SEC2_JTAG, p910_sec2_jtag_pin1), + GRP_910("hsl 6p1", HSL, p910_hsl_pin1), + GRP_910("hsl 6p2", HSL, p910_hsl_pin2), + GRP_910("hsl 6p3", HSL, p910_hsl_pin3), + GRP_910("w1-1", ONE_WIRE, p910_w1_pin1), + GRP_910("w1-2", ONE_WIRE, p910_w1_pin2), + GRP_910("w1-3", ONE_WIRE, p910_w1_pin3), + GRP_910("w1-4", ONE_WIRE, p910_w1_pin4), + GRP_910("kpmk 16p1", KP_MK, p910_kpmk_pin1), + GRP_910("kpmk 11p2", KP_MK, p910_kpmk_pin2), + GRP_910("kpdk 8p1", KP_DK, p910_kpdk_pin1), + GRP_910("tds 5p1", TDS, p910_tds_pin1), + GRP_910("tds 4p2", TDS, p910_tds_pin2), + GRP_910("tb 4p1", TB, p910_tb_pin1), + GRP_910("tb 4p2", TB, p910_tb_pin2), + GRP_910("tb 4p3", TB, p910_tb_pin3), + GRP_910("ext dma0-1", EXT_DMA, p910_ext_dma0_pin1), + GRP_910("ext dma0-2", EXT_DMA, p910_ext_dma0_pin2), + GRP_910("ext dma0-3", EXT_DMA, p910_ext_dma0_pin3), + GRP_910("ext dma1-1", EXT_DMA, p910_ext_dma1_pin1), + GRP_910("ext dma1-2", EXT_DMA, p910_ext_dma1_pin2), + GRP_910("ext dma1-3", EXT_DMA, p910_ext_dma1_pin3), + GRP_910("ext dma2", EXT_DMA, p910_ext_dma2_pin1), + GRP_910("ext0 int-1", EXT_INT, p910_ext0_int_pin1), + GRP_910("ext0 int-2", EXT_INT, p910_ext0_int_pin2), + GRP_910("ext1 int-1", EXT_INT, p910_ext1_int_pin1), + GRP_910("ext1 int-2", EXT_INT, p910_ext1_int_pin2), + GRP_910("ext2 int-1", EXT_INT, p910_ext2_int_pin1), + GRP_910("ext2 int-2", EXT_INT, p910_ext2_int_pin2), + GRP_910("dac st23-1", DAC_ST23, p910_dac_st23_pin1), + GRP_910("dac st23-2", DAC_ST23, p910_dac_st23_pin2), + GRP_910("dac st23-3", DAC_ST23, p910_dac_st23_pin3), + GRP_910("dac st23-4", DAC_ST23, p910_dac_st23_pin4), + GRP_910("vcxo out-1", VCXO_OUT, p910_vcxo_out_pin1), + GRP_910("vcxo out-2", VCXO_OUT, p910_vcxo_out_pin2), + GRP_910("vcxo out-3", VCXO_OUT, p910_vcxo_out_pin3), + GRP_910("vcxo req-1", VCXO_REQ, p910_vcxo_req_pin1), + GRP_910("vcxo req-2", VCXO_REQ, p910_vcxo_req_pin2), + GRP_910("vcxo out2-1", VCXO_OUT2, p910_vcxo_out2_pin1), + GRP_910("vcxo out2-2", VCXO_OUT2, p910_vcxo_out2_pin2), + GRP_910("vcxo req2", VCXO_REQ2, p910_vcxo_req2_pin1), + GRP_910("ulpi", ULPI, p910_ulpi_pin1), + GRP_910("nand", NAND, p910_nand_pin1), + GRP_910("gpio0-1", GPIO, p910_gpio0_pin1), + GRP_910("gpio0-2", GPIO, p910_gpio0_pin2), + GRP_910("gpio1-1", GPIO, p910_gpio1_pin1), + GRP_910("gpio1-2", GPIO, p910_gpio1_pin2), + GRP_910("gpio2-1", GPIO, p910_gpio2_pin1), + GRP_910("gpio2-2", GPIO, p910_gpio2_pin2), + GRP_910("gpio3-1", GPIO, p910_gpio3_pin1), + GRP_910("gpio3-2", GPIO, p910_gpio3_pin2), + GRP_910("gpio20-1", GPIO, p910_gpio20_pin1), + GRP_910("gpio20-2", GPIO, p910_gpio20_pin2), + GRP_910("gpio21-1", GPIO, p910_gpio21_pin1), + GRP_910("gpio21-2", GPIO, p910_gpio21_pin2), + GRP_910("gpio22-1", GPIO, p910_gpio22_pin1), + GRP_910("gpio22-2", GPIO, p910_gpio22_pin2), + GRP_910("gpio23-1", GPIO, p910_gpio23_pin1), + GRP_910("gpio23-2", GPIO, p910_gpio23_pin2), + GRP_910("gpio24-1", GPIO, p910_gpio24_pin1), + GRP_910("gpio24-2", GPIO, p910_gpio24_pin2), + GRP_910("gpio25-1", GPIO, p910_gpio25_pin1), + GRP_910("gpio25-2", GPIO, p910_gpio25_pin2), + GRP_910("gpio26-1", GPIO, p910_gpio26_pin1), + GRP_910("gpio26-2", GPIO, p910_gpio26_pin2), + GRP_910("gpio27-1", GPIO, p910_gpio27_pin1), + GRP_910("gpio27-2", GPIO, p910_gpio27_pin2), + GRP_910("gpio85-1", GPIO, p910_gpio85_pin1), + GRP_910("gpio85-2", GPIO, p910_gpio85_pin2), + GRP_910("gpio86-1", GPIO, p910_gpio86_pin1), + GRP_910("gpio86-2", GPIO, p910_gpio86_pin2), + GRP_910("gpio87-1", GPIO, p910_gpio87_pin1), + GRP_910("gpio87-2", GPIO, p910_gpio87_pin2), + GRP_910("gpio88-1", GPIO, p910_gpio88_pin1), + GRP_910("gpio88-2", GPIO, p910_gpio88_pin2), + GRP_910("gpio89-1", GPIO, p910_gpio89_pin1), + GRP_910("gpio89-2", GPIO, p910_gpio89_pin2), + GRP_910("gpio90-1", GPIO, p910_gpio90_pin1), + GRP_910("gpio90-2", GPIO, p910_gpio90_pin2), + GRP_910("gpio91-1", GPIO, p910_gpio91_pin1), + GRP_910("gpio91-2", GPIO, p910_gpio91_pin2), + GRP_910("gpio92-1", GPIO, p910_gpio92_pin1), + GRP_910("gpio92-2", GPIO, p910_gpio92_pin2), +}; + +static const char * const p910_usim2_grps[] = {"usim2 3p1", "usim2 3p2"}; +static const char * const p910_mmc1_grps[] = {"mmc1 12p"}; +static const char * const p910_mmc2_grps[] = {"mmc2 10p"}; +static const char * const p910_mmc3_grps[] = {"mmc3 6p", "mmc3 10p"}; +static const char * const p910_uart0_grps[] = {"uart0 4p"}; +static const char * const p910_uart1_grps[] = {"uart1 2p1", "uart1 2p2", + "uart1 2p3", "uart1 4p4", "uart1 4p5"}; +static const char * const p910_uart2_grps[] = {"uart2 2p1", "uart2 2p2", + "uart2 4p3", "uart2 4p4"}; +static const char * const p910_twsi_grps[] = {"twsi 2p1", "twsi 2p2", + "twsi 2p3"}; +static const char * const p910_ccic_grps[] = {"ccic"}; +static const char * const p910_lcd_grps[] = {"lcd"}; +static const char * const p910_spi_grps[] = {"spi 4p1", "spi 4p2", "spi 5p3", + "spi 5p4"}; +static const char * const p910_dssp2_grps[] = {"dssp2 4p1", "dssp2 4p2", + "dssp2 3p3"}; +static const char * const p910_dssp3_grps[] = {"dssp3 4p1", "dssp3 4p2", + "dssp3 3p3"}; +static const char * const p910_ssp0_grps[] = {"ssp0 4p1", "ssp0 4p2", + "ssp0 4p3", "ssp0 4p4"}; +static const char * const p910_ssp1_grps[] = {"ssp1 4p1", "ssp1 5p2"}; +static const char * const p910_ssp2_grps[] = {"ssp2 4p1", "ssp2 4p2", + "ssp2 4p3", "ssp2 4p4"}; +static const char * const p910_gssp_grps[] = {"gssp"}; +static const char * const p910_pwm0_grps[] = {"pwm0"}; +static const char * const p910_pwm1_grps[] = {"pwm1-1", "pwm1-2"}; +static const char * const p910_pwm2_grps[] = {"pwm2"}; +static const char * const p910_pwm3_grps[] = {"pwm3-1", "pwm3-2", "pwm3-3"}; +static const char * const p910_pri_jtag_grps[] = {"pri jtag"}; +static const char * const p910_sec1_jtag_grps[] = {"sec1 jtag"}; +static const char * const p910_sec2_jtag_grps[] = {"sec2 jtag"}; +static const char * const p910_hsl_grps[] = {"hsl 6p1", "hsl 6p2", "hsl 6p3"}; +static const char * const p910_w1_grps[] = {"w1-1", "w1-2", "w1-3", "w1-4"}; +static const char * const p910_kpmk_grps[] = {"kpmk 16p1", "kpmk 11p2"}; +static const char * const p910_kpdk_grps[] = {"kpdk 8p1"}; +static const char * const p910_tds_grps[] = {"tds 5p1", "tds 4p2"}; +static const char * const p910_tb_grps[] = {"tb 4p1", "tb 4p2", "tb 4p3"}; +static const char * const p910_dma0_grps[] = {"ext dma0-1", "ext dma0-2", + "ext dma0-3"}; +static const char * const p910_dma1_grps[] = {"ext dma1-1", "ext dma1-2", + "ext dma1-3"}; +static const char * const p910_dma2_grps[] = {"ext dma2"}; +static const char * const p910_int0_grps[] = {"ext0 int-1", "ext0 int-2"}; +static const char * const p910_int1_grps[] = {"ext1 int-1", "ext1 int-2"}; +static const char * const p910_int2_grps[] = {"ext2 int-1", "ext2 int-2"}; +static const char * const p910_dac_st23_grps[] = {"dac st23-1", "dac st23-2", + "dac st23-3", "dac st23-4"}; +static const char * const p910_vcxo_out_grps[] = {"vcxo out-1", "vcxo out-2", + "vcxo out-3"}; +static const char * const p910_vcxo_req_grps[] = {"vcxo req-1", "vcxo req-2"}; +static const char * const p910_vcxo_out2_grps[] = {"vcxo out2-1", + "vcxo out2-2"}; +static const char * const p910_vcxo_req2_grps[] = {"vcxo req2"}; +static const char * const p910_ulpi_grps[] = {"ulpi"}; +static const char * const p910_nand_grps[] = {"nand"}; +static const char * const p910_gpio0_grps[] = {"gpio0-1", "gpio0-2"}; +static const char * const p910_gpio1_grps[] = {"gpio1-1", "gpio1-2"}; +static const char * const p910_gpio2_grps[] = {"gpio2-1", "gpio2-2"}; +static const char * const p910_gpio3_grps[] = {"gpio3-1", "gpio3-2"}; +static const char * const p910_gpio20_grps[] = {"gpio20-1", "gpio20-2"}; +static const char * const p910_gpio21_grps[] = {"gpio21-1", "gpio21-2"}; +static const char * const p910_gpio22_grps[] = {"gpio22-1", "gpio22-2"}; +static const char * const p910_gpio23_grps[] = {"gpio23-1", "gpio23-2"}; +static const char * const p910_gpio24_grps[] = {"gpio24-1", "gpio24-2"}; +static const char * const p910_gpio25_grps[] = {"gpio25-1", "gpio25-2"}; +static const char * const p910_gpio26_grps[] = {"gpio26-1", "gpio26-2"}; +static const char * const p910_gpio27_grps[] = {"gpio27-1", "gpio27-2"}; +static const char * const p910_gpio85_grps[] = {"gpio85-1", "gpio85-2"}; +static const char * const p910_gpio86_grps[] = {"gpio86-1", "gpio86-2"}; +static const char * const p910_gpio87_grps[] = {"gpio87-1", "gpio87-2"}; +static const char * const p910_gpio88_grps[] = {"gpio88-1", "gpio88-2"}; +static const char * const p910_gpio89_grps[] = {"gpio89-1", "gpio89-2"}; +static const char * const p910_gpio90_grps[] = {"gpio90-1", "gpio90-2"}; +static const char * const p910_gpio91_grps[] = {"gpio91-1", "gpio91-2"}; +static const char * const p910_gpio92_grps[] = {"gpio92-1", "gpio92-2"}; + +static struct pxa3xx_pmx_func pxa910_funcs[] = { + {"usim2", ARRAY_AND_SIZE(p910_usim2_grps)}, + {"mmc1", ARRAY_AND_SIZE(p910_mmc1_grps)}, + {"mmc2", ARRAY_AND_SIZE(p910_mmc2_grps)}, + {"mmc3", ARRAY_AND_SIZE(p910_mmc3_grps)}, + {"uart0", ARRAY_AND_SIZE(p910_uart0_grps)}, + {"uart1", ARRAY_AND_SIZE(p910_uart1_grps)}, + {"uart2", ARRAY_AND_SIZE(p910_uart2_grps)}, + {"twsi", ARRAY_AND_SIZE(p910_twsi_grps)}, + {"ccic", ARRAY_AND_SIZE(p910_ccic_grps)}, + {"lcd", ARRAY_AND_SIZE(p910_lcd_grps)}, + {"spi", ARRAY_AND_SIZE(p910_spi_grps)}, + {"dssp2", ARRAY_AND_SIZE(p910_dssp2_grps)}, + {"dssp3", ARRAY_AND_SIZE(p910_dssp3_grps)}, + {"ssp0", ARRAY_AND_SIZE(p910_ssp0_grps)}, + {"ssp1", ARRAY_AND_SIZE(p910_ssp1_grps)}, + {"ssp2", ARRAY_AND_SIZE(p910_ssp2_grps)}, + {"gssp", ARRAY_AND_SIZE(p910_gssp_grps)}, + {"pwm0", ARRAY_AND_SIZE(p910_pwm0_grps)}, + {"pwm1", ARRAY_AND_SIZE(p910_pwm1_grps)}, + {"pwm2", ARRAY_AND_SIZE(p910_pwm2_grps)}, + {"pwm3", ARRAY_AND_SIZE(p910_pwm3_grps)}, + {"pri_jtag", ARRAY_AND_SIZE(p910_pri_jtag_grps)}, + {"sec1_jtag", ARRAY_AND_SIZE(p910_sec1_jtag_grps)}, + {"sec2_jtag", ARRAY_AND_SIZE(p910_sec2_jtag_grps)}, + {"hsl", ARRAY_AND_SIZE(p910_hsl_grps)}, + {"w1", ARRAY_AND_SIZE(p910_w1_grps)}, + {"kpmk", ARRAY_AND_SIZE(p910_kpmk_grps)}, + {"kpdk", ARRAY_AND_SIZE(p910_kpdk_grps)}, + {"tds", ARRAY_AND_SIZE(p910_tds_grps)}, + {"tb", ARRAY_AND_SIZE(p910_tb_grps)}, + {"dma0", ARRAY_AND_SIZE(p910_dma0_grps)}, + {"dma1", ARRAY_AND_SIZE(p910_dma1_grps)}, + {"dma2", ARRAY_AND_SIZE(p910_dma2_grps)}, + {"int0", ARRAY_AND_SIZE(p910_int0_grps)}, + {"int1", ARRAY_AND_SIZE(p910_int1_grps)}, + {"int2", ARRAY_AND_SIZE(p910_int2_grps)}, + {"dac_st23", ARRAY_AND_SIZE(p910_dac_st23_grps)}, + {"vcxo_out", ARRAY_AND_SIZE(p910_vcxo_out_grps)}, + {"vcxo_req", ARRAY_AND_SIZE(p910_vcxo_req_grps)}, + {"vcxo_out2", ARRAY_AND_SIZE(p910_vcxo_out2_grps)}, + {"vcxo_req2", ARRAY_AND_SIZE(p910_vcxo_req2_grps)}, + {"ulpi", ARRAY_AND_SIZE(p910_ulpi_grps)}, + {"nand", ARRAY_AND_SIZE(p910_nand_grps)}, + {"gpio0", ARRAY_AND_SIZE(p910_gpio0_grps)}, + {"gpio1", ARRAY_AND_SIZE(p910_gpio1_grps)}, + {"gpio2", ARRAY_AND_SIZE(p910_gpio2_grps)}, + {"gpio3", ARRAY_AND_SIZE(p910_gpio3_grps)}, + {"gpio20", ARRAY_AND_SIZE(p910_gpio20_grps)}, + {"gpio21", ARRAY_AND_SIZE(p910_gpio21_grps)}, + {"gpio22", ARRAY_AND_SIZE(p910_gpio22_grps)}, + {"gpio23", ARRAY_AND_SIZE(p910_gpio23_grps)}, + {"gpio24", ARRAY_AND_SIZE(p910_gpio24_grps)}, + {"gpio25", ARRAY_AND_SIZE(p910_gpio25_grps)}, + {"gpio26", ARRAY_AND_SIZE(p910_gpio26_grps)}, + {"gpio27", ARRAY_AND_SIZE(p910_gpio27_grps)}, + {"gpio85", ARRAY_AND_SIZE(p910_gpio85_grps)}, + {"gpio86", ARRAY_AND_SIZE(p910_gpio86_grps)}, + {"gpio87", ARRAY_AND_SIZE(p910_gpio87_grps)}, + {"gpio88", ARRAY_AND_SIZE(p910_gpio88_grps)}, + {"gpio89", ARRAY_AND_SIZE(p910_gpio89_grps)}, + {"gpio90", ARRAY_AND_SIZE(p910_gpio90_grps)}, + {"gpio91", ARRAY_AND_SIZE(p910_gpio91_grps)}, + {"gpio92", ARRAY_AND_SIZE(p910_gpio92_grps)}, +}; + +static struct pinctrl_desc pxa910_pctrl_desc = { + .name = "pxa910-pinctrl", + .owner = THIS_MODULE, +}; + +static struct pxa3xx_pinmux_info pxa910_info = { + .mfp = pxa910_mfp, + .num_mfp = ARRAY_SIZE(pxa910_mfp), + .grps = pxa910_grps, + .num_grps = ARRAY_SIZE(pxa910_grps), + .funcs = pxa910_funcs, + .num_funcs = ARRAY_SIZE(pxa910_funcs), + .num_gpio = 128, + .desc = &pxa910_pctrl_desc, + .pads = pxa910_pads, + .num_pads = ARRAY_SIZE(pxa910_pads), + + .cputype = PINCTRL_PXA910, + .ds_mask = PXA910_DS_MASK, + .ds_shift = PXA910_DS_SHIFT, +}; + +static int __devinit pxa910_pinmux_probe(struct platform_device *pdev) +{ + return pxa3xx_pinctrl_register(pdev, &pxa910_info); +} + +static int __devexit pxa910_pinmux_remove(struct platform_device *pdev) +{ + return pxa3xx_pinctrl_unregister(pdev); +} + +static struct platform_driver pxa910_pinmux_driver = { + .driver = { + .name = "pxa910-pinmux", + .owner = THIS_MODULE, + }, + .probe = pxa910_pinmux_probe, + .remove = __devexit_p(pxa910_pinmux_remove), +}; + +static int __init pxa910_pinmux_init(void) +{ + return platform_driver_register(&pxa910_pinmux_driver); +} +core_initcall_sync(pxa910_pinmux_init); + +static void __exit pxa910_pinmux_exit(void) +{ + platform_driver_unregister(&pxa910_pinmux_driver); +} +module_exit(pxa910_pinmux_exit); + +MODULE_AUTHOR("Haojian Zhuang "); +MODULE_DESCRIPTION("PXA3xx pin control driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-70-g09d2 From b5d5843a1dd0031d63d9d9484346d86eae9cab3b Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Fri, 27 Jan 2012 04:24:55 +0000 Subject: mISDN: use memchr_inv Use memchr_inv to check if the data contains all same bytes. It is faster than looping for each byte. Signed-off-by: Akinobu Mita Cc: Karsten Keil Cc: netdev@vger.kernel.org Signed-off-by: David S. Miller --- drivers/isdn/mISDN/l1oip_core.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c index 22f8ec8b924..04f115a9c43 100644 --- a/drivers/isdn/mISDN/l1oip_core.c +++ b/drivers/isdn/mISDN/l1oip_core.c @@ -1112,7 +1112,7 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb) struct l1oip *hc = bch->hw; int ret = -EINVAL; struct mISDNhead *hh = mISDN_HEAD_P(skb); - int l, ll, i; + int l, ll; unsigned char *p; switch (hh->prim) { @@ -1128,13 +1128,8 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb) break; } /* check for AIS / ulaw-silence */ - p = skb->data; l = skb->len; - for (i = 0; i < l; i++) { - if (*p++ != 0xff) - break; - } - if (i == l) { + if (!memchr_inv(skb->data, 0xff, l)) { if (debug & DEBUG_L1OIP_MSG) printk(KERN_DEBUG "%s: got AIS, not sending, " "but counting\n", __func__); @@ -1144,13 +1139,8 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb) return 0; } /* check for silence */ - p = skb->data; l = skb->len; - for (i = 0; i < l; i++) { - if (*p++ != 0x2a) - break; - } - if (i == l) { + if (!memchr_inv(skb->data, 0x2a, l)) { if (debug & DEBUG_L1OIP_MSG) printk(KERN_DEBUG "%s: got silence, not sending" ", but counting\n", __func__); -- cgit v1.2.3-70-g09d2 From 8ef78adcb03b1fcb53c3bd62df4e96c1d2706c58 Mon Sep 17 00:00:00 2001 From: Peter P Waskiewicz Jr Date: Wed, 1 Feb 2012 09:19:21 +0000 Subject: ixgbe: Add module parameter to allow untested and unsafe SFP+ modules The X520 family of network devices, with the 82599 chip, support a small number of Intel-verified SFP+ modules on their NICs. To maintain stability and quality, the current devices restrict untested 3rd party SFP+ modules. This patch introduces a module parameter for ixgbe to allow these untested modules at the user's peril. It also includes a warning to the syslog alerting users that the modules aren't supported, and results may vary. CC: Jesper Dangaard Brouer Signed-off-by: Peter P Waskiewicz Jr Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 8 ++++++++ drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c | 14 +++++++++++--- drivers/net/ethernet/intel/ixgbe/ixgbe_type.h | 1 + 3 files changed, 20 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 1ee5d0fbb90..2e8e7640b60 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -131,6 +131,11 @@ MODULE_PARM_DESC(max_vfs, "Maximum number of virtual functions to allocate per physical function"); #endif /* CONFIG_PCI_IOV */ +static unsigned int allow_unsupported_sfp; +module_param(allow_unsupported_sfp, uint, 0); +MODULE_PARM_DESC(allow_unsupported_sfp, + "Allow unsupported and untested SFP+ modules on 82599-based adapters"); + MODULE_AUTHOR("Intel Corporation, "); MODULE_DESCRIPTION("Intel(R) 10 Gigabit PCI Express Network Driver"); MODULE_LICENSE("GPL"); @@ -7489,6 +7494,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, e_crit(probe, "Fan has stopped, replace the adapter\n"); } + if (allow_unsupported_sfp) + hw->allow_unsupported_sfp = allow_unsupported_sfp; + /* reset_hw fills in the perm_addr as well */ hw->phy.reset_if_overtemp = true; err = hw->mac.ops.reset_hw(hw); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c index 7cf1e1f56c6..29fda9777ff 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c @@ -834,6 +834,7 @@ out: **/ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) { + struct ixgbe_adapter *adapter = hw->back; s32 status = IXGBE_ERR_PHY_ADDR_INVALID; u32 vendor_oui = 0; enum ixgbe_sfp_type stored_sfp_type = hw->phy.sfp_type; @@ -1068,9 +1069,16 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) if (hw->phy.type == ixgbe_phy_sfp_intel) { status = 0; } else { - hw_dbg(hw, "SFP+ module not supported\n"); - hw->phy.type = ixgbe_phy_sfp_unsupported; - status = IXGBE_ERR_SFP_NOT_SUPPORTED; + if (hw->allow_unsupported_sfp) { + e_warn(drv, "WARNING: Intel (R) Network Connections are quality tested using Intel (R) Ethernet Optics. Using untested modules is not supported and may cause unstable operation or damage to the module or the adapter. Intel Corporation is not responsible for any harm caused by using untested modules."); + status = 0; + } else { + hw_dbg(hw, + "SFP+ module not supported\n"); + hw->phy.type = + ixgbe_phy_sfp_unsupported; + status = IXGBE_ERR_SFP_NOT_SUPPORTED; + } } } else { status = 0; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h index 775602ef90e..2dc5e71cb3f 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h @@ -2892,6 +2892,7 @@ struct ixgbe_hw { u8 revision_id; bool adapter_stopped; bool force_full_reset; + bool allow_unsupported_sfp; }; struct ixgbe_info { -- cgit v1.2.3-70-g09d2 From d45b9d39a1aed7851948460d29b843ce70eb0a68 Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Sun, 29 Jan 2012 20:17:39 +0000 Subject: be2net: add descriptions for stat counters reported via ethtool Also rename a few counters appropritely and delete 2 counters that are not implemented in HW. vlan_mismatch_drops does not exist in BE3 and is accounted for in address_mismatch_drops. Do the same thing for BE2 and Lancer. Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be.h | 3 +- drivers/net/ethernet/emulex/benet/be_cmds.h | 10 ++-- drivers/net/ethernet/emulex/benet/be_ethtool.c | 64 ++++++++++++++++++++++++-- drivers/net/ethernet/emulex/benet/be_main.c | 15 +++--- 4 files changed, 74 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index 453d48612f8..74aa1481197 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h @@ -265,7 +265,6 @@ struct be_drv_stats { u32 rx_drops_no_erx_descr; u32 rx_drops_no_tpre_descr; u32 rx_drops_too_many_frags; - u32 rx_drops_invalid_ring; u32 forwarded_packets; u32 rx_drops_mtu; u32 rx_crc_errors; @@ -276,7 +275,7 @@ struct be_drv_stats { u32 rx_in_range_errors; u32 rx_out_range_errors; u32 rx_frame_too_long; - u32 rx_address_match_errors; + u32 rx_address_mismatch_drops; u32 rx_dropped_too_small; u32 rx_dropped_too_short; u32 rx_dropped_header_too_small; diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h index dca89249088..bbd012b41fb 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/drivers/net/ethernet/emulex/benet/be_cmds.h @@ -592,8 +592,8 @@ struct be_port_rxf_stats_v0 { u32 rx_in_range_errors; /* dword 10*/ u32 rx_out_range_errors; /* dword 11*/ u32 rx_frame_too_long; /* dword 12*/ - u32 rx_address_match_errors; /* dword 13*/ - u32 rx_vlan_mismatch; /* dword 14*/ + u32 rx_address_mismatch_drops; /* dword 13*/ + u32 rx_vlan_mismatch_drops; /* dword 14*/ u32 rx_dropped_too_small; /* dword 15*/ u32 rx_dropped_too_short; /* dword 16*/ u32 rx_dropped_header_too_small; /* dword 17*/ @@ -799,8 +799,8 @@ struct lancer_pport_stats { u32 rx_control_frames_unknown_opcode_hi; u32 rx_in_range_errors; u32 rx_out_of_range_errors; - u32 rx_address_match_errors; - u32 rx_vlan_mismatch_errors; + u32 rx_address_mismatch_drops; + u32 rx_vlan_mismatch_drops; u32 rx_dropped_too_small; u32 rx_dropped_too_short; u32 rx_dropped_header_too_small; @@ -1384,7 +1384,7 @@ struct be_port_rxf_stats_v1 { u32 rx_in_range_errors; u32 rx_out_range_errors; u32 rx_frame_too_long; - u32 rx_address_match_errors; + u32 rx_address_mismatch_drops; u32 rx_dropped_too_small; u32 rx_dropped_too_short; u32 rx_dropped_header_too_small; diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c index 6db6b6ae5e9..0a5ee224cfe 100644 --- a/drivers/net/ethernet/emulex/benet/be_ethtool.c +++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c @@ -42,15 +42,42 @@ static const struct be_ethtool_stat et_stats[] = { {DRVSTAT_INFO(rx_alignment_symbol_errors)}, {DRVSTAT_INFO(rx_pause_frames)}, {DRVSTAT_INFO(rx_control_frames)}, + /* Received packets dropped when the Ethernet length field + * is not equal to the actual Ethernet data length. + */ {DRVSTAT_INFO(rx_in_range_errors)}, + /* Received packets dropped when their length field is >= 1501 bytes + * and <= 1535 bytes. + */ {DRVSTAT_INFO(rx_out_range_errors)}, + /* Received packets dropped when they are longer than 9216 bytes */ {DRVSTAT_INFO(rx_frame_too_long)}, - {DRVSTAT_INFO(rx_address_match_errors)}, + /* Received packets dropped when they don't pass the unicast or + * multicast address filtering. + */ + {DRVSTAT_INFO(rx_address_mismatch_drops)}, + /* Received packets dropped when IP packet length field is less than + * the IP header length field. + */ {DRVSTAT_INFO(rx_dropped_too_small)}, + /* Received packets dropped when IP length field is greater than + * the actual packet length. + */ {DRVSTAT_INFO(rx_dropped_too_short)}, + /* Received packets dropped when the IP header length field is less + * than 5. + */ {DRVSTAT_INFO(rx_dropped_header_too_small)}, + /* Received packets dropped when the TCP header length field is less + * than 5 or the TCP header length + IP header length is more + * than IP packet length. + */ {DRVSTAT_INFO(rx_dropped_tcp_length)}, {DRVSTAT_INFO(rx_dropped_runt)}, + /* Number of received packets dropped when a fifo for descriptors going + * into the packet demux block overflows. In normal operation, this + * fifo must never overflow. + */ {DRVSTAT_INFO(rxpp_fifo_overflow_drop)}, {DRVSTAT_INFO(rx_input_fifo_overflow_drop)}, {DRVSTAT_INFO(rx_ip_checksum_errs)}, @@ -59,16 +86,35 @@ static const struct be_ethtool_stat et_stats[] = { {DRVSTAT_INFO(tx_pauseframes)}, {DRVSTAT_INFO(tx_controlframes)}, {DRVSTAT_INFO(rx_priority_pause_frames)}, + /* Received packets dropped when an internal fifo going into + * main packet buffer tank (PMEM) overflows. + */ {DRVSTAT_INFO(pmem_fifo_overflow_drop)}, {DRVSTAT_INFO(jabber_events)}, + /* Received packets dropped due to lack of available HW packet buffers + * used to temporarily hold the received packets. + */ {DRVSTAT_INFO(rx_drops_no_pbuf)}, - {DRVSTAT_INFO(rx_drops_no_txpb)}, + /* Received packets dropped due to input receive buffer + * descriptor fifo overflowing. + */ {DRVSTAT_INFO(rx_drops_no_erx_descr)}, + /* Packets dropped because the internal FIFO to the offloaded TCP + * receive processing block is full. This could happen only for + * offloaded iSCSI or FCoE trarffic. + */ {DRVSTAT_INFO(rx_drops_no_tpre_descr)}, + /* Received packets dropped when they need more than 8 + * receive buffers. This cannot happen as the driver configures + * 2048 byte receive buffers. + */ {DRVSTAT_INFO(rx_drops_too_many_frags)}, - {DRVSTAT_INFO(rx_drops_invalid_ring)}, {DRVSTAT_INFO(forwarded_packets)}, + /* Received packets dropped when the frame length + * is more than 9018 bytes + */ {DRVSTAT_INFO(rx_drops_mtu)}, + /* Number of packets dropped due to random early drop function */ {DRVSTAT_INFO(eth_red_drops)}, {DRVSTAT_INFO(be_on_die_temperature)} }; @@ -84,8 +130,15 @@ static const struct be_ethtool_stat et_rx_stats[] = { {DRVSTAT_RX_INFO(rx_events)}, {DRVSTAT_RX_INFO(rx_compl)}, {DRVSTAT_RX_INFO(rx_mcast_pkts)}, + /* Number of page allocation failures while posting receive buffers + * to HW. + */ {DRVSTAT_RX_INFO(rx_post_fail)}, + /* Recevied packets dropped due to skb allocation failure */ {DRVSTAT_RX_INFO(rx_drops_no_skbs)}, + /* Received packets dropped due to lack of available fetched buffers + * posted by the driver. + */ {DRVSTAT_RX_INFO(rx_drops_no_frags)} }; #define ETHTOOL_RXSTATS_NUM (ARRAY_SIZE(et_rx_stats)) @@ -97,9 +150,14 @@ static const struct be_ethtool_stat et_tx_stats[] = { {DRVSTAT_TX_INFO(tx_compl)}, /* If moving this member see above note */ {DRVSTAT_TX_INFO(tx_bytes)}, {DRVSTAT_TX_INFO(tx_pkts)}, + /* Number of skbs queued for trasmission by the driver */ {DRVSTAT_TX_INFO(tx_reqs)}, + /* Number of TX work request blocks DMAed to HW */ {DRVSTAT_TX_INFO(tx_wrbs)}, {DRVSTAT_TX_INFO(tx_compl)}, + /* Number of times the TX queue was stopped due to lack + * of spaces in the TXQ. + */ {DRVSTAT_TX_INFO(tx_stops)} }; #define ETHTOOL_TXSTATS_NUM (ARRAY_SIZE(et_tx_stats)) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 0fbf365f5c6..1395f803cf7 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -286,7 +286,9 @@ static void populate_be2_stats(struct be_adapter *adapter) drvs->rx_input_fifo_overflow_drop = port_stats->rx_input_fifo_overflow; drvs->rx_dropped_header_too_small = port_stats->rx_dropped_header_too_small; - drvs->rx_address_match_errors = port_stats->rx_address_match_errors; + drvs->rx_address_mismatch_drops = + port_stats->rx_address_mismatch_drops + + port_stats->rx_vlan_mismatch_drops; drvs->rx_alignment_symbol_errors = port_stats->rx_alignment_symbol_errors; @@ -298,9 +300,7 @@ static void populate_be2_stats(struct be_adapter *adapter) else drvs->jabber_events = rxf_stats->port0_jabber_events; drvs->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf; - drvs->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb; drvs->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr; - drvs->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring; drvs->forwarded_packets = rxf_stats->forwarded_packets; drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu; drvs->rx_drops_no_tpre_descr = rxf_stats->rx_drops_no_tpre_descr; @@ -337,7 +337,7 @@ static void populate_be3_stats(struct be_adapter *adapter) port_stats->rx_dropped_header_too_small; drvs->rx_input_fifo_overflow_drop = port_stats->rx_input_fifo_overflow_drop; - drvs->rx_address_match_errors = port_stats->rx_address_match_errors; + drvs->rx_address_mismatch_drops = port_stats->rx_address_mismatch_drops; drvs->rx_alignment_symbol_errors = port_stats->rx_alignment_symbol_errors; drvs->rxpp_fifo_overflow_drop = port_stats->rxpp_fifo_overflow_drop; @@ -345,9 +345,7 @@ static void populate_be3_stats(struct be_adapter *adapter) drvs->tx_controlframes = port_stats->tx_controlframes; drvs->jabber_events = port_stats->jabber_events; drvs->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf; - drvs->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb; drvs->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr; - drvs->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring; drvs->forwarded_packets = rxf_stats->forwarded_packets; drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu; drvs->rx_drops_no_tpre_descr = rxf_stats->rx_drops_no_tpre_descr; @@ -380,13 +378,14 @@ static void populate_lancer_stats(struct be_adapter *adapter) drvs->rx_dropped_header_too_small = pport_stats->rx_dropped_header_too_small; drvs->rx_input_fifo_overflow_drop = pport_stats->rx_fifo_overflow; - drvs->rx_address_match_errors = pport_stats->rx_address_match_errors; + drvs->rx_address_mismatch_drops = + pport_stats->rx_address_mismatch_drops + + pport_stats->rx_vlan_mismatch_drops; drvs->rx_alignment_symbol_errors = pport_stats->rx_symbol_errors_lo; drvs->rxpp_fifo_overflow_drop = pport_stats->rx_fifo_overflow; drvs->tx_pauseframes = pport_stats->tx_pause_frames_lo; drvs->tx_controlframes = pport_stats->tx_control_frames_lo; drvs->jabber_events = pport_stats->rx_jabbers; - drvs->rx_drops_invalid_ring = pport_stats->rx_drops_invalid_queue; drvs->forwarded_packets = pport_stats->num_forwards_lo; drvs->rx_drops_mtu = pport_stats->rx_drops_mtu_lo; drvs->rx_drops_too_many_frags = -- cgit v1.2.3-70-g09d2 From dc7cdf6c6bfc837501ea403a73eec78a350b1f7f Mon Sep 17 00:00:00 2001 From: Danny Kukawka Date: Mon, 30 Jan 2012 12:00:18 +0000 Subject: hamradio: fix incompatible pointer in module parameter Fixed 'warning: return from incompatible pointer type' related to module parameters. Signed-off-by: Danny Kukawka Signed-off-by: David S. Miller --- drivers/net/hamradio/baycom_epp.c | 2 +- drivers/net/hamradio/baycom_par.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c index 9537aaa50c2..49b8b58fc5c 100644 --- a/drivers/net/hamradio/baycom_epp.c +++ b/drivers/net/hamradio/baycom_epp.c @@ -1162,7 +1162,7 @@ static void baycom_probe(struct net_device *dev) /* * command line settable parameters */ -static const char *mode[NR_PORTS] = { "", }; +static char *mode[NR_PORTS] = { "", }; static int iobase[NR_PORTS] = { 0x378, }; module_param_array(mode, charp, NULL, 0); diff --git a/drivers/net/hamradio/baycom_par.c b/drivers/net/hamradio/baycom_par.c index 279d2296290..f1aea0c9833 100644 --- a/drivers/net/hamradio/baycom_par.c +++ b/drivers/net/hamradio/baycom_par.c @@ -477,7 +477,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, /* * command line settable parameters */ -static const char *mode[NR_PORTS] = { "picpar", }; +static char *mode[NR_PORTS] = { "picpar", }; static int iobase[NR_PORTS] = { 0x378, }; module_param_array(mode, charp, NULL, 0); -- cgit v1.2.3-70-g09d2 From 12806a241b1756518bf63c4a464fff73c1a363f2 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Wed, 1 Feb 2012 03:05:13 +0000 Subject: atm: Fix typo in lanai.c Correct spelling "reseting" to resetting" in drivers/atm/lanai.c Signed-off-by: Masanari Iida Signed-off-by: David S. Miller --- drivers/atm/lanai.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c index f5569699f31..68c75887181 100644 --- a/drivers/atm/lanai.c +++ b/drivers/atm/lanai.c @@ -1572,7 +1572,7 @@ static inline void host_vcc_unbind(struct lanai_dev *lanai, static void lanai_reset(struct lanai_dev *lanai) { - printk(KERN_CRIT DEV_LABEL "(itf %d): *NOT* reseting - not " + printk(KERN_CRIT DEV_LABEL "(itf %d): *NOT* resetting - not " "implemented\n", lanai->number); /* TODO */ /* The following is just a hack until we write the real -- cgit v1.2.3-70-g09d2 From c3ca881f0a6e6421f167d3938f4b1e1d008cb505 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Wed, 1 Feb 2012 03:13:59 +0000 Subject: vmxnet3: Fix typo in vmxnet3_drv.c Correct spelling in "uncommited" to "uncommitted" in drivers/net/vmxnet3/vmxnet3_drv.c Signed-off-by: Masanari Iida Signed-off-by: David S. Miller --- drivers/net/vmxnet3/vmxnet3_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 482cfa891f8..e1562e8acba 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -633,7 +633,7 @@ vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32 ring_idx, dev_dbg(&adapter->netdev->dev, "alloc_rx_buf: %d allocated, next2fill %u, next2comp " - "%u, uncommited %u\n", num_allocated, ring->next2fill, + "%u, uncommitted %u\n", num_allocated, ring->next2fill, ring->next2comp, rq->uncommitted[ring_idx]); /* so that the device can distinguish a full ring and an empty ring */ -- cgit v1.2.3-70-g09d2 From 07d57a32fb6eb2da017796e038682f817a4f685e Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Wed, 1 Feb 2012 11:22:22 -0700 Subject: drivercore: Output common devicetree information in uevent When userspace needs to find a specific device, it currently isn't easy to resolve a /sys/devices/ path from a specific device tree node. Nor is it easy to obtain the compatible list for devices. This patch generalizes the code that inserts OF_* values into the uevent device attribute so that any device that is attached to an OF node will have that information exported to userspace. Without this patch only platform devices and some powerpc-specific busses have access to this data. The original function also creates a MODALIAS property for the compatible list, but that code has not been generalized into the common case because it has the potential to break module loading on a lot of bus types. Bus types are still responsible for their own MODALIAS properties. Boot tested on ARM and compile tested on PowerPC and SPARC. Signed-off-by: Grant Likely Acked-by: Greg Kroah-Hartman Cc: Tobias Klauser Cc: Frederic Lambert Cc: Rob Herring Cc: Mark Brown Cc: "David S. Miller" Cc: Benjamin Herrenschmidt --- arch/powerpc/kernel/ibmebus.c | 2 +- drivers/base/core.c | 5 +++++ drivers/base/platform.c | 2 +- drivers/macintosh/macio_asic.c | 2 +- drivers/of/device.c | 30 ++++++++++++++++-------------- include/linux/of_device.h | 8 ++++++-- 6 files changed, 30 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index d39ae606ff8..79bb282e650 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c @@ -713,7 +713,7 @@ static struct dev_pm_ops ibmebus_bus_dev_pm_ops = { struct bus_type ibmebus_bus_type = { .name = "ibmebus", - .uevent = of_device_uevent, + .uevent = of_device_uevent_modalias, .bus_attrs = ibmebus_bus_attrs, .match = ibmebus_bus_bus_match, .probe = ibmebus_bus_device_probe, diff --git a/drivers/base/core.c b/drivers/base/core.c index 4a67cc0c8b3..28d8c21bb32 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include #include @@ -267,6 +269,9 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, if (dev->driver) add_uevent_var(env, "DRIVER=%s", dev->driver->name); + /* Add common DT information about the device */ + of_device_uevent(dev, env); + /* have the bus specific function add its stuff */ if (dev->bus && dev->bus->uevent) { retval = dev->bus->uevent(dev, env); diff --git a/drivers/base/platform.c b/drivers/base/platform.c index f0c605e99ad..a1a72250258 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -621,7 +621,7 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) int rc; /* Some devices have extra OF data and an OF-style MODALIAS */ - rc = of_device_uevent(dev,env); + rc = of_device_uevent_modalias(dev,env); if (rc != -ENODEV) return rc; diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 4daf9e5a773..20e5c2cda43 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c @@ -137,7 +137,7 @@ extern struct device_attribute macio_dev_attrs[]; struct bus_type macio_bus_type = { .name = "macio", .match = macio_bus_match, - .uevent = of_device_uevent, + .uevent = of_device_uevent_modalias, .probe = macio_device_probe, .remove = macio_device_remove, .shutdown = macio_device_shutdown, diff --git a/drivers/of/device.c b/drivers/of/device.c index 62b4b32ac88..4c74e4fc5a5 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -128,39 +128,41 @@ ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len) /** * of_device_uevent - Display OF related uevent information */ -int of_device_uevent(struct device *dev, struct kobj_uevent_env *env) +void of_device_uevent(struct device *dev, struct kobj_uevent_env *env) { const char *compat; int seen = 0, cplen, sl; if ((!dev) || (!dev->of_node)) - return -ENODEV; - - if (add_uevent_var(env, "OF_NAME=%s", dev->of_node->name)) - return -ENOMEM; + return; - if (add_uevent_var(env, "OF_TYPE=%s", dev->of_node->type)) - return -ENOMEM; + add_uevent_var(env, "OF_NAME=%s", dev->of_node->name); + add_uevent_var(env, "OF_FULLNAME=%s", dev->of_node->full_name); + if (dev->of_node->type && strcmp("", dev->of_node->type) != 0) + add_uevent_var(env, "OF_TYPE=%s", dev->of_node->type); /* Since the compatible field can contain pretty much anything * it's not really legal to split it out with commas. We split it * up using a number of environment variables instead. */ - compat = of_get_property(dev->of_node, "compatible", &cplen); while (compat && *compat && cplen > 0) { - if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat)) - return -ENOMEM; - + add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat); sl = strlen(compat) + 1; compat += sl; cplen -= sl; seen++; } + add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen); +} - if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen)) - return -ENOMEM; +int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env) +{ + int sl; + + if ((!dev) || (!dev->of_node)) + return -ENODEV; - /* modalias is trickier, we add it in 2 steps */ + /* Devicetree modalias is tricky, we add it in 2 steps */ if (add_uevent_var(env, "MODALIAS=")) return -ENOMEM; diff --git a/include/linux/of_device.h b/include/linux/of_device.h index ae5638480ef..cbc42143fa5 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h @@ -34,7 +34,8 @@ extern void of_device_unregister(struct platform_device *ofdev); extern ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len); -extern int of_device_uevent(struct device *dev, struct kobj_uevent_env *env); +extern void of_device_uevent(struct device *dev, struct kobj_uevent_env *env); +extern int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env); static inline void of_device_node_put(struct device *dev) { @@ -49,7 +50,10 @@ static inline int of_driver_match_device(struct device *dev, return 0; } -static inline int of_device_uevent(struct device *dev, +static inline void of_device_uevent(struct device *dev, + struct kobj_uevent_env *env) { } + +static inline int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env) { return -ENODEV; -- cgit v1.2.3-70-g09d2 From 90bbf4fdf2dc64aa7c20a93a9744c56a566baf26 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 1 Feb 2012 13:33:42 +0100 Subject: spi/nuc900: Remove unnecessary memset of struct nuc900_spi The memory allocated using kzalloc by spi_alloc_master so it doesn't need to be set to 0 again. Signed-off-by: Tobias Klauser Signed-off-by: Grant Likely --- drivers/spi/spi-nuc900.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-nuc900.c b/drivers/spi/spi-nuc900.c index 182e9c87382..dae8be229c5 100644 --- a/drivers/spi/spi-nuc900.c +++ b/drivers/spi/spi-nuc900.c @@ -360,8 +360,6 @@ static int __devinit nuc900_spi_probe(struct platform_device *pdev) } hw = spi_master_get_devdata(master); - memset(hw, 0, sizeof(struct nuc900_spi)); - hw->master = spi_master_get(master); hw->pdata = pdev->dev.platform_data; hw->dev = &pdev->dev; -- cgit v1.2.3-70-g09d2 From d976f7626627117c211137cd2aaf8c1656e6627d Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Thu, 26 Jan 2012 15:52:15 -0800 Subject: clocksource: scx200_hrt: use pr_ instead of printk Switch from printk to using pr_. Signed-off-by: Jim Cromie [added commit msg & tweaked subject -jstultz] Signed-off-by: John Stultz --- drivers/clocksource/scx200_hrt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/scx200_hrt.c b/drivers/clocksource/scx200_hrt.c index 27f4d9637b6..e4e4a04ab23 100644 --- a/drivers/clocksource/scx200_hrt.c +++ b/drivers/clocksource/scx200_hrt.c @@ -71,7 +71,7 @@ static int __init init_hrt_clocksource(void) if (!request_region(scx200_cb_base + SCx200_TIMER_OFFSET, SCx200_TIMER_SIZE, "NatSemi SCx200 High-Resolution Timer")) { - printk(KERN_WARNING NAME ": unable to lock timer region\n"); + pr_warn("unable to lock timer region\n"); return -ENODEV; } @@ -88,7 +88,7 @@ static int __init init_hrt_clocksource(void) cs_hrt.mult = clocksource_hz2mult(HRT_FREQ + ppm, cs_hrt.shift); } - printk(KERN_INFO "enabling scx200 high-res timer (%s MHz +%d ppm)\n", + pr_info("enabling scx200 high-res timer (%s MHz +%d ppm)\n", mhz27 ? "27":"1", ppm); return clocksource_register(&cs_hrt); -- cgit v1.2.3-70-g09d2 From 13f0f030fb9d52c7fd48f3e6a2fe9ab0123875da Mon Sep 17 00:00:00 2001 From: Yong Zhang Date: Thu, 1 Dec 2011 15:20:15 +0800 Subject: clocksource: dbx500: convert to clocksource_register_hz() Convert clocksource_dbx500_prcmu to use clocksource_register_hz. Cc: Thomas Gleixner Cc: Mattias Wallin Acked-by: Linus Walleij Signed-off-by: Yong Zhang Signed-off-by: John Stultz --- drivers/clocksource/clksrc-dbx500-prcmu.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/clksrc-dbx500-prcmu.c b/drivers/clocksource/clksrc-dbx500-prcmu.c index fb6b6d28b60..c26c369eb9e 100644 --- a/drivers/clocksource/clksrc-dbx500-prcmu.c +++ b/drivers/clocksource/clksrc-dbx500-prcmu.c @@ -52,7 +52,6 @@ static struct clocksource clocksource_dbx500_prcmu = { .name = "dbx500-prcmu-timer", .rating = 300, .read = clksrc_dbx500_prcmu_read, - .shift = 10, .mask = CLOCKSOURCE_MASK(32), .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; @@ -90,7 +89,5 @@ void __init clksrc_dbx500_prcmu_init(void __iomem *base) setup_sched_clock(dbx500_prcmu_sched_clock_read, 32, RATE_32K); #endif - clocksource_calc_mult_shift(&clocksource_dbx500_prcmu, - RATE_32K, SCHED_CLOCK_MIN_WRAP); - clocksource_register(&clocksource_dbx500_prcmu); + clocksource_register_hz(&clocksource_dbx500_prcmu, RATE_32K); } -- cgit v1.2.3-70-g09d2 From 12d6d41276def096cb3f7dc36f438db9ed6a0a8d Mon Sep 17 00:00:00 2001 From: John Stultz Date: Mon, 9 Jan 2012 16:15:03 -0800 Subject: clocksource: scx200_hrt: Convert scx200 to use clocksource_register_hz Converts the scx200 clocksource to using clocksource_register_hz. CC: Jim Cromie Tested-by: Jim Cromie Acked-by: Jim Cromie Signed-off-by: John Stultz --- drivers/clocksource/scx200_hrt.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/scx200_hrt.c b/drivers/clocksource/scx200_hrt.c index e4e4a04ab23..60db8b1492f 100644 --- a/drivers/clocksource/scx200_hrt.c +++ b/drivers/clocksource/scx200_hrt.c @@ -49,9 +49,6 @@ static cycle_t read_hrt(struct clocksource *cs) return (cycle_t) inl(scx200_cb_base + SCx200_TIMER_OFFSET); } -#define HRT_SHIFT_1 22 -#define HRT_SHIFT_27 26 - static struct clocksource cs_hrt = { .name = "scx200_hrt", .rating = 250, @@ -63,6 +60,7 @@ static struct clocksource cs_hrt = { static int __init init_hrt_clocksource(void) { + u32 freq; /* Make sure scx200 has initialized the configuration block */ if (!scx200_cb_present()) return -ENODEV; @@ -79,19 +77,15 @@ static int __init init_hrt_clocksource(void) outb(HR_TMEN | (mhz27 ? HR_TMCLKSEL : 0), scx200_cb_base + SCx200_TMCNFG_OFFSET); - if (mhz27) { - cs_hrt.shift = HRT_SHIFT_27; - cs_hrt.mult = clocksource_hz2mult((HRT_FREQ + ppm) * 27, - cs_hrt.shift); - } else { - cs_hrt.shift = HRT_SHIFT_1; - cs_hrt.mult = clocksource_hz2mult(HRT_FREQ + ppm, - cs_hrt.shift); - } + freq = (HRT_FREQ + ppm); + if (mhz27) + freq *= 27; + pr_info("enabling scx200 high-res timer (%s MHz +%d ppm)\n", + printk(KERN_INFO "enabling scx200 high-res timer (%s MHz +%d ppm)\n", mhz27 ? "27":"1", ppm); - return clocksource_register(&cs_hrt); + return clocksource_register_hz(&cs_hrt, freq); } module_init(init_hrt_clocksource); -- cgit v1.2.3-70-g09d2 From b519508298e0292e1771eecf14aaf67755adc39d Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Mon, 30 Jan 2012 20:23:30 -0800 Subject: clocksource: Load the ACPI PM clocksource asynchronously The ACPI clocksource takes quite some time to initialize, and this increases the boot time of the kernel for a double digit percentage. This while almost all modern systems will be using the HPET already anyway. This patch turns the clocksource loading into an asynchronous operation; which means it won't hold up the boot while still becoming available normally. To make this work well, an udelay() had to be turned into an usleep_range() so that on UP systems, we yield the CPU to regular boot tasks instead of spinning. CC: John Stultz CC: Thomas Gleixner CC: Len Brown Signed-off-by: Arjan van de Ven Signed-off-by: John Stultz --- drivers/clocksource/acpi_pm.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c index 6b5cf02c35c..82e882028fc 100644 --- a/drivers/clocksource/acpi_pm.c +++ b/drivers/clocksource/acpi_pm.c @@ -23,6 +23,7 @@ #include #include #include +#include #include /* @@ -179,17 +180,15 @@ static int verify_pmtmr_rate(void) /* Number of reads we try to get two different values */ #define ACPI_PM_READ_CHECKS 10000 -static int __init init_acpi_pm_clocksource(void) +static void __init acpi_pm_clocksource_async(void *unused, async_cookie_t cookie) { cycle_t value1, value2; unsigned int i, j = 0; - if (!pmtmr_ioport) - return -ENODEV; /* "verify" this timing source: */ for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) { - udelay(100 * j); + usleep_range(100 * j, 100 * j + 100); value1 = clocksource_acpi_pm.read(&clocksource_acpi_pm); for (i = 0; i < ACPI_PM_READ_CHECKS; i++) { value2 = clocksource_acpi_pm.read(&clocksource_acpi_pm); @@ -203,25 +202,34 @@ static int __init init_acpi_pm_clocksource(void) " 0x%#llx, 0x%#llx - aborting.\n", value1, value2); pmtmr_ioport = 0; - return -EINVAL; + return; } if (i == ACPI_PM_READ_CHECKS) { printk(KERN_INFO "PM-Timer failed consistency check " " (0x%#llx) - aborting.\n", value1); pmtmr_ioport = 0; - return -ENODEV; + return; } } if (verify_pmtmr_rate() != 0){ pmtmr_ioport = 0; - return -ENODEV; + return; } - return clocksource_register_hz(&clocksource_acpi_pm, + clocksource_register_hz(&clocksource_acpi_pm, PMTMR_TICKS_PER_SEC); } +static int __init init_acpi_pm_clocksource(void) +{ + if (!pmtmr_ioport) + return -ENODEV; + + async_schedule(acpi_pm_clocksource_async, NULL); + return 0; +} + /* We use fs_initcall because we want the PCI fixups to have run * but we still need to load before device_initcall */ -- cgit v1.2.3-70-g09d2 From 57b9bef0d6990d088a5e840c88ae137d8e76202c Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Wed, 1 Feb 2012 15:02:41 +0000 Subject: bna: Implement ethtool flash_device entry point. Incorporated review comments from Ben Hutchings. Change details: - Implement ethtool flash_device() entry point to write the firmware image to the flash firmware partition. Signed-off-by: Krishna Gudipati Reviewed-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/ethernet/brocade/bna/bfa_defs.h | 1 + drivers/net/ethernet/brocade/bna/bnad_ethtool.c | 42 +++++++++++++++++++++++++ 2 files changed, 43 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/brocade/bna/bfa_defs.h b/drivers/net/ethernet/brocade/bna/bfa_defs.h index 871c6309334..48f87733739 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_defs.h +++ b/drivers/net/ethernet/brocade/bna/bfa_defs.h @@ -297,6 +297,7 @@ enum bfa_mode { #define BFA_FLASH_PART_ENTRY_SIZE 32 /* partition entry size */ #define BFA_FLASH_PART_MAX 32 /* maximal # of partitions */ #define BFA_TOTAL_FLASH_SIZE 0x400000 +#define BFA_FLASH_PART_FWIMG 2 #define BFA_FLASH_PART_MFG 7 /* diff --git a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c index 9b44ec8096b..a27c601af3d 100644 --- a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c +++ b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c @@ -1072,6 +1072,47 @@ done: return ret; } +static int +bnad_flash_device(struct net_device *netdev, struct ethtool_flash *eflash) +{ + struct bnad *bnad = netdev_priv(netdev); + struct bnad_iocmd_comp fcomp; + const struct firmware *fw; + int ret = 0; + + ret = request_firmware(&fw, eflash->data, &bnad->pcidev->dev); + if (ret) { + pr_err("BNA: Can't locate firmware %s\n", eflash->data); + goto out; + } + + fcomp.bnad = bnad; + fcomp.comp_status = 0; + + init_completion(&fcomp.comp); + spin_lock_irq(&bnad->bna_lock); + ret = bfa_nw_flash_update_part(&bnad->bna.flash, BFA_FLASH_PART_FWIMG, + bnad->id, (u8 *)fw->data, fw->size, 0, + bnad_cb_completion, &fcomp); + if (ret != BFA_STATUS_OK) { + pr_warn("BNA: Flash update failed with err: %d\n", ret); + ret = -EIO; + spin_unlock_irq(&bnad->bna_lock); + goto out; + } + + spin_unlock_irq(&bnad->bna_lock); + wait_for_completion(&fcomp.comp); + if (fcomp.comp_status != BFA_STATUS_OK) { + ret = -EIO; + pr_warn("BNA: Firmware image update to flash failed with: %d\n", + fcomp.comp_status); + } +out: + release_firmware(fw); + return ret; +} + static const struct ethtool_ops bnad_ethtool_ops = { .get_settings = bnad_get_settings, .set_settings = bnad_set_settings, @@ -1090,6 +1131,7 @@ static const struct ethtool_ops bnad_ethtool_ops = { .get_eeprom_len = bnad_get_eeprom_len, .get_eeprom = bnad_get_eeprom, .set_eeprom = bnad_set_eeprom, + .flash_device = bnad_flash_device, }; void -- cgit v1.2.3-70-g09d2 From 3c325fbd0cdb4f83b7761cd8ba7519d7a236de38 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Tue, 31 Jan 2012 23:32:55 +0900 Subject: ath6kl: Fix typo in cfg80211.c Correct spelling "spported" to "supported" in drivers/net/wireless/ath/ath6kl/cfg80211.c Signed-off-by: Masanari Iida Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 5934e40ee55..d1922d8eb3b 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -194,7 +194,7 @@ static int ath6kl_set_auth_type(struct ath6kl_vif *vif, break; default: - ath6kl_err("%s: 0x%x not spported\n", __func__, auth_type); + ath6kl_err("%s: 0x%x not supported\n", __func__, auth_type); return -ENOTSUPP; } -- cgit v1.2.3-70-g09d2 From 1b46dc04866a4962644ef32d7398e34b40f7ac21 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 31 Jan 2012 21:26:22 +0200 Subject: ath6kl: fix compiler warning in ath6kl_init_hw_params() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both Luis and John reported that they see a compiler warning: drivers/net/wireless/ath/ath6kl/init.c: In function 'ath6kl_init_hw_params': drivers/net/wireless/ath/ath6kl/init.c:1377:26: warning: ‘hw’ may be used uninitialized in this function Oddly enough I have never seen it. But AFAICT the code is correct and hw is not used uninitalized so add uninitialized_var() to inform that to the compiler. Reported-by: Luis R. Rodriguez Reported-by: John W. Linville Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index bf56e5f1761..0d76c377810 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -1470,7 +1470,7 @@ static int ath6kl_init_upload(struct ath6kl *ar) int ath6kl_init_hw_params(struct ath6kl *ar) { - const struct ath6kl_hw *hw; + const struct ath6kl_hw *uninitialized_var(hw); int i; for (i = 0; i < ARRAY_SIZE(hw_list); i++) { -- cgit v1.2.3-70-g09d2 From 5fbea5dcc05415474bae7108803e324f112d5b58 Mon Sep 17 00:00:00 2001 From: Chilam Ng Date: Wed, 1 Feb 2012 01:03:37 -0800 Subject: ath6kl: initialize the 'nominal_phy' field in the 'wmi_create_pstream_cmd' struct for create_qos command The nominal_phy field is uninitialized. Initialize it to min_phy_rate for create_qos. kvalo: simplified the equation as checkpatch complained for a too long line Signed-off-by: Chilam Ng Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/debug.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c index 6b546dc6672..d832058816f 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.c +++ b/drivers/net/wireless/ath/ath6kl/debug.c @@ -1441,6 +1441,8 @@ static ssize_t ath6kl_create_qos_write(struct file *file, return -EINVAL; pstream.medium_time = cpu_to_le32(val32); + pstream.nominal_phy = le32_to_cpu(pstream.min_phy_rate) / 1000000; + ath6kl_wmi_create_pstream_cmd(ar->wmi, vif->fw_vif_idx, &pstream); return count; -- cgit v1.2.3-70-g09d2 From 3596bb929f2abd3433c2eaa5755fad48ac207af1 Mon Sep 17 00:00:00 2001 From: Keng-Yu Lin Date: Thu, 2 Feb 2012 10:31:26 +0100 Subject: HID: add extra hotkeys in Asus AIO keyboards The Asus All-In-One PC has a wireless keyboard with wifi toggle, brightness up, brightness down and display off hotkeys. This patch adds suppoort for these hotkeys. Signed-off-by: Keng-Yu Lin Signed-off-by: Jiri Kosina --- drivers/hid/hid-chicony.c | 5 +++++ drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h | 1 + 3 files changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/hid-chicony.c b/drivers/hid/hid-chicony.c index 8965ad93d51..4162505793c 100644 --- a/drivers/hid/hid-chicony.c +++ b/drivers/hid/hid-chicony.c @@ -45,6 +45,10 @@ static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi, case 0xff09: ch_map_key_clear(BTN_9); break; case 0xff0a: ch_map_key_clear(BTN_A); break; case 0xff0b: ch_map_key_clear(BTN_B); break; + case 0x00f1: ch_map_key_clear(KEY_WLAN); break; + case 0x00f2: ch_map_key_clear(KEY_BRIGHTNESSDOWN); break; + case 0x00f3: ch_map_key_clear(KEY_BRIGHTNESSUP); break; + case 0x00f4: ch_map_key_clear(KEY_DISPLAY_OFF); break; default: return 0; } @@ -53,6 +57,7 @@ static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi, static const struct hid_device_id ch_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) }, { } }; MODULE_DEVICE_TABLE(hid, ch_devices); diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index af08ce7207d..75dbe344cab 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1396,6 +1396,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) }, { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) }, { HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, USB_DEVICE_ID_CVTOUCH_SCREEN) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index b8574cddd95..fb9e61f8566 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -190,6 +190,7 @@ #define USB_DEVICE_ID_CHICONY_TACTICAL_PAD 0x0418 #define USB_DEVICE_ID_CHICONY_MULTI_TOUCH 0xb19d #define USB_DEVICE_ID_CHICONY_WIRELESS 0x0618 +#define USB_DEVICE_ID_CHICONY_WIRELESS2 0x1123 #define USB_VENDOR_ID_CHUNGHWAT 0x2247 #define USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH 0x0001 -- cgit v1.2.3-70-g09d2 From 6c30d5a53229aad22bb675e0bd6eb518ecaa4316 Mon Sep 17 00:00:00 2001 From: Keng-Yu Lin Date: Mon, 30 Jan 2012 14:25:45 +0800 Subject: HID: add more hotkeys in Asus AIO keyboards Add support for the camera key. The hotkey for Asus S.H.E(Super Hybrid Engine) mode is mapped to KEY_KEY_PROG1 just for notifying the userspace. Signed-off-by: Keng-Yu Lin Signed-off-by: Jiri Kosina --- drivers/hid/hid-chicony.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/hid-chicony.c b/drivers/hid/hid-chicony.c index 4162505793c..b99af346fdf 100644 --- a/drivers/hid/hid-chicony.c +++ b/drivers/hid/hid-chicony.c @@ -49,6 +49,8 @@ static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi, case 0x00f2: ch_map_key_clear(KEY_BRIGHTNESSDOWN); break; case 0x00f3: ch_map_key_clear(KEY_BRIGHTNESSUP); break; case 0x00f4: ch_map_key_clear(KEY_DISPLAY_OFF); break; + case 0x00f7: ch_map_key_clear(KEY_CAMERA); break; + case 0x00f8: ch_map_key_clear(KEY_PROG1); break; default: return 0; } -- cgit v1.2.3-70-g09d2 From 765031668fb2b064aebd9a568e5ad794cbe3413a Mon Sep 17 00:00:00 2001 From: Nestor Lopez Casado Date: Thu, 2 Feb 2012 10:54:14 +0100 Subject: HID: logitech: fix mask to enable DJ mode The user can only experience the bug if she pairs 6 devices to a Unifying receiver. The sixth paired device would not work. The value changed is actually a bitmask that enables reporting from each paired device. As the sixth bit was not set, the sixth device reports are ignored by the receiver and never get to the driver. Signed-off-by: Nestor Lopez Casado drivers/hid/hid-logitech-dj.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) Signed-off-by: Jiri Kosina --- drivers/hid/hid-logitech-dj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 38b12e45780..2b56efcbdf6 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -445,7 +445,7 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, dj_report.report_id = REPORT_ID_DJ_SHORT; dj_report.device_index = 0xFF; dj_report.report_type = REPORT_TYPE_CMD_SWITCH; - dj_report.report_params[CMD_SWITCH_PARAM_DEVBITFIELD] = 0x1F; + dj_report.report_params[CMD_SWITCH_PARAM_DEVBITFIELD] = 0x3F; dj_report.report_params[CMD_SWITCH_PARAM_TIMEOUT_SECONDS] = (u8)timeout; return logi_dj_recv_send_report(djrcv_dev, &dj_report); } -- cgit v1.2.3-70-g09d2 From b89529a10c954f14191367355da2a6053c49abb9 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Thu, 12 Jan 2012 19:40:34 +0100 Subject: Input: Use accessor for MT values The current MT accessor function does not distinguish between the MT values and the slot specification event. Add an accessor function for the values only, and use it where appropriate. Signed-off-by: Henrik Rydberg --- drivers/input/input.c | 2 +- include/linux/input/mt.h | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/input/input.c b/drivers/input/input.c index 1f78c957a75..8921c6180c5 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -180,7 +180,7 @@ static int input_handle_abs_event(struct input_dev *dev, return INPUT_IGNORE_EVENT; } - is_mt_event = code >= ABS_MT_FIRST && code <= ABS_MT_LAST; + is_mt_event = input_is_mt_value(code); if (!is_mt_event) { pold = &dev->absinfo[code].value; diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h index 318bb82325a..f86737586e1 100644 --- a/include/linux/input/mt.h +++ b/include/linux/input/mt.h @@ -48,10 +48,14 @@ static inline void input_mt_slot(struct input_dev *dev, int slot) input_event(dev, EV_ABS, ABS_MT_SLOT, slot); } +static inline bool input_is_mt_value(int axis) +{ + return axis >= ABS_MT_FIRST && axis <= ABS_MT_LAST; +} + static inline bool input_is_mt_axis(int axis) { - return axis == ABS_MT_SLOT || - (axis >= ABS_MT_FIRST && axis <= ABS_MT_LAST); + return axis == ABS_MT_SLOT || input_is_mt_value(axis); } void input_mt_report_slot_state(struct input_dev *dev, -- cgit v1.2.3-70-g09d2 From 34ce8d07e63baa37d21aeca87f3248b008114899 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Feb 2012 13:45:09 +0000 Subject: regulator: wm8350: Don't specify consumer supplies with struct device Very, very deprecated. Signed-off-by: Mark Brown --- drivers/regulator/wm8350-regulator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index 6894009d815..4f46067455c 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c @@ -1544,7 +1544,7 @@ int wm8350_register_led(struct wm8350 *wm8350, int lednum, int dcdc, int isink, return -ENOMEM; } - led->isink_consumer.dev = &pdev->dev; + led->isink_consumer.dev_name = dev_name(&pdev->dev); led->isink_consumer.supply = "led_isink"; led->isink_init.num_consumer_supplies = 1; led->isink_init.consumer_supplies = &led->isink_consumer; @@ -1559,7 +1559,7 @@ int wm8350_register_led(struct wm8350 *wm8350, int lednum, int dcdc, int isink, return ret; } - led->dcdc_consumer.dev = &pdev->dev; + led->dcdc_consumer.dev_name = dev_name(&pdev->dev); led->dcdc_consumer.supply = "led_vcc"; led->dcdc_init.num_consumer_supplies = 1; led->dcdc_init.consumer_supplies = &led->dcdc_consumer; -- cgit v1.2.3-70-g09d2 From 20a14b84f8d62ba9ad7acad1d67a2ffa3c06468b Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 31 Jan 2012 15:13:31 +0800 Subject: regulator: Kill s5m8767_get_reg_id function Calling s5m8767_get_reg_id() is exactly the same as calling rdev_get_id(). It is pointless to add s5m8767_get_reg_id() function. Use rdev_get_id() directly and remove s5m8767_get_reg_id() function. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/s5m8767.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index a5b9d83913f..5b00e5ac70c 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -120,16 +120,11 @@ static const struct s5m_voltage_desc *reg_voltage_map[] = { [S5M8767_BUCK9] = &buck_voltage_val3, }; -static inline int s5m8767_get_reg_id(struct regulator_dev *rdev) -{ - return rdev_get_id(rdev); -} - static int s5m8767_list_voltage(struct regulator_dev *rdev, unsigned int selector) { const struct s5m_voltage_desc *desc; - int reg_id = s5m8767_get_reg_id(rdev); + int reg_id = rdev_get_id(rdev); int val; if (reg_id >= ARRAY_SIZE(reg_voltage_map) || reg_id < 0) @@ -148,7 +143,7 @@ static int s5m8767_list_voltage(struct regulator_dev *rdev, static int s5m8767_get_register(struct regulator_dev *rdev, int *reg) { - int reg_id = s5m8767_get_reg_id(rdev); + int reg_id = rdev_get_id(rdev); switch (reg_id) { case S5M8767_LDO1 ... S5M8767_LDO2: @@ -224,7 +219,7 @@ static int s5m8767_reg_disable(struct regulator_dev *rdev) static int s5m8767_get_voltage_register(struct regulator_dev *rdev, int *_reg) { - int reg_id = s5m8767_get_reg_id(rdev); + int reg_id = rdev_get_id(rdev); int reg; switch (reg_id) { @@ -265,7 +260,7 @@ static int s5m8767_get_voltage_sel(struct regulator_dev *rdev) { struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); int reg, mask = 0xff, ret; - int reg_id = s5m8767_get_reg_id(rdev); + int reg_id = rdev_get_id(rdev); u8 val; ret = s5m8767_get_voltage_register(rdev, ®); @@ -325,7 +320,7 @@ static int s5m8767_set_voltage(struct regulator_dev *rdev, struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); int min_vol = min_uV, max_vol = max_uV; const struct s5m_voltage_desc *desc; - int reg_id = s5m8767_get_reg_id(rdev); + int reg_id = rdev_get_id(rdev); int reg, mask, ret; int i; u8 val; @@ -387,7 +382,7 @@ static int s5m8767_set_voltage_buck(struct regulator_dev *rdev, int min_uV, int max_uV, unsigned *selector) { struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); - int reg_id = s5m8767_get_reg_id(rdev); + int reg_id = rdev_get_id(rdev); const struct s5m_voltage_desc *desc; int new_val, old_val, i = 0; int min_vol = min_uV, max_vol = max_uV; @@ -456,7 +451,7 @@ static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev, { struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); const struct s5m_voltage_desc *desc; - int reg_id = s5m8767_get_reg_id(rdev); + int reg_id = rdev_get_id(rdev); int mask; int new_val, old_val; -- cgit v1.2.3-70-g09d2 From 737f360d5bef5e01c6cfa755dca0b449a154c1e0 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Feb 2012 00:10:51 +0000 Subject: regulator: Remove support for supplies specified by struct device This has been deprecated for a very long time now. Signed-off-by: Mark Brown Reviewed-by: Linus Walleij Acked-by: Liam Girdwood --- drivers/regulator/core.c | 23 ++++++++--------------- include/linux/regulator/machine.h | 2 -- 2 files changed, 8 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index e9a83f84ada..b9c900e8179 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -996,7 +996,6 @@ static int set_supply(struct regulator_dev *rdev, /** * set_consumer_device_supply - Bind a regulator to a symbolic supply * @rdev: regulator source - * @consumer_dev: device the supply applies to * @consumer_dev_name: dev_name() string for device supply applies to * @supply: symbolic name for supply * @@ -1008,18 +1007,12 @@ static int set_supply(struct regulator_dev *rdev, * Only one of consumer_dev and consumer_dev_name may be specified. */ static int set_consumer_device_supply(struct regulator_dev *rdev, - struct device *consumer_dev, const char *consumer_dev_name, - const char *supply) + const char *consumer_dev_name, + const char *supply) { struct regulator_map *node; int has_dev; - if (consumer_dev && consumer_dev_name) - return -EINVAL; - - if (!consumer_dev_name && consumer_dev) - consumer_dev_name = dev_name(consumer_dev); - if (supply == NULL) return -EINVAL; @@ -1039,11 +1032,12 @@ static int set_consumer_device_supply(struct regulator_dev *rdev, if (strcmp(node->supply, supply) != 0) continue; - dev_dbg(consumer_dev, "%s/%s is '%s' supply; fail %s/%s\n", - dev_name(&node->regulator->dev), - node->regulator->desc->name, - supply, - dev_name(&rdev->dev), rdev_get_name(rdev)); + pr_debug("%s: %s/%s is '%s' supply; fail %s/%s\n", + consumer_dev_name, + dev_name(&node->regulator->dev), + node->regulator->desc->name, + supply, + dev_name(&rdev->dev), rdev_get_name(rdev)); return -EBUSY; } @@ -2855,7 +2849,6 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, if (init_data) { for (i = 0; i < init_data->num_consumer_supplies; i++) { ret = set_consumer_device_supply(rdev, - init_data->consumer_supplies[i].dev, init_data->consumer_supplies[i].dev_name, init_data->consumer_supplies[i].supply); if (ret < 0) { diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index f3f13fd5868..7abb1609331 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -139,12 +139,10 @@ struct regulation_constraints { * make struct device available late such as I2C and is the preferred * form. * - * @dev: Device structure for the consumer. * @dev_name: Result of dev_name() for the consumer. * @supply: Name for the supply. */ struct regulator_consumer_supply { - struct device *dev; /* consumer */ const char *dev_name; /* dev_name() for consumer */ const char *supply; /* consumer supply - e.g. "vcc" */ }; -- cgit v1.2.3-70-g09d2 From 7437cfa532842ce75189826742bddf1ba137f58e Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 18 Jan 2012 09:17:27 +0100 Subject: ARM: 7280/1: mmc: mmci: Cache MMCICLOCK and MMCIPOWER register Instead of reading a register value everytime we need to apply a new value for it, maintain a cached copy for it. This also means we are able to skip writes that are not needed. Tested-by: Linus Walleij Signed-off-by: Ulf Hansson Signed-off-by: Linus Walleij Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 41 +++++++++++++++++++++++++++++------------ drivers/mmc/host/mmci.h | 3 ++- 2 files changed, 31 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 1f8832699cd..f36d8b8c891 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -118,6 +118,28 @@ static struct variant_data variant_ux500v2 = { .signal_direction = true, }; +/* + * This must be called with host->lock held + */ +static void mmci_write_clkreg(struct mmci_host *host, u32 clk) +{ + if (host->clk_reg != clk) { + host->clk_reg = clk; + writel(clk, host->base + MMCICLOCK); + } +} + +/* + * This must be called with host->lock held + */ +static void mmci_write_pwrreg(struct mmci_host *host, u32 pwr) +{ + if (host->pwr_reg != pwr) { + host->pwr_reg = pwr; + writel(pwr, host->base + MMCIPOWER); + } +} + /* * This must be called with host->lock held */ @@ -165,7 +187,7 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8) clk |= MCI_ST_8BIT_BUS; - writel(clk, host->base + MMCICLOCK); + mmci_write_clkreg(host, clk); } static void @@ -846,14 +868,13 @@ static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int rem */ if (variant->sdio && mmc_card_sdio(host->mmc->card)) { + u32 clk; if (count < 8) - writel(readl(host->base + MMCICLOCK) & - ~variant->clkreg_enable, - host->base + MMCICLOCK); + clk = host->clk_reg & ~variant->clkreg_enable; else - writel(readl(host->base + MMCICLOCK) | - variant->clkreg_enable, - host->base + MMCICLOCK); + clk = host->clk_reg | variant->clkreg_enable; + + mmci_write_clkreg(host, clk); } /* @@ -1114,11 +1135,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) spin_lock_irqsave(&host->lock, flags); mmci_set_clkreg(host, ios->clock); - - if (host->pwr != pwr) { - host->pwr = pwr; - writel(pwr, host->base + MMCIPOWER); - } + mmci_write_pwrreg(host, pwr); spin_unlock_irqrestore(&host->lock, flags); diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 89eb2e3556d..d437ccf62d6 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -179,7 +179,8 @@ struct mmci_host { unsigned int mclk; unsigned int cclk; - u32 pwr; + u32 pwr_reg; + u32 clk_reg; struct mmci_platform_data *plat; struct variant_data *variant; -- cgit v1.2.3-70-g09d2 From 14af60b6fb3b76634278364b697dae2f9f360abf Mon Sep 17 00:00:00 2001 From: Chris Blair Date: Thu, 2 Feb 2012 13:59:34 +0100 Subject: spi/pl022: Add high priority message pump support This switches the PL022 worker to a kthread in order to get hold of a mechanism to control the message pump priority. On low-latency systems elevating the message kthread to realtime priority give a real sleek response curve. This has been confirmed by measurements. Realtime priority elevation for a certain PL022 port can be requested from platform data. Cc: Mark Brown Acked-by: Viresh Kumar Signed-off-by: Chris Blair Signed-off-by: Linus Walleij Signed-off-by: Grant Likely --- drivers/spi/spi-pl022.c | 77 +++++++++++++++++++++++++++++++--------------- include/linux/amba/pl022.h | 3 ++ 2 files changed, 55 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 2f9cb43a239..81847c9a758 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include @@ -41,6 +41,7 @@ #include #include #include +#include /* * This macro is used to define some register default values. @@ -330,12 +331,13 @@ struct vendor_data { * @clk: outgoing clock "SPICLK" for the SPI bus * @master: SPI framework hookup * @master_info: controller-specific data from machine setup - * @workqueue: a workqueue on which any spi_message request is queued - * @pump_messages: work struct for scheduling work to the workqueue + * @kworker: thread struct for message pump + * @kworker_task: pointer to task for message pump kworker thread + * @pump_messages: work struct for scheduling work to the message pump * @queue_lock: spinlock to syncronise access to message queue * @queue: message queue - * @busy: workqueue is busy - * @running: workqueue is running + * @busy: message pump is busy + * @running: message pump is running * @pump_transfers: Tasklet used in Interrupt Transfer mode * @cur_msg: Pointer to current spi_message being processed * @cur_transfer: Pointer to current spi_transfer @@ -365,9 +367,10 @@ struct pl022 { struct clk *clk; struct spi_master *master; struct pl022_ssp_controller *master_info; - /* Driver message queue */ - struct workqueue_struct *workqueue; - struct work_struct pump_messages; + /* Driver message pump */ + struct kthread_worker kworker; + struct task_struct *kworker_task; + struct kthread_work pump_messages; spinlock_t queue_lock; struct list_head queue; bool busy; @@ -504,7 +507,7 @@ static void giveback(struct pl022 *pl022) pl022->cur_msg = NULL; pl022->cur_transfer = NULL; pl022->cur_chip = NULL; - queue_work(pl022->workqueue, &pl022->pump_messages); + queue_kthread_work(&pl022->kworker, &pl022->pump_messages); spin_unlock_irqrestore(&pl022->queue_lock, flags); msg->state = NULL; @@ -1494,8 +1497,8 @@ out: } /** - * pump_messages - Workqueue function which processes spi message queue - * @data: pointer to private data of SSP driver + * pump_messages - kthread work function which processes spi message queue + * @work: pointer to kthread work struct contained in the pl022 private struct * * This function checks if there is any spi message in the queue that * needs processing and delegate control to appropriate function @@ -1503,7 +1506,7 @@ out: * based on the kind of the transfer * */ -static void pump_messages(struct work_struct *work) +static void pump_messages(struct kthread_work *work) { struct pl022 *pl022 = container_of(work, struct pl022, pump_messages); @@ -1556,7 +1559,7 @@ static void pump_messages(struct work_struct *work) if (!was_busy) /* * We enable the core voltage and clocks here, then the clocks - * and core will be disabled when this workqueue is run again + * and core will be disabled when this thread is run again * and there is no more work to be done. */ pm_runtime_get_sync(&pl022->adev->dev); @@ -1572,6 +1575,8 @@ static void pump_messages(struct work_struct *work) static int __init init_queue(struct pl022 *pl022) { + struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 }; + INIT_LIST_HEAD(&pl022->queue); spin_lock_init(&pl022->queue_lock); @@ -1581,11 +1586,29 @@ static int __init init_queue(struct pl022 *pl022) tasklet_init(&pl022->pump_transfers, pump_transfers, (unsigned long)pl022); - INIT_WORK(&pl022->pump_messages, pump_messages); - pl022->workqueue = create_singlethread_workqueue( + init_kthread_worker(&pl022->kworker); + pl022->kworker_task = kthread_run(kthread_worker_fn, + &pl022->kworker, dev_name(pl022->master->dev.parent)); - if (pl022->workqueue == NULL) - return -EBUSY; + if (IS_ERR(pl022->kworker_task)) { + dev_err(&pl022->adev->dev, + "failed to create message pump task\n"); + return -ENOMEM; + } + init_kthread_work(&pl022->pump_messages, pump_messages); + + /* + * Board config will indicate if this controller should run the + * message pump with high (realtime) priority to reduce the transfer + * latency on the bus by minimising the delay between a transfer + * request and the scheduling of the message pump thread. Without this + * setting the message pump thread will remain at default priority. + */ + if (pl022->master_info->rt) { + dev_info(&pl022->adev->dev, + "will run message pump with realtime priority\n"); + sched_setscheduler(pl022->kworker_task, SCHED_FIFO, ¶m); + } return 0; } @@ -1608,7 +1631,7 @@ static int start_queue(struct pl022 *pl022) pl022->next_msg_cs_active = false; spin_unlock_irqrestore(&pl022->queue_lock, flags); - queue_work(pl022->workqueue, &pl022->pump_messages); + queue_kthread_work(&pl022->kworker, &pl022->pump_messages); return 0; } @@ -1646,16 +1669,20 @@ static int destroy_queue(struct pl022 *pl022) int status; status = stop_queue(pl022); - /* we are unloading the module or failing to load (only two calls + + /* + * We are unloading the module or failing to load (only two calls * to this routine), and neither call can handle a return value. - * However, destroy_workqueue calls flush_workqueue, and that will - * block until all work is done. If the reason that stop_queue - * timed out is that the work will never finish, then it does no - * good to call destroy_workqueue, so return anyway. */ + * However, flush_kthread_worker will block until all work is done. + * If the reason that stop_queue timed out is that the work will never + * finish, then it does no good to call flush/stop thread, so + * return anyway. + */ if (status != 0) return status; - destroy_workqueue(pl022->workqueue); + flush_kthread_worker(&pl022->kworker); + kthread_stop(pl022->kworker_task); return 0; } @@ -1802,7 +1829,7 @@ static int pl022_transfer(struct spi_device *spi, struct spi_message *msg) list_add_tail(&msg->queue, &pl022->queue); if (pl022->running && !pl022->busy) - queue_work(pl022->workqueue, &pl022->pump_messages); + queue_kthread_work(&pl022->kworker, &pl022->pump_messages); spin_unlock_irqrestore(&pl022->queue_lock, flags); return 0; diff --git a/include/linux/amba/pl022.h b/include/linux/amba/pl022.h index 572f637299c..3672f40f345 100644 --- a/include/linux/amba/pl022.h +++ b/include/linux/amba/pl022.h @@ -241,6 +241,8 @@ struct dma_chan; * @autosuspend_delay: delay in ms following transfer completion before the * runtime power management system suspends the device. A setting of 0 * indicates no delay and the device will be suspended immediately. + * @rt: indicates the controller should run the message pump with realtime + * priority to minimise the transfer latency on the bus. */ struct pl022_ssp_controller { u16 bus_id; @@ -250,6 +252,7 @@ struct pl022_ssp_controller { void *dma_rx_param; void *dma_tx_param; int autosuspend_delay; + bool rt; }; /** -- cgit v1.2.3-70-g09d2 From 5816269e4ee3db2bc2ad44afc89f4abe81c7aa26 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Wed, 25 Jan 2012 19:50:36 -0700 Subject: tty: serial: OMAP: use a 1-byte RX FIFO threshold in PIO mode In the (default) PIO mode, use a one-byte RX FIFO threshold. The OMAP UART IP blocks do not appear to be capable of waking the system under an RX timeout condition. Since the previous RX FIFO threshold was 16 bytes, this meant that omap-serial.c did not become aware of any received data until all those bytes arrived or until another UART interrupt occurred. This made the serial console and presumably other serial applications (GPS, serial Bluetooth) unusable or extremely slow. A 1-byte RX FIFO threshold also allows the MPU to enter a low-power consumption state while waiting for the FIFO to fill. This can be verified using the serial console by comparing the behavior when "0123456789abcde" is pasted in from another window, with the behavior when "0123456789abcdef" is pasted in. Since the former string is less than sixteen bytes long, the string is not echoed for some time, while the latter string is echoed immediately. DMA operation is unaffected by this patch. Thanks to Russell King - ARM Linux for some additional information on the standard behavior of the RX timeout event, which was used to improve this commit description. Signed-off-by: Paul Walmsley Cc: Tomi Valkeinen Cc: Govindraj Raja Cc: Alan Cox Cc: Russell King Reviewed-by: Kevin Hilman Tested-by: Kevin Hilman Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/omap-serial.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index d192dcbb82f..c9c9ba2a5bb 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -46,6 +46,13 @@ #define DEFAULT_CLK_SPEED 48000000 /* 48Mhz*/ +/* SCR register bitmasks */ +#define OMAP_UART_SCR_RX_TRIG_GRANU1_MASK (1 << 7) + +/* FCR register bitmasks */ +#define OMAP_UART_FCR_RX_FIFO_TRIG_SHIFT 6 +#define OMAP_UART_FCR_RX_FIFO_TRIG_MASK (0x3 << 6) + static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS]; /* Forward declaration of functions */ @@ -811,14 +818,21 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, up->mcr = serial_in(up, UART_MCR); serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); /* FIFO ENABLE, DMA MODE */ - serial_out(up, UART_FCR, up->fcr); - serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); + + up->scr |= OMAP_UART_SCR_RX_TRIG_GRANU1_MASK; if (up->use_dma) { serial_out(up, UART_TI752_TLR, 0); - up->scr |= (UART_FCR_TRIGGER_4 | UART_FCR_TRIGGER_8); + up->scr |= UART_FCR_TRIGGER_4; + } else { + /* Set receive FIFO threshold to 1 byte */ + up->fcr &= ~OMAP_UART_FCR_RX_FIFO_TRIG_MASK; + up->fcr |= (0x1 << OMAP_UART_FCR_RX_FIFO_TRIG_SHIFT); } + serial_out(up, UART_FCR, up->fcr); + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); + serial_out(up, UART_OMAP_SCR, up->scr); serial_out(up, UART_EFR, up->efr); -- cgit v1.2.3-70-g09d2 From edbe5dbefe5b514d094558ab59c8dc7578e117dd Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Wed, 25 Jan 2012 19:50:52 -0700 Subject: tty: serial: OMAP: block idle while the UART is transferring data in PIO mode Prevent OMAP UARTs from going idle while they are still transferring data in PIO mode. This works around an oversight in the OMAP UART hardware present in OMAP34xx and earlier: an idle UART won't send a wakeup when the TX FIFO threshold is reached. This causes long delays during data transmission when the MPU powerdomain enters a low-power mode. The MPU interrupt controller is not able to respond to interrupts when it's in a low-power state, so the TX buffer is not refilled until another wakeup event occurs. This fix changes the erratum i291 DMA idle workaround. Rather than toggling between force-idle and no-idle, it will toggle between smart-idle and no-idle. The important part of the workaround is the no-idle part, so this shouldn't result in any change in behavior. This fix should work on all OMAP UARTs. Future patches intended for the 3.4 merge window will make this workaround conditional on a "feature" flag, and will use the OMAP36xx+ TX event wakeup support. Thanks to Kevin Hilman for mentioning the erratum i291 workaround, which led to the development of this approach. Signed-off-by: Paul Walmsley Cc: Alan Cox Cc: Tomi Valkeinen Acked-by: Govindraj.R Reviewed-by: Kevin Hilman Tested-by: Kevin Hilman Signed-off-by: Greg Kroah-Hartman --- arch/arm/mach-omap2/serial.c | 8 ++++---- drivers/tty/serial/omap-serial.c | 7 +++++++ 2 files changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 247d89478f2..f590afc1f67 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -107,18 +107,18 @@ static void omap_uart_set_noidle(struct platform_device *pdev) omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_NO); } -static void omap_uart_set_forceidle(struct platform_device *pdev) +static void omap_uart_set_smartidle(struct platform_device *pdev) { struct omap_device *od = to_omap_device(pdev); - omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_FORCE); + omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_SMART); } #else static void omap_uart_enable_wakeup(struct platform_device *pdev, bool enable) {} static void omap_uart_set_noidle(struct platform_device *pdev) {} -static void omap_uart_set_forceidle(struct platform_device *pdev) {} +static void omap_uart_set_smartidle(struct platform_device *pdev) {} #endif /* CONFIG_PM */ #ifdef CONFIG_OMAP_MUX @@ -349,7 +349,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata, omap_up.uartclk = OMAP24XX_BASE_BAUD * 16; omap_up.flags = UPF_BOOT_AUTOCONF; omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count; - omap_up.set_forceidle = omap_uart_set_forceidle; + omap_up.set_forceidle = omap_uart_set_smartidle; omap_up.set_noidle = omap_uart_set_noidle; omap_up.enable_wakeup = omap_uart_enable_wakeup; omap_up.dma_rx_buf_size = info->dma_rx_buf_size; diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index c9c9ba2a5bb..11fa15623e1 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -136,6 +136,7 @@ static void serial_omap_enable_ms(struct uart_port *port) static void serial_omap_stop_tx(struct uart_port *port) { struct uart_omap_port *up = (struct uart_omap_port *)port; + struct omap_uart_port_info *pdata = up->pdev->dev.platform_data; if (up->use_dma && up->uart_dma.tx_dma_channel != OMAP_UART_DMA_CH_FREE) { @@ -158,6 +159,9 @@ static void serial_omap_stop_tx(struct uart_port *port) serial_out(up, UART_IER, up->ier); } + if (!up->use_dma && pdata->set_forceidle) + pdata->set_forceidle(up->pdev); + pm_runtime_mark_last_busy(&up->pdev->dev); pm_runtime_put_autosuspend(&up->pdev->dev); } @@ -286,6 +290,7 @@ static inline void serial_omap_enable_ier_thri(struct uart_omap_port *up) static void serial_omap_start_tx(struct uart_port *port) { struct uart_omap_port *up = (struct uart_omap_port *)port; + struct omap_uart_port_info *pdata = up->pdev->dev.platform_data; struct circ_buf *xmit; unsigned int start; int ret = 0; @@ -293,6 +298,8 @@ static void serial_omap_start_tx(struct uart_port *port) if (!up->use_dma) { pm_runtime_get_sync(&up->pdev->dev); serial_omap_enable_ier_thri(up); + if (pdata->set_noidle) + pdata->set_noidle(up->pdev); pm_runtime_mark_last_busy(&up->pdev->dev); pm_runtime_put_autosuspend(&up->pdev->dev); return; -- cgit v1.2.3-70-g09d2 From 6bbcbf22085e0b144899d6067e243dd26c0e7533 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Wed, 25 Jan 2012 19:50:56 -0700 Subject: tty: serial: omap-serial: wakeup latency constraint is in microseconds, not milliseconds The receive FIFO wakeup latency estimate in the omap-serial driver is three orders of magnitude too small. This effectively prevents the MPU from going to a low-power state when CONFIG_CPU_IDLE=y. This is a major power management regression and masks some other FIFO-related bugs in the driver. Fix by correcting the most egregious problem in the RX wakeup latency estimate. There are several other flaws in the estimator; these will be fixed by a separate patch series intended for 3.4. The difference in low-power states with this patch can be observed via debugfs in pm_debug/count. This estimate does not have any effect when CONFIG_CPU_IDLE=n. Signed-off-by: Paul Walmsley Cc: Tomi Valkeinen Cc: Alan Cox Acked-by: Govindraj.R Reviewed-by: Kevin Hilman Tested-by: Kevin Hilman Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/omap-serial.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 11fa15623e1..72fa783729d 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -740,8 +740,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, quot = serial_omap_get_divisor(port, baud); /* calculate wakeup latency constraint */ - up->calc_latency = (1000000 * up->port.fifosize) / - (1000 * baud / 8); + up->calc_latency = (USEC_PER_SEC * up->port.fifosize) / (baud / 8); up->latency = up->calc_latency; schedule_work(&up->qos_work); -- cgit v1.2.3-70-g09d2 From ed6a3803408f18da387463d569b4edc5078fd9aa Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 2 Jan 2012 16:10:08 +0200 Subject: iwlwifi: add fw_alive to transport layer API, kill tx_start Define a new handler in the transport layer API: fw_alive. Move iwl_reset_ict to this new handler, and move the content of tx_start to this handler. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 3 --- drivers/net/wireless/iwlwifi/iwl-agn.h | 2 -- drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 6 ++---- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 10 ++++++++-- drivers/net/wireless/iwlwifi/iwl-trans.h | 15 +++++++-------- drivers/net/wireless/iwlwifi/iwl-ucode.c | 2 +- 7 files changed, 19 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 90315c69cdf..9d9185ffc39 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1243,9 +1243,6 @@ int iwl_alive_start(struct iwl_priv *priv) int ret = 0; struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - /*TODO: this should go to the transport layer */ - iwl_reset_ict(trans(priv)); - IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); /* After the ALIVE response, we can send host commands to the uCode */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 39cbe1a1577..0f5133ac357 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -73,8 +73,6 @@ struct iwlagn_ucode_capabilities { extern struct ieee80211_ops iwlagn_hw_ops; -int iwl_reset_ict(struct iwl_trans *trans); - static inline void iwl_set_calib_hdr(struct iwl_calib_hdr *hdr, u8 cmd) { hdr->op_code = cmd; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 0ac9b4d3027..0f73778b73f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -258,7 +258,7 @@ void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans, /***************************************************** * ICT ******************************************************/ -int iwl_reset_ict(struct iwl_trans *trans); +void iwl_reset_ict(struct iwl_trans *trans); void iwl_disable_ict(struct iwl_trans *trans); int iwl_alloc_isr_ict(struct iwl_trans *trans); void iwl_free_isr_ict(struct iwl_trans *trans); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 848c598bfad..2822b7e8bca 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -1213,7 +1213,7 @@ int iwl_alloc_isr_ict(struct iwl_trans *trans) /* Device is going up inform it about using ICT interrupt table, * also we need to tell the driver to start using ICT interrupt. */ -int iwl_reset_ict(struct iwl_trans *trans) +void iwl_reset_ict(struct iwl_trans *trans) { u32 val; unsigned long flags; @@ -1221,7 +1221,7 @@ int iwl_reset_ict(struct iwl_trans *trans) IWL_TRANS_GET_PCIE_TRANS(trans); if (!trans_pcie->ict_tbl) - return 0; + return; spin_lock_irqsave(&trans->shrd->lock, flags); iwl_disable_interrupts(trans); @@ -1241,8 +1241,6 @@ int iwl_reset_ict(struct iwl_trans *trans) iwl_write32(bus(trans), CSR_INT, trans_pcie->inta_mask); iwl_enable_interrupts(trans); spin_unlock_irqrestore(&trans->shrd->lock, flags); - - return 0; } /* Device is going down disable ict interrupt usage */ diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 5e6af4ba965..affa56fafdb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -835,7 +835,7 @@ static void iwl_trans_txq_set_sched(struct iwl_trans *trans, u32 mask) iwl_write_prph(bus(trans), SCD_TXFACT, mask); } -static void iwl_trans_pcie_tx_start(struct iwl_trans *trans) +static void iwl_tx_start(struct iwl_trans *trans) { const struct queue_to_fifo_ac *queue_to_fifo; struct iwl_trans_pcie *trans_pcie = @@ -948,6 +948,12 @@ static void iwl_trans_pcie_tx_start(struct iwl_trans *trans) APMG_PCIDEV_STT_VAL_L1_ACT_DIS); } +static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans) +{ + iwl_reset_ict(trans); + iwl_tx_start(trans); +} + /** * iwlagn_txq_ctx_stop - Stop all Tx DMA channels */ @@ -1903,11 +1909,11 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, const struct iwl_trans_ops trans_ops_pcie = { .alloc = iwl_trans_pcie_alloc, .request_irq = iwl_trans_pcie_request_irq, + .fw_alive = iwl_trans_pcie_fw_alive, .start_device = iwl_trans_pcie_start_device, .prepare_card_hw = iwl_trans_pcie_prepare_card_hw, .stop_device = iwl_trans_pcie_stop_device, - .tx_start = iwl_trans_pcie_tx_start, .wake_any_queue = iwl_trans_pcie_wake_any_queue, .send_cmd = iwl_trans_pcie_send_cmd, diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 42a9f303f54..9795a23ee94 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -139,8 +139,7 @@ struct iwl_host_cmd { * layer. * @prepare_card_hw: claim the ownership on the HW. Will be called during * probe. - * @tx_start: starts and configures all the Tx fifo - usually done once the fw - * is alive. + * @fw_alive: called when the fw sends alive notification * @wake_any_queue: wake all the queues of a specfic context IWL_RXON_CTX_* * @stop_device:stops the whole device (embedded CPU put to reset) * @send_cmd:send a host command @@ -166,9 +165,9 @@ struct iwl_trans_ops { struct iwl_trans *(*alloc)(struct iwl_shared *shrd); int (*request_irq)(struct iwl_trans *iwl_trans); int (*start_device)(struct iwl_trans *trans); + void (*fw_alive)(struct iwl_trans *trans); int (*prepare_card_hw)(struct iwl_trans *trans); void (*stop_device)(struct iwl_trans *trans); - void (*tx_start)(struct iwl_trans *trans); void (*wake_any_queue)(struct iwl_trans *trans, enum iwl_rxon_context_id ctx, @@ -264,6 +263,11 @@ static inline int iwl_trans_request_irq(struct iwl_trans *trans) return trans->ops->request_irq(trans); } +static inline void iwl_trans_fw_alive(struct iwl_trans *trans) +{ + trans->ops->fw_alive(trans); +} + static inline int iwl_trans_start_device(struct iwl_trans *trans) { return trans->ops->start_device(trans); @@ -279,11 +283,6 @@ static inline void iwl_trans_stop_device(struct iwl_trans *trans) trans->ops->stop_device(trans); } -static inline void iwl_trans_tx_start(struct iwl_trans *trans) -{ - trans->ops->tx_start(trans); -} - static inline void iwl_trans_wake_any_queue(struct iwl_trans *trans, enum iwl_rxon_context_id ctx, const char *msg) diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 2edf0ef65a5..0d7f207ac61 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -447,7 +447,7 @@ static int iwl_alive_notify(struct iwl_trans *trans) if (!priv->tx_cmd_pool) return -ENOMEM; - iwl_trans_tx_start(trans); + iwl_trans_fw_alive(trans); for_each_context(priv, ctx) ctx->last_tx_rejected = false; -- cgit v1.2.3-70-g09d2 From a591697730a3c416cd384bc199eb5dde622c4c78 Mon Sep 17 00:00:00 2001 From: Gregory Greenman Date: Tue, 10 Jan 2012 19:22:56 +0200 Subject: iwlwifi: Connect IDI transport to driver. This patch connects IDI transport to driver. It does so by using a number of ifdefs at this stage. IDI is a new transport that is under development. Signed-off-by: Gregory Greenman Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-pci.c | 4 ++++ drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 13 ++++++++++++- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 7 ++++++- drivers/net/wireless/iwlwifi/iwl-trans.h | 1 + 4 files changed, 23 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 03702a2e913..2c46063522c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -454,7 +454,11 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) bus->irq = pdev->irq; bus->ops = &bus_ops_pci; +#ifdef CONFIG_IWLWIFI_IDI + err = iwl_probe(bus, &trans_ops_idi, cfg); +#else err = iwl_probe(bus, &trans_ops_pcie, cfg); +#endif if (err) goto out_disable_msi; return 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 2822b7e8bca..b94c95370b7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -35,6 +35,10 @@ #include "iwl-io.h" #include "iwl-trans-pcie-int.h" +#ifdef CONFIG_IWLWIFI_IDI +#include "iwl-amfh.h" +#endif + /****************************************************************************** * * RX path functions @@ -1100,8 +1104,11 @@ void iwl_irq_tasklet(struct iwl_trans *trans) /* Disable periodic interrupt; we use it as just a one-shot. */ iwl_write8(bus(trans), CSR_INT_PERIODIC_REG, CSR_INT_PERIODIC_DIS); +#ifdef CONFIG_IWLWIFI_IDI + iwl_amfh_rx_handler(); +#else iwl_rx_handle(trans); - +#endif /* * Enable periodic interrupt in 8 msec only if we received * real RX interrupt (instead of just periodic int), to catch @@ -1123,7 +1130,11 @@ void iwl_irq_tasklet(struct iwl_trans *trans) isr_stats->tx++; handled |= CSR_INT_BIT_FH_TX; /* Wake up uCode load routine, now that load is complete */ +#ifdef CONFIG_IWLWIFI_IDI + trans->shrd->trans->ucode_write_complete = 1; +#else trans->ucode_write_complete = 1; +#endif wake_up(&trans->shrd->wait_command_queue); } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index affa56fafdb..0b4280c9258 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -647,8 +647,10 @@ static int iwl_nic_init(struct iwl_trans *trans) iwl_nic_config(priv(trans)); +#ifndef CONFIG_IWLWIFI_IDI /* Allocate the RX queue, or reset if it is already allocated */ iwl_rx_init(trans); +#endif /* Allocate or reset and init all Tx and Command queues */ if (iwl_tx_init(trans)) @@ -1016,8 +1018,9 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) */ if (test_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status)) { iwl_trans_tx_stop(trans); +#ifndef CONFIG_IWLWIFI_IDI iwl_trans_rx_stop(trans); - +#endif /* Power-down device's busmaster DMA clocks */ iwl_write_prph(bus(trans), APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); @@ -1298,7 +1301,9 @@ static void iwl_trans_pcie_free(struct iwl_trans *trans) { iwl_calib_free_results(trans); iwl_trans_pcie_tx_free(trans); +#ifndef CONFIG_IWLWIFI_IDI iwl_trans_pcie_rx_free(trans); +#endif free_irq(bus(trans)->irq, trans); iwl_free_isr_ict(trans); trans->shrd->trans = NULL; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 9795a23ee94..2a6649c9ca4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -383,6 +383,7 @@ static inline int iwl_trans_resume(struct iwl_trans *trans) * Transport layers implementations ******************************************************/ extern const struct iwl_trans_ops trans_ops_pcie; +extern const struct iwl_trans_ops trans_ops_idi; int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc, const void *data, size_t len); -- cgit v1.2.3-70-g09d2 From 8747bb4936c137bb93b91afd70eedd65069d26cd Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 4 Jan 2012 16:57:09 +0200 Subject: iwlwifi: separate the APM from the EEPROM There is no link between the two. Ensure that the NIC is on outside the code of the EEPROM handling. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 ++++ drivers/net/wireless/iwlwifi/iwl-eeprom.c | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 9d9185ffc39..f3bd6a3eec3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1848,8 +1848,12 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, /***************** * 4. Read EEPROM *****************/ + /* switch the NIC on before accessing the EEPROM */ + iwl_apm_init(priv); /* Read the EEPROM */ err = iwl_eeprom_init(priv, hw_rev); + /* Reset chip to save power until we load uCode during "up". */ + iwl_apm_stop(priv); if (err) { IWL_ERR(priv, "Unable to init EEPROM\n"); goto out_free_trans; diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index e27d9f55267..ce214e0ab49 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -676,8 +676,6 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) } e = (__le16 *)shrd->eeprom; - iwl_apm_init(priv); - ret = iwl_eeprom_verify_signature(trans(priv)); if (ret < 0) { IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); @@ -758,8 +756,6 @@ done: err: if (ret) iwl_eeprom_free(priv->shrd); - /* Reset chip to save power until we load uCode during "up". */ - iwl_apm_stop(priv); alloc_err: return ret; } -- cgit v1.2.3-70-g09d2 From 87e7597b5a3f99238d95d63c44c9f872a41b37ae Mon Sep 17 00:00:00 2001 From: David Miller Date: Wed, 1 Feb 2012 10:49:17 +0000 Subject: qeth: Move away from using neighbour entries in qeth_l3_fill_header() We've moving to a model where dst_entry objects to not have a reference to the associated neighbour entry, instead such neighbours must be looked up on-demand. Here in qeth_l3_fill_header() it's actually much simpler to use the information in the route itself. The code is already conditionalized upon protocol type. Signed-off-by: David S. Miller Tested-by: Ursula Braun --- drivers/s390/net/qeth_l3_main.c | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 9648e4e6833..25cd3799a76 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -28,6 +28,8 @@ #include #include +#include +#include #include #include @@ -2832,7 +2834,6 @@ static void qeth_l3_fill_af_iucv_hdr(struct qeth_card *card, static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, struct sk_buff *skb, int ipv, int cast_type) { - struct neighbour *n = NULL; struct dst_entry *dst; memset(hdr, 0, sizeof(struct qeth_hdr)); @@ -2855,33 +2856,29 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, rcu_read_lock(); dst = skb_dst(skb); - if (dst) - n = dst_get_neighbour_noref(dst); if (ipv == 4) { + struct rtable *rt = (struct rtable *) dst; + __be32 *pkey = &ip_hdr(skb)->daddr; + + if (rt->rt_gateway) + pkey = &rt->rt_gateway; + /* IPv4 */ hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags4(cast_type); memset(hdr->hdr.l3.dest_addr, 0, 12); - if (n) { - *((u32 *) (&hdr->hdr.l3.dest_addr[12])) = - *((u32 *) n->primary_key); - } else { - /* fill in destination address used in ip header */ - *((u32 *) (&hdr->hdr.l3.dest_addr[12])) = - ip_hdr(skb)->daddr; - } + *((__be32 *) (&hdr->hdr.l3.dest_addr[12])) = *pkey; } else if (ipv == 6) { + struct rt6_info *rt = (struct rt6_info *) dst; + struct in6_addr *pkey = &ipv6_hdr(skb)->daddr; + + if (!ipv6_addr_any(&rt->rt6i_gateway)) + pkey = &rt->rt6i_gateway; + /* IPv6 */ hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags6(cast_type); if (card->info.type == QETH_CARD_TYPE_IQD) hdr->hdr.l3.flags &= ~QETH_HDR_PASSTHRU; - if (n) { - memcpy(hdr->hdr.l3.dest_addr, - n->primary_key, 16); - } else { - /* fill in destination address used in ip header */ - memcpy(hdr->hdr.l3.dest_addr, - &ipv6_hdr(skb)->daddr, 16); - } + memcpy(hdr->hdr.l3.dest_addr, pkey, 16); } else { /* passthrough */ if ((skb->dev->type == ARPHRD_IEEE802_TR) && -- cgit v1.2.3-70-g09d2 From e1f4c485cdb2b1d7aae172b731f6c2b403381ebb Mon Sep 17 00:00:00 2001 From: Danny Kukawka Date: Thu, 2 Feb 2012 03:20:28 +0000 Subject: eicon: fix -Warray-bounds warning Fix for a -Warray-bounds warning. mixer_notify_update() tries to write to ((CAPI_MSG *) msg)->info.facility_req.structs[3] while structs is defined as byte structs[1]. Set all 'structs' which are part of the typdefs in the info union to 'byte structs[0]'. v2: set all info.*.structs to byte structs[0] Signed-off-by: Danny Kukawka Signed-off-by: David S. Miller --- drivers/isdn/hardware/eicon/capi20.h | 60 ++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/hardware/eicon/capi20.h b/drivers/isdn/hardware/eicon/capi20.h index 7ebcccda74d..27ecd61888d 100644 --- a/drivers/isdn/hardware/eicon/capi20.h +++ b/drivers/isdn/hardware/eicon/capi20.h @@ -117,7 +117,7 @@ typedef struct api_profile_s { /*------------------------------------------------------------------*/ /* ALERT-REQUEST */ typedef struct { - byte structs[1]; /* Additional Info */ + byte structs[0]; /* Additional Info */ } _ALT_REQP; /* ALERT-CONFIRM */ typedef struct { @@ -126,7 +126,7 @@ typedef struct { /* CONNECT-REQUEST */ typedef struct { word CIP_Value; - byte structs[1]; /* Called party number, + byte structs[0]; /* Called party number, Called party subaddress, Calling party number, Calling party subaddress, @@ -143,7 +143,7 @@ typedef struct { /* CONNECT-INDICATION */ typedef struct { word CIP_Value; - byte structs[1]; /* Called party number, + byte structs[0]; /* Called party number, Called party subaddress, Calling party number, Calling party subaddress, @@ -155,24 +155,24 @@ typedef struct { /* CONNECT-RESPONSE */ typedef struct { word Accept; - byte structs[1]; /* B_protocol, + byte structs[0]; /* B_protocol, Connected party number, Connected party subaddress, LLC */ } _CON_RESP; /* CONNECT-ACTIVE-INDICATION */ typedef struct { - byte structs[1]; /* Connected party number, + byte structs[0]; /* Connected party number, Connected party subaddress, LLC */ } _CON_A_INDP; /* CONNECT-ACTIVE-RESPONSE */ typedef struct { - byte structs[1]; /* empty */ + byte structs[0]; /* empty */ } _CON_A_RESP; /* DISCONNECT-REQUEST */ typedef struct { - byte structs[1]; /* Additional Info */ + byte structs[0]; /* Additional Info */ } _DIS_REQP; /* DISCONNECT-CONFIRM */ typedef struct { @@ -184,13 +184,13 @@ typedef struct { } _DIS_INDP; /* DISCONNECT-RESPONSE */ typedef struct { - byte structs[1]; /* empty */ + byte structs[0]; /* empty */ } _DIS_RESP; /* LISTEN-REQUEST */ typedef struct { dword Info_Mask; dword CIP_Mask; - byte structs[1]; /* Calling party number, + byte structs[0]; /* Calling party number, Calling party subaddress */ } _LIS_REQP; /* LISTEN-CONFIRM */ @@ -199,7 +199,7 @@ typedef struct { } _LIS_CONP; /* INFO-REQUEST */ typedef struct { - byte structs[1]; /* Called party number, + byte structs[0]; /* Called party number, Additional Info */ } _INF_REQP; /* INFO-CONFIRM */ @@ -209,15 +209,15 @@ typedef struct { /* INFO-INDICATION */ typedef struct { word Number; - byte structs[1]; /* Info element */ + byte structs[0]; /* Info element */ } _INF_INDP; /* INFO-RESPONSE */ typedef struct { - byte structs[1]; /* empty */ + byte structs[0]; /* empty */ } _INF_RESP; /* SELECT-B-REQUEST */ typedef struct { - byte structs[1]; /* B-protocol */ + byte structs[0]; /* B-protocol */ } _SEL_B_REQP; /* SELECT-B-CONFIRM */ typedef struct { @@ -226,7 +226,7 @@ typedef struct { /* FACILITY-REQUEST */ typedef struct { word Selector; - byte structs[1]; /* Facility parameters */ + byte structs[0]; /* Facility parameters */ } _FAC_REQP; /* FACILITY-CONFIRM STRUCT FOR SUPPLEMENT. SERVICES */ typedef struct { @@ -240,21 +240,21 @@ typedef struct { typedef struct { word Info; word Selector; - byte structs[1]; /* Facility parameters */ + byte structs[0]; /* Facility parameters */ } _FAC_CONP; /* FACILITY-INDICATION */ typedef struct { word Selector; - byte structs[1]; /* Facility parameters */ + byte structs[0]; /* Facility parameters */ } _FAC_INDP; /* FACILITY-RESPONSE */ typedef struct { word Selector; - byte structs[1]; /* Facility parameters */ + byte structs[0]; /* Facility parameters */ } _FAC_RESP; /* CONNECT-B3-REQUEST */ typedef struct { - byte structs[1]; /* NCPI */ + byte structs[0]; /* NCPI */ } _CON_B3_REQP; /* CONNECT-B3-CONFIRM */ typedef struct { @@ -262,24 +262,24 @@ typedef struct { } _CON_B3_CONP; /* CONNECT-B3-INDICATION */ typedef struct { - byte structs[1]; /* NCPI */ + byte structs[0]; /* NCPI */ } _CON_B3_INDP; /* CONNECT-B3-RESPONSE */ typedef struct { word Accept; - byte structs[1]; /* NCPI */ + byte structs[0]; /* NCPI */ } _CON_B3_RESP; /* CONNECT-B3-ACTIVE-INDICATION */ typedef struct { - byte structs[1]; /* NCPI */ + byte structs[0]; /* NCPI */ } _CON_B3_A_INDP; /* CONNECT-B3-ACTIVE-RESPONSE */ typedef struct { - byte structs[1]; /* empty */ + byte structs[0]; /* empty */ } _CON_B3_A_RESP; /* DISCONNECT-B3-REQUEST */ typedef struct { - byte structs[1]; /* NCPI */ + byte structs[0]; /* NCPI */ } _DIS_B3_REQP; /* DISCONNECT-B3-CONFIRM */ typedef struct { @@ -288,11 +288,11 @@ typedef struct { /* DISCONNECT-B3-INDICATION */ typedef struct { word Info; - byte structs[1]; /* NCPI */ + byte structs[0]; /* NCPI */ } _DIS_B3_INDP; /* DISCONNECT-B3-RESPONSE */ typedef struct { - byte structs[1]; /* empty */ + byte structs[0]; /* empty */ } _DIS_B3_RESP; /* DATA-B3-REQUEST */ typedef struct { @@ -335,7 +335,7 @@ typedef struct { } _DAT_B3_RESP; /* RESET-B3-REQUEST */ typedef struct { - byte structs[1]; /* NCPI */ + byte structs[0]; /* NCPI */ } _RES_B3_REQP; /* RESET-B3-CONFIRM */ typedef struct { @@ -343,20 +343,20 @@ typedef struct { } _RES_B3_CONP; /* RESET-B3-INDICATION */ typedef struct { - byte structs[1]; /* NCPI */ + byte structs[0]; /* NCPI */ } _RES_B3_INDP; /* RESET-B3-RESPONSE */ typedef struct { - byte structs[1]; /* empty */ + byte structs[0]; /* empty */ } _RES_B3_RESP; /* CONNECT-B3-T90-ACTIVE-INDICATION */ typedef struct { - byte structs[1]; /* NCPI */ + byte structs[0]; /* NCPI */ } _CON_B3_T90_A_INDP; /* CONNECT-B3-T90-ACTIVE-RESPONSE */ typedef struct { word Reject; - byte structs[1]; /* NCPI */ + byte structs[0]; /* NCPI */ } _CON_B3_T90_A_RESP; /*------------------------------------------------------------------*/ /* message structure */ -- cgit v1.2.3-70-g09d2 From e81fb554cfe082dc59a707767c426cbd2e361033 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 2 Feb 2012 14:08:57 -0800 Subject: iwlwifi: move the shrd memory from priv Allocating the shrd area dynamically will allow more agility while revamping the flows. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 +--- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 - drivers/net/wireless/iwlwifi/iwl-pci.c | 10 ++++++++++ 3 files changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index f3bd6a3eec3..b42be308450 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1780,9 +1780,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, } priv = hw->priv; - priv->shrd = &priv->_shrd; - bus->shrd = priv->shrd; - priv->shrd->bus = bus; + priv->shrd = bus->shrd; priv->shrd->priv = priv; priv->shrd->trans = trans_ops->alloc(priv->shrd); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index af846002150..fff5b620927 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -821,7 +821,6 @@ struct iwl_wipan_noa_data { struct iwl_priv { /*data shared among all the driver's layers */ - struct iwl_shared _shrd; struct iwl_shared *shrd; /* ieee device used by generic ieee processing code */ diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 2c46063522c..a3ca0a78336 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -374,10 +374,18 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (!bus) { dev_printk(KERN_ERR, &pdev->dev, "Couldn't allocate iwl_pci_bus"); + return -ENOMEM; + } + + bus->shrd = kzalloc(sizeof(*bus->shrd), GFP_KERNEL); + if (!bus->shrd) { + dev_printk(KERN_ERR, &pdev->dev, + "Couldn't allocate iwl_shared"); err = -ENOMEM; goto out_no_pci; } + bus->shrd->bus = bus; pci_bus = IWL_BUS_GET_PCI_BUS(bus); pci_bus->pci_dev = pdev; @@ -472,6 +480,7 @@ out_pci_release_regions: out_pci_disable_device: pci_disable_device(pdev); out_no_pci: + kfree(bus->shrd); kfree(bus); return err; } @@ -491,6 +500,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) pci_disable_device(pci_dev); pci_set_drvdata(pci_dev, NULL); + kfree(bus->shrd); kfree(bus); } -- cgit v1.2.3-70-g09d2 From b52e7ea109cfe4ea7fea99b1cd20f57ccd95476a Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 2 Feb 2012 14:16:59 -0800 Subject: iwlwifi: allocate the transport from the bus layer Change the way we alloc the transport on the way. Since the transport is allocated from a bus specific area, we can give the bus specific parameters (i.e. pci_dev for PCI) to the transport. This will be useful when the bus layer will be killed. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 16 +++------------- drivers/net/wireless/iwlwifi/iwl-pci.c | 17 ++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 24 ++++++++++++++---------- drivers/net/wireless/iwlwifi/iwl-trans.h | 21 +++++++++++++++------ 4 files changed, 48 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b42be308450..1a4ba9de99b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1783,12 +1783,6 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, priv->shrd = bus->shrd; priv->shrd->priv = priv; - priv->shrd->trans = trans_ops->alloc(priv->shrd); - if (priv->shrd->trans == NULL) { - err = -ENOMEM; - goto out_free_traffic_mem; - } - /* At this point both hw and priv are allocated. */ SET_IEEE80211_DEV(hw, bus(priv)->dev); @@ -1835,12 +1829,12 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, err = iwl_trans_request_irq(trans(priv)); if (err) - goto out_free_trans; + goto out_free_traffic_mem; if (iwl_trans_prepare_card_hw(trans(priv))) { err = -EIO; IWL_WARN(priv, "Failed, HW not ready\n"); - goto out_free_trans; + goto out_free_traffic_mem; } /***************** @@ -1854,7 +1848,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, iwl_apm_stop(priv); if (err) { IWL_ERR(priv, "Unable to init EEPROM\n"); - goto out_free_trans; + goto out_free_traffic_mem; } err = iwl_eeprom_check_version(priv); if (err) @@ -1935,8 +1929,6 @@ out_destroy_workqueue: iwl_uninit_drv(priv); out_free_eeprom: iwl_eeprom_free(priv->shrd); -out_free_trans: - iwl_trans_free(trans(priv)); out_free_traffic_mem: iwl_free_traffic_mem(priv); ieee80211_free_hw(priv->hw); @@ -1980,8 +1972,6 @@ void __devexit iwl_remove(struct iwl_priv * priv) priv->shrd->workqueue = NULL; iwl_free_traffic_mem(priv); - iwl_trans_free(trans(priv)); - iwl_uninit_drv(priv); dev_kfree_skb(priv->beacon_skb); diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index a3ca0a78336..c0d62e72495 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -463,14 +463,28 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) bus->ops = &bus_ops_pci; #ifdef CONFIG_IWLWIFI_IDI + trans(bus) = iwl_trans_idi_alloc(bus->shrd, pdev, ent); + if (trans(bus) == NULL) { + err = -ENOMEM; + goto out_disable_msi; + } + err = iwl_probe(bus, &trans_ops_idi, cfg); #else + trans(bus) = iwl_trans_pcie_alloc(bus->shrd, pdev, ent); + if (trans(bus) == NULL) { + err = -ENOMEM; + goto out_disable_msi; + } + err = iwl_probe(bus, &trans_ops_pcie, cfg); #endif if (err) - goto out_disable_msi; + goto out_free_trans; return 0; +out_free_trans: + iwl_trans_free(trans(bus)); out_disable_msi: pci_disable_msi(pdev); pci_iounmap(pdev, pci_bus->hw_base); @@ -493,6 +507,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) struct iwl_shared *shrd = bus->shrd; iwl_remove(shrd->priv); + iwl_trans_free(shrd->trans); pci_disable_msi(pci_dev); pci_iounmap(pci_dev, pci_bus->hw_base); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 0b4280c9258..f0d8cccbcb1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1376,19 +1376,24 @@ static void iwl_trans_pcie_wake_any_queue(struct iwl_trans *trans, const struct iwl_trans_ops trans_ops_pcie; -static struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd) +struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, + struct pci_dev *pdev, + const struct pci_device_id *ent) { + struct iwl_trans_pcie *trans_pcie; struct iwl_trans *iwl_trans = kzalloc(sizeof(struct iwl_trans) + sizeof(struct iwl_trans_pcie), GFP_KERNEL); - if (iwl_trans) { - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(iwl_trans); - iwl_trans->ops = &trans_ops_pcie; - iwl_trans->shrd = shrd; - trans_pcie->trans = iwl_trans; - spin_lock_init(&iwl_trans->hcmd_lock); - } + + if (WARN_ON(!iwl_trans)) + return NULL; + + trans_pcie = IWL_TRANS_GET_PCIE_TRANS(iwl_trans); + + iwl_trans->ops = &trans_ops_pcie; + iwl_trans->shrd = shrd; + trans_pcie->trans = iwl_trans; + spin_lock_init(&iwl_trans->hcmd_lock); return iwl_trans; } @@ -1912,7 +1917,6 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, #endif /*CONFIG_IWLWIFI_DEBUGFS */ const struct iwl_trans_ops trans_ops_pcie = { - .alloc = iwl_trans_pcie_alloc, .request_irq = iwl_trans_pcie_request_irq, .fw_alive = iwl_trans_pcie_fw_alive, .start_device = iwl_trans_pcie_start_device, diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 2a6649c9ca4..b1a7af26c57 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -133,7 +133,6 @@ struct iwl_host_cmd { /** * struct iwl_trans_ops - transport specific operations - * @alloc: allocates the meta data (not the queues themselves) * @request_irq: requests IRQ - will be called before the FW load in probe flow * @start_device: allocates and inits all the resources for the transport * layer. @@ -162,7 +161,6 @@ struct iwl_host_cmd { */ struct iwl_trans_ops { - struct iwl_trans *(*alloc)(struct iwl_shared *shrd); int (*request_irq)(struct iwl_trans *iwl_trans); int (*start_device)(struct iwl_trans *trans); void (*fw_alive)(struct iwl_trans *trans); @@ -380,11 +378,8 @@ static inline int iwl_trans_resume(struct iwl_trans *trans) #endif /***************************************************** -* Transport layers implementations +* Utils functions ******************************************************/ -extern const struct iwl_trans_ops trans_ops_pcie; -extern const struct iwl_trans_ops trans_ops_idi; - int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc, const void *data, size_t len); void iwl_dealloc_ucode(struct iwl_trans *trans); @@ -394,4 +389,18 @@ int iwl_calib_set(struct iwl_trans *trans, const struct iwl_calib_hdr *cmd, int len); void iwl_calib_free_results(struct iwl_trans *trans); +/***************************************************** +* Transport layers implementations + their allocation function +******************************************************/ +struct pci_dev; +struct pci_device_id; +extern const struct iwl_trans_ops trans_ops_pcie; +struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, + struct pci_dev *pdev, + const struct pci_device_id *ent); + +extern const struct iwl_trans_ops trans_ops_idi; +struct iwl_trans *iwl_trans_idi_alloc(struct iwl_shared *shrd, + void *pdev_void, + const void *ent_void); #endif /* __iwl_trans_h__ */ -- cgit v1.2.3-70-g09d2 From a42a184458ae95937893cb873c988385637c5e14 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 2 Feb 2012 14:33:08 -0800 Subject: iwlwifi: move the bus configuration to transport All the bus configuration is now done in the transport allocation fucntion. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-bus.h | 2 - drivers/net/wireless/iwlwifi/iwl-pci.c | 93 +----------- drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 6 + drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 169 ++++++++++++++++++---- drivers/net/wireless/iwlwifi/iwl-trans.h | 5 + 5 files changed, 158 insertions(+), 117 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-bus.h b/drivers/net/wireless/iwlwifi/iwl-bus.h index 941b9cb2344..37ed7b60aaf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-bus.h +++ b/drivers/net/wireless/iwlwifi/iwl-bus.h @@ -148,7 +148,6 @@ struct iwl_bus_ops { * @shrd - pointer to iwl_shared which holds shared data from the upper layer * NB: for the time being this needs to be set by the upper layer since * it allocates the shared data - * @irq - the irq number for the device * @reg_lock - protect hw register access */ struct iwl_bus { @@ -156,7 +155,6 @@ struct iwl_bus { const struct iwl_bus_ops *ops; struct iwl_shared *shrd; - unsigned int irq; spinlock_t reg_lock; /* pointer to bus specific struct */ diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index c0d62e72495..631b67ca2b6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -367,7 +367,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); struct iwl_bus *bus; struct iwl_pci_bus *pci_bus; - u16 pci_cmd; int err; bus = kzalloc(sizeof(*bus) + sizeof(*pci_bus), GFP_KERNEL); @@ -382,7 +381,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev_printk(KERN_ERR, &pdev->dev, "Couldn't allocate iwl_shared"); err = -ENOMEM; - goto out_no_pci; + goto out_free_bus; } bus->shrd->bus = bus; @@ -391,82 +390,14 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_drvdata(pdev, bus); - /* W/A - seems to solve weird behavior. We need to remove this if we - * don't want to stay in L1 all the time. This wastes a lot of power */ - pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | - PCIE_LINK_STATE_CLKPM); - - if (pci_enable_device(pdev)) { - err = -ENODEV; - goto out_no_pci; - } - - pci_set_master(pdev); - - err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36)); - if (!err) - err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36)); - if (err) { - err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); - if (!err) - err = pci_set_consistent_dma_mask(pdev, - DMA_BIT_MASK(32)); - /* both attempts failed: */ - if (err) { - dev_printk(KERN_ERR, bus->dev, - "No suitable DMA available.\n"); - goto out_pci_disable_device; - } - } - - err = pci_request_regions(pdev, DRV_NAME); - if (err) { - dev_printk(KERN_ERR, bus->dev, "pci_request_regions failed"); - goto out_pci_disable_device; - } - - pci_bus->hw_base = pci_iomap(pdev, 0, 0); - if (!pci_bus->hw_base) { - dev_printk(KERN_ERR, bus->dev, "pci_iomap failed"); - err = -ENODEV; - goto out_pci_release_regions; - } - - dev_printk(KERN_INFO, &pdev->dev, - "pci_resource_len = 0x%08llx\n", - (unsigned long long) pci_resource_len(pdev, 0)); - dev_printk(KERN_INFO, &pdev->dev, - "pci_resource_base = %p\n", pci_bus->hw_base); - - dev_printk(KERN_INFO, &pdev->dev, - "HW Revision ID = 0x%X\n", pdev->revision); - - /* We disable the RETRY_TIMEOUT register (0x41) to keep - * PCI Tx retries from interfering with C3 CPU state */ - pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); - - err = pci_enable_msi(pdev); - if (err) - dev_printk(KERN_ERR, &pdev->dev, - "pci_enable_msi failed(0X%x)", err); - - /* TODO: Move this away, not needed if not MSI */ - /* enable rfkill interrupt: hw bug w/a */ - pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); - if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { - pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; - pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); - } - bus->dev = &pdev->dev; - bus->irq = pdev->irq; bus->ops = &bus_ops_pci; #ifdef CONFIG_IWLWIFI_IDI trans(bus) = iwl_trans_idi_alloc(bus->shrd, pdev, ent); if (trans(bus) == NULL) { err = -ENOMEM; - goto out_disable_msi; + goto out_free_bus; } err = iwl_probe(bus, &trans_ops_idi, cfg); @@ -474,26 +405,20 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) trans(bus) = iwl_trans_pcie_alloc(bus->shrd, pdev, ent); if (trans(bus) == NULL) { err = -ENOMEM; - goto out_disable_msi; + goto out_free_bus; } err = iwl_probe(bus, &trans_ops_pcie, cfg); #endif if (err) goto out_free_trans; + return 0; out_free_trans: iwl_trans_free(trans(bus)); -out_disable_msi: - pci_disable_msi(pdev); - pci_iounmap(pdev, pci_bus->hw_base); -out_pci_release_regions: pci_set_drvdata(pdev, NULL); - pci_release_regions(pdev); -out_pci_disable_device: - pci_disable_device(pdev); -out_no_pci: +out_free_bus: kfree(bus->shrd); kfree(bus); return err; @@ -502,18 +427,12 @@ out_no_pci: static void __devexit iwl_pci_remove(struct pci_dev *pdev) { struct iwl_bus *bus = pci_get_drvdata(pdev); - struct iwl_pci_bus *pci_bus = IWL_BUS_GET_PCI_BUS(bus); - struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); struct iwl_shared *shrd = bus->shrd; iwl_remove(shrd->priv); iwl_trans_free(shrd->trans); - pci_disable_msi(pci_dev); - pci_iounmap(pci_dev, pci_bus->hw_base); - pci_release_regions(pci_dev); - pci_disable_device(pci_dev); - pci_set_drvdata(pci_dev, NULL); + pci_set_drvdata(pdev, NULL); kfree(bus->shrd); kfree(bus); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 0f73778b73f..47d27bdf2df 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -211,6 +211,8 @@ struct iwl_tx_queue { * @txq_ctx_active_msk: what queue is active * queue_stopped: tracks what queue is stopped * queue_stop_count: tracks what SW queue is stopped + * @pci_dev: basic pci-network driver stuff + * @hw_base: pci hardware address support */ struct iwl_trans_pcie { struct iwl_rx_queue rxq; @@ -241,6 +243,10 @@ struct iwl_trans_pcie { #define IWL_MAX_HW_QUEUES 32 unsigned long queue_stopped[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)]; atomic_t queue_stop_count[4]; + + /* PCI bus related data */ + struct pci_dev *pci_dev; + void __iomem *hw_base; }; #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index f0d8cccbcb1..5d0cfe03340 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -60,6 +60,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ +#include +#include #include #include #include @@ -1042,7 +1044,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) spin_unlock_irqrestore(&trans->shrd->lock, flags); /* wait to make sure we flush pending tasklet*/ - synchronize_irq(bus(trans)->irq); + synchronize_irq(trans->irq); tasklet_kill(&trans_pcie->irq_tasklet); /* stop and reset the on-board processor */ @@ -1246,10 +1248,10 @@ static int iwl_trans_pcie_request_irq(struct iwl_trans *trans) iwl_alloc_isr_ict(trans); - err = request_irq(bus(trans)->irq, iwl_isr_ict, IRQF_SHARED, + err = request_irq(trans->irq, iwl_isr_ict, IRQF_SHARED, DRV_NAME, trans); if (err) { - IWL_ERR(trans, "Error allocating IRQ %d\n", bus(trans)->irq); + IWL_ERR(trans, "Error allocating IRQ %d\n", trans->irq); iwl_free_isr_ict(trans); return err; } @@ -1299,13 +1301,22 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, static void iwl_trans_pcie_free(struct iwl_trans *trans) { + struct iwl_trans_pcie *trans_pcie = + IWL_TRANS_GET_PCIE_TRANS(trans); + iwl_calib_free_results(trans); iwl_trans_pcie_tx_free(trans); #ifndef CONFIG_IWLWIFI_IDI iwl_trans_pcie_rx_free(trans); #endif - free_irq(bus(trans)->irq, trans); + free_irq(trans->irq, trans); iwl_free_isr_ict(trans); + + pci_disable_msi(trans_pcie->pci_dev); + pci_iounmap(trans_pcie->pci_dev, trans_pcie->hw_base); + pci_release_regions(trans_pcie->pci_dev); + pci_disable_device(trans_pcie->pci_dev); + trans->shrd->trans = NULL; kfree(trans); } @@ -1374,30 +1385,6 @@ static void iwl_trans_pcie_wake_any_queue(struct iwl_trans *trans, } } -const struct iwl_trans_ops trans_ops_pcie; - -struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, - struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct iwl_trans_pcie *trans_pcie; - struct iwl_trans *iwl_trans = kzalloc(sizeof(struct iwl_trans) + - sizeof(struct iwl_trans_pcie), - GFP_KERNEL); - - if (WARN_ON(!iwl_trans)) - return NULL; - - trans_pcie = IWL_TRANS_GET_PCIE_TRANS(iwl_trans); - - iwl_trans->ops = &trans_ops_pcie; - iwl_trans->shrd = shrd; - trans_pcie->trans = iwl_trans; - spin_lock_init(&iwl_trans->hcmd_lock); - - return iwl_trans; -} - static void iwl_trans_pcie_stop_queue(struct iwl_trans *trans, int txq_id, const char *msg) { @@ -1949,3 +1936,129 @@ const struct iwl_trans_ops trans_ops_pcie = { .resume = iwl_trans_pcie_resume, #endif }; + +/* TODO: remove this hack - will be possible when all the io{write/read} ops + * will be done through the transport + */ +struct iwl_pci_bus { + /* basic pci-network driver stuff */ + struct pci_dev *pci_dev; + + /* pci hardware address support */ + void __iomem *hw_base; +}; + +#define IWL_BUS_GET_PCI_BUS(_iwl_bus) \ + ((struct iwl_pci_bus *) ((_iwl_bus)->bus_specific)) + +/* PCI registers */ +#define PCI_CFG_RETRY_TIMEOUT 0x041 + +struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, + struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct iwl_pci_bus *iwl_pci_bus = IWL_BUS_GET_PCI_BUS(shrd->bus); + struct iwl_trans_pcie *trans_pcie; + struct iwl_trans *trans; + u16 pci_cmd; + int err; + + trans = kzalloc(sizeof(struct iwl_trans) + + sizeof(struct iwl_trans_pcie), GFP_KERNEL); + + if (WARN_ON(!trans)) + return NULL; + + trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + + trans->ops = &trans_ops_pcie; + trans->shrd = shrd; + trans_pcie->trans = trans; + spin_lock_init(&trans->hcmd_lock); + + /* W/A - seems to solve weird behavior. We need to remove this if we + * don't want to stay in L1 all the time. This wastes a lot of power */ + pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | + PCIE_LINK_STATE_CLKPM); + + if (pci_enable_device(pdev)) { + err = -ENODEV; + goto out_no_pci; + } + + pci_set_master(pdev); + + err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36)); + if (!err) + err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36)); + if (err) { + err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (!err) + err = pci_set_consistent_dma_mask(pdev, + DMA_BIT_MASK(32)); + /* both attempts failed: */ + if (err) { + dev_printk(KERN_ERR, &pdev->dev, + "No suitable DMA available.\n"); + goto out_pci_disable_device; + } + } + + err = pci_request_regions(pdev, DRV_NAME); + if (err) { + dev_printk(KERN_ERR, &pdev->dev, "pci_request_regions failed"); + goto out_pci_disable_device; + } + + trans_pcie->hw_base = pci_iomap(pdev, 0, 0); + if (!trans_pcie->hw_base) { + dev_printk(KERN_ERR, &pdev->dev, "pci_iomap failed"); + err = -ENODEV; + goto out_pci_release_regions; + } + + /* TODO: remove this hack */ + iwl_pci_bus->hw_base = trans_pcie->hw_base; + + dev_printk(KERN_INFO, &pdev->dev, + "pci_resource_len = 0x%08llx\n", + (unsigned long long) pci_resource_len(pdev, 0)); + dev_printk(KERN_INFO, &pdev->dev, + "pci_resource_base = %p\n", trans_pcie->hw_base); + + dev_printk(KERN_INFO, &pdev->dev, + "HW Revision ID = 0x%X\n", pdev->revision); + + /* We disable the RETRY_TIMEOUT register (0x41) to keep + * PCI Tx retries from interfering with C3 CPU state */ + pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); + + err = pci_enable_msi(pdev); + if (err) + dev_printk(KERN_ERR, &pdev->dev, + "pci_enable_msi failed(0X%x)", err); + + trans->dev = &pdev->dev; + trans->irq = pdev->irq; + trans_pcie->pci_dev = pdev; + + /* TODO: Move this away, not needed if not MSI */ + /* enable rfkill interrupt: hw bug w/a */ + pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); + if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { + pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; + pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); + } + + return trans; + +out_pci_release_regions: + pci_release_regions(pdev); +out_pci_disable_device: + pci_disable_device(pdev); +out_no_pci: + kfree(trans); + return NULL; +} + diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index b1a7af26c57..9a807619486 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -228,6 +228,8 @@ struct iwl_calib_result { * @ops - pointer to iwl_trans_ops * @shrd - pointer to iwl_shared which holds shared data from the upper layer * @hcmd_lock: protects HCMD + * @dev - pointer to struct device * that represents the device + * @irq - the irq number for the device * @ucode_write_complete: indicates that the ucode has been copied. * @ucode_rt: run time ucode image * @ucode_init: init ucode image @@ -240,6 +242,9 @@ struct iwl_trans { struct iwl_shared *shrd; spinlock_t hcmd_lock; + struct device *dev; + unsigned int irq; + u8 ucode_write_complete; /* the image write is complete */ struct fw_img ucode_rt; struct fw_img ucode_init; -- cgit v1.2.3-70-g09d2 From 0390549571cb614ac5cd3327b63f95155a75c673 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 3 Jan 2012 13:48:07 +0200 Subject: iwlwifi: the read / write register ops move to transport Most of the accesses to the registers are done from the transport layer. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-bus.h | 21 --------------- drivers/net/wireless/iwlwifi/iwl-io.h | 11 +++++--- drivers/net/wireless/iwlwifi/iwl-pci.c | 22 ---------------- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 37 ++++++++++++++------------- drivers/net/wireless/iwlwifi/iwl-trans.h | 21 +++++++++++++++ 5 files changed, 48 insertions(+), 64 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-bus.h b/drivers/net/wireless/iwlwifi/iwl-bus.h index 37ed7b60aaf..981f7b79d39 100644 --- a/drivers/net/wireless/iwlwifi/iwl-bus.h +++ b/drivers/net/wireless/iwlwifi/iwl-bus.h @@ -124,18 +124,12 @@ struct iwl_bus; * @apm_config: will be called during the config of the APM * @get_hw_id_string: prints the hw_id in the provided buffer * @get_hw_id: get hw_id in u32 - * @write8: write a byte to register at offset ofs - * @write32: write a dword to register at offset ofs - * @wread32: read a dword at register at offset ofs */ struct iwl_bus_ops { bool (*get_pm_support)(struct iwl_bus *bus); void (*apm_config)(struct iwl_bus *bus); void (*get_hw_id_string)(struct iwl_bus *bus, char buf[], int buf_len); u32 (*get_hw_id)(struct iwl_bus *bus); - void (*write8)(struct iwl_bus *bus, u32 ofs, u8 val); - void (*write32)(struct iwl_bus *bus, u32 ofs, u32 val); - u32 (*read32)(struct iwl_bus *bus, u32 ofs); }; /** @@ -183,21 +177,6 @@ static inline u32 bus_get_hw_id(struct iwl_bus *bus) return bus->ops->get_hw_id(bus); } -static inline void bus_write8(struct iwl_bus *bus, u32 ofs, u8 val) -{ - bus->ops->write8(bus, ofs, val); -} - -static inline void bus_write32(struct iwl_bus *bus, u32 ofs, u32 val) -{ - bus->ops->write32(bus, ofs, val); -} - -static inline u32 bus_read32(struct iwl_bus *bus, u32 ofs) -{ - return bus->ops->read32(bus, ofs); -} - /***************************************************** * Bus layer registration functions ******************************************************/ diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index 427d065435c..b8e00cd7b1f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h @@ -31,23 +31,28 @@ #include "iwl-devtrace.h" #include "iwl-shared.h" +/* TODO: remove when not needed any more */ #include "iwl-bus.h" +#include "iwl-trans.h" static inline void iwl_write8(struct iwl_bus *bus, u32 ofs, u8 val) { + /* TODO: get trans instead of bus */ trace_iwlwifi_dev_iowrite8(priv(bus), ofs, val); - bus_write8(bus, ofs, val); + iwl_trans_write8(trans(bus), ofs, val); } static inline void iwl_write32(struct iwl_bus *bus, u32 ofs, u32 val) { + /* TODO: get trans instead of bus */ trace_iwlwifi_dev_iowrite32(priv(bus), ofs, val); - bus_write32(bus, ofs, val); + iwl_trans_write32(trans(bus), ofs, val); } static inline u32 iwl_read32(struct iwl_bus *bus, u32 ofs) { - u32 val = bus_read32(bus, ofs); + /* TODO: get trans instead of bus */ + u32 val = iwl_trans_read32(trans(bus), ofs); trace_iwlwifi_dev_ioread32(priv(bus), ofs, val); return val; } diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 631b67ca2b6..ab462337d7a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -79,9 +79,6 @@ struct iwl_pci_bus { /* basic pci-network driver stuff */ struct pci_dev *pci_dev; - - /* pci hardware address support */ - void __iomem *hw_base; }; #define IWL_BUS_GET_PCI_BUS(_iwl_bus) \ @@ -151,30 +148,11 @@ static u32 iwl_pci_get_hw_id(struct iwl_bus *bus) return (pci_dev->device << 16) + pci_dev->subsystem_device; } -static void iwl_pci_write8(struct iwl_bus *bus, u32 ofs, u8 val) -{ - iowrite8(val, IWL_BUS_GET_PCI_BUS(bus)->hw_base + ofs); -} - -static void iwl_pci_write32(struct iwl_bus *bus, u32 ofs, u32 val) -{ - iowrite32(val, IWL_BUS_GET_PCI_BUS(bus)->hw_base + ofs); -} - -static u32 iwl_pci_read32(struct iwl_bus *bus, u32 ofs) -{ - u32 val = ioread32(IWL_BUS_GET_PCI_BUS(bus)->hw_base + ofs); - return val; -} - static const struct iwl_bus_ops bus_ops_pci = { .get_pm_support = iwl_pci_is_pm_supported, .apm_config = iwl_pci_apm_config, .get_hw_id_string = iwl_pci_get_hw_id_string, .get_hw_id = iwl_pci_get_hw_id, - .write8 = iwl_pci_write8, - .write32 = iwl_pci_write32, - .read32 = iwl_pci_read32, }; #define IWL_PCI_DEVICE(dev, subdev, cfg) \ diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 5d0cfe03340..80f531844f3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1299,6 +1299,22 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, return 0; } +static void iwl_trans_pcie_write8(struct iwl_trans *trans, u32 ofs, u8 val) +{ + iowrite8(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); +} + +static void iwl_trans_pcie_write32(struct iwl_trans *trans, u32 ofs, u32 val) +{ + iowrite32(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); +} + +static u32 iwl_trans_pcie_read32(struct iwl_trans *trans, u32 ofs) +{ + u32 val = ioread32(IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); + return val; +} + static void iwl_trans_pcie_free(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = @@ -1935,22 +1951,11 @@ const struct iwl_trans_ops trans_ops_pcie = { .suspend = iwl_trans_pcie_suspend, .resume = iwl_trans_pcie_resume, #endif + .write8 = iwl_trans_pcie_write8, + .write32 = iwl_trans_pcie_write32, + .read32 = iwl_trans_pcie_read32, }; -/* TODO: remove this hack - will be possible when all the io{write/read} ops - * will be done through the transport - */ -struct iwl_pci_bus { - /* basic pci-network driver stuff */ - struct pci_dev *pci_dev; - - /* pci hardware address support */ - void __iomem *hw_base; -}; - -#define IWL_BUS_GET_PCI_BUS(_iwl_bus) \ - ((struct iwl_pci_bus *) ((_iwl_bus)->bus_specific)) - /* PCI registers */ #define PCI_CFG_RETRY_TIMEOUT 0x041 @@ -1958,7 +1963,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, struct pci_dev *pdev, const struct pci_device_id *ent) { - struct iwl_pci_bus *iwl_pci_bus = IWL_BUS_GET_PCI_BUS(shrd->bus); struct iwl_trans_pcie *trans_pcie; struct iwl_trans *trans; u16 pci_cmd; @@ -2018,9 +2022,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, goto out_pci_release_regions; } - /* TODO: remove this hack */ - iwl_pci_bus->hw_base = trans_pcie->hw_base; - dev_printk(KERN_INFO, &pdev->dev, "pci_resource_len = 0x%08llx\n", (unsigned long long) pci_resource_len(pdev, 0)); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 9a807619486..0a3727dac6a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -158,6 +158,9 @@ struct iwl_host_cmd { * automatically deleted. * @suspend: stop the device unless WoWLAN is configured * @resume: resume activity of the device + * @write8: write a u8 to a register at offset ofs from the BAR + * @write32: write a u32 to a register at offset ofs from the BAR + * @read32: read a u32 register at offset ofs from the BAR */ struct iwl_trans_ops { @@ -201,6 +204,9 @@ struct iwl_trans_ops { int (*suspend)(struct iwl_trans *trans); int (*resume)(struct iwl_trans *trans); #endif + void (*write8)(struct iwl_trans *trans, u32 ofs, u8 val); + void (*write32)(struct iwl_trans *trans, u32 ofs, u32 val); + u32 (*read32)(struct iwl_trans *trans, u32 ofs); }; /* one for each uCode image (inst/data, boot/init/runtime) */ @@ -382,6 +388,21 @@ static inline int iwl_trans_resume(struct iwl_trans *trans) } #endif +static inline void iwl_trans_write8(struct iwl_trans *trans, u32 ofs, u8 val) +{ + trans->ops->write8(trans, ofs, val); +} + +static inline void iwl_trans_write32(struct iwl_trans *trans, u32 ofs, u32 val) +{ + trans->ops->write32(trans, ofs, val); +} + +static inline u32 iwl_trans_read32(struct iwl_trans *trans, u32 ofs) +{ + return trans->ops->read32(trans, ofs); +} + /***************************************************** * Utils functions ******************************************************/ -- cgit v1.2.3-70-g09d2 From 1042db2af183b96cdce5972014d85e8bca0634ad Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 3 Jan 2012 16:56:15 +0200 Subject: iwlwifi: give trans to all the read / write functions From now on, the transport layer in charge of providing access to the device. So change all the driver to give a pointer to the transport to all the low level functions that actually access the device. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 4 +- drivers/net/wireless/iwlwifi/iwl-2000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-5000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-6000.c | 8 +- drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 8 +- drivers/net/wireless/iwlwifi/iwl-agn-tt.c | 14 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 42 ++--- drivers/net/wireless/iwlwifi/iwl-bus.h | 3 - drivers/net/wireless/iwlwifi/iwl-core.c | 28 ++-- drivers/net/wireless/iwlwifi/iwl-core.h | 2 +- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 6 +- drivers/net/wireless/iwlwifi/iwl-eeprom.c | 61 +++---- drivers/net/wireless/iwlwifi/iwl-io.c | 193 +++++++++++----------- drivers/net/wireless/iwlwifi/iwl-io.h | 63 ++++--- drivers/net/wireless/iwlwifi/iwl-led.c | 9 +- drivers/net/wireless/iwlwifi/iwl-mac80211.c | 27 +-- drivers/net/wireless/iwlwifi/iwl-pci.c | 4 +- drivers/net/wireless/iwlwifi/iwl-testmode.c | 16 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 8 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 82 ++++----- drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 46 +++--- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 144 ++++++++-------- drivers/net/wireless/iwlwifi/iwl-trans.h | 2 + drivers/net/wireless/iwlwifi/iwl-ucode.c | 37 ++--- 24 files changed, 405 insertions(+), 406 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index cc04cce1156..f7a555b9d24 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -84,13 +84,13 @@ static void iwl1000_set_ct_threshold(struct iwl_priv *priv) static void iwl1000_nic_config(struct iwl_priv *priv) { /* set CSR_HW_CONFIG_REG for uCode use */ - iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG, + iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); /* Setting digital SVR for 1000 card to 1.32V */ /* locking is acquired in iwl_set_bits_mask_prph() function */ - iwl_set_bits_mask_prph(bus(priv), APMG_DIGITAL_SVR_REG, + iwl_set_bits_mask_prph(trans(priv), APMG_DIGITAL_SVR_REG, APMG_SVR_DIGITAL_VOLTAGE_1_32, ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK); } diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 00db092d8cd..87600345010 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -87,7 +87,7 @@ static void iwl2000_nic_config(struct iwl_priv *priv) iwl_rf_config(priv); if (cfg(priv)->iq_invert) - iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG, + iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG, CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER); } diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 47fd98b3652..5245a1422a6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -73,7 +73,7 @@ static void iwl5000_nic_config(struct iwl_priv *priv) * (PCIe power is lost before PERST# is asserted), * causing ME FW to lose ownership and not being able to obtain it back. */ - iwl_set_bits_mask_prph(bus(priv), APMG_PS_CTRL_REG, + iwl_set_bits_mask_prph(trans(priv), APMG_PS_CTRL_REG, APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS, ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS); diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index ab62c018fcd..464b8878467 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -82,7 +82,7 @@ static void iwl6050_additional_nic_config(struct iwl_priv *priv) { /* Indicate calibration version to uCode. */ if (iwl_eeprom_calib_version(priv->shrd) >= 6) - iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG, + iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG, CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); } @@ -90,9 +90,9 @@ static void iwl6150_additional_nic_config(struct iwl_priv *priv) { /* Indicate calibration version to uCode. */ if (iwl_eeprom_calib_version(priv->shrd) >= 6) - iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG, + iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG, CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); - iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG, + iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG, CSR_GP_DRIVER_REG_BIT_6050_1x2); } @@ -104,7 +104,7 @@ static void iwl6000_nic_config(struct iwl_priv *priv) /* no locking required for register write */ if (cfg(priv)->pa_type == IWL_PA_INTERNAL) { /* 2x2 IPA phy type */ - iwl_write32(bus(priv), CSR_GP_DRIVER_REG, + iwl_write32(trans(priv), CSR_GP_DRIVER_REG, CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA); } /* do additional nic configuration if needed */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index f127f913e5a..a14ddab783e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -628,16 +628,16 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED | CT_CARD_DISABLED)) { - iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_SET, + iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_SET, CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); - iwl_write_direct32(bus(priv), HBUS_TARG_MBX_C, + iwl_write_direct32(trans(priv), HBUS_TARG_MBX_C, HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); if (!(flags & RXON_CARD_DISABLED)) { - iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR, + iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); - iwl_write_direct32(bus(priv), HBUS_TARG_MBX_C, + iwl_write_direct32(trans(priv), HBUS_TARG_MBX_C, HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); } if (flags & CT_CARD_DISABLED) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c index 56c6def015a..c728ed75584 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c @@ -178,19 +178,19 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data) if (tt->state == IWL_TI_CT_KILL) { if (priv->thermal_throttle.ct_kill_toggle) { - iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR, + iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); priv->thermal_throttle.ct_kill_toggle = false; } else { - iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_SET, + iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_SET, CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); priv->thermal_throttle.ct_kill_toggle = true; } - iwl_read32(bus(priv), CSR_UCODE_DRV_GP1); - spin_lock_irqsave(&bus(priv)->reg_lock, flags); - if (!iwl_grab_nic_access(bus(priv))) - iwl_release_nic_access(bus(priv)); - spin_unlock_irqrestore(&bus(priv)->reg_lock, flags); + iwl_read32(trans(priv), CSR_UCODE_DRV_GP1); + spin_lock_irqsave(&trans(priv)->reg_lock, flags); + if (!iwl_grab_nic_access(trans(priv))) + iwl_release_nic_access(trans(priv)); + spin_unlock_irqrestore(&trans(priv)->reg_lock, flags); /* Reschedule the ct_kill timer to occur in * CT_KILL_EXIT_DURATION seconds to ensure we get a diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 1a4ba9de99b..f79791500a9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -328,14 +328,14 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, ptr = base + (4 * sizeof(u32)) + (start_idx * 3 * sizeof(u32)); /* Make sure device is powered up for SRAM reads */ - spin_lock_irqsave(&bus(priv)->reg_lock, reg_flags); - if (iwl_grab_nic_access(bus(priv))) { - spin_unlock_irqrestore(&bus(priv)->reg_lock, reg_flags); + spin_lock_irqsave(&trans(priv)->reg_lock, reg_flags); + if (iwl_grab_nic_access(trans(priv))) { + spin_unlock_irqrestore(&trans(priv)->reg_lock, reg_flags); return; } /* Set starting address; reads will auto-increment */ - iwl_write32(bus(priv), HBUS_TARG_MEM_RADDR, ptr); + iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, ptr); rmb(); /* @@ -352,19 +352,19 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, * place event id # at far right for easier visual parsing. */ for (i = 0; i < num_events; i++) { - ev = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); - time = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); + ev = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); + time = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); if (mode == 0) { trace_iwlwifi_dev_ucode_cont_event(priv, 0, time, ev); } else { - data = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); + data = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); trace_iwlwifi_dev_ucode_cont_event(priv, time, data, ev); } } /* Allow device to power down */ - iwl_release_nic_access(bus(priv)); - spin_unlock_irqrestore(&bus(priv)->reg_lock, reg_flags); + iwl_release_nic_access(trans(priv)); + spin_unlock_irqrestore(&trans(priv)->reg_lock, reg_flags); } static void iwl_continuous_event_trace(struct iwl_priv *priv) @@ -383,7 +383,7 @@ static void iwl_continuous_event_trace(struct iwl_priv *priv) base = priv->shrd->device_pointers.log_event_table; if (iwlagn_hw_valid_rtc_data_addr(base)) { - iwl_read_targ_mem_words(bus(priv), base, &read, sizeof(read)); + iwl_read_targ_mem_words(trans(priv), base, &read, sizeof(read)); capacity = read.capacity; mode = read.mode; @@ -583,7 +583,7 @@ static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first) priv->firmware_name); return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name, - bus(priv)->dev, + trans(priv)->dev, GFP_KERNEL, priv, iwl_ucode_callback); } @@ -1158,7 +1158,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv) int ret = 0; spin_lock_irqsave(&priv->shrd->lock, flags); - iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR, + iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); spin_unlock_irqrestore(&priv->shrd->lock, flags); priv->thermal_throttle.ct_kill_toggle = false; @@ -1693,7 +1693,7 @@ static void iwl_uninit_drv(struct iwl_priv *priv) static u32 iwl_hw_detect(struct iwl_priv *priv) { - return iwl_read32(bus(priv), CSR_HW_REV); + return iwl_read32(trans(priv), CSR_HW_REV); } /* Size of one Rx buffer in host DRAM */ @@ -1727,32 +1727,32 @@ static int iwl_set_hw_params(struct iwl_priv *priv) static void iwl_debug_config(struct iwl_priv *priv) { - dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEBUG " + dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEBUG " #ifdef CONFIG_IWLWIFI_DEBUG "enabled\n"); #else "disabled\n"); #endif - dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEBUGFS " + dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEBUGFS " #ifdef CONFIG_IWLWIFI_DEBUGFS "enabled\n"); #else "disabled\n"); #endif - dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TRACING " + dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TRACING " #ifdef CONFIG_IWLWIFI_DEVICE_TRACING "enabled\n"); #else "disabled\n"); #endif - dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TESTMODE " + dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TESTMODE " #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE "enabled\n"); #else "disabled\n"); #endif - dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_P2P " + dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_P2P " #ifdef CONFIG_IWLWIFI_P2P "enabled\n"); #else @@ -1810,7 +1810,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, /* these spin locks will be used in apm_ops.init and EEPROM access * we should init now */ - spin_lock_init(&bus(priv)->reg_lock); + spin_lock_init(&trans(priv)->reg_lock); spin_lock_init(&priv->shrd->lock); /* @@ -1818,7 +1818,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, * strange state ... like being left stranded by a primary kernel * and this is now the kdump kernel trying to start up */ - iwl_write32(bus(priv), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); + iwl_write32(trans(priv), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); /*********************** * 3. Read REV register @@ -1903,7 +1903,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, iwl_enable_rfkill_int(priv); /* If platform's RF_KILL switch is NOT set to KILL */ - if (iwl_read32(bus(priv), + if (iwl_read32(trans(priv), CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) clear_bit(STATUS_RF_KILL_HW, &priv->shrd->status); else diff --git a/drivers/net/wireless/iwlwifi/iwl-bus.h b/drivers/net/wireless/iwlwifi/iwl-bus.h index 981f7b79d39..ce1a9cc106e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-bus.h +++ b/drivers/net/wireless/iwlwifi/iwl-bus.h @@ -142,15 +142,12 @@ struct iwl_bus_ops { * @shrd - pointer to iwl_shared which holds shared data from the upper layer * NB: for the time being this needs to be set by the upper layer since * it allocates the shared data - * @reg_lock - protect hw register access */ struct iwl_bus { struct device *dev; const struct iwl_bus_ops *ops; struct iwl_shared *shrd; - spinlock_t reg_lock; - /* pointer to bus specific struct */ /*Ensure that this pointer will always be aligned to sizeof pointer */ char bus_specific[0] __attribute__((__aligned__(sizeof(void *)))); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 7d6eef96454..c9022c5fa81 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -888,9 +888,9 @@ static int iwl_apm_stop_master(struct iwl_priv *priv) int ret = 0; /* stop device's busmaster DMA activity */ - iwl_set_bit(bus(priv), CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); + iwl_set_bit(trans(priv), CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); - ret = iwl_poll_bit(bus(priv), CSR_RESET, + ret = iwl_poll_bit(trans(priv), CSR_RESET, CSR_RESET_REG_FLAG_MASTER_DISABLED, CSR_RESET_REG_FLAG_MASTER_DISABLED, 100); if (ret) @@ -911,7 +911,7 @@ void iwl_apm_stop(struct iwl_priv *priv) iwl_apm_stop_master(priv); /* Reset the entire device */ - iwl_set_bit(bus(priv), CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); + iwl_set_bit(trans(priv), CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); udelay(10); @@ -919,7 +919,8 @@ void iwl_apm_stop(struct iwl_priv *priv) * Clear "initialization complete" bit to move adapter from * D0A* (powered-up Active) --> D0U* (Uninitialized) state. */ - iwl_clear_bit(bus(priv), CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); + iwl_clear_bit(trans(priv), CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_INIT_DONE); } @@ -939,45 +940,46 @@ int iwl_apm_init(struct iwl_priv *priv) */ /* Disable L0S exit timer (platform NMI Work/Around) */ - iwl_set_bit(bus(priv), CSR_GIO_CHICKEN_BITS, + iwl_set_bit(trans(priv), CSR_GIO_CHICKEN_BITS, CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); /* * Disable L0s without affecting L1; * don't wait for ICH L0s (ICH bug W/A) */ - iwl_set_bit(bus(priv), CSR_GIO_CHICKEN_BITS, + iwl_set_bit(trans(priv), CSR_GIO_CHICKEN_BITS, CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); /* Set FH wait threshold to maximum (HW error during stress W/A) */ - iwl_set_bit(bus(priv), CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL); + iwl_set_bit(trans(priv), CSR_DBG_HPET_MEM_REG, + CSR_DBG_HPET_MEM_REG_VAL); /* * Enable HAP INTA (interrupt from management bus) to * wake device's PCI Express link L1a -> L0s */ - iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG, + iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); bus_apm_config(bus(priv)); /* Configure analog phase-lock-loop before activating to D0A */ if (cfg(priv)->base_params->pll_cfg_val) - iwl_set_bit(bus(priv), CSR_ANA_PLL_CFG, + iwl_set_bit(trans(priv), CSR_ANA_PLL_CFG, cfg(priv)->base_params->pll_cfg_val); /* * Set "initialization complete" bit to move adapter from * D0U* --> D0A* (powered-up active) state. */ - iwl_set_bit(bus(priv), CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); + iwl_set_bit(trans(priv), CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); /* * Wait for clock stabilization; once stabilized, access to * device-internal resources is supported, e.g. iwl_write_prph() * and accesses to uCode SRAM. */ - ret = iwl_poll_bit(bus(priv), CSR_GP_CNTRL, + ret = iwl_poll_bit(trans(priv), CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); if (ret < 0) { @@ -992,11 +994,11 @@ int iwl_apm_init(struct iwl_priv *priv) * do not disable clocks. This preserves any hardware bits already * set by default in "CLK_CTRL_REG" after reset. */ - iwl_write_prph(bus(priv), APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT); + iwl_write_prph(trans(priv), APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT); udelay(20); /* Disable L1-Active */ - iwl_set_bits_prph(bus(priv), APMG_PCIDEV_STT_REG, + iwl_set_bits_prph(trans(priv), APMG_PCIDEV_STT_REG, APMG_PCIDEV_STT_VAL_L1_ACT_DIS); set_bit(STATUS_DEVICE_ENABLED, &priv->shrd->status); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 63f29111da1..e74bfb7bbb2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -300,7 +300,7 @@ static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv) static inline void iwl_enable_rfkill_int(struct iwl_priv *priv) { IWL_DEBUG_ISR(priv, "Enabling rfkill interrupt\n"); - iwl_write32(bus(priv), CSR_INT_MASK, CSR_INT_BIT_RF_KILL); + iwl_write32(trans(priv), CSR_INT_MASK, CSR_INT_BIT_RF_KILL); } extern bool bt_siso_mode; diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 978a1d4c6a0..136de6fb3fa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -263,7 +263,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, sram = priv->dbgfs_sram_offset & ~0x3; /* read the first u32 from sram */ - val = iwl_read_targ_mem(bus(priv), sram); + val = iwl_read_targ_mem(trans(priv), sram); for (; len; len--) { /* put the address at the start of every line */ @@ -282,7 +282,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, if (++offset == 4) { sram += 4; offset = 0; - val = iwl_read_targ_mem(bus(priv), sram); + val = iwl_read_targ_mem(trans(priv), sram); } /* put in extra spaces and split lines for human readability */ @@ -2055,7 +2055,7 @@ static ssize_t iwl_dbgfs_power_save_status_read(struct file *file, const size_t bufsz = sizeof(buf); u32 pwrsave_status; - pwrsave_status = iwl_read32(bus(priv), CSR_GP_CNTRL) & + pwrsave_status = iwl_read32(trans(priv), CSR_GP_CNTRL) & CSR_GP_REG_POWER_SAVE_STATUS_MSK; pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: "); diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index ce214e0ab49..d1fd1cdb29c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -156,16 +156,16 @@ static int iwl_eeprom_acquire_semaphore(struct iwl_bus *bus) for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { /* Request semaphore */ - iwl_set_bit(bus, CSR_HW_IF_CONFIG_REG, + iwl_set_bit(trans(bus), CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); /* See if we got it */ - ret = iwl_poll_bit(bus, CSR_HW_IF_CONFIG_REG, + ret = iwl_poll_bit(trans(bus), CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, EEPROM_SEM_TIMEOUT); if (ret >= 0) { - IWL_DEBUG_EEPROM(bus, + IWL_DEBUG_EEPROM(trans(bus), "Acquired semaphore after %d tries.\n", count+1); return ret; @@ -177,14 +177,15 @@ static int iwl_eeprom_acquire_semaphore(struct iwl_bus *bus) static void iwl_eeprom_release_semaphore(struct iwl_bus *bus) { - iwl_clear_bit(bus, CSR_HW_IF_CONFIG_REG, + iwl_clear_bit(trans(bus), CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); } static int iwl_eeprom_verify_signature(struct iwl_trans *trans) { - u32 gp = iwl_read32(bus(trans), CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK; + u32 gp = iwl_read32(trans, CSR_EEPROM_GP) & + CSR_EEPROM_GP_VALID_MSK; int ret = 0; IWL_DEBUG_EEPROM(trans, "EEPROM signature=0x%08x\n", gp); @@ -305,13 +306,13 @@ void iwl_eeprom_get_mac(const struct iwl_shared *shrd, u8 *mac) static void iwl_set_otp_access(struct iwl_bus *bus, enum iwl_access_mode mode) { - iwl_read32(bus, CSR_OTP_GP_REG); + iwl_read32(trans(bus), CSR_OTP_GP_REG); if (mode == IWL_OTP_ACCESS_ABSOLUTE) - iwl_clear_bit(bus, CSR_OTP_GP_REG, + iwl_clear_bit(trans(bus), CSR_OTP_GP_REG, CSR_OTP_GP_REG_OTP_ACCESS_MODE); else - iwl_set_bit(bus, CSR_OTP_GP_REG, + iwl_set_bit(trans(bus), CSR_OTP_GP_REG, CSR_OTP_GP_REG_OTP_ACCESS_MODE); } @@ -332,7 +333,7 @@ static int iwl_get_nvm_type(struct iwl_bus *bus, u32 hw_rev) nvm_type = NVM_DEVICE_TYPE_EEPROM; break; default: - otpgp = iwl_read32(bus, CSR_OTP_GP_REG); + otpgp = iwl_read32(trans(bus), CSR_OTP_GP_REG); if (otpgp & CSR_OTP_GP_REG_DEVICE_SELECT) nvm_type = NVM_DEVICE_TYPE_OTP; else @@ -347,22 +348,22 @@ static int iwl_init_otp_access(struct iwl_bus *bus) int ret; /* Enable 40MHz radio clock */ - iwl_write32(bus, CSR_GP_CNTRL, - iwl_read32(bus, CSR_GP_CNTRL) | + iwl_write32(trans(bus), CSR_GP_CNTRL, + iwl_read32(trans(bus), CSR_GP_CNTRL) | CSR_GP_CNTRL_REG_FLAG_INIT_DONE); /* wait for clock to be ready */ - ret = iwl_poll_bit(bus, CSR_GP_CNTRL, + ret = iwl_poll_bit(trans(bus), CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); if (ret < 0) IWL_ERR(bus, "Time out access OTP\n"); else { - iwl_set_bits_prph(bus, APMG_PS_CTRL_REG, + iwl_set_bits_prph(trans(bus), APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ); udelay(5); - iwl_clear_bits_prph(bus, APMG_PS_CTRL_REG, + iwl_clear_bits_prph(trans(bus), APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ); /* @@ -370,7 +371,7 @@ static int iwl_init_otp_access(struct iwl_bus *bus) * this is only applicable for HW with OTP shadow RAM */ if (cfg(bus)->base_params->shadow_ram_support) - iwl_set_bit(bus, CSR_DBG_LINK_PWR_MGMT_REG, + iwl_set_bit(trans(bus), CSR_DBG_LINK_PWR_MGMT_REG, CSR_RESET_LINK_PWR_MGMT_DISABLED); } return ret; @@ -382,9 +383,9 @@ static int iwl_read_otp_word(struct iwl_bus *bus, u16 addr, __le16 *eeprom_data) u32 r; u32 otpgp; - iwl_write32(bus, CSR_EEPROM_REG, + iwl_write32(trans(bus), CSR_EEPROM_REG, CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); - ret = iwl_poll_bit(bus, CSR_EEPROM_REG, + ret = iwl_poll_bit(trans(bus), CSR_EEPROM_REG, CSR_EEPROM_REG_READ_VALID_MSK, CSR_EEPROM_REG_READ_VALID_MSK, IWL_EEPROM_ACCESS_TIMEOUT); @@ -392,13 +393,13 @@ static int iwl_read_otp_word(struct iwl_bus *bus, u16 addr, __le16 *eeprom_data) IWL_ERR(bus, "Time out reading OTP[%d]\n", addr); return ret; } - r = iwl_read32(bus, CSR_EEPROM_REG); + r = iwl_read32(trans(bus), CSR_EEPROM_REG); /* check for ECC errors: */ - otpgp = iwl_read32(bus, CSR_OTP_GP_REG); + otpgp = iwl_read32(trans(bus), CSR_OTP_GP_REG); if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) { /* stop in this case */ /* set the uncorrectable OTP ECC bit for acknowledgement */ - iwl_set_bit(bus, CSR_OTP_GP_REG, + iwl_set_bit(trans(bus), CSR_OTP_GP_REG, CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); IWL_ERR(bus, "Uncorrectable OTP ECC error, abort OTP read\n"); return -EINVAL; @@ -406,7 +407,7 @@ static int iwl_read_otp_word(struct iwl_bus *bus, u16 addr, __le16 *eeprom_data) if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) { /* continue in this case */ /* set the correctable OTP ECC bit for acknowledgement */ - iwl_set_bit(bus, CSR_OTP_GP_REG, + iwl_set_bit(trans(bus), CSR_OTP_GP_REG, CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK); IWL_ERR(bus, "Correctable OTP ECC error, continue read\n"); } @@ -656,7 +657,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) { struct iwl_shared *shrd = priv->shrd; __le16 *e; - u32 gp = iwl_read32(bus(priv), CSR_EEPROM_GP); + u32 gp = iwl_read32(trans(priv), CSR_EEPROM_GP); int sz; int ret; u16 addr; @@ -699,11 +700,11 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) ret = -ENOENT; goto done; } - iwl_write32(bus(priv), CSR_EEPROM_GP, - iwl_read32(bus(priv), CSR_EEPROM_GP) & + iwl_write32(trans(priv), CSR_EEPROM_GP, + iwl_read32(trans(priv), CSR_EEPROM_GP) & ~CSR_EEPROM_GP_IF_OWNER_MSK); - iwl_set_bit(bus(priv), CSR_OTP_GP_REG, + iwl_set_bit(trans(priv), CSR_OTP_GP_REG, CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); /* traversing the linked list if no shadow ram supported */ @@ -728,10 +729,10 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) for (addr = 0; addr < sz; addr += sizeof(u16)) { u32 r; - iwl_write32(bus(priv), CSR_EEPROM_REG, + iwl_write32(trans(priv), CSR_EEPROM_REG, CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); - ret = iwl_poll_bit(bus(priv), CSR_EEPROM_REG, + ret = iwl_poll_bit(trans(priv), CSR_EEPROM_REG, CSR_EEPROM_REG_READ_VALID_MSK, CSR_EEPROM_REG_READ_VALID_MSK, IWL_EEPROM_ACCESS_TIMEOUT); @@ -739,7 +740,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr); goto done; } - r = iwl_read32(bus(priv), CSR_EEPROM_REG); + r = iwl_read32(trans(priv), CSR_EEPROM_REG); e[addr / 2] = cpu_to_le16(r >> 16); } } @@ -1068,7 +1069,7 @@ void iwl_rf_config(struct iwl_priv *priv) /* write radio config values to register */ if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) { - iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG, + iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG, EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | EEPROM_RF_CFG_STEP_MSK(radio_cfg) | EEPROM_RF_CFG_DASH_MSK(radio_cfg)); @@ -1080,7 +1081,7 @@ void iwl_rf_config(struct iwl_priv *priv) WARN_ON(1); /* set CSR_HW_CONFIG_REG for uCode use */ - iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG, + iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); } diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index 83fdff38115..e2e3b5c9cf7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c @@ -34,41 +34,41 @@ #define IWL_POLL_INTERVAL 10 /* microseconds */ -static inline void __iwl_set_bit(struct iwl_bus *bus, u32 reg, u32 mask) +static inline void __iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask) { - iwl_write32(bus, reg, iwl_read32(bus, reg) | mask); + iwl_write32(trans, reg, iwl_read32(trans, reg) | mask); } -static inline void __iwl_clear_bit(struct iwl_bus *bus, u32 reg, u32 mask) +static inline void __iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask) { - iwl_write32(bus, reg, iwl_read32(bus, reg) & ~mask); + iwl_write32(trans, reg, iwl_read32(trans, reg) & ~mask); } -void iwl_set_bit(struct iwl_bus *bus, u32 reg, u32 mask) +void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask) { unsigned long flags; - spin_lock_irqsave(&bus->reg_lock, flags); - __iwl_set_bit(bus, reg, mask); - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_lock_irqsave(&trans->reg_lock, flags); + __iwl_set_bit(trans, reg, mask); + spin_unlock_irqrestore(&trans->reg_lock, flags); } -void iwl_clear_bit(struct iwl_bus *bus, u32 reg, u32 mask) +void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask) { unsigned long flags; - spin_lock_irqsave(&bus->reg_lock, flags); - __iwl_clear_bit(bus, reg, mask); - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_lock_irqsave(&trans->reg_lock, flags); + __iwl_clear_bit(trans, reg, mask); + spin_unlock_irqrestore(&trans->reg_lock, flags); } -int iwl_poll_bit(struct iwl_bus *bus, u32 addr, +int iwl_poll_bit(struct iwl_trans *trans, u32 addr, u32 bits, u32 mask, int timeout) { int t = 0; do { - if ((iwl_read32(bus, addr) & mask) == (bits & mask)) + if ((iwl_read32(trans, addr) & mask) == (bits & mask)) return t; udelay(IWL_POLL_INTERVAL); t += IWL_POLL_INTERVAL; @@ -77,14 +77,15 @@ int iwl_poll_bit(struct iwl_bus *bus, u32 addr, return -ETIMEDOUT; } -int iwl_grab_nic_access_silent(struct iwl_bus *bus) +int iwl_grab_nic_access_silent(struct iwl_trans *trans) { int ret; - lockdep_assert_held(&bus->reg_lock); + lockdep_assert_held(&trans->reg_lock); /* this bit wakes up the NIC */ - __iwl_set_bit(bus, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + __iwl_set_bit(trans, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); /* * These bits say the device is running, and should keep running for @@ -105,70 +106,70 @@ int iwl_grab_nic_access_silent(struct iwl_bus *bus) * 5000 series and later (including 1000 series) have non-volatile SRAM, * and do not save/restore SRAM when power cycling. */ - ret = iwl_poll_bit(bus, CSR_GP_CNTRL, + ret = iwl_poll_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); if (ret < 0) { - iwl_write32(bus, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI); + iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI); return -EIO; } return 0; } -int iwl_grab_nic_access(struct iwl_bus *bus) +int iwl_grab_nic_access(struct iwl_trans *trans) { - int ret = iwl_grab_nic_access_silent(bus); + int ret = iwl_grab_nic_access_silent(trans); if (ret) { - u32 val = iwl_read32(bus, CSR_GP_CNTRL); - IWL_ERR(bus, + u32 val = iwl_read32(trans, CSR_GP_CNTRL); + IWL_ERR(trans, "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val); } return ret; } -void iwl_release_nic_access(struct iwl_bus *bus) +void iwl_release_nic_access(struct iwl_trans *trans) { - lockdep_assert_held(&bus->reg_lock); - __iwl_clear_bit(bus, CSR_GP_CNTRL, + lockdep_assert_held(&trans->reg_lock); + __iwl_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); } -u32 iwl_read_direct32(struct iwl_bus *bus, u32 reg) +u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) { u32 value; unsigned long flags; - spin_lock_irqsave(&bus->reg_lock, flags); - iwl_grab_nic_access(bus); - value = iwl_read32(bus, reg); - iwl_release_nic_access(bus); - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_lock_irqsave(&trans->reg_lock, flags); + iwl_grab_nic_access(trans); + value = iwl_read32(trans, reg); + iwl_release_nic_access(trans); + spin_unlock_irqrestore(&trans->reg_lock, flags); return value; } -void iwl_write_direct32(struct iwl_bus *bus, u32 reg, u32 value) +void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) { unsigned long flags; - spin_lock_irqsave(&bus->reg_lock, flags); - if (!iwl_grab_nic_access(bus)) { - iwl_write32(bus, reg, value); - iwl_release_nic_access(bus); + spin_lock_irqsave(&trans->reg_lock, flags); + if (!iwl_grab_nic_access(trans)) { + iwl_write32(trans, reg, value); + iwl_release_nic_access(trans); } - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_unlock_irqrestore(&trans->reg_lock, flags); } -int iwl_poll_direct_bit(struct iwl_bus *bus, u32 addr, u32 mask, +int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, int timeout) { int t = 0; do { - if ((iwl_read_direct32(bus, addr) & mask) == mask) + if ((iwl_read_direct32(trans, addr) & mask) == mask) return t; udelay(IWL_POLL_INTERVAL); t += IWL_POLL_INTERVAL; @@ -177,135 +178,135 @@ int iwl_poll_direct_bit(struct iwl_bus *bus, u32 addr, u32 mask, return -ETIMEDOUT; } -static inline u32 __iwl_read_prph(struct iwl_bus *bus, u32 reg) +static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 reg) { - iwl_write32(bus, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); + iwl_write32(trans, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); rmb(); - return iwl_read32(bus, HBUS_TARG_PRPH_RDAT); + return iwl_read32(trans, HBUS_TARG_PRPH_RDAT); } -static inline void __iwl_write_prph(struct iwl_bus *bus, u32 addr, u32 val) +static inline void __iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val) { - iwl_write32(bus, HBUS_TARG_PRPH_WADDR, + iwl_write32(trans, HBUS_TARG_PRPH_WADDR, ((addr & 0x0000FFFF) | (3 << 24))); wmb(); - iwl_write32(bus, HBUS_TARG_PRPH_WDAT, val); + iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val); } -u32 iwl_read_prph(struct iwl_bus *bus, u32 reg) +u32 iwl_read_prph(struct iwl_trans *trans, u32 reg) { unsigned long flags; u32 val; - spin_lock_irqsave(&bus->reg_lock, flags); - iwl_grab_nic_access(bus); - val = __iwl_read_prph(bus, reg); - iwl_release_nic_access(bus); - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_lock_irqsave(&trans->reg_lock, flags); + iwl_grab_nic_access(trans); + val = __iwl_read_prph(trans, reg); + iwl_release_nic_access(trans); + spin_unlock_irqrestore(&trans->reg_lock, flags); return val; } -void iwl_write_prph(struct iwl_bus *bus, u32 addr, u32 val) +void iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val) { unsigned long flags; - spin_lock_irqsave(&bus->reg_lock, flags); - if (!iwl_grab_nic_access(bus)) { - __iwl_write_prph(bus, addr, val); - iwl_release_nic_access(bus); + spin_lock_irqsave(&trans->reg_lock, flags); + if (!iwl_grab_nic_access(trans)) { + __iwl_write_prph(trans, addr, val); + iwl_release_nic_access(trans); } - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_unlock_irqrestore(&trans->reg_lock, flags); } -void iwl_set_bits_prph(struct iwl_bus *bus, u32 reg, u32 mask) +void iwl_set_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) { unsigned long flags; - spin_lock_irqsave(&bus->reg_lock, flags); - iwl_grab_nic_access(bus); - __iwl_write_prph(bus, reg, __iwl_read_prph(bus, reg) | mask); - iwl_release_nic_access(bus); - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_lock_irqsave(&trans->reg_lock, flags); + iwl_grab_nic_access(trans); + __iwl_write_prph(trans, reg, __iwl_read_prph(trans, reg) | mask); + iwl_release_nic_access(trans); + spin_unlock_irqrestore(&trans->reg_lock, flags); } -void iwl_set_bits_mask_prph(struct iwl_bus *bus, u32 reg, +void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 reg, u32 bits, u32 mask) { unsigned long flags; - spin_lock_irqsave(&bus->reg_lock, flags); - iwl_grab_nic_access(bus); - __iwl_write_prph(bus, reg, - (__iwl_read_prph(bus, reg) & mask) | bits); - iwl_release_nic_access(bus); - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_lock_irqsave(&trans->reg_lock, flags); + iwl_grab_nic_access(trans); + __iwl_write_prph(trans, reg, + (__iwl_read_prph(trans, reg) & mask) | bits); + iwl_release_nic_access(trans); + spin_unlock_irqrestore(&trans->reg_lock, flags); } -void iwl_clear_bits_prph(struct iwl_bus *bus, u32 reg, u32 mask) +void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) { unsigned long flags; u32 val; - spin_lock_irqsave(&bus->reg_lock, flags); - iwl_grab_nic_access(bus); - val = __iwl_read_prph(bus, reg); - __iwl_write_prph(bus, reg, (val & ~mask)); - iwl_release_nic_access(bus); - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_lock_irqsave(&trans->reg_lock, flags); + iwl_grab_nic_access(trans); + val = __iwl_read_prph(trans, reg); + __iwl_write_prph(trans, reg, (val & ~mask)); + iwl_release_nic_access(trans); + spin_unlock_irqrestore(&trans->reg_lock, flags); } -void _iwl_read_targ_mem_words(struct iwl_bus *bus, u32 addr, +void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr, void *buf, int words) { unsigned long flags; int offs; u32 *vals = buf; - spin_lock_irqsave(&bus->reg_lock, flags); - iwl_grab_nic_access(bus); + spin_lock_irqsave(&trans->reg_lock, flags); + iwl_grab_nic_access(trans); - iwl_write32(bus, HBUS_TARG_MEM_RADDR, addr); + iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); rmb(); for (offs = 0; offs < words; offs++) - vals[offs] = iwl_read32(bus, HBUS_TARG_MEM_RDAT); + vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); - iwl_release_nic_access(bus); - spin_unlock_irqrestore(&bus->reg_lock, flags); + iwl_release_nic_access(trans); + spin_unlock_irqrestore(&trans->reg_lock, flags); } -u32 iwl_read_targ_mem(struct iwl_bus *bus, u32 addr) +u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr) { u32 value; - _iwl_read_targ_mem_words(bus, addr, &value, 1); + _iwl_read_targ_mem_words(trans, addr, &value, 1); return value; } -int _iwl_write_targ_mem_words(struct iwl_bus *bus, u32 addr, +int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr, void *buf, int words) { unsigned long flags; int offs, result = 0; u32 *vals = buf; - spin_lock_irqsave(&bus->reg_lock, flags); - if (!iwl_grab_nic_access(bus)) { - iwl_write32(bus, HBUS_TARG_MEM_WADDR, addr); + spin_lock_irqsave(&trans->reg_lock, flags); + if (!iwl_grab_nic_access(trans)) { + iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); wmb(); for (offs = 0; offs < words; offs++) - iwl_write32(bus, HBUS_TARG_MEM_WDAT, vals[offs]); - iwl_release_nic_access(bus); + iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]); + iwl_release_nic_access(trans); } else result = -EBUSY; - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_unlock_irqrestore(&trans->reg_lock, flags); return result; } -int iwl_write_targ_mem(struct iwl_bus *bus, u32 addr, u32 val) +int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val) { - return _iwl_write_targ_mem_words(bus, addr, &val, 1); + return _iwl_write_targ_mem_words(trans, addr, &val, 1); } diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index b8e00cd7b1f..782486fc2f8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h @@ -31,68 +31,63 @@ #include "iwl-devtrace.h" #include "iwl-shared.h" -/* TODO: remove when not needed any more */ -#include "iwl-bus.h" #include "iwl-trans.h" -static inline void iwl_write8(struct iwl_bus *bus, u32 ofs, u8 val) +static inline void iwl_write8(struct iwl_trans *trans, u32 ofs, u8 val) { - /* TODO: get trans instead of bus */ - trace_iwlwifi_dev_iowrite8(priv(bus), ofs, val); - iwl_trans_write8(trans(bus), ofs, val); + trace_iwlwifi_dev_iowrite8(priv(trans), ofs, val); + iwl_trans_write8(trans, ofs, val); } -static inline void iwl_write32(struct iwl_bus *bus, u32 ofs, u32 val) +static inline void iwl_write32(struct iwl_trans *trans, u32 ofs, u32 val) { - /* TODO: get trans instead of bus */ - trace_iwlwifi_dev_iowrite32(priv(bus), ofs, val); - iwl_trans_write32(trans(bus), ofs, val); + trace_iwlwifi_dev_iowrite32(priv(trans), ofs, val); + iwl_trans_write32(trans, ofs, val); } -static inline u32 iwl_read32(struct iwl_bus *bus, u32 ofs) +static inline u32 iwl_read32(struct iwl_trans *trans, u32 ofs) { - /* TODO: get trans instead of bus */ - u32 val = iwl_trans_read32(trans(bus), ofs); - trace_iwlwifi_dev_ioread32(priv(bus), ofs, val); + u32 val = iwl_trans_read32(trans, ofs); + trace_iwlwifi_dev_ioread32(priv(trans), ofs, val); return val; } -void iwl_set_bit(struct iwl_bus *bus, u32 reg, u32 mask); -void iwl_clear_bit(struct iwl_bus *bus, u32 reg, u32 mask); +void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask); +void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask); -int iwl_poll_bit(struct iwl_bus *bus, u32 addr, +int iwl_poll_bit(struct iwl_trans *trans, u32 addr, u32 bits, u32 mask, int timeout); -int iwl_poll_direct_bit(struct iwl_bus *bus, u32 addr, u32 mask, +int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, int timeout); -int iwl_grab_nic_access_silent(struct iwl_bus *bus); -int iwl_grab_nic_access(struct iwl_bus *bus); -void iwl_release_nic_access(struct iwl_bus *bus); +int iwl_grab_nic_access_silent(struct iwl_trans *trans); +int iwl_grab_nic_access(struct iwl_trans *trans); +void iwl_release_nic_access(struct iwl_trans *trans); -u32 iwl_read_direct32(struct iwl_bus *bus, u32 reg); -void iwl_write_direct32(struct iwl_bus *bus, u32 reg, u32 value); +u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg); +void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value); -u32 iwl_read_prph(struct iwl_bus *bus, u32 reg); -void iwl_write_prph(struct iwl_bus *bus, u32 addr, u32 val); -void iwl_set_bits_prph(struct iwl_bus *bus, u32 reg, u32 mask); -void iwl_set_bits_mask_prph(struct iwl_bus *bus, u32 reg, +u32 iwl_read_prph(struct iwl_trans *trans, u32 reg); +void iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val); +void iwl_set_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask); +void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 reg, u32 bits, u32 mask); -void iwl_clear_bits_prph(struct iwl_bus *bus, u32 reg, u32 mask); +void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask); -void _iwl_read_targ_mem_words(struct iwl_bus *bus, u32 addr, +void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr, void *buf, int words); -#define iwl_read_targ_mem_words(bus, addr, buf, bufsize) \ +#define iwl_read_targ_mem_words(trans, addr, buf, bufsize) \ do { \ BUILD_BUG_ON((bufsize) % sizeof(u32)); \ - _iwl_read_targ_mem_words(bus, addr, buf, \ + _iwl_read_targ_mem_words(trans, addr, buf, \ (bufsize) / sizeof(u32));\ } while (0) -int _iwl_write_targ_mem_words(struct iwl_bus *bus, u32 addr, +int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr, void *buf, int words); -u32 iwl_read_targ_mem(struct iwl_bus *bus, u32 addr); -int iwl_write_targ_mem(struct iwl_bus *bus, u32 addr, u32 val); +u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr); +int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val); #endif diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 8761438f153..5c7741f07aa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -71,7 +71,7 @@ static const struct ieee80211_tpt_blink iwl_blink[] = { /* Set led register off */ void iwlagn_led_enable(struct iwl_priv *priv) { - iwl_write32(bus(priv), CSR_LED_REG, CSR_LED_REG_TRUN_ON); + iwl_write32(trans(priv), CSR_LED_REG, CSR_LED_REG_TRUN_ON); } /* @@ -107,9 +107,10 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd) }; u32 reg; - reg = iwl_read32(bus(priv), CSR_LED_REG); + reg = iwl_read32(trans(priv), CSR_LED_REG); if (reg != (reg & CSR_LED_BSM_CTRL_MSK)) - iwl_write32(bus(priv), CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK); + iwl_write32(trans(priv), CSR_LED_REG, + reg & CSR_LED_BSM_CTRL_MSK); return iwl_trans_send_cmd(trans(priv), &cmd); } @@ -206,7 +207,7 @@ void iwl_leds_init(struct iwl_priv *priv) break; } - ret = led_classdev_register(bus(priv)->dev, &priv->led); + ret = led_classdev_register(trans(priv)->dev, &priv->led); if (ret) { kfree(priv->led.name); return; diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 965d0475aff..b911837b04f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -196,7 +196,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, WIPHY_FLAG_IBSS_RSN; if (trans(priv)->ucode_wowlan.code.len && - device_can_wakeup(bus(priv)->dev)) { + device_can_wakeup(trans(priv)->dev)) { hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_EAP_IDENTITY_REQ | @@ -347,7 +347,7 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw) /* User space software may expect getting rfkill changes * even if interface is down */ - iwl_write32(bus(priv), CSR_INT, 0xFFFFFFFF); + iwl_write32(trans(priv), CSR_INT, 0xFFFFFFFF); iwl_enable_rfkill_int(priv); IWL_DEBUG_MAC80211(priv, "leave\n"); @@ -405,10 +405,10 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw, if (ret) goto error; - device_set_wakeup_enable(bus(priv)->dev, true); + device_set_wakeup_enable(trans(priv)->dev, true); /* Now let the ucode operate on its own */ - iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_SET, + iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_SET, CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); goto out; @@ -436,19 +436,19 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) IWL_DEBUG_MAC80211(priv, "enter\n"); mutex_lock(&priv->shrd->mutex); - iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR, + iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); base = priv->shrd->device_pointers.error_event_table; if (iwlagn_hw_valid_rtc_data_addr(base)) { - spin_lock_irqsave(&bus(priv)->reg_lock, flags); - ret = iwl_grab_nic_access_silent(bus(priv)); + spin_lock_irqsave(&trans(priv)->reg_lock, flags); + ret = iwl_grab_nic_access_silent(trans(priv)); if (ret == 0) { - iwl_write32(bus(priv), HBUS_TARG_MEM_RADDR, base); - status = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); - iwl_release_nic_access(bus(priv)); + iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, base); + status = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); + iwl_release_nic_access(trans(priv)); } - spin_unlock_irqrestore(&bus(priv)->reg_lock, flags); + spin_unlock_irqrestore(&trans(priv)->reg_lock, flags); #ifdef CONFIG_IWLWIFI_DEBUGFS if (ret == 0) { @@ -460,7 +460,8 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) if (priv->wowlan_sram) _iwl_read_targ_mem_words( - bus(priv), 0x800000, priv->wowlan_sram, + trans(priv), 0x800000, + priv->wowlan_sram, trans->ucode_wowlan.data.len / 4); } #endif @@ -471,7 +472,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) priv->shrd->wowlan = false; - device_set_wakeup_enable(bus(priv)->dev, false); + device_set_wakeup_enable(trans(priv)->dev, false); iwlagn_prepare_restart(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index ab462337d7a..7bab8192848 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -121,12 +121,12 @@ static void iwl_pci_apm_config(struct iwl_bus *bus) if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN) { /* L1-ASPM enabled; disable(!) L0S */ - iwl_set_bit(bus, CSR_GIO_REG, + iwl_set_bit(trans(bus), CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); dev_printk(KERN_INFO, bus->dev, "L1 Enabled; Disabling L0S\n"); } else { /* L1-ASPM disabled; enable(!) L0S */ - iwl_clear_bit(bus, CSR_GIO_REG, + iwl_clear_bit(trans(bus), CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); dev_printk(KERN_INFO, bus->dev, "L1 Disabled; Enabling L0S\n"); } diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index a56a77b8f92..922d841faba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -208,7 +208,7 @@ static void iwl_trace_cleanup(struct iwl_priv *priv) if (priv->testmode_trace.trace_enabled) { if (priv->testmode_trace.cpu_addr && priv->testmode_trace.dma_addr) - dma_free_coherent(bus(priv)->dev, + dma_free_coherent(trans(priv)->dev, priv->testmode_trace.total_size, priv->testmode_trace.cpu_addr, priv->testmode_trace.dma_addr); @@ -302,7 +302,7 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb) switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32: - val32 = iwl_read_direct32(bus(priv), ofs); + val32 = iwl_read_direct32(trans(priv), ofs); IWL_INFO(priv, "32bit value to read 0x%x\n", val32); skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); @@ -324,7 +324,7 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb) } else { val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]); IWL_INFO(priv, "32bit value to write 0x%x\n", val32); - iwl_write_direct32(bus(priv), ofs, val32); + iwl_write_direct32(trans(priv), ofs, val32); } break; case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8: @@ -334,11 +334,11 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb) } else { val8 = nla_get_u8(tb[IWL_TM_ATTR_REG_VALUE8]); IWL_INFO(priv, "8bit value to write 0x%x\n", val8); - iwl_write8(bus(priv), ofs, val8); + iwl_write8(trans(priv), ofs, val8); } break; case IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32: - val32 = iwl_read_prph(bus(priv), ofs); + val32 = iwl_read_prph(trans(priv), ofs); IWL_INFO(priv, "32bit value to read 0x%x\n", val32); skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); @@ -360,7 +360,7 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb) } else { val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]); IWL_INFO(priv, "32bit value to write 0x%x\n", val32); - iwl_write_prph(bus(priv), ofs, val32); + iwl_write_prph(trans(priv), ofs, val32); } break; default: @@ -615,7 +615,7 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb) struct iwl_priv *priv = hw->priv; struct sk_buff *skb; int status = 0; - struct device *dev = bus(priv)->dev; + struct device *dev = trans(priv)->dev; switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { case IWL_TM_CMD_APP2DEV_BEGIN_TRACE: @@ -814,7 +814,7 @@ static int iwl_testmode_sram(struct ieee80211_hw *hw, struct nlattr **tb) IWL_ERR(priv, "Error allocating memory\n"); return -ENOMEM; } - _iwl_read_targ_mem_words(bus(priv), ofs, + _iwl_read_targ_mem_words(trans(priv), ofs, priv->testmode_sram.buff_addr, priv->testmode_sram.buff_size / 4); priv->testmode_sram.num_chunks = diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 47d27bdf2df..555175ff4f9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -317,12 +317,12 @@ static inline void iwl_disable_interrupts(struct iwl_trans *trans) clear_bit(STATUS_INT_ENABLED, &trans->shrd->status); /* disable interrupts from uCode/NIC to host */ - iwl_write32(bus(trans), CSR_INT_MASK, 0x00000000); + iwl_write32(trans, CSR_INT_MASK, 0x00000000); /* acknowledge/clear/reset any interrupts still pending * from uCode or flow handler (Rx/Tx DMA) */ - iwl_write32(bus(trans), CSR_INT, 0xffffffff); - iwl_write32(bus(trans), CSR_FH_INT_STATUS, 0xffffffff); + iwl_write32(trans, CSR_INT, 0xffffffff); + iwl_write32(trans, CSR_FH_INT_STATUS, 0xffffffff); IWL_DEBUG_ISR(trans, "Disabled interrupts\n"); } @@ -333,7 +333,7 @@ static inline void iwl_enable_interrupts(struct iwl_trans *trans) IWL_DEBUG_ISR(trans, "Enabling interrupts\n"); set_bit(STATUS_INT_ENABLED, &trans->shrd->status); - iwl_write32(bus(trans), CSR_INT_MASK, trans_pcie->inta_mask); + iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask); } /* diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index b94c95370b7..ebea2435dac 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -144,30 +144,30 @@ void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans, /* shadow register enabled */ /* Device expects a multiple of 8 */ q->write_actual = (q->write & ~0x7); - iwl_write32(bus(trans), FH_RSCSR_CHNL0_WPTR, q->write_actual); + iwl_write32(trans, FH_RSCSR_CHNL0_WPTR, q->write_actual); } else { /* If power-saving is in use, make sure device is awake */ if (test_bit(STATUS_POWER_PMI, &trans->shrd->status)) { - reg = iwl_read32(bus(trans), CSR_UCODE_DRV_GP1); + reg = iwl_read32(trans, CSR_UCODE_DRV_GP1); if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { IWL_DEBUG_INFO(trans, "Rx queue requesting wakeup," " GP1 = 0x%x\n", reg); - iwl_set_bit(bus(trans), CSR_GP_CNTRL, + iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); goto exit_unlock; } q->write_actual = (q->write & ~0x7); - iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_WPTR, + iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR, q->write_actual); /* Else device is assumed to be awake */ } else { /* Device expects a multiple of 8 */ q->write_actual = (q->write & ~0x7); - iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_WPTR, + iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR, q->write_actual); } } @@ -312,7 +312,7 @@ static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority) BUG_ON(rxb->page); rxb->page = page; /* Get physical address of the RB */ - rxb->page_dma = dma_map_page(bus(trans)->dev, page, 0, + rxb->page_dma = dma_map_page(trans->dev, page, 0, PAGE_SIZE << hw_params(trans).rx_page_order, DMA_FROM_DEVICE); /* dma address must be no more than 36 bits */ @@ -418,7 +418,7 @@ static void iwl_rx_handle(struct iwl_trans *trans) rxq->queue[i] = NULL; - dma_unmap_page(bus(trans)->dev, rxb->page_dma, + dma_unmap_page(trans->dev, rxb->page_dma, PAGE_SIZE << hw_params(trans).rx_page_order, DMA_FROM_DEVICE); pkt = rxb_addr(rxb); @@ -489,7 +489,7 @@ static void iwl_rx_handle(struct iwl_trans *trans) * rx_free list for reuse later. */ spin_lock_irqsave(&rxq->lock, flags); if (rxb->page != NULL) { - rxb->page_dma = dma_map_page(bus(trans)->dev, rxb->page, + rxb->page_dma = dma_map_page(trans->dev, rxb->page, 0, PAGE_SIZE << hw_params(trans).rx_page_order, DMA_FROM_DEVICE); @@ -616,7 +616,7 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans) return; } - iwl_read_targ_mem_words(bus(priv), base, &table, sizeof(table)); + iwl_read_targ_mem_words(trans(priv), base, &table, sizeof(table)); if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) { IWL_ERR(trans, "Start IWL Error Log Dump:\n"); @@ -677,9 +677,9 @@ static void iwl_irq_handle_error(struct iwl_trans *trans) struct iwl_priv *priv = priv(trans); /* W/A for WiFi/WiMAX coex and WiMAX own the RF */ if (cfg(priv)->internal_wimax_coex && - (!(iwl_read_prph(bus(trans), APMG_CLK_CTRL_REG) & + (!(iwl_read_prph(trans, APMG_CLK_CTRL_REG) & APMS_CLK_VAL_MRB_FUNC_MODE) || - (iwl_read_prph(bus(trans), APMG_PS_CTRL_REG) & + (iwl_read_prph(trans, APMG_PS_CTRL_REG) & APMG_PS_CTRL_VAL_RESET_REQ))) { /* * Keep the restart process from trying to send host @@ -745,18 +745,18 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, ptr = base + EVENT_START_OFFSET + (start_idx * event_size); /* Make sure device is powered up for SRAM reads */ - spin_lock_irqsave(&bus(trans)->reg_lock, reg_flags); - iwl_grab_nic_access(bus(trans)); + spin_lock_irqsave(&trans->reg_lock, reg_flags); + iwl_grab_nic_access(trans); /* Set starting address; reads will auto-increment */ - iwl_write32(bus(trans), HBUS_TARG_MEM_RADDR, ptr); + iwl_write32(trans, HBUS_TARG_MEM_RADDR, ptr); rmb(); /* "time" is actually "data" for mode 0 (no timestamp). * place event id # at far right for easier visual parsing. */ for (i = 0; i < num_events; i++) { - ev = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT); - time = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT); + ev = iwl_read32(trans, HBUS_TARG_MEM_RDAT); + time = iwl_read32(trans, HBUS_TARG_MEM_RDAT); if (mode == 0) { /* data, ev */ if (bufsz) { @@ -770,7 +770,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, time, ev); } } else { - data = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT); + data = iwl_read32(trans, HBUS_TARG_MEM_RDAT); if (bufsz) { pos += scnprintf(*buf + pos, bufsz - pos, "EVT_LOGT:%010u:0x%08x:%04u\n", @@ -785,8 +785,8 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, } /* Allow device to power down */ - iwl_release_nic_access(bus(trans)); - spin_unlock_irqrestore(&bus(trans)->reg_lock, reg_flags); + iwl_release_nic_access(trans); + spin_unlock_irqrestore(&trans->reg_lock, reg_flags); return pos; } @@ -863,10 +863,10 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log, } /* event log header */ - capacity = iwl_read_targ_mem(bus(trans), base); - mode = iwl_read_targ_mem(bus(trans), base + (1 * sizeof(u32))); - num_wraps = iwl_read_targ_mem(bus(trans), base + (2 * sizeof(u32))); - next_entry = iwl_read_targ_mem(bus(trans), base + (3 * sizeof(u32))); + capacity = iwl_read_targ_mem(trans, base); + mode = iwl_read_targ_mem(trans, base + (1 * sizeof(u32))); + num_wraps = iwl_read_targ_mem(trans, base + (2 * sizeof(u32))); + next_entry = iwl_read_targ_mem(trans, base + (3 * sizeof(u32))); if (capacity > logsize) { IWL_ERR(trans, "Log capacity %d is bogus, limit to %d " @@ -962,7 +962,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) * hardware bugs here by ACKing all the possible interrupts so that * interrupt coalescing can still be achieved. */ - iwl_write32(bus(trans), CSR_INT, + iwl_write32(trans, CSR_INT, trans_pcie->inta | ~trans_pcie->inta_mask); inta = trans_pcie->inta; @@ -970,7 +970,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) #ifdef CONFIG_IWLWIFI_DEBUG if (iwl_get_debug_level(trans->shrd) & IWL_DL_ISR) { /* just for debug */ - inta_mask = iwl_read32(bus(trans), CSR_INT_MASK); + inta_mask = iwl_read32(trans, CSR_INT_MASK); IWL_DEBUG_ISR(trans, "inta 0x%08x, enabled 0x%08x\n ", inta, inta_mask); } @@ -1018,7 +1018,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) /* HW RF KILL switch toggled */ if (inta & CSR_INT_BIT_RF_KILL) { int hw_rf_kill = 0; - if (!(iwl_read32(bus(trans), CSR_GP_CNTRL) & + if (!(iwl_read32(trans, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) hw_rf_kill = 1; @@ -1082,12 +1082,12 @@ void iwl_irq_tasklet(struct iwl_trans *trans) IWL_DEBUG_ISR(trans, "Rx interrupt\n"); if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); - iwl_write32(bus(trans), CSR_FH_INT_STATUS, + iwl_write32(trans, CSR_FH_INT_STATUS, CSR_FH_INT_RX_MASK); } if (inta & CSR_INT_BIT_RX_PERIODIC) { handled |= CSR_INT_BIT_RX_PERIODIC; - iwl_write32(bus(trans), + iwl_write32(trans, CSR_INT, CSR_INT_BIT_RX_PERIODIC); } /* Sending RX interrupt require many steps to be done in the @@ -1102,7 +1102,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) */ /* Disable periodic interrupt; we use it as just a one-shot. */ - iwl_write8(bus(trans), CSR_INT_PERIODIC_REG, + iwl_write8(trans, CSR_INT_PERIODIC_REG, CSR_INT_PERIODIC_DIS); #ifdef CONFIG_IWLWIFI_IDI iwl_amfh_rx_handler(); @@ -1117,7 +1117,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) * to extend the periodic interrupt; one-shot is enough. */ if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) - iwl_write8(bus(trans), CSR_INT_PERIODIC_REG, + iwl_write8(trans, CSR_INT_PERIODIC_REG, CSR_INT_PERIODIC_ENA); isr_stats->rx++; @@ -1125,7 +1125,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) /* This "Tx" DMA channel is used only for loading uCode */ if (inta & CSR_INT_BIT_FH_TX) { - iwl_write32(bus(trans), CSR_FH_INT_STATUS, CSR_FH_INT_TX_MASK); + iwl_write32(trans, CSR_FH_INT_STATUS, CSR_FH_INT_TX_MASK); IWL_DEBUG_ISR(trans, "uCode load interrupt\n"); isr_stats->tx++; handled |= CSR_INT_BIT_FH_TX; @@ -1175,7 +1175,7 @@ void iwl_free_isr_ict(struct iwl_trans *trans) IWL_TRANS_GET_PCIE_TRANS(trans); if (trans_pcie->ict_tbl) { - dma_free_coherent(bus(trans)->dev, ICT_SIZE, + dma_free_coherent(trans->dev, ICT_SIZE, trans_pcie->ict_tbl, trans_pcie->ict_tbl_dma); trans_pcie->ict_tbl = NULL; @@ -1195,7 +1195,7 @@ int iwl_alloc_isr_ict(struct iwl_trans *trans) IWL_TRANS_GET_PCIE_TRANS(trans); trans_pcie->ict_tbl = - dma_alloc_coherent(bus(trans)->dev, ICT_SIZE, + dma_alloc_coherent(trans->dev, ICT_SIZE, &trans_pcie->ict_tbl_dma, GFP_KERNEL); if (!trans_pcie->ict_tbl) @@ -1246,10 +1246,10 @@ void iwl_reset_ict(struct iwl_trans *trans) IWL_DEBUG_ISR(trans, "CSR_DRAM_INT_TBL_REG =0x%x\n", val); - iwl_write32(bus(trans), CSR_DRAM_INT_TBL_REG, val); + iwl_write32(trans, CSR_DRAM_INT_TBL_REG, val); trans_pcie->use_ict = true; trans_pcie->ict_index = 0; - iwl_write32(bus(trans), CSR_INT, trans_pcie->inta_mask); + iwl_write32(trans, CSR_INT, trans_pcie->inta_mask); iwl_enable_interrupts(trans); spin_unlock_irqrestore(&trans->shrd->lock, flags); } @@ -1289,11 +1289,11 @@ static irqreturn_t iwl_isr(int irq, void *data) * back-to-back ISRs and sporadic interrupts from our NIC. * If we have something to service, the tasklet will re-enable ints. * If we *don't* have something, we'll re-enable before leaving here. */ - inta_mask = iwl_read32(bus(trans), CSR_INT_MASK); /* just for debug */ - iwl_write32(bus(trans), CSR_INT_MASK, 0x00000000); + inta_mask = iwl_read32(trans, CSR_INT_MASK); /* just for debug */ + iwl_write32(trans, CSR_INT_MASK, 0x00000000); /* Discover which interrupts are active/pending */ - inta = iwl_read32(bus(trans), CSR_INT); + inta = iwl_read32(trans, CSR_INT); /* Ignore interrupt if there's nothing in NIC to service. * This may be due to IRQ shared with another device, @@ -1312,7 +1312,7 @@ static irqreturn_t iwl_isr(int irq, void *data) #ifdef CONFIG_IWLWIFI_DEBUG if (iwl_get_debug_level(trans->shrd) & (IWL_DL_ISR)) { - inta_fh = iwl_read32(bus(trans), CSR_FH_INT_STATUS); + inta_fh = iwl_read32(trans, CSR_FH_INT_STATUS); IWL_DEBUG_ISR(trans, "ISR inta 0x%08x, enabled 0x%08x, " "fh 0x%08x\n", inta, inta_mask, inta_fh); } @@ -1378,8 +1378,8 @@ irqreturn_t iwl_isr_ict(int irq, void *data) * If we have something to service, the tasklet will re-enable ints. * If we *don't* have something, we'll re-enable before leaving here. */ - inta_mask = iwl_read32(bus(trans), CSR_INT_MASK); /* just for debug */ - iwl_write32(bus(trans), CSR_INT_MASK, 0x00000000); + inta_mask = iwl_read32(trans, CSR_INT_MASK); /* just for debug */ + iwl_write32(trans, CSR_INT_MASK, 0x00000000); /* Ignore interrupt if there's nothing in NIC to service. diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 30814b55705..5e095ac5076 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -100,7 +100,7 @@ void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq) if (hw_params(trans).shadow_reg_enable) { /* shadow register enabled */ - iwl_write32(bus(trans), HBUS_TARG_WRPTR, + iwl_write32(trans, HBUS_TARG_WRPTR, txq->q.write_ptr | (txq_id << 8)); } else { /* if we're trying to save power */ @@ -108,18 +108,18 @@ void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq) /* wake up nic if it's powered down ... * uCode will wake up, and interrupt us again, so next * time we'll skip this part. */ - reg = iwl_read32(bus(trans), CSR_UCODE_DRV_GP1); + reg = iwl_read32(trans, CSR_UCODE_DRV_GP1); if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { IWL_DEBUG_INFO(trans, "Tx queue %d requesting wakeup," " GP1 = 0x%x\n", txq_id, reg); - iwl_set_bit(bus(trans), CSR_GP_CNTRL, + iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); return; } - iwl_write_direct32(bus(trans), HBUS_TARG_WRPTR, + iwl_write_direct32(trans, HBUS_TARG_WRPTR, txq->q.write_ptr | (txq_id << 8)); /* @@ -128,7 +128,7 @@ void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq) * trying to tx (during RFKILL, we're not trying to tx). */ } else - iwl_write32(bus(trans), HBUS_TARG_WRPTR, + iwl_write32(trans, HBUS_TARG_WRPTR, txq->q.write_ptr | (txq_id << 8)); } txq->need_update = 0; @@ -190,14 +190,14 @@ static void iwlagn_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta, /* Unmap tx_cmd */ if (num_tbs) - dma_unmap_single(bus(trans)->dev, + dma_unmap_single(trans->dev, dma_unmap_addr(meta, mapping), dma_unmap_len(meta, len), DMA_BIDIRECTIONAL); /* Unmap chunks, if any. */ for (i = 1; i < num_tbs; i++) - dma_unmap_single(bus(trans)->dev, iwl_tfd_tb_get_addr(tfd, i), + dma_unmap_single(trans->dev, iwl_tfd_tb_get_addr(tfd, i), iwl_tfd_tb_get_len(tfd, i), dma_dir); } @@ -383,14 +383,14 @@ static int iwlagn_tx_queue_set_q2ratid(struct iwl_trans *trans, u16 ra_tid, tbl_dw_addr = trans_pcie->scd_base_addr + SCD_TRANS_TBL_OFFSET_QUEUE(txq_id); - tbl_dw = iwl_read_targ_mem(bus(trans), tbl_dw_addr); + tbl_dw = iwl_read_targ_mem(trans, tbl_dw_addr); if (txq_id & 0x1) tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF); else tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000); - iwl_write_targ_mem(bus(trans), tbl_dw_addr, tbl_dw); + iwl_write_targ_mem(trans, tbl_dw_addr, tbl_dw); return 0; } @@ -399,7 +399,7 @@ static void iwlagn_tx_queue_stop_scheduler(struct iwl_trans *trans, u16 txq_id) { /* Simply stop the queue, but don't change any configuration; * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ - iwl_write_prph(bus(trans), + iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id), (0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)| (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); @@ -409,9 +409,9 @@ void iwl_trans_set_wr_ptrs(struct iwl_trans *trans, int txq_id, u32 index) { IWL_DEBUG_TX_QUEUES(trans, "Q %d WrPtr: %d", txq_id, index & 0xff); - iwl_write_direct32(bus(trans), HBUS_TARG_WRPTR, + iwl_write_direct32(trans, HBUS_TARG_WRPTR, (index & 0xff) | (txq_id << 8)); - iwl_write_prph(bus(trans), SCD_QUEUE_RDPTR(txq_id), index); + iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), index); } void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, @@ -423,7 +423,7 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, int active = test_bit(txq_id, &trans_pcie->txq_ctx_active_msk) ? 1 : 0; - iwl_write_prph(bus(trans), SCD_QUEUE_STATUS_BITS(txq_id), + iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id), (active << SCD_QUEUE_STTS_REG_POS_ACTIVE) | (tx_fifo_id << SCD_QUEUE_STTS_REG_POS_TXF) | (1 << SCD_QUEUE_STTS_REG_POS_WSL) | @@ -498,10 +498,10 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, iwlagn_tx_queue_set_q2ratid(trans, ra_tid, txq_id); /* Set this queue as a chain-building queue */ - iwl_set_bits_prph(bus(trans), SCD_QUEUECHAIN_SEL, (1<scd_base_addr + + iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), ((frame_limit << @@ -520,7 +520,7 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); - iwl_set_bits_prph(bus(trans), SCD_INTERRUPT_MASK, (1 << txq_id)); + iwl_set_bits_prph(trans, SCD_INTERRUPT_MASK, (1 << txq_id)); /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], @@ -584,7 +584,7 @@ int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int sta_id, int tid) iwlagn_tx_queue_stop_scheduler(trans, txq_id); - iwl_clear_bits_prph(bus(trans), SCD_AGGR_SEL, (1 << txq_id)); + iwl_clear_bits_prph(trans, SCD_AGGR_SEL, (1 << txq_id)); trans_pcie->agg_txq[sta_id][tid] = 0; trans_pcie->txq[txq_id].q.read_ptr = 0; @@ -592,7 +592,7 @@ int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int sta_id, int tid) /* supposes that ssn_idx is valid (!= 0xFFF) */ iwl_trans_set_wr_ptrs(trans, txq_id, 0); - iwl_clear_bits_prph(bus(trans), SCD_INTERRUPT_MASK, (1 << txq_id)); + iwl_clear_bits_prph(trans, SCD_INTERRUPT_MASK, (1 << txq_id)); iwl_txq_ctx_deactivate(trans_pcie, txq_id); iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], 0, 0); return 0; @@ -725,9 +725,9 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) le16_to_cpu(out_cmd->hdr.sequence), cmd_size, q->write_ptr, idx, trans->shrd->cmd_queue); - phys_addr = dma_map_single(bus(trans)->dev, &out_cmd->hdr, copy_size, + phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size, DMA_BIDIRECTIONAL); - if (unlikely(dma_mapping_error(bus(trans)->dev, phys_addr))) { + if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { idx = -ENOMEM; goto out; } @@ -748,10 +748,10 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) continue; if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) continue; - phys_addr = dma_map_single(bus(trans)->dev, + phys_addr = dma_map_single(trans->dev, (void *)cmd->data[i], cmd->len[i], DMA_BIDIRECTIONAL); - if (dma_mapping_error(bus(trans)->dev, phys_addr)) { + if (dma_mapping_error(trans->dev, phys_addr)) { iwlagn_unmap_tfd(trans, out_meta, &txq->tfds[q->write_ptr], DMA_BIDIRECTIONAL); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 80f531844f3..a1ee2e4b0ce 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -80,7 +80,7 @@ static int iwl_trans_rx_alloc(struct iwl_trans *trans) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_rx_queue *rxq = &trans_pcie->rxq; - struct device *dev = bus(trans)->dev; + struct device *dev = trans->dev; memset(&trans_pcie->rxq, 0, sizeof(trans_pcie->rxq)); @@ -124,7 +124,7 @@ static void iwl_trans_rxq_free_rx_bufs(struct iwl_trans *trans) /* In the reset function, these buffers may have been allocated * to an SKB, so we need to unmap and free potential storage */ if (rxq->pool[i].page != NULL) { - dma_unmap_page(bus(trans)->dev, rxq->pool[i].page_dma, + dma_unmap_page(trans->dev, rxq->pool[i].page_dma, PAGE_SIZE << hw_params(trans).rx_page_order, DMA_FROM_DEVICE); __free_pages(rxq->pool[i].page, @@ -148,17 +148,17 @@ static void iwl_trans_rx_hw_init(struct iwl_trans *trans, rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; /* Stop Rx DMA */ - iwl_write_direct32(bus(trans), FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); + iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); /* Reset driver's Rx queue write index */ - iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); + iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); /* Tell device where to find RBD circular buffer in DRAM */ - iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_RBDCB_BASE_REG, + iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_BASE_REG, (u32)(rxq->bd_dma >> 8)); /* Tell device where in DRAM to update its Rx status */ - iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_STTS_WPTR_REG, + iwl_write_direct32(trans, FH_RSCSR_CHNL0_STTS_WPTR_REG, rxq->rb_stts_dma >> 4); /* Enable Rx DMA @@ -169,7 +169,7 @@ static void iwl_trans_rx_hw_init(struct iwl_trans *trans, * RB timeout 0x10 * 256 RBDs */ - iwl_write_direct32(bus(trans), FH_MEM_RCSR_CHNL0_CONFIG_REG, + iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY | FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | @@ -179,7 +179,7 @@ static void iwl_trans_rx_hw_init(struct iwl_trans *trans, (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS)); /* Set interrupt coalescing timer to default (2048 usecs) */ - iwl_write8(bus(trans), CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); + iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); } static int iwl_rx_init(struct iwl_trans *trans) @@ -244,13 +244,13 @@ static void iwl_trans_pcie_rx_free(struct iwl_trans *trans) iwl_trans_rxq_free_rx_bufs(trans); spin_unlock_irqrestore(&rxq->lock, flags); - dma_free_coherent(bus(trans)->dev, sizeof(__le32) * RX_QUEUE_SIZE, + dma_free_coherent(trans->dev, sizeof(__le32) * RX_QUEUE_SIZE, rxq->bd, rxq->bd_dma); memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma)); rxq->bd = NULL; if (rxq->rb_stts) - dma_free_coherent(bus(trans)->dev, + dma_free_coherent(trans->dev, sizeof(struct iwl_rb_status), rxq->rb_stts, rxq->rb_stts_dma); else @@ -263,8 +263,8 @@ static int iwl_trans_rx_stop(struct iwl_trans *trans) { /* stop Rx DMA */ - iwl_write_direct32(bus(trans), FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); - return iwl_poll_direct_bit(bus(trans), FH_MEM_RSSR_RX_STATUS_REG, + iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); + return iwl_poll_direct_bit(trans, FH_MEM_RSSR_RX_STATUS_REG, FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); } @@ -274,7 +274,7 @@ static inline int iwlagn_alloc_dma_ptr(struct iwl_trans *trans, if (WARN_ON(ptr->addr)) return -EINVAL; - ptr->addr = dma_alloc_coherent(bus(trans)->dev, size, + ptr->addr = dma_alloc_coherent(trans->dev, size, &ptr->dma, GFP_KERNEL); if (!ptr->addr) return -ENOMEM; @@ -288,7 +288,7 @@ static inline void iwlagn_free_dma_ptr(struct iwl_trans *trans, if (unlikely(!ptr->addr)) return; - dma_free_coherent(bus(trans)->dev, ptr->size, ptr->addr, ptr->dma); + dma_free_coherent(trans->dev, ptr->size, ptr->addr, ptr->dma); memset(ptr, 0, sizeof(*ptr)); } @@ -335,7 +335,7 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans, /* Circular buffer of transmit frame descriptors (TFDs), * shared with device */ - txq->tfds = dma_alloc_coherent(bus(trans)->dev, tfd_sz, + txq->tfds = dma_alloc_coherent(trans->dev, tfd_sz, &txq->q.dma_addr, GFP_KERNEL); if (!txq->tfds) { IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz); @@ -391,7 +391,7 @@ static int iwl_trans_txq_init(struct iwl_trans *trans, struct iwl_tx_queue *txq, * Tell nic where to find circular buffer of Tx Frame Descriptors for * given Tx queue, and enable the DMA channel used for that queue. * Circular buffer (TFD queue in DRAM) physical base address */ - iwl_write_direct32(bus(trans), FH_MEM_CBBC_QUEUE(txq_id), + iwl_write_direct32(trans, FH_MEM_CBBC_QUEUE(txq_id), txq->q.dma_addr >> 8); return 0; @@ -445,7 +445,7 @@ static void iwl_tx_queue_free(struct iwl_trans *trans, int txq_id) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; - struct device *dev = bus(trans)->dev; + struct device *dev = trans->dev; int i; if (WARN_ON(!txq)) return; @@ -586,10 +586,10 @@ static int iwl_tx_init(struct iwl_trans *trans) spin_lock_irqsave(&trans->shrd->lock, flags); /* Turn off all Tx DMA fifos */ - iwl_write_prph(bus(trans), SCD_TXFACT, 0); + iwl_write_prph(trans, SCD_TXFACT, 0); /* Tell NIC where to find the "keep warm" buffer */ - iwl_write_direct32(bus(trans), FH_KW_MEM_ADDR_REG, + iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG, trans_pcie->kw.dma >> 4); spin_unlock_irqrestore(&trans->shrd->lock, flags); @@ -621,12 +621,12 @@ static void iwl_set_pwr_vmain(struct iwl_trans *trans) * to set power to V_AUX, do: if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) - iwl_set_bits_mask_prph(bus(trans), APMG_PS_CTRL_REG, + iwl_set_bits_mask_prph(trans, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_PWR_SRC_VAUX, ~APMG_PS_CTRL_MSK_PWR_SRC); */ - iwl_set_bits_mask_prph(bus(trans), APMG_PS_CTRL_REG, + iwl_set_bits_mask_prph(trans, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, ~APMG_PS_CTRL_MSK_PWR_SRC); } @@ -640,7 +640,7 @@ static int iwl_nic_init(struct iwl_trans *trans) iwl_apm_init(priv(trans)); /* Set interrupt coalescing calibration timer to default (512 usecs) */ - iwl_write8(bus(trans), CSR_INT_COALESCING, + iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF); spin_unlock_irqrestore(&trans->shrd->lock, flags); @@ -660,7 +660,7 @@ static int iwl_nic_init(struct iwl_trans *trans) if (hw_params(trans).shadow_reg_enable) { /* enable shadow regs in HW */ - iwl_set_bit(bus(trans), CSR_MAC_SHADOW_REG_CTRL, + iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL, 0x800FFFFF); } @@ -676,11 +676,11 @@ static int iwl_set_hw_ready(struct iwl_trans *trans) { int ret; - iwl_set_bit(bus(trans), CSR_HW_IF_CONFIG_REG, + iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_NIC_READY); /* See if we got it */ - ret = iwl_poll_bit(bus(trans), CSR_HW_IF_CONFIG_REG, + ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, HW_READY_TIMEOUT); @@ -701,10 +701,10 @@ static int iwl_trans_pcie_prepare_card_hw(struct iwl_trans *trans) return 0; /* If HW is not ready, prepare the conditions to check again */ - iwl_set_bit(bus(trans), CSR_HW_IF_CONFIG_REG, + iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_PREPARE); - ret = iwl_poll_bit(bus(trans), CSR_HW_IF_CONFIG_REG, + ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG, ~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000); @@ -794,7 +794,7 @@ static int iwl_trans_pcie_start_device(struct iwl_trans *trans) } /* If platform's RF_KILL switch is NOT set to KILL */ - if (iwl_read32(bus(trans), CSR_GP_CNTRL) & + if (iwl_read32(trans, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status); else @@ -806,7 +806,7 @@ static int iwl_trans_pcie_start_device(struct iwl_trans *trans) return -ERFKILL; } - iwl_write32(bus(trans), CSR_INT, 0xFFFFFFFF); + iwl_write32(trans, CSR_INT, 0xFFFFFFFF); ret = iwl_nic_init(trans); if (ret) { @@ -815,17 +815,17 @@ static int iwl_trans_pcie_start_device(struct iwl_trans *trans) } /* make sure rfkill handshake bits are cleared */ - iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); - iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR, + iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); /* clear (again), then enable host interrupts */ - iwl_write32(bus(trans), CSR_INT, 0xFFFFFFFF); + iwl_write32(trans, CSR_INT, 0xFFFFFFFF); iwl_enable_interrupts(trans); /* really make sure rfkill handshake bits are cleared */ - iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); - iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); return 0; } @@ -836,7 +836,7 @@ static int iwl_trans_pcie_start_device(struct iwl_trans *trans) */ static void iwl_trans_txq_set_sched(struct iwl_trans *trans, u32 mask) { - iwl_write_prph(bus(trans), SCD_TXFACT, mask); + iwl_write_prph(trans, SCD_TXFACT, mask); } static void iwl_tx_start(struct iwl_trans *trans) @@ -852,46 +852,46 @@ static void iwl_tx_start(struct iwl_trans *trans) spin_lock_irqsave(&trans->shrd->lock, flags); trans_pcie->scd_base_addr = - iwl_read_prph(bus(trans), SCD_SRAM_BASE_ADDR); + iwl_read_prph(trans, SCD_SRAM_BASE_ADDR); a = trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_LOWER_BOUND; /* reset conext data memory */ for (; a < trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_UPPER_BOUND; a += 4) - iwl_write_targ_mem(bus(trans), a, 0); + iwl_write_targ_mem(trans, a, 0); /* reset tx status memory */ for (; a < trans_pcie->scd_base_addr + SCD_TX_STTS_MEM_UPPER_BOUND; a += 4) - iwl_write_targ_mem(bus(trans), a, 0); + iwl_write_targ_mem(trans, a, 0); for (; a < trans_pcie->scd_base_addr + SCD_TRANS_TBL_OFFSET_QUEUE(hw_params(trans).max_txq_num); a += 4) - iwl_write_targ_mem(bus(trans), a, 0); + iwl_write_targ_mem(trans, a, 0); - iwl_write_prph(bus(trans), SCD_DRAM_BASE_ADDR, + iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, trans_pcie->scd_bc_tbls.dma >> 10); /* Enable DMA channel */ for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++) - iwl_write_direct32(bus(trans), FH_TCSR_CHNL_TX_CONFIG_REG(chan), + iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(chan), FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE); /* Update FH chicken bits */ - reg_val = iwl_read_direct32(bus(trans), FH_TX_CHICKEN_BITS_REG); - iwl_write_direct32(bus(trans), FH_TX_CHICKEN_BITS_REG, + reg_val = iwl_read_direct32(trans, FH_TX_CHICKEN_BITS_REG); + iwl_write_direct32(trans, FH_TX_CHICKEN_BITS_REG, reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); - iwl_write_prph(bus(trans), SCD_QUEUECHAIN_SEL, + iwl_write_prph(trans, SCD_QUEUECHAIN_SEL, SCD_QUEUECHAIN_SEL_ALL(trans)); - iwl_write_prph(bus(trans), SCD_AGGR_SEL, 0); + iwl_write_prph(trans, SCD_AGGR_SEL, 0); /* initiate the queues */ for (i = 0; i < hw_params(trans).max_txq_num; i++) { - iwl_write_prph(bus(trans), SCD_QUEUE_RDPTR(i), 0); - iwl_write_direct32(bus(trans), HBUS_TARG_WRPTR, 0 | (i << 8)); - iwl_write_targ_mem(bus(trans), trans_pcie->scd_base_addr + + iwl_write_prph(trans, SCD_QUEUE_RDPTR(i), 0); + iwl_write_direct32(trans, HBUS_TARG_WRPTR, 0 | (i << 8)); + iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + SCD_CONTEXT_QUEUE_OFFSET(i), 0); - iwl_write_targ_mem(bus(trans), trans_pcie->scd_base_addr + + iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + SCD_CONTEXT_QUEUE_OFFSET(i) + sizeof(u32), ((SCD_WIN_SIZE << @@ -902,7 +902,7 @@ static void iwl_tx_start(struct iwl_trans *trans) SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); } - iwl_write_prph(bus(trans), SCD_INTERRUPT_MASK, + iwl_write_prph(trans, SCD_INTERRUPT_MASK, IWL_MASK(0, hw_params(trans).max_txq_num)); /* Activate all Tx DMA/FIFO channels */ @@ -948,7 +948,7 @@ static void iwl_tx_start(struct iwl_trans *trans) spin_unlock_irqrestore(&trans->shrd->lock, flags); /* Enable L1-Active */ - iwl_clear_bits_prph(bus(trans), APMG_PCIDEV_STT_REG, + iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG, APMG_PCIDEV_STT_VAL_L1_ACT_DIS); } @@ -974,14 +974,14 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans) /* Stop each Tx DMA channel, and wait for it to be idle */ for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) { - iwl_write_direct32(bus(trans), + iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); - if (iwl_poll_direct_bit(bus(trans), FH_TSSR_TX_STATUS_REG, + if (iwl_poll_direct_bit(trans, FH_TSSR_TX_STATUS_REG, FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), 1000)) IWL_ERR(trans, "Failing on timeout while stopping" " DMA channel %d [0x%08x]", ch, - iwl_read_direct32(bus(trans), + iwl_read_direct32(trans, FH_TSSR_TX_STATUS_REG)); } spin_unlock_irqrestore(&trans->shrd->lock, flags); @@ -1024,13 +1024,13 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) iwl_trans_rx_stop(trans); #endif /* Power-down device's busmaster DMA clocks */ - iwl_write_prph(bus(trans), APMG_CLK_DIS_REG, + iwl_write_prph(trans, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); udelay(5); } /* Make sure (redundant) we've released our request to stay awake */ - iwl_clear_bit(bus(trans), CSR_GP_CNTRL, + iwl_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); /* Stop the device, and put it in low power state */ @@ -1048,7 +1048,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) tasklet_kill(&trans_pcie->irq_tasklet); /* stop and reset the on-board processor */ - iwl_write32(bus(trans), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); + iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); } static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, @@ -1145,10 +1145,10 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, /* Physical address of this Tx command's header (not MAC header!), * within command buffer array. */ - txcmd_phys = dma_map_single(bus(trans)->dev, + txcmd_phys = dma_map_single(trans->dev, &dev_cmd->hdr, firstlen, DMA_BIDIRECTIONAL); - if (unlikely(dma_mapping_error(bus(trans)->dev, txcmd_phys))) + if (unlikely(dma_mapping_error(trans->dev, txcmd_phys))) return -1; dma_unmap_addr_set(out_meta, mapping, txcmd_phys); dma_unmap_len_set(out_meta, len, firstlen); @@ -1164,10 +1164,10 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, * if any (802.11 null frames have no payload). */ secondlen = skb->len - hdr_len; if (secondlen > 0) { - phys_addr = dma_map_single(bus(trans)->dev, skb->data + hdr_len, + phys_addr = dma_map_single(trans->dev, skb->data + hdr_len, secondlen, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(bus(trans)->dev, phys_addr))) { - dma_unmap_single(bus(trans)->dev, + 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); @@ -1185,7 +1185,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, offsetof(struct iwl_tx_cmd, scratch); /* take back ownership of DMA buffer to enable update */ - dma_sync_single_for_cpu(bus(trans)->dev, txcmd_phys, firstlen, + 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); @@ -1199,7 +1199,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, /* Set up entry for this TFD in Tx byte-count array */ iwl_trans_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); - dma_sync_single_for_device(bus(trans)->dev, txcmd_phys, firstlen, + dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen, DMA_BIDIRECTIONAL); trace_iwlwifi_dev_tx(priv(trans), @@ -1232,7 +1232,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, static void iwl_trans_pcie_kick_nic(struct iwl_trans *trans) { /* Remove all resets to allow NIC to operate */ - iwl_write32(bus(trans), CSR_RESET, 0); + iwl_write32(trans, CSR_RESET, 0); } static int iwl_trans_pcie_request_irq(struct iwl_trans *trans) @@ -1355,7 +1355,7 @@ static int iwl_trans_pcie_suspend(struct iwl_trans *trans) iwl_apm_stop(priv(trans)); } else { iwl_disable_interrupts(trans); - iwl_clear_bit(bus(trans), CSR_GP_CNTRL, + iwl_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); } @@ -1368,7 +1368,7 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans) iwl_enable_interrupts(trans); - if (!(iwl_read32(bus(trans), CSR_GP_CNTRL) & + if (!(iwl_read32(trans, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) hw_rfkill = true; @@ -1464,9 +1464,9 @@ static int iwl_trans_pcie_check_stuck_queue(struct iwl_trans *trans, int cnt) IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n", q->read_ptr, q->write_ptr); IWL_ERR(trans, "Current HW read_ptr %d write_ptr %d\n", - iwl_read_prph(bus(trans), SCD_QUEUE_RDPTR(cnt)) + iwl_read_prph(trans, SCD_QUEUE_RDPTR(cnt)) & (TFD_QUEUE_SIZE_MAX - 1), - iwl_read_prph(bus(trans), SCD_QUEUE_WRPTR(cnt))); + iwl_read_prph(trans, SCD_QUEUE_WRPTR(cnt))); return 1; } @@ -1520,7 +1520,7 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display) pos += scnprintf(*buf + pos, bufsz - pos, " %34s: 0X%08x\n", get_fh_string(fh_tbl[i]), - iwl_read_direct32(bus(trans), fh_tbl[i])); + iwl_read_direct32(trans, fh_tbl[i])); } return pos; } @@ -1529,7 +1529,7 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display) for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { IWL_ERR(trans, " %34s: 0X%08x\n", get_fh_string(fh_tbl[i]), - iwl_read_direct32(bus(trans), fh_tbl[i])); + iwl_read_direct32(trans, fh_tbl[i])); } return 0; } @@ -1599,7 +1599,7 @@ void iwl_dump_csr(struct iwl_trans *trans) for (i = 0; i < ARRAY_SIZE(csr_tbl); i++) { IWL_ERR(trans, " %25s: 0X%08x\n", get_csr_string(csr_tbl[i]), - iwl_read32(bus(trans), csr_tbl[i])); + iwl_read32(trans, csr_tbl[i])); } } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 0a3727dac6a..dec935a84a7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -234,6 +234,7 @@ struct iwl_calib_result { * @ops - pointer to iwl_trans_ops * @shrd - pointer to iwl_shared which holds shared data from the upper layer * @hcmd_lock: protects HCMD + * @reg_lock - protect hw register access * @dev - pointer to struct device * that represents the device * @irq - the irq number for the device * @ucode_write_complete: indicates that the ucode has been copied. @@ -247,6 +248,7 @@ struct iwl_trans { const struct iwl_trans_ops *ops; struct iwl_shared *shrd; spinlock_t hcmd_lock; + spinlock_t reg_lock; struct device *dev; unsigned int irq; diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 0d7f207ac61..5de8b5beb09 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -126,42 +126,41 @@ int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc, static int iwl_load_section(struct iwl_trans *trans, const char *name, struct fw_desc *image, u32 dst_addr) { - struct iwl_bus *bus = bus(trans); dma_addr_t phy_addr = image->p_addr; u32 byte_cnt = image->len; int ret; trans->ucode_write_complete = 0; - iwl_write_direct32(bus, + iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE); - iwl_write_direct32(bus, + iwl_write_direct32(trans, FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr); - iwl_write_direct32(bus, + iwl_write_direct32(trans, FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL), phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK); - iwl_write_direct32(bus, + iwl_write_direct32(trans, FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL), (iwl_get_dma_hi_addr(phy_addr) << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt); - iwl_write_direct32(bus, + iwl_write_direct32(trans, FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL), 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM | 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX | FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID); - iwl_write_direct32(bus, + iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); - IWL_DEBUG_FW(bus, "%s uCode section being loaded...\n", name); + IWL_DEBUG_FW(trans, "%s uCode section being loaded...\n", name); ret = wait_event_timeout(trans->shrd->wait_command_queue, trans->ucode_write_complete, 5 * HZ); if (!ret) { @@ -470,7 +469,7 @@ static int iwl_alive_notify(struct iwl_trans *trans) * using sample data 100 bytes apart. If these sample points are good, * it's a pretty good bet that everything between them is good, too. */ -static int iwl_verify_inst_sparse(struct iwl_bus *bus, +static int iwl_verify_inst_sparse(struct iwl_trans *trans, struct fw_desc *fw_desc) { __le32 *image = (__le32 *)fw_desc->v_addr; @@ -478,15 +477,15 @@ static int iwl_verify_inst_sparse(struct iwl_bus *bus, u32 val; u32 i; - IWL_DEBUG_FW(bus, "ucode inst image size is %u\n", len); + IWL_DEBUG_FW(trans, "ucode inst image size is %u\n", len); for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { /* read data comes through single port, auto-incr addr */ /* NOTE: Use the debugless read so we don't flood kernel log * if IWL_DL_IO is set */ - iwl_write_direct32(bus, HBUS_TARG_MEM_RADDR, + iwl_write_direct32(trans, HBUS_TARG_MEM_RADDR, i + IWLAGN_RTC_INST_LOWER_BOUND); - val = iwl_read32(bus, HBUS_TARG_MEM_RDAT); + val = iwl_read32(trans, HBUS_TARG_MEM_RDAT); if (val != le32_to_cpu(*image)) return -EIO; } @@ -494,7 +493,7 @@ static int iwl_verify_inst_sparse(struct iwl_bus *bus, return 0; } -static void iwl_print_mismatch_inst(struct iwl_bus *bus, +static void iwl_print_mismatch_inst(struct iwl_trans *trans, struct fw_desc *fw_desc) { __le32 *image = (__le32 *)fw_desc->v_addr; @@ -503,18 +502,18 @@ static void iwl_print_mismatch_inst(struct iwl_bus *bus, u32 offs; int errors = 0; - IWL_DEBUG_FW(bus, "ucode inst image size is %u\n", len); + IWL_DEBUG_FW(trans, "ucode inst image size is %u\n", len); - iwl_write_direct32(bus, HBUS_TARG_MEM_RADDR, + iwl_write_direct32(trans, HBUS_TARG_MEM_RADDR, IWLAGN_RTC_INST_LOWER_BOUND); for (offs = 0; offs < len && errors < 20; offs += sizeof(u32), image++) { /* read data comes through single port, auto-incr addr */ - val = iwl_read32(bus, HBUS_TARG_MEM_RDAT); + val = iwl_read32(trans, HBUS_TARG_MEM_RDAT); if (val != le32_to_cpu(*image)) { - IWL_ERR(bus, "uCode INST section at " + IWL_ERR(trans, "uCode INST section at " "offset 0x%x, is 0x%x, s/b 0x%x\n", offs, val, le32_to_cpu(*image)); errors++; @@ -536,14 +535,14 @@ static int iwl_verify_ucode(struct iwl_trans *trans, return -EINVAL; } - if (!iwl_verify_inst_sparse(bus(trans), &img->code)) { + if (!iwl_verify_inst_sparse(trans, &img->code)) { IWL_DEBUG_FW(trans, "uCode is good in inst SRAM\n"); return 0; } IWL_ERR(trans, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); - iwl_print_mismatch_inst(bus(trans), &img->code); + iwl_print_mismatch_inst(trans, &img->code); return -EIO; } -- cgit v1.2.3-70-g09d2 From ea4caade104490de0fadb64660f9e228c050fb3d Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 4 Jan 2012 14:23:20 +0200 Subject: iwlwifi: remove the pointer to dev from the bus layer Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-bus.h | 2 -- drivers/net/wireless/iwlwifi/iwl-debug.h | 16 ++++++++-------- drivers/net/wireless/iwlwifi/iwl-pci.c | 7 ++++--- drivers/net/wireless/iwlwifi/iwl-ucode.c | 4 ++-- 5 files changed, 16 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index f79791500a9..d890b6481b8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1146,7 +1146,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) iwl_dealloc_ucode(trans(priv)); out_unbind: complete(&priv->firmware_loading_complete); - device_release_driver(bus(priv)->dev); + device_release_driver(trans(priv)->dev); release_firmware(ucode_raw); } @@ -1785,7 +1785,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, /* At this point both hw and priv are allocated. */ - SET_IEEE80211_DEV(hw, bus(priv)->dev); + SET_IEEE80211_DEV(hw, trans(priv)->dev); /* what debugging capabilities we have */ iwl_debug_config(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-bus.h b/drivers/net/wireless/iwlwifi/iwl-bus.h index ce1a9cc106e..2065c5b7416 100644 --- a/drivers/net/wireless/iwlwifi/iwl-bus.h +++ b/drivers/net/wireless/iwlwifi/iwl-bus.h @@ -137,14 +137,12 @@ struct iwl_bus_ops { * * This data is common to all bus layer implementations. * - * @dev - pointer to struct device * that represents the device * @ops - pointer to iwl_bus_ops * @shrd - pointer to iwl_shared which holds shared data from the upper layer * NB: for the time being this needs to be set by the upper layer since * it allocates the shared data */ struct iwl_bus { - struct device *dev; const struct iwl_bus_ops *ops; struct iwl_shared *shrd; diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 6f7612781e0..351b41d7f4f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -35,10 +35,10 @@ struct iwl_priv; /*No matter what is m (priv, bus, trans), this will work */ -#define IWL_ERR(m, f, a...) dev_err(bus(m)->dev, f, ## a) -#define IWL_WARN(m, f, a...) dev_warn(bus(m)->dev, f, ## a) -#define IWL_INFO(m, f, a...) dev_info(bus(m)->dev, f, ## a) -#define IWL_CRIT(m, f, a...) dev_crit(bus(m)->dev, f, ## a) +#define IWL_ERR(m, f, a...) dev_err(trans(m)->dev, f, ## a) +#define IWL_WARN(m, f, a...) dev_warn(trans(m)->dev, f, ## a) +#define IWL_INFO(m, f, a...) dev_info(trans(m)->dev, f, ## a) +#define IWL_CRIT(m, f, a...) dev_crit(trans(m)->dev, f, ## a) #define iwl_print_hex_error(m, p, len) \ do { \ @@ -50,7 +50,7 @@ do { \ #define IWL_DEBUG(m, level, fmt, ...) \ do { \ if (iwl_get_debug_level((m)->shrd) & (level)) \ - dev_err(bus(m)->dev, "%c %s " fmt, \ + dev_err(trans(m)->dev, "%c %s " fmt, \ in_interrupt() ? 'I' : 'U', __func__, \ ##__VA_ARGS__); \ } while (0) @@ -59,7 +59,7 @@ do { \ do { \ if (iwl_get_debug_level((m)->shrd) & (level) && \ net_ratelimit()) \ - dev_err(bus(m)->dev, "%c %s " fmt, \ + dev_err(trans(m)->dev, "%c %s " fmt, \ in_interrupt() ? 'I' : 'U', __func__, \ ##__VA_ARGS__); \ } while (0) @@ -74,12 +74,12 @@ do { \ #define IWL_DEBUG_QUIET_RFKILL(p, fmt, ...) \ do { \ if (!iwl_is_rfkill(p->shrd)) \ - dev_err(bus(p)->dev, "%s%c %s " fmt, \ + dev_err(trans(p)->dev, "%s%c %s " fmt, \ "", \ in_interrupt() ? 'I' : 'U', __func__, \ ##__VA_ARGS__); \ else if (iwl_get_debug_level(p->shrd) & IWL_DL_RADIO) \ - dev_err(bus(p)->dev, "%s%c %s " fmt, \ + dev_err(trans(p)->dev, "%s%c %s " fmt, \ "(RFKILL) ", \ in_interrupt() ? 'I' : 'U', __func__, \ ##__VA_ARGS__); \ diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 7bab8192848..6451739aed2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -123,12 +123,14 @@ static void iwl_pci_apm_config(struct iwl_bus *bus) /* L1-ASPM enabled; disable(!) L0S */ iwl_set_bit(trans(bus), CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); - dev_printk(KERN_INFO, bus->dev, "L1 Enabled; Disabling L0S\n"); + dev_printk(KERN_INFO, trans(bus)->dev, + "L1 Enabled; Disabling L0S\n"); } else { /* L1-ASPM disabled; enable(!) L0S */ iwl_clear_bit(trans(bus), CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); - dev_printk(KERN_INFO, bus->dev, "L1 Disabled; Enabling L0S\n"); + dev_printk(KERN_INFO, trans(bus)->dev, + "L1 Disabled; Enabling L0S\n"); } } @@ -368,7 +370,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_drvdata(pdev, bus); - bus->dev = &pdev->dev; bus->ops = &bus_ops_pci; #ifdef CONFIG_IWLWIFI_IDI diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 5de8b5beb09..08483d785e2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -83,7 +83,7 @@ static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { static void iwl_free_fw_desc(struct iwl_bus *bus, struct fw_desc *desc) { if (desc->v_addr) - dma_free_coherent(bus->dev, desc->len, + dma_free_coherent(trans(bus)->dev, desc->len, desc->v_addr, desc->p_addr); desc->v_addr = NULL; desc->len = 0; @@ -110,7 +110,7 @@ int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc, return -EINVAL; } - desc->v_addr = dma_alloc_coherent(bus->dev, len, + desc->v_addr = dma_alloc_coherent(trans(bus)->dev, len, &desc->p_addr, GFP_KERNEL); if (!desc->v_addr) return -ENOMEM; -- cgit v1.2.3-70-g09d2 From 8467ab4f42396a3714b59ca187f470542970ff9d Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 3 Jan 2012 16:28:12 +0200 Subject: iwlwifi: don't use the bus for ucode fw_desc any more This is transport related Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 14 ++++++++------ drivers/net/wireless/iwlwifi/iwl-trans.h | 2 +- drivers/net/wireless/iwlwifi/iwl-ucode.c | 20 ++++++++++---------- 3 files changed, 19 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index d890b6481b8..8b1839aec40 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1023,31 +1023,33 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) /* Runtime instructions and 2 copies of data: * 1) unmodified from disk * 2) backup cache for save/restore during power-downs */ - if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_rt.code, + if (iwl_alloc_fw_desc(trans(priv), &trans(priv)->ucode_rt.code, pieces.inst, pieces.inst_size)) goto err_pci_alloc; - if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_rt.data, + if (iwl_alloc_fw_desc(trans(priv), &trans(priv)->ucode_rt.data, pieces.data, pieces.data_size)) goto err_pci_alloc; /* Initialization instructions and data */ if (pieces.init_size && pieces.init_data_size) { - if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_init.code, + if (iwl_alloc_fw_desc(trans(priv), + &trans(priv)->ucode_init.code, pieces.init, pieces.init_size)) goto err_pci_alloc; - if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_init.data, + if (iwl_alloc_fw_desc(trans(priv), + &trans(priv)->ucode_init.data, pieces.init_data, pieces.init_data_size)) goto err_pci_alloc; } /* WoWLAN instructions and data */ if (pieces.wowlan_inst_size && pieces.wowlan_data_size) { - if (iwl_alloc_fw_desc(bus(priv), + if (iwl_alloc_fw_desc(trans(priv), &trans(priv)->ucode_wowlan.code, pieces.wowlan_inst, pieces.wowlan_inst_size)) goto err_pci_alloc; - if (iwl_alloc_fw_desc(bus(priv), + if (iwl_alloc_fw_desc(trans(priv), &trans(priv)->ucode_wowlan.data, pieces.wowlan_data, pieces.wowlan_data_size)) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index dec935a84a7..d5195998417 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -408,7 +408,7 @@ static inline u32 iwl_trans_read32(struct iwl_trans *trans, u32 ofs) /***************************************************** * Utils functions ******************************************************/ -int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc, +int iwl_alloc_fw_desc(struct iwl_trans *trans, struct fw_desc *desc, const void *data, size_t len); void iwl_dealloc_ucode(struct iwl_trans *trans); diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 08483d785e2..793524a3ed7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -80,29 +80,29 @@ static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { * ******************************************************************************/ -static void iwl_free_fw_desc(struct iwl_bus *bus, struct fw_desc *desc) +static void iwl_free_fw_desc(struct iwl_trans *trans, struct fw_desc *desc) { if (desc->v_addr) - dma_free_coherent(trans(bus)->dev, desc->len, + dma_free_coherent(trans->dev, desc->len, desc->v_addr, desc->p_addr); desc->v_addr = NULL; desc->len = 0; } -static void iwl_free_fw_img(struct iwl_bus *bus, struct fw_img *img) +static void iwl_free_fw_img(struct iwl_trans *trans, struct fw_img *img) { - iwl_free_fw_desc(bus, &img->code); - iwl_free_fw_desc(bus, &img->data); + iwl_free_fw_desc(trans, &img->code); + iwl_free_fw_desc(trans, &img->data); } void iwl_dealloc_ucode(struct iwl_trans *trans) { - iwl_free_fw_img(bus(trans), &trans->ucode_rt); - iwl_free_fw_img(bus(trans), &trans->ucode_init); - iwl_free_fw_img(bus(trans), &trans->ucode_wowlan); + iwl_free_fw_img(trans, &trans->ucode_rt); + iwl_free_fw_img(trans, &trans->ucode_init); + iwl_free_fw_img(trans, &trans->ucode_wowlan); } -int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc, +int iwl_alloc_fw_desc(struct iwl_trans *trans, struct fw_desc *desc, const void *data, size_t len) { if (!len) { @@ -110,7 +110,7 @@ int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc, return -EINVAL; } - desc->v_addr = dma_alloc_coherent(trans(bus)->dev, len, + desc->v_addr = dma_alloc_coherent(trans->dev, len, &desc->p_addr, GFP_KERNEL); if (!desc->v_addr) return -ENOMEM; -- cgit v1.2.3-70-g09d2 From 57a1dc89097982874f50a0e6f68ab08f62e9e5aa Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 8 Jan 2012 13:22:16 +0200 Subject: iwlwifi: rename trans_ops->request_irq to trans_ops->start_hw This handler will become thicker, reflect its real role now. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 36 ++++++++++++++--------- drivers/net/wireless/iwlwifi/iwl-trans.h | 8 ++--- 4 files changed, 29 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 8b1839aec40..1c00691c9f0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1829,7 +1829,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, IWL_INFO(priv, "Detected %s, REV=0x%X\n", cfg(priv)->name, hw_rev); - err = iwl_trans_request_irq(trans(priv)); + err = iwl_trans_start_hw(trans(priv)); if (err) goto out_free_traffic_mem; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 555175ff4f9..561865f29d5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -201,6 +201,7 @@ struct iwl_tx_queue { * @rxq: all the RX queue data * @rx_replenish: work that will be called when buffers need to be allocated * @trans: pointer to the generic transport area + * @irq_requested: true when the irq has been requested * @scd_base_addr: scheduler sram base address in SRAM * @scd_bc_tbls: pointer to the byte count table of the scheduler * @kw: keep warm address @@ -225,6 +226,7 @@ struct iwl_trans_pcie { int ict_index; u32 inta; bool use_ict; + bool irq_requested; struct tasklet_struct irq_tasklet; struct isr_statistics isr_stats; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index a1ee2e4b0ce..ffbafb9e447 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1235,7 +1235,7 @@ static void iwl_trans_pcie_kick_nic(struct iwl_trans *trans) iwl_write32(trans, CSR_RESET, 0); } -static int iwl_trans_pcie_request_irq(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); @@ -1243,20 +1243,26 @@ static int iwl_trans_pcie_request_irq(struct iwl_trans *trans) trans_pcie->inta_mask = CSR_INI_SET_MASK; - tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long)) - iwl_irq_tasklet, (unsigned long)trans); + if (!trans_pcie->irq_requested) { + tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long)) + iwl_irq_tasklet, (unsigned long)trans); - iwl_alloc_isr_ict(trans); + iwl_alloc_isr_ict(trans); - err = request_irq(trans->irq, iwl_isr_ict, IRQF_SHARED, - DRV_NAME, trans); - if (err) { - IWL_ERR(trans, "Error allocating IRQ %d\n", trans->irq); - iwl_free_isr_ict(trans); - return err; + err = request_irq(trans->irq, iwl_isr_ict, IRQF_SHARED, + DRV_NAME, trans); + if (err) { + IWL_ERR(trans, "Error allocating IRQ %d\n", + trans->irq); + iwl_free_isr_ict(trans); + tasklet_kill(&trans_pcie->irq_tasklet); + return err; + } + + INIT_WORK(&trans_pcie->rx_replenish, iwl_bg_rx_replenish); + trans_pcie->irq_requested = true; } - INIT_WORK(&trans_pcie->rx_replenish, iwl_bg_rx_replenish); return 0; } @@ -1325,8 +1331,10 @@ static void iwl_trans_pcie_free(struct iwl_trans *trans) #ifndef CONFIG_IWLWIFI_IDI iwl_trans_pcie_rx_free(trans); #endif - free_irq(trans->irq, trans); - iwl_free_isr_ict(trans); + if (trans_pcie->irq_requested == true) { + free_irq(trans->irq, trans); + iwl_free_isr_ict(trans); + } pci_disable_msi(trans_pcie->pci_dev); pci_iounmap(trans_pcie->pci_dev, trans_pcie->hw_base); @@ -1920,7 +1928,7 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, #endif /*CONFIG_IWLWIFI_DEBUGFS */ const struct iwl_trans_ops trans_ops_pcie = { - .request_irq = iwl_trans_pcie_request_irq, + .start_hw = iwl_trans_pcie_start_hw, .fw_alive = iwl_trans_pcie_fw_alive, .start_device = iwl_trans_pcie_start_device, .prepare_card_hw = iwl_trans_pcie_prepare_card_hw, diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index d5195998417..ddc3a0627dd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -133,7 +133,7 @@ struct iwl_host_cmd { /** * struct iwl_trans_ops - transport specific operations - * @request_irq: requests IRQ - will be called before the FW load in probe flow + * @start_hw: starts the HW- from that point on, the HW can send interrupts * @start_device: allocates and inits all the resources for the transport * layer. * @prepare_card_hw: claim the ownership on the HW. Will be called during @@ -164,7 +164,7 @@ struct iwl_host_cmd { */ struct iwl_trans_ops { - int (*request_irq)(struct iwl_trans *iwl_trans); + int (*start_hw)(struct iwl_trans *iwl_trans); int (*start_device)(struct iwl_trans *trans); void (*fw_alive)(struct iwl_trans *trans); int (*prepare_card_hw)(struct iwl_trans *trans); @@ -269,9 +269,9 @@ struct iwl_trans { char trans_specific[0] __attribute__((__aligned__(sizeof(void *)))); }; -static inline int iwl_trans_request_irq(struct iwl_trans *trans) +static inline int iwl_trans_start_hw(struct iwl_trans *trans) { - return trans->ops->request_irq(trans); + return trans->ops->start_hw(trans); } static inline void iwl_trans_fw_alive(struct iwl_trans *trans) -- cgit v1.2.3-70-g09d2 From ebb7678d00b2fa0d7db76b5303a5bf46a5aed8f3 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 8 Jan 2012 13:24:57 +0200 Subject: iwlwifi: move prepare_card_hw to start_hw Kill the trans_ops->prepare_card_hw which is now useless. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 6 ------ drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 22 +++++++++++++++------- drivers/net/wireless/iwlwifi/iwl-trans.h | 8 -------- 3 files changed, 15 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 1c00691c9f0..5ab7f681991 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1833,12 +1833,6 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, if (err) goto out_free_traffic_mem; - if (iwl_trans_prepare_card_hw(trans(priv))) { - err = -EIO; - IWL_WARN(priv, "Failed, HW not ready\n"); - goto out_free_traffic_mem; - } - /***************** * 4. Read EEPROM *****************/ diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index ffbafb9e447..d1ab57a7988 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -690,13 +690,14 @@ static int iwl_set_hw_ready(struct iwl_trans *trans) } /* Note: returns standard 0/-ERROR code */ -static int iwl_trans_pcie_prepare_card_hw(struct iwl_trans *trans) +static int iwl_prepare_card_hw(struct iwl_trans *trans) { int ret; IWL_DEBUG_INFO(trans, "iwl_trans_prepare_card_hw enter\n"); ret = iwl_set_hw_ready(trans); + /* If the card is ready, exit 0 */ if (ret >= 0) return 0; @@ -788,7 +789,7 @@ static int iwl_trans_pcie_start_device(struct iwl_trans *trans) trans_pcie->mcast_queue[IWL_RXON_CTX_PAN] = IWL_IPAN_MCAST_QUEUE; if ((hw_params(trans).sku & EEPROM_SKU_CAP_AMT_ENABLE) && - iwl_trans_pcie_prepare_card_hw(trans)) { + iwl_prepare_card_hw(trans)) { IWL_WARN(trans, "Exit HW not ready\n"); return -EIO; } @@ -1254,16 +1255,24 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) if (err) { IWL_ERR(trans, "Error allocating IRQ %d\n", trans->irq); - iwl_free_isr_ict(trans); - tasklet_kill(&trans_pcie->irq_tasklet); - return err; + goto error; } INIT_WORK(&trans_pcie->rx_replenish, iwl_bg_rx_replenish); trans_pcie->irq_requested = true; } - return 0; + err = iwl_prepare_card_hw(trans); + if (err) { + IWL_ERR(trans, "Error while preparing HW: %d", err); + goto error; + } + return err; + +error: + iwl_free_isr_ict(trans); + tasklet_kill(&trans_pcie->irq_tasklet); + return err; } static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, @@ -1931,7 +1940,6 @@ const struct iwl_trans_ops trans_ops_pcie = { .start_hw = iwl_trans_pcie_start_hw, .fw_alive = iwl_trans_pcie_fw_alive, .start_device = iwl_trans_pcie_start_device, - .prepare_card_hw = iwl_trans_pcie_prepare_card_hw, .stop_device = iwl_trans_pcie_stop_device, .wake_any_queue = iwl_trans_pcie_wake_any_queue, diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index ddc3a0627dd..55b5dc3b5dd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -136,8 +136,6 @@ struct iwl_host_cmd { * @start_hw: starts the HW- from that point on, the HW can send interrupts * @start_device: allocates and inits all the resources for the transport * layer. - * @prepare_card_hw: claim the ownership on the HW. Will be called during - * probe. * @fw_alive: called when the fw sends alive notification * @wake_any_queue: wake all the queues of a specfic context IWL_RXON_CTX_* * @stop_device:stops the whole device (embedded CPU put to reset) @@ -167,7 +165,6 @@ struct iwl_trans_ops { int (*start_hw)(struct iwl_trans *iwl_trans); int (*start_device)(struct iwl_trans *trans); void (*fw_alive)(struct iwl_trans *trans); - int (*prepare_card_hw)(struct iwl_trans *trans); void (*stop_device)(struct iwl_trans *trans); void (*wake_any_queue)(struct iwl_trans *trans, @@ -284,11 +281,6 @@ static inline int iwl_trans_start_device(struct iwl_trans *trans) return trans->ops->start_device(trans); } -static inline int iwl_trans_prepare_card_hw(struct iwl_trans *trans) -{ - return trans->ops->prepare_card_hw(trans); -} - static inline void iwl_trans_stop_device(struct iwl_trans *trans) { trans->ops->stop_device(trans); -- cgit v1.2.3-70-g09d2 From a6c684ee489a99a54f978aa92a9bf1e82f8c633b Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 8 Jan 2012 13:24:57 +0200 Subject: iwlwifi: move apm_init to start_hw This is transport related Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 - drivers/net/wireless/iwlwifi/iwl-core.c | 85 -------------------------- drivers/net/wireless/iwlwifi/iwl-shared.h | 1 - drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 88 ++++++++++++++++++++++++++- 4 files changed, 87 insertions(+), 89 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 5ab7f681991..3aeaa890e64 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1836,8 +1836,6 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, /***************** * 4. Read EEPROM *****************/ - /* switch the NIC on before accessing the EEPROM */ - iwl_apm_init(priv); /* Read the EEPROM */ err = iwl_eeprom_init(priv, hw_rev); /* Reset chip to save power until we load uCode during "up". */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index c9022c5fa81..3ba59fa3108 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -923,91 +923,6 @@ void iwl_apm_stop(struct iwl_priv *priv) CSR_GP_CNTRL_REG_FLAG_INIT_DONE); } - -/* - * Start up NIC's basic functionality after it has been reset - * (e.g. after platform boot, or shutdown via iwl_apm_stop()) - * NOTE: This does not load uCode nor start the embedded processor - */ -int iwl_apm_init(struct iwl_priv *priv) -{ - int ret = 0; - IWL_DEBUG_INFO(priv, "Init card's basic functions\n"); - - /* - * Use "set_bit" below rather than "write", to preserve any hardware - * bits already set by default after reset. - */ - - /* Disable L0S exit timer (platform NMI Work/Around) */ - iwl_set_bit(trans(priv), CSR_GIO_CHICKEN_BITS, - CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); - - /* - * Disable L0s without affecting L1; - * don't wait for ICH L0s (ICH bug W/A) - */ - iwl_set_bit(trans(priv), CSR_GIO_CHICKEN_BITS, - CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); - - /* Set FH wait threshold to maximum (HW error during stress W/A) */ - iwl_set_bit(trans(priv), CSR_DBG_HPET_MEM_REG, - CSR_DBG_HPET_MEM_REG_VAL); - - /* - * Enable HAP INTA (interrupt from management bus) to - * wake device's PCI Express link L1a -> L0s - */ - iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); - - bus_apm_config(bus(priv)); - - /* Configure analog phase-lock-loop before activating to D0A */ - if (cfg(priv)->base_params->pll_cfg_val) - iwl_set_bit(trans(priv), CSR_ANA_PLL_CFG, - cfg(priv)->base_params->pll_cfg_val); - - /* - * Set "initialization complete" bit to move adapter from - * D0U* --> D0A* (powered-up active) state. - */ - iwl_set_bit(trans(priv), CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); - - /* - * Wait for clock stabilization; once stabilized, access to - * device-internal resources is supported, e.g. iwl_write_prph() - * and accesses to uCode SRAM. - */ - ret = iwl_poll_bit(trans(priv), CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, - CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); - if (ret < 0) { - IWL_DEBUG_INFO(priv, "Failed to init the card\n"); - goto out; - } - - /* - * Enable DMA clock and wait for it to stabilize. - * - * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits - * do not disable clocks. This preserves any hardware bits already - * set by default in "CLK_CTRL_REG" after reset. - */ - iwl_write_prph(trans(priv), APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT); - udelay(20); - - /* Disable L1-Active */ - iwl_set_bits_prph(trans(priv), APMG_PCIDEV_STT_REG, - APMG_PCIDEV_STT_VAL_L1_ACT_DIS); - - set_bit(STATUS_DEVICE_ENABLED, &priv->shrd->status); - -out: - return ret; -} - - int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) { int ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 04975b7b65b..338a55f403d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -544,7 +544,6 @@ void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state); void iwl_nic_config(struct iwl_priv *priv); void iwl_free_skb(struct iwl_priv *priv, struct sk_buff *skb); void iwl_apm_stop(struct iwl_priv *priv); -int iwl_apm_init(struct iwl_priv *priv); void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand); const char *get_cmd_string(u8 cmd); bool iwl_check_for_ct_kill(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index d1ab57a7988..335d4b1508c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -74,6 +74,7 @@ #include "iwl-shared.h" #include "iwl-eeprom.h" #include "iwl-agn-hw.h" +#include "iwl-core.h" static int iwl_trans_rx_alloc(struct iwl_trans *trans) { @@ -631,13 +632,95 @@ static void iwl_set_pwr_vmain(struct iwl_trans *trans) ~APMG_PS_CTRL_MSK_PWR_SRC); } +/* + * Start up NIC's basic functionality after it has been reset + * (e.g. after platform boot, or shutdown via iwl_apm_stop()) + * NOTE: This does not load uCode nor start the embedded processor + */ +static int iwl_apm_init(struct iwl_trans *trans) +{ + int ret = 0; + IWL_DEBUG_INFO(trans, "Init card's basic functions\n"); + + /* + * Use "set_bit" below rather than "write", to preserve any hardware + * bits already set by default after reset. + */ + + /* Disable L0S exit timer (platform NMI Work/Around) */ + iwl_set_bit(trans, CSR_GIO_CHICKEN_BITS, + CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); + + /* + * Disable L0s without affecting L1; + * don't wait for ICH L0s (ICH bug W/A) + */ + iwl_set_bit(trans, CSR_GIO_CHICKEN_BITS, + CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); + + /* Set FH wait threshold to maximum (HW error during stress W/A) */ + iwl_set_bit(trans, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL); + + /* + * Enable HAP INTA (interrupt from management bus) to + * wake device's PCI Express link L1a -> L0s + */ + iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); + + bus_apm_config(bus(trans)); + + /* Configure analog phase-lock-loop before activating to D0A */ + if (cfg(trans)->base_params->pll_cfg_val) + iwl_set_bit(trans, CSR_ANA_PLL_CFG, + cfg(trans)->base_params->pll_cfg_val); + + /* + * Set "initialization complete" bit to move adapter from + * D0U* --> D0A* (powered-up active) state. + */ + iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); + + /* + * Wait for clock stabilization; once stabilized, access to + * device-internal resources is supported, e.g. iwl_write_prph() + * and accesses to uCode SRAM. + */ + ret = iwl_poll_bit(trans, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, + CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); + if (ret < 0) { + IWL_DEBUG_INFO(trans, "Failed to init the card\n"); + goto out; + } + + /* + * Enable DMA clock and wait for it to stabilize. + * + * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits + * do not disable clocks. This preserves any hardware bits already + * set by default in "CLK_CTRL_REG" after reset. + */ + iwl_write_prph(trans, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT); + udelay(20); + + /* Disable L1-Active */ + iwl_set_bits_prph(trans, APMG_PCIDEV_STT_REG, + APMG_PCIDEV_STT_VAL_L1_ACT_DIS); + + set_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status); + +out: + return ret; +} + static int iwl_nic_init(struct iwl_trans *trans) { unsigned long flags; /* nic_init */ spin_lock_irqsave(&trans->shrd->lock, flags); - iwl_apm_init(priv(trans)); + iwl_apm_init(trans); /* Set interrupt coalescing calibration timer to default (512 usecs) */ iwl_write8(trans, CSR_INT_COALESCING, @@ -1267,6 +1350,9 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) IWL_ERR(trans, "Error while preparing HW: %d", err); goto error; } + + iwl_apm_init(trans); + return err; error: -- cgit v1.2.3-70-g09d2 From cc56feb2eb06a0a80a8f07e4adab7e6626009cca Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 8 Jan 2012 13:37:59 +0200 Subject: iwlwifi: introduce trans_ops->stop_hw This handler stops the HW and puts it in low power state. It will allow to clean up the flows in the upper layers. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl-core.c | 40 -------------------- drivers/net/wireless/iwlwifi/iwl-shared.h | 1 - drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 54 ++++++++++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-trans.h | 8 ++++ 5 files changed, 61 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 3aeaa890e64..88462467a95 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1839,7 +1839,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, /* Read the EEPROM */ err = iwl_eeprom_init(priv, hw_rev); /* Reset chip to save power until we load uCode during "up". */ - iwl_apm_stop(priv); + iwl_trans_stop_hw(trans(priv)); if (err) { IWL_ERR(priv, "Unable to init EEPROM\n"); goto out_free_traffic_mem; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 3ba59fa3108..95f2c33695b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -883,46 +883,6 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) } } -static int iwl_apm_stop_master(struct iwl_priv *priv) -{ - int ret = 0; - - /* stop device's busmaster DMA activity */ - iwl_set_bit(trans(priv), CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); - - ret = iwl_poll_bit(trans(priv), CSR_RESET, - CSR_RESET_REG_FLAG_MASTER_DISABLED, - CSR_RESET_REG_FLAG_MASTER_DISABLED, 100); - if (ret) - IWL_WARN(priv, "Master Disable Timed Out, 100 usec\n"); - - IWL_DEBUG_INFO(priv, "stop master\n"); - - return ret; -} - -void iwl_apm_stop(struct iwl_priv *priv) -{ - IWL_DEBUG_INFO(priv, "Stop card, put in low power state\n"); - - clear_bit(STATUS_DEVICE_ENABLED, &priv->shrd->status); - - /* Stop device's DMA activity */ - iwl_apm_stop_master(priv); - - /* Reset the entire device */ - iwl_set_bit(trans(priv), CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); - - udelay(10); - - /* - * Clear "initialization complete" bit to move adapter from - * D0A* (powered-up Active) --> D0U* (Uninitialized) state. - */ - iwl_clear_bit(trans(priv), CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_FLAG_INIT_DONE); -} - int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) { int ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 338a55f403d..63d4a4fc5b9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -543,7 +543,6 @@ int iwlagn_hw_valid_rtc_data_addr(u32 addr); void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state); void iwl_nic_config(struct iwl_priv *priv); void iwl_free_skb(struct iwl_priv *priv, struct sk_buff *skb); -void iwl_apm_stop(struct iwl_priv *priv); void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand); const char *get_cmd_string(u8 cmd); bool iwl_check_for_ct_kill(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 335d4b1508c..43e894f6737 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -714,6 +714,46 @@ out: return ret; } +static int iwl_apm_stop_master(struct iwl_trans *trans) +{ + int ret = 0; + + /* stop device's busmaster DMA activity */ + iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); + + ret = iwl_poll_bit(trans, CSR_RESET, + CSR_RESET_REG_FLAG_MASTER_DISABLED, + CSR_RESET_REG_FLAG_MASTER_DISABLED, 100); + if (ret) + IWL_WARN(trans, "Master Disable Timed Out, 100 usec\n"); + + IWL_DEBUG_INFO(trans, "stop master\n"); + + return ret; +} + +static void iwl_apm_stop(struct iwl_trans *trans) +{ + IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n"); + + clear_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status); + + /* Stop device's DMA activity */ + iwl_apm_stop_master(trans); + + /* Reset the entire device */ + iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); + + udelay(10); + + /* + * Clear "initialization complete" bit to move adapter from + * D0A* (powered-up Active) --> D0U* (Uninitialized) state. + */ + iwl_clear_bit(trans, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_INIT_DONE); +} + static int iwl_nic_init(struct iwl_trans *trans) { unsigned long flags; @@ -1118,7 +1158,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); /* Stop the device, and put it in low power state */ - iwl_apm_stop(priv(trans)); + iwl_apm_stop(trans); /* Upon stop, the APM issues an interrupt if HW RF kill is set. * Clean again the interrupt here @@ -1361,6 +1401,15 @@ error: return err; } +static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans) +{ + iwl_apm_stop(trans); + + /* Even if we stop the HW, we still want the RF kill interrupt */ + IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n"); + iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL); +} + static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, int txq_id, int ssn, u32 status, struct sk_buff_head *skbs) @@ -1455,7 +1504,7 @@ static int iwl_trans_pcie_suspend(struct iwl_trans *trans) * things already :-) */ if (!trans->shrd->wowlan) { - iwl_apm_stop(priv(trans)); + iwl_apm_stop(trans); } else { iwl_disable_interrupts(trans); iwl_clear_bit(trans, CSR_GP_CNTRL, @@ -2024,6 +2073,7 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, const struct iwl_trans_ops trans_ops_pcie = { .start_hw = iwl_trans_pcie_start_hw, + .stop_hw = iwl_trans_pcie_stop_hw, .fw_alive = iwl_trans_pcie_fw_alive, .start_device = iwl_trans_pcie_start_device, .stop_device = iwl_trans_pcie_stop_device, diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 55b5dc3b5dd..d0b6146b097 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -134,6 +134,8 @@ struct iwl_host_cmd { /** * struct iwl_trans_ops - transport specific operations * @start_hw: starts the HW- from that point on, the HW can send interrupts + * @stop_hw: stops the HW- from that point on, the HW will be in low power but + * will still issue interrupt if the HW RF kill is triggered. * @start_device: allocates and inits all the resources for the transport * layer. * @fw_alive: called when the fw sends alive notification @@ -163,6 +165,7 @@ struct iwl_host_cmd { struct iwl_trans_ops { int (*start_hw)(struct iwl_trans *iwl_trans); + void (*stop_hw)(struct iwl_trans *iwl_trans); int (*start_device)(struct iwl_trans *trans); void (*fw_alive)(struct iwl_trans *trans); void (*stop_device)(struct iwl_trans *trans); @@ -271,6 +274,11 @@ static inline int iwl_trans_start_hw(struct iwl_trans *trans) return trans->ops->start_hw(trans); } +static inline void iwl_trans_stop_hw(struct iwl_trans *trans) +{ + trans->ops->stop_hw(trans); +} + static inline void iwl_trans_fw_alive(struct iwl_trans *trans) { trans->ops->fw_alive(trans); -- cgit v1.2.3-70-g09d2 From d48e2074e240192e8a0396e1ae0082dd0e78aa8e Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 8 Jan 2012 13:48:21 +0200 Subject: iwlwifi: move the RF kill logic from iwl_probe to transport This is another clean up of the proble flow. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 23 ----------------------- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 11 +++++++++++ 2 files changed, 11 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 88462467a95..14f8b750c7c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1815,13 +1815,6 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, spin_lock_init(&trans(priv)->reg_lock); spin_lock_init(&priv->shrd->lock); - /* - * stop and reset the on-board processor just in case it is in a - * strange state ... like being left stranded by a primary kernel - * and this is now the kdump kernel trying to start up - */ - iwl_write32(trans(priv), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); - /*********************** * 3. Read REV register ***********************/ @@ -1890,22 +1883,6 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, iwl_setup_rx_handlers(priv); iwl_testmode_init(priv); - /********************************************* - * 8. Enable interrupts - *********************************************/ - - iwl_enable_rfkill_int(priv); - - /* If platform's RF_KILL switch is NOT set to KILL */ - if (iwl_read32(trans(priv), - CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) - clear_bit(STATUS_RF_KILL_HW, &priv->shrd->status); - else - set_bit(STATUS_RF_KILL_HW, &priv->shrd->status); - - wiphy_rfkill_set_hw_state(priv->hw->wiphy, - test_bit(STATUS_RF_KILL_HW, &priv->shrd->status)); - iwl_power_initialize(priv); iwl_tt_initialize(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 43e894f6737..362444a7ed5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1393,6 +1393,17 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) iwl_apm_init(trans); + /* If platform's RF_KILL switch is NOT set to KILL */ + if (iwl_read32(trans, + CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) + clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status); + else + set_bit(STATUS_RF_KILL_HW, &trans->shrd->status); + + iwl_set_hw_rfkill_state(priv(trans), + test_bit(STATUS_RF_KILL_HW, + &trans->shrd->status)); + return err; error: -- cgit v1.2.3-70-g09d2 From cf6142975bcbb731bc131ee9d2a68b7561076545 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 8 Jan 2012 16:33:58 +0200 Subject: iwlwifi: consolidate the start_device flow Now there is only one transport function that launch a specific fw: trans_ops->start_fw. This one replaces trans_ops->start_device and trans_ops->kick_nic. The code that actually loads the fw to the device has been moved to the transport specific code. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 4 -- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 88 +++++++++++++++++++++--- drivers/net/wireless/iwlwifi/iwl-trans.h | 44 +++++------- drivers/net/wireless/iwlwifi/iwl-ucode.c | 87 ++--------------------- 4 files changed, 103 insertions(+), 120 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index ebea2435dac..731f287c0f3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -1130,11 +1130,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) isr_stats->tx++; handled |= CSR_INT_BIT_FH_TX; /* Wake up uCode load routine, now that load is complete */ -#ifdef CONFIG_IWLWIFI_IDI - trans->shrd->trans->ucode_write_complete = 1; -#else trans->ucode_write_complete = 1; -#endif wake_up(&trans->shrd->wait_command_queue); } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 362444a7ed5..1030a252405 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -64,6 +64,7 @@ #include #include #include +#include #include #include @@ -895,7 +896,79 @@ static const u8 iwlagn_pan_ac_to_queue[] = { 7, 6, 5, 4, }; -static int iwl_trans_pcie_start_device(struct iwl_trans *trans) +/* + * ucode + */ +static int iwl_load_section(struct iwl_trans *trans, const char *name, + struct fw_desc *image, u32 dst_addr) +{ + dma_addr_t phy_addr = image->p_addr; + u32 byte_cnt = image->len; + int ret; + + trans->ucode_write_complete = 0; + + iwl_write_direct32(trans, + FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), + FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE); + + iwl_write_direct32(trans, + FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr); + + iwl_write_direct32(trans, + FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL), + phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK); + + iwl_write_direct32(trans, + FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL), + (iwl_get_dma_hi_addr(phy_addr) + << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt); + + iwl_write_direct32(trans, + FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL), + 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM | + 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX | + FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID); + + iwl_write_direct32(trans, + FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), + FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | + FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | + FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); + + IWL_DEBUG_FW(trans, "%s uCode section being loaded...\n", name); + ret = wait_event_timeout(trans->shrd->wait_command_queue, + trans->ucode_write_complete, 5 * HZ); + if (!ret) { + IWL_ERR(trans, "Could not load the %s uCode section\n", + name); + return -ETIMEDOUT; + } + + return 0; +} + +static int iwl_load_given_ucode(struct iwl_trans *trans, struct fw_img *image) +{ + int ret = 0; + + ret = iwl_load_section(trans, "INST", &image->code, + IWLAGN_RTC_INST_LOWER_BOUND); + if (ret) + return ret; + + ret = iwl_load_section(trans, "DATA", &image->data, + IWLAGN_RTC_DATA_LOWER_BOUND); + if (ret) + return ret; + + /* Remove all resets to allow NIC to operate */ + iwl_write32(trans, CSR_RESET, 0); + + return 0; +} + +static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, struct fw_img *fw) { int ret; struct iwl_trans_pcie *trans_pcie = @@ -951,6 +1024,9 @@ static int iwl_trans_pcie_start_device(struct iwl_trans *trans) iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + /* Load the given image to the HW */ + iwl_load_given_ucode(trans, fw); + return 0; } @@ -1353,12 +1429,6 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, return 0; } -static void iwl_trans_pcie_kick_nic(struct iwl_trans *trans) -{ - /* Remove all resets to allow NIC to operate */ - iwl_write32(trans, CSR_RESET, 0); -} - static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = @@ -2086,7 +2156,7 @@ const struct iwl_trans_ops trans_ops_pcie = { .start_hw = iwl_trans_pcie_start_hw, .stop_hw = iwl_trans_pcie_stop_hw, .fw_alive = iwl_trans_pcie_fw_alive, - .start_device = iwl_trans_pcie_start_device, + .start_fw = iwl_trans_pcie_start_fw, .stop_device = iwl_trans_pcie_stop_device, .wake_any_queue = iwl_trans_pcie_wake_any_queue, @@ -2100,8 +2170,6 @@ const struct iwl_trans_ops trans_ops_pcie = { .tx_agg_alloc = iwl_trans_pcie_tx_agg_alloc, .tx_agg_setup = iwl_trans_pcie_tx_agg_setup, - .kick_nic = iwl_trans_pcie_kick_nic, - .free = iwl_trans_pcie_free, .stop_queue = iwl_trans_pcie_stop_queue, diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index d0b6146b097..4d1ae65b68e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -131,13 +131,25 @@ struct iwl_host_cmd { u8 id; }; +/* one for each uCode image (inst/data, boot/init/runtime) */ +struct fw_desc { + dma_addr_t p_addr; /* hardware address */ + void *v_addr; /* software address */ + u32 len; /* size in bytes */ +}; + +struct fw_img { + struct fw_desc code; /* firmware code image */ + struct fw_desc data; /* firmware data image */ +}; + /** * struct iwl_trans_ops - transport specific operations * @start_hw: starts the HW- from that point on, the HW can send interrupts * @stop_hw: stops the HW- from that point on, the HW will be in low power but * will still issue interrupt if the HW RF kill is triggered. - * @start_device: allocates and inits all the resources for the transport - * layer. + * @start_fw: allocates and inits all the resources for the transport + * layer. Also kick a fw image. This handler may sleep. * @fw_alive: called when the fw sends alive notification * @wake_any_queue: wake all the queues of a specfic context IWL_RXON_CTX_* * @stop_device:stops the whole device (embedded CPU put to reset) @@ -148,7 +160,6 @@ struct iwl_host_cmd { * @tx_agg_setup: setup a tx queue for AMPDU - will be called once the HW is * ready and a successful ADDBA response has been received. * @tx_agg_disable: de-configure a Tx queue to send AMPDUs - * @kick_nic: remove the RESET from the embedded CPU and let it run * @free: release all the ressource for the transport layer itself such as * irq, tasklet etc... * @stop_queue: stop a specific queue @@ -166,7 +177,7 @@ struct iwl_trans_ops { int (*start_hw)(struct iwl_trans *iwl_trans); void (*stop_hw)(struct iwl_trans *iwl_trans); - int (*start_device)(struct iwl_trans *trans); + int (*start_fw)(struct iwl_trans *trans, struct fw_img *fw); void (*fw_alive)(struct iwl_trans *trans); void (*stop_device)(struct iwl_trans *trans); @@ -191,8 +202,6 @@ struct iwl_trans_ops { enum iwl_rxon_context_id ctx, int sta_id, int tid, int frame_limit, u16 ssn); - void (*kick_nic)(struct iwl_trans *trans); - void (*free)(struct iwl_trans *trans); void (*stop_queue)(struct iwl_trans *trans, int q, const char *msg); @@ -209,18 +218,6 @@ struct iwl_trans_ops { u32 (*read32)(struct iwl_trans *trans, u32 ofs); }; -/* one for each uCode image (inst/data, boot/init/runtime) */ -struct fw_desc { - dma_addr_t p_addr; /* hardware address */ - void *v_addr; /* software address */ - u32 len; /* size in bytes */ -}; - -struct fw_img { - struct fw_desc code; /* firmware code image */ - struct fw_desc data; /* firmware data image */ -}; - /* Opaque calibration results */ struct iwl_calib_result { struct list_head list; @@ -284,9 +281,11 @@ static inline void iwl_trans_fw_alive(struct iwl_trans *trans) trans->ops->fw_alive(trans); } -static inline int iwl_trans_start_device(struct iwl_trans *trans) +static inline int iwl_trans_start_fw(struct iwl_trans *trans, struct fw_img *fw) { - return trans->ops->start_device(trans); + might_sleep(); + + return trans->ops->start_fw(trans, fw); } static inline void iwl_trans_stop_device(struct iwl_trans *trans) @@ -347,11 +346,6 @@ static inline void iwl_trans_tx_agg_setup(struct iwl_trans *trans, trans->ops->tx_agg_setup(trans, ctx, sta_id, tid, frame_limit, ssn); } -static inline void iwl_trans_kick_nic(struct iwl_trans *trans) -{ - trans->ops->kick_nic(trans); -} - static inline void iwl_trans_free(struct iwl_trans *trans) { trans->ops->free(trans); diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 793524a3ed7..87ce587d7d5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -120,58 +120,6 @@ int iwl_alloc_fw_desc(struct iwl_trans *trans, struct fw_desc *desc, return 0; } -/* - * ucode - */ -static int iwl_load_section(struct iwl_trans *trans, const char *name, - struct fw_desc *image, u32 dst_addr) -{ - dma_addr_t phy_addr = image->p_addr; - u32 byte_cnt = image->len; - int ret; - - trans->ucode_write_complete = 0; - - iwl_write_direct32(trans, - FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), - FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE); - - iwl_write_direct32(trans, - FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr); - - iwl_write_direct32(trans, - FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL), - phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK); - - iwl_write_direct32(trans, - FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL), - (iwl_get_dma_hi_addr(phy_addr) - << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt); - - iwl_write_direct32(trans, - FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL), - 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM | - 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX | - FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID); - - iwl_write_direct32(trans, - FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), - FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | - FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | - FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); - - IWL_DEBUG_FW(trans, "%s uCode section being loaded...\n", name); - ret = wait_event_timeout(trans->shrd->wait_command_queue, - trans->ucode_write_complete, 5 * HZ); - if (!ret) { - IWL_ERR(trans, "Could not load the %s uCode section\n", - name); - return -ETIMEDOUT; - } - - return 0; -} - static inline struct fw_img *iwl_get_ucode_image(struct iwl_trans *trans, enum iwl_ucode_type ucode_type) { @@ -188,28 +136,6 @@ static inline struct fw_img *iwl_get_ucode_image(struct iwl_trans *trans, return NULL; } -static int iwl_load_given_ucode(struct iwl_trans *trans, - enum iwl_ucode_type ucode_type) -{ - int ret = 0; - struct fw_img *image = iwl_get_ucode_image(trans, ucode_type); - - - if (!image) { - IWL_ERR(trans, "Invalid ucode requested (%d)\n", - ucode_type); - return -EINVAL; - } - - ret = iwl_load_section(trans, "INST", &image->code, - IWLAGN_RTC_INST_LOWER_BOUND); - if (ret) - return ret; - - return iwl_load_section(trans, "DATA", &image->data, - IWLAGN_RTC_DATA_LOWER_BOUND); -} - /* * Calibration */ @@ -646,28 +572,27 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans, { struct iwl_notification_wait alive_wait; struct iwl_alive_data alive_data; + struct fw_img *fw; int ret; enum iwl_ucode_type old_type; - ret = iwl_trans_start_device(trans); - if (ret) - return ret; - iwl_init_notification_wait(trans->shrd, &alive_wait, REPLY_ALIVE, iwl_alive_fn, &alive_data); old_type = trans->shrd->ucode_type; trans->shrd->ucode_type = ucode_type; + fw = iwl_get_ucode_image(trans, ucode_type); - ret = iwl_load_given_ucode(trans, ucode_type); + if (!fw) + return -EINVAL; + + ret = iwl_trans_start_fw(trans, fw); if (ret) { trans->shrd->ucode_type = old_type; iwl_remove_notification(trans->shrd, &alive_wait); return ret; } - iwl_trans_kick_nic(trans); - /* * Some things may run in the background now, but we * just wait for the ALIVE notification here. -- cgit v1.2.3-70-g09d2 From af634bee8c4a15629da5e114c491acb8ee50e1e9 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 8 Jan 2012 21:12:22 +0200 Subject: iwlwifi: kill bus_apm_config This handler was called from the transport layer only. Merge it to the transport's apm_init. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-bus.h | 7 ---- drivers/net/wireless/iwlwifi/iwl-pci.c | 29 ---------------- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 50 ++++++++++++++++++++++++--- 3 files changed, 46 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-bus.h b/drivers/net/wireless/iwlwifi/iwl-bus.h index 2065c5b7416..d385f692ef1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-bus.h +++ b/drivers/net/wireless/iwlwifi/iwl-bus.h @@ -121,13 +121,11 @@ struct iwl_bus; /** * struct iwl_bus_ops - bus specific operations * @get_pm_support: must returns true if the bus can go to sleep - * @apm_config: will be called during the config of the APM * @get_hw_id_string: prints the hw_id in the provided buffer * @get_hw_id: get hw_id in u32 */ struct iwl_bus_ops { bool (*get_pm_support)(struct iwl_bus *bus); - void (*apm_config)(struct iwl_bus *bus); void (*get_hw_id_string)(struct iwl_bus *bus, char buf[], int buf_len); u32 (*get_hw_id)(struct iwl_bus *bus); }; @@ -156,11 +154,6 @@ static inline bool bus_get_pm_support(struct iwl_bus *bus) return bus->ops->get_pm_support(bus); } -static inline void bus_apm_config(struct iwl_bus *bus) -{ - bus->ops->apm_config(bus); -} - static inline void bus_get_hw_id_string(struct iwl_bus *bus, char buf[], int buf_len) { diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 6451739aed2..353022d406e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -106,34 +106,6 @@ static bool iwl_pci_is_pm_supported(struct iwl_bus *bus) return !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN); } -static void iwl_pci_apm_config(struct iwl_bus *bus) -{ - /* - * HW bug W/A for instability in PCIe bus L0S->L1 transition. - * Check if BIOS (or OS) enabled L1-ASPM on this device. - * If so (likely), disable L0S, so device moves directly L0->L1; - * costs negligible amount of power savings. - * If not (unlikely), enable L0S, so there is at least some - * power savings, even without L1. - */ - u16 lctl = iwl_pciexp_link_ctrl(bus); - - if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == - PCI_CFG_LINK_CTRL_VAL_L1_EN) { - /* L1-ASPM enabled; disable(!) L0S */ - iwl_set_bit(trans(bus), CSR_GIO_REG, - CSR_GIO_REG_VAL_L0S_ENABLED); - dev_printk(KERN_INFO, trans(bus)->dev, - "L1 Enabled; Disabling L0S\n"); - } else { - /* L1-ASPM disabled; enable(!) L0S */ - iwl_clear_bit(trans(bus), CSR_GIO_REG, - CSR_GIO_REG_VAL_L0S_ENABLED); - dev_printk(KERN_INFO, trans(bus)->dev, - "L1 Disabled; Enabling L0S\n"); - } -} - static void iwl_pci_get_hw_id_string(struct iwl_bus *bus, char buf[], int buf_len) { @@ -152,7 +124,6 @@ static u32 iwl_pci_get_hw_id(struct iwl_bus *bus) static const struct iwl_bus_ops bus_ops_pci = { .get_pm_support = iwl_pci_is_pm_supported, - .apm_config = iwl_pci_apm_config, .get_hw_id_string = iwl_pci_get_hw_id_string, .get_hw_id = iwl_pci_get_hw_id, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 1030a252405..c9fe8889ad8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -633,6 +633,51 @@ static void iwl_set_pwr_vmain(struct iwl_trans *trans) ~APMG_PS_CTRL_MSK_PWR_SRC); } +/* PCI registers */ +#define PCI_CFG_RETRY_TIMEOUT 0x041 +#define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01 +#define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02 + +static u16 iwl_pciexp_link_ctrl(struct iwl_trans *trans) +{ + int pos; + u16 pci_lnk_ctl; + struct iwl_trans_pcie *trans_pcie = + IWL_TRANS_GET_PCIE_TRANS(trans); + + struct pci_dev *pci_dev = trans_pcie->pci_dev; + + pos = pci_pcie_cap(pci_dev); + pci_read_config_word(pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl); + return pci_lnk_ctl; +} + +static void iwl_apm_config(struct iwl_trans *trans) +{ + /* + * HW bug W/A for instability in PCIe bus L0S->L1 transition. + * Check if BIOS (or OS) enabled L1-ASPM on this device. + * If so (likely), disable L0S, so device moves directly L0->L1; + * costs negligible amount of power savings. + * If not (unlikely), enable L0S, so there is at least some + * power savings, even without L1. + */ + u16 lctl = iwl_pciexp_link_ctrl(trans); + + if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == + PCI_CFG_LINK_CTRL_VAL_L1_EN) { + /* L1-ASPM enabled; disable(!) L0S */ + iwl_set_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); + dev_printk(KERN_INFO, trans->dev, + "L1 Enabled; Disabling L0S\n"); + } else { + /* L1-ASPM disabled; enable(!) L0S */ + iwl_clear_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); + dev_printk(KERN_INFO, trans->dev, + "L1 Disabled; Enabling L0S\n"); + } +} + /* * Start up NIC's basic functionality after it has been reset * (e.g. after platform boot, or shutdown via iwl_apm_stop()) @@ -669,7 +714,7 @@ static int iwl_apm_init(struct iwl_trans *trans) iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); - bus_apm_config(bus(trans)); + iwl_apm_config(trans); /* Configure analog phase-lock-loop before activating to D0A */ if (cfg(trans)->base_params->pll_cfg_val) @@ -2187,9 +2232,6 @@ const struct iwl_trans_ops trans_ops_pcie = { .read32 = iwl_trans_pcie_read32, }; -/* PCI registers */ -#define PCI_CFG_RETRY_TIMEOUT 0x041 - struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, struct pci_dev *pdev, const struct pci_device_id *ent) -- cgit v1.2.3-70-g09d2 From f6d0e9be6580ba607f730d7e056518c95a864601 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 8 Jan 2012 21:19:45 +0200 Subject: iwlwifi: kill bus_is_pm_supported Get this information from the transport layer which is now in charge of the APM too. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-bus.h | 7 ------- drivers/net/wireless/iwlwifi/iwl-pci.c | 20 -------------------- drivers/net/wireless/iwlwifi/iwl-power.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 1 + drivers/net/wireless/iwlwifi/iwl-trans.h | 2 ++ 5 files changed, 4 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-bus.h b/drivers/net/wireless/iwlwifi/iwl-bus.h index d385f692ef1..2b0b48edf28 100644 --- a/drivers/net/wireless/iwlwifi/iwl-bus.h +++ b/drivers/net/wireless/iwlwifi/iwl-bus.h @@ -120,12 +120,10 @@ struct iwl_bus; /** * struct iwl_bus_ops - bus specific operations - * @get_pm_support: must returns true if the bus can go to sleep * @get_hw_id_string: prints the hw_id in the provided buffer * @get_hw_id: get hw_id in u32 */ struct iwl_bus_ops { - bool (*get_pm_support)(struct iwl_bus *bus); void (*get_hw_id_string)(struct iwl_bus *bus, char buf[], int buf_len); u32 (*get_hw_id)(struct iwl_bus *bus); }; @@ -149,11 +147,6 @@ struct iwl_bus { char bus_specific[0] __attribute__((__aligned__(sizeof(void *)))); }; -static inline bool bus_get_pm_support(struct iwl_bus *bus) -{ - return bus->ops->get_pm_support(bus); -} - static inline void bus_get_hw_id_string(struct iwl_bus *bus, char buf[], int buf_len) { diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 353022d406e..0c16efebf93 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -87,25 +87,6 @@ struct iwl_pci_bus { #define IWL_BUS_GET_PCI_DEV(_iwl_bus) \ ((IWL_BUS_GET_PCI_BUS(_iwl_bus))->pci_dev) -static u16 iwl_pciexp_link_ctrl(struct iwl_bus *bus) -{ - int pos; - u16 pci_lnk_ctl; - - struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); - - pos = pci_pcie_cap(pci_dev); - pci_read_config_word(pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl); - return pci_lnk_ctl; -} - -static bool iwl_pci_is_pm_supported(struct iwl_bus *bus) -{ - u16 lctl = iwl_pciexp_link_ctrl(bus); - - return !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN); -} - static void iwl_pci_get_hw_id_string(struct iwl_bus *bus, char buf[], int buf_len) { @@ -123,7 +104,6 @@ static u32 iwl_pci_get_hw_id(struct iwl_bus *bus) } static const struct iwl_bus_ops bus_ops_pci = { - .get_pm_support = iwl_pci_is_pm_supported, .get_hw_id_string = iwl_pci_get_hw_id_string, .get_hw_id = iwl_pci_get_hw_id, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index c7394ef2e49..fd008c4e41f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -436,7 +436,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force) /* initialize to default */ void iwl_power_initialize(struct iwl_priv *priv) { - priv->power_data.bus_pm = bus_get_pm_support(bus(priv)); + priv->power_data.bus_pm = trans(priv)->pm_support; priv->power_data.debug_sleep_level_override = -1; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index c9fe8889ad8..8ebb5a54441 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -676,6 +676,7 @@ static void iwl_apm_config(struct iwl_trans *trans) dev_printk(KERN_INFO, trans->dev, "L1 Disabled; Enabling L0S\n"); } + trans->pm_support = !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN); } /* diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 4d1ae65b68e..7f6963ffa7c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -239,6 +239,7 @@ struct iwl_calib_result { * @ucode_init: init ucode image * @ucode_wowlan: wake on wireless ucode image (optional) * @nvm_device_type: indicates OTP or eeprom + * @pm_support: set to true in start_hw if link pm is supported * @calib_results: list head for init calibration results */ struct iwl_trans { @@ -257,6 +258,7 @@ struct iwl_trans { /* eeprom related variables */ int nvm_device_type; + bool pm_support; /* init calibration results */ struct list_head calib_results; -- cgit v1.2.3-70-g09d2 From 9ca859615212deb7dd0aee26972799d1910d050f Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 8 Jan 2012 21:19:45 +0200 Subject: iwlwifi: kill bus_get_hw_id_string Get this information from the transport layer. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-bus.h | 8 -------- drivers/net/wireless/iwlwifi/iwl-core.c | 5 ++--- drivers/net/wireless/iwlwifi/iwl-pci.c | 10 ---------- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 2 ++ drivers/net/wireless/iwlwifi/iwl-trans.h | 2 ++ 5 files changed, 6 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-bus.h b/drivers/net/wireless/iwlwifi/iwl-bus.h index 2b0b48edf28..61130895428 100644 --- a/drivers/net/wireless/iwlwifi/iwl-bus.h +++ b/drivers/net/wireless/iwlwifi/iwl-bus.h @@ -120,11 +120,9 @@ struct iwl_bus; /** * struct iwl_bus_ops - bus specific operations - * @get_hw_id_string: prints the hw_id in the provided buffer * @get_hw_id: get hw_id in u32 */ struct iwl_bus_ops { - void (*get_hw_id_string)(struct iwl_bus *bus, char buf[], int buf_len); u32 (*get_hw_id)(struct iwl_bus *bus); }; @@ -147,12 +145,6 @@ struct iwl_bus { char bus_specific[0] __attribute__((__aligned__(sizeof(void *)))); }; -static inline void bus_get_hw_id_string(struct iwl_bus *bus, char buf[], - int buf_len) -{ - bus->ops->get_hw_id_string(bus, buf, buf_len); -} - static inline u32 bus_get_hw_id(struct iwl_bus *bus) { return bus->ops->get_hw_id(bus); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 95f2c33695b..0677b3dfbfb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -203,10 +203,9 @@ int iwl_init_geos(struct iwl_priv *priv) if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && cfg(priv)->sku & EEPROM_SKU_CAP_BAND_52GHZ) { - char buf[32]; - bus_get_hw_id_string(bus(priv), buf, sizeof(buf)); IWL_INFO(priv, "Incorrectly detected BG card as ABG. " - "Please send your %s to maintainer.\n", buf); + "Please send your %s to maintainer.\n", + trans(priv)->hw_id_str); cfg(priv)->sku &= ~EEPROM_SKU_CAP_BAND_52GHZ; } diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 0c16efebf93..15864760733 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -87,15 +87,6 @@ struct iwl_pci_bus { #define IWL_BUS_GET_PCI_DEV(_iwl_bus) \ ((IWL_BUS_GET_PCI_BUS(_iwl_bus))->pci_dev) -static void iwl_pci_get_hw_id_string(struct iwl_bus *bus, char buf[], - int buf_len) -{ - struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); - - snprintf(buf, buf_len, "PCI ID: 0x%04X:0x%04X", pci_dev->device, - pci_dev->subsystem_device); -} - static u32 iwl_pci_get_hw_id(struct iwl_bus *bus) { struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); @@ -104,7 +95,6 @@ static u32 iwl_pci_get_hw_id(struct iwl_bus *bus) } static const struct iwl_bus_ops bus_ops_pci = { - .get_hw_id_string = iwl_pci_get_hw_id_string, .get_hw_id = iwl_pci_get_hw_id, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 8ebb5a54441..73ff68ac7c4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -2317,6 +2317,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, trans->dev = &pdev->dev; trans->irq = pdev->irq; trans_pcie->pci_dev = pdev; + snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), + "PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device); /* TODO: Move this away, not needed if not MSI */ /* enable rfkill interrupt: hw bug w/a */ diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 7f6963ffa7c..593102d89c7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -234,6 +234,7 @@ struct iwl_calib_result { * @reg_lock - protect hw register access * @dev - pointer to struct device * that represents the device * @irq - the irq number for the device + * @hw_id_str: a string with info about HW ID. Set during transport allocation. * @ucode_write_complete: indicates that the ucode has been copied. * @ucode_rt: run time ucode image * @ucode_init: init ucode image @@ -250,6 +251,7 @@ struct iwl_trans { struct device *dev; unsigned int irq; + char hw_id_str[52]; u8 ucode_write_complete; /* the image write is complete */ struct fw_img ucode_rt; -- cgit v1.2.3-70-g09d2 From 99673ee556fce2fb973eaa571adb12663330caa9 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 8 Jan 2012 21:19:45 +0200 Subject: iwlwifi: kill bus_get_hw_id Get this information from the transport layer. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-bus.h | 14 ---------- drivers/net/wireless/iwlwifi/iwl-mac80211.c | 2 +- drivers/net/wireless/iwlwifi/iwl-pci.c | 37 +++------------------------ drivers/net/wireless/iwlwifi/iwl-testmode.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 1 + drivers/net/wireless/iwlwifi/iwl-trans.h | 3 +++ 6 files changed, 10 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-bus.h b/drivers/net/wireless/iwlwifi/iwl-bus.h index 61130895428..30965e0e8ab 100644 --- a/drivers/net/wireless/iwlwifi/iwl-bus.h +++ b/drivers/net/wireless/iwlwifi/iwl-bus.h @@ -118,14 +118,6 @@ struct iwl_shared; struct iwl_bus; -/** - * struct iwl_bus_ops - bus specific operations - * @get_hw_id: get hw_id in u32 - */ -struct iwl_bus_ops { - u32 (*get_hw_id)(struct iwl_bus *bus); -}; - /** * struct iwl_bus - bus common data * @@ -137,7 +129,6 @@ struct iwl_bus_ops { * it allocates the shared data */ struct iwl_bus { - const struct iwl_bus_ops *ops; struct iwl_shared *shrd; /* pointer to bus specific struct */ @@ -145,11 +136,6 @@ struct iwl_bus { char bus_specific[0] __attribute__((__aligned__(sizeof(void *)))); }; -static inline u32 bus_get_hw_id(struct iwl_bus *bus) -{ - return bus->ops->get_hw_id(bus); -} - /***************************************************** * Bus layer registration functions ******************************************************/ diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index b911837b04f..78bc1e857b0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -234,7 +234,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &priv->bands[IEEE80211_BAND_5GHZ]; - hw->wiphy->hw_version = bus_get_hw_id(bus(priv)); + hw->wiphy->hw_version = trans(priv)->hw_id; iwl_leds_init(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 15864760733..3e2fce4ce00 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -71,33 +71,6 @@ #include "iwl-csr.h" #include "iwl-cfg.h" -/* PCI registers */ -#define PCI_CFG_RETRY_TIMEOUT 0x041 -#define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01 -#define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02 - -struct iwl_pci_bus { - /* basic pci-network driver stuff */ - struct pci_dev *pci_dev; -}; - -#define IWL_BUS_GET_PCI_BUS(_iwl_bus) \ - ((struct iwl_pci_bus *) ((_iwl_bus)->bus_specific)) - -#define IWL_BUS_GET_PCI_DEV(_iwl_bus) \ - ((IWL_BUS_GET_PCI_BUS(_iwl_bus))->pci_dev) - -static u32 iwl_pci_get_hw_id(struct iwl_bus *bus) -{ - struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); - - return (pci_dev->device << 16) + pci_dev->subsystem_device; -} - -static const struct iwl_bus_ops bus_ops_pci = { - .get_hw_id = iwl_pci_get_hw_id, -}; - #define IWL_PCI_DEVICE(dev, subdev, cfg) \ .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \ .subvendor = PCI_ANY_ID, .subdevice = (subdev), \ @@ -283,14 +256,16 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { }; MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); +/* PCI registers */ +#define PCI_CFG_RETRY_TIMEOUT 0x041 + static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); struct iwl_bus *bus; - struct iwl_pci_bus *pci_bus; int err; - bus = kzalloc(sizeof(*bus) + sizeof(*pci_bus), GFP_KERNEL); + bus = kzalloc(sizeof(*bus), GFP_KERNEL); if (!bus) { dev_printk(KERN_ERR, &pdev->dev, "Couldn't allocate iwl_pci_bus"); @@ -306,13 +281,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } bus->shrd->bus = bus; - pci_bus = IWL_BUS_GET_PCI_BUS(bus); - pci_bus->pci_dev = pdev; pci_set_drvdata(pdev, bus); - bus->ops = &bus_ops_pci; - #ifdef CONFIG_IWLWIFI_IDI trans(bus) = iwl_trans_idi_alloc(bus->shrd, pdev, ent); if (trans(bus) == NULL) { diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index 922d841faba..7c17b9d5217 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -536,7 +536,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) break; case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: - devid = bus_get_hw_id(bus(priv)); + devid = trans(priv)->hw_id; IWL_INFO(priv, "hw version: 0x%x\n", devid); skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 73ff68ac7c4..4b711b790a9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -2317,6 +2317,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, trans->dev = &pdev->dev; trans->irq = pdev->irq; trans_pcie->pci_dev = pdev; + trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), "PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 593102d89c7..0359d71e554 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -234,6 +234,8 @@ struct iwl_calib_result { * @reg_lock - protect hw register access * @dev - pointer to struct device * that represents the device * @irq - the irq number for the device + * @hw_id: a u32 with the ID of the device / subdevice. + * Set during transport alloaction. * @hw_id_str: a string with info about HW ID. Set during transport allocation. * @ucode_write_complete: indicates that the ucode has been copied. * @ucode_rt: run time ucode image @@ -251,6 +253,7 @@ struct iwl_trans { struct device *dev; unsigned int irq; + u32 hw_id; char hw_id_str[52]; u8 ucode_write_complete; /* the image write is complete */ -- cgit v1.2.3-70-g09d2 From 08079a4919ca960c0f46d244cae3a6ec2c39041d Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 9 Jan 2012 16:23:00 +0200 Subject: iwlwifi: move hw_rev to transport layer The HW revision is now read by the transport layer in its allocation. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 13 ++----------- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 1 + drivers/net/wireless/iwlwifi/iwl-trans.h | 1 + 3 files changed, 4 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 14f8b750c7c..36f7adeb176 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1691,13 +1691,6 @@ static void iwl_uninit_drv(struct iwl_priv *priv) #endif } - - -static u32 iwl_hw_detect(struct iwl_priv *priv) -{ - return iwl_read32(trans(priv), CSR_HW_REV); -} - /* Size of one Rx buffer in host DRAM */ #define IWL_RX_BUF_SIZE_4K (4 * 1024) #define IWL_RX_BUF_SIZE_8K (8 * 1024) @@ -1769,7 +1762,6 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, struct iwl_priv *priv; struct ieee80211_hw *hw; u16 num_mac; - u32 hw_rev; /************************ * 1. Allocating HW data @@ -1818,9 +1810,8 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, /*********************** * 3. Read REV register ***********************/ - hw_rev = iwl_hw_detect(priv); IWL_INFO(priv, "Detected %s, REV=0x%X\n", - cfg(priv)->name, hw_rev); + cfg(priv)->name, trans(priv)->hw_rev); err = iwl_trans_start_hw(trans(priv)); if (err) @@ -1830,7 +1821,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, * 4. Read EEPROM *****************/ /* Read the EEPROM */ - err = iwl_eeprom_init(priv, hw_rev); + err = iwl_eeprom_init(priv, trans(priv)->hw_rev); /* Reset chip to save power until we load uCode during "up". */ iwl_trans_stop_hw(trans(priv)); if (err) { diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 4b711b790a9..ed2a9216d80 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -2317,6 +2317,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, trans->dev = &pdev->dev; trans->irq = pdev->irq; trans_pcie->pci_dev = pdev; + trans->hw_rev = iwl_read32(trans, CSR_HW_REV); trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), "PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 0359d71e554..a305e96d82a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -253,6 +253,7 @@ struct iwl_trans { struct device *dev; unsigned int irq; + u32 hw_rev; u32 hw_id; char hw_id_str[52]; -- cgit v1.2.3-70-g09d2 From 1df06bdc6fb26d13af18c5dbb3144f13cf55de3c Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 9 Jan 2012 16:35:08 +0200 Subject: iwlwifi: stop_hw replace enable_rfkill_int This trans_ops->stop_hw leaves the RFKILL interrupt enabled, we can call that one instead of enable_rfkill_int. By that, we reduce the numbers of acceesses to the NIC from the upper layers. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-core.h | 6 ------ drivers/net/wireless/iwlwifi/iwl-mac80211.c | 7 ++++--- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 6 ++++-- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 2 ++ 4 files changed, 10 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index e74bfb7bbb2..8d60dcf6f2e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -297,12 +297,6 @@ static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv) cfg(priv)->bt_params->advanced_bt_coexist; } -static inline void iwl_enable_rfkill_int(struct iwl_priv *priv) -{ - IWL_DEBUG_ISR(priv, "Enabling rfkill interrupt\n"); - iwl_write32(trans(priv), CSR_INT_MASK, CSR_INT_BIT_RF_KILL); -} - extern bool bt_siso_mode; #endif /* __iwl_core_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 78bc1e857b0..7177fd76e28 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -346,9 +346,10 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw) flush_workqueue(priv->shrd->workqueue); /* User space software may expect getting rfkill changes - * even if interface is down */ - iwl_write32(trans(priv), CSR_INT, 0xFFFFFFFF); - iwl_enable_rfkill_int(priv); + * even if interface is down, trans->down will leave the RF + * kill interrupt enabled + */ + iwl_trans_stop_hw(trans(priv)); IWL_DEBUG_MAC80211(priv, "leave\n"); } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 731f287c0f3..78abff00453 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -1149,8 +1149,10 @@ void iwl_irq_tasklet(struct iwl_trans *trans) if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status)) iwl_enable_interrupts(trans); /* Re-enable RF_KILL if it occurred */ - else if (handled & CSR_INT_BIT_RF_KILL) - iwl_enable_rfkill_int(priv(trans)); + else if (handled & CSR_INT_BIT_RF_KILL) { + IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n"); + iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL); + } } /****************************************************************************** diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index ed2a9216d80..ec26950ebb5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1532,6 +1532,8 @@ static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans) { iwl_apm_stop(trans); + iwl_write32(trans, CSR_INT, 0xFFFFFFFF); + /* Even if we stop the HW, we still want the RF kill interrupt */ IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n"); iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL); -- cgit v1.2.3-70-g09d2 From 1dcedc8e07902b32027e4cf00dc8150774a492e2 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 19 Jan 2012 08:27:03 +0200 Subject: iwlwifi: debug print in tx_queue_set_status is more clear The message was misleading when a queue is deactivated. The fifo number is irrelevant then, so don't print it. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 5e095ac5076..08e0a7da48a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -431,9 +431,12 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, txq->sched_retry = scd_retry; - IWL_DEBUG_TX_QUEUES(trans, "%s %s Queue %d on FIFO %d\n", - active ? "Activate" : "Deactivate", - scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id); + if (active) + IWL_DEBUG_TX_QUEUES(trans, "Activate %s Queue %d on FIFO %d\n", + scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id); + else + IWL_DEBUG_TX_QUEUES(trans, "Deactivate %s Queue %d\n", + scd_retry ? "BA" : "AC/CMD", txq_id); } static inline int get_fifo_from_tid(struct iwl_trans_pcie *trans_pcie, -- cgit v1.2.3-70-g09d2 From 1589c5629c336dbb813accec03619940695339ec Mon Sep 17 00:00:00 2001 From: Don Fry Date: Fri, 27 Jan 2012 13:15:54 -0800 Subject: iwlwifi: clarify comment change a comment to be a little more clear Signed-off-by: Don Fry Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 36f7adeb176..82f8836f304 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1781,7 +1781,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, SET_IEEE80211_DEV(hw, trans(priv)->dev); - /* what debugging capabilities we have */ + /* show what debugging capabilities we have */ iwl_debug_config(priv); IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); -- cgit v1.2.3-70-g09d2 From 87272af74e98225672c9165a20b0604a7db758cf Mon Sep 17 00:00:00 2001 From: Don Fry Date: Wed, 25 Jan 2012 15:26:34 -0800 Subject: iwlwifi: move bcast_sta_id init to common routine There is nothing device specific in the initialization of the bcast_sta_id so move it to the common inititalization routine. Signed-off-by: Don Fry Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-2000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-5000.c | 4 ---- drivers/net/wireless/iwlwifi/iwl-6000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-agn.c | 1 + 5 files changed, 1 insertion(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index f7a555b9d24..8c1466c907f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -128,8 +128,6 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) iwlagn_mod_params.num_of_queues; hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; - priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; - hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE; hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE; diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 87600345010..d4f5f3b8757 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -124,8 +124,6 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv) iwlagn_mod_params.num_of_queues; hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; - priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; - hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE; hw_params(priv).max_inst_size = IWL60_RTC_INST_SIZE; diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 5245a1422a6..dc9317d0343 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -170,8 +170,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) iwlagn_mod_params.num_of_queues; hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; - priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; - hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE; hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE; @@ -199,8 +197,6 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv) iwlagn_mod_params.num_of_queues; hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; - priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; - hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE; hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE; diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 464b8878467..c36fb858a45 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -145,8 +145,6 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) iwlagn_mod_params.num_of_queues; hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; - priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; - hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE; hw_params(priv).max_inst_size = IWL60_RTC_INST_SIZE; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 82f8836f304..c41c394de2c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -513,6 +513,7 @@ static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; + priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes = BIT(NL80211_IFTYPE_ADHOC); priv->contexts[IWL_RXON_CTX_BSS].interface_modes = -- cgit v1.2.3-70-g09d2 From edf38334061cb87c68cfc7fdc192c850b7e02320 Mon Sep 17 00:00:00 2001 From: Don Fry Date: Wed, 25 Jan 2012 16:18:52 -0800 Subject: iwlwifi: move all ucode routines to iwl-ucode.c The routines dealing with the ucode are spread through several files. Move them all to the same file and create a iwl-ucode.h file with the ucode file definitions. Signed-off-by: Don Fry Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 609 +-------------------------- drivers/net/wireless/iwlwifi/iwl-agn.h | 1 + drivers/net/wireless/iwlwifi/iwl-dev.h | 108 ----- drivers/net/wireless/iwlwifi/iwl-mac80211.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans.h | 2 - drivers/net/wireless/iwlwifi/iwl-ucode.c | 610 +++++++++++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-ucode.h | 178 ++++++++ 7 files changed, 791 insertions(+), 719 deletions(-) create mode 100644 drivers/net/wireless/iwlwifi/iwl-ucode.h (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index c41c394de2c..8837171ad55 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include @@ -42,6 +41,7 @@ #include +#include "iwl-ucode.h" #include "iwl-eeprom.h" #include "iwl-wifi.h" #include "iwl-dev.h" @@ -490,7 +490,7 @@ static void iwl_bg_tx_flush(struct work_struct *work) iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); } -static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) +void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) { int i; @@ -548,611 +548,6 @@ static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); } -static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); - -#define UCODE_EXPERIMENTAL_INDEX 100 -#define UCODE_EXPERIMENTAL_TAG "exp" - -static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first) -{ - const char *name_pre = cfg(priv)->fw_name_pre; - char tag[8]; - - if (first) { -#ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE - priv->fw_index = UCODE_EXPERIMENTAL_INDEX; - strcpy(tag, UCODE_EXPERIMENTAL_TAG); - } else if (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) { -#endif - priv->fw_index = cfg(priv)->ucode_api_max; - sprintf(tag, "%d", priv->fw_index); - } else { - priv->fw_index--; - sprintf(tag, "%d", priv->fw_index); - } - - if (priv->fw_index < cfg(priv)->ucode_api_min) { - IWL_ERR(priv, "no suitable firmware found!\n"); - return -ENOENT; - } - - sprintf(priv->firmware_name, "%s%s%s", name_pre, tag, ".ucode"); - - IWL_DEBUG_INFO(priv, "attempting to load firmware %s'%s'\n", - (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) - ? "EXPERIMENTAL " : "", - priv->firmware_name); - - return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name, - trans(priv)->dev, - GFP_KERNEL, priv, iwl_ucode_callback); -} - -struct iwlagn_firmware_pieces { - const void *inst, *data, *init, *init_data, *wowlan_inst, *wowlan_data; - size_t inst_size, data_size, init_size, init_data_size, - wowlan_inst_size, wowlan_data_size; - - u32 build; - - u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; - u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; -}; - -static int iwlagn_load_legacy_firmware(struct iwl_priv *priv, - const struct firmware *ucode_raw, - struct iwlagn_firmware_pieces *pieces) -{ - struct iwl_ucode_header *ucode = (void *)ucode_raw->data; - u32 api_ver, hdr_size; - const u8 *src; - - priv->ucode_ver = le32_to_cpu(ucode->ver); - api_ver = IWL_UCODE_API(priv->ucode_ver); - - switch (api_ver) { - default: - hdr_size = 28; - if (ucode_raw->size < hdr_size) { - IWL_ERR(priv, "File size too small!\n"); - return -EINVAL; - } - pieces->build = le32_to_cpu(ucode->u.v2.build); - pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size); - pieces->data_size = le32_to_cpu(ucode->u.v2.data_size); - pieces->init_size = le32_to_cpu(ucode->u.v2.init_size); - pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size); - src = ucode->u.v2.data; - break; - case 0: - case 1: - case 2: - hdr_size = 24; - if (ucode_raw->size < hdr_size) { - IWL_ERR(priv, "File size too small!\n"); - return -EINVAL; - } - pieces->build = 0; - pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size); - pieces->data_size = le32_to_cpu(ucode->u.v1.data_size); - pieces->init_size = le32_to_cpu(ucode->u.v1.init_size); - pieces->init_data_size = le32_to_cpu(ucode->u.v1.init_data_size); - src = ucode->u.v1.data; - break; - } - - /* Verify size of file vs. image size info in file's header */ - if (ucode_raw->size != hdr_size + pieces->inst_size + - pieces->data_size + pieces->init_size + - pieces->init_data_size) { - - IWL_ERR(priv, - "uCode file size %d does not match expected size\n", - (int)ucode_raw->size); - return -EINVAL; - } - - pieces->inst = src; - src += pieces->inst_size; - pieces->data = src; - src += pieces->data_size; - pieces->init = src; - src += pieces->init_size; - pieces->init_data = src; - src += pieces->init_data_size; - - return 0; -} - -static int iwlagn_load_firmware(struct iwl_priv *priv, - const struct firmware *ucode_raw, - struct iwlagn_firmware_pieces *pieces, - struct iwlagn_ucode_capabilities *capa) -{ - struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data; - struct iwl_ucode_tlv *tlv; - size_t len = ucode_raw->size; - const u8 *data; - int wanted_alternative = iwlagn_mod_params.wanted_ucode_alternative; - int tmp; - u64 alternatives; - u32 tlv_len; - enum iwl_ucode_tlv_type tlv_type; - const u8 *tlv_data; - - if (len < sizeof(*ucode)) { - IWL_ERR(priv, "uCode has invalid length: %zd\n", len); - return -EINVAL; - } - - if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) { - IWL_ERR(priv, "invalid uCode magic: 0X%x\n", - le32_to_cpu(ucode->magic)); - return -EINVAL; - } - - /* - * Check which alternatives are present, and "downgrade" - * when the chosen alternative is not present, warning - * the user when that happens. Some files may not have - * any alternatives, so don't warn in that case. - */ - alternatives = le64_to_cpu(ucode->alternatives); - tmp = wanted_alternative; - if (wanted_alternative > 63) - wanted_alternative = 63; - while (wanted_alternative && !(alternatives & BIT(wanted_alternative))) - wanted_alternative--; - if (wanted_alternative && wanted_alternative != tmp) - IWL_WARN(priv, - "uCode alternative %d not available, choosing %d\n", - tmp, wanted_alternative); - - priv->ucode_ver = le32_to_cpu(ucode->ver); - pieces->build = le32_to_cpu(ucode->build); - data = ucode->data; - - len -= sizeof(*ucode); - - while (len >= sizeof(*tlv)) { - u16 tlv_alt; - - len -= sizeof(*tlv); - tlv = (void *)data; - - tlv_len = le32_to_cpu(tlv->length); - tlv_type = le16_to_cpu(tlv->type); - tlv_alt = le16_to_cpu(tlv->alternative); - tlv_data = tlv->data; - - if (len < tlv_len) { - IWL_ERR(priv, "invalid TLV len: %zd/%u\n", - len, tlv_len); - return -EINVAL; - } - len -= ALIGN(tlv_len, 4); - data += sizeof(*tlv) + ALIGN(tlv_len, 4); - - /* - * Alternative 0 is always valid. - * - * Skip alternative TLVs that are not selected. - */ - if (tlv_alt != 0 && tlv_alt != wanted_alternative) - continue; - - switch (tlv_type) { - case IWL_UCODE_TLV_INST: - pieces->inst = tlv_data; - pieces->inst_size = tlv_len; - break; - case IWL_UCODE_TLV_DATA: - pieces->data = tlv_data; - pieces->data_size = tlv_len; - break; - case IWL_UCODE_TLV_INIT: - pieces->init = tlv_data; - pieces->init_size = tlv_len; - break; - case IWL_UCODE_TLV_INIT_DATA: - pieces->init_data = tlv_data; - pieces->init_data_size = tlv_len; - break; - case IWL_UCODE_TLV_BOOT: - IWL_ERR(priv, "Found unexpected BOOT ucode\n"); - break; - case IWL_UCODE_TLV_PROBE_MAX_LEN: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - capa->max_probe_length = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_PAN: - if (tlv_len) - goto invalid_tlv_len; - capa->flags |= IWL_UCODE_TLV_FLAGS_PAN; - break; - case IWL_UCODE_TLV_FLAGS: - /* must be at least one u32 */ - if (tlv_len < sizeof(u32)) - goto invalid_tlv_len; - /* and a proper number of u32s */ - if (tlv_len % sizeof(u32)) - goto invalid_tlv_len; - /* - * This driver only reads the first u32 as - * right now no more features are defined, - * if that changes then either the driver - * will not work with the new firmware, or - * it'll not take advantage of new features. - */ - capa->flags = le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_INIT_EVTLOG_PTR: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->init_evtlog_ptr = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_INIT_EVTLOG_SIZE: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->init_evtlog_size = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_INIT_ERRLOG_PTR: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->init_errlog_ptr = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_RUNT_EVTLOG_PTR: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->inst_evtlog_ptr = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->inst_evtlog_size = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_RUNT_ERRLOG_PTR: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->inst_errlog_ptr = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_ENHANCE_SENS_TBL: - if (tlv_len) - goto invalid_tlv_len; - priv->enhance_sensitivity_table = true; - break; - case IWL_UCODE_TLV_WOWLAN_INST: - pieces->wowlan_inst = tlv_data; - pieces->wowlan_inst_size = tlv_len; - break; - case IWL_UCODE_TLV_WOWLAN_DATA: - pieces->wowlan_data = tlv_data; - pieces->wowlan_data_size = tlv_len; - break; - case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - capa->standard_phy_calibration_size = - le32_to_cpup((__le32 *)tlv_data); - break; - default: - IWL_DEBUG_INFO(priv, "unknown TLV: %d\n", tlv_type); - break; - } - } - - if (len) { - IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len); - iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len); - return -EINVAL; - } - - return 0; - - invalid_tlv_len: - IWL_ERR(priv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); - iwl_print_hex_dump(priv, IWL_DL_FW, tlv_data, tlv_len); - - return -EINVAL; -} - -/** - * iwl_ucode_callback - callback when firmware was loaded - * - * If loaded successfully, copies the firmware into buffers - * for the card to fetch (via DMA). - */ -static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) -{ - struct iwl_priv *priv = context; - struct iwl_ucode_header *ucode; - int err; - struct iwlagn_firmware_pieces pieces; - const unsigned int api_max = cfg(priv)->ucode_api_max; - unsigned int api_ok = cfg(priv)->ucode_api_ok; - const unsigned int api_min = cfg(priv)->ucode_api_min; - u32 api_ver; - char buildstr[25]; - u32 build; - struct iwlagn_ucode_capabilities ucode_capa = { - .max_probe_length = 200, - .standard_phy_calibration_size = - IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE, - }; - - if (!api_ok) - api_ok = api_max; - - memset(&pieces, 0, sizeof(pieces)); - - if (!ucode_raw) { - if (priv->fw_index <= api_ok) - IWL_ERR(priv, - "request for firmware file '%s' failed.\n", - priv->firmware_name); - goto try_again; - } - - IWL_DEBUG_INFO(priv, "Loaded firmware file '%s' (%zd bytes).\n", - priv->firmware_name, ucode_raw->size); - - /* Make sure that we got at least the API version number */ - if (ucode_raw->size < 4) { - IWL_ERR(priv, "File size way too small!\n"); - goto try_again; - } - - /* Data from ucode file: header followed by uCode images */ - ucode = (struct iwl_ucode_header *)ucode_raw->data; - - if (ucode->ver) - err = iwlagn_load_legacy_firmware(priv, ucode_raw, &pieces); - else - err = iwlagn_load_firmware(priv, ucode_raw, &pieces, - &ucode_capa); - - if (err) - goto try_again; - - api_ver = IWL_UCODE_API(priv->ucode_ver); - build = pieces.build; - - /* - * api_ver should match the api version forming part of the - * firmware filename ... but we don't check for that and only rely - * on the API version read from firmware header from here on forward - */ - /* no api version check required for experimental uCode */ - if (priv->fw_index != UCODE_EXPERIMENTAL_INDEX) { - if (api_ver < api_min || api_ver > api_max) { - IWL_ERR(priv, - "Driver unable to support your firmware API. " - "Driver supports v%u, firmware is v%u.\n", - api_max, api_ver); - goto try_again; - } - - if (api_ver < api_ok) { - if (api_ok != api_max) - IWL_ERR(priv, "Firmware has old API version, " - "expected v%u through v%u, got v%u.\n", - api_ok, api_max, api_ver); - else - IWL_ERR(priv, "Firmware has old API version, " - "expected v%u, got v%u.\n", - api_max, api_ver); - IWL_ERR(priv, "New firmware can be obtained from " - "http://www.intellinuxwireless.org/.\n"); - } - } - - if (build) - sprintf(buildstr, " build %u%s", build, - (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) - ? " (EXP)" : ""); - else - buildstr[0] = '\0'; - - IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u%s\n", - IWL_UCODE_MAJOR(priv->ucode_ver), - IWL_UCODE_MINOR(priv->ucode_ver), - IWL_UCODE_API(priv->ucode_ver), - IWL_UCODE_SERIAL(priv->ucode_ver), - buildstr); - - snprintf(priv->hw->wiphy->fw_version, - sizeof(priv->hw->wiphy->fw_version), - "%u.%u.%u.%u%s", - IWL_UCODE_MAJOR(priv->ucode_ver), - IWL_UCODE_MINOR(priv->ucode_ver), - IWL_UCODE_API(priv->ucode_ver), - IWL_UCODE_SERIAL(priv->ucode_ver), - buildstr); - - /* - * For any of the failures below (before allocating pci memory) - * we will try to load a version with a smaller API -- maybe the - * user just got a corrupted version of the latest API. - */ - - IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n", - priv->ucode_ver); - IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %Zd\n", - pieces.inst_size); - IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %Zd\n", - pieces.data_size); - IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %Zd\n", - pieces.init_size); - IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %Zd\n", - pieces.init_data_size); - - /* Verify that uCode images will fit in card's SRAM */ - if (pieces.inst_size > hw_params(priv).max_inst_size) { - IWL_ERR(priv, "uCode instr len %Zd too large to fit in\n", - pieces.inst_size); - goto try_again; - } - - if (pieces.data_size > hw_params(priv).max_data_size) { - IWL_ERR(priv, "uCode data len %Zd too large to fit in\n", - pieces.data_size); - goto try_again; - } - - if (pieces.init_size > hw_params(priv).max_inst_size) { - IWL_ERR(priv, "uCode init instr len %Zd too large to fit in\n", - pieces.init_size); - goto try_again; - } - - if (pieces.init_data_size > hw_params(priv).max_data_size) { - IWL_ERR(priv, "uCode init data len %Zd too large to fit in\n", - pieces.init_data_size); - goto try_again; - } - - /* Allocate ucode buffers for card's bus-master loading ... */ - - /* Runtime instructions and 2 copies of data: - * 1) unmodified from disk - * 2) backup cache for save/restore during power-downs */ - if (iwl_alloc_fw_desc(trans(priv), &trans(priv)->ucode_rt.code, - pieces.inst, pieces.inst_size)) - goto err_pci_alloc; - if (iwl_alloc_fw_desc(trans(priv), &trans(priv)->ucode_rt.data, - pieces.data, pieces.data_size)) - goto err_pci_alloc; - - /* Initialization instructions and data */ - if (pieces.init_size && pieces.init_data_size) { - if (iwl_alloc_fw_desc(trans(priv), - &trans(priv)->ucode_init.code, - pieces.init, pieces.init_size)) - goto err_pci_alloc; - if (iwl_alloc_fw_desc(trans(priv), - &trans(priv)->ucode_init.data, - pieces.init_data, pieces.init_data_size)) - goto err_pci_alloc; - } - - /* WoWLAN instructions and data */ - if (pieces.wowlan_inst_size && pieces.wowlan_data_size) { - if (iwl_alloc_fw_desc(trans(priv), - &trans(priv)->ucode_wowlan.code, - pieces.wowlan_inst, - pieces.wowlan_inst_size)) - goto err_pci_alloc; - if (iwl_alloc_fw_desc(trans(priv), - &trans(priv)->ucode_wowlan.data, - pieces.wowlan_data, - pieces.wowlan_data_size)) - goto err_pci_alloc; - } - - /* Now that we can no longer fail, copy information */ - - /* - * The (size - 16) / 12 formula is based on the information recorded - * for each event, which is of mode 1 (including timestamp) for all - * new microcodes that include this information. - */ - priv->init_evtlog_ptr = pieces.init_evtlog_ptr; - if (pieces.init_evtlog_size) - priv->init_evtlog_size = (pieces.init_evtlog_size - 16)/12; - else - priv->init_evtlog_size = - cfg(priv)->base_params->max_event_log_size; - priv->init_errlog_ptr = pieces.init_errlog_ptr; - priv->inst_evtlog_ptr = pieces.inst_evtlog_ptr; - if (pieces.inst_evtlog_size) - priv->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; - else - priv->inst_evtlog_size = - cfg(priv)->base_params->max_event_log_size; - priv->inst_errlog_ptr = pieces.inst_errlog_ptr; -#ifndef CONFIG_IWLWIFI_P2P - ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN; -#endif - - priv->new_scan_threshold_behaviour = - !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); - - if (!(cfg(priv)->sku & EEPROM_SKU_CAP_IPAN_ENABLE)) - ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN; - - /* - * if not PAN, then don't support P2P -- might be a uCode - * packaging bug or due to the eeprom check above - */ - if (!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN)) - ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_P2P; - - if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) { - priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; - priv->shrd->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; - } else { - priv->sta_key_max_num = STA_KEY_MAX_NUM; - priv->shrd->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; - } - /* - * figure out the offset of chain noise reset and gain commands - * base on the size of standard phy calibration commands table size - */ - if (ucode_capa.standard_phy_calibration_size > - IWL_MAX_PHY_CALIBRATE_TBL_SIZE) - ucode_capa.standard_phy_calibration_size = - IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE; - - priv->phy_calib_chain_noise_reset_cmd = - ucode_capa.standard_phy_calibration_size; - priv->phy_calib_chain_noise_gain_cmd = - ucode_capa.standard_phy_calibration_size + 1; - - /* initialize all valid contexts */ - iwl_init_context(priv, ucode_capa.flags); - - /************************************************** - * This is still part of probe() in a sense... - * - * 9. Setup and register with mac80211 and debugfs - **************************************************/ - err = iwlagn_mac_setup_register(priv, &ucode_capa); - if (err) - goto out_unbind; - - err = iwl_dbgfs_register(priv, DRV_NAME); - if (err) - IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); - - /* We have our copies now, allow OS release its copies */ - release_firmware(ucode_raw); - complete(&priv->firmware_loading_complete); - return; - - try_again: - /* try next, if any */ - if (iwl_request_firmware(priv, false)) - goto out_unbind; - release_firmware(ucode_raw); - return; - - err_pci_alloc: - IWL_ERR(priv, "failed to allocate pci memory\n"); - iwl_dealloc_ucode(trans(priv)); - out_unbind: - complete(&priv->firmware_loading_complete); - device_release_driver(trans(priv)->dev); - release_firmware(ucode_raw); -} - static void iwl_rf_kill_ct_config(struct iwl_priv *priv) { struct iwl_ct_kill_config cmd; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 0f5133ac357..37c325ff6e8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -107,6 +107,7 @@ void iwlagn_config_ht40(struct ieee80211_conf *conf, int iwlagn_rx_calib_result(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, struct iwl_device_cmd *cmd); +void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags); /* lib */ int iwlagn_send_tx_power(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index fff5b620927..aa99457c3a5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -292,114 +292,6 @@ struct iwl_vif_priv { u8 ibss_bssid_sta_id; }; -/* v1/v2 uCode file layout */ -struct iwl_ucode_header { - __le32 ver; /* major/minor/API/serial */ - union { - struct { - __le32 inst_size; /* bytes of runtime code */ - __le32 data_size; /* bytes of runtime data */ - __le32 init_size; /* bytes of init code */ - __le32 init_data_size; /* bytes of init data */ - __le32 boot_size; /* bytes of bootstrap code */ - u8 data[0]; /* in same order as sizes */ - } v1; - struct { - __le32 build; /* build number */ - __le32 inst_size; /* bytes of runtime code */ - __le32 data_size; /* bytes of runtime data */ - __le32 init_size; /* bytes of init code */ - __le32 init_data_size; /* bytes of init data */ - __le32 boot_size; /* bytes of bootstrap code */ - u8 data[0]; /* in same order as sizes */ - } v2; - } u; -}; - -/* - * new TLV uCode file layout - * - * The new TLV file format contains TLVs, that each specify - * some piece of data. To facilitate "groups", for example - * different instruction image with different capabilities, - * bundled with the same init image, an alternative mechanism - * is provided: - * When the alternative field is 0, that means that the item - * is always valid. When it is non-zero, then it is only - * valid in conjunction with items of the same alternative, - * in which case the driver (user) selects one alternative - * to use. - */ - -enum iwl_ucode_tlv_type { - IWL_UCODE_TLV_INVALID = 0, /* unused */ - IWL_UCODE_TLV_INST = 1, - IWL_UCODE_TLV_DATA = 2, - IWL_UCODE_TLV_INIT = 3, - IWL_UCODE_TLV_INIT_DATA = 4, - IWL_UCODE_TLV_BOOT = 5, - IWL_UCODE_TLV_PROBE_MAX_LEN = 6, /* a u32 value */ - IWL_UCODE_TLV_PAN = 7, - IWL_UCODE_TLV_RUNT_EVTLOG_PTR = 8, - IWL_UCODE_TLV_RUNT_EVTLOG_SIZE = 9, - IWL_UCODE_TLV_RUNT_ERRLOG_PTR = 10, - IWL_UCODE_TLV_INIT_EVTLOG_PTR = 11, - IWL_UCODE_TLV_INIT_EVTLOG_SIZE = 12, - IWL_UCODE_TLV_INIT_ERRLOG_PTR = 13, - IWL_UCODE_TLV_ENHANCE_SENS_TBL = 14, - IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15, - IWL_UCODE_TLV_WOWLAN_INST = 16, - IWL_UCODE_TLV_WOWLAN_DATA = 17, - IWL_UCODE_TLV_FLAGS = 18, -}; - -/** - * enum iwl_ucode_tlv_flag - ucode API flags - * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously - * was a separate TLV but moved here to save space. - * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID, - * treats good CRC threshold as a boolean - * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). - * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. - */ -enum iwl_ucode_tlv_flag { - IWL_UCODE_TLV_FLAGS_PAN = BIT(0), - IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), - IWL_UCODE_TLV_FLAGS_MFP = BIT(2), - IWL_UCODE_TLV_FLAGS_P2P = BIT(3), -}; - -struct iwl_ucode_tlv { - __le16 type; /* see above */ - __le16 alternative; /* see comment */ - __le32 length; /* not including type/length fields */ - u8 data[0]; -} __packed; - -#define IWL_TLV_UCODE_MAGIC 0x0a4c5749 - -struct iwl_tlv_ucode_header { - /* - * The TLV style ucode header is distinguished from - * the v1/v2 style header by first four bytes being - * zero, as such is an invalid combination of - * major/minor/API/serial versions. - */ - __le32 zero; - __le32 magic; - u8 human_readable[64]; - __le32 ver; /* major/minor/API/serial */ - __le32 build; - __le64 alternatives; /* bitmask of valid alternatives */ - /* - * The data contained herein has a TLV layout, - * see above for the TLV header and types. - * Note that each TLV is padded to a length - * that is a multiple of 4 for alignment. - */ - u8 data[0]; -}; - struct iwl_sensitivity_ranges { u16 min_nrg_cck; u16 max_nrg_cck; diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 7177fd76e28..d8025fee7e0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include @@ -43,6 +42,7 @@ #include +#include "iwl-ucode.h" #include "iwl-eeprom.h" #include "iwl-wifi.h" #include "iwl-dev.h" diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index a305e96d82a..ae68c51e532 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -410,8 +410,6 @@ static inline u32 iwl_trans_read32(struct iwl_trans *trans, u32 ofs) /***************************************************** * Utils functions ******************************************************/ -int iwl_alloc_fw_desc(struct iwl_trans *trans, struct fw_desc *desc, - const void *data, size_t len); void iwl_dealloc_ucode(struct iwl_trans *trans); int iwl_send_calib_results(struct iwl_trans *trans); diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 87ce587d7d5..11b659ab261 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -32,7 +32,9 @@ #include #include #include +#include +#include "iwl-ucode.h" #include "iwl-wifi.h" #include "iwl-dev.h" #include "iwl-core.h" @@ -102,7 +104,7 @@ void iwl_dealloc_ucode(struct iwl_trans *trans) iwl_free_fw_img(trans, &trans->ucode_wowlan); } -int iwl_alloc_fw_desc(struct iwl_trans *trans, struct fw_desc *desc, +static int iwl_alloc_fw_desc(struct iwl_trans *trans, struct fw_desc *desc, const void *data, size_t len) { if (!len) { @@ -680,3 +682,609 @@ int iwl_run_init_ucode(struct iwl_trans *trans) iwl_trans_stop_device(trans); return ret; } + +static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); + +#define UCODE_EXPERIMENTAL_INDEX 100 +#define UCODE_EXPERIMENTAL_TAG "exp" + +int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first) +{ + const char *name_pre = cfg(priv)->fw_name_pre; + char tag[8]; + + if (first) { +#ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE + priv->fw_index = UCODE_EXPERIMENTAL_INDEX; + strcpy(tag, UCODE_EXPERIMENTAL_TAG); + } else if (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) { +#endif + priv->fw_index = cfg(priv)->ucode_api_max; + sprintf(tag, "%d", priv->fw_index); + } else { + priv->fw_index--; + sprintf(tag, "%d", priv->fw_index); + } + + if (priv->fw_index < cfg(priv)->ucode_api_min) { + IWL_ERR(priv, "no suitable firmware found!\n"); + return -ENOENT; + } + + sprintf(priv->firmware_name, "%s%s%s", name_pre, tag, ".ucode"); + + IWL_DEBUG_INFO(priv, "attempting to load firmware %s'%s'\n", + (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) + ? "EXPERIMENTAL " : "", + priv->firmware_name); + + return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name, + trans(priv)->dev, + GFP_KERNEL, priv, iwl_ucode_callback); +} + +struct iwlagn_firmware_pieces { + const void *inst, *data, *init, *init_data, *wowlan_inst, *wowlan_data; + size_t inst_size, data_size, init_size, init_data_size, + wowlan_inst_size, wowlan_data_size; + + u32 build; + + u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; + u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; +}; + +static int iwlagn_load_legacy_firmware(struct iwl_priv *priv, + const struct firmware *ucode_raw, + struct iwlagn_firmware_pieces *pieces) +{ + struct iwl_ucode_header *ucode = (void *)ucode_raw->data; + u32 api_ver, hdr_size; + const u8 *src; + + priv->ucode_ver = le32_to_cpu(ucode->ver); + api_ver = IWL_UCODE_API(priv->ucode_ver); + + switch (api_ver) { + default: + hdr_size = 28; + if (ucode_raw->size < hdr_size) { + IWL_ERR(priv, "File size too small!\n"); + return -EINVAL; + } + pieces->build = le32_to_cpu(ucode->u.v2.build); + pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size); + pieces->data_size = le32_to_cpu(ucode->u.v2.data_size); + pieces->init_size = le32_to_cpu(ucode->u.v2.init_size); + pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size); + src = ucode->u.v2.data; + break; + case 0: + case 1: + case 2: + hdr_size = 24; + if (ucode_raw->size < hdr_size) { + IWL_ERR(priv, "File size too small!\n"); + return -EINVAL; + } + pieces->build = 0; + pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size); + pieces->data_size = le32_to_cpu(ucode->u.v1.data_size); + pieces->init_size = le32_to_cpu(ucode->u.v1.init_size); + pieces->init_data_size = le32_to_cpu(ucode->u.v1.init_data_size); + src = ucode->u.v1.data; + break; + } + + /* Verify size of file vs. image size info in file's header */ + if (ucode_raw->size != hdr_size + pieces->inst_size + + pieces->data_size + pieces->init_size + + pieces->init_data_size) { + + IWL_ERR(priv, + "uCode file size %d does not match expected size\n", + (int)ucode_raw->size); + return -EINVAL; + } + + pieces->inst = src; + src += pieces->inst_size; + pieces->data = src; + src += pieces->data_size; + pieces->init = src; + src += pieces->init_size; + pieces->init_data = src; + src += pieces->init_data_size; + + return 0; +} + +static int iwlagn_load_firmware(struct iwl_priv *priv, + const struct firmware *ucode_raw, + struct iwlagn_firmware_pieces *pieces, + struct iwlagn_ucode_capabilities *capa) +{ + struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data; + struct iwl_ucode_tlv *tlv; + size_t len = ucode_raw->size; + const u8 *data; + int wanted_alternative = iwlagn_mod_params.wanted_ucode_alternative; + int tmp; + u64 alternatives; + u32 tlv_len; + enum iwl_ucode_tlv_type tlv_type; + const u8 *tlv_data; + + if (len < sizeof(*ucode)) { + IWL_ERR(priv, "uCode has invalid length: %zd\n", len); + return -EINVAL; + } + + if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) { + IWL_ERR(priv, "invalid uCode magic: 0X%x\n", + le32_to_cpu(ucode->magic)); + return -EINVAL; + } + + /* + * Check which alternatives are present, and "downgrade" + * when the chosen alternative is not present, warning + * the user when that happens. Some files may not have + * any alternatives, so don't warn in that case. + */ + alternatives = le64_to_cpu(ucode->alternatives); + tmp = wanted_alternative; + if (wanted_alternative > 63) + wanted_alternative = 63; + while (wanted_alternative && !(alternatives & BIT(wanted_alternative))) + wanted_alternative--; + if (wanted_alternative && wanted_alternative != tmp) + IWL_WARN(priv, + "uCode alternative %d not available, choosing %d\n", + tmp, wanted_alternative); + + priv->ucode_ver = le32_to_cpu(ucode->ver); + pieces->build = le32_to_cpu(ucode->build); + data = ucode->data; + + len -= sizeof(*ucode); + + while (len >= sizeof(*tlv)) { + u16 tlv_alt; + + len -= sizeof(*tlv); + tlv = (void *)data; + + tlv_len = le32_to_cpu(tlv->length); + tlv_type = le16_to_cpu(tlv->type); + tlv_alt = le16_to_cpu(tlv->alternative); + tlv_data = tlv->data; + + if (len < tlv_len) { + IWL_ERR(priv, "invalid TLV len: %zd/%u\n", + len, tlv_len); + return -EINVAL; + } + len -= ALIGN(tlv_len, 4); + data += sizeof(*tlv) + ALIGN(tlv_len, 4); + + /* + * Alternative 0 is always valid. + * + * Skip alternative TLVs that are not selected. + */ + if (tlv_alt != 0 && tlv_alt != wanted_alternative) + continue; + + switch (tlv_type) { + case IWL_UCODE_TLV_INST: + pieces->inst = tlv_data; + pieces->inst_size = tlv_len; + break; + case IWL_UCODE_TLV_DATA: + pieces->data = tlv_data; + pieces->data_size = tlv_len; + break; + case IWL_UCODE_TLV_INIT: + pieces->init = tlv_data; + pieces->init_size = tlv_len; + break; + case IWL_UCODE_TLV_INIT_DATA: + pieces->init_data = tlv_data; + pieces->init_data_size = tlv_len; + break; + case IWL_UCODE_TLV_BOOT: + IWL_ERR(priv, "Found unexpected BOOT ucode\n"); + break; + case IWL_UCODE_TLV_PROBE_MAX_LEN: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + capa->max_probe_length = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_PAN: + if (tlv_len) + goto invalid_tlv_len; + capa->flags |= IWL_UCODE_TLV_FLAGS_PAN; + break; + case IWL_UCODE_TLV_FLAGS: + /* must be at least one u32 */ + if (tlv_len < sizeof(u32)) + goto invalid_tlv_len; + /* and a proper number of u32s */ + if (tlv_len % sizeof(u32)) + goto invalid_tlv_len; + /* + * This driver only reads the first u32 as + * right now no more features are defined, + * if that changes then either the driver + * will not work with the new firmware, or + * it'll not take advantage of new features. + */ + capa->flags = le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_INIT_EVTLOG_PTR: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->init_evtlog_ptr = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_INIT_EVTLOG_SIZE: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->init_evtlog_size = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_INIT_ERRLOG_PTR: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->init_errlog_ptr = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_RUNT_EVTLOG_PTR: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->inst_evtlog_ptr = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->inst_evtlog_size = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_RUNT_ERRLOG_PTR: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->inst_errlog_ptr = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_ENHANCE_SENS_TBL: + if (tlv_len) + goto invalid_tlv_len; + priv->enhance_sensitivity_table = true; + break; + case IWL_UCODE_TLV_WOWLAN_INST: + pieces->wowlan_inst = tlv_data; + pieces->wowlan_inst_size = tlv_len; + break; + case IWL_UCODE_TLV_WOWLAN_DATA: + pieces->wowlan_data = tlv_data; + pieces->wowlan_data_size = tlv_len; + break; + case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + capa->standard_phy_calibration_size = + le32_to_cpup((__le32 *)tlv_data); + break; + default: + IWL_DEBUG_INFO(priv, "unknown TLV: %d\n", tlv_type); + break; + } + } + + if (len) { + IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len); + iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len); + return -EINVAL; + } + + return 0; + + invalid_tlv_len: + IWL_ERR(priv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); + iwl_print_hex_dump(priv, IWL_DL_FW, tlv_data, tlv_len); + + return -EINVAL; +} + +/** + * iwl_ucode_callback - callback when firmware was loaded + * + * If loaded successfully, copies the firmware into buffers + * for the card to fetch (via DMA). + */ +static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) +{ + struct iwl_priv *priv = context; + struct iwl_ucode_header *ucode; + int err; + struct iwlagn_firmware_pieces pieces; + const unsigned int api_max = cfg(priv)->ucode_api_max; + unsigned int api_ok = cfg(priv)->ucode_api_ok; + const unsigned int api_min = cfg(priv)->ucode_api_min; + u32 api_ver; + char buildstr[25]; + u32 build; + struct iwlagn_ucode_capabilities ucode_capa = { + .max_probe_length = 200, + .standard_phy_calibration_size = + IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE, + }; + + if (!api_ok) + api_ok = api_max; + + memset(&pieces, 0, sizeof(pieces)); + + if (!ucode_raw) { + if (priv->fw_index <= api_ok) + IWL_ERR(priv, + "request for firmware file '%s' failed.\n", + priv->firmware_name); + goto try_again; + } + + IWL_DEBUG_INFO(priv, "Loaded firmware file '%s' (%zd bytes).\n", + priv->firmware_name, ucode_raw->size); + + /* Make sure that we got at least the API version number */ + if (ucode_raw->size < 4) { + IWL_ERR(priv, "File size way too small!\n"); + goto try_again; + } + + /* Data from ucode file: header followed by uCode images */ + ucode = (struct iwl_ucode_header *)ucode_raw->data; + + if (ucode->ver) + err = iwlagn_load_legacy_firmware(priv, ucode_raw, &pieces); + else + err = iwlagn_load_firmware(priv, ucode_raw, &pieces, + &ucode_capa); + + if (err) + goto try_again; + + api_ver = IWL_UCODE_API(priv->ucode_ver); + build = pieces.build; + + /* + * api_ver should match the api version forming part of the + * firmware filename ... but we don't check for that and only rely + * on the API version read from firmware header from here on forward + */ + /* no api version check required for experimental uCode */ + if (priv->fw_index != UCODE_EXPERIMENTAL_INDEX) { + if (api_ver < api_min || api_ver > api_max) { + IWL_ERR(priv, + "Driver unable to support your firmware API. " + "Driver supports v%u, firmware is v%u.\n", + api_max, api_ver); + goto try_again; + } + + if (api_ver < api_ok) { + if (api_ok != api_max) + IWL_ERR(priv, "Firmware has old API version, " + "expected v%u through v%u, got v%u.\n", + api_ok, api_max, api_ver); + else + IWL_ERR(priv, "Firmware has old API version, " + "expected v%u, got v%u.\n", + api_max, api_ver); + IWL_ERR(priv, "New firmware can be obtained from " + "http://www.intellinuxwireless.org/.\n"); + } + } + + if (build) + sprintf(buildstr, " build %u%s", build, + (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) + ? " (EXP)" : ""); + else + buildstr[0] = '\0'; + + IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u%s\n", + IWL_UCODE_MAJOR(priv->ucode_ver), + IWL_UCODE_MINOR(priv->ucode_ver), + IWL_UCODE_API(priv->ucode_ver), + IWL_UCODE_SERIAL(priv->ucode_ver), + buildstr); + + snprintf(priv->hw->wiphy->fw_version, + sizeof(priv->hw->wiphy->fw_version), + "%u.%u.%u.%u%s", + IWL_UCODE_MAJOR(priv->ucode_ver), + IWL_UCODE_MINOR(priv->ucode_ver), + IWL_UCODE_API(priv->ucode_ver), + IWL_UCODE_SERIAL(priv->ucode_ver), + buildstr); + + /* + * For any of the failures below (before allocating pci memory) + * we will try to load a version with a smaller API -- maybe the + * user just got a corrupted version of the latest API. + */ + + IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n", + priv->ucode_ver); + IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %Zd\n", + pieces.inst_size); + IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %Zd\n", + pieces.data_size); + IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %Zd\n", + pieces.init_size); + IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %Zd\n", + pieces.init_data_size); + + /* Verify that uCode images will fit in card's SRAM */ + if (pieces.inst_size > hw_params(priv).max_inst_size) { + IWL_ERR(priv, "uCode instr len %Zd too large to fit in\n", + pieces.inst_size); + goto try_again; + } + + if (pieces.data_size > hw_params(priv).max_data_size) { + IWL_ERR(priv, "uCode data len %Zd too large to fit in\n", + pieces.data_size); + goto try_again; + } + + if (pieces.init_size > hw_params(priv).max_inst_size) { + IWL_ERR(priv, "uCode init instr len %Zd too large to fit in\n", + pieces.init_size); + goto try_again; + } + + if (pieces.init_data_size > hw_params(priv).max_data_size) { + IWL_ERR(priv, "uCode init data len %Zd too large to fit in\n", + pieces.init_data_size); + goto try_again; + } + + /* Allocate ucode buffers for card's bus-master loading ... */ + + /* Runtime instructions and 2 copies of data: + * 1) unmodified from disk + * 2) backup cache for save/restore during power-downs */ + if (iwl_alloc_fw_desc(trans(priv), &trans(priv)->ucode_rt.code, + pieces.inst, pieces.inst_size)) + goto err_pci_alloc; + if (iwl_alloc_fw_desc(trans(priv), &trans(priv)->ucode_rt.data, + pieces.data, pieces.data_size)) + goto err_pci_alloc; + + /* Initialization instructions and data */ + if (pieces.init_size && pieces.init_data_size) { + if (iwl_alloc_fw_desc(trans(priv), + &trans(priv)->ucode_init.code, + pieces.init, pieces.init_size)) + goto err_pci_alloc; + if (iwl_alloc_fw_desc(trans(priv), + &trans(priv)->ucode_init.data, + pieces.init_data, pieces.init_data_size)) + goto err_pci_alloc; + } + + /* WoWLAN instructions and data */ + if (pieces.wowlan_inst_size && pieces.wowlan_data_size) { + if (iwl_alloc_fw_desc(trans(priv), + &trans(priv)->ucode_wowlan.code, + pieces.wowlan_inst, + pieces.wowlan_inst_size)) + goto err_pci_alloc; + if (iwl_alloc_fw_desc(trans(priv), + &trans(priv)->ucode_wowlan.data, + pieces.wowlan_data, + pieces.wowlan_data_size)) + goto err_pci_alloc; + } + + /* Now that we can no longer fail, copy information */ + + /* + * The (size - 16) / 12 formula is based on the information recorded + * for each event, which is of mode 1 (including timestamp) for all + * new microcodes that include this information. + */ + priv->init_evtlog_ptr = pieces.init_evtlog_ptr; + if (pieces.init_evtlog_size) + priv->init_evtlog_size = (pieces.init_evtlog_size - 16)/12; + else + priv->init_evtlog_size = + cfg(priv)->base_params->max_event_log_size; + priv->init_errlog_ptr = pieces.init_errlog_ptr; + priv->inst_evtlog_ptr = pieces.inst_evtlog_ptr; + if (pieces.inst_evtlog_size) + priv->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; + else + priv->inst_evtlog_size = + cfg(priv)->base_params->max_event_log_size; + priv->inst_errlog_ptr = pieces.inst_errlog_ptr; +#ifndef CONFIG_IWLWIFI_P2P + ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN; +#endif + + priv->new_scan_threshold_behaviour = + !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); + + if (!(cfg(priv)->sku & EEPROM_SKU_CAP_IPAN_ENABLE)) + ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN; + + /* + * if not PAN, then don't support P2P -- might be a uCode + * packaging bug or due to the eeprom check above + */ + if (!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN)) + ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_P2P; + + if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) { + priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; + priv->shrd->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; + } else { + priv->sta_key_max_num = STA_KEY_MAX_NUM; + priv->shrd->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; + } + /* + * figure out the offset of chain noise reset and gain commands + * base on the size of standard phy calibration commands table size + */ + if (ucode_capa.standard_phy_calibration_size > + IWL_MAX_PHY_CALIBRATE_TBL_SIZE) + ucode_capa.standard_phy_calibration_size = + IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE; + + priv->phy_calib_chain_noise_reset_cmd = + ucode_capa.standard_phy_calibration_size; + priv->phy_calib_chain_noise_gain_cmd = + ucode_capa.standard_phy_calibration_size + 1; + + /* initialize all valid contexts */ + iwl_init_context(priv, ucode_capa.flags); + + /************************************************** + * This is still part of probe() in a sense... + * + * 9. Setup and register with mac80211 and debugfs + **************************************************/ + err = iwlagn_mac_setup_register(priv, &ucode_capa); + if (err) + goto out_unbind; + + err = iwl_dbgfs_register(priv, DRV_NAME); + if (err) + IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); + + /* We have our copies now, allow OS release its copies */ + release_firmware(ucode_raw); + complete(&priv->firmware_loading_complete); + return; + + try_again: + /* try next, if any */ + if (iwl_request_firmware(priv, false)) + goto out_unbind; + release_firmware(ucode_raw); + return; + + err_pci_alloc: + IWL_ERR(priv, "failed to allocate pci memory\n"); + iwl_dealloc_ucode(trans(priv)); + out_unbind: + complete(&priv->firmware_loading_complete); + device_release_driver(trans(priv)->dev); + release_firmware(ucode_raw); +} + diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.h b/drivers/net/wireless/iwlwifi/iwl-ucode.h new file mode 100644 index 00000000000..eccf92519a8 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.h @@ -0,0 +1,178 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#ifndef __iwl_ucode_h__ +#define __iwl_ucode_h__ + +/* v1/v2 uCode file layout */ +struct iwl_ucode_header { + __le32 ver; /* major/minor/API/serial */ + union { + struct { + __le32 inst_size; /* bytes of runtime code */ + __le32 data_size; /* bytes of runtime data */ + __le32 init_size; /* bytes of init code */ + __le32 init_data_size; /* bytes of init data */ + __le32 boot_size; /* bytes of bootstrap code */ + u8 data[0]; /* in same order as sizes */ + } v1; + struct { + __le32 build; /* build number */ + __le32 inst_size; /* bytes of runtime code */ + __le32 data_size; /* bytes of runtime data */ + __le32 init_size; /* bytes of init code */ + __le32 init_data_size; /* bytes of init data */ + __le32 boot_size; /* bytes of bootstrap code */ + u8 data[0]; /* in same order as sizes */ + } v2; + } u; +}; + +/* + * new TLV uCode file layout + * + * The new TLV file format contains TLVs, that each specify + * some piece of data. To facilitate "groups", for example + * different instruction image with different capabilities, + * bundled with the same init image, an alternative mechanism + * is provided: + * When the alternative field is 0, that means that the item + * is always valid. When it is non-zero, then it is only + * valid in conjunction with items of the same alternative, + * in which case the driver (user) selects one alternative + * to use. + */ + +enum iwl_ucode_tlv_type { + IWL_UCODE_TLV_INVALID = 0, /* unused */ + IWL_UCODE_TLV_INST = 1, + IWL_UCODE_TLV_DATA = 2, + IWL_UCODE_TLV_INIT = 3, + IWL_UCODE_TLV_INIT_DATA = 4, + IWL_UCODE_TLV_BOOT = 5, + IWL_UCODE_TLV_PROBE_MAX_LEN = 6, /* a u32 value */ + IWL_UCODE_TLV_PAN = 7, + IWL_UCODE_TLV_RUNT_EVTLOG_PTR = 8, + IWL_UCODE_TLV_RUNT_EVTLOG_SIZE = 9, + IWL_UCODE_TLV_RUNT_ERRLOG_PTR = 10, + IWL_UCODE_TLV_INIT_EVTLOG_PTR = 11, + IWL_UCODE_TLV_INIT_EVTLOG_SIZE = 12, + IWL_UCODE_TLV_INIT_ERRLOG_PTR = 13, + IWL_UCODE_TLV_ENHANCE_SENS_TBL = 14, + IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15, + IWL_UCODE_TLV_WOWLAN_INST = 16, + IWL_UCODE_TLV_WOWLAN_DATA = 17, + IWL_UCODE_TLV_FLAGS = 18, +}; + +/** + * enum iwl_ucode_tlv_flag - ucode API flags + * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously + * was a separate TLV but moved here to save space. + * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID, + * treats good CRC threshold as a boolean + * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). + * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. + */ +enum iwl_ucode_tlv_flag { + IWL_UCODE_TLV_FLAGS_PAN = BIT(0), + IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), + IWL_UCODE_TLV_FLAGS_MFP = BIT(2), + IWL_UCODE_TLV_FLAGS_P2P = BIT(3), +}; + +struct iwl_ucode_tlv { + __le16 type; /* see above */ + __le16 alternative; /* see comment */ + __le32 length; /* not including type/length fields */ + u8 data[0]; +}; + +#define IWL_TLV_UCODE_MAGIC 0x0a4c5749 + +struct iwl_tlv_ucode_header { + /* + * The TLV style ucode header is distinguished from + * the v1/v2 style header by first four bytes being + * zero, as such is an invalid combination of + * major/minor/API/serial versions. + */ + __le32 zero; + __le32 magic; + u8 human_readable[64]; + __le32 ver; /* major/minor/API/serial */ + __le32 build; + __le64 alternatives; /* bitmask of valid alternatives */ + /* + * The data contained herein has a TLV layout, + * see above for the TLV header and types. + * Note that each TLV is padded to a length + * that is a multiple of 4 for alignment. + */ + u8 data[0]; +}; + +struct iwl_priv; + +int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first); + +#endif /* __iwl_ucode_h__ */ -- cgit v1.2.3-70-g09d2 From f057ac4ed77d3390b517ee2be8e88615b9994272 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 29 Jan 2012 18:36:01 -0800 Subject: iwlwifi: release IRQ in error path smatch correctly complains: iwl-trans-pcie.c +1528 iwl_trans_pcie_start_hw(50) warn: 'trans->irq' was not released on error Fix it. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi W Guy --- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index ec26950ebb5..836caf9c68b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1504,7 +1504,7 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) err = iwl_prepare_card_hw(trans); if (err) { IWL_ERR(trans, "Error while preparing HW: %d", err); - goto error; + goto err_free_irq; } iwl_apm_init(trans); @@ -1522,6 +1522,8 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) return err; +err_free_irq: + free_irq(trans->irq, trans); error: iwl_free_isr_ict(trans); tasklet_kill(&trans_pcie->irq_tasklet); -- cgit v1.2.3-70-g09d2 From 6fe7dd0db0af18a8792d8551fd19a184f39a732c Mon Sep 17 00:00:00 2001 From: Amit Beka Date: Wed, 25 Jan 2012 09:19:24 +0200 Subject: iwlwifi: range check to testmode direct reg access Added a check on the direct register access. Checks that the address is in the lower ragnge (0x0-0x2000), which belongs to CSR, HBUS and FH registers. Signed-off-by: Amit Beka Signed-off-by: Wey-Yi W Guy --- drivers/net/wireless/iwlwifi/iwl-testmode.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index 7c17b9d5217..df7ab332c83 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -79,6 +79,7 @@ #include "iwl-testmode.h" #include "iwl-trans.h" #include "iwl-bus.h" +#include "iwl-fh.h" /* The TLVs used in the gnl message policy between the kernel module and * user space application. iwl_testmode_gnl_msg_policy is to be carried @@ -288,7 +289,7 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb) static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb) { struct iwl_priv *priv = hw->priv; - u32 ofs, val32; + u32 ofs, val32, cmd; u8 val8; struct sk_buff *skb; int status = 0; @@ -300,7 +301,20 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb) ofs = nla_get_u32(tb[IWL_TM_ATTR_REG_OFFSET]); IWL_INFO(priv, "testmode register access command offset 0x%x\n", ofs); - switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { + /* Allow access only to FH/CSR/HBUS in direct mode. + Since we don't have the upper bounds for the CSR and HBUS segments, + we will use only the upper bound of FH for sanity check. */ + cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]); + if ((cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32 || + cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32 || + cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8) && + (ofs >= FH_MEM_UPPER_BOUND)) { + IWL_DEBUG_INFO(priv, "offset out of segment (0x0 - 0x%x)\n", + FH_MEM_UPPER_BOUND); + return -EINVAL; + } + + switch (cmd) { case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32: val32 = iwl_read_direct32(trans(priv), ofs); IWL_INFO(priv, "32bit value to read 0x%x\n", val32); -- cgit v1.2.3-70-g09d2 From c898add51c7b5b99fcecdeaf4df2ca30949cacb6 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 11 Jan 2012 12:42:32 +0100 Subject: usb/uas: only bind if the hcd supports SG The UAS driver requires SG support by the HCD operating the device. This patch stops UAS from operating on a HCD without sg support and prints a message to let him know. The spec says: |For [USB2] backward compatibility, the device shall present [BOT] as |alternate interface zero (primary) and [UAS] as alternate interface one |(secondary). A device which does not need backward compatibility with |[BOT] shall present [UAS] as alternate interface zero. In [USB2] |systems, the [BOT] driver or an associated filter driver may need to |issue a SET INTERFACE request for alternate interface one and then allow |the [UAS] driver to load. If the user used usb_modeswitch to switch to UAS then he can go back to BOT or use a different HCD. In case UAS is the only interface then there is currently no way out. In future usb_sg_wait() should be extended to provide a non-blocking interface so it can work with the UAS driver. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Sarah Sharp --- drivers/usb/storage/uas.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index e0133c9ab0b..e34c75970ed 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -621,22 +622,34 @@ static int uas_is_interface(struct usb_host_interface *intf) intf->desc.bInterfaceProtocol == USB_PR_UAS); } +static int uas_isnt_supported(struct usb_device *udev) +{ + struct usb_hcd *hcd = bus_to_hcd(udev->bus); + + dev_warn(&udev->dev, "The driver for the USB controller %s does not " + "support scatter-gather which is\n", + hcd->driver->description); + dev_warn(&udev->dev, "required by the UAS driver. Please try an" + "alternative USB controller if you wish to use UAS.\n"); + return -ENODEV; +} + static int uas_switch_interface(struct usb_device *udev, struct usb_interface *intf) { int i; - - if (uas_is_interface(intf->cur_altsetting)) - return 0; + int sg_supported = udev->bus->sg_tablesize != 0; for (i = 0; i < intf->num_altsetting; i++) { struct usb_host_interface *alt = &intf->altsetting[i]; - if (alt == intf->cur_altsetting) - continue; - if (uas_is_interface(alt)) + + if (uas_is_interface(alt)) { + if (!sg_supported) + return uas_isnt_supported(udev); return usb_set_interface(udev, alt->desc.bInterfaceNumber, alt->desc.bAlternateSetting); + } } return -ENODEV; -- cgit v1.2.3-70-g09d2 From 348748b0e8cccc675e2f3a1456460ffcd540e1a1 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 11 Jan 2012 12:45:56 +0100 Subject: usb/uas: move UAS structs / defines into a header file The protocol specific structures and defines which are used by UAS are moved into a header files by this patch so it can be accessed by the UAS gadget as well. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Sarah Sharp --- drivers/usb/storage/uas.c | 56 +------------------------------------------ include/linux/usb/uas.h | 61 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 55 deletions(-) create mode 100644 include/linux/usb/uas.h (limited to 'drivers') diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index e34c75970ed..f98ba40352c 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -23,49 +24,6 @@ #include #include -/* Common header for all IUs */ -struct iu { - __u8 iu_id; - __u8 rsvd1; - __be16 tag; -}; - -enum { - IU_ID_COMMAND = 0x01, - IU_ID_STATUS = 0x03, - IU_ID_RESPONSE = 0x04, - IU_ID_TASK_MGMT = 0x05, - IU_ID_READ_READY = 0x06, - IU_ID_WRITE_READY = 0x07, -}; - -struct command_iu { - __u8 iu_id; - __u8 rsvd1; - __be16 tag; - __u8 prio_attr; - __u8 rsvd5; - __u8 len; - __u8 rsvd7; - struct scsi_lun lun; - __u8 cdb[16]; /* XXX: Overflow-checking tools may misunderstand */ -}; - -/* - * Also used for the Read Ready and Write Ready IUs since they have the - * same first four bytes - */ -struct sense_iu { - __u8 iu_id; - __u8 rsvd1; - __be16 tag; - __be16 status_qual; - __u8 status; - __u8 rsvd7[7]; - __be16 len; - __u8 sense[SCSI_SENSE_BUFFERSIZE]; -}; - /* * The r00-r01c specs define this version of the SENSE IU data structure. * It's still in use by several different firmware releases. @@ -80,18 +38,6 @@ struct sense_iu_old { __u8 sense[SCSI_SENSE_BUFFERSIZE]; }; -enum { - CMD_PIPE_ID = 1, - STATUS_PIPE_ID = 2, - DATA_IN_PIPE_ID = 3, - DATA_OUT_PIPE_ID = 4, - - UAS_SIMPLE_TAG = 0, - UAS_HEAD_TAG = 1, - UAS_ORDERED_TAG = 2, - UAS_ACA = 4, -}; - struct uas_dev_info { struct usb_interface *intf; struct usb_device *udev; diff --git a/include/linux/usb/uas.h b/include/linux/usb/uas.h new file mode 100644 index 00000000000..856be7fcbbd --- /dev/null +++ b/include/linux/usb/uas.h @@ -0,0 +1,61 @@ +#ifndef __USB_UAS_H__ +#define __USB_UAS_H__ + +#include +#include + +/* Common header for all IUs */ +struct iu { + __u8 iu_id; + __u8 rsvd1; + __be16 tag; +}; + +enum { + IU_ID_COMMAND = 0x01, + IU_ID_STATUS = 0x03, + IU_ID_RESPONSE = 0x04, + IU_ID_TASK_MGMT = 0x05, + IU_ID_READ_READY = 0x06, + IU_ID_WRITE_READY = 0x07, +}; + +struct command_iu { + __u8 iu_id; + __u8 rsvd1; + __be16 tag; + __u8 prio_attr; + __u8 rsvd5; + __u8 len; + __u8 rsvd7; + struct scsi_lun lun; + __u8 cdb[16]; /* XXX: Overflow-checking tools may misunderstand */ +}; + +/* + * Also used for the Read Ready and Write Ready IUs since they have the + * same first four bytes + */ +struct sense_iu { + __u8 iu_id; + __u8 rsvd1; + __be16 tag; + __be16 status_qual; + __u8 status; + __u8 rsvd7[7]; + __be16 len; + __u8 sense[SCSI_SENSE_BUFFERSIZE]; +}; + +enum { + CMD_PIPE_ID = 1, + STATUS_PIPE_ID = 2, + DATA_IN_PIPE_ID = 3, + DATA_OUT_PIPE_ID = 4, + + UAS_SIMPLE_TAG = 0, + UAS_HEAD_TAG = 1, + UAS_ORDERED_TAG = 2, + UAS_ACA = 4, +}; +#endif -- cgit v1.2.3-70-g09d2 From e4d8318a85779b25b880187b1b1c44e797bd7d4b Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 25 Jan 2012 11:48:40 +0100 Subject: usb/uas: make sure data urb is gone if we receive status before that Just run into the following: - new disk arrived in the system - udev couldn't wait to get its hands on to to run ata_id /dev/sda - this sent the cdb 0xa1 to the device. - my UAS-gadget recevied the cdb and had no idea what to do with it. It decided to send a status URB back with sense set to invalid opcode. - the host side received it status and completed the scsi command. - the host sent another scsi with 4kib data buffer - Now I was confused why the data transfer is only 512 bytes instead of 4kib since the host is always allocating the complete transfer in one go. - Finally the system crashed while walking through the sg list. This patch adds three new flags in order to distinguish between DATA URB completed and outstanding. If we receive status before data, we cancel data and let data complete the command. This solves the problem for IN and OUT transfers but does not work for BIDI. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Sarah Sharp --- drivers/usb/storage/uas.c | 90 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 75 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index f98ba40352c..8ec8a6e66f5 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -58,6 +58,9 @@ enum { SUBMIT_DATA_OUT_URB = (1 << 5), ALLOC_CMD_URB = (1 << 6), SUBMIT_CMD_URB = (1 << 7), + COMPLETED_DATA_IN = (1 << 8), + COMPLETED_DATA_OUT = (1 << 9), + DATA_COMPLETES_CMD = (1 << 10), }; /* Overrides scsi_pointer */ @@ -111,6 +114,7 @@ static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd) { struct sense_iu *sense_iu = urb->transfer_buffer; struct scsi_device *sdev = cmnd->device; + struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; if (urb->actual_length > 16) { unsigned len = be16_to_cpup(&sense_iu->len); @@ -128,13 +132,15 @@ static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd) } cmnd->result = sense_iu->status; - cmnd->scsi_done(cmnd); + if (!(cmdinfo->state & DATA_COMPLETES_CMD)) + cmnd->scsi_done(cmnd); } static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd) { struct sense_iu_old *sense_iu = urb->transfer_buffer; struct scsi_device *sdev = cmnd->device; + struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; if (urb->actual_length > 8) { unsigned len = be16_to_cpup(&sense_iu->len) - 2; @@ -152,7 +158,8 @@ static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd) } cmnd->result = sense_iu->status; - cmnd->scsi_done(cmnd); + if (!(cmdinfo->state & DATA_COMPLETES_CMD)) + cmnd->scsi_done(cmnd); } static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd, @@ -177,6 +184,7 @@ static void uas_stat_cmplt(struct urb *urb) struct Scsi_Host *shost = urb->context; struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; struct scsi_cmnd *cmnd; + struct uas_cmd_info *cmdinfo; u16 tag; int ret; @@ -202,12 +210,32 @@ static void uas_stat_cmplt(struct urb *urb) dev_err(&urb->dev->dev, "failed submit status urb\n"); return; } + cmdinfo = (void *)&cmnd->SCp; switch (iu->iu_id) { case IU_ID_STATUS: if (devinfo->cmnd == cmnd) devinfo->cmnd = NULL; + if (!(cmdinfo->state & COMPLETED_DATA_IN) && + cmdinfo->data_in_urb) { + if (devinfo->use_streams) { + cmdinfo->state |= DATA_COMPLETES_CMD; + usb_unlink_urb(cmdinfo->data_in_urb); + } else { + usb_free_urb(cmdinfo->data_in_urb); + } + } + if (!(cmdinfo->state & COMPLETED_DATA_OUT) && + cmdinfo->data_out_urb) { + if (devinfo->use_streams) { + cmdinfo->state |= DATA_COMPLETES_CMD; + usb_unlink_urb(cmdinfo->data_in_urb); + } else { + usb_free_urb(cmdinfo->data_out_urb); + } + } + if (urb->actual_length < 16) devinfo->uas_sense_old = 1; if (devinfo->uas_sense_old) @@ -236,27 +264,59 @@ static void uas_stat_cmplt(struct urb *urb) dev_err(&urb->dev->dev, "failed submit status urb\n"); } -static void uas_data_cmplt(struct urb *urb) +static void uas_data_out_cmplt(struct urb *urb) +{ + struct scsi_cmnd *cmnd = urb->context; + struct scsi_data_buffer *sdb = scsi_out(cmnd); + struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; + + cmdinfo->state |= COMPLETED_DATA_OUT; + + sdb->resid = sdb->length - urb->actual_length; + usb_free_urb(urb); + + if (cmdinfo->state & DATA_COMPLETES_CMD) + cmnd->scsi_done(cmnd); +} + +static void uas_data_in_cmplt(struct urb *urb) { - struct scsi_data_buffer *sdb = urb->context; + struct scsi_cmnd *cmnd = urb->context; + struct scsi_data_buffer *sdb = scsi_in(cmnd); + struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; + + cmdinfo->state |= COMPLETED_DATA_IN; + sdb->resid = sdb->length - urb->actual_length; usb_free_urb(urb); + + if (cmdinfo->state & DATA_COMPLETES_CMD) + cmnd->scsi_done(cmnd); } static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp, - unsigned int pipe, u16 stream_id, - struct scsi_data_buffer *sdb, - enum dma_data_direction dir) + unsigned int pipe, struct scsi_cmnd *cmnd, + enum dma_data_direction dir) { + struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; struct usb_device *udev = devinfo->udev; struct urb *urb = usb_alloc_urb(0, gfp); + struct scsi_data_buffer *sdb; + usb_complete_t complete_fn; + u16 stream_id = cmdinfo->stream; if (!urb) goto out; - usb_fill_bulk_urb(urb, udev, pipe, NULL, sdb->length, uas_data_cmplt, - sdb); - if (devinfo->use_streams) - urb->stream_id = stream_id; + if (dir == DMA_FROM_DEVICE) { + sdb = scsi_in(cmnd); + complete_fn = uas_data_in_cmplt; + } else { + sdb = scsi_out(cmnd); + complete_fn = uas_data_out_cmplt; + } + usb_fill_bulk_urb(urb, udev, pipe, NULL, sdb->length, + complete_fn, cmnd); + urb->stream_id = stream_id; urb->num_sgs = udev->bus->sg_tablesize ? sdb->table.nents : 0; urb->sg = sdb->table.sgl; out: @@ -358,8 +418,8 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, if (cmdinfo->state & ALLOC_DATA_IN_URB) { cmdinfo->data_in_urb = uas_alloc_data_urb(devinfo, gfp, - devinfo->data_in_pipe, cmdinfo->stream, - scsi_in(cmnd), DMA_FROM_DEVICE); + devinfo->data_in_pipe, cmnd, + DMA_FROM_DEVICE); if (!cmdinfo->data_in_urb) return SCSI_MLQUEUE_DEVICE_BUSY; cmdinfo->state &= ~ALLOC_DATA_IN_URB; @@ -376,8 +436,8 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, if (cmdinfo->state & ALLOC_DATA_OUT_URB) { cmdinfo->data_out_urb = uas_alloc_data_urb(devinfo, gfp, - devinfo->data_out_pipe, cmdinfo->stream, - scsi_out(cmnd), DMA_TO_DEVICE); + devinfo->data_out_pipe, cmnd, + DMA_TO_DEVICE); if (!cmdinfo->data_out_urb) return SCSI_MLQUEUE_DEVICE_BUSY; cmdinfo->state &= ~ALLOC_DATA_OUT_URB; -- cgit v1.2.3-70-g09d2 From 66d450e84ec656ec4b774c41cd8d46b3e48d51df Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 30 Jan 2012 21:14:28 +0100 Subject: TTY: provide tty_standard_install helper There are currently many cut&paste copies of what tty_driver_install_tty does when custom ->install method is not provided. Let's get rid of the copies and create a helper with this setup code. Signed-off-by: Jiri Slaby Cc: Havard Skinnemoen Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 30 +++++++++++++++--------------- include/linux/tty.h | 2 ++ 2 files changed, 17 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index fbcc1406380..44736f9e61d 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1271,6 +1271,19 @@ int tty_init_termios(struct tty_struct *tty) } EXPORT_SYMBOL_GPL(tty_init_termios); +int tty_standard_install(struct tty_driver *driver, struct tty_struct *tty) +{ + int ret = tty_init_termios(tty); + if (ret) + return ret; + + tty_driver_kref_get(driver); + tty->count++; + driver->ttys[tty->index] = tty; + return 0; +} +EXPORT_SYMBOL_GPL(tty_standard_install); + /** * tty_driver_install_tty() - install a tty entry in the driver * @driver: the driver for the tty @@ -1286,21 +1299,8 @@ EXPORT_SYMBOL_GPL(tty_init_termios); static int tty_driver_install_tty(struct tty_driver *driver, struct tty_struct *tty) { - int idx = tty->index; - int ret; - - if (driver->ops->install) { - ret = driver->ops->install(driver, tty); - return ret; - } - - if (tty_init_termios(tty) == 0) { - tty_driver_kref_get(driver); - tty->count++; - driver->ttys[idx] = tty; - return 0; - } - return -ENOMEM; + return driver->ops->install ? driver->ops->install(driver, tty) : + tty_standard_install(driver, tty); } /** diff --git a/include/linux/tty.h b/include/linux/tty.h index d4077418820..a91ff403b3b 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -484,6 +484,8 @@ extern void deinitialize_tty_struct(struct tty_struct *tty); extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx); extern int tty_release(struct inode *inode, struct file *filp); extern int tty_init_termios(struct tty_struct *tty); +extern int tty_standard_install(struct tty_driver *driver, + struct tty_struct *tty); extern struct tty_struct *tty_pair_get_tty(struct tty_struct *tty); extern struct tty_struct *tty_pair_get_pty(struct tty_struct *tty); -- cgit v1.2.3-70-g09d2 From 76f82a7ab3a724791d184e74529e96ad6947a98f Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 30 Jan 2012 21:14:29 +0100 Subject: USB: serial, use tty_standard_install But before that we need to reorder the calls so that we don't need to lower the reference counts if usb_autopm_get_interface fails. Signed-off-by: Jiri Slaby Cc: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 611b206591c..1e30cc92719 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -214,15 +214,14 @@ static int serial_install(struct tty_driver *driver, struct tty_struct *tty) if (!try_module_get(serial->type->driver.owner)) goto error_module_get; - /* perform the standard setup */ - retval = tty_init_termios(tty); - if (retval) - goto error_init_termios; - retval = usb_autopm_get_interface(serial->interface); if (retval) goto error_get_interface; + retval = tty_standard_install(driver, tty); + if (retval) + goto error_init_termios; + mutex_unlock(&serial->disc_mutex); /* allow the driver to update the settings */ @@ -231,14 +230,11 @@ static int serial_install(struct tty_driver *driver, struct tty_struct *tty) tty->driver_data = port; - /* Final install (we use the default method) */ - tty_driver_kref_get(driver); - tty->count++; - driver->ttys[idx] = tty; return retval; - error_get_interface: error_init_termios: + usb_autopm_put_interface(serial->interface); + error_get_interface: module_put(serial->type->driver.owner); error_module_get: error_no_port: -- cgit v1.2.3-70-g09d2 From 81f5835eae424be646753ec5a044ed4db1fcc09a Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 30 Jan 2012 21:14:30 +0100 Subject: TTY: use tty_standard_install Use the helper in the rest of the tty drivers. This is a simple replacement. Signed-off-by: Jiri Slaby Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/isdn/capi/capi.c | 9 +++------ drivers/misc/pti.c | 6 +----- drivers/mmc/card/sdio_uart.c | 9 +++------ drivers/tty/nozomi.c | 8 ++------ 4 files changed, 9 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index e44933d5879..94948be5d36 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -1015,14 +1015,11 @@ capinc_tty_install(struct tty_driver *driver, struct tty_struct *tty) { int idx = tty->index; struct capiminor *mp = capiminor_get(idx); - int ret = tty_init_termios(tty); + int ret = tty_standard_install(driver, tty); - if (ret == 0) { - tty_driver_kref_get(driver); - tty->count++; + if (ret == 0) tty->driver_data = mp; - driver->ttys[idx] = tty; - } else + else capiminor_put(mp); return ret; } diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c index 0b56e3f4357..471ff4c85cd 100644 --- a/drivers/misc/pti.c +++ b/drivers/misc/pti.c @@ -481,13 +481,9 @@ static int pti_tty_install(struct tty_driver *driver, struct tty_struct *tty) { int idx = tty->index; struct pti_tty *pti_tty_data; - int ret = tty_init_termios(tty); + int ret = tty_standard_install(driver, tty); if (ret == 0) { - tty_driver_kref_get(driver); - tty->count++; - driver->ttys[idx] = tty; - pti_tty_data = kmalloc(sizeof(struct pti_tty), GFP_KERNEL); if (pti_tty_data == NULL) return -ENOMEM; diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c index 2c151e18c9e..bd4a67cdac3 100644 --- a/drivers/mmc/card/sdio_uart.c +++ b/drivers/mmc/card/sdio_uart.c @@ -750,15 +750,12 @@ static int sdio_uart_install(struct tty_driver *driver, struct tty_struct *tty) { int idx = tty->index; struct sdio_uart_port *port = sdio_uart_port_get(idx); - int ret = tty_init_termios(tty); + int ret = tty_standard_install(driver, tty); - if (ret == 0) { - tty_driver_kref_get(driver); - tty->count++; + if (ret == 0) /* This is the ref sdio_uart_port get provided */ tty->driver_data = port; - driver->ttys[idx] = tty; - } else + else sdio_uart_port_put(port); return ret; } diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index fd347ff34d0..580da78b2d8 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c @@ -1602,13 +1602,9 @@ static int ntty_install(struct tty_driver *driver, struct tty_struct *tty) int ret; if (!port || !dc || dc->state != NOZOMI_STATE_READY) return -ENODEV; - ret = tty_init_termios(tty); - if (ret == 0) { - tty_driver_kref_get(driver); - tty->count++; + ret = tty_standard_install(driver, tty); + if (ret == 0) tty->driver_data = port; - driver->ttys[tty->index] = tty; - } return ret; } -- cgit v1.2.3-70-g09d2 From a50f724a432997321cabb6c9e665c28e34850f78 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 30 Jan 2012 21:14:31 +0100 Subject: TTY: pty, remove superfluous ptm test The code looks like: if (tty->driver->subtype == PTY_TYPE_MASTER) { ... if (tty->driver == ptm_driver) But the second if is superfluous because only the ptm_driver is of PTY_TYPE_MASTER subtype. Also we can remove the #if now because devpts_pty_kill is defined as an empty function for non-CONFIG_UNIX98_PTYS configs. Signed-off-by: Jiri Slaby Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/pty.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index d505837b347..ddec9f3c339 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -54,10 +54,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp) wake_up_interruptible(&tty->link->write_wait); if (tty->driver->subtype == PTY_TYPE_MASTER) { set_bit(TTY_OTHER_CLOSED, &tty->flags); -#ifdef CONFIG_UNIX98_PTYS - if (tty->driver == ptm_driver) - devpts_pty_kill(tty->link); -#endif + devpts_pty_kill(tty->link); tty_unlock(); tty_vhangup(tty->link); tty_lock(); -- cgit v1.2.3-70-g09d2 From d3bda5298aad98c7a27678bdd0dd9d008ab9e685 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 30 Jan 2012 21:14:32 +0100 Subject: TTY: get rid of BTM around devpts_* devpts operations are protected by inode mutexes and dentry refcounting. There is no need to hold BTM. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/pty.c | 6 ++---- drivers/tty/tty_io.c | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index ddec9f3c339..39afd045f8e 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -54,8 +54,8 @@ static void pty_close(struct tty_struct *tty, struct file *filp) wake_up_interruptible(&tty->link->write_wait); if (tty->driver->subtype == PTY_TYPE_MASTER) { set_bit(TTY_OTHER_CLOSED, &tty->flags); - devpts_pty_kill(tty->link); tty_unlock(); + devpts_pty_kill(tty->link); tty_vhangup(tty->link); tty_lock(); } @@ -613,9 +613,7 @@ static int ptmx_open(struct inode *inode, struct file *filp) return retval; /* find a device that is not in use. */ - tty_lock(); index = devpts_new_index(inode); - tty_unlock(); if (index < 0) { retval = index; goto err_file; @@ -650,8 +648,8 @@ err_release: tty_release(inode, filp); return retval; out: - devpts_kill_index(inode, index); tty_unlock(); + devpts_kill_index(inode, index); err_file: tty_free_file(filp); return retval; diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 44736f9e61d..ea7ebe22a16 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1789,11 +1789,11 @@ int tty_release(struct inode *inode, struct file *filp) * the slots and preserving the termios structure. */ release_tty(tty, idx); + tty_unlock(); /* Make this pty number available for reallocation */ if (devpts) devpts_kill_index(inode, idx); - tty_unlock(); return 0; } -- cgit v1.2.3-70-g09d2 From 4f03a2c934894f30a64d397df8c7c4de129c5b30 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Fri, 27 Jan 2012 15:55:57 -0800 Subject: drivers: hv: kvp: Add/cleanup connector defines The current KVP code carries some private connector related defines. Update connector.h to have all the KVP defines. As part of this patch get rid of some unused defines. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv_kvp.h | 3 --- include/linux/connector.h | 1 + tools/hv/hv_kvp_daemon.c | 4 ---- 3 files changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/hv/hv_kvp.h b/drivers/hv/hv_kvp.h index 9b765d7df83..c2c5bba25a5 100644 --- a/drivers/hv/hv_kvp.h +++ b/drivers/hv/hv_kvp.h @@ -107,9 +107,6 @@ * the KVP user-mode component. */ -#define CN_KVP_VAL 0x1 /* This supports queries from the kernel */ -#define CN_KVP_USER_VAL 0x2 /* This supports queries from the user */ - enum hv_ku_op { KVP_REGISTER = 0, /* Register the user mode component */ KVP_KERNEL_GET, /* Kernel is requesting the value */ diff --git a/include/linux/connector.h b/include/linux/connector.h index 3c9c54fd569..76384074262 100644 --- a/include/linux/connector.h +++ b/include/linux/connector.h @@ -43,6 +43,7 @@ #define CN_IDX_DRBD 0x8 #define CN_VAL_DRBD 0x1 #define CN_KVP_IDX 0x9 /* HyperV KVP */ +#define CN_KVP_VAL 0x1 /* queries from the kernel */ #define CN_NETLINK_USERS 10 /* Highest index + 1 */ diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c index 11224eddcdc..2b6a2d950b8 100644 --- a/tools/hv/hv_kvp_daemon.c +++ b/tools/hv/hv_kvp_daemon.c @@ -40,15 +40,11 @@ #include /* - * KYS: TODO. Need to register these in the kernel. * * The following definitions are shared with the in-kernel component; do not * change any of this without making the corresponding changes in * the KVP kernel component. */ -#define CN_KVP_IDX 0x9 /* MSFT KVP functionality */ -#define CN_KVP_VAL 0x1 /* This supports queries from the kernel */ -#define CN_KVP_USER_VAL 0x2 /* This supports queries from the user */ /* * KVP protocol: The user mode component first registers with the -- cgit v1.2.3-70-g09d2 From 2939437ce8f2de07237eb2bcce29b6a699bfe799 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Fri, 27 Jan 2012 15:55:58 -0800 Subject: drivers: hv: kvp: Move the contents of hv_kvp.h to hyperv.h In preparation for consolidating all KVP related defines into a single header file that both the kernel and user level components can use, move the contents of hv_kvp.h into hyperv.h. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv_kvp.c | 2 - drivers/hv/hv_kvp.h | 181 ------------------------------------------------- drivers/hv/hv_util.c | 3 - include/linux/hyperv.h | 165 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 165 insertions(+), 186 deletions(-) delete mode 100644 drivers/hv/hv_kvp.h (limited to 'drivers') diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c index 0e8343f585b..4a6971e1353 100644 --- a/drivers/hv/hv_kvp.c +++ b/drivers/hv/hv_kvp.c @@ -28,8 +28,6 @@ #include #include -#include "hv_kvp.h" - /* diff --git a/drivers/hv/hv_kvp.h b/drivers/hv/hv_kvp.h deleted file mode 100644 index c2c5bba25a5..00000000000 --- a/drivers/hv/hv_kvp.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * An implementation of HyperV key value pair (KVP) functionality for Linux. - * - * - * Copyright (C) 2010, Novell, 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. - * - * You 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 _KVP_H -#define _KVP_H_ - -/* - * Maximum value size - used for both key names and value data, and includes - * any applicable NULL terminators. - * - * Note: This limit is somewhat arbitrary, but falls easily within what is - * supported for all native guests (back to Win 2000) and what is reasonable - * for the IC KVP exchange functionality. Note that Windows Me/98/95 are - * limited to 255 character key names. - * - * MSDN recommends not storing data values larger than 2048 bytes in the - * registry. - * - * Note: This value is used in defining the KVP exchange message - this value - * cannot be modified without affecting the message size and compatibility. - */ - -/* - * bytes, including any null terminators - */ -#define HV_KVP_EXCHANGE_MAX_VALUE_SIZE (2048) - - -/* - * Maximum key size - the registry limit for the length of an entry name - * is 256 characters, including the null terminator - */ - -#define HV_KVP_EXCHANGE_MAX_KEY_SIZE (512) - -/* - * In Linux, we implement the KVP functionality in two components: - * 1) The kernel component which is packaged as part of the hv_utils driver - * is responsible for communicating with the host and responsible for - * implementing the host/guest protocol. 2) A user level daemon that is - * responsible for data gathering. - * - * Host/Guest Protocol: The host iterates over an index and expects the guest - * to assign a key name to the index and also return the value corresponding to - * the key. The host will have atmost one KVP transaction outstanding at any - * given point in time. The host side iteration stops when the guest returns - * an error. Microsoft has specified the following mapping of key names to - * host specified index: - * - * Index Key Name - * 0 FullyQualifiedDomainName - * 1 IntegrationServicesVersion - * 2 NetworkAddressIPv4 - * 3 NetworkAddressIPv6 - * 4 OSBuildNumber - * 5 OSName - * 6 OSMajorVersion - * 7 OSMinorVersion - * 8 OSVersion - * 9 ProcessorArchitecture - * - * The Windows host expects the Key Name and Key Value to be encoded in utf16. - * - * Guest Kernel/KVP Daemon Protocol: As noted earlier, we implement all of the - * data gathering functionality in a user mode daemon. The user level daemon - * is also responsible for binding the key name to the index as well. The - * kernel and user-level daemon communicate using a connector channel. - * - * The user mode component first registers with the - * the kernel component. Subsequently, the kernel component requests, data - * for the specified keys. In response to this message the user mode component - * fills in the value corresponding to the specified key. We overload the - * sequence field in the cn_msg header to define our KVP message types. - * - * - * The kernel component simply acts as a conduit for communication between the - * Windows host and the user-level daemon. The kernel component passes up the - * index received from the Host to the user-level daemon. If the index is - * valid (supported), the corresponding key as well as its - * value (both are strings) is returned. If the index is invalid - * (not supported), a NULL key string is returned. - */ - -/* - * - * The following definitions are shared with the user-mode component; do not - * change any of this without making the corresponding changes in - * the KVP user-mode component. - */ - -enum hv_ku_op { - KVP_REGISTER = 0, /* Register the user mode component */ - KVP_KERNEL_GET, /* Kernel is requesting the value */ - KVP_KERNEL_SET, /* Kernel is providing the value */ - KVP_USER_GET, /* User is requesting the value */ - KVP_USER_SET /* User is providing the value */ -}; - -struct hv_ku_msg { - __u32 kvp_index; /* Key index */ - __u8 kvp_key[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; /* Key name */ - __u8 kvp_value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; /* Key value */ -}; - - - - -#ifdef __KERNEL__ - -/* - * Registry value types. - */ - -#define REG_SZ 1 - -enum hv_kvp_exchg_op { - KVP_OP_GET = 0, - KVP_OP_SET, - KVP_OP_DELETE, - KVP_OP_ENUMERATE, - KVP_OP_COUNT /* Number of operations, must be last. */ -}; - -enum hv_kvp_exchg_pool { - KVP_POOL_EXTERNAL = 0, - KVP_POOL_GUEST, - KVP_POOL_AUTO, - KVP_POOL_AUTO_EXTERNAL, - KVP_POOL_AUTO_INTERNAL, - KVP_POOL_COUNT /* Number of pools, must be last. */ -}; - -struct hv_kvp_hdr { - u8 operation; - u8 pool; -}; - -struct hv_kvp_exchg_msg_value { - u32 value_type; - u32 key_size; - u32 value_size; - u8 key[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; - u8 value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; -}; - -struct hv_kvp_msg_enumerate { - u32 index; - struct hv_kvp_exchg_msg_value data; -}; - -struct hv_kvp_msg { - struct hv_kvp_hdr kvp_hdr; - struct hv_kvp_msg_enumerate kvp_data; -}; - -int hv_kvp_init(struct hv_util_service *); -void hv_kvp_deinit(void); -void hv_kvp_onchannelcallback(void *); - -#endif /* __KERNEL__ */ -#endif /* _KVP_H */ - diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c index 55d58f21e6d..dbb8b8eec21 100644 --- a/drivers/hv/hv_util.c +++ b/drivers/hv/hv_util.c @@ -28,9 +28,6 @@ #include #include -#include "hv_kvp.h" - - static void shutdown_onchannelcallback(void *context); static struct hv_util_service util_shutdown = { .util_cb = shutdown_onchannelcallback, diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 62b908e0e59..7332b3faecc 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -25,6 +25,166 @@ #ifndef _HYPERV_H #define _HYPERV_H +#include + +/* + * An implementation of HyperV key value pair (KVP) functionality for Linux. + * + * + * Copyright (C) 2010, Novell, Inc. + * Author : K. Y. Srinivasan + * + */ + +/* + * Maximum value size - used for both key names and value data, and includes + * any applicable NULL terminators. + * + * Note: This limit is somewhat arbitrary, but falls easily within what is + * supported for all native guests (back to Win 2000) and what is reasonable + * for the IC KVP exchange functionality. Note that Windows Me/98/95 are + * limited to 255 character key names. + * + * MSDN recommends not storing data values larger than 2048 bytes in the + * registry. + * + * Note: This value is used in defining the KVP exchange message - this value + * cannot be modified without affecting the message size and compatibility. + */ + +/* + * bytes, including any null terminators + */ +#define HV_KVP_EXCHANGE_MAX_VALUE_SIZE (2048) + + +/* + * Maximum key size - the registry limit for the length of an entry name + * is 256 characters, including the null terminator + */ + +#define HV_KVP_EXCHANGE_MAX_KEY_SIZE (512) + +/* + * In Linux, we implement the KVP functionality in two components: + * 1) The kernel component which is packaged as part of the hv_utils driver + * is responsible for communicating with the host and responsible for + * implementing the host/guest protocol. 2) A user level daemon that is + * responsible for data gathering. + * + * Host/Guest Protocol: The host iterates over an index and expects the guest + * to assign a key name to the index and also return the value corresponding to + * the key. The host will have atmost one KVP transaction outstanding at any + * given point in time. The host side iteration stops when the guest returns + * an error. Microsoft has specified the following mapping of key names to + * host specified index: + * + * Index Key Name + * 0 FullyQualifiedDomainName + * 1 IntegrationServicesVersion + * 2 NetworkAddressIPv4 + * 3 NetworkAddressIPv6 + * 4 OSBuildNumber + * 5 OSName + * 6 OSMajorVersion + * 7 OSMinorVersion + * 8 OSVersion + * 9 ProcessorArchitecture + * + * The Windows host expects the Key Name and Key Value to be encoded in utf16. + * + * Guest Kernel/KVP Daemon Protocol: As noted earlier, we implement all of the + * data gathering functionality in a user mode daemon. The user level daemon + * is also responsible for binding the key name to the index as well. The + * kernel and user-level daemon communicate using a connector channel. + * + * The user mode component first registers with the + * the kernel component. Subsequently, the kernel component requests, data + * for the specified keys. In response to this message the user mode component + * fills in the value corresponding to the specified key. We overload the + * sequence field in the cn_msg header to define our KVP message types. + * + * + * The kernel component simply acts as a conduit for communication between the + * Windows host and the user-level daemon. The kernel component passes up the + * index received from the Host to the user-level daemon. If the index is + * valid (supported), the corresponding key as well as its + * value (both are strings) is returned. If the index is invalid + * (not supported), a NULL key string is returned. + */ + +/* + * + * The following definitions are shared with the user-mode component; do not + * change any of this without making the corresponding changes in + * the KVP user-mode component. + */ + +enum hv_ku_op { + KVP_REGISTER = 0, /* Register the user mode component */ + KVP_KERNEL_GET, /* Kernel is requesting the value */ + KVP_KERNEL_SET, /* Kernel is providing the value */ + KVP_USER_GET, /* User is requesting the value */ + KVP_USER_SET /* User is providing the value */ +}; + +struct hv_ku_msg { + __u32 kvp_index; /* Key index */ + __u8 kvp_key[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; /* Key name */ + __u8 kvp_value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; /* Key value */ +}; + + + + +#ifdef __KERNEL__ + +/* + * Registry value types. + */ + +#define REG_SZ 1 + +enum hv_kvp_exchg_op { + KVP_OP_GET = 0, + KVP_OP_SET, + KVP_OP_DELETE, + KVP_OP_ENUMERATE, + KVP_OP_COUNT /* Number of operations, must be last. */ +}; + +enum hv_kvp_exchg_pool { + KVP_POOL_EXTERNAL = 0, + KVP_POOL_GUEST, + KVP_POOL_AUTO, + KVP_POOL_AUTO_EXTERNAL, + KVP_POOL_AUTO_INTERNAL, + KVP_POOL_COUNT /* Number of pools, must be last. */ +}; + +struct hv_kvp_hdr { + u8 operation; + u8 pool; +}; + +struct hv_kvp_exchg_msg_value { + u32 value_type; + u32 key_size; + u32 value_size; + u8 key[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; + u8 value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; +}; + +struct hv_kvp_msg_enumerate { + u32 index; + struct hv_kvp_exchg_msg_value data; +}; + +struct hv_kvp_msg { + struct hv_kvp_hdr kvp_hdr; + struct hv_kvp_msg_enumerate kvp_data; +}; + #include #include #include @@ -870,4 +1030,9 @@ struct hyperv_service_callback { extern void vmbus_prep_negotiate_resp(struct icmsg_hdr *, struct icmsg_negotiate *, u8 *); +int hv_kvp_init(struct hv_util_service *); +void hv_kvp_deinit(void); +void hv_kvp_onchannelcallback(void *); + +#endif /* __KERNEL__ */ #endif /* _HYPERV_H */ -- cgit v1.2.3-70-g09d2 From b3012e12cdc5825f93367cc6294419e7ab1f00cc Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 30 Jan 2012 14:47:28 +0000 Subject: cpufreq/gx: Fix the compile error Someone forgot to test this one it seems. Signed-off-by: Alan Cox Acked-by: Andi Kleen Signed-off-by: Greg Kroah-Hartman --- drivers/cpufreq/gx-suspmod.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpufreq/gx-suspmod.c b/drivers/cpufreq/gx-suspmod.c index 5a06c0ba245..456bee058fe 100644 --- a/drivers/cpufreq/gx-suspmod.c +++ b/drivers/cpufreq/gx-suspmod.c @@ -172,7 +172,7 @@ static struct pci_device_id gx_chipset_tbl[] __initdata = { { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), }, { 0, }, }; -MODULE_DEVICE_TABLE(gx_chipset_tbl); +MODULE_DEVICE_TABLE(pci, gx_chipset_tbl); static void gx_write_byte(int reg, int value) { -- cgit v1.2.3-70-g09d2 From 0cb54a3e47cb4baf0bc7463f0a64cfeae5e35697 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 2 Feb 2012 15:38:14 -0500 Subject: USB: debugging code shouldn't alter control flow People have complained that debugging code shouldn't alter the flow of control; it should restrict itself to printing out warnings and error messages. Bowing to popular opinion, this patch (as1518) changes the debugging checks in usb_submit_urb() to follow this guideline. Signed-off-by: Alan Stern Reported-by: Keith Packard CC: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/urb.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 909625b91eb..f4f20c7b776 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -403,20 +403,17 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) * cause problems in HCDs if they get it wrong. */ { - unsigned int orig_flags = urb->transfer_flags; unsigned int allowed; static int pipetypes[4] = { PIPE_CONTROL, PIPE_ISOCHRONOUS, PIPE_BULK, PIPE_INTERRUPT }; /* Check that the pipe's type matches the endpoint's type */ - if (usb_pipetype(urb->pipe) != pipetypes[xfertype]) { - dev_err(&dev->dev, "BOGUS urb xfer, pipe %x != type %x\n", + if (usb_pipetype(urb->pipe) != pipetypes[xfertype]) + dev_WARN(&dev->dev, "BOGUS urb xfer, pipe %x != type %x\n", usb_pipetype(urb->pipe), pipetypes[xfertype]); - return -EPIPE; /* The most suitable error code :-) */ - } - /* enforce simple/standard policy */ + /* Check against a simple/standard policy */ allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT | URB_DIR_MASK | URB_FREE_BUFFER); switch (xfertype) { @@ -435,14 +432,12 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) allowed |= URB_ISO_ASAP; break; } - urb->transfer_flags &= allowed; + allowed &= urb->transfer_flags; - /* fail if submitter gave bogus flags */ - if (urb->transfer_flags != orig_flags) { - dev_err(&dev->dev, "BOGUS urb flags, %x --> %x\n", - orig_flags, urb->transfer_flags); - return -EINVAL; - } + /* warn if submitter gave bogus flags */ + if (allowed != urb->transfer_flags) + dev_WARN(&dev->dev, "BOGUS urb flags, %x --> %x\n", + urb->transfer_flags, allowed); } #endif /* -- cgit v1.2.3-70-g09d2 From f84cbda06f79f05b748707b33b925b50c2fedc84 Mon Sep 17 00:00:00 2001 From: Sebastian Haas Date: Thu, 22 Dec 2011 23:57:49 +0100 Subject: can: ems_usb: Removed double netif_device_detach netif_device_attched is called twice when ems_usb_start fails with -ENODEV Signed-off-by: Sebastian Haas Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/ems_usb.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c index 9697c14b8dc..7dae64d44e8 100644 --- a/drivers/net/can/usb/ems_usb.c +++ b/drivers/net/can/usb/ems_usb.c @@ -627,9 +627,6 @@ static int ems_usb_start(struct ems_usb *dev) err = usb_submit_urb(urb, GFP_KERNEL); if (err) { - if (err == -ENODEV) - netif_device_detach(dev->netdev); - usb_unanchor_urb(urb); usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf, urb->transfer_dma); @@ -659,9 +656,6 @@ static int ems_usb_start(struct ems_usb *dev) err = usb_submit_urb(dev->intr_urb, GFP_KERNEL); if (err) { - if (err == -ENODEV) - netif_device_detach(dev->netdev); - dev_warn(netdev->dev.parent, "intr URB submit failed: %d\n", err); @@ -692,9 +686,6 @@ static int ems_usb_start(struct ems_usb *dev) return 0; failed: - if (err == -ENODEV) - netif_device_detach(dev->netdev); - dev_warn(netdev->dev.parent, "couldn't submit control: %d\n", err); return err; -- cgit v1.2.3-70-g09d2 From cf5046b309b3a05c444a8edba6b44108510b7d7d Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Mon, 10 Oct 2011 23:43:53 +0200 Subject: can: dev: let can_get_echo_skb() return dlc of CAN frame can_get_echo_skb() is usually called in the TX complete handler. The stats->tx_packets and stats->tx_bytes should be updated there, too. This patch simplifies to figure out the size of the sent CAN frame. Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev.c | 10 +++++++++- include/linux/can/dev.h | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 120f1ab5a2c..9d9799cf68c 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -327,16 +327,24 @@ EXPORT_SYMBOL_GPL(can_put_echo_skb); * is handled in the device driver. The driver must protect * access to priv->echo_skb, if necessary. */ -void can_get_echo_skb(struct net_device *dev, unsigned int idx) +unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx) { struct can_priv *priv = netdev_priv(dev); BUG_ON(idx >= priv->echo_skb_max); if (priv->echo_skb[idx]) { + struct sk_buff *skb = priv->echo_skb[idx]; + struct can_frame *cf = (struct can_frame *)skb->data; + u8 dlc = cf->can_dlc; + netif_rx(priv->echo_skb[idx]); priv->echo_skb[idx] = NULL; + + return dlc; } + + return 0; } EXPORT_SYMBOL_GPL(can_get_echo_skb); diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h index a0969fcb72b..5d2efe7e3f1 100644 --- a/include/linux/can/dev.h +++ b/include/linux/can/dev.h @@ -92,7 +92,7 @@ void can_bus_off(struct net_device *dev); void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, unsigned int idx); -void can_get_echo_skb(struct net_device *dev, unsigned int idx); +unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx); void can_free_echo_skb(struct net_device *dev, unsigned int idx); struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf); -- cgit v1.2.3-70-g09d2 From 9a12349663061d25b49e6542d005fa7193a2cb44 Mon Sep 17 00:00:00 2001 From: Reuben Dowle Date: Tue, 1 Nov 2011 11:18:03 +1300 Subject: can: flexcan: Fix CAN_RAW_RECV_OWN_MSGS and CAN_RAW_LOOPBACK Currently the flexcan driver uses hardware local echo. This blindly echos all transmitted frames to all receiving sockets, regardless what CAN_RAW_RECV_OWN_MSGS and CAN_RAW_LOOPBACK are set to. This patch now submits transmitted frames to be echoed in the transmit complete interrupt, preserving the reference to the sending socket. This allows the can protocol to correctly handle the local echo. Further this patch moves tx_bytes statistic accounting into the tx_complete handler. Signed-off-by: Reuben Dowle [mkl: move tx_bytes accounting into tx_complete handler; cleanups] Signed-off-by: Marc Kleine-Budde --- drivers/net/can/flexcan.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 7fd8089946f..ab0136f49f4 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -269,7 +269,6 @@ static int flexcan_get_berr_counter(const struct net_device *dev, static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev) { const struct flexcan_priv *priv = netdev_priv(dev); - struct net_device_stats *stats = &dev->stats; struct flexcan_regs __iomem *regs = priv->base; struct can_frame *cf = (struct can_frame *)skb->data; u32 can_id; @@ -299,14 +298,11 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev) flexcan_write(data, ®s->cantxfg[FLEXCAN_TX_BUF_ID].data[1]); } + can_put_echo_skb(skb, dev, 0); + flexcan_write(can_id, ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_id); flexcan_write(ctrl, ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl); - kfree_skb(skb); - - /* tx_packets is incremented in flexcan_irq */ - stats->tx_bytes += cf->can_dlc; - return NETDEV_TX_OK; } @@ -609,7 +605,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) /* transmission complete interrupt */ if (reg_iflag1 & (1 << FLEXCAN_TX_BUF_ID)) { - /* tx_bytes is incremented in flexcan_start_xmit */ + stats->tx_bytes += can_get_echo_skb(dev, 0); stats->tx_packets++; flexcan_write((1 << FLEXCAN_TX_BUF_ID), ®s->iflag1); netif_wake_queue(dev); @@ -697,12 +693,13 @@ static int flexcan_chip_start(struct net_device *dev) * only supervisor access * enable warning int * choose format C + * disable local echo * */ reg_mcr = flexcan_read(®s->mcr); reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN | - FLEXCAN_MCR_IDAM_C; + FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_SRX_DIS; dev_dbg(dev->dev.parent, "%s: writing mcr=0x%08x", __func__, reg_mcr); flexcan_write(reg_mcr, ®s->mcr); @@ -970,7 +967,7 @@ static int __devinit flexcan_probe(struct platform_device *pdev) goto failed_map; } - dev = alloc_candev(sizeof(struct flexcan_priv), 0); + dev = alloc_candev(sizeof(struct flexcan_priv), 1); if (!dev) { err = -ENOMEM; goto failed_alloc; @@ -978,7 +975,7 @@ static int __devinit flexcan_probe(struct platform_device *pdev) dev->netdev_ops = &flexcan_netdev_ops; dev->irq = irq; - dev->flags |= IFF_ECHO; /* we support local echo in hardware */ + dev->flags |= IFF_ECHO; priv = netdev_priv(dev); priv->can.clock.freq = clock_freq; -- cgit v1.2.3-70-g09d2 From 2ee6850ca0cac95101d2a36c8b186b40d4fc7311 Mon Sep 17 00:00:00 2001 From: Sebastian Haas Date: Thu, 22 Dec 2011 23:58:34 +0100 Subject: can: ems_usb: Improved memory handling on ems_usb_start Do not return from ems_usb_start if allocation fails. If not all URBs could be allocated use the one already submitted. Signed-off-by: Sebastian Haas Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/ems_usb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c index 7dae64d44e8..9783e02fbc2 100644 --- a/drivers/net/can/usb/ems_usb.c +++ b/drivers/net/can/usb/ems_usb.c @@ -607,7 +607,8 @@ static int ems_usb_start(struct ems_usb *dev) if (!urb) { dev_err(netdev->dev.parent, "No memory left for URBs\n"); - return -ENOMEM; + err = -ENOMEM; + break; } buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL, @@ -616,7 +617,8 @@ static int ems_usb_start(struct ems_usb *dev) dev_err(netdev->dev.parent, "No memory left for USB buffer\n"); usb_free_urb(urb); - return -ENOMEM; + err = -ENOMEM; + break; } usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 2), -- cgit v1.2.3-70-g09d2 From e08534b57e79fa722e3136b79868a725a8eea0f0 Mon Sep 17 00:00:00 2001 From: James Kime Date: Mon, 12 Dec 2011 13:45:58 +0100 Subject: can: plx_pci: add support for IXXAT PCI cards This patch adds support for IXXAT passive CAN controllers Signed-off-by: James Kime Acked-by: Wolfgang Grandegger Signed-off-by: Marc Kleine-Budde --- drivers/net/can/sja1000/Kconfig | 1 + drivers/net/can/sja1000/plx_pci.c | 22 +++++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/can/sja1000/Kconfig b/drivers/net/can/sja1000/Kconfig index 36e9d594069..b21523ddff3 100644 --- a/drivers/net/can/sja1000/Kconfig +++ b/drivers/net/can/sja1000/Kconfig @@ -71,6 +71,7 @@ config CAN_PLX_PCI - esd CAN-PCIe/2000 - Marathon CAN-bus-PCI card (http://www.marathon.ru/) - TEWS TECHNOLOGIES TPMC810 card (http://www.tews.com/) + - IXXAT Automation PC-I 04/PCI card (http://www.ixxat.com/) config CAN_TSCAN1 tristate "TS-CAN1 PC104 boards" diff --git a/drivers/net/can/sja1000/plx_pci.c b/drivers/net/can/sja1000/plx_pci.c index c7f3d4ea116..a227586ddd5 100644 --- a/drivers/net/can/sja1000/plx_pci.c +++ b/drivers/net/can/sja1000/plx_pci.c @@ -43,7 +43,8 @@ MODULE_SUPPORTED_DEVICE("Adlink PCI-7841/cPCI-7841, " "TEWS TECHNOLOGIES TPMC810, " "esd CAN-PCI/CPCI/PCI104/200, " "esd CAN-PCI/PMC/266, " - "esd CAN-PCIe/2000") + "esd CAN-PCIe/2000, " + "IXXAT PC-I 04/PCI") MODULE_LICENSE("GPL v2"); #define PLX_PCI_MAX_CHAN 2 @@ -121,6 +122,10 @@ struct plx_pci_card { #define ESD_PCI_SUB_SYS_ID_PCIE2000 0x0200 #define ESD_PCI_SUB_SYS_ID_PCI104200 0x0501 +#define IXXAT_PCI_VENDOR_ID 0x10b5 +#define IXXAT_PCI_DEVICE_ID 0x9050 +#define IXXAT_PCI_SUB_SYS_ID 0x2540 + #define MARATHON_PCI_DEVICE_ID 0x2715 #define TEWS_PCI_VENDOR_ID 0x1498 @@ -193,6 +198,14 @@ static struct plx_pci_card_info plx_pci_card_info_esd2000 __devinitdata = { /* based on PEX8311 */ }; +static struct plx_pci_card_info plx_pci_card_info_ixxat __devinitdata = { + "IXXAT PC-I 04/PCI", 2, + PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR, + {0, 0x00, 0x00}, { {2, 0x00, 0x80}, {2, 0x200, 0x80} }, + &plx_pci_reset_common + /* based on PLX9050 */ +}; + static struct plx_pci_card_info plx_pci_card_info_marathon __devinitdata = { "Marathon CAN-bus-PCI", 2, PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR, @@ -266,6 +279,13 @@ static DEFINE_PCI_DEVICE_TABLE(plx_pci_tbl) = { 0, 0, (kernel_ulong_t)&plx_pci_card_info_esd2000 }, + { + /* IXXAT PC-I 04/PCI card */ + IXXAT_PCI_VENDOR_ID, IXXAT_PCI_DEVICE_ID, + PCI_ANY_ID, IXXAT_PCI_SUB_SYS_ID, + 0, 0, + (kernel_ulong_t)&plx_pci_card_info_ixxat + }, { /* Marathon CAN-bus-PCI card */ PCI_VENDOR_ID_PLX, MARATHON_PCI_DEVICE_ID, -- cgit v1.2.3-70-g09d2 From 74b5127884d76ccbf4f445f650f9e969ccb4a374 Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Fri, 27 Jan 2012 20:05:21 +0900 Subject: can: pch_can: Change company name OKI SEMICONDUCTOR to LAPIS Semiconductor On October 1 in 2011, OKI SEMICONDUCTOR Co., Ltd. changed the company name in to LAPIS Semiconductor Signed-off-by: Tomoya MORINAGA Signed-off-by: Marc Kleine-Budde --- drivers/net/can/pch_can.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index d11fbb2b95f..cc3ed57b6b1 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -1,6 +1,6 @@ /* * Copyright (C) 1999 - 2010 Intel Corporation. - * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD. + * Copyright (C) 2010 LAPIS SEMICONDUCTOR CO., LTD. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by -- cgit v1.2.3-70-g09d2 From 03c49daa8168b58e6256f0cad88771b9440ca5f7 Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Fri, 27 Jan 2012 20:05:22 +0900 Subject: can: Kconfig: add more information about Intel EG20T PCH CAN controller Current menu description, not easy to understand what the description means. So, add information about the device. Signed-off-by: Tomoya MORINAGA [mkl: Added space before opening parentheses in Kconfig. Make commit message more descriptive.] Signed-off-by: Marc Kleine-Budde --- drivers/net/can/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index ab45758c49a..bb709fd6699 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -103,11 +103,11 @@ config CAN_FLEXCAN Say Y here if you want to support for Freescale FlexCAN. config PCH_CAN - tristate "PCH CAN" + tristate "Intel EG20T PCH CAN controller" depends on CAN_DEV && PCI ---help--- - This driver is for PCH CAN of Topcliff which is an IOH for x86 - embedded processor. + This driver is for PCH CAN of Topcliff (Intel EG20T PCH) which + is an IOH for x86 embedded processor (Intel Atom E6xx series). This driver can access CAN bus. source "drivers/net/can/mscan/Kconfig" -- cgit v1.2.3-70-g09d2 From 79d0d8a7d5edca459f544c2ad75088e99307795e Mon Sep 17 00:00:00 2001 From: Wolfgang Grandegger Date: Wed, 1 Feb 2012 11:14:13 +0100 Subject: can: bfin_can/ti_hecc/mscan: add missing do_get_berr_counter callback Cc: Anant Gole Signed-off-by: Wolfgang Grandegger Signed-off-by: Marc Kleine-Budde --- drivers/net/can/bfin_can.c | 15 +++++++++++++++ drivers/net/can/mscan/mscan.c | 16 +++++++++++++++- drivers/net/can/ti_hecc.c | 12 ++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/can/bfin_can.c b/drivers/net/can/bfin_can.c index 349e0fabb63..e1e7f9da3da 100644 --- a/drivers/net/can/bfin_can.c +++ b/drivers/net/can/bfin_can.c @@ -224,6 +224,20 @@ static int bfin_can_set_mode(struct net_device *dev, enum can_mode mode) return 0; } +static int bfin_can_get_berr_counter(const struct net_device *dev, + struct can_berr_counter *bec) +{ + struct bfin_can_priv *priv = netdev_priv(dev); + struct bfin_can_regs __iomem *reg = priv->membase; + + u16 cec = bfin_read(®->cec); + + bec->txerr = cec >> 8; + bec->rxerr = cec; + + return 0; +} + static int bfin_can_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct bfin_can_priv *priv = netdev_priv(dev); @@ -509,6 +523,7 @@ struct net_device *alloc_bfin_candev(void) priv->can.bittiming_const = &bfin_can_bittiming_const; priv->can.do_set_bittiming = bfin_can_set_bittiming; priv->can.do_set_mode = bfin_can_set_mode; + priv->can.do_get_berr_counter = bfin_can_get_berr_counter; priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; return dev; diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c index 1c82dd8b896..d11b0832ccd 100644 --- a/drivers/net/can/mscan/mscan.c +++ b/drivers/net/can/mscan/mscan.c @@ -560,6 +560,18 @@ static int mscan_do_set_bittiming(struct net_device *dev) return 0; } +static int mscan_get_berr_counter(const struct net_device *dev, + struct can_berr_counter *bec) +{ + struct mscan_priv *priv = netdev_priv(dev); + struct mscan_regs __iomem *regs = priv->reg_base; + + bec->txerr = in_8(®s->cantxerr); + bec->rxerr = in_8(®s->canrxerr); + + return 0; +} + static int mscan_open(struct net_device *dev) { int ret; @@ -639,8 +651,10 @@ int register_mscandev(struct net_device *dev, int mscan_clksrc) else ctl1 &= ~MSCAN_CLKSRC; - if (priv->type == MSCAN_TYPE_MPC5121) + if (priv->type == MSCAN_TYPE_MPC5121) { + priv->can.do_get_berr_counter = mscan_get_berr_counter; ctl1 |= MSCAN_BORM; /* bus-off recovery upon request */ + } ctl1 |= MSCAN_CANE; out_8(®s->canctl1, ctl1); diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index df809e3f130..aee925ab0de 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c @@ -458,6 +458,17 @@ static int ti_hecc_do_set_mode(struct net_device *ndev, enum can_mode mode) return ret; } +static int ti_hecc_get_berr_counter(const struct net_device *ndev, + struct can_berr_counter *bec) +{ + struct ti_hecc_priv *priv = netdev_priv(ndev); + + bec->txerr = hecc_read(priv, HECC_CANTEC); + bec->rxerr = hecc_read(priv, HECC_CANREC); + + return 0; +} + /* * ti_hecc_xmit: HECC Transmit * @@ -922,6 +933,7 @@ static int ti_hecc_probe(struct platform_device *pdev) priv->can.bittiming_const = &ti_hecc_bittiming_const; priv->can.do_set_mode = ti_hecc_do_set_mode; priv->can.do_get_state = ti_hecc_get_state; + priv->can.do_get_berr_counter = ti_hecc_get_berr_counter; priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; spin_lock_init(&priv->mbx_lock); -- cgit v1.2.3-70-g09d2 From aabdfd6adb804d0aaba0188ade0f1afe42a52e31 Mon Sep 17 00:00:00 2001 From: Wolfgang Grandegger Date: Wed, 1 Feb 2012 11:02:05 +0100 Subject: can: replace the dev_dbg/info/err/... with the new netdev_xxx macros Cc: uclinux-dist-devel@blackfin.uclinux.org Cc: Anant Gole Cc: Chris Elston Cc: Sebastian Haas Cc: Matthias Fuchs Signed-off-by: Wolfgang Grandegger Acked-by: Sebastian Haas Acked-by: Mike Frysinger Signed-off-by: Marc Kleine-Budde --- drivers/net/can/bfin_can.c | 21 ++++++--------- drivers/net/can/dev.c | 23 ++++++++-------- drivers/net/can/flexcan.c | 44 +++++++++++++++--------------- drivers/net/can/mcp251x.c | 3 +-- drivers/net/can/mscan/mscan.c | 17 ++++++------ drivers/net/can/sja1000/sja1000.c | 19 +++++++------ drivers/net/can/ti_hecc.c | 20 +++++++------- drivers/net/can/usb/ems_usb.c | 57 ++++++++++++++++----------------------- drivers/net/can/usb/esd_usb2.c | 27 +++++++++---------- 9 files changed, 103 insertions(+), 128 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/bfin_can.c b/drivers/net/can/bfin_can.c index e1e7f9da3da..3f88473423e 100644 --- a/drivers/net/can/bfin_can.c +++ b/drivers/net/can/bfin_can.c @@ -82,8 +82,7 @@ static int bfin_can_set_bittiming(struct net_device *dev) bfin_write(®->clock, clk); bfin_write(®->timing, timing); - dev_info(dev->dev.parent, "setting CLOCK=0x%04x TIMING=0x%04x\n", - clk, timing); + netdev_info(dev, "setting CLOCK=0x%04x TIMING=0x%04x\n", clk, timing); return 0; } @@ -108,8 +107,7 @@ static void bfin_can_set_reset_mode(struct net_device *dev) while (!(bfin_read(®->control) & CCA)) { udelay(10); if (--timeout == 0) { - dev_err(dev->dev.parent, - "fail to enter configuration mode\n"); + netdev_err(dev, "fail to enter configuration mode\n"); BUG(); } } @@ -165,8 +163,7 @@ static void bfin_can_set_normal_mode(struct net_device *dev) while (bfin_read(®->status) & CCA) { udelay(10); if (--timeout == 0) { - dev_err(dev->dev.parent, - "fail to leave configuration mode\n"); + netdev_err(dev, "fail to leave configuration mode\n"); BUG(); } } @@ -345,7 +342,7 @@ static int bfin_can_err(struct net_device *dev, u16 isrc, u16 status) if (isrc & RMLIS) { /* data overrun interrupt */ - dev_dbg(dev->dev.parent, "data overrun interrupt\n"); + netdev_dbg(dev, "data overrun interrupt\n"); cf->can_id |= CAN_ERR_CRTL; cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; stats->rx_over_errors++; @@ -353,7 +350,7 @@ static int bfin_can_err(struct net_device *dev, u16 isrc, u16 status) } if (isrc & BOIS) { - dev_dbg(dev->dev.parent, "bus-off mode interrupt\n"); + netdev_dbg(dev, "bus-off mode interrupt\n"); state = CAN_STATE_BUS_OFF; cf->can_id |= CAN_ERR_BUSOFF; can_bus_off(dev); @@ -361,13 +358,12 @@ static int bfin_can_err(struct net_device *dev, u16 isrc, u16 status) if (isrc & EPIS) { /* error passive interrupt */ - dev_dbg(dev->dev.parent, "error passive interrupt\n"); + netdev_dbg(dev, "error passive interrupt\n"); state = CAN_STATE_ERROR_PASSIVE; } if ((isrc & EWTIS) || (isrc & EWRIS)) { - dev_dbg(dev->dev.parent, - "Error Warning Transmit/Receive Interrupt\n"); + netdev_dbg(dev, "Error Warning Transmit/Receive Interrupt\n"); state = CAN_STATE_ERROR_WARNING; } @@ -651,8 +647,7 @@ static int bfin_can_suspend(struct platform_device *pdev, pm_message_t mesg) while (!(bfin_read(®->intr) & SMACK)) { udelay(10); if (--timeout == 0) { - dev_err(dev->dev.parent, - "fail to enter sleep mode\n"); + netdev_err(dev, "fail to enter sleep mode\n"); BUG(); } } diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 9d9799cf68c..c5fe3a3db8c 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -130,13 +130,13 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt) /* Error in one-tenth of a percent */ error = (best_error * 1000) / bt->bitrate; if (error > CAN_CALC_MAX_ERROR) { - dev_err(dev->dev.parent, - "bitrate error %ld.%ld%% too high\n", - error / 10, error % 10); + netdev_err(dev, + "bitrate error %ld.%ld%% too high\n", + error / 10, error % 10); return -EDOM; } else { - dev_warn(dev->dev.parent, "bitrate error %ld.%ld%%\n", - error / 10, error % 10); + netdev_warn(dev, "bitrate error %ld.%ld%%\n", + error / 10, error % 10); } } @@ -172,7 +172,7 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt) #else /* !CONFIG_CAN_CALC_BITTIMING */ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt) { - dev_err(dev->dev.parent, "bit-timing calculation not available\n"); + netdev_err(dev, "bit-timing calculation not available\n"); return -EINVAL; } #endif /* CONFIG_CAN_CALC_BITTIMING */ @@ -313,8 +313,7 @@ void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, priv->echo_skb[idx] = skb; } else { /* locking problem with netif_stop_queue() ?? */ - dev_err(dev->dev.parent, "%s: BUG! echo_skb is occupied!\n", - __func__); + netdev_err(dev, "%s: BUG! echo_skb is occupied!\n", __func__); kfree_skb(skb); } } @@ -400,7 +399,7 @@ void can_restart(unsigned long data) stats->rx_bytes += cf->can_dlc; restart: - dev_dbg(dev->dev.parent, "restarted\n"); + netdev_dbg(dev, "restarted\n"); priv->can_stats.restarts++; /* Now restart the device */ @@ -408,7 +407,7 @@ restart: netif_carrier_on(dev); if (err) - dev_err(dev->dev.parent, "Error %d during restart", err); + netdev_err(dev, "Error %d during restart", err); } int can_restart_now(struct net_device *dev) @@ -441,7 +440,7 @@ void can_bus_off(struct net_device *dev) { struct can_priv *priv = netdev_priv(dev); - dev_dbg(dev->dev.parent, "bus-off\n"); + netdev_dbg(dev, "bus-off\n"); netif_carrier_off(dev); priv->can_stats.bus_off++; @@ -553,7 +552,7 @@ int open_candev(struct net_device *dev) struct can_priv *priv = netdev_priv(dev); if (!priv->bittiming.tq && !priv->bittiming.bitrate) { - dev_err(dev->dev.parent, "bit-timing not yet defined\n"); + netdev_err(dev, "bit-timing not yet defined\n"); return -EINVAL; } diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index ab0136f49f4..e636287213f 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -315,34 +315,34 @@ static void do_bus_err(struct net_device *dev, cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; if (reg_esr & FLEXCAN_ESR_BIT1_ERR) { - dev_dbg(dev->dev.parent, "BIT1_ERR irq\n"); + netdev_dbg(dev, "BIT1_ERR irq\n"); cf->data[2] |= CAN_ERR_PROT_BIT1; tx_errors = 1; } if (reg_esr & FLEXCAN_ESR_BIT0_ERR) { - dev_dbg(dev->dev.parent, "BIT0_ERR irq\n"); + netdev_dbg(dev, "BIT0_ERR irq\n"); cf->data[2] |= CAN_ERR_PROT_BIT0; tx_errors = 1; } if (reg_esr & FLEXCAN_ESR_ACK_ERR) { - dev_dbg(dev->dev.parent, "ACK_ERR irq\n"); + netdev_dbg(dev, "ACK_ERR irq\n"); cf->can_id |= CAN_ERR_ACK; cf->data[3] |= CAN_ERR_PROT_LOC_ACK; tx_errors = 1; } if (reg_esr & FLEXCAN_ESR_CRC_ERR) { - dev_dbg(dev->dev.parent, "CRC_ERR irq\n"); + netdev_dbg(dev, "CRC_ERR irq\n"); cf->data[2] |= CAN_ERR_PROT_BIT; cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ; rx_errors = 1; } if (reg_esr & FLEXCAN_ESR_FRM_ERR) { - dev_dbg(dev->dev.parent, "FRM_ERR irq\n"); + netdev_dbg(dev, "FRM_ERR irq\n"); cf->data[2] |= CAN_ERR_PROT_FORM; rx_errors = 1; } if (reg_esr & FLEXCAN_ESR_STF_ERR) { - dev_dbg(dev->dev.parent, "STF_ERR irq\n"); + netdev_dbg(dev, "STF_ERR irq\n"); cf->data[2] |= CAN_ERR_PROT_STUFF; rx_errors = 1; } @@ -389,7 +389,7 @@ static void do_state(struct net_device *dev, */ if (new_state >= CAN_STATE_ERROR_WARNING && new_state <= CAN_STATE_BUS_OFF) { - dev_dbg(dev->dev.parent, "Error Warning IRQ\n"); + netdev_dbg(dev, "Error Warning IRQ\n"); priv->can.can_stats.error_warning++; cf->can_id |= CAN_ERR_CRTL; @@ -405,7 +405,7 @@ static void do_state(struct net_device *dev, */ if (new_state >= CAN_STATE_ERROR_PASSIVE && new_state <= CAN_STATE_BUS_OFF) { - dev_dbg(dev->dev.parent, "Error Passive IRQ\n"); + netdev_dbg(dev, "Error Passive IRQ\n"); priv->can.can_stats.error_passive++; cf->can_id |= CAN_ERR_CRTL; @@ -415,8 +415,8 @@ static void do_state(struct net_device *dev, } break; case CAN_STATE_BUS_OFF: - dev_err(dev->dev.parent, - "BUG! hardware recovered automatically from BUS_OFF\n"); + netdev_err(dev, "BUG! " + "hardware recovered automatically from BUS_OFF\n"); break; default: break; @@ -425,7 +425,7 @@ static void do_state(struct net_device *dev, /* process state changes depending on the new state */ switch (new_state) { case CAN_STATE_ERROR_ACTIVE: - dev_dbg(dev->dev.parent, "Error Active\n"); + netdev_dbg(dev, "Error Active\n"); cf->can_id |= CAN_ERR_PROT; cf->data[2] = CAN_ERR_PROT_ACTIVE; break; @@ -644,12 +644,12 @@ static void flexcan_set_bittiming(struct net_device *dev) if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) reg |= FLEXCAN_CTRL_SMP; - dev_info(dev->dev.parent, "writing ctrl=0x%08x\n", reg); + netdev_info(dev, "writing ctrl=0x%08x\n", reg); flexcan_write(reg, ®s->ctrl); /* print chip status */ - dev_dbg(dev->dev.parent, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__, - flexcan_read(®s->mcr), flexcan_read(®s->ctrl)); + netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__, + flexcan_read(®s->mcr), flexcan_read(®s->ctrl)); } /* @@ -675,9 +675,8 @@ static int flexcan_chip_start(struct net_device *dev) reg_mcr = flexcan_read(®s->mcr); if (reg_mcr & FLEXCAN_MCR_SOFTRST) { - dev_err(dev->dev.parent, - "Failed to softreset can module (mcr=0x%08x)\n", - reg_mcr); + netdev_err(dev, "Failed to softreset can module (mcr=0x%08x)\n", + reg_mcr); err = -ENODEV; goto out; } @@ -700,7 +699,7 @@ static int flexcan_chip_start(struct net_device *dev) reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_SRX_DIS; - dev_dbg(dev->dev.parent, "%s: writing mcr=0x%08x", __func__, reg_mcr); + netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr); flexcan_write(reg_mcr, ®s->mcr); /* @@ -726,7 +725,7 @@ static int flexcan_chip_start(struct net_device *dev) /* save for later use */ priv->reg_ctrl_default = reg_ctrl; - dev_dbg(dev->dev.parent, "%s: writing ctrl=0x%08x", __func__, reg_ctrl); + netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl); flexcan_write(reg_ctrl, ®s->ctrl); for (i = 0; i < ARRAY_SIZE(regs->cantxfg); i++) { @@ -758,8 +757,8 @@ static int flexcan_chip_start(struct net_device *dev) flexcan_write(FLEXCAN_IFLAG_DEFAULT, ®s->imask1); /* print chip status */ - dev_dbg(dev->dev.parent, "%s: reading mcr=0x%08x ctrl=0x%08x\n", - __func__, flexcan_read(®s->mcr), flexcan_read(®s->ctrl)); + netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n", __func__, + flexcan_read(®s->mcr), flexcan_read(®s->ctrl)); return 0; @@ -897,8 +896,7 @@ static int __devinit register_flexcandev(struct net_device *dev) */ reg = flexcan_read(®s->mcr); if (!(reg & FLEXCAN_MCR_FEN)) { - dev_err(dev->dev.parent, - "Could not enable RX FIFO, unsupported core\n"); + netdev_err(dev, "Could not enable RX FIFO, unsupported core\n"); err = -ENODEV; goto out; } diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index 330140ee266..346785c56a2 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -712,8 +712,7 @@ static void mcp251x_error_skb(struct net_device *net, int can_id, int data1) frame->data[1] = data1; netif_rx_ni(skb); } else { - dev_err(&net->dev, - "cannot allocate error skb\n"); + netdev_err(net, "cannot allocate error skb\n"); } } diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c index d11b0832ccd..41a2a2dda7e 100644 --- a/drivers/net/can/mscan/mscan.c +++ b/drivers/net/can/mscan/mscan.c @@ -95,9 +95,9 @@ static int mscan_set_mode(struct net_device *dev, u8 mode) * any, at once. */ if (i >= MSCAN_SET_MODE_RETRIES) - dev_dbg(dev->dev.parent, - "device failed to enter sleep mode. " - "We proceed anyhow.\n"); + netdev_dbg(dev, + "device failed to enter sleep mode. " + "We proceed anyhow.\n"); else priv->can.state = CAN_STATE_SLEEPING; } @@ -213,7 +213,7 @@ static netdev_tx_t mscan_start_xmit(struct sk_buff *skb, struct net_device *dev) switch (hweight8(i)) { case 0: netif_stop_queue(dev); - dev_err(dev->dev.parent, "Tx Ring full when queue awake!\n"); + netdev_err(dev, "Tx Ring full when queue awake!\n"); return NETDEV_TX_BUSY; case 1: /* @@ -352,7 +352,7 @@ static void mscan_get_err_frame(struct net_device *dev, struct can_frame *frame, struct net_device_stats *stats = &dev->stats; enum can_state old_state; - dev_dbg(dev->dev.parent, "error interrupt (canrflg=%#x)\n", canrflg); + netdev_dbg(dev, "error interrupt (canrflg=%#x)\n", canrflg); frame->can_id = CAN_ERR_FLAG; if (canrflg & MSCAN_OVRIF) { @@ -427,7 +427,7 @@ static int mscan_rx_poll(struct napi_struct *napi, int quota) skb = alloc_can_skb(dev, &frame); if (!skb) { if (printk_ratelimit()) - dev_notice(dev->dev.parent, "packet dropped\n"); + netdev_notice(dev, "packet dropped\n"); stats->rx_dropped++; out_8(®s->canrflg, canrflg); continue; @@ -551,8 +551,7 @@ static int mscan_do_set_bittiming(struct net_device *dev) BTR1_SET_TSEG2(bt->phase_seg2) | BTR1_SET_SAM(priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)); - dev_info(dev->dev.parent, "setting BTR0=0x%02x BTR1=0x%02x\n", - btr0, btr1); + netdev_info(dev, "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1); out_8(®s->canbtr0, btr0); out_8(®s->canbtr1, btr1); @@ -587,7 +586,7 @@ static int mscan_open(struct net_device *dev) ret = request_irq(dev->irq, mscan_isr, 0, dev->name, dev); if (ret < 0) { - dev_err(dev->dev.parent, "failed to attach interrupt\n"); + netdev_err(dev, "failed to attach interrupt\n"); goto exit_napi_disable; } diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c index 04a3f1b756a..ebbcfcafe29 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c @@ -128,7 +128,7 @@ static void set_reset_mode(struct net_device *dev) status = priv->read_reg(priv, REG_MOD); } - dev_err(dev->dev.parent, "setting SJA1000 into reset mode failed!\n"); + netdev_err(dev, "setting SJA1000 into reset mode failed!\n"); } static void set_normal_mode(struct net_device *dev) @@ -156,7 +156,7 @@ static void set_normal_mode(struct net_device *dev) status = priv->read_reg(priv, REG_MOD); } - dev_err(dev->dev.parent, "setting SJA1000 into normal mode failed!\n"); + netdev_err(dev, "setting SJA1000 into normal mode failed!\n"); } static void sja1000_start(struct net_device *dev) @@ -209,8 +209,7 @@ static int sja1000_set_bittiming(struct net_device *dev) if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) btr1 |= 0x80; - dev_info(dev->dev.parent, - "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1); + netdev_info(dev, "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1); priv->write_reg(priv, REG_BTR0, btr0); priv->write_reg(priv, REG_BTR1, btr1); @@ -378,7 +377,7 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) if (isrc & IRQ_DOI) { /* data overrun interrupt */ - dev_dbg(dev->dev.parent, "data overrun interrupt\n"); + netdev_dbg(dev, "data overrun interrupt\n"); cf->can_id |= CAN_ERR_CRTL; cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; stats->rx_over_errors++; @@ -388,7 +387,7 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) if (isrc & IRQ_EI) { /* error warning interrupt */ - dev_dbg(dev->dev.parent, "error warning interrupt\n"); + netdev_dbg(dev, "error warning interrupt\n"); if (status & SR_BS) { state = CAN_STATE_BUS_OFF; @@ -429,7 +428,7 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) } if (isrc & IRQ_EPI) { /* error passive interrupt */ - dev_dbg(dev->dev.parent, "error passive interrupt\n"); + netdev_dbg(dev, "error passive interrupt\n"); if (status & SR_ES) state = CAN_STATE_ERROR_PASSIVE; else @@ -437,7 +436,7 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) } if (isrc & IRQ_ALI) { /* arbitration lost interrupt */ - dev_dbg(dev->dev.parent, "arbitration lost interrupt\n"); + netdev_dbg(dev, "arbitration lost interrupt\n"); alc = priv->read_reg(priv, REG_ALC); priv->can.can_stats.arbitration_lost++; stats->tx_errors++; @@ -495,7 +494,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id) status = priv->read_reg(priv, REG_SR); if (isrc & IRQ_WUI) - dev_warn(dev->dev.parent, "wakeup interrupt\n"); + netdev_warn(dev, "wakeup interrupt\n"); if (isrc & IRQ_TI) { /* transmission complete interrupt */ @@ -522,7 +521,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id) priv->post_irq(priv); if (n >= SJA1000_MAX_IRQ) - dev_dbg(dev->dev.parent, "%d messages handled in ISR", n); + netdev_dbg(dev, "%d messages handled in ISR", n); return (n) ? IRQ_HANDLED : IRQ_NONE; } diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index aee925ab0de..0d18a931972 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c @@ -306,7 +306,7 @@ static int ti_hecc_set_btc(struct ti_hecc_priv *priv) if (bit_timing->brp > 4) can_btc |= HECC_CANBTC_SAM; else - dev_warn(priv->ndev->dev.parent, "WARN: Triple" \ + netdev_warn(priv->ndev, "WARN: Triple" "sampling not set due to h/w limitations"); } can_btc |= ((bit_timing->sjw - 1) & 0x3) << 8; @@ -315,7 +315,7 @@ static int ti_hecc_set_btc(struct ti_hecc_priv *priv) /* ERM being set to 0 by default meaning resync at falling edge */ hecc_write(priv, HECC_CANBTC, can_btc); - dev_info(priv->ndev->dev.parent, "setting CANBTC=%#x\n", can_btc); + netdev_info(priv->ndev, "setting CANBTC=%#x\n", can_btc); return 0; } @@ -332,7 +332,7 @@ static void ti_hecc_reset(struct net_device *ndev) u32 cnt; struct ti_hecc_priv *priv = netdev_priv(ndev); - dev_dbg(ndev->dev.parent, "resetting hecc ...\n"); + netdev_dbg(ndev, "resetting hecc ...\n"); hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_SRES); /* Set change control request and wait till enabled */ @@ -507,7 +507,7 @@ static netdev_tx_t ti_hecc_xmit(struct sk_buff *skb, struct net_device *ndev) if (unlikely(hecc_read(priv, HECC_CANME) & mbx_mask)) { spin_unlock_irqrestore(&priv->mbx_lock, flags); netif_stop_queue(ndev); - dev_err(priv->ndev->dev.parent, + netdev_err(priv->ndev, "BUG: TX mbx not ready tx_head=%08X, tx_tail=%08X\n", priv->tx_head, priv->tx_tail); return NETDEV_TX_BUSY; @@ -561,7 +561,7 @@ static int ti_hecc_rx_pkt(struct ti_hecc_priv *priv, int mbxno) skb = alloc_can_skb(priv->ndev, &cf); if (!skb) { if (printk_ratelimit()) - dev_err(priv->ndev->dev.parent, + netdev_err(priv->ndev, "ti_hecc_rx_pkt: alloc_can_skb() failed\n"); return -ENOMEM; } @@ -679,7 +679,7 @@ static int ti_hecc_error(struct net_device *ndev, int int_status, skb = alloc_can_err_skb(ndev, &cf); if (!skb) { if (printk_ratelimit()) - dev_err(priv->ndev->dev.parent, + netdev_err(priv->ndev, "ti_hecc_error: alloc_can_err_skb() failed\n"); return -ENOMEM; } @@ -695,7 +695,7 @@ static int ti_hecc_error(struct net_device *ndev, int int_status, cf->data[1] |= CAN_ERR_CRTL_RX_WARNING; } hecc_set_bit(priv, HECC_CANES, HECC_CANES_EW); - dev_dbg(priv->ndev->dev.parent, "Error Warning interrupt\n"); + netdev_dbg(priv->ndev, "Error Warning interrupt\n"); hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_CCR); } @@ -710,7 +710,7 @@ static int ti_hecc_error(struct net_device *ndev, int int_status, cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE; } hecc_set_bit(priv, HECC_CANES, HECC_CANES_EP); - dev_dbg(priv->ndev->dev.parent, "Error passive interrupt\n"); + netdev_dbg(priv->ndev, "Error passive interrupt\n"); hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_CCR); } @@ -835,7 +835,7 @@ static int ti_hecc_open(struct net_device *ndev) err = request_irq(ndev->irq, ti_hecc_interrupt, IRQF_SHARED, ndev->name, ndev); if (err) { - dev_err(ndev->dev.parent, "error requesting interrupt\n"); + netdev_err(ndev, "error requesting interrupt\n"); return err; } @@ -844,7 +844,7 @@ static int ti_hecc_open(struct net_device *ndev) /* Open common can device */ err = open_candev(ndev); if (err) { - dev_err(ndev->dev.parent, "open_candev() failed %d\n", err); + netdev_err(ndev, "open_candev() failed %d\n", err); ti_hecc_transceiver_switch(priv, 0); free_irq(ndev->irq, ndev); return err; diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c index 9783e02fbc2..7ae65fc8003 100644 --- a/drivers/net/can/usb/ems_usb.c +++ b/drivers/net/can/usb/ems_usb.c @@ -288,8 +288,7 @@ static void ems_usb_read_interrupt_callback(struct urb *urb) return; default: - dev_info(netdev->dev.parent, "Rx interrupt aborted %d\n", - urb->status); + netdev_info(netdev, "Rx interrupt aborted %d\n", urb->status); break; } @@ -298,8 +297,7 @@ static void ems_usb_read_interrupt_callback(struct urb *urb) if (err == -ENODEV) netif_device_detach(netdev); else if (err) - dev_err(netdev->dev.parent, - "failed resubmitting intr urb: %d\n", err); + netdev_err(netdev, "failed resubmitting intr urb: %d\n", err); } static void ems_usb_rx_can_msg(struct ems_usb *dev, struct ems_cpc_msg *msg) @@ -431,8 +429,7 @@ static void ems_usb_read_bulk_callback(struct urb *urb) return; default: - dev_info(netdev->dev.parent, "Rx URB aborted (%d)\n", - urb->status); + netdev_info(netdev, "Rx URB aborted (%d)\n", urb->status); goto resubmit_urb; } @@ -477,7 +474,7 @@ static void ems_usb_read_bulk_callback(struct urb *urb) msg_count--; if (start > urb->transfer_buffer_length) { - dev_err(netdev->dev.parent, "format error\n"); + netdev_err(netdev, "format error\n"); break; } } @@ -493,8 +490,8 @@ resubmit_urb: if (retval == -ENODEV) netif_device_detach(netdev); else if (retval) - dev_err(netdev->dev.parent, - "failed resubmitting read bulk urb: %d\n", retval); + netdev_err(netdev, + "failed resubmitting read bulk urb: %d\n", retval); } /* @@ -521,8 +518,7 @@ static void ems_usb_write_bulk_callback(struct urb *urb) return; if (urb->status) - dev_info(netdev->dev.parent, "Tx URB aborted (%d)\n", - urb->status); + netdev_info(netdev, "Tx URB aborted (%d)\n", urb->status); netdev->trans_start = jiffies; @@ -605,8 +601,7 @@ static int ems_usb_start(struct ems_usb *dev) /* create a URB, and a buffer for it */ urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { - dev_err(netdev->dev.parent, - "No memory left for URBs\n"); + netdev_err(netdev, "No memory left for URBs\n"); err = -ENOMEM; break; } @@ -614,8 +609,7 @@ static int ems_usb_start(struct ems_usb *dev) buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL, &urb->transfer_dma); if (!buf) { - dev_err(netdev->dev.parent, - "No memory left for USB buffer\n"); + netdev_err(netdev, "No memory left for USB buffer\n"); usb_free_urb(urb); err = -ENOMEM; break; @@ -641,13 +635,13 @@ static int ems_usb_start(struct ems_usb *dev) /* Did we submit any URBs */ if (i == 0) { - dev_warn(netdev->dev.parent, "couldn't setup read URBs\n"); + netdev_warn(netdev, "couldn't setup read URBs\n"); return err; } /* Warn if we've couldn't transmit all the URBs */ if (i < MAX_RX_URBS) - dev_warn(netdev->dev.parent, "rx performance may be slow\n"); + netdev_warn(netdev, "rx performance may be slow\n"); /* Setup and start interrupt URB */ usb_fill_int_urb(dev->intr_urb, dev->udev, @@ -658,8 +652,7 @@ static int ems_usb_start(struct ems_usb *dev) err = usb_submit_urb(dev->intr_urb, GFP_KERNEL); if (err) { - dev_warn(netdev->dev.parent, "intr URB submit failed: %d\n", - err); + netdev_warn(netdev, "intr URB submit failed: %d\n", err); return err; } @@ -688,7 +681,7 @@ static int ems_usb_start(struct ems_usb *dev) return 0; failed: - dev_warn(netdev->dev.parent, "couldn't submit control: %d\n", err); + netdev_warn(netdev, "couldn't submit control: %d\n", err); return err; } @@ -728,8 +721,7 @@ static int ems_usb_open(struct net_device *netdev) if (err == -ENODEV) netif_device_detach(dev->netdev); - dev_warn(netdev->dev.parent, "couldn't start device: %d\n", - err); + netdev_warn(netdev, "couldn't start device: %d\n", err); close_candev(netdev); @@ -762,13 +754,13 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne /* create a URB, and a buffer for it, and copy the data to the URB */ urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { - dev_err(netdev->dev.parent, "No memory left for URBs\n"); + netdev_err(netdev, "No memory left for URBs\n"); goto nomem; } buf = usb_alloc_coherent(dev->udev, size, GFP_ATOMIC, &urb->transfer_dma); if (!buf) { - dev_err(netdev->dev.parent, "No memory left for USB buffer\n"); + netdev_err(netdev, "No memory left for USB buffer\n"); usb_free_urb(urb); goto nomem; } @@ -811,7 +803,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne usb_unanchor_urb(urb); usb_free_coherent(dev->udev, size, buf, urb->transfer_dma); - dev_warn(netdev->dev.parent, "couldn't find free context\n"); + netdev_warn(netdev, "couldn't find free context\n"); return NETDEV_TX_BUSY; } @@ -842,7 +834,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne if (err == -ENODEV) { netif_device_detach(netdev); } else { - dev_warn(netdev->dev.parent, "failed tx_urb %d\n", err); + netdev_warn(netdev, "failed tx_urb %d\n", err); stats->tx_dropped++; } @@ -882,7 +874,7 @@ static int ems_usb_close(struct net_device *netdev) /* Set CAN controller to reset mode */ if (ems_usb_write_mode(dev, SJA1000_MOD_RM)) - dev_warn(netdev->dev.parent, "couldn't stop device"); + netdev_warn(netdev, "couldn't stop device"); close_candev(netdev); @@ -919,7 +911,7 @@ static int ems_usb_set_mode(struct net_device *netdev, enum can_mode mode) switch (mode) { case CAN_MODE_START: if (ems_usb_write_mode(dev, SJA1000_MOD_NORMAL)) - dev_warn(netdev->dev.parent, "couldn't start device"); + netdev_warn(netdev, "couldn't start device"); if (netif_queue_stopped(netdev)) netif_wake_queue(netdev); @@ -944,8 +936,7 @@ static int ems_usb_set_bittiming(struct net_device *netdev) if (dev->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) btr1 |= 0x80; - dev_info(netdev->dev.parent, "setting BTR0=0x%02x BTR1=0x%02x\n", - btr0, btr1); + netdev_info(netdev, "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1); dev->active_params.msg.can_params.cc_params.sja1000.btr0 = btr0; dev->active_params.msg.can_params.cc_params.sja1000.btr1 = btr1; @@ -1050,15 +1041,13 @@ static int ems_usb_probe(struct usb_interface *intf, err = ems_usb_command_msg(dev, &dev->active_params); if (err) { - dev_err(netdev->dev.parent, - "couldn't initialize controller: %d\n", err); + netdev_err(netdev, "couldn't initialize controller: %d\n", err); goto cleanup_tx_msg_buffer; } err = register_candev(netdev); if (err) { - dev_err(netdev->dev.parent, - "couldn't register CAN device: %d\n", err); + netdev_err(netdev, "couldn't register CAN device: %d\n", err); goto cleanup_tx_msg_buffer; } diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c index 92774637aad..09b1da5bc51 100644 --- a/drivers/net/can/usb/esd_usb2.c +++ b/drivers/net/can/usb/esd_usb2.c @@ -470,8 +470,7 @@ static void esd_usb2_write_bulk_callback(struct urb *urb) return; if (urb->status) - dev_info(netdev->dev.parent, "Tx URB aborted (%d)\n", - urb->status); + netdev_info(netdev, "Tx URB aborted (%d)\n", urb->status); netdev->trans_start = jiffies; } @@ -651,7 +650,7 @@ failed: if (err == -ENODEV) netif_device_detach(netdev); - dev_err(netdev->dev.parent, "couldn't start device: %d\n", err); + netdev_err(netdev, "couldn't start device: %d\n", err); return err; } @@ -687,8 +686,7 @@ static int esd_usb2_open(struct net_device *netdev) /* finally start device */ err = esd_usb2_start(priv); if (err) { - dev_warn(netdev->dev.parent, - "couldn't start device: %d\n", err); + netdev_warn(netdev, "couldn't start device: %d\n", err); close_candev(netdev); return err; } @@ -721,7 +719,7 @@ static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb, /* create a URB, and a buffer for it, and copy the data to the URB */ urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { - dev_err(netdev->dev.parent, "No memory left for URBs\n"); + netdev_err(netdev, "No memory left for URBs\n"); stats->tx_dropped++; dev_kfree_skb(skb); goto nourbmem; @@ -730,7 +728,7 @@ static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb, buf = usb_alloc_coherent(dev->udev, size, GFP_ATOMIC, &urb->transfer_dma); if (!buf) { - dev_err(netdev->dev.parent, "No memory left for USB buffer\n"); + netdev_err(netdev, "No memory left for USB buffer\n"); stats->tx_dropped++; dev_kfree_skb(skb); goto nobufmem; @@ -766,7 +764,7 @@ static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb, * This may never happen. */ if (!context) { - dev_warn(netdev->dev.parent, "couldn't find free context\n"); + netdev_warn(netdev, "couldn't find free context\n"); ret = NETDEV_TX_BUSY; goto releasebuf; } @@ -806,7 +804,7 @@ static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb, if (err == -ENODEV) netif_device_detach(netdev); else - dev_warn(netdev->dev.parent, "failed tx_urb %d\n", err); + netdev_warn(netdev, "failed tx_urb %d\n", err); goto releasebuf; } @@ -845,7 +843,7 @@ static int esd_usb2_close(struct net_device *netdev) for (i = 0; i <= ESD_MAX_ID_SEGMENT; i++) msg.msg.filter.mask[i] = 0; if (esd_usb2_send_msg(priv->usb2, &msg) < 0) - dev_err(netdev->dev.parent, "sending idadd message failed\n"); + netdev_err(netdev, "sending idadd message failed\n"); /* set CAN controller to reset mode */ msg.msg.hdr.len = 2; @@ -854,7 +852,7 @@ static int esd_usb2_close(struct net_device *netdev) msg.msg.setbaud.rsvd = 0; msg.msg.setbaud.baud = cpu_to_le32(ESD_USB2_NO_BAUDRATE); if (esd_usb2_send_msg(priv->usb2, &msg) < 0) - dev_err(netdev->dev.parent, "sending setbaud message failed\n"); + netdev_err(netdev, "sending setbaud message failed\n"); priv->can.state = CAN_STATE_STOPPED; @@ -910,7 +908,7 @@ static int esd_usb2_set_bittiming(struct net_device *netdev) msg.msg.setbaud.rsvd = 0; msg.msg.setbaud.baud = cpu_to_le32(canbtr); - dev_info(netdev->dev.parent, "setting BTR=%#x\n", canbtr); + netdev_info(netdev, "setting BTR=%#x\n", canbtr); return esd_usb2_send_msg(priv->usb2, &msg); } @@ -988,15 +986,14 @@ static int esd_usb2_probe_one_net(struct usb_interface *intf, int index) err = register_candev(netdev); if (err) { - dev_err(&intf->dev, - "couldn't register CAN device: %d\n", err); + dev_err(&intf->dev, "couldn't register CAN device: %d\n", err); free_candev(netdev); err = -ENOMEM; goto done; } dev->nets[index] = priv; - dev_info(netdev->dev.parent, "device %s registered\n", netdev->name); + netdev_info(netdev, "device %s registered\n", netdev->name); done: return err; -- cgit v1.2.3-70-g09d2 From a80b83b7b8456e9b475346c2e01d7e210883208c Mon Sep 17 00:00:00 2001 From: John Stultz Date: Fri, 3 Feb 2012 00:19:07 -0800 Subject: Input: add infrastructure for selecting clockid for event time stamps As noted by Arve and others, since wall time can jump backwards, it is difficult to use for input because one cannot determine if one event occurred before another or for how long a key was pressed. However, the timestamp field is part of the kernel ABI, and cannot be changed without possibly breaking existing users. This patch adds a new IOCTL that allows a clockid to be set in the evdev_client struct that will specify which time base to use for event timestamps (ie: CLOCK_MONOTONIC instead of CLOCK_REALTIME). For now we only support CLOCK_MONOTONIC and CLOCK_REALTIME, but in the future we could support other clockids if appropriate. The default remains CLOCK_REALTIME, so we don't change the ABI. Signed-off-by: John Stultz Reviewed-by: Daniel Kurtz Signed-off-by: Dmitry Torokhov --- drivers/input/evdev.c | 25 +++++++++++++++++++++---- include/linux/input.h | 2 ++ kernel/time/timekeeping.c | 2 ++ 3 files changed, 25 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 76457d50bc3..c1740974299 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -46,6 +46,7 @@ struct evdev_client { struct fasync_struct *fasync; struct evdev *evdev; struct list_head node; + int clkid; unsigned int bufsize; struct input_event buffer[]; }; @@ -54,8 +55,12 @@ static struct evdev *evdev_table[EVDEV_MINORS]; static DEFINE_MUTEX(evdev_table_mutex); static void evdev_pass_event(struct evdev_client *client, - struct input_event *event) + struct input_event *event, + ktime_t mono, ktime_t real) { + event->time = ktime_to_timeval(client->clkid == CLOCK_MONOTONIC ? + mono : real); + /* Interrupts are disabled, just acquire the lock. */ spin_lock(&client->buffer_lock); @@ -94,8 +99,11 @@ static void evdev_event(struct input_handle *handle, struct evdev *evdev = handle->private; struct evdev_client *client; struct input_event event; + ktime_t time_mono, time_real; + + time_mono = ktime_get(); + time_real = ktime_sub(time_mono, ktime_get_monotonic_offset()); - do_gettimeofday(&event.time); event.type = type; event.code = code; event.value = value; @@ -103,11 +111,12 @@ static void evdev_event(struct input_handle *handle, rcu_read_lock(); client = rcu_dereference(evdev->grab); + if (client) - evdev_pass_event(client, &event); + evdev_pass_event(client, &event, time_mono, time_real); else list_for_each_entry_rcu(client, &evdev->client_list, node) - evdev_pass_event(client, &event); + evdev_pass_event(client, &event, time_mono, time_real); rcu_read_unlock(); @@ -685,6 +694,14 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, else return evdev_ungrab(evdev, client); + case EVIOCSCLOCKID: + if (copy_from_user(&i, p, sizeof(unsigned int))) + return -EFAULT; + if (i != CLOCK_MONOTONIC && i != CLOCK_REALTIME) + return -EINVAL; + client->clkid = i; + return 0; + case EVIOCGKEYCODE: return evdev_handle_get_keycode(dev, p); diff --git a/include/linux/input.h b/include/linux/input.h index 3862e32c4ee..177261ea6f5 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -129,6 +129,8 @@ struct input_keymap_entry { #define EVIOCGRAB _IOW('E', 0x90, int) /* Grab/Release device */ +#define EVIOCSCLOCKID _IOW('E', 0xa0, int) /* Set clockid to be used for timestamps */ + /* * Device properties and quirks */ diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 2b021b0e850..16947999475 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -1140,6 +1140,8 @@ ktime_t ktime_get_monotonic_offset(void) } while (read_seqretry(&xtime_lock, seq)); return timespec_to_ktime(wtom); } +EXPORT_SYMBOL_GPL(ktime_get_monotonic_offset); + /** * xtime_update() - advances the timekeeping infrastructure -- cgit v1.2.3-70-g09d2 From 8491ee1093c476ea3a9a19ab8593d8531cab40f7 Mon Sep 17 00:00:00 2001 From: Jan Steinhoff Date: Fri, 3 Feb 2012 00:21:31 -0800 Subject: Input: add Synaptics USB device driver This patch adds a driver for Synaptics USB touchpad or pointing stick devices. These USB devices emulate an USB mouse by default, so one can also use the usbhid driver. However, in combination with special user space drivers this kernel driver allows one to customize the behaviour of the device. An extended version of this driver with support for the cPad background display can be found at . Signed-off-by: Jan Steinhoff Acked-by: Jiri Kosina Signed-off-by: Dmitry Torokhov --- drivers/hid/hid-core.c | 10 + drivers/hid/hid-ids.h | 11 + drivers/input/mouse/Kconfig | 17 ++ drivers/input/mouse/Makefile | 1 + drivers/input/mouse/synaptics_usb.c | 568 ++++++++++++++++++++++++++++++++++++ 5 files changed, 607 insertions(+) create mode 100644 drivers/input/mouse/synaptics_usb.c (limited to 'drivers') diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 848a56c0279..b639855acd2 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1892,6 +1892,16 @@ static const struct hid_device_id hid_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) }, { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE) }, { HID_USB_DEVICE(USB_VENDOR_ID_POWERCOM, USB_DEVICE_ID_POWERCOM_UPS) }, +#if defined(CONFIG_MOUSE_SYNAPTICS_USB) || defined(CONFIG_MOUSE_SYNAPTICS_USB_MODULE) + { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_TP) }, + { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_INT_TP) }, + { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_CPAD) }, + { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_STICK) }, + { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_WP) }, + { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_COMP_TP) }, + { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_WTP) }, + { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_DPAD) }, +#endif { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) }, { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) }, { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 06ce996b8b6..3b683439c6c 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -633,6 +633,17 @@ #define USB_DEVICE_ID_SYMBOL_SCANNER_1 0x0800 #define USB_DEVICE_ID_SYMBOL_SCANNER_2 0x1300 +#define USB_VENDOR_ID_SYNAPTICS 0x06cb +#define USB_DEVICE_ID_SYNAPTICS_TP 0x0001 +#define USB_DEVICE_ID_SYNAPTICS_INT_TP 0x0002 +#define USB_DEVICE_ID_SYNAPTICS_CPAD 0x0003 +#define USB_DEVICE_ID_SYNAPTICS_TS 0x0006 +#define USB_DEVICE_ID_SYNAPTICS_STICK 0x0007 +#define USB_DEVICE_ID_SYNAPTICS_WP 0x0008 +#define USB_DEVICE_ID_SYNAPTICS_COMP_TP 0x0009 +#define USB_DEVICE_ID_SYNAPTICS_WTP 0x0010 +#define USB_DEVICE_ID_SYNAPTICS_DPAD 0x0013 + #define USB_VENDOR_ID_THRUSTMASTER 0x044f #define USB_VENDOR_ID_TOPSEED 0x0766 diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index 9c1e6ee8353..9b8db821d5f 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig @@ -322,4 +322,21 @@ config MOUSE_SYNAPTICS_I2C To compile this driver as a module, choose M here: the module will be called synaptics_i2c. +config MOUSE_SYNAPTICS_USB + tristate "Synaptics USB device support" + depends on USB_ARCH_HAS_HCD + select USB + help + Say Y here if you want to use a Synaptics USB touchpad or pointing + stick. + + While these devices emulate an USB mouse by default and can be used + with standard usbhid driver, this driver, together with its X.Org + counterpart, allows you to fully utilize capabilities of the device. + More information can be found at: + + + To compile this driver as a module, choose M here: the + module will be called synaptics_usb. + endif diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile index 570c84a4a65..4718effeb8d 100644 --- a/drivers/input/mouse/Makefile +++ b/drivers/input/mouse/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_MOUSE_PXA930_TRKBALL) += pxa930_trkball.o obj-$(CONFIG_MOUSE_RISCPC) += rpcmouse.o obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o obj-$(CONFIG_MOUSE_SYNAPTICS_I2C) += synaptics_i2c.o +obj-$(CONFIG_MOUSE_SYNAPTICS_USB) += synaptics_usb.o obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o psmouse-objs := psmouse-base.o synaptics.o diff --git a/drivers/input/mouse/synaptics_usb.c b/drivers/input/mouse/synaptics_usb.c new file mode 100644 index 00000000000..e559a947bb5 --- /dev/null +++ b/drivers/input/mouse/synaptics_usb.c @@ -0,0 +1,568 @@ +/* + * USB Synaptics device driver + * + * Copyright (c) 2002 Rob Miller (rob@inpharmatica . co . uk) + * Copyright (c) 2003 Ron Lee (ron@debian.org) + * cPad driver for kernel 2.4 + * + * Copyright (c) 2004 Jan Steinhoff (cpad@jan-steinhoff . de) + * Copyright (c) 2004 Ron Lee (ron@debian.org) + * rewritten for kernel 2.6 + * + * cPad display character device part is not included. It can be found at + * http://jan-steinhoff.de/linux/synaptics-usb.html + * + * Bases on: usb_skeleton.c v2.2 by Greg Kroah-Hartman + * drivers/hid/usbhid/usbmouse.c by Vojtech Pavlik + * drivers/input/mouse/synaptics.c by Peter Osterlund + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * Trademarks are the property of their respective owners. + */ + +/* + * There are three different types of Synaptics USB devices: Touchpads, + * touchsticks (or trackpoints), and touchscreens. Touchpads are well supported + * by this driver, touchstick support has not been tested much yet, and + * touchscreens have not been tested at all. + * + * Up to three alternate settings are possible: + * setting 0: one int endpoint for relative movement (used by usbhid.ko) + * setting 1: one int endpoint for absolute finger position + * setting 2 (cPad only): one int endpoint for absolute finger position and + * two bulk endpoints for the display (in/out) + * This driver uses setting 1. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define USB_VENDOR_ID_SYNAPTICS 0x06cb +#define USB_DEVICE_ID_SYNAPTICS_TP 0x0001 /* Synaptics USB TouchPad */ +#define USB_DEVICE_ID_SYNAPTICS_INT_TP 0x0002 /* Integrated USB TouchPad */ +#define USB_DEVICE_ID_SYNAPTICS_CPAD 0x0003 /* Synaptics cPad */ +#define USB_DEVICE_ID_SYNAPTICS_TS 0x0006 /* Synaptics TouchScreen */ +#define USB_DEVICE_ID_SYNAPTICS_STICK 0x0007 /* Synaptics USB Styk */ +#define USB_DEVICE_ID_SYNAPTICS_WP 0x0008 /* Synaptics USB WheelPad */ +#define USB_DEVICE_ID_SYNAPTICS_COMP_TP 0x0009 /* Composite USB TouchPad */ +#define USB_DEVICE_ID_SYNAPTICS_WTP 0x0010 /* Wireless TouchPad */ +#define USB_DEVICE_ID_SYNAPTICS_DPAD 0x0013 /* DisplayPad */ + +#define SYNUSB_TOUCHPAD (1 << 0) +#define SYNUSB_STICK (1 << 1) +#define SYNUSB_TOUCHSCREEN (1 << 2) +#define SYNUSB_AUXDISPLAY (1 << 3) /* For cPad */ +#define SYNUSB_COMBO (1 << 4) /* Composite device (TP + stick) */ +#define SYNUSB_IO_ALWAYS (1 << 5) + +#define USB_DEVICE_SYNAPTICS(prod, kind) \ + USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, \ + USB_DEVICE_ID_SYNAPTICS_##prod), \ + .driver_info = (kind), + +#define SYNUSB_RECV_SIZE 8 + +#define XMIN_NOMINAL 1472 +#define XMAX_NOMINAL 5472 +#define YMIN_NOMINAL 1408 +#define YMAX_NOMINAL 4448 + +struct synusb { + struct usb_device *udev; + struct usb_interface *intf; + struct urb *urb; + unsigned char *data; + + /* input device related data structures */ + struct input_dev *input; + char name[128]; + char phys[64]; + + /* characteristics of the device */ + unsigned long flags; +}; + +static void synusb_report_buttons(struct synusb *synusb) +{ + struct input_dev *input_dev = synusb->input; + + input_report_key(input_dev, BTN_LEFT, synusb->data[1] & 0x04); + input_report_key(input_dev, BTN_RIGHT, synusb->data[1] & 0x01); + input_report_key(input_dev, BTN_MIDDLE, synusb->data[1] & 0x02); +} + +static void synusb_report_stick(struct synusb *synusb) +{ + struct input_dev *input_dev = synusb->input; + int x, y; + unsigned int pressure; + + pressure = synusb->data[6]; + x = (s16)(be16_to_cpup((__be16 *)&synusb->data[2]) << 3) >> 7; + y = (s16)(be16_to_cpup((__be16 *)&synusb->data[4]) << 3) >> 7; + + if (pressure > 0) { + input_report_rel(input_dev, REL_X, x); + input_report_rel(input_dev, REL_Y, -y); + } + + input_report_abs(input_dev, ABS_PRESSURE, pressure); + + synusb_report_buttons(synusb); + + input_sync(input_dev); +} + +static void synusb_report_touchpad(struct synusb *synusb) +{ + struct input_dev *input_dev = synusb->input; + unsigned int num_fingers, tool_width; + unsigned int x, y; + unsigned int pressure, w; + + pressure = synusb->data[6]; + x = be16_to_cpup((__be16 *)&synusb->data[2]); + y = be16_to_cpup((__be16 *)&synusb->data[4]); + w = synusb->data[0] & 0x0f; + + if (pressure > 0) { + num_fingers = 1; + tool_width = 5; + switch (w) { + case 0 ... 1: + num_fingers = 2 + w; + break; + + case 2: /* pen, pretend its a finger */ + break; + + case 4 ... 15: + tool_width = w; + break; + } + } else { + num_fingers = 0; + tool_width = 0; + } + + /* + * Post events + * BTN_TOUCH has to be first as mousedev relies on it when doing + * absolute -> relative conversion + */ + + if (pressure > 30) + input_report_key(input_dev, BTN_TOUCH, 1); + if (pressure < 25) + input_report_key(input_dev, BTN_TOUCH, 0); + + if (num_fingers > 0) { + input_report_abs(input_dev, ABS_X, x); + input_report_abs(input_dev, ABS_Y, + YMAX_NOMINAL + YMIN_NOMINAL - y); + } + + input_report_abs(input_dev, ABS_PRESSURE, pressure); + input_report_abs(input_dev, ABS_TOOL_WIDTH, tool_width); + + input_report_key(input_dev, BTN_TOOL_FINGER, num_fingers == 1); + input_report_key(input_dev, BTN_TOOL_DOUBLETAP, num_fingers == 2); + input_report_key(input_dev, BTN_TOOL_TRIPLETAP, num_fingers == 3); + + synusb_report_buttons(synusb); + if (synusb->flags & SYNUSB_AUXDISPLAY) + input_report_key(input_dev, BTN_MIDDLE, synusb->data[1] & 0x08); + + input_sync(input_dev); +} + +static void synusb_irq(struct urb *urb) +{ + struct synusb *synusb = urb->context; + int error; + + /* Check our status in case we need to bail out early. */ + switch (urb->status) { + case 0: + usb_mark_last_busy(synusb->udev); + break; + + /* Device went away so don't keep trying to read from it. */ + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + return; + + default: + goto resubmit; + break; + } + + if (synusb->flags & SYNUSB_STICK) + synusb_report_stick(synusb); + else + synusb_report_touchpad(synusb); + +resubmit: + error = usb_submit_urb(urb, GFP_ATOMIC); + if (error && error != -EPERM) + dev_err(&synusb->intf->dev, + "%s - usb_submit_urb failed with result: %d", + __func__, error); +} + +static struct usb_endpoint_descriptor * +synusb_get_in_endpoint(struct usb_host_interface *iface) +{ + + struct usb_endpoint_descriptor *endpoint; + int i; + + for (i = 0; i < iface->desc.bNumEndpoints; ++i) { + endpoint = &iface->endpoint[i].desc; + + if (usb_endpoint_is_int_in(endpoint)) { + /* we found our interrupt in endpoint */ + return endpoint; + } + } + + return NULL; +} + +static int synusb_open(struct input_dev *dev) +{ + struct synusb *synusb = input_get_drvdata(dev); + int retval; + + retval = usb_autopm_get_interface(synusb->intf); + if (retval) { + dev_err(&synusb->intf->dev, + "%s - usb_autopm_get_interface failed, error: %d\n", + __func__, retval); + return retval; + } + + retval = usb_submit_urb(synusb->urb, GFP_KERNEL); + if (retval) { + dev_err(&synusb->intf->dev, + "%s - usb_submit_urb failed, error: %d\n", + __func__, retval); + retval = -EIO; + goto out; + } + + synusb->intf->needs_remote_wakeup = 1; + +out: + usb_autopm_put_interface(synusb->intf); + return retval; +} + +static void synusb_close(struct input_dev *dev) +{ + struct synusb *synusb = input_get_drvdata(dev); + int autopm_error; + + autopm_error = usb_autopm_get_interface(synusb->intf); + + usb_kill_urb(synusb->urb); + synusb->intf->needs_remote_wakeup = 0; + + if (!autopm_error) + usb_autopm_put_interface(synusb->intf); +} + +static int synusb_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_device *udev = interface_to_usbdev(intf); + struct usb_endpoint_descriptor *ep; + struct synusb *synusb; + struct input_dev *input_dev; + unsigned int intf_num = intf->cur_altsetting->desc.bInterfaceNumber; + unsigned int altsetting = min(intf->num_altsetting, 1U); + int error; + + error = usb_set_interface(udev, intf_num, altsetting); + if (error) { + dev_err(&udev->dev, + "Can not set alternate setting to %i, error: %i", + altsetting, error); + return error; + } + + ep = synusb_get_in_endpoint(intf->cur_altsetting); + if (!ep) + return -ENODEV; + + synusb = kzalloc(sizeof(*synusb), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!synusb || !input_dev) { + error = -ENOMEM; + goto err_free_mem; + } + + synusb->udev = udev; + synusb->intf = intf; + synusb->input = input_dev; + + synusb->flags = id->driver_info; + if (synusb->flags & SYNUSB_COMBO) { + /* + * This is a combo device, we need to set proper + * capability, depending on the interface. + */ + synusb->flags |= intf_num == 1 ? + SYNUSB_STICK : SYNUSB_TOUCHPAD; + } + + synusb->urb = usb_alloc_urb(0, GFP_KERNEL); + if (!synusb->urb) { + error = -ENOMEM; + goto err_free_mem; + } + + synusb->data = usb_alloc_coherent(udev, SYNUSB_RECV_SIZE, GFP_KERNEL, + &synusb->urb->transfer_dma); + if (!synusb->data) { + error = -ENOMEM; + goto err_free_urb; + } + + usb_fill_int_urb(synusb->urb, udev, + usb_rcvintpipe(udev, ep->bEndpointAddress), + synusb->data, SYNUSB_RECV_SIZE, + synusb_irq, synusb, + ep->bInterval); + synusb->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + if (udev->manufacturer) + strlcpy(synusb->name, udev->manufacturer, + sizeof(synusb->name)); + + if (udev->product) { + if (udev->manufacturer) + strlcat(synusb->name, " ", sizeof(synusb->name)); + strlcat(synusb->name, udev->product, sizeof(synusb->name)); + } + + if (!strlen(synusb->name)) + snprintf(synusb->name, sizeof(synusb->name), + "USB Synaptics Device %04x:%04x", + le16_to_cpu(udev->descriptor.idVendor), + le16_to_cpu(udev->descriptor.idProduct)); + + if (synusb->flags & SYNUSB_STICK) + strlcat(synusb->name, " (Stick) ", sizeof(synusb->name)); + + usb_make_path(udev, synusb->phys, sizeof(synusb->phys)); + strlcat(synusb->phys, "/input0", sizeof(synusb->phys)); + + input_dev->name = synusb->name; + input_dev->phys = synusb->phys; + usb_to_input_id(udev, &input_dev->id); + input_dev->dev.parent = &synusb->intf->dev; + + if (!(synusb->flags & SYNUSB_IO_ALWAYS)) { + input_dev->open = synusb_open; + input_dev->close = synusb_close; + } + + input_set_drvdata(input_dev, synusb); + + __set_bit(EV_ABS, input_dev->evbit); + __set_bit(EV_KEY, input_dev->evbit); + + if (synusb->flags & SYNUSB_STICK) { + __set_bit(EV_REL, input_dev->evbit); + __set_bit(REL_X, input_dev->relbit); + __set_bit(REL_Y, input_dev->relbit); + input_set_abs_params(input_dev, ABS_PRESSURE, 0, 127, 0, 0); + } else { + input_set_abs_params(input_dev, ABS_X, + XMIN_NOMINAL, XMAX_NOMINAL, 0, 0); + input_set_abs_params(input_dev, ABS_Y, + YMIN_NOMINAL, YMAX_NOMINAL, 0, 0); + input_set_abs_params(input_dev, ABS_PRESSURE, 0, 255, 0, 0); + input_set_abs_params(input_dev, ABS_TOOL_WIDTH, 0, 15, 0, 0); + __set_bit(BTN_TOUCH, 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_LEFT, input_dev->keybit); + __set_bit(BTN_RIGHT, input_dev->keybit); + __set_bit(BTN_MIDDLE, input_dev->keybit); + + usb_set_intfdata(intf, synusb); + + if (synusb->flags & SYNUSB_IO_ALWAYS) { + error = synusb_open(input_dev); + if (error) + goto err_free_dma; + } + + error = input_register_device(input_dev); + if (error) { + dev_err(&udev->dev, + "Failed to register input device, error %d\n", + error); + goto err_stop_io; + } + + return 0; + +err_stop_io: + if (synusb->flags & SYNUSB_IO_ALWAYS) + synusb_close(synusb->input); +err_free_dma: + usb_free_coherent(udev, SYNUSB_RECV_SIZE, synusb->data, + synusb->urb->transfer_dma); +err_free_urb: + usb_free_urb(synusb->urb); +err_free_mem: + input_free_device(input_dev); + kfree(synusb); + usb_set_intfdata(intf, NULL); + + return error; +} + +static void synusb_disconnect(struct usb_interface *intf) +{ + struct synusb *synusb = usb_get_intfdata(intf); + struct usb_device *udev = interface_to_usbdev(intf); + + if (synusb->flags & SYNUSB_IO_ALWAYS) + synusb_close(synusb->input); + + input_unregister_device(synusb->input); + + usb_free_coherent(udev, SYNUSB_RECV_SIZE, synusb->data, + synusb->urb->transfer_dma); + usb_free_urb(synusb->urb); + kfree(synusb); + + usb_set_intfdata(intf, NULL); +} + +static int synusb_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct synusb *synusb = usb_get_intfdata(intf); + struct input_dev *input_dev = synusb->input; + + mutex_lock(&input_dev->mutex); + usb_kill_urb(synusb->urb); + mutex_unlock(&input_dev->mutex); + + return 0; +} + +static int synusb_resume(struct usb_interface *intf) +{ + struct synusb *synusb = usb_get_intfdata(intf); + struct input_dev *input_dev = synusb->input; + int retval = 0; + + mutex_lock(&input_dev->mutex); + + if ((input_dev->users || (synusb->flags & SYNUSB_IO_ALWAYS)) && + usb_submit_urb(synusb->urb, GFP_NOIO) < 0) { + retval = -EIO; + } + + mutex_unlock(&input_dev->mutex); + + return retval; +} + +static int synusb_pre_reset(struct usb_interface *intf) +{ + struct synusb *synusb = usb_get_intfdata(intf); + struct input_dev *input_dev = synusb->input; + + mutex_lock(&input_dev->mutex); + usb_kill_urb(synusb->urb); + + return 0; +} + +static int synusb_post_reset(struct usb_interface *intf) +{ + struct synusb *synusb = usb_get_intfdata(intf); + struct input_dev *input_dev = synusb->input; + int retval = 0; + + if ((input_dev->users || (synusb->flags & SYNUSB_IO_ALWAYS)) && + usb_submit_urb(synusb->urb, GFP_NOIO) < 0) { + retval = -EIO; + } + + mutex_unlock(&input_dev->mutex); + + return retval; +} + +static int synusb_reset_resume(struct usb_interface *intf) +{ + return synusb_resume(intf); +} + +static struct usb_device_id synusb_idtable[] = { + { USB_DEVICE_SYNAPTICS(TP, SYNUSB_TOUCHPAD) }, + { USB_DEVICE_SYNAPTICS(INT_TP, SYNUSB_TOUCHPAD) }, + { USB_DEVICE_SYNAPTICS(CPAD, + SYNUSB_TOUCHPAD | SYNUSB_AUXDISPLAY | SYNUSB_IO_ALWAYS) }, + { USB_DEVICE_SYNAPTICS(TS, SYNUSB_TOUCHSCREEN) }, + { USB_DEVICE_SYNAPTICS(STICK, SYNUSB_STICK) }, + { USB_DEVICE_SYNAPTICS(WP, SYNUSB_TOUCHPAD) }, + { USB_DEVICE_SYNAPTICS(COMP_TP, SYNUSB_COMBO) }, + { USB_DEVICE_SYNAPTICS(WTP, SYNUSB_TOUCHPAD) }, + { USB_DEVICE_SYNAPTICS(DPAD, SYNUSB_TOUCHPAD) }, + { } +}; +MODULE_DEVICE_TABLE(usb, synusb_idtable); + +static struct usb_driver synusb_driver = { + .name = "synaptics_usb", + .probe = synusb_probe, + .disconnect = synusb_disconnect, + .id_table = synusb_idtable, + .suspend = synusb_suspend, + .resume = synusb_resume, + .pre_reset = synusb_pre_reset, + .post_reset = synusb_post_reset, + .reset_resume = synusb_reset_resume, + .supports_autosuspend = 1, +}; + +static int __init synusb_init(void) +{ + return usb_register(&synusb_driver); +} + +static void __exit synusb_exit(void) +{ + usb_deregister(&synusb_driver); +} + +module_init(synusb_init); +module_exit(synusb_exit); + +MODULE_AUTHOR("Rob Miller , " + "Ron Lee , " + "Jan Steinhoff "); +MODULE_DESCRIPTION("Synaptics USB device driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From 023cea0ecfa2df034096c3f4afa796a0b2d1188a Mon Sep 17 00:00:00 2001 From: Shridhar Rasal Date: Fri, 3 Feb 2012 00:27:30 -0800 Subject: Input: tegra-kbc - allow skipping setting up some of GPIO pins Allow marking some of GPIO pins as ignored to to avoid continuously generating KBC input events. Signed-off-by: Shridhar Rasal Signed-off-by: Dmitry Torokhov --- arch/arm/mach-tegra/include/mach/kbc.h | 8 +++++++- drivers/input/keyboard/tegra-kbc.c | 34 +++++++++++++++++++++++++++------- 2 files changed, 34 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-tegra/include/mach/kbc.h b/arch/arm/mach-tegra/include/mach/kbc.h index d34ecd1bea6..a1302561293 100644 --- a/arch/arm/mach-tegra/include/mach/kbc.h +++ b/arch/arm/mach-tegra/include/mach/kbc.h @@ -31,8 +31,14 @@ #define KBC_MAX_COL 8 #define KBC_MAX_KEY (KBC_MAX_ROW * KBC_MAX_COL) +enum tegra_pin_type { + PIN_CFG_IGNORE, + PIN_CFG_COL, + PIN_CFG_ROW, +}; + struct tegra_kbc_pin_cfg { - bool is_row; + enum tegra_pin_type type; unsigned char num; }; diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index b307a46ecef..dc19432c665 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c @@ -468,10 +468,18 @@ static void tegra_kbc_config_pins(struct tegra_kbc *kbc) row_cfg &= ~r_mask; col_cfg &= ~c_mask; - if (pdata->pin_cfg[i].is_row) + switch (pdata->pin_cfg[i].type) { + case PIN_CFG_ROW: row_cfg |= ((pdata->pin_cfg[i].num << 1) | 1) << r_shft; - else + break; + + case PIN_CFG_COL: col_cfg |= ((pdata->pin_cfg[i].num << 1) | 1) << c_shft; + break; + + case PIN_CFG_IGNORE: + break; + } writel(row_cfg, kbc->mmio + r_offs); writel(col_cfg, kbc->mmio + c_offs); @@ -576,7 +584,8 @@ tegra_kbc_check_pin_cfg(const struct tegra_kbc_platform_data *pdata, for (i = 0; i < KBC_MAX_GPIO; i++) { const struct tegra_kbc_pin_cfg *pin_cfg = &pdata->pin_cfg[i]; - if (pin_cfg->is_row) { + switch (pin_cfg->type) { + case PIN_CFG_ROW: if (pin_cfg->num >= KBC_MAX_ROW) { dev_err(dev, "pin_cfg[%d]: invalid row number %d\n", @@ -584,13 +593,25 @@ tegra_kbc_check_pin_cfg(const struct tegra_kbc_platform_data *pdata, return false; } (*num_rows)++; - } else { + break; + + case PIN_CFG_COL: if (pin_cfg->num >= KBC_MAX_COL) { dev_err(dev, "pin_cfg[%d]: invalid column number %d\n", i, pin_cfg->num); return false; } + break; + + case PIN_CFG_IGNORE: + break; + + default: + dev_err(dev, + "pin_cfg[%d]: invalid entry type %d\n", + pin_cfg->type, pin_cfg->num); + return false; } } @@ -607,7 +628,6 @@ tegra_kbc_dt_parse_pdata(struct platform_device *pdev) if (!np) return NULL; - pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); if (!pdata) return NULL; @@ -629,12 +649,12 @@ tegra_kbc_dt_parse_pdata(struct platform_device *pdev) */ for (i = 0; i < KBC_MAX_ROW; i++) { pdata->pin_cfg[i].num = i; - pdata->pin_cfg[i].is_row = true; + pdata->pin_cfg[i].type = PIN_CFG_ROW; } for (i = 0; i < KBC_MAX_COL; i++) { pdata->pin_cfg[KBC_MAX_ROW + i].num = i; - pdata->pin_cfg[KBC_MAX_ROW + i].is_row = false; + pdata->pin_cfg[KBC_MAX_ROW + i].type = PIN_CFG_COL; } return pdata; -- cgit v1.2.3-70-g09d2 From a14b1b42477c5ef089fcda88cbaae50d979eb8f9 Mon Sep 17 00:00:00 2001 From: Mandeep Singh Baines Date: Fri, 20 Jan 2012 12:11:16 -0800 Subject: drm: remove master fd restriction on mode setting getters Its useful to be able to call the mode setting getter ioctls. Not requiring master fd, enables writing a simple program which can query the state of the video system. Since these ioctls are only "getters" there is no security or synchronization issues which would require master fd. Opening an new fd is already protected by the file permissions on the device file. Signed-off-by: Mandeep Singh Baines Cc: Dave Airlie Cc: Daniel Vetter Cc: Ilija Hadzic Cc: Jesse Barnes Cc: Stephane Marchesin Cc: dri-devel@lists.freedesktop.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_drv.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index ebf7d3f68fc..d166bd08040 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -135,23 +135,23 @@ static struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_MASTER|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), -- cgit v1.2.3-70-g09d2 From 86a4d69c0ad62ced87a74bbd43f2acefc66a97b0 Mon Sep 17 00:00:00 2001 From: Ilija Hadzic Date: Wed, 1 Feb 2012 11:42:38 -0500 Subject: drm/radeon/kms: common definitions for blit copy code R600/700 and Evergreen/NI blit code have a few redundant definitions in respective .c file. Move common definitions into a separate (new) .h file. Signed-off-by: Ilija Hadzic Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen_blit_kms.c | 12 +------- drivers/gpu/drm/radeon/r600_blit_kms.c | 15 +--------- drivers/gpu/drm/radeon/radeon_blit_common.h | 44 +++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 25 deletions(-) create mode 100644 drivers/gpu/drm/radeon/radeon_blit_common.h (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c index 2379849515c..4e83fdcf4bc 100644 --- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c +++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c @@ -32,17 +32,7 @@ #include "evergreend.h" #include "evergreen_blit_shaders.h" #include "cayman_blit_shaders.h" - -#define DI_PT_RECTLIST 0x11 -#define DI_INDEX_SIZE_16_BIT 0x0 -#define DI_SRC_SEL_AUTO_INDEX 0x2 - -#define FMT_8 0x1 -#define FMT_5_6_5 0x8 -#define FMT_8_8_8_8 0x1a -#define COLOR_8 0x1 -#define COLOR_5_6_5 0x8 -#define COLOR_8_8_8_8 0x1a +#include "radeon_blit_common.h" /* emits 17 */ static void diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index accc032c103..db38f587f27 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c @@ -30,20 +30,7 @@ #include "r600d.h" #include "r600_blit_shaders.h" - -#define DI_PT_RECTLIST 0x11 -#define DI_INDEX_SIZE_16_BIT 0x0 -#define DI_SRC_SEL_AUTO_INDEX 0x2 - -#define FMT_8 0x1 -#define FMT_5_6_5 0x8 -#define FMT_8_8_8_8 0x1a -#define COLOR_8 0x1 -#define COLOR_5_6_5 0x8 -#define COLOR_8_8_8_8 0x1a - -#define RECT_UNIT_H 32 -#define RECT_UNIT_W (RADEON_GPU_PAGE_SIZE / 4 / RECT_UNIT_H) +#include "radeon_blit_common.h" /* emits 21 on rv770+, 23 on r600 */ static void diff --git a/drivers/gpu/drm/radeon/radeon_blit_common.h b/drivers/gpu/drm/radeon/radeon_blit_common.h new file mode 100644 index 00000000000..4ecbe72c9d2 --- /dev/null +++ b/drivers/gpu/drm/radeon/radeon_blit_common.h @@ -0,0 +1,44 @@ +/* + * Copyright 2009 Advanced Micro Devices, Inc. + * Copyright 2009 Red Hat Inc. + * Copyright 2012 Alcatel-Lucent, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __RADEON_BLIT_COMMON_H__ + +#define DI_PT_RECTLIST 0x11 +#define DI_INDEX_SIZE_16_BIT 0x0 +#define DI_SRC_SEL_AUTO_INDEX 0x2 + +#define FMT_8 0x1 +#define FMT_5_6_5 0x8 +#define FMT_8_8_8_8 0x1a +#define COLOR_8 0x1 +#define COLOR_5_6_5 0x8 +#define COLOR_8_8_8_8 0x1a + +#define RECT_UNIT_H 32 +#define RECT_UNIT_W (RADEON_GPU_PAGE_SIZE / 4 / RECT_UNIT_H) + +#define __RADEON_BLIT_COMMON_H__ +#endif -- cgit v1.2.3-70-g09d2 From 6d75e83ee31c146c8a3d56c762d3e15c483dc40e Mon Sep 17 00:00:00 2001 From: Ilija Hadzic Date: Tue, 31 Jan 2012 09:35:25 -0500 Subject: drm/radeon/kms: remove benchmarks shorter than one page copy_blit operation works only on integral number of pages so benchmarks shorter than one page size (4K) do not make sense v2: use RADEON_GPU_PAGE_SIZE instead of "magic" 1024 number and sweep sizes between 1 * to 16K * doubling the size in each iteration; we get the same coverage, as in the original benchmark, but guarantee integer multiples of page size v3: add whitespace between '*' operator per review received from zajec5@gmail.com Signed-off-by: Ilija Hadzic Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_benchmark.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c index 815f2341ab9..58cee89215c 100644 --- a/drivers/gpu/drm/radeon/radeon_benchmark.c +++ b/drivers/gpu/drm/radeon/radeon_benchmark.c @@ -208,22 +208,22 @@ void radeon_benchmark(struct radeon_device *rdev, int test_number) break; case 3: /* GTT to VRAM, buffer size sweep, powers of 2 */ - for (i = 1; i <= 65536; i <<= 1) - radeon_benchmark_move(rdev, i*1024, + for (i = 1; i <= 16384; i <<= 1) + radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE, RADEON_GEM_DOMAIN_GTT, RADEON_GEM_DOMAIN_VRAM); break; case 4: /* VRAM to GTT, buffer size sweep, powers of 2 */ - for (i = 1; i <= 65536; i <<= 1) - radeon_benchmark_move(rdev, i*1024, + for (i = 1; i <= 16384; i <<= 1) + radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE, RADEON_GEM_DOMAIN_VRAM, RADEON_GEM_DOMAIN_GTT); break; case 5: /* VRAM to VRAM, buffer size sweep, powers of 2 */ - for (i = 1; i <= 65536; i <<= 1) - radeon_benchmark_move(rdev, i*1024, + for (i = 1; i <= 16384; i <<= 1) + radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE, RADEON_GEM_DOMAIN_VRAM, RADEON_GEM_DOMAIN_VRAM); break; -- cgit v1.2.3-70-g09d2 From 1849ecb22fb3b5d57b65e7369a3957adf9f26f39 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 28 Jan 2012 11:07:09 +0100 Subject: drm/kms: Make i2c buses faster A udelay value of 20 leads to an I2C bus running at only 25 kbps. I2C devices can typically operate faster than this, 50 kbps should be fine for all devices (and compliant devices can always stretch the clock if needed.) FWIW, the vast majority of framebuffer drivers set udelay to 10 already. So set it to 10 in DRM drivers too, this will make EDID block reads faster. We might even lower the udelay value later if no problem is reported. Signed-off-by: Jean Delvare Acked-by: Eugeni Dodonov Cc: Keith Packard Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/intel_i2c.c | 2 +- drivers/gpu/drm/radeon/radeon_i2c.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index d30ccccb9d7..7fa4f640e6f 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c @@ -37,7 +37,7 @@ /* Intel GPIO access functions */ -#define I2C_RISEFALL_TIME 20 +#define I2C_RISEFALL_TIME 10 static inline struct intel_gmbus * to_intel_gmbus(struct i2c_adapter *i2c) diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index 98a8ad68010..b7ec89bf393 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c @@ -925,7 +925,7 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, i2c->algo.bit.setscl = set_clock; i2c->algo.bit.getsda = get_data; i2c->algo.bit.getscl = get_clock; - i2c->algo.bit.udelay = 20; + i2c->algo.bit.udelay = 10; /* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always * make this, 2 jiffies is a lot more reliable */ i2c->algo.bit.timeout = 2; -- cgit v1.2.3-70-g09d2 From 9048955748aa14b1dbf068ef3a9288ec15cabc66 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 28 Jan 2012 11:08:58 +0100 Subject: drm/radeon/kms: Use the standard VESA timeout for DDC channels The VESA specification suggests a 2.2 ms timeout on DDC channels. Use exactly that (as the i915 driver does) instead of hard-coding a jiffy count. Signed-off-by: Jean Delvare Reviewed-by: Keith Packard Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_i2c.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index b7ec89bf393..c47f222f744 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c @@ -926,9 +926,7 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, i2c->algo.bit.getsda = get_data; i2c->algo.bit.getscl = get_clock; i2c->algo.bit.udelay = 10; - /* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always - * make this, 2 jiffies is a lot more reliable */ - i2c->algo.bit.timeout = 2; + i2c->algo.bit.timeout = usecs_to_jiffies(2200); /* from VESA */ i2c->algo.bit.data = i2c; ret = i2c_bit_add_bus(&i2c->adapter); if (ret) { -- cgit v1.2.3-70-g09d2 From 30388c6e48e62b2806b14552275f091e2f5adbf4 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 20 Jan 2012 14:50:18 -0500 Subject: drm/radeon/kms/dce3+: add support for hw i2c using atom Starting with DCE3 hardware, atom contains a general purpose ProcessI2cChannelTransaction similar to ProcessAuxChannelTransaction. Add an implementation using the atom tables for DCE3+ hardware. This should be a little less CPU intensive than bit banging and may work better in certain cases. Enable it by setting the radeon hw_i2c module parameter to 1. E.g., radeon.hw_i2c=1 on the kernel command line in grub. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/Makefile | 2 +- drivers/gpu/drm/radeon/atombios_i2c.c | 139 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_i2c.c | 21 +++++ 3 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/radeon/atombios_i2c.c (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index 2139fe893ec..84104153a68 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile @@ -71,7 +71,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \ evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o \ radeon_trace_points.o ni.o cayman_blit_shaders.o atombios_encoders.o \ - radeon_semaphore.o radeon_sa.o + radeon_semaphore.o radeon_sa.o atombios_i2c.o radeon-$(CONFIG_COMPAT) += radeon_ioc32.o radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o diff --git a/drivers/gpu/drm/radeon/atombios_i2c.c b/drivers/gpu/drm/radeon/atombios_i2c.c new file mode 100644 index 00000000000..44d87b6b422 --- /dev/null +++ b/drivers/gpu/drm/radeon/atombios_i2c.c @@ -0,0 +1,139 @@ +/* + * Copyright 2011 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Alex Deucher + * + */ +#include "drmP.h" +#include "radeon_drm.h" +#include "radeon.h" +#include "atom.h" + +#define TARGET_HW_I2C_CLOCK 50 + +/* these are a limitation of ProcessI2cChannelTransaction not the hw */ +#define ATOM_MAX_HW_I2C_WRITE 2 +#define ATOM_MAX_HW_I2C_READ 255 + +static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan, + u8 slave_addr, u8 flags, + u8 *buf, u8 num) +{ + struct drm_device *dev = chan->dev; + struct radeon_device *rdev = dev->dev_private; + PROCESS_I2C_CHANNEL_TRANSACTION_PS_ALLOCATION args; + int index = GetIndexIntoMasterTable(COMMAND, ProcessI2cChannelTransaction); + unsigned char *base; + u16 out; + + memset(&args, 0, sizeof(args)); + + base = (unsigned char *)rdev->mode_info.atom_context->scratch; + + if (flags & HW_I2C_WRITE) { + if (num > ATOM_MAX_HW_I2C_WRITE) { + DRM_ERROR("hw i2c: tried to write too many bytes (%d vs 2)\n", num); + return -EINVAL; + } + memcpy(&out, buf, num); + args.lpI2CDataOut = cpu_to_le16(out); + } else { + if (num > ATOM_MAX_HW_I2C_READ) { + DRM_ERROR("hw i2c: tried to read too many bytes (%d vs 255)\n", num); + return -EINVAL; + } + } + + args.ucI2CSpeed = TARGET_HW_I2C_CLOCK; + args.ucRegIndex = 0; + args.ucTransBytes = num; + args.ucSlaveAddr = slave_addr << 1; + args.ucLineNumber = chan->rec.i2c_id; + + atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); + + /* error */ + if (args.ucStatus != HW_ASSISTED_I2C_STATUS_SUCCESS) { + DRM_DEBUG_KMS("hw_i2c error\n"); + return -EIO; + } + + if (!(flags & HW_I2C_WRITE)) + memcpy(buf, base, num); + + return 0; +} + +int radeon_atom_hw_i2c_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg *msgs, int num) +{ + struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); + struct i2c_msg *p; + int i, remaining, current_count, buffer_offset, max_bytes, ret; + u8 buf = 0, flags; + + /* check for bus probe */ + p = &msgs[0]; + if ((num == 1) && (p->len == 0)) { + ret = radeon_process_i2c_ch(i2c, + p->addr, HW_I2C_WRITE, + &buf, 1); + if (ret) + return ret; + else + return num; + } + + for (i = 0; i < num; i++) { + p = &msgs[i]; + remaining = p->len; + buffer_offset = 0; + /* max_bytes are a limitation of ProcessI2cChannelTransaction not the hw */ + if (p->flags & I2C_M_RD) { + max_bytes = ATOM_MAX_HW_I2C_READ; + flags = HW_I2C_READ; + } else { + max_bytes = ATOM_MAX_HW_I2C_WRITE; + flags = HW_I2C_WRITE; + } + while (remaining) { + if (remaining > max_bytes) + current_count = max_bytes; + else + current_count = remaining; + ret = radeon_process_i2c_ch(i2c, + p->addr, flags, + &p->buf[buffer_offset], current_count); + if (ret) + return ret; + remaining -= current_count; + buffer_offset += current_count; + } + } + + return num; +} + +u32 radeon_atom_hw_i2c_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index c47f222f744..3265a7a5797 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c @@ -30,6 +30,10 @@ #include "radeon.h" #include "atom.h" +extern int radeon_atom_hw_i2c_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg *msgs, int num); +extern u32 radeon_atom_hw_i2c_func(struct i2c_adapter *adap); + /** * radeon_ddc_probe * @@ -882,6 +886,11 @@ static const struct i2c_algorithm radeon_i2c_algo = { .functionality = radeon_hw_i2c_func, }; +static const struct i2c_algorithm radeon_atom_i2c_algo = { + .master_xfer = radeon_atom_hw_i2c_xfer, + .functionality = radeon_atom_hw_i2c_func, +}; + struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, struct radeon_i2c_bus_rec *rec, const char *name) @@ -914,6 +923,18 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, DRM_ERROR("Failed to register hw i2c %s\n", name); goto out_free; } + } else if (rec->hw_capable && + radeon_hw_i2c && + ASIC_IS_DCE3(rdev)) { + /* hw i2c using atom */ + snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), + "Radeon i2c hw bus %s", name); + i2c->adapter.algo = &radeon_atom_i2c_algo; + ret = i2c_add_adapter(&i2c->adapter); + if (ret) { + DRM_ERROR("Failed to register hw i2c %s\n", name); + goto out_free; + } } else { /* set the radeon bit adapter */ snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), -- cgit v1.2.3-70-g09d2 From 9292f37e1f5c79400254dca46f83313488093825 Mon Sep 17 00:00:00 2001 From: Eugeni Dodonov Date: Thu, 5 Jan 2012 09:34:28 -0200 Subject: drm: give up on edid retries when i2c bus is not responding This allows to avoid talking to a non-responding bus repeatedly until we finally timeout after 15 attempts. We can do this by catching the -ENXIO error, provided by i2c_algo_bit:bit_doAddress call. Within the bit_doAddress we already try 3 times to get the edid data, so if the routine tells us that bus is not responding, it is mostly pointless to keep re-trying those attempts over and over again until we reach final number of retries. This change should fix https://bugs.freedesktop.org/show_bug.cgi?id=41059 and improve overall edid detection timing by 10-30% in most cases, and by a much larger margin in case of phantom outputs (up to 30x in one worst case). Timing results for i915-powered machines for 'time xrandr' command: Machine 1: from 0.840s to 0.290s Machine 2: from 0.315s to 0.280s Machine 3: from +/- 4s to 0.184s Timing results for HD5770 with 'time xrandr' command: Machine 4: from 3.210s to 1.060s Reviewed-by: Chris Wilson Reviewed-by: Keith Packard Tested-by: Sean Finney Tested-by: Soren Hansen Tested-by: Hernando Torque Tested-by: Mike Lothian Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=41059 Signed-off-by: Eugeni Dodonov Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_edid.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index ece03fc2d38..54a4efa0eef 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -266,6 +266,11 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf, } }; ret = i2c_transfer(adapter, msgs, 2); + if (ret == -ENXIO) { + DRM_DEBUG_KMS("drm: skipping non-existent adapter %s\n", + adapter->name); + break; + } } while (ret != 2 && --retries); return ret == 2 ? 0 : -1; -- cgit v1.2.3-70-g09d2 From c9068eb296fc682513f8612168f605c169b773e4 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 2 Feb 2012 10:11:11 -0500 Subject: drm/radeon/kms: add r1xx/r2xx support for CS_KEEP_TILING_FLAGS Previous patch only updates r3xx+. It's not likely anyone will use this on r1xx/r2xx, but add it for consistency. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r100.c | 46 ++++++++++++++++++++++++------------------- drivers/gpu/drm/radeon/r200.c | 17 +++++++++------- 2 files changed, 36 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index bfd36ab643a..7dd6a1c4734 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -87,23 +87,27 @@ int r100_reloc_pitch_offset(struct radeon_cs_parser *p, r100_cs_dump_packet(p, pkt); return r; } + value = radeon_get_ib_value(p, idx); tmp = value & 0x003fffff; tmp += (((u32)reloc->lobj.gpu_offset) >> 10); - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) - tile_flags |= RADEON_DST_TILE_MACRO; - if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { - if (reg == RADEON_SRC_PITCH_OFFSET) { - DRM_ERROR("Cannot src blit from microtiled surface\n"); - r100_cs_dump_packet(p, pkt); - return -EINVAL; + if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { + if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) + tile_flags |= RADEON_DST_TILE_MACRO; + if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { + if (reg == RADEON_SRC_PITCH_OFFSET) { + DRM_ERROR("Cannot src blit from microtiled surface\n"); + r100_cs_dump_packet(p, pkt); + return -EINVAL; + } + tile_flags |= RADEON_DST_TILE_MICRO; } - tile_flags |= RADEON_DST_TILE_MICRO; - } - tmp |= tile_flags; - p->ib->ptr[idx] = (value & 0x3fc00000) | tmp; + tmp |= tile_flags; + p->ib->ptr[idx] = (value & 0x3fc00000) | tmp; + } else + p->ib->ptr[idx] = (value & 0xffc00000) | tmp; return 0; } @@ -1625,15 +1629,17 @@ static int r100_packet0_check(struct radeon_cs_parser *p, r100_cs_dump_packet(p, pkt); return r; } - - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) - tile_flags |= RADEON_COLOR_TILE_ENABLE; - if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) - tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; - - tmp = idx_value & ~(0x7 << 16); - tmp |= tile_flags; - ib[idx] = tmp; + if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { + if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) + tile_flags |= RADEON_COLOR_TILE_ENABLE; + if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) + tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; + + tmp = idx_value & ~(0x7 << 16); + tmp |= tile_flags; + ib[idx] = tmp; + } else + ib[idx] = idx_value; track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; track->cb_dirty = true; diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c index eba4cbfa78f..2f44397f6df 100644 --- a/drivers/gpu/drm/radeon/r200.c +++ b/drivers/gpu/drm/radeon/r200.c @@ -277,14 +277,17 @@ int r200_packet0_check(struct radeon_cs_parser *p, return r; } - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) - tile_flags |= RADEON_COLOR_TILE_ENABLE; - if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) - tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; + if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { + if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) + tile_flags |= RADEON_COLOR_TILE_ENABLE; + if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) + tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; - tmp = idx_value & ~(0x7 << 16); - tmp |= tile_flags; - ib[idx] = tmp; + tmp = idx_value & ~(0x7 << 16); + tmp |= tile_flags; + ib[idx] = tmp; + } else + ib[idx] = idx_value; track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; track->cb_dirty = true; -- cgit v1.2.3-70-g09d2 From f2746f83d50287fdb6768e0f20168c64b6a7c9cb Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 2 Feb 2012 10:11:12 -0500 Subject: drm/radeon/kms: add r1xx/r2xx CS support for tiled textures Not likely this will be implemented anytime soon, but for completeness... Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r100.c | 12 +++++++++++- drivers/gpu/drm/radeon/r200.c | 12 +++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 7dd6a1c4734..99bb0064935 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -1558,7 +1558,17 @@ static int r100_packet0_check(struct radeon_cs_parser *p, r100_cs_dump_packet(p, pkt); return r; } - ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); + if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { + if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) + tile_flags |= RADEON_TXO_MACRO_TILE; + if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) + tile_flags |= RADEON_TXO_MICRO_TILE_X2; + + tmp = idx_value & ~(0x7 << 2); + tmp |= tile_flags; + ib[idx] = tmp + ((u32)reloc->lobj.gpu_offset); + } else + ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); track->textures[i].robj = reloc->robj; track->tex_dirty = true; break; diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c index 2f44397f6df..a59cc474d53 100644 --- a/drivers/gpu/drm/radeon/r200.c +++ b/drivers/gpu/drm/radeon/r200.c @@ -215,7 +215,17 @@ int r200_packet0_check(struct radeon_cs_parser *p, r100_cs_dump_packet(p, pkt); return r; } - ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); + if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { + if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) + tile_flags |= R200_TXO_MACRO_TILE; + if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) + tile_flags |= R200_TXO_MICRO_TILE; + + tmp = idx_value & ~(0x7 << 2); + tmp |= tile_flags; + ib[idx] = tmp + ((u32)reloc->lobj.gpu_offset); + } else + ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); track->textures[i].robj = reloc->robj; track->tex_dirty = true; break; -- cgit v1.2.3-70-g09d2 From 59ce062ead2a7d114a1e7f505f250eabab9e9d85 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 1 Feb 2012 11:38:20 +0100 Subject: drm crtc: add forgotten idr cleanup functions drm_mode_config_init initializes the idr with idr_init, so add the missing counterparts in drm_mode_config_cleanup. Signed-off-by: Sascha Hauer Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 5e818a808ac..c1a0d346b0c 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1048,6 +1048,9 @@ void drm_mode_config_cleanup(struct drm_device *dev) head) { plane->funcs->destroy(plane); } + + idr_remove_all(&dev->mode_config.crtc_idr); + idr_destroy(&dev->mode_config.crtc_idr); } EXPORT_SYMBOL(drm_mode_config_cleanup); -- cgit v1.2.3-70-g09d2 From aefd330e694d5b7b9657cc53821c7879b14c8128 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 1 Feb 2012 11:38:21 +0100 Subject: drm/edid: drm modes have to be free with drm_mode_destroy to add the missing drm_mode_object_put for that mode. Signed-off-by: Sascha Hauer Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_edid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 54a4efa0eef..7ee7be1e5ce 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -750,7 +750,7 @@ drm_mode_std(struct drm_connector *connector, struct edid *edid, */ mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); if (drm_mode_hsync(mode) > drm_gtf2_hbreak(edid)) { - kfree(mode); + drm_mode_destroy(dev, mode); mode = drm_gtf_mode_complex(dev, hsize, vsize, vrefresh_rate, 0, 0, drm_gtf2_m(edid), -- cgit v1.2.3-70-g09d2 From 554f1d7888d4a1055965198d0ac46ba50e8b684e Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 1 Feb 2012 11:38:19 +0100 Subject: drm crtc: use drm_mode_destroy instead of kfree in drm_mode_remove Modes are created using drm_mode_create which does a drm_mode_object_get, so use drm_mode_destroy in drm_mode_remove which does a drm_mode_object_put. Signed-off-by: Sascha Hauer Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index c1a0d346b0c..33ebe291d18 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -442,7 +442,7 @@ void drm_mode_remove(struct drm_connector *connector, struct drm_display_mode *mode) { list_del(&mode->head); - kfree(mode); + drm_mode_destroy(connector->dev, mode); } EXPORT_SYMBOL(drm_mode_remove); -- cgit v1.2.3-70-g09d2 From a1b7736dac5f2d5876e68c47a0fce3f423840070 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 1 Feb 2012 11:38:22 +0100 Subject: drm drm_fb_helper: destroy modes drm_setup_crtcs allocated modes using drm_mode_duplicate. Free them in drm_fb_helper_crtc_free. Signed-off-by: Sascha Hauer Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_fb_helper.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index aada26f63de..77fec5a9383 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -430,8 +430,11 @@ static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper) for (i = 0; i < helper->connector_count; i++) kfree(helper->connector_info[i]); kfree(helper->connector_info); - for (i = 0; i < helper->crtc_count; i++) + for (i = 0; i < helper->crtc_count; i++) { kfree(helper->crtc_info[i].mode_set.connectors); + if (helper->crtc_info[i].mode_set.mode) + drm_mode_destroy(helper->dev, helper->crtc_info[i].mode_set.mode); + } kfree(helper->crtc_info); } -- cgit v1.2.3-70-g09d2 From 4cae5b84628d5df76247d494e51b89d07e28e6aa Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 1 Feb 2012 11:38:23 +0100 Subject: drm: add proper return value for drm_mode_crtc_set_gamma_size drm_mode_crtc_set_gamma_size returns boolean true for success and false for failure. This is not very kernel conform, so change it to return 0 for success and a propert error code otherwise. Noone checks the return value, so no users have to be fixed. Signed-off-by: Sascha Hauer Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc.c | 6 +++--- include/drm/drm_crtc.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 33ebe291d18..df6e4135680 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -3024,7 +3024,7 @@ void drm_mode_connector_detach_encoder(struct drm_connector *connector, } EXPORT_SYMBOL(drm_mode_connector_detach_encoder); -bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, +int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, int gamma_size) { crtc->gamma_size = gamma_size; @@ -3032,10 +3032,10 @@ bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, crtc->gamma_store = kzalloc(gamma_size * sizeof(uint16_t) * 3, GFP_KERNEL); if (!crtc->gamma_store) { crtc->gamma_size = 0; - return false; + return -ENOMEM; } - return true; + return 0; } EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size); diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 4cd4be26722..8d593ad95f1 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -919,7 +919,7 @@ extern int drm_mode_connector_attach_encoder(struct drm_connector *connector, struct drm_encoder *encoder); extern void drm_mode_connector_detach_encoder(struct drm_connector *connector, struct drm_encoder *encoder); -extern bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, +extern int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, int gamma_size); extern struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type); -- cgit v1.2.3-70-g09d2 From 3a8148c514b45672f876c4d7c23ed1f54e7c48e7 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 1 Feb 2012 11:38:24 +0100 Subject: drm fb helper: use drm_helper_connector_dpms to do dpms drm_fb_helper_on|off currently manually searches for encoders to turn on/off. Make this simpler by using the helper function. Signed-off-by: Sascha Hauer Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_fb_helper.c | 80 ++++++----------------------------------- 1 file changed, 10 insertions(+), 70 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 77fec5a9383..4fc38a7fc0b 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -306,91 +306,31 @@ static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { }; #endif -static void drm_fb_helper_on(struct fb_info *info) +static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode) { struct drm_fb_helper *fb_helper = info->par; struct drm_device *dev = fb_helper->dev; struct drm_crtc *crtc; - struct drm_crtc_helper_funcs *crtc_funcs; struct drm_connector *connector; - struct drm_encoder *encoder; int i, j; /* - * For each CRTC in this fb, turn the crtc on then, - * find all associated encoders and turn them on. + * For each CRTC in this fb, turn the connectors on/off. */ mutex_lock(&dev->mode_config.mutex); for (i = 0; i < fb_helper->crtc_count; i++) { crtc = fb_helper->crtc_info[i].mode_set.crtc; - crtc_funcs = crtc->helper_private; if (!crtc->enabled) continue; - crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON); - - /* Walk the connectors & encoders on this fb turning them on */ + /* Walk the connectors & encoders on this fb turning them on/off */ for (j = 0; j < fb_helper->connector_count; j++) { connector = fb_helper->connector_info[j]->connector; - connector->dpms = DRM_MODE_DPMS_ON; + drm_helper_connector_dpms(connector, dpms_mode); drm_connector_property_set_value(connector, - dev->mode_config.dpms_property, - DRM_MODE_DPMS_ON); - } - /* Found a CRTC on this fb, now find encoders */ - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (encoder->crtc == crtc) { - struct drm_encoder_helper_funcs *encoder_funcs; - - encoder_funcs = encoder->helper_private; - encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); - } - } - } - mutex_unlock(&dev->mode_config.mutex); -} - -static void drm_fb_helper_off(struct fb_info *info, int dpms_mode) -{ - struct drm_fb_helper *fb_helper = info->par; - struct drm_device *dev = fb_helper->dev; - struct drm_crtc *crtc; - struct drm_crtc_helper_funcs *crtc_funcs; - struct drm_connector *connector; - struct drm_encoder *encoder; - int i, j; - - /* - * For each CRTC in this fb, find all associated encoders - * and turn them off, then turn off the CRTC. - */ - mutex_lock(&dev->mode_config.mutex); - for (i = 0; i < fb_helper->crtc_count; i++) { - crtc = fb_helper->crtc_info[i].mode_set.crtc; - crtc_funcs = crtc->helper_private; - - if (!crtc->enabled) - continue; - - /* Walk the connectors on this fb and mark them off */ - for (j = 0; j < fb_helper->connector_count; j++) { - connector = fb_helper->connector_info[j]->connector; - connector->dpms = dpms_mode; - drm_connector_property_set_value(connector, - dev->mode_config.dpms_property, - dpms_mode); - } - /* Found a CRTC on this fb, now find encoders */ - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (encoder->crtc == crtc) { - struct drm_encoder_helper_funcs *encoder_funcs; - - encoder_funcs = encoder->helper_private; - encoder_funcs->dpms(encoder, dpms_mode); - } + dev->mode_config.dpms_property, dpms_mode); } - crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); } mutex_unlock(&dev->mode_config.mutex); } @@ -400,23 +340,23 @@ int drm_fb_helper_blank(int blank, struct fb_info *info) switch (blank) { /* Display: On; HSync: On, VSync: On */ case FB_BLANK_UNBLANK: - drm_fb_helper_on(info); + drm_fb_helper_dpms(info, DRM_MODE_DPMS_ON); break; /* Display: Off; HSync: On, VSync: On */ case FB_BLANK_NORMAL: - drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY); + drm_fb_helper_dpms(info, DRM_MODE_DPMS_STANDBY); break; /* Display: Off; HSync: Off, VSync: On */ case FB_BLANK_HSYNC_SUSPEND: - drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY); + drm_fb_helper_dpms(info, DRM_MODE_DPMS_STANDBY); break; /* Display: Off; HSync: On, VSync: Off */ case FB_BLANK_VSYNC_SUSPEND: - drm_fb_helper_off(info, DRM_MODE_DPMS_SUSPEND); + drm_fb_helper_dpms(info, DRM_MODE_DPMS_SUSPEND); break; /* Display: Off; HSync: Off, VSync: Off */ case FB_BLANK_POWERDOWN: - drm_fb_helper_off(info, DRM_MODE_DPMS_OFF); + drm_fb_helper_dpms(info, DRM_MODE_DPMS_OFF); break; } return 0; -- cgit v1.2.3-70-g09d2 From e9ad318128aa858f713d6f2c4623f7583ca53a71 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 1 Feb 2012 11:38:25 +0100 Subject: drm fb helper: remove unused variable conn_limit conn_limit is set but never used. Remove it from struct drm_fb_helper. Signed-off-by: Sascha Hauer Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_fb_helper.c | 2 +- include/drm/drm_fb_helper.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 4fc38a7fc0b..7b37874741f 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -421,7 +421,7 @@ int drm_fb_helper_init(struct drm_device *dev, fb_helper->crtc_info[i].mode_set.crtc = crtc; i++; } - fb_helper->conn_limit = max_conn_count; + return 0; out_free: drm_fb_helper_crtc_free(fb_helper); diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 6e3076ad646..55e10d62eab 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -74,7 +74,6 @@ struct drm_fb_helper { int connector_count; struct drm_fb_helper_connector **connector_info; struct drm_fb_helper_funcs *funcs; - int conn_limit; struct fb_info *fbdev; u32 pseudo_palette[17]; struct list_head kernel_fb_list; -- cgit v1.2.3-70-g09d2 From 4f988d132d2668b4f3b42bfc70daa531115ccca1 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 1 Feb 2012 11:38:26 +0100 Subject: drm fb helper: remove unused variable crtc_id crtc_id is set but never used, so remove it from struct drm_fb_helper_crtc. Signed-off-by: Sascha Hauer Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_fb_helper.c | 1 - include/drm/drm_fb_helper.h | 1 - 2 files changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 7b37874741f..7740dd26f00 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -417,7 +417,6 @@ int drm_fb_helper_init(struct drm_device *dev, i = 0; list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - fb_helper->crtc_info[i].crtc_id = crtc->base.id; fb_helper->crtc_info[i].mode_set.crtc = crtc; i++; } diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 55e10d62eab..5120b01c2ee 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -35,7 +35,6 @@ struct drm_fb_helper; #include struct drm_fb_helper_crtc { - uint32_t crtc_id; struct drm_mode_set mode_set; struct drm_display_mode *desired_mode; }; -- cgit v1.2.3-70-g09d2 From b20f38679fee704d5ebfe2815fb5af492a0dde9f Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 1 Feb 2012 11:38:31 +0100 Subject: drm crtc: Fix locking comments Several comments above functions say that the caller must hold the mode_config lock, but the functions take the lock themselves. Fix the comments. Signed-off-by: Sascha Hauer Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index df6e4135680..322bc7b1300 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -454,7 +454,7 @@ EXPORT_SYMBOL(drm_mode_remove); * @name: user visible name of the connector * * LOCKING: - * Caller must hold @dev's mode_config lock. + * Takes mode config lock. * * Initialises a preallocated connector. Connectors should be * subclassed as part of driver connector objects. @@ -497,7 +497,7 @@ EXPORT_SYMBOL(drm_connector_init); * @connector: connector to cleanup * * LOCKING: - * Caller must hold @dev's mode_config lock. + * Takes mode config lock. * * Cleans up the connector but doesn't free the object. */ @@ -1314,7 +1314,7 @@ out: * @arg: arg from ioctl * * LOCKING: - * Caller? (FIXME) + * Takes mode config lock. * * Construct a CRTC configuration structure to return to the user. * @@ -1374,7 +1374,7 @@ out: * @arg: arg from ioctl * * LOCKING: - * Caller? (FIXME) + * Takes mode config lock. * * Construct a connector configuration structure to return to the user. * @@ -1556,6 +1556,9 @@ out: * @data: ioctl data * @file_priv: DRM file info * + * LOCKING: + * Takes mode config lock. + * * Return an plane count and set of IDs. */ int drm_mode_getplane_res(struct drm_device *dev, void *data, @@ -1602,6 +1605,9 @@ out: * @data: ioctl data * @file_priv: DRM file info * + * LOCKING: + * Takes mode config lock. + * * Return plane info, including formats supported, gamma size, any * current fb, etc. */ @@ -1667,6 +1673,9 @@ out: * @data: ioctl data* * @file_prive: DRM file info * + * LOCKING: + * Takes mode config lock. + * * Set plane info, including placement, fb, scaling, and other factors. * Or pass a NULL fb to disable. */ @@ -1797,7 +1806,7 @@ out: * @arg: arg from ioctl * * LOCKING: - * Caller? (FIXME) + * Takes mode config lock. * * Build a new CRTC configuration based on user request. * @@ -2278,7 +2287,7 @@ out: * @arg: arg from ioctl * * LOCKING: - * Caller? (FIXME) + * Takes mode config lock. * * Lookup the FB given its ID and return info about it. * -- cgit v1.2.3-70-g09d2 From a1178ca06213ba937b20d3d32102f64c15dd9a9d Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 1 Feb 2012 11:38:30 +0100 Subject: drm crtc_helper: use list_for_each_entry list_for_each_entry_safe is for walking a list safe against removal of entries. Here, no entries are removed, so use list_for_each_entry. Signed-off-by: Sascha Hauer Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc_helper.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 84a4a809793..d761d124115 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -44,12 +44,12 @@ module_param_named(poll, drm_kms_helper_poll, bool, 0600); static void drm_mode_validate_flag(struct drm_connector *connector, int flags) { - struct drm_display_mode *mode, *t; + struct drm_display_mode *mode; if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE)) return; - list_for_each_entry_safe(mode, t, &connector->modes, head) { + list_for_each_entry(mode, &connector->modes, head) { if ((mode->flags & DRM_MODE_FLAG_INTERLACE) && !(flags & DRM_MODE_FLAG_INTERLACE)) mode->status = MODE_NO_INTERLACE; @@ -87,7 +87,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY) { struct drm_device *dev = connector->dev; - struct drm_display_mode *mode, *t; + struct drm_display_mode *mode; struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; int count = 0; @@ -96,7 +96,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, drm_get_connector_name(connector)); /* set all modes to the unverified state */ - list_for_each_entry_safe(mode, t, &connector->modes, head) + list_for_each_entry(mode, &connector->modes, head) mode->status = MODE_UNVERIFIED; if (connector->force) { @@ -136,7 +136,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, mode_flags |= DRM_MODE_FLAG_DBLSCAN; drm_mode_validate_flag(connector, mode_flags); - list_for_each_entry_safe(mode, t, &connector->modes, head) { + list_for_each_entry(mode, &connector->modes, head) { if (mode->status == MODE_OK) mode->status = connector_funcs->mode_valid(connector, mode); @@ -152,7 +152,7 @@ prune: DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id, drm_get_connector_name(connector)); - list_for_each_entry_safe(mode, t, &connector->modes, head) { + list_for_each_entry(mode, &connector->modes, head) { mode->vrefresh = drm_mode_vrefresh(mode); drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); -- cgit v1.2.3-70-g09d2 From 83b316fdafcc37e3e65b4a650afb7aab5cc2d271 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 1 Feb 2012 11:38:37 +0100 Subject: drm exynos: use drm_fb_helper_set_par directly info->fix.visual already is correctly set from drm_fb_helper_fill_fix. info->fix.line_length is also set from drm_fb_helper_fill_fix, so drm_fb_helper_set_par directly instead of a custom exynos_drm_fbdev_set_par. Signed-off-by: Sascha Hauer Tested-by: Inki Dae Signed-off-by: Dave Airlie --- drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index d7ae29d2f3d..5737bc5e6ed 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -46,39 +46,13 @@ struct exynos_drm_fbdev { struct exynos_drm_gem_obj *exynos_gem_obj; }; -static int exynos_drm_fbdev_set_par(struct fb_info *info) -{ - struct fb_var_screeninfo *var = &info->var; - - switch (var->bits_per_pixel) { - case 32: - case 24: - case 18: - case 16: - case 12: - info->fix.visual = FB_VISUAL_TRUECOLOR; - break; - case 1: - info->fix.visual = FB_VISUAL_MONO01; - break; - default: - info->fix.visual = FB_VISUAL_PSEUDOCOLOR; - break; - } - - info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8; - - return drm_fb_helper_set_par(info); -} - - static struct fb_ops exynos_drm_fb_ops = { .owner = THIS_MODULE, .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, .fb_check_var = drm_fb_helper_check_var, - .fb_set_par = exynos_drm_fbdev_set_par, + .fb_set_par = drm_fb_helper_set_par, .fb_blank = drm_fb_helper_blank, .fb_pan_display = drm_fb_helper_pan_display, .fb_setcmap = drm_fb_helper_setcmap, -- cgit v1.2.3-70-g09d2 From 1b65fa8496059d919a16b8431672d11e199ae515 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 3 Feb 2012 11:02:58 +0000 Subject: mfd: twl-core: Don't specify regulator consumers by struct device This has been deprecated for considerable time now and support has been removed from the regulator API. dev_name should be used instead. Signed-off-by: Mark Brown --- drivers/mfd/twl-core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index e04e04ddc15..8dcf70f8d65 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -751,9 +751,9 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) /* we need to connect regulators to this transceiver */ if (twl_has_regulator() && child) { - usb1v5.dev = child; - usb1v8.dev = child; - usb3v1.dev = child; + usb1v5.dev_name = dev_name(child); + usb1v8.dev_name = dev_name(child); + usb3v1.dev_name = dev_name(child); } } if (twl_has_usb() && pdata->usb && twl_class_is_6030()) { @@ -799,7 +799,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) return PTR_ERR(child); /* we need to connect regulators to this transceiver */ if (twl_has_regulator() && child) - usb3v3.dev = child; + usb3v3.dev_name = dev_name(child); } else if (twl_has_regulator() && twl_class_is_6030()) { if (features & TWL6025_SUBCLASS) child = add_regulator(TWL6025_REG_LDOUSB, -- cgit v1.2.3-70-g09d2 From ad075370ba0dd92fdb92989d1019bfc57ea42e1d Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sun, 15 Jan 2012 21:12:23 +0100 Subject: dm-bufio.c: there's no need to include linux/version.h As 'make versioncheck' points out, drivers/md/dm-bufio.c has no need to include linux/version.h, so this patch removes the unneeded include. Signed-off-by: Jesper Juhl Acked-by: Mikulas Patocka Signed-off-by: Jiri Kosina --- drivers/md/dm-bufio.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c index 0a6806f80ab..b6e58c7b6df 100644 --- a/drivers/md/dm-bufio.c +++ b/drivers/md/dm-bufio.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include -- cgit v1.2.3-70-g09d2 From 61c54d20d16f098823058b07b399ac5b716ea5ba Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sun, 15 Jan 2012 21:26:46 +0100 Subject: ab5500-core.c: Don't needlessly include linux/version.h As 'make versioncheck' so nicely points out, there's no need for drivers/mfd/ab5500-core.c to #include the linux/version.h header. This patch removes the pointless include. Signed-off-by: Jesper Juhl Acked-by: Linus Walleij Signed-off-by: Jiri Kosina --- drivers/mfd/ab5500-core.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mfd/ab5500-core.c b/drivers/mfd/ab5500-core.c index ec10629a0b0..f5019d58212 100644 --- a/drivers/mfd/ab5500-core.c +++ b/drivers/mfd/ab5500-core.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include "ab5500-core.h" -- cgit v1.2.3-70-g09d2 From 5980c001352cfdc66d055abed6f6ca6ebce793ad Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Fri, 20 Jan 2012 02:00:24 +0900 Subject: tty: fix comment typo in synclink_gt.c Fix typo "looopback" to "loopback" in synclink_gt.c Signed-off-by: Masanari Iida cc:Jiri Koshina Signed-off-by: Jiri Kosina --- drivers/tty/synclink_gt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index 18b48cd3b41..01a1ff4d18f 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -3924,7 +3924,7 @@ static void tdma_reset(struct slgt_info *info) */ static void enable_loopback(struct slgt_info *info) { - /* SCR (serial control) BIT2=looopback enable */ + /* SCR (serial control) BIT2=loopback enable */ wr_reg16(info, SCR, (unsigned short)(rd_reg16(info, SCR) | BIT2)); if (info->params.mode != MGSL_MODE_ASYNC) { -- cgit v1.2.3-70-g09d2 From 19f2da3505ba99de3512dad34a0f1ed0609144c6 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Sat, 21 Jan 2012 23:23:37 +0900 Subject: mpt2sas: Fix typo in mpt2sas_config.c Correct spelling "mappping" to "mapping" in drivers/scsi/mpt2sas/mpt2sas_config.c Signed-off-by: Masanari Iida Signed-off-by: Jiri Kosina --- drivers/scsi/mpt2sas/mpt2sas_config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c index 36ea0b2d802..2b4d37613d3 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_config.c +++ b/drivers/scsi/mpt2sas/mpt2sas_config.c @@ -149,7 +149,7 @@ _config_display_some_debug(struct MPT2SAS_ADAPTER *ioc, u16 smid, desc = "raid_config"; break; case MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING: - desc = "driver_mappping"; + desc = "driver_mapping"; break; } break; -- cgit v1.2.3-70-g09d2 From 64f3e70be63cf0006b7a332901015e6d04217a45 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 23 Jan 2012 23:45:58 +0100 Subject: drivers/media/dvb/frontends/drxk_hard.c does not need to include linux/version.h This patch removes the unneeded include. Signed-off-by: Jesper Juhl Signed-off-by: Jiri Kosina --- drivers/media/dvb/frontends/drxk_hard.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c index f6431ef827d..0024d9b92c2 100644 --- a/drivers/media/dvb/frontends/drxk_hard.c +++ b/drivers/media/dvb/frontends/drxk_hard.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include "dvb_frontend.h" -- cgit v1.2.3-70-g09d2 From ec16f3df1320c7529c69d3a1e05dbcb50aac9402 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Tue, 24 Jan 2012 02:26:36 +0900 Subject: macintosh: fix string typo in mediabay.c Fix typo "unsuported" to "unsupported" in drivers/machintosh/mediabay.c Signed-off-by: Masanari Iida Signed-off-by: Jiri Kosina --- drivers/macintosh/mediabay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c index 2fd435bc542..831d7517c75 100644 --- a/drivers/macintosh/mediabay.c +++ b/drivers/macintosh/mediabay.c @@ -356,7 +356,7 @@ static void poll_media_bay(struct media_bay_info* bay) static char *mb_content_types[] = { "a floppy drive", "a floppy drive", - "an unsuported audio device", + "an unsupported audio device", "an ATA device", "an unsupported PCI device", "an unknown device", -- cgit v1.2.3-70-g09d2 From 5196d20305d5e30d871111d3a876cf067dd94255 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Tue, 24 Jan 2012 22:48:04 +0000 Subject: drivers/char: comment fix: CMOS RTC update code is now in kernel/time/ntp.c This commit updates some comments to reflect the fact that code for periodically updating the CMOS RTC was moved to: kernel/time/ntp.c probably by this commit: commit 82644459c592a28a3eab682f9b88d81019ddfe8b Author: Thomas Gleixner Date: Sat Jul 21 04:37:37 2007 -0700 NTP: move the cmos update code into ntp.c i386 and sparc64 have the identical code to update the cmos clock. Move it into kernel/time/ntp.c as there are other architectures coming along with the same requirements. Signed-off-by: Michael Witten Signed-off-by: Jiri Kosina --- drivers/char/nvram.c | 2 +- drivers/char/rtc.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c index da3cfee782d..eaade8a1ecd 100644 --- a/drivers/char/nvram.c +++ b/drivers/char/nvram.c @@ -94,7 +94,7 @@ /* Note that *all* calls to CMOS_READ and CMOS_WRITE must be done with * rtc_lock held. Due to the index-port/data-port design of the RTC, we * don't want two different things trying to get to it at once. (e.g. the - * periodic 11 min sync from time.c vs. this driver.) + * periodic 11 min sync from kernel/time/ntp.c vs. this driver.) */ #include diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index ccd124ab7ca..872e09a02d2 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c @@ -57,8 +57,8 @@ * Note that *all* calls to CMOS_READ and CMOS_WRITE are done with * interrupts disabled. Due to the index-port/data-port (0x70/0x71) * design of the RTC, we don't want two different things trying to - * get to it at once. (e.g. the periodic 11 min sync from time.c vs. - * this driver.) + * get to it at once. (e.g. the periodic 11 min sync from + * kernel/time/ntp.c vs. this driver.) */ #include -- cgit v1.2.3-70-g09d2 From 4b2453114f770fe6b2fe5c191f9a1539f52ce2ce Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Fri, 3 Feb 2012 23:14:19 +0100 Subject: gma500, lvds: Fix use after free and mem leak in psb_intel_lvds_init() In psb_intel_lvds_init(), if we fail to allocate memory for 'psb_intel_connector' we free the memory we previously allocated for 'psb_intel_encoder', but we then proceed to use that free'd pointer when we do 'psb_intel_encoder->dev_priv = lvds_priv;'. We may also leak the memory we allocated for 'psb_intel_encoder' if we 'goto failed_connector;' and the variable goes out of scope. While I was there anyway, I also removed the pointless 'if (psb_intel_connector)' before freeing it at the 'failed_connector:' label - kfree() deals gracefully with NULL pointers, so it is not needed. Signed-off-by: Jesper Juhl Acked-by: Patrik Jakobsson Signed-off-by: Jiri Kosina --- drivers/gpu/drm/gma500/psb_intel_lvds.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/gma500/psb_intel_lvds.c b/drivers/gpu/drm/gma500/psb_intel_lvds.c index a25e4ca5e91..0a437586d8c 100644 --- a/drivers/gpu/drm/gma500/psb_intel_lvds.c +++ b/drivers/gpu/drm/gma500/psb_intel_lvds.c @@ -713,7 +713,6 @@ void psb_intel_lvds_init(struct drm_device *dev, psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder), GFP_KERNEL); - if (!psb_intel_encoder) { dev_err(dev->dev, "psb_intel_encoder allocation error\n"); return; @@ -721,10 +720,9 @@ void psb_intel_lvds_init(struct drm_device *dev, psb_intel_connector = kzalloc(sizeof(struct psb_intel_connector), GFP_KERNEL); - if (!psb_intel_connector) { - kfree(psb_intel_encoder); dev_err(dev->dev, "psb_intel_connector allocation error\n"); + goto failed_encoder; } lvds_priv = kzalloc(sizeof(struct psb_intel_lvds_priv), GFP_KERNEL); @@ -862,7 +860,8 @@ failed_blc_i2c: drm_encoder_cleanup(encoder); drm_connector_cleanup(connector); failed_connector: - if (psb_intel_connector) - kfree(psb_intel_connector); + kfree(psb_intel_connector); +failed_encoder: + kfree(psb_intel_encoder); } -- cgit v1.2.3-70-g09d2 From 382d19f197f9870522a23d726ce857cd7bc572fe Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Sun, 29 Jan 2012 21:50:53 +0900 Subject: media: Fix typo in mixer_drv.c and hdmi_drv.c Correct typo "sucessful" to "successful" in drivers/media/video/s5p-tv/mixer_drv.c drivers/media/video/s5p-tv/hdmi_drv.c Signed-off-by: Masanari Iida Acked-by: Kyungmin Park Signed-off-by: Jiri Kosina --- drivers/media/video/s5p-tv/hdmi_drv.c | 4 ++-- drivers/media/video/s5p-tv/mixer_drv.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/s5p-tv/hdmi_drv.c b/drivers/media/video/s5p-tv/hdmi_drv.c index 8b41a0410ab..3e0dd099b2e 100644 --- a/drivers/media/video/s5p-tv/hdmi_drv.c +++ b/drivers/media/video/s5p-tv/hdmi_drv.c @@ -962,7 +962,7 @@ static int __devinit hdmi_probe(struct platform_device *pdev) /* storing subdev for call that have only access to struct device */ dev_set_drvdata(dev, sd); - dev_info(dev, "probe sucessful\n"); + dev_info(dev, "probe successful\n"); return 0; @@ -1000,7 +1000,7 @@ static int __devexit hdmi_remove(struct platform_device *pdev) iounmap(hdmi_dev->regs); hdmi_resources_cleanup(hdmi_dev); kfree(hdmi_dev); - dev_info(dev, "remove sucessful\n"); + dev_info(dev, "remove successful\n"); return 0; } diff --git a/drivers/media/video/s5p-tv/mixer_drv.c b/drivers/media/video/s5p-tv/mixer_drv.c index 00643094b22..a2c0c25ad13 100644 --- a/drivers/media/video/s5p-tv/mixer_drv.c +++ b/drivers/media/video/s5p-tv/mixer_drv.c @@ -444,7 +444,7 @@ static int __devexit mxr_remove(struct platform_device *pdev) kfree(mdev); - dev_info(dev, "remove sucessful\n"); + dev_info(dev, "remove successful\n"); return 0; } -- cgit v1.2.3-70-g09d2 From 4087c471e74064650a1f2eec79bcf97acbb99fb1 Mon Sep 17 00:00:00 2001 From: Danny Kukawka Date: Mon, 30 Jan 2012 20:40:49 +0100 Subject: hdaps: fix for -Wuninitialized Trivial fix for some -Wuninitialized compiler warnings. Signed-off-by: Danny Kukawka Signed-off-by: Jiri Kosina --- drivers/platform/x86/hdaps.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/hdaps.c b/drivers/platform/x86/hdaps.c index 5a34973dc16..ba68d4e7a77 100644 --- a/drivers/platform/x86/hdaps.c +++ b/drivers/platform/x86/hdaps.c @@ -379,7 +379,7 @@ static ssize_t hdaps_temp1_show(struct device *dev, int ret; ret = hdaps_readb_one(HDAPS_PORT_TEMP1, &temp); - if (ret < 0) + if (ret) return ret; return sprintf(buf, "%u\n", temp); @@ -392,7 +392,7 @@ static ssize_t hdaps_temp2_show(struct device *dev, int ret; ret = hdaps_readb_one(HDAPS_PORT_TEMP2, &temp); - if (ret < 0) + if (ret) return ret; return sprintf(buf, "%u\n", temp); -- cgit v1.2.3-70-g09d2 From 6ac2c3a6faa3450fc2138ce56d068ff29072a444 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Tue, 31 Jan 2012 23:23:45 +0900 Subject: iwmc3200wifi: fix printk typo in trace.h Correct spelling "embeded" to "embedded" in drivers/net/wireless/iwmc3200wifi/trace.h Signed-off-by: Masanari Iida Acked-by: Samuel Ortiz Signed-off-by: Jiri Kosina --- drivers/net/wireless/iwmc3200wifi/trace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwmc3200wifi/trace.h b/drivers/net/wireless/iwmc3200wifi/trace.h index abb4805fa8d..f5f7070b7e2 100644 --- a/drivers/net/wireless/iwmc3200wifi/trace.h +++ b/drivers/net/wireless/iwmc3200wifi/trace.h @@ -144,7 +144,7 @@ TRACE_EVENT(iwm_tx_packets, TP_printk( IWM_PR_FMT " Tx %spacket: eot %d, seq 0x%x, sta_color 0x%x, " - "ra_tid 0x%x, credit_group 0x%x, embeded_packets %d, %d bytes", + "ra_tid 0x%x, credit_group 0x%x, embedded_packets %d, %d bytes", IWM_PR_ARG, !__entry->eot ? "concatenated " : "", __entry->eot, __entry->seq, __entry->color, __entry->ra_tid, __entry->credit_group, __entry->npkt, __entry->bytes -- cgit v1.2.3-70-g09d2 From 44ebf89e40ed824f034438b00a4e1b3afe2a15b1 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Fri, 3 Feb 2012 02:25:22 +0900 Subject: pm8001: fix printk typo in pm8001_hwi.c Correct typo "unresgister" to "unregister" and "deviece" to "device" in drivers/scsi/pm8001/pm8001_hwi.c Signed-off-by: Masanari Iida Acked-by: Jack Wang Signed-off-by: Jiri Kosina --- drivers/scsi/pm8001/pm8001_hwi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index b7b92f7be2a..e12c4f632a6 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -3532,7 +3532,7 @@ static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb) break; case OPC_OUB_DEREG_DEV: PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("unresgister the deviece\n")); + pm8001_printk("unregister the device\n")); mpi_dereg_resp(pm8001_ha, piomb); break; case OPC_OUB_GET_DEV_HANDLE: -- cgit v1.2.3-70-g09d2 From 36e4d267f3a0b2c04ec965eb8f821315e084e8a9 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Fri, 3 Feb 2012 22:15:25 +0900 Subject: qla2xxx: fix printk typo in qla_bsg.c Correct spelling "curent" to "current" in drivers/scsi/qla2xxx/qla_bsg.c Signed-off-by: Masanari Iida Acked-by: Chad Dupuis Signed-off-by: Jiri Kosina --- drivers/scsi/qla2xxx/qla_bsg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index b1d0f936bf2..a1c6a166a93 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -745,7 +745,7 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job) if (elreq.options != EXTERNAL_LOOPBACK) { ql_dbg(ql_dbg_user, vha, 0x7020, - "Internal: curent port config = %x\n", + "Internal: current port config = %x\n", config[0]); if (qla81xx_set_internal_loopback(vha, config, new_config)) { -- cgit v1.2.3-70-g09d2 From 7ce6e52ee5aca058dc8068e041a97c35d7f6054f Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Mon, 30 Jan 2012 22:52:10 +0900 Subject: net: fix printk typo in ipw2x00/libipw_rx.c Correct spelling in "suppported" to "supported" in drivers/net/wireless/ipw2x00/libipw_rx.c Signed-off-by: Masanari Iida Reviewed-by: Jesper Juhl Signed-off-by: Jiri Kosina --- drivers/net/wireless/ipw2x00/libipw_rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c index 32a9966c3bf..c4955d25a19 100644 --- a/drivers/net/wireless/ipw2x00/libipw_rx.c +++ b/drivers/net/wireless/ipw2x00/libipw_rx.c @@ -172,7 +172,7 @@ libipw_rx_frame_mgmt(struct libipw_device *ieee, struct sk_buff *skb, u16 stype) { if (ieee->iw_mode == IW_MODE_MASTER) { - printk(KERN_DEBUG "%s: Master mode not yet suppported.\n", + printk(KERN_DEBUG "%s: Master mode not yet supported.\n", ieee->dev->name); return 0; /* -- cgit v1.2.3-70-g09d2 From 45d9c273b262cde84bb6bb3fc02c01d07da76936 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 7 Dec 2011 17:31:43 -0800 Subject: HID: hid-input/battery: set scope and powered device for HID battery Set the battery's power supply scope to "Device" and point the power supply to the powered device. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Jiri Kosina --- drivers/hid/hid-input.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 9333d692a78..af0200f061c 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -279,7 +279,8 @@ static enum power_supply_property hidinput_battery_props[] = { POWER_SUPPLY_PROP_ONLINE, POWER_SUPPLY_PROP_CAPACITY, POWER_SUPPLY_PROP_MODEL_NAME, - POWER_SUPPLY_PROP_STATUS + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_SCOPE, }; #define HID_BATTERY_QUIRK_PERCENT (1 << 0) /* always reports percent */ @@ -344,6 +345,10 @@ static int hidinput_get_battery_property(struct power_supply *psy, val->intval = POWER_SUPPLY_STATUS_DISCHARGING; break; + case POWER_SUPPLY_PROP_SCOPE: + val->intval = POWER_SUPPLY_SCOPE_DEVICE; + break; + default: ret = -EINVAL; break; @@ -403,6 +408,8 @@ static bool hidinput_setup_battery(struct hid_device *dev, unsigned report_type, battery->name = NULL; } + power_supply_powers(battery, &dev->dev); + out: return true; } -- cgit v1.2.3-70-g09d2 From a9bb5a4bf9f84256499c802fd397d56d55227e4f Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 13 Jan 2012 22:56:32 +0000 Subject: PCMCIA: pxa: convert PXA socket drivers to use new irq/gpio management Convert all the PXA platform socket drivers to use the new irq/gpio management provided by soc_common. This relieves these drivers from having to do anything with these GPIOs other than provide the numbers to soc_common. Acked-by: Dominik Brodowski Signed-off-by: Russell King --- arch/arm/mach-pxa/include/mach/balloon3.h | 1 - drivers/pcmcia/pxa2xx_balloon3.c | 21 +++------- drivers/pcmcia/pxa2xx_cm_x255.c | 38 ++++++----------- drivers/pcmcia/pxa2xx_cm_x270.c | 22 ++-------- drivers/pcmcia/pxa2xx_colibri.c | 20 +-------- drivers/pcmcia/pxa2xx_e740.c | 70 ++++++------------------------- drivers/pcmcia/pxa2xx_mainstone.c | 30 +++++++------ drivers/pcmcia/pxa2xx_palmld.c | 7 +--- drivers/pcmcia/pxa2xx_palmtc.c | 7 +--- drivers/pcmcia/pxa2xx_palmtx.c | 7 +--- drivers/pcmcia/pxa2xx_sharpsl.c | 30 +------------ drivers/pcmcia/pxa2xx_stargate2.c | 33 +++------------ drivers/pcmcia/pxa2xx_trizeps4.c | 60 +++----------------------- drivers/pcmcia/pxa2xx_viper.c | 38 +++-------------- drivers/pcmcia/pxa2xx_vpac270.c | 53 ++++------------------- 15 files changed, 81 insertions(+), 356 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-pxa/include/mach/balloon3.h b/arch/arm/mach-pxa/include/mach/balloon3.h index f02fa1e6ba8..954641e6c8b 100644 --- a/arch/arm/mach-pxa/include/mach/balloon3.h +++ b/arch/arm/mach-pxa/include/mach/balloon3.h @@ -174,7 +174,6 @@ enum balloon3_features { #define BALLOON3_AUX_NIRQ PXA_GPIO_TO_IRQ(BALLOON3_GPIO_AUX_NIRQ) #define BALLOON3_CODEC_IRQ PXA_GPIO_TO_IRQ(BALLOON3_GPIO_CODEC_IRQ) -#define BALLOON3_S0_CD_IRQ PXA_GPIO_TO_IRQ(BALLOON3_GPIO_S0_CD) #define BALLOON3_NR_IRQS (IRQ_BOARD_START + 16) diff --git a/drivers/pcmcia/pxa2xx_balloon3.c b/drivers/pcmcia/pxa2xx_balloon3.c index 22a75e610f1..12e38b49771 100644 --- a/drivers/pcmcia/pxa2xx_balloon3.c +++ b/drivers/pcmcia/pxa2xx_balloon3.c @@ -29,15 +29,6 @@ #include "soc_common.h" -/* - * These are a list of interrupt sources that provokes a polled - * check of status - */ -static struct pcmcia_irqs irqs[] = { - { 0, BALLOON3_S0_CD_IRQ, "PCMCIA0 CD" }, - { 0, BALLOON3_BP_NSTSCHG_IRQ, "PCMCIA0 STSCHG" }, -}; - static int balloon3_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { uint16_t ver; @@ -49,12 +40,12 @@ static int balloon3_pcmcia_hw_init(struct soc_pcmcia_socket *skt) ver); skt->socket.pci_irq = BALLOON3_BP_CF_NRDY_IRQ; - return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); -} + skt->stat[SOC_STAT_CD].gpio = BALLOON3_GPIO_S0_CD; + skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD"; + skt->stat[SOC_STAT_BVD1].irq = BALLOON3_BP_NSTSCHG_IRQ; + skt->stat[SOC_STAT_BVD1].name = "PCMCIA0 STSCHG"; -static void balloon3_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) -{ - soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); + return 0; } static unsigned long balloon3_pcmcia_status[2] = { @@ -85,7 +76,6 @@ static void balloon3_pcmcia_socket_state(struct soc_pcmcia_socket *skt, disable_irq(BALLOON3_BP_NSTSCHG_IRQ); } - state->detect = !gpio_get_value(BALLOON3_GPIO_S0_CD); state->ready = !!(status & BALLOON3_CF_nIRQ); state->bvd1 = !!(status & BALLOON3_CF_nSTSCHG_BVD1); state->bvd2 = 0; /* not available */ @@ -106,7 +96,6 @@ static int balloon3_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, static struct pcmcia_low_level balloon3_pcmcia_ops = { .owner = THIS_MODULE, .hw_init = balloon3_pcmcia_hw_init, - .hw_shutdown = balloon3_pcmcia_hw_shutdown, .socket_state = balloon3_pcmcia_socket_state, .configure_socket = balloon3_pcmcia_configure_socket, .first = 0, diff --git a/drivers/pcmcia/pxa2xx_cm_x255.c b/drivers/pcmcia/pxa2xx_cm_x255.c index 31ab6ddf52c..f90e7b1a595 100644 --- a/drivers/pcmcia/pxa2xx_cm_x255.c +++ b/drivers/pcmcia/pxa2xx_cm_x255.c @@ -25,17 +25,6 @@ #define GPIO_PCMCIA_S1_RDYINT (8) #define GPIO_PCMCIA_RESET (9) -#define PCMCIA_S0_CD_VALID gpio_to_irq(GPIO_PCMCIA_S0_CD_VALID) -#define PCMCIA_S1_CD_VALID gpio_to_irq(GPIO_PCMCIA_S1_CD_VALID) -#define PCMCIA_S0_RDYINT gpio_to_irq(GPIO_PCMCIA_S0_RDYINT) -#define PCMCIA_S1_RDYINT gpio_to_irq(GPIO_PCMCIA_S1_RDYINT) - - -static struct pcmcia_irqs irqs[] = { - { .sock = 0, .str = "PCMCIA0 CD" }, - { .sock = 1, .str = "PCMCIA1 CD" }, -}; - static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset"); @@ -43,19 +32,23 @@ static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt) return ret; gpio_direction_output(GPIO_PCMCIA_RESET, 0); - skt->socket.pci_irq = skt->nr == 0 ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT; - irqs[0].irq = PCMCIA_S0_CD_VALID; - irqs[1].irq = PCMCIA_S1_CD_VALID; - ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); - if (!ret) - gpio_free(GPIO_PCMCIA_RESET); + if (skt->nr == 0) { + skt->stat[SOC_STAT_CD].gpio = GPIO_PCMCIA_S0_CD_VALID; + skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD"; + skt->stat[SOC_STAT_RDY].gpio = GPIO_PCMCIA_S0_RDYINT; + skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY"; + } else { + skt->stat[SOC_STAT_CD].gpio = GPIO_PCMCIA_S1_CD_VALID; + skt->stat[SOC_STAT_CD].name = "PCMCIA1 CD"; + skt->stat[SOC_STAT_RDY].gpio = GPIO_PCMCIA_S1_RDYINT; + skt->stat[SOC_STAT_RDY].name = "PCMCIA1 RDY"; + } - return ret; + return 0; } static void cmx255_pcmcia_shutdown(struct soc_pcmcia_socket *skt) { - soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); gpio_free(GPIO_PCMCIA_RESET); } @@ -63,13 +56,6 @@ static void cmx255_pcmcia_shutdown(struct soc_pcmcia_socket *skt) static void cmx255_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) { - int cd = skt->nr ? GPIO_PCMCIA_S1_CD_VALID : GPIO_PCMCIA_S0_CD_VALID; - int rdy = skt->nr ? GPIO_PCMCIA_S1_RDYINT : GPIO_PCMCIA_S0_RDYINT; - - state->detect = !gpio_get_value(cd); - state->ready = !!gpio_get_value(rdy); - state->bvd1 = 1; - state->bvd2 = 1; state->vs_3v = 0; state->vs_Xv = 0; state->wrprot = 0; /* not available */ diff --git a/drivers/pcmcia/pxa2xx_cm_x270.c b/drivers/pcmcia/pxa2xx_cm_x270.c index 3dc7621a076..efb5f132851 100644 --- a/drivers/pcmcia/pxa2xx_cm_x270.c +++ b/drivers/pcmcia/pxa2xx_cm_x270.c @@ -22,14 +22,6 @@ #define GPIO_PCMCIA_S0_RDYINT (82) #define GPIO_PCMCIA_RESET (53) -#define PCMCIA_S0_CD_VALID gpio_to_irq(GPIO_PCMCIA_S0_CD_VALID) -#define PCMCIA_S0_RDYINT gpio_to_irq(GPIO_PCMCIA_S0_RDYINT) - - -static struct pcmcia_irqs irqs[] = { - { .sock = 0, .str = "PCMCIA0 CD" }, -}; - static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset"); @@ -37,18 +29,16 @@ static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) return ret; gpio_direction_output(GPIO_PCMCIA_RESET, 0); - skt->socket.pci_irq = PCMCIA_S0_RDYINT; - irqs[0].irq = PCMCIA_S0_CD_VALID; - ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); - if (!ret) - gpio_free(GPIO_PCMCIA_RESET); + skt->stat[SOC_STAT_CD].gpio = GPIO_PCMCIA_S0_CD_VALID; + skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD"; + skt->stat[SOC_STAT_RDY].gpio = GPIO_PCMCIA_S0_RDYINT; + skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY"; return ret; } static void cmx270_pcmcia_shutdown(struct soc_pcmcia_socket *skt) { - soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); gpio_free(GPIO_PCMCIA_RESET); } @@ -56,10 +46,6 @@ static void cmx270_pcmcia_shutdown(struct soc_pcmcia_socket *skt) static void cmx270_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) { - state->detect = (gpio_get_value(GPIO_PCMCIA_S0_CD_VALID) == 0) ? 1 : 0; - state->ready = (gpio_get_value(GPIO_PCMCIA_S0_RDYINT) == 0) ? 0 : 1; - state->bvd1 = 1; - state->bvd2 = 1; state->vs_3v = 0; state->vs_Xv = 0; state->wrprot = 0; /* not available */ diff --git a/drivers/pcmcia/pxa2xx_colibri.c b/drivers/pcmcia/pxa2xx_colibri.c index c6dec572a05..3565169a00f 100644 --- a/drivers/pcmcia/pxa2xx_colibri.c +++ b/drivers/pcmcia/pxa2xx_colibri.c @@ -53,13 +53,6 @@ static struct gpio colibri_pcmcia_gpios[] = { { 0, GPIOF_INIT_HIGH,"PCMCIA Reset" }, }; -static struct pcmcia_irqs colibri_irqs[] = { - { - .sock = 0, - .str = "PCMCIA CD" - }, -}; - static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { int ret; @@ -69,19 +62,10 @@ static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt) if (ret) goto err1; - colibri_irqs[0].irq = gpio_to_irq(colibri_pcmcia_gpios[DETECT].gpio); skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpios[READY].gpio); + skt->stat[SOC_STAT_CD].irq = gpio_to_irq(colibri_pcmcia_gpios[DETECT].gpio); + skt->stat[SOC_STAT_CD].name = "PCMCIA CD"; - ret = soc_pcmcia_request_irqs(skt, colibri_irqs, - ARRAY_SIZE(colibri_irqs)); - if (ret) - goto err2; - - return ret; - -err2: - gpio_free_array(colibri_pcmcia_gpios, - ARRAY_SIZE(colibri_pcmcia_gpios)); err1: return ret; } diff --git a/drivers/pcmcia/pxa2xx_e740.c b/drivers/pcmcia/pxa2xx_e740.c index 17cd2ce7428..24e00a503d0 100644 --- a/drivers/pcmcia/pxa2xx_e740.c +++ b/drivers/pcmcia/pxa2xx_e740.c @@ -23,52 +23,27 @@ #include "soc_common.h" -static struct pcmcia_irqs cd_irqs[] = { - { - .sock = 0, - .str = "CF card detect" - }, - { - .sock = 1, - .str = "Wifi switch" - }, -}; - static int e740_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { - if (skt->nr == 0) - skt->socket.pci_irq = gpio_to_irq(GPIO_E740_PCMCIA_RDY0); - else - skt->socket.pci_irq = gpio_to_irq(GPIO_E740_PCMCIA_RDY1); - - cd_irqs[0].irq = gpio_to_irq(GPIO_E740_PCMCIA_CD0); - cd_irqs[1].irq = gpio_to_irq(GPIO_E740_PCMCIA_CD1); - - return soc_pcmcia_request_irqs(skt, &cd_irqs[skt->nr], 1); -} + if (skt->nr == 0) { + skt->stat[SOC_STAT_CD].gpio = GPIO_E740_PCMCIA_CD0; + skt->stat[SOC_STAT_CD].name = "CF card detect"; + skt->stat[SOC_STAT_RDY].gpio = GPIO_E740_PCMCIA_RDY0; + skt->stat[SOC_STAT_RDY].name = "CF ready"; + } else { + skt->stat[SOC_STAT_CD].gpio = GPIO_E740_PCMCIA_CD1; + skt->stat[SOC_STAT_CD].name = "Wifi switch"; + skt->stat[SOC_STAT_RDY].gpio = GPIO_E740_PCMCIA_RDY1; + skt->stat[SOC_STAT_RDY].name = "Wifi ready"; + } -/* - * Release all resources. - */ -static void e740_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) -{ - soc_pcmcia_free_irqs(skt, &cd_irqs[skt->nr], 1); + return 0; } static void e740_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) { - if (skt->nr == 0) { - state->detect = gpio_get_value(GPIO_E740_PCMCIA_CD0) ? 0 : 1; - state->ready = gpio_get_value(GPIO_E740_PCMCIA_RDY0) ? 1 : 0; - } else { - state->detect = gpio_get_value(GPIO_E740_PCMCIA_CD1) ? 0 : 1; - state->ready = gpio_get_value(GPIO_E740_PCMCIA_RDY1) ? 1 : 0; - } - state->vs_3v = 1; - state->bvd1 = 1; - state->bvd2 = 1; state->wrprot = 0; state->vs_Xv = 0; } @@ -109,32 +84,11 @@ static int e740_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, return 0; } -/* - * Enable card status IRQs on (re-)initialisation. This can - * be called at initialisation, power management event, or - * pcmcia event. - */ -static void e740_pcmcia_socket_init(struct soc_pcmcia_socket *skt) -{ - soc_pcmcia_enable_irqs(skt, cd_irqs, ARRAY_SIZE(cd_irqs)); -} - -/* - * Disable card status IRQs on suspend. - */ -static void e740_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) -{ - soc_pcmcia_disable_irqs(skt, cd_irqs, ARRAY_SIZE(cd_irqs)); -} - static struct pcmcia_low_level e740_pcmcia_ops = { .owner = THIS_MODULE, .hw_init = e740_pcmcia_hw_init, - .hw_shutdown = e740_pcmcia_hw_shutdown, .socket_state = e740_pcmcia_socket_state, .configure_socket = e740_pcmcia_configure_socket, - .socket_init = e740_pcmcia_socket_init, - .socket_suspend = e740_pcmcia_socket_suspend, .nr = 2, }; diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c index aded706c0b9..b0ea4d3f8a1 100644 --- a/drivers/pcmcia/pxa2xx_mainstone.c +++ b/drivers/pcmcia/pxa2xx_mainstone.c @@ -30,27 +30,26 @@ #include "soc_common.h" -static struct pcmcia_irqs irqs[] = { - { 0, MAINSTONE_S0_CD_IRQ, "PCMCIA0 CD" }, - { 1, MAINSTONE_S1_CD_IRQ, "PCMCIA1 CD" }, - { 0, MAINSTONE_S0_STSCHG_IRQ, "PCMCIA0 STSCHG" }, - { 1, MAINSTONE_S1_STSCHG_IRQ, "PCMCIA1 STSCHG" }, -}; - static int mst_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { /* * Setup default state of GPIO outputs * before we enable them as outputs. */ - - skt->socket.pci_irq = (skt->nr == 0) ? MAINSTONE_S0_IRQ : MAINSTONE_S1_IRQ; - return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); -} - -static void mst_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) -{ - soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); + if (skt->nr == 0) { + skt->socket.pci_irq = MAINSTONE_S0_IRQ; + skt->stat[SOC_STAT_CD].irq = MAINSTONE_S0_CD_IRQ; + skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD"; + skt->stat[SOC_STAT_BVD1].irq = MAINSTONE_S0_STSCHG_IRQ; + skt->stat[SOC_STAT_BVD1].name = "PCMCIA0 STSCHG"; + } else { + skt->socket.pci_irq = MAINSTONE_S1_IRQ; + skt->stat[SOC_STAT_CD].irq = MAINSTONE_S1_CD_IRQ; + skt->stat[SOC_STAT_CD].name = "PCMCIA1 CD"; + skt->stat[SOC_STAT_BVD1].irq = MAINSTONE_S1_STSCHG_IRQ; + skt->stat[SOC_STAT_BVD1].name = "PCMCIA1 STSCHG"; + } + return 0; } static unsigned long mst_pcmcia_status[2]; @@ -131,7 +130,6 @@ static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, static struct pcmcia_low_level mst_pcmcia_ops __initdata = { .owner = THIS_MODULE, .hw_init = mst_pcmcia_hw_init, - .hw_shutdown = mst_pcmcia_hw_shutdown, .socket_state = mst_pcmcia_socket_state, .configure_socket = mst_pcmcia_configure_socket, .nr = 2, diff --git a/drivers/pcmcia/pxa2xx_palmld.c b/drivers/pcmcia/pxa2xx_palmld.c index 6a8e011a8c1..4bf68144c36 100644 --- a/drivers/pcmcia/pxa2xx_palmld.c +++ b/drivers/pcmcia/pxa2xx_palmld.c @@ -23,7 +23,6 @@ static struct gpio palmld_pcmcia_gpios[] = { { GPIO_NR_PALMLD_PCMCIA_POWER, GPIOF_INIT_LOW, "PCMCIA Power" }, { GPIO_NR_PALMLD_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" }, - { GPIO_NR_PALMLD_PCMCIA_READY, GPIOF_IN, "PCMCIA Ready" }, }; static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt) @@ -33,7 +32,8 @@ static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt) ret = gpio_request_array(palmld_pcmcia_gpios, ARRAY_SIZE(palmld_pcmcia_gpios)); - skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMLD_PCMCIA_READY); + skt->stat[SOC_STAT_RDY].gpio = GPIO_NR_PALMLD_PCMCIA_READY; + skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready"; return ret; } @@ -47,9 +47,6 @@ static void palmld_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) { state->detect = 1; /* always inserted */ - state->ready = !!gpio_get_value(GPIO_NR_PALMLD_PCMCIA_READY); - state->bvd1 = 1; - state->bvd2 = 1; state->wrprot = 0; state->vs_3v = 1; state->vs_Xv = 0; diff --git a/drivers/pcmcia/pxa2xx_palmtc.c b/drivers/pcmcia/pxa2xx_palmtc.c index 9e38de769ba..b32d05f8678 100644 --- a/drivers/pcmcia/pxa2xx_palmtc.c +++ b/drivers/pcmcia/pxa2xx_palmtc.c @@ -26,7 +26,6 @@ static struct gpio palmtc_pcmcia_gpios[] = { { GPIO_NR_PALMTC_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" }, { GPIO_NR_PALMTC_PCMCIA_POWER3, GPIOF_INIT_LOW, "PCMCIA Power 3" }, { GPIO_NR_PALMTC_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" }, - { GPIO_NR_PALMTC_PCMCIA_READY, GPIOF_IN, "PCMCIA Ready" }, { GPIO_NR_PALMTC_PCMCIA_PWRREADY, GPIOF_IN, "PCMCIA Power Ready" }, }; @@ -37,7 +36,8 @@ static int palmtc_pcmcia_hw_init(struct soc_pcmcia_socket *skt) ret = gpio_request_array(palmtc_pcmcia_gpios, ARRAY_SIZE(palmtc_pcmcia_gpios)); - skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTC_PCMCIA_READY); + skt->stat[SOC_STAT_RDY].gpio = GPIO_NR_PALMTC_PCMCIA_READY; + skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready"; return ret; } @@ -51,9 +51,6 @@ static void palmtc_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) { state->detect = 1; /* always inserted */ - state->ready = !!gpio_get_value(GPIO_NR_PALMTC_PCMCIA_READY); - state->bvd1 = 1; - state->bvd2 = 1; state->wrprot = 0; state->vs_3v = 1; state->vs_Xv = 0; diff --git a/drivers/pcmcia/pxa2xx_palmtx.c b/drivers/pcmcia/pxa2xx_palmtx.c index 80645a688ee..ee024ff0980 100644 --- a/drivers/pcmcia/pxa2xx_palmtx.c +++ b/drivers/pcmcia/pxa2xx_palmtx.c @@ -23,7 +23,6 @@ static struct gpio palmtx_pcmcia_gpios[] = { { GPIO_NR_PALMTX_PCMCIA_POWER1, GPIOF_INIT_LOW, "PCMCIA Power 1" }, { GPIO_NR_PALMTX_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" }, { GPIO_NR_PALMTX_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" }, - { GPIO_NR_PALMTX_PCMCIA_READY, GPIOF_IN, "PCMCIA Ready" }, }; static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt) @@ -33,7 +32,8 @@ static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt) ret = gpio_request_array(palmtx_pcmcia_gpios, ARRAY_SIZE(palmtx_pcmcia_gpios)); - skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY); + skt->stat[SOC_STAT_RDY].gpio = GPIO_NR_PALMTX_PCMCIA_READY; + skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready"; return ret; } @@ -47,9 +47,6 @@ static void palmtx_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) { state->detect = 1; /* always inserted */ - state->ready = !!gpio_get_value(GPIO_NR_PALMTX_PCMCIA_READY); - state->bvd1 = 1; - state->bvd2 = 1; state->wrprot = 0; state->vs_3v = 1; state->vs_Xv = 0; diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c index 69ae2fd2240..b066273b6b4 100644 --- a/drivers/pcmcia/pxa2xx_sharpsl.c +++ b/drivers/pcmcia/pxa2xx_sharpsl.c @@ -46,21 +46,9 @@ static void sharpsl_pcmcia_init_reset(struct soc_pcmcia_socket *skt) static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { - int ret; - - /* Register interrupts */ if (SCOOP_DEV[skt->nr].cd_irq >= 0) { - struct pcmcia_irqs cd_irq; - - cd_irq.sock = skt->nr; - cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq; - cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str; - ret = soc_pcmcia_request_irqs(skt, &cd_irq, 1); - - if (ret) { - printk(KERN_ERR "Request for Compact Flash IRQ failed\n"); - return ret; - } + skt->stat[SOC_STAT_CD].irq = SCOOP_DEV[skt->nr].cd_irq; + skt->stat[SOC_STAT_CD].name = SCOOP_DEV[skt->nr].cd_irq_str; } skt->socket.pci_irq = SCOOP_DEV[skt->nr].irq; @@ -68,19 +56,6 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt) return 0; } -static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) -{ - if (SCOOP_DEV[skt->nr].cd_irq >= 0) { - struct pcmcia_irqs cd_irq; - - cd_irq.sock = skt->nr; - cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq; - cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str; - soc_pcmcia_free_irqs(skt, &cd_irq, 1); - } -} - - static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) { @@ -222,7 +197,6 @@ static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) static struct pcmcia_low_level sharpsl_pcmcia_ops __initdata = { .owner = THIS_MODULE, .hw_init = sharpsl_pcmcia_hw_init, - .hw_shutdown = sharpsl_pcmcia_hw_shutdown, .socket_state = sharpsl_pcmcia_socket_state, .configure_socket = sharpsl_pcmcia_configure_socket, .socket_init = sharpsl_pcmcia_socket_init, diff --git a/drivers/pcmcia/pxa2xx_stargate2.c b/drivers/pcmcia/pxa2xx_stargate2.c index 6c2366b74a3..e7c7eb530cb 100644 --- a/drivers/pcmcia/pxa2xx_stargate2.c +++ b/drivers/pcmcia/pxa2xx_stargate2.c @@ -33,10 +33,6 @@ #define SG2_S0_GPIO_DETECT 53 #define SG2_S0_GPIO_READY 81 -static struct pcmcia_irqs irqs[] = { - {.sock = 0, .str = "PCMCIA0 CD" }, -}; - static struct gpio sg2_pcmcia_gpios[] = { { SG2_S0_GPIO_RESET, GPIOF_OUT_INIT_HIGH, "PCMCIA Reset" }, { SG2_S0_POWER_CTL, GPIOF_OUT_INIT_HIGH, "PCMCIA Power Ctrl" }, @@ -44,22 +40,16 @@ static struct gpio sg2_pcmcia_gpios[] = { static int sg2_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { - skt->socket.pci_irq = gpio_to_irq(SG2_S0_GPIO_READY); - irqs[0].irq = gpio_to_irq(SG2_S0_GPIO_DETECT); - - return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); -} - -static void sg2_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) -{ - soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); + skt->stat[SOC_STAT_CD].gpio = SG2_S0_GPIO_DETECT; + skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD"; + skt->stat[SOC_STAT_RDY].gpio = SG2_S0_GPIO_READY; + skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY"; + return 0; } static void sg2_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) { - state->detect = !gpio_get_value(SG2_S0_GPIO_DETECT); - state->ready = !!gpio_get_value(SG2_S0_GPIO_READY); state->bvd1 = 0; /* not available - battery detect on card */ state->bvd2 = 0; /* not available */ state->vs_3v = 1; /* not available - voltage detect for card */ @@ -94,24 +84,11 @@ static int sg2_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, return 0; } -static void sg2_pcmcia_socket_init(struct soc_pcmcia_socket *skt) -{ - soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); -} - -static void sg2_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) -{ - soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); -} - static struct pcmcia_low_level sg2_pcmcia_ops __initdata = { .owner = THIS_MODULE, .hw_init = sg2_pcmcia_hw_init, - .hw_shutdown = sg2_pcmcia_hw_shutdown, .socket_state = sg2_pcmcia_socket_state, .configure_socket = sg2_pcmcia_configure_socket, - .socket_init = sg2_pcmcia_socket_init, - .socket_suspend = sg2_pcmcia_socket_suspend, .nr = 1, }; diff --git a/drivers/pcmcia/pxa2xx_trizeps4.c b/drivers/pcmcia/pxa2xx_trizeps4.c index 7c33f898135..31fd9344991 100644 --- a/drivers/pcmcia/pxa2xx_trizeps4.c +++ b/drivers/pcmcia/pxa2xx_trizeps4.c @@ -29,32 +29,17 @@ extern void board_pcmcia_power(int power); -static struct pcmcia_irqs irqs[] = { - { .sock = 0, .str = "cs0_cd" } - /* on other baseboards we can have more inputs */ -}; - static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { - int ret, i; /* we dont have voltage/card/ready detection * so we dont need interrupts for it */ switch (skt->nr) { case 0: - if (gpio_request(GPIO_PRDY, "cf_irq") < 0) { - pr_err("%s: sock %d unable to request gpio %d\n", __func__, - skt->nr, GPIO_PRDY); - return -EBUSY; - } - if (gpio_direction_input(GPIO_PRDY) < 0) { - pr_err("%s: sock %d unable to set input gpio %d\n", __func__, - skt->nr, GPIO_PRDY); - gpio_free(GPIO_PRDY); - return -EINVAL; - } - skt->socket.pci_irq = gpio_to_irq(GPIO_PRDY); - irqs[0].irq = gpio_to_irq(GPIO_PCD); + skt->stat[SOC_STAT_CD].gpio = GPIO_PCD; + skt->stat[SOC_STAT_CD].name = "cs0_cd"; + skt->stat[SOC_STAT_RDY].gpio = GPIO_PRDY; + skt->stat[SOC_STAT_RDY].name = "cs0_rdy"; break; default: break; @@ -62,39 +47,7 @@ static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt) /* release the reset of this card */ pr_debug("%s: sock %d irq %d\n", __func__, skt->nr, skt->socket.pci_irq); - /* supplementory irqs for the socket */ - for (i = 0; i < ARRAY_SIZE(irqs); i++) { - if (irqs[i].sock != skt->nr) - continue; - if (gpio_request(irq_to_gpio(irqs[i].irq), irqs[i].str) < 0) { - pr_err("%s: sock %d unable to request gpio %d\n", - __func__, skt->nr, irq_to_gpio(irqs[i].irq)); - ret = -EBUSY; - goto error; - } - if (gpio_direction_input(irq_to_gpio(irqs[i].irq)) < 0) { - pr_err("%s: sock %d unable to set input gpio %d\n", - __func__, skt->nr, irq_to_gpio(irqs[i].irq)); - ret = -EINVAL; - goto error; - } - } - return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); - -error: - for (; i >= 0; i--) { - gpio_free(irq_to_gpio(irqs[i].irq)); - } - return (ret); -} - -static void trizeps_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) -{ - int i; - /* free allocated gpio's */ - gpio_free(GPIO_PRDY); - for (i = 0; i < ARRAY_SIZE(irqs); i++) - gpio_free(irq_to_gpio(irqs[i].irq)); + return 0; } static unsigned long trizeps_pcmcia_status[2]; @@ -118,8 +71,6 @@ static void trizeps_pcmcia_socket_state(struct soc_pcmcia_socket *skt, switch (skt->nr) { case 0: /* just fill in fix states */ - state->detect = gpio_get_value(GPIO_PCD) ? 0 : 1; - state->ready = gpio_get_value(GPIO_PRDY) ? 1 : 0; state->bvd1 = (status & ConXS_CFSR_BVD1) ? 1 : 0; state->bvd2 = (status & ConXS_CFSR_BVD2) ? 1 : 0; state->vs_3v = (status & ConXS_CFSR_VS1) ? 0 : 1; @@ -204,7 +155,6 @@ static void trizeps_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) static struct pcmcia_low_level trizeps_pcmcia_ops = { .owner = THIS_MODULE, .hw_init = trizeps_pcmcia_hw_init, - .hw_shutdown = trizeps_pcmcia_hw_shutdown, .socket_state = trizeps_pcmcia_socket_state, .configure_socket = trizeps_pcmcia_configure_socket, .socket_init = trizeps_pcmcia_socket_init, diff --git a/drivers/pcmcia/pxa2xx_viper.c b/drivers/pcmcia/pxa2xx_viper.c index 1064b1c2869..6100ef8ce53 100644 --- a/drivers/pcmcia/pxa2xx_viper.c +++ b/drivers/pcmcia/pxa2xx_viper.c @@ -32,13 +32,6 @@ static struct platform_device *arcom_pcmcia_dev; -static struct pcmcia_irqs irqs[] = { - { - .sock = 0, - .str = "PCMCIA_CD", - }, -}; - static inline struct arcom_pcmcia_pdata *viper_get_pdata(void) { return arcom_pcmcia_dev->dev.platform_data; @@ -49,38 +42,28 @@ static int viper_pcmcia_hw_init(struct soc_pcmcia_socket *skt) struct arcom_pcmcia_pdata *pdata = viper_get_pdata(); unsigned long flags; - skt->socket.pci_irq = gpio_to_irq(pdata->rdy_gpio); - irqs[0].irq = gpio_to_irq(pdata->cd_gpio); - - if (gpio_request(pdata->cd_gpio, "CF detect")) - goto err_request_cd; - - if (gpio_request(pdata->rdy_gpio, "CF ready")) - goto err_request_rdy; + skt->stat[SOC_STAT_CD].gpio = pdata->cd_gpio; + skt->stat[SOC_STAT_CD].name = "PCMCIA_CD"; + skt->stat[SOC_STAT_RDY].gpio = pdata->rdy_gpio; + skt->stat[SOC_STAT_RDY].name = "CF ready"; if (gpio_request(pdata->pwr_gpio, "CF power")) goto err_request_pwr; local_irq_save(flags); - if (gpio_direction_output(pdata->pwr_gpio, 0) || - gpio_direction_input(pdata->cd_gpio) || - gpio_direction_input(pdata->rdy_gpio)) { + if (gpio_direction_output(pdata->pwr_gpio, 0)) { local_irq_restore(flags); goto err_dir; } local_irq_restore(flags); - return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); + return 0; err_dir: gpio_free(pdata->pwr_gpio); err_request_pwr: - gpio_free(pdata->rdy_gpio); -err_request_rdy: - gpio_free(pdata->cd_gpio); -err_request_cd: dev_err(&arcom_pcmcia_dev->dev, "Failed to setup PCMCIA GPIOs\n"); return -1; } @@ -92,21 +75,12 @@ static void viper_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) { struct arcom_pcmcia_pdata *pdata = viper_get_pdata(); - soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); gpio_free(pdata->pwr_gpio); - gpio_free(pdata->rdy_gpio); - gpio_free(pdata->cd_gpio); } static void viper_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) { - struct arcom_pcmcia_pdata *pdata = viper_get_pdata(); - - state->detect = !gpio_get_value(pdata->cd_gpio); - state->ready = !!gpio_get_value(pdata->rdy_gpio); - state->bvd1 = 1; - state->bvd2 = 1; state->wrprot = 0; state->vs_3v = 1; /* Can only apply 3.3V */ state->vs_Xv = 0; diff --git a/drivers/pcmcia/pxa2xx_vpac270.c b/drivers/pcmcia/pxa2xx_vpac270.c index 61b17d235db..cf07d882551 100644 --- a/drivers/pcmcia/pxa2xx_vpac270.c +++ b/drivers/pcmcia/pxa2xx_vpac270.c @@ -23,29 +23,14 @@ #include "soc_common.h" static struct gpio vpac270_pcmcia_gpios[] = { - { GPIO84_VPAC270_PCMCIA_CD, GPIOF_IN, "PCMCIA Card Detect" }, - { GPIO35_VPAC270_PCMCIA_RDY, GPIOF_IN, "PCMCIA Ready" }, { GPIO107_VPAC270_PCMCIA_PPEN, GPIOF_INIT_LOW, "PCMCIA PPEN" }, { GPIO11_VPAC270_PCMCIA_RESET, GPIOF_INIT_LOW, "PCMCIA Reset" }, }; static struct gpio vpac270_cf_gpios[] = { - { GPIO17_VPAC270_CF_CD, GPIOF_IN, "CF Card Detect" }, - { GPIO12_VPAC270_CF_RDY, GPIOF_IN, "CF Ready" }, { GPIO16_VPAC270_CF_RESET, GPIOF_INIT_LOW, "CF Reset" }, }; -static struct pcmcia_irqs cd_irqs[] = { - { - .sock = 0, - .str = "PCMCIA CD" - }, - { - .sock = 1, - .str = "CF CD" - }, -}; - static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { int ret; @@ -54,20 +39,18 @@ static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) ret = gpio_request_array(vpac270_pcmcia_gpios, ARRAY_SIZE(vpac270_pcmcia_gpios)); - skt->socket.pci_irq = gpio_to_irq(GPIO35_VPAC270_PCMCIA_RDY); - cd_irqs[0].irq = gpio_to_irq(GPIO84_VPAC270_PCMCIA_CD); - - if (!ret) - ret = soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1); + skt->stat[SOC_STAT_CD].gpio = GPIO84_VPAC270_PCMCIA_CD; + skt->stat[SOC_STAT_CD].name = "PCMCIA CD"; + skt->stat[SOC_STAT_RDY].gpio = GPIO35_VPAC270_PCMCIA_RDY; + skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready"; } else { ret = gpio_request_array(vpac270_cf_gpios, ARRAY_SIZE(vpac270_cf_gpios)); - skt->socket.pci_irq = gpio_to_irq(GPIO12_VPAC270_CF_RDY); - cd_irqs[1].irq = gpio_to_irq(GPIO17_VPAC270_CF_CD); - - if (!ret) - ret = soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1); + skt->stat[SOC_STAT_CD].gpio = GPIO17_VPAC270_CF_CD; + skt->stat[SOC_STAT_CD].name = "CF CD"; + skt->stat[SOC_STAT_RDY].gpio = GPIO12_VPAC270_CF_RDY; + skt->stat[SOC_STAT_RDY].name = "CF Ready"; } return ret; @@ -86,15 +69,6 @@ static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) { - if (skt->nr == 0) { - state->detect = !gpio_get_value(GPIO84_VPAC270_PCMCIA_CD); - state->ready = !!gpio_get_value(GPIO35_VPAC270_PCMCIA_RDY); - } else { - state->detect = !gpio_get_value(GPIO17_VPAC270_CF_CD); - state->ready = !!gpio_get_value(GPIO12_VPAC270_CF_RDY); - } - state->bvd1 = 1; - state->bvd2 = 1; state->wrprot = 0; state->vs_3v = 1; state->vs_Xv = 0; @@ -117,14 +91,6 @@ vpac270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, return 0; } -static void vpac270_pcmcia_socket_init(struct soc_pcmcia_socket *skt) -{ -} - -static void vpac270_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) -{ -} - static struct pcmcia_low_level vpac270_pcmcia_ops = { .owner = THIS_MODULE, @@ -136,9 +102,6 @@ static struct pcmcia_low_level vpac270_pcmcia_ops = { .socket_state = vpac270_pcmcia_socket_state, .configure_socket = vpac270_pcmcia_configure_socket, - - .socket_init = vpac270_pcmcia_socket_init, - .socket_suspend = vpac270_pcmcia_socket_suspend, }; static struct platform_device *vpac270_pcmcia_device; -- cgit v1.2.3-70-g09d2 From 81f33c65e6c09597e748288010476861ac5bd166 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 19 Dec 2011 23:04:22 +0000 Subject: PCMCIA: sa1111: use new per-socket irq/gpio infrastructure Convert sa1111 PCMCIA drivers to use the new per-socket irq/gpio infrastructure. As the core takes care of handling the IRQs, we can get rid of sa1111_pcmcia_socket_init(), sa1111_pcmcia_socket_suspend(), sa1111_pcmcia_hw_init() and sa1111_pcmcia_hw_shutdown(), as well as the private IRQ table. We remove the NCR_0 setting in Neponset, as this is duplicating what's already done via configure_socket in suspend. Acked-by: Dominik Brodowski Signed-off-by: Russell King --- drivers/pcmcia/pxa2xx_lubbock.c | 1 - drivers/pcmcia/sa1100_badge4.c | 1 - drivers/pcmcia/sa1100_jornada720.c | 1 - drivers/pcmcia/sa1100_neponset.c | 9 ------- drivers/pcmcia/sa1111_generic.c | 52 ++++++++++---------------------------- drivers/pcmcia/sa1111_generic.h | 1 - 6 files changed, 13 insertions(+), 52 deletions(-) (limited to 'drivers') diff --git a/drivers/pcmcia/pxa2xx_lubbock.c b/drivers/pcmcia/pxa2xx_lubbock.c index c21888eebb5..c5caf579045 100644 --- a/drivers/pcmcia/pxa2xx_lubbock.c +++ b/drivers/pcmcia/pxa2xx_lubbock.c @@ -202,7 +202,6 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, static struct pcmcia_low_level lubbock_pcmcia_ops = { .owner = THIS_MODULE, .configure_socket = lubbock_pcmcia_configure_socket, - .socket_init = sa1111_pcmcia_socket_init, .first = 0, .nr = 2, }; diff --git a/drivers/pcmcia/sa1100_badge4.c b/drivers/pcmcia/sa1100_badge4.c index 1ce53f493be..ca97cb86389 100644 --- a/drivers/pcmcia/sa1100_badge4.c +++ b/drivers/pcmcia/sa1100_badge4.c @@ -128,7 +128,6 @@ badge4_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state static struct pcmcia_low_level badge4_pcmcia_ops = { .owner = THIS_MODULE, .configure_socket = badge4_pcmcia_configure_socket, - .socket_init = sa1111_pcmcia_socket_init, .first = 0, .nr = 2, }; diff --git a/drivers/pcmcia/sa1100_jornada720.c b/drivers/pcmcia/sa1100_jornada720.c index 6bcabee6bde..61b443e8e07 100644 --- a/drivers/pcmcia/sa1100_jornada720.c +++ b/drivers/pcmcia/sa1100_jornada720.c @@ -92,7 +92,6 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s static struct pcmcia_low_level jornada720_pcmcia_ops = { .owner = THIS_MODULE, .configure_socket = jornada720_pcmcia_configure_socket, - .socket_init = sa1111_pcmcia_socket_init, .first = 0, .nr = 2, }; diff --git a/drivers/pcmcia/sa1100_neponset.c b/drivers/pcmcia/sa1100_neponset.c index c95639b5f2a..1eac3fd60d7 100644 --- a/drivers/pcmcia/sa1100_neponset.c +++ b/drivers/pcmcia/sa1100_neponset.c @@ -106,18 +106,9 @@ neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_sta return 0; } -static void neponset_pcmcia_socket_init(struct soc_pcmcia_socket *skt) -{ - if (skt->nr == 0) - NCR_0 &= ~(NCR_A0VPP | NCR_A1VPP); - - sa1111_pcmcia_socket_init(skt); -} - static struct pcmcia_low_level neponset_pcmcia_ops = { .owner = THIS_MODULE, .configure_socket = neponset_pcmcia_configure_socket, - .socket_init = neponset_pcmcia_socket_init, .first = 0, .nr = 2, }; diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c index 7d6d3d423ef..7510d506b8c 100644 --- a/drivers/pcmcia/sa1111_generic.c +++ b/drivers/pcmcia/sa1111_generic.c @@ -29,23 +29,6 @@ #define IDX_IRQ_S1_CD_VALID (4) #define IDX_IRQ_S1_BVD1_STSCHG (5) -static struct pcmcia_irqs irqs[] = { - { 0, NO_IRQ, "SA1111 PCMCIA card detect" }, - { 0, NO_IRQ, "SA1111 PCMCIA BVD1" }, - { 1, NO_IRQ, "SA1111 CF card detect" }, - { 1, NO_IRQ, "SA1111 CF BVD1" }, -}; - -static int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *skt) -{ - return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); -} - -static void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) -{ - soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); -} - void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) { struct sa1111_pcmcia_socket *s = to_skt(skt); @@ -114,26 +97,13 @@ int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s return 0; } -void sa1111_pcmcia_socket_init(struct soc_pcmcia_socket *skt) -{ - soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); -} - -static void sa1111_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) -{ - soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); -} - int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, int (*add)(struct soc_pcmcia_socket *)) { struct sa1111_pcmcia_socket *s; int i, ret = 0; - ops->hw_init = sa1111_pcmcia_hw_init; - ops->hw_shutdown = sa1111_pcmcia_hw_shutdown; ops->socket_state = sa1111_pcmcia_socket_state; - ops->socket_suspend = sa1111_pcmcia_socket_suspend; for (i = 0; i < ops->nr; i++) { s = kzalloc(sizeof(*s), GFP_KERNEL); @@ -142,10 +112,20 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, s->soc.nr = ops->first + i; soc_pcmcia_init_one(&s->soc, ops, &dev->dev); - s->soc.socket.pci_irq = s->soc.nr ? - dev->irq[IDX_IRQ_S0_READY_NINT] : - dev->irq[IDX_IRQ_S1_READY_NINT]; s->dev = dev; + if (s->soc.nr) { + s->soc.socket.pci_irq = dev->irq[IDX_IRQ_S1_READY_NINT]; + s->soc.stat[SOC_STAT_CD].irq = dev->irq[IDX_IRQ_S1_CD_VALID]; + s->soc.stat[SOC_STAT_CD].name = "SA1111 CF card detect"; + s->soc.stat[SOC_STAT_BVD1].irq = dev->irq[IDX_IRQ_S1_BVD1_STSCHG]; + s->soc.stat[SOC_STAT_BVD1].name = "SA1111 CF BVD1"; + } else { + s->soc.socket.pci_irq = dev->irq[IDX_IRQ_S0_READY_NINT]; + s->soc.stat[SOC_STAT_CD].irq = dev->irq[IDX_IRQ_S0_CD_VALID]; + s->soc.stat[SOC_STAT_CD].name = "SA1111 PCMCIA card detect"; + s->soc.stat[SOC_STAT_BVD1].irq = dev->irq[IDX_IRQ_S0_BVD1_STSCHG]; + s->soc.stat[SOC_STAT_BVD1].name = "SA1111 PCMCIA BVD1"; + } ret = add(&s->soc); if (ret == 0) { @@ -170,12 +150,6 @@ static int pcmcia_probe(struct sa1111_dev *dev) base = dev->mapbase; - /* Initialize PCMCIA IRQs */ - irqs[0].irq = dev->irq[IDX_IRQ_S0_CD_VALID]; - irqs[1].irq = dev->irq[IDX_IRQ_S0_BVD1_STSCHG]; - irqs[2].irq = dev->irq[IDX_IRQ_S1_CD_VALID]; - irqs[3].irq = dev->irq[IDX_IRQ_S1_BVD1_STSCHG]; - /* * Initialise the suspend state. */ diff --git a/drivers/pcmcia/sa1111_generic.h b/drivers/pcmcia/sa1111_generic.h index 02dc8577cda..f6376e34a7e 100644 --- a/drivers/pcmcia/sa1111_generic.h +++ b/drivers/pcmcia/sa1111_generic.h @@ -17,7 +17,6 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, extern void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *, struct pcmcia_state *); extern int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *, const socket_state_t *); -extern void sa1111_pcmcia_socket_init(struct soc_pcmcia_socket *); extern int pcmcia_badge4_init(struct device *); extern int pcmcia_jornada720_init(struct device *); -- cgit v1.2.3-70-g09d2 From 03e0092c85e34b6f84bb3b852579b78a17496be2 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 13 Jan 2012 23:02:15 +0000 Subject: PCMCIA: sa11x0: assabet: convert to use new irq/gpio management Convert Assabet socket driver to use the new irq/gpio management. This is slightly more involved because we have to touch the private platform header file to modify the GPIO bitmasks to be GPIO numbers. Acked-by: Dominik Brodowski Signed-off-by: Russell King --- arch/arm/mach-sa1100/include/mach/assabet.h | 15 +++---- drivers/pcmcia/sa1100_assabet.c | 64 +++++++---------------------- 2 files changed, 21 insertions(+), 58 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-sa1100/include/mach/assabet.h b/arch/arm/mach-sa1100/include/mach/assabet.h index 28c2cf50c25..307391488c2 100644 --- a/arch/arm/mach-sa1100/include/mach/assabet.h +++ b/arch/arm/mach-sa1100/include/mach/assabet.h @@ -85,21 +85,18 @@ extern void ASSABET_BCR_frob(unsigned int mask, unsigned int set); #define ASSABET_BSR_RAD_RI (1 << 31) -/* GPIOs for which the generic definition doesn't say much */ +/* GPIOs (bitmasks) for which the generic definition doesn't say much */ #define ASSABET_GPIO_RADIO_IRQ GPIO_GPIO (14) /* Radio interrupt request */ #define ASSABET_GPIO_PS_MODE_SYNC GPIO_GPIO (16) /* Power supply mode/sync */ #define ASSABET_GPIO_STEREO_64FS_CLK GPIO_GPIO (19) /* SSP UDA1341 clock input */ -#define ASSABET_GPIO_CF_IRQ GPIO_GPIO (21) /* CF IRQ */ -#define ASSABET_GPIO_CF_CD GPIO_GPIO (22) /* CF CD */ -#define ASSABET_GPIO_CF_BVD2 GPIO_GPIO (24) /* CF BVD */ #define ASSABET_GPIO_GFX_IRQ GPIO_GPIO (24) /* Graphics IRQ */ -#define ASSABET_GPIO_CF_BVD1 GPIO_GPIO (25) /* CF BVD */ #define ASSABET_GPIO_BATT_LOW GPIO_GPIO (26) /* Low battery */ #define ASSABET_GPIO_RCLK GPIO_GPIO (26) /* CCLK/2 */ -#define ASSABET_IRQ_GPIO_CF_IRQ IRQ_GPIO21 -#define ASSABET_IRQ_GPIO_CF_CD IRQ_GPIO22 -#define ASSABET_IRQ_GPIO_CF_BVD2 IRQ_GPIO24 -#define ASSABET_IRQ_GPIO_CF_BVD1 IRQ_GPIO25 +/* These are gpiolib GPIO numbers, not bitmasks */ +#define ASSABET_GPIO_CF_IRQ 21 /* CF IRQ */ +#define ASSABET_GPIO_CF_CD 22 /* CF CD */ +#define ASSABET_GPIO_CF_BVD2 24 /* CF BVD / IOSPKR */ +#define ASSABET_GPIO_CF_BVD1 25 /* CF BVD / IOSTSCHG */ #endif diff --git a/drivers/pcmcia/sa1100_assabet.c b/drivers/pcmcia/sa1100_assabet.c index f1e882272ab..618f546e19c 100644 --- a/drivers/pcmcia/sa1100_assabet.c +++ b/drivers/pcmcia/sa1100_assabet.c @@ -10,45 +10,30 @@ #include #include #include +#include -#include #include -#include -#include #include #include "sa1100_generic.h" -static struct pcmcia_irqs irqs[] = { - { 1, ASSABET_IRQ_GPIO_CF_CD, "CF CD" }, - { 1, ASSABET_IRQ_GPIO_CF_BVD2, "CF BVD2" }, - { 1, ASSABET_IRQ_GPIO_CF_BVD1, "CF BVD1" }, -}; - static int assabet_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { - skt->socket.pci_irq = ASSABET_IRQ_GPIO_CF_IRQ; - - return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); -} + skt->stat[SOC_STAT_CD].gpio = ASSABET_GPIO_CF_CD; + skt->stat[SOC_STAT_CD].name = "CF CD"; + skt->stat[SOC_STAT_BVD1].gpio = ASSABET_GPIO_CF_BVD1; + skt->stat[SOC_STAT_BVD1].name = "CF BVD1"; + skt->stat[SOC_STAT_BVD2].gpio = ASSABET_GPIO_CF_BVD2; + skt->stat[SOC_STAT_BVD2].name = "CF BVD2"; + skt->stat[SOC_STAT_RDY].gpio = ASSABET_GPIO_CF_IRQ; + skt->stat[SOC_STAT_RDY].name = "CF RDY"; -/* - * Release all resources. - */ -static void assabet_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) -{ - soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); + return 0; } static void assabet_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) { - unsigned long levels = GPLR; - - state->detect = (levels & ASSABET_GPIO_CF_CD) ? 0 : 1; - state->ready = (levels & ASSABET_GPIO_CF_IRQ) ? 1 : 0; - state->bvd1 = (levels & ASSABET_GPIO_CF_BVD1) ? 1 : 0; - state->bvd2 = (levels & ASSABET_GPIO_CF_BVD2) ? 1 : 0; state->wrprot = 0; /* Not available on Assabet. */ state->vs_3v = 1; /* Can only apply 3.3V on Assabet. */ state->vs_Xv = 0; @@ -78,38 +63,24 @@ assabet_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_stat return -1; } - /* Silently ignore Vpp, output enable, speaker enable. */ + /* Silently ignore Vpp, speaker enable. */ if (state->flags & SS_RESET) mask |= ASSABET_BCR_CF_RST; + if (!(state->flags & SS_OUTPUT_ENA)) + mask |= ASSABET_BCR_CF_BUS_OFF; - ASSABET_BCR_frob(ASSABET_BCR_CF_RST | ASSABET_BCR_CF_PWR, mask); + ASSABET_BCR_frob(ASSABET_BCR_CF_RST | ASSABET_BCR_CF_PWR | + ASSABET_BCR_CF_BUS_OFF, mask); return 0; } -/* - * Enable card status IRQs on (re-)initialisation. This can - * be called at initialisation, power management event, or - * pcmcia event. - */ -static void assabet_pcmcia_socket_init(struct soc_pcmcia_socket *skt) -{ - /* - * Enable CF bus - */ - ASSABET_BCR_clear(ASSABET_BCR_CF_BUS_OFF); - - soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); -} - /* * Disable card status IRQs on suspend. */ static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) { - soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); - /* * Tristate the CF bus signals. Also assert CF * reset as per user guide page 4-11. @@ -119,14 +90,9 @@ static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) static struct pcmcia_low_level assabet_pcmcia_ops = { .owner = THIS_MODULE, - .hw_init = assabet_pcmcia_hw_init, - .hw_shutdown = assabet_pcmcia_hw_shutdown, - .socket_state = assabet_pcmcia_socket_state, .configure_socket = assabet_pcmcia_configure_socket, - - .socket_init = assabet_pcmcia_socket_init, .socket_suspend = assabet_pcmcia_socket_suspend, }; -- cgit v1.2.3-70-g09d2 From f793e3ab9f4cfbdba6269c8a6c522c5d665289b1 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 13 Jan 2012 23:03:57 +0000 Subject: PCMCIA: sa11x0: cerf: convert to use new irq/gpio management Convert Cerf socket driver to use the new irq/gpio management. This is slightly more involved because we have to touch the private platform header file to modify the GPIO bitmasks to be GPIO numbers. Acked-by: Dominik Brodowski Signed-off-by: Russell King --- arch/arm/mach-sa1100/include/mach/cerf.h | 13 +++------- drivers/pcmcia/sa1100_cerf.c | 42 +++++++------------------------- 2 files changed, 13 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-sa1100/include/mach/cerf.h b/arch/arm/mach-sa1100/include/mach/cerf.h index c3ac3d0f946..0e49545a372 100644 --- a/arch/arm/mach-sa1100/include/mach/cerf.h +++ b/arch/arm/mach-sa1100/include/mach/cerf.h @@ -14,15 +14,10 @@ #define CERF_ETH_IO 0xf0000000 #define CERF_ETH_IRQ IRQ_GPIO26 -#define CERF_GPIO_CF_BVD2 GPIO_GPIO (19) -#define CERF_GPIO_CF_BVD1 GPIO_GPIO (20) +#define CERF_GPIO_CF_BVD2 19 +#define CERF_GPIO_CF_BVD1 20 #define CERF_GPIO_CF_RESET GPIO_GPIO (21) -#define CERF_GPIO_CF_IRQ GPIO_GPIO (22) -#define CERF_GPIO_CF_CD GPIO_GPIO (23) - -#define CERF_IRQ_GPIO_CF_BVD2 IRQ_GPIO19 -#define CERF_IRQ_GPIO_CF_BVD1 IRQ_GPIO20 -#define CERF_IRQ_GPIO_CF_IRQ IRQ_GPIO22 -#define CERF_IRQ_GPIO_CF_CD IRQ_GPIO23 +#define CERF_GPIO_CF_IRQ 22 +#define CERF_GPIO_CF_CD 23 #endif // _INCLUDE_CERF_H_ diff --git a/drivers/pcmcia/sa1100_cerf.c b/drivers/pcmcia/sa1100_cerf.c index 30560df8c76..9d0424ea9a4 100644 --- a/drivers/pcmcia/sa1100_cerf.c +++ b/drivers/pcmcia/sa1100_cerf.c @@ -19,33 +19,23 @@ #define CERF_SOCKET 1 -static struct pcmcia_irqs irqs[] = { - { CERF_SOCKET, CERF_IRQ_GPIO_CF_CD, "CF_CD" }, - { CERF_SOCKET, CERF_IRQ_GPIO_CF_BVD2, "CF_BVD2" }, - { CERF_SOCKET, CERF_IRQ_GPIO_CF_BVD1, "CF_BVD1" } -}; - static int cerf_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { - skt->socket.pci_irq = CERF_IRQ_GPIO_CF_IRQ; - - return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); -} + skt->stat[SOC_STAT_CD].gpio = CERF_GPIO_CF_CD; + skt->stat[SOC_STAT_CD].name = "CF_CD"; + skt->stat[SOC_STAT_BVD1].gpio = CERF_GPIO_CF_BVD1; + skt->stat[SOC_STAT_BVD1].name = "CF_BVD1"; + skt->stat[SOC_STAT_BVD2].gpio = CERF_GPIO_CF_BVD2; + skt->stat[SOC_STAT_BVD2].name = "CF_BVD2"; + skt->stat[SOC_STAT_RDY].gpio = CERF_GPIO_CF_IRQ; + skt->stat[SOC_STAT_RDY].name = "CF_IRQ"; -static void cerf_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) -{ - soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); + return 0; } static void cerf_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) { - unsigned long levels = GPLR; - - state->detect = (levels & CERF_GPIO_CF_CD) ?0:1; - state->ready = (levels & CERF_GPIO_CF_IRQ) ?1:0; - state->bvd1 = (levels & CERF_GPIO_CF_BVD1)?1:0; - state->bvd2 = (levels & CERF_GPIO_CF_BVD2)?1:0; state->wrprot = 0; state->vs_3v = 1; state->vs_Xv = 0; @@ -76,25 +66,11 @@ cerf_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, return 0; } -static void cerf_pcmcia_socket_init(struct soc_pcmcia_socket *skt) -{ - soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); -} - -static void cerf_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) -{ - soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); -} - static struct pcmcia_low_level cerf_pcmcia_ops = { .owner = THIS_MODULE, .hw_init = cerf_pcmcia_hw_init, - .hw_shutdown = cerf_pcmcia_hw_shutdown, .socket_state = cerf_pcmcia_socket_state, .configure_socket = cerf_pcmcia_configure_socket, - - .socket_init = cerf_pcmcia_socket_init, - .socket_suspend = cerf_pcmcia_socket_suspend, }; int __devinit pcmcia_cerf_init(struct device *dev) -- cgit v1.2.3-70-g09d2 From bbb58a1210c6fdc68b09f7b9e12096c2a1886aa1 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 18 Jan 2012 12:32:37 +0000 Subject: PCMCIA: sa11x0: cerf: convert reset handling to use GPIO subsystem Rather than accessing GPSR and GPCR directly, use the GPIO subsystem instead. Acked-by: Dominik Brodowski Signed-off-by: Russell King --- arch/arm/mach-sa1100/include/mach/cerf.h | 2 +- drivers/pcmcia/sa1100_cerf.c | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-sa1100/include/mach/cerf.h b/arch/arm/mach-sa1100/include/mach/cerf.h index 0e49545a372..88fd9c006ce 100644 --- a/arch/arm/mach-sa1100/include/mach/cerf.h +++ b/arch/arm/mach-sa1100/include/mach/cerf.h @@ -16,7 +16,7 @@ #define CERF_GPIO_CF_BVD2 19 #define CERF_GPIO_CF_BVD1 20 -#define CERF_GPIO_CF_RESET GPIO_GPIO (21) +#define CERF_GPIO_CF_RESET 21 #define CERF_GPIO_CF_IRQ 22 #define CERF_GPIO_CF_CD 23 diff --git a/drivers/pcmcia/sa1100_cerf.c b/drivers/pcmcia/sa1100_cerf.c index 9d0424ea9a4..50df0e682b6 100644 --- a/drivers/pcmcia/sa1100_cerf.c +++ b/drivers/pcmcia/sa1100_cerf.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -21,6 +22,12 @@ static int cerf_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { + int ret; + + ret = gpio_request_one(CERF_GPIO_CF_RESET, GPIOF_OUT_INIT_LOW, "CF_RESET"); + if (ret) + return ret; + skt->stat[SOC_STAT_CD].gpio = CERF_GPIO_CF_CD; skt->stat[SOC_STAT_CD].name = "CF_CD"; skt->stat[SOC_STAT_BVD1].gpio = CERF_GPIO_CF_BVD1; @@ -33,6 +40,11 @@ static int cerf_pcmcia_hw_init(struct soc_pcmcia_socket *skt) return 0; } +static void cerf_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) +{ + gpio_free(CERF_GPIO_CF_RESET); +} + static void cerf_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) { @@ -57,11 +69,7 @@ cerf_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, return -1; } - if (state->flags & SS_RESET) { - GPSR = CERF_GPIO_CF_RESET; - } else { - GPCR = CERF_GPIO_CF_RESET; - } + gpio_set_value(CERF_GPIO_CF_RESET, !!(state->flags & SS_RESET)); return 0; } @@ -69,6 +77,7 @@ cerf_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, static struct pcmcia_low_level cerf_pcmcia_ops = { .owner = THIS_MODULE, .hw_init = cerf_pcmcia_hw_init, + .hw_shutdown = cerf_pcmcia_hw_shutdown, .socket_state = cerf_pcmcia_socket_state, .configure_socket = cerf_pcmcia_configure_socket, }; -- cgit v1.2.3-70-g09d2 From 7cf779cb8ddeef797a3a265889c7f088d42a12f7 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 13 Jan 2012 23:05:12 +0000 Subject: PCMCIA: sa11x0: nanoengine: convert to use new irq/gpio management Convert Nanoengine socket driver to use the new irq/gpio management. This is slightly more involved because we have to touch the private platform header file to modify the GPIO bitmasks to be GPIO numbers. Acked-by: Dominik Brodowski Signed-off-by: Russell King --- arch/arm/mach-sa1100/include/mach/nanoengine.h | 8 +- drivers/pcmcia/sa1100_nanoengine.c | 101 +++---------------------- 2 files changed, 15 insertions(+), 94 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-sa1100/include/mach/nanoengine.h b/arch/arm/mach-sa1100/include/mach/nanoengine.h index 14f8382d066..ad24c6c3740 100644 --- a/arch/arm/mach-sa1100/include/mach/nanoengine.h +++ b/arch/arm/mach-sa1100/include/mach/nanoengine.h @@ -16,10 +16,10 @@ #include -#define GPIO_PC_READY0 GPIO_GPIO(11) /* ready for socket 0 (active high)*/ -#define GPIO_PC_READY1 GPIO_GPIO(12) /* ready for socket 1 (active high) */ -#define GPIO_PC_CD0 GPIO_GPIO(13) /* detect for socket 0 (active low) */ -#define GPIO_PC_CD1 GPIO_GPIO(14) /* detect for socket 1 (active low) */ +#define GPIO_PC_READY0 11 /* ready for socket 0 (active high)*/ +#define GPIO_PC_READY1 12 /* ready for socket 1 (active high) */ +#define GPIO_PC_CD0 13 /* detect for socket 0 (active low) */ +#define GPIO_PC_CD1 14 /* detect for socket 1 (active low) */ #define GPIO_PC_RESET0 GPIO_GPIO(15) /* reset socket 0 */ #define GPIO_PC_RESET1 GPIO_GPIO(16) /* reset socket 1 */ diff --git a/drivers/pcmcia/sa1100_nanoengine.c b/drivers/pcmcia/sa1100_nanoengine.c index 93b9c9ba57c..b19b8161395 100644 --- a/drivers/pcmcia/sa1100_nanoengine.c +++ b/drivers/pcmcia/sa1100_nanoengine.c @@ -34,43 +34,24 @@ #include "sa1100_generic.h" -static struct pcmcia_irqs irqs_skt0[] = { - /* socket, IRQ, name */ - { 0, NANOENGINE_IRQ_GPIO_PC_CD0, "PC CD0" }, -}; - -static struct pcmcia_irqs irqs_skt1[] = { - /* socket, IRQ, name */ - { 1, NANOENGINE_IRQ_GPIO_PC_CD1, "PC CD1" }, -}; - struct nanoengine_pins { - unsigned input_pins; unsigned output_pins; unsigned clear_outputs; - unsigned transition_pins; - unsigned pci_irq; - struct pcmcia_irqs *pcmcia_irqs; - unsigned pcmcia_irqs_size; + int gpio_cd; + int gpio_rdy; }; static struct nanoengine_pins nano_skts[] = { { - .input_pins = GPIO_PC_READY0 | GPIO_PC_CD0, .output_pins = GPIO_PC_RESET0, .clear_outputs = GPIO_PC_RESET0, - .transition_pins = NANOENGINE_IRQ_GPIO_PC_CD0, - .pci_irq = NANOENGINE_IRQ_GPIO_PC_READY0, - .pcmcia_irqs = irqs_skt0, - .pcmcia_irqs_size = ARRAY_SIZE(irqs_skt0) + .gpio_cd = GPIO_PC_CD0, + .gpio_rdy = GPIO_PC_READY0, }, { - .input_pins = GPIO_PC_READY1 | GPIO_PC_CD1, .output_pins = GPIO_PC_RESET1, .clear_outputs = GPIO_PC_RESET1, - .transition_pins = NANOENGINE_IRQ_GPIO_PC_CD1, - .pci_irq = NANOENGINE_IRQ_GPIO_PC_READY1, - .pcmcia_irqs = irqs_skt1, - .pcmcia_irqs_size = ARRAY_SIZE(irqs_skt1) + .gpio_cd = GPIO_PC_CD1, + .gpio_rdy = GPIO_PC_READY1, } }; @@ -83,28 +64,15 @@ static int nanoengine_pcmcia_hw_init(struct soc_pcmcia_socket *skt) if (i >= num_nano_pcmcia_sockets) return -ENXIO; - GPDR &= ~nano_skts[i].input_pins; GPDR |= nano_skts[i].output_pins; GPCR = nano_skts[i].clear_outputs; - irq_set_irq_type(nano_skts[i].transition_pins, IRQ_TYPE_EDGE_BOTH); - skt->socket.pci_irq = nano_skts[i].pci_irq; - return soc_pcmcia_request_irqs(skt, - nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size); -} + skt->stat[SOC_STAT_CD].gpio = nano_skts[i].gpio_cd; + skt->stat[SOC_STAT_CD].name = i ? "PC CD1" : "PC CD0"; + skt->stat[SOC_STAT_RDY].gpio = nano_skts[i].gpio_rdy; + skt->stat[SOC_STAT_RDY].name = i ? "PC RDY1" : "PC RDY0"; -/* - * Release all resources. - */ -static void nanoengine_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) -{ - unsigned i = skt->nr; - - if (i >= num_nano_pcmcia_sockets) - return; - - soc_pcmcia_free_irqs(skt, - nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size); + return 0; } static int nanoengine_pcmcia_configure_socket( @@ -138,25 +106,11 @@ static int nanoengine_pcmcia_configure_socket( static void nanoengine_pcmcia_socket_state( struct soc_pcmcia_socket *skt, struct pcmcia_state *state) { - unsigned long levels = GPLR; unsigned i = skt->nr; if (i >= num_nano_pcmcia_sockets) return; - memset(state, 0, sizeof(struct pcmcia_state)); - switch (i) { - case 0: - state->ready = (levels & GPIO_PC_READY0) ? 1 : 0; - state->detect = !(levels & GPIO_PC_CD0) ? 1 : 0; - break; - case 1: - state->ready = (levels & GPIO_PC_READY1) ? 1 : 0; - state->detect = !(levels & GPIO_PC_CD1) ? 1 : 0; - break; - default: - return; - } state->bvd1 = 1; state->bvd2 = 1; state->wrprot = 0; /* Not available */ @@ -164,46 +118,13 @@ static void nanoengine_pcmcia_socket_state( state->vs_Xv = 0; } -/* - * Enable card status IRQs on (re-)initialisation. This can - * be called at initialisation, power management event, or - * pcmcia event. - */ -static void nanoengine_pcmcia_socket_init(struct soc_pcmcia_socket *skt) -{ - unsigned i = skt->nr; - - if (i >= num_nano_pcmcia_sockets) - return; - - soc_pcmcia_enable_irqs(skt, - nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size); -} - -/* - * Disable card status IRQs on suspend. - */ -static void nanoengine_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) -{ - unsigned i = skt->nr; - - if (i >= num_nano_pcmcia_sockets) - return; - - soc_pcmcia_disable_irqs(skt, - nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size); -} - static struct pcmcia_low_level nanoengine_pcmcia_ops = { .owner = THIS_MODULE, .hw_init = nanoengine_pcmcia_hw_init, - .hw_shutdown = nanoengine_pcmcia_hw_shutdown, .configure_socket = nanoengine_pcmcia_configure_socket, .socket_state = nanoengine_pcmcia_socket_state, - .socket_init = nanoengine_pcmcia_socket_init, - .socket_suspend = nanoengine_pcmcia_socket_suspend, }; int pcmcia_nanoengine_init(struct device *dev) -- cgit v1.2.3-70-g09d2 From 76346a4eabf85a44dc425c0197ba46a8884e6090 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 18 Jan 2012 12:37:20 +0000 Subject: PCMCIA: sa11x0: nanoengine: convert reset handling to use GPIO subsystem Rather than accessing GPSR and GPCR directly, use the GPIO subsystem instead. Acked-by: Dominik Brodowski Signed-off-by: Russell King --- arch/arm/mach-sa1100/include/mach/nanoengine.h | 4 +-- drivers/pcmcia/sa1100_nanoengine.c | 38 +++++++++++--------------- 2 files changed, 18 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-sa1100/include/mach/nanoengine.h b/arch/arm/mach-sa1100/include/mach/nanoengine.h index ad24c6c3740..5ebd469a31f 100644 --- a/arch/arm/mach-sa1100/include/mach/nanoengine.h +++ b/arch/arm/mach-sa1100/include/mach/nanoengine.h @@ -20,8 +20,8 @@ #define GPIO_PC_READY1 12 /* ready for socket 1 (active high) */ #define GPIO_PC_CD0 13 /* detect for socket 0 (active low) */ #define GPIO_PC_CD1 14 /* detect for socket 1 (active low) */ -#define GPIO_PC_RESET0 GPIO_GPIO(15) /* reset socket 0 */ -#define GPIO_PC_RESET1 GPIO_GPIO(16) /* reset socket 1 */ +#define GPIO_PC_RESET0 15 /* reset socket 0 */ +#define GPIO_PC_RESET1 16 /* reset socket 1 */ #define NANOENGINE_IRQ_GPIO_PCI IRQ_GPIO0 #define NANOENGINE_IRQ_GPIO_PC_READY0 IRQ_GPIO11 diff --git a/drivers/pcmcia/sa1100_nanoengine.c b/drivers/pcmcia/sa1100_nanoengine.c index b19b8161395..cb43e39aef3 100644 --- a/drivers/pcmcia/sa1100_nanoengine.c +++ b/drivers/pcmcia/sa1100_nanoengine.c @@ -19,6 +19,7 @@ */ #include #include +#include #include #include #include @@ -37,19 +38,18 @@ struct nanoengine_pins { unsigned output_pins; unsigned clear_outputs; + int gpio_rst; int gpio_cd; int gpio_rdy; }; static struct nanoengine_pins nano_skts[] = { { - .output_pins = GPIO_PC_RESET0, - .clear_outputs = GPIO_PC_RESET0, + .gpio_rst = GPIO_PC_RESET0, .gpio_cd = GPIO_PC_CD0, .gpio_rdy = GPIO_PC_READY0, }, { - .output_pins = GPIO_PC_RESET1, - .clear_outputs = GPIO_PC_RESET1, + .gpio_rst = GPIO_PC_RESET1, .gpio_cd = GPIO_PC_CD1, .gpio_rdy = GPIO_PC_READY1, } @@ -60,12 +60,15 @@ unsigned num_nano_pcmcia_sockets = ARRAY_SIZE(nano_skts); static int nanoengine_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { unsigned i = skt->nr; + int ret; if (i >= num_nano_pcmcia_sockets) return -ENXIO; - GPDR |= nano_skts[i].output_pins; - GPCR = nano_skts[i].clear_outputs; + ret = gpio_request_one(nano_skts[i].gpio_rst, GPIOF_OUT_INIT_LOW, + i ? "PC RST1" : "PC RST0"); + if (ret) + return ret; skt->stat[SOC_STAT_CD].gpio = nano_skts[i].gpio_cd; skt->stat[SOC_STAT_CD].name = i ? "PC CD1" : "PC CD0"; @@ -75,30 +78,20 @@ static int nanoengine_pcmcia_hw_init(struct soc_pcmcia_socket *skt) return 0; } +static void nanoengine_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) +{ + gpio_free(nano_skts[skt->nr].gpio_rst); +} + static int nanoengine_pcmcia_configure_socket( struct soc_pcmcia_socket *skt, const socket_state_t *state) { - unsigned reset; unsigned i = skt->nr; if (i >= num_nano_pcmcia_sockets) return -ENXIO; - switch (i) { - case 0: - reset = GPIO_PC_RESET0; - break; - case 1: - reset = GPIO_PC_RESET1; - break; - default: - return -ENXIO; - } - - if (state->flags & SS_RESET) - GPSR = reset; - else - GPCR = reset; + gpio_set_value(nano_skts[skt->nr].gpio_rst, !!(state->flags & SS_RESET)); return 0; } @@ -122,6 +115,7 @@ static struct pcmcia_low_level nanoengine_pcmcia_ops = { .owner = THIS_MODULE, .hw_init = nanoengine_pcmcia_hw_init, + .hw_shutdown = nanoengine_pcmcia_hw_shutdown, .configure_socket = nanoengine_pcmcia_configure_socket, .socket_state = nanoengine_pcmcia_socket_state, -- cgit v1.2.3-70-g09d2 From 2dcd5d95ad6b281fca6f2d5e252bbf7e8e20655b Mon Sep 17 00:00:00 2001 From: Sritej Velaga Date: Fri, 3 Feb 2012 11:35:10 +0000 Subject: netxen_nic: fix cdrp race condition Reading CRB registers(if reqd) before releasing the api lock. Signed-off-by: Sritej Velaga Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/netxen/netxen_nic.h | 12 ++ .../net/ethernet/qlogic/netxen/netxen_nic_ctx.c | 149 +++++++++++---------- 2 files changed, 89 insertions(+), 72 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h index a876dffd710..1b09ba17231 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h @@ -686,6 +686,18 @@ struct netxen_recv_context { dma_addr_t phys_addr; }; +struct _cdrp_cmd { + u32 cmd; + u32 arg1; + u32 arg2; + u32 arg3; +}; + +struct netxen_cmd_args { + struct _cdrp_cmd req; + struct _cdrp_cmd rsp; +}; + /* New HW context creation */ #define NX_OS_CRB_RETRY_COUNT 4000 diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c index a925392abd6..d46e8cb394e 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c @@ -48,28 +48,27 @@ netxen_poll_rsp(struct netxen_adapter *adapter) } static u32 -netxen_issue_cmd(struct netxen_adapter *adapter, - u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd) +netxen_issue_cmd(struct netxen_adapter *adapter, struct netxen_cmd_args *cmd) { u32 rsp; u32 signature = 0; u32 rcode = NX_RCODE_SUCCESS; - signature = NX_CDRP_SIGNATURE_MAKE(pci_fn, version); - + signature = NX_CDRP_SIGNATURE_MAKE(adapter->ahw.pci_func, + NXHAL_VERSION); /* Acquire semaphore before accessing CRB */ if (netxen_api_lock(adapter)) return NX_RCODE_TIMEOUT; NXWR32(adapter, NX_SIGN_CRB_OFFSET, signature); - NXWR32(adapter, NX_ARG1_CRB_OFFSET, arg1); + NXWR32(adapter, NX_ARG1_CRB_OFFSET, cmd->req.arg1); - NXWR32(adapter, NX_ARG2_CRB_OFFSET, arg2); + NXWR32(adapter, NX_ARG2_CRB_OFFSET, cmd->req.arg2); - NXWR32(adapter, NX_ARG3_CRB_OFFSET, arg3); + NXWR32(adapter, NX_ARG3_CRB_OFFSET, cmd->req.arg3); - NXWR32(adapter, NX_CDRP_CRB_OFFSET, NX_CDRP_FORM_CMD(cmd)); + NXWR32(adapter, NX_CDRP_CRB_OFFSET, NX_CDRP_FORM_CMD(cmd->req.cmd)); rsp = netxen_poll_rsp(adapter); @@ -83,8 +82,15 @@ netxen_issue_cmd(struct netxen_adapter *adapter, printk(KERN_ERR "%s: failed card response code:0x%x\n", netxen_nic_driver_name, rcode); + } else if (rsp == NX_CDRP_RSP_OK) { + if (cmd->rsp.arg2) + cmd->rsp.arg2 = NXRD32(adapter, NX_ARG2_CRB_OFFSET); + if (cmd->rsp.arg3) + cmd->rsp.arg3 = NXRD32(adapter, NX_ARG3_CRB_OFFSET); } + if (cmd->rsp.arg1) + cmd->rsp.arg1 = NXRD32(adapter, NX_ARG1_CRB_OFFSET); /* Release semaphore */ netxen_api_unlock(adapter); @@ -96,15 +102,16 @@ nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu) { u32 rcode = NX_RCODE_SUCCESS; struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; + struct netxen_cmd_args cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.req.cmd = NX_CDRP_CMD_SET_MTU; + cmd.req.arg1 = recv_ctx->context_id; + cmd.req.arg2 = mtu; + cmd.req.arg3 = 0; if (recv_ctx->state == NX_HOST_CTX_STATE_ACTIVE) - rcode = netxen_issue_cmd(adapter, - adapter->ahw.pci_func, - NXHAL_VERSION, - recv_ctx->context_id, - mtu, - 0, - NX_CDRP_CMD_SET_MTU); + netxen_issue_cmd(adapter, &cmd); if (rcode != NX_RCODE_SUCCESS) return -EIO; @@ -116,15 +123,14 @@ int nx_fw_cmd_set_gbe_port(struct netxen_adapter *adapter, u32 speed, u32 duplex, u32 autoneg) { - - return netxen_issue_cmd(adapter, - adapter->ahw.pci_func, - NXHAL_VERSION, - speed, - duplex, - autoneg, - NX_CDRP_CMD_CONFIG_GBE_PORT); - + struct netxen_cmd_args cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.req.cmd = NX_CDRP_CMD_CONFIG_GBE_PORT; + cmd.req.arg1 = speed; + cmd.req.arg2 = duplex; + cmd.req.arg3 = autoneg; + return netxen_issue_cmd(adapter, &cmd); } static int @@ -139,6 +145,7 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter) nx_cardrsp_sds_ring_t *prsp_sds; struct nx_host_rds_ring *rds_ring; struct nx_host_sds_ring *sds_ring; + struct netxen_cmd_args cmd; dma_addr_t hostrq_phys_addr, cardrsp_phys_addr; u64 phys_addr; @@ -218,13 +225,12 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter) } phys_addr = hostrq_phys_addr; - err = netxen_issue_cmd(adapter, - adapter->ahw.pci_func, - NXHAL_VERSION, - (u32)(phys_addr >> 32), - (u32)(phys_addr & 0xffffffff), - rq_size, - NX_CDRP_CMD_CREATE_RX_CTX); + memset(&cmd, 0, sizeof(cmd)); + cmd.req.arg1 = (u32)(phys_addr >> 32); + cmd.req.arg2 = (u32)(phys_addr & 0xffffffff); + cmd.req.arg3 = rq_size; + cmd.req.cmd = NX_CDRP_CMD_CREATE_RX_CTX; + err = netxen_issue_cmd(adapter, &cmd); if (err) { printk(KERN_WARNING "Failed to create rx ctx in firmware%d\n", err); @@ -273,15 +279,15 @@ static void nx_fw_cmd_destroy_rx_ctx(struct netxen_adapter *adapter) { struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; + struct netxen_cmd_args cmd; - if (netxen_issue_cmd(adapter, - adapter->ahw.pci_func, - NXHAL_VERSION, - recv_ctx->context_id, - NX_DESTROY_CTX_RESET, - 0, - NX_CDRP_CMD_DESTROY_RX_CTX)) { + memset(&cmd, 0, sizeof(cmd)); + cmd.req.arg1 = recv_ctx->context_id; + cmd.req.arg2 = NX_DESTROY_CTX_RESET; + cmd.req.arg3 = 0; + cmd.req.cmd = NX_CDRP_CMD_DESTROY_RX_CTX; + if (netxen_issue_cmd(adapter, &cmd)) { printk(KERN_WARNING "%s: Failed to destroy rx ctx in firmware\n", netxen_nic_driver_name); @@ -302,6 +308,7 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter) dma_addr_t rq_phys_addr, rsp_phys_addr; struct nx_host_tx_ring *tx_ring = adapter->tx_ring; struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; + struct netxen_cmd_args cmd; rq_size = SIZEOF_HOSTRQ_TX(nx_hostrq_tx_ctx_t); rq_addr = pci_alloc_consistent(adapter->pdev, @@ -345,13 +352,12 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter) prq_cds->ring_size = cpu_to_le32(tx_ring->num_desc); phys_addr = rq_phys_addr; - err = netxen_issue_cmd(adapter, - adapter->ahw.pci_func, - NXHAL_VERSION, - (u32)(phys_addr >> 32), - ((u32)phys_addr & 0xffffffff), - rq_size, - NX_CDRP_CMD_CREATE_TX_CTX); + memset(&cmd, 0, sizeof(cmd)); + cmd.req.arg1 = (u32)(phys_addr >> 32); + cmd.req.arg2 = ((u32)phys_addr & 0xffffffff); + cmd.req.arg3 = rq_size; + cmd.req.cmd = NX_CDRP_CMD_CREATE_TX_CTX; + err = netxen_issue_cmd(adapter, &cmd); if (err == NX_RCODE_SUCCESS) { temp = le32_to_cpu(prsp->cds_ring.host_producer_crb); @@ -380,14 +386,14 @@ out_free_rq: static void nx_fw_cmd_destroy_tx_ctx(struct netxen_adapter *adapter) { - if (netxen_issue_cmd(adapter, - adapter->ahw.pci_func, - NXHAL_VERSION, - adapter->tx_context_id, - NX_DESTROY_CTX_RESET, - 0, - NX_CDRP_CMD_DESTROY_TX_CTX)) { - + struct netxen_cmd_args cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.req.arg1 = adapter->tx_context_id; + cmd.req.arg2 = NX_DESTROY_CTX_RESET; + cmd.req.arg3 = 0; + cmd.req.cmd = NX_CDRP_CMD_DESTROY_TX_CTX; + if (netxen_issue_cmd(adapter, &cmd)) { printk(KERN_WARNING "%s: Failed to destroy tx ctx in firmware\n", netxen_nic_driver_name); @@ -398,34 +404,33 @@ int nx_fw_cmd_query_phy(struct netxen_adapter *adapter, u32 reg, u32 *val) { u32 rcode; - - rcode = netxen_issue_cmd(adapter, - adapter->ahw.pci_func, - NXHAL_VERSION, - reg, - 0, - 0, - NX_CDRP_CMD_READ_PHY); - + struct netxen_cmd_args cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.req.arg1 = reg; + cmd.req.arg2 = 0; + cmd.req.arg3 = 0; + cmd.req.cmd = NX_CDRP_CMD_READ_PHY; + cmd.rsp.arg1 = 1; + rcode = netxen_issue_cmd(adapter, &cmd); if (rcode != NX_RCODE_SUCCESS) return -EIO; - return NXRD32(adapter, NX_ARG1_CRB_OFFSET); + return cmd.rsp.arg1; } int nx_fw_cmd_set_phy(struct netxen_adapter *adapter, u32 reg, u32 val) { u32 rcode; - - rcode = netxen_issue_cmd(adapter, - adapter->ahw.pci_func, - NXHAL_VERSION, - reg, - val, - 0, - NX_CDRP_CMD_WRITE_PHY); - + struct netxen_cmd_args cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.req.arg1 = reg; + cmd.req.arg2 = val; + cmd.req.arg3 = 0; + cmd.req.cmd = NX_CDRP_CMD_WRITE_PHY; + rcode = netxen_issue_cmd(adapter, &cmd); if (rcode != NX_RCODE_SUCCESS) return -EIO; -- cgit v1.2.3-70-g09d2 From 83f18a557c6d6cdc03c7821e0b596c8f8b7bdb9f Mon Sep 17 00:00:00 2001 From: Manish chopra Date: Fri, 3 Feb 2012 11:35:11 +0000 Subject: netxen_nic: fw dump support Signed-off-by: Manish Chopra Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/netxen/netxen_nic.h | 421 +++++++++++++- .../net/ethernet/qlogic/netxen/netxen_nic_ctx.c | 143 +++++ .../ethernet/qlogic/netxen/netxen_nic_ethtool.c | 104 ++++ drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c | 629 ++++++++++++++++++++- .../net/ethernet/qlogic/netxen/netxen_nic_init.c | 3 +- .../net/ethernet/qlogic/netxen/netxen_nic_main.c | 102 +++- 6 files changed, 1380 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h index 1b09ba17231..8a35430b2f8 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h @@ -1154,6 +1154,7 @@ typedef struct { #define NETXEN_NIC_LRO_DISABLED 0x00 #define NETXEN_NIC_BRIDGE_ENABLED 0X10 #define NETXEN_NIC_DIAG_ENABLED 0x20 +#define NETXEN_FW_RESET_OWNER 0x40 #define NETXEN_IS_MSI_FAMILY(adapter) \ ((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED)) @@ -1171,6 +1172,419 @@ typedef struct { #define __NX_DEV_UP 1 #define __NX_RESETTING 2 +/* Mini Coredump FW supported version */ +#define NX_MD_SUPPORT_MAJOR 4 +#define NX_MD_SUPPORT_MINOR 0 +#define NX_MD_SUPPORT_SUBVERSION 579 + +#define LSW(x) ((uint16_t)(x)) +#define LSD(x) ((uint32_t)((uint64_t)(x))) +#define MSD(x) ((uint32_t)((((uint64_t)(x)) >> 16) >> 16)) + +/* Mini Coredump mask level */ +#define NX_DUMP_MASK_MIN 0x03 +#define NX_DUMP_MASK_DEF 0x1f +#define NX_DUMP_MASK_MAX 0xff + +/* Mini Coredump CDRP commands */ +#define NX_CDRP_CMD_TEMP_SIZE 0x0000002f +#define NX_CDRP_CMD_GET_TEMP_HDR 0x00000030 + + +#define NX_DUMP_STATE_ARRAY_LEN 16 +#define NX_DUMP_CAP_SIZE_ARRAY_LEN 8 + +/* Mini Coredump sysfs entries flags*/ +#define NX_FORCE_FW_DUMP_KEY 0xdeadfeed +#define NX_ENABLE_FW_DUMP 0xaddfeed +#define NX_DISABLE_FW_DUMP 0xbadfeed +#define NX_FORCE_FW_RESET 0xdeaddead + + +/* Flash read/write address */ +#define NX_FW_DUMP_REG1 0x00130060 +#define NX_FW_DUMP_REG2 0x001e0000 +#define NX_FLASH_SEM2_LK 0x0013C010 +#define NX_FLASH_SEM2_ULK 0x0013C014 +#define NX_FLASH_LOCK_ID 0x001B2100 +#define FLASH_ROM_WINDOW 0x42110030 +#define FLASH_ROM_DATA 0x42150000 + +/* Mini Coredump register read/write routine */ +#define NX_RD_DUMP_REG(addr, bar0, data) do { \ + writel((addr & 0xFFFF0000), (void __iomem *) (bar0 + \ + NX_FW_DUMP_REG1)); \ + readl((void __iomem *) (bar0 + NX_FW_DUMP_REG1)); \ + *data = readl((void __iomem *) (bar0 + NX_FW_DUMP_REG2 + \ + LSW(addr))); \ +} while (0) + +#define NX_WR_DUMP_REG(addr, bar0, data) do { \ + writel((addr & 0xFFFF0000), (void __iomem *) (bar0 + \ + NX_FW_DUMP_REG1)); \ + readl((void __iomem *) (bar0 + NX_FW_DUMP_REG1)); \ + writel(data, (void __iomem *) (bar0 + NX_FW_DUMP_REG2 + LSW(addr)));\ + readl((void __iomem *) (bar0 + NX_FW_DUMP_REG2 + LSW(addr))); \ +} while (0) + + +/* +Entry Type Defines +*/ + +#define RDNOP 0 +#define RDCRB 1 +#define RDMUX 2 +#define QUEUE 3 +#define BOARD 4 +#define RDSRE 5 +#define RDOCM 6 +#define PREGS 7 +#define L1DTG 8 +#define L1ITG 9 +#define CACHE 10 + +#define L1DAT 11 +#define L1INS 12 +#define RDSTK 13 +#define RDCON 14 + +#define L2DTG 21 +#define L2ITG 22 +#define L2DAT 23 +#define L2INS 24 +#define RDOC3 25 + +#define MEMBK 32 + +#define RDROM 71 +#define RDMEM 72 +#define RDMN 73 + +#define INFOR 81 +#define CNTRL 98 + +#define TLHDR 99 +#define RDEND 255 + +#define PRIMQ 103 +#define SQG2Q 104 +#define SQG3Q 105 + +/* +* Opcodes for Control Entries. +* These Flags are bit fields. +*/ +#define NX_DUMP_WCRB 0x01 +#define NX_DUMP_RWCRB 0x02 +#define NX_DUMP_ANDCRB 0x04 +#define NX_DUMP_ORCRB 0x08 +#define NX_DUMP_POLLCRB 0x10 +#define NX_DUMP_RD_SAVE 0x20 +#define NX_DUMP_WRT_SAVED 0x40 +#define NX_DUMP_MOD_SAVE_ST 0x80 + +/* Driver Flags */ +#define NX_DUMP_SKIP 0x80 /* driver skipped this entry */ +#define NX_DUMP_SIZE_ERR 0x40 /*entry size vs capture size mismatch*/ + +#define NX_PCI_READ_32(ADDR) readl((ADDR)) +#define NX_PCI_WRITE_32(DATA, ADDR) writel(DATA, (ADDR)) + + + +struct netxen_minidump { + u32 pos; /* position in the dump buffer */ + u8 fw_supports_md; /* FW supports Mini cordump */ + u8 has_valid_dump; /* indicates valid dump */ + u8 md_capture_mask; /* driver capture mask */ + u8 md_enabled; /* Turn Mini Coredump on/off */ + u32 md_dump_size; /* Total FW Mini Coredump size */ + u32 md_capture_size; /* FW dump capture size */ + u32 md_template_size; /* FW template size */ + u32 md_template_ver; /* FW template version */ + u64 md_timestamp; /* FW Mini dump timestamp */ + void *md_template; /* FW template will be stored */ + void *md_capture_buff; /* FW dump will be stored */ +}; + + + +struct netxen_minidump_template_hdr { + u32 entry_type; + u32 first_entry_offset; + u32 size_of_template; + u32 capture_mask; + u32 num_of_entries; + u32 version; + u32 driver_timestamp; + u32 checksum; + u32 driver_capture_mask; + u32 driver_info_word2; + u32 driver_info_word3; + u32 driver_info_word4; + u32 saved_state_array[NX_DUMP_STATE_ARRAY_LEN]; + u32 capture_size_array[NX_DUMP_CAP_SIZE_ARRAY_LEN]; + u32 rsvd[0]; +}; + +/* Common Entry Header: Common to All Entry Types */ +/* + * Driver Code is for driver to write some info about the entry. + * Currently not used. + */ + +struct netxen_common_entry_hdr { + u32 entry_type; + u32 entry_size; + u32 entry_capture_size; + union { + struct { + u8 entry_capture_mask; + u8 entry_code; + u8 driver_code; + u8 driver_flags; + }; + u32 entry_ctrl_word; + }; +}; + + +/* Generic Entry Including Header */ +struct netxen_minidump_entry { + struct netxen_common_entry_hdr hdr; + u32 entry_data00; + u32 entry_data01; + u32 entry_data02; + u32 entry_data03; + u32 entry_data04; + u32 entry_data05; + u32 entry_data06; + u32 entry_data07; +}; + +/* Read ROM Header */ +struct netxen_minidump_entry_rdrom { + struct netxen_common_entry_hdr h; + union { + struct { + u32 select_addr_reg; + }; + u32 rsvd_0; + }; + union { + struct { + u8 addr_stride; + u8 addr_cnt; + u16 data_size; + }; + u32 rsvd_1; + }; + union { + struct { + u32 op_count; + }; + u32 rsvd_2; + }; + union { + struct { + u32 read_addr_reg; + }; + u32 rsvd_3; + }; + union { + struct { + u32 write_mask; + }; + u32 rsvd_4; + }; + union { + struct { + u32 read_mask; + }; + u32 rsvd_5; + }; + u32 read_addr; + u32 read_data_size; +}; + + +/* Read CRB and Control Entry Header */ +struct netxen_minidump_entry_crb { + struct netxen_common_entry_hdr h; + u32 addr; + union { + struct { + u8 addr_stride; + u8 state_index_a; + u16 poll_timeout; + }; + u32 addr_cntrl; + }; + u32 data_size; + u32 op_count; + union { + struct { + u8 opcode; + u8 state_index_v; + u8 shl; + u8 shr; + }; + u32 control_value; + }; + u32 value_1; + u32 value_2; + u32 value_3; +}; + +/* Read Memory and MN Header */ +struct netxen_minidump_entry_rdmem { + struct netxen_common_entry_hdr h; + union { + struct { + u32 select_addr_reg; + }; + u32 rsvd_0; + }; + union { + struct { + u8 addr_stride; + u8 addr_cnt; + u16 data_size; + }; + u32 rsvd_1; + }; + union { + struct { + u32 op_count; + }; + u32 rsvd_2; + }; + union { + struct { + u32 read_addr_reg; + }; + u32 rsvd_3; + }; + union { + struct { + u32 cntrl_addr_reg; + }; + u32 rsvd_4; + }; + union { + struct { + u8 wr_byte0; + u8 wr_byte1; + u8 poll_mask; + u8 poll_cnt; + }; + u32 rsvd_5; + }; + u32 read_addr; + u32 read_data_size; +}; + +/* Read Cache L1 and L2 Header */ +struct netxen_minidump_entry_cache { + struct netxen_common_entry_hdr h; + u32 tag_reg_addr; + union { + struct { + u16 tag_value_stride; + u16 init_tag_value; + }; + u32 select_addr_cntrl; + }; + u32 data_size; + u32 op_count; + u32 control_addr; + union { + struct { + u16 write_value; + u8 poll_mask; + u8 poll_wait; + }; + u32 control_value; + }; + u32 read_addr; + union { + struct { + u8 read_addr_stride; + u8 read_addr_cnt; + u16 rsvd_1; + }; + u32 read_addr_cntrl; + }; +}; + +/* Read OCM Header */ +struct netxen_minidump_entry_rdocm { + struct netxen_common_entry_hdr h; + u32 rsvd_0; + union { + struct { + u32 rsvd_1; + }; + u32 select_addr_cntrl; + }; + u32 data_size; + u32 op_count; + u32 rsvd_2; + u32 rsvd_3; + u32 read_addr; + union { + struct { + u32 read_addr_stride; + }; + u32 read_addr_cntrl; + }; +}; + +/* Read MUX Header */ +struct netxen_minidump_entry_mux { + struct netxen_common_entry_hdr h; + u32 select_addr; + union { + struct { + u32 rsvd_0; + }; + u32 select_addr_cntrl; + }; + u32 data_size; + u32 op_count; + u32 select_value; + u32 select_value_stride; + u32 read_addr; + u32 rsvd_1; +}; + +/* Read Queue Header */ +struct netxen_minidump_entry_queue { + struct netxen_common_entry_hdr h; + u32 select_addr; + union { + struct { + u16 queue_id_stride; + u16 rsvd_0; + }; + u32 select_addr_cntrl; + }; + u32 data_size; + u32 op_count; + u32 rsvd_1; + u32 rsvd_2; + u32 read_addr; + union { + struct { + u8 read_addr_stride; + u8 read_addr_cnt; + u16 rsvd_3; + }; + u32 read_addr_cntrl; + }; +}; + struct netxen_dummy_dma { void *addr; dma_addr_t phys_addr; @@ -1275,6 +1689,8 @@ struct netxen_adapter { __le32 file_prd_off; /*File fw product offset*/ u32 fw_version; const struct firmware *fw; + struct netxen_minidump mdump; /* mdump ptr */ + int fw_mdump_rdy; /* for mdump ready */ }; int nx_fw_cmd_query_phy(struct netxen_adapter *adapter, u32 reg, u32 *val); @@ -1377,13 +1793,16 @@ int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu); int netxen_config_hw_lro(struct netxen_adapter *adapter, int enable); int netxen_config_bridged_mode(struct netxen_adapter *adapter, int enable); int netxen_send_lro_cleanup(struct netxen_adapter *adapter); - +int netxen_setup_minidump(struct netxen_adapter *adapter); +void netxen_dump_fw(struct netxen_adapter *adapter); void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, struct nx_host_tx_ring *tx_ring); /* Functions from netxen_nic_main.c */ int netxen_nic_reset_context(struct netxen_adapter *); +int nx_dev_request_reset(struct netxen_adapter *adapter); + /* * NetXen Board information */ diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c index d46e8cb394e..8f89c05e0c7 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c @@ -83,6 +83,7 @@ netxen_issue_cmd(struct netxen_adapter *adapter, struct netxen_cmd_args *cmd) printk(KERN_ERR "%s: failed card response code:0x%x\n", netxen_nic_driver_name, rcode); } else if (rsp == NX_CDRP_RSP_OK) { + cmd->rsp.cmd = NX_RCODE_SUCCESS; if (cmd->rsp.arg2) cmd->rsp.arg2 = NXRD32(adapter, NX_ARG2_CRB_OFFSET); if (cmd->rsp.arg3) @@ -97,6 +98,148 @@ netxen_issue_cmd(struct netxen_adapter *adapter, struct netxen_cmd_args *cmd) return rcode; } +static int +netxen_get_minidump_template_size(struct netxen_adapter *adapter) +{ + struct netxen_cmd_args cmd; + memset(&cmd, 0, sizeof(cmd)); + cmd.req.cmd = NX_CDRP_CMD_TEMP_SIZE; + memset(&cmd.rsp, 1, sizeof(struct _cdrp_cmd)); + netxen_issue_cmd(adapter, &cmd); + if (cmd.rsp.cmd != NX_RCODE_SUCCESS) { + dev_info(&adapter->pdev->dev, + "Can't get template size %d\n", cmd.rsp.cmd); + return -EIO; + } + adapter->mdump.md_template_size = cmd.rsp.arg2; + adapter->mdump.md_template_ver = cmd.rsp.arg3; + return 0; +} + +static int +netxen_get_minidump_template(struct netxen_adapter *adapter) +{ + dma_addr_t md_template_addr; + void *addr; + u32 size; + struct netxen_cmd_args cmd; + size = adapter->mdump.md_template_size; + + if (size == 0) { + dev_err(&adapter->pdev->dev, "Can not capture Minidump " + "template. Invalid template size.\n"); + return NX_RCODE_INVALID_ARGS; + } + + addr = pci_alloc_consistent(adapter->pdev, size, &md_template_addr); + + if (!addr) { + dev_err(&adapter->pdev->dev, "Unable to allocate dmable memory for template.\n"); + return -ENOMEM; + } + + memset(addr, 0, size); + memset(&cmd, 0, sizeof(cmd)); + memset(&cmd.rsp, 1, sizeof(struct _cdrp_cmd)); + cmd.req.cmd = NX_CDRP_CMD_GET_TEMP_HDR; + cmd.req.arg1 = LSD(md_template_addr); + cmd.req.arg2 = MSD(md_template_addr); + cmd.req.arg3 |= size; + netxen_issue_cmd(adapter, &cmd); + + if ((cmd.rsp.cmd == NX_RCODE_SUCCESS) && (size == cmd.rsp.arg2)) { + memcpy(adapter->mdump.md_template, addr, size); + } else { + dev_err(&adapter->pdev->dev, "Failed to get minidump template, " + "err_code : %d, requested_size : %d, actual_size : %d\n ", + cmd.rsp.cmd, size, cmd.rsp.arg2); + } + pci_free_consistent(adapter->pdev, size, addr, md_template_addr); + return 0; +} + +static u32 +netxen_check_template_checksum(struct netxen_adapter *adapter) +{ + u64 sum = 0 ; + u32 *buff = adapter->mdump.md_template; + int count = adapter->mdump.md_template_size/sizeof(uint32_t) ; + + while (count-- > 0) + sum += *buff++ ; + while (sum >> 32) + sum = (sum & 0xFFFFFFFF) + (sum >> 32) ; + + return ~sum; +} + +int +netxen_setup_minidump(struct netxen_adapter *adapter) +{ + int err = 0, i; + u32 *template, *tmp_buf; + struct netxen_minidump_template_hdr *hdr; + err = netxen_get_minidump_template_size(adapter); + if (err) { + adapter->mdump.fw_supports_md = 0; + if ((err == NX_RCODE_CMD_INVALID) || + (err == NX_RCODE_CMD_NOT_IMPL)) { + dev_info(&adapter->pdev->dev, + "Flashed firmware version does not support minidump, " + "minimum version required is [ %u.%u.%u ].\n ", + NX_MD_SUPPORT_MAJOR, NX_MD_SUPPORT_MINOR, + NX_MD_SUPPORT_SUBVERSION); + } + return err; + } + + if (!adapter->mdump.md_template_size) { + dev_err(&adapter->pdev->dev, "Error : Invalid template size " + ",should be non-zero.\n"); + return -EIO; + } + adapter->mdump.md_template = + kmalloc(adapter->mdump.md_template_size, GFP_KERNEL); + + if (!adapter->mdump.md_template) { + dev_err(&adapter->pdev->dev, "Unable to allocate memory " + "for minidump template.\n"); + return -ENOMEM; + } + + err = netxen_get_minidump_template(adapter); + if (err) { + if (err == NX_RCODE_CMD_NOT_IMPL) + adapter->mdump.fw_supports_md = 0; + goto free_template; + } + + if (netxen_check_template_checksum(adapter)) { + dev_err(&adapter->pdev->dev, "Minidump template checksum Error\n"); + err = -EIO; + goto free_template; + } + + adapter->mdump.md_capture_mask = NX_DUMP_MASK_DEF; + tmp_buf = (u32 *) adapter->mdump.md_template; + template = (u32 *) adapter->mdump.md_template; + for (i = 0; i < adapter->mdump.md_template_size/sizeof(u32); i++) + *template++ = __le32_to_cpu(*tmp_buf++); + hdr = (struct netxen_minidump_template_hdr *) + adapter->mdump.md_template; + adapter->mdump.md_capture_buff = NULL; + adapter->mdump.fw_supports_md = 1; + adapter->mdump.md_enabled = 1; + + return err; + +free_template: + kfree(adapter->mdump.md_template); + adapter->mdump.md_template = NULL; + return err; +} + + int nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu) { diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c index 8a371985319..3e73d35ccea 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c @@ -812,6 +812,107 @@ static int netxen_get_intr_coalesce(struct net_device *netdev, return 0; } +static int +netxen_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump) +{ + struct netxen_adapter *adapter = netdev_priv(netdev); + struct netxen_minidump *mdump = &adapter->mdump; + if (adapter->fw_mdump_rdy) + dump->len = mdump->md_dump_size; + else + dump->len = 0; + dump->flag = mdump->md_capture_mask; + dump->version = adapter->fw_version; + return 0; +} + +static int +netxen_set_dump(struct net_device *netdev, struct ethtool_dump *val) +{ + int ret = 0; + struct netxen_adapter *adapter = netdev_priv(netdev); + struct netxen_minidump *mdump = &adapter->mdump; + + switch (val->flag) { + case NX_FORCE_FW_DUMP_KEY: + if (!mdump->md_enabled) + mdump->md_enabled = 1; + if (adapter->fw_mdump_rdy) { + netdev_info(netdev, "Previous dump not cleared, not forcing dump\n"); + return ret; + } + netdev_info(netdev, "Forcing a fw dump\n"); + nx_dev_request_reset(adapter); + break; + case NX_DISABLE_FW_DUMP: + if (mdump->md_enabled) { + netdev_info(netdev, "Disabling FW Dump\n"); + mdump->md_enabled = 0; + } + break; + case NX_ENABLE_FW_DUMP: + if (!mdump->md_enabled) { + netdev_info(netdev, "Enabling FW dump\n"); + mdump->md_enabled = 1; + } + break; + case NX_FORCE_FW_RESET: + netdev_info(netdev, "Forcing FW reset\n"); + nx_dev_request_reset(adapter); + adapter->flags &= ~NETXEN_FW_RESET_OWNER; + break; + default: + if (val->flag <= NX_DUMP_MASK_MAX && + val->flag >= NX_DUMP_MASK_MIN) { + mdump->md_capture_mask = val->flag & 0xff; + netdev_info(netdev, "Driver mask changed to: 0x%x\n", + mdump->md_capture_mask); + break; + } + netdev_info(netdev, + "Invalid dump level: 0x%x\n", val->flag); + return -EINVAL; + } + + return ret; +} + +static int +netxen_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump, + void *buffer) +{ + int i, copy_sz; + u32 *hdr_ptr, *data; + struct netxen_adapter *adapter = netdev_priv(netdev); + struct netxen_minidump *mdump = &adapter->mdump; + + + if (!adapter->fw_mdump_rdy) { + netdev_info(netdev, "Dump not available\n"); + return -EINVAL; + } + /* Copy template header first */ + copy_sz = mdump->md_template_size; + hdr_ptr = (u32 *) mdump->md_template; + data = buffer; + for (i = 0; i < copy_sz/sizeof(u32); i++) + *data++ = cpu_to_le32(*hdr_ptr++); + + /* Copy captured dump data */ + memcpy(buffer + copy_sz, + mdump->md_capture_buff + mdump->md_template_size, + mdump->md_capture_size); + dump->len = copy_sz + mdump->md_capture_size; + dump->flag = mdump->md_capture_mask; + + /* Free dump area once data has been captured */ + vfree(mdump->md_capture_buff); + mdump->md_capture_buff = NULL; + adapter->fw_mdump_rdy = 0; + netdev_info(netdev, "extracted the fw dump Successfully\n"); + return 0; +} + const struct ethtool_ops netxen_nic_ethtool_ops = { .get_settings = netxen_nic_get_settings, .set_settings = netxen_nic_set_settings, @@ -833,4 +934,7 @@ const struct ethtool_ops netxen_nic_ethtool_ops = { .get_sset_count = netxen_get_sset_count, .get_coalesce = netxen_get_intr_coalesce, .set_coalesce = netxen_set_intr_coalesce, + .get_dump_flag = netxen_get_dump_flag, + .get_dump_data = netxen_get_dump_data, + .set_dump = netxen_set_dump, }; diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c index 3f89e57cae5..0a812285102 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c @@ -46,7 +46,6 @@ static void netxen_nic_io_write_128M(struct netxen_adapter *adapter, void __iomem *addr, u32 data); static u32 netxen_nic_io_read_128M(struct netxen_adapter *adapter, void __iomem *addr); - #ifndef readq static inline u64 readq(void __iomem *addr) { @@ -1974,3 +1973,631 @@ netxen_nic_wol_supported(struct netxen_adapter *adapter) return 0; } + +static u32 netxen_md_cntrl(struct netxen_adapter *adapter, + struct netxen_minidump_template_hdr *template_hdr, + struct netxen_minidump_entry_crb *crtEntry) +{ + int loop_cnt, i, rv = 0, timeout_flag; + u32 op_count, stride; + u32 opcode, read_value, addr; + unsigned long timeout, timeout_jiffies; + addr = crtEntry->addr; + op_count = crtEntry->op_count; + stride = crtEntry->addr_stride; + + for (loop_cnt = 0; loop_cnt < op_count; loop_cnt++) { + for (i = 0; i < sizeof(crtEntry->opcode) * 8; i++) { + opcode = (crtEntry->opcode & (0x1 << i)); + if (opcode) { + switch (opcode) { + case NX_DUMP_WCRB: + NX_WR_DUMP_REG(addr, + adapter->ahw.pci_base0, + crtEntry->value_1); + break; + case NX_DUMP_RWCRB: + NX_RD_DUMP_REG(addr, + adapter->ahw.pci_base0, + &read_value); + NX_WR_DUMP_REG(addr, + adapter->ahw.pci_base0, + read_value); + break; + case NX_DUMP_ANDCRB: + NX_RD_DUMP_REG(addr, + adapter->ahw.pci_base0, + &read_value); + read_value &= crtEntry->value_2; + NX_WR_DUMP_REG(addr, + adapter->ahw.pci_base0, + read_value); + break; + case NX_DUMP_ORCRB: + NX_RD_DUMP_REG(addr, + adapter->ahw.pci_base0, + &read_value); + read_value |= crtEntry->value_3; + NX_WR_DUMP_REG(addr, + adapter->ahw.pci_base0, + read_value); + break; + case NX_DUMP_POLLCRB: + timeout = crtEntry->poll_timeout; + NX_RD_DUMP_REG(addr, + adapter->ahw.pci_base0, + &read_value); + timeout_jiffies = + msecs_to_jiffies(timeout) + jiffies; + for (timeout_flag = 0; + !timeout_flag + && ((read_value & crtEntry->value_2) + != crtEntry->value_1);) { + if (time_after(jiffies, + timeout_jiffies)) + timeout_flag = 1; + NX_RD_DUMP_REG(addr, + adapter->ahw.pci_base0, + &read_value); + } + + if (timeout_flag) { + dev_err(&adapter->pdev->dev, "%s : " + "Timeout in poll_crb control operation.\n" + , __func__); + return -1; + } + break; + case NX_DUMP_RD_SAVE: + /* Decide which address to use */ + if (crtEntry->state_index_a) + addr = + template_hdr->saved_state_array + [crtEntry->state_index_a]; + NX_RD_DUMP_REG(addr, + adapter->ahw.pci_base0, + &read_value); + template_hdr->saved_state_array + [crtEntry->state_index_v] + = read_value; + break; + case NX_DUMP_WRT_SAVED: + /* Decide which value to use */ + if (crtEntry->state_index_v) + read_value = + template_hdr->saved_state_array + [crtEntry->state_index_v]; + else + read_value = crtEntry->value_1; + + /* Decide which address to use */ + if (crtEntry->state_index_a) + addr = + template_hdr->saved_state_array + [crtEntry->state_index_a]; + + NX_WR_DUMP_REG(addr, + adapter->ahw.pci_base0, + read_value); + break; + case NX_DUMP_MOD_SAVE_ST: + read_value = + template_hdr->saved_state_array + [crtEntry->state_index_v]; + read_value <<= crtEntry->shl; + read_value >>= crtEntry->shr; + if (crtEntry->value_2) + read_value &= + crtEntry->value_2; + read_value |= crtEntry->value_3; + read_value += crtEntry->value_1; + /* Write value back to state area.*/ + template_hdr->saved_state_array + [crtEntry->state_index_v] + = read_value; + break; + default: + rv = 1; + break; + } + } + } + addr = addr + stride; + } + return rv; +} + +/* Read memory or MN */ +static u32 +netxen_md_rdmem(struct netxen_adapter *adapter, + struct netxen_minidump_entry_rdmem + *memEntry, u64 *data_buff) +{ + u64 addr, value = 0; + int i = 0, loop_cnt; + + addr = (u64)memEntry->read_addr; + loop_cnt = memEntry->read_data_size; /* This is size in bytes */ + loop_cnt /= sizeof(value); + + for (i = 0; i < loop_cnt; i++) { + if (netxen_nic_pci_mem_read_2M(adapter, addr, &value)) + goto out; + *data_buff++ = value; + addr += sizeof(value); + } +out: + return i * sizeof(value); +} + +/* Read CRB operation */ +static u32 netxen_md_rd_crb(struct netxen_adapter *adapter, + struct netxen_minidump_entry_crb + *crbEntry, u32 *data_buff) +{ + int loop_cnt; + u32 op_count, addr, stride, value; + + addr = crbEntry->addr; + op_count = crbEntry->op_count; + stride = crbEntry->addr_stride; + + for (loop_cnt = 0; loop_cnt < op_count; loop_cnt++) { + NX_RD_DUMP_REG(addr, adapter->ahw.pci_base0, &value); + *data_buff++ = addr; + *data_buff++ = value; + addr = addr + stride; + } + return loop_cnt * (2 * sizeof(u32)); +} + +/* Read ROM */ +static u32 +netxen_md_rdrom(struct netxen_adapter *adapter, + struct netxen_minidump_entry_rdrom + *romEntry, u32 *data_buff) +{ + int i, count = 0; + u32 size, lck_val; + u32 val; + u32 fl_addr, waddr, raddr; + fl_addr = romEntry->read_addr; + size = romEntry->read_data_size/4; +lock_try: + lck_val = readl((void __iomem *)(adapter->ahw.pci_base0 + + NX_FLASH_SEM2_LK)); + if (!lck_val && count < MAX_CTL_CHECK) { + msleep(20); + count++; + goto lock_try; + } + writel(adapter->ahw.pci_func, (void __iomem *)(adapter->ahw.pci_base0 + + NX_FLASH_LOCK_ID)); + for (i = 0; i < size; i++) { + waddr = fl_addr & 0xFFFF0000; + NX_WR_DUMP_REG(FLASH_ROM_WINDOW, adapter->ahw.pci_base0, waddr); + raddr = FLASH_ROM_DATA + (fl_addr & 0x0000FFFF); + NX_RD_DUMP_REG(raddr, adapter->ahw.pci_base0, &val); + *data_buff++ = cpu_to_le32(val); + fl_addr += sizeof(val); + } + readl((void __iomem *)(adapter->ahw.pci_base0 + NX_FLASH_SEM2_ULK)); + return romEntry->read_data_size; +} + +/* Handle L2 Cache */ +static u32 +netxen_md_L2Cache(struct netxen_adapter *adapter, + struct netxen_minidump_entry_cache + *cacheEntry, u32 *data_buff) +{ + int loop_cnt, i, k, timeout_flag = 0; + u32 addr, read_addr, read_value, cntrl_addr, tag_reg_addr; + u32 tag_value, read_cnt; + u8 cntl_value_w, cntl_value_r; + unsigned long timeout, timeout_jiffies; + + loop_cnt = cacheEntry->op_count; + read_addr = cacheEntry->read_addr; + cntrl_addr = cacheEntry->control_addr; + cntl_value_w = (u32) cacheEntry->write_value; + tag_reg_addr = cacheEntry->tag_reg_addr; + tag_value = cacheEntry->init_tag_value; + read_cnt = cacheEntry->read_addr_cnt; + + for (i = 0; i < loop_cnt; i++) { + NX_WR_DUMP_REG(tag_reg_addr, adapter->ahw.pci_base0, tag_value); + if (cntl_value_w) + NX_WR_DUMP_REG(cntrl_addr, adapter->ahw.pci_base0, + (u32)cntl_value_w); + if (cacheEntry->poll_mask) { + timeout = cacheEntry->poll_wait; + NX_RD_DUMP_REG(cntrl_addr, adapter->ahw.pci_base0, + &cntl_value_r); + timeout_jiffies = msecs_to_jiffies(timeout) + jiffies; + for (timeout_flag = 0; !timeout_flag && + ((cntl_value_r & cacheEntry->poll_mask) != 0);) { + if (time_after(jiffies, timeout_jiffies)) + timeout_flag = 1; + NX_RD_DUMP_REG(cntrl_addr, + adapter->ahw.pci_base0, + &cntl_value_r); + } + if (timeout_flag) { + dev_err(&adapter->pdev->dev, + "Timeout in processing L2 Tag poll.\n"); + return -1; + } + } + addr = read_addr; + for (k = 0; k < read_cnt; k++) { + NX_RD_DUMP_REG(addr, adapter->ahw.pci_base0, + &read_value); + *data_buff++ = read_value; + addr += cacheEntry->read_addr_stride; + } + tag_value += cacheEntry->tag_value_stride; + } + return read_cnt * loop_cnt * sizeof(read_value); +} + + +/* Handle L1 Cache */ +static u32 netxen_md_L1Cache(struct netxen_adapter *adapter, + struct netxen_minidump_entry_cache + *cacheEntry, u32 *data_buff) +{ + int i, k, loop_cnt; + u32 addr, read_addr, read_value, cntrl_addr, tag_reg_addr; + u32 tag_value, read_cnt; + u8 cntl_value_w; + + loop_cnt = cacheEntry->op_count; + read_addr = cacheEntry->read_addr; + cntrl_addr = cacheEntry->control_addr; + cntl_value_w = (u32) cacheEntry->write_value; + tag_reg_addr = cacheEntry->tag_reg_addr; + tag_value = cacheEntry->init_tag_value; + read_cnt = cacheEntry->read_addr_cnt; + + for (i = 0; i < loop_cnt; i++) { + NX_WR_DUMP_REG(tag_reg_addr, adapter->ahw.pci_base0, tag_value); + NX_WR_DUMP_REG(cntrl_addr, adapter->ahw.pci_base0, + (u32) cntl_value_w); + addr = read_addr; + for (k = 0; k < read_cnt; k++) { + NX_RD_DUMP_REG(addr, + adapter->ahw.pci_base0, + &read_value); + *data_buff++ = read_value; + addr += cacheEntry->read_addr_stride; + } + tag_value += cacheEntry->tag_value_stride; + } + return read_cnt * loop_cnt * sizeof(read_value); +} + +/* Reading OCM memory */ +static u32 +netxen_md_rdocm(struct netxen_adapter *adapter, + struct netxen_minidump_entry_rdocm + *ocmEntry, u32 *data_buff) +{ + int i, loop_cnt; + u32 value; + void __iomem *addr; + addr = (ocmEntry->read_addr + adapter->ahw.pci_base0); + loop_cnt = ocmEntry->op_count; + + for (i = 0; i < loop_cnt; i++) { + value = readl(addr); + *data_buff++ = value; + addr += ocmEntry->read_addr_stride; + } + return i * sizeof(u32); +} + +/* Read MUX data */ +static u32 +netxen_md_rdmux(struct netxen_adapter *adapter, struct netxen_minidump_entry_mux + *muxEntry, u32 *data_buff) +{ + int loop_cnt = 0; + u32 read_addr, read_value, select_addr, sel_value; + + read_addr = muxEntry->read_addr; + sel_value = muxEntry->select_value; + select_addr = muxEntry->select_addr; + + for (loop_cnt = 0; loop_cnt < muxEntry->op_count; loop_cnt++) { + NX_WR_DUMP_REG(select_addr, adapter->ahw.pci_base0, sel_value); + NX_RD_DUMP_REG(read_addr, adapter->ahw.pci_base0, &read_value); + *data_buff++ = sel_value; + *data_buff++ = read_value; + sel_value += muxEntry->select_value_stride; + } + return loop_cnt * (2 * sizeof(u32)); +} + +/* Handling Queue State Reads */ +static u32 +netxen_md_rdqueue(struct netxen_adapter *adapter, + struct netxen_minidump_entry_queue + *queueEntry, u32 *data_buff) +{ + int loop_cnt, k; + u32 queue_id, read_addr, read_value, read_stride, select_addr, read_cnt; + + read_cnt = queueEntry->read_addr_cnt; + read_stride = queueEntry->read_addr_stride; + select_addr = queueEntry->select_addr; + + for (loop_cnt = 0, queue_id = 0; loop_cnt < queueEntry->op_count; + loop_cnt++) { + NX_WR_DUMP_REG(select_addr, adapter->ahw.pci_base0, queue_id); + read_addr = queueEntry->read_addr; + for (k = 0; k < read_cnt; k--) { + NX_RD_DUMP_REG(read_addr, adapter->ahw.pci_base0, + &read_value); + *data_buff++ = read_value; + read_addr += read_stride; + } + queue_id += queueEntry->queue_id_stride; + } + return loop_cnt * (read_cnt * sizeof(read_value)); +} + + +/* +* We catch an error where driver does not read +* as much data as we expect from the entry. +*/ + +static int netxen_md_entry_err_chk(struct netxen_adapter *adapter, + struct netxen_minidump_entry *entry, u32 esize) +{ + if (esize < 0) { + entry->hdr.driver_flags |= NX_DUMP_SKIP; + return esize; + } + if (esize != entry->hdr.entry_capture_size) { + entry->hdr.entry_capture_size = esize; + entry->hdr.driver_flags |= NX_DUMP_SIZE_ERR; + dev_info(&adapter->pdev->dev, + "Invalidate dump, Type:%d\tMask:%d\tSize:%dCap_size:%d\n", + entry->hdr.entry_type, entry->hdr.entry_capture_mask, + esize, entry->hdr.entry_capture_size); + dev_info(&adapter->pdev->dev, "Aborting further dump capture\n"); + } + return 0; +} + +static int netxen_parse_md_template(struct netxen_adapter *adapter) +{ + int num_of_entries, buff_level, e_cnt, esize; + int end_cnt = 0, rv = 0, sane_start = 0, sane_end = 0; + char *dbuff; + void *template_buff = adapter->mdump.md_template; + char *dump_buff = adapter->mdump.md_capture_buff; + int capture_mask = adapter->mdump.md_capture_mask; + struct netxen_minidump_template_hdr *template_hdr; + struct netxen_minidump_entry *entry; + + if ((capture_mask & 0x3) != 0x3) { + dev_err(&adapter->pdev->dev, "Capture mask %02x below minimum needed " + "for valid firmware dump\n", capture_mask); + return -EINVAL; + } + template_hdr = (struct netxen_minidump_template_hdr *) template_buff; + num_of_entries = template_hdr->num_of_entries; + entry = (struct netxen_minidump_entry *) ((char *) template_buff + + template_hdr->first_entry_offset); + memcpy(dump_buff, template_buff, adapter->mdump.md_template_size); + dump_buff = dump_buff + adapter->mdump.md_template_size; + + if (template_hdr->entry_type == TLHDR) + sane_start = 1; + + for (e_cnt = 0, buff_level = 0; e_cnt < num_of_entries; e_cnt++) { + if (!(entry->hdr.entry_capture_mask & capture_mask)) { + entry->hdr.driver_flags |= NX_DUMP_SKIP; + entry = (struct netxen_minidump_entry *) + ((char *) entry + entry->hdr.entry_size); + continue; + } + switch (entry->hdr.entry_type) { + case RDNOP: + entry->hdr.driver_flags |= NX_DUMP_SKIP; + break; + case RDEND: + entry->hdr.driver_flags |= NX_DUMP_SKIP; + if (!sane_end) + end_cnt = e_cnt; + sane_end += 1; + break; + case CNTRL: + rv = netxen_md_cntrl(adapter, + template_hdr, (void *)entry); + if (rv) + entry->hdr.driver_flags |= NX_DUMP_SKIP; + break; + case RDCRB: + dbuff = dump_buff + buff_level; + esize = netxen_md_rd_crb(adapter, + (void *) entry, (void *) dbuff); + rv = netxen_md_entry_err_chk + (adapter, entry, esize); + if (rv < 0) + break; + buff_level += esize; + break; + case RDMN: + case RDMEM: + dbuff = dump_buff + buff_level; + esize = netxen_md_rdmem(adapter, + (void *) entry, (void *) dbuff); + rv = netxen_md_entry_err_chk + (adapter, entry, esize); + if (rv < 0) + break; + buff_level += esize; + break; + case BOARD: + case RDROM: + dbuff = dump_buff + buff_level; + esize = netxen_md_rdrom(adapter, + (void *) entry, (void *) dbuff); + rv = netxen_md_entry_err_chk + (adapter, entry, esize); + if (rv < 0) + break; + buff_level += esize; + break; + case L2ITG: + case L2DTG: + case L2DAT: + case L2INS: + dbuff = dump_buff + buff_level; + esize = netxen_md_L2Cache(adapter, + (void *) entry, (void *) dbuff); + rv = netxen_md_entry_err_chk + (adapter, entry, esize); + if (rv < 0) + break; + buff_level += esize; + break; + case L1DAT: + case L1INS: + dbuff = dump_buff + buff_level; + esize = netxen_md_L1Cache(adapter, + (void *) entry, (void *) dbuff); + rv = netxen_md_entry_err_chk + (adapter, entry, esize); + if (rv < 0) + break; + buff_level += esize; + break; + case RDOCM: + dbuff = dump_buff + buff_level; + esize = netxen_md_rdocm(adapter, + (void *) entry, (void *) dbuff); + rv = netxen_md_entry_err_chk + (adapter, entry, esize); + if (rv < 0) + break; + buff_level += esize; + break; + case RDMUX: + dbuff = dump_buff + buff_level; + esize = netxen_md_rdmux(adapter, + (void *) entry, (void *) dbuff); + rv = netxen_md_entry_err_chk + (adapter, entry, esize); + if (rv < 0) + break; + buff_level += esize; + break; + case QUEUE: + dbuff = dump_buff + buff_level; + esize = netxen_md_rdqueue(adapter, + (void *) entry, (void *) dbuff); + rv = netxen_md_entry_err_chk + (adapter, entry, esize); + if (rv < 0) + break; + buff_level += esize; + break; + default: + entry->hdr.driver_flags |= NX_DUMP_SKIP; + break; + } + /* Next entry in the template */ + entry = (struct netxen_minidump_entry *) + ((char *) entry + entry->hdr.entry_size); + } + if (!sane_start || sane_end > 1) { + dev_err(&adapter->pdev->dev, + "Firmware minidump template configuration error.\n"); + } + return 0; +} + +static int +netxen_collect_minidump(struct netxen_adapter *adapter) +{ + int ret = 0; + struct netxen_minidump_template_hdr *hdr; + struct timespec val; + hdr = (struct netxen_minidump_template_hdr *) + adapter->mdump.md_template; + hdr->driver_capture_mask = adapter->mdump.md_capture_mask; + jiffies_to_timespec(jiffies, &val); + hdr->driver_timestamp = (u32) val.tv_sec; + hdr->driver_info_word2 = adapter->fw_version; + hdr->driver_info_word3 = NXRD32(adapter, CRB_DRIVER_VERSION); + ret = netxen_parse_md_template(adapter); + if (ret) + return ret; + + return ret; +} + + +void +netxen_dump_fw(struct netxen_adapter *adapter) +{ + struct netxen_minidump_template_hdr *hdr; + int i, k, data_size = 0; + u32 capture_mask; + hdr = (struct netxen_minidump_template_hdr *) + adapter->mdump.md_template; + capture_mask = adapter->mdump.md_capture_mask; + + for (i = 0x2, k = 1; (i & NX_DUMP_MASK_MAX); i <<= 1, k++) { + if (i & capture_mask) + data_size += hdr->capture_size_array[k]; + } + if (!data_size) { + dev_err(&adapter->pdev->dev, + "Invalid cap sizes for capture_mask=0x%x\n", + adapter->mdump.md_capture_mask); + return; + } + adapter->mdump.md_capture_size = data_size; + adapter->mdump.md_dump_size = adapter->mdump.md_template_size + + adapter->mdump.md_capture_size; + if (!adapter->mdump.md_capture_buff) { + adapter->mdump.md_capture_buff = + vmalloc(adapter->mdump.md_dump_size); + if (!adapter->mdump.md_capture_buff) { + dev_info(&adapter->pdev->dev, + "Unable to allocate memory for minidump " + "capture_buffer(%d bytes).\n", + adapter->mdump.md_dump_size); + return; + } + memset(adapter->mdump.md_capture_buff, 0, + adapter->mdump.md_dump_size); + if (netxen_collect_minidump(adapter)) { + adapter->mdump.has_valid_dump = 0; + adapter->mdump.md_dump_size = 0; + vfree(adapter->mdump.md_capture_buff); + adapter->mdump.md_capture_buff = NULL; + dev_err(&adapter->pdev->dev, + "Error in collecting firmware minidump.\n"); + } else { + adapter->mdump.md_timestamp = jiffies; + adapter->mdump.has_valid_dump = 1; + adapter->fw_mdump_rdy = 1; + dev_info(&adapter->pdev->dev, "%s Successfully " + "collected fw dump.\n", adapter->netdev->name); + } + + } else { + dev_info(&adapter->pdev->dev, + "Cannot overwrite previously collected " + "firmware minidump.\n"); + adapter->fw_mdump_rdy = 1; + return; + } +} diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c index 094d26c5181..f69ac442c6a 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c @@ -446,7 +446,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter) /* resetall */ netxen_rom_lock(adapter); - NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xffffffff); + NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xfeffffff); netxen_rom_unlock(adapter); if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { @@ -1347,7 +1347,6 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) do { val = NXRD32(adapter, CRB_CMDPEG_STATE); - switch (val) { case PHAN_INITIALIZE_COMPLETE: case PHAN_INITIALIZE_ACK: diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index 64aa44d5dab..f67655f3462 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c @@ -82,7 +82,6 @@ static void netxen_create_sysfs_entries(struct netxen_adapter *adapter); static void netxen_remove_sysfs_entries(struct netxen_adapter *adapter); static void netxen_create_diag_entries(struct netxen_adapter *adapter); static void netxen_remove_diag_entries(struct netxen_adapter *adapter); - static int nx_dev_request_aer(struct netxen_adapter *adapter); static int nx_decr_dev_ref_cnt(struct netxen_adapter *adapter); static int netxen_can_start_firmware(struct netxen_adapter *adapter); @@ -802,10 +801,10 @@ err_out: static void netxen_check_options(struct netxen_adapter *adapter) { - u32 fw_major, fw_minor, fw_build; + u32 fw_major, fw_minor, fw_build, prev_fw_version; char brd_name[NETXEN_MAX_SHORT_NAME]; char serial_num[32]; - int i, offset, val; + int i, offset, val, err; int *ptr32; struct pci_dev *pdev = adapter->pdev; @@ -826,9 +825,22 @@ netxen_check_options(struct netxen_adapter *adapter) fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR); fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR); fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB); - + prev_fw_version = adapter->fw_version; adapter->fw_version = NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build); + /* Get FW Mini Coredump template and store it */ + if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { + if (adapter->mdump.md_template == NULL || + adapter->fw_version > prev_fw_version) { + kfree(adapter->mdump.md_template); + adapter->mdump.md_template = NULL; + err = netxen_setup_minidump(adapter); + if (err) + dev_err(&adapter->pdev->dev, + "Failed to setup minidump rcode = %d\n", err); + } + } + if (adapter->portnum == 0) { get_brd_name_by_type(adapter->ahw.board_type, brd_name); @@ -909,7 +921,12 @@ netxen_start_firmware(struct netxen_adapter *adapter) if (err) return err; - if (!netxen_can_start_firmware(adapter)) + err = netxen_can_start_firmware(adapter); + + if (err < 0) + return err; + + if (!err) goto wait_init; first_boot = NXRD32(adapter, NETXEN_CAM_RAM(0x1fc)); @@ -1528,6 +1545,18 @@ err_out_disable_pdev: return err; } +static +void netxen_cleanup_minidump(struct netxen_adapter *adapter) +{ + kfree(adapter->mdump.md_template); + adapter->mdump.md_template = NULL; + + if (adapter->mdump.md_capture_buff) { + vfree(adapter->mdump.md_capture_buff); + adapter->mdump.md_capture_buff = NULL; + } +} + static void __devexit netxen_nic_remove(struct pci_dev *pdev) { struct netxen_adapter *adapter; @@ -1563,8 +1592,10 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) netxen_release_firmware(adapter); - if (NX_IS_REVISION_P3(pdev->revision)) + if (NX_IS_REVISION_P3(pdev->revision)) { + netxen_cleanup_minidump(adapter); pci_disable_pcie_error_reporting(pdev); + } pci_release_regions(pdev); pci_disable_device(pdev); @@ -2316,7 +2347,7 @@ nx_incr_dev_ref_cnt(struct netxen_adapter *adapter) static int nx_decr_dev_ref_cnt(struct netxen_adapter *adapter) { - int count; + int count, state; if (netxen_api_lock(adapter)) return -EIO; @@ -2324,8 +2355,9 @@ nx_decr_dev_ref_cnt(struct netxen_adapter *adapter) WARN_ON(count == 0); NXWR32(adapter, NX_CRB_DEV_REF_COUNT, --count); + state = NXRD32(adapter, NX_CRB_DEV_STATE); - if (count == 0) + if (count == 0 && state != NX_DEV_FAILED) NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_COLD); netxen_api_unlock(adapter); @@ -2354,7 +2386,7 @@ nx_dev_request_aer(struct netxen_adapter *adapter) return ret; } -static int +int nx_dev_request_reset(struct netxen_adapter *adapter) { u32 state; @@ -2365,10 +2397,11 @@ nx_dev_request_reset(struct netxen_adapter *adapter) state = NXRD32(adapter, NX_CRB_DEV_STATE); - if (state == NX_DEV_NEED_RESET) + if (state == NX_DEV_NEED_RESET || state == NX_DEV_FAILED) ret = 0; else if (state != NX_DEV_INITALIZING && state != NX_DEV_NEED_AER) { NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_NEED_RESET); + adapter->flags |= NETXEN_FW_RESET_OWNER; ret = 0; } @@ -2383,8 +2416,10 @@ netxen_can_start_firmware(struct netxen_adapter *adapter) int count; int can_start = 0; - if (netxen_api_lock(adapter)) - return 0; + if (netxen_api_lock(adapter)) { + nx_incr_dev_ref_cnt(adapter); + return -1; + } count = NXRD32(adapter, NX_CRB_DEV_REF_COUNT); @@ -2456,8 +2491,31 @@ netxen_fwinit_work(struct work_struct *work) struct netxen_adapter *adapter = container_of(work, struct netxen_adapter, fw_work.work); int dev_state; - + int count; dev_state = NXRD32(adapter, NX_CRB_DEV_STATE); + if (adapter->flags & NETXEN_FW_RESET_OWNER) { + count = NXRD32(adapter, NX_CRB_DEV_REF_COUNT); + WARN_ON(count == 0); + if (count == 1) { + if (adapter->mdump.md_enabled) { + rtnl_lock(); + netxen_dump_fw(adapter); + rtnl_unlock(); + } + adapter->flags &= ~NETXEN_FW_RESET_OWNER; + if (netxen_api_lock(adapter)) { + clear_bit(__NX_RESETTING, &adapter->state); + NXWR32(adapter, NX_CRB_DEV_STATE, + NX_DEV_FAILED); + return; + } + count = NXRD32(adapter, NX_CRB_DEV_REF_COUNT); + NXWR32(adapter, NX_CRB_DEV_REF_COUNT, --count); + NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_COLD); + dev_state = NX_DEV_COLD; + netxen_api_unlock(adapter); + } + } switch (dev_state) { case NX_DEV_COLD: @@ -2470,11 +2528,9 @@ netxen_fwinit_work(struct work_struct *work) case NX_DEV_NEED_RESET: case NX_DEV_INITALIZING: - if (++adapter->fw_wait_cnt < FW_POLL_THRESH) { netxen_schedule_work(adapter, netxen_fwinit_work, 2 * FW_POLL_DELAY); return; - } case NX_DEV_FAILED: default: @@ -2482,6 +2538,15 @@ netxen_fwinit_work(struct work_struct *work) break; } + if (netxen_api_lock(adapter)) { + clear_bit(__NX_RESETTING, &adapter->state); + return; + } + NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_FAILED); + netxen_api_unlock(adapter); + dev_err(&adapter->pdev->dev, "%s: Device initialization Failed\n", + adapter->netdev->name); + clear_bit(__NX_RESETTING, &adapter->state); } @@ -2491,7 +2556,7 @@ netxen_detach_work(struct work_struct *work) struct netxen_adapter *adapter = container_of(work, struct netxen_adapter, fw_work.work); struct net_device *netdev = adapter->netdev; - int ref_cnt, delay; + int ref_cnt = 0, delay; u32 status; netif_device_detach(netdev); @@ -2510,7 +2575,8 @@ netxen_detach_work(struct work_struct *work) if (adapter->temp == NX_TEMP_PANIC) goto err_ret; - ref_cnt = nx_decr_dev_ref_cnt(adapter); + if (!(adapter->flags & NETXEN_FW_RESET_OWNER)) + ref_cnt = nx_decr_dev_ref_cnt(adapter); if (ref_cnt == -EIO) goto err_ret; @@ -2550,7 +2616,7 @@ netxen_check_health(struct netxen_adapter *adapter) * Send request to destroy context in case of tx timeout only * and doesn't required in case of Fw hang */ - if (state == NX_DEV_NEED_RESET) { + if (state == NX_DEV_NEED_RESET || state == NX_DEV_FAILED) { adapter->need_fw_reset = 1; if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) goto detach; -- cgit v1.2.3-70-g09d2 From db608c129b5258dbdff9c221857a95bc2dc1128e Mon Sep 17 00:00:00 2001 From: Sritej Velaga Date: Fri, 3 Feb 2012 11:35:12 +0000 Subject: netxen_nic: Fix phy link status Pass the adapter phy link status to the caller. Signed-off-by: Sritej Velaga Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c index 8f89c05e0c7..f3c0057a802 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c @@ -559,7 +559,11 @@ nx_fw_cmd_query_phy(struct netxen_adapter *adapter, u32 reg, u32 *val) if (rcode != NX_RCODE_SUCCESS) return -EIO; - return cmd.rsp.arg1; + if (val == NULL) + return -EIO; + + *val = cmd.rsp.arg1; + return 0; } int -- cgit v1.2.3-70-g09d2 From 5471aed0259298e4e258b8a9e403ebdf88ebcd56 Mon Sep 17 00:00:00 2001 From: Sritej Velaga Date: Fri, 3 Feb 2012 11:35:13 +0000 Subject: netxen_nic: Error logging on firmware hang Log states of essential registers on firmware hang detection. Signed-off-by: Sritej Velaga Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h | 1 + .../net/ethernet/qlogic/netxen/netxen_nic_main.c | 21 +++++++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h index dc1967c1f31..b1a897cd9a8 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h @@ -969,6 +969,7 @@ enum { #define NX_RCODE_FATAL_ERROR 0x80000000 #define NX_FWERROR_PEGNUM(code) ((code) & 0xff) #define NX_FWERROR_CODE(code) ((code >> 8) & 0xfffff) +#define NX_FWERROR_PEGSTAT1(code) ((code >> 8) & 0x1fffff) #define FW_POLL_DELAY (2 * HZ) #define FW_FAIL_THRESH 3 diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index f67655f3462..f517c16bfa3 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c @@ -2596,6 +2596,7 @@ static int netxen_check_health(struct netxen_adapter *adapter) { u32 state, heartbit; + u32 peg_status; struct net_device *netdev = adapter->netdev; state = NXRD32(adapter, NX_CRB_DEV_STATE); @@ -2642,8 +2643,24 @@ netxen_check_health(struct netxen_adapter *adapter) clear_bit(__NX_FW_ATTACHED, &adapter->state); - dev_info(&netdev->dev, "firmware hang detected\n"); - + dev_err(&netdev->dev, "firmware hang detected\n"); + peg_status = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1); + dev_err(&adapter->pdev->dev, "Dumping hw/fw registers\n" + "PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2: 0x%x,\n" + "PEG_NET_0_PC: 0x%x, PEG_NET_1_PC: 0x%x,\n" + "PEG_NET_2_PC: 0x%x, PEG_NET_3_PC: 0x%x,\n" + "PEG_NET_4_PC: 0x%x\n", + peg_status, + NXRD32(adapter, NETXEN_PEG_HALT_STATUS2), + NXRD32(adapter, NETXEN_CRB_PEG_NET_0 + 0x3c), + NXRD32(adapter, NETXEN_CRB_PEG_NET_1 + 0x3c), + NXRD32(adapter, NETXEN_CRB_PEG_NET_2 + 0x3c), + NXRD32(adapter, NETXEN_CRB_PEG_NET_3 + 0x3c), + NXRD32(adapter, NETXEN_CRB_PEG_NET_4 + 0x3c)); + if (NX_FWERROR_PEGSTAT1(peg_status) == 0x67) + dev_err(&adapter->pdev->dev, + "Firmware aborted with error code 0x00006700. " + "Device is being reset.\n"); detach: if ((auto_fw_reset == AUTO_FW_RESET_ENABLED) && !test_and_set_bit(__NX_RESETTING, &adapter->state)) -- cgit v1.2.3-70-g09d2 From b8c30812b479a53b717ad665728df55d30f784d5 Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Fri, 3 Feb 2012 11:35:14 +0000 Subject: netxen: Fix a panic during driver unload in device_remove_file o Pass adapter->pdev->dev instead of netdev->dev Signed-off-by: Rajesh Borundia Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index f517c16bfa3..8dc4a134dec 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c @@ -2930,13 +2930,12 @@ static struct bin_attribute bin_attr_mem = { static void netxen_create_sysfs_entries(struct netxen_adapter *adapter) { - struct net_device *netdev = adapter->netdev; - struct device *dev = &netdev->dev; + struct device *dev = &adapter->pdev->dev; if (adapter->capabilities & NX_FW_CAPABILITY_BDG) { /* bridged_mode control */ if (device_create_file(dev, &dev_attr_bridged_mode)) { - dev_warn(&netdev->dev, + dev_warn(dev, "failed to create bridged_mode sysfs entry\n"); } } @@ -2945,8 +2944,7 @@ netxen_create_sysfs_entries(struct netxen_adapter *adapter) static void netxen_remove_sysfs_entries(struct netxen_adapter *adapter) { - struct net_device *netdev = adapter->netdev; - struct device *dev = &netdev->dev; + struct device *dev = &adapter->pdev->dev; if (adapter->capabilities & NX_FW_CAPABILITY_BDG) device_remove_file(dev, &dev_attr_bridged_mode); -- cgit v1.2.3-70-g09d2 From 34d6fde187f169a1b155d091158f97ab34d93bab Mon Sep 17 00:00:00 2001 From: Sony Chacko Date: Fri, 3 Feb 2012 11:35:15 +0000 Subject: netxen: report valid speed and duplex status when link is down o Update version to 4.0.78 Signed-off-by: Sony Chacko Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/netxen/netxen_nic.h | 4 ++-- drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h index 8a35430b2f8..2eeac32f7fd 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h @@ -53,8 +53,8 @@ #define _NETXEN_NIC_LINUX_MAJOR 4 #define _NETXEN_NIC_LINUX_MINOR 0 -#define _NETXEN_NIC_LINUX_SUBVERSION 77 -#define NETXEN_NIC_LINUX_VERSIONID "4.0.77" +#define _NETXEN_NIC_LINUX_SUBVERSION 78 +#define NETXEN_NIC_LINUX_VERSIONID "4.0.78" #define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) #define _major(v) (((v) >> 24) & 0xff) diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c index 3e73d35ccea..8c39299331a 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c @@ -248,6 +248,11 @@ skip: } } + if (!netif_running(dev) || !adapter->ahw.linkup) { + ecmd->duplex = DUPLEX_UNKNOWN; + ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN); + } + return 0; } -- cgit v1.2.3-70-g09d2 From 646779f1b4ade4acac6b49dbfa8be84a98ab85b4 Mon Sep 17 00:00:00 2001 From: Sritej Velaga Date: Fri, 3 Feb 2012 13:45:41 +0000 Subject: qlcnic: Stop pause ctrl frames on fw hang. When firmware hang is detected, fw should stop sending pause control frames. Signed-off-by: Sritej Velaga Signed-off-by: Sony Chacko Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 7bfdf57f4b7..a47c70b0934 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -2999,8 +2999,18 @@ qlcnic_set_npar_non_operational(struct qlcnic_adapter *adapter) void qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) { - u32 state; - + u32 state, xg_val = 0, gb_val = 0; + + qlcnic_xg_set_xg0_mask(xg_val); + qlcnic_xg_set_xg1_mask(xg_val); + QLCWR32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, xg_val); + qlcnic_gb_set_gb0_mask(gb_val); + qlcnic_gb_set_gb1_mask(gb_val); + qlcnic_gb_set_gb2_mask(gb_val); + qlcnic_gb_set_gb3_mask(gb_val); + QLCWR32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, gb_val); + dev_info(&adapter->pdev->dev, "Pause control frames disabled" + " on all ports\n"); adapter->need_fw_reset = 1; if (qlcnic_api_lock(adapter)) return; -- cgit v1.2.3-70-g09d2 From 476a4b6d2543f0d9fa5205e0c25ebcd7973337bd Mon Sep 17 00:00:00 2001 From: Sony Chacko Date: Fri, 3 Feb 2012 13:45:42 +0000 Subject: qlcnic: report valid speed and duplex status when link is down Report valid link statistics when link is down. Signed-off-by: Sony Chacko Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 7 ++----- drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c | 8 +++++++- 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c index cc228cf3d84..6b2cf8bd16c 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c @@ -155,7 +155,6 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) { struct qlcnic_adapter *adapter = netdev_priv(dev); int check_sfp_module = 0; - u16 pcifn = adapter->ahw->pci_func; /* read which mode */ if (adapter->ahw->port_type == QLCNIC_GBE) { @@ -194,10 +193,8 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) goto skip; } - val = QLCRD32(adapter, P3P_LINK_SPEED_REG(pcifn)); - ethtool_cmd_speed_set(ecmd, P3P_LINK_SPEED_MHZ * - P3P_LINK_SPEED_VAL(pcifn, val)); - ecmd->duplex = DUPLEX_FULL; + ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN); + ecmd->duplex = DUPLEX_UNKNOWN; ecmd->autoneg = AUTONEG_DISABLE; } else return -EIO; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c index 38669583840..41d85efee42 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c @@ -1369,7 +1369,13 @@ qlcnic_handle_linkevent(struct qlcnic_adapter *adapter, adapter->module_type = module; adapter->link_autoneg = autoneg; - adapter->link_speed = link_speed; + + if (link_status) { + adapter->link_speed = link_speed; + } else { + adapter->link_speed = SPEED_UNKNOWN; + adapter->link_duplex = DUPLEX_UNKNOWN; + } } static void -- cgit v1.2.3-70-g09d2 From 97048a1f2b2f0ca2b2f690b551d5e97eeb94a0e9 Mon Sep 17 00:00:00 2001 From: Sritej Velaga Date: Fri, 3 Feb 2012 13:45:43 +0000 Subject: qlcnic: Fix firmware abort code check. Check bits 8-28 of peg_halt status register for firmware abort code. Signed-off-by: Sritej Velaga Signed-off-by: Sony Chacko Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index a47c70b0934..dba95311a46 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -3159,7 +3159,7 @@ qlcnic_check_health(struct qlcnic_adapter *adapter) QLCRD32(adapter, QLCNIC_CRB_PEG_NET_3 + 0x3c), QLCRD32(adapter, QLCNIC_CRB_PEG_NET_4 + 0x3c)); peg_status = QLCRD32(adapter, QLCNIC_PEG_HALT_STATUS1); - if (LSW(MSB(peg_status)) == 0x67) + if (QLCNIC_FWERROR_CODE(peg_status) == 0x67) dev_err(&adapter->pdev->dev, "Firmware aborted with error code 0x00006700. " "Device is being reset.\n"); -- cgit v1.2.3-70-g09d2 From c47884e4551cdea35f5bed60d0ae53d9b6c73dc2 Mon Sep 17 00:00:00 2001 From: Manish chopra Date: Fri, 3 Feb 2012 13:45:44 +0000 Subject: qlcnic: Fix API unlock Log dump status. Remove unmatched qlcnic_api_unlock call. Update version to 5.0.26. Signed-off-by: Manish Chopra Signed-off-by: Sony Chacko Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 2 +- drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 60976fc4ccc..2b5af22419a 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h @@ -37,7 +37,7 @@ #define _QLCNIC_LINUX_MAJOR 5 #define _QLCNIC_LINUX_MINOR 0 #define _QLCNIC_LINUX_SUBVERSION 25 -#define QLCNIC_LINUX_VERSIONID "5.0.25" +#define QLCNIC_LINUX_VERSIONID "5.0.26" #define QLCNIC_DRV_IDC_VER 0x01 #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c index 6b2cf8bd16c..30dcbfba8f2 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c @@ -1152,7 +1152,6 @@ qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump, if (!fw_dump->clr) { netdev_info(netdev, "Dump not available\n"); - qlcnic_api_unlock(adapter); return -EINVAL; } /* Copy template header first */ @@ -1171,7 +1170,7 @@ qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump, vfree(fw_dump->data); fw_dump->data = NULL; fw_dump->clr = 0; - + netdev_info(netdev, "extracted the FW dump Successfully\n"); return 0; } @@ -1189,7 +1188,7 @@ qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val) return ret; } if (fw_dump->clr) { - dev_info(&adapter->pdev->dev, + netdev_info(netdev, "Previous dump not cleared, not forcing dump\n"); return ret; } -- cgit v1.2.3-70-g09d2 From e02ef3311ae7329335d7c2b954b3988f7628a109 Mon Sep 17 00:00:00 2001 From: Jitendra Kalsaria Date: Fri, 3 Feb 2012 14:06:49 +0000 Subject: qlge: Fixed invalid reference to ip header we have copied skb into addr(page), skb->data doesn't contain ip header information. Signed-off-by: Jitendra Kalsaria Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlge/qlge_main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c index b5489873728..582b2374687 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c @@ -1576,13 +1576,14 @@ static void ql_process_mac_rx_page(struct ql_adapter *qdev, } else if ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_U) && (ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_V4)) { /* Unfragmented ipv4 UDP frame. */ - struct iphdr *iph = (struct iphdr *) skb->data; + struct iphdr *iph = + (struct iphdr *) ((u8 *)addr + ETH_HLEN); if (!(iph->frag_off & cpu_to_be16(IP_MF|IP_OFFSET))) { skb->ip_summed = CHECKSUM_UNNECESSARY; netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "TCP checksum done!\n"); + "UDP checksum done!\n"); } } } @@ -1690,7 +1691,7 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev, skb->ip_summed = CHECKSUM_UNNECESSARY; netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, - "TCP checksum done!\n"); + "UDP checksum done!\n"); } } } -- cgit v1.2.3-70-g09d2 From 19257f5a1a20ceacb49a474ce39108f75ea51886 Mon Sep 17 00:00:00 2001 From: Jitendra Kalsaria Date: Fri, 3 Feb 2012 14:06:50 +0000 Subject: qlge: Removing needless print's which are not Signed-off-by: Jitendra Kalsaria Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlge/qlge_main.c | 71 +--------------------------- 1 file changed, 1 insertion(+), 70 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c index 582b2374687..af12e80975d 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c @@ -375,13 +375,6 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type, u32 lower = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | (addr[5]); - - netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev, - "Adding %s address %pM at index %d in the CAM.\n", - type == MAC_ADDR_TYPE_MULTI_MAC ? - "MULTICAST" : "UNICAST", - addr, index); - status = ql_wait_reg_rdy(qdev, MAC_ADDR_IDX, MAC_ADDR_MW, 0); @@ -430,12 +423,6 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type, * addressing. It's either MAC_ADDR_E on or off. * That's bit-27 we're talking about. */ - netif_info(qdev, ifup, qdev->ndev, - "%s VLAN ID %d %s the CAM.\n", - enable_bit ? "Adding" : "Removing", - index, - enable_bit ? "to" : "from"); - status = ql_wait_reg_rdy(qdev, MAC_ADDR_IDX, MAC_ADDR_MW, 0); @@ -535,28 +522,6 @@ static int ql_set_routing_reg(struct ql_adapter *qdev, u32 index, u32 mask, int status = -EINVAL; /* Return error if no mask match. */ u32 value = 0; - netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev, - "%s %s mask %s the routing reg.\n", - enable ? "Adding" : "Removing", - index == RT_IDX_ALL_ERR_SLOT ? "MAC ERROR/ALL ERROR" : - index == RT_IDX_IP_CSUM_ERR_SLOT ? "IP CSUM ERROR" : - index == RT_IDX_TCP_UDP_CSUM_ERR_SLOT ? "TCP/UDP CSUM ERROR" : - index == RT_IDX_BCAST_SLOT ? "BROADCAST" : - index == RT_IDX_MCAST_MATCH_SLOT ? "MULTICAST MATCH" : - index == RT_IDX_ALLMULTI_SLOT ? "ALL MULTICAST MATCH" : - index == RT_IDX_UNUSED6_SLOT ? "UNUSED6" : - index == RT_IDX_UNUSED7_SLOT ? "UNUSED7" : - index == RT_IDX_RSS_MATCH_SLOT ? "RSS ALL/IPV4 MATCH" : - index == RT_IDX_RSS_IPV6_SLOT ? "RSS IPV6" : - index == RT_IDX_RSS_TCP4_SLOT ? "RSS TCP4" : - index == RT_IDX_RSS_TCP6_SLOT ? "RSS TCP6" : - index == RT_IDX_CAM_HIT_SLOT ? "CAM HIT" : - index == RT_IDX_UNUSED013 ? "UNUSED13" : - index == RT_IDX_UNUSED014 ? "UNUSED14" : - index == RT_IDX_PROMISCUOUS_SLOT ? "PROMISCUOUS" : - "(Bad index != RT_IDX)", - enable ? "to" : "from"); - switch (mask) { case RT_IDX_CAM_HIT: { @@ -2313,13 +2278,9 @@ static void qlge_vlan_mode(struct net_device *ndev, netdev_features_t features) struct ql_adapter *qdev = netdev_priv(ndev); if (features & NETIF_F_HW_VLAN_RX) { - netif_printk(qdev, ifup, KERN_DEBUG, ndev, - "Turning on VLAN in NIC_RCV_CFG.\n"); ql_write32(qdev, NIC_RCV_CFG, NIC_RCV_CFG_VLAN_MASK | NIC_RCV_CFG_VLAN_MATCH_AND_NON); } else { - netif_printk(qdev, ifup, KERN_DEBUG, ndev, - "Turning off VLAN in NIC_RCV_CFG.\n"); ql_write32(qdev, NIC_RCV_CFG, NIC_RCV_CFG_VLAN_MASK); } } @@ -3184,8 +3145,6 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring) netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev, "Invalid rx_ring->type = %d.\n", rx_ring->type); } - netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev, - "Initializing rx work queue.\n"); err = ql_write_cfg(qdev, cqicb, sizeof(struct cqicb), CFG_LCQ, rx_ring->cq_id); if (err) { @@ -3238,8 +3197,6 @@ static int ql_start_tx_ring(struct ql_adapter *qdev, struct tx_ring *tx_ring) netif_err(qdev, ifup, qdev->ndev, "Failed to load tx_ring.\n"); return err; } - netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev, - "Successfully loaded WQICB.\n"); return err; } @@ -3489,12 +3446,8 @@ static void ql_free_irq(struct ql_adapter *qdev) if (test_bit(QL_MSIX_ENABLED, &qdev->flags)) { free_irq(qdev->msi_x_entry[i].vector, &qdev->rx_ring[i]); - netif_printk(qdev, ifdown, KERN_DEBUG, qdev->ndev, - "freeing msix interrupt %d.\n", i); } else { free_irq(qdev->pdev->irq, &qdev->rx_ring[0]); - netif_printk(qdev, ifdown, KERN_DEBUG, qdev->ndev, - "freeing msi interrupt %d.\n", i); } } } @@ -3523,17 +3476,6 @@ static int ql_request_irq(struct ql_adapter *qdev) "Failed request for MSIX interrupt %d.\n", i); goto err_irq; - } else { - netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev, - "Hooked intr %d, queue type %s, with name %s.\n", - i, - qdev->rx_ring[i].type == DEFAULT_Q ? - "DEFAULT_Q" : - qdev->rx_ring[i].type == TX_Q ? - "TX_Q" : - qdev->rx_ring[i].type == RX_Q ? - "RX_Q" : "", - intr_context->name); } } else { netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev, @@ -3603,15 +3545,11 @@ static int ql_start_rss(struct ql_adapter *qdev) memcpy((void *)&ricb->ipv6_hash_key[0], init_hash_seed, 40); memcpy((void *)&ricb->ipv4_hash_key[0], init_hash_seed, 16); - netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev, "Initializing RSS.\n"); - status = ql_write_cfg(qdev, ricb, sizeof(*ricb), CFG_LR, 0); if (status) { netif_err(qdev, ifup, qdev->ndev, "Failed to load RICB.\n"); return status; } - netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev, - "Successfully loaded RICB.\n"); return status; } @@ -3818,11 +3756,8 @@ static int ql_adapter_initialize(struct ql_adapter *qdev) } /* Start NAPI for the RSS queues. */ - for (i = 0; i < qdev->rss_ring_count; i++) { - netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev, - "Enabling NAPI for rx_ring[%d].\n", i); + for (i = 0; i < qdev->rss_ring_count; i++) napi_enable(&qdev->rx_ring[i].napi); - } return status; } @@ -4122,10 +4057,6 @@ static int ql_configure_rings(struct ql_adapter *qdev) rx_ring->lbq_size = rx_ring->lbq_len * sizeof(__le64); rx_ring->lbq_buf_size = (u16)lbq_buf_len; - netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev, - "lbq_buf_size %d, order = %d\n", - rx_ring->lbq_buf_size, - qdev->lbq_buf_order); rx_ring->sbq_len = NUM_SMALL_BUFFERS; rx_ring->sbq_size = rx_ring->sbq_len * sizeof(__le64); -- cgit v1.2.3-70-g09d2 From 81f25d96f1c9fa116f9c6f06ae490c2f8fa5ebaf Mon Sep 17 00:00:00 2001 From: Jitendra Kalsaria Date: Fri, 3 Feb 2012 14:06:51 +0000 Subject: qlge: Fix memory leak in the process of refill Driver was leaking memory when page allocation failures occurs. Signed-off-by: Jitendra Kalsaria Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlge/qlge_main.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c index af12e80975d..49343ec21c8 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c @@ -1143,14 +1143,16 @@ static void ql_update_lbq(struct ql_adapter *qdev, struct rx_ring *rx_ring) int i; while (rx_ring->lbq_free_cnt > 32) { - for (i = 0; i < 16; i++) { + for (i = (rx_ring->lbq_clean_idx % 16); i < 16; i++) { netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, "lbq: try cleaning clean_idx = %d.\n", clean_idx); lbq_desc = &rx_ring->lbq[clean_idx]; if (ql_get_next_chunk(qdev, rx_ring, lbq_desc)) { + rx_ring->lbq_clean_idx = clean_idx; netif_err(qdev, ifup, qdev->ndev, - "Could not get a page chunk.\n"); + "Could not get a page chunk, i=%d, clean_idx =%d .\n", + i, clean_idx); return; } @@ -1195,7 +1197,7 @@ static void ql_update_sbq(struct ql_adapter *qdev, struct rx_ring *rx_ring) int i; while (rx_ring->sbq_free_cnt > 16) { - for (i = 0; i < 16; i++) { + for (i = (rx_ring->sbq_clean_idx % 16); i < 16; i++) { sbq_desc = &rx_ring->sbq[clean_idx]; netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev, "sbq: try cleaning clean_idx = %d.\n", -- cgit v1.2.3-70-g09d2 From dc4790a9ba3536384123f50ff21a219bc60c9c92 Mon Sep 17 00:00:00 2001 From: Jitendra Kalsaria Date: Fri, 3 Feb 2012 14:06:52 +0000 Subject: qlge: Bumped driver version to 1.00.00.30. Signed-off-by: Jitendra Kalsaria Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlge/qlge.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/qlge/qlge.h b/drivers/net/ethernet/qlogic/qlge/qlge.h index b8478aab050..5a639df33f1 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge.h +++ b/drivers/net/ethernet/qlogic/qlge/qlge.h @@ -18,7 +18,7 @@ */ #define DRV_NAME "qlge" #define DRV_STRING "QLogic 10 Gigabit PCI-E Ethernet Driver " -#define DRV_VERSION "v1.00.00.29.00.00-01" +#define DRV_VERSION "v1.00.00.30.00.00-01" #define WQ_ADDR_ALIGN 0x3 /* 4 byte alignment */ -- cgit v1.2.3-70-g09d2 From 63da93d932af04cf80507b110afe894a8a8d1f90 Mon Sep 17 00:00:00 2001 From: Neel Patel Date: Fri, 3 Feb 2012 08:25:14 +0000 Subject: enic: Enable support for multiple hardware receive queues This patch enables support for multiple receive queues. If multiple receive queues are used ingress traffic is hashed into one of the receive queues based on IP or TCP or both headers. The max number of supported receive queues per vnic is 8. Signed-off-by: Neel Patel Signed-off-by: Christian Benvenuti Signed-off-by: Roopa Prabhu Signed-off-by: Nishank Trivedi Signed-off-by: David S. Miller --- drivers/net/ethernet/cisco/enic/enic.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h index ee93a2087fe..24bb088a7bc 100644 --- a/drivers/net/ethernet/cisco/enic/enic.h +++ b/drivers/net/ethernet/cisco/enic/enic.h @@ -32,13 +32,13 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "2.1.1.31" +#define DRV_VERSION "2.1.1.32" #define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 #define ENIC_WQ_MAX 1 -#define ENIC_RQ_MAX 1 +#define ENIC_RQ_MAX 8 #define ENIC_CQ_MAX (ENIC_WQ_MAX + ENIC_RQ_MAX) #define ENIC_INTR_MAX (ENIC_CQ_MAX + 2) -- cgit v1.2.3-70-g09d2 From f8a6dd59f79f83d7188909331dcdf6e45e1b2c1f Mon Sep 17 00:00:00 2001 From: Neel Patel Date: Fri, 3 Feb 2012 08:25:19 +0000 Subject: enic: Check firmware capability before issuing firmware commands Check if firmware supports a particular command by first checking capability using devcmd CMD_CAPABILITY. Signed-off-by: Neel Patel Signed-off-by: Christian Benvenuti Signed-off-by: Roopa Prabhu Signed-off-by: Nishank Trivedi Signed-off-by: David S. Miller --- drivers/net/ethernet/cisco/enic/enic.h | 2 +- drivers/net/ethernet/cisco/enic/vnic_dev.c | 58 ++++++++++++++++-------------- 2 files changed, 32 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h index 24bb088a7bc..54fd9c314b3 100644 --- a/drivers/net/ethernet/cisco/enic/enic.h +++ b/drivers/net/ethernet/cisco/enic/enic.h @@ -32,7 +32,7 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "2.1.1.32" +#define DRV_VERSION "2.1.1.33" #define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 diff --git a/drivers/net/ethernet/cisco/enic/vnic_dev.c b/drivers/net/ethernet/cisco/enic/vnic_dev.c index 31e7f9bc206..298ad6f865b 100644 --- a/drivers/net/ethernet/cisco/enic/vnic_dev.c +++ b/drivers/net/ethernet/cisco/enic/vnic_dev.c @@ -439,11 +439,12 @@ int vnic_dev_fw_info(struct vnic_dev *vdev, a1 = sizeof(struct vnic_devcmd_fw_info); /* only get fw_info once and cache it */ - err = vnic_dev_cmd(vdev, CMD_MCPU_FW_INFO, &a0, &a1, wait); - if (err == ERR_ECMDUNKNOWN) { + if (vnic_dev_capable(vdev, CMD_MCPU_FW_INFO)) + err = vnic_dev_cmd(vdev, CMD_MCPU_FW_INFO, + &a0, &a1, wait); + else err = vnic_dev_cmd(vdev, CMD_MCPU_FW_INFO_OLD, &a0, &a1, wait); - } } *fw_info = vdev->fw_info; @@ -504,13 +505,11 @@ int vnic_dev_enable_wait(struct vnic_dev *vdev) { u64 a0 = 0, a1 = 0; int wait = 1000; - int err; - err = vnic_dev_cmd(vdev, CMD_ENABLE_WAIT, &a0, &a1, wait); - if (err == ERR_ECMDUNKNOWN) + if (vnic_dev_capable(vdev, CMD_ENABLE_WAIT)) + return vnic_dev_cmd(vdev, CMD_ENABLE_WAIT, &a0, &a1, wait); + else return vnic_dev_cmd(vdev, CMD_ENABLE, &a0, &a1, wait); - - return err; } int vnic_dev_disable(struct vnic_dev *vdev) @@ -574,16 +573,15 @@ int vnic_dev_hang_reset(struct vnic_dev *vdev, int arg) int wait = 1000; int err; - err = vnic_dev_cmd(vdev, CMD_HANG_RESET, &a0, &a1, wait); - if (err == ERR_ECMDUNKNOWN) { + if (vnic_dev_capable(vdev, CMD_HANG_RESET)) { + return vnic_dev_cmd(vdev, CMD_HANG_RESET, + &a0, &a1, wait); + } else { err = vnic_dev_soft_reset(vdev, arg); if (err) return err; - return vnic_dev_init(vdev, 0); } - - return err; } int vnic_dev_hang_reset_done(struct vnic_dev *vdev, int *done) @@ -594,11 +592,13 @@ int vnic_dev_hang_reset_done(struct vnic_dev *vdev, int *done) *done = 0; - err = vnic_dev_cmd(vdev, CMD_HANG_RESET_STATUS, &a0, &a1, wait); - if (err) { - if (err == ERR_ECMDUNKNOWN) - return vnic_dev_soft_reset_done(vdev, done); - return err; + if (vnic_dev_capable(vdev, CMD_HANG_RESET_STATUS)) { + err = vnic_dev_cmd(vdev, CMD_HANG_RESET_STATUS, + &a0, &a1, wait); + if (err) + return err; + } else { + return vnic_dev_soft_reset_done(vdev, done); } *done = (a0 == 0); @@ -691,13 +691,12 @@ int vnic_dev_set_ig_vlan_rewrite_mode(struct vnic_dev *vdev, { u64 a0 = ig_vlan_rewrite_mode, a1 = 0; int wait = 1000; - int err; - err = vnic_dev_cmd(vdev, CMD_IG_VLAN_REWRITE_MODE, &a0, &a1, wait); - if (err == ERR_ECMDUNKNOWN) + if (vnic_dev_capable(vdev, CMD_IG_VLAN_REWRITE_MODE)) + return vnic_dev_cmd(vdev, CMD_IG_VLAN_REWRITE_MODE, + &a0, &a1, wait); + else return 0; - - return err; } static int vnic_dev_notify_setcmd(struct vnic_dev *vdev, @@ -835,7 +834,10 @@ int vnic_dev_intr_coal_timer_info(struct vnic_dev *vdev) memset(vdev->args, 0, sizeof(vdev->args)); - err = _vnic_dev_cmd(vdev, CMD_INTR_COAL_CONVERT, wait); + if (vnic_dev_capable(vdev, CMD_INTR_COAL_CONVERT)) + err = _vnic_dev_cmd(vdev, CMD_INTR_COAL_CONVERT, wait); + else + err = ERR_ECMDUNKNOWN; /* Use defaults when firmware doesn't support the devcmd at all or * supports it for only specific hardware @@ -848,9 +850,11 @@ int vnic_dev_intr_coal_timer_info(struct vnic_dev *vdev) return 0; } - vdev->intr_coal_timer_info.mul = (u32) vdev->args[0]; - vdev->intr_coal_timer_info.div = (u32) vdev->args[1]; - vdev->intr_coal_timer_info.max_usec = (u32) vdev->args[2]; + if (!err) { + vdev->intr_coal_timer_info.mul = (u32) vdev->args[0]; + vdev->intr_coal_timer_info.div = (u32) vdev->args[1]; + vdev->intr_coal_timer_info.max_usec = (u32) vdev->args[2]; + } return err; } -- cgit v1.2.3-70-g09d2 From 332ad43f19848ed653a5e44afa8e2f4a7d34ed44 Mon Sep 17 00:00:00 2001 From: "sjur.brandeland@stericsson.com" Date: Fri, 3 Feb 2012 04:36:21 +0000 Subject: caif-hsi: Add RX flip buffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement RX flip buffer in the cfhsi_rx_done function, piggy-backed frames is also supported. This gives a significant performance gain for CAIF over HSI. Signed-off-by: Sjur Brændeland Signed-off-by: David S. Miller --- drivers/net/caif/caif_hsi.c | 145 +++++++++++++++++++++++++++++++------------- include/net/caif/caif_hsi.h | 1 + 2 files changed, 104 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c index 0a4fc62a381..c8afd62239e 100644 --- a/drivers/net/caif/caif_hsi.c +++ b/drivers/net/caif/caif_hsi.c @@ -426,6 +426,35 @@ static int cfhsi_rx_desc(struct cfhsi_desc *desc, struct cfhsi *cfhsi) return xfer_sz; } +static int cfhsi_rx_desc_len(struct cfhsi_desc *desc) +{ + int xfer_sz = 0; + int nfrms = 0; + u16 *plen; + + if ((desc->header & ~CFHSI_PIGGY_DESC) || + (desc->offset > CFHSI_MAX_EMB_FRM_SZ)) { + + pr_err("Invalid descriptor. %x %x\n", desc->header, + desc->offset); + return -EPROTO; + } + + /* Calculate transfer length. */ + plen = desc->cffrm_len; + while (nfrms < CFHSI_MAX_PKTS && *plen) { + xfer_sz += *plen; + plen++; + nfrms++; + } + + if (xfer_sz % 4) { + pr_err("Invalid payload len: %d, ignored.\n", xfer_sz); + return -EPROTO; + } + return xfer_sz; +} + static int cfhsi_rx_pld(struct cfhsi_desc *desc, struct cfhsi *cfhsi) { int rx_sz = 0; @@ -517,8 +546,10 @@ static int cfhsi_rx_pld(struct cfhsi_desc *desc, struct cfhsi *cfhsi) static void cfhsi_rx_done(struct cfhsi *cfhsi) { int res; - int desc_pld_len = 0; + int desc_pld_len = 0, rx_len, rx_state; struct cfhsi_desc *desc = NULL; + u8 *rx_ptr, *rx_buf; + struct cfhsi_desc *piggy_desc = NULL; desc = (struct cfhsi_desc *)cfhsi->rx_buf; @@ -534,65 +565,71 @@ static void cfhsi_rx_done(struct cfhsi *cfhsi) spin_unlock_bh(&cfhsi->lock); if (cfhsi->rx_state.state == CFHSI_RX_STATE_DESC) { - desc_pld_len = cfhsi_rx_desc(desc, cfhsi); - if (desc_pld_len == -ENOMEM) - goto restart; - if (desc_pld_len == -EPROTO) + desc_pld_len = cfhsi_rx_desc_len(desc); + + if (desc_pld_len < 0) goto out_of_sync; + + rx_buf = cfhsi->rx_buf; + rx_len = desc_pld_len; + if (desc_pld_len > 0 && (desc->header & CFHSI_PIGGY_DESC)) + rx_len += CFHSI_DESC_SZ; + if (desc_pld_len == 0) + rx_buf = cfhsi->rx_flip_buf; } else { - int pld_len; + rx_buf = cfhsi->rx_flip_buf; - if (!cfhsi->rx_state.piggy_desc) { - pld_len = cfhsi_rx_pld(desc, cfhsi); - if (pld_len == -ENOMEM) - goto restart; - if (pld_len == -EPROTO) - goto out_of_sync; - cfhsi->rx_state.pld_len = pld_len; - } else { - pld_len = cfhsi->rx_state.pld_len; - } + rx_len = CFHSI_DESC_SZ; + if (cfhsi->rx_state.pld_len > 0 && + (desc->header & CFHSI_PIGGY_DESC)) { - if ((pld_len > 0) && (desc->header & CFHSI_PIGGY_DESC)) { - struct cfhsi_desc *piggy_desc; piggy_desc = (struct cfhsi_desc *) (desc->emb_frm + CFHSI_MAX_EMB_FRM_SZ + - pld_len); + cfhsi->rx_state.pld_len); + cfhsi->rx_state.piggy_desc = true; - /* Extract piggy-backed descriptor. */ - desc_pld_len = cfhsi_rx_desc(piggy_desc, cfhsi); - if (desc_pld_len == -ENOMEM) - goto restart; + /* Extract payload len from piggy-backed descriptor. */ + desc_pld_len = cfhsi_rx_desc_len(piggy_desc); + if (desc_pld_len < 0) + goto out_of_sync; + + if (desc_pld_len > 0) + rx_len = desc_pld_len; + + if (desc_pld_len > 0 && + (piggy_desc->header & CFHSI_PIGGY_DESC)) + rx_len += CFHSI_DESC_SZ; /* * Copy needed information from the piggy-backed * descriptor to the descriptor in the start. */ - memcpy((u8 *)desc, (u8 *)piggy_desc, + memcpy(rx_buf, (u8 *)piggy_desc, CFHSI_DESC_SHORT_SZ); - + /* Mark no embedded frame here */ + piggy_desc->offset = 0; if (desc_pld_len == -EPROTO) goto out_of_sync; } } - memset(&cfhsi->rx_state, 0, sizeof(cfhsi->rx_state)); if (desc_pld_len) { - cfhsi->rx_state.state = CFHSI_RX_STATE_PAYLOAD; - cfhsi->rx_ptr = cfhsi->rx_buf + CFHSI_DESC_SZ; - cfhsi->rx_len = desc_pld_len; + rx_state = CFHSI_RX_STATE_PAYLOAD; + rx_ptr = rx_buf + CFHSI_DESC_SZ; } else { - cfhsi->rx_state.state = CFHSI_RX_STATE_DESC; - cfhsi->rx_ptr = cfhsi->rx_buf; - cfhsi->rx_len = CFHSI_DESC_SZ; + rx_state = CFHSI_RX_STATE_DESC; + rx_ptr = rx_buf; + rx_len = CFHSI_DESC_SZ; } + /* Initiate next read */ if (test_bit(CFHSI_AWAKE, &cfhsi->bits)) { /* Set up new transfer. */ dev_dbg(&cfhsi->ndev->dev, "%s: Start RX.\n", - __func__); - res = cfhsi->dev->cfhsi_rx(cfhsi->rx_ptr, cfhsi->rx_len, + __func__); + + res = cfhsi->dev->cfhsi_rx(rx_ptr, rx_len, cfhsi->dev); if (WARN_ON(res < 0)) { dev_err(&cfhsi->ndev->dev, "%s: RX error %d.\n", @@ -601,16 +638,32 @@ static void cfhsi_rx_done(struct cfhsi *cfhsi) cfhsi->ndev->stats.rx_dropped++; } } - return; -restart: - if (++cfhsi->rx_state.retries > CFHSI_MAX_RX_RETRIES) { - dev_err(&cfhsi->ndev->dev, "%s: No memory available " - "in %d iterations.\n", - __func__, CFHSI_MAX_RX_RETRIES); - BUG(); + if (cfhsi->rx_state.state == CFHSI_RX_STATE_DESC) { + /* Extract payload from descriptor */ + if (cfhsi_rx_desc(desc, cfhsi) < 0) + goto out_of_sync; + } else { + /* Extract payload */ + if (cfhsi_rx_pld(desc, cfhsi) < 0) + goto out_of_sync; + if (piggy_desc) { + /* Extract any payload in piggyback descriptor. */ + if (cfhsi_rx_desc(piggy_desc, cfhsi) < 0) + goto out_of_sync; + } } - mod_timer(&cfhsi->rx_slowpath_timer, jiffies + 1); + + /* Update state info */ + memset(&cfhsi->rx_state, 0, sizeof(cfhsi->rx_state)); + cfhsi->rx_state.state = rx_state; + cfhsi->rx_ptr = rx_ptr; + cfhsi->rx_len = rx_len; + cfhsi->rx_state.pld_len = desc_pld_len; + cfhsi->rx_state.piggy_desc = desc->header & CFHSI_PIGGY_DESC; + + if (rx_buf != cfhsi->rx_buf) + swap(cfhsi->rx_buf, cfhsi->rx_flip_buf); return; out_of_sync: @@ -1040,6 +1093,12 @@ int cfhsi_probe(struct platform_device *pdev) goto err_alloc_rx; } + cfhsi->rx_flip_buf = kzalloc(CFHSI_BUF_SZ_RX, GFP_KERNEL); + if (!cfhsi->rx_flip_buf) { + res = -ENODEV; + goto err_alloc_rx_flip; + } + /* Pre-calculate inactivity timeout. */ if (inactivity_timeout != -1) { cfhsi->inactivity_timeout = @@ -1138,6 +1197,8 @@ int cfhsi_probe(struct platform_device *pdev) err_activate: destroy_workqueue(cfhsi->wq); err_create_wq: + kfree(cfhsi->rx_flip_buf); + err_alloc_rx_flip: kfree(cfhsi->rx_buf); err_alloc_rx: kfree(cfhsi->tx_buf); diff --git a/include/net/caif/caif_hsi.h b/include/net/caif/caif_hsi.h index 8d552519ff6..6db8ecf52aa 100644 --- a/include/net/caif/caif_hsi.h +++ b/include/net/caif/caif_hsi.h @@ -138,6 +138,7 @@ struct cfhsi { u8 *rx_ptr; u8 *tx_buf; u8 *rx_buf; + u8 *rx_flip_buf; spinlock_t lock; int flow_off_sent; u32 q_low_mark; -- cgit v1.2.3-70-g09d2 From 57cd80d4d511748f3973accc6919e7e1e1936ebb Mon Sep 17 00:00:00 2001 From: Padmanabh Ratnakar Date: Fri, 3 Feb 2012 09:49:46 +0000 Subject: be2net: Fix link status query command Version number in query link status command is getting overwritten in be_wrb_cmd_hdr_prepare() routine. Move the initialization to fix this issue. Also initialize the domain field. Signed-off-by: Padmanabh Ratnakar Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_cmds.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 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 0fcb4562479..dd6e8e2b347 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -1257,11 +1257,13 @@ int be_cmd_link_status_query(struct be_adapter *adapter, u8 *mac_speed, } req = embedded_payload(wrb); + be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, + OPCODE_COMMON_NTWK_LINK_STATUS_QUERY, sizeof(*req), wrb, NULL); + if (adapter->generation == BE_GEN3 || lancer_chip(adapter)) req->hdr.version = 1; - be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, - OPCODE_COMMON_NTWK_LINK_STATUS_QUERY, sizeof(*req), wrb, NULL); + req->hdr.domain = dom; status = be_mcc_notify_wait(adapter); if (!status) { -- cgit v1.2.3-70-g09d2 From e5e1ee89461543043a0144e6dac90547fefe2f89 Mon Sep 17 00:00:00 2001 From: Padmanabh Ratnakar Date: Fri, 3 Feb 2012 09:50:17 +0000 Subject: be2net: Use new implementation of get mac list command VFs use get mac list command to get their mac address. The format of this command has changed. Update driver to use the new format. Signed-off-by: Mammatha Edhala Signed-off-by: Padmanabh Ratnakar Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_cmds.c | 67 +++++++++++++++++++++-------- drivers/net/ethernet/emulex/benet/be_cmds.h | 36 +++++++++++----- drivers/net/ethernet/emulex/benet/be_main.c | 29 ++++++++----- 3 files changed, 92 insertions(+), 40 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 dd6e8e2b347..29dff7de66b 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -2300,52 +2300,81 @@ err: /* Uses synchronous MCCQ */ int be_cmd_get_mac_from_list(struct be_adapter *adapter, u32 domain, - u32 *pmac_id) + bool *pmac_id_active, u32 *pmac_id, u8 *mac) { struct be_mcc_wrb *wrb; struct be_cmd_req_get_mac_list *req; int status; int mac_count; + struct be_dma_mem get_mac_list_cmd; + int i; + + memset(&get_mac_list_cmd, 0, sizeof(struct be_dma_mem)); + get_mac_list_cmd.size = sizeof(struct be_cmd_resp_get_mac_list); + get_mac_list_cmd.va = pci_alloc_consistent(adapter->pdev, + get_mac_list_cmd.size, + &get_mac_list_cmd.dma); + + if (!get_mac_list_cmd.va) { + dev_err(&adapter->pdev->dev, + "Memory allocation failure during GET_MAC_LIST\n"); + return -ENOMEM; + } spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { status = -EBUSY; - goto err; + goto out; } - req = embedded_payload(wrb); + + req = get_mac_list_cmd.va; be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, OPCODE_COMMON_GET_MAC_LIST, sizeof(*req), - wrb, NULL); + wrb, &get_mac_list_cmd); req->hdr.domain = domain; + req->mac_type = MAC_ADDRESS_TYPE_NETWORK; + req->perm_override = 1; status = be_mcc_notify_wait(adapter); if (!status) { struct be_cmd_resp_get_mac_list *resp = - embedded_payload(wrb); - int i; - u8 *ctxt = &resp->context[0][0]; - status = -EIO; - mac_count = resp->mac_count; - be_dws_le_to_cpu(&resp->context, sizeof(resp->context)); + get_mac_list_cmd.va; + mac_count = resp->true_mac_count + resp->pseudo_mac_count; + /* Mac list returned could contain one or more active mac_ids + * or one or more pseudo permanant mac addresses. If an active + * mac_id is present, return first active mac_id found + */ for (i = 0; i < mac_count; i++) { - if (!AMAP_GET_BITS(struct amap_get_mac_list_context, - act, ctxt)) { - *pmac_id = AMAP_GET_BITS - (struct amap_get_mac_list_context, - macid, ctxt); - status = 0; - break; + struct get_list_macaddr *mac_entry; + u16 mac_addr_size; + u32 mac_id; + + mac_entry = &resp->macaddr_list[i]; + mac_addr_size = le16_to_cpu(mac_entry->mac_addr_size); + /* mac_id is a 32 bit value and mac_addr size + * is 6 bytes + */ + if (mac_addr_size == sizeof(u32)) { + *pmac_id_active = true; + mac_id = mac_entry->mac_addr_id.s_mac_id.mac_id; + *pmac_id = le32_to_cpu(mac_id); + goto out; } - ctxt += sizeof(struct amap_get_mac_list_context) / 8; } + /* If no active mac_id found, return first pseudo mac addr */ + *pmac_id_active = false; + memcpy(mac, resp->macaddr_list[0].mac_addr_id.macaddr, + ETH_ALEN); } -err: +out: spin_unlock_bh(&adapter->mcc_lock); + pci_free_consistent(adapter->pdev, get_mac_list_cmd.size, + get_mac_list_cmd.va, get_mac_list_cmd.dma); return status; } diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h index bbd012b41fb..5bb66c80f05 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/drivers/net/ethernet/emulex/benet/be_cmds.h @@ -1346,22 +1346,36 @@ struct be_cmd_resp_set_func_cap { /******************** GET/SET_MACLIST **************************/ #define BE_MAX_MAC 64 -struct amap_get_mac_list_context { - u8 macid[31]; - u8 act; -} __packed; - struct be_cmd_req_get_mac_list { struct be_cmd_req_hdr hdr; - u32 rsvd; + u8 mac_type; + u8 perm_override; + u16 iface_id; + u32 mac_id; + u32 rsvd[3]; +} __packed; + +struct get_list_macaddr { + u16 mac_addr_size; + union { + u8 macaddr[6]; + struct { + u8 rsvd[2]; + u32 mac_id; + } __packed s_mac_id; + } __packed mac_addr_id; } __packed; struct be_cmd_resp_get_mac_list { struct be_cmd_resp_hdr hdr; - u8 mac_count; - u8 rsvd1; - u16 rsvd2; - u8 context[sizeof(struct amap_get_mac_list_context) / 8][BE_MAX_MAC]; + struct get_list_macaddr fd_macaddr; /* Factory default mac */ + struct get_list_macaddr macid_macaddr; /* soft mac */ + u8 true_mac_count; + u8 pseudo_mac_count; + u8 mac_list_size; + u8 rsvd; + /* perm override mac */ + struct get_list_macaddr macaddr_list[BE_MAX_MAC]; } __packed; struct be_cmd_req_set_mac_list { @@ -1575,7 +1589,7 @@ extern int be_cmd_req_native_mode(struct be_adapter *adapter); extern int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size); extern void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf); extern int be_cmd_get_mac_from_list(struct be_adapter *adapter, u32 domain, - u32 *pmac_id); + bool *pmac_id_active, u32 *pmac_id, u8 *mac); extern int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array, u8 mac_count, u32 domain); diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 1395f803cf7..780498784d8 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -2608,19 +2608,28 @@ static void be_setup_init(struct be_adapter *adapter) adapter->eq_next_idx = 0; } -static int be_configure_mac_from_list(struct be_adapter *adapter, u8 *mac) +static int be_add_mac_from_list(struct be_adapter *adapter, u8 *mac) { u32 pmac_id; - int status = be_cmd_get_mac_from_list(adapter, 0, &pmac_id); - if (status != 0) - goto do_none; - status = be_cmd_mac_addr_query(adapter, mac, - MAC_ADDRESS_TYPE_NETWORK, - false, adapter->if_handle, pmac_id); + int status; + bool pmac_id_active; + + status = be_cmd_get_mac_from_list(adapter, 0, &pmac_id_active, + &pmac_id, mac); if (status != 0) goto do_none; - status = be_cmd_pmac_add(adapter, mac, adapter->if_handle, - &adapter->pmac_id, 0); + + if (pmac_id_active) { + status = be_cmd_mac_addr_query(adapter, mac, + MAC_ADDRESS_TYPE_NETWORK, + false, adapter->if_handle, pmac_id); + + if (!status) + adapter->pmac_id = pmac_id; + } else { + status = be_cmd_pmac_add(adapter, mac, + adapter->if_handle, &adapter->pmac_id, 0); + } do_none: return status; } @@ -2685,7 +2694,7 @@ static int be_setup(struct be_adapter *adapter) */ if (!be_physfn(adapter)) { if (lancer_chip(adapter)) - status = be_configure_mac_from_list(adapter, mac); + status = be_add_mac_from_list(adapter, mac); else status = be_cmd_mac_addr_query(adapter, mac, MAC_ADDRESS_TYPE_NETWORK, false, -- cgit v1.2.3-70-g09d2 From 76a82abc0598f9cd881154369c3afdff9c28568b Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 4 Feb 2012 10:52:56 +0000 Subject: tms380tr: Fix cascading if/else tab abuse Cascading "if/else if"'s are ugly. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/tokenring/tms380tr.c | 179 +++++++++++++++------------------------ 1 file changed, 67 insertions(+), 112 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c index 65e9cf3a71f..102f896bbc5 100644 --- a/drivers/net/tokenring/tms380tr.c +++ b/drivers/net/tokenring/tms380tr.c @@ -1525,10 +1525,8 @@ static void tms380tr_chk_outstanding_cmds(struct net_device *dev) /* Check if adapter is opened, avoiding COMMAND_REJECT * interrupt by the adapter! */ - if(tp->AdapterOpenFlag == 0) - { - if(tp->CMDqueue & OC_OPEN) - { + if (tp->AdapterOpenFlag == 0) { + if (tp->CMDqueue & OC_OPEN) { /* Execute OPEN command */ tp->CMDqueue ^= OC_OPEN; @@ -1536,21 +1534,17 @@ static void tms380tr_chk_outstanding_cmds(struct net_device *dev) tp->scb.Parm[0] = LOWORD(Addr); tp->scb.Parm[1] = HIWORD(Addr); tp->scb.CMD = OPEN; - } - else + } else /* No OPEN command queued, but adapter closed. Note: * We'll try to re-open the adapter in DriverPoll() */ return; /* No adapter command issued */ - } - else - { + } else { /* Adapter is open; evaluate command queue: try to execute * outstanding commands (depending on priority!) CLOSE * command queued */ - if(tp->CMDqueue & OC_CLOSE) - { + if (tp->CMDqueue & OC_CLOSE) { tp->CMDqueue ^= OC_CLOSE; tp->AdapterOpenFlag = 0; tp->scb.Parm[0] = 0; /* Parm[0], Parm[1] are ignored */ @@ -1560,109 +1554,70 @@ static void tms380tr_chk_outstanding_cmds(struct net_device *dev) tp->CMDqueue |= OC_OPEN; /* re-open adapter */ else tp->CMDqueue = 0; /* no more commands */ - } - else - { - if(tp->CMDqueue & OC_RECEIVE) - { - tp->CMDqueue ^= OC_RECEIVE; - Addr = htonl(((char *)tp->RplHead - (char *)tp) + tp->dmabuffer); - tp->scb.Parm[0] = LOWORD(Addr); - tp->scb.Parm[1] = HIWORD(Addr); - tp->scb.CMD = RECEIVE; - } - else - { - if(tp->CMDqueue & OC_TRANSMIT_HALT) - { - /* NOTE: TRANSMIT.HALT must be checked - * before TRANSMIT. - */ - tp->CMDqueue ^= OC_TRANSMIT_HALT; - tp->scb.CMD = TRANSMIT_HALT; - - /* Parm[0] and Parm[1] are ignored - * but should be set to zero! - */ - tp->scb.Parm[0] = 0; - tp->scb.Parm[1] = 0; - } - else - { - if(tp->CMDqueue & OC_TRANSMIT) - { - /* NOTE: TRANSMIT must be - * checked after TRANSMIT.HALT - */ - if(tp->TransmitCommandActive) - { - if(!tp->TransmitHaltScheduled) - { - tp->TransmitHaltScheduled = 1; - tms380tr_exec_cmd(dev, OC_TRANSMIT_HALT) ; - } - tp->TransmitCommandActive = 0; - return; - } - - tp->CMDqueue ^= OC_TRANSMIT; - tms380tr_cancel_tx_queue(tp); - Addr = htonl(((char *)tp->TplBusy - (char *)tp) + tp->dmabuffer); - tp->scb.Parm[0] = LOWORD(Addr); - tp->scb.Parm[1] = HIWORD(Addr); - tp->scb.CMD = TRANSMIT; - tp->TransmitCommandActive = 1; - } - else - { - if(tp->CMDqueue & OC_MODIFY_OPEN_PARMS) - { - tp->CMDqueue ^= OC_MODIFY_OPEN_PARMS; - tp->scb.Parm[0] = tp->ocpl.OPENOptions; /* new OPEN options*/ - tp->scb.Parm[0] |= ENABLE_FULL_DUPLEX_SELECTION; - tp->scb.Parm[1] = 0; /* is ignored but should be zero */ - tp->scb.CMD = MODIFY_OPEN_PARMS; - } - else - { - if(tp->CMDqueue & OC_SET_FUNCT_ADDR) - { - tp->CMDqueue ^= OC_SET_FUNCT_ADDR; - tp->scb.Parm[0] = LOWORD(tp->ocpl.FunctAddr); - tp->scb.Parm[1] = HIWORD(tp->ocpl.FunctAddr); - tp->scb.CMD = SET_FUNCT_ADDR; - } - else - { - if(tp->CMDqueue & OC_SET_GROUP_ADDR) - { - tp->CMDqueue ^= OC_SET_GROUP_ADDR; - tp->scb.Parm[0] = LOWORD(tp->ocpl.GroupAddr); - tp->scb.Parm[1] = HIWORD(tp->ocpl.GroupAddr); - tp->scb.CMD = SET_GROUP_ADDR; - } - else - { - if(tp->CMDqueue & OC_READ_ERROR_LOG) - { - tp->CMDqueue ^= OC_READ_ERROR_LOG; - Addr = htonl(((char *)&tp->errorlogtable - (char *)tp) + tp->dmabuffer); - tp->scb.Parm[0] = LOWORD(Addr); - tp->scb.Parm[1] = HIWORD(Addr); - tp->scb.CMD = READ_ERROR_LOG; - } - else - { - printk(KERN_WARNING "CheckForOutstandingCommand: unknown Command\n"); - tp->CMDqueue = 0; - return; - } - } - } - } - } + } else if (tp->CMDqueue & OC_RECEIVE) { + tp->CMDqueue ^= OC_RECEIVE; + Addr = htonl(((char *)tp->RplHead - (char *)tp) + tp->dmabuffer); + tp->scb.Parm[0] = LOWORD(Addr); + tp->scb.Parm[1] = HIWORD(Addr); + tp->scb.CMD = RECEIVE; + } else if (tp->CMDqueue & OC_TRANSMIT_HALT) { + /* NOTE: TRANSMIT.HALT must be checked + * before TRANSMIT. + */ + tp->CMDqueue ^= OC_TRANSMIT_HALT; + tp->scb.CMD = TRANSMIT_HALT; + + /* Parm[0] and Parm[1] are ignored + * but should be set to zero! + */ + tp->scb.Parm[0] = 0; + tp->scb.Parm[1] = 0; + } else if (tp->CMDqueue & OC_TRANSMIT) { + /* NOTE: TRANSMIT must be + * checked after TRANSMIT.HALT + */ + if (tp->TransmitCommandActive) { + if (!tp->TransmitHaltScheduled) { + tp->TransmitHaltScheduled = 1; + tms380tr_exec_cmd(dev, OC_TRANSMIT_HALT); } + tp->TransmitCommandActive = 0; + return; } + + tp->CMDqueue ^= OC_TRANSMIT; + tms380tr_cancel_tx_queue(tp); + Addr = htonl(((char *)tp->TplBusy - (char *)tp) + tp->dmabuffer); + tp->scb.Parm[0] = LOWORD(Addr); + tp->scb.Parm[1] = HIWORD(Addr); + tp->scb.CMD = TRANSMIT; + tp->TransmitCommandActive = 1; + } else if (tp->CMDqueue & OC_MODIFY_OPEN_PARMS) { + tp->CMDqueue ^= OC_MODIFY_OPEN_PARMS; + tp->scb.Parm[0] = tp->ocpl.OPENOptions; /* new OPEN options*/ + tp->scb.Parm[0] |= ENABLE_FULL_DUPLEX_SELECTION; + tp->scb.Parm[1] = 0; /* is ignored but should be zero */ + tp->scb.CMD = MODIFY_OPEN_PARMS; + } else if (tp->CMDqueue & OC_SET_FUNCT_ADDR) { + tp->CMDqueue ^= OC_SET_FUNCT_ADDR; + tp->scb.Parm[0] = LOWORD(tp->ocpl.FunctAddr); + tp->scb.Parm[1] = HIWORD(tp->ocpl.FunctAddr); + tp->scb.CMD = SET_FUNCT_ADDR; + } else if (tp->CMDqueue & OC_SET_GROUP_ADDR) { + tp->CMDqueue ^= OC_SET_GROUP_ADDR; + tp->scb.Parm[0] = LOWORD(tp->ocpl.GroupAddr); + tp->scb.Parm[1] = HIWORD(tp->ocpl.GroupAddr); + tp->scb.CMD = SET_GROUP_ADDR; + } else if (tp->CMDqueue & OC_READ_ERROR_LOG) { + tp->CMDqueue ^= OC_READ_ERROR_LOG; + Addr = htonl(((char *)&tp->errorlogtable - (char *)tp) + tp->dmabuffer); + tp->scb.Parm[0] = LOWORD(Addr); + tp->scb.Parm[1] = HIWORD(Addr); + tp->scb.CMD = READ_ERROR_LOG; + } else { + printk(KERN_WARNING "CheckForOutstandingCommand: unknown Command\n"); + tp->CMDqueue = 0; + return; } } -- cgit v1.2.3-70-g09d2 From 8d9eb069eafce49307f839783e4a4673414b1fd5 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Fri, 3 Feb 2012 03:27:38 +0000 Subject: mlx4: Fix typo in cmd.c Correct spelling "reseting" to "resetting" in drivers/net/ethernet/mellanox/mlx4/cmd.c Signed-off-by: Masanari Iida Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/cmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index 405e6ac3faf..1831ddeebc4 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c @@ -1314,7 +1314,7 @@ static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd, down(&priv->cmd.slave_sem); if (mlx4_master_process_vhcr(dev, slave, NULL)) { mlx4_err(dev, "Failed processing vhcr for slave:%d," - " reseting slave.\n", slave); + " resetting slave.\n", slave); up(&priv->cmd.slave_sem); goto reset_slave; } -- cgit v1.2.3-70-g09d2 From 68aeb9683fa683357fa4b3d4f4347c64289c1ff7 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Wed, 25 Jan 2012 00:25:52 +0900 Subject: iommu: Fix typo in intel-iommu.c Correct spelling "supportd" to "supported" in drivers/iommu/intel-iommu.c Signed-off-by: Masanari Iida Signed-off-by: Jiri Kosina --- drivers/iommu/intel-iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index c9c6053198d..e23f273f7cb 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -1241,7 +1241,7 @@ static int iommu_init_domains(struct intel_iommu *iommu) unsigned long nlongs; ndomains = cap_ndoms(iommu->cap); - pr_debug("IOMMU %d: Number of Domains supportd <%ld>\n", iommu->seq_id, + pr_debug("IOMMU %d: Number of Domains supported <%ld>\n", iommu->seq_id, ndomains); nlongs = BITS_TO_LONGS(ndomains); -- cgit v1.2.3-70-g09d2 From 04a5602db4a07ef3cad3eff5c757384096ab8758 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Wed, 25 Jan 2012 00:35:41 +0900 Subject: staging: Fix typo in ieee80211_rx.c Correct spelling "suppported" to "supported" in drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c Signed-off-by: Masanari iida Signed-off-by: Jiri Kosina --- drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c index c9bdc7f6bdc..be2a28cf8ed 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c @@ -237,7 +237,7 @@ ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb, #ifdef NOT_YET if (ieee->iw_mode == IW_MODE_MASTER) { - printk(KERN_DEBUG "%s: Master mode not yet suppported.\n", + printk(KERN_DEBUG "%s: Master mode not yet supported.\n", ieee->dev->name); return 0; /* -- cgit v1.2.3-70-g09d2 From 1aa76df4f26bf02be1dde8ee3c3d16c4c5433a26 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Wed, 25 Jan 2012 23:14:56 +0900 Subject: staging: Fix typo in mei/interrupt.c Correct spelling "reseting" to "resetting" in drivers/staging/mei/interrupt.c Signed-off-by: Masanari Iida Signed-off-by: Jiri Kosina --- drivers/staging/mei/interrupt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/mei/interrupt.c b/drivers/staging/mei/interrupt.c index 3544fee34e4..e85a85a9603 100644 --- a/drivers/staging/mei/interrupt.c +++ b/drivers/staging/mei/interrupt.c @@ -1423,7 +1423,7 @@ void mei_timer(struct work_struct *work) if (dev->iamthif_stall_timer) { if (--dev->iamthif_stall_timer == 0) { - dev_dbg(&dev->pdev->dev, "reseting because of hang to amthi.\n"); + dev_dbg(&dev->pdev->dev, "resetting because of hang to amthi.\n"); mei_reset(dev, 1); dev->iamthif_msg_buf_size = 0; dev->iamthif_msg_buf_index = 0; -- cgit v1.2.3-70-g09d2 From 3f4f27e1783b3fe57f1f8c441b1376fae48dfb15 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Fri, 27 Jan 2012 00:32:19 +0900 Subject: aic7xxx: Fix typo in aic7xxx Correct spelling "staus" to "status" in aic79xx_core.c and Correct spelling "staus" to "status" in aic7xxx_core.c and Correct spelling "supportd" to "supported" in aic79xx_core.c Signed-off-by: Masanari Iida Signed-off-by: Jiri Kosina --- drivers/scsi/aic7xxx/aic79xx_core.c | 4 ++-- drivers/scsi/aic7xxx/aic7xxx_core.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index 5f8617dd43b..25417d0e7ac 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c @@ -8993,7 +8993,7 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb) printk("Invalid Command IU Field\n"); break; case SIU_PFC_TMF_NOT_SUPPORTED: - printk("TMF not supportd\n"); + printk("TMF not supported\n"); break; case SIU_PFC_TMF_FAILED: printk("TMF failed\n"); @@ -9113,7 +9113,7 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb) break; } case SCSI_STATUS_OK: - printk("%s: Interrupted for staus of 0???\n", + printk("%s: Interrupted for status of 0???\n", ahd_name(ahd)); /* FALLTHROUGH */ default: diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c index dc28b0a91b2..10172a3af1b 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_core.c +++ b/drivers/scsi/aic7xxx/aic7xxx_core.c @@ -1049,7 +1049,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat) ahc_set_scsi_status(scb, hscb->shared_data.status.scsi_status); switch (hscb->shared_data.status.scsi_status) { case SCSI_STATUS_OK: - printk("%s: Interrupted for staus of 0???\n", + printk("%s: Interrupted for status of 0???\n", ahc_name(ahc)); break; case SCSI_STATUS_CMD_TERMINATED: -- cgit v1.2.3-70-g09d2 From b6d60fde1c9bbaa9fc9068eff4657f52b309cdea Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Fri, 27 Jan 2012 22:47:04 +0900 Subject: media: Fix typo in lmedm04.c Correct spelling "reseting" to "resetting" in drivers/media/dvb/dvb-usb/lmedm04.c Signed-off-by: Masanari Iida Signed-off-by: Jiri Kosina --- drivers/media/dvb/dvb-usb/lmedm04.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/lmedm04.c b/drivers/media/dvb/dvb-usb/lmedm04.c index b3fe05bbffc..291f6b11039 100644 --- a/drivers/media/dvb/dvb-usb/lmedm04.c +++ b/drivers/media/dvb/dvb-usb/lmedm04.c @@ -1054,7 +1054,7 @@ static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap) if (ret) info("TUN Found %s tuner", tun_msg[ret]); else { - info("TUN No tuner found --- reseting device"); + info("TUN No tuner found --- resetting device"); lme_coldreset(adap->dev->udev); return -ENODEV; } -- cgit v1.2.3-70-g09d2 From b6695e411f46036bcaab29908e8aa46fbbe101ed Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Fri, 27 Jan 2012 23:00:53 +0900 Subject: dma: Fix typo in iop-adma.c Correct spelling "allocted" to "allocated" in drivers/dma/iop-adma.c Signed-off-by: Masanari Iida Signed-off-by: Jiri Kosina --- drivers/dma/iop-adma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c index 04be90b645b..faf88b7e1e7 100644 --- a/drivers/dma/iop-adma.c +++ b/drivers/dma/iop-adma.c @@ -1482,7 +1482,7 @@ static int __devinit iop_adma_probe(struct platform_device *pdev) goto err_free_adev; } - dev_dbg(&pdev->dev, "%s: allocted descriptor pool virt %p phys %p\n", + dev_dbg(&pdev->dev, "%s: allocated descriptor pool virt %p phys %p\n", __func__, adev->dma_desc_pool_virt, (void *) adev->dma_desc_pool); -- cgit v1.2.3-70-g09d2 From 629398eae5d77dd08101b736f7d2faab3fc94725 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Sat, 28 Jan 2012 00:04:51 +0900 Subject: media: Fix typo in ov6650.c Correct spelling "unspported" to "unsupported" in drivers/media/video/ov6650.c Signed-off-by: Masanari Iida Signed-off-by: Jiri Kosina --- drivers/media/video/ov6650.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/ov6650.c b/drivers/media/video/ov6650.c index 6806345ec2f..3627f3225bb 100644 --- a/drivers/media/video/ov6650.c +++ b/drivers/media/video/ov6650.c @@ -649,7 +649,7 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) clkrc = CLKRC_24MHz; } else { dev_err(&client->dev, - "unspported input clock, check platform data\n"); + "unsupported input clock, check platform data\n"); return -EINVAL; } mclk = sense->master_clock; -- cgit v1.2.3-70-g09d2 From 4aa6ded9fa72a584f3e646b52c64238426b0103a Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Sun, 29 Jan 2012 21:58:57 +0900 Subject: mmc: Fix typo in s3cmci.c Correct typo "resouce" to "resource" in drivers/mmc/host/s3cmci.c Signed-off-by: Masanari Iida Signed-off-by: Jiri Kosina --- drivers/mmc/host/s3cmci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 1bcfd6dbb5c..c3622a69f43 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -1606,7 +1606,7 @@ static int __devinit s3cmci_probe(struct platform_device *pdev) host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!host->mem) { dev_err(&pdev->dev, - "failed to get io memory region resouce.\n"); + "failed to get io memory region resource.\n"); ret = -ENOENT; goto probe_free_gpio; @@ -1630,7 +1630,7 @@ static int __devinit s3cmci_probe(struct platform_device *pdev) host->irq = platform_get_irq(pdev, 0); if (host->irq == 0) { - dev_err(&pdev->dev, "failed to get interrupt resouce.\n"); + dev_err(&pdev->dev, "failed to get interrupt resource.\n"); ret = -EINVAL; goto probe_iounmap; } -- cgit v1.2.3-70-g09d2 From 3472a2caa49b55c2923e7c876aa84f13eb4b8863 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Fri, 3 Feb 2012 22:56:59 +0900 Subject: frontends: Fix typo in tda1004x.c Correct spelling "alocate" to "allocate" in drivers/media/dvb/frontends/tda1004x.c Signed-off-by: Masanari Iida Signed-off-by: Jiri Kosina --- drivers/media/dvb/frontends/tda1004x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c index ae6f22aae67..35d72b46aa1 100644 --- a/drivers/media/dvb/frontends/tda1004x.c +++ b/drivers/media/dvb/frontends/tda1004x.c @@ -1272,7 +1272,7 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, /* allocate memory for the internal state */ state = kzalloc(sizeof(struct tda1004x_state), GFP_KERNEL); if (!state) { - printk(KERN_ERR "Can't alocate memory for tda10045 state\n"); + printk(KERN_ERR "Can't allocate memory for tda10045 state\n"); return NULL; } @@ -1342,7 +1342,7 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, /* allocate memory for the internal state */ state = kzalloc(sizeof(struct tda1004x_state), GFP_KERNEL); if (!state) { - printk(KERN_ERR "Can't alocate memory for tda10046 state\n"); + printk(KERN_ERR "Can't allocate memory for tda10046 state\n"); return NULL; } -- cgit v1.2.3-70-g09d2 From 496259048e6c75a212fa1c5bb863cfd6b008903c Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Sun, 5 Feb 2012 22:50:36 +0900 Subject: drm: Fix typo in vmwgfx_drv.c Correct spelling "unsuported" to "unsupported" in drivers/gpu/drm/vmwgfx/vmwgfx_drv.c Signed-off-by: Masanari Iida Signed-off-by: Jiri Kosina --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index f390f5f9cb6..2d6f573bfff 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -430,7 +430,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) svga_id = vmw_read(dev_priv, SVGA_REG_ID); if (svga_id != SVGA_ID_2) { ret = -ENOSYS; - DRM_ERROR("Unsuported SVGA ID 0x%x\n", svga_id); + DRM_ERROR("Unsupported SVGA ID 0x%x\n", svga_id); mutex_unlock(&dev_priv->hw_mutex); goto out_err0; } -- cgit v1.2.3-70-g09d2 From 481e6283bbccc20a3a7e6a8e50f9562a20e9b45d Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Sun, 5 Feb 2012 23:01:34 +0900 Subject: drm: Fix typo in rv515.c Correct spelling "reseting" to "resetting" in drivers/gpu/drm/radeon/rv515.c Signed-off-by: Masanari Iida Signed-off-by: Jiri Kosina --- drivers/gpu/drm/radeon/rv515.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 880637fd194..8787b18d637 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c @@ -150,7 +150,7 @@ void rv515_gpu_init(struct radeon_device *rdev) if (r100_gui_wait_for_idle(rdev)) { printk(KERN_WARNING "Failed to wait GUI idle while " - "reseting GPU. Bad things might happen.\n"); + "resetting GPU. Bad things might happen.\n"); } rv515_vga_render_disable(rdev); r420_pipes_init(rdev); @@ -162,7 +162,7 @@ void rv515_gpu_init(struct radeon_device *rdev) WREG32_PLL(0x000D, tmp); if (r100_gui_wait_for_idle(rdev)) { printk(KERN_WARNING "Failed to wait GUI idle while " - "reseting GPU. Bad things might happen.\n"); + "resetting GPU. Bad things might happen.\n"); } if (rv515_mc_wait_for_idle(rdev)) { printk(KERN_WARNING "Failed to wait MC idle while " -- cgit v1.2.3-70-g09d2 From bd393dbd33aeae0bb239f3c69938d37cc55193ca Mon Sep 17 00:00:00 2001 From: Stefan Achatz Date: Thu, 29 Dec 2011 17:20:14 +0100 Subject: HID: roccat: Only one Kconfig entry for all roccat drivers To cleanup Kconfig space and ease selection for users there is now a single entry that selects all roccat related drivers at once. Signed-off-by: Stefan Achatz Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 55 ++++------------------------------------------------ drivers/hid/Makefile | 11 +++-------- 2 files changed, 7 insertions(+), 59 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index a421abdd1ab..5a763d5a7bf 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -476,59 +476,12 @@ config HID_PRIMAX HID standard. config HID_ROCCAT - tristate "Roccat special event support" + tristate "Roccat device support" depends on USB_HID - select HID_ROCCAT_COMMON ---help--- - Support for Roccat special events. - Say Y here if you have a Roccat mouse or keyboard and want OSD or - macro execution support. - -config HID_ROCCAT_COMMON - tristate - depends on HID_ROCCAT - -config HID_ROCCAT_ARVO - tristate "Roccat Arvo keyboard support" - depends on USB_HID - depends on HID_ROCCAT - ---help--- - Support for Roccat Arvo keyboard. - -config HID_ROCCAT_ISKU - tristate "Roccat Isku keyboard support" - depends on USB_HID - depends on HID_ROCCAT - ---help--- - Support for Roccat Isku keyboard. - -config HID_ROCCAT_KONE - tristate "Roccat Kone Mouse support" - depends on USB_HID - depends on HID_ROCCAT - ---help--- - Support for Roccat Kone mouse. - -config HID_ROCCAT_KONEPLUS - tristate "Roccat Kone[+] mouse support" - depends on USB_HID - depends on HID_ROCCAT - ---help--- - Support for Roccat Kone[+] mouse. - -config HID_ROCCAT_KOVAPLUS - tristate "Roccat Kova[+] mouse support" - depends on USB_HID - depends on HID_ROCCAT - ---help--- - Support for Roccat Kova[+] mouse. - -config HID_ROCCAT_PYRA - tristate "Roccat Pyra mouse support" - depends on USB_HID - depends on HID_ROCCAT - ---help--- - Support for Roccat Pyra mouse. + Support for Roccat devices. + Say Y here if you have a Roccat mouse or keyboard and want + support for its special functionalities. config HID_SAMSUNG tristate "Samsung InfraRed remote control or keyboards" diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 8aefdc963cc..7d926719e21 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -64,14 +64,9 @@ obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o obj-$(CONFIG_HID_PRIMAX) += hid-primax.o -obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o -obj-$(CONFIG_HID_ROCCAT_COMMON) += hid-roccat-common.o -obj-$(CONFIG_HID_ROCCAT_ARVO) += hid-roccat-arvo.o -obj-$(CONFIG_HID_ROCCAT_ISKU) += hid-roccat-isku.o -obj-$(CONFIG_HID_ROCCAT_KONE) += hid-roccat-kone.o -obj-$(CONFIG_HID_ROCCAT_KONEPLUS) += hid-roccat-koneplus.o -obj-$(CONFIG_HID_ROCCAT_KOVAPLUS) += hid-roccat-kovaplus.o -obj-$(CONFIG_HID_ROCCAT_PYRA) += hid-roccat-pyra.o +obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \ + hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \ + hid-roccat-koneplus.o hid-roccat-kovaplus.o hid-roccat-pyra.o obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o obj-$(CONFIG_HID_SONY) += hid-sony.o -- cgit v1.2.3-70-g09d2 From 5fccab3b66d53883a97fc65e0c33f3ebf74e8ff9 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Sun, 5 Feb 2012 12:13:08 +0000 Subject: net/hyperv: Convert camel cased variables in rndis_filter.c to lower cases Signed-off-by: Haiyang Zhang Signed-off-by: K. Y. Srinivasan Reviewed-by: Jesper Juhl Signed-off-by: David S. Miller --- drivers/net/hyperv/rndis_filter.c | 60 +++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index 133b7fbf859..a60e5e2e621 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c @@ -758,66 +758,66 @@ int rndis_filter_open(struct hv_device *dev) int rndis_filter_close(struct hv_device *dev) { - struct netvsc_device *netDevice = hv_get_drvdata(dev); + struct netvsc_device *nvdev = hv_get_drvdata(dev); - if (!netDevice) + if (!nvdev) return -EINVAL; - return rndis_filter_close_device(netDevice->extension); + return rndis_filter_close_device(nvdev->extension); } int rndis_filter_send(struct hv_device *dev, struct hv_netvsc_packet *pkt) { int ret; - struct rndis_filter_packet *filterPacket; - struct rndis_message *rndisMessage; - struct rndis_packet *rndisPacket; - u32 rndisMessageSize; + struct rndis_filter_packet *filter_pkt; + struct rndis_message *rndis_msg; + struct rndis_packet *rndis_pkt; + u32 rndis_msg_size; /* Add the rndis header */ - filterPacket = (struct rndis_filter_packet *)pkt->extension; + filter_pkt = (struct rndis_filter_packet *)pkt->extension; - memset(filterPacket, 0, sizeof(struct rndis_filter_packet)); + memset(filter_pkt, 0, sizeof(struct rndis_filter_packet)); - rndisMessage = &filterPacket->msg; - rndisMessageSize = RNDIS_MESSAGE_SIZE(struct rndis_packet); + rndis_msg = &filter_pkt->msg; + rndis_msg_size = RNDIS_MESSAGE_SIZE(struct rndis_packet); - rndisMessage->ndis_msg_type = REMOTE_NDIS_PACKET_MSG; - rndisMessage->msg_len = pkt->total_data_buflen + - rndisMessageSize; + rndis_msg->ndis_msg_type = REMOTE_NDIS_PACKET_MSG; + rndis_msg->msg_len = pkt->total_data_buflen + + rndis_msg_size; - rndisPacket = &rndisMessage->msg.pkt; - rndisPacket->data_offset = sizeof(struct rndis_packet); - rndisPacket->data_len = pkt->total_data_buflen; + rndis_pkt = &rndis_msg->msg.pkt; + rndis_pkt->data_offset = sizeof(struct rndis_packet); + rndis_pkt->data_len = pkt->total_data_buflen; pkt->is_data_pkt = true; - pkt->page_buf[0].pfn = virt_to_phys(rndisMessage) >> PAGE_SHIFT; + pkt->page_buf[0].pfn = virt_to_phys(rndis_msg) >> PAGE_SHIFT; pkt->page_buf[0].offset = - (unsigned long)rndisMessage & (PAGE_SIZE-1); - pkt->page_buf[0].len = rndisMessageSize; + (unsigned long)rndis_msg & (PAGE_SIZE-1); + pkt->page_buf[0].len = rndis_msg_size; /* Add one page_buf if the rndis msg goes beyond page boundary */ - if (pkt->page_buf[0].offset + rndisMessageSize > PAGE_SIZE) { + if (pkt->page_buf[0].offset + rndis_msg_size > PAGE_SIZE) { int i; for (i = pkt->page_buf_cnt; i > 1; i--) pkt->page_buf[i] = pkt->page_buf[i-1]; pkt->page_buf_cnt++; pkt->page_buf[0].len = PAGE_SIZE - pkt->page_buf[0].offset; pkt->page_buf[1].pfn = virt_to_phys((void *)((ulong) - rndisMessage + pkt->page_buf[0].len)) >> PAGE_SHIFT; + rndis_msg + pkt->page_buf[0].len)) >> PAGE_SHIFT; pkt->page_buf[1].offset = 0; - pkt->page_buf[1].len = rndisMessageSize - pkt->page_buf[0].len; + pkt->page_buf[1].len = rndis_msg_size - pkt->page_buf[0].len; } /* Save the packet send completion and context */ - filterPacket->completion = pkt->completion.send.send_completion; - filterPacket->completion_ctx = + filter_pkt->completion = pkt->completion.send.send_completion; + filter_pkt->completion_ctx = pkt->completion.send.send_completion_ctx; /* Use ours */ pkt->completion.send.send_completion = rndis_filter_send_completion; - pkt->completion.send.send_completion_ctx = filterPacket; + pkt->completion.send.send_completion_ctx = filter_pkt; ret = netvsc_send(dev, pkt); if (ret != 0) { @@ -826,9 +826,9 @@ int rndis_filter_send(struct hv_device *dev, * above */ pkt->completion.send.send_completion = - filterPacket->completion; + filter_pkt->completion; pkt->completion.send.send_completion_ctx = - filterPacket->completion_ctx; + filter_pkt->completion_ctx; } return ret; @@ -836,10 +836,10 @@ int rndis_filter_send(struct hv_device *dev, static void rndis_filter_send_completion(void *ctx) { - struct rndis_filter_packet *filterPacket = ctx; + struct rndis_filter_packet *filter_pkt = ctx; /* Pass it back to the original handler */ - filterPacket->completion(filterPacket->completion_ctx); + filter_pkt->completion(filter_pkt->completion_ctx); } -- cgit v1.2.3-70-g09d2 From 6f4c44460750dd4eb9926a58ab1ad0ceacef8284 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Sun, 5 Feb 2012 12:13:09 +0000 Subject: net/hyperv: Correct the assignment in netvsc_recv_callback() The first assignment to variable "net" is wrong, but overridden by the latter assignments. So the bug isn't manifested. Signed-off-by: Haiyang Zhang Signed-off-by: K. Y. Srinivasan Signed-off-by: David S. Miller --- drivers/net/hyperv/netvsc_drv.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 466c58a7353..0ae7a1a6aeb 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -267,13 +267,10 @@ void netvsc_linkstatus_callback(struct hv_device *device_obj, int netvsc_recv_callback(struct hv_device *device_obj, struct hv_netvsc_packet *packet) { - struct net_device *net = dev_get_drvdata(&device_obj->device); + struct net_device *net; struct sk_buff *skb; - struct netvsc_device *net_device; - - net_device = hv_get_drvdata(device_obj); - net = net_device->ndev; + net = ((struct netvsc_device *)hv_get_drvdata(device_obj))->ndev; if (!net) { netdev_err(net, "got receive callback but net device" " not initialized yet\n"); -- cgit v1.2.3-70-g09d2 From bce60806de882cf15ad3a80a51e9878863a8fced Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Sun, 5 Feb 2012 12:13:10 +0000 Subject: net/hyperv: Remove the unnecessary memset in rndis_filter_send() The memory has been allocated by kzalloc, so it's unnecessary to memset again. Signed-off-by: Haiyang Zhang Signed-off-by: K. Y. Srinivasan Signed-off-by: David S. Miller --- drivers/net/hyperv/rndis_filter.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index a60e5e2e621..136efd84373 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c @@ -778,8 +778,6 @@ int rndis_filter_send(struct hv_device *dev, /* Add the rndis header */ filter_pkt = (struct rndis_filter_packet *)pkt->extension; - memset(filter_pkt, 0, sizeof(struct rndis_filter_packet)); - rndis_msg = &filter_pkt->msg; rndis_msg_size = RNDIS_MESSAGE_SIZE(struct rndis_packet); -- cgit v1.2.3-70-g09d2 From b9d6d2dbf45b038a94c63295203525101a9fbbb7 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sun, 5 Feb 2012 13:18:57 +0000 Subject: bonding: Fix misspelling of "since" Signed-off-by: Jesper Juhl Signed-off-by: David S. Miller --- drivers/net/bonding/bond_3ad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 0ae0d7c54cc..793b0013827 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -660,7 +660,7 @@ static void __attach_bond_to_agg(struct port *port) static void __detach_bond_from_agg(struct port *port) { port = NULL; /* just to satisfy the compiler */ - // This function does nothing sience the parser/multiplexer of the receive + // This function does nothing since the parser/multiplexer of the receive // and the parser/multiplexer of the aggregator are already combined } -- cgit v1.2.3-70-g09d2 From b033281f618fa40ee1b24a60cd8043b4979bfee4 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sun, 5 Feb 2012 15:24:38 +0000 Subject: bnx2: Add support for ethtool --show-channels|--set-channels Allow the user to override the default number of RSS/TSS rings. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2.c | 99 ++++++++++++++++++++++++++++++++---- drivers/net/ethernet/broadcom/bnx2.h | 3 ++ 2 files changed, 93 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index 0a4c5405dcf..2ab31daef80 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -6246,7 +6246,16 @@ static int bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi) { int cpus = num_online_cpus(); - int msix_vecs = min(cpus + 1, RX_MAX_RINGS); + int msix_vecs; + + if (!bp->num_req_rx_rings) + msix_vecs = max(cpus + 1, bp->num_req_tx_rings); + else if (!bp->num_req_tx_rings) + msix_vecs = max(cpus, bp->num_req_rx_rings); + else + msix_vecs = max(bp->num_req_rx_rings, bp->num_req_tx_rings); + + msix_vecs = min(msix_vecs, RX_MAX_RINGS); bp->irq_tbl[0].handler = bnx2_interrupt; strcpy(bp->irq_tbl[0].name, bp->dev->name); @@ -6270,10 +6279,18 @@ bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi) } } - bp->num_tx_rings = rounddown_pow_of_two(bp->irq_nvecs); + if (!bp->num_req_tx_rings) + bp->num_tx_rings = rounddown_pow_of_two(bp->irq_nvecs); + else + bp->num_tx_rings = min(bp->irq_nvecs, bp->num_req_tx_rings); + + if (!bp->num_req_rx_rings) + bp->num_rx_rings = bp->irq_nvecs; + else + bp->num_rx_rings = min(bp->irq_nvecs, bp->num_req_rx_rings); + netif_set_real_num_tx_queues(bp->dev, bp->num_tx_rings); - bp->num_rx_rings = bp->irq_nvecs; return netif_set_real_num_rx_queues(bp->dev, bp->num_rx_rings); } @@ -7162,7 +7179,7 @@ bnx2_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) } static int -bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx) +bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx, bool reset_irq) { if (netif_running(bp->dev)) { /* Reset will erase chipset stats; save them */ @@ -7170,7 +7187,12 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx) bnx2_netif_stop(bp, true); bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET); - __bnx2_free_irq(bp); + if (reset_irq) { + bnx2_free_irq(bp); + bnx2_del_napi(bp); + } else { + __bnx2_free_irq(bp); + } bnx2_free_skbs(bp); bnx2_free_mem(bp); } @@ -7179,9 +7201,16 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx) bp->tx_ring_size = tx; if (netif_running(bp->dev)) { - int rc; + int rc = 0; + + if (reset_irq) { + rc = bnx2_setup_int_mode(bp, disable_msi); + bnx2_init_napi(bp); + } + + if (!rc) + rc = bnx2_alloc_mem(bp); - rc = bnx2_alloc_mem(bp); if (!rc) rc = bnx2_request_irq(bp); @@ -7217,7 +7246,8 @@ bnx2_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) return -EINVAL; } - rc = bnx2_change_ring_size(bp, ering->rx_pending, ering->tx_pending); + rc = bnx2_change_ring_size(bp, ering->rx_pending, ering->tx_pending, + false); return rc; } @@ -7605,6 +7635,54 @@ bnx2_set_features(struct net_device *dev, netdev_features_t features) return 0; } +static void bnx2_get_channels(struct net_device *dev, + struct ethtool_channels *channels) +{ + struct bnx2 *bp = netdev_priv(dev); + u32 max_rx_rings = 1; + u32 max_tx_rings = 1; + + if ((bp->flags & BNX2_FLAG_MSIX_CAP) && !disable_msi) { + max_rx_rings = RX_MAX_RINGS; + max_tx_rings = TX_MAX_RINGS; + } + + channels->max_rx = max_rx_rings; + channels->max_tx = max_tx_rings; + channels->max_other = 0; + channels->max_combined = 0; + channels->rx_count = bp->num_rx_rings; + channels->tx_count = bp->num_tx_rings; + channels->other_count = 0; + channels->combined_count = 0; +} + +static int bnx2_set_channels(struct net_device *dev, + struct ethtool_channels *channels) +{ + struct bnx2 *bp = netdev_priv(dev); + u32 max_rx_rings = 1; + u32 max_tx_rings = 1; + int rc = 0; + + if ((bp->flags & BNX2_FLAG_MSIX_CAP) && !disable_msi) { + max_rx_rings = RX_MAX_RINGS; + max_tx_rings = TX_MAX_RINGS; + } + if (channels->rx_count > max_rx_rings || + channels->tx_count > max_tx_rings) + return -EINVAL; + + bp->num_req_rx_rings = channels->rx_count; + bp->num_req_tx_rings = channels->tx_count; + + if (netif_running(dev)) + rc = bnx2_change_ring_size(bp, bp->rx_ring_size, + bp->tx_ring_size, true); + + return rc; +} + static const struct ethtool_ops bnx2_ethtool_ops = { .get_settings = bnx2_get_settings, .set_settings = bnx2_set_settings, @@ -7629,6 +7707,8 @@ static const struct ethtool_ops bnx2_ethtool_ops = { .set_phys_id = bnx2_set_phys_id, .get_ethtool_stats = bnx2_get_ethtool_stats, .get_sset_count = bnx2_get_sset_count, + .get_channels = bnx2_get_channels, + .set_channels = bnx2_set_channels, }; /* Called with rtnl_lock */ @@ -7710,7 +7790,8 @@ bnx2_change_mtu(struct net_device *dev, int new_mtu) return -EINVAL; dev->mtu = new_mtu; - return bnx2_change_ring_size(bp, bp->rx_ring_size, bp->tx_ring_size); + return bnx2_change_ring_size(bp, bp->rx_ring_size, bp->tx_ring_size, + false); } #ifdef CONFIG_NET_POLL_CONTROLLER diff --git a/drivers/net/ethernet/broadcom/bnx2.h b/drivers/net/ethernet/broadcom/bnx2.h index 1db2d51ba3f..dc06bda73be 100644 --- a/drivers/net/ethernet/broadcom/bnx2.h +++ b/drivers/net/ethernet/broadcom/bnx2.h @@ -6933,6 +6933,9 @@ struct bnx2 { u8 num_tx_rings; u8 num_rx_rings; + int num_req_tx_rings; + int num_req_rx_rings; + u32 leds_save; u32 idle_chk_status_idx; -- cgit v1.2.3-70-g09d2 From 94bf91baf3a16ec274de3cd913be3033c029f853 Mon Sep 17 00:00:00 2001 From: Vlad Zolotarov Date: Sun, 5 Feb 2012 15:24:39 +0000 Subject: bnx2: Add missing memory barrier in bnx2_start_xmit() Sync DMA descriptor before hitting the TX mailbox for weak memory model CPUs. There has been discussions several years ago about this. Some believe that writel() should guarantee ordering. Others want explicit barriers if necessary. Today writel() does not have the ordering guarantee and many other drivers use explicit barriers. Signed-off-by: Vlad Zolotarov Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index 2ab31daef80..7105989ba65 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -6565,6 +6565,9 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) } txbd->tx_bd_vlan_tag_flags |= TX_BD_FLAGS_END; + /* Sync BD data before updating TX mailbox */ + wmb(); + netdev_tx_sent_queue(txq, skb->len); prod = NEXT_TX_BD(prod); -- cgit v1.2.3-70-g09d2 From 3238a9be4d7ad95c741bcfe6c147406eeef62d95 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sun, 5 Feb 2012 15:24:40 +0000 Subject: cnic: Add FCoE parity error recovery When bnx2x returns error on FCoE SPQ messages, generate an error completion to bnx2fc immediately to speed up error recovery. This will eliminate length timeouts and spped up the reset of the device. Signed-off-by: Bhanu Prakash Gollapudi Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/cnic.c | 38 +++++++++++++++++++++++++++---- drivers/net/ethernet/broadcom/cnic_defs.h | 3 ++- 2 files changed, 36 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index dd3a0a232ea..7381460142e 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c @@ -1,6 +1,6 @@ /* cnic.c: Broadcom CNIC core network driver. * - * Copyright (c) 2006-2011 Broadcom Corporation + * Copyright (c) 2006-2012 Broadcom 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 @@ -2521,12 +2521,35 @@ static void cnic_bnx2x_kwqe_err(struct cnic_dev *dev, struct kwqe *kwqe) u32 cid; u32 opcode = KWQE_OPCODE(kwqe->kwqe_op_flag); u32 layer_code = kwqe->kwqe_op_flag & KWQE_LAYER_MASK; + u32 kcqe_op; int ulp_type; cid = kwqe->kwqe_info0; memset(&kcqe, 0, sizeof(kcqe)); - if (layer_code == KWQE_FLAGS_LAYER_MASK_L5_ISCSI) { + if (layer_code == KWQE_FLAGS_LAYER_MASK_L5_FCOE) { + u32 l5_cid = 0; + + ulp_type = CNIC_ULP_FCOE; + if (opcode == FCOE_KWQE_OPCODE_DISABLE_CONN) { + struct fcoe_kwqe_conn_enable_disable *req; + + req = (struct fcoe_kwqe_conn_enable_disable *) kwqe; + kcqe_op = FCOE_KCQE_OPCODE_DISABLE_CONN; + cid = req->context_id; + l5_cid = req->conn_id; + } else if (opcode == FCOE_KWQE_OPCODE_DESTROY) { + kcqe_op = FCOE_KCQE_OPCODE_DESTROY_FUNC; + } else { + return; + } + kcqe.kcqe_op_flag = kcqe_op << KCQE_FLAGS_OPCODE_SHIFT; + kcqe.kcqe_op_flag |= KCQE_FLAGS_LAYER_MASK_L5_FCOE; + kcqe.kcqe_info1 = FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR; + kcqe.kcqe_info2 = cid; + kcqe.kcqe_info0 = l5_cid; + + } else if (layer_code == KWQE_FLAGS_LAYER_MASK_L5_ISCSI) { ulp_type = CNIC_ULP_ISCSI; if (opcode == ISCSI_KWQE_OPCODE_UPDATE_CONN) cid = kwqe->kwqe_info1; @@ -2539,7 +2562,6 @@ static void cnic_bnx2x_kwqe_err(struct cnic_dev *dev, struct kwqe *kwqe) } else if (layer_code == KWQE_FLAGS_LAYER_MASK_L4) { struct l4_kcq *l4kcqe = (struct l4_kcq *) &kcqe; - u32 kcqe_op; ulp_type = CNIC_ULP_L4; if (opcode == L4_KWQE_OPCODE_VALUE_CONNECT1) @@ -2686,9 +2708,17 @@ static int cnic_submit_bnx2x_fcoe_kwqes(struct cnic_dev *dev, opcode); break; } - if (ret < 0) + if (ret < 0) { netdev_err(dev->netdev, "KWQE(0x%x) failed\n", opcode); + + /* Possibly bnx2x parity error, send completion + * to ulp drivers with error code to speed up + * cleanup and reset recovery. + */ + if (ret == -EIO || ret == -EAGAIN) + cnic_bnx2x_kwqe_err(dev, kwqe); + } i += work; } return 0; diff --git a/drivers/net/ethernet/broadcom/cnic_defs.h b/drivers/net/ethernet/broadcom/cnic_defs.h index 86936f6b6db..7271f14bda3 100644 --- a/drivers/net/ethernet/broadcom/cnic_defs.h +++ b/drivers/net/ethernet/broadcom/cnic_defs.h @@ -1,7 +1,7 @@ /* cnic.c: Broadcom CNIC core network driver. * - * Copyright (c) 2006-2009 Broadcom Corporation + * Copyright (c) 2006-2012 Broadcom 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 @@ -69,6 +69,7 @@ #define FCOE_KCQE_COMPLETION_STATUS_ERROR (0x1) #define FCOE_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE (0x3) +#define FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR (0x5) /* KCQ (kernel completion queue) response op codes */ #define L4_KCQE_OPCODE_VALUE_CLOSE_COMP (53) -- cgit v1.2.3-70-g09d2 From 04a9bfcd50dd568a8f1a10194a7f336f6b3ad81c Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 2 Jan 2012 18:25:43 +0200 Subject: usb: dwc3: gadget: re-factor USB2 test mode to a function There are some situations were we might need to enable USB Test Modes without having access to a Host stack. In such situations we cannot rely solely on USB Control Messages to enable test features. For those cases, we will also allow test mode to be enabled via debugfs and this patch is a preparation for that. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/ep0.c | 23 +++++------------------ drivers/usb/dwc3/gadget.c | 33 +++++++++++++++++++++++++++++++++ drivers/usb/dwc3/gadget.h | 2 ++ 3 files changed, 40 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index c8df1dd967e..5eb7095e400 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -315,7 +315,6 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc, u32 recip; u32 wValue; u32 wIndex; - u32 reg; int ret; u32 mode; @@ -357,24 +356,12 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc, return -EINVAL; mode = wIndex >> 8; - reg = dwc3_readl(dwc->regs, DWC3_DCTL); - reg &= ~DWC3_DCTL_TSTCTRL_MASK; - - switch (mode) { - case TEST_J: - case TEST_K: - case TEST_SE0_NAK: - case TEST_PACKET: - case TEST_FORCE_EN: - reg |= mode << 1; - break; - default: - return -EINVAL; + ret = dwc3_gadget_set_test_mode(dwc, mode); + if (ret < 0) { + dev_dbg(dwc->dev, "Invalid Test #%d\n", + mode); + return ret; } - dwc3_writel(dwc->regs, DWC3_DCTL, reg); - break; - default: - return -EINVAL; } break; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 064b6e2cd41..1dee17e7b77 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -56,6 +56,39 @@ #define DMA_ADDR_INVALID (~(dma_addr_t)0) +/** + * dwc3_gadget_set_test_mode - Enables USB2 Test Modes + * @dwc: pointer to our context structure + * @mode: the mode to set (J, K SE0 NAK, Force Enable) + * + * Caller should take care of locking. This function will + * return 0 on success or -EINVAL if wrong Test Selector + * is passed + */ +int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode) +{ + u32 reg; + + reg = dwc3_readl(dwc->regs, DWC3_DCTL); + reg &= ~DWC3_DCTL_TSTCTRL_MASK; + + switch (mode) { + case TEST_J: + case TEST_K: + case TEST_SE0_NAK: + case TEST_PACKET: + case TEST_FORCE_EN: + reg |= mode << 1; + break; + default: + return -EINVAL; + } + + dwc3_writel(dwc->regs, DWC3_DCTL, reg); + + return 0; +} + void dwc3_map_buffer_to_dma(struct dwc3_request *req) { struct dwc3 *dwc = req->dep->dwc; diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h index d97f467d41c..2cf6f2989f7 100644 --- a/drivers/usb/dwc3/gadget.h +++ b/drivers/usb/dwc3/gadget.h @@ -100,6 +100,8 @@ static inline void dwc3_gadget_move_request_queued(struct dwc3_request *req) void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, int status); +int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode); + void dwc3_ep0_interrupt(struct dwc3 *dwc, const struct dwc3_event_depevt *event); void dwc3_ep0_out_start(struct dwc3 *dwc); -- cgit v1.2.3-70-g09d2 From 080d921fe7a8d27c07eba7723fe53a3bea100327 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 2 Jan 2012 18:38:30 +0200 Subject: usb: dwc3: gadget: allow testmodes changes via debugfs This is very useful for low level Link Testing where we might not have a USB Host stack, only a scope to verify signal integrity. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/debugfs.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index 433c97c15fc..c7e85024fda 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c @@ -46,6 +46,8 @@ #include #include +#include + #include "core.h" #include "gadget.h" #include "io.h" @@ -464,6 +466,89 @@ static const struct file_operations dwc3_mode_fops = { .release = single_release, }; +static int dwc3_testmode_show(struct seq_file *s, void *unused) +{ + struct dwc3 *dwc = s->private; + unsigned long flags; + u32 reg; + + spin_lock_irqsave(&dwc->lock, flags); + reg = dwc3_readl(dwc->regs, DWC3_DCTL); + reg &= DWC3_DCTL_TSTCTRL_MASK; + reg >>= 1; + spin_unlock_irqrestore(&dwc->lock, flags); + + switch (reg) { + case 0: + seq_printf(s, "no test\n"); + break; + case TEST_J: + seq_printf(s, "test_j\n"); + break; + case TEST_K: + seq_printf(s, "test_k\n"); + break; + case TEST_SE0_NAK: + seq_printf(s, "test_se0_nak\n"); + break; + case TEST_PACKET: + seq_printf(s, "test_packet\n"); + break; + case TEST_FORCE_EN: + seq_printf(s, "test_force_enable\n"); + break; + default: + seq_printf(s, "UNKNOWN %d\n", reg); + } + + return 0; +} + +static int dwc3_testmode_open(struct inode *inode, struct file *file) +{ + return single_open(file, dwc3_testmode_show, inode->i_private); +} + +static ssize_t dwc3_testmode_write(struct file *file, + const char __user *ubuf, size_t count, loff_t *ppos) +{ + struct seq_file *s = file->private_data; + struct dwc3 *dwc = s->private; + unsigned long flags; + u32 testmode = 0; + char buf[32]; + + if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) + return -EFAULT; + + if (!strncmp(buf, "test_j", 6)) + testmode = TEST_J; + else if (!strncmp(buf, "test_k", 6)) + testmode = TEST_K; + else if (!strncmp(buf, "test_se0_nak", 13)) + testmode = TEST_SE0_NAK; + else if (!strncmp(buf, "test_packet", 12)) + testmode = TEST_PACKET; + else if (!strncmp(buf, "test_force_enable", 18)) + testmode = TEST_FORCE_EN; + else + testmode = 0; + + spin_lock_irqsave(&dwc->lock, flags); + dwc3_gadget_set_test_mode(dwc, testmode); + spin_unlock_irqrestore(&dwc->lock, flags); + + return count; +} + +static const struct file_operations dwc3_testmode_fops = { + .open = dwc3_testmode_open, + .write = dwc3_testmode_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + int __devinit dwc3_debugfs_init(struct dwc3 *dwc) { struct dentry *root; @@ -492,6 +577,13 @@ int __devinit dwc3_debugfs_init(struct dwc3 *dwc) goto err1; } + file = debugfs_create_file("testmode", S_IRUGO | S_IWUSR, root, + dwc, &dwc3_testmode_fops); + if (IS_ERR(file)) { + ret = PTR_ERR(file); + goto err1; + } + return 0; err1: -- cgit v1.2.3-70-g09d2 From 8598bde7fa125e85bc97decd6513d37dcf1e7bd9 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 2 Jan 2012 18:55:57 +0200 Subject: usb: dwc3: gadget: re-factor Link state change to a function Most link changes will, of course, happen with the help of a matching host HW, but in some cases we might want to debug very low level details about the link and exposing this to debugfs sounds like a good plan. This is a preparation for such setup. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 52 +++++++++++++++++++++++++++++++++++++---------- drivers/usb/dwc3/gadget.h | 1 + 2 files changed, 42 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 1dee17e7b77..80003952547 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -89,6 +89,42 @@ int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode) return 0; } +/** + * dwc3_gadget_set_link_state - Sets USB Link to a particular State + * @dwc: pointer to our context structure + * @state: the state to put link into + * + * Caller should take care of locking. This function will + * return 0 on success or -EINVAL. + */ +int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state) +{ + int retries = 100; + u32 reg; + + reg = dwc3_readl(dwc->regs, DWC3_DCTL); + reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK; + + /* set requested state */ + reg |= DWC3_DCTL_ULSTCHNGREQ(state); + dwc3_writel(dwc->regs, DWC3_DCTL, reg); + + /* wait for a change in DSTS */ + while (--retries) { + reg = dwc3_readl(dwc->regs, DWC3_DSTS); + + /* in HS, means ON */ + if (DWC3_DSTS_USBLNKST(reg) == state) + return 0; + + usleep_range(500, 1500); + } + + dev_vdbg(dwc->dev, "link state change request timed out\n"); + + return -ETIMEDOUT; +} + void dwc3_map_buffer_to_dma(struct dwc3_request *req) { struct dwc3 *dwc = req->dep->dwc; @@ -1155,17 +1191,11 @@ static int dwc3_gadget_wakeup(struct usb_gadget *g) goto out; } - reg = dwc3_readl(dwc->regs, DWC3_DCTL); - - /* - * Switch link state to Recovery. In HS/FS/LS this means - * RemoteWakeup Request - */ - reg |= DWC3_DCTL_ULSTCHNG_RECOVERY; - dwc3_writel(dwc->regs, DWC3_DCTL, reg); - - /* wait for at least 2000us */ - usleep_range(2000, 2500); + ret = dwc3_gadget_set_link_state(dwc, DWC3_LINK_STATE_RECOV); + if (ret < 0) { + dev_err(dwc->dev, "failed to put link in Recovery\n"); + goto out; + } /* write zeroes to Link Change Request */ reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK; diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h index 2cf6f2989f7..152b6de0649 100644 --- a/drivers/usb/dwc3/gadget.h +++ b/drivers/usb/dwc3/gadget.h @@ -101,6 +101,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, int status); int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode); +int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state); void dwc3_ep0_interrupt(struct dwc3 *dwc, const struct dwc3_event_depevt *event); -- cgit v1.2.3-70-g09d2 From 138801aaa566ecb5a5739a85909b9ec7285efd70 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 2 Jan 2012 19:25:16 +0200 Subject: usb: dwc3: gadget: allow Link state changes via debugfs This is very useful for low level link testing where we might not have a USB Host stack, only a scope to verify signal integrity. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/debugfs.c | 110 +++++++++++++++++++++++++++++++++++++++++++++ drivers/usb/dwc3/gadget.c | 2 +- 2 files changed, 111 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index c7e85024fda..a2c1cc64b48 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c @@ -549,6 +549,109 @@ static const struct file_operations dwc3_testmode_fops = { .release = single_release, }; +static int dwc3_link_state_show(struct seq_file *s, void *unused) +{ + struct dwc3 *dwc = s->private; + unsigned long flags; + enum dwc3_link_state state; + u32 reg; + + spin_lock_irqsave(&dwc->lock, flags); + reg = dwc3_readl(dwc->regs, DWC3_DSTS); + state = DWC3_DSTS_USBLNKST(reg); + spin_unlock_irqrestore(&dwc->lock, flags); + + switch (state) { + case DWC3_LINK_STATE_U0: + seq_printf(s, "U0\n"); + break; + case DWC3_LINK_STATE_U1: + seq_printf(s, "U1\n"); + break; + case DWC3_LINK_STATE_U2: + seq_printf(s, "U2\n"); + break; + case DWC3_LINK_STATE_U3: + seq_printf(s, "U3\n"); + break; + case DWC3_LINK_STATE_SS_DIS: + seq_printf(s, "SS.Disabled\n"); + break; + case DWC3_LINK_STATE_RX_DET: + seq_printf(s, "Rx.Detect\n"); + break; + case DWC3_LINK_STATE_SS_INACT: + seq_printf(s, "SS.Inactive\n"); + break; + case DWC3_LINK_STATE_POLL: + seq_printf(s, "Poll\n"); + break; + case DWC3_LINK_STATE_RECOV: + seq_printf(s, "Recovery\n"); + break; + case DWC3_LINK_STATE_HRESET: + seq_printf(s, "HRESET\n"); + break; + case DWC3_LINK_STATE_CMPLY: + seq_printf(s, "Compliance\n"); + break; + case DWC3_LINK_STATE_LPBK: + seq_printf(s, "Loopback\n"); + break; + default: + seq_printf(s, "UNKNOWN %d\n", reg); + } + + return 0; +} + +static int dwc3_link_state_open(struct inode *inode, struct file *file) +{ + return single_open(file, dwc3_link_state_show, inode->i_private); +} + +static ssize_t dwc3_link_state_write(struct file *file, + const char __user *ubuf, size_t count, loff_t *ppos) +{ + struct seq_file *s = file->private_data; + struct dwc3 *dwc = s->private; + unsigned long flags; + enum dwc3_link_state state = 0; + char buf[32]; + + if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) + return -EFAULT; + + if (!strncmp(buf, "SS.Disabled", 11)) + state = DWC3_LINK_STATE_SS_DIS; + else if (!strncmp(buf, "Rx.Detect", 9)) + state = DWC3_LINK_STATE_RX_DET; + else if (!strncmp(buf, "SS.Inactive", 11)) + state = DWC3_LINK_STATE_SS_INACT; + else if (!strncmp(buf, "Recovery", 8)) + state = DWC3_LINK_STATE_RECOV; + else if (!strncmp(buf, "Compliance", 10)) + state = DWC3_LINK_STATE_CMPLY; + else if (!strncmp(buf, "Loopback", 8)) + state = DWC3_LINK_STATE_LPBK; + else + return -EINVAL; + + spin_lock_irqsave(&dwc->lock, flags); + dwc3_gadget_set_link_state(dwc, state); + spin_unlock_irqrestore(&dwc->lock, flags); + + return count; +} + +static const struct file_operations dwc3_link_state_fops = { + .open = dwc3_link_state_open, + .write = dwc3_link_state_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + int __devinit dwc3_debugfs_init(struct dwc3 *dwc) { struct dentry *root; @@ -584,6 +687,13 @@ int __devinit dwc3_debugfs_init(struct dwc3 *dwc) goto err1; } + file = debugfs_create_file("link_state", S_IRUGO | S_IWUSR, root, + dwc, &dwc3_link_state_fops); + if (IS_ERR(file)) { + ret = PTR_ERR(file); + goto err1; + } + return 0; err1: diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 80003952547..e0e2337dad1 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -117,7 +117,7 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state) if (DWC3_DSTS_USBLNKST(reg) == state) return 0; - usleep_range(500, 1500); + udelay(500); } dev_vdbg(dwc->dev, "link state change request timed out\n"); -- cgit v1.2.3-70-g09d2 From 40aa41fba348bc5bd19ff5bcf2b03d67bb01d1ce Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 18 Jan 2012 17:06:03 +0200 Subject: usb: dwc3: gadget: fix XferNotReady debug print Only bit 3 of the event status bitfield is valid and the others should not be considered. Make sure SW matches documentation on that case to avoid bogus debugging prints which would confuse an engineer. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.h | 5 +++++ drivers/usb/dwc3/gadget.c | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 9e57f8e9bf1..f4878c4dec0 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -719,6 +719,11 @@ struct dwc3_event_depevt { u32 endpoint_event:4; u32 reserved11_10:2; u32 status:4; + +/* Within XferNotReady */ +#define DEPEVT_STATUS_TRANSFER_ACTIVE (1 << 3) + +/* Within XferComplete */ #define DEPEVT_STATUS_BUSERR (1 << 0) #define DEPEVT_STATUS_SHORT (1 << 1) #define DEPEVT_STATUS_IOC (1 << 2) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index e0e2337dad1..4b64dc0bfa2 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1657,7 +1657,8 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, int ret; dev_vdbg(dwc->dev, "%s: reason %s\n", - dep->name, event->status + dep->name, event->status & + DEPEVT_STATUS_TRANSFER_ACTIVE ? "Transfer Active" : "Transfer Not Active"); -- cgit v1.2.3-70-g09d2 From 7b7dd0253cd50fdc413b4ec199f1f3af08b7ba0d Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 18 Jan 2012 17:09:17 +0200 Subject: usb: dwc3: gadget: use the descriptor pointer we hold We hold that pointer for one reason. It just looks nicer to use it. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 4b64dc0bfa2..d406a75456a 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -943,7 +943,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) int start_trans; start_trans = 1; - if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && + if (usb_endpoint_xfer_isoc(dep->desc) && dep->flags & DWC3_EP_BUSY) start_trans = 0; -- cgit v1.2.3-70-g09d2 From bb5cfd6811c63c47403e98028bde7e98bd7a1751 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 18 Jan 2012 20:18:45 +0200 Subject: usb: dwc3: ep0: move to CONFIGURED also on delayed status Mass Storage gadget will take some time to handle the SetConfiguration request, but even on those cases we should move to CONFIGURED state. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/ep0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 5eb7095e400..e90ebb9dd3e 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -457,7 +457,7 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) case DWC3_ADDRESS_STATE: ret = dwc3_ep0_delegate_req(dwc, ctrl); /* if the cfg matches and the cfg is non zero */ - if (!ret && cfg) + if (cfg && (!ret || (ret == USB_GADGET_DELAYED_STATUS))) dwc->dev_state = DWC3_CONFIGURED_STATE; break; -- cgit v1.2.3-70-g09d2 From 457e84b6624b4d97e6ffae437887ea51a22d54a0 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 18 Jan 2012 18:04:09 +0200 Subject: usb: dwc3: gadget: dynamically re-size TxFifos We need to dynamically re-size TxFifos for the cases where default values will not do. While at that, we create a simple function which, for now, will just allocate one full packet fifo space for each of the enabled endpoints. This can be improved later in order to allow for better throughput by allocating more space for endpoints which could make good use of that like isochronous and bulk. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 5 ++++ drivers/usb/dwc3/core.h | 16 +++++++++- drivers/usb/dwc3/ep0.c | 11 ++++++- drivers/usb/dwc3/gadget.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 104 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 7c9df630dbe..d119a1fbf94 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -404,6 +405,7 @@ static void dwc3_core_exit(struct dwc3 *dwc) static int __devinit dwc3_probe(struct platform_device *pdev) { + struct device_node *node = pdev->dev.of_node; struct resource *res; struct dwc3 *dwc; @@ -469,6 +471,9 @@ static int __devinit dwc3_probe(struct platform_device *pdev) else dwc->maximum_speed = DWC3_DCFG_SUPERSPEED; + if (of_get_property(node, "tx-fifo-resize", NULL)) + dwc->needs_fifo_resize = true; + pm_runtime_enable(&pdev->dev); pm_runtime_get_sync(&pdev->dev); pm_runtime_forbid(&pdev->dev); diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index f4878c4dec0..123c3aa4712 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -172,6 +172,10 @@ #define DWC3_GUSB3PIPECTL_PHYSOFTRST (1 << 31) #define DWC3_GUSB3PIPECTL_SUSPHY (1 << 17) +/* Global TX Fifo Size Register */ +#define DWC3_GTXFIFOSIZ_TXFDEF(n) ((n) & 0xffff) +#define DWC3_GTXFIFOSIZ_TXFSTADDR(n) ((n) & 0xffff0000) + /* Global HWPARAMS1 Register */ #define DWC3_GHWPARAMS1_EN_PWROPT(n) ((n & (3 << 24)) >> 24) #define DWC3_GHWPARAMS1_EN_PWROPT_NO 0 @@ -546,8 +550,13 @@ struct dwc3_hwparams { #define DWC3_MODE_DRD 2 #define DWC3_MODE_HUB 3 +#define DWC3_MDWIDTH(n) (((n) & 0xff00) >> 8) + /* HWPARAMS1 */ -#define DWC3_NUM_INT(n) (((n) & (0x3f << 15)) >> 15) +#define DWC3_NUM_INT(n) (((n) & (0x3f << 15)) >> 15) + +/* HWPARAMS7 */ +#define DWC3_RAM1_DEPTH(n) ((n) & 0xffff) struct dwc3_request { struct usb_request request; @@ -594,6 +603,8 @@ struct dwc3_request { * @ep0_expect_in: true when we expect a DATA IN transfer * @start_config_issued: true when StartConfig command has been issued * @setup_packet_pending: true when there's a Setup Packet in FIFO. Workaround + * @needs_fifo_resize: not all users might want fifo resizing, flag it + * @resize_fifos: tells us it's ok to reconfigure our TxFIFO sizes. * @ep0_next_event: hold the next expected event * @ep0state: state of endpoint zero * @link_state: link state @@ -651,6 +662,8 @@ struct dwc3 { unsigned start_config_issued:1; unsigned setup_packet_pending:1; unsigned delayed_status:1; + unsigned needs_fifo_resize:1; + unsigned resize_fifos:1; enum dwc3_ep0_next ep0_next_event; enum dwc3_ep0_state ep0state; @@ -812,6 +825,7 @@ union dwc3_event { /* prototypes */ void dwc3_set_mode(struct dwc3 *dwc, u32 mode); +int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc); int dwc3_host_init(struct dwc3 *dwc); void dwc3_host_exit(struct dwc3 *dwc); diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index e90ebb9dd3e..5104dbf4668 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -457,8 +457,11 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) case DWC3_ADDRESS_STATE: 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))) + if (cfg && (!ret || (ret == USB_GADGET_DELAYED_STATUS))) { dwc->dev_state = DWC3_CONFIGURED_STATE; + dwc->resize_fifos = true; + dev_dbg(dwc->dev, "resize fifos flag SET\n"); + } break; case DWC3_CONFIGURED_STATE: @@ -707,6 +710,12 @@ static void dwc3_ep0_do_control_status(struct dwc3 *dwc, u32 epnum) { struct dwc3_ep *dep = dwc->eps[epnum]; + if (dwc->resize_fifos) { + dev_dbg(dwc->dev, "starting to resize fifos\n"); + dwc3_gadget_resize_tx_fifos(dwc); + dwc->resize_fifos = 0; + } + WARN_ON(dwc3_ep0_start_control_status(dep)); } diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index d406a75456a..7913d1b50e3 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -125,6 +125,80 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state) return -ETIMEDOUT; } +/** + * dwc3_gadget_resize_tx_fifos - reallocate fifo spaces for current use-case + * @dwc: pointer to our context structure + * + * This function will a best effort FIFO allocation in order + * to improve FIFO usage and throughput, while still allowing + * us to enable as many endpoints as possible. + * + * Keep in mind that this operation will be highly dependent + * on the configured size for RAM1 - which contains TxFifo -, + * the amount of endpoints enabled on coreConsultant tool, and + * the width of the Master Bus. + * + * In the ideal world, we would always be able to satisfy the + * following equation: + * + * ((512 + 2 * MDWIDTH-Bytes) + (Number of IN Endpoints - 1) * \ + * (3 * (1024 + MDWIDTH-Bytes) + MDWIDTH-Bytes)) / MDWIDTH-Bytes + * + * Unfortunately, due to many variables that's not always the case. + */ +int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc) +{ + int last_fifo_depth = 0; + int ram1_depth; + int fifo_size; + int mdwidth; + int num; + + if (!dwc->needs_fifo_resize) + return 0; + + ram1_depth = DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7); + mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0); + + /* MDWIDTH is represented in bits, we need it in bytes */ + mdwidth >>= 3; + + /* + * FIXME For now we will only allocate 1 wMaxPacketSize space + * for each enabled endpoint, later patches will come to + * improve this algorithm so that we better use the internal + * FIFO space + */ + for (num = 0; num < DWC3_ENDPOINTS_NUM; num++) { + struct dwc3_ep *dep = dwc->eps[num]; + int fifo_number = dep->number >> 1; + int tmp; + + if (!(dep->number & 1)) + continue; + + if (!(dep->flags & DWC3_EP_ENABLED)) + continue; + + tmp = dep->endpoint.maxpacket; + tmp += mdwidth; + tmp += mdwidth; + + fifo_size = DIV_ROUND_UP(tmp, mdwidth); + fifo_size |= (last_fifo_depth << 16); + + dev_vdbg(dwc->dev, "%s: Fifo Addr %04x Size %d\n", + dep->name, last_fifo_depth, fifo_size & 0xffff); + + dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(fifo_number), + fifo_size); + + last_fifo_depth += (fifo_size & 0xffff); + } + + return 0; +} + void dwc3_map_buffer_to_dma(struct dwc3_request *req) { struct dwc3 *dwc = req->dep->dwc; -- cgit v1.2.3-70-g09d2 From 8db7ed15f2557e26371e4b2d98fee290d992b715 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 18 Jan 2012 18:32:29 +0200 Subject: usb: dwc3: gadget: start core on Rx.Detect When we set Run/Stop bit, we also move the core to Rx.Detect state so that USB3 handshake can start from a known location. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.h | 9 +++++++++ drivers/usb/dwc3/gadget.c | 9 ++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 123c3aa4712..71d958af239 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -202,6 +202,15 @@ #define DWC3_DCTL_APPL1RES (1 << 23) +#define DWC3_DCTL_TRGTULST_MASK (0x0f << 17) +#define DWC3_DCTL_TRGTULST(n) ((n) << 17) + +#define DWC3_DCTL_TRGTULST_U2 (DWC3_DCTL_TRGTULST(2)) +#define DWC3_DCTL_TRGTULST_U3 (DWC3_DCTL_TRGTULST(3)) +#define DWC3_DCTL_TRGTULST_SS_DIS (DWC3_DCTL_TRGTULST(4)) +#define DWC3_DCTL_TRGTULST_RX_DET (DWC3_DCTL_TRGTULST(5)) +#define DWC3_DCTL_TRGTULST_SS_INACT (DWC3_DCTL_TRGTULST(6)) + #define DWC3_DCTL_INITU2ENA (1 << 12) #define DWC3_DCTL_ACCEPTU2ENA (1 << 11) #define DWC3_DCTL_INITU1ENA (1 << 10) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 7913d1b50e3..2c4482f13a1 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1313,10 +1313,13 @@ static void dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on) u32 timeout = 500; reg = dwc3_readl(dwc->regs, DWC3_DCTL); - if (is_on) - reg |= DWC3_DCTL_RUN_STOP; - else + if (is_on) { + reg &= ~DWC3_DCTL_TRGTULST_MASK; + reg |= (DWC3_DCTL_RUN_STOP + | DWC3_DCTL_TRGTULST_RX_DET); + } else { reg &= ~DWC3_DCTL_RUN_STOP; + } dwc3_writel(dwc->regs, DWC3_DCTL, reg); -- cgit v1.2.3-70-g09d2 From 45b3cd4ad79b31289aa7da7a6448ec5afb7780a4 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 25 Jan 2012 11:07:03 +0200 Subject: usb: dwc3: omap: convert pdata to of property Convert our platform_data usage to OF property, keep the legacy pdata for a while until the complete conversion is done. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-omap.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 3274ac8f120..64e29c31df2 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include "core.h" @@ -197,14 +198,18 @@ static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap) static int __devinit 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 platform_device *dwc3; struct dwc3_omap *omap; struct resource *res; int devid; + int size; int ret = -ENOMEM; int irq; + const u32 *utmi_mode; u32 reg; void __iomem *base; @@ -269,19 +274,24 @@ static int __devinit dwc3_omap_probe(struct platform_device *pdev) reg = dwc3_readl(omap->base, USBOTGSS_UTMI_OTG_STATUS); - if (!pdata) { - dev_dbg(&pdev->dev, "missing platform data\n"); + utmi_mode = of_get_property(node, "utmi-mode", &size); + if (utmi_mode && size == sizeof(*utmi_mode)) { + reg |= *utmi_mode; } 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(&pdev->dev, "UNKNOWN utmi mode %d\n", - pdata->utmi_mode); + if (!pdata) { + dev_dbg(&pdev->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(&pdev->dev, "UNKNOWN utmi mode %d\n", + pdata->utmi_mode); + } } } -- cgit v1.2.3-70-g09d2 From 3d4c0d4ffb418800b2d1af111f9e1d5b204ee55c Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 31 Jan 2012 13:33:32 +0200 Subject: usb: dwc3: debugfs: fix error check debugfs APIs will return NULL if it fails to create the file/directory we ask it to create. Instead of checking for IS_ERR(ptr) we must check for !ptr. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/debugfs.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index a2c1cc64b48..78ec092db5e 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c @@ -659,8 +659,8 @@ int __devinit dwc3_debugfs_init(struct dwc3 *dwc) int ret; root = debugfs_create_dir(dev_name(dwc->dev), NULL); - if (IS_ERR(root)) { - ret = PTR_ERR(root); + if (!root) { + ret = -ENOMEM; goto err0; } @@ -668,29 +668,29 @@ int __devinit dwc3_debugfs_init(struct dwc3 *dwc) file = debugfs_create_file("regdump", S_IRUGO, root, dwc, &dwc3_regdump_fops); - if (IS_ERR(file)) { - ret = PTR_ERR(file); + if (!file) { + ret = -ENOMEM; goto err1; } file = debugfs_create_file("mode", S_IRUGO | S_IWUSR, root, dwc, &dwc3_mode_fops); - if (IS_ERR(file)) { - ret = PTR_ERR(file); + if (!file) { + ret = -ENOMEM; goto err1; } file = debugfs_create_file("testmode", S_IRUGO | S_IWUSR, root, dwc, &dwc3_testmode_fops); - if (IS_ERR(file)) { - ret = PTR_ERR(file); + if (!file) { + ret = -ENOMEM; goto err1; } file = debugfs_create_file("link_state", S_IRUGO | S_IWUSR, root, dwc, &dwc3_link_state_fops); - if (IS_ERR(file)) { - ret = PTR_ERR(file); + if (!file) { + ret = -ENOMEM; goto err1; } -- cgit v1.2.3-70-g09d2 From 8b5d6b0a4353d0e3517947f894be215750d681bb Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 3 Feb 2012 15:04:46 +0200 Subject: usb: dwc3: host: align on host device name PCI uses xhci-hcd, so let's use the same device name to avoid confusion. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c index 7cfe211b6c3..b108d18fd40 100644 --- a/drivers/usb/dwc3/host.c +++ b/drivers/usb/dwc3/host.c @@ -53,7 +53,7 @@ int dwc3_host_init(struct dwc3 *dwc) struct platform_device *xhci; int ret; - xhci = platform_device_alloc("xhci", -1); + xhci = platform_device_alloc("xhci-hcd", -1); if (!xhci) { dev_err(dwc->dev, "couldn't allocate xHCI device\n"); ret = -ENOMEM; -- cgit v1.2.3-70-g09d2 From d70d84423cbc5d6d929640189cf204e693024309 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 6 Feb 2012 13:40:17 +0200 Subject: usb: dwc3: gadget: avoid memcpy()ing event buffer We're only using the 4 byte events and memcpy() will make us slower. We can easily avoid that. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 2c4482f13a1..1f64e7c1c34 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2223,7 +2223,8 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc, u32 buf) while (left > 0) { union dwc3_event event; - memcpy(&event.raw, (evt->buf + evt->lpos), sizeof(event.raw)); + 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 -- cgit v1.2.3-70-g09d2 From c2ef8f21ea8f7c34dfa0b569fdee431348205955 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Sat, 4 Feb 2012 17:08:48 +0100 Subject: HID: multitouch: add support for trackpads * some multitouch trackpads present the touch usage. This needs to be filtered as it will conflict with mt-implementation. * trackpads send BTN_TOOL_* to notify how many fingers are present (this is used by xorg to use synaptics instead of generic evdev) * trackpads like Perixx 701 are not different from a hid point of view from a touchscreen, and we need to manually set them as touchpad. Signed-off-by: Benjamin Tissoires Acked-by: Henrik Rydberg Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 24fc4423b93..4c697498fcf 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -1,9 +1,9 @@ /* * HID driver for multitouch panels * - * Copyright (c) 2010-2011 Stephane Chatty - * Copyright (c) 2010-2011 Benjamin Tissoires - * Copyright (c) 2010-2011 Ecole Nationale de l'Aviation Civile, France + * Copyright (c) 2010-2012 Stephane Chatty + * Copyright (c) 2010-2012 Benjamin Tissoires + * Copyright (c) 2010-2012 Ecole Nationale de l'Aviation Civile, France * * This code is partly based on hid-egalax.c: * @@ -67,6 +67,7 @@ struct mt_class { __s32 sn_height; /* Signal/noise ratio for height events */ __s32 sn_pressure; /* Signal/noise ratio for pressure events */ __u8 maxcontacts; + bool is_indirect; /* true for touchpads */ }; struct mt_device { @@ -265,17 +266,31 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, { struct mt_device *td = hid_get_drvdata(hdev); struct mt_class *cls = &td->mtclass; + int code; /* Only map fields from TouchScreen or TouchPad collections. * We need to ignore fields that belong to other collections * such as Mouse that might have the same GenericDesktop usages. */ if (field->application == HID_DG_TOUCHSCREEN) set_bit(INPUT_PROP_DIRECT, hi->input->propbit); - else if (field->application == HID_DG_TOUCHPAD) - set_bit(INPUT_PROP_POINTER, hi->input->propbit); - else + else if (field->application != HID_DG_TOUCHPAD) return 0; + /* In case of an indirect device (touchpad), we need to add + * specific BTN_TOOL_* to be handled by the synaptics xorg + * driver. + * We also consider that touchscreens providing buttons are touchpads. + */ + if (field->application == HID_DG_TOUCHPAD || + (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON || + cls->is_indirect) { + set_bit(INPUT_PROP_POINTER, hi->input->propbit); + set_bit(BTN_TOOL_FINGER, hi->input->keybit); + set_bit(BTN_TOOL_DOUBLETAP, hi->input->keybit); + set_bit(BTN_TOOL_TRIPLETAP, hi->input->keybit); + set_bit(BTN_TOOL_QUADTAP, hi->input->keybit); + } + /* eGalax devices provide a Digitizer.Stylus input which overrides * the correct Digitizers.Finger X/Y ranges. * Let's just ignore this input. */ @@ -389,9 +404,19 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, td->last_field_index = field->index; return -1; } + case HID_DG_TOUCH: + /* Legacy devices use TIPSWITCH and not TOUCH. + * Let's just ignore this field. */ + return -1; /* let hid-input decide for the others */ return 0; + case HID_UP_BUTTON: + code = BTN_MOUSE + ((usage->hid - 1) & HID_USAGE); + hid_map_usage(hi, usage, bit, max, EV_KEY, code); + input_set_capability(hi->input, EV_KEY, code); + return 1; + case 0xff000000: /* we do not want to map these: no input-oriented meaning */ return -1; @@ -538,6 +563,9 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, if (value) td->num_expected = value; break; + case HID_DG_TOUCH: + /* do nothing */ + break; default: /* fallback to the generic hidinput handling */ -- cgit v1.2.3-70-g09d2 From 31ae9bddb935c74b51ead08d54948e5bea0f0344 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Sat, 4 Feb 2012 17:08:49 +0100 Subject: HID: multitouch: add control of the feature "Maximum Contact Number" Some devices, like Perixx Peripad 701 do not work if the feature "Maximum Contact Number" is not set to the right value. This patch allows hid-multitouch to control this feature. If the programmer fills the field maxcontacts in the mt_class, then the driver will set the feature to this value. It is safe for current drivers as the feature is read/write in the HID norm and all devices should implement the norm. Signed-off-by: Benjamin Tissoires Acked-by: Henrik Rydberg Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 4c697498fcf..d0fa6a7e9bc 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -77,6 +77,8 @@ struct mt_device { unsigned last_slot_field; /* the last field of a slot */ int last_mt_collection; /* last known mt-related collection */ __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ + __s8 maxcontact_report_id; /* Maximum Contact Number HID feature, + -1 if non-existent */ __u8 num_received; /* how many contacts we received */ __u8 num_expected; /* expected last contact index */ __u8 maxcontacts; @@ -242,6 +244,7 @@ static void mt_feature_mapping(struct hid_device *hdev, td->inputmode = field->report->id; break; case HID_DG_CONTACTMAX: + td->maxcontact_report_id = field->report->id; td->maxcontacts = field->value[0]; if (td->mtclass.maxcontacts) /* check if the maxcontacts is given by the class */ @@ -606,6 +609,32 @@ static void mt_set_input_mode(struct hid_device *hdev) } } +static void mt_set_maxcontacts(struct hid_device *hdev) +{ + struct mt_device *td = hid_get_drvdata(hdev); + struct hid_report *r; + struct hid_report_enum *re; + int fieldmax, max; + + if (td->maxcontact_report_id < 0) + return; + + if (!td->mtclass.maxcontacts) + return; + + re = &hdev->report_enum[HID_FEATURE_REPORT]; + r = re->report_id_hash[td->maxcontact_report_id]; + if (r) { + max = td->mtclass.maxcontacts; + fieldmax = r->field[0]->logical_maximum; + max = min(fieldmax, max); + if (r->field[0]->value[0] != max) { + r->field[0]->value[0] = max; + usbhid_submit_report(hdev, r, USB_DIR_OUT); + } + } +} + static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) { int ret, i; @@ -631,6 +660,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) } td->mtclass = *mtclass; td->inputmode = -1; + td->maxcontact_report_id = -1; td->last_mt_collection = -1; hid_set_drvdata(hdev, td); @@ -653,6 +683,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group); + mt_set_maxcontacts(hdev); mt_set_input_mode(hdev); return 0; @@ -665,6 +696,7 @@ fail: #ifdef CONFIG_PM static int mt_reset_resume(struct hid_device *hdev) { + mt_set_maxcontacts(hdev); mt_set_input_mode(hdev); return 0; } -- cgit v1.2.3-70-g09d2 From 847672cd141c07db3d5fc1442b4c3e8a702488df Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Sat, 4 Feb 2012 17:08:50 +0100 Subject: HID: multitouch: support Perixx PERIPAD 701 Perixx Peripad 701 is an hybrid device which presents a touchpad and a keyboard on the same surface. The switch between the two is controlled by a physical switch, and the firmware sends the events on the right interface (mouse, keyboard or multitouch). This patch enables the multitouch interface of this device to work. We need to manually set the device as a trackpad (we cannot infer it from the reports descriptors as the device works under Windows, a system that does not allow multitouch touchpad). We also need to set the hid feature MAX CONTACT NUMBER to 2 or the device stops sending events once it has been pressed by two touches. Signed-off-by: Benjamin Tissoires Acked-by: Henrik Rydberg Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 1 + drivers/hid/hid-ids.h | 1 + drivers/hid/hid-multitouch.c | 11 +++++++++++ 3 files changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index a421abdd1ab..f7c43b6c356 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -355,6 +355,7 @@ config HID_MULTITOUCH - Lumio CrystalTouch panels - MosArt dual-touch panels - PenMount dual touch panels + - Perixx Peripad 701 touchpad - PixArt optical touch screen - Pixcir dual touch panels - Quanta panels diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index b8574cddd95..662a0b6a664 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -659,6 +659,7 @@ #define USB_VENDOR_ID_TOPSEED2 0x1784 #define USB_DEVICE_ID_TOPSEED2_RF_COMBO 0x0004 +#define USB_DEVICE_ID_TOPSEED2_PERIPAD_701 0x0016 #define USB_VENDOR_ID_TOPMAX 0x0663 #define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103 diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index d0fa6a7e9bc..387a72fb1c8 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -103,6 +103,7 @@ struct mt_device { #define MT_CLS_CYPRESS 0x0102 #define MT_CLS_EGALAX 0x0103 #define MT_CLS_EGALAX_SERIAL 0x0104 +#define MT_CLS_TOPSEED 0x0105 #define MT_DEFAULT_MAXCONTACT 10 @@ -192,6 +193,11 @@ static struct mt_class mt_classes[] = { .sn_move = 4096, .sn_pressure = 32, }, + { .name = MT_CLS_TOPSEED, + .quirks = MT_QUIRK_ALWAYS_VALID, + .is_indirect = true, + .maxcontacts = 2, + }, { } }; @@ -897,6 +903,11 @@ static const struct hid_device_id mt_devices[] = { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, USB_DEVICE_ID_MTP_SITRONIX)}, + /* TopSeed panels */ + { .driver_data = MT_CLS_TOPSEED, + HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, + USB_DEVICE_ID_TOPSEED2_PERIPAD_701) }, + /* Touch International panels */ { .driver_data = MT_CLS_DEFAULT, HID_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL, -- cgit v1.2.3-70-g09d2 From 2e81c36a00d0eb8ce72faaaec1a1d865617374ae Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 2 Feb 2012 13:01:12 +0200 Subject: usb: dwc3: gadget: allocate 3 packets for bulk and isoc endpoints Those transfer types are generally high bandwidth, so we want to optimize transfers with those endpoints. For that, databook suggests allocating 3 * wMaxPacketSize of FIFO. Let's do that. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 1f64e7c1c34..c30ab6da3d0 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -172,6 +172,7 @@ int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc) for (num = 0; num < DWC3_ENDPOINTS_NUM; num++) { struct dwc3_ep *dep = dwc->eps[num]; int fifo_number = dep->number >> 1; + int mult = 1; int tmp; if (!(dep->number & 1)) @@ -180,11 +181,26 @@ int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc) if (!(dep->flags & DWC3_EP_ENABLED)) continue; - tmp = dep->endpoint.maxpacket; - tmp += mdwidth; + if (usb_endpoint_xfer_bulk(dep->desc) + || usb_endpoint_xfer_isoc(dep->desc)) + mult = 3; + + /* + * REVISIT: the following assumes we will always have enough + * space available on the FIFO RAM for all possible use cases. + * Make sure that's true somehow and change FIFO allocation + * accordingly. + * + * If we have Bulk or Isochronous endpoints, we want + * them to be able to be very, very fast. So we're giving + * those endpoints a fifo_size which is enough for 3 full + * packets + */ + tmp = mult * (dep->endpoint.maxpacket + mdwidth); tmp += mdwidth; fifo_size = DIV_ROUND_UP(tmp, mdwidth); + fifo_size |= (last_fifo_depth << 16); dev_vdbg(dwc->dev, "%s: Fifo Addr %04x Size %d\n", -- cgit v1.2.3-70-g09d2 From 44ea35c138d400b3aeeb2a5317edd4634e6823e3 Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Fri, 14 Oct 2011 16:57:42 -0400 Subject: HID: add support for tivo slide remote This patch finishes off adding full support for the TiVo Slide remote, which is a mostly pure HID device from the perspective of the kernel. There are a few mappings that use a vendor-specific usage page, and a few keys in the consumer usage page that I think make sense to remap slightly, to better fit their key labels' intended use. Doing this in a stand-alone hid-tivo.c makes the modifications only matter for this specific device. What's actually connected to the computer is a Broadcom-made usb dongle, which has an embedded hub, bluetooth adapter, mouse and keyboard devices. You pair with the dongle, then the remote sends data that its converted into HID on the keyboard interface (the mouse interface doesn't do anything interesting, so far as I can tell). lsusb for this device: Bus 004 Device 005: ID 0a5c:2190 Broadcom Corp. Bus 004 Device 004: ID 0a5c:4503 Broadcom Corp. Bus 004 Device 003: ID 150a:1201 Bus 004 Device 002: ID 0a5c:4500 Broadcom Corp. BCM2046B1 USB 2.0 Hub (part of BCM2046 Bluetooth) Speaking of the keyboard interface, the remote actually does contain a keyboard as well. The top slides away, revealing a reasonably functional qwerty keyboard (not unlike many slide cell phones), thus the product name. CC: Jiri Kosina Signed-off-by: Jarod Wilson Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 6 ++++ drivers/hid/Makefile | 1 + drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h | 3 ++ drivers/hid/hid-tivo.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 100 insertions(+) create mode 100644 drivers/hid/hid-tivo.c (limited to 'drivers') diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index a421abdd1ab..1f0b229f7df 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -594,6 +594,12 @@ config SMARTJOYPLUS_FF Say Y here if you have a SmartJoy PLUS PS2/USB adapter and want to enable force feedback support for it. +config HID_TIVO_SLIDE + tristate "TiVo Slide Bluetooth remote control support" + depends on USB_HID + ---help--- + Say Y if you have a TiVo Slide Bluetooth remote control. + config HID_TOPSEED tristate "TopSeed Cyberlink, BTC Emprex, Conceptronic remote control support" depends on USB_HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 8aefdc963cc..c05f448f34a 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -79,6 +79,7 @@ obj-$(CONFIG_HID_SPEEDLINK) += hid-speedlink.o obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o +obj-$(CONFIG_HID_TIVO) += hid-tivo.o obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o obj-$(CONFIG_HID_TWINHAN) += hid-twinhan.o obj-$(CONFIG_HID_UCLOGIC) += hid-uclogic.o diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 75dbe344cab..23fa03176ac 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1536,6 +1536,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653) }, { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) }, { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a) }, + { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) }, { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) }, { HID_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL, USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index fb9e61f8566..5f63e361be1 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -655,6 +655,9 @@ #define USB_VENDOR_ID_THRUSTMASTER 0x044f +#define USB_VENDOR_ID_TIVO 0x150a +#define USB_DEVICE_ID_TIVO_SLIDE 0x1201 + #define USB_VENDOR_ID_TOPSEED 0x0766 #define USB_DEVICE_ID_TOPSEED_CYBERLINK 0x0204 diff --git a/drivers/hid/hid-tivo.c b/drivers/hid/hid-tivo.c new file mode 100644 index 00000000000..3d43c06dfff --- /dev/null +++ b/drivers/hid/hid-tivo.c @@ -0,0 +1,89 @@ +/* + * HID driver for TiVo Slide Bluetooth remote + * + * Copyright (c) 2011 Jarod Wilson + * based on the hid-topseed driver, which is in turn, based on hid-cherry... + */ + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the 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 "hid-ids.h" + +#define HID_UP_TIVOVENDOR 0xffff0000 +#define tivo_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ + EV_KEY, (c)) + +static int tivo_input_mapping(struct hid_device *hdev, struct hid_input *hi, + struct hid_field *field, struct hid_usage *usage, + unsigned long **bit, int *max) +{ + switch (usage->hid & HID_USAGE_PAGE) { + case HID_UP_TIVOVENDOR: + switch (usage->hid & HID_USAGE) { + /* TiVo button */ + case 0x3d: tivo_map_key_clear(KEY_MEDIA); break; + /* Live TV */ + case 0x3e: tivo_map_key_clear(KEY_TV); break; + /* Red thumbs down */ + case 0x41: tivo_map_key_clear(KEY_KPMINUS); break; + /* Green thumbs up */ + case 0x42: tivo_map_key_clear(KEY_KPPLUS); break; + default: + return 0; + } + break; + case HID_UP_CONSUMER: + switch (usage->hid & HID_USAGE) { + /* Enter/Last (default mapping: KEY_LAST) */ + case 0x083: tivo_map_key_clear(KEY_ENTER); break; + /* Info (default mapping: KEY_PROPS) */ + case 0x209: tivo_map_key_clear(KEY_INFO); break; + default: + return 0; + } + break; + default: + return 0; + } + + /* This means we found a matching mapping here, else, look in the + * standard hid mappings in hid-input.c */ + return 1; +} + +static const struct hid_device_id tivo_devices[] = { + /* TiVo Slide Bluetooth remote, pairs with a Broadcom dongle */ + { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) }, + { } +}; +MODULE_DEVICE_TABLE(hid, tivo_devices); + +static struct hid_driver tivo_driver = { + .name = "tivo_slide", + .id_table = tivo_devices, + .input_mapping = tivo_input_mapping, +}; + +static int __init tivo_init(void) +{ + return hid_register_driver(&tivo_driver); +} + +static void __exit tivo_exit(void) +{ + hid_unregister_driver(&tivo_driver); +} + +module_init(tivo_init); +module_exit(tivo_exit); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Jarod Wilson "); -- cgit v1.2.3-70-g09d2 From 2701eaabd7599a2aebae22caf00869a383d66a05 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Mon, 6 Feb 2012 17:36:38 +0100 Subject: HID: tivo: fix broken build Fix mismatch between Kconfig name and Makefile expectation. Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 1f0b229f7df..0a55866f1f7 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -594,7 +594,7 @@ config SMARTJOYPLUS_FF Say Y here if you have a SmartJoy PLUS PS2/USB adapter and want to enable force feedback support for it. -config HID_TIVO_SLIDE +config HID_TIVO tristate "TiVo Slide Bluetooth remote control support" depends on USB_HID ---help--- -- cgit v1.2.3-70-g09d2 From 0c3d0b20cf9cee1023b1a2e27cfd79db95b578b5 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 6 Feb 2012 21:01:14 +0800 Subject: regulator: Remove redundant regmap_update_bits call for TPS65023_REG_CON_CTRL2 This looks like a merge mistake. Calling regmap_update_bits once is enough. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/tps65023-regulator.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index 18d61a0529a..43e4902d7af 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c @@ -487,10 +487,6 @@ static int __devinit tps_65023_probe(struct i2c_client *client, i2c_set_clientdata(client, tps); - /* Enable setting output voltage by I2C */ - regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2, - TPS65023_REG_CTRL2_CORE_ADJ, TPS65023_REG_CTRL2_CORE_ADJ); - /* Enable setting output voltage by I2C */ regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2, TPS65023_REG_CTRL2_CORE_ADJ, TPS65023_REG_CTRL2_CORE_ADJ); -- cgit v1.2.3-70-g09d2 From da7de6a161d280736f399a378e43ea9e6861bd04 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 6 Feb 2012 20:37:46 +0800 Subject: regulator: Show correct chip id for max8649 Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/max8649.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c index b06a2399587..636dfd45b75 100644 --- a/drivers/regulator/max8649.c +++ b/drivers/regulator/max8649.c @@ -270,7 +270,7 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client, ret); goto out; } - dev_info(info->dev, "Detected MAX8649 (ID:%x)\n", ret); + dev_info(info->dev, "Detected MAX8649 (ID:%x)\n", val); /* enable VID0 & VID1 */ regmap_update_bits(info->regmap, MAX8649_CONTROL, MAX8649_VID_MASK, 0); -- cgit v1.2.3-70-g09d2 From 1d266430546acf01438ae42d0a7370db4817e2ad Mon Sep 17 00:00:00 2001 From: Pradeep A Dalvi Date: Sun, 5 Feb 2012 02:49:09 +0000 Subject: netdev: ethernet dev_alloc_skb to netdev_alloc_skb Replaced deprecating dev_alloc_skb with netdev_alloc_skb in drivers/net/ethernet - Removed extra skb->dev = dev after netdev_alloc_skb Signed-off-by: Pradeep A Dalvi Signed-off-by: David S. Miller --- drivers/net/ethernet/3com/3c501.c | 2 +- drivers/net/ethernet/3com/3c509.c | 2 +- drivers/net/ethernet/3com/3c574_cs.c | 2 +- drivers/net/ethernet/3com/3c589_cs.c | 2 +- drivers/net/ethernet/3com/3c59x.c | 5 +++-- drivers/net/ethernet/3com/typhoon.c | 5 ++--- drivers/net/ethernet/8390/axnet_cs.c | 2 +- drivers/net/ethernet/8390/lib8390.c | 2 +- drivers/net/ethernet/adaptec/starfire.c | 8 +++----- drivers/net/ethernet/aeroflex/greth.c | 1 - drivers/net/ethernet/amd/7990.c | 2 +- drivers/net/ethernet/amd/a2065.c | 2 +- drivers/net/ethernet/amd/am79c961a.c | 2 +- drivers/net/ethernet/amd/amd8111e.c | 6 ++++-- drivers/net/ethernet/amd/ariadne.c | 2 +- drivers/net/ethernet/amd/atarilance.c | 2 +- drivers/net/ethernet/amd/au1000_eth.c | 2 +- drivers/net/ethernet/amd/declance.c | 2 +- drivers/net/ethernet/amd/depca.c | 2 +- drivers/net/ethernet/amd/ni65.c | 2 +- drivers/net/ethernet/amd/nmclan_cs.c | 2 +- drivers/net/ethernet/amd/pcnet32.c | 14 +++++++------- drivers/net/ethernet/amd/sun3lance.c | 2 +- drivers/net/ethernet/amd/sunlance.c | 4 ++-- drivers/net/ethernet/apple/mace.c | 4 ++-- drivers/net/ethernet/apple/macmace.c | 2 +- drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 2 +- drivers/net/ethernet/cadence/at91_ether.c | 2 +- 28 files changed, 43 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/3com/3c501.c b/drivers/net/ethernet/3com/3c501.c index 68da81d476f..bf73e1a0229 100644 --- a/drivers/net/ethernet/3com/3c501.c +++ b/drivers/net/ethernet/3com/3c501.c @@ -702,7 +702,7 @@ static void el_receive(struct net_device *dev) */ outb(AX_SYS, AX_CMD); - skb = dev_alloc_skb(pkt_len+2); + skb = netdev_alloc_skb(dev, pkt_len + 2); /* * Start of frame diff --git a/drivers/net/ethernet/3com/3c509.c b/drivers/net/ethernet/3com/3c509.c index 92053e6fc98..41719da2e17 100644 --- a/drivers/net/ethernet/3com/3c509.c +++ b/drivers/net/ethernet/3com/3c509.c @@ -1066,7 +1066,7 @@ el3_rx(struct net_device *dev) short pkt_len = rx_status & 0x7ff; struct sk_buff *skb; - skb = dev_alloc_skb(pkt_len+5); + skb = netdev_alloc_skb(dev, pkt_len + 5); if (el3_debug > 4) pr_debug("Receiving packet size %d status %4.4x.\n", pkt_len, rx_status); diff --git a/drivers/net/ethernet/3com/3c574_cs.c b/drivers/net/ethernet/3com/3c574_cs.c index 9c01bc9235b..e61b2f82ba3 100644 --- a/drivers/net/ethernet/3com/3c574_cs.c +++ b/drivers/net/ethernet/3com/3c574_cs.c @@ -1012,7 +1012,7 @@ static int el3_rx(struct net_device *dev, int worklimit) short pkt_len = rx_status & 0x7ff; struct sk_buff *skb; - skb = dev_alloc_skb(pkt_len+5); + skb = netdev_alloc_skb(dev, pkt_len + 5); pr_debug(" Receiving packet size %d status %4.4x.\n", pkt_len, rx_status); diff --git a/drivers/net/ethernet/3com/3c589_cs.c b/drivers/net/ethernet/3com/3c589_cs.c index da410f03686..b23253b9f74 100644 --- a/drivers/net/ethernet/3com/3c589_cs.c +++ b/drivers/net/ethernet/3com/3c589_cs.c @@ -819,7 +819,7 @@ static int el3_rx(struct net_device *dev) short pkt_len = rx_status & 0x7ff; struct sk_buff *skb; - skb = dev_alloc_skb(pkt_len+5); + skb = netdev_alloc_skb(dev, pkt_len + 5); netdev_dbg(dev, " Receiving packet size %d status %4.4x.\n", pkt_len, rx_status); diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c index dc51d9218e6..1282f048dfa 100644 --- a/drivers/net/ethernet/3com/3c59x.c +++ b/drivers/net/ethernet/3com/3c59x.c @@ -2499,7 +2499,7 @@ static int vortex_rx(struct net_device *dev) int pkt_len = rx_status & 0x1fff; struct sk_buff *skb; - skb = dev_alloc_skb(pkt_len + 5); + skb = netdev_alloc_skb(dev, pkt_len + 5); if (vortex_debug > 4) pr_debug("Receiving packet size %d status %4.4x.\n", pkt_len, rx_status); @@ -2578,7 +2578,8 @@ boomerang_rx(struct net_device *dev) /* Check if the packet is long enough to just accept without copying to a properly sized skbuff. */ - if (pkt_len < rx_copybreak && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) { + if (pkt_len < rx_copybreak && + (skb = netdev_alloc_skb(dev, pkt_len + 2)) != NULL) { skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ pci_dma_sync_single_for_cpu(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); /* 'skb_put()' points to the start of sk_buff data area. */ diff --git a/drivers/net/ethernet/3com/typhoon.c b/drivers/net/ethernet/3com/typhoon.c index 6d6bc754b1a..f7d622eed20 100644 --- a/drivers/net/ethernet/3com/typhoon.c +++ b/drivers/net/ethernet/3com/typhoon.c @@ -1607,7 +1607,7 @@ typhoon_alloc_rx_skb(struct typhoon *tp, u32 idx) le32_to_cpu(indexes->rxBuffCleared)) return -ENOMEM; - skb = dev_alloc_skb(PKT_BUF_SZ); + skb = netdev_alloc_skb(tp->dev, PKT_BUF_SZ); if(!skb) return -ENOMEM; @@ -1618,7 +1618,6 @@ typhoon_alloc_rx_skb(struct typhoon *tp, u32 idx) skb_reserve(skb, 2); #endif - skb->dev = tp->dev; dma_addr = pci_map_single(tp->pdev, skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); @@ -1673,7 +1672,7 @@ typhoon_rx(struct typhoon *tp, struct basic_ring *rxRing, volatile __le32 * read pkt_len = le16_to_cpu(rx->frameLen); if(pkt_len < rx_copybreak && - (new_skb = dev_alloc_skb(pkt_len + 2)) != NULL) { + (new_skb = netdev_alloc_skb(tp->dev, pkt_len + 2)) != NULL) { skb_reserve(new_skb, 2); pci_dma_sync_single_for_cpu(tp->pdev, dma_addr, PKT_BUF_SZ, diff --git a/drivers/net/ethernet/8390/axnet_cs.c b/drivers/net/ethernet/8390/axnet_cs.c index 5de394368ff..c5bd8eb7a9f 100644 --- a/drivers/net/ethernet/8390/axnet_cs.c +++ b/drivers/net/ethernet/8390/axnet_cs.c @@ -1408,7 +1408,7 @@ static void ei_receive(struct net_device *dev) { struct sk_buff *skb; - skb = dev_alloc_skb(pkt_len+2); + skb = netdev_alloc_skb(dev, pkt_len + 2); if (skb == NULL) { if (ei_debug > 1) diff --git a/drivers/net/ethernet/8390/lib8390.c b/drivers/net/ethernet/8390/lib8390.c index 05ae21435bf..e77f624e819 100644 --- a/drivers/net/ethernet/8390/lib8390.c +++ b/drivers/net/ethernet/8390/lib8390.c @@ -717,7 +717,7 @@ static void ei_receive(struct net_device *dev) } else if ((pkt_stat & 0x0F) == ENRSR_RXOK) { struct sk_buff *skb; - skb = dev_alloc_skb(pkt_len+2); + skb = netdev_alloc_skb(dev, pkt_len + 2); if (skb == NULL) { if (ei_debug > 1) netdev_dbg(dev, "Couldn't allocate a sk_buff of size %d\n", diff --git a/drivers/net/ethernet/adaptec/starfire.c b/drivers/net/ethernet/adaptec/starfire.c index 11fc2eccb0f..d896816512c 100644 --- a/drivers/net/ethernet/adaptec/starfire.c +++ b/drivers/net/ethernet/adaptec/starfire.c @@ -1179,12 +1179,11 @@ static void init_ring(struct net_device *dev) /* Fill in the Rx buffers. Handle allocation failure gracefully. */ for (i = 0; i < RX_RING_SIZE; i++) { - struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz); + struct sk_buff *skb = netdev_alloc_skb(dev, np->rx_buf_sz); np->rx_info[i].skb = skb; if (skb == NULL) break; np->rx_info[i].mapping = pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE); - skb->dev = dev; /* Mark as being used by this device. */ /* Grrr, we cannot offset to correctly align the IP header. */ np->rx_ring[i].rxaddr = cpu_to_dma(np->rx_info[i].mapping | RxDescValid); } @@ -1472,7 +1471,7 @@ static int __netdev_rx(struct net_device *dev, int *quota) /* Check if the packet is long enough to accept without copying to a minimally-sized skbuff. */ if (pkt_len < rx_copybreak && - (skb = dev_alloc_skb(pkt_len + 2)) != NULL) { + (skb = netdev_alloc_skb(dev, pkt_len + 2)) != NULL) { skb_reserve(skb, 2); /* 16 byte align the IP header */ pci_dma_sync_single_for_cpu(np->pci_dev, np->rx_info[entry].mapping, @@ -1596,13 +1595,12 @@ static void refill_rx_ring(struct net_device *dev) for (; np->cur_rx - np->dirty_rx > 0; np->dirty_rx++) { entry = np->dirty_rx % RX_RING_SIZE; if (np->rx_info[entry].skb == NULL) { - skb = dev_alloc_skb(np->rx_buf_sz); + skb = netdev_alloc_skb(dev, np->rx_buf_sz); np->rx_info[entry].skb = skb; if (skb == NULL) break; /* Better luck next round. */ np->rx_info[entry].mapping = pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE); - skb->dev = dev; /* Mark as being used by this device. */ np->rx_ring[entry].rxaddr = cpu_to_dma(np->rx_info[entry].mapping | RxDescValid); } diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c index c885aa905de..b23751e683c 100644 --- a/drivers/net/ethernet/aeroflex/greth.c +++ b/drivers/net/ethernet/aeroflex/greth.c @@ -785,7 +785,6 @@ static int greth_rx(struct net_device *dev, int limit) } else { skb_reserve(skb, NET_IP_ALIGN); - skb->dev = dev; dma_sync_single_for_cpu(greth->dev, dma_addr, diff --git a/drivers/net/ethernet/amd/7990.c b/drivers/net/ethernet/amd/7990.c index 60b35fb5f52..1b046f58d58 100644 --- a/drivers/net/ethernet/amd/7990.c +++ b/drivers/net/ethernet/amd/7990.c @@ -316,7 +316,7 @@ static int lance_rx (struct net_device *dev) if (bits & LE_R1_EOP) dev->stats.rx_errors++; } else { int len = (rd->mblength & 0xfff) - 4; - struct sk_buff *skb = dev_alloc_skb (len+2); + struct sk_buff *skb = netdev_alloc_skb(dev, len + 2); if (!skb) { printk ("%s: Memory squeeze, deferring packet.\n", diff --git a/drivers/net/ethernet/amd/a2065.c b/drivers/net/ethernet/amd/a2065.c index 825e5d4ef4c..689dfcafc6d 100644 --- a/drivers/net/ethernet/amd/a2065.c +++ b/drivers/net/ethernet/amd/a2065.c @@ -290,7 +290,7 @@ static int lance_rx(struct net_device *dev) dev->stats.rx_errors++; } else { int len = (rd->mblength & 0xfff) - 4; - struct sk_buff *skb = dev_alloc_skb(len + 2); + struct sk_buff *skb = netdev_alloc_skb(dev, len + 2); if (!skb) { netdev_warn(dev, "Memory squeeze, deferring packet\n"); diff --git a/drivers/net/ethernet/amd/am79c961a.c b/drivers/net/ethernet/amd/am79c961a.c index 216ae87b945..cc7b9e46780 100644 --- a/drivers/net/ethernet/amd/am79c961a.c +++ b/drivers/net/ethernet/amd/am79c961a.c @@ -516,7 +516,7 @@ am79c961_rx(struct net_device *dev, struct dev_priv *priv) } len = am_readword(dev, hdraddr + 6); - skb = dev_alloc_skb(len + 2); + skb = netdev_alloc_skb(dev, len + 2); if (skb) { skb_reserve(skb, 2); diff --git a/drivers/net/ethernet/amd/amd8111e.c b/drivers/net/ethernet/amd/amd8111e.c index b8306a58955..9f62504d008 100644 --- a/drivers/net/ethernet/amd/amd8111e.c +++ b/drivers/net/ethernet/amd/amd8111e.c @@ -336,7 +336,8 @@ static int amd8111e_init_ring(struct net_device *dev) /* Allocating receive skbs */ for (i = 0; i < NUM_RX_BUFFERS; i++) { - if (!(lp->rx_skbuff[i] = dev_alloc_skb(lp->rx_buff_len))) { + lp->rx_skbuff[i] = netdev_alloc_skb(dev, lp->rx_buff_len); + if (!lp->rx_skbuff[i]) { /* Release previos allocated skbs */ for(--i; i >= 0 ;i--) dev_kfree_skb(lp->rx_skbuff[i]); @@ -768,7 +769,8 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget) } if(--rx_pkt_limit < 0) goto rx_not_empty; - if(!(new_skb = dev_alloc_skb(lp->rx_buff_len))){ + new_skb = netdev_alloc_skb(dev, lp->rx_buff_len); + if (!new_skb) { /* if allocation fail, ignore that pkt and go to next one */ lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS; diff --git a/drivers/net/ethernet/amd/ariadne.c b/drivers/net/ethernet/amd/ariadne.c index eb18e1fe65c..f4c228e4d76 100644 --- a/drivers/net/ethernet/amd/ariadne.c +++ b/drivers/net/ethernet/amd/ariadne.c @@ -191,7 +191,7 @@ static int ariadne_rx(struct net_device *dev) short pkt_len = swapw(priv->rx_ring[entry]->RMD3); struct sk_buff *skb; - skb = dev_alloc_skb(pkt_len + 2); + skb = netdev_alloc_skb(dev, pkt_len + 2); if (skb == NULL) { netdev_warn(dev, "Memory squeeze, deferring packet\n"); for (i = 0; i < RX_RING_SIZE; i++) diff --git a/drivers/net/ethernet/amd/atarilance.c b/drivers/net/ethernet/amd/atarilance.c index 15bfa28d6c5..70ed79c4624 100644 --- a/drivers/net/ethernet/amd/atarilance.c +++ b/drivers/net/ethernet/amd/atarilance.c @@ -997,7 +997,7 @@ static int lance_rx( struct net_device *dev ) dev->stats.rx_errors++; } else { - skb = dev_alloc_skb( pkt_len+2 ); + skb = netdev_alloc_skb(dev, pkt_len + 2); if (skb == NULL) { DPRINTK( 1, ( "%s: Memory squeeze, deferring packet.\n", dev->name )); diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c index a81c871aeac..c1dfdc8b707 100644 --- a/drivers/net/ethernet/amd/au1000_eth.c +++ b/drivers/net/ethernet/amd/au1000_eth.c @@ -725,7 +725,7 @@ static int au1000_rx(struct net_device *dev) /* good frame */ frmlen = (status & RX_FRAME_LEN_MASK); frmlen -= 4; /* Remove FCS */ - skb = dev_alloc_skb(frmlen + 2); + skb = netdev_alloc_skb(dev, frmlen + 2); if (skb == NULL) { netdev_err(dev, "Memory squeeze, dropping packet.\n"); dev->stats.rx_dropped++; diff --git a/drivers/net/ethernet/amd/declance.c b/drivers/net/ethernet/amd/declance.c index dd82ee2f8d2..7dc508e5c72 100644 --- a/drivers/net/ethernet/amd/declance.c +++ b/drivers/net/ethernet/amd/declance.c @@ -605,7 +605,7 @@ static int lance_rx(struct net_device *dev) dev->stats.rx_errors++; } else { len = (*rds_ptr(rd, mblength, lp->type) & 0xfff) - 4; - skb = dev_alloc_skb(len + 2); + skb = netdev_alloc_skb(dev, len + 2); if (skb == 0) { printk("%s: Memory squeeze, deferring packet.\n", diff --git a/drivers/net/ethernet/amd/depca.c b/drivers/net/ethernet/amd/depca.c index 681970c07f2..86dd95766a6 100644 --- a/drivers/net/ethernet/amd/depca.c +++ b/drivers/net/ethernet/amd/depca.c @@ -1042,7 +1042,7 @@ static int depca_rx(struct net_device *dev) short len, pkt_len = readw(&lp->rx_ring[entry].msg_length) - 4; struct sk_buff *skb; - skb = dev_alloc_skb(pkt_len + 2); + skb = netdev_alloc_skb(dev, pkt_len + 2); if (skb != NULL) { unsigned char *buf; skb_reserve(skb, 2); /* 16 byte align the IP header */ diff --git a/drivers/net/ethernet/amd/ni65.c b/drivers/net/ethernet/amd/ni65.c index 735c213798b..013b6510853 100644 --- a/drivers/net/ethernet/amd/ni65.c +++ b/drivers/net/ethernet/amd/ni65.c @@ -1089,7 +1089,7 @@ static void ni65_recv_intr(struct net_device *dev,int csr0) if (skb) skb_reserve(skb,16); #else - struct sk_buff *skb = dev_alloc_skb(len+2); + struct sk_buff *skb = netdev_alloc_skb(dev, len + 2); #endif if(skb) { diff --git a/drivers/net/ethernet/amd/nmclan_cs.c b/drivers/net/ethernet/amd/nmclan_cs.c index 6be0dd67631..ebdb9e238a8 100644 --- a/drivers/net/ethernet/amd/nmclan_cs.c +++ b/drivers/net/ethernet/amd/nmclan_cs.c @@ -1104,7 +1104,7 @@ static int mace_rx(struct net_device *dev, unsigned char RxCnt) pr_debug(" receiving packet size 0x%X rx_status" " 0x%X.\n", pkt_len, rx_status); - skb = dev_alloc_skb(pkt_len+2); + skb = netdev_alloc_skb(dev, pkt_len + 2); if (skb != NULL) { skb_reserve(skb, 2); diff --git a/drivers/net/ethernet/amd/pcnet32.c b/drivers/net/ethernet/amd/pcnet32.c index 1bb388f62e5..86b6d8e4e6c 100644 --- a/drivers/net/ethernet/amd/pcnet32.c +++ b/drivers/net/ethernet/amd/pcnet32.c @@ -588,11 +588,11 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev, /* now allocate any new buffers needed */ for (; new < size; new++) { struct sk_buff *rx_skbuff; - new_skb_list[new] = dev_alloc_skb(PKT_BUF_SKB); + new_skb_list[new] = netdev_alloc_skb(dev, PKT_BUF_SKB); rx_skbuff = new_skb_list[new]; if (!rx_skbuff) { /* keep the original lists and buffers */ - netif_err(lp, drv, dev, "%s dev_alloc_skb failed\n", + netif_err(lp, drv, dev, "%s netdev_alloc_skb failed\n", __func__); goto free_all_new; } @@ -909,7 +909,7 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1) /* Initialize Transmit buffers. */ size = data_len + 15; for (x = 0; x < numbuffs; x++) { - skb = dev_alloc_skb(size); + skb = netdev_alloc_skb(dev, size); if (!skb) { netif_printk(lp, hw, KERN_DEBUG, dev, "Cannot allocate skb at line: %d!\n", @@ -1152,7 +1152,7 @@ static void pcnet32_rx_entry(struct net_device *dev, if (pkt_len > rx_copybreak) { struct sk_buff *newskb; - newskb = dev_alloc_skb(PKT_BUF_SKB); + newskb = netdev_alloc_skb(dev, PKT_BUF_SKB); if (newskb) { skb_reserve(newskb, NET_IP_ALIGN); skb = lp->rx_skbuff[entry]; @@ -1172,7 +1172,7 @@ static void pcnet32_rx_entry(struct net_device *dev, } else skb = NULL; } else - skb = dev_alloc_skb(pkt_len + NET_IP_ALIGN); + skb = netdev_alloc_skb(dev, pkt_len + NET_IP_ALIGN); if (skb == NULL) { netif_err(lp, drv, dev, "Memory squeeze, dropping packet\n"); @@ -2271,11 +2271,11 @@ static int pcnet32_init_ring(struct net_device *dev) for (i = 0; i < lp->rx_ring_size; i++) { struct sk_buff *rx_skbuff = lp->rx_skbuff[i]; if (rx_skbuff == NULL) { - lp->rx_skbuff[i] = dev_alloc_skb(PKT_BUF_SKB); + lp->rx_skbuff[i] = netdev_alloc_skb(dev, PKT_BUF_SKB); rx_skbuff = lp->rx_skbuff[i]; if (!rx_skbuff) { /* there is not much we can do at this point */ - netif_err(lp, drv, dev, "%s dev_alloc_skb failed\n", + netif_err(lp, drv, dev, "%s netdev_alloc_skb failed\n", __func__); return -1; } diff --git a/drivers/net/ethernet/amd/sun3lance.c b/drivers/net/ethernet/amd/sun3lance.c index 080b71fcc68..74b3891b648 100644 --- a/drivers/net/ethernet/amd/sun3lance.c +++ b/drivers/net/ethernet/amd/sun3lance.c @@ -810,7 +810,7 @@ static int lance_rx( struct net_device *dev ) dev->stats.rx_errors++; } else { - skb = dev_alloc_skb( pkt_len+2 ); + skb = netdev_alloc_skb(dev, pkt_len + 2); if (skb == NULL) { DPRINTK( 1, ( "%s: Memory squeeze, deferring packet.\n", dev->name )); diff --git a/drivers/net/ethernet/amd/sunlance.c b/drivers/net/ethernet/amd/sunlance.c index 7ea16d32a5f..e3fe3504e19 100644 --- a/drivers/net/ethernet/amd/sunlance.c +++ b/drivers/net/ethernet/amd/sunlance.c @@ -534,7 +534,7 @@ static void lance_rx_dvma(struct net_device *dev) if (bits & LE_R1_EOP) dev->stats.rx_errors++; } else { len = (rd->mblength & 0xfff) - 4; - skb = dev_alloc_skb(len + 2); + skb = netdev_alloc_skb(dev, len + 2); if (skb == NULL) { printk(KERN_INFO "%s: Memory squeeze, deferring packet.\n", @@ -706,7 +706,7 @@ static void lance_rx_pio(struct net_device *dev) if (bits & LE_R1_EOP) dev->stats.rx_errors++; } else { len = (sbus_readw(&rd->mblength) & 0xfff) - 4; - skb = dev_alloc_skb(len + 2); + skb = netdev_alloc_skb(dev, len + 2); if (skb == NULL) { printk(KERN_INFO "%s: Memory squeeze, deferring packet.\n", diff --git a/drivers/net/ethernet/apple/mace.c b/drivers/net/ethernet/apple/mace.c index bd5555dbe02..06998462e0d 100644 --- a/drivers/net/ethernet/apple/mace.c +++ b/drivers/net/ethernet/apple/mace.c @@ -444,7 +444,7 @@ static int mace_open(struct net_device *dev) memset((char *)mp->rx_cmds, 0, N_RX_RING * sizeof(struct dbdma_cmd)); cp = mp->rx_cmds; for (i = 0; i < N_RX_RING - 1; ++i) { - skb = dev_alloc_skb(RX_BUFLEN + 2); + skb = netdev_alloc_skb(dev, RX_BUFLEN + 2); if (!skb) { data = dummy_buf; } else { @@ -956,7 +956,7 @@ static irqreturn_t mace_rxdma_intr(int irq, void *dev_id) cp = mp->rx_cmds + i; skb = mp->rx_bufs[i]; if (!skb) { - skb = dev_alloc_skb(RX_BUFLEN + 2); + skb = netdev_alloc_skb(RX_BUFLEN + 2); if (skb) { skb_reserve(skb, 2); mp->rx_bufs[i] = skb; diff --git a/drivers/net/ethernet/apple/macmace.c b/drivers/net/ethernet/apple/macmace.c index 7cf81bbffe0..ab7ff8645ab 100644 --- a/drivers/net/ethernet/apple/macmace.c +++ b/drivers/net/ethernet/apple/macmace.c @@ -661,7 +661,7 @@ static void mace_dma_rx_frame(struct net_device *dev, struct mace_frame *mf) } else { unsigned int frame_length = mf->rcvcnt + ((frame_status & 0x0F) << 8 ); - skb = dev_alloc_skb(frame_length + 2); + skb = netdev_alloc_skb(dev, frame_length + 2); if (!skb) { dev->stats.rx_dropped++; return; diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c index 7ee4aacb01a..2c8ed70704a 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c @@ -1765,7 +1765,7 @@ static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter, const int ringid while (next_info->flags & ATL1C_BUFFER_FREE) { rfd_desc = ATL1C_RFD_DESC(rfd_ring, rfd_next_to_use); - skb = dev_alloc_skb(adapter->rx_buffer_len); + skb = netdev_alloc_skb(adapter->netdev, adapter->rx_buffer_len); if (unlikely(!skb)) { if (netif_msg_rx_err(adapter)) dev_warn(&pdev->dev, "alloc rx buffer failed\n"); diff --git a/drivers/net/ethernet/cadence/at91_ether.c b/drivers/net/ethernet/cadence/at91_ether.c index 1a5b6efa012..906117016fc 100644 --- a/drivers/net/ethernet/cadence/at91_ether.c +++ b/drivers/net/ethernet/cadence/at91_ether.c @@ -886,7 +886,7 @@ static void at91ether_rx(struct net_device *dev) while (dlist->descriptors[lp->rxBuffIndex].addr & EMAC_DESC_DONE) { p_recv = dlist->recv_buf[lp->rxBuffIndex]; pktlen = dlist->descriptors[lp->rxBuffIndex].size & 0x7ff; /* Length of frame including FCS */ - skb = dev_alloc_skb(pktlen + 2); + skb = netdev_alloc_skb(dev, pktlen + 2); if (skb != NULL) { skb_reserve(skb, 2); memcpy(skb_put(skb, pktlen), p_recv, pktlen); -- cgit v1.2.3-70-g09d2 From 21a4e46995fa1a76281ac0281ff837f706231a37 Mon Sep 17 00:00:00 2001 From: Pradeep A Dalvi Date: Sun, 5 Feb 2012 02:50:10 +0000 Subject: netdev: ethernet dev_alloc_skb to netdev_alloc_skb Replaced deprecating dev_alloc_skb with netdev_alloc_skb in drivers/net/ethernet - Removed extra skb->dev = dev after netdev_alloc_skb Signed-off-by: Pradeep A Dalvi Signed-off-by: David S. Miller --- drivers/net/ethernet/cadence/macb.c | 2 +- drivers/net/ethernet/cirrus/cs89x0.c | 4 ++-- drivers/net/ethernet/cirrus/ep93xx_eth.c | 2 +- drivers/net/ethernet/davicom/dm9000.c | 2 +- drivers/net/ethernet/dec/ewrk3.c | 4 +++- drivers/net/ethernet/dec/tulip/de2104x.c | 6 ++---- drivers/net/ethernet/dec/tulip/de4x5.c | 4 ++-- drivers/net/ethernet/dec/tulip/interrupt.c | 8 ++++---- drivers/net/ethernet/dec/tulip/tulip_core.c | 5 ++--- drivers/net/ethernet/dec/tulip/winbond-840.c | 6 +++--- drivers/net/ethernet/dec/tulip/xircom_cb.c | 2 +- drivers/net/ethernet/dlink/de600.c | 2 +- drivers/net/ethernet/dlink/de620.c | 2 +- drivers/net/ethernet/dlink/sundance.c | 9 ++++----- drivers/net/ethernet/dnet.c | 2 +- drivers/net/ethernet/fealnx.c | 8 +++----- drivers/net/ethernet/freescale/fec.c | 4 ++-- drivers/net/ethernet/freescale/fec_mpc52xx.c | 4 ++-- drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c | 12 ++++++------ drivers/net/ethernet/freescale/ucc_geth.c | 7 +++---- drivers/net/ethernet/fujitsu/at1700.c | 2 +- 21 files changed, 46 insertions(+), 51 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index 3c315f46859..85e044567f6 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -397,7 +397,7 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag, netdev_dbg(bp->dev, "macb_rx_frame frags %u - %u (len %u)\n", first_frag, last_frag, len); - skb = dev_alloc_skb(len + RX_OFFSET); + skb = netdev_alloc_skb(bp->dev, len + RX_OFFSET); if (!skb) { bp->stats.rx_dropped++; for (frag = first_frag; ; frag = NEXT_RX(frag)) { diff --git a/drivers/net/ethernet/cirrus/cs89x0.c b/drivers/net/ethernet/cirrus/cs89x0.c index f328da24c8f..d5ff93653e4 100644 --- a/drivers/net/ethernet/cirrus/cs89x0.c +++ b/drivers/net/ethernet/cirrus/cs89x0.c @@ -911,7 +911,7 @@ dma_rx(struct net_device *dev) } /* Malloc up new buffer. */ - skb = dev_alloc_skb(length + 2); + skb = netdev_alloc_skb(dev, length + 2); if (skb == NULL) { if (net_debug) /* I don't think we want to do this to a stressed system */ printk("%s: Memory squeeze, dropping packet.\n", dev->name); @@ -1616,7 +1616,7 @@ net_rx(struct net_device *dev) } /* Malloc up new buffer. */ - skb = dev_alloc_skb(length + 2); + skb = netdev_alloc_skb(dev, length + 2); if (skb == NULL) { #if 0 /* Again, this seems a cruel thing to do */ printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name); diff --git a/drivers/net/ethernet/cirrus/ep93xx_eth.c b/drivers/net/ethernet/cirrus/ep93xx_eth.c index 4317af8d2f0..c21e5ab8d1e 100644 --- a/drivers/net/ethernet/cirrus/ep93xx_eth.c +++ b/drivers/net/ethernet/cirrus/ep93xx_eth.c @@ -282,7 +282,7 @@ static int ep93xx_rx(struct net_device *dev, int processed, int budget) if (rstat0 & RSTAT0_CRCI) length -= 4; - skb = dev_alloc_skb(length + 2); + skb = netdev_alloc_skb(dev, length + 2); if (likely(skb != NULL)) { struct ep93xx_rdesc *rxd = &ep->descs->rdesc[entry]; skb_reserve(skb, 2); diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c index 493cc620208..42383ab5227 100644 --- a/drivers/net/ethernet/davicom/dm9000.c +++ b/drivers/net/ethernet/davicom/dm9000.c @@ -1028,7 +1028,7 @@ dm9000_rx(struct net_device *dev) /* Move data from DM9000 */ if (GoodPacket && - ((skb = dev_alloc_skb(RxLen + 4)) != NULL)) { + ((skb = netdev_alloc_skb(dev, RxLen + 4)) != NULL)) { skb_reserve(skb, 2); rdptr = (u8 *) skb_put(skb, RxLen - 4); diff --git a/drivers/net/ethernet/dec/ewrk3.c b/drivers/net/ethernet/dec/ewrk3.c index f9df5e4d034..1879f84a25a 100644 --- a/drivers/net/ethernet/dec/ewrk3.c +++ b/drivers/net/ethernet/dec/ewrk3.c @@ -986,8 +986,10 @@ static int ewrk3_rx(struct net_device *dev) dev->stats.rx_fifo_errors++; } else { struct sk_buff *skb; + skb = netdev_alloc_skb(dev, + pkt_len + 2); - if ((skb = dev_alloc_skb(pkt_len + 2)) != NULL) { + if (skb != NULL) { unsigned char *p; skb_reserve(skb, 2); /* Align to 16 bytes */ p = skb_put(skb, pkt_len); diff --git a/drivers/net/ethernet/dec/tulip/de2104x.c b/drivers/net/ethernet/dec/tulip/de2104x.c index 1eb46a0bb48..68f1c39184d 100644 --- a/drivers/net/ethernet/dec/tulip/de2104x.c +++ b/drivers/net/ethernet/dec/tulip/de2104x.c @@ -439,7 +439,7 @@ static void de_rx (struct de_private *de) rx_tail, status, len, copying_skb); buflen = copying_skb ? (len + RX_OFFSET) : de->rx_buf_sz; - copy_skb = dev_alloc_skb (buflen); + copy_skb = netdev_alloc_skb(de->dev, buflen); if (unlikely(!copy_skb)) { de->net_stats.rx_dropped++; drop = 1; @@ -1283,12 +1283,10 @@ static int de_refill_rx (struct de_private *de) for (i = 0; i < DE_RX_RING_SIZE; i++) { struct sk_buff *skb; - skb = dev_alloc_skb(de->rx_buf_sz); + skb = netdev_alloc_skb(de->dev, de->rx_buf_sz); if (!skb) goto err_out; - skb->dev = de->dev; - de->rx_skb[i].mapping = pci_map_single(de->pdev, skb->data, de->rx_buf_sz, PCI_DMA_FROMDEVICE); de->rx_skb[i].skb = skb; diff --git a/drivers/net/ethernet/dec/tulip/de4x5.c b/drivers/net/ethernet/dec/tulip/de4x5.c index 4d71f5ae20c..93583408a32 100644 --- a/drivers/net/ethernet/dec/tulip/de4x5.c +++ b/drivers/net/ethernet/dec/tulip/de4x5.c @@ -3598,7 +3598,7 @@ de4x5_alloc_rx_buff(struct net_device *dev, int index, int len) struct sk_buff *ret; u_long i=0, tmp; - p = dev_alloc_skb(IEEE802_3_SZ + DE4X5_ALIGN + 2); + p = netdev_alloc_skb(dev, IEEE802_3_SZ + DE4X5_ALIGN + 2); if (!p) return NULL; tmp = virt_to_bus(p->data); @@ -3618,7 +3618,7 @@ de4x5_alloc_rx_buff(struct net_device *dev, int index, int len) #else if (lp->state != OPEN) return (struct sk_buff *)1; /* Fake out the open */ - p = dev_alloc_skb(len + 2); + p = netdev_alloc_skb(dev, len + 2); if (!p) return NULL; skb_reserve(p, 2); /* Align */ diff --git a/drivers/net/ethernet/dec/tulip/interrupt.c b/drivers/net/ethernet/dec/tulip/interrupt.c index feaee7424bd..28a5e425fec 100644 --- a/drivers/net/ethernet/dec/tulip/interrupt.c +++ b/drivers/net/ethernet/dec/tulip/interrupt.c @@ -69,7 +69,8 @@ int tulip_refill_rx(struct net_device *dev) struct sk_buff *skb; dma_addr_t mapping; - skb = tp->rx_buffers[entry].skb = dev_alloc_skb(PKT_BUF_SZ); + skb = tp->rx_buffers[entry].skb = + netdev_alloc_skb(dev, PKT_BUF_SZ); if (skb == NULL) break; @@ -77,7 +78,6 @@ int tulip_refill_rx(struct net_device *dev) PCI_DMA_FROMDEVICE); tp->rx_buffers[entry].mapping = mapping; - skb->dev = dev; /* Mark as being used by this device. */ tp->rx_ring[entry].buffer1 = cpu_to_le32(mapping); refilled++; } @@ -202,7 +202,7 @@ int tulip_poll(struct napi_struct *napi, int budget) /* Check if the packet is long enough to accept without copying to a minimally-sized skbuff. */ if (pkt_len < tulip_rx_copybreak && - (skb = dev_alloc_skb(pkt_len + 2)) != NULL) { + (skb = netdev_alloc_skb(dev, pkt_len + 2)) != NULL) { skb_reserve(skb, 2); /* 16 byte align the IP header */ pci_dma_sync_single_for_cpu(tp->pdev, tp->rx_buffers[entry].mapping, @@ -428,7 +428,7 @@ static int tulip_rx(struct net_device *dev) /* Check if the packet is long enough to accept without copying to a minimally-sized skbuff. */ if (pkt_len < tulip_rx_copybreak && - (skb = dev_alloc_skb(pkt_len + 2)) != NULL) { + (skb = netdev_alloc_skb(dev, pkt_len + 2)) != NULL) { skb_reserve(skb, 2); /* 16 byte align the IP header */ pci_dma_sync_single_for_cpu(tp->pdev, tp->rx_buffers[entry].mapping, diff --git a/drivers/net/ethernet/dec/tulip/tulip_core.c b/drivers/net/ethernet/dec/tulip/tulip_core.c index 17ecb18341c..fea3641d939 100644 --- a/drivers/net/ethernet/dec/tulip/tulip_core.c +++ b/drivers/net/ethernet/dec/tulip/tulip_core.c @@ -636,16 +636,15 @@ static void tulip_init_ring(struct net_device *dev) dma_addr_t mapping; /* Note the receive buffer must be longword aligned. - dev_alloc_skb() provides 16 byte alignment. But do *not* + netdev_alloc_skb() provides 16 byte alignment. But do *not* use skb_reserve() to align the IP header! */ - struct sk_buff *skb = dev_alloc_skb(PKT_BUF_SZ); + struct sk_buff *skb = netdev_alloc_skb(dev, PKT_BUF_SZ); tp->rx_buffers[i].skb = skb; if (skb == NULL) break; mapping = pci_map_single(tp->pdev, skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); tp->rx_buffers[i].mapping = mapping; - skb->dev = dev; /* Mark as being used by this device. */ tp->rx_ring[i].status = cpu_to_le32(DescOwned); /* Owned by Tulip chip */ tp->rx_ring[i].buffer1 = cpu_to_le32(mapping); } diff --git a/drivers/net/ethernet/dec/tulip/winbond-840.c b/drivers/net/ethernet/dec/tulip/winbond-840.c index 52da7b2fe3b..2ac6fff0363 100644 --- a/drivers/net/ethernet/dec/tulip/winbond-840.c +++ b/drivers/net/ethernet/dec/tulip/winbond-840.c @@ -815,7 +815,7 @@ static void init_rxtx_rings(struct net_device *dev) /* Fill in the Rx buffers. Handle allocation failure gracefully. */ for (i = 0; i < RX_RING_SIZE; i++) { - struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz); + struct sk_buff *skb = netdev_alloc_skb(dev, np->rx_buf_sz); np->rx_skbuff[i] = skb; if (skb == NULL) break; @@ -1231,7 +1231,7 @@ static int netdev_rx(struct net_device *dev) /* Check if the packet is long enough to accept without copying to a minimally-sized skbuff. */ if (pkt_len < rx_copybreak && - (skb = dev_alloc_skb(pkt_len + 2)) != NULL) { + (skb = netdev_alloc_skb(dev, pkt_len + 2)) != NULL) { skb_reserve(skb, 2); /* 16 byte align the IP header */ pci_dma_sync_single_for_cpu(np->pci_dev,np->rx_addr[entry], np->rx_skbuff[entry]->len, @@ -1270,7 +1270,7 @@ static int netdev_rx(struct net_device *dev) struct sk_buff *skb; entry = np->dirty_rx % RX_RING_SIZE; if (np->rx_skbuff[entry] == NULL) { - skb = dev_alloc_skb(np->rx_buf_sz); + skb = netdev_alloc_skb(dev, np->rx_buf_sz); np->rx_skbuff[entry] = skb; if (skb == NULL) break; /* Better luck next round. */ diff --git a/drivers/net/ethernet/dec/tulip/xircom_cb.c b/drivers/net/ethernet/dec/tulip/xircom_cb.c index b7c73eefb54..fdb329fe6e8 100644 --- a/drivers/net/ethernet/dec/tulip/xircom_cb.c +++ b/drivers/net/ethernet/dec/tulip/xircom_cb.c @@ -1084,7 +1084,7 @@ investigate_read_descriptor(struct net_device *dev, struct xircom_private *card, pkt_len = 1518; } - skb = dev_alloc_skb(pkt_len + 2); + skb = netdev_alloc_skb(dev, pkt_len + 2); if (skb == NULL) { dev->stats.rx_dropped++; goto out; diff --git a/drivers/net/ethernet/dlink/de600.c b/drivers/net/ethernet/dlink/de600.c index c24fab1e9cb..682750c052c 100644 --- a/drivers/net/ethernet/dlink/de600.c +++ b/drivers/net/ethernet/dlink/de600.c @@ -335,7 +335,7 @@ static void de600_rx_intr(struct net_device *dev) return; } - skb = dev_alloc_skb(size+2); + skb = netdev_alloc_skb(dev, size + 2); if (skb == NULL) { printk("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, size); return; diff --git a/drivers/net/ethernet/dlink/de620.c b/drivers/net/ethernet/dlink/de620.c index 3b934ab784d..afc5aaac6b6 100644 --- a/drivers/net/ethernet/dlink/de620.c +++ b/drivers/net/ethernet/dlink/de620.c @@ -650,7 +650,7 @@ static int de620_rx_intr(struct net_device *dev) printk(KERN_WARNING "%s: Illegal packet size: %d!\n", dev->name, size); } else { /* Good packet? */ - skb = dev_alloc_skb(size+2); + skb = netdev_alloc_skb(dev, size + 2); if (skb == NULL) { /* Yeah, but no place to put it... */ printk(KERN_WARNING "%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, size); dev->stats.rx_dropped++; diff --git a/drivers/net/ethernet/dlink/sundance.c b/drivers/net/ethernet/dlink/sundance.c index 28a3a9b50b8..7227f29ee2e 100644 --- a/drivers/net/ethernet/dlink/sundance.c +++ b/drivers/net/ethernet/dlink/sundance.c @@ -1020,11 +1020,11 @@ static void init_ring(struct net_device *dev) /* Fill in the Rx buffers. Handle allocation failure gracefully. */ for (i = 0; i < RX_RING_SIZE; i++) { - struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz + 2); + struct sk_buff *skb = + netdev_alloc_skb(dev, np->rx_buf_sz + 2); np->rx_skbuff[i] = skb; if (skb == NULL) break; - skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* 16 byte align the IP header. */ np->rx_ring[i].frag[0].addr = cpu_to_le32( dma_map_single(&np->pci_dev->dev, skb->data, @@ -1358,7 +1358,7 @@ static void rx_poll(unsigned long data) /* Check if the packet is long enough to accept without copying to a minimally-sized skbuff. */ if (pkt_len < rx_copybreak && - (skb = dev_alloc_skb(pkt_len + 2)) != NULL) { + (skb = netdev_alloc_skb(dev, pkt_len + 2)) != NULL) { skb_reserve(skb, 2); /* 16 byte align the IP header */ dma_sync_single_for_cpu(&np->pci_dev->dev, le32_to_cpu(desc->frag[0].addr), @@ -1411,11 +1411,10 @@ static void refill_rx (struct net_device *dev) struct sk_buff *skb; entry = np->dirty_rx % RX_RING_SIZE; if (np->rx_skbuff[entry] == NULL) { - skb = dev_alloc_skb(np->rx_buf_sz + 2); + skb = netdev_alloc_skb(dev, np->rx_buf_sz + 2); np->rx_skbuff[entry] = skb; if (skb == NULL) break; /* Better luck next round. */ - skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ np->rx_ring[entry].frag[0].addr = cpu_to_le32( dma_map_single(&np->pci_dev->dev, skb->data, diff --git a/drivers/net/ethernet/dnet.c b/drivers/net/ethernet/dnet.c index fe48cb7dde2..8536e376555 100644 --- a/drivers/net/ethernet/dnet.c +++ b/drivers/net/ethernet/dnet.c @@ -421,7 +421,7 @@ static int dnet_poll(struct napi_struct *napi, int budget) printk(KERN_ERR "%s packet receive error %x\n", __func__, cmd_word); - skb = dev_alloc_skb(pkt_len + 5); + skb = netdev_alloc_skb(dev, pkt_len + 5); if (skb != NULL) { /* Align IP on 16 byte boundaries */ skb_reserve(skb, 2); diff --git a/drivers/net/ethernet/fealnx.c b/drivers/net/ethernet/fealnx.c index c82d444b582..1637b986229 100644 --- a/drivers/net/ethernet/fealnx.c +++ b/drivers/net/ethernet/fealnx.c @@ -1070,14 +1070,13 @@ static void allocate_rx_buffers(struct net_device *dev) while (np->really_rx_count != RX_RING_SIZE) { struct sk_buff *skb; - skb = dev_alloc_skb(np->rx_buf_sz); + skb = netdev_alloc_skb(dev, np->rx_buf_sz); if (skb == NULL) break; /* Better luck next round. */ while (np->lack_rxbuf->skbuff) np->lack_rxbuf = np->lack_rxbuf->next_desc_logical; - skb->dev = dev; /* Mark as being used by this device. */ np->lack_rxbuf->skbuff = skb; np->lack_rxbuf->buffer = pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE); @@ -1265,7 +1264,7 @@ static void init_ring(struct net_device *dev) /* allocate skb for rx buffers */ for (i = 0; i < RX_RING_SIZE; i++) { - struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz); + struct sk_buff *skb = netdev_alloc_skb(dev, np->rx_buf_sz); if (skb == NULL) { np->lack_rxbuf = &np->rx_ring[i]; @@ -1274,7 +1273,6 @@ static void init_ring(struct net_device *dev) ++np->really_rx_count; np->rx_ring[i].skbuff = skb; - skb->dev = dev; /* Mark as being used by this device. */ np->rx_ring[i].buffer = pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE); np->rx_ring[i].status = RXOWN; @@ -1704,7 +1702,7 @@ static int netdev_rx(struct net_device *dev) /* Check if the packet is long enough to accept without copying to a minimally-sized skbuff. */ if (pkt_len < rx_copybreak && - (skb = dev_alloc_skb(pkt_len + 2)) != NULL) { + (skb = netdev_alloc_skb(dev, pkt_len + 2)) != NULL) { skb_reserve(skb, 2); /* 16 byte align the IP header */ pci_dma_sync_single_for_cpu(np->pci_dev, np->cur_rx->buffer, diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index 336edd7e0b7..f976619d1b2 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -711,7 +711,7 @@ fec_enet_rx(struct net_device *ndev) * include that when passing upstream as it messes up * bridging applications. */ - skb = dev_alloc_skb(pkt_len - 4 + NET_IP_ALIGN); + skb = netdev_alloc_skb(dev, pkt_len - 4 + NET_IP_ALIGN); if (unlikely(!skb)) { printk("%s: Memory squeeze, dropping packet.\n", @@ -1210,7 +1210,7 @@ static int fec_enet_alloc_buffers(struct net_device *ndev) bdp = fep->rx_bd_base; for (i = 0; i < RX_RING_SIZE; i++) { - skb = dev_alloc_skb(FEC_ENET_RX_FRSIZE); + skb = netdev_alloc_skb(dev, FEC_ENET_RX_FRSIZE); if (!skb) { fec_enet_free_buffers(ndev); return -ENOMEM; diff --git a/drivers/net/ethernet/freescale/fec_mpc52xx.c b/drivers/net/ethernet/freescale/fec_mpc52xx.c index 30745b56fe5..7b34d8c698d 100644 --- a/drivers/net/ethernet/freescale/fec_mpc52xx.c +++ b/drivers/net/ethernet/freescale/fec_mpc52xx.c @@ -160,7 +160,7 @@ static int mpc52xx_fec_alloc_rx_buffers(struct net_device *dev, struct bcom_task struct sk_buff *skb; while (!bcom_queue_full(rxtsk)) { - skb = dev_alloc_skb(FEC_RX_BUFFER_SIZE); + skb = netdev_alloc_skb(dev, FEC_RX_BUFFER_SIZE); if (!skb) return -EAGAIN; @@ -416,7 +416,7 @@ static irqreturn_t mpc52xx_fec_rx_interrupt(int irq, void *dev_id) /* skbs are allocated on open, so now we allocate a new one, * and remove the old (with the packet) */ - skb = dev_alloc_skb(FEC_RX_BUFFER_SIZE); + skb = netdev_alloc_skb(dev, FEC_RX_BUFFER_SIZE); if (!skb) { /* Can't get a new one : reuse the same & drop pkt */ dev_notice(&dev->dev, "Low memory - dropped packet.\n"); diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c index 910a8e18a9a..999638a7c85 100644 --- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c +++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c @@ -154,7 +154,7 @@ static int fs_enet_rx_napi(struct napi_struct *napi, int budget) if (pkt_len <= fpi->rx_copybreak) { /* +2 to make IP header L1 cache aligned */ - skbn = dev_alloc_skb(pkt_len + 2); + skbn = netdev_alloc_skb(dev, pkt_len + 2); if (skbn != NULL) { skb_reserve(skbn, 2); /* align IP header */ skb_copy_from_linear_data(skb, @@ -165,7 +165,7 @@ static int fs_enet_rx_napi(struct napi_struct *napi, int budget) skbn = skbt; } } else { - skbn = dev_alloc_skb(ENET_RX_FRSIZE); + skbn = netdev_alloc_skb(dev, ENET_RX_FRSIZE); if (skbn) skb_align(skbn, ENET_RX_ALIGN); @@ -286,7 +286,7 @@ static int fs_enet_rx_non_napi(struct net_device *dev) if (pkt_len <= fpi->rx_copybreak) { /* +2 to make IP header L1 cache aligned */ - skbn = dev_alloc_skb(pkt_len + 2); + skbn = netdev_alloc_skb(dev, pkt_len + 2); if (skbn != NULL) { skb_reserve(skbn, 2); /* align IP header */ skb_copy_from_linear_data(skb, @@ -297,7 +297,7 @@ static int fs_enet_rx_non_napi(struct net_device *dev) skbn = skbt; } } else { - skbn = dev_alloc_skb(ENET_RX_FRSIZE); + skbn = netdev_alloc_skb(dev, ENET_RX_FRSIZE); if (skbn) skb_align(skbn, ENET_RX_ALIGN); @@ -504,7 +504,7 @@ void fs_init_bds(struct net_device *dev) * Initialize the receive buffer descriptors. */ for (i = 0, bdp = fep->rx_bd_base; i < fep->rx_ring; i++, bdp++) { - skb = dev_alloc_skb(ENET_RX_FRSIZE); + skb = netdev_alloc_skb(dev, ENET_RX_FRSIZE); if (skb == NULL) { dev_warn(fep->dev, "Memory squeeze, unable to allocate skb\n"); @@ -592,7 +592,7 @@ static struct sk_buff *tx_skb_align_workaround(struct net_device *dev, struct fs_enet_private *fep = netdev_priv(dev); /* Alloc new skb */ - new_skb = dev_alloc_skb(skb->len + 4); + new_skb = netdev_alloc_skb(dev, skb->len + 4); if (!new_skb) { if (net_ratelimit()) { dev_warn(fep->dev, diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c index ba2dc083bfc..ec090546131 100644 --- a/drivers/net/ethernet/freescale/ucc_geth.c +++ b/drivers/net/ethernet/freescale/ucc_geth.c @@ -214,8 +214,9 @@ static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth, skb = __skb_dequeue(&ugeth->rx_recycle); if (!skb) - skb = dev_alloc_skb(ugeth->ug_info->uf_info.max_rx_buf_length + - UCC_GETH_RX_DATA_BUF_ALIGNMENT); + skb = netdev_alloc_skb(ugeth->ndev, + ugeth->ug_info->uf_info.max_rx_buf_length + + UCC_GETH_RX_DATA_BUF_ALIGNMENT); if (skb == NULL) return NULL; @@ -227,8 +228,6 @@ static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth, (((unsigned)skb->data) & (UCC_GETH_RX_DATA_BUF_ALIGNMENT - 1))); - skb->dev = ugeth->ndev; - out_be32(&((struct qe_bd __iomem *)bd)->buf, dma_map_single(ugeth->dev, skb->data, diff --git a/drivers/net/ethernet/fujitsu/at1700.c b/drivers/net/ethernet/fujitsu/at1700.c index 7c6c908bdf0..586b46fd4ee 100644 --- a/drivers/net/ethernet/fujitsu/at1700.c +++ b/drivers/net/ethernet/fujitsu/at1700.c @@ -757,7 +757,7 @@ net_rx(struct net_device *dev) dev->stats.rx_errors++; break; } - skb = dev_alloc_skb(pkt_len+3); + skb = netdev_alloc_skb(dev, pkt_len + 3); if (skb == NULL) { printk("%s: Memory squeeze, dropping packet (len %d).\n", dev->name, pkt_len); -- cgit v1.2.3-70-g09d2 From c056b734e54e12f38f34a2583a4824e6cecc16c1 Mon Sep 17 00:00:00 2001 From: Pradeep A Dalvi Date: Sun, 5 Feb 2012 02:50:38 +0000 Subject: netdev: ethernet dev_alloc_skb to netdev_alloc_skb Replaced deprecating dev_alloc_skb with netdev_alloc_skb in drivers/net/ethernet - Removed extra skb->dev = dev after netdev_alloc_skb Signed-off-by: Pradeep A Dalvi Signed-off-by: David S. Miller --- drivers/net/ethernet/fujitsu/eth16i.c | 2 +- drivers/net/ethernet/fujitsu/fmvj18x_cs.c | 2 +- drivers/net/ethernet/hp/hp100.c | 5 ++--- drivers/net/ethernet/i825xx/3c505.c | 2 +- drivers/net/ethernet/i825xx/3c507.c | 2 +- drivers/net/ethernet/i825xx/3c523.c | 2 +- drivers/net/ethernet/i825xx/3c527.c | 4 ++-- drivers/net/ethernet/i825xx/82596.c | 8 +++----- drivers/net/ethernet/i825xx/eepro.c | 2 +- drivers/net/ethernet/i825xx/eexpress.c | 2 +- drivers/net/ethernet/i825xx/ether1.c | 2 +- drivers/net/ethernet/i825xx/lp486e.c | 2 +- drivers/net/ethernet/i825xx/ni52.c | 2 +- drivers/net/ethernet/i825xx/sun3_82586.c | 2 +- drivers/net/ethernet/i825xx/znet.c | 2 +- drivers/net/ethernet/icplus/ipg.c | 3 --- drivers/net/ethernet/lantiq_etop.c | 2 +- drivers/net/ethernet/marvell/mv643xx_eth.c | 2 +- drivers/net/ethernet/marvell/pxa168_eth.c | 2 +- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 3 +-- drivers/net/ethernet/micrel/ks8695net.c | 4 ++-- drivers/net/ethernet/micrel/ks8851_mll.c | 2 +- drivers/net/ethernet/micrel/ksz884x.c | 6 +++--- drivers/net/ethernet/microchip/enc28j60.c | 3 +-- drivers/net/ethernet/mipsnet.c | 2 +- drivers/net/ethernet/natsemi/ibmlana.c | 2 +- drivers/net/ethernet/natsemi/natsemi.c | 5 ++--- drivers/net/ethernet/natsemi/sonic.c | 4 ++-- drivers/net/ethernet/neterion/s2io.c | 6 +++--- 29 files changed, 39 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/fujitsu/eth16i.c b/drivers/net/ethernet/fujitsu/eth16i.c index b0e2313af3d..c3f0178fb5c 100644 --- a/drivers/net/ethernet/fujitsu/eth16i.c +++ b/drivers/net/ethernet/fujitsu/eth16i.c @@ -1164,7 +1164,7 @@ static void eth16i_rx(struct net_device *dev) else { /* Ok so now we should have a good packet */ struct sk_buff *skb; - skb = dev_alloc_skb(pkt_len + 3); + skb = netdev_alloc_skb(dev, pkt_len + 3); if( skb == NULL ) { printk(KERN_WARNING "%s: Could'n allocate memory for packet (len %d)\n", dev->name, pkt_len); diff --git a/drivers/net/ethernet/fujitsu/fmvj18x_cs.c b/drivers/net/ethernet/fujitsu/fmvj18x_cs.c index ee84b472cee..0230319ddb5 100644 --- a/drivers/net/ethernet/fujitsu/fmvj18x_cs.c +++ b/drivers/net/ethernet/fujitsu/fmvj18x_cs.c @@ -1002,7 +1002,7 @@ static void fjn_rx(struct net_device *dev) dev->stats.rx_errors++; break; } - skb = dev_alloc_skb(pkt_len+2); + skb = netdev_alloc_skb(dev, pkt_len + 2); if (skb == NULL) { netdev_notice(dev, "Memory squeeze, dropping packet (len %d)\n", pkt_len); diff --git a/drivers/net/ethernet/hp/hp100.c b/drivers/net/ethernet/hp/hp100.c index 3598c5408e7..d496673f090 100644 --- a/drivers/net/ethernet/hp/hp100.c +++ b/drivers/net/ethernet/hp/hp100.c @@ -1274,7 +1274,7 @@ static int hp100_build_rx_pdl(hp100_ring_t * ringptr, /* Note: This depends on the alloc_skb functions allocating more * space than requested, i.e. aligning to 16bytes */ - ringptr->skb = dev_alloc_skb(roundup(MAX_ETHER_SIZE + 2, 4)); + ringptr->skb = netdev_alloc_skb(dev, roundup(MAX_ETHER_SIZE + 2, 4)); if (NULL != ringptr->skb) { /* @@ -1284,7 +1284,6 @@ static int hp100_build_rx_pdl(hp100_ring_t * ringptr, */ skb_reserve(ringptr->skb, 2); - ringptr->skb->dev = dev; ringptr->skb->data = (u_char *) skb_put(ringptr->skb, MAX_ETHER_SIZE); /* ringptr->pdl points to the beginning of the PDL, i.e. the PDH */ @@ -1817,7 +1816,7 @@ static void hp100_rx(struct net_device *dev) #endif /* Now we allocate the skb and transfer the data into it. */ - skb = dev_alloc_skb(pkt_len+2); + skb = netdev_alloc_skb(dev, pkt_len + 2); if (skb == NULL) { /* Not enough memory->drop packet */ #ifdef HP100_DEBUG printk("hp100: %s: rx: couldn't allocate a sk_buff of size %d\n", diff --git a/drivers/net/ethernet/i825xx/3c505.c b/drivers/net/ethernet/i825xx/3c505.c index ba82a266051..6a5c21b82c5 100644 --- a/drivers/net/ethernet/i825xx/3c505.c +++ b/drivers/net/ethernet/i825xx/3c505.c @@ -583,7 +583,7 @@ static void receive_packet(struct net_device *dev, int len) unsigned long flags; rlen = (len + 1) & ~1; - skb = dev_alloc_skb(rlen + 2); + skb = netdev_alloc_skb(dev, rlen + 2); if (!skb) { pr_warning("%s: memory squeeze, dropping packet\n", dev->name); diff --git a/drivers/net/ethernet/i825xx/3c507.c b/drivers/net/ethernet/i825xx/3c507.c index 1e945551c14..ed6925f1147 100644 --- a/drivers/net/ethernet/i825xx/3c507.c +++ b/drivers/net/ethernet/i825xx/3c507.c @@ -851,7 +851,7 @@ static void el16_rx(struct net_device *dev) struct sk_buff *skb; pkt_len &= 0x3fff; - skb = dev_alloc_skb(pkt_len+2); + skb = netdev_alloc_skb(dev, pkt_len + 2); if (skb == NULL) { pr_err("%s: Memory squeeze, dropping packet.\n", dev->name); diff --git a/drivers/net/ethernet/i825xx/3c523.c b/drivers/net/ethernet/i825xx/3c523.c index d70d3df4c98..8451ecd4c1e 100644 --- a/drivers/net/ethernet/i825xx/3c523.c +++ b/drivers/net/ethernet/i825xx/3c523.c @@ -983,7 +983,7 @@ static void elmc_rcv_int(struct net_device *dev) if ((totlen = rbd->status) & RBD_LAST) { /* the first and the last buffer? */ totlen &= RBD_MASK; /* length of this frame */ rbd->status = 0; - skb = (struct sk_buff *) dev_alloc_skb(totlen + 2); + skb = netdev_alloc_skb(dev, totlen + 2); if (skb != NULL) { skb_reserve(skb, 2); /* 16 byte alignment */ skb_put(skb,totlen); diff --git a/drivers/net/ethernet/i825xx/3c527.c b/drivers/net/ethernet/i825xx/3c527.c index 474b5e71a53..ef43f3e951c 100644 --- a/drivers/net/ethernet/i825xx/3c527.c +++ b/drivers/net/ethernet/i825xx/3c527.c @@ -1169,7 +1169,7 @@ static void mc32_rx_ring(struct net_device *dev) /* Try to save time by avoiding a copy on big frames */ if ((length > RX_COPYBREAK) && - ((newskb=dev_alloc_skb(1532)) != NULL)) + ((newskb = netdev_alloc_skb(dev, 1532)) != NULL)) { skb=lp->rx_ring[rx_ring_tail].skb; skb_put(skb, length); @@ -1180,7 +1180,7 @@ static void mc32_rx_ring(struct net_device *dev) } else { - skb=dev_alloc_skb(length+2); + skb = netdev_alloc_skb(dev, length + 2); if(skb==NULL) { dev->stats.rx_dropped++; diff --git a/drivers/net/ethernet/i825xx/82596.c b/drivers/net/ethernet/i825xx/82596.c index f2408a4d5d9..6aa927af382 100644 --- a/drivers/net/ethernet/i825xx/82596.c +++ b/drivers/net/ethernet/i825xx/82596.c @@ -549,14 +549,13 @@ static inline int init_rx_bufs(struct net_device *dev) /* First build the Receive Buffer Descriptor List */ for (i = 0, rbd = lp->rbds; i < rx_ring_size; i++, rbd++) { - struct sk_buff *skb = dev_alloc_skb(PKT_BUF_SZ); + struct sk_buff *skb = netdev_alloc_skb(dev, PKT_BUF_SZ); if (skb == NULL) { remove_rx_bufs(dev); return -ENOMEM; } - skb->dev = dev; rbd->v_next = rbd+1; rbd->b_next = WSWAPrbd(virt_to_bus(rbd+1)); rbd->b_addr = WSWAPrbd(virt_to_bus(rbd)); @@ -810,7 +809,7 @@ static inline int i596_rx(struct net_device *dev) struct sk_buff *newskb; /* Get fresh skbuff to replace filled one. */ - newskb = dev_alloc_skb(PKT_BUF_SZ); + newskb = netdev_alloc_skb(dev, PKT_BUF_SZ); if (newskb == NULL) { skb = NULL; /* drop pkt */ goto memory_squeeze; @@ -819,7 +818,6 @@ static inline int i596_rx(struct net_device *dev) skb_put(skb, pkt_len); rx_in_place = 1; rbd->skb = newskb; - newskb->dev = dev; rbd->v_data = newskb->data; rbd->b_data = WSWAPchar(virt_to_bus(newskb->data)); #ifdef __mc68000__ @@ -827,7 +825,7 @@ static inline int i596_rx(struct net_device *dev) #endif } else - skb = dev_alloc_skb(pkt_len + 2); + skb = netdev_alloc_skb(dev, pkt_len + 2); memory_squeeze: if (skb == NULL) { /* XXX tulip.c can defer packets here!! */ diff --git a/drivers/net/ethernet/i825xx/eepro.c b/drivers/net/ethernet/i825xx/eepro.c index 114cda7721f..7a4ad4a0791 100644 --- a/drivers/net/ethernet/i825xx/eepro.c +++ b/drivers/net/ethernet/i825xx/eepro.c @@ -1563,7 +1563,7 @@ eepro_rx(struct net_device *dev) dev->stats.rx_bytes+=rcv_size; rcv_size &= 0x3fff; - skb = dev_alloc_skb(rcv_size+5); + skb = netdev_alloc_skb(dev, rcv_size + 5); if (skb == NULL) { printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name); dev->stats.rx_dropped++; diff --git a/drivers/net/ethernet/i825xx/eexpress.c b/drivers/net/ethernet/i825xx/eexpress.c index 3a9580f3d4d..3fc649e54a3 100644 --- a/drivers/net/ethernet/i825xx/eexpress.c +++ b/drivers/net/ethernet/i825xx/eexpress.c @@ -955,7 +955,7 @@ static void eexp_hw_rx_pio(struct net_device *dev) { struct sk_buff *skb; pkt_len &= 0x3fff; - skb = dev_alloc_skb(pkt_len+16); + skb = netdev_alloc_skb(dev, pkt_len + 16); if (skb == NULL) { printk(KERN_WARNING "%s: Memory squeeze, dropping packet\n",dev->name); diff --git a/drivers/net/ethernet/i825xx/ether1.c b/drivers/net/ethernet/i825xx/ether1.c index 42e90a97c7a..406a12b4640 100644 --- a/drivers/net/ethernet/i825xx/ether1.c +++ b/drivers/net/ethernet/i825xx/ether1.c @@ -867,7 +867,7 @@ ether1_recv_done (struct net_device *dev) struct sk_buff *skb; length = (length + 1) & ~1; - skb = dev_alloc_skb (length + 2); + skb = netdev_alloc_skb(dev, length + 2); if (skb) { skb_reserve (skb, 2); diff --git a/drivers/net/ethernet/i825xx/lp486e.c b/drivers/net/ethernet/i825xx/lp486e.c index 02df5f5accb..6c2952c8ea1 100644 --- a/drivers/net/ethernet/i825xx/lp486e.c +++ b/drivers/net/ethernet/i825xx/lp486e.c @@ -656,7 +656,7 @@ i596_rx_one(struct net_device *dev, struct i596_private *lp, if (rfd->stat & RFD_STAT_OK) { /* a good frame */ int pkt_len = (rfd->count & 0x3fff); - struct sk_buff *skb = dev_alloc_skb(pkt_len); + struct sk_buff *skb = netdev_alloc_skb(dev, pkt_len); (*frames)++; diff --git a/drivers/net/ethernet/i825xx/ni52.c b/drivers/net/ethernet/i825xx/ni52.c index c0893715ef4..272976e1bb0 100644 --- a/drivers/net/ethernet/i825xx/ni52.c +++ b/drivers/net/ethernet/i825xx/ni52.c @@ -964,7 +964,7 @@ static void ni52_rcv_int(struct net_device *dev) /* the first and the last buffer? */ totlen &= RBD_MASK; /* length of this frame */ writew(0x00, &rbd->status); - skb = (struct sk_buff *)dev_alloc_skb(totlen+2); + skb = netdev_alloc_skb(dev, totlen + 2); if (skb != NULL) { skb_reserve(skb, 2); skb_put(skb, totlen); diff --git a/drivers/net/ethernet/i825xx/sun3_82586.c b/drivers/net/ethernet/i825xx/sun3_82586.c index 296cf8a0ee5..cae17f4bc93 100644 --- a/drivers/net/ethernet/i825xx/sun3_82586.c +++ b/drivers/net/ethernet/i825xx/sun3_82586.c @@ -778,7 +778,7 @@ static void sun3_82586_rcv_int(struct net_device *dev) { totlen &= RBD_MASK; /* length of this frame */ rbd->status = 0; - skb = (struct sk_buff *) dev_alloc_skb(totlen+2); + skb = netdev_alloc_skb(dev, totlen + 2); if(skb != NULL) { skb_reserve(skb,2); diff --git a/drivers/net/ethernet/i825xx/znet.c b/drivers/net/ethernet/i825xx/znet.c index 962b4c421f3..a43649735a0 100644 --- a/drivers/net/ethernet/i825xx/znet.c +++ b/drivers/net/ethernet/i825xx/znet.c @@ -762,7 +762,7 @@ static void znet_rx(struct net_device *dev) /* Malloc up new buffer. */ struct sk_buff *skb; - skb = dev_alloc_skb(pkt_len); + skb = netdev_alloc_skb(dev, pkt_len); if (skb == NULL) { if (znet_debug) printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name); diff --git a/drivers/net/ethernet/icplus/ipg.c b/drivers/net/ethernet/icplus/ipg.c index 3c636f16a3c..1b563bb959c 100644 --- a/drivers/net/ethernet/icplus/ipg.c +++ b/drivers/net/ethernet/icplus/ipg.c @@ -744,9 +744,6 @@ static int ipg_get_rxbuff(struct net_device *dev, int entry) return -ENOMEM; } - /* Associate the receive buffer with the IPG NIC. */ - skb->dev = dev; - /* Save the address of the sk_buff structure. */ sp->rx_buff[entry] = skb; diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c index 86d2fe6e053..3369b7db777 100644 --- a/drivers/net/ethernet/lantiq_etop.c +++ b/drivers/net/ethernet/lantiq_etop.c @@ -114,7 +114,7 @@ struct ltq_etop_priv { static int ltq_etop_alloc_skb(struct ltq_etop_chan *ch) { - ch->skb[ch->dma.desc] = dev_alloc_skb(MAX_DMA_DATA_LEN); + ch->skb[ch->dma.desc] = netdev_alloc_skb(ch->netdev, MAX_DMA_DATA_LEN); if (!ch->skb[ch->dma.desc]) return -ENOMEM; ch->dma.desc_base[ch->dma.desc].addr = dma_map_single(NULL, diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index 9edecfa1f0f..f702d0dc18c 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c @@ -667,7 +667,7 @@ static int rxq_refill(struct rx_queue *rxq, int budget) skb = __skb_dequeue(&mp->rx_recycle); if (skb == NULL) - skb = dev_alloc_skb(mp->skb_size); + skb = netdev_alloc_skb(mp->dev, mp->skb_size); if (skb == NULL) { mp->oom = 1; diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c index 92b4b4e68e3..75df2091bd2 100644 --- a/drivers/net/ethernet/marvell/pxa168_eth.c +++ b/drivers/net/ethernet/marvell/pxa168_eth.c @@ -350,7 +350,7 @@ static void rxq_refill(struct net_device *dev) while (pep->rx_desc_count < pep->rx_ring_size) { int size; - skb = dev_alloc_skb(pep->skb_size); + skb = netdev_alloc_skb(dev, pep->skb_size); if (!skb) break; if (SKB_DMA_REALIGN) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index f61d0e08f52..fb6e899f38d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -463,12 +463,11 @@ static struct sk_buff *mlx4_en_rx_skb(struct mlx4_en_priv *priv, int used_frags; dma_addr_t dma; - skb = dev_alloc_skb(SMALL_PACKET_SIZE + NET_IP_ALIGN); + skb = netdev_alloc_skb(priv->dev, SMALL_PACKET_SIZE + NET_IP_ALIGN); if (!skb) { en_dbg(RX_ERR, priv, "Failed allocating skb\n"); return NULL; } - skb->dev = priv->dev; skb_reserve(skb, NET_IP_ALIGN); skb->len = length; diff --git a/drivers/net/ethernet/micrel/ks8695net.c b/drivers/net/ethernet/micrel/ks8695net.c index 7c717276502..dccae1d1743 100644 --- a/drivers/net/ethernet/micrel/ks8695net.c +++ b/drivers/net/ethernet/micrel/ks8695net.c @@ -278,7 +278,8 @@ ks8695_refill_rxbuffers(struct ks8695_priv *ksp) for (buff_n = 0; buff_n < MAX_RX_DESC; ++buff_n) { if (!ksp->rx_buffers[buff_n].skb) { - struct sk_buff *skb = dev_alloc_skb(MAX_RXBUF_SIZE); + struct sk_buff *skb = + netdev_alloc_skb(ksp->ndev, MAX_RXBUF_SIZE); dma_addr_t mapping; ksp->rx_buffers[buff_n].skb = skb; @@ -299,7 +300,6 @@ ks8695_refill_rxbuffers(struct ks8695_priv *ksp) break; } ksp->rx_buffers[buff_n].dma_ptr = mapping; - skb->dev = ksp->ndev; ksp->rx_buffers[buff_n].length = MAX_RXBUF_SIZE; /* Record this into the DMA ring */ diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c index 4a9d57fb9fb..61a2f61a31f 100644 --- a/drivers/net/ethernet/micrel/ks8851_mll.c +++ b/drivers/net/ethernet/micrel/ks8851_mll.c @@ -796,7 +796,7 @@ static void ks_rcv(struct ks_net *ks, struct net_device *netdev) frame_hdr = ks->frame_head_info; while (ks->frame_cnt--) { - skb = dev_alloc_skb(frame_hdr->len + 16); + skb = netdev_alloc_skb(netdev, frame_hdr->len + 16); if (likely(skb && (frame_hdr->sts & RXFSHR_RXFV) && (frame_hdr->len < RX_BUF_SIZE) && frame_hdr->len)) { skb_reserve(skb, 2); diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index 2725d693c3c..ef723b185d8 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c @@ -4863,7 +4863,7 @@ static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev) memset(&skb->data[skb->len], 0, 50 - skb->len); skb->len = 50; } else { - skb = dev_alloc_skb(50); + skb = netdev_alloc_skb(dev, 50); if (!skb) return NETDEV_TX_BUSY; memcpy(skb->data, org_skb->data, org_skb->len); @@ -4885,7 +4885,7 @@ static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev) (ETH_P_IPV6 == htons(skb->protocol)))) { struct sk_buff *org_skb = skb; - skb = dev_alloc_skb(org_skb->len); + skb = netdev_alloc_skb(dev, org_skb->len); if (!skb) { rc = NETDEV_TX_BUSY; goto unlock; @@ -5019,7 +5019,7 @@ static inline int rx_proc(struct net_device *dev, struct ksz_hw* hw, do { /* skb->data != skb->head */ - skb = dev_alloc_skb(packet_len + 2); + skb = netdev_alloc_skb(dev, packet_len + 2); if (!skb) { dev->stats.rx_dropped++; return -ENOMEM; diff --git a/drivers/net/ethernet/microchip/enc28j60.c b/drivers/net/ethernet/microchip/enc28j60.c index c813e5d8db9..1d6b7ce3e1e 100644 --- a/drivers/net/ethernet/microchip/enc28j60.c +++ b/drivers/net/ethernet/microchip/enc28j60.c @@ -954,14 +954,13 @@ static void enc28j60_hw_rx(struct net_device *ndev) if (len > MAX_FRAMELEN) ndev->stats.rx_over_errors++; } else { - skb = dev_alloc_skb(len + NET_IP_ALIGN); + skb = netdev_alloc_skb(ndev, len + NET_IP_ALIGN); if (!skb) { if (netif_msg_rx_err(priv)) dev_err(&ndev->dev, "out of memory for Rx'd frame\n"); ndev->stats.rx_dropped++; } else { - skb->dev = ndev; skb_reserve(skb, NET_IP_ALIGN); /* copy the packet from the receive buffer */ enc28j60_mem_read(priv, diff --git a/drivers/net/ethernet/mipsnet.c b/drivers/net/ethernet/mipsnet.c index d05b0c9e1e9..dbc666a3d52 100644 --- a/drivers/net/ethernet/mipsnet.c +++ b/drivers/net/ethernet/mipsnet.c @@ -152,7 +152,7 @@ static inline ssize_t mipsnet_get_fromdev(struct net_device *dev, size_t len) if (!len) return len; - skb = dev_alloc_skb(len + NET_IP_ALIGN); + skb = netdev_alloc_skb(dev, len + NET_IP_ALIGN); if (!skb) { dev->stats.rx_dropped++; return -ENOMEM; diff --git a/drivers/net/ethernet/natsemi/ibmlana.c b/drivers/net/ethernet/natsemi/ibmlana.c index 999407f7ebd..3f94ddbf4dc 100644 --- a/drivers/net/ethernet/natsemi/ibmlana.c +++ b/drivers/net/ethernet/natsemi/ibmlana.c @@ -589,7 +589,7 @@ static void irqrx_handler(struct net_device *dev) /* fetch buffer */ - skb = dev_alloc_skb(rda.length + 2); + skb = netdev_alloc_skb(dev, rda.length + 2); if (skb == NULL) dev->stats.rx_dropped++; else { diff --git a/drivers/net/ethernet/natsemi/natsemi.c b/drivers/net/ethernet/natsemi/natsemi.c index ac7b16b6e7a..d38e48d4f43 100644 --- a/drivers/net/ethernet/natsemi/natsemi.c +++ b/drivers/net/ethernet/natsemi/natsemi.c @@ -1934,11 +1934,10 @@ static void refill_rx(struct net_device *dev) int entry = np->dirty_rx % RX_RING_SIZE; if (np->rx_skbuff[entry] == NULL) { unsigned int buflen = np->rx_buf_sz+NATSEMI_PADDING; - skb = dev_alloc_skb(buflen); + skb = netdev_alloc_skb(dev, buflen); np->rx_skbuff[entry] = skb; if (skb == NULL) break; /* Better luck next round. */ - skb->dev = dev; /* Mark as being used by this device. */ np->rx_dma[entry] = pci_map_single(np->pci_dev, skb->data, buflen, PCI_DMA_FROMDEVICE); np->rx_ring[entry].addr = cpu_to_le32(np->rx_dma[entry]); @@ -2344,7 +2343,7 @@ static void netdev_rx(struct net_device *dev, int *work_done, int work_to_do) /* Check if the packet is long enough to accept * without copying to a minimally-sized skbuff. */ if (pkt_len < rx_copybreak && - (skb = dev_alloc_skb(pkt_len + RX_OFFSET)) != NULL) { + (skb = netdev_alloc_skb(dev, pkt_len + RX_OFFSET)) != NULL) { /* 16 byte align the IP header */ skb_reserve(skb, RX_OFFSET); pci_dma_sync_single_for_cpu(np->pci_dev, diff --git a/drivers/net/ethernet/natsemi/sonic.c b/drivers/net/ethernet/natsemi/sonic.c index 26e25d7f582..0452e2968d2 100644 --- a/drivers/net/ethernet/natsemi/sonic.c +++ b/drivers/net/ethernet/natsemi/sonic.c @@ -51,7 +51,7 @@ static int sonic_open(struct net_device *dev) printk("sonic_open: initializing sonic driver.\n"); for (i = 0; i < SONIC_NUM_RRS; i++) { - struct sk_buff *skb = dev_alloc_skb(SONIC_RBSIZE + 2); + struct sk_buff *skb = netdev_alloc_skb(dev, SONIC_RBSIZE + 2); if (skb == NULL) { while(i > 0) { /* free any that were allocated successfully */ i--; @@ -422,7 +422,7 @@ static void sonic_rx(struct net_device *dev) status = sonic_rda_get(dev, entry, SONIC_RD_STATUS); if (status & SONIC_RCR_PRX) { /* Malloc up new buffer. */ - new_skb = dev_alloc_skb(SONIC_RBSIZE + 2); + new_skb = netdev_alloc_skb(SONIC_RBSIZE + 2); if (new_skb == NULL) { printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n", dev->name); lp->stats.rx_dropped++; diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c index 13858460880..44a6065794c 100644 --- a/drivers/net/ethernet/neterion/s2io.c +++ b/drivers/net/ethernet/neterion/s2io.c @@ -2524,7 +2524,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring, size = ring->mtu + ALIGN_SIZE + BUF0_LEN + 4; /* allocate skb */ - skb = dev_alloc_skb(size); + skb = netdev_alloc_skb(nic->dev, size); if (!skb) { DBG_PRINT(INFO_DBG, "%s: Could not allocate skb\n", ring->dev->name); @@ -6820,7 +6820,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, */ rxdp1->Buffer0_ptr = *temp0; } else { - *skb = dev_alloc_skb(size); + *skb = netdev_alloc_skb(dev, size); if (!(*skb)) { DBG_PRINT(INFO_DBG, "%s: Out of memory to allocate %s\n", @@ -6849,7 +6849,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, rxdp3->Buffer0_ptr = *temp0; rxdp3->Buffer1_ptr = *temp1; } else { - *skb = dev_alloc_skb(size); + *skb = netdev_alloc_skb(dev, size); if (!(*skb)) { DBG_PRINT(INFO_DBG, "%s: Out of memory to allocate %s\n", -- cgit v1.2.3-70-g09d2 From 847fb6fdf58c0ef4c207d2853a043a4da3db9c76 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 6 Feb 2012 18:01:35 +0000 Subject: regmap: Don't use bitfields for booleans This was a cut'n'paste from some older code. Since we're about to add debugfs support don't do the obvious thing and use bool, use u32 instead (which debugfs has been using since time immemorial). Signed-off-by: Mark Brown --- drivers/base/regmap/internal.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index e33f1be2b29..e93d7b7d1cf 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h @@ -66,16 +66,16 @@ struct regmap { unsigned int num_reg_defaults_raw; /* if set, only the cache is modified not the HW */ - unsigned int cache_only:1; + u32 cache_only; /* if set, only the HW is modified not the cache */ - unsigned int cache_bypass:1; + u32 cache_bypass; /* if set, remember to free reg_defaults_raw */ - unsigned int cache_free:1; + bool cache_free; struct reg_default *reg_defaults; const void *reg_defaults_raw; void *cache; - bool cache_dirty; + u32 cache_dirty; }; struct regcache_ops { -- cgit v1.2.3-70-g09d2 From 028a01e601487b5991b70dba506dfe87d83543f6 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 6 Feb 2012 18:02:06 +0000 Subject: regmap: Add debugfs information for the cache status Show all the cache status flags in debugfs if we have a cache. Signed-off-by: Mark Brown --- drivers/base/regmap/regmap-debugfs.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c index 6f397476e27..b3b4b8f7f40 100644 --- a/drivers/base/regmap/regmap-debugfs.c +++ b/drivers/base/regmap/regmap-debugfs.c @@ -192,6 +192,15 @@ void regmap_debugfs_init(struct regmap *map) debugfs_create_file("access", 0400, map->debugfs, map, ®map_access_fops); } + + if (map->cache_type) { + debugfs_create_bool("cache_only", 0400, map->debugfs, + &map->cache_only); + debugfs_create_bool("cache_dirty", 0400, map->debugfs, + &map->cache_dirty); + debugfs_create_bool("cache_bypass", 0400, map->debugfs, + &map->cache_bypass); + } } void regmap_debugfs_exit(struct regmap *map) -- cgit v1.2.3-70-g09d2 From 5718b134b1fe09087ca225b0e475ef65536d02b4 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Mon, 30 Jan 2012 22:52:10 +0900 Subject: net: Fix typo in ipw2x00/libipw_rx.c Correct spelling in "suppported" to "supported" in drivers/net/wireless/ipw2x00/libipw_rx.c Signed-off-by: Masanari Iida Reviewed-by: Jesper Juhl Signed-off-by: John W. Linville --- drivers/net/wireless/ipw2x00/libipw_rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c index 32a9966c3bf..c4955d25a19 100644 --- a/drivers/net/wireless/ipw2x00/libipw_rx.c +++ b/drivers/net/wireless/ipw2x00/libipw_rx.c @@ -172,7 +172,7 @@ libipw_rx_frame_mgmt(struct libipw_device *ieee, struct sk_buff *skb, u16 stype) { if (ieee->iw_mode == IW_MODE_MASTER) { - printk(KERN_DEBUG "%s: Master mode not yet suppported.\n", + printk(KERN_DEBUG "%s: Master mode not yet supported.\n", ieee->dev->name); return 0; /* -- cgit v1.2.3-70-g09d2 From 7f4666ab3fd656513bffd449410a4d7c189081ec Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 30 Jan 2012 16:17:56 +0100 Subject: rt2800: radio 3xxx: reprogram only lower bits of RF_R3 Synchronize code with Ralink driver: 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO (functions: RT33xx_ChipSwitchChannel() and RT30xx_ChipSwitchChannel()) Acked-by: Gertjan van Wingerde Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 5 +++++ drivers/net/wireless/rt2x00/rt2800lib.c | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 2571a2fa3d0..abf2ae58816 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -1795,6 +1795,11 @@ struct mac_iveiv_entry { */ #define RFCSR2_RESCAL_EN FIELD8(0x80) +/* + * RFCSR 3: + */ +#define RFCSR3_K FIELD8(0x0f) + /* * FRCSR 5: */ diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 165535cc507..006347e4d6e 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1648,7 +1648,10 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev, u8 rfcsr; rt2800_rfcsr_write(rt2x00dev, 2, rf->rf1); - rt2800_rfcsr_write(rt2x00dev, 3, rf->rf3); + + rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR3_K, rf->rf3); + rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr); rt2x00_set_field8(&rfcsr, RFCSR6_R1, rf->rf2); -- cgit v1.2.3-70-g09d2 From e3bab197622276faac83eac3dfb993967d8d47e3 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 30 Jan 2012 16:17:57 +0100 Subject: rt2800: radio 3xxx: program RF_R1 during channel switch Synchronize code with Ralink driver: 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO Based on functions: RT33xx_ChipSwitchChannel RT30xx_ChipSwitchChannel RT33xx_Init Signed-off-by: Stanislaw Gruszka Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 34 +++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 006347e4d6e..1bdf1ec33cd 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1665,6 +1665,40 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev, rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, info->default_power2); rt2800_rfcsr_write(rt2x00dev, 13, rfcsr); + rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0); + rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0); + if (rt2x00_rt(rt2x00dev, RT3390)) { + rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, + rt2x00dev->default_ant.rx_chain_num == 1); + rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, + rt2x00dev->default_ant.tx_chain_num == 1); + } else { + rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0); + rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0); + rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0); + rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0); + + switch (rt2x00dev->default_ant.tx_chain_num) { + case 1: + rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1); + /* fall through */ + case 2: + rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1); + break; + } + + switch (rt2x00dev->default_ant.rx_chain_num) { + case 1: + rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1); + /* fall through */ + case 2: + rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1); + break; + } + } + rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); + rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr); rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset); rt2800_rfcsr_write(rt2x00dev, 23, rfcsr); -- cgit v1.2.3-70-g09d2 From 3e0c7643c561c7052430f5c033d5b1b1289c962e Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 30 Jan 2012 16:17:58 +0100 Subject: rt2800: radio 3xxx: add channel switch calibration routines Synchronize code with Ralink driver: 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO Based on functions: RT33xx_ChipSwitchChannel RT30xx_ChipSwitchChannel Acked-by: Gertjan van Wingerde Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 1bdf1ec33cd..0076bc7a9b3 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1699,6 +1699,13 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev, } rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); + rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); + rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); + msleep(1); + rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0); + rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); + rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr); rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset); rt2800_rfcsr_write(rt2x00dev, 23, rfcsr); @@ -1709,6 +1716,13 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev, rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr); rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1); rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); + rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); + msleep(1); + rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0); + rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); } static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev, -- cgit v1.2.3-70-g09d2 From f1f12f9894c48dc8284762bc71e4a3ed5caf546f Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 30 Jan 2012 16:17:59 +0100 Subject: rt2800: radio 3xxxx: channel switch RX/TX calibration fixes Synchronize code with Ralink driver: 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO Based on functions: RT30xx_ChipSwitchChannel RT33xx_ChipSwitchChannel NICInitRT3370RFRegisters and defines from: include/chip/rt33xx.h Signed-off-by: Stanislaw Gruszka Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 8 ++++++++ drivers/net/wireless/rt2x00/rt2800lib.c | 19 ++++++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index abf2ae58816..c92fb2eee92 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -1871,6 +1871,13 @@ struct mac_iveiv_entry { */ #define RFCSR23_FREQ_OFFSET FIELD8(0x7f) +/* + * RFCSR 24: + */ +#define RFCSR24_TX_AGC_FC FIELD8(0x1f) +#define RFCSR24_TX_H20M FIELD8(0x20) +#define RFCSR24_TX_CALIB FIELD8(0x7f) + /* * RFCSR 27: */ @@ -1892,6 +1899,7 @@ struct mac_iveiv_entry { */ #define RFCSR31_RX_AGC_FC FIELD8(0x1f) #define RFCSR31_RX_H20M FIELD8(0x20) +#define RFCSR31_RX_CALIB FIELD8(0x7f) /* * RFCSR 38: diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 0076bc7a9b3..c326e7b1c37 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1645,7 +1645,7 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev, struct rf_channel *rf, struct channel_info *info) { - u8 rfcsr; + u8 rfcsr, calib_tx, calib_rx; rt2800_rfcsr_write(rt2x00dev, 2, rf->rf1); @@ -1710,8 +1710,21 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev, rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset); rt2800_rfcsr_write(rt2x00dev, 23, rfcsr); - rt2800_rfcsr_write(rt2x00dev, 24, - rt2x00dev->calibration[conf_is_ht40(conf)]); + if (rt2x00_rt(rt2x00dev, RT3390)) { + calib_tx = conf_is_ht40(conf) ? 0x68 : 0x4f; + calib_rx = conf_is_ht40(conf) ? 0x6f : 0x4f; + } else { + calib_tx = rt2x00dev->calibration[conf_is_ht40(conf)]; + calib_rx = rt2x00dev->calibration[conf_is_ht40(conf)]; + } + + rt2800_rfcsr_read(rt2x00dev, 24, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR24_TX_CALIB, calib_tx); + rt2800_rfcsr_write(rt2x00dev, 24, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 31, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR31_RX_CALIB, calib_rx); + rt2800_rfcsr_write(rt2x00dev, 31, rfcsr); rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr); rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1); -- cgit v1.2.3-70-g09d2 From 268bd858df5052f97722b123e990119c89171fd7 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 1 Feb 2012 16:17:40 +0100 Subject: rt2800: document RF_R03 register bits [7:4] Taken from: 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO (based on function RT33xx_ChipSwitchChannel) Signed-off-by: Stanislaw Gruszka Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index c92fb2eee92..fac9ece22b2 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -1799,6 +1799,9 @@ struct mac_iveiv_entry { * RFCSR 3: */ #define RFCSR3_K FIELD8(0x0f) +/* Bits [7-4] for RF3320 (RT3370/RT3390), on other chipsets reserved */ +#define RFCSR3_PA1_BIAS_CCK FIELD8(0x70); +#define RFCSR3_PA2_CASCODE_BIAS_CCKK FIELD8(0x80); /* * FRCSR 5: -- cgit v1.2.3-70-g09d2 From 5f2d6171e1e70584b9819771443485750453fd16 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 31 Jan 2012 00:03:31 +0100 Subject: bcma: add the core unit number Some SoCs have two pcie or gmac cores and we need to know the number of the specific core on the bus. This is the case for the BCM4706. Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- drivers/bcma/scan.c | 14 ++++++++++++++ include/linux/bcma/bcma.h | 1 + 2 files changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c index cad99485768..e513aa83ec2 100644 --- a/drivers/bcma/scan.c +++ b/drivers/bcma/scan.c @@ -212,6 +212,17 @@ static struct bcma_device *bcma_find_core_by_index(struct bcma_bus *bus, return NULL; } +static struct bcma_device *bcma_find_core_reverse(struct bcma_bus *bus, u16 coreid) +{ + struct bcma_device *core; + + list_for_each_entry_reverse(core, &bus->cores, list) { + if (core->id.id == coreid) + return core; + } + return NULL; +} + static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr, struct bcma_device_id *match, int core_num, struct bcma_device *core) @@ -392,6 +403,7 @@ int bcma_bus_scan(struct bcma_bus *bus) bcma_scan_switch_core(bus, erombase); while (eromptr < eromend) { + struct bcma_device *other_core; struct bcma_device *core = kzalloc(sizeof(*core), GFP_KERNEL); if (!core) return -ENOMEM; @@ -411,6 +423,8 @@ int bcma_bus_scan(struct bcma_bus *bus) core->core_index = core_num++; bus->nr_cores++; + other_core = bcma_find_core_reverse(bus, core->id.id); + core->core_unit = (other_core == NULL) ? 0 : other_core->core_unit + 1; pr_info("Core %d found: %s " "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n", diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h index 83c209f3949..024a6e2a908 100644 --- a/include/linux/bcma/bcma.h +++ b/include/linux/bcma/bcma.h @@ -136,6 +136,7 @@ struct bcma_device { bool dev_registered; u8 core_index; + u8 core_unit; u32 addr; u32 wrap; -- cgit v1.2.3-70-g09d2 From 2be25cac8402fab56bb51166f464d1b420bcf744 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 31 Jan 2012 00:03:32 +0100 Subject: bcma: add constants for PCI and use them There are many magic numbers used in the PCIe code. Replace them with some constants from the Broadcom SDK and also use them in the pcie host controller. Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- drivers/bcma/driver_pci.c | 124 ++++++++++++++++++++--------------- include/linux/bcma/bcma_driver_pci.h | 85 ++++++++++++++++++++++++ 2 files changed, 155 insertions(+), 54 deletions(-) (limited to 'drivers') diff --git a/drivers/bcma/driver_pci.c b/drivers/bcma/driver_pci.c index 4fde6254f04..fc462b4a099 100644 --- a/drivers/bcma/driver_pci.c +++ b/drivers/bcma/driver_pci.c @@ -4,6 +4,7 @@ * * Copyright 2005, Broadcom Corporation * Copyright 2006, 2007, Michael Buesch + * Copyright 2011, 2012, Hauke Mehrtens * * Licensed under the GNU/GPL. See COPYING for details. */ @@ -18,38 +19,39 @@ static u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address) { - pcicore_write32(pc, 0x130, address); - pcicore_read32(pc, 0x130); - return pcicore_read32(pc, 0x134); + pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address); + pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR); + return pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_DATA); } #if 0 static void bcma_pcie_write(struct bcma_drv_pci *pc, u32 address, u32 data) { - pcicore_write32(pc, 0x130, address); - pcicore_read32(pc, 0x130); - pcicore_write32(pc, 0x134, data); + pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address); + pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR); + pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_DATA, data); } #endif static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy) { - const u16 mdio_control = 0x128; - const u16 mdio_data = 0x12C; u32 v; int i; - v = (1 << 30); /* Start of Transaction */ - v |= (1 << 28); /* Write Transaction */ - v |= (1 << 17); /* Turnaround */ - v |= (0x1F << 18); + v = BCMA_CORE_PCI_MDIODATA_START; + v |= BCMA_CORE_PCI_MDIODATA_WRITE; + v |= (BCMA_CORE_PCI_MDIODATA_DEV_ADDR << + BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF); + v |= (BCMA_CORE_PCI_MDIODATA_BLK_ADDR << + BCMA_CORE_PCI_MDIODATA_REGADDR_SHF); + v |= BCMA_CORE_PCI_MDIODATA_TA; v |= (phy << 4); - pcicore_write32(pc, mdio_data, v); + pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v); udelay(10); for (i = 0; i < 200; i++) { - v = pcicore_read32(pc, mdio_control); - if (v & 0x100 /* Trans complete */) + v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL); + if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE) break; msleep(1); } @@ -57,79 +59,84 @@ static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy) static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address) { - const u16 mdio_control = 0x128; - const u16 mdio_data = 0x12C; int max_retries = 10; u16 ret = 0; u32 v; int i; - v = 0x80; /* Enable Preamble Sequence */ - v |= 0x2; /* MDIO Clock Divisor */ - pcicore_write32(pc, mdio_control, v); + /* enable mdio access to SERDES */ + v = BCMA_CORE_PCI_MDIOCTL_PREAM_EN; + v |= BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL; + pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, v); if (pc->core->id.rev >= 10) { max_retries = 200; bcma_pcie_mdio_set_phy(pc, device); + v = (BCMA_CORE_PCI_MDIODATA_DEV_ADDR << + BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF); + v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF); + } else { + v = (device << BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD); + v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD); } - v = (1 << 30); /* Start of Transaction */ - v |= (1 << 29); /* Read Transaction */ - v |= (1 << 17); /* Turnaround */ - if (pc->core->id.rev < 10) - v |= (u32)device << 22; - v |= (u32)address << 18; - pcicore_write32(pc, mdio_data, v); + v = BCMA_CORE_PCI_MDIODATA_START; + v |= BCMA_CORE_PCI_MDIODATA_READ; + v |= BCMA_CORE_PCI_MDIODATA_TA; + + pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v); /* Wait for the device to complete the transaction */ udelay(10); for (i = 0; i < max_retries; i++) { - v = pcicore_read32(pc, mdio_control); - if (v & 0x100 /* Trans complete */) { + v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL); + if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE) { udelay(10); - ret = pcicore_read32(pc, mdio_data); + ret = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_DATA); break; } msleep(1); } - pcicore_write32(pc, mdio_control, 0); + pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0); return ret; } static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device, u8 address, u16 data) { - const u16 mdio_control = 0x128; - const u16 mdio_data = 0x12C; int max_retries = 10; u32 v; int i; - v = 0x80; /* Enable Preamble Sequence */ - v |= 0x2; /* MDIO Clock Divisor */ - pcicore_write32(pc, mdio_control, v); + /* enable mdio access to SERDES */ + v = BCMA_CORE_PCI_MDIOCTL_PREAM_EN; + v |= BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL; + pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, v); if (pc->core->id.rev >= 10) { max_retries = 200; bcma_pcie_mdio_set_phy(pc, device); + v = (BCMA_CORE_PCI_MDIODATA_DEV_ADDR << + BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF); + v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF); + } else { + v = (device << BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD); + v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD); } - v = (1 << 30); /* Start of Transaction */ - v |= (1 << 28); /* Write Transaction */ - v |= (1 << 17); /* Turnaround */ - if (pc->core->id.rev < 10) - v |= (u32)device << 22; - v |= (u32)address << 18; + v = BCMA_CORE_PCI_MDIODATA_START; + v |= BCMA_CORE_PCI_MDIODATA_WRITE; + v |= BCMA_CORE_PCI_MDIODATA_TA; v |= data; - pcicore_write32(pc, mdio_data, v); + pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v); /* Wait for the device to complete the transaction */ udelay(10); for (i = 0; i < max_retries; i++) { - v = pcicore_read32(pc, mdio_control); - if (v & 0x100 /* Trans complete */) + v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL); + if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE) break; msleep(1); } - pcicore_write32(pc, mdio_control, 0); + pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0); } /************************************************** @@ -138,20 +145,29 @@ static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device, static u8 bcma_pcicore_polarity_workaround(struct bcma_drv_pci *pc) { - return (bcma_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80; + u32 tmp; + + tmp = bcma_pcie_read(pc, BCMA_CORE_PCI_PLP_STATUSREG); + if (tmp & BCMA_CORE_PCI_PLP_POLARITYINV_STAT) + return BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE | + BCMA_CORE_PCI_SERDES_RX_CTRL_POLARITY; + else + return BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE; } static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc) { - const u8 serdes_pll_device = 0x1D; - const u8 serdes_rx_device = 0x1F; u16 tmp; - bcma_pcie_mdio_write(pc, serdes_rx_device, 1 /* Control */, - bcma_pcicore_polarity_workaround(pc)); - tmp = bcma_pcie_mdio_read(pc, serdes_pll_device, 1 /* Control */); - if (tmp & 0x4000) - bcma_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000); + bcma_pcie_mdio_write(pc, BCMA_CORE_PCI_MDIODATA_DEV_RX, + BCMA_CORE_PCI_SERDES_RX_CTRL, + bcma_pcicore_polarity_workaround(pc)); + tmp = bcma_pcie_mdio_read(pc, BCMA_CORE_PCI_MDIODATA_DEV_PLL, + BCMA_CORE_PCI_SERDES_PLL_CTRL); + if (tmp & BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN) + bcma_pcie_mdio_write(pc, BCMA_CORE_PCI_MDIODATA_DEV_PLL, + BCMA_CORE_PCI_SERDES_PLL_CTRL, + tmp & ~BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN); } /************************************************** diff --git a/include/linux/bcma/bcma_driver_pci.h b/include/linux/bcma/bcma_driver_pci.h index 3871b668caf..67ea7beff9f 100644 --- a/include/linux/bcma/bcma_driver_pci.h +++ b/include/linux/bcma/bcma_driver_pci.h @@ -53,6 +53,35 @@ struct pci_dev; #define BCMA_CORE_PCI_SBTOPCI1_MASK 0xFC000000 #define BCMA_CORE_PCI_SBTOPCI2 0x0108 /* Backplane to PCI translation 2 (sbtopci2) */ #define BCMA_CORE_PCI_SBTOPCI2_MASK 0xC0000000 +#define BCMA_CORE_PCI_CONFIG_ADDR 0x0120 /* pcie config space access */ +#define BCMA_CORE_PCI_CONFIG_DATA 0x0124 /* pcie config space access */ +#define BCMA_CORE_PCI_MDIO_CONTROL 0x0128 /* controls the mdio access */ +#define BCMA_CORE_PCI_MDIOCTL_DIVISOR_MASK 0x7f /* clock to be used on MDIO */ +#define BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL 0x2 +#define BCMA_CORE_PCI_MDIOCTL_PREAM_EN 0x80 /* Enable preamble sequnce */ +#define BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE 0x100 /* Tranaction complete */ +#define BCMA_CORE_PCI_MDIO_DATA 0x012c /* Data to the mdio access */ +#define BCMA_CORE_PCI_MDIODATA_MASK 0x0000ffff /* data 2 bytes */ +#define BCMA_CORE_PCI_MDIODATA_TA 0x00020000 /* Turnaround */ +#define BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD 18 /* Regaddr shift (rev < 10) */ +#define BCMA_CORE_PCI_MDIODATA_REGADDR_MASK_OLD 0x003c0000 /* Regaddr Mask (rev < 10) */ +#define BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD 22 /* Physmedia devaddr shift (rev < 10) */ +#define BCMA_CORE_PCI_MDIODATA_DEVADDR_MASK_OLD 0x0fc00000 /* Physmedia devaddr Mask (rev < 10) */ +#define BCMA_CORE_PCI_MDIODATA_REGADDR_SHF 18 /* Regaddr shift */ +#define BCMA_CORE_PCI_MDIODATA_REGADDR_MASK 0x007c0000 /* Regaddr Mask */ +#define BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF 23 /* Physmedia devaddr shift */ +#define BCMA_CORE_PCI_MDIODATA_DEVADDR_MASK 0x0f800000 /* Physmedia devaddr Mask */ +#define BCMA_CORE_PCI_MDIODATA_WRITE 0x10000000 /* write Transaction */ +#define BCMA_CORE_PCI_MDIODATA_READ 0x20000000 /* Read Transaction */ +#define BCMA_CORE_PCI_MDIODATA_START 0x40000000 /* start of Transaction */ +#define BCMA_CORE_PCI_MDIODATA_DEV_ADDR 0x0 /* dev address for serdes */ +#define BCMA_CORE_PCI_MDIODATA_BLK_ADDR 0x1F /* blk address for serdes */ +#define BCMA_CORE_PCI_MDIODATA_DEV_PLL 0x1d /* SERDES PLL Dev */ +#define BCMA_CORE_PCI_MDIODATA_DEV_TX 0x1e /* SERDES TX Dev */ +#define BCMA_CORE_PCI_MDIODATA_DEV_RX 0x1f /* SERDES RX Dev */ +#define BCMA_CORE_PCI_PCIEIND_ADDR 0x0130 /* indirect access to the internal register */ +#define BCMA_CORE_PCI_PCIEIND_DATA 0x0134 /* Data to/from the internal regsiter */ +#define BCMA_CORE_PCI_CLKREQENCTRL 0x0138 /* >= rev 6, Clkreq rdma control */ #define BCMA_CORE_PCI_PCICFG0 0x0400 /* PCI config space 0 (rev >= 8) */ #define BCMA_CORE_PCI_PCICFG1 0x0500 /* PCI config space 1 (rev >= 8) */ #define BCMA_CORE_PCI_PCICFG2 0x0600 /* PCI config space 2 (rev >= 8) */ @@ -72,6 +101,62 @@ struct pci_dev; #define BCMA_CORE_PCI_SBTOPCI_RC_READL 0x00000010 /* Memory read line */ #define BCMA_CORE_PCI_SBTOPCI_RC_READM 0x00000020 /* Memory read multiple */ +/* PCIE protocol PHY diagnostic registers */ +#define BCMA_CORE_PCI_PLP_MODEREG 0x200 /* Mode */ +#define BCMA_CORE_PCI_PLP_STATUSREG 0x204 /* Status */ +#define BCMA_CORE_PCI_PLP_POLARITYINV_STAT 0x10 /* Status reg PCIE_PLP_STATUSREG */ +#define BCMA_CORE_PCI_PLP_LTSSMCTRLREG 0x208 /* LTSSM control */ +#define BCMA_CORE_PCI_PLP_LTLINKNUMREG 0x20c /* Link Training Link number */ +#define BCMA_CORE_PCI_PLP_LTLANENUMREG 0x210 /* Link Training Lane number */ +#define BCMA_CORE_PCI_PLP_LTNFTSREG 0x214 /* Link Training N_FTS */ +#define BCMA_CORE_PCI_PLP_ATTNREG 0x218 /* Attention */ +#define BCMA_CORE_PCI_PLP_ATTNMASKREG 0x21C /* Attention Mask */ +#define BCMA_CORE_PCI_PLP_RXERRCTR 0x220 /* Rx Error */ +#define BCMA_CORE_PCI_PLP_RXFRMERRCTR 0x224 /* Rx Framing Error */ +#define BCMA_CORE_PCI_PLP_RXERRTHRESHREG 0x228 /* Rx Error threshold */ +#define BCMA_CORE_PCI_PLP_TESTCTRLREG 0x22C /* Test Control reg */ +#define BCMA_CORE_PCI_PLP_SERDESCTRLOVRDREG 0x230 /* SERDES Control Override */ +#define BCMA_CORE_PCI_PLP_TIMINGOVRDREG 0x234 /* Timing param override */ +#define BCMA_CORE_PCI_PLP_RXTXSMDIAGREG 0x238 /* RXTX State Machine Diag */ +#define BCMA_CORE_PCI_PLP_LTSSMDIAGREG 0x23C /* LTSSM State Machine Diag */ + +/* PCIE protocol DLLP diagnostic registers */ +#define BCMA_CORE_PCI_DLLP_LCREG 0x100 /* Link Control */ +#define BCMA_CORE_PCI_DLLP_LSREG 0x104 /* Link Status */ +#define BCMA_CORE_PCI_DLLP_LAREG 0x108 /* Link Attention */ +#define BCMA_CORE_PCI_DLLP_LSREG_LINKUP (1 << 16) +#define BCMA_CORE_PCI_DLLP_LAMASKREG 0x10C /* Link Attention Mask */ +#define BCMA_CORE_PCI_DLLP_NEXTTXSEQNUMREG 0x110 /* Next Tx Seq Num */ +#define BCMA_CORE_PCI_DLLP_ACKEDTXSEQNUMREG 0x114 /* Acked Tx Seq Num */ +#define BCMA_CORE_PCI_DLLP_PURGEDTXSEQNUMREG 0x118 /* Purged Tx Seq Num */ +#define BCMA_CORE_PCI_DLLP_RXSEQNUMREG 0x11C /* Rx Sequence Number */ +#define BCMA_CORE_PCI_DLLP_LRREG 0x120 /* Link Replay */ +#define BCMA_CORE_PCI_DLLP_LACKTOREG 0x124 /* Link Ack Timeout */ +#define BCMA_CORE_PCI_DLLP_PMTHRESHREG 0x128 /* Power Management Threshold */ +#define BCMA_CORE_PCI_DLLP_RTRYWPREG 0x12C /* Retry buffer write ptr */ +#define BCMA_CORE_PCI_DLLP_RTRYRPREG 0x130 /* Retry buffer Read ptr */ +#define BCMA_CORE_PCI_DLLP_RTRYPPREG 0x134 /* Retry buffer Purged ptr */ +#define BCMA_CORE_PCI_DLLP_RTRRWREG 0x138 /* Retry buffer Read/Write */ +#define BCMA_CORE_PCI_DLLP_ECTHRESHREG 0x13C /* Error Count Threshold */ +#define BCMA_CORE_PCI_DLLP_TLPERRCTRREG 0x140 /* TLP Error Counter */ +#define BCMA_CORE_PCI_DLLP_ERRCTRREG 0x144 /* Error Counter */ +#define BCMA_CORE_PCI_DLLP_NAKRXCTRREG 0x148 /* NAK Received Counter */ +#define BCMA_CORE_PCI_DLLP_TESTREG 0x14C /* Test */ +#define BCMA_CORE_PCI_DLLP_PKTBIST 0x150 /* Packet BIST */ +#define BCMA_CORE_PCI_DLLP_PCIE11 0x154 /* DLLP PCIE 1.1 reg */ + +/* SERDES RX registers */ +#define BCMA_CORE_PCI_SERDES_RX_CTRL 1 /* Rx cntrl */ +#define BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE 0x80 /* rxpolarity_force */ +#define BCMA_CORE_PCI_SERDES_RX_CTRL_POLARITY 0x40 /* rxpolarity_value */ +#define BCMA_CORE_PCI_SERDES_RX_TIMER1 2 /* Rx Timer1 */ +#define BCMA_CORE_PCI_SERDES_RX_CDR 6 /* CDR */ +#define BCMA_CORE_PCI_SERDES_RX_CDRBW 7 /* CDR BW */ + +/* SERDES PLL registers */ +#define BCMA_CORE_PCI_SERDES_PLL_CTRL 1 /* PLL control reg */ +#define BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN 0x4000 /* bit 14 is FREQDET on */ + /* PCIcore specific boardflags */ #define BCMA_CORE_PCI_BFL_NOPCI 0x00000400 /* Board leaves PCI floating */ -- cgit v1.2.3-70-g09d2 From 4b259a5cc5ea967fa243dfc1f95a59ae74106f5b Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 31 Jan 2012 00:03:33 +0100 Subject: bcma: export bcma_pcie_read() This will be needed by the host controller. Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- drivers/bcma/bcma_private.h | 3 +++ drivers/bcma/driver_pci.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h index 0def898a1d1..6109da5d883 100644 --- a/drivers/bcma/bcma_private.h +++ b/drivers/bcma/bcma_private.h @@ -48,6 +48,9 @@ extern int __init bcma_host_pci_init(void); extern void __exit bcma_host_pci_exit(void); #endif /* CONFIG_BCMA_HOST_PCI */ +/* driver_pci.c */ +u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address); + #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc); #endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */ diff --git a/drivers/bcma/driver_pci.c b/drivers/bcma/driver_pci.c index fc462b4a099..22dc9fca6dc 100644 --- a/drivers/bcma/driver_pci.c +++ b/drivers/bcma/driver_pci.c @@ -17,7 +17,7 @@ * R/W ops. **************************************************/ -static u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address) +u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address) { pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address); pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR); -- cgit v1.2.3-70-g09d2 From d1a7a8e1d367e34e5adce91f48cae07dc08d9e6c Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 31 Jan 2012 00:03:34 +0100 Subject: bcma: make some functions __devinit bcma_core_pci_hostmode_init() has to be in __devinit as it will call a function in that section and so all functions calling it also have to be in __devinit. Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- drivers/bcma/bcma_private.h | 4 ++-- drivers/bcma/driver_pci.c | 6 +++--- drivers/bcma/driver_pci_host.c | 2 +- drivers/bcma/host_pci.c | 4 ++-- drivers/bcma/main.c | 2 +- include/linux/bcma/bcma_driver_pci.h | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h index 6109da5d883..63c5242159f 100644 --- a/drivers/bcma/bcma_private.h +++ b/drivers/bcma/bcma_private.h @@ -13,7 +13,7 @@ struct bcma_bus; /* main.c */ -int bcma_bus_register(struct bcma_bus *bus); +int __devinit bcma_bus_register(struct bcma_bus *bus); void bcma_bus_unregister(struct bcma_bus *bus); int __init bcma_bus_early_register(struct bcma_bus *bus, struct bcma_device *core_cc, @@ -52,7 +52,7 @@ extern void __exit bcma_host_pci_exit(void); u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address); #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE -void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc); +void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc); #endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */ #endif diff --git a/drivers/bcma/driver_pci.c b/drivers/bcma/driver_pci.c index 22dc9fca6dc..155d953dba7 100644 --- a/drivers/bcma/driver_pci.c +++ b/drivers/bcma/driver_pci.c @@ -174,12 +174,12 @@ static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc) * Init. **************************************************/ -static void bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc) +static void __devinit bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc) { bcma_pcicore_serdes_workaround(pc); } -static bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc) +static bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc) { struct bcma_bus *bus = pc->core->bus; u16 chipid_top; @@ -204,7 +204,7 @@ static bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc) return true; } -void bcma_core_pci_init(struct bcma_drv_pci *pc) +void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc) { if (pc->setup_done) return; diff --git a/drivers/bcma/driver_pci_host.c b/drivers/bcma/driver_pci_host.c index eb332b75ce8..99e040b607a 100644 --- a/drivers/bcma/driver_pci_host.c +++ b/drivers/bcma/driver_pci_host.c @@ -8,7 +8,7 @@ #include "bcma_private.h" #include -void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc) +void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc) { pr_err("No support for PCI core in hostmode yet\n"); } diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c index f59244e3397..e3928d68802 100644 --- a/drivers/bcma/host_pci.c +++ b/drivers/bcma/host_pci.c @@ -154,8 +154,8 @@ const struct bcma_host_ops bcma_host_pci_ops = { .awrite32 = bcma_host_pci_awrite32, }; -static int bcma_host_pci_probe(struct pci_dev *dev, - const struct pci_device_id *id) +static int __devinit bcma_host_pci_probe(struct pci_dev *dev, + const struct pci_device_id *id) { struct bcma_bus *bus; int err = -ENOMEM; diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index febbc0a1222..3363036f23d 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c @@ -132,7 +132,7 @@ static void bcma_unregister_cores(struct bcma_bus *bus) } } -int bcma_bus_register(struct bcma_bus *bus) +int __devinit bcma_bus_register(struct bcma_bus *bus) { int err; struct bcma_device *core; diff --git a/include/linux/bcma/bcma_driver_pci.h b/include/linux/bcma/bcma_driver_pci.h index 67ea7beff9f..679d4cab454 100644 --- a/include/linux/bcma/bcma_driver_pci.h +++ b/include/linux/bcma/bcma_driver_pci.h @@ -169,7 +169,7 @@ struct bcma_drv_pci { #define pcicore_read32(pc, offset) bcma_read32((pc)->core, offset) #define pcicore_write32(pc, offset, val) bcma_write32((pc)->core, offset, val) -extern void bcma_core_pci_init(struct bcma_drv_pci *pc); +extern void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc); extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core, bool enable); -- cgit v1.2.3-70-g09d2 From 49dc9577155576b10ff79f0c1486c816b01f58bf Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 31 Jan 2012 00:03:35 +0100 Subject: bcma: add PCIe host controller Some SoCs have a PCIe host controller to make it possible to attach some other devices to it, like an other Wifi card. This code was tested with an Netgear WNDR3400 (bcm4716 based), but should work with all bcma based SoCs. Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- arch/mips/pci/pci-bcm47xx.c | 49 ++- drivers/bcma/bcma_private.h | 1 + drivers/bcma/driver_pci.c | 38 +-- drivers/bcma/driver_pci_host.c | 576 ++++++++++++++++++++++++++++++++++- include/linux/bcma/bcma_driver_pci.h | 38 +++ include/linux/bcma/bcma_regs.h | 27 ++ 6 files changed, 690 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/arch/mips/pci/pci-bcm47xx.c b/arch/mips/pci/pci-bcm47xx.c index 400535a955d..c682468010c 100644 --- a/arch/mips/pci/pci-bcm47xx.c +++ b/arch/mips/pci/pci-bcm47xx.c @@ -25,6 +25,7 @@ #include #include #include +#include #include int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) @@ -32,15 +33,12 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) return 0; } -int pcibios_plat_dev_init(struct pci_dev *dev) -{ #ifdef CONFIG_BCM47XX_SSB +static int bcm47xx_pcibios_plat_dev_init_ssb(struct pci_dev *dev) +{ int res; u8 slot, pin; - if (bcm47xx_bus_type != BCM47XX_BUS_TYPE_SSB) - return 0; - res = ssb_pcibios_plat_dev_init(dev); if (res < 0) { printk(KERN_ALERT "PCI: Failed to init device %s\n", @@ -60,6 +58,47 @@ int pcibios_plat_dev_init(struct pci_dev *dev) } dev->irq = res; + return 0; +} #endif + +#ifdef CONFIG_BCM47XX_BCMA +static int bcm47xx_pcibios_plat_dev_init_bcma(struct pci_dev *dev) +{ + int res; + + res = bcma_core_pci_plat_dev_init(dev); + if (res < 0) { + printk(KERN_ALERT "PCI: Failed to init device %s\n", + pci_name(dev)); + return res; + } + + res = bcma_core_pci_pcibios_map_irq(dev); + + /* IRQ-0 and IRQ-1 are software interrupts. */ + if (res < 2) { + printk(KERN_ALERT "PCI: Failed to map IRQ of device %s\n", + pci_name(dev)); + return res; + } + + dev->irq = res; return 0; } +#endif + +int pcibios_plat_dev_init(struct pci_dev *dev) +{ +#ifdef CONFIG_BCM47XX_SSB + if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_SSB) + return bcm47xx_pcibios_plat_dev_init_ssb(dev); + else +#endif +#ifdef CONFIG_BCM47XX_BCMA + if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) + return bcm47xx_pcibios_plat_dev_init_bcma(dev); + else +#endif + return 0; +} diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h index 63c5242159f..b81755bb479 100644 --- a/drivers/bcma/bcma_private.h +++ b/drivers/bcma/bcma_private.h @@ -52,6 +52,7 @@ extern void __exit bcma_host_pci_exit(void); u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address); #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE +bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc); void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc); #endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */ diff --git a/drivers/bcma/driver_pci.c b/drivers/bcma/driver_pci.c index 155d953dba7..4d38ae179b4 100644 --- a/drivers/bcma/driver_pci.c +++ b/drivers/bcma/driver_pci.c @@ -2,7 +2,7 @@ * Broadcom specific AMBA * PCI Core * - * Copyright 2005, Broadcom Corporation + * Copyright 2005, 2011, Broadcom Corporation * Copyright 2006, 2007, Michael Buesch * Copyright 2011, 2012, Hauke Mehrtens * @@ -179,47 +179,19 @@ static void __devinit bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc) bcma_pcicore_serdes_workaround(pc); } -static bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc) -{ - struct bcma_bus *bus = pc->core->bus; - u16 chipid_top; - - chipid_top = (bus->chipinfo.id & 0xFF00); - if (chipid_top != 0x4700 && - chipid_top != 0x5300) - return false; - -#ifdef CONFIG_SSB_DRIVER_PCICORE - if (bus->sprom.boardflags_lo & SSB_BFL_NOPCI) - return false; -#endif /* CONFIG_SSB_DRIVER_PCICORE */ - -#if 0 - /* TODO: on BCMA we use address from EROM instead of magic formula */ - u32 tmp; - return !mips_busprobe32(tmp, (bus->mmio + - (pc->core->core_index * BCMA_CORE_SIZE))); -#endif - - return true; -} - void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc) { if (pc->setup_done) return; - if (bcma_core_pci_is_in_hostmode(pc)) { #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE + pc->hostmode = bcma_core_pci_is_in_hostmode(pc); + if (pc->hostmode) bcma_core_pci_hostmode_init(pc); -#else - pr_err("Driver compiled without support for hostmode PCI\n"); #endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */ - } else { - bcma_core_pci_clientmode_init(pc); - } - pc->setup_done = true; + if (!pc->hostmode) + bcma_core_pci_clientmode_init(pc); } int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core, diff --git a/drivers/bcma/driver_pci_host.c b/drivers/bcma/driver_pci_host.c index 99e040b607a..4e20bcfa7ec 100644 --- a/drivers/bcma/driver_pci_host.c +++ b/drivers/bcma/driver_pci_host.c @@ -2,13 +2,587 @@ * Broadcom specific AMBA * PCI Core in hostmode * + * Copyright 2005 - 2011, Broadcom Corporation + * Copyright 2006, 2007, Michael Buesch + * Copyright 2011, 2012, Hauke Mehrtens + * * Licensed under the GNU/GPL. See COPYING for details. */ #include "bcma_private.h" +#include #include +#include + +/* Probe a 32bit value on the bus and catch bus exceptions. + * Returns nonzero on a bus exception. + * This is MIPS specific */ +#define mips_busprobe32(val, addr) get_dbe((val), ((u32 *)(addr))) + +/* Assume one-hot slot wiring */ +#define BCMA_PCI_SLOT_MAX 16 +#define PCI_CONFIG_SPACE_SIZE 256 + +bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc) +{ + struct bcma_bus *bus = pc->core->bus; + u16 chipid_top; + u32 tmp; + + chipid_top = (bus->chipinfo.id & 0xFF00); + if (chipid_top != 0x4700 && + chipid_top != 0x5300) + return false; + + if (bus->sprom.boardflags_lo & BCMA_CORE_PCI_BFL_NOPCI) { + pr_info("This PCI core is disabled and not working\n"); + return false; + } + + bcma_core_enable(pc->core, 0); + + return !mips_busprobe32(tmp, pc->core->io_addr); +} + +static u32 bcma_pcie_read_config(struct bcma_drv_pci *pc, u32 address) +{ + pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_ADDR, address); + pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_ADDR); + return pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_DATA); +} + +static void bcma_pcie_write_config(struct bcma_drv_pci *pc, u32 address, + u32 data) +{ + pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_ADDR, address); + pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_ADDR); + pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_DATA, data); +} + +static u32 bcma_get_cfgspace_addr(struct bcma_drv_pci *pc, unsigned int dev, + unsigned int func, unsigned int off) +{ + u32 addr = 0; + + /* Issue config commands only when the data link is up (atleast + * one external pcie device is present). + */ + if (dev >= 2 || !(bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_LSREG) + & BCMA_CORE_PCI_DLLP_LSREG_LINKUP)) + goto out; + + /* Type 0 transaction */ + /* Slide the PCI window to the appropriate slot */ + pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI1, BCMA_CORE_PCI_SBTOPCI_CFG0); + /* Calculate the address */ + addr = pc->host_controller->host_cfg_addr; + addr |= (dev << BCMA_CORE_PCI_CFG_SLOT_SHIFT); + addr |= (func << BCMA_CORE_PCI_CFG_FUN_SHIFT); + addr |= (off & ~3); + +out: + return addr; +} + +static int bcma_extpci_read_config(struct bcma_drv_pci *pc, unsigned int dev, + unsigned int func, unsigned int off, + void *buf, int len) +{ + int err = -EINVAL; + u32 addr, val; + void __iomem *mmio = 0; + + WARN_ON(!pc->hostmode); + if (unlikely(len != 1 && len != 2 && len != 4)) + goto out; + if (dev == 0) { + /* we support only two functions on device 0 */ + if (func > 1) + return -EINVAL; + + /* accesses to config registers with offsets >= 256 + * requires indirect access. + */ + if (off >= PCI_CONFIG_SPACE_SIZE) { + addr = (func << 12); + addr |= (off & 0x0FFF); + val = bcma_pcie_read_config(pc, addr); + } else { + addr = BCMA_CORE_PCI_PCICFG0; + addr |= (func << 8); + addr |= (off & 0xfc); + val = pcicore_read32(pc, addr); + } + } else { + addr = bcma_get_cfgspace_addr(pc, dev, func, off); + if (unlikely(!addr)) + goto out; + err = -ENOMEM; + mmio = ioremap_nocache(addr, len); + if (!mmio) + goto out; + + if (mips_busprobe32(val, mmio)) { + val = 0xffffffff; + goto unmap; + } + + val = readl(mmio); + } + val >>= (8 * (off & 3)); + + switch (len) { + case 1: + *((u8 *)buf) = (u8)val; + break; + case 2: + *((u16 *)buf) = (u16)val; + break; + case 4: + *((u32 *)buf) = (u32)val; + break; + } + err = 0; +unmap: + if (mmio) + iounmap(mmio); +out: + return err; +} + +static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev, + unsigned int func, unsigned int off, + const void *buf, int len) +{ + int err = -EINVAL; + u32 addr = 0, val = 0; + void __iomem *mmio = 0; + u16 chipid = pc->core->bus->chipinfo.id; + + WARN_ON(!pc->hostmode); + if (unlikely(len != 1 && len != 2 && len != 4)) + goto out; + if (dev == 0) { + /* accesses to config registers with offsets >= 256 + * requires indirect access. + */ + if (off < PCI_CONFIG_SPACE_SIZE) { + addr = pc->core->addr + BCMA_CORE_PCI_PCICFG0; + addr |= (func << 8); + addr |= (off & 0xfc); + mmio = ioremap_nocache(addr, len); + if (!mmio) + goto out; + } + } else { + addr = bcma_get_cfgspace_addr(pc, dev, func, off); + if (unlikely(!addr)) + goto out; + err = -ENOMEM; + mmio = ioremap_nocache(addr, len); + if (!mmio) + goto out; + + if (mips_busprobe32(val, mmio)) { + val = 0xffffffff; + goto unmap; + } + } + + switch (len) { + case 1: + val = readl(mmio); + val &= ~(0xFF << (8 * (off & 3))); + val |= *((const u8 *)buf) << (8 * (off & 3)); + break; + case 2: + val = readl(mmio); + val &= ~(0xFFFF << (8 * (off & 3))); + val |= *((const u16 *)buf) << (8 * (off & 3)); + break; + case 4: + val = *((const u32 *)buf); + break; + } + if (dev == 0 && !addr) { + /* accesses to config registers with offsets >= 256 + * requires indirect access. + */ + addr = (func << 12); + addr |= (off & 0x0FFF); + bcma_pcie_write_config(pc, addr, val); + } else { + writel(val, mmio); + + if (chipid == 0x4716 || chipid == 0x4748) + readl(mmio); + } + + err = 0; +unmap: + if (mmio) + iounmap(mmio); +out: + return err; +} + +static int bcma_core_pci_hostmode_read_config(struct pci_bus *bus, + unsigned int devfn, + int reg, int size, u32 *val) +{ + unsigned long flags; + int err; + struct bcma_drv_pci *pc; + struct bcma_drv_pci_host *pc_host; + + pc_host = container_of(bus->ops, struct bcma_drv_pci_host, pci_ops); + pc = pc_host->pdev; + + spin_lock_irqsave(&pc_host->cfgspace_lock, flags); + err = bcma_extpci_read_config(pc, PCI_SLOT(devfn), + PCI_FUNC(devfn), reg, val, size); + spin_unlock_irqrestore(&pc_host->cfgspace_lock, flags); + + return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; +} + +static int bcma_core_pci_hostmode_write_config(struct pci_bus *bus, + unsigned int devfn, + int reg, int size, u32 val) +{ + unsigned long flags; + int err; + struct bcma_drv_pci *pc; + struct bcma_drv_pci_host *pc_host; + + pc_host = container_of(bus->ops, struct bcma_drv_pci_host, pci_ops); + pc = pc_host->pdev; + + spin_lock_irqsave(&pc_host->cfgspace_lock, flags); + err = bcma_extpci_write_config(pc, PCI_SLOT(devfn), + PCI_FUNC(devfn), reg, &val, size); + spin_unlock_irqrestore(&pc_host->cfgspace_lock, flags); + + return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; +} + +/* return cap_offset if requested capability exists in the PCI config space */ +static u8 __devinit bcma_find_pci_capability(struct bcma_drv_pci *pc, + unsigned int dev, + unsigned int func, u8 req_cap_id, + unsigned char *buf, u32 *buflen) +{ + u8 cap_id; + u8 cap_ptr = 0; + u32 bufsize; + u8 byte_val; + + /* check for Header type 0 */ + bcma_extpci_read_config(pc, dev, func, PCI_HEADER_TYPE, &byte_val, + sizeof(u8)); + if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL) + return cap_ptr; + + /* check if the capability pointer field exists */ + bcma_extpci_read_config(pc, dev, func, PCI_STATUS, &byte_val, + sizeof(u8)); + if (!(byte_val & PCI_STATUS_CAP_LIST)) + return cap_ptr; + + /* check if the capability pointer is 0x00 */ + bcma_extpci_read_config(pc, dev, func, PCI_CAPABILITY_LIST, &cap_ptr, + sizeof(u8)); + if (cap_ptr == 0x00) + return cap_ptr; + + /* loop thr'u the capability list and see if the requested capabilty + * exists */ + bcma_extpci_read_config(pc, dev, func, cap_ptr, &cap_id, sizeof(u8)); + while (cap_id != req_cap_id) { + bcma_extpci_read_config(pc, dev, func, cap_ptr + 1, &cap_ptr, + sizeof(u8)); + if (cap_ptr == 0x00) + return cap_ptr; + bcma_extpci_read_config(pc, dev, func, cap_ptr, &cap_id, + sizeof(u8)); + } + + /* found the caller requested capability */ + if ((buf != NULL) && (buflen != NULL)) { + u8 cap_data; + + bufsize = *buflen; + if (!bufsize) + return cap_ptr; + + *buflen = 0; + + /* copy the cpability data excluding cap ID and next ptr */ + cap_data = cap_ptr + 2; + if ((bufsize + cap_data) > PCI_CONFIG_SPACE_SIZE) + bufsize = PCI_CONFIG_SPACE_SIZE - cap_data; + *buflen = bufsize; + while (bufsize--) { + bcma_extpci_read_config(pc, dev, func, cap_data, buf, + sizeof(u8)); + cap_data++; + buf++; + } + } + + return cap_ptr; +} + +/* If the root port is capable of returning Config Request + * Retry Status (CRS) Completion Status to software then + * enable the feature. + */ +static void __devinit bcma_core_pci_enable_crs(struct bcma_drv_pci *pc) +{ + u8 cap_ptr, root_ctrl, root_cap, dev; + u16 val16; + int i; + + cap_ptr = bcma_find_pci_capability(pc, 0, 0, PCI_CAP_ID_EXP, NULL, + NULL); + root_cap = cap_ptr + PCI_EXP_RTCAP; + bcma_extpci_read_config(pc, 0, 0, root_cap, &val16, sizeof(u16)); + if (val16 & BCMA_CORE_PCI_RC_CRS_VISIBILITY) { + /* Enable CRS software visibility */ + root_ctrl = cap_ptr + PCI_EXP_RTCTL; + val16 = PCI_EXP_RTCTL_CRSSVE; + bcma_extpci_read_config(pc, 0, 0, root_ctrl, &val16, + sizeof(u16)); + + /* Initiate a configuration request to read the vendor id + * field of the device function's config space header after + * 100 ms wait time from the end of Reset. If the device is + * not done with its internal initialization, it must at + * least return a completion TLP, with a completion status + * of "Configuration Request Retry Status (CRS)". The root + * complex must complete the request to the host by returning + * a read-data value of 0001h for the Vendor ID field and + * all 1s for any additional bytes included in the request. + * Poll using the config reads for max wait time of 1 sec or + * until we receive the successful completion status. Repeat + * the procedure for all the devices. + */ + for (dev = 1; dev < BCMA_PCI_SLOT_MAX; dev++) { + for (i = 0; i < 100000; i++) { + bcma_extpci_read_config(pc, dev, 0, + PCI_VENDOR_ID, &val16, + sizeof(val16)); + if (val16 != 0x1) + break; + udelay(10); + } + if (val16 == 0x1) + pr_err("PCI: Broken device in slot %d\n", dev); + } + } +} void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc) { - pr_err("No support for PCI core in hostmode yet\n"); + struct bcma_bus *bus = pc->core->bus; + struct bcma_drv_pci_host *pc_host; + u32 tmp; + u32 pci_membase_1G; + unsigned long io_map_base; + + pr_info("PCIEcore in host mode found\n"); + + pc_host = kzalloc(sizeof(*pc_host), GFP_KERNEL); + if (!pc_host) { + pr_err("can not allocate memory"); + return; + } + + 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; + pc_host->pci_controller.pci_ops = &pc_host->pci_ops; + pc_host->pdev = pc; + + pci_membase_1G = BCMA_SOC_PCI_DMA; + pc_host->host_cfg_addr = BCMA_SOC_PCI_CFG; + + pc_host->pci_ops.read = bcma_core_pci_hostmode_read_config; + pc_host->pci_ops.write = bcma_core_pci_hostmode_write_config; + + pc_host->mem_resource.name = "BCMA PCIcore external memory", + pc_host->mem_resource.start = BCMA_SOC_PCI_DMA; + pc_host->mem_resource.end = BCMA_SOC_PCI_DMA + BCMA_SOC_PCI_DMA_SZ - 1; + pc_host->mem_resource.flags = IORESOURCE_MEM | IORESOURCE_PCI_FIXED; + + pc_host->io_resource.name = "BCMA PCIcore external I/O", + pc_host->io_resource.start = 0x100; + pc_host->io_resource.end = 0x7FF; + pc_host->io_resource.flags = IORESOURCE_IO | IORESOURCE_PCI_FIXED; + + /* Reset RC */ + udelay(3000); + pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST_OE); + udelay(1000); + pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST | + BCMA_CORE_PCI_CTL_RST_OE); + + /* 64 MB I/O access window. On 4716, use + * sbtopcie0 to access the device registers. We + * can't use address match 2 (1 GB window) region + * as mips can't generate 64-bit address on the + * backplane. + */ + if (bus->chipinfo.id == 0x4716 || bus->chipinfo.id == 0x4748) { + pc_host->mem_resource.start = BCMA_SOC_PCI_MEM; + pc_host->mem_resource.end = BCMA_SOC_PCI_MEM + + BCMA_SOC_PCI_MEM_SZ - 1; + pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0, + BCMA_CORE_PCI_SBTOPCI_MEM | BCMA_SOC_PCI_MEM); + } else if (bus->chipinfo.id == 0x5300) { + tmp = BCMA_CORE_PCI_SBTOPCI_MEM; + tmp |= BCMA_CORE_PCI_SBTOPCI_PREF; + tmp |= BCMA_CORE_PCI_SBTOPCI_BURST; + if (pc->core->core_unit == 0) { + pc_host->mem_resource.start = BCMA_SOC_PCI_MEM; + pc_host->mem_resource.end = BCMA_SOC_PCI_MEM + + BCMA_SOC_PCI_MEM_SZ - 1; + pci_membase_1G = BCMA_SOC_PCIE_DMA_H32; + pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0, + tmp | BCMA_SOC_PCI_MEM); + } else if (pc->core->core_unit == 1) { + pc_host->mem_resource.start = BCMA_SOC_PCI1_MEM; + pc_host->mem_resource.end = BCMA_SOC_PCI1_MEM + + BCMA_SOC_PCI_MEM_SZ - 1; + pci_membase_1G = BCMA_SOC_PCIE1_DMA_H32; + pc_host->host_cfg_addr = BCMA_SOC_PCI1_CFG; + pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0, + tmp | BCMA_SOC_PCI1_MEM); + } + } else + pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0, + BCMA_CORE_PCI_SBTOPCI_IO); + + /* 64 MB configuration access window */ + pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI1, BCMA_CORE_PCI_SBTOPCI_CFG0); + + /* 1 GB memory access window */ + pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI2, + BCMA_CORE_PCI_SBTOPCI_MEM | pci_membase_1G); + + + /* As per PCI Express Base Spec 1.1 we need to wait for + * at least 100 ms from the end of a reset (cold/warm/hot) + * before issuing configuration requests to PCI Express + * devices. + */ + udelay(100000); + + bcma_core_pci_enable_crs(pc); + + /* Enable PCI bridge BAR0 memory & master access */ + tmp = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; + bcma_extpci_write_config(pc, 0, 0, PCI_COMMAND, &tmp, sizeof(tmp)); + + /* Enable PCI interrupts */ + pcicore_write32(pc, BCMA_CORE_PCI_IMASK, BCMA_CORE_PCI_IMASK_INTA); + + /* Ok, ready to run, register it to the system. + * The following needs change, if we want to port hostmode + * to non-MIPS platform. */ + io_map_base = (unsigned long)ioremap_nocache(BCMA_SOC_PCI_MEM, + 0x04000000); + pc_host->pci_controller.io_map_base = io_map_base; + set_io_port_base(pc_host->pci_controller.io_map_base); + /* Give some time to the PCI controller to configure itself with the new + * values. Not waiting at this point causes crashes of the machine. */ + mdelay(10); + register_pci_controller(&pc_host->pci_controller); + return; +} + +/* Early PCI fixup for a device on the PCI-core bridge. */ +static void bcma_core_pci_fixup_pcibridge(struct pci_dev *dev) +{ + if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) { + /* This is not a device on the PCI-core bridge. */ + return; + } + if (PCI_SLOT(dev->devfn) != 0) + return; + + pr_info("PCI: Fixing up bridge %s\n", pci_name(dev)); + + /* Enable PCI bridge bus mastering and memory space */ + pci_set_master(dev); + if (pcibios_enable_device(dev, ~0) < 0) { + pr_err("PCI: BCMA bridge enable failed\n"); + return; + } + + /* Enable PCI bridge BAR1 prefetch and burst */ + pci_write_config_dword(dev, BCMA_PCI_BAR1_CONTROL, 3); +} +DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_pcibridge); + +/* Early PCI fixup for all PCI-cores to set the correct memory address. */ +static void bcma_core_pci_fixup_addresses(struct pci_dev *dev) +{ + struct resource *res; + int pos; + + if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) { + /* This is not a device on the PCI-core bridge. */ + return; + } + if (PCI_SLOT(dev->devfn) == 0) + return; + + pr_info("PCI: Fixing up addresses %s\n", pci_name(dev)); + + for (pos = 0; pos < 6; pos++) { + res = &dev->resource[pos]; + if (res->flags & (IORESOURCE_IO | IORESOURCE_MEM)) + pci_assign_resource(dev, pos); + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_addresses); + +/* This function is called when doing a pci_enable_device(). + * We must first check if the device is a device on the PCI-core bridge. */ +int bcma_core_pci_plat_dev_init(struct pci_dev *dev) +{ + struct bcma_drv_pci_host *pc_host; + + if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) { + /* This is not a device on the PCI-core bridge. */ + return -ENODEV; + } + pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host, + pci_ops); + + pr_info("PCI: Fixing up device %s\n", pci_name(dev)); + + /* Fix up interrupt lines */ + dev->irq = bcma_core_mips_irq(pc_host->pdev->core) + 2; + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + + return 0; +} +EXPORT_SYMBOL(bcma_core_pci_plat_dev_init); + +/* PCI device IRQ mapping. */ +int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev) +{ + struct bcma_drv_pci_host *pc_host; + + if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) { + /* This is not a device on the PCI-core bridge. */ + return -ENODEV; + } + + pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host, + pci_ops); + return bcma_core_mips_irq(pc_host->pdev->core) + 2; } +EXPORT_SYMBOL(bcma_core_pci_pcibios_map_irq); diff --git a/include/linux/bcma/bcma_driver_pci.h b/include/linux/bcma/bcma_driver_pci.h index 679d4cab454..46c71e27d31 100644 --- a/include/linux/bcma/bcma_driver_pci.h +++ b/include/linux/bcma/bcma_driver_pci.h @@ -160,9 +160,44 @@ struct pci_dev; /* PCIcore specific boardflags */ #define BCMA_CORE_PCI_BFL_NOPCI 0x00000400 /* Board leaves PCI floating */ +/* PCIE Config space accessing MACROS */ +#define BCMA_CORE_PCI_CFG_BUS_SHIFT 24 /* Bus shift */ +#define BCMA_CORE_PCI_CFG_SLOT_SHIFT 19 /* Slot/Device shift */ +#define BCMA_CORE_PCI_CFG_FUN_SHIFT 16 /* Function shift */ +#define BCMA_CORE_PCI_CFG_OFF_SHIFT 0 /* Register shift */ + +#define BCMA_CORE_PCI_CFG_BUS_MASK 0xff /* Bus mask */ +#define BCMA_CORE_PCI_CFG_SLOT_MASK 0x1f /* Slot/Device mask */ +#define BCMA_CORE_PCI_CFG_FUN_MASK 7 /* Function mask */ +#define BCMA_CORE_PCI_CFG_OFF_MASK 0xfff /* Register mask */ + +/* PCIE Root Capability Register bits (Host mode only) */ +#define BCMA_CORE_PCI_RC_CRS_VISIBILITY 0x0001 + +struct bcma_drv_pci; + +#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE +struct bcma_drv_pci_host { + struct bcma_drv_pci *pdev; + + u32 host_cfg_addr; + spinlock_t cfgspace_lock; + + struct pci_controller pci_controller; + struct pci_ops pci_ops; + struct resource mem_resource; + struct resource io_resource; +}; +#endif + struct bcma_drv_pci { struct bcma_device *core; u8 setup_done:1; + u8 hostmode:1; + +#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE + struct bcma_drv_pci_host *host_controller; +#endif }; /* Register access */ @@ -173,4 +208,7 @@ extern void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc); extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core, bool enable); +extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev); +extern int bcma_core_pci_plat_dev_init(struct pci_dev *dev); + #endif /* LINUX_BCMA_DRIVER_PCI_H_ */ diff --git a/include/linux/bcma/bcma_regs.h b/include/linux/bcma/bcma_regs.h index 9faae2ae02e..5a71d571964 100644 --- a/include/linux/bcma/bcma_regs.h +++ b/include/linux/bcma/bcma_regs.h @@ -56,4 +56,31 @@ #define BCMA_PCI_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal powerup */ #define BCMA_PCI_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL powerdown */ +/* SiliconBackplane Address Map. + * All regions may not exist on all chips. + */ +#define BCMA_SOC_SDRAM_BASE 0x00000000U /* Physical SDRAM */ +#define BCMA_SOC_PCI_MEM 0x08000000U /* Host Mode sb2pcitranslation0 (64 MB) */ +#define BCMA_SOC_PCI_MEM_SZ (64 * 1024 * 1024) +#define BCMA_SOC_PCI_CFG 0x0c000000U /* Host Mode sb2pcitranslation1 (64 MB) */ +#define BCMA_SOC_SDRAM_SWAPPED 0x10000000U /* Byteswapped Physical SDRAM */ +#define BCMA_SOC_SDRAM_R2 0x80000000U /* Region 2 for sdram (512 MB) */ + + +#define BCMA_SOC_PCI_DMA 0x40000000U /* Client Mode sb2pcitranslation2 (1 GB) */ +#define BCMA_SOC_PCI_DMA2 0x80000000U /* Client Mode sb2pcitranslation2 (1 GB) */ +#define BCMA_SOC_PCI_DMA_SZ 0x40000000U /* Client Mode sb2pcitranslation2 size in bytes */ +#define BCMA_SOC_PCIE_DMA_L32 0x00000000U /* PCIE Client Mode sb2pcitranslation2 + * (2 ZettaBytes), low 32 bits + */ +#define BCMA_SOC_PCIE_DMA_H32 0x80000000U /* PCIE Client Mode sb2pcitranslation2 + * (2 ZettaBytes), high 32 bits + */ + +#define BCMA_SOC_PCI1_MEM 0x40000000U /* Host Mode sb2pcitranslation0 (64 MB) */ +#define BCMA_SOC_PCI1_CFG 0x44000000U /* Host Mode sb2pcitranslation1 (64 MB) */ +#define BCMA_SOC_PCIE1_DMA_H32 0xc0000000U /* PCIE Client Mode sb2pcitranslation2 + * (2 ZettaBytes), high 32 bits + */ + #endif /* LINUX_BCMA_REGS_H_ */ -- cgit v1.2.3-70-g09d2 From 8f9ada4fa1926e540b1562cb9bacb3e51a698c35 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 31 Jan 2012 00:03:36 +0100 Subject: bcma: add bus num counter If we have two bcma buses on one computer the second will not work without this patch. Now each bus gets an own number. Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- drivers/bcma/main.c | 12 +++++++++++- include/linux/bcma/bcma.h | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 3363036f23d..bcd1c01cde9 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c @@ -13,6 +13,12 @@ MODULE_DESCRIPTION("Broadcom's specific AMBA driver"); MODULE_LICENSE("GPL"); +/* contains the number the next bus should get. */ +static unsigned int bcma_bus_next_num = 0; + +/* bcma_buses_mutex locks the bcma_bus_next_num */ +static DEFINE_MUTEX(bcma_buses_mutex); + static int bcma_bus_match(struct device *dev, struct device_driver *drv); static int bcma_device_probe(struct device *dev); static int bcma_device_remove(struct device *dev); @@ -93,7 +99,7 @@ static int bcma_register_cores(struct bcma_bus *bus) core->dev.release = bcma_release_core_dev; core->dev.bus = &bcma_bus_type; - dev_set_name(&core->dev, "bcma%d:%d", 0/*bus->num*/, dev_id); + dev_set_name(&core->dev, "bcma%d:%d", bus->num, dev_id); switch (bus->hosttype) { case BCMA_HOSTTYPE_PCI: @@ -137,6 +143,10 @@ int __devinit bcma_bus_register(struct bcma_bus *bus) int err; struct bcma_device *core; + mutex_lock(&bcma_buses_mutex); + bus->num = bcma_bus_next_num++; + mutex_unlock(&bcma_buses_mutex); + /* Scan for devices (cores) */ err = bcma_bus_scan(bus); if (err) { diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h index 024a6e2a908..b9f65fbee42 100644 --- a/include/linux/bcma/bcma.h +++ b/include/linux/bcma/bcma.h @@ -196,6 +196,7 @@ struct bcma_bus { struct list_head cores; u8 nr_cores; u8 init_done:1; + u8 num; struct bcma_drv_cc drv_cc; struct bcma_drv_pci drv_pci; -- cgit v1.2.3-70-g09d2 From d6865dcc58f252480515101fd13532f0fc420b53 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 31 Jan 2012 00:03:37 +0100 Subject: bcma: add extra sprom check This check is needed on the BCM43224 device as it says in the capabilities it has an sprom but is extra check says it has not. Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- drivers/bcma/sprom.c | 7 +++++++ include/linux/bcma/bcma_driver_chipcommon.h | 16 ++++++++++++++++ 2 files changed, 23 insertions(+) (limited to 'drivers') diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c index e35134f724f..ca7752510d5 100644 --- a/drivers/bcma/sprom.c +++ b/drivers/bcma/sprom.c @@ -250,6 +250,7 @@ int bcma_sprom_get(struct bcma_bus *bus) { u16 offset; u16 *sprom; + u32 sromctrl; int err = 0; if (!bus->drv_cc.core) @@ -258,6 +259,12 @@ int bcma_sprom_get(struct bcma_bus *bus) if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM)) return -ENOENT; + if (bus->drv_cc.core->id.rev >= 32) { + sromctrl = bcma_read32(bus->drv_cc.core, BCMA_CC_SROM_CONTROL); + if (!(sromctrl & BCMA_CC_SROM_CONTROL_PRESENT)) + return -ENOENT; + } + sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16), GFP_KERNEL); if (!sprom) diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h index a33086a7530..e72938b1071 100644 --- a/include/linux/bcma/bcma_driver_chipcommon.h +++ b/include/linux/bcma/bcma_driver_chipcommon.h @@ -181,6 +181,22 @@ #define BCMA_CC_FLASH_CFG 0x0128 #define BCMA_CC_FLASH_CFG_DS 0x0010 /* Data size, 0=8bit, 1=16bit */ #define BCMA_CC_FLASH_WAITCNT 0x012C +#define BCMA_CC_SROM_CONTROL 0x0190 +#define BCMA_CC_SROM_CONTROL_START 0x80000000 +#define BCMA_CC_SROM_CONTROL_BUSY 0x80000000 +#define BCMA_CC_SROM_CONTROL_OPCODE 0x60000000 +#define BCMA_CC_SROM_CONTROL_OP_READ 0x00000000 +#define BCMA_CC_SROM_CONTROL_OP_WRITE 0x20000000 +#define BCMA_CC_SROM_CONTROL_OP_WRDIS 0x40000000 +#define BCMA_CC_SROM_CONTROL_OP_WREN 0x60000000 +#define BCMA_CC_SROM_CONTROL_OTPSEL 0x00000010 +#define BCMA_CC_SROM_CONTROL_LOCK 0x00000008 +#define BCMA_CC_SROM_CONTROL_SIZE_MASK 0x00000006 +#define BCMA_CC_SROM_CONTROL_SIZE_1K 0x00000000 +#define BCMA_CC_SROM_CONTROL_SIZE_4K 0x00000002 +#define BCMA_CC_SROM_CONTROL_SIZE_16K 0x00000004 +#define BCMA_CC_SROM_CONTROL_SIZE_SHIFT 1 +#define BCMA_CC_SROM_CONTROL_PRESENT 0x00000001 /* 0x1E0 is defined as shared BCMA_CLKCTLST */ #define BCMA_CC_HW_WORKAROUND 0x01E4 /* Hardware workaround (rev >= 20) */ #define BCMA_CC_UART0_DATA 0x0300 -- cgit v1.2.3-70-g09d2 From 1d73c51a8476847d96a6c5a2ae3715d7099c58c9 Mon Sep 17 00:00:00 2001 From: "Devendra.Naga" Date: Tue, 31 Jan 2012 01:28:15 -0500 Subject: rtlwifi: remove return in _rtl_pci_switch_clk_req the return value from _rtl_pci_switch_clk_req is not used by any of its callers. Signed-off-by: Devendra.Naga Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/pci.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 5cb2199435d..9a0190944de 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -198,7 +198,7 @@ static bool _rtl_pci_platform_switch_device_pci_aspm( } /*When we set 0x01 to enable clk request. Set 0x0 to disable clk req.*/ -static bool _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value) +static void _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value) { struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); @@ -207,8 +207,6 @@ static bool _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value) if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) udelay(100); - - return true; } /*Disable RTL8192SE ASPM & Disable Pci Bridge ASPM*/ -- cgit v1.2.3-70-g09d2 From f3e1b97f036ee477c49b8ec561027db8e3863eab Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Tue, 31 Jan 2012 23:23:45 +0900 Subject: iwmc3200wifi: Fix typo in trace.h Correct spelling "embeded" to "embedded" in drivers/net/wireless/iwmc3200wifi/trace.h Signed-off-by: Masanari Iida Acked-by: Samuel Ortiz Signed-off-by: John W. Linville --- drivers/net/wireless/iwmc3200wifi/trace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwmc3200wifi/trace.h b/drivers/net/wireless/iwmc3200wifi/trace.h index abb4805fa8d..f5f7070b7e2 100644 --- a/drivers/net/wireless/iwmc3200wifi/trace.h +++ b/drivers/net/wireless/iwmc3200wifi/trace.h @@ -144,7 +144,7 @@ TRACE_EVENT(iwm_tx_packets, TP_printk( IWM_PR_FMT " Tx %spacket: eot %d, seq 0x%x, sta_color 0x%x, " - "ra_tid 0x%x, credit_group 0x%x, embeded_packets %d, %d bytes", + "ra_tid 0x%x, credit_group 0x%x, embedded_packets %d, %d bytes", IWM_PR_ARG, !__entry->eot ? "concatenated " : "", __entry->eot, __entry->seq, __entry->color, __entry->ra_tid, __entry->credit_group, __entry->npkt, __entry->bytes -- cgit v1.2.3-70-g09d2 From 5aff4e74dc69105b95b799b036aa597ce0726e07 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Tue, 31 Jan 2012 09:42:58 -0600 Subject: rtlwifi: Fix typo in dm.c Correct a spelling "disconnet" to "disconnect" in drivers/net/wireless/rtlwifi/rtl8192de/dm.c Signed-off-by: Masanari Iida Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192de/dm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c index 181ed6fc90e..9fda1af44b3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c @@ -294,7 +294,7 @@ static void rtl92d_dm_find_minimum_rssi(struct ieee80211_hw *hw) de_digtable.min_undecorated_pwdb_for_dm = rtlpriv->dm.UNDEC_SM_PWDB; RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, - "AP Ext Port or disconnet PWDB = 0x%x\n", + "AP Ext Port or disconnect PWDB = 0x%x\n", de_digtable.min_undecorated_pwdb_for_dm); } -- cgit v1.2.3-70-g09d2 From 3eda95de19e1781612091869e866a5014257f462 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Tue, 31 Jan 2012 10:29:22 -0600 Subject: rtlwifi: Remove extra debugging message accidentally left in In commit b0302aba812bcc39291cdab9ad7e37008f352a91, an extra debugging message that is spamming the logs was not deleted before submission. Signed-off-by: Larry Finger Cc: Stable Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/core.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index f231b918043..278e9f957e0 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -296,12 +296,10 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) * because that will cause nullfunc send by mac80211 * fail, and cause pkt loss, we have tested that 5mA * is worked very well */ - if (!rtlpriv->psc.multi_buffered) { + if (!rtlpriv->psc.multi_buffered) queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_work, MSECS(5)); - pr_info("In section\n"); - } } else { rtl_swlps_rf_awake(hw); rtlpriv->psc.sw_ps_enabled = false; -- cgit v1.2.3-70-g09d2 From f0d4724b2a663089d21e19933ca591d842b63230 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Wed, 1 Feb 2012 00:13:54 +0100 Subject: bcma: log the id, rev and pkg of the chip found This makes us see what type of hardware someone uses by the dmesg output. Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- drivers/bcma/scan.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c index e513aa83ec2..6621b2221b4 100644 --- a/drivers/bcma/scan.c +++ b/drivers/bcma/scan.c @@ -364,6 +364,7 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr, void bcma_init_bus(struct bcma_bus *bus) { s32 tmp; + struct bcma_chipinfo *chipinfo = &(bus->chipinfo); if (bus->init_done) return; @@ -374,9 +375,12 @@ void bcma_init_bus(struct bcma_bus *bus) bcma_scan_switch_core(bus, BCMA_ADDR_BASE); tmp = bcma_scan_read32(bus, 0, BCMA_CC_ID); - bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT; - bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT; - bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT; + chipinfo->id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT; + chipinfo->rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT; + chipinfo->pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT; + pr_info("Found chip with id 0x%04X, rev 0x%02X and package 0x%02X\n", + chipinfo->id, chipinfo->rev, chipinfo->pkg); + bus->init_done = true; } -- cgit v1.2.3-70-g09d2 From bedb2a18af0a4e7565182c07fadd854e3ae8c9bc Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Wed, 1 Feb 2012 00:13:55 +0100 Subject: ssb: log the id, rev and pkg of the chip found This makes us see what type of hardware someone uses by the dmesg output. Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- drivers/ssb/scan.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c index 3e844874631..266c7c5c86d 100644 --- a/drivers/ssb/scan.c +++ b/drivers/ssb/scan.c @@ -318,6 +318,9 @@ int ssb_bus_scan(struct ssb_bus *bus, bus->chip_package = 0; } } + ssb_printk(KERN_INFO PFX "Found chip with id 0x%04X, rev 0x%02X and " + "package 0x%02X\n", bus->chip_id, bus->chip_rev, + bus->chip_package); if (!bus->nr_devices) bus->nr_devices = chipid_to_nrcores(bus->chip_id); if (bus->nr_devices > ARRAY_SIZE(bus->devices)) { -- cgit v1.2.3-70-g09d2 From d486a5b4996d2fffd10098725781f2c5690774bc Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Wed, 1 Feb 2012 00:13:56 +0100 Subject: ssb: add support for bcm5354 This patch adds support the the BCM5354 SoC. It has a PMU and a constant not configurable clock. Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- drivers/ssb/driver_chipcommon_pmu.c | 48 +++++++++++++++++++++++++++++++++---- drivers/ssb/driver_mipscore.c | 3 +++ drivers/ssb/main.c | 3 +++ drivers/ssb/ssb_private.h | 4 ++++ 4 files changed, 53 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c index e5a2e0e9bc1..b58fef780ea 100644 --- a/drivers/ssb/driver_chipcommon_pmu.c +++ b/drivers/ssb/driver_chipcommon_pmu.c @@ -13,6 +13,9 @@ #include #include #include +#ifdef CONFIG_BCM47XX +#include +#endif #include "ssb_private.h" @@ -92,10 +95,6 @@ static void ssb_pmu0_pllinit_r0(struct ssb_chipcommon *cc, u32 pmuctl, tmp, pllctl; unsigned int i; - if ((bus->chip_id == 0x5354) && !crystalfreq) { - /* The 5354 crystal freq is 25MHz */ - crystalfreq = 25000; - } if (crystalfreq) e = pmu0_plltab_find_entry(crystalfreq); if (!e) @@ -321,7 +320,11 @@ static void ssb_pmu_pll_init(struct ssb_chipcommon *cc) u32 crystalfreq = 0; /* in kHz. 0 = keep default freq. */ if (bus->bustype == SSB_BUSTYPE_SSB) { - /* TODO: The user may override the crystal frequency. */ +#ifdef CONFIG_BCM47XX + char buf[20]; + if (nvram_getenv("xtalfreq", buf, sizeof(buf)) >= 0) + crystalfreq = simple_strtoul(buf, NULL, 0); +#endif } switch (bus->chip_id) { @@ -330,7 +333,11 @@ static void ssb_pmu_pll_init(struct ssb_chipcommon *cc) ssb_pmu1_pllinit_r0(cc, crystalfreq); break; case 0x4328: + ssb_pmu0_pllinit_r0(cc, crystalfreq); + break; case 0x5354: + if (crystalfreq == 0) + crystalfreq = 25000; ssb_pmu0_pllinit_r0(cc, crystalfreq); break; case 0x4322: @@ -607,3 +614,34 @@ void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on) EXPORT_SYMBOL(ssb_pmu_set_ldo_voltage); EXPORT_SYMBOL(ssb_pmu_set_ldo_paref); + +u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc) +{ + struct ssb_bus *bus = cc->dev->bus; + + switch (bus->chip_id) { + case 0x5354: + /* 5354 chip uses a non programmable PLL of frequency 240MHz */ + return 240000000; + default: + ssb_printk(KERN_ERR PFX + "ERROR: PMU cpu clock unknown for device %04X\n", + bus->chip_id); + return 0; + } +} + +u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc) +{ + struct ssb_bus *bus = cc->dev->bus; + + switch (bus->chip_id) { + case 0x5354: + return 120000000; + default: + ssb_printk(KERN_ERR PFX + "ERROR: PMU controlclock unknown for device %04X\n", + bus->chip_id); + return 0; + } +} diff --git a/drivers/ssb/driver_mipscore.c b/drivers/ssb/driver_mipscore.c index ced50156859..7e2ddc042f5 100644 --- a/drivers/ssb/driver_mipscore.c +++ b/drivers/ssb/driver_mipscore.c @@ -208,6 +208,9 @@ u32 ssb_cpu_clock(struct ssb_mipscore *mcore) struct ssb_bus *bus = mcore->dev->bus; u32 pll_type, n, m, rate = 0; + if (bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU) + return ssb_pmu_get_cpu_clock(&bus->chipco); + if (bus->extif.dev) { ssb_extif_get_clockcontrol(&bus->extif, &pll_type, &n, &m); } else if (bus->chipco.dev) { diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index bb6317fb925..2a0a1b99e0e 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -1094,6 +1094,9 @@ u32 ssb_clockspeed(struct ssb_bus *bus) u32 plltype; u32 clkctl_n, clkctl_m; + if (bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU) + return ssb_pmu_get_controlclock(&bus->chipco); + if (ssb_extif_available(&bus->extif)) ssb_extif_get_clockcontrol(&bus->extif, &plltype, &clkctl_n, &clkctl_m); diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h index 77653014db0..a305550b4b6 100644 --- a/drivers/ssb/ssb_private.h +++ b/drivers/ssb/ssb_private.h @@ -207,4 +207,8 @@ static inline void b43_pci_ssb_bridge_exit(void) } #endif /* CONFIG_SSB_B43_PCI_BRIDGE */ +/* driver_chipcommon_pmu.c */ +extern u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc); +extern u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc); + #endif /* LINUX_SSB_PRIVATE_H_ */ -- cgit v1.2.3-70-g09d2 From 291689fcfbf0046d17c83c36fc983400f499dec3 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 1 Feb 2012 10:43:31 +0300 Subject: ath9k: cleanup a min_t() cast If the firmware was over 2G, it would cause memory corruption and the system would die here. Obviously we all know the firmware isn't going to be that large but static checkers get upset. Signed-off-by: Dan Carpenter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index f317515d8bf..424aabb2c73 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -981,7 +981,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) return -ENOMEM; while (len) { - transfer = min_t(int, len, 4096); + transfer = min_t(size_t, len, 4096); memcpy(buf, data, transfer); err = usb_control_msg(hif_dev->udev, -- cgit v1.2.3-70-g09d2 From 197a4e4e1f7ef11458f09b4dd74397baf6758133 Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Wed, 1 Feb 2012 16:19:54 +0530 Subject: mwl8k: Remove BSSID from the firmware when the BSS is stopped Using command DEL_MAC_ADDR, remove the mac address of the BSS when it is stopped i.e the corresponding vif is removed. Without this, the stale bss entry will still be maintained in the firmware which causes issues when the BSS's are recreated. Signed-off-by: Nishant Sarmukadam Signed-off-by: Yogesh Ashok Powar Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index fd125473be7..ac7c983f163 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -402,6 +402,7 @@ static const struct ieee80211_rate mwl8k_rates_50[] = { #define MWL8K_CMD_SET_MAC_ADDR 0x0202 /* per-vif */ #define MWL8K_CMD_SET_RATEADAPT_MODE 0x0203 #define MWL8K_CMD_GET_WATCHDOG_BITMAP 0x0205 +#define MWL8K_CMD_DEL_MAC_ADDR 0x0206 /* per-vif */ #define MWL8K_CMD_BSS_START 0x1100 /* per-vif */ #define MWL8K_CMD_SET_NEW_STN 0x1111 /* per-vif */ #define MWL8K_CMD_UPDATE_ENCRYPTION 0x1122 /* per-vif */ @@ -3430,10 +3431,7 @@ static int mwl8k_cmd_enable_sniffer(struct ieee80211_hw *hw, bool enable) return rc; } -/* - * CMD_SET_MAC_ADDR. - */ -struct mwl8k_cmd_set_mac_addr { +struct mwl8k_cmd_update_mac_addr { struct mwl8k_cmd_pkt header; union { struct { @@ -3449,12 +3447,12 @@ struct mwl8k_cmd_set_mac_addr { #define MWL8K_MAC_TYPE_PRIMARY_AP 2 #define MWL8K_MAC_TYPE_SECONDARY_AP 3 -static int mwl8k_cmd_set_mac_addr(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, u8 *mac) +static int mwl8k_cmd_update_mac_addr(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, u8 *mac, bool set) { struct mwl8k_priv *priv = hw->priv; struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif); - struct mwl8k_cmd_set_mac_addr *cmd; + struct mwl8k_cmd_update_mac_addr *cmd; int mac_type; int rc; @@ -3475,7 +3473,11 @@ static int mwl8k_cmd_set_mac_addr(struct ieee80211_hw *hw, if (cmd == NULL) return -ENOMEM; - cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_MAC_ADDR); + if (set) + cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_MAC_ADDR); + else + cmd->header.code = cpu_to_le16(MWL8K_CMD_DEL_MAC_ADDR); + cmd->header.length = cpu_to_le16(sizeof(*cmd)); if (priv->ap_fw) { cmd->mbss.mac_type = cpu_to_le16(mac_type); @@ -3490,6 +3492,24 @@ static int mwl8k_cmd_set_mac_addr(struct ieee80211_hw *hw, return rc; } +/* + * MWL8K_CMD_SET_MAC_ADDR. + */ +static inline int mwl8k_cmd_set_mac_addr(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, u8 *mac) +{ + return mwl8k_cmd_update_mac_addr(hw, vif, mac, true); +} + +/* + * MWL8K_CMD_DEL_MAC_ADDR. + */ +static inline int mwl8k_cmd_del_mac_addr(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, u8 *mac) +{ + return mwl8k_cmd_update_mac_addr(hw, vif, mac, false); +} + /* * CMD_SET_RATEADAPT_MODE. */ @@ -4542,7 +4562,7 @@ static void mwl8k_remove_interface(struct ieee80211_hw *hw, if (priv->ap_fw) mwl8k_cmd_set_new_stn_del(hw, vif, vif->addr); - mwl8k_cmd_set_mac_addr(hw, vif, "\x00\x00\x00\x00\x00\x00"); + mwl8k_cmd_del_mac_addr(hw, vif, vif->addr); mwl8k_remove_vif(priv, mwl8k_vif); } -- cgit v1.2.3-70-g09d2 From 477778bb0e7c671860528946b412294684337c5e Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Wed, 1 Feb 2012 20:41:44 -0800 Subject: mwifiex: fix NULL pointer dereference in set_channel() In set_channel() callback handler, "priv" pointer is derived from net_device. Sometimes net_device pointer coming from the stack is NULL which causes kernel crash. This patch fixes the problem by deriving "priv" from wiphy when net_device pointer is NULL. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 6fef4925d13..54e45c829c5 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -376,7 +376,12 @@ mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type) { - struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + struct mwifiex_private *priv; + + if (dev) + priv = mwifiex_netdev_get_priv(dev); + else + priv = mwifiex_cfg80211_get_priv(wiphy); if (priv->media_connected) { wiphy_err(wiphy, "This setting is valid only when station " -- cgit v1.2.3-70-g09d2 From 3dc5e1751803e812806d7aa46150af92f91ef489 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Wed, 1 Feb 2012 20:41:45 -0800 Subject: mwifiex: enable HT operating mode This patch sets default adapter channel_type as HT. Hence the device will opearate in HT mode. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/init.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index e13b6d99171..83cc10fca4b 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -280,6 +280,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) adapter->adhoc_awake_period = 0; memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter)); adapter->arp_filter_size = 0; + adapter->channel_type = NL80211_CHAN_HT20; } /* -- cgit v1.2.3-70-g09d2 From 3d86b93064c7f18378a2008bab9608ca7d11bdbb Mon Sep 17 00:00:00 2001 From: Tim Gardner Date: Thu, 2 Feb 2012 13:48:06 -0700 Subject: rtlwifi: Fix PCI probe error path orphaned memory Memory allocated by ieee80211_alloc_hw() will get orphaned if any subsequent initializations fail. Also don't pci_set_drvdata(pdev, NULL) until just before disabling the PCI device. Functions called by rtl_deinit_core(hw) may eventually need the context (when its actually implemented). Cc: Larry Finger Cc: Chaoming Li Cc: John W. Linville Cc: linux-wireless@vger.kernel.org Cc: netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Tim Gardner Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/pci.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 9a0190944de..c5f6a322feb 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -1758,8 +1758,8 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { RT_ASSERT(false, "Unable to obtain 32bit DMA for consistent allocations\n"); - pci_disable_device(pdev); - return -ENOMEM; + err = -ENOMEM; + goto fail1; } } @@ -1801,7 +1801,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, err = pci_request_regions(pdev, KBUILD_MODNAME); if (err) { RT_ASSERT(false, "Can't obtain PCI resources\n"); - goto fail2; + goto fail1; } pmem_start = pci_resource_start(pdev, rtlpriv->cfg->bar_id); @@ -1814,6 +1814,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, rtlpriv->cfg->bar_id, pmem_len); if (rtlpriv->io.pci_mem_start == 0) { RT_ASSERT(false, "Can't map PCI mem\n"); + err = -ENOMEM; goto fail2; } @@ -1830,8 +1831,10 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, pci_write_config_byte(pdev, 0x04, 0x07); /* find adapter */ - if (!_rtl_pci_find_adapter(pdev, hw)) + if (!_rtl_pci_find_adapter(pdev, hw)) { + err = -ENODEV; goto fail3; + } /* Init IO handler */ _rtl_pci_io_handler_init(&pdev->dev, hw); @@ -1841,6 +1844,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, if (rtlpriv->cfg->ops->init_sw_vars(hw)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n"); + err = -ENODEV; goto fail3; } @@ -1885,7 +1889,6 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, return 0; fail3: - pci_set_drvdata(pdev, NULL); rtl_deinit_core(hw); _rtl_pci_io_handler_release(hw); @@ -1897,10 +1900,12 @@ fail2: complete(&rtlpriv->firmware_loading_complete); fail1: - + if (hw) + ieee80211_free_hw(hw); + pci_set_drvdata(pdev, NULL); pci_disable_device(pdev); - return -ENODEV; + return err; } EXPORT_SYMBOL(rtl_pci_probe); -- cgit v1.2.3-70-g09d2 From f3c8d2591fa7278abe58ee0278a41d5b130d1718 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Thu, 2 Feb 2012 20:48:57 -0800 Subject: mwifiex: cleanup in snmp_mib command preparation code 1) Remove unnecessary switch case usage. 2) Replace "X=cpu_to_le16(le16_to_cpu(X) + Y)" by "le16_add_cpu(X, Y)" 3) Declare "ul_temp" variable as u16 instead of u32 to avoid unnecessary typecasting Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/sta_cmd.c | 60 +++++----------------------------- 1 file changed, 8 insertions(+), 52 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 6e443ffa046..324c651527c 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c @@ -103,7 +103,7 @@ static int mwifiex_cmd_mac_control(struct mwifiex_private *priv, static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, u16 cmd_action, u32 cmd_oid, - u32 *ul_temp) + u16 *ul_temp) { struct host_cmd_ds_802_11_snmp_mib *snmp_mib = &cmd->params.smib; @@ -112,62 +112,18 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_snmp_mib) - 1 + S_DS_GEN); + snmp_mib->oid = cpu_to_le16((u16)cmd_oid); if (cmd_action == HostCmd_ACT_GEN_GET) { snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_GET); snmp_mib->buf_size = cpu_to_le16(MAX_SNMP_BUF_SIZE); - cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) - + MAX_SNMP_BUF_SIZE); + le16_add_cpu(&cmd->size, MAX_SNMP_BUF_SIZE); + } else if (cmd_action == HostCmd_ACT_GEN_SET) { + snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); + snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); + *((__le16 *) (snmp_mib->value)) = cpu_to_le16(*ul_temp); + le16_add_cpu(&cmd->size, sizeof(u16)); } - switch (cmd_oid) { - case FRAG_THRESH_I: - snmp_mib->oid = cpu_to_le16((u16) FRAG_THRESH_I); - if (cmd_action == HostCmd_ACT_GEN_SET) { - snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); - snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); - *((__le16 *) (snmp_mib->value)) = - cpu_to_le16((u16) *ul_temp); - cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) - + sizeof(u16)); - } - break; - case RTS_THRESH_I: - snmp_mib->oid = cpu_to_le16((u16) RTS_THRESH_I); - if (cmd_action == HostCmd_ACT_GEN_SET) { - snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); - snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); - *(__le16 *) (snmp_mib->value) = - cpu_to_le16((u16) *ul_temp); - cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) - + sizeof(u16)); - } - break; - - case SHORT_RETRY_LIM_I: - snmp_mib->oid = cpu_to_le16((u16) SHORT_RETRY_LIM_I); - if (cmd_action == HostCmd_ACT_GEN_SET) { - snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); - snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); - *((__le16 *) (snmp_mib->value)) = - cpu_to_le16((u16) *ul_temp); - cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) - + sizeof(u16)); - } - break; - case DOT11D_I: - snmp_mib->oid = cpu_to_le16((u16) DOT11D_I); - if (cmd_action == HostCmd_ACT_GEN_SET) { - snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); - snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); - *((__le16 *) (snmp_mib->value)) = - cpu_to_le16((u16) *ul_temp); - cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) - + sizeof(u16)); - } - break; - default: - break; - } dev_dbg(priv->adapter->dev, "cmd: SNMP_CMD: Action=0x%x, OID=0x%x, OIDSize=0x%x," " Value=0x%x\n", -- cgit v1.2.3-70-g09d2 From caf60a6c957e7a35837a41f845e57b4433e20276 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Thu, 2 Feb 2012 20:48:58 -0800 Subject: mwifiex: update correct dtim_period in dump_station() Earlier we were using dtim period extracted from scan response buffer provided by FW in scan operation. But it is observed that sometimes the buffer doesn't contain dtim period tlv, and wrong value (0) was sent to user space. After association FW will start listening to beacon frames of connected AP and store dtim period. Therefore we can get it from FW in dump_station() instead of using wrong value obtained in scanning. Redundant code after adapting new approach for dtim period is also removed in this patch. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 8 ++++++-- drivers/net/wireless/mwifiex/main.h | 2 +- drivers/net/wireless/mwifiex/scan.c | 6 ------ drivers/net/wireless/mwifiex/sta_cmdresp.c | 3 +++ 4 files changed, 10 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 54e45c829c5..478d2f12c02 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -539,6 +539,11 @@ mwifiex_dump_station_info(struct mwifiex_private *priv, ret = -EFAULT; } + /* Get DTIM period information from firmware */ + mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, + HostCmd_ACT_GEN_GET, DTIM_PERIOD_I, + &priv->dtim_period); + /* * Bit 0 in tx_htinfo indicates that current Tx rate is 11n rate. Valid * MCS index values for us are 0 to 7. @@ -573,8 +578,7 @@ mwifiex_dump_station_info(struct mwifiex_private *priv, WLAN_CAPABILITY_SHORT_SLOT_TIME) sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME; - sinfo->bss_param.dtim_period = - priv->curr_bss_params.bss_descriptor.dtim_period; + sinfo->bss_param.dtim_period = priv->dtim_period; sinfo->bss_param.beacon_interval = priv->curr_bss_params.bss_descriptor.beacon_period; } diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 3dc0f721c1d..52810b1497e 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -249,7 +249,6 @@ struct mwifiex_bssdescriptor { u32 channel; u32 freq; u16 beacon_period; - u8 dtim_period; u8 erp_flags; u32 bss_mode; u8 supported_rates[MWIFIEX_SUPPORTED_RATES]; @@ -392,6 +391,7 @@ struct mwifiex_private { u8 prev_bssid[ETH_ALEN]; struct mwifiex_current_bss_params curr_bss_params; u16 beacon_period; + u8 dtim_period; u16 listen_interval; u16 atim_window; u8 adhoc_channel; diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 135208596af..98f1ca9cd6d 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -1086,7 +1086,6 @@ mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, struct ieee_types_vendor_specific *vendor_ie; const u8 wpa_oui[4] = { 0x00, 0x50, 0xf2, 0x01 }; const u8 wmm_oui[4] = { 0x00, 0x50, 0xf2, 0x02 }; - struct ieee80211_tim_ie *tim_ie; found_data_rate_ie = false; rate_size = 0; @@ -1259,11 +1258,6 @@ mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, sizeof(struct ieee_types_header) - bss_entry->beacon_buf); break; - case WLAN_EID_TIM: - tim_ie = (void *) (current_ptr + - sizeof(struct ieee_types_header)); - bss_entry->dtim_period = tim_ie->dtim_period; - break; default: break; } diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index e812db8b695..0d8618a8443 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -210,6 +210,9 @@ static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv, dev_dbg(priv->adapter->dev, "info: SNMP_RESP: TxRetryCount=%u\n", ul_temp); break; + case DTIM_PERIOD_I: + dev_dbg(priv->adapter->dev, + "info: SNMP_RESP: DTIM period=%u\n", ul_temp); default: break; } -- cgit v1.2.3-70-g09d2 From c8b03958d4b23dc48932ec095a391f3d6447e0e9 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 3 Feb 2012 17:31:37 +0100 Subject: iwlegacy: move rxon commands out of ctx structure Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/3945-mac.c | 82 +++++++-------- drivers/net/wireless/iwlegacy/3945-rs.c | 2 +- drivers/net/wireless/iwlegacy/3945.c | 22 ++-- drivers/net/wireless/iwlegacy/4965-calib.c | 6 +- drivers/net/wireless/iwlegacy/4965-mac.c | 31 +++--- drivers/net/wireless/iwlegacy/4965.c | 99 +++++++++--------- drivers/net/wireless/iwlegacy/common.c | 157 ++++++++++++++--------------- drivers/net/wireless/iwlegacy/common.h | 30 +++--- drivers/net/wireless/iwlegacy/debug.c | 4 +- 9 files changed, 205 insertions(+), 228 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c index 54b2d391e91..980566fdb81 100644 --- a/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/iwlegacy/3945-mac.c @@ -672,15 +672,13 @@ il3945_get_measurement(struct il_priv *il, int rc; int spectrum_resp_status; int duration = le16_to_cpu(params->duration); - struct il_rxon_context *ctx = &il->ctx; if (il_is_associated(il)) add_time = il_usecs_to_beacons(il, le64_to_cpu(params->start_time) - il->_3945.last_tsf, - le16_to_cpu(ctx->timing. - beacon_interval)); + le16_to_cpu(il->timing.beacon_interval)); memset(&spectrum, 0, sizeof(spectrum)); @@ -694,15 +692,14 @@ il3945_get_measurement(struct il_priv *il, if (il_is_associated(il)) spectrum.start_time = il_add_beacon_time(il, il->_3945.last_beacon_time, add_time, - le16_to_cpu(ctx->timing. - beacon_interval)); + le16_to_cpu(il->timing.beacon_interval)); else spectrum.start_time = 0; spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT); spectrum.channels[0].channel = params->channel; spectrum.channels[0].type = type; - if (ctx->active.flags & RXON_FLG_BAND_24G_MSK) + if (il->active.flags & RXON_FLG_BAND_24G_MSK) spectrum.flags |= RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK; @@ -2150,7 +2147,6 @@ il3945_alive_start(struct il_priv *il) { int thermal_spin = 0; u32 rfkill; - struct il_rxon_context *ctx = &il->ctx; D_INFO("Runtime Alive received.\n"); @@ -2206,13 +2202,13 @@ il3945_alive_start(struct il_priv *il) if (il_is_associated(il)) { struct il3945_rxon_cmd *active_rxon = - (struct il3945_rxon_cmd *)(&ctx->active); + (struct il3945_rxon_cmd *)(&il->active); - ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; } else { /* Initialize our rx_config data */ - il_connection_init_rx_config(il, ctx); + il_connection_init_rx_config(il, &il->ctx); } /* Configure Bluetooth device coexistence support */ @@ -2221,7 +2217,7 @@ il3945_alive_start(struct il_priv *il) set_bit(S_READY, &il->status); /* Configure the adapter for unassociated operation */ - il3945_commit_rxon(il, ctx); + il3945_commit_rxon(il, &il->ctx); il3945_reg_txpower_periodic(il); @@ -2670,7 +2666,7 @@ il3945_post_scan(struct il_priv *il) * Since setting the RXON may have been deferred while * performing the scan, fire one off if needed */ - if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) + if (memcmp(&il->staging, &il->active, sizeof(il->staging))) il3945_commit_rxon(il, ctx); } @@ -2728,7 +2724,7 @@ il3945_post_associate(struct il_priv *il) return; D_ASSOC("Associated as %d to: %pM\n", ctx->vif->bss_conf.aid, - ctx->active.bssid_addr); + il->active.bssid_addr); if (test_bit(S_EXIT_PENDING, &il->status)) return; @@ -2737,30 +2733,30 @@ il3945_post_associate(struct il_priv *il) conf = &il->hw->conf; - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; il3945_commit_rxon(il, ctx); rc = il_send_rxon_timing(il, ctx); if (rc) IL_WARN("C_RXON_TIMING failed - " "Attempting to continue.\n"); - ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; - ctx->staging.assoc_id = cpu_to_le16(ctx->vif->bss_conf.aid); + il->staging.assoc_id = cpu_to_le16(ctx->vif->bss_conf.aid); D_ASSOC("assoc id %d beacon interval %d\n", ctx->vif->bss_conf.aid, ctx->vif->bss_conf.beacon_int); if (ctx->vif->bss_conf.use_short_preamble) - ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; else - ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; - if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { + if (il->staging.flags & RXON_FLG_BAND_24G_MSK) { if (ctx->vif->bss_conf.use_short_slot) - ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; + il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; else - ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; + il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; } il3945_commit_rxon(il, ctx); @@ -2902,7 +2898,7 @@ il3945_config_ap(struct il_priv *il) if (!(il_is_associated(il))) { /* RXON - unassoc (to set timing command) */ - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; il3945_commit_rxon(il, ctx); /* RXON Timing */ @@ -2911,21 +2907,21 @@ il3945_config_ap(struct il_priv *il) IL_WARN("C_RXON_TIMING failed - " "Attempting to continue.\n"); - ctx->staging.assoc_id = 0; + il->staging.assoc_id = 0; if (vif->bss_conf.use_short_preamble) - ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; else - ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; - if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { + if (il->staging.flags & RXON_FLG_BAND_24G_MSK) { if (vif->bss_conf.use_short_slot) - ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; + il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; else - ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; + il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; } /* restore RXON assoc */ - ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; il3945_commit_rxon(il, ctx); } il3945_send_beacon_cmd(il); @@ -3032,7 +3028,6 @@ il3945_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, { struct il_priv *il = hw->priv; __le32 filter_or = 0, filter_nand = 0; - struct il_rxon_context *ctx = &il->ctx; #define CHK(test, flag) do { \ if (*total_flags & (test)) \ @@ -3052,8 +3047,8 @@ il3945_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, mutex_lock(&il->mutex); - ctx->staging.filter_flags &= ~filter_nand; - ctx->staging.filter_flags |= filter_or; + il->staging.filter_flags &= ~filter_nand; + il->staging.filter_flags |= filter_or; /* * Not committing directly because hardware can perform a scan, @@ -3170,9 +3165,8 @@ static ssize_t il3945_show_flags(struct device *d, struct device_attribute *attr, char *buf) { struct il_priv *il = dev_get_drvdata(d); - struct il_rxon_context *ctx = &il->ctx; - return sprintf(buf, "0x%04X\n", ctx->active.flags); + return sprintf(buf, "0x%04X\n", il->active.flags); } static ssize_t @@ -3181,17 +3175,16 @@ il3945_store_flags(struct device *d, struct device_attribute *attr, { struct il_priv *il = dev_get_drvdata(d); u32 flags = simple_strtoul(buf, NULL, 0); - struct il_rxon_context *ctx = &il->ctx; mutex_lock(&il->mutex); - if (le32_to_cpu(ctx->staging.flags) != flags) { + if (le32_to_cpu(il->staging.flags) != flags) { /* Cancel any currently running scans... */ if (il_scan_cancel_timeout(il, 100)) IL_WARN("Could not cancel scan.\n"); else { D_INFO("Committing rxon.flags = 0x%04X\n", flags); - ctx->staging.flags = cpu_to_le32(flags); - il3945_commit_rxon(il, ctx); + il->staging.flags = cpu_to_le32(flags); + il3945_commit_rxon(il, &il->ctx); } } mutex_unlock(&il->mutex); @@ -3207,9 +3200,8 @@ il3945_show_filter_flags(struct device *d, struct device_attribute *attr, char *buf) { struct il_priv *il = dev_get_drvdata(d); - struct il_rxon_context *ctx = &il->ctx; - return sprintf(buf, "0x%04X\n", le32_to_cpu(ctx->active.filter_flags)); + return sprintf(buf, "0x%04X\n", le32_to_cpu(il->active.filter_flags)); } static ssize_t @@ -3217,19 +3209,18 @@ il3945_store_filter_flags(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { struct il_priv *il = dev_get_drvdata(d); - struct il_rxon_context *ctx = &il->ctx; u32 filter_flags = simple_strtoul(buf, NULL, 0); mutex_lock(&il->mutex); - if (le32_to_cpu(ctx->staging.filter_flags) != filter_flags) { + if (le32_to_cpu(il->staging.filter_flags) != filter_flags) { /* Cancel any currently running scans... */ if (il_scan_cancel_timeout(il, 100)) IL_WARN("Could not cancel scan.\n"); else { D_INFO("Committing rxon.filter_flags = " "0x%04X\n", filter_flags); - ctx->staging.filter_flags = cpu_to_le32(filter_flags); - il3945_commit_rxon(il, ctx); + il->staging.filter_flags = cpu_to_le32(filter_flags); + il3945_commit_rxon(il, &il->ctx); } } mutex_unlock(&il->mutex); @@ -3278,9 +3269,8 @@ il3945_store_measurement(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { struct il_priv *il = dev_get_drvdata(d); - struct il_rxon_context *ctx = &il->ctx; struct ieee80211_measurement_params params = { - .channel = le16_to_cpu(ctx->active.channel), + .channel = le16_to_cpu(il->active.channel), .start_time = cpu_to_le64(il->_3945.last_tsf), .duration = cpu_to_le16(1), }; diff --git a/drivers/net/wireless/iwlegacy/3945-rs.c b/drivers/net/wireless/iwlegacy/3945-rs.c index d7a83f22919..40d17d7fcfe 100644 --- a/drivers/net/wireless/iwlegacy/3945-rs.c +++ b/drivers/net/wireless/iwlegacy/3945-rs.c @@ -944,7 +944,7 @@ il3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) switch (il->band) { case IEEE80211_BAND_2GHZ: /* TODO: this always does G, not a regression */ - if (il->ctx.active.flags & RXON_FLG_TGG_PROTECT_MSK) { + if (il->active.flags & RXON_FLG_TGG_PROTECT_MSK) { rs_sta->tgg = 1; rs_sta->expected_tpt = il3945_expected_tpt_g_prot; } else diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c index 1489b1573a6..dc0433f6801 100644 --- a/drivers/net/wireless/iwlegacy/3945.c +++ b/drivers/net/wireless/iwlegacy/3945.c @@ -1388,7 +1388,7 @@ il3945_send_tx_power(struct il_priv *il) int rate_idx, i; const struct il_channel_info *ch_info = NULL; struct il3945_txpowertable_cmd txpower = { - .channel = il->ctx.active.channel, + .channel = il->active.channel, }; u16 chan; @@ -1397,7 +1397,7 @@ il3945_send_tx_power(struct il_priv *il) "TX Power requested while scanning!\n")) return -EAGAIN; - chan = le16_to_cpu(il->ctx.active.channel); + chan = le16_to_cpu(il->active.channel); txpower.band = (il->band == IEEE80211_BAND_5GHZ) ? 0 : 1; ch_info = il_get_channel_info(il, il->band, chan); @@ -1673,8 +1673,8 @@ il3945_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx) .flags = CMD_WANT_SKB, .data = &rxon_assoc, }; - const struct il_rxon_cmd *rxon1 = &ctx->staging; - const struct il_rxon_cmd *rxon2 = &ctx->active; + const struct il_rxon_cmd *rxon1 = &il->staging; + const struct il_rxon_cmd *rxon2 = &il->active; if (rxon1->flags == rxon2->flags && rxon1->filter_flags == rxon2->filter_flags && @@ -1684,10 +1684,10 @@ il3945_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx) return 0; } - rxon_assoc.flags = ctx->staging.flags; - rxon_assoc.filter_flags = ctx->staging.filter_flags; - rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates; - rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates; + rxon_assoc.flags = il->staging.flags; + rxon_assoc.filter_flags = il->staging.filter_flags; + rxon_assoc.ofdm_basic_rates = il->staging.ofdm_basic_rates; + rxon_assoc.cck_basic_rates = il->staging.cck_basic_rates; rxon_assoc.reserved = 0; rc = il_send_cmd_sync(il, &cmd); @@ -1717,8 +1717,8 @@ int il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) { /* cast away the const for active_rxon in this function */ - struct il3945_rxon_cmd *active_rxon = (void *)&ctx->active; - struct il3945_rxon_cmd *staging_rxon = (void *)&ctx->staging; + struct il3945_rxon_cmd *active_rxon = (void *)&il->active; + struct il3945_rxon_cmd *staging_rxon = (void *)&il->staging; int rc = 0; bool new_assoc = !!(staging_rxon->filter_flags & RXON_FILTER_ASSOC_MSK); @@ -1776,7 +1776,7 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) active_rxon->reserved4 = 0; active_rxon->reserved5 = 0; rc = il_send_cmd_pdu(il, C_RXON, sizeof(struct il3945_rxon_cmd), - &il->ctx.active); + &il->active); /* If the mask clearing failed then we set * active_rxon back to what it was previously */ diff --git a/drivers/net/wireless/iwlegacy/4965-calib.c b/drivers/net/wireless/iwlegacy/4965-calib.c index d3248e3ef23..f302a6ac628 100644 --- a/drivers/net/wireless/iwlegacy/4965-calib.c +++ b/drivers/net/wireless/iwlegacy/4965-calib.c @@ -806,8 +806,6 @@ il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp) unsigned long flags; struct stats_rx_non_phy *rx_info; - struct il_rxon_context *ctx = &il->ctx; - if (il->disable_chain_noise_cal) return; @@ -833,8 +831,8 @@ il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp) return; } - rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK); - rxon_chnum = le16_to_cpu(ctx->staging.channel); + rxon_band24 = !!(il->staging.flags & RXON_FLG_BAND_24G_MSK); + rxon_chnum = le16_to_cpu(il->staging.channel); stat_band24 = !!(((struct il_notif_stats *)stat_resp)-> diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 1667232af64..6a77f41dd36 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -926,8 +926,7 @@ il4965_request_scan(struct il_priv *il, struct ieee80211_vif *vif) case IEEE80211_BAND_2GHZ: scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; chan_mod = - le32_to_cpu(il->ctx.active. - flags & RXON_FLG_CHANNEL_MODE_MSK) >> + le32_to_cpu(il->active.flags & RXON_FLG_CHANNEL_MODE_MSK) >> RXON_FLG_CHANNEL_MODE_POS; if (chan_mod == CHANNEL_MODE_PURE_40) { rate = RATE_6M_PLCP; @@ -1164,14 +1163,14 @@ il4965_set_rxon_chain(struct il_priv *il, struct il_rxon_context *ctx) rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS; rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS; - ctx->staging.rx_chain = cpu_to_le16(rx_chain); + il->staging.rx_chain = cpu_to_le16(rx_chain); if (!is_single && active_rx_cnt >= IL_NUM_RX_CHAINS_SINGLE && is_cam) - ctx->staging.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK; + il->staging.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK; else - ctx->staging.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK; + il->staging.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK; - D_ASSOC("rx_chain=0x%X active=%d idle=%d\n", ctx->staging.rx_chain, + D_ASSOC("rx_chain=0x%X active=%d idle=%d\n", il->staging.rx_chain, active_rx_cnt, idle_rx_cnt); WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 || @@ -3378,7 +3377,7 @@ il4965_update_chain_flags(struct il_priv *il) { if (il->cfg->ops->hcmd->set_rxon_chain) { il->cfg->ops->hcmd->set_rxon_chain(il, &il->ctx); - if (il->ctx.active.rx_chain != il->ctx.staging.rx_chain) + if (il->active.rx_chain != il->staging.rx_chain) il_commit_rxon(il, &il->ctx); } } @@ -5019,11 +5018,11 @@ il4965_alive_start(struct il_priv *il) il->active_rate = RATES_MASK; - if (il_is_associated_ctx(ctx)) { + if (il_is_associated(il)) { struct il_rxon_cmd *active_rxon = - (struct il_rxon_cmd *)&ctx->active; + (struct il_rxon_cmd *)&il->active; /* apply any changes in staging */ - ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; } else { /* Initialize our rx_config data */ @@ -5768,14 +5767,14 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw, test_bit(S_CHANNEL_SWITCH_PENDING, &il->status)) goto out; - if (!il_is_associated_ctx(ctx)) + if (!il_is_associated(il)) goto out; if (!il->cfg->ops->lib->set_channel_switch) goto out; ch = channel->hw_value; - if (le16_to_cpu(ctx->active.channel) == ch) + if (le16_to_cpu(il->active.channel) == ch) goto out; ch_info = il_get_channel_info(il, channel->band, ch); @@ -5807,8 +5806,8 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw, } else ctx->ht.is_40mhz = false; - if ((le16_to_cpu(ctx->staging.channel) != ch)) - ctx->staging.flags = 0; + if ((le16_to_cpu(il->staging.channel) != ch)) + il->staging.flags = 0; il_set_rxon_channel(il, channel, ctx); il_set_rxon_ht(il, ht_conf); @@ -5860,8 +5859,8 @@ il4965_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, mutex_lock(&il->mutex); - il->ctx.staging.filter_flags &= ~filter_nand; - il->ctx.staging.filter_flags |= filter_or; + il->staging.filter_flags &= ~filter_nand; + il->staging.filter_flags |= filter_or; /* * Not committing directly because hardware can perform a scan, diff --git a/drivers/net/wireless/iwlegacy/4965.c b/drivers/net/wireless/iwlegacy/4965.c index cacbc03880b..b34de143312 100644 --- a/drivers/net/wireless/iwlegacy/4965.c +++ b/drivers/net/wireless/iwlegacy/4965.c @@ -1342,7 +1342,6 @@ il4965_send_tx_power(struct il_priv *il) u8 band = 0; bool is_ht40 = false; u8 ctrl_chan_high = 0; - struct il_rxon_context *ctx = &il->ctx; if (WARN_ONCE (test_bit(S_SCAN_HW, &il->status), @@ -1351,16 +1350,16 @@ il4965_send_tx_power(struct il_priv *il) band = il->band == IEEE80211_BAND_2GHZ; - is_ht40 = iw4965_is_ht40_channel(ctx->active.flags); + is_ht40 = iw4965_is_ht40_channel(il->active.flags); - if (is_ht40 && (ctx->active.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) + if (is_ht40 && (il->active.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) ctrl_chan_high = 1; cmd.band = band; - cmd.channel = ctx->active.channel; + cmd.channel = il->active.channel; ret = - il4965_fill_txpower_tbl(il, band, le16_to_cpu(ctx->active.channel), + il4965_fill_txpower_tbl(il, band, le16_to_cpu(il->active.channel), is_ht40, ctrl_chan_high, &cmd.tx_power); if (ret) goto out; @@ -1376,8 +1375,8 @@ il4965_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx) { int ret = 0; struct il4965_rxon_assoc_cmd rxon_assoc; - const struct il_rxon_cmd *rxon1 = &ctx->staging; - const struct il_rxon_cmd *rxon2 = &ctx->active; + const struct il_rxon_cmd *rxon1 = &il->staging; + const struct il_rxon_cmd *rxon2 = &il->active; if (rxon1->flags == rxon2->flags && rxon1->filter_flags == rxon2->filter_flags && @@ -1392,16 +1391,16 @@ il4965_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx) return 0; } - rxon_assoc.flags = ctx->staging.flags; - rxon_assoc.filter_flags = ctx->staging.filter_flags; - rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates; - rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates; + rxon_assoc.flags = il->staging.flags; + rxon_assoc.filter_flags = il->staging.filter_flags; + rxon_assoc.ofdm_basic_rates = il->staging.ofdm_basic_rates; + rxon_assoc.cck_basic_rates = il->staging.cck_basic_rates; rxon_assoc.reserved = 0; rxon_assoc.ofdm_ht_single_stream_basic_rates = - ctx->staging.ofdm_ht_single_stream_basic_rates; + il->staging.ofdm_ht_single_stream_basic_rates; rxon_assoc.ofdm_ht_dual_stream_basic_rates = - ctx->staging.ofdm_ht_dual_stream_basic_rates; - rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain; + il->staging.ofdm_ht_dual_stream_basic_rates; + rxon_assoc.rx_chain_select_flags = il->staging.rx_chain; ret = il_send_cmd_pdu_async(il, C_RXON_ASSOC, sizeof(rxon_assoc), @@ -1414,9 +1413,9 @@ static int il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) { /* cast away the const for active_rxon in this function */ - struct il_rxon_cmd *active_rxon = (void *)&ctx->active; + struct il_rxon_cmd *active_rxon = (void *)&il->active; int ret; - bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); + bool new_assoc = !!(il->staging.filter_flags & RXON_FILTER_ASSOC_MSK); if (!il_is_alive(il)) return -EBUSY; @@ -1425,7 +1424,7 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) return 0; /* always get timestamp with Rx frame */ - ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; + il->staging.flags |= RXON_FLG_TSF2HOST_MSK; ret = il_check_rxon_cmd(il, ctx); if (ret) { @@ -1438,7 +1437,7 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) * abort any previous channel switch if still in process */ if (test_bit(S_CHANNEL_SWITCH_PENDING, &il->status) && - il->switch_channel != ctx->staging.channel) { + il->switch_channel != il->staging.channel) { D_11H("abort channel switch on %d\n", le16_to_cpu(il->switch_channel)); il_chswitch_done(il, false); @@ -1454,7 +1453,7 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) return ret; } - memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); + memcpy(active_rxon, &il->staging, sizeof(*active_rxon)); il_print_rx_config_cmd(il, ctx); /* * We do not commit tx power settings while channel changing, @@ -1468,7 +1467,7 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) * an RXON_ASSOC and the new config wants the associated mask enabled, * we must clear the associated from the active configuration * before we apply the new config */ - if (il_is_associated_ctx(ctx) && new_assoc) { + if (il_is_associated(il) && new_assoc) { D_INFO("Toggling associated bit on current RXON\n"); active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; @@ -1494,7 +1493,7 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) D_INFO("Sending RXON\n" "* with%s RXON_FILTER_ASSOC_MSK\n" "* channel = %d\n" "* bssid = %pM\n", (new_assoc ? "" : "out"), - le16_to_cpu(ctx->staging.channel), ctx->staging.bssid_addr); + le16_to_cpu(il->staging.channel), il->staging.bssid_addr); il_set_rxon_hwcrypto(il, ctx, !il->cfg->mod_params->sw_crypto); @@ -1505,13 +1504,13 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) if (!new_assoc) { ret = il_send_cmd_pdu(il, ctx->rxon_cmd, - sizeof(struct il_rxon_cmd), &ctx->staging); + sizeof(struct il_rxon_cmd), &il->staging); if (ret) { IL_ERR("Error setting new RXON (%d)\n", ret); return ret; } D_INFO("Return from !new_assoc RXON.\n"); - memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); + memcpy(active_rxon, &il->staging, sizeof(*active_rxon)); il_clear_ucode_stations(il, ctx); il_restore_stations(il, ctx); ret = il4965_restore_default_wep_keys(il, ctx); @@ -1527,12 +1526,12 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) */ ret = il_send_cmd_pdu(il, ctx->rxon_cmd, - sizeof(struct il_rxon_cmd), &ctx->staging); + sizeof(struct il_rxon_cmd), &il->staging); if (ret) { IL_ERR("Error setting new RXON (%d)\n", ret); return ret; } - memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); + memcpy(active_rxon, &il->staging, sizeof(*active_rxon)); } il_print_rx_config_cmd(il, ctx); @@ -1564,21 +1563,21 @@ il4965_hw_channel_switch(struct il_priv *il, u16 ch; u32 tsf_low; u8 switch_count; - u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); + u16 beacon_interval = le16_to_cpu(il->timing.beacon_interval); struct ieee80211_vif *vif = ctx->vif; band = il->band == IEEE80211_BAND_2GHZ; - is_ht40 = iw4965_is_ht40_channel(ctx->staging.flags); + is_ht40 = iw4965_is_ht40_channel(il->staging.flags); - if (is_ht40 && (ctx->staging.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) + if (is_ht40 && (il->staging.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) ctrl_chan_high = 1; cmd.band = band; cmd.expect_beacon = 0; ch = ch_switch->channel->hw_value; cmd.channel = cpu_to_le16(ch); - cmd.rxon_flags = ctx->staging.flags; - cmd.rxon_filter_flags = ctx->staging.filter_flags; + cmd.rxon_flags = il->staging.flags; + cmd.rxon_filter_flags = il->staging.filter_flags; switch_count = ch_switch->count; tsf_low = ch_switch->timestamp & 0x0ffffffff; /* @@ -1611,7 +1610,7 @@ il4965_hw_channel_switch(struct il_priv *il, cmd.expect_beacon = il_is_channel_radar(ch_info); else { IL_ERR("invalid channel switch from %u to %u\n", - ctx->active.channel, ch); + il->active.channel, ch); return -EFAULT; } @@ -2139,7 +2138,7 @@ il4965_post_scan(struct il_priv *il) * Since setting the RXON may have been deferred while * performing the scan, fire one off if needed */ - if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) + if (memcmp(&il->staging, &il->active, sizeof(il->staging))) il_commit_rxon(il, ctx); } @@ -2161,41 +2160,41 @@ il4965_post_associate(struct il_priv *il) conf = &il->hw->conf; - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; il_commit_rxon(il, ctx); ret = il_send_rxon_timing(il, ctx); if (ret) IL_WARN("RXON timing - " "Attempting to continue.\n"); - ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; il_set_rxon_ht(il, &il->current_ht_config); if (il->cfg->ops->hcmd->set_rxon_chain) il->cfg->ops->hcmd->set_rxon_chain(il, ctx); - ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid); + il->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid); D_ASSOC("assoc id %d beacon interval %d\n", vif->bss_conf.aid, vif->bss_conf.beacon_int); if (vif->bss_conf.use_short_preamble) - ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; else - ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; - if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { + if (il->staging.flags & RXON_FLG_BAND_24G_MSK) { if (vif->bss_conf.use_short_slot) - ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; + il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; else - ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; + il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; } il_commit_rxon(il, ctx); D_ASSOC("Associated as %d to: %pM\n", vif->bss_conf.aid, - ctx->active.bssid_addr); + il->active.bssid_addr); switch (vif->type) { case NL80211_IFTYPE_STATION: @@ -2233,10 +2232,10 @@ il4965_config_ap(struct il_priv *il) return; /* The following should be done only at AP bring up */ - if (!il_is_associated_ctx(ctx)) { + if (!il_is_associated(il)) { /* RXON - unassoc (to set timing command) */ - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; il_commit_rxon(il, ctx); /* RXON Timing */ @@ -2251,23 +2250,23 @@ il4965_config_ap(struct il_priv *il) if (il->cfg->ops->hcmd->set_rxon_chain) il->cfg->ops->hcmd->set_rxon_chain(il, ctx); - ctx->staging.assoc_id = 0; + il->staging.assoc_id = 0; if (vif->bss_conf.use_short_preamble) - ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; else - ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; - if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { + if (il->staging.flags & RXON_FLG_BAND_24G_MSK) { if (vif->bss_conf.use_short_slot) - ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; + il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; else - ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; + il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; } /* need to send beacon cmd before committing assoc RXON! */ il4965_send_beacon_cmd(il); /* restore RXON assoc */ - ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; il_commit_rxon(il, ctx); } il4965_send_beacon_cmd(il); diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index 36454d0bbee..2b5622695cc 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -2361,7 +2361,7 @@ il_is_lq_table_valid(struct il_priv *il, struct il_rxon_context *ctx, if (ctx->ht.enabled) return true; - D_INFO("Channel %u is not an HT channel\n", ctx->active.channel); + D_INFO("Channel %u is not an HT channel\n", il->active.channel); for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) { if (le32_to_cpu(lq->rs_table[i].rate_n_flags) & RATE_MCS_HT_MSK) { D_INFO("idx %d of LQ expects HT channel\n", i); @@ -2648,7 +2648,7 @@ il_set_decrypted_flag(struct il_priv *il, struct ieee80211_hdr *hdr, * All contexts have the same setting here due to it being * a module parameter, so OK to check any context. */ - if (il->ctx.active.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK) + if (il->active.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK) return 0; if (!(fc & IEEE80211_FCTL_PROTECTED)) @@ -3581,7 +3581,7 @@ il_is_ht40_tx_allowed(struct il_priv *il, struct il_rxon_context *ctx, #endif return il_is_channel_extension(il, il->band, - le16_to_cpu(ctx->staging.channel), + le16_to_cpu(il->staging.channel), ctx->ht.extension_chan_offset); } EXPORT_SYMBOL(il_is_ht40_tx_allowed); @@ -3633,10 +3633,10 @@ il_send_rxon_timing(struct il_priv *il, struct il_rxon_context *ctx) lockdep_assert_held(&il->mutex); - memset(&ctx->timing, 0, sizeof(struct il_rxon_time_cmd)); + memset(&il->timing, 0, sizeof(struct il_rxon_time_cmd)); - ctx->timing.timestamp = cpu_to_le64(il->timestamp); - ctx->timing.listen_interval = cpu_to_le16(conf->listen_interval); + il->timing.timestamp = cpu_to_le64(il->timestamp); + il->timing.listen_interval = cpu_to_le16(conf->listen_interval); beacon_int = vif ? vif->bss_conf.beacon_int : 0; @@ -3644,28 +3644,28 @@ il_send_rxon_timing(struct il_priv *il, struct il_rxon_context *ctx) * TODO: For IBSS we need to get atim_win from mac80211, * for now just always use 0 */ - ctx->timing.atim_win = 0; + il->timing.atim_win = 0; beacon_int = il_adjust_beacon_interval(beacon_int, il->hw_params.max_beacon_itrvl * TIME_UNIT); - ctx->timing.beacon_interval = cpu_to_le16(beacon_int); + il->timing.beacon_interval = cpu_to_le16(beacon_int); tsf = il->timestamp; /* tsf is modifed by do_div: copy it */ interval_tm = beacon_int * TIME_UNIT; rem = do_div(tsf, interval_tm); - ctx->timing.beacon_init_val = cpu_to_le32(interval_tm - rem); + il->timing.beacon_init_val = cpu_to_le32(interval_tm - rem); - ctx->timing.dtim_period = vif ? (vif->bss_conf.dtim_period ? : 1) : 1; + il->timing.dtim_period = vif ? (vif->bss_conf.dtim_period ? : 1) : 1; D_ASSOC("beacon interval %d beacon timer %d beacon tim %d\n", - le16_to_cpu(ctx->timing.beacon_interval), - le32_to_cpu(ctx->timing.beacon_init_val), - le16_to_cpu(ctx->timing.atim_win)); + le16_to_cpu(il->timing.beacon_interval), + le32_to_cpu(il->timing.beacon_init_val), + le16_to_cpu(il->timing.atim_win)); - return il_send_cmd_pdu(il, ctx->rxon_timing_cmd, sizeof(ctx->timing), - &ctx->timing); + return il_send_cmd_pdu(il, il->ctx.rxon_timing_cmd, sizeof(il->timing), + &il->timing); } EXPORT_SYMBOL(il_send_rxon_timing); @@ -3673,7 +3673,7 @@ void il_set_rxon_hwcrypto(struct il_priv *il, struct il_rxon_context *ctx, int hw_decrypt) { - struct il_rxon_cmd *rxon = &ctx->staging; + struct il_rxon_cmd *rxon = &il->staging; if (hw_decrypt) rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK; @@ -3687,7 +3687,7 @@ EXPORT_SYMBOL(il_set_rxon_hwcrypto); int il_check_rxon_cmd(struct il_priv *il, struct il_rxon_context *ctx) { - struct il_rxon_cmd *rxon = &ctx->staging; + struct il_rxon_cmd *rxon = &il->staging; bool error = false; if (rxon->flags & RXON_FLG_BAND_24G_MSK) { @@ -3767,8 +3767,8 @@ EXPORT_SYMBOL(il_check_rxon_cmd); int il_full_rxon_required(struct il_priv *il, struct il_rxon_context *ctx) { - const struct il_rxon_cmd *staging = &ctx->staging; - const struct il_rxon_cmd *active = &ctx->active; + const struct il_rxon_cmd *staging = &il->staging; + const struct il_rxon_cmd *active = &il->active; #define CHK(cond) \ if ((cond)) { \ @@ -3785,7 +3785,7 @@ il_full_rxon_required(struct il_priv *il, struct il_rxon_context *ctx) } /* These items are only settable from the full RXON command */ - CHK(!il_is_associated_ctx(ctx)); + CHK(!il_is_associated(il)); CHK(compare_ether_addr(staging->bssid_addr, active->bssid_addr)); CHK(compare_ether_addr(staging->node_addr, active->node_addr)); CHK(compare_ether_addr @@ -3825,7 +3825,7 @@ il_get_lowest_plcp(struct il_priv *il, struct il_rxon_context *ctx) * Assign the lowest rate -- should really get this from * the beacon skb from mac80211. */ - if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) + if (il->staging.flags & RXON_FLG_BAND_24G_MSK) return RATE_1M_PLCP; else return RATE_6M_PLCP; @@ -3836,7 +3836,7 @@ static void _il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf, struct il_rxon_context *ctx) { - struct il_rxon_cmd *rxon = &ctx->staging; + struct il_rxon_cmd *rxon = &il->staging; if (!ctx->ht.enabled) { rxon->flags &= @@ -3925,7 +3925,7 @@ il_get_single_channel_number(struct il_priv *il, enum ieee80211_band band) for (i = min; i < max; i++) { channel = il->channel_info[i].channel; - if (channel == le16_to_cpu(il->ctx.staging.channel)) + if (channel == le16_to_cpu(il->staging.channel)) continue; ch_info = il_get_channel_info(il, band, channel); @@ -3951,14 +3951,14 @@ il_set_rxon_channel(struct il_priv *il, struct ieee80211_channel *ch, enum ieee80211_band band = ch->band; u16 channel = ch->hw_value; - if (le16_to_cpu(ctx->staging.channel) == channel && il->band == band) + if (le16_to_cpu(il->staging.channel) == channel && il->band == band) return 0; - ctx->staging.channel = cpu_to_le16(channel); + il->staging.channel = cpu_to_le16(channel); if (band == IEEE80211_BAND_5GHZ) - ctx->staging.flags &= ~RXON_FLG_BAND_24G_MSK; + il->staging.flags &= ~RXON_FLG_BAND_24G_MSK; else - ctx->staging.flags |= RXON_FLG_BAND_24G_MSK; + il->staging.flags |= RXON_FLG_BAND_24G_MSK; il->band = band; @@ -3973,20 +3973,20 @@ il_set_flags_for_band(struct il_priv *il, struct il_rxon_context *ctx, enum ieee80211_band band, struct ieee80211_vif *vif) { if (band == IEEE80211_BAND_5GHZ) { - ctx->staging.flags &= + il->staging.flags &= ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_CCK_MSK); - ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; + il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; } else { /* Copied from il_post_associate() */ if (vif && vif->bss_conf.use_short_slot) - ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; + il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; else - ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; + il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; - ctx->staging.flags |= RXON_FLG_BAND_24G_MSK; - ctx->staging.flags |= RXON_FLG_AUTO_DETECT_MSK; - ctx->staging.flags &= ~RXON_FLG_CCK_MSK; + il->staging.flags |= RXON_FLG_BAND_24G_MSK; + il->staging.flags |= RXON_FLG_AUTO_DETECT_MSK; + il->staging.flags &= ~RXON_FLG_CCK_MSK; } } EXPORT_SYMBOL(il_set_flags_for_band); @@ -3999,22 +3999,22 @@ il_connection_init_rx_config(struct il_priv *il, struct il_rxon_context *ctx) { const struct il_channel_info *ch_info; - memset(&ctx->staging, 0, sizeof(ctx->staging)); + memset(&il->staging, 0, sizeof(il->staging)); if (!ctx->vif) { - ctx->staging.dev_type = ctx->unused_devtype; + il->staging.dev_type = ctx->unused_devtype; } else switch (ctx->vif->type) { case NL80211_IFTYPE_STATION: - ctx->staging.dev_type = ctx->station_devtype; - ctx->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; + il->staging.dev_type = ctx->station_devtype; + il->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; break; case NL80211_IFTYPE_ADHOC: - ctx->staging.dev_type = ctx->ibss_devtype; - ctx->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK; - ctx->staging.filter_flags = + il->staging.dev_type = ctx->ibss_devtype; + il->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK; + il->staging.filter_flags = RXON_FILTER_BCON_AWARE_MSK | RXON_FILTER_ACCEPT_GRP_MSK; break; @@ -4029,35 +4029,35 @@ il_connection_init_rx_config(struct il_priv *il, struct il_rxon_context *ctx) /* TODO: Figure out when short_preamble would be set and cache from * that */ if (!hw_to_local(il->hw)->short_preamble) - ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; else - ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; #endif ch_info = - il_get_channel_info(il, il->band, le16_to_cpu(ctx->active.channel)); + il_get_channel_info(il, il->band, le16_to_cpu(il->active.channel)); if (!ch_info) ch_info = &il->channel_info[0]; - ctx->staging.channel = cpu_to_le16(ch_info->channel); + il->staging.channel = cpu_to_le16(ch_info->channel); il->band = ch_info->band; il_set_flags_for_band(il, ctx, il->band, ctx->vif); - ctx->staging.ofdm_basic_rates = + il->staging.ofdm_basic_rates = (IL_OFDM_RATES_MASK >> IL_FIRST_OFDM_RATE) & 0xFF; - ctx->staging.cck_basic_rates = + il->staging.cck_basic_rates = (IL_CCK_RATES_MASK >> IL_FIRST_CCK_RATE) & 0xF; /* clear both MIX and PURE40 mode flag */ - ctx->staging.flags &= + il->staging.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED | RXON_FLG_CHANNEL_MODE_PURE_40); if (ctx->vif) - memcpy(ctx->staging.node_addr, ctx->vif->addr, ETH_ALEN); + memcpy(il->staging.node_addr, ctx->vif->addr, ETH_ALEN); - ctx->staging.ofdm_ht_single_stream_basic_rates = 0xff; - ctx->staging.ofdm_ht_dual_stream_basic_rates = 0xff; + il->staging.ofdm_ht_single_stream_basic_rates = 0xff; + il->staging.ofdm_ht_dual_stream_basic_rates = 0xff; } EXPORT_SYMBOL(il_connection_init_rx_config); @@ -4084,10 +4084,10 @@ il_set_rate(struct il_priv *il) D_RATE("Set active_rate = %0x\n", il->active_rate); - il->ctx.staging.cck_basic_rates = + il->staging.cck_basic_rates = (IL_CCK_BASIC_RATES_MASK >> IL_FIRST_CCK_RATE) & 0xF; - il->ctx.staging.ofdm_basic_rates = + il->staging.ofdm_basic_rates = (IL_OFDM_BASIC_RATES_MASK >> IL_FIRST_OFDM_RATE) & 0xFF; } EXPORT_SYMBOL(il_set_rate); @@ -4110,16 +4110,14 @@ il_hdl_csa(struct il_priv *il, struct il_rx_buf *rxb) { struct il_rx_pkt *pkt = rxb_addr(rxb); struct il_csa_notification *csa = &(pkt->u.csa_notif); - - struct il_rxon_context *ctx = &il->ctx; - struct il_rxon_cmd *rxon = (void *)&ctx->active; + struct il_rxon_cmd *rxon = (void *)&il->active; if (!test_bit(S_CHANNEL_SWITCH_PENDING, &il->status)) return; if (!le32_to_cpu(csa->status) && csa->channel == il->switch_channel) { rxon->channel = csa->channel; - ctx->staging.channel = csa->channel; + il->staging.channel = csa->channel; D_11H("CSA notif: channel %d\n", le16_to_cpu(csa->channel)); il_chswitch_done(il, true); } else { @@ -4134,7 +4132,7 @@ EXPORT_SYMBOL(il_hdl_csa); void il_print_rx_config_cmd(struct il_priv *il, struct il_rxon_context *ctx) { - struct il_rxon_cmd *rxon = &ctx->staging; + struct il_rxon_cmd *rxon = &il->staging; D_RADIO("RX CONFIG:\n"); il_print_hex_dump(il, IL_DL_RADIO, (u8 *) rxon, sizeof(*rxon)); @@ -4347,7 +4345,6 @@ il_set_tx_power(struct il_priv *il, s8 tx_power, bool force) int ret; s8 prev_tx_power; bool defer; - struct il_rxon_context *ctx = &il->ctx; lockdep_assert_held(&il->mutex); @@ -4378,7 +4375,7 @@ il_set_tx_power(struct il_priv *il, s8 tx_power, bool force) /* do not set tx power when scanning or channel changing */ defer = test_bit(S_SCANNING, &il->status) || - memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)); + memcmp(&il->active, &il->staging, sizeof(il->staging)); if (defer && !force) { D_INFO("Deferring tx power set\n"); return 0; @@ -5379,8 +5376,8 @@ il_mac_config(struct ieee80211_hw *hw, u32 changed) /* if we are switching from ht to 2.4 clear flags * from any ht related info since 2.4 does not * support ht */ - if ((le16_to_cpu(ctx->staging.channel) != ch)) - ctx->staging.flags = 0; + if ((le16_to_cpu(il->staging.channel) != ch)) + il->staging.flags = 0; il_set_rxon_channel(il, channel, ctx); il_set_rxon_ht(il, ht_conf); @@ -5420,7 +5417,7 @@ set_ch_out: if (scan_active) goto out; - if (memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging))) + if (memcmp(&il->active, &il->staging, sizeof(il->staging))) il_commit_rxon(il, ctx); else D_INFO("Not re-sending same RXON configuration.\n"); @@ -5473,7 +5470,7 @@ il_mac_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) /* we are restarting association process * clear RXON_FILTER_ASSOC_MSK bit */ - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; il_commit_rxon(il, ctx); il_set_rate(il); @@ -5555,8 +5552,8 @@ il_set_no_assoc(struct il_priv *il, struct ieee80211_vif *vif) * association and that no more packets should be * sent */ - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - ctx->staging.assoc_id = 0; + il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + il->staging.assoc_id = 0; il_commit_rxon(il, ctx); } @@ -5660,13 +5657,13 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, /* mac80211 only sets assoc when in STATION mode */ if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) { - memcpy(ctx->staging.bssid_addr, bss_conf->bssid, + memcpy(il->staging.bssid_addr, bss_conf->bssid, ETH_ALEN); /* currently needed in a few places */ memcpy(il->bssid, bss_conf->bssid, ETH_ALEN); } else { - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; } } @@ -5682,21 +5679,21 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (changes & BSS_CHANGED_ERP_PREAMBLE) { D_MAC80211("ERP_PREAMBLE %d\n", bss_conf->use_short_preamble); if (bss_conf->use_short_preamble) - ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; else - ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; } if (changes & BSS_CHANGED_ERP_CTS_PROT) { D_MAC80211("ERP_CTS %d\n", bss_conf->use_cts_prot); if (bss_conf->use_cts_prot && il->band != IEEE80211_BAND_5GHZ) - ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK; + il->staging.flags |= RXON_FLG_TGG_PROTECT_MSK; else - ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK; + il->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK; if (bss_conf->use_cts_prot) - ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; + il->staging.flags |= RXON_FLG_SELF_CTS_EN; else - ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN; + il->staging.flags &= ~RXON_FLG_SELF_CTS_EN; } if (changes & BSS_CHANGED_BASIC_RATES) { @@ -5706,12 +5703,12 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, * like this here: * if (A-band) - ctx->staging.ofdm_basic_rates = + il->staging.ofdm_basic_rates = bss_conf->basic_rates; else - ctx->staging.ofdm_basic_rates = + il->staging.ofdm_basic_rates = bss_conf->basic_rates >> 4; - ctx->staging.cck_basic_rates = + il->staging.cck_basic_rates = bss_conf->basic_rates & 0xF; */ } @@ -5734,19 +5731,19 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, il_set_no_assoc(il, vif); } - if (changes && il_is_associated_ctx(ctx) && bss_conf->aid) { + if (changes && il_is_associated(il) && bss_conf->aid) { D_MAC80211("Changes (%#x) while associated\n", changes); ret = il_send_rxon_assoc(il, ctx); if (!ret) { /* Sync active_rxon with latest change. */ - memcpy((void *)&ctx->active, &ctx->staging, + memcpy((void *)&il->active, &il->staging, sizeof(struct il_rxon_cmd)); } } if (changes & BSS_CHANGED_BEACON_ENABLED) { if (vif->bss_conf.enable_beacon) { - memcpy(ctx->staging.bssid_addr, bss_conf->bssid, + memcpy(il->staging.bssid_addr, bss_conf->bssid, ETH_ALEN); memcpy(il->bssid, bss_conf->bssid, ETH_ALEN); il->cfg->ops->legacy->config_ap(il); diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index abfa388588b..ba801c7d9ad 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -1171,17 +1171,6 @@ struct il_rxon_context { u32 interface_modes, exclusive_interface_modes; u8 unused_devtype, ap_devtype, ibss_devtype, station_devtype; - /* - * We declare this const so it can only be - * changed via explicit cast within the - * routines that actually update the physical - * hardware. - */ - const struct il_rxon_cmd active; - struct il_rxon_cmd staging; - - struct il_rxon_time_cmd timing; - struct il_qos_info qos_data; u8 bcast_sta_id, ap_sta_id; @@ -1306,6 +1295,17 @@ struct il_priv { struct il_rxon_context ctx; + /* + * We declare this const so it can only be + * changed via explicit cast within the + * routines that actually update the physical + * hardware. + */ + const struct il_rxon_cmd active; + struct il_rxon_cmd staging; + + struct il_rxon_time_cmd timing; + __le16 switch_channel; /* 1st responses from initialize and runtime uCode images. @@ -1530,7 +1530,7 @@ il_rxon_ctx_from_vif(struct ieee80211_vif *vif) static inline int il_is_associated(struct il_priv *il) { - return (il->ctx.active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0; + return (il->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0; } static inline int @@ -1539,12 +1539,6 @@ il_is_any_associated(struct il_priv *il) return il_is_associated(il); } -static inline int -il_is_associated_ctx(struct il_rxon_context *ctx) -{ - return (ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0; -} - static inline int il_is_channel_valid(const struct il_channel_info *ch_info) { diff --git a/drivers/net/wireless/iwlegacy/debug.c b/drivers/net/wireless/iwlegacy/debug.c index b1b8926a9c7..6e3841beb1d 100644 --- a/drivers/net/wireless/iwlegacy/debug.c +++ b/drivers/net/wireless/iwlegacy/debug.c @@ -1153,7 +1153,7 @@ il_dbgfs_rxon_flags_read(struct file *file, char __user *user_buf, int len = 0; char buf[20]; - len = sprintf(buf, "0x%04X\n", le32_to_cpu(il->ctx.active.flags)); + len = sprintf(buf, "0x%04X\n", le32_to_cpu(il->active.flags)); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -1167,7 +1167,7 @@ il_dbgfs_rxon_filter_flags_read(struct file *file, char __user *user_buf, char buf[20]; len = - sprintf(buf, "0x%04X\n", le32_to_cpu(il->ctx.active.filter_flags)); + sprintf(buf, "0x%04X\n", le32_to_cpu(il->active.filter_flags)); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } -- cgit v1.2.3-70-g09d2 From 6122d18236837ed7f264632e6b27d5cb3005add2 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 3 Feb 2012 17:31:38 +0100 Subject: iwlegacy: get rid of ctx->rxon_cmd Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/3945-mac.c | 1 - drivers/net/wireless/iwlegacy/4965-mac.c | 1 - drivers/net/wireless/iwlegacy/4965.c | 6 +++--- drivers/net/wireless/iwlegacy/common.h | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c index 980566fdb81..8de8355c523 100644 --- a/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/iwlegacy/3945-mac.c @@ -3619,7 +3619,6 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) il->ctx.ctxid = 0; - il->ctx.rxon_cmd = C_RXON; il->ctx.rxon_timing_cmd = C_RXON_TIMING; il->ctx.rxon_assoc_cmd = C_RXON_ASSOC; il->ctx.qos_cmd = C_QOS_PARAM; diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 6a77f41dd36..2368f3ab02b 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -6135,7 +6135,6 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) il->ctx.always_active = true; il->ctx.is_active = true; - il->ctx.rxon_cmd = C_RXON; il->ctx.rxon_timing_cmd = C_RXON_TIMING; il->ctx.rxon_assoc_cmd = C_RXON_ASSOC; il->ctx.qos_cmd = C_QOS_PARAM; diff --git a/drivers/net/wireless/iwlegacy/4965.c b/drivers/net/wireless/iwlegacy/4965.c index b34de143312..8926108118f 100644 --- a/drivers/net/wireless/iwlegacy/4965.c +++ b/drivers/net/wireless/iwlegacy/4965.c @@ -1472,7 +1472,7 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; ret = - il_send_cmd_pdu(il, ctx->rxon_cmd, + il_send_cmd_pdu(il, C_RXON, sizeof(struct il_rxon_cmd), active_rxon); /* If the mask clearing failed then we set @@ -1503,7 +1503,7 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) */ if (!new_assoc) { ret = - il_send_cmd_pdu(il, ctx->rxon_cmd, + il_send_cmd_pdu(il, C_RXON, sizeof(struct il_rxon_cmd), &il->staging); if (ret) { IL_ERR("Error setting new RXON (%d)\n", ret); @@ -1525,7 +1525,7 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) * RXON assoc doesn't clear the station table in uCode, */ ret = - il_send_cmd_pdu(il, ctx->rxon_cmd, + il_send_cmd_pdu(il, C_RXON, sizeof(struct il_rxon_cmd), &il->staging); if (ret) { IL_ERR("Error setting new RXON (%d)\n", ret); diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index ba801c7d9ad..80c60e57de3 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -1175,7 +1175,7 @@ struct il_rxon_context { u8 bcast_sta_id, ap_sta_id; - u8 rxon_cmd, rxon_assoc_cmd, rxon_timing_cmd; + u8 rxon_assoc_cmd, rxon_timing_cmd; u8 qos_cmd; u8 wep_key_cmd; -- cgit v1.2.3-70-g09d2 From 63d0f0c5512e29f87ed2e1612bb637d857f3b345 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 3 Feb 2012 17:31:39 +0100 Subject: iwlegacy: get rid of ctx->rxon_timing_cmd Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/3945-mac.c | 1 - drivers/net/wireless/iwlegacy/4965-mac.c | 1 - drivers/net/wireless/iwlegacy/common.c | 2 +- drivers/net/wireless/iwlegacy/common.h | 2 +- 4 files changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c index 8de8355c523..5ca8a784436 100644 --- a/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/iwlegacy/3945-mac.c @@ -3619,7 +3619,6 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) il->ctx.ctxid = 0; - il->ctx.rxon_timing_cmd = C_RXON_TIMING; il->ctx.rxon_assoc_cmd = C_RXON_ASSOC; il->ctx.qos_cmd = C_QOS_PARAM; il->ctx.ap_sta_id = IL_AP_ID; diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 2368f3ab02b..9539acc132a 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -6135,7 +6135,6 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) il->ctx.always_active = true; il->ctx.is_active = true; - il->ctx.rxon_timing_cmd = C_RXON_TIMING; il->ctx.rxon_assoc_cmd = C_RXON_ASSOC; il->ctx.qos_cmd = C_QOS_PARAM; il->ctx.ap_sta_id = IL_AP_ID; diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index 2b5622695cc..902521469e1 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -3664,7 +3664,7 @@ il_send_rxon_timing(struct il_priv *il, struct il_rxon_context *ctx) le32_to_cpu(il->timing.beacon_init_val), le16_to_cpu(il->timing.atim_win)); - return il_send_cmd_pdu(il, il->ctx.rxon_timing_cmd, sizeof(il->timing), + return il_send_cmd_pdu(il, C_RXON_TIMING, sizeof(il->timing), &il->timing); } EXPORT_SYMBOL(il_send_rxon_timing); diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index 80c60e57de3..d1d505580b1 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -1175,7 +1175,7 @@ struct il_rxon_context { u8 bcast_sta_id, ap_sta_id; - u8 rxon_assoc_cmd, rxon_timing_cmd; + u8 rxon_assoc_cmd; u8 qos_cmd; u8 wep_key_cmd; -- cgit v1.2.3-70-g09d2 From 5e349f02963acc2c3607119e6e64f0cbc8d23e17 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 3 Feb 2012 17:31:40 +0100 Subject: iwlegacy: get rid of rxon_assoc_cmd Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/3945-mac.c | 1 - drivers/net/wireless/iwlegacy/4965-mac.c | 1 - drivers/net/wireless/iwlegacy/common.h | 1 - 3 files changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c index 5ca8a784436..e5857df2df2 100644 --- a/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/iwlegacy/3945-mac.c @@ -3619,7 +3619,6 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) il->ctx.ctxid = 0; - il->ctx.rxon_assoc_cmd = C_RXON_ASSOC; il->ctx.qos_cmd = C_QOS_PARAM; il->ctx.ap_sta_id = IL_AP_ID; il->ctx.wep_key_cmd = C_WEPKEY; diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 9539acc132a..bd83299be31 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -6135,7 +6135,6 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) il->ctx.always_active = true; il->ctx.is_active = true; - il->ctx.rxon_assoc_cmd = C_RXON_ASSOC; il->ctx.qos_cmd = C_QOS_PARAM; il->ctx.ap_sta_id = IL_AP_ID; il->ctx.wep_key_cmd = C_WEPKEY; diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index d1d505580b1..d8e309a1756 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -1175,7 +1175,6 @@ struct il_rxon_context { u8 bcast_sta_id, ap_sta_id; - u8 rxon_assoc_cmd; u8 qos_cmd; u8 wep_key_cmd; -- cgit v1.2.3-70-g09d2 From b96ed60cd0c352891fd04f4aa748f4d36a6cec5b Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 3 Feb 2012 17:31:41 +0100 Subject: iwlegacy: get rid of qos_cmd Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/3945-mac.c | 1 - drivers/net/wireless/iwlegacy/4965-mac.c | 1 - drivers/net/wireless/iwlegacy/common.c | 2 +- drivers/net/wireless/iwlegacy/common.h | 1 - 4 files changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c index e5857df2df2..bbbac26d8f4 100644 --- a/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/iwlegacy/3945-mac.c @@ -3619,7 +3619,6 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) il->ctx.ctxid = 0; - il->ctx.qos_cmd = C_QOS_PARAM; il->ctx.ap_sta_id = IL_AP_ID; il->ctx.wep_key_cmd = C_WEPKEY; il->ctx.interface_modes = diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index bd83299be31..2ee5de38bb3 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -6135,7 +6135,6 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) il->ctx.always_active = true; il->ctx.is_active = true; - il->ctx.qos_cmd = C_QOS_PARAM; il->ctx.ap_sta_id = IL_AP_ID; il->ctx.wep_key_cmd = C_WEPKEY; il->ctx.ac_to_fifo = il4965_bss_ac_to_fifo; diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index 902521469e1..b95f832b14e 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -5269,7 +5269,7 @@ il_update_qos(struct il_priv *il, struct il_rxon_context *ctx) D_QOS("send QoS cmd with Qos active=%d FLAGS=0x%X\n", ctx->qos_data.qos_active, ctx->qos_data.def_qos_parm.qos_flags); - il_send_cmd_pdu_async(il, ctx->qos_cmd, sizeof(struct il_qosparam_cmd), + il_send_cmd_pdu_async(il, C_QOS_PARAM, sizeof(struct il_qosparam_cmd), &ctx->qos_data.def_qos_parm, NULL); } diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index d8e309a1756..b08ddd13443 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -1175,7 +1175,6 @@ struct il_rxon_context { u8 bcast_sta_id, ap_sta_id; - u8 qos_cmd; u8 wep_key_cmd; struct il_wep_key wep_keys[WEP_KEYS_MAX]; -- cgit v1.2.3-70-g09d2 From d98e294231a29699848fd0e923d91fe979e13802 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 3 Feb 2012 17:31:42 +0100 Subject: iwlegacy: get rid of wep_key_cmd Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/3945-mac.c | 1 - drivers/net/wireless/iwlegacy/4965-mac.c | 3 +-- drivers/net/wireless/iwlegacy/common.h | 2 -- 3 files changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c index bbbac26d8f4..4a01acbf3a2 100644 --- a/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/iwlegacy/3945-mac.c @@ -3620,7 +3620,6 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) il->ctx.ctxid = 0; il->ctx.ap_sta_id = IL_AP_ID; - il->ctx.wep_key_cmd = C_WEPKEY; il->ctx.interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); il->ctx.ibss_devtype = RXON_DEV_TYPE_IBSS; diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 2ee5de38bb3..a2955a45c33 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -2823,7 +2823,7 @@ il4965_static_wepkey_cmd(struct il_priv *il, struct il_rxon_context *ctx, struct il_wep_cmd *wep_cmd = (struct il_wep_cmd *)buff; size_t cmd_size = sizeof(struct il_wep_cmd); struct il_host_cmd cmd = { - .id = ctx->wep_key_cmd, + .id = C_WEPKEY, .data = wep_cmd, .flags = CMD_SYNC, }; @@ -6136,7 +6136,6 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) il->ctx.always_active = true; il->ctx.is_active = true; il->ctx.ap_sta_id = IL_AP_ID; - il->ctx.wep_key_cmd = C_WEPKEY; il->ctx.ac_to_fifo = il4965_bss_ac_to_fifo; il->ctx.ac_to_queue = il4965_bss_ac_to_queue; il->ctx.exclusive_interface_modes = BIT(NL80211_IFTYPE_ADHOC); diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index b08ddd13443..46835f932bf 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -1175,8 +1175,6 @@ struct il_rxon_context { u8 bcast_sta_id, ap_sta_id; - u8 wep_key_cmd; - struct il_wep_key wep_keys[WEP_KEYS_MAX]; u8 key_mapping_keys; -- cgit v1.2.3-70-g09d2 From 8f9e56455310a3d75e8239db9729acb2b31dbdad Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 3 Feb 2012 17:31:43 +0100 Subject: iwlegacy: get rid of ap_sta_id Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/3945-mac.c | 1 - drivers/net/wireless/iwlegacy/4965-mac.c | 3 +-- drivers/net/wireless/iwlegacy/common.c | 2 +- drivers/net/wireless/iwlegacy/common.h | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c index 4a01acbf3a2..8072ae8b0ce 100644 --- a/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/iwlegacy/3945-mac.c @@ -3619,7 +3619,6 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) il->ctx.ctxid = 0; - il->ctx.ap_sta_id = IL_AP_ID; il->ctx.interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); il->ctx.ibss_devtype = RXON_DEV_TYPE_IBSS; diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index a2955a45c33..f2b03cd243b 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -2906,7 +2906,7 @@ il4965_set_default_wep_key(struct il_priv *il, struct il_rxon_context *ctx, keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; keyconf->hw_key_idx = HW_KEY_DEFAULT; - il->stations[ctx->ap_sta_id].keyinfo.cipher = keyconf->cipher; + il->stations[IL_AP_ID].keyinfo.cipher = keyconf->cipher; ctx->wep_keys[keyconf->keyidx].key_size = keyconf->keylen; memcpy(&ctx->wep_keys[keyconf->keyidx].key, &keyconf->key, @@ -6135,7 +6135,6 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) il->ctx.always_active = true; il->ctx.is_active = true; - il->ctx.ap_sta_id = IL_AP_ID; il->ctx.ac_to_fifo = il4965_bss_ac_to_fifo; il->ctx.ac_to_queue = il4965_bss_ac_to_queue; il->ctx.exclusive_interface_modes = BIT(NL80211_IFTYPE_ADHOC); diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index b95f832b14e..d30a2062992 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -1899,7 +1899,7 @@ il_prep_station(struct il_priv *il, struct il_rxon_context *ctx, u16 rate; if (is_ap) - sta_id = ctx->ap_sta_id; + sta_id = IL_AP_ID; else if (is_broadcast_ether_addr(addr)) sta_id = ctx->bcast_sta_id; else diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index 46835f932bf..cf7352f45cd 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -1173,7 +1173,7 @@ struct il_rxon_context { struct il_qos_info qos_data; - u8 bcast_sta_id, ap_sta_id; + u8 bcast_sta_id; struct il_wep_key wep_keys[WEP_KEYS_MAX]; u8 key_mapping_keys; -- cgit v1.2.3-70-g09d2 From b16db50a6dc486c3a6c32cd7982a75452cb785c2 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 3 Feb 2012 17:31:44 +0100 Subject: iwlegacy: move bcast_sta_id to hw_params Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/3945-mac.c | 4 ++-- drivers/net/wireless/iwlegacy/3945-rs.c | 2 +- drivers/net/wireless/iwlegacy/3945.c | 5 +++-- drivers/net/wireless/iwlegacy/4965-mac.c | 15 ++++++++------- drivers/net/wireless/iwlegacy/4965.c | 3 +-- drivers/net/wireless/iwlegacy/common.c | 2 +- drivers/net/wireless/iwlegacy/common.h | 6 +++--- 7 files changed, 19 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c index 8072ae8b0ce..b11701f5874 100644 --- a/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/iwlegacy/3945-mac.c @@ -140,7 +140,7 @@ il3945_set_ccmp_dynamic_key_info(struct il_priv *il, key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK); key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); - if (sta_id == il->ctx.bcast_sta_id) + if (sta_id == il->hw_params.bcast_id) key_flags |= STA_KEY_MULTICAST_MSK; keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; @@ -2598,7 +2598,7 @@ il3945_request_scan(struct il_priv *il, struct ieee80211_vif *vif) /* We don't build a direct scan probe request; the uCode will do * that based on the direct_mask added to each channel entry */ scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; - scan->tx_cmd.sta_id = il->ctx.bcast_sta_id; + scan->tx_cmd.sta_id = il->hw_params.bcast_id; scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; /* flags + rate selection */ diff --git a/drivers/net/wireless/iwlegacy/3945-rs.c b/drivers/net/wireless/iwlegacy/3945-rs.c index 40d17d7fcfe..6a782b5c0c5 100644 --- a/drivers/net/wireless/iwlegacy/3945-rs.c +++ b/drivers/net/wireless/iwlegacy/3945-rs.c @@ -342,7 +342,7 @@ il3945_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, u8 sta_id) int i; D_INFO("enter\n"); - if (sta_id == il->ctx.bcast_sta_id) + if (sta_id == il->hw_params.bcast_id) goto out; psta = (struct il3945_sta_priv *)sta->drv_priv; diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c index dc0433f6801..3024645a6be 100644 --- a/drivers/net/wireless/iwlegacy/3945.c +++ b/drivers/net/wireless/iwlegacy/3945.c @@ -2396,6 +2396,8 @@ il3945_hw_set_hw_params(struct il_priv *il) return -ENOMEM; } + il->hw_params.bcast_id = IL3945_BROADCAST_ID; + /* Assign number of Usable TX queues */ il->hw_params.max_txq_num = il->cfg->base_params->num_of_queues; @@ -2404,7 +2406,6 @@ il3945_hw_set_hw_params(struct il_priv *il) il->hw_params.max_rxq_size = RX_QUEUE_SIZE; il->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; il->hw_params.max_stations = IL3945_STATION_COUNT; - il->ctx.bcast_sta_id = IL3945_BROADCAST_ID; il->sta_key_max_num = STA_KEY_MAX_NUM; @@ -2425,7 +2426,7 @@ il3945_hw_get_beacon_cmd(struct il_priv *il, struct il3945_frame *frame, tx_beacon_cmd = (struct il3945_tx_beacon_cmd *)&frame->u; memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd)); - tx_beacon_cmd->tx.sta_id = il->ctx.bcast_sta_id; + tx_beacon_cmd->tx.sta_id = il->hw_params.bcast_id; tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; frame_size = diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index f2b03cd243b..af7886243fe 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -919,7 +919,7 @@ il4965_request_scan(struct il_priv *il, struct ieee80211_vif *vif) D_SCAN("Start passive scan.\n"); scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; - scan->tx_cmd.sta_id = ctx->bcast_sta_id; + scan->tx_cmd.sta_id = il->hw_params.bcast_id; scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; switch (il->scan_band) { @@ -1678,7 +1678,7 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb) /* For management frames use broadcast id to do not break aggregation */ if (!ieee80211_is_data(fc)) - sta_id = ctx->bcast_sta_id; + sta_id = il->hw_params.bcast_id; else { /* Find idx into station table for destination station */ sta_id = il_sta_id_or_broadcast(il, ctx, info->control.sta); @@ -2938,7 +2938,7 @@ il4965_set_wep_dynamic_key_info(struct il_priv *il, struct il_rxon_context *ctx, if (keyconf->keylen == WEP_KEY_LEN_128) key_flags |= STA_KEY_FLG_KEY_SIZE_MSK; - if (sta_id == ctx->bcast_sta_id) + if (sta_id == il->hw_params.bcast_id) key_flags |= STA_KEY_MULTICAST_MSK; spin_lock_irqsave(&il->sta_lock, flags); @@ -2988,7 +2988,7 @@ il4965_set_ccmp_dynamic_key_info(struct il_priv *il, key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); key_flags &= ~STA_KEY_FLG_INVALID; - if (sta_id == ctx->bcast_sta_id) + if (sta_id == il->hw_params.bcast_id) key_flags |= STA_KEY_MULTICAST_MSK; keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; @@ -3035,7 +3035,7 @@ il4965_set_tkip_dynamic_key_info(struct il_priv *il, key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); key_flags &= ~STA_KEY_FLG_INVALID; - if (sta_id == ctx->bcast_sta_id) + if (sta_id == il->hw_params.bcast_id) key_flags |= STA_KEY_MULTICAST_MSK; keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; @@ -3253,7 +3253,7 @@ il4965_update_bcast_station(struct il_priv *il, struct il_rxon_context *ctx) { unsigned long flags; struct il_link_quality_cmd *link_cmd; - u8 sta_id = ctx->bcast_sta_id; + u8 sta_id = il->hw_params.bcast_id; link_cmd = il4965_sta_alloc_lq(il, sta_id); if (!link_cmd) { @@ -3510,7 +3510,7 @@ il4965_hw_get_beacon_cmd(struct il_priv *il, struct il_frame *frame) /* Set up TX command fields */ tx_beacon_cmd->tx.len = cpu_to_le16((u16) frame_size); - tx_beacon_cmd->tx.sta_id = il->beacon_ctx->bcast_sta_id; + tx_beacon_cmd->tx.sta_id = il->hw_params.bcast_id; tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK | TX_CMD_FLG_TSF_MSK | @@ -6082,6 +6082,7 @@ il4965_hw_detect(struct il_priv *il) static int il4965_set_hw_params(struct il_priv *il) { + il->hw_params.bcast_id = IL4965_BROADCAST_ID; il->hw_params.max_rxq_size = RX_QUEUE_SIZE; il->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; if (il->cfg->mod_params->amsdu_size_8K) diff --git a/drivers/net/wireless/iwlegacy/4965.c b/drivers/net/wireless/iwlegacy/4965.c index 8926108118f..8d0fd60bc49 100644 --- a/drivers/net/wireless/iwlegacy/4965.c +++ b/drivers/net/wireless/iwlegacy/4965.c @@ -624,7 +624,6 @@ il4965_hw_set_hw_params(struct il_priv *il) sizeof(struct il4965_scd_bc_tbl); il->hw_params.tfd_size = sizeof(struct il_tfd); il->hw_params.max_stations = IL4965_STATION_COUNT; - il->ctx.bcast_sta_id = IL4965_BROADCAST_ID; il->hw_params.max_data_size = IL49_RTC_DATA_SIZE; il->hw_params.max_inst_size = IL49_RTC_INST_SIZE; il->hw_params.max_bsm_size = BSM_SRAM_SIZE; @@ -1968,7 +1967,7 @@ il4965_find_station(struct il_priv *il, const u8 * addr) start = IL_STA_ID; if (is_broadcast_ether_addr(addr)) - return il->ctx.bcast_sta_id; + return il->hw_params.bcast_id; spin_lock_irqsave(&il->sta_lock, flags); for (i = start; i < il->hw_params.max_stations; i++) diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index d30a2062992..b7567a8063b 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -1901,7 +1901,7 @@ il_prep_station(struct il_priv *il, struct il_rxon_context *ctx, if (is_ap) sta_id = IL_AP_ID; else if (is_broadcast_ether_addr(addr)) - sta_id = ctx->bcast_sta_id; + sta_id = il->hw_params.bcast_id; else for (i = IL_STA_ID; i < il->hw_params.max_stations; i++) { if (!compare_ether_addr diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index cf7352f45cd..66d0c1dd589 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -816,6 +816,7 @@ struct il_sensitivity_ranges { /** * struct il_hw_params + * @bcast_id: f/w broadcast station ID * @max_txq_num: Max # Tx queues supported * @dma_chnl_num: Number of Tx DMA/FIFO channels * @scd_bc_tbls_size: size of scheduler byte count tables @@ -836,6 +837,7 @@ struct il_sensitivity_ranges { * @struct il_sensitivity_ranges: range of sensitivity values */ struct il_hw_params { + u8 bcast_id; u8 max_txq_num; u8 dma_chnl_num; u16 scd_bc_tbls_size; @@ -1173,8 +1175,6 @@ struct il_rxon_context { struct il_qos_info qos_data; - u8 bcast_sta_id; - struct il_wep_key wep_keys[WEP_KEYS_MAX]; u8 key_mapping_keys; @@ -2372,7 +2372,7 @@ il_sta_id_or_broadcast(struct il_priv *il, struct il_rxon_context *context, int sta_id; if (!sta) - return context->bcast_sta_id; + return il->hw_params.bcast_id; sta_id = il_sta_id(sta); -- cgit v1.2.3-70-g09d2 From 0f8b90f526f097a5c897f52b3595e9af55fc9b59 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 3 Feb 2012 17:31:45 +0100 Subject: iwlegacy: get rid of *_devtype Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/3945-mac.c | 3 --- drivers/net/wireless/iwlegacy/4965-mac.c | 4 ---- drivers/net/wireless/iwlegacy/common.c | 6 +++--- drivers/net/wireless/iwlegacy/common.h | 1 - 4 files changed, 3 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c index b11701f5874..15dcafbf29d 100644 --- a/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/iwlegacy/3945-mac.c @@ -3621,9 +3621,6 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) il->ctx.interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); - il->ctx.ibss_devtype = RXON_DEV_TYPE_IBSS; - il->ctx.station_devtype = RXON_DEV_TYPE_ESS; - il->ctx.unused_devtype = RXON_DEV_TYPE_ESS; /* * Disabling hardware scan means that mac80211 will perform scans diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index af7886243fe..33725e14e14 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -6140,10 +6140,6 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) il->ctx.ac_to_queue = il4965_bss_ac_to_queue; il->ctx.exclusive_interface_modes = BIT(NL80211_IFTYPE_ADHOC); il->ctx.interface_modes = BIT(NL80211_IFTYPE_STATION); - il->ctx.ap_devtype = RXON_DEV_TYPE_AP; - il->ctx.ibss_devtype = RXON_DEV_TYPE_IBSS; - il->ctx.station_devtype = RXON_DEV_TYPE_ESS; - il->ctx.unused_devtype = RXON_DEV_TYPE_ESS; SET_IEEE80211_DEV(hw, &pdev->dev); diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index b7567a8063b..19ed86771a2 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -4002,17 +4002,17 @@ il_connection_init_rx_config(struct il_priv *il, struct il_rxon_context *ctx) memset(&il->staging, 0, sizeof(il->staging)); if (!ctx->vif) { - il->staging.dev_type = ctx->unused_devtype; + il->staging.dev_type = RXON_DEV_TYPE_ESS; } else switch (ctx->vif->type) { case NL80211_IFTYPE_STATION: - il->staging.dev_type = ctx->station_devtype; + il->staging.dev_type = RXON_DEV_TYPE_ESS; il->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; break; case NL80211_IFTYPE_ADHOC: - il->staging.dev_type = ctx->ibss_devtype; + il->staging.dev_type = RXON_DEV_TYPE_IBSS; il->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK; il->staging.filter_flags = RXON_FILTER_BCON_AWARE_MSK | diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index 66d0c1dd589..8eac5712415 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -1171,7 +1171,6 @@ struct il_rxon_context { int ctxid; u32 interface_modes, exclusive_interface_modes; - u8 unused_devtype, ap_devtype, ibss_devtype, station_devtype; struct il_qos_info qos_data; -- cgit v1.2.3-70-g09d2 From 6aa0c25435e6383d4a4af88fae8d128200dcd471 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 3 Feb 2012 17:31:46 +0100 Subject: iwlegacy: get rid of ctxid Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/3945-mac.c | 2 -- drivers/net/wireless/iwlegacy/4965-mac.c | 2 -- drivers/net/wireless/iwlegacy/common.c | 6 ------ drivers/net/wireless/iwlegacy/common.h | 4 +--- drivers/net/wireless/iwlegacy/debug.c | 1 - 5 files changed, 1 insertion(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c index 15dcafbf29d..52cac0cd106 100644 --- a/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/iwlegacy/3945-mac.c @@ -3617,8 +3617,6 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) il->cmd_queue = IL39_CMD_QUEUE_NUM; - il->ctx.ctxid = 0; - il->ctx.interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 33725e14e14..3209970cf45 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -6132,8 +6132,6 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) il = hw->priv; /* At this point both hw and il are allocated. */ - il->ctx.ctxid = 0; - il->ctx.always_active = true; il->ctx.is_active = true; il->ctx.ac_to_fifo = il4965_bss_ac_to_fifo; diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index 19ed86771a2..7c7ea778d21 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -1951,7 +1951,6 @@ il_prep_station(struct il_priv *il, struct il_rxon_context *ctx, station->sta.mode = 0; station->sta.sta.sta_id = sta_id; station->sta.station_flags = ctx->station_flags; - station->ctxid = ctx->ctxid; if (sta) { struct il_station_priv_common *sta_priv; @@ -2191,9 +2190,6 @@ il_clear_ucode_stations(struct il_priv *il, struct il_rxon_context *ctx) spin_lock_irqsave(&il->sta_lock, flags_spin); for (i = 0; i < il->hw_params.max_stations; i++) { - if (ctx && ctx->ctxid != il->stations[i].ctxid) - continue; - if (il->stations[i].used & IL_STA_UCODE_ACTIVE) { D_INFO("Clearing ucode active for station %d\n", i); il->stations[i].used &= ~IL_STA_UCODE_ACTIVE; @@ -2234,8 +2230,6 @@ il_restore_stations(struct il_priv *il, struct il_rxon_context *ctx) D_ASSOC("Restoring all known stations ... start.\n"); spin_lock_irqsave(&il->sta_lock, flags_spin); for (i = 0; i < il->hw_params.max_stations; i++) { - if (ctx->ctxid != il->stations[i].ctxid) - continue; if ((il->stations[i].used & IL_STA_DRIVER_ACTIVE) && !(il->stations[i].used & IL_STA_UCODE_ACTIVE)) { D_ASSOC("Restoring sta %pM\n", diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index 8eac5712415..8df2286ea05 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -735,7 +735,7 @@ struct il_qos_info { struct il_station_entry { struct il_addsta_cmd sta; struct il_tid_data tid[MAX_TID_COUNT]; - u8 used, ctxid; + u8 used; struct il_hw_key keyinfo; struct il_link_quality_cmd *lq; }; @@ -1168,8 +1168,6 @@ struct il_rxon_context { bool ht_need_multiple_chains; - int ctxid; - u32 interface_modes, exclusive_interface_modes; struct il_qos_info qos_data; diff --git a/drivers/net/wireless/iwlegacy/debug.c b/drivers/net/wireless/iwlegacy/debug.c index 6e3841beb1d..f3cb45e53c0 100644 --- a/drivers/net/wireless/iwlegacy/debug.c +++ b/drivers/net/wireless/iwlegacy/debug.c @@ -649,7 +649,6 @@ il_dbgfs_qos_read(struct file *file, char __user *user_buf, size_t count, char buf[256]; const size_t bufsz = sizeof(buf); - pos += scnprintf(buf + pos, bufsz - pos, "context %d:\n", ctx->ctxid); for (i = 0; i < AC_NUM; i++) { pos += scnprintf(buf + pos, bufsz - pos, -- cgit v1.2.3-70-g09d2 From d1e14e942430cd42df9913337aebbcaef53e4515 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 3 Feb 2012 17:31:47 +0100 Subject: iwlegacy: get rid of mcast_queue Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/4965-mac.c | 17 ++++------------- drivers/net/wireless/iwlegacy/common.h | 3 --- 2 files changed, 4 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 3209970cf45..ecb7b542b96 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -1708,19 +1708,10 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb) il4965_sta_modify_sleep_tx_count(il, sta_id, 1); } - /* - * Send this frame after DTIM -- there's a special queue - * reserved for this for contexts that support AP mode. - */ - if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) { - txq_id = ctx->mcast_queue; - /* - * The microcode will clear the more data - * bit in the last frame it transmits. - */ - hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); - } else - txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)]; + /* FIXME: remove me ? */ + WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM); + + txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)]; /* irqs already disabled/saved above when locking il->lock */ spin_lock(&il->sta_lock); diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index 8df2286ea05..89922e0a70d 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -1157,7 +1157,6 @@ struct il_rxon_context { const u8 *ac_to_fifo; const u8 *ac_to_queue; - u8 mcast_queue; /* * We could use the vif to indicate active, but we @@ -1166,8 +1165,6 @@ struct il_rxon_context { */ bool always_active, is_active; - bool ht_need_multiple_chains; - u32 interface_modes, exclusive_interface_modes; struct il_qos_info qos_data; -- cgit v1.2.3-70-g09d2 From d735f9213d11e34e6ed074acea30b6743b3385e6 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 3 Feb 2012 17:31:48 +0100 Subject: iwlegacy: move wep_keys out of context Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/4965-mac.c | 58 ++++++++++++++++++++------------ drivers/net/wireless/iwlegacy/common.h | 19 ++--------- 2 files changed, 39 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index ecb7b542b96..35d868c4ba9 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -2808,7 +2808,7 @@ static int il4965_static_wepkey_cmd(struct il_priv *il, struct il_rxon_context *ctx, bool send_if_empty) { - int i, not_empty = 0; + int i; u8 buff[sizeof(struct il_wep_cmd) + sizeof(struct il_wep_key) * WEP_KEYS_MAX]; struct il_wep_cmd *wep_cmd = (struct il_wep_cmd *)buff; @@ -2818,6 +2818,7 @@ il4965_static_wepkey_cmd(struct il_priv *il, struct il_rxon_context *ctx, .data = wep_cmd, .flags = CMD_SYNC, }; + bool not_empty = false; might_sleep(); @@ -2825,24 +2826,23 @@ il4965_static_wepkey_cmd(struct il_priv *il, struct il_rxon_context *ctx, cmd_size + (sizeof(struct il_wep_key) * WEP_KEYS_MAX)); for (i = 0; i < WEP_KEYS_MAX; i++) { + u8 key_size = il->_4965.wep_keys[i].key_size; + wep_cmd->key[i].key_idx = i; - if (ctx->wep_keys[i].key_size) { + if (key_size) { wep_cmd->key[i].key_offset = i; - not_empty = 1; - } else { + not_empty = true; + } else wep_cmd->key[i].key_offset = WEP_INVALID_OFFSET; - } - wep_cmd->key[i].key_size = ctx->wep_keys[i].key_size; - memcpy(&wep_cmd->key[i].key[3], ctx->wep_keys[i].key, - ctx->wep_keys[i].key_size); + wep_cmd->key[i].key_size = key_size; + memcpy(&wep_cmd->key[i].key[3], il->_4965.wep_keys[i].key, key_size); } wep_cmd->global_key_type = WEP_KEY_WEP_TYPE; wep_cmd->num_keys = WEP_KEYS_MAX; cmd_size += sizeof(struct il_wep_key) * WEP_KEYS_MAX; - cmd.len = cmd_size; if (not_empty || send_if_empty) @@ -2864,19 +2864,20 @@ il4965_remove_default_wep_key(struct il_priv *il, struct il_rxon_context *ctx, struct ieee80211_key_conf *keyconf) { int ret; + int idx = keyconf->keyidx; lockdep_assert_held(&il->mutex); - D_WEP("Removing default WEP key: idx=%d\n", keyconf->keyidx); + D_WEP("Removing default WEP key: idx=%d\n", idx); - memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0])); + memset(&il->_4965.wep_keys[idx], 0, sizeof(struct il_wep_key)); if (il_is_rfkill(il)) { D_WEP("Not sending C_WEPKEY command due to RFKILL.\n"); /* but keys in device are clear anyway so return success */ return 0; } ret = il4965_static_wepkey_cmd(il, ctx, 1); - D_WEP("Remove default WEP key: idx=%d ret=%d\n", keyconf->keyidx, ret); + D_WEP("Remove default WEP key: idx=%d ret=%d\n", idx, ret); return ret; } @@ -2886,11 +2887,12 @@ il4965_set_default_wep_key(struct il_priv *il, struct il_rxon_context *ctx, struct ieee80211_key_conf *keyconf) { int ret; + int len = keyconf->keylen; + int idx = keyconf->keyidx; lockdep_assert_held(&il->mutex); - if (keyconf->keylen != WEP_KEY_LEN_128 && - keyconf->keylen != WEP_KEY_LEN_64) { + if (len != WEP_KEY_LEN_128 && len != WEP_KEY_LEN_64) { D_WEP("Bad WEP key length %d\n", keyconf->keylen); return -EINVAL; } @@ -2899,14 +2901,12 @@ il4965_set_default_wep_key(struct il_priv *il, struct il_rxon_context *ctx, keyconf->hw_key_idx = HW_KEY_DEFAULT; il->stations[IL_AP_ID].keyinfo.cipher = keyconf->cipher; - ctx->wep_keys[keyconf->keyidx].key_size = keyconf->keylen; - memcpy(&ctx->wep_keys[keyconf->keyidx].key, &keyconf->key, - keyconf->keylen); + il->_4965.wep_keys[idx].key_size = len; + memcpy(&il->_4965.wep_keys[idx].key, &keyconf->key, len); ret = il4965_static_wepkey_cmd(il, ctx, false); - D_WEP("Set default WEP key: len=%d idx=%d ret=%d\n", keyconf->keylen, - keyconf->keyidx, ret); + D_WEP("Set default WEP key: len=%d idx=%d ret=%d\n", len, idx, ret); return ret; } @@ -3106,7 +3106,7 @@ il4965_remove_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx, lockdep_assert_held(&il->mutex); - ctx->key_mapping_keys--; + il->_4965.key_mapping_keys--; spin_lock_irqsave(&il->sta_lock, flags); key_flags = le16_to_cpu(il->stations[sta_id].sta.key.key_flags); @@ -3164,7 +3164,7 @@ il4965_set_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx, lockdep_assert_held(&il->mutex); - ctx->key_mapping_keys++; + il->_4965.key_mapping_keys++; keyconf->hw_key_idx = HW_KEY_DYNAMIC; switch (keyconf->cipher) { @@ -5067,6 +5067,20 @@ __il4965_down(struct il_priv *il) del_timer_sync(&il->watchdog); il_clear_ucode_stations(il, NULL); + + /* FIXME: race conditions ? */ + spin_lock_irq(&il->sta_lock); + /* + * Remove all key information that is not stored as part + * of station information since mac80211 may not have had + * a chance to remove all the keys. When device is + * reconfigured by mac80211 after an error all keys will + * be reconfigured. + */ + memset(il->_4965.wep_keys, 0, sizeof(il->_4965.wep_keys)); + il->_4965.key_mapping_keys = 0; + spin_unlock_irq(&il->sta_lock); + il_dealloc_bcast_stations(il); il_clear_driver_stations(il); @@ -5613,7 +5627,7 @@ il4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 || key->cipher == WLAN_CIPHER_SUITE_WEP104) && !sta) { if (cmd == SET_KEY) - is_default_wep_key = !ctx->key_mapping_keys; + is_default_wep_key = !il->_4965.key_mapping_keys; else is_default_wep_key = (key->hw_key_idx == HW_KEY_DEFAULT); diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index 89922e0a70d..811e768637c 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -1169,9 +1169,6 @@ struct il_rxon_context { struct il_qos_info qos_data; - struct il_wep_key wep_keys[WEP_KEYS_MAX]; - u8 key_mapping_keys; - __le32 station_flags; struct { @@ -1417,6 +1414,9 @@ struct il_priv { u8 phy_calib_chain_noise_reset_cmd; u8 phy_calib_chain_noise_gain_cmd; + u8 key_mapping_keys; + struct il_wep_key wep_keys[WEP_KEYS_MAX]; + struct il_notif_stats stats; #ifdef CONFIG_IWLEGACY_DEBUGFS struct il_notif_stats accum_stats; @@ -2318,24 +2318,11 @@ static inline void il_clear_driver_stations(struct il_priv *il) { unsigned long flags; - struct il_rxon_context *ctx = &il->ctx; spin_lock_irqsave(&il->sta_lock, flags); memset(il->stations, 0, sizeof(il->stations)); il->num_stations = 0; - il->ucode_key_table = 0; - - /* - * Remove all key information that is not stored as part - * of station information since mac80211 may not have had - * a chance to remove all the keys. When device is - * reconfigured by mac80211 after an error all keys will - * be reconfigured. - */ - memset(ctx->wep_keys, 0, sizeof(ctx->wep_keys)); - ctx->key_mapping_keys = 0; - spin_unlock_irqrestore(&il->sta_lock, flags); } -- cgit v1.2.3-70-g09d2 From fd6415bcfb303e37052c72a3f44b7f81089d7336 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 3 Feb 2012 17:31:49 +0100 Subject: iwlegacy: get rid of ctx->station_flags Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/common.c | 2 +- drivers/net/wireless/iwlegacy/common.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index 7c7ea778d21..ac269856be1 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -1950,7 +1950,7 @@ il_prep_station(struct il_priv *il, struct il_rxon_context *ctx, memcpy(station->sta.sta.addr, addr, ETH_ALEN); station->sta.mode = 0; station->sta.sta.sta_id = sta_id; - station->sta.station_flags = ctx->station_flags; + station->sta.station_flags = 0; if (sta) { struct il_station_priv_common *sta_priv; diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index 811e768637c..a872175f164 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -1169,8 +1169,6 @@ struct il_rxon_context { struct il_qos_info qos_data; - __le32 station_flags; - struct { bool non_gf_sta_present; u8 protection; -- cgit v1.2.3-70-g09d2 From 8c9c48d5a9ca5e1426372f8a747846bd0609dc08 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 3 Feb 2012 17:31:50 +0100 Subject: iwlegacy: remove ctx interface_modes Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/3945-mac.c | 6 ++---- drivers/net/wireless/iwlegacy/4965-mac.c | 6 ++---- drivers/net/wireless/iwlegacy/common.c | 29 ++++------------------------- drivers/net/wireless/iwlegacy/common.h | 2 -- 4 files changed, 8 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c index 52cac0cd106..7c81f5aaf7a 100644 --- a/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/iwlegacy/3945-mac.c @@ -3557,7 +3557,8 @@ il3945_setup_mac(struct il_priv *il) /* Tell mac80211 our characteristics */ hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SPECTRUM_MGMT; - hw->wiphy->interface_modes = il->ctx.interface_modes; + hw->wiphy->interface_modes = + BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS | @@ -3617,9 +3618,6 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) il->cmd_queue = IL39_CMD_QUEUE_NUM; - il->ctx.interface_modes = - BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); - /* * Disabling hardware scan means that mac80211 will perform scans * "the hard way", rather than using device's scan. diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 35d868c4ba9..1dd00147552 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -5454,8 +5454,8 @@ il4965_mac_setup_register(struct il_priv *il, u32 max_probe_length) hw->sta_data_size = sizeof(struct il_station_priv); hw->vif_data_size = sizeof(struct il_vif_priv); - hw->wiphy->interface_modes |= il->ctx.interface_modes; - hw->wiphy->interface_modes |= il->ctx.exclusive_interface_modes; + hw->wiphy->interface_modes = + BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS; @@ -6141,8 +6141,6 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) il->ctx.is_active = true; il->ctx.ac_to_fifo = il4965_bss_ac_to_fifo; il->ctx.ac_to_queue = il4965_bss_ac_to_queue; - il->ctx.exclusive_interface_modes = BIT(NL80211_IFTYPE_ADHOC); - il->ctx.interface_modes = BIT(NL80211_IFTYPE_STATION); SET_IEEE80211_DEV(hw, &pdev->dev); diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index ac269856be1..7f4c6bf4199 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -4566,7 +4566,6 @@ il_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) struct il_priv *il = hw->priv; struct il_vif_priv *vif_priv = (void *)vif->drv_priv; int err; - u32 modes; D_MAC80211("enter: type %d, addr %pM\n", vif->type, vif->addr); @@ -4578,15 +4577,7 @@ il_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) goto out; } - /* check if busy context is exclusive */ - if (il->ctx.vif && - (il->ctx.exclusive_interface_modes & BIT(il->ctx.vif->type))) { - err = -EINVAL; - goto out; - } - - modes = il->ctx.interface_modes | il->ctx.exclusive_interface_modes; - if (!(modes & BIT(vif->type))) { + if (il->ctx.vif) { err = -EOPNOTSUPP; goto out; } @@ -4979,10 +4970,10 @@ il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, { struct il_priv *il = hw->priv; struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif); - u32 modes; int err; - newtype = ieee80211_iftype_p2p(newtype, newp2p); + if (newp2p) + return -EOPNOTSUPP; mutex_lock(&il->mutex); @@ -4995,22 +4986,10 @@ il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, goto out; } - modes = ctx->interface_modes | ctx->exclusive_interface_modes; - if (!(modes & BIT(newtype))) { - err = -EOPNOTSUPP; - goto out; - } - - if ((il->ctx.exclusive_interface_modes & BIT(il->ctx.vif->type)) || - (il->ctx.exclusive_interface_modes & BIT(newtype))) { - err = -EINVAL; - goto out; - } - /* success */ il_teardown_interface(il, vif, true); vif->type = newtype; - vif->p2p = newp2p; + vif->p2p = false; err = il_setup_interface(il, ctx); WARN_ON(err); /* diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index a872175f164..eddf22d4f1b 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -1165,8 +1165,6 @@ struct il_rxon_context { */ bool always_active, is_active; - u32 interface_modes, exclusive_interface_modes; - struct il_qos_info qos_data; struct { -- cgit v1.2.3-70-g09d2 From 8d44f2bd7554734913f1256e4f45c35454167161 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 3 Feb 2012 17:31:51 +0100 Subject: iwlegacy: move qos_data out of ctx structure Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/common.c | 24 ++++++++++++------------ drivers/net/wireless/iwlegacy/common.h | 4 ++-- drivers/net/wireless/iwlegacy/debug.c | 9 ++++----- 3 files changed, 18 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index 7f4c6bf4199..c93fa1b85da 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -4496,15 +4496,15 @@ il_mac_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, spin_lock_irqsave(&il->lock, flags); - il->ctx.qos_data.def_qos_parm.ac[q].cw_min = + il->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min); - il->ctx.qos_data.def_qos_parm.ac[q].cw_max = + il->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max); - il->ctx.qos_data.def_qos_parm.ac[q].aifsn = params->aifs; - il->ctx.qos_data.def_qos_parm.ac[q].edca_txop = + il->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; + il->qos_data.def_qos_parm.ac[q].edca_txop = cpu_to_le16((params->txop * 32)); - il->ctx.qos_data.def_qos_parm.ac[q].reserved1 = 0; + il->qos_data.def_qos_parm.ac[q].reserved1 = 0; spin_unlock_irqrestore(&il->lock, flags); @@ -5230,20 +5230,20 @@ il_update_qos(struct il_priv *il, struct il_rxon_context *ctx) if (!ctx->is_active) return; - ctx->qos_data.def_qos_parm.qos_flags = 0; + il->qos_data.def_qos_parm.qos_flags = 0; - if (ctx->qos_data.qos_active) - ctx->qos_data.def_qos_parm.qos_flags |= + if (il->qos_data.qos_active) + il->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_UPDATE_EDCA_MSK; if (ctx->ht.enabled) - ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; + il->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; D_QOS("send QoS cmd with Qos active=%d FLAGS=0x%X\n", - ctx->qos_data.qos_active, ctx->qos_data.def_qos_parm.qos_flags); + il->qos_data.qos_active, il->qos_data.def_qos_parm.qos_flags); il_send_cmd_pdu_async(il, C_QOS_PARAM, sizeof(struct il_qosparam_cmd), - &ctx->qos_data.def_qos_parm, NULL); + &il->qos_data.def_qos_parm, NULL); } /** @@ -5596,7 +5596,7 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, unsigned long flags; spin_lock_irqsave(&il->lock, flags); - ctx->qos_data.qos_active = bss_conf->qos; + il->qos_data.qos_active = bss_conf->qos; il_update_qos(il, ctx); spin_unlock_irqrestore(&il->lock, flags); } diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index eddf22d4f1b..18375cb7904 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -1165,8 +1165,6 @@ struct il_rxon_context { */ bool always_active, is_active; - struct il_qos_info qos_data; - struct { bool non_gf_sta_present; u8 protection; @@ -1278,6 +1276,8 @@ struct il_priv { struct il_rxon_context ctx; + struct il_qos_info qos_data; + /* * We declare this const so it can only be * changed via explicit cast within the diff --git a/drivers/net/wireless/iwlegacy/debug.c b/drivers/net/wireless/iwlegacy/debug.c index f3cb45e53c0..3a9609a8874 100644 --- a/drivers/net/wireless/iwlegacy/debug.c +++ b/drivers/net/wireless/iwlegacy/debug.c @@ -644,7 +644,6 @@ il_dbgfs_qos_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct il_priv *il = file->private_data; - struct il_rxon_context *ctx = &il->ctx; int pos = 0, i; char buf[256]; const size_t bufsz = sizeof(buf); @@ -656,10 +655,10 @@ il_dbgfs_qos_read(struct file *file, char __user *user_buf, size_t count, pos += scnprintf(buf + pos, bufsz - pos, "AC[%d]\t%u\t%u\t%u\t%u\n", i, - ctx->qos_data.def_qos_parm.ac[i].cw_min, - ctx->qos_data.def_qos_parm.ac[i].cw_max, - ctx->qos_data.def_qos_parm.ac[i].aifsn, - ctx->qos_data.def_qos_parm.ac[i].edca_txop); + il->qos_data.def_qos_parm.ac[i].cw_min, + il->qos_data.def_qos_parm.ac[i].cw_max, + il->qos_data.def_qos_parm.ac[i].aifsn, + il->qos_data.def_qos_parm.ac[i].edca_txop); } return simple_read_from_buffer(user_buf, count, ppos, buf, pos); -- cgit v1.2.3-70-g09d2 From 1c03c4620edc551b5bbcc87c7aca02b482d8bc51 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 3 Feb 2012 17:31:52 +0100 Subject: iwlegacy: move ht out of ctx structure Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/4965-mac.c | 18 ++++++------ drivers/net/wireless/iwlegacy/4965-rs.c | 13 ++++----- drivers/net/wireless/iwlegacy/common.c | 49 ++++++++++++++++---------------- drivers/net/wireless/iwlegacy/common.h | 15 +++++----- 4 files changed, 46 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 1dd00147552..94984c850e8 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -5793,23 +5793,23 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw, il->current_ht_config.smps = conf->smps_mode; /* Configure HT40 channels */ - ctx->ht.enabled = conf_is_ht(conf); - if (ctx->ht.enabled) { + il->ht.enabled = conf_is_ht(conf); + if (il->ht.enabled) { if (conf_is_ht40_minus(conf)) { - ctx->ht.extension_chan_offset = + il->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW; - ctx->ht.is_40mhz = true; + il->ht.is_40mhz = true; } else if (conf_is_ht40_plus(conf)) { - ctx->ht.extension_chan_offset = + il->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; - ctx->ht.is_40mhz = true; + il->ht.is_40mhz = true; } else { - ctx->ht.extension_chan_offset = + il->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE; - ctx->ht.is_40mhz = false; + il->ht.is_40mhz = false; } } else - ctx->ht.is_40mhz = false; + il->ht.is_40mhz = false; if ((le16_to_cpu(il->staging.channel) != ch)) il->staging.flags = 0; diff --git a/drivers/net/wireless/iwlegacy/4965-rs.c b/drivers/net/wireless/iwlegacy/4965-rs.c index 467d0cb14ec..ad186d9a598 100644 --- a/drivers/net/wireless/iwlegacy/4965-rs.c +++ b/drivers/net/wireless/iwlegacy/4965-rs.c @@ -641,13 +641,10 @@ il4965_rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags, * there are no non-GF stations present in the BSS. */ static bool -il4965_rs_use_green(struct ieee80211_sta *sta) +il4965_rs_use_green(struct il_priv *il, struct ieee80211_sta *sta) { - struct il_station_priv *sta_priv = (void *)sta->drv_priv; - struct il_rxon_context *ctx = sta_priv->common.ctx; - return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && - !(ctx->ht.non_gf_sta_present); + !il->ht.non_gf_sta_present; } /** @@ -1815,7 +1812,7 @@ il4965_rs_rate_scale_perform(struct il_priv *il, struct sk_buff *skb, if (is_legacy(tbl->lq_type)) lq_sta->is_green = 0; else - lq_sta->is_green = il4965_rs_use_green(sta); + lq_sta->is_green = il4965_rs_use_green(il, sta); is_green = lq_sta->is_green; /* current tx rate */ @@ -2166,7 +2163,7 @@ il4965_rs_initialize_lq(struct il_priv *il, struct ieee80211_conf *conf, int rate_idx; int i; u32 rate; - u8 use_green = il4965_rs_use_green(sta); + u8 use_green = il4965_rs_use_green(il, sta); u8 active_tbl = 0; u8 valid_tx_ant; struct il_station_priv *sta_priv; @@ -2341,7 +2338,7 @@ il4965_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, u8 sta_id) lq_sta->is_dup = 0; lq_sta->max_rate_idx = -1; lq_sta->missed_rate_counter = IL_MISSED_RATE_MAX; - lq_sta->is_green = il4965_rs_use_green(sta); + lq_sta->is_green = il4965_rs_use_green(il, sta); lq_sta->active_legacy_rate = il->active_rate & ~(0x1000); lq_sta->band = il->band; /* diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index c93fa1b85da..db2e8bb11fa 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -2352,7 +2352,7 @@ il_is_lq_table_valid(struct il_priv *il, struct il_rxon_context *ctx, { int i; - if (ctx->ht.enabled) + if (il->ht.enabled) return true; D_INFO("Channel %u is not an HT channel\n", il->active.channel); @@ -3559,7 +3559,7 @@ bool il_is_ht40_tx_allowed(struct il_priv *il, struct il_rxon_context *ctx, struct ieee80211_sta_ht_cap *ht_cap) { - if (!ctx->ht.enabled || !ctx->ht.is_40mhz) + if (!il->ht.enabled || !il->ht.is_40mhz) return false; /* @@ -3576,7 +3576,7 @@ il_is_ht40_tx_allowed(struct il_priv *il, struct il_rxon_context *ctx, return il_is_channel_extension(il, il->band, le16_to_cpu(il->staging.channel), - ctx->ht.extension_chan_offset); + il->ht.extension_chan_offset); } EXPORT_SYMBOL(il_is_ht40_tx_allowed); @@ -3832,7 +3832,7 @@ _il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf, { struct il_rxon_cmd *rxon = &il->staging; - if (!ctx->ht.enabled) { + if (!il->ht.enabled) { rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK | RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK | RXON_FLG_HT40_PROT_MSK @@ -3841,7 +3841,7 @@ _il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf, } rxon->flags |= - cpu_to_le32(ctx->ht.protection << RXON_FLG_HT_OPERATING_MODE_POS); + cpu_to_le32(il->ht.protection << RXON_FLG_HT_OPERATING_MODE_POS); /* Set up channel bandwidth: * 20 MHz only, 20/40 mixed or pure 40 if ht40 ok */ @@ -3850,10 +3850,10 @@ _il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf, ~(RXON_FLG_CHANNEL_MODE_MSK | RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); if (il_is_ht40_tx_allowed(il, ctx, NULL)) { /* pure ht40 */ - if (ctx->ht.protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) { + if (il->ht.protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) { rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40; /* Note: control channel is opposite of extension channel */ - switch (ctx->ht.extension_chan_offset) { + switch (il->ht.extension_chan_offset) { case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: rxon->flags &= ~RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; @@ -3864,7 +3864,7 @@ _il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf, } } else { /* Note: control channel is opposite of extension channel */ - switch (ctx->ht.extension_chan_offset) { + switch (il->ht.extension_chan_offset) { case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); @@ -3890,7 +3890,7 @@ _il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf, D_ASSOC("rxon flags 0x%X operation mode :0x%X " "extension channel offset 0x%x\n", le32_to_cpu(rxon->flags), - ctx->ht.protection, ctx->ht.extension_chan_offset); + il->ht.protection, il->ht.extension_chan_offset); } void @@ -5236,7 +5236,7 @@ il_update_qos(struct il_priv *il, struct il_rxon_context *ctx) il->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_UPDATE_EDCA_MSK; - if (ctx->ht.enabled) + if (il->ht.enabled) il->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; D_QOS("send QoS cmd with Qos active=%d FLAGS=0x%X\n", @@ -5319,32 +5319,32 @@ il_mac_config(struct ieee80211_hw *hw, u32 changed) spin_lock_irqsave(&il->lock, flags); /* Configure HT40 channels */ - if (ctx->ht.enabled != conf_is_ht(conf)) { - ctx->ht.enabled = conf_is_ht(conf); + if (il->ht.enabled != conf_is_ht(conf)) { + il->ht.enabled = conf_is_ht(conf); ht_changed = true; } - if (ctx->ht.enabled) { + if (il->ht.enabled) { if (conf_is_ht40_minus(conf)) { - ctx->ht.extension_chan_offset = + il->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW; - ctx->ht.is_40mhz = true; + il->ht.is_40mhz = true; } else if (conf_is_ht40_plus(conf)) { - ctx->ht.extension_chan_offset = + il->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; - ctx->ht.is_40mhz = true; + il->ht.is_40mhz = true; } else { - ctx->ht.extension_chan_offset = + il->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE; - ctx->ht.is_40mhz = false; + il->ht.is_40mhz = false; } } else - ctx->ht.is_40mhz = false; + il->ht.is_40mhz = false; /* * Default to no protection. Protection mode will * later be set from BSS config in il_ht_conf */ - ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE; + il->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE; /* if we are switching from ht to 2.4 clear flags * from any ht related info since 2.4 does not @@ -5460,16 +5460,15 @@ il_ht_conf(struct il_priv *il, struct ieee80211_vif *vif) struct il_ht_config *ht_conf = &il->current_ht_config; struct ieee80211_sta *sta; struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; - struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif); D_ASSOC("enter:\n"); - if (!ctx->ht.enabled) + if (!il->ht.enabled) return; - ctx->ht.protection = + il->ht.protection = bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION; - ctx->ht.non_gf_sta_present = + il->ht.non_gf_sta_present = !!(bss_conf-> ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index 18375cb7904..df4d1602289 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -1164,13 +1164,6 @@ struct il_rxon_context { * we already removed the vif for type setting. */ bool always_active, is_active; - - struct { - bool non_gf_sta_present; - u8 protection; - bool enabled, is_40mhz; - u8 extension_chan_offset; - } ht; }; struct il_power_mgr { @@ -1278,6 +1271,14 @@ struct il_priv { struct il_qos_info qos_data; + struct { + bool enabled; + bool is_40mhz; + bool non_gf_sta_present; + u8 protection; + u8 extension_chan_offset; + } ht; + /* * We declare this const so it can only be * changed via explicit cast within the -- cgit v1.2.3-70-g09d2 From b75b3a70a623e6c39512e3ed9a0fd76cea19c085 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 3 Feb 2012 17:31:53 +0100 Subject: iwlegacy: get rid of ctx->ac_to_fifo Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/4965-mac.c | 17 ++++++++--------- drivers/net/wireless/iwlegacy/common.h | 1 - 2 files changed, 8 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 94984c850e8..731bb8c10b4 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -1458,8 +1458,15 @@ il4965_get_ac_from_tid(u16 tid) static inline int il4965_get_fifo_from_tid(struct il_rxon_context *ctx, u16 tid) { + const u8 ac_to_fifo[] = { + IL_TX_FIFO_VO, + IL_TX_FIFO_VI, + IL_TX_FIFO_BE, + IL_TX_FIFO_BK, + }; + if (likely(tid < ARRAY_SIZE(tid_to_ac))) - return ctx->ac_to_fifo[tid_to_ac[tid]]; + return ac_to_fifo[tid_to_ac[tid]]; /* no support for TIDs 8-15 yet */ return -EINVAL; @@ -6104,13 +6111,6 @@ il4965_set_hw_params(struct il_priv *il) return il->cfg->ops->lib->set_hw_params(il); } -static const u8 il4965_bss_ac_to_fifo[] = { - IL_TX_FIFO_VO, - IL_TX_FIFO_VI, - IL_TX_FIFO_BE, - IL_TX_FIFO_BK, -}; - static const u8 il4965_bss_ac_to_queue[] = { 0, 1, 2, 3, }; @@ -6139,7 +6139,6 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) il->ctx.always_active = true; il->ctx.is_active = true; - il->ctx.ac_to_fifo = il4965_bss_ac_to_fifo; il->ctx.ac_to_queue = il4965_bss_ac_to_queue; SET_IEEE80211_DEV(hw, &pdev->dev); diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index df4d1602289..e0e4d013660 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -1155,7 +1155,6 @@ struct il_force_reset { struct il_rxon_context { struct ieee80211_vif *vif; - const u8 *ac_to_fifo; const u8 *ac_to_queue; /* -- cgit v1.2.3-70-g09d2 From eb123af3d1e038c486fc8fcf19518133883792d5 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 3 Feb 2012 17:31:54 +0100 Subject: iwlegacy: get rid of ctx->ac_to_queue Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/4965-mac.c | 8 ++------ drivers/net/wireless/iwlegacy/common.h | 2 -- 2 files changed, 2 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 731bb8c10b4..1c3c85ec111 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -1718,7 +1718,8 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb) /* FIXME: remove me ? */ WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM); - txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)]; + /* Access category (AC) is also the queue number */ + txq_id = skb_get_queue_mapping(skb); /* irqs already disabled/saved above when locking il->lock */ spin_lock(&il->sta_lock); @@ -6111,10 +6112,6 @@ il4965_set_hw_params(struct il_priv *il) return il->cfg->ops->lib->set_hw_params(il); } -static const u8 il4965_bss_ac_to_queue[] = { - 0, 1, 2, 3, -}; - static int il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -6139,7 +6136,6 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) il->ctx.always_active = true; il->ctx.is_active = true; - il->ctx.ac_to_queue = il4965_bss_ac_to_queue; SET_IEEE80211_DEV(hw, &pdev->dev); diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index e0e4d013660..e085131a457 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -1155,8 +1155,6 @@ struct il_force_reset { struct il_rxon_context { struct ieee80211_vif *vif; - const u8 *ac_to_queue; - /* * We could use the vif to indicate active, but we * also need it to be active during disabling when -- cgit v1.2.3-70-g09d2 From dee9a09eb34a272494a315fe0c19e49b6375a000 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 3 Feb 2012 17:31:55 +0100 Subject: iwlegacy: get rid of ctx->is_active Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/4965-mac.c | 3 --- drivers/net/wireless/iwlegacy/4965.c | 3 --- drivers/net/wireless/iwlegacy/common.c | 21 +++------------------ drivers/net/wireless/iwlegacy/common.h | 7 ------- 4 files changed, 3 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 1c3c85ec111..1a54c1a812d 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -6134,9 +6134,6 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) il = hw->priv; /* At this point both hw and il are allocated. */ - il->ctx.always_active = true; - il->ctx.is_active = true; - SET_IEEE80211_DEV(hw, &pdev->dev); D_INFO("*** LOAD DRIVER ***\n"); diff --git a/drivers/net/wireless/iwlegacy/4965.c b/drivers/net/wireless/iwlegacy/4965.c index 8d0fd60bc49..7b0192aff83 100644 --- a/drivers/net/wireless/iwlegacy/4965.c +++ b/drivers/net/wireless/iwlegacy/4965.c @@ -1419,9 +1419,6 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) if (!il_is_alive(il)) return -EBUSY; - if (!ctx->is_active) - return 0; - /* always get timestamp with Rx frame */ il->staging.flags |= RXON_FLG_TSF2HOST_MSK; diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index db2e8bb11fa..13bd3a8c21b 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -4537,7 +4537,6 @@ static int il_setup_interface(struct il_priv *il, struct il_rxon_context *ctx) { struct ieee80211_vif *vif = ctx->vif; - int err; lockdep_assert_held(&il->mutex); @@ -4548,16 +4547,7 @@ il_setup_interface(struct il_priv *il, struct il_rxon_context *ctx) */ il->iw_mode = vif->type; - ctx->is_active = true; - - err = il_set_mode(il, ctx); - if (err) { - if (!ctx->always_active) - ctx->is_active = false; - return err; - } - - return 0; + return il_set_mode(il, ctx); } int @@ -4612,11 +4602,9 @@ il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif, il_force_scan_end(il); } - if (!mode_change) { + if (!mode_change) il_set_mode(il, ctx); - if (!ctx->always_active) - ctx->is_active = false; - } + } void @@ -5227,9 +5215,6 @@ il_update_qos(struct il_priv *il, struct il_rxon_context *ctx) if (test_bit(S_EXIT_PENDING, &il->status)) return; - if (!ctx->is_active) - return; - il->qos_data.def_qos_parm.qos_flags = 0; if (il->qos_data.qos_active) diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index e085131a457..51c1eecf751 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -1154,13 +1154,6 @@ struct il_force_reset { struct il_rxon_context { struct ieee80211_vif *vif; - - /* - * We could use the vif to indicate active, but we - * also need it to be active during disabling when - * we already removed the vif for type setting. - */ - bool always_active, is_active; }; struct il_power_mgr { -- cgit v1.2.3-70-g09d2 From 20c47eba7001680e62878c5b20e487a8b0b873ad Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 3 Feb 2012 17:31:56 +0100 Subject: iwlegacy: remove il_setup_interface() Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/common.c | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index 13bd3a8c21b..ea2fa97fa36 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -4533,23 +4533,6 @@ il_set_mode(struct il_priv *il, struct il_rxon_context *ctx) return il_commit_rxon(il, ctx); } -static int -il_setup_interface(struct il_priv *il, struct il_rxon_context *ctx) -{ - struct ieee80211_vif *vif = ctx->vif; - - lockdep_assert_held(&il->mutex); - - /* - * This variable will be correct only when there's just - * a single context, but all code using it is for hardware - * that supports only one context. - */ - il->iw_mode = vif->type; - - return il_set_mode(il, ctx); -} - int il_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { @@ -4574,8 +4557,9 @@ il_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) vif_priv->ctx = &il->ctx; il->ctx.vif = vif; + il->iw_mode = vif->type; - err = il_setup_interface(il, &il->ctx); + err = il_set_mode(il, &il->ctx); if (err) { il->ctx.vif = NULL; il->iw_mode = NL80211_IFTYPE_STATION; @@ -4978,7 +4962,7 @@ il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, il_teardown_interface(il, vif, true); vif->type = newtype; vif->p2p = false; - err = il_setup_interface(il, ctx); + err = il_set_mode(il, ctx); WARN_ON(err); /* * We've switched internally, but submitting to the -- cgit v1.2.3-70-g09d2 From 83007196037cc2d0bffd9f7afbe56d675779a6cb Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 3 Feb 2012 17:31:57 +0100 Subject: iwlegacy: get rid of ctx structure Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/3945-mac.c | 67 +++++------ drivers/net/wireless/iwlegacy/3945-rs.c | 3 +- drivers/net/wireless/iwlegacy/3945.c | 23 ++-- drivers/net/wireless/iwlegacy/3945.h | 2 +- drivers/net/wireless/iwlegacy/4965-mac.c | 150 ++++++++++------------- drivers/net/wireless/iwlegacy/4965-rs.c | 35 ++---- drivers/net/wireless/iwlegacy/4965.c | 62 +++++----- drivers/net/wireless/iwlegacy/4965.h | 19 ++- drivers/net/wireless/iwlegacy/common.c | 199 ++++++++++++------------------- drivers/net/wireless/iwlegacy/common.h | 79 +++++------- 10 files changed, 261 insertions(+), 378 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c index 7c81f5aaf7a..b2e04c591c6 100644 --- a/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/iwlegacy/3945-mac.c @@ -341,7 +341,7 @@ il3945_send_beacon_cmd(struct il_priv *il) return -ENOMEM; } - rate = il_get_lowest_plcp(il, &il->ctx); + rate = il_get_lowest_plcp(il); frame_size = il3945_hw_get_beacon_cmd(il, frame, rate); @@ -512,7 +512,7 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb) hdr_len = ieee80211_hdrlen(fc); /* Find idx into station table for destination station */ - sta_id = il_sta_id_or_broadcast(il, &il->ctx, info->control.sta); + sta_id = il_sta_id_or_broadcast(il, info->control.sta); if (sta_id == IL_INVALID_STATION) { D_DROP("Dropping - INVALID STATION: %pM\n", hdr->addr1); goto drop; @@ -541,7 +541,6 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb) /* Set up driver data for this TFD */ memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct il_tx_info)); txq->txb[q->write_ptr].skb = skb; - txq->txb[q->write_ptr].ctx = &il->ctx; /* Init first empty entry in queue's array of Tx/cmd buffers */ out_cmd = txq->cmd[idx]; @@ -2208,7 +2207,7 @@ il3945_alive_start(struct il_priv *il) active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; } else { /* Initialize our rx_config data */ - il_connection_init_rx_config(il, &il->ctx); + il_connection_init_rx_config(il); } /* Configure Bluetooth device coexistence support */ @@ -2217,7 +2216,7 @@ il3945_alive_start(struct il_priv *il) set_bit(S_READY, &il->status); /* Configure the adapter for unassociated operation */ - il3945_commit_rxon(il, &il->ctx); + il3945_commit_rxon(il); il3945_reg_txpower_periodic(il); @@ -2249,7 +2248,7 @@ __il3945_down(struct il_priv *il) del_timer_sync(&il->watchdog); /* Station information will now be cleared in device */ - il_clear_ucode_stations(il, NULL); + il_clear_ucode_stations(il); il_dealloc_bcast_stations(il); il_clear_driver_stations(il); @@ -2335,12 +2334,11 @@ il3945_down(struct il_priv *il) static int il3945_alloc_bcast_station(struct il_priv *il) { - struct il_rxon_context *ctx = &il->ctx; unsigned long flags; u8 sta_id; spin_lock_irqsave(&il->sta_lock, flags); - sta_id = il_prep_station(il, ctx, il_bcast_addr, false, NULL); + sta_id = il_prep_station(il, il_bcast_addr, false, NULL); if (sta_id == IL_INVALID_STATION) { IL_ERR("Unable to prepare broadcast station\n"); spin_unlock_irqrestore(&il->sta_lock, flags); @@ -2660,14 +2658,12 @@ il3945_request_scan(struct il_priv *il, struct ieee80211_vif *vif) void il3945_post_scan(struct il_priv *il) { - struct il_rxon_context *ctx = &il->ctx; - /* * Since setting the RXON may have been deferred while * performing the scan, fire one off if needed */ if (memcmp(&il->staging, &il->active, sizeof(il->staging))) - il3945_commit_rxon(il, ctx); + il3945_commit_rxon(il); } static void @@ -2680,7 +2676,8 @@ il3945_bg_restart(struct work_struct *data) if (test_and_clear_bit(S_FW_ERROR, &il->status)) { mutex_lock(&il->mutex); - il->ctx.vif = NULL; + /* FIXME: vif can be dereferenced */ + il->vif = NULL; il->is_open = 0; mutex_unlock(&il->mutex); il3945_down(il); @@ -2718,12 +2715,11 @@ il3945_post_associate(struct il_priv *il) { int rc = 0; struct ieee80211_conf *conf = NULL; - struct il_rxon_context *ctx = &il->ctx; - if (!ctx->vif || !il->is_open) + if (!il->vif || !il->is_open) return; - D_ASSOC("Associated as %d to: %pM\n", ctx->vif->bss_conf.aid, + D_ASSOC("Associated as %d to: %pM\n", il->vif->bss_conf.aid, il->active.bssid_addr); if (test_bit(S_EXIT_PENDING, &il->status)) @@ -2734,34 +2730,34 @@ il3945_post_associate(struct il_priv *il) conf = &il->hw->conf; il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - il3945_commit_rxon(il, ctx); + il3945_commit_rxon(il); - rc = il_send_rxon_timing(il, ctx); + rc = il_send_rxon_timing(il); if (rc) IL_WARN("C_RXON_TIMING failed - " "Attempting to continue.\n"); il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; - il->staging.assoc_id = cpu_to_le16(ctx->vif->bss_conf.aid); + il->staging.assoc_id = cpu_to_le16(il->vif->bss_conf.aid); - D_ASSOC("assoc id %d beacon interval %d\n", ctx->vif->bss_conf.aid, - ctx->vif->bss_conf.beacon_int); + D_ASSOC("assoc id %d beacon interval %d\n", il->vif->bss_conf.aid, + il->vif->bss_conf.beacon_int); - if (ctx->vif->bss_conf.use_short_preamble) + if (il->vif->bss_conf.use_short_preamble) il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; else il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; if (il->staging.flags & RXON_FLG_BAND_24G_MSK) { - if (ctx->vif->bss_conf.use_short_slot) + if (il->vif->bss_conf.use_short_slot) il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; else il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; } - il3945_commit_rxon(il, ctx); + il3945_commit_rxon(il); - switch (ctx->vif->type) { + switch (il->vif->type) { case NL80211_IFTYPE_STATION: il3945_rate_scale_init(il->hw, IL_AP_ID); break; @@ -2770,7 +2766,7 @@ il3945_post_associate(struct il_priv *il) break; default: IL_ERR("%s Should not be called in %d mode\n", __func__, - ctx->vif->type); + il->vif->type); break; } } @@ -2887,8 +2883,7 @@ il3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) void il3945_config_ap(struct il_priv *il) { - struct il_rxon_context *ctx = &il->ctx; - struct ieee80211_vif *vif = ctx->vif; + struct ieee80211_vif *vif = il->vif; int rc = 0; if (test_bit(S_EXIT_PENDING, &il->status)) @@ -2899,10 +2894,10 @@ il3945_config_ap(struct il_priv *il) /* RXON - unassoc (to set timing command) */ il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - il3945_commit_rxon(il, ctx); + il3945_commit_rxon(il); /* RXON Timing */ - rc = il_send_rxon_timing(il, ctx); + rc = il_send_rxon_timing(il); if (rc) IL_WARN("C_RXON_TIMING failed - " "Attempting to continue.\n"); @@ -2922,7 +2917,7 @@ il3945_config_ap(struct il_priv *il) } /* restore RXON assoc */ il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; - il3945_commit_rxon(il, ctx); + il3945_commit_rxon(il); } il3945_send_beacon_cmd(il); } @@ -2955,7 +2950,7 @@ il3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, static_key = !il_is_associated(il); if (!static_key) { - sta_id = il_sta_id_or_broadcast(il, &il->ctx, sta); + sta_id = il_sta_id_or_broadcast(il, sta); if (sta_id == IL_INVALID_STATION) return -EINVAL; } @@ -3003,8 +2998,7 @@ il3945_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, D_INFO("proceeding to add station %pM\n", sta->addr); sta_priv->common.sta_id = IL_INVALID_STATION; - ret = - il_add_station_common(il, &il->ctx, sta->addr, is_ap, sta, &sta_id); + ret = il_add_station_common(il, sta->addr, is_ap, sta, &sta_id); if (ret) { IL_ERR("Unable to add station %pM (%d)\n", sta->addr, ret); /* Should we return success if return code is EEXIST ? */ @@ -3184,7 +3178,7 @@ il3945_store_flags(struct device *d, struct device_attribute *attr, else { D_INFO("Committing rxon.flags = 0x%04X\n", flags); il->staging.flags = cpu_to_le32(flags); - il3945_commit_rxon(il, &il->ctx); + il3945_commit_rxon(il); } } mutex_unlock(&il->mutex); @@ -3220,7 +3214,7 @@ il3945_store_filter_flags(struct device *d, struct device_attribute *attr, D_INFO("Committing rxon.filter_flags = " "0x%04X\n", filter_flags); il->staging.filter_flags = cpu_to_le32(filter_flags); - il3945_commit_rxon(il, &il->ctx); + il3945_commit_rxon(il); } } mutex_unlock(&il->mutex); @@ -3750,8 +3744,7 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto out_release_irq; } - il_set_rxon_channel(il, &il->bands[IEEE80211_BAND_2GHZ].channels[5], - &il->ctx); + il_set_rxon_channel(il, &il->bands[IEEE80211_BAND_2GHZ].channels[5]); il3945_setup_deferred_work(il); il3945_setup_handlers(il); il_power_initialize(il); diff --git a/drivers/net/wireless/iwlegacy/3945-rs.c b/drivers/net/wireless/iwlegacy/3945-rs.c index 6a782b5c0c5..70bee1a4d87 100644 --- a/drivers/net/wireless/iwlegacy/3945-rs.c +++ b/drivers/net/wireless/iwlegacy/3945-rs.c @@ -927,8 +927,7 @@ il3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) rcu_read_lock(); - sta = - ieee80211_find_sta(il->ctx.vif, il->stations[sta_id].sta.sta.addr); + sta = ieee80211_find_sta(il->vif, il->stations[sta_id].sta.sta.addr); if (!sta) { D_RATE("Unable to find station to initialize rate scaling.\n"); rcu_read_unlock(); diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c index 3024645a6be..1e617c9fc3c 100644 --- a/drivers/net/wireless/iwlegacy/3945.c +++ b/drivers/net/wireless/iwlegacy/3945.c @@ -1662,7 +1662,7 @@ il3945_hw_reg_set_txpower(struct il_priv *il, s8 power) } static int -il3945_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx) +il3945_send_rxon_assoc(struct il_priv *il) { int rc = 0; struct il_rx_pkt *pkt; @@ -1714,7 +1714,7 @@ il3945_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx) * a HW tune is required based on the RXON structure changes. */ int -il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) +il3945_commit_rxon(struct il_priv *il) { /* cast away the const for active_rxon in this function */ struct il3945_rxon_cmd *active_rxon = (void *)&il->active; @@ -1735,7 +1735,7 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) staging_rxon->flags &= ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK); staging_rxon->flags |= il3945_get_antenna_flags(il); - rc = il_check_rxon_cmd(il, ctx); + rc = il_check_rxon_cmd(il); if (rc) { IL_ERR("Invalid RXON configuration. Not committing.\n"); return -EINVAL; @@ -1744,8 +1744,8 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) /* If we don't need to send a full RXON, we can use * il3945_rxon_assoc_cmd which is used to reconfigure filter * and other flags for the current radio configuration. */ - if (!il_full_rxon_required(il, &il->ctx)) { - rc = il_send_rxon_assoc(il, &il->ctx); + if (!il_full_rxon_required(il)) { + rc = il_send_rxon_assoc(il); if (rc) { IL_ERR("Error setting RXON_ASSOC " "configuration (%d).\n", rc); @@ -1786,8 +1786,8 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) "configuration (%d).\n", rc); return rc; } - il_clear_ucode_stations(il, &il->ctx); - il_restore_stations(il, &il->ctx); + il_clear_ucode_stations(il); + il_restore_stations(il); } D_INFO("Sending RXON\n" "* with%s RXON_FILTER_ASSOC_MSK\n" @@ -1801,7 +1801,7 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) staging_rxon->reserved4 = 0; staging_rxon->reserved5 = 0; - il_set_rxon_hwcrypto(il, ctx, !il3945_mod_params.sw_crypto); + il_set_rxon_hwcrypto(il, !il3945_mod_params.sw_crypto); /* Apply the new configuration */ rc = il_send_cmd_pdu(il, C_RXON, sizeof(struct il3945_rxon_cmd), @@ -1814,8 +1814,8 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); if (!new_assoc) { - il_clear_ucode_stations(il, &il->ctx); - il_restore_stations(il, &il->ctx); + il_clear_ucode_stations(il); + il_restore_stations(il); } /* If we issue a new RXON command which required a tune then we must @@ -2258,7 +2258,6 @@ il3945_build_addsta_hcmd(const struct il_addsta_cmd *cmd, u8 * data) static int il3945_add_bssid_station(struct il_priv *il, const u8 * addr, u8 * sta_id_r) { - struct il_rxon_context *ctx = &il->ctx; int ret; u8 sta_id; unsigned long flags; @@ -2266,7 +2265,7 @@ il3945_add_bssid_station(struct il_priv *il, const u8 * addr, u8 * sta_id_r) if (sta_id_r) *sta_id_r = IL_INVALID_STATION; - ret = il_add_station_common(il, ctx, addr, 0, NULL, &sta_id); + ret = il_add_station_common(il, addr, 0, NULL, &sta_id); if (ret) { IL_ERR("Unable to add station %pM\n", addr); return ret; diff --git a/drivers/net/wireless/iwlegacy/3945.h b/drivers/net/wireless/iwlegacy/3945.h index 9f42f79f877..8bee127d413 100644 --- a/drivers/net/wireless/iwlegacy/3945.h +++ b/drivers/net/wireless/iwlegacy/3945.h @@ -249,7 +249,7 @@ extern int il4965_get_temperature(const struct il_priv *il); extern void il3945_post_associate(struct il_priv *il); extern void il3945_config_ap(struct il_priv *il); -extern int il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx); +extern int il3945_commit_rxon(struct il_priv *il); /** * il3945_hw_find_station - Find station id for a given BSSID diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 1a54c1a812d..4be53cc9198 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -843,7 +843,6 @@ il4965_request_scan(struct il_priv *il, struct ieee80211_vif *vif) .flags = CMD_SIZE_HUGE, }; struct il_scan_cmd *scan; - struct il_rxon_context *ctx = &il->ctx; u32 rate_flags = 0; u16 cmd_len; u16 rx_chain = 0; @@ -859,8 +858,6 @@ il4965_request_scan(struct il_priv *il, struct ieee80211_vif *vif) lockdep_assert_held(&il->mutex); - ctx = il_rxon_ctx_from_vif(vif); - if (!il->scan_cmd) { il->scan_cmd = kmalloc(sizeof(struct il_scan_cmd) + IL_MAX_SCAN_SIZE, @@ -1033,8 +1030,7 @@ il4965_manage_ibss_station(struct il_priv *il, struct ieee80211_vif *vif, struct il_vif_priv *vif_priv = (void *)vif->drv_priv; if (add) - return il4965_add_bssid_station(il, vif_priv->ctx, - vif->bss_conf.bssid, + return il4965_add_bssid_station(il, vif->bss_conf.bssid, &vif_priv->ibss_bssid_sta_id); return il_remove_station(il, vif_priv->ibss_bssid_sta_id, vif->bss_conf.bssid); @@ -1127,7 +1123,7 @@ il4965_count_chain_bitmap(u32 chain_bitmap) * This should not be used for scan command ... it puts data in wrong place. */ void -il4965_set_rxon_chain(struct il_priv *il, struct il_rxon_context *ctx) +il4965_set_rxon_chain(struct il_priv *il) { bool is_single = il4965_is_single_rx_stream(il); bool is_cam = !test_bit(S_POWER_PMI, &il->status); @@ -1456,7 +1452,7 @@ il4965_get_ac_from_tid(u16 tid) } static inline int -il4965_get_fifo_from_tid(struct il_rxon_context *ctx, u16 tid) +il4965_get_fifo_from_tid(u16 tid) { const u8 ac_to_fifo[] = { IL_TX_FIFO_VO, @@ -1645,7 +1641,6 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb) struct il_device_cmd *out_cmd; struct il_cmd_meta *out_meta; struct il_tx_cmd *tx_cmd; - struct il_rxon_context *ctx = &il->ctx; int txq_id; dma_addr_t phys_addr; dma_addr_t txcmd_phys; @@ -1661,9 +1656,6 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb) unsigned long flags; bool is_agg = false; - if (info->control.vif) - ctx = il_rxon_ctx_from_vif(info->control.vif); - spin_lock_irqsave(&il->lock, flags); if (il_is_rfkill(il)) { D_DROP("Dropping - RF KILL\n"); @@ -1688,7 +1680,7 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb) sta_id = il->hw_params.bcast_id; else { /* Find idx into station table for destination station */ - sta_id = il_sta_id_or_broadcast(il, ctx, info->control.sta); + sta_id = il_sta_id_or_broadcast(il, info->control.sta); if (sta_id == IL_INVALID_STATION) { D_DROP("Dropping - INVALID STATION: %pM\n", hdr->addr1); @@ -1764,7 +1756,6 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb) /* Set up driver data for this TFD */ memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct il_tx_info)); txq->txb[q->write_ptr].skb = skb; - txq->txb[q->write_ptr].ctx = ctx; /* Set up first empty entry in queue's array of Tx/cmd buffers */ out_cmd = txq->cmd[q->write_ptr]; @@ -2228,7 +2219,8 @@ il4965_tx_agg_start(struct il_priv *il, struct ieee80211_vif *vif, unsigned long flags; struct il_tid_data *tid_data; - tx_fifo = il4965_get_fifo_from_tid(il_rxon_ctx_from_vif(vif), tid); + /* FIXME: warning if tx fifo not found ? */ + tx_fifo = il4965_get_fifo_from_tid(tid); if (unlikely(tx_fifo < 0)) return tx_fifo; @@ -2321,7 +2313,8 @@ il4965_tx_agg_stop(struct il_priv *il, struct ieee80211_vif *vif, int write_ptr, read_ptr; unsigned long flags; - tx_fifo_id = il4965_get_fifo_from_tid(il_rxon_ctx_from_vif(vif), tid); + /* FIXME: warning if tx_fifo_id not found ? */ + tx_fifo_id = il4965_get_fifo_from_tid(tid); if (unlikely(tx_fifo_id < 0)) return tx_fifo_id; @@ -2395,9 +2388,6 @@ il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id) struct il_queue *q = &il->txq[txq_id].q; u8 *addr = il->stations[sta_id].sta.sta.addr; struct il_tid_data *tid_data = &il->stations[sta_id].tid[tid]; - struct il_rxon_context *ctx; - - ctx = &il->ctx; lockdep_assert_held(&il->sta_lock); @@ -2408,11 +2398,11 @@ il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id) if (txq_id == tid_data->agg.txq_id && q->read_ptr == q->write_ptr) { u16 ssn = SEQ_TO_SN(tid_data->seq_number); - int tx_fifo = il4965_get_fifo_from_tid(ctx, tid); + int tx_fifo = il4965_get_fifo_from_tid(tid); D_HT("HW queue empty: continue DELBA flow\n"); il4965_txq_agg_disable(il, txq_id, ssn, tx_fifo); tid_data->agg.state = IL_AGG_OFF; - ieee80211_stop_tx_ba_cb_irqsafe(ctx->vif, addr, tid); + ieee80211_stop_tx_ba_cb_irqsafe(il->vif, addr, tid); } break; case IL_EMPTYING_HW_QUEUE_ADDBA: @@ -2420,7 +2410,7 @@ il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id) if (tid_data->tfds_in_queue == 0) { D_HT("HW queue empty: continue ADDBA flow\n"); tid_data->agg.state = IL_AGG_ON; - ieee80211_start_tx_ba_cb_irqsafe(ctx->vif, addr, tid); + ieee80211_start_tx_ba_cb_irqsafe(il->vif, addr, tid); } break; } @@ -2429,14 +2419,13 @@ il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id) } static void -il4965_non_agg_tx_status(struct il_priv *il, struct il_rxon_context *ctx, - const u8 *addr1) +il4965_non_agg_tx_status(struct il_priv *il, const u8 *addr1) { struct ieee80211_sta *sta; struct il_station_priv *sta_priv; rcu_read_lock(); - sta = ieee80211_find_sta(ctx->vif, addr1); + sta = ieee80211_find_sta(il->vif, addr1); if (sta) { sta_priv = (void *)sta->drv_priv; /* avoid atomic ops if this isn't a client */ @@ -2453,7 +2442,7 @@ il4965_tx_status(struct il_priv *il, struct il_tx_info *tx_info, bool is_agg) struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx_info->skb->data; if (!is_agg) - il4965_non_agg_tx_status(il, tx_info->ctx, hdr->addr1); + il4965_non_agg_tx_status(il, hdr->addr1); ieee80211_tx_status_irqsafe(il->hw, tx_info->skb); } @@ -2769,8 +2758,7 @@ il4965_sta_alloc_lq(struct il_priv *il, u8 sta_id) * Function sleeps. */ int -il4965_add_bssid_station(struct il_priv *il, struct il_rxon_context *ctx, - const u8 *addr, u8 *sta_id_r) +il4965_add_bssid_station(struct il_priv *il, const u8 *addr, u8 *sta_id_r) { int ret; u8 sta_id; @@ -2780,7 +2768,7 @@ il4965_add_bssid_station(struct il_priv *il, struct il_rxon_context *ctx, if (sta_id_r) *sta_id_r = IL_INVALID_STATION; - ret = il_add_station_common(il, ctx, addr, 0, NULL, &sta_id); + ret = il_add_station_common(il, addr, 0, NULL, &sta_id); if (ret) { IL_ERR("Unable to add station %pM\n", addr); return ret; @@ -2801,7 +2789,7 @@ il4965_add_bssid_station(struct il_priv *il, struct il_rxon_context *ctx, return -ENOMEM; } - ret = il_send_lq_cmd(il, ctx, link_cmd, CMD_SYNC, true); + ret = il_send_lq_cmd(il, link_cmd, CMD_SYNC, true); if (ret) IL_ERR("Link quality command failed (%d)\n", ret); @@ -2813,8 +2801,7 @@ il4965_add_bssid_station(struct il_priv *il, struct il_rxon_context *ctx, } static int -il4965_static_wepkey_cmd(struct il_priv *il, struct il_rxon_context *ctx, - bool send_if_empty) +il4965_static_wepkey_cmd(struct il_priv *il, bool send_if_empty) { int i; u8 buff[sizeof(struct il_wep_cmd) + @@ -2860,15 +2847,15 @@ il4965_static_wepkey_cmd(struct il_priv *il, struct il_rxon_context *ctx, } int -il4965_restore_default_wep_keys(struct il_priv *il, struct il_rxon_context *ctx) +il4965_restore_default_wep_keys(struct il_priv *il) { lockdep_assert_held(&il->mutex); - return il4965_static_wepkey_cmd(il, ctx, false); + return il4965_static_wepkey_cmd(il, false); } int -il4965_remove_default_wep_key(struct il_priv *il, struct il_rxon_context *ctx, +il4965_remove_default_wep_key(struct il_priv *il, struct ieee80211_key_conf *keyconf) { int ret; @@ -2884,14 +2871,14 @@ il4965_remove_default_wep_key(struct il_priv *il, struct il_rxon_context *ctx, /* but keys in device are clear anyway so return success */ return 0; } - ret = il4965_static_wepkey_cmd(il, ctx, 1); + ret = il4965_static_wepkey_cmd(il, 1); D_WEP("Remove default WEP key: idx=%d ret=%d\n", idx, ret); return ret; } int -il4965_set_default_wep_key(struct il_priv *il, struct il_rxon_context *ctx, +il4965_set_default_wep_key(struct il_priv *il, struct ieee80211_key_conf *keyconf) { int ret; @@ -2912,14 +2899,14 @@ il4965_set_default_wep_key(struct il_priv *il, struct il_rxon_context *ctx, il->_4965.wep_keys[idx].key_size = len; memcpy(&il->_4965.wep_keys[idx].key, &keyconf->key, len); - ret = il4965_static_wepkey_cmd(il, ctx, false); + ret = il4965_static_wepkey_cmd(il, false); D_WEP("Set default WEP key: len=%d idx=%d ret=%d\n", len, idx, ret); return ret; } static int -il4965_set_wep_dynamic_key_info(struct il_priv *il, struct il_rxon_context *ctx, +il4965_set_wep_dynamic_key_info(struct il_priv *il, struct ieee80211_key_conf *keyconf, u8 sta_id) { unsigned long flags; @@ -2974,7 +2961,6 @@ il4965_set_wep_dynamic_key_info(struct il_priv *il, struct il_rxon_context *ctx, static int il4965_set_ccmp_dynamic_key_info(struct il_priv *il, - struct il_rxon_context *ctx, struct ieee80211_key_conf *keyconf, u8 sta_id) { unsigned long flags; @@ -3023,7 +3009,6 @@ il4965_set_ccmp_dynamic_key_info(struct il_priv *il, static int il4965_set_tkip_dynamic_key_info(struct il_priv *il, - struct il_rxon_context *ctx, struct ieee80211_key_conf *keyconf, u8 sta_id) { unsigned long flags; @@ -3068,9 +3053,8 @@ il4965_set_tkip_dynamic_key_info(struct il_priv *il, } void -il4965_update_tkip_key(struct il_priv *il, struct il_rxon_context *ctx, - struct ieee80211_key_conf *keyconf, - struct ieee80211_sta *sta, u32 iv32, u16 * phase1key) +il4965_update_tkip_key(struct il_priv *il, struct ieee80211_key_conf *keyconf, + struct ieee80211_sta *sta, u32 iv32, u16 *phase1key) { u8 sta_id; unsigned long flags; @@ -3082,7 +3066,7 @@ il4965_update_tkip_key(struct il_priv *il, struct il_rxon_context *ctx, return; } - sta_id = il_sta_id_or_broadcast(il, ctx, sta); + sta_id = il_sta_id_or_broadcast(il, sta); if (sta_id == IL_INVALID_STATION) return; @@ -3100,11 +3084,10 @@ il4965_update_tkip_key(struct il_priv *il, struct il_rxon_context *ctx, il_send_add_sta(il, &il->stations[sta_id].sta, CMD_ASYNC); spin_unlock_irqrestore(&il->sta_lock, flags); - } int -il4965_remove_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx, +il4965_remove_dynamic_key(struct il_priv *il, struct ieee80211_key_conf *keyconf, u8 sta_id) { unsigned long flags; @@ -3165,8 +3148,8 @@ il4965_remove_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx, } int -il4965_set_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx, - struct ieee80211_key_conf *keyconf, u8 sta_id) +il4965_set_dynamic_key(struct il_priv *il, struct ieee80211_key_conf *keyconf, + u8 sta_id) { int ret; @@ -3178,15 +3161,15 @@ il4965_set_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx, switch (keyconf->cipher) { case WLAN_CIPHER_SUITE_CCMP: ret = - il4965_set_ccmp_dynamic_key_info(il, ctx, keyconf, sta_id); + il4965_set_ccmp_dynamic_key_info(il, keyconf, sta_id); break; case WLAN_CIPHER_SUITE_TKIP: ret = - il4965_set_tkip_dynamic_key_info(il, ctx, keyconf, sta_id); + il4965_set_tkip_dynamic_key_info(il, keyconf, sta_id); break; case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: - ret = il4965_set_wep_dynamic_key_info(il, ctx, keyconf, sta_id); + ret = il4965_set_wep_dynamic_key_info(il, keyconf, sta_id); break; default: IL_ERR("Unknown alg: %s cipher = %x\n", __func__, @@ -3208,14 +3191,14 @@ il4965_set_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx, * device at the next best time. */ int -il4965_alloc_bcast_station(struct il_priv *il, struct il_rxon_context *ctx) +il4965_alloc_bcast_station(struct il_priv *il) { struct il_link_quality_cmd *link_cmd; unsigned long flags; u8 sta_id; spin_lock_irqsave(&il->sta_lock, flags); - sta_id = il_prep_station(il, ctx, il_bcast_addr, false, NULL); + sta_id = il_prep_station(il, il_bcast_addr, false, NULL); if (sta_id == IL_INVALID_STATION) { IL_ERR("Unable to prepare broadcast station\n"); spin_unlock_irqrestore(&il->sta_lock, flags); @@ -3248,7 +3231,7 @@ il4965_alloc_bcast_station(struct il_priv *il, struct il_rxon_context *ctx) * code together. */ static int -il4965_update_bcast_station(struct il_priv *il, struct il_rxon_context *ctx) +il4965_update_bcast_station(struct il_priv *il) { unsigned long flags; struct il_link_quality_cmd *link_cmd; @@ -3274,7 +3257,7 @@ il4965_update_bcast_station(struct il_priv *il, struct il_rxon_context *ctx) int il4965_update_bcast_stations(struct il_priv *il) { - return il4965_update_bcast_station(il, &il->ctx); + return il4965_update_bcast_station(il); } /** @@ -3375,9 +3358,9 @@ void il4965_update_chain_flags(struct il_priv *il) { if (il->cfg->ops->hcmd->set_rxon_chain) { - il->cfg->ops->hcmd->set_rxon_chain(il, &il->ctx); + il->cfg->ops->hcmd->set_rxon_chain(il); if (il->active.rx_chain != il->staging.rx_chain) - il_commit_rxon(il, &il->ctx); + il_commit_rxon(il); } } @@ -3489,8 +3472,8 @@ il4965_hw_get_beacon_cmd(struct il_priv *il, struct il_frame *frame) lockdep_assert_held(&il->mutex); - if (!il->beacon_ctx) { - IL_ERR("trying to build beacon w/o beacon context!\n"); + if (!il->beacon_enabled) { + IL_ERR("Trying to build beacon without beaconing enabled\n"); return 0; } @@ -3520,7 +3503,7 @@ il4965_hw_get_beacon_cmd(struct il_priv *il, struct il_frame *frame) frame_size); /* Set up packet rate and flags */ - rate = il_get_lowest_plcp(il, il->beacon_ctx); + rate = il_get_lowest_plcp(il); il4965_toggle_tx_ant(il, &il->mgmt_tx_ant, il->hw_params.valid_tx_ant); rate_flags = BIT(il->mgmt_tx_ant) << RATE_MCS_ANT_POS; if ((rate >= IL_FIRST_CCK_RATE) && (rate <= IL_LAST_CCK_RATE)) @@ -4977,7 +4960,6 @@ static void il4965_alive_start(struct il_priv *il) { int ret = 0; - struct il_rxon_context *ctx = &il->ctx; D_INFO("Runtime Alive received.\n"); @@ -5025,10 +5007,10 @@ il4965_alive_start(struct il_priv *il) active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; } else { /* Initialize our rx_config data */ - il_connection_init_rx_config(il, &il->ctx); + il_connection_init_rx_config(il); if (il->cfg->ops->hcmd->set_rxon_chain) - il->cfg->ops->hcmd->set_rxon_chain(il, ctx); + il->cfg->ops->hcmd->set_rxon_chain(il); } /* Configure bluetooth coexistence if enabled */ @@ -5039,7 +5021,7 @@ il4965_alive_start(struct il_priv *il) set_bit(S_READY, &il->status); /* Configure the adapter for unassociated operation */ - il_commit_rxon(il, ctx); + il_commit_rxon(il); /* At this point, the NIC is initialized and operational */ il4965_rf_kill_ct_config(il); @@ -5074,7 +5056,7 @@ __il4965_down(struct il_priv *il) * to prevent rearm timer */ del_timer_sync(&il->watchdog); - il_clear_ucode_stations(il, NULL); + il_clear_ucode_stations(il); /* FIXME: race conditions ? */ spin_lock_irq(&il->sta_lock); @@ -5239,7 +5221,7 @@ __il4965_up(struct il_priv *il) return -EIO; } - ret = il4965_alloc_bcast_station(il, &il->ctx); + ret = il4965_alloc_bcast_station(il); if (ret) { il_dealloc_bcast_stations(il); return ret; @@ -5393,7 +5375,8 @@ il4965_bg_restart(struct work_struct *data) if (test_and_clear_bit(S_FW_ERROR, &il->status)) { mutex_lock(&il->mutex); - il->ctx.vif = NULL; + /* FIXME: do we dereference vif without mutex locked ? */ + il->vif = NULL; il->is_open = 0; __il4965_down(il); @@ -5590,12 +5573,10 @@ il4965_mac_update_tkip_key(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u32 iv32, u16 * phase1key) { struct il_priv *il = hw->priv; - struct il_vif_priv *vif_priv = (void *)vif->drv_priv; D_MAC80211("enter\n"); - il4965_update_tkip_key(il, vif_priv->ctx, keyconf, sta, iv32, - phase1key); + il4965_update_tkip_key(il, keyconf, sta, iv32, phase1key); D_MAC80211("leave\n"); } @@ -5606,8 +5587,6 @@ il4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ieee80211_key_conf *key) { struct il_priv *il = hw->priv; - struct il_vif_priv *vif_priv = (void *)vif->drv_priv; - struct il_rxon_context *ctx = vif_priv->ctx; int ret; u8 sta_id; bool is_default_wep_key = false; @@ -5619,7 +5598,7 @@ il4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return -EOPNOTSUPP; } - sta_id = il_sta_id_or_broadcast(il, vif_priv->ctx, sta); + sta_id = il_sta_id_or_broadcast(il, sta); if (sta_id == IL_INVALID_STATION) return -EINVAL; @@ -5644,20 +5623,17 @@ il4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, switch (cmd) { case SET_KEY: if (is_default_wep_key) - ret = - il4965_set_default_wep_key(il, vif_priv->ctx, key); + ret = il4965_set_default_wep_key(il, key); else - ret = - il4965_set_dynamic_key(il, vif_priv->ctx, key, - sta_id); + ret = il4965_set_dynamic_key(il, key, sta_id); D_MAC80211("enable hwcrypto key\n"); break; case DISABLE_KEY: if (is_default_wep_key) - ret = il4965_remove_default_wep_key(il, ctx, key); + ret = il4965_remove_default_wep_key(il, key); else - ret = il4965_remove_dynamic_key(il, ctx, key, sta_id); + ret = il4965_remove_dynamic_key(il, key, sta_id); D_MAC80211("disable hwcrypto key\n"); break; @@ -5723,7 +5699,6 @@ il4965_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, { struct il_priv *il = hw->priv; struct il_station_priv *sta_priv = (void *)sta->drv_priv; - struct il_vif_priv *vif_priv = (void *)vif->drv_priv; bool is_ap = vif->type == NL80211_IFTYPE_STATION; int ret; u8 sta_id; @@ -5736,8 +5711,7 @@ il4965_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, atomic_set(&sta_priv->pending_frames, 0); ret = - il_add_station_common(il, vif_priv->ctx, sta->addr, is_ap, sta, - &sta_id); + il_add_station_common(il, sta->addr, is_ap, sta, &sta_id); if (ret) { IL_ERR("Unable to add station %pM (%d)\n", sta->addr, ret); /* Should we return success if return code is EEXIST ? */ @@ -5764,8 +5738,6 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw, struct ieee80211_conf *conf = &hw->conf; struct ieee80211_channel *channel = ch_switch->channel; struct il_ht_config *ht_conf = &il->current_ht_config; - - struct il_rxon_context *ctx = &il->ctx; u16 ch; D_MAC80211("enter\n"); @@ -5822,9 +5794,9 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw, if ((le16_to_cpu(il->staging.channel) != ch)) il->staging.flags = 0; - il_set_rxon_channel(il, channel, ctx); + il_set_rxon_channel(il, channel); il_set_rxon_ht(il, ht_conf); - il_set_flags_for_band(il, ctx, channel->band, ctx->vif); + il_set_flags_for_band(il, channel->band, il->vif); spin_unlock_irq(&il->lock); @@ -5838,7 +5810,7 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw, if (il->cfg->ops->lib->set_channel_switch(il, ch_switch)) { clear_bit(S_CHANNEL_SWITCH_PENDING, &il->status); il->switch_channel = 0; - ieee80211_chswitch_done(ctx->vif, false); + ieee80211_chswitch_done(il->vif, false); } out: @@ -6049,7 +6021,7 @@ il4965_init_drv(struct il_priv *il) /* Choose which receivers/antennas to use */ if (il->cfg->ops->hcmd->set_rxon_chain) - il->cfg->ops->hcmd->set_rxon_chain(il, &il->ctx); + il->cfg->ops->hcmd->set_rxon_chain(il); il_init_scan_params(il); diff --git a/drivers/net/wireless/iwlegacy/4965-rs.c b/drivers/net/wireless/iwlegacy/4965-rs.c index ad186d9a598..d7e2856e41d 100644 --- a/drivers/net/wireless/iwlegacy/4965-rs.c +++ b/drivers/net/wireless/iwlegacy/4965-rs.c @@ -820,8 +820,6 @@ il4965_rs_tx_status(void *il_r, struct ieee80211_supported_band *sband, u32 tx_rate; struct il_scale_tbl_info tbl_type; struct il_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; - struct il_station_priv *sta_priv = (void *)sta->drv_priv; - struct il_rxon_context *ctx = sta_priv->common.ctx; D_RATE("get frame ack response, update rate scale win\n"); @@ -889,7 +887,7 @@ il4965_rs_tx_status(void *il_r, struct ieee80211_supported_band *sband, lq_sta->missed_rate_counter++; if (lq_sta->missed_rate_counter > IL_MISSED_RATE_MAX) { lq_sta->missed_rate_counter = 0; - il_send_lq_cmd(il, ctx, &lq_sta->lq, CMD_ASYNC, false); + il_send_lq_cmd(il, &lq_sta->lq, CMD_ASYNC, false); } /* Regardless, ignore this status info for outdated rate */ return; @@ -1181,8 +1179,6 @@ il4965_rs_switch_to_mimo2(struct il_priv *il, struct il_lq_sta *lq_sta, u16 rate_mask; s32 rate; s8 is_green = lq_sta->is_green; - struct il_station_priv *sta_priv = (void *)sta->drv_priv; - struct il_rxon_context *ctx = sta_priv->common.ctx; if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) return -1; @@ -1203,7 +1199,7 @@ il4965_rs_switch_to_mimo2(struct il_priv *il, struct il_lq_sta *lq_sta, tbl->max_search = IL_MAX_SEARCH; rate_mask = lq_sta->active_mimo2_rate; - if (il_is_ht40_tx_allowed(il, ctx, &sta->ht_cap)) + if (il_is_ht40_tx_allowed(il, &sta->ht_cap)) tbl->is_ht40 = 1; else tbl->is_ht40 = 0; @@ -1237,8 +1233,6 @@ il4965_rs_switch_to_siso(struct il_priv *il, struct il_lq_sta *lq_sta, u16 rate_mask; u8 is_green = lq_sta->is_green; s32 rate; - struct il_station_priv *sta_priv = (void *)sta->drv_priv; - struct il_rxon_context *ctx = sta_priv->common.ctx; if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) return -1; @@ -1251,7 +1245,7 @@ il4965_rs_switch_to_siso(struct il_priv *il, struct il_lq_sta *lq_sta, tbl->max_search = IL_MAX_SEARCH; rate_mask = lq_sta->active_siso_rate; - if (il_is_ht40_tx_allowed(il, ctx, &sta->ht_cap)) + if (il_is_ht40_tx_allowed(il, &sta->ht_cap)) tbl->is_ht40 = 1; else tbl->is_ht40 = 0; @@ -1730,8 +1724,7 @@ il4965_rs_stay_in_table(struct il_lq_sta *lq_sta, bool force_search) * setup rate table in uCode */ static void -il4965_rs_update_rate_tbl(struct il_priv *il, struct il_rxon_context *ctx, - struct il_lq_sta *lq_sta, +il4965_rs_update_rate_tbl(struct il_priv *il, struct il_lq_sta *lq_sta, struct il_scale_tbl_info *tbl, int idx, u8 is_green) { u32 rate; @@ -1739,7 +1732,7 @@ il4965_rs_update_rate_tbl(struct il_priv *il, struct il_rxon_context *ctx, /* Update uCode's rate table. */ rate = il4965_rate_n_flags_from_tbl(il, tbl, idx, is_green); il4965_rs_fill_link_cmd(il, lq_sta, rate); - il_send_lq_cmd(il, ctx, &lq_sta->lq, CMD_ASYNC, false); + il_send_lq_cmd(il, &lq_sta->lq, CMD_ASYNC, false); } /* @@ -1775,8 +1768,6 @@ il4965_rs_rate_scale_perform(struct il_priv *il, struct sk_buff *skb, s32 sr; u8 tid = MAX_TID_COUNT; struct il_tid_data *tid_data; - struct il_station_priv *sta_priv = (void *)sta->drv_priv; - struct il_rxon_context *ctx = sta_priv->common.ctx; D_RATE("rate scale calculate new rate for skb\n"); @@ -1851,7 +1842,7 @@ il4965_rs_rate_scale_perform(struct il_priv *il, struct sk_buff *skb, tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); /* get "active" rate info */ idx = il4965_hwrate_to_plcp_idx(tbl->current_rate); - il4965_rs_update_rate_tbl(il, ctx, lq_sta, tbl, idx, + il4965_rs_update_rate_tbl(il, lq_sta, tbl, idx, is_green); } return; @@ -2054,8 +2045,7 @@ il4965_rs_rate_scale_perform(struct il_priv *il, struct sk_buff *skb, lq_update: /* Replace uCode's rate table for the destination station. */ if (update_lq) - il4965_rs_update_rate_tbl(il, ctx, lq_sta, tbl, idx, - is_green); + il4965_rs_update_rate_tbl(il, lq_sta, tbl, idx, is_green); /* Should we stay with this modulation mode, * or search for a new one? */ @@ -2095,7 +2085,7 @@ lq_update: D_RATE("Switch current mcs: %X idx: %d\n", tbl->current_rate, idx); il4965_rs_fill_link_cmd(il, lq_sta, tbl->current_rate); - il_send_lq_cmd(il, ctx, &lq_sta->lq, CMD_ASYNC, false); + il_send_lq_cmd(il, &lq_sta->lq, CMD_ASYNC, false); } else done_search = 1; } @@ -2167,13 +2157,11 @@ il4965_rs_initialize_lq(struct il_priv *il, struct ieee80211_conf *conf, u8 active_tbl = 0; u8 valid_tx_ant; struct il_station_priv *sta_priv; - struct il_rxon_context *ctx; if (!sta || !lq_sta) return; sta_priv = (void *)sta->drv_priv; - ctx = sta_priv->common.ctx; i = lq_sta->last_txrate_idx; @@ -2205,7 +2193,7 @@ il4965_rs_initialize_lq(struct il_priv *il, struct ieee80211_conf *conf, il4965_rs_set_expected_tpt_table(lq_sta, tbl); il4965_rs_fill_link_cmd(NULL, lq_sta, rate); il->stations[lq_sta->lq.sta_id].lq = &lq_sta->lq; - il_send_lq_cmd(il, ctx, &lq_sta->lq, CMD_SYNC, true); + il_send_lq_cmd(il, &lq_sta->lq, CMD_SYNC, true); } static void @@ -2576,9 +2564,6 @@ il4965_rs_sta_dbgfs_scale_table_write(struct file *file, char buf[64]; size_t buf_size; u32 parsed_rate; - struct il_station_priv *sta_priv = - container_of(lq_sta, struct il_station_priv, lq_sta); - struct il_rxon_context *ctx = sta_priv->common.ctx; il = lq_sta->drv; memset(buf, 0, sizeof(buf)); @@ -2600,7 +2585,7 @@ il4965_rs_sta_dbgfs_scale_table_write(struct file *file, if (lq_sta->dbg_fixed_rate) { il4965_rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate); - il_send_lq_cmd(lq_sta->drv, ctx, &lq_sta->lq, CMD_ASYNC, false); + il_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC, false); } return count; diff --git a/drivers/net/wireless/iwlegacy/4965.c b/drivers/net/wireless/iwlegacy/4965.c index 7b0192aff83..9d9197f7fa3 100644 --- a/drivers/net/wireless/iwlegacy/4965.c +++ b/drivers/net/wireless/iwlegacy/4965.c @@ -1370,7 +1370,7 @@ out: } static int -il4965_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx) +il4965_send_rxon_assoc(struct il_priv *il) { int ret = 0; struct il4965_rxon_assoc_cmd rxon_assoc; @@ -1409,7 +1409,7 @@ il4965_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx) } static int -il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) +il4965_commit_rxon(struct il_priv *il) { /* cast away the const for active_rxon in this function */ struct il_rxon_cmd *active_rxon = (void *)&il->active; @@ -1422,7 +1422,7 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) /* always get timestamp with Rx frame */ il->staging.flags |= RXON_FLG_TSF2HOST_MSK; - ret = il_check_rxon_cmd(il, ctx); + ret = il_check_rxon_cmd(il); if (ret) { IL_ERR("Invalid RXON configuration. Not committing.\n"); return -EINVAL; @@ -1442,15 +1442,15 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) /* If we don't need to send a full RXON, we can use * il_rxon_assoc_cmd which is used to reconfigure filter * and other flags for the current radio configuration. */ - if (!il_full_rxon_required(il, ctx)) { - ret = il_send_rxon_assoc(il, ctx); + if (!il_full_rxon_required(il)) { + ret = il_send_rxon_assoc(il); if (ret) { IL_ERR("Error setting RXON_ASSOC (%d)\n", ret); return ret; } memcpy(active_rxon, &il->staging, sizeof(*active_rxon)); - il_print_rx_config_cmd(il, ctx); + il_print_rx_config_cmd(il); /* * We do not commit tx power settings while channel changing, * do it now if tx power changed. @@ -1478,9 +1478,9 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) IL_ERR("Error clearing ASSOC_MSK (%d)\n", ret); return ret; } - il_clear_ucode_stations(il, ctx); - il_restore_stations(il, ctx); - ret = il4965_restore_default_wep_keys(il, ctx); + il_clear_ucode_stations(il); + il_restore_stations(il); + ret = il4965_restore_default_wep_keys(il); if (ret) { IL_ERR("Failed to restore WEP keys (%d)\n", ret); return ret; @@ -1491,7 +1491,7 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) "* channel = %d\n" "* bssid = %pM\n", (new_assoc ? "" : "out"), le16_to_cpu(il->staging.channel), il->staging.bssid_addr); - il_set_rxon_hwcrypto(il, ctx, !il->cfg->mod_params->sw_crypto); + il_set_rxon_hwcrypto(il, !il->cfg->mod_params->sw_crypto); /* Apply the new configuration * RXON unassoc clears the station table in uCode so restoration of @@ -1507,9 +1507,9 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) } D_INFO("Return from !new_assoc RXON.\n"); memcpy(active_rxon, &il->staging, sizeof(*active_rxon)); - il_clear_ucode_stations(il, ctx); - il_restore_stations(il, ctx); - ret = il4965_restore_default_wep_keys(il, ctx); + il_clear_ucode_stations(il); + il_restore_stations(il); + ret = il4965_restore_default_wep_keys(il); if (ret) { IL_ERR("Failed to restore WEP keys (%d)\n", ret); return ret; @@ -1529,7 +1529,7 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) } memcpy(active_rxon, &il->staging, sizeof(*active_rxon)); } - il_print_rx_config_cmd(il, ctx); + il_print_rx_config_cmd(il); il4965_init_sensitivity(il); @@ -1548,7 +1548,6 @@ static int il4965_hw_channel_switch(struct il_priv *il, struct ieee80211_channel_switch *ch_switch) { - struct il_rxon_context *ctx = &il->ctx; int rc; u8 band = 0; bool is_ht40 = false; @@ -1560,8 +1559,11 @@ il4965_hw_channel_switch(struct il_priv *il, u32 tsf_low; u8 switch_count; u16 beacon_interval = le16_to_cpu(il->timing.beacon_interval); - struct ieee80211_vif *vif = ctx->vif; - band = il->band == IEEE80211_BAND_2GHZ; + struct ieee80211_vif *vif = il->vif; + band = (il->band == IEEE80211_BAND_2GHZ); + + if (WARN_ON_ONCE(vif == NULL)) + return -EIO; is_ht40 = iw4965_is_ht40_channel(il->staging.flags); @@ -2128,21 +2130,18 @@ static struct il_hcmd_ops il4965_hcmd = { static void il4965_post_scan(struct il_priv *il) { - struct il_rxon_context *ctx = &il->ctx; - /* * Since setting the RXON may have been deferred while * performing the scan, fire one off if needed */ if (memcmp(&il->staging, &il->active, sizeof(il->staging))) - il_commit_rxon(il, ctx); + il_commit_rxon(il); } static void il4965_post_associate(struct il_priv *il) { - struct il_rxon_context *ctx = &il->ctx; - struct ieee80211_vif *vif = ctx->vif; + struct ieee80211_vif *vif = il->vif; struct ieee80211_conf *conf = NULL; int ret = 0; @@ -2157,9 +2156,9 @@ il4965_post_associate(struct il_priv *il) conf = &il->hw->conf; il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - il_commit_rxon(il, ctx); + il_commit_rxon(il); - ret = il_send_rxon_timing(il, ctx); + ret = il_send_rxon_timing(il); if (ret) IL_WARN("RXON timing - " "Attempting to continue.\n"); @@ -2168,7 +2167,7 @@ il4965_post_associate(struct il_priv *il) il_set_rxon_ht(il, &il->current_ht_config); if (il->cfg->ops->hcmd->set_rxon_chain) - il->cfg->ops->hcmd->set_rxon_chain(il, ctx); + il->cfg->ops->hcmd->set_rxon_chain(il); il->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid); @@ -2187,7 +2186,7 @@ il4965_post_associate(struct il_priv *il) il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; } - il_commit_rxon(il, ctx); + il_commit_rxon(il); D_ASSOC("Associated as %d to: %pM\n", vif->bss_conf.aid, il->active.bssid_addr); @@ -2218,8 +2217,7 @@ il4965_post_associate(struct il_priv *il) static void il4965_config_ap(struct il_priv *il) { - struct il_rxon_context *ctx = &il->ctx; - struct ieee80211_vif *vif = ctx->vif; + struct ieee80211_vif *vif = il->vif; int ret = 0; lockdep_assert_held(&il->mutex); @@ -2232,10 +2230,10 @@ il4965_config_ap(struct il_priv *il) /* RXON - unassoc (to set timing command) */ il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - il_commit_rxon(il, ctx); + il_commit_rxon(il); /* RXON Timing */ - ret = il_send_rxon_timing(il, ctx); + ret = il_send_rxon_timing(il); if (ret) IL_WARN("RXON timing failed - " "Attempting to continue.\n"); @@ -2244,7 +2242,7 @@ il4965_config_ap(struct il_priv *il) il->chain_noise_data.active_chains = il->hw_params.valid_rx_ant; il_set_rxon_ht(il, &il->current_ht_config); if (il->cfg->ops->hcmd->set_rxon_chain) - il->cfg->ops->hcmd->set_rxon_chain(il, ctx); + il->cfg->ops->hcmd->set_rxon_chain(il); il->staging.assoc_id = 0; @@ -2263,7 +2261,7 @@ il4965_config_ap(struct il_priv *il) il4965_send_beacon_cmd(il); /* restore RXON assoc */ il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; - il_commit_rxon(il, ctx); + il_commit_rxon(il); } il4965_send_beacon_cmd(il); } diff --git a/drivers/net/wireless/iwlegacy/4965.h b/drivers/net/wireless/iwlegacy/4965.h index f280e0161b1..67899602ee5 100644 --- a/drivers/net/wireless/iwlegacy/4965.h +++ b/drivers/net/wireless/iwlegacy/4965.h @@ -48,7 +48,7 @@ void il4965_free_tfds_in_queue(struct il_priv *il, int sta_id, int tid, int freed); /* RXON */ -void il4965_set_rxon_chain(struct il_priv *il, struct il_rxon_context *ctx); +void il4965_set_rxon_chain(struct il_priv *il); /* uCode */ int il4965_verify_ucode(struct il_priv *il); @@ -134,21 +134,18 @@ il4965_get_tx_fail_reason(u32 status) #endif /* station management */ -int il4965_alloc_bcast_station(struct il_priv *il, struct il_rxon_context *ctx); -int il4965_add_bssid_station(struct il_priv *il, struct il_rxon_context *ctx, - const u8 *addr, u8 *sta_id_r); +int il4965_alloc_bcast_station(struct il_priv *il); +int il4965_add_bssid_station(struct il_priv *il, const u8 *addr, u8 *sta_id_r); int il4965_remove_default_wep_key(struct il_priv *il, - struct il_rxon_context *ctx, struct ieee80211_key_conf *key); -int il4965_set_default_wep_key(struct il_priv *il, struct il_rxon_context *ctx, +int il4965_set_default_wep_key(struct il_priv *il, struct ieee80211_key_conf *key); -int il4965_restore_default_wep_keys(struct il_priv *il, - struct il_rxon_context *ctx); -int il4965_set_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx, +int il4965_restore_default_wep_keys(struct il_priv *il); +int il4965_set_dynamic_key(struct il_priv *il, struct ieee80211_key_conf *key, u8 sta_id); -int il4965_remove_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx, +int il4965_remove_dynamic_key(struct il_priv *il, struct ieee80211_key_conf *key, u8 sta_id); -void il4965_update_tkip_key(struct il_priv *il, struct il_rxon_context *ctx, +void il4965_update_tkip_key(struct il_priv *il, struct ieee80211_key_conf *keyconf, struct ieee80211_sta *sta, u32 iv32, u16 *phase1key); diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index ea2fa97fa36..bee11a3aeac 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -1442,7 +1442,6 @@ u16 il_get_passive_dwell_time(struct il_priv *il, enum ieee80211_band band, struct ieee80211_vif *vif) { - struct il_rxon_context *ctx = &il->ctx; u16 value; u16 passive = @@ -1457,7 +1456,7 @@ il_get_passive_dwell_time(struct il_priv *il, enum ieee80211_band band, * dwell time to be 98% of the smallest beacon interval * (minus 2 * channel tune time) */ - value = ctx->vif ? ctx->vif->bss_conf.beacon_int : 0; + value = il->vif ? il->vif->bss_conf.beacon_int : 0; if (value > IL_PASSIVE_DWELL_BASE || !value) value = IL_PASSIVE_DWELL_BASE; value = (value * 98) / 100 - IL_CHANNEL_TUNE_TIME * 2; @@ -1832,8 +1831,7 @@ il_send_add_sta(struct il_priv *il, struct il_addsta_cmd *sta, u8 flags) EXPORT_SYMBOL(il_send_add_sta); static void -il_set_ht_add_station(struct il_priv *il, u8 idx, struct ieee80211_sta *sta, - struct il_rxon_context *ctx) +il_set_ht_add_station(struct il_priv *il, u8 idx, struct ieee80211_sta *sta) { struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap; __le32 sta_flags; @@ -1874,7 +1872,7 @@ il_set_ht_add_station(struct il_priv *il, u8 idx, struct ieee80211_sta *sta, cpu_to_le32((u32) sta_ht_inf-> ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); - if (il_is_ht40_tx_allowed(il, ctx, &sta->ht_cap)) + if (il_is_ht40_tx_allowed(il, &sta->ht_cap)) sta_flags |= STA_FLG_HT40_EN_MSK; else sta_flags &= ~STA_FLG_HT40_EN_MSK; @@ -1890,8 +1888,8 @@ done: * should be called with sta_lock held */ u8 -il_prep_station(struct il_priv *il, struct il_rxon_context *ctx, - const u8 *addr, bool is_ap, struct ieee80211_sta *sta) +il_prep_station(struct il_priv *il, const u8 *addr, bool is_ap, + struct ieee80211_sta *sta) { struct il_station_entry *station; int i; @@ -1952,19 +1950,12 @@ il_prep_station(struct il_priv *il, struct il_rxon_context *ctx, station->sta.sta.sta_id = sta_id; station->sta.station_flags = 0; - if (sta) { - struct il_station_priv_common *sta_priv; - - sta_priv = (void *)sta->drv_priv; - sta_priv->ctx = ctx; - } - /* * OK to call unconditionally, since local stations (IBSS BSSID * STA and broadcast STA) pass in a NULL sta, and mac80211 * doesn't allow HT IBSS. */ - il_set_ht_add_station(il, sta_id, sta, ctx); + il_set_ht_add_station(il, sta_id, sta); /* 3945 only */ rate = (il->band == IEEE80211_BAND_5GHZ) ? RATE_6M_PLCP : RATE_1M_PLCP; @@ -1982,9 +1973,8 @@ EXPORT_SYMBOL_GPL(il_prep_station); * il_add_station_common - */ int -il_add_station_common(struct il_priv *il, struct il_rxon_context *ctx, - const u8 *addr, bool is_ap, struct ieee80211_sta *sta, - u8 *sta_id_r) +il_add_station_common(struct il_priv *il, const u8 *addr, bool is_ap, + struct ieee80211_sta *sta, u8 *sta_id_r) { unsigned long flags_spin; int ret = 0; @@ -1993,7 +1983,7 @@ il_add_station_common(struct il_priv *il, struct il_rxon_context *ctx, *sta_id_r = 0; spin_lock_irqsave(&il->sta_lock, flags_spin); - sta_id = il_prep_station(il, ctx, addr, is_ap, sta); + sta_id = il_prep_station(il, addr, is_ap, sta); if (sta_id == IL_INVALID_STATION) { IL_ERR("Unable to prepare station %pM for addition\n", addr); spin_unlock_irqrestore(&il->sta_lock, flags_spin); @@ -2180,7 +2170,7 @@ EXPORT_SYMBOL_GPL(il_remove_station); * the ucode, e.g. unassociated RXON. */ void -il_clear_ucode_stations(struct il_priv *il, struct il_rxon_context *ctx) +il_clear_ucode_stations(struct il_priv *il) { int i; unsigned long flags_spin; @@ -2212,7 +2202,7 @@ EXPORT_SYMBOL(il_clear_ucode_stations); * Function sleeps. */ void -il_restore_stations(struct il_priv *il, struct il_rxon_context *ctx) +il_restore_stations(struct il_priv *il) { struct il_addsta_cmd sta_cmd; struct il_link_quality_cmd lq; @@ -2267,7 +2257,7 @@ il_restore_stations(struct il_priv *il, struct il_rxon_context *ctx) * current LQ command */ if (send_lq) - il_send_lq_cmd(il, ctx, &lq, CMD_SYNC, true); + il_send_lq_cmd(il, &lq, CMD_SYNC, true); spin_lock_irqsave(&il->sta_lock, flags_spin); il->stations[i].used &= ~IL_STA_UCODE_INPROGRESS; } @@ -2347,8 +2337,7 @@ il_dump_lq_cmd(struct il_priv *il, struct il_link_quality_cmd *lq) * RXON flags are updated and when LQ command is updated. */ static bool -il_is_lq_table_valid(struct il_priv *il, struct il_rxon_context *ctx, - struct il_link_quality_cmd *lq) +il_is_lq_table_valid(struct il_priv *il, struct il_link_quality_cmd *lq) { int i; @@ -2376,8 +2365,8 @@ il_is_lq_table_valid(struct il_priv *il, struct il_rxon_context *ctx, * progress. */ int -il_send_lq_cmd(struct il_priv *il, struct il_rxon_context *ctx, - struct il_link_quality_cmd *lq, u8 flags, bool init) +il_send_lq_cmd(struct il_priv *il, struct il_link_quality_cmd *lq, + u8 flags, bool init) { int ret = 0; unsigned long flags_spin; @@ -2402,7 +2391,7 @@ il_send_lq_cmd(struct il_priv *il, struct il_rxon_context *ctx, il_dump_lq_cmd(il, lq); BUG_ON(init && (cmd.flags & CMD_ASYNC)); - if (il_is_lq_table_valid(il, ctx, lq)) + if (il_is_lq_table_valid(il, lq)) ret = il_send_cmd(il, &cmd); else ret = -EINVAL; @@ -3556,8 +3545,7 @@ il_is_channel_extension(struct il_priv *il, enum ieee80211_band band, } bool -il_is_ht40_tx_allowed(struct il_priv *il, struct il_rxon_context *ctx, - struct ieee80211_sta_ht_cap *ht_cap) +il_is_ht40_tx_allowed(struct il_priv *il, struct ieee80211_sta_ht_cap *ht_cap) { if (!il->ht.enabled || !il->ht.is_40mhz) return false; @@ -3615,13 +3603,13 @@ il_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val) } int -il_send_rxon_timing(struct il_priv *il, struct il_rxon_context *ctx) +il_send_rxon_timing(struct il_priv *il) { u64 tsf; s32 interval_tm, rem; struct ieee80211_conf *conf = NULL; u16 beacon_int; - struct ieee80211_vif *vif = ctx->vif; + struct ieee80211_vif *vif = il->vif; conf = &il->hw->conf; @@ -3664,8 +3652,7 @@ il_send_rxon_timing(struct il_priv *il, struct il_rxon_context *ctx) EXPORT_SYMBOL(il_send_rxon_timing); void -il_set_rxon_hwcrypto(struct il_priv *il, struct il_rxon_context *ctx, - int hw_decrypt) +il_set_rxon_hwcrypto(struct il_priv *il, int hw_decrypt) { struct il_rxon_cmd *rxon = &il->staging; @@ -3679,7 +3666,7 @@ EXPORT_SYMBOL(il_set_rxon_hwcrypto); /* validate RXON structure is valid */ int -il_check_rxon_cmd(struct il_priv *il, struct il_rxon_context *ctx) +il_check_rxon_cmd(struct il_priv *il) { struct il_rxon_cmd *rxon = &il->staging; bool error = false; @@ -3759,7 +3746,7 @@ EXPORT_SYMBOL(il_check_rxon_cmd); * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required. */ int -il_full_rxon_required(struct il_priv *il, struct il_rxon_context *ctx) +il_full_rxon_required(struct il_priv *il) { const struct il_rxon_cmd *staging = &il->staging; const struct il_rxon_cmd *active = &il->active; @@ -3813,7 +3800,7 @@ il_full_rxon_required(struct il_priv *il, struct il_rxon_context *ctx) EXPORT_SYMBOL(il_full_rxon_required); u8 -il_get_lowest_plcp(struct il_priv *il, struct il_rxon_context *ctx) +il_get_lowest_plcp(struct il_priv *il) { /* * Assign the lowest rate -- should really get this from @@ -3827,8 +3814,7 @@ il_get_lowest_plcp(struct il_priv *il, struct il_rxon_context *ctx) EXPORT_SYMBOL(il_get_lowest_plcp); static void -_il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf, - struct il_rxon_context *ctx) +_il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf) { struct il_rxon_cmd *rxon = &il->staging; @@ -3848,7 +3834,7 @@ _il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf, /* clear the HT channel mode before set the mode */ rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK | RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); - if (il_is_ht40_tx_allowed(il, ctx, NULL)) { + if (il_is_ht40_tx_allowed(il, NULL)) { /* pure ht40 */ if (il->ht.protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) { rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40; @@ -3886,7 +3872,7 @@ _il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf, } if (il->cfg->ops->hcmd->set_rxon_chain) - il->cfg->ops->hcmd->set_rxon_chain(il, ctx); + il->cfg->ops->hcmd->set_rxon_chain(il); D_ASSOC("rxon flags 0x%X operation mode :0x%X " "extension channel offset 0x%x\n", le32_to_cpu(rxon->flags), @@ -3896,7 +3882,7 @@ _il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf, void il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf) { - _il_set_rxon_ht(il, ht_conf, &il->ctx); + _il_set_rxon_ht(il, ht_conf); } EXPORT_SYMBOL(il_set_rxon_ht); @@ -3939,8 +3925,7 @@ EXPORT_SYMBOL(il_get_single_channel_number); * in the staging RXON flag structure based on the ch->band */ int -il_set_rxon_channel(struct il_priv *il, struct ieee80211_channel *ch, - struct il_rxon_context *ctx) +il_set_rxon_channel(struct il_priv *il, struct ieee80211_channel *ch) { enum ieee80211_band band = ch->band; u16 channel = ch->hw_value; @@ -3963,8 +3948,8 @@ il_set_rxon_channel(struct il_priv *il, struct ieee80211_channel *ch, EXPORT_SYMBOL(il_set_rxon_channel); void -il_set_flags_for_band(struct il_priv *il, struct il_rxon_context *ctx, - enum ieee80211_band band, struct ieee80211_vif *vif) +il_set_flags_for_band(struct il_priv *il, enum ieee80211_band band, + struct ieee80211_vif *vif) { if (band == IEEE80211_BAND_5GHZ) { il->staging.flags &= @@ -3989,35 +3974,26 @@ EXPORT_SYMBOL(il_set_flags_for_band); * initialize rxon structure with default values from eeprom */ void -il_connection_init_rx_config(struct il_priv *il, struct il_rxon_context *ctx) +il_connection_init_rx_config(struct il_priv *il) { const struct il_channel_info *ch_info; memset(&il->staging, 0, sizeof(il->staging)); - if (!ctx->vif) { + if (!il->vif) { il->staging.dev_type = RXON_DEV_TYPE_ESS; - } else - switch (ctx->vif->type) { - - case NL80211_IFTYPE_STATION: - il->staging.dev_type = RXON_DEV_TYPE_ESS; - il->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; - break; - - case NL80211_IFTYPE_ADHOC: - il->staging.dev_type = RXON_DEV_TYPE_IBSS; - il->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK; - il->staging.filter_flags = - RXON_FILTER_BCON_AWARE_MSK | - RXON_FILTER_ACCEPT_GRP_MSK; - break; - - default: - IL_ERR("Unsupported interface type %d\n", - ctx->vif->type); - break; - } + } else if (il->vif->type == NL80211_IFTYPE_STATION) { + il->staging.dev_type = RXON_DEV_TYPE_ESS; + il->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; + } else if (il->vif->type == NL80211_IFTYPE_ADHOC) { + il->staging.dev_type = RXON_DEV_TYPE_IBSS; + il->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK; + il->staging.filter_flags = + RXON_FILTER_BCON_AWARE_MSK | RXON_FILTER_ACCEPT_GRP_MSK; + } else { + IL_ERR("Unsupported interface type %d\n", il->vif->type); + return; + } #if 0 /* TODO: Figure out when short_preamble would be set and cache from @@ -4037,7 +4013,7 @@ il_connection_init_rx_config(struct il_priv *il, struct il_rxon_context *ctx) il->staging.channel = cpu_to_le16(ch_info->channel); il->band = ch_info->band; - il_set_flags_for_band(il, ctx, il->band, ctx->vif); + il_set_flags_for_band(il, il->band, il->vif); il->staging.ofdm_basic_rates = (IL_OFDM_RATES_MASK >> IL_FIRST_OFDM_RATE) & 0xFF; @@ -4047,8 +4023,8 @@ il_connection_init_rx_config(struct il_priv *il, struct il_rxon_context *ctx) /* clear both MIX and PURE40 mode flag */ il->staging.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED | RXON_FLG_CHANNEL_MODE_PURE_40); - if (ctx->vif) - memcpy(il->staging.node_addr, ctx->vif->addr, ETH_ALEN); + if (il->vif) + memcpy(il->staging.node_addr, il->vif->addr, ETH_ALEN); il->staging.ofdm_ht_single_stream_basic_rates = 0xff; il->staging.ofdm_ht_dual_stream_basic_rates = 0xff; @@ -4089,13 +4065,11 @@ EXPORT_SYMBOL(il_set_rate); void il_chswitch_done(struct il_priv *il, bool is_success) { - struct il_rxon_context *ctx = &il->ctx; - if (test_bit(S_EXIT_PENDING, &il->status)) return; if (test_and_clear_bit(S_CHANNEL_SWITCH_PENDING, &il->status)) - ieee80211_chswitch_done(ctx->vif, is_success); + ieee80211_chswitch_done(il->vif, is_success); } EXPORT_SYMBOL(il_chswitch_done); @@ -4124,7 +4098,7 @@ EXPORT_SYMBOL(il_hdl_csa); #ifdef CONFIG_IWLEGACY_DEBUG void -il_print_rx_config_cmd(struct il_priv *il, struct il_rxon_context *ctx) +il_print_rx_config_cmd(struct il_priv *il) { struct il_rxon_cmd *rxon = &il->staging; @@ -4161,7 +4135,7 @@ il_irq_handle_error(struct il_priv *il) il->cfg->ops->lib->dump_fh(il, NULL, false); #ifdef CONFIG_IWLEGACY_DEBUG if (il_get_debug_level(il) & IL_DL_FW_ERRORS) - il_print_rx_config_cmd(il, &il->ctx); + il_print_rx_config_cmd(il); #endif wake_up(&il->wait_command_queue); @@ -4523,21 +4497,20 @@ il_mac_tx_last_beacon(struct ieee80211_hw *hw) EXPORT_SYMBOL_GPL(il_mac_tx_last_beacon); static int -il_set_mode(struct il_priv *il, struct il_rxon_context *ctx) +il_set_mode(struct il_priv *il) { - il_connection_init_rx_config(il, ctx); + il_connection_init_rx_config(il); if (il->cfg->ops->hcmd->set_rxon_chain) - il->cfg->ops->hcmd->set_rxon_chain(il, ctx); + il->cfg->ops->hcmd->set_rxon_chain(il); - return il_commit_rxon(il, ctx); + return il_commit_rxon(il); } int il_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct il_priv *il = hw->priv; - struct il_vif_priv *vif_priv = (void *)vif->drv_priv; int err; D_MAC80211("enter: type %d, addr %pM\n", vif->type, vif->addr); @@ -4550,18 +4523,17 @@ il_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) goto out; } - if (il->ctx.vif) { + if (il->vif) { err = -EOPNOTSUPP; goto out; } - vif_priv->ctx = &il->ctx; - il->ctx.vif = vif; + il->vif = vif; il->iw_mode = vif->type; - err = il_set_mode(il, &il->ctx); + err = il_set_mode(il); if (err) { - il->ctx.vif = NULL; + il->vif = NULL; il->iw_mode = NL80211_IFTYPE_STATION; } @@ -4577,8 +4549,6 @@ static void il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif, bool mode_change) { - struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif); - lockdep_assert_held(&il->mutex); if (il->scan_vif == vif) { @@ -4587,7 +4557,7 @@ il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif, } if (!mode_change) - il_set_mode(il, ctx); + il_set_mode(il); } @@ -4595,14 +4565,13 @@ void il_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct il_priv *il = hw->priv; - struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif); D_MAC80211("enter\n"); mutex_lock(&il->mutex); - WARN_ON(ctx->vif != vif); - ctx->vif = NULL; + WARN_ON(il->vif != vif); + il->vif = NULL; il_teardown_interface(il, vif, false); @@ -4941,7 +4910,6 @@ il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum nl80211_iftype newtype, bool newp2p) { struct il_priv *il = hw->priv; - struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif); int err; if (newp2p) @@ -4949,7 +4917,7 @@ il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mutex_lock(&il->mutex); - if (!ctx->vif || !il_is_ready_rf(il)) { + if (!il->vif || !il_is_ready_rf(il)) { /* * Huh? But wait ... this can maybe happen when * we're in the middle of a firmware restart! @@ -4962,7 +4930,7 @@ il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, il_teardown_interface(il, vif, true); vif->type = newtype; vif->p2p = false; - err = il_set_mode(il, ctx); + err = il_set_mode(il); WARN_ON(err); /* * We've switched internally, but submitting to the @@ -5194,7 +5162,7 @@ EXPORT_SYMBOL(il_pm_ops); #endif /* CONFIG_PM */ static void -il_update_qos(struct il_priv *il, struct il_rxon_context *ctx) +il_update_qos(struct il_priv *il) { if (test_bit(S_EXIT_PENDING, &il->status)) return; @@ -5226,7 +5194,6 @@ il_mac_config(struct ieee80211_hw *hw, u32 changed) struct ieee80211_conf *conf = &hw->conf; struct ieee80211_channel *channel = conf->channel; struct il_ht_config *ht_conf = &il->current_ht_config; - struct il_rxon_context *ctx = &il->ctx; unsigned long flags = 0; int ret = 0; u16 ch; @@ -5259,7 +5226,7 @@ il_mac_config(struct ieee80211_hw *hw, u32 changed) * configured. */ if (il->cfg->ops->hcmd->set_rxon_chain) - il->cfg->ops->hcmd->set_rxon_chain(il, &il->ctx); + il->cfg->ops->hcmd->set_rxon_chain(il); } /* during scanning mac80211 will delay channel setting until @@ -5321,10 +5288,10 @@ il_mac_config(struct ieee80211_hw *hw, u32 changed) if ((le16_to_cpu(il->staging.channel) != ch)) il->staging.flags = 0; - il_set_rxon_channel(il, channel, ctx); + il_set_rxon_channel(il, channel); il_set_rxon_ht(il, ht_conf); - il_set_flags_for_band(il, ctx, channel->band, ctx->vif); + il_set_flags_for_band(il, channel->band, il->vif); spin_unlock_irqrestore(&il->lock, flags); @@ -5360,11 +5327,11 @@ set_ch_out: goto out; if (memcmp(&il->active, &il->staging, sizeof(il->staging))) - il_commit_rxon(il, ctx); + il_commit_rxon(il); else D_INFO("Not re-sending same RXON configuration.\n"); if (ht_changed) - il_update_qos(il, ctx); + il_update_qos(il); out: D_MAC80211("leave\n"); @@ -5378,7 +5345,6 @@ il_mac_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct il_priv *il = hw->priv; unsigned long flags; - struct il_rxon_context *ctx = &il->ctx; if (WARN_ON(!il->cfg->ops->legacy)) return; @@ -5413,7 +5379,7 @@ il_mac_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) * clear RXON_FILTER_ASSOC_MSK bit */ il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - il_commit_rxon(il, ctx); + il_commit_rxon(il); il_set_rate(il); @@ -5486,8 +5452,6 @@ il_ht_conf(struct il_priv *il, struct ieee80211_vif *vif) static inline void il_set_no_assoc(struct il_priv *il, struct ieee80211_vif *vif) { - struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif); - /* * inform the ucode that there is no longer an * association and that no more packets should be @@ -5495,7 +5459,7 @@ il_set_no_assoc(struct il_priv *il, struct ieee80211_vif *vif) */ il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; il->staging.assoc_id = 0; - il_commit_rxon(il, ctx); + il_commit_rxon(il); } static void @@ -5513,8 +5477,8 @@ il_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) lockdep_assert_held(&il->mutex); - if (!il->beacon_ctx) { - IL_ERR("update beacon but no beacon context!\n"); + if (!il->beacon_enabled) { + IL_ERR("update beacon with no beaconing enabled\n"); dev_kfree_skb(skb); return; } @@ -5545,7 +5509,6 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, u32 changes) { struct il_priv *il = hw->priv; - struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif); int ret; if (WARN_ON(!il->cfg->ops->legacy)) @@ -5565,20 +5528,16 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, spin_lock_irqsave(&il->lock, flags); il->qos_data.qos_active = bss_conf->qos; - il_update_qos(il, ctx); + il_update_qos(il); spin_unlock_irqrestore(&il->lock, flags); } if (changes & BSS_CHANGED_BEACON_ENABLED) { - /* - * the add_interface code must make sure we only ever - * have a single interface that could be beaconing at - * any time. - */ + /* FIXME: can we remove beacon_enabled ? */ if (vif->bss_conf.enable_beacon) - il->beacon_ctx = ctx; + il->beacon_enabled = true; else - il->beacon_ctx = NULL; + il->beacon_enabled = false; } if (changes & BSS_CHANGED_BSSID) { @@ -5658,7 +5617,7 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, il_ht_conf(il, vif); if (il->cfg->ops->hcmd->set_rxon_chain) - il->cfg->ops->hcmd->set_rxon_chain(il, ctx); + il->cfg->ops->hcmd->set_rxon_chain(il); } if (changes & BSS_CHANGED_ASSOC) { @@ -5674,7 +5633,7 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (changes && il_is_associated(il) && bss_conf->aid) { D_MAC80211("Changes (%#x) while associated\n", changes); - ret = il_send_rxon_assoc(il, ctx); + ret = il_send_rxon_assoc(il); if (!ret) { /* Sync active_rxon with latest change. */ memcpy((void *)&il->active, &il->staging, diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index 51c1eecf751..746eec08886 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -146,7 +146,6 @@ struct il_queue { /* One for each TFD */ struct il_tx_info { struct sk_buff *skb; - struct il_rxon_context *ctx; }; /** @@ -741,7 +740,6 @@ struct il_station_entry { }; struct il_station_priv_common { - struct il_rxon_context *ctx; u8 sta_id; }; @@ -752,7 +750,6 @@ struct il_station_priv_common { * space for us to put data into. */ struct il_vif_priv { - struct il_rxon_context *ctx; u8 ibss_bssid_sta_id; }; @@ -1257,7 +1254,7 @@ struct il_priv { u8 ucode_write_complete; /* the image write is complete */ char firmware_name[25]; - struct il_rxon_context ctx; + struct ieee80211_vif *vif; struct il_qos_info qos_data; @@ -1426,7 +1423,7 @@ struct il_priv { struct work_struct rx_replenish; struct work_struct abort_scan; - struct il_rxon_context *beacon_ctx; + bool beacon_enabled; struct sk_buff *beacon_skb; struct work_struct tx_flush; @@ -1493,17 +1490,6 @@ il_tx_queue_get_hdr(struct il_priv *il, int txq_id, int idx) return NULL; } -static inline struct il_rxon_context * -il_rxon_ctx_from_vif(struct ieee80211_vif *vif) -{ - struct il_vif_priv *vif_priv = (void *)vif->drv_priv; - - return vif_priv->ctx; -} - -#define for_each_context(il, _ctx) \ - for (_ctx = &il->ctx; _ctx == &il->ctx; _ctx++) - static inline int il_is_associated(struct il_priv *il) { @@ -1585,10 +1571,9 @@ il_free_pages(struct il_priv *il, unsigned long page) #define IL_RX_BUF_SIZE_8K (8 * 1024) struct il_hcmd_ops { - int (*rxon_assoc) (struct il_priv *il, struct il_rxon_context *ctx); - int (*commit_rxon) (struct il_priv *il, struct il_rxon_context *ctx); - void (*set_rxon_chain) (struct il_priv *il, - struct il_rxon_context *ctx); + int (*rxon_assoc) (struct il_priv *il); + int (*commit_rxon) (struct il_priv *il); + void (*set_rxon_chain) (struct il_priv *il); }; struct il_hcmd_utils_ops { @@ -1811,20 +1796,17 @@ int il_mac_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, const struct ieee80211_tx_queue_params *params); int il_mac_tx_last_beacon(struct ieee80211_hw *hw); -void il_set_rxon_hwcrypto(struct il_priv *il, struct il_rxon_context *ctx, - int hw_decrypt); -int il_check_rxon_cmd(struct il_priv *il, struct il_rxon_context *ctx); -int il_full_rxon_required(struct il_priv *il, struct il_rxon_context *ctx); -int il_set_rxon_channel(struct il_priv *il, struct ieee80211_channel *ch, - struct il_rxon_context *ctx); -void il_set_flags_for_band(struct il_priv *il, struct il_rxon_context *ctx, - enum ieee80211_band band, struct ieee80211_vif *vif); +void il_set_rxon_hwcrypto(struct il_priv *il, int hw_decrypt); +int il_check_rxon_cmd(struct il_priv *il); +int il_full_rxon_required(struct il_priv *il); +int il_set_rxon_channel(struct il_priv *il, struct ieee80211_channel *ch); +void il_set_flags_for_band(struct il_priv *il, enum ieee80211_band band, + struct ieee80211_vif *vif); u8 il_get_single_channel_number(struct il_priv *il, enum ieee80211_band band); void il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf); -bool il_is_ht40_tx_allowed(struct il_priv *il, struct il_rxon_context *ctx, +bool il_is_ht40_tx_allowed(struct il_priv *il, struct ieee80211_sta_ht_cap *ht_cap); -void il_connection_init_rx_config(struct il_priv *il, - struct il_rxon_context *ctx); +void il_connection_init_rx_config(struct il_priv *il); void il_set_rate(struct il_priv *il); int il_set_decrypted_flag(struct il_priv *il, struct ieee80211_hdr *hdr, u32 decrypt_res, struct ieee80211_rx_status *stats); @@ -1927,7 +1909,7 @@ int il_set_tx_power(struct il_priv *il, s8 tx_power, bool force); * Rate ******************************************************************************/ -u8 il_get_lowest_plcp(struct il_priv *il, struct il_rxon_context *ctx); +u8 il_get_lowest_plcp(struct il_priv *il); /******************************************************************************* * Scanning @@ -2014,10 +1996,10 @@ extern const struct dev_pm_ops il_pm_ops; ******************************************************/ void il4965_dump_nic_error_log(struct il_priv *il); #ifdef CONFIG_IWLEGACY_DEBUG -void il_print_rx_config_cmd(struct il_priv *il, struct il_rxon_context *ctx); +void il_print_rx_config_cmd(struct il_priv *il); #else static inline void -il_print_rx_config_cmd(struct il_priv *il, struct il_rxon_context *ctx) +il_print_rx_config_cmd(struct il_priv *il) { } #endif @@ -2106,17 +2088,18 @@ extern int il_send_stats_request(struct il_priv *il, u8 flags, bool clear); void il_apm_stop(struct il_priv *il); int il_apm_init(struct il_priv *il); -int il_send_rxon_timing(struct il_priv *il, struct il_rxon_context *ctx); +int il_send_rxon_timing(struct il_priv *il); + static inline int -il_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx) +il_send_rxon_assoc(struct il_priv *il) { - return il->cfg->ops->hcmd->rxon_assoc(il, ctx); + return il->cfg->ops->hcmd->rxon_assoc(il); } static inline int -il_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) +il_commit_rxon(struct il_priv *il) { - return il->cfg->ops->hcmd->commit_rxon(il, ctx); + return il->cfg->ops->hcmd->commit_rxon(il); } static inline const struct ieee80211_supported_band * @@ -2274,23 +2257,22 @@ il_clear_bits_prph(struct il_priv *il, u32 reg, u32 mask) (this is for the IBSS BSSID stations) */ #define IL_STA_BCAST BIT(4) /* this station is the special bcast station */ -void il_restore_stations(struct il_priv *il, struct il_rxon_context *ctx); -void il_clear_ucode_stations(struct il_priv *il, struct il_rxon_context *ctx); +void il_restore_stations(struct il_priv *il); +void il_clear_ucode_stations(struct il_priv *il); void il_dealloc_bcast_stations(struct il_priv *il); int il_get_free_ucode_key_idx(struct il_priv *il); int il_send_add_sta(struct il_priv *il, struct il_addsta_cmd *sta, u8 flags); -int il_add_station_common(struct il_priv *il, struct il_rxon_context *ctx, - const u8 *addr, bool is_ap, +int il_add_station_common(struct il_priv *il, const u8 *addr, bool is_ap, struct ieee80211_sta *sta, u8 *sta_id_r); int il_remove_station(struct il_priv *il, const u8 sta_id, const u8 * addr); int il_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); -u8 il_prep_station(struct il_priv *il, struct il_rxon_context *ctx, - const u8 *addr, bool is_ap, struct ieee80211_sta *sta); +u8 il_prep_station(struct il_priv *il, const u8 *addr, bool is_ap, + struct ieee80211_sta *sta); -int il_send_lq_cmd(struct il_priv *il, struct il_rxon_context *ctx, - struct il_link_quality_cmd *lq, u8 flags, bool init); +int il_send_lq_cmd(struct il_priv *il, struct il_link_quality_cmd *lq, + u8 flags, bool init); /** * il_clear_driver_stations - clear knowledge of all stations from driver @@ -2334,8 +2316,7 @@ il_sta_id(struct ieee80211_sta *sta) * inline wraps that pattern. */ static inline int -il_sta_id_or_broadcast(struct il_priv *il, struct il_rxon_context *context, - struct ieee80211_sta *sta) +il_sta_id_or_broadcast(struct il_priv *il, struct ieee80211_sta *sta) { int sta_id; -- cgit v1.2.3-70-g09d2 From c39ae9fd505ae314a7a4a159a41e3e022cfa317f Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 3 Feb 2012 17:31:58 +0100 Subject: iwlegacy: move ops out of config Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/3945-mac.c | 22 +++--- drivers/net/wireless/iwlegacy/3945.c | 13 ++-- drivers/net/wireless/iwlegacy/3945.h | 4 +- drivers/net/wireless/iwlegacy/4965-calib.c | 4 +- drivers/net/wireless/iwlegacy/4965-mac.c | 78 +++++++++++-------- drivers/net/wireless/iwlegacy/4965.c | 34 ++------- drivers/net/wireless/iwlegacy/4965.h | 3 +- drivers/net/wireless/iwlegacy/common.c | 115 +++++++++++------------------ drivers/net/wireless/iwlegacy/common.h | 8 +- drivers/net/wireless/iwlegacy/debug.c | 13 ++-- 10 files changed, 127 insertions(+), 167 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c index b2e04c591c6..40ce692b2c9 100644 --- a/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/iwlegacy/3945-mac.c @@ -618,8 +618,7 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb) /* Add buffer containing Tx command and MAC(!) header to TFD's * first entry */ - il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq, txcmd_phys, len, 1, - 0); + il->ops->lib->txq_attach_buf_to_tfd(il, txq, txcmd_phys, len, 1, 0); /* Set up TFD's 2nd entry to point directly to remainder of skb, * if any (802.11 null frames have no payload). */ @@ -628,8 +627,8 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb) phys_addr = pci_map_single(il->pci_dev, skb->data + hdr_len, len, PCI_DMA_TODEVICE); - il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq, phys_addr, - len, 0, U32_PAD(len)); + il->ops->lib->txq_attach_buf_to_tfd(il, txq, phys_addr, len, 0, + U32_PAD(len)); } /* Tell device the write idx *just past* this latest filled TFD */ @@ -2416,7 +2415,7 @@ __il3945_up(struct il_priv *il) /* load bootstrap state machine, * load bootstrap program into processor's memory, * prepare to load the "initialize" uCode */ - rc = il->cfg->ops->lib->load_ucode(il); + rc = il->ops->lib->load_ucode(il); if (rc) { IL_ERR("Unable to set up bootstrap uCode: %d\n", rc); @@ -3458,7 +3457,7 @@ static struct attribute_group il3945_attribute_group = { .attrs = il3945_sysfs_entries, }; -struct ieee80211_ops il3945_hw_ops = { +struct ieee80211_ops il3945_mac_ops = { .tx = il3945_mac_tx, .start = il3945_mac_start, .stop = il3945_mac_stop, @@ -3599,15 +3598,13 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * 1. Allocating HW data * ********************/ - /* mac80211 allocates memory for this device instance, including - * space for this driver's ilate structure */ - hw = il_alloc_all(cfg); - if (hw == NULL) { - pr_err("Can not allocate network device\n"); + hw = ieee80211_alloc_hw(sizeof(struct il_priv), &il3945_mac_ops); + if (!hw) { err = -ENOMEM; goto out; } il = hw->priv; + il->hw = hw; SET_IEEE80211_DEV(hw, &pdev->dev); il->cmd_queue = IL39_CMD_QUEUE_NUM; @@ -3618,11 +3615,12 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) */ if (il3945_mod_params.disable_hw_scan) { D_INFO("Disabling hw_scan\n"); - il3945_hw_ops.hw_scan = NULL; + il3945_mac_ops.hw_scan = NULL; } D_INFO("*** LOAD DRIVER ***\n"); il->cfg = cfg; + il->ops = &il3945_ops; il->pci_dev = pdev; il->inta_mask = CSR_INI_SET_MASK; diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c index 1e617c9fc3c..918cbefd657 100644 --- a/drivers/net/wireless/iwlegacy/3945.c +++ b/drivers/net/wireless/iwlegacy/3945.c @@ -303,7 +303,7 @@ il3945_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx) tx_info = &txq->txb[txq->q.read_ptr]; ieee80211_tx_status_irqsafe(il->hw, tx_info->skb); tx_info->skb = NULL; - il->cfg->ops->lib->txq_free_tfd(il, txq); + il->ops->lib->txq_free_tfd(il, txq); } if (il_queue_space(q) > q->low_mark && txq_id >= 0 && @@ -960,12 +960,12 @@ il3945_hw_nic_init(struct il_priv *il) struct il_rx_queue *rxq = &il->rxq; spin_lock_irqsave(&il->lock, flags); - il->cfg->ops->lib->apm_ops.init(il); + il->ops->lib->apm_ops.init(il); spin_unlock_irqrestore(&il->lock, flags); il3945_set_pwr_vmain(il); - il->cfg->ops->lib->apm_ops.config(il); + il->ops->lib->apm_ops.config(il); /* Allocate the RX queue, or reset if it is already allocated */ if (!rxq->bd) { @@ -1615,7 +1615,7 @@ il3945_hw_reg_comp_txpower_temp(struct il_priv *il) } /* send Txpower command for current channel to ucode */ - return il->cfg->ops->lib->send_tx_power(il); + return il->ops->lib->send_tx_power(il); } int @@ -2685,13 +2685,12 @@ static struct il_hcmd_utils_ops il3945_hcmd_utils = { .post_scan = il3945_post_scan, }; -static const struct il_ops il3945_ops = { +const struct il_ops il3945_ops = { .lib = &il3945_lib, .hcmd = &il3945_hcmd, .utils = &il3945_hcmd_utils, .led = &il3945_led_ops, .legacy = &il3945_legacy_ops, - .ieee80211_ops = &il3945_hw_ops, }; static struct il_base_params il3945_base_params = { @@ -2711,7 +2710,6 @@ static struct il_cfg il3945_bg_cfg = { .ucode_api_min = IL3945_UCODE_API_MIN, .sku = IL_SKU_G, .eeprom_ver = EEPROM_3945_EEPROM_VERSION, - .ops = &il3945_ops, .mod_params = &il3945_mod_params, .base_params = &il3945_base_params, .led_mode = IL_LED_BLINK, @@ -2724,7 +2722,6 @@ static struct il_cfg il3945_abg_cfg = { .ucode_api_min = IL3945_UCODE_API_MIN, .sku = IL_SKU_A | IL_SKU_G, .eeprom_ver = EEPROM_3945_EEPROM_VERSION, - .ops = &il3945_ops, .mod_params = &il3945_mod_params, .base_params = &il3945_base_params, .led_mode = IL_LED_BLINK, diff --git a/drivers/net/wireless/iwlegacy/3945.h b/drivers/net/wireless/iwlegacy/3945.h index 8bee127d413..c00a8d30b6f 100644 --- a/drivers/net/wireless/iwlegacy/3945.h +++ b/drivers/net/wireless/iwlegacy/3945.h @@ -36,6 +36,8 @@ extern const struct pci_device_id il3945_hw_card_ids[]; #include "common.h" +extern const struct il_ops il3945_ops; + /* Highest firmware API version supported */ #define IL3945_UCODE_API_MAX 2 @@ -261,8 +263,6 @@ extern int il3945_commit_rxon(struct il_priv *il); */ extern u8 il3945_hw_find_station(struct il_priv *il, const u8 * bssid); -extern struct ieee80211_ops il3945_hw_ops; - extern __le32 il3945_get_antenna_flags(const struct il_priv *il); extern int il3945_init_hw_rate_table(struct il_priv *il); extern void il3945_reg_txpower_periodic(struct il_priv *il); diff --git a/drivers/net/wireless/iwlegacy/4965-calib.c b/drivers/net/wireless/iwlegacy/4965-calib.c index f302a6ac628..bfb361dbba5 100644 --- a/drivers/net/wireless/iwlegacy/4965-calib.c +++ b/drivers/net/wireless/iwlegacy/4965-calib.c @@ -923,8 +923,8 @@ il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp) /* Some power changes may have been made during the calibration. * Update and commit the RXON */ - if (il->cfg->ops->lib->update_chain_flags) - il->cfg->ops->lib->update_chain_flags(il); + if (il->ops->lib->update_chain_flags) + il->ops->lib->update_chain_flags(il); data->state = IL_CHAIN_NOISE_DONE; il_power_update_mode(il, false); diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 4be53cc9198..2bf743fc782 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -201,7 +201,7 @@ il4965_hw_nic_init(struct il_priv *il) /* nic_init */ spin_lock_irqsave(&il->lock, flags); - il->cfg->ops->lib->apm_ops.init(il); + il->ops->lib->apm_ops.init(il); /* Set interrupt coalescing calibration timer to default (512 usecs) */ il_write8(il, CSR_INT_COALESCING, IL_HOST_INT_CALIB_TIMEOUT_DEF); @@ -210,7 +210,7 @@ il4965_hw_nic_init(struct il_priv *il) il4965_set_pwr_vmain(il); - il->cfg->ops->lib->apm_ops.config(il); + il->ops->lib->apm_ops.config(il); /* Allocate the RX queue, or reset if it is already allocated */ if (!rxq->bd) { @@ -1381,8 +1381,8 @@ il4965_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb) il4965_rx_calc_noise(il); queue_work(il->workqueue, &il->run_time_calib_work); } - if (il->cfg->ops->lib->temp_ops.temperature && change) - il->cfg->ops->lib->temp_ops.temperature(il); + if (il->ops->lib->temp_ops.temperature && change) + il->ops->lib->temp_ops.temperature(il); } void @@ -1817,8 +1817,7 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb) dma_unmap_len_set(out_meta, len, firstlen); /* Add buffer containing Tx command and MAC(!) header to TFD's * first entry */ - il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq, txcmd_phys, firstlen, - 1, 0); + il->ops->lib->txq_attach_buf_to_tfd(il, txq, txcmd_phys, firstlen, 1, 0); if (!ieee80211_has_morefrags(hdr->frame_control)) { txq->need_update = 1; @@ -1834,8 +1833,8 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb) phys_addr = pci_map_single(il->pci_dev, skb->data + hdr_len, secondlen, PCI_DMA_TODEVICE); - il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq, phys_addr, - secondlen, 0, 0); + il->ops->lib->txq_attach_buf_to_tfd(il, txq, phys_addr, + secondlen, 0, 0); } scratch_phys = @@ -1855,9 +1854,8 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb) /* Set up entry for this TFD in Tx byte-count array */ if (info->flags & IEEE80211_TX_CTL_AMPDU) - il->cfg->ops->lib->txq_update_byte_cnt_tbl(il, txq, - le16_to_cpu(tx_cmd-> - len)); + il->ops->lib->txq_update_byte_cnt_tbl(il, txq, + le16_to_cpu(tx_cmd->len)); pci_dma_sync_single_for_device(il->pci_dev, txcmd_phys, firstlen, PCI_DMA_BIDIRECTIONAL); @@ -2479,7 +2477,7 @@ il4965_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx) txq_id >= IL4965_FIRST_AMPDU_QUEUE); tx_info->skb = NULL; - il->cfg->ops->lib->txq_free_tfd(il, txq); + il->ops->lib->txq_free_tfd(il, txq); } return nfreed; } @@ -3357,8 +3355,8 @@ il4965_sta_modify_sleep_tx_count(struct il_priv *il, int sta_id, int cnt) void il4965_update_chain_flags(struct il_priv *il) { - if (il->cfg->ops->hcmd->set_rxon_chain) { - il->cfg->ops->hcmd->set_rxon_chain(il); + if (il->ops->hcmd->set_rxon_chain) { + il->ops->hcmd->set_rxon_chain(il); if (il->active.rx_chain != il->staging.rx_chain) il_commit_rxon(il); } @@ -3878,7 +3876,7 @@ il4965_setup_handlers(struct il_priv *il) /* block ack */ il->handlers[N_COMPRESSED_BA] = il4965_hdl_compressed_ba; /* Set up hardware specific Rx handlers */ - il->cfg->ops->lib->handler_setup(il); + il->ops->lib->handler_setup(il); } /** @@ -4780,7 +4778,7 @@ il4965_dump_nic_error_log(struct il_priv *il) else base = le32_to_cpu(il->card_alive.error_event_table_ptr); - if (!il->cfg->ops->lib->is_valid_rtc_data_addr(base)) { + if (!il->ops->lib->is_valid_rtc_data_addr(base)) { IL_ERR("Not valid error log pointer 0x%08X for %s uCode\n", base, (il->ucode_type == UCODE_INIT) ? "Init" : "RT"); return; @@ -5009,8 +5007,8 @@ il4965_alive_start(struct il_priv *il) /* Initialize our rx_config data */ il_connection_init_rx_config(il); - if (il->cfg->ops->hcmd->set_rxon_chain) - il->cfg->ops->hcmd->set_rxon_chain(il); + if (il->ops->hcmd->set_rxon_chain) + il->ops->hcmd->set_rxon_chain(il); } /* Configure bluetooth coexistence if enabled */ @@ -5282,7 +5280,7 @@ __il4965_up(struct il_priv *il) /* load bootstrap state machine, * load bootstrap program into processor's memory, * prepare to load the "initialize" uCode */ - ret = il->cfg->ops->lib->load_ucode(il); + ret = il->ops->lib->load_ucode(il); if (ret) { IL_ERR("Unable to set up bootstrap uCode: %d\n", ret); @@ -5323,7 +5321,7 @@ il4965_bg_init_alive_start(struct work_struct *data) if (test_bit(S_EXIT_PENDING, &il->status)) goto out; - il->cfg->ops->lib->init_alive_start(il); + il->ops->lib->init_alive_start(il); out: mutex_unlock(&il->mutex); } @@ -5755,7 +5753,7 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw, if (!il_is_associated(il)) goto out; - if (!il->cfg->ops->lib->set_channel_switch) + if (!il->ops->lib->set_channel_switch) goto out; ch = channel->hw_value; @@ -5807,7 +5805,7 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw, */ set_bit(S_CHANNEL_SWITCH_PENDING, &il->status); il->switch_channel = cpu_to_le16(ch); - if (il->cfg->ops->lib->set_channel_switch(il, ch_switch)) { + if (il->ops->lib->set_channel_switch(il, ch_switch)) { clear_bit(S_CHANNEL_SWITCH_PENDING, &il->status); il->switch_channel = 0; ieee80211_chswitch_done(il->vif, false); @@ -5890,7 +5888,7 @@ il4965_bg_txpower_work(struct work_struct *work) /* Regardless of if we are associated, we must reconfigure the * TX power since frames can be sent on non-radar channels while * not associated */ - il->cfg->ops->lib->send_tx_power(il); + il->ops->lib->send_tx_power(il); /* Update last_temperature to keep is_calib_needed from running * when it isn't needed... */ @@ -5996,6 +5994,28 @@ il4965_tx_queue_set_status(struct il_priv *il, struct il_tx_queue *txq, scd_retry ? "BA" : "AC", txq_id, tx_fifo_id); } +const struct ieee80211_ops il4965_mac_ops = { + .tx = il4965_mac_tx, + .start = il4965_mac_start, + .stop = il4965_mac_stop, + .add_interface = il_mac_add_interface, + .remove_interface = il_mac_remove_interface, + .change_interface = il_mac_change_interface, + .config = il_mac_config, + .configure_filter = il4965_configure_filter, + .set_key = il4965_mac_set_key, + .update_tkip_key = il4965_mac_update_tkip_key, + .conf_tx = il_mac_conf_tx, + .reset_tsf = il_mac_reset_tsf, + .bss_info_changed = il_mac_bss_info_changed, + .ampdu_action = il4965_mac_ampdu_action, + .hw_scan = il_mac_hw_scan, + .sta_add = il4965_mac_sta_add, + .sta_remove = il_mac_sta_remove, + .channel_switch = il4965_mac_channel_switch, + .tx_last_beacon = il_mac_tx_last_beacon, +}; + static int il4965_init_drv(struct il_priv *il) { @@ -6020,8 +6040,8 @@ il4965_init_drv(struct il_priv *il) il->force_reset.reset_duration = IL_DELAY_NEXT_FORCE_FW_RELOAD; /* Choose which receivers/antennas to use */ - if (il->cfg->ops->hcmd->set_rxon_chain) - il->cfg->ops->hcmd->set_rxon_chain(il); + if (il->ops->hcmd->set_rxon_chain) + il->ops->hcmd->set_rxon_chain(il); il_init_scan_params(il); @@ -6081,7 +6101,7 @@ il4965_set_hw_params(struct il_priv *il) il->cfg->sku &= ~IL_SKU_N; /* Device-specific setup */ - return il->cfg->ops->lib->set_hw_params(il); + return il->ops->lib->set_hw_params(il); } static int @@ -6098,18 +6118,18 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * 1. Allocating HW data ************************/ - hw = il_alloc_all(cfg); + hw = ieee80211_alloc_hw(sizeof(struct il_priv), &il4965_mac_ops); if (!hw) { err = -ENOMEM; goto out; } il = hw->priv; - /* At this point both hw and il are allocated. */ - + il->hw = hw; SET_IEEE80211_DEV(hw, &pdev->dev); D_INFO("*** LOAD DRIVER ***\n"); il->cfg = cfg; + il->ops = &il4965_ops; il->pci_dev = pdev; il->inta_mask = CSR_INI_SET_MASK; diff --git a/drivers/net/wireless/iwlegacy/4965.c b/drivers/net/wireless/iwlegacy/4965.c index 9d9197f7fa3..27feb533d02 100644 --- a/drivers/net/wireless/iwlegacy/4965.c +++ b/drivers/net/wireless/iwlegacy/4965.c @@ -2166,8 +2166,8 @@ il4965_post_associate(struct il_priv *il) il_set_rxon_ht(il, &il->current_ht_config); - if (il->cfg->ops->hcmd->set_rxon_chain) - il->cfg->ops->hcmd->set_rxon_chain(il); + if (il->ops->hcmd->set_rxon_chain) + il->ops->hcmd->set_rxon_chain(il); il->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid); @@ -2241,8 +2241,8 @@ il4965_config_ap(struct il_priv *il) /* AP has all antennas */ il->chain_noise_data.active_chains = il->hw_params.valid_rx_ant; il_set_rxon_ht(il, &il->current_ht_config); - if (il->cfg->ops->hcmd->set_rxon_chain) - il->cfg->ops->hcmd->set_rxon_chain(il); + if (il->ops->hcmd->set_rxon_chain) + il->ops->hcmd->set_rxon_chain(il); il->staging.assoc_id = 0; @@ -2323,35 +2323,12 @@ static const struct il_legacy_ops il4965_legacy_ops = { .update_bcast_stations = il4965_update_bcast_stations, }; -struct ieee80211_ops il4965_hw_ops = { - .tx = il4965_mac_tx, - .start = il4965_mac_start, - .stop = il4965_mac_stop, - .add_interface = il_mac_add_interface, - .remove_interface = il_mac_remove_interface, - .change_interface = il_mac_change_interface, - .config = il_mac_config, - .configure_filter = il4965_configure_filter, - .set_key = il4965_mac_set_key, - .update_tkip_key = il4965_mac_update_tkip_key, - .conf_tx = il_mac_conf_tx, - .reset_tsf = il_mac_reset_tsf, - .bss_info_changed = il_mac_bss_info_changed, - .ampdu_action = il4965_mac_ampdu_action, - .hw_scan = il_mac_hw_scan, - .sta_add = il4965_mac_sta_add, - .sta_remove = il_mac_sta_remove, - .channel_switch = il4965_mac_channel_switch, - .tx_last_beacon = il_mac_tx_last_beacon, -}; - -static const struct il_ops il4965_ops = { +const struct il_ops il4965_ops = { .lib = &il4965_lib, .hcmd = &il4965_hcmd, .utils = &il4965_hcmd_utils, .led = &il4965_led_ops, .legacy = &il4965_legacy_ops, - .ieee80211_ops = &il4965_hw_ops, }; static struct il_base_params il4965_base_params = { @@ -2380,7 +2357,6 @@ struct il_cfg il4965_cfg = { .valid_rx_ant = ANT_ABC, .eeprom_ver = EEPROM_4965_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION, - .ops = &il4965_ops, .mod_params = &il4965_mod_params, .base_params = &il4965_base_params, .led_mode = IL_LED_BLINK, diff --git a/drivers/net/wireless/iwlegacy/4965.h b/drivers/net/wireless/iwlegacy/4965.h index 67899602ee5..83ab6049638 100644 --- a/drivers/net/wireless/iwlegacy/4965.h +++ b/drivers/net/wireless/iwlegacy/4965.h @@ -38,11 +38,10 @@ struct il_rxon_context; /* configuration for the _4965 devices */ extern struct il_cfg il4965_cfg; +extern const struct il_ops il4965_ops; extern struct il_mod_params il4965_mod_params; -extern struct ieee80211_ops il4965_hw_ops; - /* tx queue */ void il4965_free_tfds_in_queue(struct il_priv *il, int sta_id, int tid, int freed); diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index bee11a3aeac..3bd18333656 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -520,7 +520,7 @@ il_led_cmd(struct il_priv *il, unsigned long on, unsigned long off) il_blink_compensation(il, off, il->cfg->base_params->led_compensation); - ret = il->cfg->ops->led->cmd(il, &led_cmd); + ret = il->ops->led->cmd(il, &led_cmd); if (!ret) { il->blink_on = on; il->blink_off = off; @@ -731,7 +731,7 @@ il_eeprom_init(struct il_priv *il) } e = (__le16 *) il->eeprom; - il->cfg->ops->lib->apm_ops.init(il); + il->ops->lib->apm_ops.init(il); ret = il_eeprom_verify_signature(il); if (ret < 0) { @@ -741,7 +741,7 @@ il_eeprom_init(struct il_priv *il) } /* Make sure driver (instead of uCode) is allowed to read EEPROM */ - ret = il->cfg->ops->lib->eeprom_ops.acquire_semaphore(il); + ret = il->ops->lib->eeprom_ops.acquire_semaphore(il); if (ret < 0) { IL_ERR("Failed to acquire EEPROM semaphore.\n"); ret = -ENOENT; @@ -773,7 +773,7 @@ il_eeprom_init(struct il_priv *il) ret = 0; done: - il->cfg->ops->lib->eeprom_ops.release_semaphore(il); + il->ops->lib->eeprom_ops.release_semaphore(il); err: if (ret) @@ -800,7 +800,7 @@ il_init_band_reference(const struct il_priv *il, int eep_band, const u8 **eeprom_ch_idx) { u32 offset = - il->cfg->ops->lib->eeprom_ops.regulatory_bands[eep_band - 1]; + il->ops->lib->eeprom_ops.regulatory_bands[eep_band - 1]; switch (eep_band) { case 1: /* 2.4GHz band */ *eeprom_ch_count = ARRAY_SIZE(il_eeprom_band_1); @@ -1001,9 +1001,9 @@ il_init_channel_map(struct il_priv *il) } /* Check if we do have HT40 channels */ - if (il->cfg->ops->lib->eeprom_ops.regulatory_bands[5] == + if (il->ops->lib->eeprom_ops.regulatory_bands[5] == EEPROM_REGULATORY_BAND_NO_HT40 && - il->cfg->ops->lib->eeprom_ops.regulatory_bands[6] == + il->ops->lib->eeprom_ops.regulatory_bands[6] == EEPROM_REGULATORY_BAND_NO_HT40) return 0; @@ -1158,9 +1158,9 @@ il_power_set_mode(struct il_priv *il, struct il_powertable_cmd *cmd, bool force) if (!(cmd->flags & IL_POWER_DRIVER_ALLOW_SLEEP_MSK)) clear_bit(S_POWER_PMI, &il->status); - if (il->cfg->ops->lib->update_chain_flags && update_chains) - il->cfg->ops->lib->update_chain_flags(il); - else if (il->cfg->ops->lib->update_chain_flags) + if (il->ops->lib->update_chain_flags && update_chains) + il->ops->lib->update_chain_flags(il); + else if (il->ops->lib->update_chain_flags) D_POWER("Cannot update the power, chain noise " "calibration running: %d\n", il->chain_noise_data.state); @@ -1485,7 +1485,7 @@ il_scan_initiate(struct il_priv *il, struct ieee80211_vif *vif) lockdep_assert_held(&il->mutex); - if (WARN_ON(!il->cfg->ops->utils->request_scan)) + if (WARN_ON(!il->ops->utils->request_scan)) return -EOPNOTSUPP; cancel_delayed_work(&il->scan_check); @@ -1510,7 +1510,7 @@ il_scan_initiate(struct il_priv *il, struct ieee80211_vif *vif) set_bit(S_SCANNING, &il->status); il->scan_start = jiffies; - ret = il->cfg->ops->utils->request_scan(il, vif); + ret = il->ops->utils->request_scan(il, vif); if (ret) { clear_bit(S_SCANNING, &il->status); return ret; @@ -1672,7 +1672,7 @@ out_settings: il_power_set_mode(il, &il->power_data.sleep_cmd_next, false); il_set_tx_power(il, il->tx_power_next, false); - il->cfg->ops->utils->post_scan(il); + il->ops->utils->post_scan(il); out: mutex_unlock(&il->mutex); @@ -1814,7 +1814,7 @@ il_send_add_sta(struct il_priv *il, struct il_addsta_cmd *sta, u8 flags) might_sleep(); } - cmd.len = il->cfg->ops->utils->build_addsta_hcmd(sta, data); + cmd.len = il->ops->utils->build_addsta_hcmd(sta, data); ret = il_send_cmd(il, &cmd); if (ret || (flags & CMD_ASYNC)) @@ -2722,7 +2722,7 @@ il_tx_queue_unmap(struct il_priv *il, int txq_id) return; while (q->write_ptr != q->read_ptr) { - il->cfg->ops->lib->txq_free_tfd(il, txq); + il->ops->lib->txq_free_tfd(il, txq); q->read_ptr = il_queue_inc_wrap(q->read_ptr, q->n_bd); } } @@ -3024,7 +3024,7 @@ il_tx_queue_init(struct il_priv *il, struct il_tx_queue *txq, int slots_num, il_queue_init(il, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); /* Tell device where to find queue */ - il->cfg->ops->lib->txq_init(il, txq); + il->ops->lib->txq_init(il, txq); return 0; err: @@ -3055,7 +3055,7 @@ il_tx_queue_reset(struct il_priv *il, struct il_tx_queue *txq, int slots_num, il_queue_init(il, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); /* Tell device where to find queue */ - il->cfg->ops->lib->txq_init(il, txq); + il->ops->lib->txq_init(il, txq); } EXPORT_SYMBOL(il_tx_queue_reset); @@ -3083,7 +3083,7 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd) u32 idx; u16 fix_size; - cmd->len = il->cfg->ops->utils->get_hcmd_size(cmd->id, cmd->len); + cmd->len = il->ops->utils->get_hcmd_size(cmd->id, cmd->len); fix_size = (u16) (cmd->len + sizeof(out_cmd->hdr)); /* If any of the command structures end up being larger than @@ -3162,9 +3162,9 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd) #endif txq->need_update = 1; - if (il->cfg->ops->lib->txq_update_byte_cnt_tbl) + if (il->ops->lib->txq_update_byte_cnt_tbl) /* Set up entry in queue's byte count circular buffer */ - il->cfg->ops->lib->txq_update_byte_cnt_tbl(il, txq, 0); + il->ops->lib->txq_update_byte_cnt_tbl(il, txq, 0); phys_addr = pci_map_single(il->pci_dev, &out_cmd->hdr, fix_size, @@ -3172,8 +3172,8 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd) dma_unmap_addr_set(out_meta, mapping, phys_addr); dma_unmap_len_set(out_meta, len, fix_size); - il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq, phys_addr, fix_size, - 1, U32_PAD(cmd->len)); + il->ops->lib->txq_attach_buf_to_tfd(il, txq, phys_addr, fix_size, 1, + U32_PAD(cmd->len)); /* Increment and update queue's write idx */ q->write_ptr = il_queue_inc_wrap(q->write_ptr, q->n_bd); @@ -3315,30 +3315,6 @@ EXPORT_SYMBOL(il_debug_level); const u8 il_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; EXPORT_SYMBOL(il_bcast_addr); -/* This function both allocates and initializes hw and il. */ -struct ieee80211_hw * -il_alloc_all(struct il_cfg *cfg) -{ - struct il_priv *il; - /* mac80211 allocates memory for this device instance, including - * space for this driver's ilate structure */ - struct ieee80211_hw *hw; - - hw = ieee80211_alloc_hw(sizeof(struct il_priv), - cfg->ops->ieee80211_ops); - if (hw == NULL) { - pr_err("%s: Can not allocate network device\n", cfg->name); - goto out; - } - - il = hw->priv; - il->hw = hw; - -out: - return hw; -} -EXPORT_SYMBOL(il_alloc_all); - #define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ #define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ static void @@ -3871,8 +3847,8 @@ _il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf) rxon->flags |= RXON_FLG_CHANNEL_MODE_LEGACY; } - if (il->cfg->ops->hcmd->set_rxon_chain) - il->cfg->ops->hcmd->set_rxon_chain(il); + if (il->ops->hcmd->set_rxon_chain) + il->ops->hcmd->set_rxon_chain(il); D_ASSOC("rxon flags 0x%X operation mode :0x%X " "extension channel offset 0x%x\n", le32_to_cpu(rxon->flags), @@ -4130,9 +4106,9 @@ il_irq_handle_error(struct il_priv *il) IL_ERR("Loaded firmware version: %s\n", il->hw->wiphy->fw_version); - il->cfg->ops->lib->dump_nic_error_log(il); - if (il->cfg->ops->lib->dump_fh) - il->cfg->ops->lib->dump_fh(il, NULL, false); + il->ops->lib->dump_nic_error_log(il); + if (il->ops->lib->dump_fh) + il->ops->lib->dump_fh(il, NULL, false); #ifdef CONFIG_IWLEGACY_DEBUG if (il_get_debug_level(il) & IL_DL_FW_ERRORS) il_print_rx_config_cmd(il); @@ -4319,7 +4295,7 @@ il_set_tx_power(struct il_priv *il, s8 tx_power, bool force) if (il->tx_power_user_lmt == tx_power && !force) return 0; - if (!il->cfg->ops->lib->send_tx_power) + if (!il->ops->lib->send_tx_power) return -EOPNOTSUPP; /* 0 dBm mean 1 milliwatt */ @@ -4352,7 +4328,7 @@ il_set_tx_power(struct il_priv *il, s8 tx_power, bool force) prev_tx_power = il->tx_power_user_lmt; il->tx_power_user_lmt = tx_power; - ret = il->cfg->ops->lib->send_tx_power(il); + ret = il->ops->lib->send_tx_power(il); /* if fail to set tx_power, restore the orig. tx power */ if (ret) { @@ -4501,8 +4477,8 @@ il_set_mode(struct il_priv *il) { il_connection_init_rx_config(il); - if (il->cfg->ops->hcmd->set_rxon_chain) - il->cfg->ops->hcmd->set_rxon_chain(il); + if (il->ops->hcmd->set_rxon_chain) + il->ops->hcmd->set_rxon_chain(il); return il_commit_rxon(il); } @@ -5200,7 +5176,7 @@ il_mac_config(struct ieee80211_hw *hw, u32 changed) int scan_active = 0; bool ht_changed = false; - if (WARN_ON(!il->cfg->ops->legacy)) + if (WARN_ON(!il->ops->legacy)) return -EOPNOTSUPP; mutex_lock(&il->mutex); @@ -5225,8 +5201,8 @@ il_mac_config(struct ieee80211_hw *hw, u32 changed) * set up the SM PS mode to OFF if an HT channel is * configured. */ - if (il->cfg->ops->hcmd->set_rxon_chain) - il->cfg->ops->hcmd->set_rxon_chain(il); + if (il->ops->hcmd->set_rxon_chain) + il->ops->hcmd->set_rxon_chain(il); } /* during scanning mac80211 will delay channel setting until @@ -5295,8 +5271,8 @@ il_mac_config(struct ieee80211_hw *hw, u32 changed) spin_unlock_irqrestore(&il->lock, flags); - if (il->cfg->ops->legacy->update_bcast_stations) - ret = il->cfg->ops->legacy->update_bcast_stations(il); + if (il->ops->legacy->update_bcast_stations) + ret = il->ops->legacy->update_bcast_stations(il); set_ch_out: /* The list of supported rates and rate mask can be different @@ -5346,7 +5322,7 @@ il_mac_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) struct il_priv *il = hw->priv; unsigned long flags; - if (WARN_ON(!il->cfg->ops->legacy)) + if (WARN_ON(!il->ops->legacy)) return; mutex_lock(&il->mutex); @@ -5501,7 +5477,7 @@ il_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) return; } - il->cfg->ops->legacy->post_associate(il); + il->ops->legacy->post_associate(il); } void @@ -5511,7 +5487,7 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct il_priv *il = hw->priv; int ret; - if (WARN_ON(!il->cfg->ops->legacy)) + if (WARN_ON(!il->ops->legacy)) return; D_MAC80211("changes = 0x%X\n", changes); @@ -5616,8 +5592,8 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (changes & BSS_CHANGED_HT) { il_ht_conf(il, vif); - if (il->cfg->ops->hcmd->set_rxon_chain) - il->cfg->ops->hcmd->set_rxon_chain(il); + if (il->ops->hcmd->set_rxon_chain) + il->ops->hcmd->set_rxon_chain(il); } if (changes & BSS_CHANGED_ASSOC) { @@ -5626,7 +5602,7 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, il->timestamp = bss_conf->timestamp; if (!il_is_rfkill(il)) - il->cfg->ops->legacy->post_associate(il); + il->ops->legacy->post_associate(il); } else il_set_no_assoc(il, vif); } @@ -5646,16 +5622,15 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, memcpy(il->staging.bssid_addr, bss_conf->bssid, ETH_ALEN); memcpy(il->bssid, bss_conf->bssid, ETH_ALEN); - il->cfg->ops->legacy->config_ap(il); + il->ops->legacy->config_ap(il); } else il_set_no_assoc(il, vif); } if (changes & BSS_CHANGED_IBSS) { ret = - il->cfg->ops->legacy->manage_ibss_station(il, vif, - bss_conf-> - ibss_joined); + il->ops->legacy->manage_ibss_station(il, vif, + bss_conf->ibss_joined); if (ret) IL_ERR("failed to %s IBSS station %pM\n", bss_conf->ibss_joined ? "add" : "remove", diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index 746eec08886..2af861062de 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -1167,6 +1167,7 @@ struct il_priv { struct ieee80211_channel *ieee_channels; struct ieee80211_rate *ieee_rates; struct il_cfg *cfg; + const struct il_ops *ops; /* temporary frame storage list */ struct list_head free_frames; @@ -1668,7 +1669,6 @@ struct il_ops { const struct il_led_ops *led; const struct il_nic_ops *nic; const struct il_legacy_ops *legacy; - const struct ieee80211_ops *ieee80211_ops; }; struct il_mod_params { @@ -1777,7 +1777,6 @@ struct il_cfg { unsigned int sku; u16 eeprom_ver; u16 eeprom_calib_ver; - const struct il_ops *ops; /* module based parameters which can be set from modprobe cmd */ const struct il_mod_params *mod_params; /* params not likely to change within a device family */ @@ -1791,7 +1790,6 @@ struct il_cfg { * L i b * ***************************/ -struct ieee80211_hw *il_alloc_all(struct il_cfg *cfg); int il_mac_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, const struct ieee80211_tx_queue_params *params); int il_mac_tx_last_beacon(struct ieee80211_hw *hw); @@ -2093,13 +2091,13 @@ int il_send_rxon_timing(struct il_priv *il); static inline int il_send_rxon_assoc(struct il_priv *il) { - return il->cfg->ops->hcmd->rxon_assoc(il); + return il->ops->hcmd->rxon_assoc(il); } static inline int il_commit_rxon(struct il_priv *il) { - return il->cfg->ops->hcmd->commit_rxon(il); + return il->ops->hcmd->commit_rxon(il); } static inline const struct ieee80211_supported_band * diff --git a/drivers/net/wireless/iwlegacy/debug.c b/drivers/net/wireless/iwlegacy/debug.c index 3a9609a8874..4fb769caef5 100644 --- a/drivers/net/wireless/iwlegacy/debug.c +++ b/drivers/net/wireless/iwlegacy/debug.c @@ -901,8 +901,7 @@ il_dbgfs_ucode_rx_stats_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct il_priv *il = file->private_data; - return il->cfg->ops->lib->debugfs_ops.rx_stats_read(file, user_buf, - count, ppos); + return il->ops->lib->debugfs_ops.rx_stats_read(file, user_buf, count, ppos); } static ssize_t @@ -910,8 +909,7 @@ il_dbgfs_ucode_tx_stats_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct il_priv *il = file->private_data; - return il->cfg->ops->lib->debugfs_ops.tx_stats_read(file, user_buf, - count, ppos); + return il->ops->lib->debugfs_ops.tx_stats_read(file, user_buf, count, ppos); } static ssize_t @@ -919,8 +917,7 @@ il_dbgfs_ucode_general_stats_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct il_priv *il = file->private_data; - return il->cfg->ops->lib->debugfs_ops.general_stats_read(file, user_buf, - count, ppos); + return il->ops->lib->debugfs_ops.general_stats_read(file, user_buf, count, ppos); } static ssize_t @@ -1178,8 +1175,8 @@ il_dbgfs_fh_reg_read(struct file *file, char __user *user_buf, size_t count, int pos = 0; ssize_t ret = -EFAULT; - if (il->cfg->ops->lib->dump_fh) { - ret = pos = il->cfg->ops->lib->dump_fh(il, &buf, true); + if (il->ops->lib->dump_fh) { + ret = pos = il->ops->lib->dump_fh(il, &buf, true); if (buf) { ret = simple_read_from_buffer(user_buf, count, ppos, buf, -- cgit v1.2.3-70-g09d2 From 89ef1ed2d241d3dfe884055d8446a5dd94919e54 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 3 Feb 2012 17:31:59 +0100 Subject: iwlegacy: merge il_base_params into il_cfg Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/3945.c | 30 +++++++++++++----------- drivers/net/wireless/iwlegacy/4965-calib.c | 14 +++++------ drivers/net/wireless/iwlegacy/4965-mac.c | 8 +++---- drivers/net/wireless/iwlegacy/4965.c | 37 ++++++++++++++---------------- drivers/net/wireless/iwlegacy/common.c | 28 +++++++++++----------- drivers/net/wireless/iwlegacy/common.h | 31 +++++++++++++------------ drivers/net/wireless/iwlegacy/debug.c | 16 ++++++------- 7 files changed, 83 insertions(+), 81 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c index 918cbefd657..7c21a57d1bb 100644 --- a/drivers/net/wireless/iwlegacy/3945.c +++ b/drivers/net/wireless/iwlegacy/3945.c @@ -2398,7 +2398,7 @@ il3945_hw_set_hw_params(struct il_priv *il) il->hw_params.bcast_id = IL3945_BROADCAST_ID; /* Assign number of Usable TX queues */ - il->hw_params.max_txq_num = il->cfg->base_params->num_of_queues; + il->hw_params.max_txq_num = il->cfg->num_of_queues; il->hw_params.tfd_size = sizeof(struct il3945_tfd); il->hw_params.rx_page_order = get_order(IL_RX_BUF_SIZE_3K); @@ -2693,16 +2693,6 @@ const struct il_ops il3945_ops = { .legacy = &il3945_legacy_ops, }; -static struct il_base_params il3945_base_params = { - .eeprom_size = IL3945_EEPROM_IMG_SIZE, - .num_of_queues = IL39_NUM_QUEUES, - .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL, - .set_l0s = false, - .use_bsm = true, - .led_compensation = 64, - .wd_timeout = IL_DEF_WD_TIMEOUT, -}; - static struct il_cfg il3945_bg_cfg = { .name = "3945BG", .fw_name_pre = IL3945_FW_PRE, @@ -2711,8 +2701,15 @@ static struct il_cfg il3945_bg_cfg = { .sku = IL_SKU_G, .eeprom_ver = EEPROM_3945_EEPROM_VERSION, .mod_params = &il3945_mod_params, - .base_params = &il3945_base_params, .led_mode = IL_LED_BLINK, + + .eeprom_size = IL3945_EEPROM_IMG_SIZE, + .num_of_queues = IL39_NUM_QUEUES, + .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL, + .set_l0s = false, + .use_bsm = true, + .led_compensation = 64, + .wd_timeout = IL_DEF_WD_TIMEOUT }; static struct il_cfg il3945_abg_cfg = { @@ -2723,8 +2720,15 @@ static struct il_cfg il3945_abg_cfg = { .sku = IL_SKU_A | IL_SKU_G, .eeprom_ver = EEPROM_3945_EEPROM_VERSION, .mod_params = &il3945_mod_params, - .base_params = &il3945_base_params, .led_mode = IL_LED_BLINK, + + .eeprom_size = IL3945_EEPROM_IMG_SIZE, + .num_of_queues = IL39_NUM_QUEUES, + .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL, + .set_l0s = false, + .use_bsm = true, + .led_compensation = 64, + .wd_timeout = IL_DEF_WD_TIMEOUT }; DEFINE_PCI_DEVICE_TABLE(il3945_hw_card_ids) = { diff --git a/drivers/net/wireless/iwlegacy/4965-calib.c b/drivers/net/wireless/iwlegacy/4965-calib.c index bfb361dbba5..fe9171506a9 100644 --- a/drivers/net/wireless/iwlegacy/4965-calib.c +++ b/drivers/net/wireless/iwlegacy/4965-calib.c @@ -627,13 +627,13 @@ il4965_find_disconn_antenna(struct il_priv *il, u32 * average_sig, average_sig[0] = data->chain_signal_a / - il->cfg->base_params->chain_noise_num_beacons; + il->cfg->chain_noise_num_beacons; average_sig[1] = data->chain_signal_b / - il->cfg->base_params->chain_noise_num_beacons; + il->cfg->chain_noise_num_beacons; average_sig[2] = data->chain_signal_c / - il->cfg->base_params->chain_noise_num_beacons; + il->cfg->chain_noise_num_beacons; if (average_sig[0] >= average_sig[1]) { max_average_sig = average_sig[0]; @@ -886,7 +886,7 @@ il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp) /* If this is the "chain_noise_num_beacons", determine: * 1) Disconnected antennas (using signal strengths) * 2) Differential gain (using silence noise) to balance receivers */ - if (data->beacon_count != il->cfg->base_params->chain_noise_num_beacons) + if (data->beacon_count != il->cfg->chain_noise_num_beacons) return; /* Analyze signal for disconnected antenna */ @@ -894,11 +894,11 @@ il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp) /* Analyze noise for rx balance */ average_noise[0] = - data->chain_noise_a / il->cfg->base_params->chain_noise_num_beacons; + data->chain_noise_a / il->cfg->chain_noise_num_beacons; average_noise[1] = - data->chain_noise_b / il->cfg->base_params->chain_noise_num_beacons; + data->chain_noise_b / il->cfg->chain_noise_num_beacons; average_noise[2] = - data->chain_noise_c / il->cfg->base_params->chain_noise_num_beacons; + data->chain_noise_c / il->cfg->chain_noise_num_beacons; for (i = 0; i < NUM_RX_CHAINS; i++) { if (!data->disconn_array[i] && diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 2bf743fc782..49dd1e0e9a5 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -2150,11 +2150,11 @@ il4965_txq_agg_enable(struct il_priv *il, int txq_id, int tx_fifo, int sta_id, if ((IL49_FIRST_AMPDU_QUEUE > txq_id) || (IL49_FIRST_AMPDU_QUEUE + - il->cfg->base_params->num_of_ampdu_queues <= txq_id)) { + il->cfg->num_of_ampdu_queues <= txq_id)) { IL_WARN("queue number out of range: %d, must be %d to %d\n", txq_id, IL49_FIRST_AMPDU_QUEUE, IL49_FIRST_AMPDU_QUEUE + - il->cfg->base_params->num_of_ampdu_queues - 1); + il->cfg->num_of_ampdu_queues - 1); return -EINVAL; } @@ -2278,11 +2278,11 @@ il4965_txq_agg_disable(struct il_priv *il, u16 txq_id, u16 ssn_idx, u8 tx_fifo) { if ((IL49_FIRST_AMPDU_QUEUE > txq_id) || (IL49_FIRST_AMPDU_QUEUE + - il->cfg->base_params->num_of_ampdu_queues <= txq_id)) { + il->cfg->num_of_ampdu_queues <= txq_id)) { IL_WARN("queue number out of range: %d, must be %d to %d\n", txq_id, IL49_FIRST_AMPDU_QUEUE, IL49_FIRST_AMPDU_QUEUE + - il->cfg->base_params->num_of_ampdu_queues - 1); + il->cfg->num_of_ampdu_queues - 1); return -EINVAL; } diff --git a/drivers/net/wireless/iwlegacy/4965.c b/drivers/net/wireless/iwlegacy/4965.c index 27feb533d02..cf1d0164a9a 100644 --- a/drivers/net/wireless/iwlegacy/4965.c +++ b/drivers/net/wireless/iwlegacy/4965.c @@ -614,13 +614,13 @@ il4965_hw_set_hw_params(struct il_priv *il) { if (il->cfg->mod_params->num_of_queues >= IL_MIN_NUM_QUEUES && il->cfg->mod_params->num_of_queues <= IL49_NUM_QUEUES) - il->cfg->base_params->num_of_queues = + il->cfg->num_of_queues = il->cfg->mod_params->num_of_queues; - il->hw_params.max_txq_num = il->cfg->base_params->num_of_queues; + il->hw_params.max_txq_num = il->cfg->num_of_queues; il->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM; il->hw_params.scd_bc_tbls_size = - il->cfg->base_params->num_of_queues * + il->cfg->num_of_queues * sizeof(struct il4965_scd_bc_tbl); il->hw_params.tfd_size = sizeof(struct il_tfd); il->hw_params.max_stations = IL4965_STATION_COUNT; @@ -2331,22 +2331,6 @@ const struct il_ops il4965_ops = { .legacy = &il4965_legacy_ops, }; -static struct il_base_params il4965_base_params = { - .eeprom_size = IL4965_EEPROM_IMG_SIZE, - .num_of_queues = IL49_NUM_QUEUES, - .num_of_ampdu_queues = IL49_NUM_AMPDU_QUEUES, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = true, - .led_compensation = 61, - .chain_noise_num_beacons = IL4965_CAL_NUM_BEACONS, - .wd_timeout = IL_DEF_WD_TIMEOUT, - .temperature_kelvin = true, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, -}; - struct il_cfg il4965_cfg = { .name = "Intel(R) Wireless WiFi Link 4965AGN", .fw_name_pre = IL4965_FW_PRE, @@ -2358,13 +2342,26 @@ struct il_cfg il4965_cfg = { .eeprom_ver = EEPROM_4965_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION, .mod_params = &il4965_mod_params, - .base_params = &il4965_base_params, .led_mode = IL_LED_BLINK, /* * Force use of chains B and C for scan RX on 5 GHz band * because the device has off-channel reception on chain A. */ .scan_rx_antennas[IEEE80211_BAND_5GHZ] = ANT_BC, + + .eeprom_size = IL4965_EEPROM_IMG_SIZE, + .num_of_queues = IL49_NUM_QUEUES, + .num_of_ampdu_queues = IL49_NUM_AMPDU_QUEUES, + .pll_cfg_val = 0, + .set_l0s = true, + .use_bsm = true, + .led_compensation = 61, + .chain_noise_num_beacons = IL4965_CAL_NUM_BEACONS, + .wd_timeout = IL_DEF_WD_TIMEOUT, + .temperature_kelvin = true, + .ucode_tracing = true, + .sensitivity_calib_by_driver = true, + .chain_noise_calib_by_driver = true, }; /* Module firmware */ diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index 3bd18333656..1173521f21f 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -512,13 +512,13 @@ il_led_cmd(struct il_priv *il, unsigned long on, unsigned long off) } D_LED("Led blink time compensation=%u\n", - il->cfg->base_params->led_compensation); + il->cfg->led_compensation); led_cmd.on = il_blink_compensation(il, on, - il->cfg->base_params->led_compensation); + il->cfg->led_compensation); led_cmd.off = il_blink_compensation(il, off, - il->cfg->base_params->led_compensation); + il->cfg->led_compensation); ret = il->ops->led->cmd(il, &led_cmd); if (!ret) { @@ -691,7 +691,7 @@ il_eeprom_verify_signature(struct il_priv *il) const u8 * il_eeprom_query_addr(const struct il_priv *il, size_t offset) { - BUG_ON(offset >= il->cfg->base_params->eeprom_size); + BUG_ON(offset >= il->cfg->eeprom_size); return &il->eeprom[offset]; } EXPORT_SYMBOL(il_eeprom_query_addr); @@ -722,7 +722,7 @@ il_eeprom_init(struct il_priv *il) u16 addr; /* allocate eeprom */ - sz = il->cfg->base_params->eeprom_size; + sz = il->cfg->eeprom_size; D_EEPROM("NVM size = %d\n", sz); il->eeprom = kzalloc(sz, GFP_KERNEL); if (!il->eeprom) { @@ -4218,7 +4218,7 @@ il_apm_init(struct il_priv *il) * If not (unlikely), enable L0S, so there is at least some * power savings, even without L1. */ - if (il->cfg->base_params->set_l0s) { + if (il->cfg->set_l0s) { lctl = il_pcie_link_ctl(il); if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN) { @@ -4235,9 +4235,9 @@ il_apm_init(struct il_priv *il) } /* Configure analog phase-lock-loop before activating to D0A */ - if (il->cfg->base_params->pll_cfg_val) + if (il->cfg->pll_cfg_val) il_set_bit(il, CSR_ANA_PLL_CFG, - il->cfg->base_params->pll_cfg_val); + il->cfg->pll_cfg_val); /* * Set "initialization complete" bit to move adapter from @@ -4267,7 +4267,7 @@ il_apm_init(struct il_priv *il) * do not disable clocks. This preserves any hardware bits already * set by default in "CLK_CTRL_REG" after reset. */ - if (il->cfg->base_params->use_bsm) + if (il->cfg->use_bsm) il_wr_prph(il, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT); else @@ -4565,7 +4565,7 @@ il_alloc_txq_mem(struct il_priv *il) if (!il->txq) il->txq = kzalloc(sizeof(struct il_tx_queue) * - il->cfg->base_params->num_of_queues, GFP_KERNEL); + il->cfg->num_of_queues, GFP_KERNEL); if (!il->txq) { IL_ERR("Not enough memory for txq\n"); return -ENOMEM; @@ -4942,11 +4942,11 @@ il_check_stuck_queue(struct il_priv *il, int cnt) timeout = txq->time_stamp + - msecs_to_jiffies(il->cfg->base_params->wd_timeout); + msecs_to_jiffies(il->cfg->wd_timeout); if (time_after(jiffies, timeout)) { IL_ERR("Queue %d stuck for %u ms.\n", q->id, - il->cfg->base_params->wd_timeout); + il->cfg->wd_timeout); ret = il_force_reset(il, false); return (ret == -EAGAIN) ? 0 : 1; } @@ -4974,7 +4974,7 @@ il_bg_watchdog(unsigned long data) if (test_bit(S_EXIT_PENDING, &il->status)) return; - timeout = il->cfg->base_params->wd_timeout; + timeout = il->cfg->wd_timeout; if (timeout == 0) return; @@ -5001,7 +5001,7 @@ EXPORT_SYMBOL(il_bg_watchdog); void il_setup_watchdog(struct il_priv *il) { - unsigned int timeout = il->cfg->base_params->wd_timeout; + unsigned int timeout = il->cfg->wd_timeout; if (timeout) mod_timer(&il->watchdog, diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index 2af861062de..21ed70a7f68 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -1695,21 +1695,6 @@ struct il_mod_params { * chain noise calibration operation */ struct il_base_params { - int eeprom_size; - int num_of_queues; /* def: HW dependent */ - int num_of_ampdu_queues; /* def: HW dependent */ - /* for il_apm_init() */ - u32 pll_cfg_val; - bool set_l0s; - bool use_bsm; - - u16 led_compensation; - int chain_noise_num_beacons; - unsigned int wd_timeout; - bool temperature_kelvin; - const bool ucode_tracing; - const bool sensitivity_calib_by_driver; - const bool chain_noise_calib_by_driver; }; #define IL_LED_SOLID 11 @@ -1784,6 +1769,22 @@ struct il_cfg { /* params likely to change within a device family */ u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; enum il_led_mode led_mode; + + int eeprom_size; + int num_of_queues; /* def: HW dependent */ + int num_of_ampdu_queues; /* def: HW dependent */ + /* for il_apm_init() */ + u32 pll_cfg_val; + bool set_l0s; + bool use_bsm; + + u16 led_compensation; + int chain_noise_num_beacons; + unsigned int wd_timeout; + bool temperature_kelvin; + const bool ucode_tracing; + const bool sensitivity_calib_by_driver; + const bool chain_noise_calib_by_driver; }; /*************************** diff --git a/drivers/net/wireless/iwlegacy/debug.c b/drivers/net/wireless/iwlegacy/debug.c index 4fb769caef5..bb7c95607a6 100644 --- a/drivers/net/wireless/iwlegacy/debug.c +++ b/drivers/net/wireless/iwlegacy/debug.c @@ -361,7 +361,7 @@ il_dbgfs_nvm_read(struct file *file, char __user *user_buf, size_t count, const u8 *ptr; char *buf; u16 eeprom_ver; - size_t eeprom_len = il->cfg->base_params->eeprom_size; + size_t eeprom_len = il->cfg->eeprom_size; buf_size = 4 * eeprom_len + 256; if (eeprom_len % 16) { @@ -727,7 +727,7 @@ il_dbgfs_traffic_log_read(struct file *file, char __user *user_buf, char *buf; int bufsz = ((IL_TRAFFIC_ENTRIES * IL_TRAFFIC_ENTRY_SIZE * 64) * 2) + - (il->cfg->base_params->num_of_queues * 32 * 8) + 400; + (il->cfg->num_of_queues * 32 * 8) + 400; const u8 *ptr; ssize_t ret; @@ -833,7 +833,7 @@ il_dbgfs_tx_queue_read(struct file *file, char __user *user_buf, size_t count, int cnt; int ret; const size_t bufsz = - sizeof(char) * 64 * il->cfg->base_params->num_of_queues; + sizeof(char) * 64 * il->cfg->num_of_queues; if (!il->txq) { IL_ERR("txq not ready\n"); @@ -1293,7 +1293,7 @@ il_dbgfs_wd_timeout_write(struct file *file, const char __user *user_buf, if (timeout < 0 || timeout > IL_MAX_WD_TIMEOUT) timeout = IL_DEF_WD_TIMEOUT; - il->cfg->base_params->wd_timeout = timeout; + il->cfg->wd_timeout = timeout; il_setup_watchdog(il); return count; } @@ -1367,17 +1367,17 @@ il_dbgfs_register(struct il_priv *il, const char *name) DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR); - if (il->cfg->base_params->sensitivity_calib_by_driver) + if (il->cfg->sensitivity_calib_by_driver) DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); - if (il->cfg->base_params->chain_noise_calib_by_driver) + if (il->cfg->chain_noise_calib_by_driver) DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR); - if (il->cfg->base_params->sensitivity_calib_by_driver) + if (il->cfg->sensitivity_calib_by_driver) DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, &il->disable_sens_cal); - if (il->cfg->base_params->chain_noise_calib_by_driver) + if (il->cfg->chain_noise_calib_by_driver) DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf, &il->disable_chain_noise_cal); DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf, &il->disable_tx_power_cal); -- cgit v1.2.3-70-g09d2 From 00ea99e1d86b05e7ba90d66673b536b731af87cd Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 3 Feb 2012 17:32:00 +0100 Subject: iwlegacy: remove struct il_tx_info It's just wrapper to sk_buff pointers ... Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/3945-mac.c | 4 +--- drivers/net/wireless/iwlegacy/3945.c | 18 ++++++++--------- drivers/net/wireless/iwlegacy/4965-mac.c | 33 ++++++++++++++------------------ drivers/net/wireless/iwlegacy/4965.c | 18 +++++++++-------- drivers/net/wireless/iwlegacy/common.c | 24 +++++++++++------------ drivers/net/wireless/iwlegacy/common.h | 18 ++--------------- 6 files changed, 46 insertions(+), 69 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c index 40ce692b2c9..aa8f5c0bd64 100644 --- a/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/iwlegacy/3945-mac.c @@ -538,9 +538,7 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb) idx = il_get_cmd_idx(q, q->write_ptr, 0); - /* Set up driver data for this TFD */ - memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct il_tx_info)); - txq->txb[q->write_ptr].skb = skb; + txq->skbs[q->write_ptr] = skb; /* Init first empty entry in queue's array of Tx/cmd buffers */ out_cmd = txq->cmd[idx]; diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c index 7c21a57d1bb..6c1ae5fab89 100644 --- a/drivers/net/wireless/iwlegacy/3945.c +++ b/drivers/net/wireless/iwlegacy/3945.c @@ -293,16 +293,16 @@ il3945_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx) { struct il_tx_queue *txq = &il->txq[txq_id]; struct il_queue *q = &txq->q; - struct il_tx_info *tx_info; + struct sk_buff *skb; BUG_ON(txq_id == IL39_CMD_QUEUE_NUM); for (idx = il_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx; q->read_ptr = il_queue_inc_wrap(q->read_ptr, q->n_bd)) { - tx_info = &txq->txb[txq->q.read_ptr]; - ieee80211_tx_status_irqsafe(il->hw, tx_info->skb); - tx_info->skb = NULL; + skb = txq->skbs[txq->q.read_ptr]; + ieee80211_tx_status_irqsafe(il->hw, skb); + txq->skbs[txq->q.read_ptr] = NULL; il->ops->lib->txq_free_tfd(il, txq); } @@ -336,7 +336,7 @@ il3945_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb) } txq->time_stamp = jiffies; - info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb); + info = IEEE80211_SKB_CB(txq->skbs[txq->q.read_ptr]); ieee80211_tx_info_clear_status(info); /* Fill the MRR chain with some info about on-chip retransmissions */ @@ -660,15 +660,13 @@ il3945_hw_txq_free_tfd(struct il_priv *il, struct il_tx_queue *txq) PCI_DMA_TODEVICE); /* free SKB */ - if (txq->txb) { - struct sk_buff *skb; - - skb = txq->txb[txq->q.read_ptr].skb; + if (txq->skbs) { + struct sk_buff *skb = txq->skbs[txq->q.read_ptr]; /* can be called from irqs-disabled context */ if (skb) { dev_kfree_skb_any(skb); - txq->txb[txq->q.read_ptr].skb = NULL; + txq->skbs[txq->q.read_ptr] = NULL; } } } diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 49dd1e0e9a5..2a52e7b7325 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -1753,9 +1753,7 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb) spin_unlock(&il->sta_lock); - /* Set up driver data for this TFD */ - memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct il_tx_info)); - txq->txb[q->write_ptr].skb = skb; + txq->skbs[q->write_ptr] = skb; /* Set up first empty entry in queue's array of Tx/cmd buffers */ out_cmd = txq->cmd[q->write_ptr]; @@ -2435,14 +2433,14 @@ il4965_non_agg_tx_status(struct il_priv *il, const u8 *addr1) } static void -il4965_tx_status(struct il_priv *il, struct il_tx_info *tx_info, bool is_agg) +il4965_tx_status(struct il_priv *il, struct sk_buff *skb, bool is_agg) { - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx_info->skb->data; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; if (!is_agg) il4965_non_agg_tx_status(il, hdr->addr1); - ieee80211_tx_status_irqsafe(il->hw, tx_info->skb); + ieee80211_tx_status_irqsafe(il->hw, skb); } int @@ -2450,9 +2448,9 @@ il4965_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx) { struct il_tx_queue *txq = &il->txq[txq_id]; struct il_queue *q = &txq->q; - struct il_tx_info *tx_info; int nfreed = 0; struct ieee80211_hdr *hdr; + struct sk_buff *skb; if (idx >= q->n_bd || il_queue_used(q, idx) == 0) { IL_ERR("Read idx for DMA queue txq id (%d), idx %d, " @@ -2464,19 +2462,18 @@ il4965_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx) for (idx = il_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx; q->read_ptr = il_queue_inc_wrap(q->read_ptr, q->n_bd)) { - tx_info = &txq->txb[txq->q.read_ptr]; + skb = txq->skbs[txq->q.read_ptr]; - if (WARN_ON_ONCE(tx_info->skb == NULL)) + if (WARN_ON_ONCE(skb == NULL)) continue; - hdr = (struct ieee80211_hdr *)tx_info->skb->data; + hdr = (struct ieee80211_hdr *) skb->data; if (ieee80211_is_data_qos(hdr->frame_control)) nfreed++; - il4965_tx_status(il, tx_info, - txq_id >= IL4965_FIRST_AMPDU_QUEUE); - tx_info->skb = NULL; + il4965_tx_status(il, skb, txq_id >= IL4965_FIRST_AMPDU_QUEUE); + txq->skbs[txq->q.read_ptr] = NULL; il->ops->lib->txq_free_tfd(il, txq); } return nfreed; @@ -2540,7 +2537,7 @@ il4965_tx_status_reply_compressed_ba(struct il_priv *il, struct il_ht_agg *agg, D_TX_REPLY("Bitmap %llx\n", (unsigned long long)bitmap); - info = IEEE80211_SKB_CB(il->txq[scd_flow].txb[agg->start_idx].skb); + info = IEEE80211_SKB_CB(il->txq[scd_flow].skbs[agg->start_idx]); memset(&info->status, 0, sizeof(info->status)); info->flags |= IEEE80211_TX_STAT_ACK; info->flags |= IEEE80211_TX_STAT_AMPDU; @@ -3624,15 +3621,13 @@ il4965_hw_txq_free_tfd(struct il_priv *il, struct il_tx_queue *txq) PCI_DMA_TODEVICE); /* free SKB */ - if (txq->txb) { - struct sk_buff *skb; - - skb = txq->txb[txq->q.read_ptr].skb; + if (txq->skbs) { + struct sk_buff *skb = txq->skbs[txq->q.read_ptr]; /* can be called from irqs-disabled context */ if (skb) { dev_kfree_skb_any(skb); - txq->txb[txq->q.read_ptr].skb = NULL; + txq->skbs[txq->q.read_ptr] = NULL; } } } diff --git a/drivers/net/wireless/iwlegacy/4965.c b/drivers/net/wireless/iwlegacy/4965.c index cf1d0164a9a..17a6922e890 100644 --- a/drivers/net/wireless/iwlegacy/4965.c +++ b/drivers/net/wireless/iwlegacy/4965.c @@ -1873,7 +1873,7 @@ il4965_tx_status_reply_tx(struct il_priv *il, struct il_ht_agg *agg, D_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n", agg->frame_count, agg->start_idx, idx); - info = IEEE80211_SKB_CB(il->txq[txq_id].txb[idx].skb); + info = IEEE80211_SKB_CB(il->txq[txq_id].skbs[idx]); info->status.rates[0].count = tx_resp->failure_frame + 1; info->flags &= ~IEEE80211_TX_CTL_AMPDU; info->flags |= il4965_tx_status_to_mac80211(status); @@ -1888,6 +1888,7 @@ il4965_tx_status_reply_tx(struct il_priv *il, struct il_ht_agg *agg, /* Two or more frames were attempted; expect block-ack */ u64 bitmap = 0; int start = agg->start_idx; + struct sk_buff *skb; /* Construct bit-map of pending frames within Tx win */ for (i = 0; i < agg->frame_count; i++) { @@ -1905,12 +1906,10 @@ il4965_tx_status_reply_tx(struct il_priv *il, struct il_ht_agg *agg, D_TX_REPLY("FrameCnt = %d, txq_id=%d idx=%d\n", agg->frame_count, txq_id, idx); - hdr = il_tx_queue_get_hdr(il, txq_id, idx); - if (!hdr) { - IL_ERR("BUG_ON idx doesn't point to valid skb" - " idx=%d, txq_id=%d\n", idx, txq_id); + skb = il->txq[txq_id].skbs[idx]; + if (WARN_ON_ONCE(skb == NULL)) return -1; - } + hdr = (struct ieee80211_hdr *) skb->data; sc = le16_to_cpu(hdr->seq_ctrl); if (idx != (SEQ_TO_SN(sc) & 0xff)) { @@ -2018,6 +2017,7 @@ il4965_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb) int txq_id = SEQ_TO_QUEUE(sequence); int idx = SEQ_TO_IDX(sequence); struct il_tx_queue *txq = &il->txq[txq_id]; + struct sk_buff *skb; struct ieee80211_hdr *hdr; struct ieee80211_tx_info *info; struct il4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; @@ -2036,10 +2036,12 @@ il4965_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb) } txq->time_stamp = jiffies; - info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb); + + skb = txq->skbs[txq->q.read_ptr]; + info = IEEE80211_SKB_CB(skb); memset(&info->status, 0, sizeof(info->status)); - hdr = il_tx_queue_get_hdr(il, txq_id, idx); + hdr = (struct ieee80211_hdr *) skb->data; if (ieee80211_is_data_qos(hdr->frame_control)) { qc = ieee80211_get_qos_ctl(hdr); tid = qc[0] & 0xf; diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index 1173521f21f..04ec38e5eaa 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -2755,8 +2755,8 @@ il_tx_queue_free(struct il_priv *il, int txq_id) txq->tfds, txq->q.dma_addr); /* De-alloc array of per-TFD driver data */ - kfree(txq->txb); - txq->txb = NULL; + kfree(txq->skbs); + txq->skbs = NULL; /* deallocate arrays */ kfree(txq->cmd); @@ -2930,23 +2930,21 @@ il_tx_queue_alloc(struct il_priv *il, struct il_tx_queue *txq, u32 id) /* Driver ilate data, only for Tx (not command) queues, * not shared with device. */ if (id != il->cmd_queue) { - txq->txb = kcalloc(TFD_QUEUE_SIZE_MAX, sizeof(txq->txb[0]), - GFP_KERNEL); - if (!txq->txb) { - IL_ERR("kmalloc for auxiliary BD " - "structures failed\n"); + txq->skbs = kcalloc(TFD_QUEUE_SIZE_MAX, sizeof(struct skb *), + GFP_KERNEL); + if (!txq->skbs) { + IL_ERR("Fail to alloc skbs\n"); goto error; } - } else { - txq->txb = NULL; - } + } else + txq->skbs = NULL; /* Circular buffer of transmit frame descriptors (TFDs), * shared with device */ txq->tfds = dma_alloc_coherent(dev, tfd_sz, &txq->q.dma_addr, GFP_KERNEL); if (!txq->tfds) { - IL_ERR("pci_alloc_consistent(%zd) failed\n", tfd_sz); + IL_ERR("Fail to alloc TFDs\n"); goto error; } txq->q.id = id; @@ -2954,8 +2952,8 @@ il_tx_queue_alloc(struct il_priv *il, struct il_tx_queue *txq, u32 id) return 0; error: - kfree(txq->txb); - txq->txb = NULL; + kfree(txq->skbs); + txq->skbs = NULL; return -ENOMEM; } diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index 21ed70a7f68..527a1b9f99e 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -143,11 +143,6 @@ struct il_queue { * space less than this */ }; -/* One for each TFD */ -struct il_tx_info { - struct sk_buff *skb; -}; - /** * struct il_tx_queue - Tx Queue for DMA * @q: generic Rx/Tx queue descriptor @@ -155,7 +150,7 @@ struct il_tx_info { * @cmd: array of command/TX buffer pointers * @meta: array of meta data for each command/tx buffer * @dma_addr_cmd: physical address of cmd/tx buffer array - * @txb: array of per-TFD driver data + * @skbs: array of per-TFD socket buffer pointers * @time_stamp: time (in jiffies) of last read_ptr change * @need_update: indicates need to update read/write idx * @sched_retry: indicates queue is high-throughput aggregation (HT AGG) enabled @@ -171,7 +166,7 @@ struct il_tx_queue { void *tfds; struct il_device_cmd **cmd; struct il_cmd_meta *meta; - struct il_tx_info *txb; + struct sk_buff **skbs; unsigned long time_stamp; u8 need_update; u8 sched_retry; @@ -1482,15 +1477,6 @@ il_txq_ctx_deactivate(struct il_priv *il, int txq_id) clear_bit(txq_id, &il->txq_ctx_active_msk); } -static inline struct ieee80211_hdr * -il_tx_queue_get_hdr(struct il_priv *il, int txq_id, int idx) -{ - if (il->txq[txq_id].txb[idx].skb) - return (struct ieee80211_hdr *)il->txq[txq_id].txb[idx].skb-> - data; - return NULL; -} - static inline int il_is_associated(struct il_priv *il) { -- cgit v1.2.3-70-g09d2 From 1023f3bc7b3f56da1f79f605cbe459318c4792ae Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 3 Feb 2012 17:32:01 +0100 Subject: iwlegacy: remove set_hw_params callback We do not need that callback, settings parameters can be done locally. Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/4965-mac.c | 66 ++++++++++++++++++++++++--- drivers/net/wireless/iwlegacy/4965.c | 76 -------------------------------- drivers/net/wireless/iwlegacy/common.h | 2 - 3 files changed, 59 insertions(+), 85 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 2a52e7b7325..235812ac6a0 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -6079,7 +6079,34 @@ il4965_hw_detect(struct il_priv *il) D_INFO("HW Revision ID = 0x%X\n", il->rev_id); } -static int +static struct il_sensitivity_ranges il4965_sensitivity = { + .min_nrg_cck = 97, + .max_nrg_cck = 0, /* not used, set to 0 */ + + .auto_corr_min_ofdm = 85, + .auto_corr_min_ofdm_mrc = 170, + .auto_corr_min_ofdm_x1 = 105, + .auto_corr_min_ofdm_mrc_x1 = 220, + + .auto_corr_max_ofdm = 120, + .auto_corr_max_ofdm_mrc = 210, + .auto_corr_max_ofdm_x1 = 140, + .auto_corr_max_ofdm_mrc_x1 = 270, + + .auto_corr_min_cck = 125, + .auto_corr_max_cck = 200, + .auto_corr_min_cck_mrc = 200, + .auto_corr_max_cck_mrc = 400, + + .nrg_th_cck = 100, + .nrg_th_ofdm = 100, + + .barker_corr_th_min = 190, + .barker_corr_th_min_mrc = 390, + .nrg_th_cca = 62, +}; + +static void il4965_set_hw_params(struct il_priv *il) { il->hw_params.bcast_id = IL4965_BROADCAST_ID; @@ -6095,8 +6122,36 @@ il4965_set_hw_params(struct il_priv *il) if (il->cfg->mod_params->disable_11n) il->cfg->sku &= ~IL_SKU_N; - /* Device-specific setup */ - return il->ops->lib->set_hw_params(il); + if (il->cfg->mod_params->num_of_queues >= IL_MIN_NUM_QUEUES && + il->cfg->mod_params->num_of_queues <= IL49_NUM_QUEUES) + il->cfg->num_of_queues = + il->cfg->mod_params->num_of_queues; + + il->hw_params.max_txq_num = il->cfg->num_of_queues; + il->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM; + il->hw_params.scd_bc_tbls_size = + il->cfg->num_of_queues * + sizeof(struct il4965_scd_bc_tbl); + + il->hw_params.tfd_size = sizeof(struct il_tfd); + il->hw_params.max_stations = IL4965_STATION_COUNT; + il->hw_params.max_data_size = IL49_RTC_DATA_SIZE; + il->hw_params.max_inst_size = IL49_RTC_INST_SIZE; + il->hw_params.max_bsm_size = BSM_SRAM_SIZE; + il->hw_params.ht40_channel = BIT(IEEE80211_BAND_5GHZ); + + il->hw_params.rx_wrt_ptr_reg = FH49_RSCSR_CHNL0_WPTR; + + il->hw_params.tx_chains_num = il4965_num_of_ant(il->cfg->valid_tx_ant); + il->hw_params.rx_chains_num = il4965_num_of_ant(il->cfg->valid_rx_ant); + il->hw_params.valid_tx_ant = il->cfg->valid_tx_ant; + il->hw_params.valid_rx_ant = il->cfg->valid_rx_ant; + + il->hw_params.ct_kill_threshold = + CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY); + + il->hw_params.sens = &il4965_sensitivity; + il->hw_params.beacon_time_tsf_bits = IL4965_EXT_BEACON_TIME_POS; } static int @@ -6230,10 +6285,7 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /************************ * 5. Setup HW constants ************************/ - if (il4965_set_hw_params(il)) { - IL_ERR("failed to set hw parameters\n"); - goto out_free_eeprom; - } + il4965_set_hw_params(il); /******************* * 6. Setup il diff --git a/drivers/net/wireless/iwlegacy/4965.c b/drivers/net/wireless/iwlegacy/4965.c index 17a6922e890..79e4e797133 100644 --- a/drivers/net/wireless/iwlegacy/4965.c +++ b/drivers/net/wireless/iwlegacy/4965.c @@ -569,81 +569,6 @@ il4965_chain_noise_reset(struct il_priv *il) } } -static struct il_sensitivity_ranges il4965_sensitivity = { - .min_nrg_cck = 97, - .max_nrg_cck = 0, /* not used, set to 0 */ - - .auto_corr_min_ofdm = 85, - .auto_corr_min_ofdm_mrc = 170, - .auto_corr_min_ofdm_x1 = 105, - .auto_corr_min_ofdm_mrc_x1 = 220, - - .auto_corr_max_ofdm = 120, - .auto_corr_max_ofdm_mrc = 210, - .auto_corr_max_ofdm_x1 = 140, - .auto_corr_max_ofdm_mrc_x1 = 270, - - .auto_corr_min_cck = 125, - .auto_corr_max_cck = 200, - .auto_corr_min_cck_mrc = 200, - .auto_corr_max_cck_mrc = 400, - - .nrg_th_cck = 100, - .nrg_th_ofdm = 100, - - .barker_corr_th_min = 190, - .barker_corr_th_min_mrc = 390, - .nrg_th_cca = 62, -}; - -static void -il4965_set_ct_threshold(struct il_priv *il) -{ - /* want Kelvin */ - il->hw_params.ct_kill_threshold = - CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY); -} - -/** - * il4965_hw_set_hw_params - * - * Called when initializing driver - */ -static int -il4965_hw_set_hw_params(struct il_priv *il) -{ - if (il->cfg->mod_params->num_of_queues >= IL_MIN_NUM_QUEUES && - il->cfg->mod_params->num_of_queues <= IL49_NUM_QUEUES) - il->cfg->num_of_queues = - il->cfg->mod_params->num_of_queues; - - il->hw_params.max_txq_num = il->cfg->num_of_queues; - il->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM; - il->hw_params.scd_bc_tbls_size = - il->cfg->num_of_queues * - sizeof(struct il4965_scd_bc_tbl); - il->hw_params.tfd_size = sizeof(struct il_tfd); - il->hw_params.max_stations = IL4965_STATION_COUNT; - il->hw_params.max_data_size = IL49_RTC_DATA_SIZE; - il->hw_params.max_inst_size = IL49_RTC_INST_SIZE; - il->hw_params.max_bsm_size = BSM_SRAM_SIZE; - il->hw_params.ht40_channel = BIT(IEEE80211_BAND_5GHZ); - - il->hw_params.rx_wrt_ptr_reg = FH49_RSCSR_CHNL0_WPTR; - - il->hw_params.tx_chains_num = il4965_num_of_ant(il->cfg->valid_tx_ant); - il->hw_params.rx_chains_num = il4965_num_of_ant(il->cfg->valid_rx_ant); - il->hw_params.valid_tx_ant = il->cfg->valid_tx_ant; - il->hw_params.valid_rx_ant = il->cfg->valid_rx_ant; - - il4965_set_ct_threshold(il); - - il->hw_params.sens = &il4965_sensitivity; - il->hw_params.beacon_time_tsf_bits = IL4965_EXT_BEACON_TIME_POS; - - return 0; -} - static s32 il4965_math_div_round(s32 num, s32 denom, s32 * res) { @@ -2276,7 +2201,6 @@ static struct il_hcmd_utils_ops il4965_hcmd_utils = { }; static struct il_lib_ops il4965_lib = { - .set_hw_params = il4965_hw_set_hw_params, .txq_update_byte_cnt_tbl = il4965_txq_update_byte_cnt_tbl, .txq_attach_buf_to_tfd = il4965_hw_txq_attach_buf_to_tfd, .txq_free_tfd = il4965_hw_txq_free_tfd, diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index 527a1b9f99e..708095644f1 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -1592,8 +1592,6 @@ struct il_temp_ops { }; struct il_lib_ops { - /* set hw dependent parameters */ - int (*set_hw_params) (struct il_priv *il); /* Handling TX */ void (*txq_update_byte_cnt_tbl) (struct il_priv *il, struct il_tx_queue *txq, -- cgit v1.2.3-70-g09d2 From ab50a2a430693b0961dc7b7d9fe2a4bd77d11ea6 Mon Sep 17 00:00:00 2001 From: Mitch A Williams Date: Sat, 14 Jan 2012 08:10:50 +0000 Subject: igbvf: refactor Interrupt Throttle Rate code The existing ITR code is broken and confusing, with lots of similarly-named variables that do different things. Additionally, after the driver carefully determines the optimal interrupt rate for the adapter, it then ignores it and always writes a fixed, suboptimal value. This patch refactors that code to make variable names more descriptive of what they actually do, and then actually writes the calculated result to the hardware. Preliminary testing shows that netperf TCP_STREAM tests goes from ~918Mbps to ~940Mbps, and TCP_RR goes from ~2k transactions/sec up to > 8k. Signed-off-by: Mitch Williams Tested-by: Robert E Garrett Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/igbvf/ethtool.c | 19 +++-- drivers/net/ethernet/intel/igbvf/igbvf.h | 27 +++--- drivers/net/ethernet/intel/igbvf/netdev.c | 131 ++++++++++++++++------------- 3 files changed, 99 insertions(+), 78 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/igbvf/ethtool.c b/drivers/net/ethernet/intel/igbvf/ethtool.c index db7dce2351c..8ce67064b9c 100644 --- a/drivers/net/ethernet/intel/igbvf/ethtool.c +++ b/drivers/net/ethernet/intel/igbvf/ethtool.c @@ -343,10 +343,10 @@ static int igbvf_get_coalesce(struct net_device *netdev, { struct igbvf_adapter *adapter = netdev_priv(netdev); - if (adapter->itr_setting <= 3) - ec->rx_coalesce_usecs = adapter->itr_setting; + if (adapter->requested_itr <= 3) + ec->rx_coalesce_usecs = adapter->requested_itr; else - ec->rx_coalesce_usecs = adapter->itr_setting >> 2; + ec->rx_coalesce_usecs = adapter->current_itr >> 2; return 0; } @@ -365,15 +365,16 @@ static int igbvf_set_coalesce(struct net_device *netdev, /* convert to rate of irq's per second */ if (ec->rx_coalesce_usecs && ec->rx_coalesce_usecs <= 3) { - adapter->itr = IGBVF_START_ITR; - adapter->itr_setting = ec->rx_coalesce_usecs; + adapter->current_itr = IGBVF_START_ITR; + adapter->requested_itr = ec->rx_coalesce_usecs; } else { - adapter->itr = ec->rx_coalesce_usecs << 2; - adapter->itr_setting = adapter->itr; + adapter->current_itr = ec->rx_coalesce_usecs << 2; + adapter->requested_itr = 1000000000 / + (adapter->current_itr * 256); } - writel(adapter->itr, - hw->hw_addr + adapter->rx_ring[0].itr_register); + writel(adapter->current_itr, + hw->hw_addr + adapter->rx_ring->itr_register); return 0; } diff --git a/drivers/net/ethernet/intel/igbvf/igbvf.h b/drivers/net/ethernet/intel/igbvf/igbvf.h index 2c6d87e4d3d..a895e2f7b34 100644 --- a/drivers/net/ethernet/intel/igbvf/igbvf.h +++ b/drivers/net/ethernet/intel/igbvf/igbvf.h @@ -43,7 +43,18 @@ struct igbvf_info; struct igbvf_adapter; /* Interrupt defines */ -#define IGBVF_START_ITR 648 /* ~6000 ints/sec */ +#define IGBVF_START_ITR 488 /* ~8000 ints/sec */ +#define IGBVF_4K_ITR 980 +#define IGBVF_20K_ITR 196 +#define IGBVF_70K_ITR 56 + +enum latency_range { + lowest_latency = 0, + low_latency = 1, + bulk_latency = 2, + latency_invalid = 255 +}; + /* Interrupt modes, as used by the IntMode parameter */ #define IGBVF_INT_MODE_LEGACY 0 @@ -155,6 +166,7 @@ struct igbvf_ring { char name[IFNAMSIZ + 5]; u32 eims_value; u32 itr_val; + enum latency_range itr_range; u16 itr_register; int set_itr; @@ -187,10 +199,8 @@ struct igbvf_adapter { unsigned long state; /* Interrupt Throttle Rate */ - u32 itr; - u32 itr_setting; - u16 tx_itr; - u16 rx_itr; + u32 requested_itr; /* ints/sec or adaptive */ + u32 current_itr; /* Actual ITR register value, not ints/sec */ /* * Tx @@ -299,13 +309,6 @@ enum igbvf_state_t { __IGBVF_DOWN }; -enum latency_range { - lowest_latency = 0, - low_latency = 1, - bulk_latency = 2, - latency_invalid = 255 -}; - extern char igbvf_driver_name[]; extern const char igbvf_driver_version[]; diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c index 4e9141cfe81..446297ff010 100644 --- a/drivers/net/ethernet/intel/igbvf/netdev.c +++ b/drivers/net/ethernet/intel/igbvf/netdev.c @@ -632,14 +632,13 @@ void igbvf_free_rx_resources(struct igbvf_ring *rx_ring) * traffic pattern. Constants in this function were computed * based on theoretical maximum wire speed and thresholds were set based * on testing data as well as attempting to minimize response time - * while increasing bulk throughput. This functionality is controlled - * by the InterruptThrottleRate module parameter. + * while increasing bulk throughput. **/ -static unsigned int igbvf_update_itr(struct igbvf_adapter *adapter, - u16 itr_setting, int packets, - int bytes) +static enum latency_range igbvf_update_itr(struct igbvf_adapter *adapter, + enum latency_range itr_setting, + int packets, int bytes) { - unsigned int retval = itr_setting; + enum latency_range retval = itr_setting; if (packets == 0) goto update_itr_done; @@ -675,65 +674,87 @@ static unsigned int igbvf_update_itr(struct igbvf_adapter *adapter, retval = low_latency; } break; + default: + break; } update_itr_done: return retval; } -static void igbvf_set_itr(struct igbvf_adapter *adapter) +static int igbvf_range_to_itr(enum latency_range current_range) { - struct e1000_hw *hw = &adapter->hw; - u16 current_itr; - u32 new_itr = adapter->itr; - - adapter->tx_itr = igbvf_update_itr(adapter, adapter->tx_itr, - adapter->total_tx_packets, - adapter->total_tx_bytes); - /* conservative mode (itr 3) eliminates the lowest_latency setting */ - if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency) - adapter->tx_itr = low_latency; - - adapter->rx_itr = igbvf_update_itr(adapter, adapter->rx_itr, - adapter->total_rx_packets, - adapter->total_rx_bytes); - /* conservative mode (itr 3) eliminates the lowest_latency setting */ - if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency) - adapter->rx_itr = low_latency; + int new_itr; - current_itr = max(adapter->rx_itr, adapter->tx_itr); - - switch (current_itr) { + switch (current_range) { /* counts and packets in update_itr are dependent on these numbers */ case lowest_latency: - new_itr = 70000; + new_itr = IGBVF_70K_ITR; break; case low_latency: - new_itr = 20000; /* aka hwitr = ~200 */ + new_itr = IGBVF_20K_ITR; break; case bulk_latency: - new_itr = 4000; + new_itr = IGBVF_4K_ITR; break; default: + new_itr = IGBVF_START_ITR; break; } + return new_itr; +} + +static void igbvf_set_itr(struct igbvf_adapter *adapter) +{ + u32 new_itr; + + adapter->tx_ring->itr_range = + igbvf_update_itr(adapter, + adapter->tx_ring->itr_val, + adapter->total_tx_packets, + adapter->total_tx_bytes); + + /* conservative mode (itr 3) eliminates the lowest_latency setting */ + if (adapter->requested_itr == 3 && + adapter->tx_ring->itr_range == lowest_latency) + adapter->tx_ring->itr_range = low_latency; - if (new_itr != adapter->itr) { + new_itr = igbvf_range_to_itr(adapter->tx_ring->itr_range); + + + if (new_itr != adapter->tx_ring->itr_val) { + u32 current_itr = adapter->tx_ring->itr_val; /* * this attempts to bias the interrupt rate towards Bulk * by adding intermediate steps when interrupt rate is * increasing */ - new_itr = new_itr > adapter->itr ? - min(adapter->itr + (new_itr >> 2), new_itr) : - new_itr; - adapter->itr = new_itr; - adapter->rx_ring->itr_val = 1952; - - if (adapter->msix_entries) - adapter->rx_ring->set_itr = 1; - else - ew32(ITR, 1952); + new_itr = new_itr > current_itr ? + min(current_itr + (new_itr >> 2), new_itr) : + new_itr; + adapter->tx_ring->itr_val = new_itr; + + adapter->tx_ring->set_itr = 1; + } + + adapter->rx_ring->itr_range = + igbvf_update_itr(adapter, adapter->rx_ring->itr_val, + adapter->total_rx_packets, + adapter->total_rx_bytes); + if (adapter->requested_itr == 3 && + adapter->rx_ring->itr_range == lowest_latency) + adapter->rx_ring->itr_range = low_latency; + + new_itr = igbvf_range_to_itr(adapter->rx_ring->itr_range); + + if (new_itr != adapter->rx_ring->itr_val) { + u32 current_itr = adapter->rx_ring->itr_val; + new_itr = new_itr > current_itr ? + min(current_itr + (new_itr >> 2), new_itr) : + new_itr; + adapter->rx_ring->itr_val = new_itr; + + adapter->rx_ring->set_itr = 1; } } @@ -835,6 +856,11 @@ static irqreturn_t igbvf_intr_msix_tx(int irq, void *data) struct e1000_hw *hw = &adapter->hw; struct igbvf_ring *tx_ring = adapter->tx_ring; + if (tx_ring->set_itr) { + writel(tx_ring->itr_val, + adapter->hw.hw_addr + tx_ring->itr_register); + adapter->tx_ring->set_itr = 0; + } adapter->total_tx_bytes = 0; adapter->total_tx_packets = 0; @@ -937,19 +963,10 @@ static void igbvf_configure_msix(struct igbvf_adapter *adapter) igbvf_assign_vector(adapter, IGBVF_NO_QUEUE, 0, vector++); adapter->eims_enable_mask |= tx_ring->eims_value; - if (tx_ring->itr_val) - writel(tx_ring->itr_val, - hw->hw_addr + tx_ring->itr_register); - else - writel(1952, hw->hw_addr + tx_ring->itr_register); - + writel(tx_ring->itr_val, hw->hw_addr + tx_ring->itr_register); igbvf_assign_vector(adapter, 0, IGBVF_NO_QUEUE, vector++); adapter->eims_enable_mask |= rx_ring->eims_value; - if (rx_ring->itr_val) - writel(rx_ring->itr_val, - hw->hw_addr + rx_ring->itr_register); - else - writel(1952, hw->hw_addr + rx_ring->itr_register); + writel(rx_ring->itr_val, hw->hw_addr + rx_ring->itr_register); /* set vector for other causes, i.e. link changes */ @@ -1027,7 +1044,7 @@ static int igbvf_request_msix(struct igbvf_adapter *adapter) goto out; adapter->tx_ring->itr_register = E1000_EITR(vector); - adapter->tx_ring->itr_val = 1952; + adapter->tx_ring->itr_val = adapter->current_itr; vector++; err = request_irq(adapter->msix_entries[vector].vector, @@ -1037,7 +1054,7 @@ static int igbvf_request_msix(struct igbvf_adapter *adapter) goto out; adapter->rx_ring->itr_register = E1000_EITR(vector); - adapter->rx_ring->itr_val = 1952; + adapter->rx_ring->itr_val = adapter->current_itr; vector++; err = request_irq(adapter->msix_entries[vector].vector, @@ -1151,7 +1168,7 @@ static int igbvf_poll(struct napi_struct *napi, int budget) if (work_done < budget) { napi_complete(napi); - if (adapter->itr_setting & 3) + if (adapter->requested_itr & 3) igbvf_set_itr(adapter); if (!test_bit(__IGBVF_DOWN, &adapter->state)) @@ -1521,8 +1538,8 @@ static int __devinit igbvf_sw_init(struct igbvf_adapter *adapter) adapter->tx_abs_int_delay = 32; adapter->rx_int_delay = 0; adapter->rx_abs_int_delay = 8; - adapter->itr_setting = 3; - adapter->itr = 20000; + adapter->requested_itr = 3; + adapter->current_itr = IGBVF_START_ITR; /* Set various function pointers */ adapter->ei->init_ops(&adapter->hw); -- cgit v1.2.3-70-g09d2 From b04e36bac5075ceeacf11b639fbf0cb69aa68996 Mon Sep 17 00:00:00 2001 From: Tushar Dave Date: Fri, 27 Jan 2012 09:00:46 +0000 Subject: e1000: Adding e1000_dump function When TX hang occurs e1000_dump prints TX ring, RX ring and Device registers. Signed-off-by: Tushar Dave Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000/e1000.h | 1 + drivers/net/ethernet/intel/e1000/e1000_hw.h | 10 ++ drivers/net/ethernet/intel/e1000/e1000_main.c | 224 ++++++++++++++++++++++++++ 3 files changed, 235 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000/e1000.h b/drivers/net/ethernet/intel/e1000/e1000.h index 1e1596990b5..2b6cd02bfba 100644 --- a/drivers/net/ethernet/intel/e1000/e1000.h +++ b/drivers/net/ethernet/intel/e1000/e1000.h @@ -254,6 +254,7 @@ struct e1000_adapter { atomic_t tx_fifo_stall; bool pcix_82544; bool detect_tx_hung; + bool dump_buffers; /* RX */ bool (*clean_rx)(struct e1000_adapter *adapter, diff --git a/drivers/net/ethernet/intel/e1000/e1000_hw.h b/drivers/net/ethernet/intel/e1000/e1000_hw.h index f6c4d7e2560..11578c8978d 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_hw.h +++ b/drivers/net/ethernet/intel/e1000/e1000_hw.h @@ -895,6 +895,11 @@ struct e1000_ffvt_entry { #define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */ #define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */ #define E1000_PSRCTL 0x02170 /* Packet Split Receive Control - RW */ +#define E1000_RDFH 0x02410 /* RX Data FIFO Head - RW */ +#define E1000_RDFT 0x02418 /* RX Data FIFO Tail - RW */ +#define E1000_RDFHS 0x02420 /* RX Data FIFO Head Saved - RW */ +#define E1000_RDFTS 0x02428 /* RX Data FIFO Tail Saved - RW */ +#define E1000_RDFPC 0x02430 /* RX Data FIFO Packet Count - RW */ #define E1000_RDBAL 0x02800 /* RX Descriptor Base Address Low - RW */ #define E1000_RDBAH 0x02804 /* RX Descriptor Base Address High - RW */ #define E1000_RDLEN 0x02808 /* RX Descriptor Length - RW */ @@ -1074,6 +1079,11 @@ struct e1000_ffvt_entry { #define E1000_82542_IMC E1000_IMC #define E1000_82542_RCTL E1000_RCTL #define E1000_82542_RDTR 0x00108 +#define E1000_82542_RDFH E1000_RDFH +#define E1000_82542_RDFT E1000_RDFT +#define E1000_82542_RDFHS E1000_RDFHS +#define E1000_82542_RDFTS E1000_RDFTS +#define E1000_82542_RDFPC E1000_RDFPC #define E1000_82542_RDBAL 0x00110 #define E1000_82542_RDBAH 0x00114 #define E1000_82542_RDLEN 0x00118 diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 363fd395c75..1f86a70b88a 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -3239,6 +3239,228 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, return NETDEV_TX_OK; } +#define NUM_REGS 38 /* 1 based count */ +static void e1000_regdump(struct e1000_adapter *adapter) +{ + struct e1000_hw *hw = &adapter->hw; + u32 regs[NUM_REGS]; + u32 *regs_buff = regs; + int i = 0; + + char *reg_name[] = { + "CTRL", "STATUS", + "RCTL", "RDLEN", "RDH", "RDT", "RDTR", + "TCTL", "TDBAL", "TDBAH", "TDLEN", "TDH", "TDT", + "TIDV", "TXDCTL", "TADV", "TARC0", + "TDBAL1", "TDBAH1", "TDLEN1", "TDH1", "TDT1", + "TXDCTL1", "TARC1", + "CTRL_EXT", "ERT", "RDBAL", "RDBAH", + "TDFH", "TDFT", "TDFHS", "TDFTS", "TDFPC", + "RDFH", "RDFT", "RDFHS", "RDFTS", "RDFPC" + }; + + regs_buff[0] = er32(CTRL); + regs_buff[1] = er32(STATUS); + + regs_buff[2] = er32(RCTL); + regs_buff[3] = er32(RDLEN); + regs_buff[4] = er32(RDH); + regs_buff[5] = er32(RDT); + regs_buff[6] = er32(RDTR); + + regs_buff[7] = er32(TCTL); + regs_buff[8] = er32(TDBAL); + regs_buff[9] = er32(TDBAH); + regs_buff[10] = er32(TDLEN); + regs_buff[11] = er32(TDH); + regs_buff[12] = er32(TDT); + regs_buff[13] = er32(TIDV); + regs_buff[14] = er32(TXDCTL); + regs_buff[15] = er32(TADV); + regs_buff[16] = er32(TARC0); + + regs_buff[17] = er32(TDBAL1); + regs_buff[18] = er32(TDBAH1); + regs_buff[19] = er32(TDLEN1); + regs_buff[20] = er32(TDH1); + regs_buff[21] = er32(TDT1); + regs_buff[22] = er32(TXDCTL1); + regs_buff[23] = er32(TARC1); + regs_buff[24] = er32(CTRL_EXT); + regs_buff[25] = er32(ERT); + regs_buff[26] = er32(RDBAL0); + regs_buff[27] = er32(RDBAH0); + regs_buff[28] = er32(TDFH); + regs_buff[29] = er32(TDFT); + regs_buff[30] = er32(TDFHS); + regs_buff[31] = er32(TDFTS); + regs_buff[32] = er32(TDFPC); + regs_buff[33] = er32(RDFH); + regs_buff[34] = er32(RDFT); + regs_buff[35] = er32(RDFHS); + regs_buff[36] = er32(RDFTS); + regs_buff[37] = er32(RDFPC); + + pr_info("Register dump\n"); + for (i = 0; i < NUM_REGS; i++) { + printk(KERN_INFO "%-15s %08x\n", + reg_name[i], regs_buff[i]); + } +} + +/* + * e1000_dump: Print registers, tx ring and rx ring + */ +static void e1000_dump(struct e1000_adapter *adapter) +{ + /* this code doesn't handle multiple rings */ + struct e1000_tx_ring *tx_ring = adapter->tx_ring; + struct e1000_rx_ring *rx_ring = adapter->rx_ring; + int i; + + if (!netif_msg_hw(adapter)) + return; + + /* Print Registers */ + e1000_regdump(adapter); + + /* + * transmit dump + */ + pr_info("TX Desc ring0 dump\n"); + + /* Transmit Descriptor Formats - DEXT[29] is 0 (Legacy) or 1 (Extended) + * + * Legacy Transmit Descriptor + * +--------------------------------------------------------------+ + * 0 | Buffer Address [63:0] (Reserved on Write Back) | + * +--------------------------------------------------------------+ + * 8 | Special | CSS | Status | CMD | CSO | Length | + * +--------------------------------------------------------------+ + * 63 48 47 36 35 32 31 24 23 16 15 0 + * + * Extended Context Descriptor (DTYP=0x0) for TSO or checksum offload + * 63 48 47 40 39 32 31 16 15 8 7 0 + * +----------------------------------------------------------------+ + * 0 | TUCSE | TUCS0 | TUCSS | IPCSE | IPCS0 | IPCSS | + * +----------------------------------------------------------------+ + * 8 | MSS | HDRLEN | RSV | STA | TUCMD | DTYP | PAYLEN | + * +----------------------------------------------------------------+ + * 63 48 47 40 39 36 35 32 31 24 23 20 19 0 + * + * Extended Data Descriptor (DTYP=0x1) + * +----------------------------------------------------------------+ + * 0 | Buffer Address [63:0] | + * +----------------------------------------------------------------+ + * 8 | VLAN tag | POPTS | Rsvd | Status | Command | DTYP | DTALEN | + * +----------------------------------------------------------------+ + * 63 48 47 40 39 36 35 32 31 24 23 20 19 0 + */ + printk(KERN_INFO "Tc[desc] [Ce CoCsIpceCoS] [MssHlRSCm0Plen] [bi->dma ]" + " leng ntw timestmp bi->skb\n"); + printk(KERN_INFO "Td[desc] [address 63:0 ] [VlaPoRSCm1Dlen] [bi->dma ]" + " leng ntw timestmp bi->skb\n"); + + if (!netif_msg_tx_done(adapter)) + goto rx_ring_summary; + + for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) { + struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*tx_ring, i); + struct e1000_buffer *buffer_info = &tx_ring->buffer_info[i]; + struct my_u { u64 a; u64 b; }; + struct my_u *u = (struct my_u *)tx_desc; + printk(KERN_INFO "T%c[0x%03X] %016llX %016llX %016llX %04X %3X " + "%016llX %p", + ((le64_to_cpu(u->b) & (1<<20)) ? 'd' : 'c'), i, + le64_to_cpu(u->a), le64_to_cpu(u->b), + (u64)buffer_info->dma, buffer_info->length, + buffer_info->next_to_watch, (u64)buffer_info->time_stamp, + buffer_info->skb); + if (i == tx_ring->next_to_use && i == tx_ring->next_to_clean) + printk(KERN_CONT" NTC/U\n"); + else if (i == tx_ring->next_to_use) + printk(KERN_CONT " NTU\n"); + else if (i == tx_ring->next_to_clean) + printk(KERN_CONT " NTC\n"); + else + printk(KERN_CONT "\n"); + + + if (netif_msg_pktdata(adapter) && buffer_info->dma != 0) + print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, + 16, 1, phys_to_virt(buffer_info->dma), + buffer_info->length, true); + } + +rx_ring_summary: + /* + * receive dump + */ + pr_info("\nRX Desc ring dump\n"); + + /* Legacy Receive Descriptor Format + * + * +-----------------------------------------------------+ + * | Buffer Address [63:0] | + * +-----------------------------------------------------+ + * | VLAN Tag | Errors | Status 0 | Packet csum | Length | + * +-----------------------------------------------------+ + * 63 48 47 40 39 32 31 16 15 0 + */ + printk(KERN_INFO "R[desc] [address 63:0 ] [vl er S cks ln] " + "[bi->dma ] [bi->skb]\n"); + + if (!netif_msg_rx_status(adapter)) + goto exit; + + for (i = 0; rx_ring->desc && (i < rx_ring->count); i++) { + struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rx_ring, i); + struct e1000_buffer *buffer_info = &rx_ring->buffer_info[i]; + struct my_u { u64 a; u64 b; }; + struct my_u *u = (struct my_u *)rx_desc; + printk(KERN_INFO "R[0x%03X] %016llX %016llX %016llX %p", + i, le64_to_cpu(u->a), le64_to_cpu(u->b), + (u64)buffer_info->dma, buffer_info->skb); + if (i == rx_ring->next_to_use) + printk(KERN_CONT " NTU\n"); + else if (i == rx_ring->next_to_clean) + printk(KERN_CONT " NTC\n"); + else + printk(KERN_CONT "\n"); + + if (netif_msg_pktdata(adapter)) + print_hex_dump(KERN_INFO, "", + DUMP_PREFIX_ADDRESS, 16, 1, + phys_to_virt(buffer_info->dma), + buffer_info->length, true); + + } /* for */ + + /* dump the descriptor caches */ + /* rx */ + printk(KERN_INFO "e1000: Rx descriptor cache in 64bit format\n"); + for (i = 0x6000; i <= 0x63FF ; i += 0x10) { + printk(KERN_INFO "R%04X: %08X|%08X %08X|%08X\n", + i, + readl(adapter->hw.hw_addr + i+4), + readl(adapter->hw.hw_addr + i), + readl(adapter->hw.hw_addr + i+12), + readl(adapter->hw.hw_addr + i+8)); + } + /* tx */ + printk(KERN_INFO "e1000: Tx descriptor cache in 64bit format\n"); + for (i = 0x7000; i <= 0x73FF ; i += 0x10) { + printk(KERN_INFO "T%04X: %08X|%08X %08X|%08X\n", + i, + readl(adapter->hw.hw_addr + i+4), + readl(adapter->hw.hw_addr + i), + readl(adapter->hw.hw_addr + i+12), + readl(adapter->hw.hw_addr + i+8)); + } +exit: + return; +} + /** * e1000_tx_timeout - Respond to a Tx Hang * @netdev: network interface device structure @@ -3260,6 +3482,7 @@ static void e1000_reset_task(struct work_struct *work) if (test_bit(__E1000_DOWN, &adapter->flags)) return; + e_err(drv, "Reset adapter\n"); e1000_reinit_safe(adapter); } @@ -3677,6 +3900,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter, eop, jiffies, eop_desc->upper.fields.status); + e1000_dump(adapter); netif_stop_queue(netdev); } } -- cgit v1.2.3-70-g09d2 From f36bb6cacd3bcbab9605e06f585ee8f1ea450876 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Tue, 31 Jan 2012 06:38:04 +0000 Subject: e1000e: add missing initializers reported when compiling with W=1 warning: missing initializer Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/netdev.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 1a8dd2f0e60..c05137f362a 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -137,7 +137,7 @@ static const struct e1000_reg_info e1000_reg_info_tbl[] = { {E1000_TDFPC, "TDFPC"}, /* List Terminator */ - {} + {0, NULL} }; /* @@ -6502,7 +6502,7 @@ static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = { { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH2_LV_LM), board_pch2lan }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH2_LV_V), board_pch2lan }, - { } /* terminate list */ + { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */ }; MODULE_DEVICE_TABLE(pci, e1000_pci_tbl); @@ -6521,7 +6521,9 @@ static struct pci_driver e1000_driver = { .probe = e1000_probe, .remove = __devexit_p(e1000_remove), #ifdef CONFIG_PM - .driver.pm = &e1000_pm_ops, + .driver = { + .pm = &e1000_pm_ops, + }, #endif .shutdown = e1000_shutdown, .err_handler = &e1000_err_handler -- cgit v1.2.3-70-g09d2 From 9e2d7657e2a8fb40f732563dffb05151ea2d7e01 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Tue, 31 Jan 2012 06:37:27 +0000 Subject: e1000e: cleanup - check return values consistently The majority of the e1000e code checks most function return values using a test like 'if (ret_val)' or 'if (!ret_val)' but there are a few instances of 'if (ret_val == 0)'. This patch converts the latter to the former for consistency. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/ethtool.c | 2 +- drivers/net/ethernet/intel/e1000e/ich8lan.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index 92d5b627895..f43af463ddc 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -537,7 +537,7 @@ static int e1000_set_eeprom(struct net_device *netdev, ret_val = e1000_read_nvm(hw, first_word, 1, &eeprom_buff[0]); ptr++; } - if (((eeprom->offset + eeprom->len) & 1) && (ret_val == 0)) + if (((eeprom->offset + eeprom->len) & 1) && (!ret_val)) /* need read/modify/write of last changed EEPROM word */ /* only the first byte of the word is being modified */ ret_val = e1000_read_nvm(hw, last_word, 1, diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 907b17b2e66..0e64cc43849 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -2286,7 +2286,7 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw) } udelay(1); } - if (ret_val == 0) { + if (!ret_val) { /* * Successful in waiting for previous cycle to timeout, * now set the Flash Cycle Done. @@ -2404,7 +2404,7 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, udelay(1); /* Steps */ ret_val = e1000_flash_cycle_init_ich8lan(hw); - if (ret_val != 0) + if (ret_val) break; hsflctl.regval = er16flash(ICH_FLASH_HSFCTL); @@ -2424,7 +2424,7 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, * read in (shift in) the Flash Data0, the order is * least significant byte first msb to lsb */ - if (ret_val == 0) { + if (!ret_val) { flash_data = er32flash(ICH_FLASH_FDATA0); if (size == 1) *data = (u8)(flash_data & 0x000000FF); @@ -2936,7 +2936,7 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank) ret_val = e1000_flash_cycle_ich8lan(hw, ICH_FLASH_ERASE_COMMAND_TIMEOUT); - if (ret_val == 0) + if (!ret_val) break; /* -- cgit v1.2.3-70-g09d2 From e68782ed789a8e52af410368a185b3768fa64614 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Tue, 31 Jan 2012 06:37:43 +0000 Subject: e1000e: cleanup e1000_init_mac_params_80003es2lan() Combine two switch statements into one, convert a nebulous pointer to one that is a bit more in keeping with the rest of the driver code and remove some dead code (there are no 80003es2lan devices with fiber). No change in functionality, just cosmetic changes. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/80003es2lan.c | 28 +++++++------------------ 1 file changed, 7 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/80003es2lan.c b/drivers/net/ethernet/intel/e1000e/80003es2lan.c index 82a5d87c90c..9b969615b72 100644 --- a/drivers/net/ethernet/intel/e1000e/80003es2lan.c +++ b/drivers/net/ethernet/intel/e1000e/80003es2lan.c @@ -205,15 +205,20 @@ static s32 e1000_init_mac_params_80003es2lan(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; struct e1000_mac_info *mac = &hw->mac; - struct e1000_mac_operations *func = &mac->ops; - /* Set media type */ + /* Set media type and media-dependent function pointers */ switch (adapter->pdev->device) { case E1000_DEV_ID_80003ES2LAN_SERDES_DPT: hw->phy.media_type = e1000_media_type_internal_serdes; + mac->ops.check_for_link = e1000e_check_for_serdes_link; + mac->ops.setup_physical_interface = + e1000e_setup_fiber_serdes_link; break; default: hw->phy.media_type = e1000_media_type_copper; + mac->ops.check_for_link = e1000e_check_for_copper_link; + mac->ops.setup_physical_interface = + e1000_setup_copper_link_80003es2lan; break; } @@ -230,25 +235,6 @@ static s32 e1000_init_mac_params_80003es2lan(struct e1000_adapter *adapter) /* Adaptive IFS not supported */ mac->adaptive_ifs = false; - /* check for link */ - switch (hw->phy.media_type) { - case e1000_media_type_copper: - func->setup_physical_interface = e1000_setup_copper_link_80003es2lan; - func->check_for_link = e1000e_check_for_copper_link; - break; - case e1000_media_type_fiber: - func->setup_physical_interface = e1000e_setup_fiber_serdes_link; - func->check_for_link = e1000e_check_for_fiber_link; - break; - case e1000_media_type_internal_serdes: - func->setup_physical_interface = e1000e_setup_fiber_serdes_link; - func->check_for_link = e1000e_check_for_serdes_link; - break; - default: - return -E1000_ERR_CONFIG; - break; - } - /* set lan id for port to determine which phy lock to use */ hw->mac.ops.set_lan_id(hw); -- cgit v1.2.3-70-g09d2 From 66092f59252cb53e5a997e1222ad203b78c8aa97 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Tue, 31 Jan 2012 06:37:48 +0000 Subject: e1000e: cleanup e1000_init_mac_params_82571() Combine two switch statements into one, convert a nebulous pointer to one that is a bit more in keeping with the rest of the driver code and cleanup some coding style. No change in functionality, just cosmetic changes. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/82571.c | 72 +++++++++++++------------------ 1 file changed, 30 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/82571.c b/drivers/net/ethernet/intel/e1000e/82571.c index 844907da8aa..4cadcc76ad5 100644 --- a/drivers/net/ethernet/intel/e1000e/82571.c +++ b/drivers/net/ethernet/intel/e1000e/82571.c @@ -239,26 +239,39 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; struct e1000_mac_info *mac = &hw->mac; - struct e1000_mac_operations *func = &mac->ops; u32 swsm = 0; u32 swsm2 = 0; bool force_clear_smbi = false; - /* Set media type */ + /* Set media type and media-dependent function pointers */ switch (adapter->pdev->device) { case E1000_DEV_ID_82571EB_FIBER: case E1000_DEV_ID_82572EI_FIBER: case E1000_DEV_ID_82571EB_QUAD_FIBER: hw->phy.media_type = e1000_media_type_fiber; + mac->ops.setup_physical_interface = + e1000_setup_fiber_serdes_link_82571; + mac->ops.check_for_link = e1000e_check_for_fiber_link; + mac->ops.get_link_up_info = + e1000e_get_speed_and_duplex_fiber_serdes; break; case E1000_DEV_ID_82571EB_SERDES: - case E1000_DEV_ID_82572EI_SERDES: case E1000_DEV_ID_82571EB_SERDES_DUAL: case E1000_DEV_ID_82571EB_SERDES_QUAD: + case E1000_DEV_ID_82572EI_SERDES: hw->phy.media_type = e1000_media_type_internal_serdes; + mac->ops.setup_physical_interface = + e1000_setup_fiber_serdes_link_82571; + mac->ops.check_for_link = e1000_check_for_serdes_link_82571; + mac->ops.get_link_up_info = + e1000e_get_speed_and_duplex_fiber_serdes; break; default: hw->phy.media_type = e1000_media_type_copper; + mac->ops.setup_physical_interface = + e1000_setup_copper_link_82571; + mac->ops.check_for_link = e1000e_check_for_copper_link; + mac->ops.get_link_up_info = e1000e_get_speed_and_duplex_copper; break; } @@ -269,38 +282,13 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter) /* Adaptive IFS supported */ mac->adaptive_ifs = true; - /* check for link */ - switch (hw->phy.media_type) { - case e1000_media_type_copper: - func->setup_physical_interface = e1000_setup_copper_link_82571; - func->check_for_link = e1000e_check_for_copper_link; - func->get_link_up_info = e1000e_get_speed_and_duplex_copper; - break; - case e1000_media_type_fiber: - func->setup_physical_interface = - e1000_setup_fiber_serdes_link_82571; - func->check_for_link = e1000e_check_for_fiber_link; - func->get_link_up_info = - e1000e_get_speed_and_duplex_fiber_serdes; - break; - case e1000_media_type_internal_serdes: - func->setup_physical_interface = - e1000_setup_fiber_serdes_link_82571; - func->check_for_link = e1000_check_for_serdes_link_82571; - func->get_link_up_info = - e1000e_get_speed_and_duplex_fiber_serdes; - break; - default: - return -E1000_ERR_CONFIG; - break; - } - + /* MAC-specific function pointers */ switch (hw->mac.type) { case e1000_82573: - func->set_lan_id = e1000_set_lan_id_single_port; - func->check_mng_mode = e1000e_check_mng_mode_generic; - func->led_on = e1000e_led_on_generic; - func->blink_led = e1000e_blink_led_generic; + mac->ops.set_lan_id = e1000_set_lan_id_single_port; + mac->ops.check_mng_mode = e1000e_check_mng_mode_generic; + mac->ops.led_on = e1000e_led_on_generic; + mac->ops.blink_led = e1000e_blink_led_generic; /* FWSM register */ mac->has_fwsm = true; @@ -314,14 +302,14 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter) break; case e1000_82574: case e1000_82583: - func->set_lan_id = e1000_set_lan_id_single_port; - func->check_mng_mode = e1000_check_mng_mode_82574; - func->led_on = e1000_led_on_82574; + mac->ops.set_lan_id = e1000_set_lan_id_single_port; + mac->ops.check_mng_mode = e1000_check_mng_mode_82574; + mac->ops.led_on = e1000_led_on_82574; break; default: - func->check_mng_mode = e1000e_check_mng_mode_generic; - func->led_on = e1000e_led_on_generic; - func->blink_led = e1000e_blink_led_generic; + mac->ops.check_mng_mode = e1000e_check_mng_mode_generic; + mac->ops.led_on = e1000e_led_on_generic; + mac->ops.blink_led = e1000e_blink_led_generic; /* FWSM register */ mac->has_fwsm = true; @@ -342,11 +330,11 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter) if (!(swsm2 & E1000_SWSM2_LOCK)) { /* Only do this for the first interface on this card */ - ew32(SWSM2, - swsm2 | E1000_SWSM2_LOCK); + ew32(SWSM2, swsm2 | E1000_SWSM2_LOCK); force_clear_smbi = true; - } else + } else { force_clear_smbi = false; + } break; default: force_clear_smbi = true; -- cgit v1.2.3-70-g09d2 From f23efdff77bbc1207255ccebe04771970604bbd9 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Tue, 31 Jan 2012 06:37:38 +0000 Subject: e1000e: cleanup e1000_set_phys_id Use the existing hw pointer. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/ethtool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index f43af463ddc..fd2ba3818d3 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -1856,11 +1856,11 @@ static int e1000_set_phys_id(struct net_device *netdev, break; case ETHTOOL_ID_ON: - adapter->hw.mac.ops.led_on(&adapter->hw); + hw->mac.ops.led_on(hw); break; case ETHTOOL_ID_OFF: - adapter->hw.mac.ops.led_off(&adapter->hw); + hw->mac.ops.led_off(hw); break; } return 0; -- cgit v1.2.3-70-g09d2 From 24b706b2f4bb28c34d32f9d333d8a118215a38cc Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Tue, 31 Jan 2012 06:37:22 +0000 Subject: e1000e: cleanup - use braces in both branches of a conditional statement Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/netdev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index c05137f362a..02efae08ce3 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -3756,8 +3756,9 @@ static int e1000_test_msi_interrupt(struct e1000_adapter *adapter) if (adapter->flags & FLAG_MSI_TEST_FAILED) { adapter->int_mode = E1000E_INT_MODE_LEGACY; e_info("MSI interrupt test failed, using legacy interrupt.\n"); - } else + } else { e_dbg("MSI interrupt test succeeded!\n"); + } free_irq(adapter->pdev->irq, netdev); pci_disable_msi(adapter->pdev); -- cgit v1.2.3-70-g09d2 From a2a5b3235d0dce0feaadf4e76727adea1caa6869 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Tue, 31 Jan 2012 06:37:17 +0000 Subject: e1000e: fix checkpatch warning from MINMAX test WARNING: min() should probably be min_t(unsigned int, 4, skb->data_len) Signed-off-by: Bruce Allan 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 02efae08ce3..a9f25fcfbfe 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -5023,7 +5023,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, if (skb->data_len && (hdr_len == len)) { unsigned int pull_size; - pull_size = min((unsigned int)4, skb->data_len); + pull_size = min_t(unsigned int, 4, skb->data_len); if (!__pskb_pull_tail(skb, pull_size)) { e_err("__pskb_pull_tail failed.\n"); dev_kfree_skb_any(skb); -- cgit v1.2.3-70-g09d2 From e885d762b7f73e811432f67608a6f0affa861029 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Tue, 31 Jan 2012 06:37:32 +0000 Subject: e1000e: fix sparse warnings with -D__CHECK_ENDIAN__ Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/ethtool.c | 2 +- drivers/net/ethernet/intel/e1000e/netdev.c | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index fd2ba3818d3..f4dc0fa9d9b 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -553,7 +553,7 @@ static int e1000_set_eeprom(struct net_device *netdev, memcpy(ptr, bytes, eeprom->len); for (i = 0; i < last_word - first_word + 1; i++) - eeprom_buff[i] = cpu_to_le16(eeprom_buff[i]); + cpu_to_le16s(&eeprom_buff[i]); ret_val = e1000_write_nvm(hw, first_word, last_word - first_word + 1, eeprom_buff); diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index a9f25fcfbfe..2ac1164d04e 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -183,18 +183,18 @@ static void e1000e_dump(struct e1000_adapter *adapter) struct e1000_ring *tx_ring = adapter->tx_ring; struct e1000_tx_desc *tx_desc; struct my_u0 { - u64 a; - u64 b; + __le64 a; + __le64 b; } *u0; struct e1000_buffer *buffer_info; struct e1000_ring *rx_ring = adapter->rx_ring; union e1000_rx_desc_packet_split *rx_desc_ps; union e1000_rx_desc_extended *rx_desc; struct my_u1 { - u64 a; - u64 b; - u64 c; - u64 d; + __le64 a; + __le64 b; + __le64 c; + __le64 d; } *u1; u32 staterr; int i = 0; @@ -5963,7 +5963,8 @@ static void e1000_eeprom_checks(struct e1000_adapter *adapter) return; ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &buf); - if (!ret_val && (!(le16_to_cpu(buf) & (1 << 0)))) { + le16_to_cpus(&buf); + if (!ret_val && (!(buf & (1 << 0)))) { /* Deep Smart Power Down (DSPD) */ dev_warn(&adapter->pdev->dev, "Warning: detected DSPD enabled in EEPROM\n"); -- cgit v1.2.3-70-g09d2 From 0e15df490eef6f5080b84533dcd3068a78122768 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Tue, 31 Jan 2012 06:37:11 +0000 Subject: e1000e: minor whitespace and indentation cleanup Cleanup of some whitespace and indentation of a single code block. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/ich8lan.c | 4 +- drivers/net/ethernet/intel/e1000e/netdev.c | 76 ++++++++++++++++------------- 2 files changed, 43 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 0e64cc43849..5061d4ded6e 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -280,8 +280,8 @@ static inline void __ew32flash(struct e1000_hw *hw, unsigned long reg, u32 val) #define er16flash(reg) __er16flash(hw, (reg)) #define er32flash(reg) __er32flash(hw, (reg)) -#define ew16flash(reg,val) __ew16flash(hw, (reg), (val)) -#define ew32flash(reg,val) __ew32flash(hw, (reg), (val)) +#define ew16flash(reg, val) __ew16flash(hw, (reg), (val)) +#define ew32flash(reg, val) __ew32flash(hw, (reg), (val)) static void e1000_toggle_lanphypc_value_ich8lan(struct e1000_hw *hw) { diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 2ac1164d04e..293a7606e0f 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -1267,43 +1267,49 @@ static bool e1000_clean_rx_irq_ps(struct e1000_ring *rx_ring, int *work_done, skb_put(skb, length); { - /* - * this looks ugly, but it seems compiler issues make it - * more efficient than reusing j - */ - int l1 = le16_to_cpu(rx_desc->wb.upper.length[0]); - - /* - * page alloc/put takes too long and effects small packet - * throughput, so unsplit small packets and save the alloc/put - * only valid in softirq (napi) context to call kmap_* - */ - if (l1 && (l1 <= copybreak) && - ((length + l1) <= adapter->rx_ps_bsize0)) { - u8 *vaddr; - - ps_page = &buffer_info->ps_pages[0]; + /* + * this looks ugly, but it seems compiler issues make + * it more efficient than reusing j + */ + int l1 = le16_to_cpu(rx_desc->wb.upper.length[0]); /* - * there is no documentation about how to call - * kmap_atomic, so we can't hold the mapping - * very long + * page alloc/put takes too long and effects small + * packet throughput, so unsplit small packets and + * save the alloc/put only valid in softirq (napi) + * context to call kmap_* */ - dma_sync_single_for_cpu(&pdev->dev, ps_page->dma, - PAGE_SIZE, DMA_FROM_DEVICE); - vaddr = kmap_atomic(ps_page->page, KM_SKB_DATA_SOFTIRQ); - memcpy(skb_tail_pointer(skb), vaddr, l1); - kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ); - dma_sync_single_for_device(&pdev->dev, ps_page->dma, - PAGE_SIZE, DMA_FROM_DEVICE); - - /* remove the CRC */ - if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) - l1 -= 4; - - skb_put(skb, l1); - goto copydone; - } /* if */ + if (l1 && (l1 <= copybreak) && + ((length + l1) <= adapter->rx_ps_bsize0)) { + u8 *vaddr; + + ps_page = &buffer_info->ps_pages[0]; + + /* + * there is no documentation about how to call + * kmap_atomic, so we can't hold the mapping + * very long + */ + dma_sync_single_for_cpu(&pdev->dev, + ps_page->dma, + PAGE_SIZE, + DMA_FROM_DEVICE); + vaddr = kmap_atomic(ps_page->page, + KM_SKB_DATA_SOFTIRQ); + memcpy(skb_tail_pointer(skb), vaddr, l1); + kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ); + dma_sync_single_for_device(&pdev->dev, + ps_page->dma, + PAGE_SIZE, + DMA_FROM_DEVICE); + + /* remove the CRC */ + if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) + l1 -= 4; + + skb_put(skb, l1); + goto copydone; + } /* if */ } for (j = 0; j < PS_PAGE_BUFFERS; j++) { @@ -4969,7 +4975,7 @@ static int e1000_maybe_stop_tx(struct e1000_ring *tx_ring, int size) return __e1000_maybe_stop_tx(tx_ring, size); } -#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 ) +#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1) static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) { -- cgit v1.2.3-70-g09d2 From 4fdc18d15151f3e7cc43070ec8d13570431b5abc Mon Sep 17 00:00:00 2001 From: Nikolai Kondrashov Date: Mon, 6 Feb 2012 22:54:20 +0200 Subject: HID: waltop: Add support for Waltop Q Pad Add support for Waltop Q Pad by fixing its report descriptor. This tablet is also sold as Aiptek HyperPen Mini. Other possible names include: NGS Flexi Style, VisTablet PenPad, iVistaTablet Q Flex Pad, Bravod Q-PD65-S. Signed-off-by: Nikolai Kondrashov Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h | 1 + drivers/hid/hid-waltop.c | 192 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 194 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 23fa03176ac..162be0955df 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1558,6 +1558,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) }, { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) }, { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) }, + { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_Q_PAD) }, { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) }, { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) }, { HID_USB_DEVICE(USB_VENDOR_ID_XAT, USB_DEVICE_ID_XAT_CSR) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 5f63e361be1..1a002201516 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -707,6 +707,7 @@ #define USB_VENDOR_ID_WALTOP 0x172f #define USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH 0x0032 #define USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH 0x0034 +#define USB_DEVICE_ID_WALTOP_Q_PAD 0x0037 #define USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH 0x0501 #define USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH 0x0500 diff --git a/drivers/hid/hid-waltop.c b/drivers/hid/hid-waltop.c index b3a4163f2e6..0ec169646ec 100644 --- a/drivers/hid/hid-waltop.c +++ b/drivers/hid/hid-waltop.c @@ -423,6 +423,190 @@ static __u8 slim_tablet_12_1_inch_rdesc_fixed[] = { 0xC0 /* End Collection */ }; +/* + * Original Q Pad report descriptor. + * + * The descriptor is similar to the Slim Tablet 5.8 inch descriptor with the + * addition of consumer AC Pan field to the report ID 1, which seems to be + * unused in the default mode. However, this tablet has resolution of 2048 LPI. + * + * Usage Page (Desktop), ; Generic desktop controls (01h) + * Usage (Mouse), ; Mouse (02h, application collection) + * Collection (Application), + * Report ID (1), + * Usage (Pointer), ; Pointer (01h, physical collection) + * Collection (Physical), + * Usage Page (Button), ; Button (09h) + * Usage Minimum (01h), + * Usage Maximum (05h), + * Logical Minimum (0), + * Logical Maximum (1), + * Report Size (1), + * Report Count (5), + * Input (Variable), + * Report Size (3), + * Report Count (1), + * Input (Constant, Variable), + * Usage Page (Desktop), ; Generic desktop controls (01h) + * Usage (X), ; X (30h, dynamic value) + * Usage (Y), ; Y (31h, dynamic value) + * Usage (Wheel), ; Wheel (38h, dynamic value) + * Logical Minimum (-127), + * Logical Maximum (127), + * Report Size (8), + * Report Count (3), + * Input (Variable, Relative), + * Usage Page (Consumer), ; Consumer (0Ch) + * Logical Minimum (-127), + * Logical Maximum (127), + * Report Size (8), + * Report Count (1), + * Usage (AC Pan), ; AC pan (0238h, linear control) + * Input (Variable, Relative), + * End Collection, + * End Collection, + * Usage Page (Digitizer), ; Digitizer (0Dh) + * Usage (Pen), ; Pen (02h, application collection) + * Collection (Application), + * Report ID (2), + * Usage (Stylus), ; Stylus (20h, logical collection) + * Collection (Physical), + * Usage (00h), + * Logical Minimum (0), + * Logical Maximum (255), + * Report Size (8), + * Report Count (7), + * Input (Variable), + * Usage (Azimuth), ; Azimuth (3Fh, dynamic value) + * Usage (Altitude), ; Altitude (40h, dynamic value) + * Logical Minimum (0), + * Logical Maximum (255), + * Report Size (8), + * Report Count (2), + * Feature (Variable), + * End Collection, + * Report ID (5), + * Usage Page (Digitizer), ; Digitizer (0Dh) + * Usage (Stylus), ; Stylus (20h, logical collection) + * Collection (Physical), + * Usage (00h), + * Logical Minimum (0), + * Logical Maximum (255), + * Report Size (8), + * Report Count (7), + * Input (Variable), + * End Collection, + * Report ID (10), + * Usage Page (Digitizer), ; Digitizer (0Dh) + * Usage (Stylus), ; Stylus (20h, logical collection) + * Collection (Physical), + * Usage (00h), + * Logical Minimum (0), + * Logical Maximum (255), + * Report Size (8), + * Report Count (7), + * Input (Variable), + * End Collection, + * Report ID (16), + * Usage (Stylus), ; Stylus (20h, logical collection) + * Collection (Physical), + * Usage (Tip Switch), ; Tip switch (42h, momentary control) + * Usage (Barrel Switch), ; Barrel switch (44h, momentary control) + * Usage (Invert), ; Invert (3Ch, momentary control) + * Usage (Eraser), ; Eraser (45h, momentary control) + * Usage (In Range), ; In range (32h, momentary control) + * Logical Minimum (0), + * Logical Maximum (1), + * Report Size (1), + * Report Count (5), + * Input (Variable), + * Report Count (3), + * Input (Constant, Variable), + * Usage Page (Desktop), ; Generic desktop controls (01h) + * Usage (X), ; X (30h, dynamic value) + * Report Size (16), + * Report Count (1), + * Push, + * Unit Exponent (13), + * Unit (Inch^3), + * Logical Minimum (0), + * Logical Maximum (12288), + * Physical Minimum (0), + * Physical Maximum (12288), + * Input (Variable), + * Usage (Y), ; Y (31h, dynamic value) + * Logical Minimum (0), + * Logical Maximum (9216), + * Physical Minimum (0), + * Physical Maximum (9216), + * Input (Variable), + * Usage Page (Digitizer), ; Digitizer (0Dh) + * Usage (Tip Pressure), ; Tip pressure (30h, dynamic value) + * Logical Minimum (0), + * Logical Maximum (1023), + * Physical Minimum (0), + * Physical Maximum (1023), + * Input (Variable), + * End Collection, + * End Collection + */ + +/* Size of the original report descriptor of Q Pad */ +#define Q_PAD_RDESC_ORIG_SIZE 241 + +/* + * Fixed Q Pad descriptor. + * + * All the reports except the stylus report (ID 16) were removed as unused. + * The stylus buttons description was fixed. + */ +static __u8 q_pad_rdesc_fixed[] = { + 0x05, 0x0D, /* Usage Page (Digitizer), */ + 0x09, 0x02, /* Usage (Pen), */ + 0xA1, 0x01, /* Collection (Application), */ + 0x85, 0x10, /* Report ID (16), */ + 0x09, 0x20, /* Usage (Stylus), */ + 0xA0, /* Collection (Physical), */ + 0x09, 0x42, /* Usage (Tip Switch), */ + 0x09, 0x44, /* Usage (Barrel Switch), */ + 0x09, 0x46, /* Usage (Tablet Pick), */ + 0x15, 0x01, /* Logical Minimum (1), */ + 0x25, 0x03, /* Logical Maximum (3), */ + 0x75, 0x04, /* Report Size (4), */ + 0x95, 0x01, /* Report Count (1), */ + 0x80, /* Input, */ + 0x09, 0x32, /* Usage (In Range), */ + 0x14, /* Logical Minimum (0), */ + 0x25, 0x01, /* Logical Maximum (1), */ + 0x75, 0x01, /* Report Size (1), */ + 0x95, 0x01, /* Report Count (1), */ + 0x81, 0x02, /* Input (Variable), */ + 0x95, 0x03, /* Report Count (3), */ + 0x81, 0x03, /* Input (Constant, Variable), */ + 0x75, 0x10, /* Report Size (16), */ + 0x95, 0x01, /* Report Count (1), */ + 0x14, /* Logical Minimum (0), */ + 0xA4, /* Push, */ + 0x05, 0x01, /* Usage Page (Desktop), */ + 0x65, 0x13, /* Unit (Inch), */ + 0x55, 0xFD, /* Unit Exponent (-3), */ + 0x34, /* Physical Minimum (0), */ + 0x09, 0x30, /* Usage (X), */ + 0x46, 0x70, 0x17, /* Physical Maximum (6000), */ + 0x26, 0x00, 0x30, /* Logical Maximum (12288), */ + 0x81, 0x02, /* Input (Variable), */ + 0x09, 0x31, /* Usage (Y), */ + 0x46, 0x94, 0x11, /* Physical Maximum (4500), */ + 0x26, 0x00, 0x24, /* Logical Maximum (9216), */ + 0x81, 0x02, /* Input (Variable), */ + 0xB4, /* Pop, */ + 0x09, 0x30, /* Usage (Tip Pressure), */ + 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ + 0x81, 0x02, /* Input (Variable), */ + 0xC0, /* End Collection, */ + 0xC0 /* End Collection */ +}; + /* * Original Media Tablet 10.6 inch report descriptor. * @@ -1049,6 +1233,12 @@ static __u8 *waltop_report_fixup(struct hid_device *hdev, __u8 *rdesc, *rsize = sizeof(slim_tablet_12_1_inch_rdesc_fixed); } break; + case USB_DEVICE_ID_WALTOP_Q_PAD: + if (*rsize == Q_PAD_RDESC_ORIG_SIZE) { + rdesc = q_pad_rdesc_fixed; + *rsize = sizeof(q_pad_rdesc_fixed); + } + break; case USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH: if (*rsize == MEDIA_TABLET_10_6_INCH_RDESC_ORIG_SIZE) { rdesc = media_tablet_10_6_inch_rdesc_fixed; @@ -1070,6 +1260,8 @@ static const struct hid_device_id waltop_devices[] = { USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) }, { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) }, + { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, + USB_DEVICE_ID_WALTOP_Q_PAD) }, { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) }, { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, -- cgit v1.2.3-70-g09d2 From b72061a3cb0f1c5aa3f919e2dadb4a1631773e7a Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 7 Feb 2012 08:27:31 +0000 Subject: net: fec: Fix build due to wrong dev annotation commit 21a4e469 (netdev: ethernet dev_alloc_skb to netdev_alloc_skb) should have used "ndev" instead of "dev". This causes the following build errors: drivers/net/ethernet/freescale/fec.c: In function 'fec_enet_rx': drivers/net/ethernet/freescale/fec.c:714: error: 'dev' undeclared (first use in this function) drivers/net/ethernet/freescale/fec.c:714: error: (Each undeclared identifier is reported only once drivers/net/ethernet/freescale/fec.c:714: error: for each function it appears in.) drivers/net/ethernet/freescale/fec.c: In function 'fec_enet_alloc_buffers': drivers/net/ethernet/freescale/fec.c:1213: error: 'dev' undeclared (first use in this function) Fix it, so that fec driver can be built again. Signed-off-by: Fabio Estevam Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index f976619d1b2..0ee2ca7baaf 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -711,7 +711,7 @@ fec_enet_rx(struct net_device *ndev) * include that when passing upstream as it messes up * bridging applications. */ - skb = netdev_alloc_skb(dev, pkt_len - 4 + NET_IP_ALIGN); + skb = netdev_alloc_skb(ndev, pkt_len - 4 + NET_IP_ALIGN); if (unlikely(!skb)) { printk("%s: Memory squeeze, dropping packet.\n", @@ -1210,7 +1210,7 @@ static int fec_enet_alloc_buffers(struct net_device *ndev) bdp = fep->rx_bd_base; for (i = 0; i < RX_RING_SIZE; i++) { - skb = netdev_alloc_skb(dev, FEC_ENET_RX_FRSIZE); + skb = netdev_alloc_skb(ndev, FEC_ENET_RX_FRSIZE); if (!skb) { fec_enet_free_buffers(ndev); return -ENOMEM; -- cgit v1.2.3-70-g09d2 From bb7d92e3e3049e22b5807ac559a72b38fad5f499 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 6 Feb 2012 22:17:21 +0000 Subject: sh-eth: use netdev stats structure and fix dma_map_single No need to maintain a parallel net_device_stats structure in sh_eth_private, since we have a generic one in netdev Fix two dma_map_single() incorrect parameters, passing skb->tail instead of skb->data. Seems that there is no corresponding dmap_unmap_single() calls for the moment in this driver. Signed-off-by: Eric Dumazet Cc: Yoshihiro Shimoda Tested-by: Yoshihiro Shimoda Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 62 +++++++++++++++++------------------ drivers/net/ethernet/renesas/sh_eth.h | 1 - 2 files changed, 31 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 1cb5a34d577..dacd13150b6 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -657,7 +657,7 @@ static void sh_eth_ring_format(struct net_device *ndev) mdp->rx_skbuff[i] = skb; if (skb == NULL) break; - dma_map_single(&ndev->dev, skb->tail, mdp->rx_buf_sz, + dma_map_single(&ndev->dev, skb->data, mdp->rx_buf_sz, DMA_FROM_DEVICE); skb->dev = ndev; /* Mark as being used by this device. */ sh_eth_set_receive_align(skb); @@ -881,8 +881,8 @@ static int sh_eth_txfree(struct net_device *ndev) if (entry >= TX_RING_SIZE - 1) txdesc->status |= cpu_to_edmac(mdp, TD_TDLE); - mdp->stats.tx_packets++; - mdp->stats.tx_bytes += txdesc->buffer_length; + ndev->stats.tx_packets++; + ndev->stats.tx_bytes += txdesc->buffer_length; } return freeNum; } @@ -908,23 +908,23 @@ static int sh_eth_rx(struct net_device *ndev) break; if (!(desc_status & RDFEND)) - mdp->stats.rx_length_errors++; + ndev->stats.rx_length_errors++; if (desc_status & (RD_RFS1 | RD_RFS2 | RD_RFS3 | RD_RFS4 | RD_RFS5 | RD_RFS6 | RD_RFS10)) { - mdp->stats.rx_errors++; + ndev->stats.rx_errors++; if (desc_status & RD_RFS1) - mdp->stats.rx_crc_errors++; + ndev->stats.rx_crc_errors++; if (desc_status & RD_RFS2) - mdp->stats.rx_frame_errors++; + ndev->stats.rx_frame_errors++; if (desc_status & RD_RFS3) - mdp->stats.rx_length_errors++; + ndev->stats.rx_length_errors++; if (desc_status & RD_RFS4) - mdp->stats.rx_length_errors++; + ndev->stats.rx_length_errors++; if (desc_status & RD_RFS6) - mdp->stats.rx_missed_errors++; + ndev->stats.rx_missed_errors++; if (desc_status & RD_RFS10) - mdp->stats.rx_over_errors++; + ndev->stats.rx_over_errors++; } else { if (!mdp->cd->hw_swap) sh_eth_soft_swap( @@ -937,8 +937,8 @@ static int sh_eth_rx(struct net_device *ndev) skb_put(skb, pkt_len); skb->protocol = eth_type_trans(skb, ndev); netif_rx(skb); - mdp->stats.rx_packets++; - mdp->stats.rx_bytes += pkt_len; + ndev->stats.rx_packets++; + ndev->stats.rx_bytes += pkt_len; } rxdesc->status |= cpu_to_edmac(mdp, RD_RACT); entry = (++mdp->cur_rx) % RX_RING_SIZE; @@ -957,7 +957,7 @@ static int sh_eth_rx(struct net_device *ndev) mdp->rx_skbuff[entry] = skb; if (skb == NULL) break; /* Better luck next round. */ - dma_map_single(&ndev->dev, skb->tail, mdp->rx_buf_sz, + dma_map_single(&ndev->dev, skb->data, mdp->rx_buf_sz, DMA_FROM_DEVICE); skb->dev = ndev; sh_eth_set_receive_align(skb); @@ -1007,7 +1007,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) felic_stat = sh_eth_read(ndev, ECSR); sh_eth_write(ndev, felic_stat, ECSR); /* clear int */ if (felic_stat & ECSR_ICD) - mdp->stats.tx_carrier_errors++; + ndev->stats.tx_carrier_errors++; if (felic_stat & ECSR_LCHNG) { /* Link Changed */ if (mdp->cd->no_psr || mdp->no_ether_link) { @@ -1040,7 +1040,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) if (intr_status & EESR_TWB) { /* Write buck end. unused write back interrupt */ if (intr_status & EESR_TABT) /* Transmit Abort int */ - mdp->stats.tx_aborted_errors++; + ndev->stats.tx_aborted_errors++; if (netif_msg_tx_err(mdp)) dev_err(&ndev->dev, "Transmit Abort\n"); } @@ -1049,7 +1049,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) /* Receive Abort int */ if (intr_status & EESR_RFRMER) { /* Receive Frame Overflow int */ - mdp->stats.rx_frame_errors++; + ndev->stats.rx_frame_errors++; if (netif_msg_rx_err(mdp)) dev_err(&ndev->dev, "Receive Abort\n"); } @@ -1057,21 +1057,21 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) if (intr_status & EESR_TDE) { /* Transmit Descriptor Empty int */ - mdp->stats.tx_fifo_errors++; + ndev->stats.tx_fifo_errors++; if (netif_msg_tx_err(mdp)) dev_err(&ndev->dev, "Transmit Descriptor Empty\n"); } if (intr_status & EESR_TFE) { /* FIFO under flow */ - mdp->stats.tx_fifo_errors++; + ndev->stats.tx_fifo_errors++; if (netif_msg_tx_err(mdp)) dev_err(&ndev->dev, "Transmit FIFO Under flow\n"); } if (intr_status & EESR_RDE) { /* Receive Descriptor Empty int */ - mdp->stats.rx_over_errors++; + ndev->stats.rx_over_errors++; if (sh_eth_read(ndev, EDRRR) ^ EDRRR_R) sh_eth_write(ndev, EDRRR_R, EDRRR); @@ -1081,14 +1081,14 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) if (intr_status & EESR_RFE) { /* Receive FIFO Overflow int */ - mdp->stats.rx_fifo_errors++; + ndev->stats.rx_fifo_errors++; if (netif_msg_rx_err(mdp)) dev_err(&ndev->dev, "Receive FIFO Overflow\n"); } if (!mdp->cd->no_ade && (intr_status & EESR_ADE)) { /* Address Error */ - mdp->stats.tx_fifo_errors++; + ndev->stats.tx_fifo_errors++; if (netif_msg_tx_err(mdp)) dev_err(&ndev->dev, "Address Error\n"); } @@ -1445,7 +1445,7 @@ static void sh_eth_tx_timeout(struct net_device *ndev) " resetting...\n", ndev->name, (int)sh_eth_read(ndev, EESR)); /* tx_errors count up */ - mdp->stats.tx_errors++; + ndev->stats.tx_errors++; /* timer off */ del_timer_sync(&mdp->timer); @@ -1567,27 +1567,27 @@ static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev) pm_runtime_get_sync(&mdp->pdev->dev); - mdp->stats.tx_dropped += sh_eth_read(ndev, TROCR); + ndev->stats.tx_dropped += sh_eth_read(ndev, TROCR); sh_eth_write(ndev, 0, TROCR); /* (write clear) */ - mdp->stats.collisions += sh_eth_read(ndev, CDCR); + ndev->stats.collisions += sh_eth_read(ndev, CDCR); sh_eth_write(ndev, 0, CDCR); /* (write clear) */ - mdp->stats.tx_carrier_errors += sh_eth_read(ndev, LCCR); + ndev->stats.tx_carrier_errors += sh_eth_read(ndev, LCCR); sh_eth_write(ndev, 0, LCCR); /* (write clear) */ if (sh_eth_is_gether(mdp)) { - mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CERCR); + ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CERCR); sh_eth_write(ndev, 0, CERCR); /* (write clear) */ - mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CEECR); + ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CEECR); sh_eth_write(ndev, 0, CEECR); /* (write clear) */ } else { - mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CNDCR); + ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CNDCR); sh_eth_write(ndev, 0, CNDCR); /* (write clear) */ } pm_runtime_put_sync(&mdp->pdev->dev); - return &mdp->stats; + return &ndev->stats; } -/* ioctl to device funciotn*/ +/* ioctl to device function */ static int sh_eth_do_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) { diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h index 47877b13ffa..ba72976926f 100644 --- a/drivers/net/ethernet/renesas/sh_eth.h +++ b/drivers/net/ethernet/renesas/sh_eth.h @@ -762,7 +762,6 @@ struct sh_eth_private { struct sh_eth_txdesc *tx_ring; struct sk_buff **rx_skbuff; struct sk_buff **tx_skbuff; - struct net_device_stats stats; struct timer_list timer; spinlock_t lock; u32 cur_rx, dirty_rx; /* Producer/consumer ring indices */ -- cgit v1.2.3-70-g09d2 From 7280f5ae0d71f2259a42d1f7603480809e4867fb Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 7 Feb 2012 15:28:15 -0500 Subject: sonice: Fix build due to botched netdev_alloc_skb() conversion. Reported-by: Geert Uytterhoeven Signed-off-by: David S. Miller --- drivers/net/ethernet/natsemi/sonic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/natsemi/sonic.c b/drivers/net/ethernet/natsemi/sonic.c index 0452e2968d2..46795e40346 100644 --- a/drivers/net/ethernet/natsemi/sonic.c +++ b/drivers/net/ethernet/natsemi/sonic.c @@ -422,7 +422,7 @@ static void sonic_rx(struct net_device *dev) status = sonic_rda_get(dev, entry, SONIC_RD_STATUS); if (status & SONIC_RCR_PRX) { /* Malloc up new buffer. */ - new_skb = netdev_alloc_skb(SONIC_RBSIZE + 2); + new_skb = netdev_alloc_skb(dev, SONIC_RBSIZE + 2); if (new_skb == NULL) { printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n", dev->name); lp->stats.rx_dropped++; -- cgit v1.2.3-70-g09d2 From 9b9a4f2acac2a04416ba15242b8666d4f8273e31 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Mon, 6 Feb 2012 08:23:27 +0200 Subject: ath6kl: store firmware logs in skbuffs Currently firmware logs are stored in a circular buffer, but this was not very flexible and fragile. It's a lot easier to store logs to struct skbuffs and store them in a skb queue. Also this makes it possible to easily increase the buffer size, even dynamically if we so want (but that's not yet supported). From user space point of view nothing should change. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/core.h | 5 +- drivers/net/wireless/ath/ath6kl/debug.c | 121 ++++++++++---------------------- 2 files changed, 41 insertions(+), 85 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index c4d66e066dc..9a58214135b 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -652,10 +652,9 @@ struct ath6kl { #ifdef CONFIG_ATH6KL_DEBUG struct { - struct circ_buf fwlog_buf; - spinlock_t fwlog_lock; - void *fwlog_tmp; + struct sk_buff_head fwlog_queue; u32 fwlog_mask; + unsigned int dbgfs_diag_reg; u32 diag_reg_addr_wr; u32 diag_reg_val_wr; diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c index d832058816f..98b5f15f622 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.c +++ b/drivers/net/wireless/ath/ath6kl/debug.c @@ -16,7 +16,7 @@ #include "core.h" -#include +#include #include #include #include @@ -32,9 +32,8 @@ struct ath6kl_fwlog_slot { u8 payload[0]; }; -#define ATH6KL_FWLOG_SIZE 32768 -#define ATH6KL_FWLOG_SLOT_SIZE (sizeof(struct ath6kl_fwlog_slot) + \ - ATH6KL_FWLOG_PAYLOAD_SIZE) +#define ATH6KL_FWLOG_MAX_ENTRIES 20 + #define ATH6KL_FWLOG_VALID_MASK 0x1ffff int ath6kl_printk(const char *level, const char *fmt, ...) @@ -268,105 +267,77 @@ static const struct file_operations fops_war_stats = { .llseek = default_llseek, }; -static void ath6kl_debug_fwlog_add(struct ath6kl *ar, const void *buf, - size_t buf_len) -{ - struct circ_buf *fwlog = &ar->debug.fwlog_buf; - size_t space; - int i; - - /* entries must all be equal size */ - if (WARN_ON(buf_len != ATH6KL_FWLOG_SLOT_SIZE)) - return; - - space = CIRC_SPACE(fwlog->head, fwlog->tail, ATH6KL_FWLOG_SIZE); - if (space < buf_len) - /* discard oldest slot */ - fwlog->tail = (fwlog->tail + ATH6KL_FWLOG_SLOT_SIZE) & - (ATH6KL_FWLOG_SIZE - 1); - - for (i = 0; i < buf_len; i += space) { - space = CIRC_SPACE_TO_END(fwlog->head, fwlog->tail, - ATH6KL_FWLOG_SIZE); - - if ((size_t) space > buf_len - i) - space = buf_len - i; - - memcpy(&fwlog->buf[fwlog->head], buf, space); - fwlog->head = (fwlog->head + space) & (ATH6KL_FWLOG_SIZE - 1); - } - -} - void ath6kl_debug_fwlog_event(struct ath6kl *ar, const void *buf, size_t len) { - struct ath6kl_fwlog_slot *slot = ar->debug.fwlog_tmp; + struct ath6kl_fwlog_slot *slot; + struct sk_buff *skb; size_t slot_len; if (WARN_ON(len > ATH6KL_FWLOG_PAYLOAD_SIZE)) return; - spin_lock_bh(&ar->debug.fwlog_lock); + slot_len = sizeof(*slot) + len; + skb = alloc_skb(slot_len, GFP_KERNEL); + if (!skb) + return; + + slot = (struct ath6kl_fwlog_slot *) skb_put(skb, slot_len); slot->timestamp = cpu_to_le32(jiffies); slot->length = cpu_to_le32(len); memcpy(slot->payload, buf, len); - slot_len = sizeof(*slot) + len; + spin_lock(&ar->debug.fwlog_queue.lock); - if (slot_len < ATH6KL_FWLOG_SLOT_SIZE) - memset(slot->payload + len, 0, - ATH6KL_FWLOG_SLOT_SIZE - slot_len); + __skb_queue_tail(&ar->debug.fwlog_queue, skb); - ath6kl_debug_fwlog_add(ar, slot, ATH6KL_FWLOG_SLOT_SIZE); + /* drop oldest entries */ + while (skb_queue_len(&ar->debug.fwlog_queue) > + ATH6KL_FWLOG_MAX_ENTRIES) { + skb = __skb_dequeue(&ar->debug.fwlog_queue); + kfree_skb(skb); + } - spin_unlock_bh(&ar->debug.fwlog_lock); -} + spin_unlock(&ar->debug.fwlog_queue.lock); -static bool ath6kl_debug_fwlog_empty(struct ath6kl *ar) -{ - return CIRC_CNT(ar->debug.fwlog_buf.head, - ar->debug.fwlog_buf.tail, - ATH6KL_FWLOG_SLOT_SIZE) == 0; + return; } static ssize_t ath6kl_fwlog_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct ath6kl *ar = file->private_data; - struct circ_buf *fwlog = &ar->debug.fwlog_buf; - size_t len = 0, buf_len = count; + struct sk_buff *skb; ssize_t ret_cnt; + size_t len = 0; char *buf; - int ccnt; - buf = vmalloc(buf_len); + buf = vmalloc(count); if (!buf) return -ENOMEM; /* read undelivered logs from firmware */ ath6kl_read_fwlogs(ar); - spin_lock_bh(&ar->debug.fwlog_lock); + spin_lock(&ar->debug.fwlog_queue.lock); - while (len < buf_len && !ath6kl_debug_fwlog_empty(ar)) { - ccnt = CIRC_CNT_TO_END(fwlog->head, fwlog->tail, - ATH6KL_FWLOG_SIZE); + while ((skb = __skb_dequeue(&ar->debug.fwlog_queue))) { + if (skb->len > count - len) { + /* not enough space, put skb back and leave */ + __skb_queue_head(&ar->debug.fwlog_queue, skb); + break; + } - if ((size_t) ccnt > buf_len - len) - ccnt = buf_len - len; - memcpy(buf + len, &fwlog->buf[fwlog->tail], ccnt); - len += ccnt; + memcpy(buf + len, skb->data, skb->len); + len += skb->len; - fwlog->tail = (fwlog->tail + ccnt) & - (ATH6KL_FWLOG_SIZE - 1); + kfree_skb(skb); } - spin_unlock_bh(&ar->debug.fwlog_lock); + spin_unlock(&ar->debug.fwlog_queue.lock); - if (WARN_ON(len > buf_len)) - len = buf_len; + /* FIXME: what to do if len == 0? */ ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); @@ -1651,17 +1622,7 @@ static const struct file_operations fops_power_params = { int ath6kl_debug_init(struct ath6kl *ar) { - ar->debug.fwlog_buf.buf = vmalloc(ATH6KL_FWLOG_SIZE); - if (ar->debug.fwlog_buf.buf == NULL) - return -ENOMEM; - - ar->debug.fwlog_tmp = kmalloc(ATH6KL_FWLOG_SLOT_SIZE, GFP_KERNEL); - if (ar->debug.fwlog_tmp == NULL) { - vfree(ar->debug.fwlog_buf.buf); - return -ENOMEM; - } - - spin_lock_init(&ar->debug.fwlog_lock); + skb_queue_head_init(&ar->debug.fwlog_queue); /* * Actually we are lying here but don't know how to read the mask @@ -1671,11 +1632,8 @@ int ath6kl_debug_init(struct ath6kl *ar) ar->debugfs_phy = debugfs_create_dir("ath6kl", ar->wiphy->debugfsdir); - if (!ar->debugfs_phy) { - vfree(ar->debug.fwlog_buf.buf); - kfree(ar->debug.fwlog_tmp); + if (!ar->debugfs_phy) return -ENOMEM; - } debugfs_create_file("tgt_stats", S_IRUSR, ar->debugfs_phy, ar, &fops_tgt_stats); @@ -1742,8 +1700,7 @@ int ath6kl_debug_init(struct ath6kl *ar) void ath6kl_debug_cleanup(struct ath6kl *ar) { - vfree(ar->debug.fwlog_buf.buf); - kfree(ar->debug.fwlog_tmp); + skb_queue_purge(&ar->debug.fwlog_queue); kfree(ar->debug.roam_tbl); } -- cgit v1.2.3-70-g09d2 From c807b30d2588dd3c74db1f690a0e9e724dd332da Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Mon, 6 Feb 2012 08:23:40 +0200 Subject: ath6kl: add blocking debugfs file for retrieving firmware logs When debugging firmware issues it's not always enough to get the latest firmware logs, sometimes we need to get logs from a longer period. To make this possible, add a debugfs file named fwlog_block. When reading from this file ath6kl will send firmware logs whenever available and otherwise it will block and wait for new logs. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/core.h | 3 + drivers/net/wireless/ath/ath6kl/debug.c | 104 +++++++++++++++++++++++++++++++- 2 files changed, 106 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 9a58214135b..4ff06a32678 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -653,6 +653,9 @@ struct ath6kl { #ifdef CONFIG_ATH6KL_DEBUG struct { struct sk_buff_head fwlog_queue; + struct completion fwlog_completion; + bool fwlog_open; + u32 fwlog_mask; unsigned int dbgfs_diag_reg; diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c index 98b5f15f622..ec32ff69216 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.c +++ b/drivers/net/wireless/ath/ath6kl/debug.c @@ -290,6 +290,7 @@ void ath6kl_debug_fwlog_event(struct ath6kl *ar, const void *buf, size_t len) spin_lock(&ar->debug.fwlog_queue.lock); __skb_queue_tail(&ar->debug.fwlog_queue, skb); + complete(&ar->debug.fwlog_completion); /* drop oldest entries */ while (skb_queue_len(&ar->debug.fwlog_queue) > @@ -303,6 +304,28 @@ void ath6kl_debug_fwlog_event(struct ath6kl *ar, const void *buf, size_t len) return; } +static int ath6kl_fwlog_open(struct inode *inode, struct file *file) +{ + struct ath6kl *ar = inode->i_private; + + if (ar->debug.fwlog_open) + return -EBUSY; + + ar->debug.fwlog_open = true; + + file->private_data = inode->i_private; + return 0; +} + +static int ath6kl_fwlog_release(struct inode *inode, struct file *file) +{ + struct ath6kl *ar = inode->i_private; + + ar->debug.fwlog_open = false; + + return 0; +} + static ssize_t ath6kl_fwlog_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -347,12 +370,87 @@ static ssize_t ath6kl_fwlog_read(struct file *file, char __user *user_buf, } static const struct file_operations fops_fwlog = { - .open = ath6kl_debugfs_open, + .open = ath6kl_fwlog_open, + .release = ath6kl_fwlog_release, .read = ath6kl_fwlog_read, .owner = THIS_MODULE, .llseek = default_llseek, }; +static ssize_t ath6kl_fwlog_block_read(struct file *file, + char __user *user_buf, + size_t count, + loff_t *ppos) +{ + struct ath6kl *ar = file->private_data; + struct sk_buff *skb; + ssize_t ret_cnt; + size_t len = 0, not_copied; + char *buf; + int ret; + + buf = vmalloc(count); + if (!buf) + return -ENOMEM; + + spin_lock(&ar->debug.fwlog_queue.lock); + + if (skb_queue_len(&ar->debug.fwlog_queue) == 0) { + /* we must init under queue lock */ + init_completion(&ar->debug.fwlog_completion); + + spin_unlock(&ar->debug.fwlog_queue.lock); + + ret = wait_for_completion_interruptible( + &ar->debug.fwlog_completion); + if (ret == -ERESTARTSYS) + return ret; + + spin_lock(&ar->debug.fwlog_queue.lock); + } + + while ((skb = __skb_dequeue(&ar->debug.fwlog_queue))) { + if (skb->len > count - len) { + /* not enough space, put skb back and leave */ + __skb_queue_head(&ar->debug.fwlog_queue, skb); + break; + } + + + memcpy(buf + len, skb->data, skb->len); + len += skb->len; + + kfree_skb(skb); + } + + spin_unlock(&ar->debug.fwlog_queue.lock); + + /* FIXME: what to do if len == 0? */ + + not_copied = copy_to_user(user_buf, buf, len); + if (not_copied != 0) { + ret_cnt = -EFAULT; + goto out; + } + + *ppos = *ppos + len; + + ret_cnt = len; + +out: + vfree(buf); + + return ret_cnt; +} + +static const struct file_operations fops_fwlog_block = { + .open = ath6kl_fwlog_open, + .release = ath6kl_fwlog_release, + .read = ath6kl_fwlog_block_read, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + static ssize_t ath6kl_fwlog_mask_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -1623,6 +1721,7 @@ static const struct file_operations fops_power_params = { int ath6kl_debug_init(struct ath6kl *ar) { skb_queue_head_init(&ar->debug.fwlog_queue); + init_completion(&ar->debug.fwlog_completion); /* * Actually we are lying here but don't know how to read the mask @@ -1647,6 +1746,9 @@ int ath6kl_debug_init(struct ath6kl *ar) debugfs_create_file("fwlog", S_IRUSR, ar->debugfs_phy, ar, &fops_fwlog); + debugfs_create_file("fwlog_block", S_IRUSR, ar->debugfs_phy, ar, + &fops_fwlog_block); + debugfs_create_file("fwlog_mask", S_IRUSR | S_IWUSR, ar->debugfs_phy, ar, &fops_fwlog_mask); -- cgit v1.2.3-70-g09d2 From 1b2df4073447234034e2329f0df584c6346a8ec3 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 6 Feb 2012 20:15:53 +0530 Subject: ath6kl: Update license header Update license header with the copyright to Qualcomm Atheros, Inc. for the year 2011-2012. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/Makefile | 3 ++- drivers/net/wireless/ath/ath6kl/bmi.c | 1 + drivers/net/wireless/ath/ath6kl/bmi.h | 1 + drivers/net/wireless/ath/ath6kl/cfg80211.c | 1 + drivers/net/wireless/ath/ath6kl/cfg80211.h | 1 + drivers/net/wireless/ath/ath6kl/common.h | 1 + drivers/net/wireless/ath/ath6kl/core.c | 1 + drivers/net/wireless/ath/ath6kl/core.h | 1 + drivers/net/wireless/ath/ath6kl/debug.c | 1 + drivers/net/wireless/ath/ath6kl/debug.h | 1 + drivers/net/wireless/ath/ath6kl/hif-ops.h | 1 + drivers/net/wireless/ath/ath6kl/hif.c | 1 + drivers/net/wireless/ath/ath6kl/hif.h | 1 + drivers/net/wireless/ath/ath6kl/htc.c | 1 + drivers/net/wireless/ath/ath6kl/htc.h | 1 + drivers/net/wireless/ath/ath6kl/init.c | 1 + drivers/net/wireless/ath/ath6kl/main.c | 1 + drivers/net/wireless/ath/ath6kl/sdio.c | 1 + drivers/net/wireless/ath/ath6kl/target.h | 1 + drivers/net/wireless/ath/ath6kl/testmode.c | 1 + drivers/net/wireless/ath/ath6kl/testmode.h | 1 + drivers/net/wireless/ath/ath6kl/txrx.c | 1 + drivers/net/wireless/ath/ath6kl/usb.c | 1 + drivers/net/wireless/ath/ath6kl/wmi.c | 1 + drivers/net/wireless/ath/ath6kl/wmi.h | 1 + 25 files changed, 26 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile index 9ba42fa0496..85746c3eb02 100644 --- a/drivers/net/wireless/ath/ath6kl/Makefile +++ b/drivers/net/wireless/ath/ath6kl/Makefile @@ -1,5 +1,6 @@ #------------------------------------------------------------------------------ -# Copyright (c) 2004-2010 Atheros Communications Inc. +# Copyright (c) 2004-2011 Atheros Communications Inc. +# Copyright (c) 2011-2012 Qualcomm Atheros, Inc. # All rights reserved. # # diff --git a/drivers/net/wireless/ath/ath6kl/bmi.c b/drivers/net/wireless/ath/ath6kl/bmi.c index aef00d5a143..05d1d8941fd 100644 --- a/drivers/net/wireless/ath/ath6kl/bmi.c +++ b/drivers/net/wireless/ath/ath6kl/bmi.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/bmi.h b/drivers/net/wireless/ath/ath6kl/bmi.h index f1ca6812456..114f7b265a3 100644 --- a/drivers/net/wireless/ath/ath6kl/bmi.h +++ b/drivers/net/wireless/ath/ath6kl/bmi.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index d1922d8eb3b..a91f521c522 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h index 3c693b7c0ef..c5def436417 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.h +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/common.h b/drivers/net/wireless/ath/ath6kl/common.h index f89f1e180da..a60e78c0472 100644 --- a/drivers/net/wireless/ath/ath6kl/common.h +++ b/drivers/net/wireless/ath/ath6kl/common.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2010-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c index 722ca59b88c..c4926cf1121 100644 --- a/drivers/net/wireless/ath/ath6kl/core.c +++ b/drivers/net/wireless/ath/ath6kl/core.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 4ff06a32678..ec7d6b67b7f 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2010-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c index ec32ff69216..3d0713dfe3b 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.c +++ b/drivers/net/wireless/ath/ath6kl/debug.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h index c4be6e50996..c5d5e6c8259 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.h +++ b/drivers/net/wireless/ath/ath6kl/debug.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/hif-ops.h b/drivers/net/wireless/ath/ath6kl/hif-ops.h index 2fe1dadfc77..fd84086638e 100644 --- a/drivers/net/wireless/ath/ath6kl/hif-ops.h +++ b/drivers/net/wireless/ath/ath6kl/hif-ops.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/hif.c b/drivers/net/wireless/ath/ath6kl/hif.c index e911737ab34..18c7f645331 100644 --- a/drivers/net/wireless/ath/ath6kl/hif.c +++ b/drivers/net/wireless/ath/ath6kl/hif.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2007-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/hif.h b/drivers/net/wireless/ath/ath6kl/hif.h index 699a036f3a4..fb4186f5d43 100644 --- a/drivers/net/wireless/ath/ath6kl/hif.h +++ b/drivers/net/wireless/ath/ath6kl/hif.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c index 2d721903640..1385f719ad0 100644 --- a/drivers/net/wireless/ath/ath6kl/htc.c +++ b/drivers/net/wireless/ath/ath6kl/htc.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2007-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/htc.h b/drivers/net/wireless/ath/ath6kl/htc.h index 57672e1ed1a..84a2ab52aa6 100644 --- a/drivers/net/wireless/ath/ath6kl/htc.h +++ b/drivers/net/wireless/ath/ath6kl/htc.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 0d76c377810..6183d579492 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index b96d01a7919..d463a18332d 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index 4febee72349..2826613b193 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/target.h b/drivers/net/wireless/ath/ath6kl/target.h index 108a723a108..ac27962f8fc 100644 --- a/drivers/net/wireless/ath/ath6kl/target.h +++ b/drivers/net/wireless/ath/ath6kl/target.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2010 Atheros Communications Inc. + * Copyright (c) 2011 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/testmode.c b/drivers/net/wireless/ath/ath6kl/testmode.c index f0cd61d6188..6675c92b542 100644 --- a/drivers/net/wireless/ath/ath6kl/testmode.c +++ b/drivers/net/wireless/ath/ath6kl/testmode.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2010-2011 Atheros Communications Inc. + * Copyright (c) 2011 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/testmode.h b/drivers/net/wireless/ath/ath6kl/testmode.h index 7fd47a62d07..fe651d6707d 100644 --- a/drivers/net/wireless/ath/ath6kl/testmode.h +++ b/drivers/net/wireless/ath/ath6kl/testmode.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2010-2011 Atheros Communications Inc. + * Copyright (c) 2011 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index a3dc6943c7f..87d46460a52 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c index c72567c6d33..325b1224c2b 100644 --- a/drivers/net/wireless/ath/ath6kl/usb.c +++ b/drivers/net/wireless/ath/ath6kl/usb.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2007-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 18fa9aa8af9..bbbe0a74d3c 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index e7919869725..e7d031b8451 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2010-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above -- cgit v1.2.3-70-g09d2 From b29072cc7b0e08ace48ab709c40cf6246fb2e8b0 Mon Sep 17 00:00:00 2001 From: Chilam Ng Date: Tue, 7 Feb 2012 01:33:00 -0800 Subject: ath6kl: prioritize Tx bundling based on AC priorities Tx bundling is the more efficient use of SDIO bus and allows more packet transfers with fewer bus transactions, and is a way to improve overall throughput. However, Tx bundling has only 4 scatter request resources available. When there are multiple traffic streams of different priorities, it's possible that lower priority traffic may hog all the scatter requests and lock out the higher prioirty traffic from bundling. Tx bundling is now enabled per AC. When an AC do a scatter request and the remaining scatter request resources is lower than a configurable threshold, it will disable Tx bundling for all AC's of lower priorities. When an AC has Tx bundling disabled and has no Tx bundles sent in a consecutive and configurable number of packets, Tx bundling will be re-enabled for that AC. Signed-off-by: Chilam Ng Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/hif.h | 2 + drivers/net/wireless/ath/ath6kl/htc.c | 77 ++++++++++++++++++++++++++++++---- drivers/net/wireless/ath/ath6kl/htc.h | 7 +++- drivers/net/wireless/ath/ath6kl/sdio.c | 2 + 4 files changed, 80 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/hif.h b/drivers/net/wireless/ath/ath6kl/hif.h index fb4186f5d43..904458ab484 100644 --- a/drivers/net/wireless/ath/ath6kl/hif.h +++ b/drivers/net/wireless/ath/ath6kl/hif.h @@ -198,6 +198,8 @@ struct hif_scatter_req { u8 *virt_dma_buf; struct hif_scatter_item scat_list[1]; + + u32 scat_q_depth; }; struct ath6kl_irq_proc_registers { diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c index 1385f719ad0..c703ef9c531 100644 --- a/drivers/net/wireless/ath/ath6kl/htc.c +++ b/drivers/net/wireless/ath/ath6kl/htc.c @@ -23,6 +23,9 @@ #define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask)) +/* threshold to re-enable Tx bundling for an AC*/ +#define TX_RESUME_BUNDLE_THRESHOLD 1500 + /* Functions for Tx credit handling */ static void ath6kl_credit_deposit(struct ath6kl_htc_credit_info *cred_info, struct htc_endpoint_credit_dist *ep_dist, @@ -745,6 +748,12 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint, struct hif_scatter_req *scat_req = NULL; int n_scat, n_sent_bundle = 0, tot_pkts_bundle = 0; int status; + u32 txb_mask; + u8 ac = WMM_NUM_AC; + + if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) || + (WMI_CONTROL_SVC != endpoint->svc_id)) + ac = target->dev->ar->ep2ac_map[endpoint->eid]; while (true) { status = 0; @@ -764,6 +773,31 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint, break; } + if ((ac < WMM_NUM_AC) && (ac != WMM_AC_BK)) { + if (WMM_AC_BE == ac) + /* + * BE, BK have priorities and bit + * positions reversed + */ + txb_mask = (1 << WMM_AC_BK); + else + /* + * any AC with priority lower than + * itself + */ + txb_mask = ((1 << ac) - 1); + /* + * when the scatter request resources drop below a + * certain threshold, disable Tx bundling for all + * AC's with priority lower than the current requesting + * AC. Otherwise re-enable Tx bundling for them + */ + if (scat_req->scat_q_depth < ATH6KL_SCATTER_REQS) + target->tx_bndl_mask &= ~txb_mask; + else + target->tx_bndl_mask |= txb_mask; + } + ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx pkts to scatter: %d\n", n_scat); @@ -807,6 +841,7 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target, struct htc_packet *packet; int bundle_sent; int n_pkts_bundle; + u8 ac = WMM_NUM_AC; spin_lock_bh(&target->tx_lock); @@ -824,6 +859,10 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target, */ INIT_LIST_HEAD(&txq); + if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) || + (WMI_CONTROL_SVC != endpoint->svc_id)) + ac = target->dev->ar->ep2ac_map[endpoint->eid]; + while (true) { if (list_empty(&endpoint->txq)) @@ -841,15 +880,18 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target, while (true) { /* try to send a bundle on each pass */ - if ((target->tx_bndl_enable) && + if ((target->tx_bndl_mask) && (get_queue_depth(&txq) >= HTC_MIN_HTC_MSGS_TO_BUNDLE)) { int temp1 = 0, temp2 = 0; - ath6kl_htc_tx_bundle(endpoint, &txq, - &temp1, &temp2); - bundle_sent += temp1; - n_pkts_bundle += temp2; + /* check if bundling is enabled for an AC */ + if (target->tx_bndl_mask & (1 << ac)) { + ath6kl_htc_tx_bundle(endpoint, &txq, + &temp1, &temp2); + bundle_sent += temp1; + n_pkts_bundle += temp2; + } } if (list_empty(&txq)) @@ -868,6 +910,26 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target, endpoint->ep_st.tx_bundles += bundle_sent; endpoint->ep_st.tx_pkt_bundled += n_pkts_bundle; + + /* + * if an AC has bundling disabled and no tx bundling + * has occured continously for a certain number of TX, + * enable tx bundling for this AC + */ + if (!bundle_sent) { + if (!(target->tx_bndl_mask & (1 << ac)) && + (ac < WMM_NUM_AC)) { + if (++target->ac_tx_count[ac] >= + TX_RESUME_BUNDLE_THRESHOLD) { + target->ac_tx_count[ac] = 0; + target->tx_bndl_mask |= (1 << ac); + } + } + } else { + /* tx bundling will reset the counter */ + if (ac < WMM_NUM_AC) + target->ac_tx_count[ac] = 0; + } } endpoint->tx_proc_cnt = 0; @@ -2518,7 +2580,8 @@ static void htc_setup_msg_bndl(struct htc_target *target) target->max_rx_bndl_sz, target->max_tx_bndl_sz); if (target->max_tx_bndl_sz) - target->tx_bndl_enable = true; + /* tx_bndl_mask is enabled per AC, each has 1 bit */ + target->tx_bndl_mask = (1 << WMM_NUM_AC) - 1; if (target->max_rx_bndl_sz) target->rx_bndl_enable = true; @@ -2533,7 +2596,7 @@ static void htc_setup_msg_bndl(struct htc_target *target) * padding will spill into the next credit buffer * which is fatal. */ - target->tx_bndl_enable = false; + target->tx_bndl_mask = 0; } } diff --git a/drivers/net/wireless/ath/ath6kl/htc.h b/drivers/net/wireless/ath/ath6kl/htc.h index 84a2ab52aa6..51976657133 100644 --- a/drivers/net/wireless/ath/ath6kl/htc.h +++ b/drivers/net/wireless/ath/ath6kl/htc.h @@ -88,6 +88,8 @@ #define WMI_DATA_VO_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 4) #define WMI_MAX_SERVICES 5 +#define WMM_NUM_AC 4 + /* reserved and used to flush ALL packets */ #define HTC_TX_PACKET_TAG_ALL 0 #define HTC_SERVICE_TX_PACKET_TAG 1 @@ -532,7 +534,7 @@ struct htc_target { /* max messages per bundle for HTC */ int msg_per_bndl_max; - bool tx_bndl_enable; + u32 tx_bndl_mask; int rx_bndl_enable; int max_rx_bndl_sz; int max_tx_bndl_sz; @@ -544,6 +546,9 @@ struct htc_target { int max_xfer_szper_scatreq; int chk_irq_status_cnt; + + /* counts the number of Tx without bundling continously per AC */ + u32 ac_tx_count[WMM_NUM_AC]; }; void *ath6kl_htc_create(struct ath6kl *ar); diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index 2826613b193..cae446bf212 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -602,6 +602,8 @@ static struct hif_scatter_req *ath6kl_sdio_scatter_req_get(struct ath6kl *ar) node = list_first_entry(&ar_sdio->scat_req, struct hif_scatter_req, list); list_del(&node->list); + + node->scat_q_depth = get_queue_depth(&ar_sdio->scat_req); } spin_unlock_bh(&ar_sdio->scat_lock); -- cgit v1.2.3-70-g09d2 From fb1ac2efa323de21bc83c1b3d326d06f8251ea4f Mon Sep 17 00:00:00 2001 From: Prasanna Kumar Date: Tue, 7 Feb 2012 14:58:54 -0800 Subject: ath6kl: add support for AR6003 2048 byte board file AR6003 2.1.1 supports both 1792 and 2048 byte board files. Add support for 2048 byte board file. kvalo: add ath6kl prefix to the title Signed-off-by: Prasanna Kumar Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/init.c | 2 ++ drivers/net/wireless/ath/ath6kl/target.h | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 6183d579492..72f1b4f52b2 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -1124,6 +1124,8 @@ static int ath6kl_upload_board_file(struct ath6kl *ar) case TARGET_TYPE_AR6003: board_data_size = AR6003_BOARD_DATA_SZ; board_ext_data_size = AR6003_BOARD_EXT_DATA_SZ; + if (ar->fw_board_len > (board_data_size + board_ext_data_size)) + board_ext_data_size = AR6003_BOARD_EXT_DATA_SZ_V2; break; case TARGET_TYPE_AR6004: board_data_size = AR6004_BOARD_DATA_SZ; diff --git a/drivers/net/wireless/ath/ath6kl/target.h b/drivers/net/wireless/ath/ath6kl/target.h index ac27962f8fc..78e0ef4567a 100644 --- a/drivers/net/wireless/ath/ath6kl/target.h +++ b/drivers/net/wireless/ath/ath6kl/target.h @@ -20,6 +20,7 @@ #define AR6003_BOARD_DATA_SZ 1024 #define AR6003_BOARD_EXT_DATA_SZ 768 +#define AR6003_BOARD_EXT_DATA_SZ_V2 1024 #define AR6004_BOARD_DATA_SZ 6144 #define AR6004_BOARD_EXT_DATA_SZ 0 -- cgit v1.2.3-70-g09d2 From 3b96d49a79021ce4c1ca26aecd784d16aeb91a7c Mon Sep 17 00:00:00 2001 From: Naveen Gangadharan Date: Tue, 7 Feb 2012 22:53:32 -0800 Subject: ath6kl: Fix firmware crash dump The firmware crash dump printout was wrong as it was using incorrect offsets. kvalo: improve commit log, change the "%d:" to print word indexes, not bytes Signed-off-by: Naveen Gangadharan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/hif.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/hif.c b/drivers/net/wireless/ath/ath6kl/hif.c index 18c7f645331..ef650b61740 100644 --- a/drivers/net/wireless/ath/ath6kl/hif.c +++ b/drivers/net/wireless/ath/ath6kl/hif.c @@ -107,9 +107,9 @@ static void ath6kl_hif_dump_fw_crash(struct ath6kl *ar) BUILD_BUG_ON(REG_DUMP_COUNT_AR6003 % 4); - for (i = 0; i < REG_DUMP_COUNT_AR6003 / 4; i++) { + for (i = 0; i < REG_DUMP_COUNT_AR6003; i += 4) { ath6kl_info("%d: 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x\n", - 4 * i, + i, le32_to_cpu(regdump_val[i]), le32_to_cpu(regdump_val[i + 1]), le32_to_cpu(regdump_val[i + 2]), -- cgit v1.2.3-70-g09d2 From 260a8f7b06c9f8fba20bea7cd76281a533241076 Mon Sep 17 00:00:00 2001 From: Jose Alberto Reguero Date: Thu, 26 Jan 2012 20:02:52 -0300 Subject: [media] az6007: add another Terratec H7 usb id Signed-off-by: Jose Alberto Reguero Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 3 ++- drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 02efd94dc72..df4cbc0ed93 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -481,6 +481,7 @@ static int az6007_usb_probe(struct usb_interface *intf, static struct usb_device_id az6007_usb_table[] = { {USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_6007)}, {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7)}, + {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7_2)}, {0}, }; @@ -534,7 +535,7 @@ static struct dvb_usb_device_properties az6007_properties = { .warm_ids = { NULL }, }, { .name = "TerraTec DTV StarBox DVB-T/C USB2.0 (az6007)", - .cold_ids = { &az6007_usb_table[1], NULL }, + .cold_ids = { &az6007_usb_table[1], &az6007_usb_table[2], NULL }, .warm_ids = { NULL }, }, { NULL }, diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index b3e7be4718a..9c3dae10016 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -228,6 +228,7 @@ #define USB_PID_TERRATEC_CINERGY_T_XXS 0x0078 #define USB_PID_TERRATEC_CINERGY_T_XXS_2 0x00ab #define USB_PID_TERRATEC_H7 0x10b4 +#define USB_PID_TERRATEC_H7_2 0x10a3 #define USB_PID_TERRATEC_T3 0x10a0 #define USB_PID_TERRATEC_T5 0x10a1 #define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e -- cgit v1.2.3-70-g09d2 From db38951cce88eae36909143291545a59db4efa59 Mon Sep 17 00:00:00 2001 From: Manjunath Hadli Date: Fri, 23 Dec 2011 03:28:44 -0300 Subject: [media] davinci: vpif: remove machine specific header file includes remove unnecessary inclusion of machine specific header files mach/dm646x.h, mach/hardware.h from vpif.h and aslo mach/dm646x.h from vpif_display.c driver which comes in the way of platform code consolidation. Add linux/i2c.h header file in vpif_types.h which is required for building. Signed-off-by: Manjunath Hadli Cc: Mauro Carvalho Chehab Cc: LMML Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/davinci/vpif.h | 2 -- drivers/media/video/davinci/vpif_display.c | 2 -- include/media/davinci/vpif_types.h | 2 ++ 3 files changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/davinci/vpif.h b/drivers/media/video/davinci/vpif.h index 25036cb11be..8bcac65f929 100644 --- a/drivers/media/video/davinci/vpif.h +++ b/drivers/media/video/davinci/vpif.h @@ -18,8 +18,6 @@ #include #include -#include -#include #include /* Maximum channel allowed */ diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c index 286f0291004..7fa34b4fae2 100644 --- a/drivers/media/video/davinci/vpif_display.c +++ b/drivers/media/video/davinci/vpif_display.c @@ -39,8 +39,6 @@ #include #include -#include - #include "vpif_display.h" #include "vpif.h" diff --git a/include/media/davinci/vpif_types.h b/include/media/davinci/vpif_types.h index 9929b05cff3..bd8217c2577 100644 --- a/include/media/davinci/vpif_types.h +++ b/include/media/davinci/vpif_types.h @@ -17,6 +17,8 @@ #ifndef _VPIF_TYPES_H #define _VPIF_TYPES_H +#include + #define VPIF_CAPTURE_MAX_CHANNELS 2 enum vpif_if_type { -- cgit v1.2.3-70-g09d2 From 0d616ca37108289b59b02191377261d12d3ae3e7 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Fri, 27 Jan 2012 09:47:04 -0300 Subject: [media] [trivial] lmedm04: Fix typo Correct spelling "reseting" to "resetting" in drivers/media/dvb/dvb-usb/lmedm04.c Signed-off-by: Masanari Iida Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/lmedm04.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/lmedm04.c b/drivers/media/dvb/dvb-usb/lmedm04.c index b3fe05bbffc..291f6b11039 100644 --- a/drivers/media/dvb/dvb-usb/lmedm04.c +++ b/drivers/media/dvb/dvb-usb/lmedm04.c @@ -1054,7 +1054,7 @@ static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap) if (ret) info("TUN Found %s tuner", tun_msg[ret]); else { - info("TUN No tuner found --- reseting device"); + info("TUN No tuner found --- resetting device"); lme_coldreset(adap->dev->udev); return -ENODEV; } -- cgit v1.2.3-70-g09d2 From 6d73d072fce26567a0e3da5eb86499de9142ffc1 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Fri, 27 Jan 2012 11:04:51 -0300 Subject: [media] [trivial] ov6650: Fix typo Correct spelling "unspported" to "unsupported" in drivers/media/video/ov6650.c Signed-off-by: Masanari Iida Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ov6650.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/ov6650.c b/drivers/media/video/ov6650.c index 6806345ec2f..3627f3225bb 100644 --- a/drivers/media/video/ov6650.c +++ b/drivers/media/video/ov6650.c @@ -649,7 +649,7 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) clkrc = CLKRC_24MHz; } else { dev_err(&client->dev, - "unspported input clock, check platform data\n"); + "unsupported input clock, check platform data\n"); return -EINVAL; } mclk = sense->master_clock; -- cgit v1.2.3-70-g09d2 From dc66d7f455988310ce2dbd4a0df23af2e5626a89 Mon Sep 17 00:00:00 2001 From: Jose Alberto Reguero Date: Fri, 27 Jan 2012 18:34:49 -0300 Subject: [media] drxk: Fix get_tune_settings for DVB-T DVB-T also use step_size=0. Signed-off-by: Jose Alberto Reguero Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/drxk_hard.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c index 47bf16d44bc..36d11756492 100644 --- a/drivers/media/dvb/frontends/drxk_hard.c +++ b/drivers/media/dvb/frontends/drxk_hard.c @@ -6316,15 +6316,12 @@ static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_t switch (p->delivery_system) { case SYS_DVBC_ANNEX_A: case SYS_DVBC_ANNEX_C: + case SYS_DVBT: sets->min_delay_ms = 3000; sets->max_drift = 0; sets->step_size = 0; return 0; default: - /* - * For DVB-T, let it use the default DVB core way, that is: - * fepriv->step_size = fe->ops.info.frequency_stepsize * 2 - */ return -EINVAL; } } -- cgit v1.2.3-70-g09d2 From db5823b52c87b42567504b3976edfc5dc50ab8c4 Mon Sep 17 00:00:00 2001 From: Jose Alberto Reguero Date: Fri, 27 Jan 2012 18:43:28 -0300 Subject: [media] mt2063: increase frequency_max to tune channel 69 Increase mt2063 frequency_max to tune to channel 69(858Mhz). Jose Alberto Signed-off-by: Jose Alberto Reguero Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/mt2063.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/common/tuners/mt2063.c b/drivers/media/common/tuners/mt2063.c index 7bbf25da3ef..0ed9091ff48 100644 --- a/drivers/media/common/tuners/mt2063.c +++ b/drivers/media/common/tuners/mt2063.c @@ -2226,7 +2226,7 @@ static struct dvb_tuner_ops mt2063_ops = { .info = { .name = "MT2063 Silicon Tuner", .frequency_min = 45000000, - .frequency_max = 850000000, + .frequency_max = 865000000, .frequency_step = 0, }, -- cgit v1.2.3-70-g09d2 From fc594e3e5196d4cf7ace7735eeca399f7a80868b Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sat, 28 Jan 2012 18:02:34 -0300 Subject: [media] it913x ver 1.24 Make 0x60 default on version 2 devices Some version 2 devices have different tuner IDs. ID 0x38 appears to have weak signal strength. Apply default 0x60 to unknown IDs. Signed-off-by: Malcolm Priestley Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/it913x.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/it913x.c b/drivers/media/dvb/dvb-usb/it913x.c index 50d578c7b8c..c80098ad34a 100644 --- a/drivers/media/dvb/dvb-usb/it913x.c +++ b/drivers/media/dvb/dvb-usb/it913x.c @@ -409,8 +409,15 @@ static int ite_firmware_select(struct usb_device *udev, it913x_config.firmware_ver = 1; it913x_config.adc_x2 = 1; props->firmware = fw_it9135_v2; - if (it913x_config.tuner_id_0 == 0) + switch (it913x_config.tuner_id_0) { + case IT9135_61: + case IT9135_62: + break; + default: + info("Unknown tuner ID applying default 0x60"); + case IT9135_60: it913x_config.tuner_id_0 = IT9135_60; + } break; case IT9137_FW: default: @@ -818,5 +825,5 @@ module_usb_driver(it913x_driver); MODULE_AUTHOR("Malcolm Priestley "); MODULE_DESCRIPTION("it913x USB 2 Driver"); -MODULE_VERSION("1.23"); +MODULE_VERSION("1.24"); MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From c659395935d6ad8781fe9958ed1a9dbe969b3a17 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sat, 28 Jan 2012 21:41:52 -0300 Subject: [media] tm6000: Don't use pointer after freeing it in tm6000_ir_fini() In tm6000_ir_fini() there seems to be a problem. rc_unregister_device(ir->rc); calls rc_free_device() on the pointer it is given, which frees it. Subsequently the function does: if (!ir->polling) __tm6000_ir_int_stop(ir->rc); and __tm6000_ir_int_stop() dereferences the pointer it is given, which has already been freed. and it also does: tm6000_ir_stop(ir->rc); which also dereferences the (already freed) pointer. So, it seems that the call to rc_unregister_device() should be move below the calls to __tm6000_ir_int_stop() and tm6000_ir_stop(), so those don't operate on a already freed pointer. But, I must admit that I don't know this code *at all*, so someone who knows the code should take a careful look before applying this patch. It is based purely on inspection of facts of what is beeing freed where and not at all on understanding what the code does or why. I don't even have a means to test it, so beyond testing that the change compiles it has seen no testing what-so-ever. Anyway, here's a proposed patch. Signed-off-by: Jesper Juhl Reviewed-by: Thierry Reding Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tm6000/tm6000-input.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/tm6000/tm6000-input.c b/drivers/media/video/tm6000/tm6000-input.c index 7844607dd45..859eb90e4d5 100644 --- a/drivers/media/video/tm6000/tm6000-input.c +++ b/drivers/media/video/tm6000/tm6000-input.c @@ -481,8 +481,6 @@ int tm6000_ir_fini(struct tm6000_core *dev) dprintk(2, "%s\n",__func__); - rc_unregister_device(ir->rc); - if (!ir->polling) __tm6000_ir_int_stop(ir->rc); @@ -492,6 +490,7 @@ int tm6000_ir_fini(struct tm6000_core *dev) tm6000_flash_led(dev, 0); ir->pwled = 0; + rc_unregister_device(ir->rc); kfree(ir); dev->ir = NULL; -- cgit v1.2.3-70-g09d2 From 41292b16117bdd8e1321223b6a14e86aa1cb5fbb Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Sun, 29 Jan 2012 08:50:53 -0300 Subject: [media] [trivial] s5p: Fix typo in mixer_drv.c and hdmi_drv.c Correct typo "sucessful" to "successful" in drivers/media/video/s5p-tv/mixer_drv.c drivers/media/video/s5p-tv/hdmi_drv.c Signed-off-by: Masanari Iida Acked-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-tv/hdmi_drv.c | 4 ++-- drivers/media/video/s5p-tv/mixer_drv.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/s5p-tv/hdmi_drv.c b/drivers/media/video/s5p-tv/hdmi_drv.c index 8b41a0410ab..3e0dd099b2e 100644 --- a/drivers/media/video/s5p-tv/hdmi_drv.c +++ b/drivers/media/video/s5p-tv/hdmi_drv.c @@ -962,7 +962,7 @@ static int __devinit hdmi_probe(struct platform_device *pdev) /* storing subdev for call that have only access to struct device */ dev_set_drvdata(dev, sd); - dev_info(dev, "probe sucessful\n"); + dev_info(dev, "probe successful\n"); return 0; @@ -1000,7 +1000,7 @@ static int __devexit hdmi_remove(struct platform_device *pdev) iounmap(hdmi_dev->regs); hdmi_resources_cleanup(hdmi_dev); kfree(hdmi_dev); - dev_info(dev, "remove sucessful\n"); + dev_info(dev, "remove successful\n"); return 0; } diff --git a/drivers/media/video/s5p-tv/mixer_drv.c b/drivers/media/video/s5p-tv/mixer_drv.c index 00643094b22..a2c0c25ad13 100644 --- a/drivers/media/video/s5p-tv/mixer_drv.c +++ b/drivers/media/video/s5p-tv/mixer_drv.c @@ -444,7 +444,7 @@ static int __devexit mxr_remove(struct platform_device *pdev) kfree(mdev); - dev_info(dev, "remove sucessful\n"); + dev_info(dev, "remove successful\n"); return 0; } -- cgit v1.2.3-70-g09d2 From 9fa728ea35501fb5cd56880839ad867265c61822 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sun, 29 Jan 2012 16:55:28 -0300 Subject: [media] easycap: Fix mem leak in easycap_usb_probe() If allocating 'pdata_urb' fails, the function will return -ENOMEM without freeing the memory allocated, just a few lines above, for 'purb' and will leak that memory when 'purb' goes out of scope. This patch resolves the leak by freeing the allocated storage with usb_free_urb() before the return. Signed-off-by: Jesper Juhl Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/easycap/easycap_main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/media/easycap/easycap_main.c b/drivers/staging/media/easycap/easycap_main.c index 8ff5f38ea19..3d439b790cc 100644 --- a/drivers/staging/media/easycap/easycap_main.c +++ b/drivers/staging/media/easycap/easycap_main.c @@ -3825,6 +3825,7 @@ static int easycap_usb_probe(struct usb_interface *intf, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL); if (!pdata_urb) { + usb_free_urb(purb); SAM("ERROR: Could not allocate struct data_urb.\n"); return -ENOMEM; } -- cgit v1.2.3-70-g09d2 From 31a4c8b82788fa369c709bb3366c8b90c77c0dee Mon Sep 17 00:00:00 2001 From: "Pradeep A. Dalvi" Date: Wed, 8 Feb 2012 00:03:15 +0000 Subject: mace: Fix build for mace due to netdev_alloc_skb Refs: 1. pmac32_defconfig http://kisskb.ellerman.id.au/kisskb/buildresult/5583746/ 2. ppc6xx_defconfig http://kisskb.ellerman.id.au/kisskb/buildresult/5584116/ Confirmed any such occurances from all failed defconfigs & in net-next sources with grep -nrs "netdev_alloc_skb" drivers/net/ethernet/ | grep -v "," Reported-by: Geert Uytterhoeven Signed-off-by: Pradeep A Dalvi Signed-off-by: David S. Miller --- drivers/net/ethernet/apple/mace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/apple/mace.c b/drivers/net/ethernet/apple/mace.c index 06998462e0d..e1df4b76c88 100644 --- a/drivers/net/ethernet/apple/mace.c +++ b/drivers/net/ethernet/apple/mace.c @@ -956,7 +956,7 @@ static irqreturn_t mace_rxdma_intr(int irq, void *dev_id) cp = mp->rx_cmds + i; skb = mp->rx_bufs[i]; if (!skb) { - skb = netdev_alloc_skb(RX_BUFLEN + 2); + skb = netdev_alloc_skb(dev, RX_BUFLEN + 2); if (skb) { skb_reserve(skb, 2); mp->rx_bufs[i] = skb; -- cgit v1.2.3-70-g09d2 From 1ebbc48520a0853cd4d812d8342f9886b2b07b92 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Mon, 6 Feb 2012 23:45:06 +0100 Subject: rt2x00: Introduce concept of driver data in struct rt2x00_dev. We are getting more and more fields in struct rt2x00_dev that are specific to one or two of the low-level drivers. Instead of putting these fields inside the main structure and thus clobbering all low-level drivers with these fields, introduce the concept of driver data inside struct rt2x00_dev, whose size is indicated by the low-level driver and which can be populated by the low-level driver. Signed-off-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 6 ++++++ drivers/net/wireless/rt2x00/rt2x00dev.c | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index b03b22c47b1..b4260bfb6cb 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -647,6 +647,7 @@ struct rt2x00lib_ops { */ struct rt2x00_ops { const char *name; + const unsigned int drv_data_size; const unsigned int max_sta_intf; const unsigned int max_ap_intf; const unsigned int eeprom_size; @@ -741,6 +742,11 @@ struct rt2x00_dev { */ const struct rt2x00_ops *ops; + /* + * Driver data. + */ + void *drv_data; + /* * IEEE80211 control structure. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index c3e1aa7c1a8..bae5b01299e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -1121,6 +1121,18 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) { int retval = -ENOMEM; + /* + * Allocate the driver data memory, if necessary. + */ + if (rt2x00dev->ops->drv_data_size > 0) { + rt2x00dev->drv_data = kzalloc(rt2x00dev->ops->drv_data_size, + GFP_KERNEL); + if (!rt2x00dev->drv_data) { + retval = -ENOMEM; + goto exit; + } + } + spin_lock_init(&rt2x00dev->irqmask_lock); mutex_init(&rt2x00dev->csr_mutex); @@ -1261,6 +1273,12 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) * Free queue structures. */ rt2x00queue_free(rt2x00dev); + + /* + * Free the driver data. + */ + if (rt2x00dev->drv_data) + kfree(rt2x00dev->drv_data); } EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev); -- cgit v1.2.3-70-g09d2 From 3a1c01288e5596fb70ca48ec9d9d8b561121c544 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Mon, 6 Feb 2012 23:45:07 +0100 Subject: rt2x00: Use struct rt2x00_dev driver data in rt2800{pci,usb}. Start using the struct rt2x00_dev driver data in rt2800 for the calibration data. Signed-off-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 8 ++++++++ drivers/net/wireless/rt2x00/rt2800lib.c | 31 +++++++++++++++++++++---------- drivers/net/wireless/rt2x00/rt2800pci.c | 1 + drivers/net/wireless/rt2x00/rt2800usb.c | 1 + drivers/net/wireless/rt2x00/rt2x00.h | 7 ------- 5 files changed, 31 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index fac9ece22b2..7c05dee5787 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -2438,4 +2438,12 @@ struct mac_iveiv_entry { */ #define EIRP_MAX_TX_POWER_LIMIT 0x50 +/* + * RT2800 driver data structure + */ +struct rt2800_drv_data { + u8 calibration_bw20; + u8 calibration_bw40; +}; + #endif /* RT2800_H */ diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index c326e7b1c37..131139ed4b1 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1645,6 +1645,7 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev, struct rf_channel *rf, struct channel_info *info) { + struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; u8 rfcsr, calib_tx, calib_rx; rt2800_rfcsr_write(rt2x00dev, 2, rf->rf1); @@ -1714,8 +1715,13 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev, calib_tx = conf_is_ht40(conf) ? 0x68 : 0x4f; calib_rx = conf_is_ht40(conf) ? 0x6f : 0x4f; } else { - calib_tx = rt2x00dev->calibration[conf_is_ht40(conf)]; - calib_rx = rt2x00dev->calibration[conf_is_ht40(conf)]; + if (conf_is_ht40(conf)) { + calib_tx = drv_data->calibration_bw40; + calib_rx = drv_data->calibration_bw40; + } else { + calib_tx = drv_data->calibration_bw20; + calib_rx = drv_data->calibration_bw20; + } } rt2800_rfcsr_read(rt2x00dev, 24, &rfcsr); @@ -1743,6 +1749,7 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev, struct rf_channel *rf, struct channel_info *info) { + struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; u8 rfcsr; u32 reg; @@ -1836,10 +1843,13 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev, rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset); rt2800_rfcsr_write(rt2x00dev, 23, rfcsr); - rt2800_rfcsr_write(rt2x00dev, 24, - rt2x00dev->calibration[conf_is_ht40(conf)]); - rt2800_rfcsr_write(rt2x00dev, 31, - rt2x00dev->calibration[conf_is_ht40(conf)]); + if (conf_is_ht40(conf)) { + rt2800_rfcsr_write(rt2x00dev, 24, drv_data->calibration_bw40); + rt2800_rfcsr_write(rt2x00dev, 31, drv_data->calibration_bw40); + } else { + rt2800_rfcsr_write(rt2x00dev, 24, drv_data->calibration_bw20); + rt2800_rfcsr_write(rt2x00dev, 31, drv_data->calibration_bw20); + } if (rf->channel <= 14) { rt2800_rfcsr_write(rt2x00dev, 7, 0xd8); @@ -3310,6 +3320,7 @@ static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) { + struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; u8 rfcsr; u8 bbp; u32 reg; @@ -3598,17 +3609,17 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) * Set RX Filter calibration for 20MHz and 40MHz */ if (rt2x00_rt(rt2x00dev, RT3070)) { - rt2x00dev->calibration[0] = + drv_data->calibration_bw20 = rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x16); - rt2x00dev->calibration[1] = + drv_data->calibration_bw40 = rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x19); } else if (rt2x00_rt(rt2x00dev, RT3071) || rt2x00_rt(rt2x00dev, RT3090) || rt2x00_rt(rt2x00dev, RT3390) || rt2x00_rt(rt2x00dev, RT3572)) { - rt2x00dev->calibration[0] = + drv_data->calibration_bw20 = rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x13); - rt2x00dev->calibration[1] = + drv_data->calibration_bw40 = rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x15); } diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 4e985026985..6ad692914ee 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -1093,6 +1093,7 @@ static const struct data_queue_desc rt2800pci_queue_bcn = { static const struct rt2x00_ops rt2800pci_ops = { .name = KBUILD_MODNAME, + .drv_data_size = sizeof(struct rt2800_drv_data), .max_sta_intf = 1, .max_ap_intf = 8, .eeprom_size = EEPROM_SIZE, diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index f0074bcee7c..d009b6b794b 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -827,6 +827,7 @@ static const struct data_queue_desc rt2800usb_queue_bcn = { static const struct rt2x00_ops rt2800usb_ops = { .name = KBUILD_MODNAME, + .drv_data_size = sizeof(struct rt2800_drv_data), .max_sta_intf = 1, .max_ap_intf = 8, .eeprom_size = EEPROM_SIZE, diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index b4260bfb6cb..5bd2f225ce4 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -896,13 +896,6 @@ struct rt2x00_dev { */ u8 freq_offset; - /* - * Calibration information (for rt2800usb & rt2800pci). - * [0] -> BW20 - * [1] -> BW40 - */ - u8 calibration[2]; - /* * Association id. */ -- cgit v1.2.3-70-g09d2 From bef453dc9cf1999348e568068f256b1c439d1152 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Mon, 6 Feb 2012 23:45:08 +0100 Subject: rt2x00: Update comment on freq_offset field in struct rt2x00_dev. The comment states that the field is only used for rt61pci and rt73usb. However, it is now used by rt2800pci and rt2800usb as well, so the comment is not correct anymore. Update the comment to not state any low-level drivers anymore. Signed-off-by: Gertjan van Wingerde Acked-by: Stanislaw Gruszka Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 5bd2f225ce4..ed2ae6efcaa 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -892,7 +892,7 @@ struct rt2x00_dev { u8 rssi_offset; /* - * Frequency offset (for rt61pci & rt73usb). + * Frequency offset. */ u8 freq_offset; -- cgit v1.2.3-70-g09d2 From 5d137dff36dce1eda0617a00eb87b57e48300045 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Mon, 6 Feb 2012 23:45:09 +0100 Subject: rt2x00: Use saved BBP 25 and 26 values when configuring channel on RT3572. This brings the rt2800 channel switching code for RT3572 closer to the v2.5.0.0 Ralink RT3572 driver. Signed-off-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 2 ++ drivers/net/wireless/rt2x00/rt2800lib.c | 10 ++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 7c05dee5787..8aabd0dc02c 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -2444,6 +2444,8 @@ struct mac_iveiv_entry { struct rt2800_drv_data { u8 calibration_bw20; u8 calibration_bw40; + u8 bbp25; + u8 bbp26; }; #endif /* RT2800_H */ diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 131139ed4b1..3873a155587 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1754,8 +1754,8 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev, u32 reg; if (rf->channel <= 14) { - rt2800_bbp_write(rt2x00dev, 25, 0x15); - rt2800_bbp_write(rt2x00dev, 26, 0x85); + rt2800_bbp_write(rt2x00dev, 25, drv_data->bbp25); + rt2800_bbp_write(rt2x00dev, 26, drv_data->bbp26); } else { rt2800_bbp_write(rt2x00dev, 25, 0x09); rt2800_bbp_write(rt2x00dev, 26, 0xff); @@ -3623,6 +3623,12 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x15); } + /* + * Save BBP 25 & 26 values for later use in channel switching + */ + rt2800_bbp_read(rt2x00dev, 25, &drv_data->bbp25); + rt2800_bbp_read(rt2x00dev, 26, &drv_data->bbp26); + if (!rt2x00_rt(rt2x00dev, RT5390)) { /* * Set back to initial state -- cgit v1.2.3-70-g09d2 From 569ffa56344e7e2a1d635a9c620215196f5c7298 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Mon, 6 Feb 2012 23:45:10 +0100 Subject: rt2x00: Fix RFCSR 12 & 13 programming on RT3572 channel switching. Align with v2.5.0.0 Ralink RT3572 driver for 2.4GHz band channel switch. Signed-off-by: Gertjan van Wingerde Acked-by: Stanislaw Gruszka Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 3873a155587..80a2087fcf8 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1783,8 +1783,7 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev, if (rf->channel <= 14) { rt2x00_set_field8(&rfcsr, RFCSR12_DR0, 3); rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER, - (info->default_power1 & 0x3) | - ((info->default_power1 & 0xC) << 1)); + info->default_power1); } else { rt2x00_set_field8(&rfcsr, RFCSR12_DR0, 7); rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER, @@ -1797,8 +1796,7 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev, if (rf->channel <= 14) { rt2x00_set_field8(&rfcsr, RFCSR13_DR0, 3); rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, - (info->default_power2 & 0x3) | - ((info->default_power2 & 0xC) << 1)); + info->default_power2); } else { rt2x00_set_field8(&rfcsr, RFCSR13_DR0, 7); rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, -- cgit v1.2.3-70-g09d2 From 0cd461efcc1df6763b86b29ef4d6ee1cb923aa47 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Mon, 6 Feb 2012 23:45:11 +0100 Subject: rt2x00: Align RT3572 channel switch RFCSR 1 programming with Ralink driver. Align with the v2.5.0.0 Ralink RT3572 driver. Signed-off-by: Gertjan van Wingerde Acked-by: Stanislaw Gruszka Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 80a2087fcf8..135e8a40edd 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1806,11 +1806,12 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev, rt2800_rfcsr_write(rt2x00dev, 13, rfcsr); rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0); rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0); rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0); rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0); + rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0); + rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0); if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) { if (rf->channel <= 14) { rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1); -- cgit v1.2.3-70-g09d2 From 58b8ae14d58319bff63a30a9e1c0ebb9c07f2243 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Mon, 6 Feb 2012 23:45:12 +0100 Subject: rt2x00: Fix RT3572 channel switch RFCSR 7 programming. Align with the v2.5.0.0 Ralink RT3572 driver. Signed-off-by: Gertjan van Wingerde Acked-by: Stanislaw Gruszka Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 10 ++++++---- drivers/net/wireless/rt2x00/rt2800lib.c | 7 ++++++- 2 files changed, 12 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 8aabd0dc02c..c6648b02bf8 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -1819,10 +1819,12 @@ struct mac_iveiv_entry { * RFCSR 7: */ #define RFCSR7_RF_TUNING FIELD8(0x01) -#define RFCSR7_R02 FIELD8(0x07) -#define RFCSR7_R3 FIELD8(0x08) -#define RFCSR7_R45 FIELD8(0x30) -#define RFCSR7_R67 FIELD8(0xc0) +#define RFCSR7_BIT1 FIELD8(0x02) +#define RFCSR7_BIT2 FIELD8(0x04) +#define RFCSR7_BIT3 FIELD8(0x08) +#define RFCSR7_BIT4 FIELD8(0x10) +#define RFCSR7_BIT5 FIELD8(0x20) +#define RFCSR7_BITS67 FIELD8(0xc0) /* * RFCSR 11: diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 135e8a40edd..395453c41e2 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1865,7 +1865,12 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev, rt2800_rfcsr_write(rt2x00dev, 27, 0x00); rt2800_rfcsr_write(rt2x00dev, 29, 0x9b); } else { - rt2800_rfcsr_write(rt2x00dev, 7, 0x14); + rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR7_BIT2, 1); + rt2x00_set_field8(&rfcsr, RFCSR7_BIT3, 0); + rt2x00_set_field8(&rfcsr, RFCSR7_BIT4, 1); + rt2x00_set_field8(&rfcsr, RFCSR7_BITS67, 0); + rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); rt2800_rfcsr_write(rt2x00dev, 9, 0xc0); rt2800_rfcsr_write(rt2x00dev, 10, 0xf1); rt2800_rfcsr_write(rt2x00dev, 11, 0x00); -- cgit v1.2.3-70-g09d2 From 77c06c2cb44fe68295efdd33939153c7d56de004 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Mon, 6 Feb 2012 23:45:13 +0100 Subject: rt2x00: Correctly set txmixer_gain in RT3572 channel switching. Align with the v2.5.0.0 Ralink RT3572 driver. Save the EEPROM txmixer_gain values inside the rt2800 driver data structure and use it throughout the code. Signed-off-by: Gertjan van Wingerde Acked-by: Stanislaw Gruszka Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 13 +++++++++++++ drivers/net/wireless/rt2x00/rt2800lib.c | 34 ++++++++++++++++++++++++++------- 2 files changed, 40 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index c6648b02bf8..06acabd0298 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -1848,6 +1848,11 @@ struct mac_iveiv_entry { */ #define RFCSR15_TX_LO2_EN FIELD8(0x08) +/* + * RFCSR 16: + */ +#define RFCSR16_TXMIXER_GAIN FIELD8(0x07) + /* * RFCSR 17: */ @@ -2110,6 +2115,12 @@ struct mac_iveiv_entry { #define EEPROM_RSSI_A2_OFFSET2 FIELD16(0x00ff) #define EEPROM_RSSI_A2_LNA_A2 FIELD16(0xff00) +/* + * EEPROM TXMIXER GAIN A offset (note overlaps with EEPROM RSSI A2). + */ +#define EEPROM_TXMIXER_GAIN_A 0x0026 +#define EEPROM_TXMIXER_GAIN_A_VAL FIELD16(0x0007) + /* * EEPROM EIRP Maximum TX power values(unit: dbm) */ @@ -2448,6 +2459,8 @@ struct rt2800_drv_data { u8 calibration_bw40; u8 bbp25; u8 bbp26; + u8 txmixer_gain_24g; + u8 txmixer_gain_5g; }; #endif /* RT2800_H */ diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 395453c41e2..52728be6527 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1856,7 +1856,10 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev, rt2800_rfcsr_write(rt2x00dev, 10, 0xf1); rt2800_rfcsr_write(rt2x00dev, 11, 0xb9); rt2800_rfcsr_write(rt2x00dev, 15, 0x53); - rt2800_rfcsr_write(rt2x00dev, 16, 0x4c); + rfcsr = 0x4c; + rt2x00_set_field8(&rfcsr, RFCSR16_TXMIXER_GAIN, + drv_data->txmixer_gain_24g); + rt2800_rfcsr_write(rt2x00dev, 16, rfcsr); rt2800_rfcsr_write(rt2x00dev, 17, 0x23); rt2800_rfcsr_write(rt2x00dev, 19, 0x93); rt2800_rfcsr_write(rt2x00dev, 20, 0xb3); @@ -1875,7 +1878,10 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev, rt2800_rfcsr_write(rt2x00dev, 10, 0xf1); rt2800_rfcsr_write(rt2x00dev, 11, 0x00); rt2800_rfcsr_write(rt2x00dev, 15, 0x43); - rt2800_rfcsr_write(rt2x00dev, 16, 0x7a); + rfcsr = 0x7a; + rt2x00_set_field8(&rfcsr, RFCSR16_TXMIXER_GAIN, + drv_data->txmixer_gain_5g); + rt2800_rfcsr_write(rt2x00dev, 16, rfcsr); rt2800_rfcsr_write(rt2x00dev, 17, 0x23); if (rf->channel <= 64) { rt2800_rfcsr_write(rt2x00dev, 19, 0xb7); @@ -3672,11 +3678,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) &rt2x00dev->cap_flags)) rt2x00_set_field8(&rfcsr, RFCSR17_R, 1); } - rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom); - if (rt2x00_get_field16(eeprom, EEPROM_TXMIXER_GAIN_BG_VAL) >= 1) - rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN, - rt2x00_get_field16(eeprom, - EEPROM_TXMIXER_GAIN_BG_VAL)); + rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN, + drv_data->txmixer_gain_24g); rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); } @@ -3884,6 +3887,7 @@ EXPORT_SYMBOL_GPL(rt2800_read_eeprom_efuse); int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) { + struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; u16 word; u8 *mac; u8 default_lna_gain; @@ -3967,6 +3971,14 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET1, 0); rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG, word); + rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word); + if ((word & 0x00ff) != 0x00ff) { + drv_data->txmixer_gain_24g = + rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_BG_VAL); + } else { + drv_data->txmixer_gain_24g = 0; + } + rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word); if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10) rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0); @@ -3976,6 +3988,14 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) default_lna_gain); rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG2, word); + rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_A, &word); + if ((word & 0x00ff) != 0x00ff) { + drv_data->txmixer_gain_5g = + rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_A_VAL); + } else { + drv_data->txmixer_gain_5g = 0; + } + rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &word); if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET0)) > 10) rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET0, 0); -- cgit v1.2.3-70-g09d2 From 7f66c2f93e5779625c10d262c84537427a2673ca Mon Sep 17 00:00:00 2001 From: Simon Graham Date: Tue, 7 Feb 2012 18:07:38 -0600 Subject: rtlwifi: Handle previous allocation failures when freeing device memory Handle previous allocation failures when freeing device memory Signed-off-by: Simon Graham Signed-off-by: Larry Finger Cc: Stable Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/pci.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index c5f6a322feb..c503bd3b809 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -1148,10 +1148,12 @@ static void _rtl_pci_free_tx_ring(struct ieee80211_hw *hw, ring->idx = (ring->idx + 1) % ring->entries; } - pci_free_consistent(rtlpci->pdev, - sizeof(*ring->desc) * ring->entries, - ring->desc, ring->dma); - ring->desc = NULL; + if (ring->desc) { + pci_free_consistent(rtlpci->pdev, + sizeof(*ring->desc) * ring->entries, + ring->desc, ring->dma); + ring->desc = NULL; + } } static void _rtl_pci_free_rx_ring(struct rtl_pci *rtlpci) @@ -1175,12 +1177,14 @@ static void _rtl_pci_free_rx_ring(struct rtl_pci *rtlpci) kfree_skb(skb); } - pci_free_consistent(rtlpci->pdev, + if (rtlpci->rx_ring[rx_queue_idx].desc) { + pci_free_consistent(rtlpci->pdev, sizeof(*rtlpci->rx_ring[rx_queue_idx]. desc) * rtlpci->rxringcount, rtlpci->rx_ring[rx_queue_idx].desc, rtlpci->rx_ring[rx_queue_idx].dma); - rtlpci->rx_ring[rx_queue_idx].desc = NULL; + rtlpci->rx_ring[rx_queue_idx].desc = NULL; + } } } -- cgit v1.2.3-70-g09d2 From 8c1a7f5283e72306d1d23524f051501ffa1baf57 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Wed, 8 Feb 2012 02:08:21 +0000 Subject: stmmac: Fix typo in stmmac_pci.c Correct spelling "regiser" to "register" in drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c Signed-off-by: Masanari Iida Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c index c796de9eed7..6ce0706b2d1 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c @@ -85,7 +85,7 @@ static int __devinit stmmac_pci_probe(struct pci_dev *pdev, continue; addr = pci_iomap(pdev, i, 0); if (addr == NULL) { - pr_err("%s: ERROR: cannot map regiser memory, aborting", + pr_err("%s: ERROR: cannot map register memory, aborting", __func__); ret = -EIO; goto err_out_map_failed; -- cgit v1.2.3-70-g09d2 From 377cb4f9e763465984b9bb5187747fd9b02a14c0 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Tue, 7 Feb 2012 14:51:21 +0000 Subject: IPoIB: Stop lying about hard_header_len and use skb->cb to stash LL addresses Commit a0417fa3a18a ("net: Make qdisc_skb_cb upper size bound explicit.") made it possible for a netdev driver to use skb->cb between its header_ops.create method and its .ndo_start_xmit method. Use this in ipoib_hard_header() to stash away the LL address (GID + QPN), instead of the "ipoib_pseudoheader" hack. This allows IPoIB to stop lying about its hard_header_len, which will let us fix the L2 check for GRO. Signed-off-by: Roland Dreier Signed-off-by: David S. Miller --- drivers/infiniband/ulp/ipoib/ipoib.h | 6 ++- drivers/infiniband/ulp/ipoib/ipoib_main.c | 55 +++++++++----------------- drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 10 +---- 3 files changed, 24 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index b3cc1e062b1..86df632ea61 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h @@ -44,6 +44,7 @@ #include #include +#include #include @@ -117,8 +118,9 @@ struct ipoib_header { u16 reserved; }; -struct ipoib_pseudoheader { - u8 hwaddr[INFINIBAND_ALEN]; +struct ipoib_cb { + struct qdisc_skb_cb qdisc_cb; + u8 hwaddr[INFINIBAND_ALEN]; }; /* Used for all multicast joins (broadcast, IPv4 mcast and IPv6 mcast) */ diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 3514ca05dee..3974c290b66 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -653,7 +653,7 @@ static void ipoib_path_lookup(struct sk_buff *skb, struct neighbour *n, struct n } static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, - struct ipoib_pseudoheader *phdr) + struct ipoib_cb *cb) { struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_path *path; @@ -661,17 +661,15 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, spin_lock_irqsave(&priv->lock, flags); - path = __path_find(dev, phdr->hwaddr + 4); + path = __path_find(dev, cb->hwaddr + 4); if (!path || !path->valid) { int new_path = 0; if (!path) { - path = path_rec_create(dev, phdr->hwaddr + 4); + path = path_rec_create(dev, cb->hwaddr + 4); new_path = 1; } if (path) { - /* put pseudoheader back on for next time */ - skb_push(skb, sizeof *phdr); __skb_queue_tail(&path->queue, skb); if (!path->query && path_rec_start(dev, path)) { @@ -695,12 +693,10 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, be16_to_cpu(path->pathrec.dlid)); spin_unlock_irqrestore(&priv->lock, flags); - ipoib_send(dev, skb, path->ah, IPOIB_QPN(phdr->hwaddr)); + ipoib_send(dev, skb, path->ah, IPOIB_QPN(cb->hwaddr)); return; } else if ((path->query || !path_rec_start(dev, path)) && skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) { - /* put pseudoheader back on for next time */ - skb_push(skb, sizeof *phdr); __skb_queue_tail(&path->queue, skb); } else { ++dev->stats.tx_dropped; @@ -774,16 +770,14 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) dev_kfree_skb_any(skb); } } else { - struct ipoib_pseudoheader *phdr = - (struct ipoib_pseudoheader *) skb->data; - skb_pull(skb, sizeof *phdr); + struct ipoib_cb *cb = (struct ipoib_cb *) skb->cb; - if (phdr->hwaddr[4] == 0xff) { + if (cb->hwaddr[4] == 0xff) { /* Add in the P_Key for multicast*/ - phdr->hwaddr[8] = (priv->pkey >> 8) & 0xff; - phdr->hwaddr[9] = priv->pkey & 0xff; + cb->hwaddr[8] = (priv->pkey >> 8) & 0xff; + cb->hwaddr[9] = priv->pkey & 0xff; - ipoib_mcast_send(dev, phdr->hwaddr + 4, skb); + ipoib_mcast_send(dev, cb->hwaddr + 4, skb); } else { /* unicast GID -- should be ARP or RARP reply */ @@ -792,14 +786,14 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) ipoib_warn(priv, "Unicast, no %s: type %04x, QPN %06x %pI6\n", skb_dst(skb) ? "neigh" : "dst", be16_to_cpup((__be16 *) skb->data), - IPOIB_QPN(phdr->hwaddr), - phdr->hwaddr + 4); + IPOIB_QPN(cb->hwaddr), + cb->hwaddr + 4); dev_kfree_skb_any(skb); ++dev->stats.tx_dropped; goto unlock; } - unicast_arp_send(skb, dev, phdr); + unicast_arp_send(skb, dev, cb); } } unlock: @@ -825,8 +819,6 @@ static int ipoib_hard_header(struct sk_buff *skb, const void *daddr, const void *saddr, unsigned len) { struct ipoib_header *header; - struct dst_entry *dst; - struct neighbour *n; header = (struct ipoib_header *) skb_push(skb, sizeof *header); @@ -834,18 +826,13 @@ static int ipoib_hard_header(struct sk_buff *skb, header->reserved = 0; /* - * If we don't have a neighbour structure, stuff the - * destination address onto the front of the skb so we can - * figure out where to send the packet later. + * If we don't have a dst_entry structure, stuff the + * destination address into skb->cb so we can figure out where + * to send the packet later. */ - dst = skb_dst(skb); - n = NULL; - if (dst) - n = dst_get_neighbour_noref_raw(dst); - if ((!dst || !n) && daddr) { - struct ipoib_pseudoheader *phdr = - (struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr); - memcpy(phdr->hwaddr, daddr, INFINIBAND_ALEN); + if (!skb_dst(skb)) { + struct ipoib_cb *cb = (struct ipoib_cb *) skb->cb; + memcpy(cb->hwaddr, daddr, INFINIBAND_ALEN); } return 0; @@ -1021,11 +1008,7 @@ static void ipoib_setup(struct net_device *dev) dev->flags |= IFF_BROADCAST | IFF_MULTICAST; - /* - * We add in INFINIBAND_ALEN to allow for the destination - * address "pseudoheader" for skbs without neighbour struct. - */ - dev->hard_header_len = IPOIB_ENCAP_LEN + INFINIBAND_ALEN; + dev->hard_header_len = IPOIB_ENCAP_LEN; dev->addr_len = INFINIBAND_ALEN; dev->type = ARPHRD_INFINIBAND; dev->tx_queue_len = ipoib_sendq_size * 2; diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index f7ff9dd66cd..20ebc6fd1bb 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -262,21 +262,13 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast, netif_tx_lock_bh(dev); while (!skb_queue_empty(&mcast->pkt_queue)) { struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue); - struct dst_entry *dst = skb_dst(skb); - struct neighbour *n = NULL; netif_tx_unlock_bh(dev); skb->dev = dev; - if (dst) - n = dst_get_neighbour_noref_raw(dst); - if (!dst || !n) { - /* put pseudoheader back on for next time */ - skb_push(skb, sizeof (struct ipoib_pseudoheader)); - } - if (dev_queue_xmit(skb)) ipoib_warn(priv, "dev_queue_xmit failed to requeue packet\n"); + netif_tx_lock_bh(dev); } netif_tx_unlock_bh(dev); -- cgit v1.2.3-70-g09d2 From 42bc0c9716c456a9686fcd4ee5cf115b992b9952 Mon Sep 17 00:00:00 2001 From: Simon Graham Date: Wed, 8 Feb 2012 12:34:23 -0500 Subject: rtlwifi: Return correct failure code on error Callers of rtl_pci_init expect zero to be returned on error. Returning the error code leads to, amongst other things, divide by zero panics attempting to use the ring size that is set to zero. Signed-off-by: Simon Graham Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index c503bd3b809..8a941b588a4 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -1492,7 +1492,7 @@ static int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev) if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "tx ring initialization failed\n"); - return err; + return 0; } return 1; -- cgit v1.2.3-70-g09d2 From f691e2f4cec334e906f971471b3bf1460c6256d4 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 2 Feb 2012 09:58:12 +0100 Subject: drm/i915: swizzling support for snb/ivb We have to do this manually. Somebody had a Great Idea. I've measured speed-ups just a few percent above the noise level (below 5% for the best case), but no slowdows. Chris Wilson measured quite a bit more (10-20% above the usual snb variance) on a more recent and better tuned version of sna, but also recorded a few slow-downs on benchmarks know for uglier amounts of snb-induced variance. v2: Incorporate Ben Widawsky's preliminary review comments and elaborate a bit about the performance impact in the changelog. v3: Add a comment as to why we don't need to check the 3rd memory channel. v4: Fixup whitespace. Acked-by: Chris Wilson Reviewed-by: Ben Widawsky Reviewed-by: Eric Anholt Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 2 +- drivers/gpu/drm/i915/i915_drv.c | 4 +++- drivers/gpu/drm/i915/i915_drv.h | 3 ++- drivers/gpu/drm/i915/i915_gem.c | 23 +++++++++++++++++++++-- drivers/gpu/drm/i915/i915_gem_tiling.c | 19 +++++++++++++++++-- drivers/gpu/drm/i915/i915_reg.h | 34 ++++++++++++++++++++++++++++++++++ 6 files changed, 78 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 3f27173fb51..dfef9569f2a 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1208,7 +1208,7 @@ static int i915_load_gem_init(struct drm_device *dev) i915_gem_do_init(dev, 0, mappable_size, gtt_size - PAGE_SIZE); mutex_lock(&dev->struct_mutex); - ret = i915_gem_init_ringbuffer(dev); + ret = i915_gem_init_hw(dev); mutex_unlock(&dev->struct_mutex); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 1658cfd85aa..12ddf47b818 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -495,7 +495,7 @@ static int i915_drm_thaw(struct drm_device *dev) mutex_lock(&dev->struct_mutex); dev_priv->mm.suspended = 0; - error = i915_gem_init_ringbuffer(dev); + error = i915_gem_init_hw(dev); mutex_unlock(&dev->struct_mutex); if (HAS_PCH_SPLIT(dev)) @@ -686,6 +686,8 @@ int i915_reset(struct drm_device *dev, u8 flags) !dev_priv->mm.suspended) { dev_priv->mm.suspended = 0; + i915_gem_init_swizzling(dev); + dev_priv->ring[RCS].init(&dev_priv->ring[RCS]); if (HAS_BSD(dev)) dev_priv->ring[VCS].init(&dev_priv->ring[VCS]); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 865de800756..08454192c4c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1187,7 +1187,8 @@ int __must_check i915_gem_object_set_domain(struct drm_i915_gem_object *obj, uint32_t read_domains, uint32_t write_domain); int __must_check i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj); -int __must_check i915_gem_init_ringbuffer(struct drm_device *dev); +int __must_check i915_gem_init_hw(struct drm_device *dev); +void i915_gem_init_swizzling(struct drm_device *dev); void i915_gem_cleanup_ringbuffer(struct drm_device *dev); void i915_gem_do_init(struct drm_device *dev, unsigned long start, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 51a2b0c2a30..86fffd26a89 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3681,12 +3681,31 @@ i915_gem_idle(struct drm_device *dev) return 0; } +void i915_gem_init_swizzling(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + + if (INTEL_INFO(dev)->gen < 6 || + dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_NONE) + return; + + I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) | + DISP_TILE_SURFACE_SWIZZLING); + + I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_SWZCTL); + if (IS_GEN6(dev)) + I915_WRITE(ARB_MODE, ARB_MODE_ENABLE(ARB_MODE_SWIZZLE_SNB)); + else + I915_WRITE(ARB_MODE, ARB_MODE_ENABLE(ARB_MODE_SWIZZLE_IVB)); +} int -i915_gem_init_ringbuffer(struct drm_device *dev) +i915_gem_init_hw(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; int ret; + i915_gem_init_swizzling(dev); + ret = intel_init_render_ring_buffer(dev); if (ret) return ret; @@ -3742,7 +3761,7 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data, mutex_lock(&dev->struct_mutex); dev_priv->mm.suspended = 0; - ret = i915_gem_init_ringbuffer(dev); + ret = i915_gem_init_hw(dev); if (ret != 0) { mutex_unlock(&dev->struct_mutex); return ret; diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 861223bf394..1a930666598 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -93,8 +93,23 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; if (INTEL_INFO(dev)->gen >= 6) { - swizzle_x = I915_BIT_6_SWIZZLE_NONE; - swizzle_y = I915_BIT_6_SWIZZLE_NONE; + uint32_t dimm_c0, dimm_c1; + dimm_c0 = I915_READ(MAD_DIMM_C0); + dimm_c1 = I915_READ(MAD_DIMM_C1); + dimm_c0 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK; + dimm_c1 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK; + /* Enable swizzling when the channels are populated with + * identically sized dimms. We don't need to check the 3rd + * channel because no cpu with gpu attached ships in that + * configuration. Also, swizzling only makes sense for 2 + * channels anyway. */ + if (dimm_c0 == dimm_c1) { + swizzle_x = I915_BIT_6_SWIZZLE_9_10; + swizzle_y = I915_BIT_6_SWIZZLE_9; + } else { + swizzle_x = I915_BIT_6_SWIZZLE_NONE; + swizzle_y = I915_BIT_6_SWIZZLE_NONE; + } } else if (IS_GEN5(dev)) { /* On Ironlake whatever DRAM config, GPU always do * same swizzling setup. diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f9607387c00..89816fe3f9d 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -295,6 +295,12 @@ #define FENCE_REG_SANDYBRIDGE_0 0x100000 #define SANDYBRIDGE_FENCE_PITCH_SHIFT 32 +/* control register for cpu gtt access */ +#define TILECTL 0x101000 +#define TILECTL_SWZCTL (1 << 0) +#define TILECTL_TLB_PREFETCH_DIS (1 << 2) +#define TILECTL_BACKSNOOP_DIS (1 << 3) + /* * Instruction and interrupt control regs */ @@ -318,6 +324,11 @@ #define RING_MAX_IDLE(base) ((base)+0x54) #define RING_HWS_PGA(base) ((base)+0x80) #define RING_HWS_PGA_GEN6(base) ((base)+0x2080) +#define ARB_MODE 0x04030 +#define ARB_MODE_SWIZZLE_SNB (1<<4) +#define ARB_MODE_SWIZZLE_IVB (1<<5) +#define ARB_MODE_ENABLE(x) GFX_MODE_ENABLE(x) +#define ARB_MODE_DISABLE(x) GFX_MODE_DISABLE(x) #define RENDER_HWS_PGA_GEN7 (0x04080) #define RING_FAULT_REG(ring) (0x4094 + 0x100*(ring)->id) #define DONE_REG 0x40b0 @@ -1037,6 +1048,29 @@ #define C0DRB3 0x10206 #define C1DRB3 0x10606 +/** snb MCH registers for reading the DRAM channel configuration */ +#define MAD_DIMM_C0 (MCHBAR_MIRROR_BASE_SNB + 0x5004) +#define MAD_DIMM_C1 (MCHBAR_MIRROR_BASE_SNB + 0x5008) +#define MAD_DIMM_C2 (MCHBAR_MIRROR_BASE_SNB + 0x500C) +#define MAD_DIMM_ECC_MASK (0x3 << 24) +#define MAD_DIMM_ECC_OFF (0x0 << 24) +#define MAD_DIMM_ECC_IO_ON_LOGIC_OFF (0x1 << 24) +#define MAD_DIMM_ECC_IO_OFF_LOGIC_ON (0x2 << 24) +#define MAD_DIMM_ECC_ON (0x3 << 24) +#define MAD_DIMM_ENH_INTERLEAVE (0x1 << 22) +#define MAD_DIMM_RANK_INTERLEAVE (0x1 << 21) +#define MAD_DIMM_B_WIDTH_X16 (0x1 << 20) /* X8 chips if unset */ +#define MAD_DIMM_A_WIDTH_X16 (0x1 << 19) /* X8 chips if unset */ +#define MAD_DIMM_B_DUAL_RANK (0x1 << 18) +#define MAD_DIMM_A_DUAL_RANK (0x1 << 17) +#define MAD_DIMM_A_SELECT (0x1 << 16) +/* DIMM sizes are in multiples of 256mb. */ +#define MAD_DIMM_B_SIZE_SHIFT 8 +#define MAD_DIMM_B_SIZE_MASK (0xff << MAD_DIMM_B_SIZE_SHIFT) +#define MAD_DIMM_A_SIZE_SHIFT 0 +#define MAD_DIMM_A_SIZE_MASK (0xff << MAD_DIMM_A_SIZE_SHIFT) + + /* Clocking configuration register */ #define CLKCFG 0x10c00 #define CLKCFG_FSB_400 (5 << 0) /* hrawclk 100 */ -- cgit v1.2.3-70-g09d2 From 11782b0233c06a35776786f30e19dc4168eb5406 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 31 Jan 2012 16:47:55 +0100 Subject: drm/i915: consolidate swizzling control bit frobbing On gen5 we also need to correctly set up swizzling in the display scanout engine, but only there. Consolidate this into the same function. This has a small effect on ums setups - the kernel now also sets this bit in addition to userspace setting it. Given that this code only runs when userspace either can't (resume, gpu reset) or explicitly won't(gem_init) touch the hw this shouldn't have an adverse effect. Reviewed-by: Ben Widawsky Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 5 ++++- drivers/gpu/drm/i915/intel_display.c | 6 ------ 2 files changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 86fffd26a89..27fe07a2fd3 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3685,13 +3685,16 @@ void i915_gem_init_swizzling(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; - if (INTEL_INFO(dev)->gen < 6 || + if (INTEL_INFO(dev)->gen < 5 || dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_NONE) return; I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) | DISP_TILE_SURFACE_SWIZZLING); + if (IS_GEN5(dev)) + return; + I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_SWZCTL); if (IS_GEN6(dev)) I915_WRITE(ARB_MODE, ARB_MODE_ENABLE(ARB_MODE_SWIZZLE_SNB)); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index fc9bc19f6db..5ab967ce86c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6029,12 +6029,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, intel_wait_for_vblank(dev, pipe); - if (IS_GEN5(dev)) { - /* enable address swizzle for tiling buffer */ - temp = I915_READ(DISP_ARB_CTL); - I915_WRITE(DISP_ARB_CTL, temp | DISP_TILE_SURFACE_SWIZZLING); - } - I915_WRITE(DSPCNTR(plane), dspcntr); POSTING_READ(DSPCNTR(plane)); -- cgit v1.2.3-70-g09d2 From 3fa7d235440a18855cfdba76d6fc788db99eac28 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 31 Jan 2012 16:47:56 +0100 Subject: drm/i915: add gen6+ registers to i915_swizzle_info Reviewed-by: Ben Widawsky Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 681cbe4e6e2..4ebca6d0494 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1422,6 +1422,19 @@ static int i915_swizzle_info(struct seq_file *m, void *data) I915_READ16(C0DRB3)); seq_printf(m, "C1DRB3 = 0x%04x\n", I915_READ16(C1DRB3)); + } else if (IS_GEN6(dev) || IS_GEN7(dev)) { + seq_printf(m, "MAD_DIMM_C0 = 0x%08x\n", + I915_READ(MAD_DIMM_C0)); + seq_printf(m, "MAD_DIMM_C1 = 0x%08x\n", + I915_READ(MAD_DIMM_C1)); + seq_printf(m, "MAD_DIMM_C2 = 0x%08x\n", + I915_READ(MAD_DIMM_C2)); + seq_printf(m, "TILECTL = 0x%08x\n", + I915_READ(TILECTL)); + seq_printf(m, "ARB_MODE = 0x%08x\n", + I915_READ(ARB_MODE)); + seq_printf(m, "DISP_ARB_CTL = 0x%08x\n", + I915_READ(DISP_ARB_CTL)); } mutex_unlock(&dev->struct_mutex); -- cgit v1.2.3-70-g09d2 From dae2e9f430c46c29e3f771110094bd3da3625aa4 Mon Sep 17 00:00:00 2001 From: "Pradeep A. Dalvi" Date: Mon, 6 Feb 2012 11:16:13 +0000 Subject: netdev: ethernet dev_alloc_skb to netdev_alloc_skb Replaced deprecating dev_alloc_skb with netdev_alloc_skb in drivers/net/ethernet - Removed extra skb->dev = dev after netdev_alloc_skb Signed-off-by: Pradeep A Dalvi Signed-off-by: David S. Miller --- drivers/net/ethernet/netx-eth.c | 2 +- drivers/net/ethernet/nuvoton/w90p910_ether.c | 2 +- drivers/net/ethernet/nvidia/forcedeth.c | 8 ++++---- drivers/net/ethernet/packetengines/hamachi.c | 8 +++----- drivers/net/ethernet/packetengines/yellowfin.c | 8 +++----- drivers/net/ethernet/pasemi/pasemi_mac.c | 2 +- drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c | 2 +- drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 2 +- drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c | 2 +- drivers/net/ethernet/racal/ni5010.c | 2 +- drivers/net/ethernet/realtek/atp.c | 2 +- drivers/net/ethernet/renesas/sh_eth.c | 6 ++---- drivers/net/ethernet/seeq/ether3.c | 2 +- drivers/net/ethernet/seeq/seeq8005.c | 2 +- drivers/net/ethernet/sis/sis900.c | 6 +++--- drivers/net/ethernet/smsc/epic100.c | 6 +++--- drivers/net/ethernet/smsc/smc911x.c | 2 +- drivers/net/ethernet/smsc/smc9194.c | 2 +- drivers/net/ethernet/smsc/smc91c92_cs.c | 2 +- drivers/net/ethernet/smsc/smc91x.c | 2 +- drivers/net/ethernet/smsc/smsc9420.c | 2 -- drivers/net/ethernet/sun/cassini.c | 2 +- drivers/net/ethernet/sun/sunbmac.c | 2 +- drivers/net/ethernet/sun/sunhme.c | 2 +- drivers/net/ethernet/sun/sunqe.c | 2 +- drivers/net/ethernet/tehuti/tehuti.c | 7 +++---- drivers/net/ethernet/ti/davinci_emac.c | 3 +-- drivers/net/ethernet/tile/tilepro.c | 4 ++-- drivers/net/ethernet/toshiba/tc35815.c | 2 +- drivers/net/ethernet/via/via-rhine.c | 2 -- drivers/net/ethernet/via/via-velocity.c | 2 +- drivers/net/ethernet/xilinx/xilinx_emaclite.c | 2 +- drivers/net/ethernet/xircom/xirc2ps_cs.c | 3 ++- 33 files changed, 47 insertions(+), 58 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/netx-eth.c b/drivers/net/ethernet/netx-eth.c index 5a12276f810..9d11ab7521b 100644 --- a/drivers/net/ethernet/netx-eth.c +++ b/drivers/net/ethernet/netx-eth.c @@ -150,7 +150,7 @@ static void netx_eth_receive(struct net_device *ndev) seg = (val & FIFO_PTR_SEGMENT_MASK) >> FIFO_PTR_SEGMENT_SHIFT; len = (val & FIFO_PTR_FRAMELEN_MASK) >> FIFO_PTR_FRAMELEN_SHIFT; - skb = dev_alloc_skb(len); + skb = netdev_alloc_skb(ndev, len); if (unlikely(skb == NULL)) { printk(KERN_NOTICE "%s: Low memory, packet dropped.\n", ndev->name); diff --git a/drivers/net/ethernet/nuvoton/w90p910_ether.c b/drivers/net/ethernet/nuvoton/w90p910_ether.c index b75a0497d58..6893a65ae55 100644 --- a/drivers/net/ethernet/nuvoton/w90p910_ether.c +++ b/drivers/net/ethernet/nuvoton/w90p910_ether.c @@ -735,7 +735,7 @@ static void netdev_rx(struct net_device *dev) if (status & RXDS_RXGD) { data = ether->rdesc->recv_buf[ether->cur_rx]; - skb = dev_alloc_skb(length+2); + skb = netdev_alloc_skb(dev, length + 2); if (!skb) { dev_err(&pdev->dev, "get skb buffer error\n"); ether->stats.rx_dropped++; diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c index 4c4e7f45838..5eeb92f8738 100644 --- a/drivers/net/ethernet/nvidia/forcedeth.c +++ b/drivers/net/ethernet/nvidia/forcedeth.c @@ -1815,7 +1815,7 @@ static int nv_alloc_rx(struct net_device *dev) less_rx = np->last_rx.orig; while (np->put_rx.orig != less_rx) { - struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz + NV_RX_ALLOC_PAD); + struct sk_buff *skb = netdev_alloc_skb(dev, np->rx_buf_sz + NV_RX_ALLOC_PAD); if (skb) { np->put_rx_ctx->skb = skb; np->put_rx_ctx->dma = pci_map_single(np->pci_dev, @@ -1850,7 +1850,7 @@ static int nv_alloc_rx_optimized(struct net_device *dev) less_rx = np->last_rx.ex; while (np->put_rx.ex != less_rx) { - struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz + NV_RX_ALLOC_PAD); + struct sk_buff *skb = netdev_alloc_skb(dev, np->rx_buf_sz + NV_RX_ALLOC_PAD); if (skb) { np->put_rx_ctx->skb = skb; np->put_rx_ctx->dma = pci_map_single(np->pci_dev, @@ -4993,9 +4993,9 @@ static int nv_loopback_test(struct net_device *dev) /* setup packet for tx */ pkt_len = ETH_DATA_LEN; - tx_skb = dev_alloc_skb(pkt_len); + tx_skb = netdev_alloc_skb(dev, pkt_len); if (!tx_skb) { - netdev_err(dev, "dev_alloc_skb() failed during loopback test\n"); + netdev_err(dev, "netdev_alloc_skb() failed during loopback test\n"); ret = 0; goto out; } diff --git a/drivers/net/ethernet/packetengines/hamachi.c b/drivers/net/ethernet/packetengines/hamachi.c index 3458df3780b..0d29f5f4b8e 100644 --- a/drivers/net/ethernet/packetengines/hamachi.c +++ b/drivers/net/ethernet/packetengines/hamachi.c @@ -1188,11 +1188,10 @@ static void hamachi_init_ring(struct net_device *dev) } /* Fill in the Rx buffers. Handle allocation failure gracefully. */ for (i = 0; i < RX_RING_SIZE; i++) { - struct sk_buff *skb = dev_alloc_skb(hmp->rx_buf_sz + 2); + struct sk_buff *skb = netdev_alloc_skb(dev, hmp->rx_buf_sz + 2); hmp->rx_skbuff[i] = skb; if (skb == NULL) break; - skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* 16 byte align the IP header. */ hmp->rx_ring[i].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev, skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE)); @@ -1488,7 +1487,7 @@ static int hamachi_rx(struct net_device *dev) /* Check if the packet is long enough to accept without copying to a minimally-sized skbuff. */ if (pkt_len < rx_copybreak && - (skb = dev_alloc_skb(pkt_len + 2)) != NULL) { + (skb = netdev_alloc_skb(dev, pkt_len + 2)) != NULL) { #ifdef RX_CHECKSUM printk(KERN_ERR "%s: rx_copybreak non-zero " "not good with RX_CHECKSUM\n", dev->name); @@ -1591,12 +1590,11 @@ static int hamachi_rx(struct net_device *dev) entry = hmp->dirty_rx % RX_RING_SIZE; desc = &(hmp->rx_ring[entry]); if (hmp->rx_skbuff[entry] == NULL) { - struct sk_buff *skb = dev_alloc_skb(hmp->rx_buf_sz + 2); + struct sk_buff *skb = netdev_alloc_skb(dev, hmp->rx_buf_sz + 2); hmp->rx_skbuff[entry] = skb; if (skb == NULL) break; /* Better luck next round. */ - skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ desc->addr = cpu_to_leXX(pci_map_single(hmp->pci_dev, skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE)); diff --git a/drivers/net/ethernet/packetengines/yellowfin.c b/drivers/net/ethernet/packetengines/yellowfin.c index 4a5774271bd..7757b80ef92 100644 --- a/drivers/net/ethernet/packetengines/yellowfin.c +++ b/drivers/net/ethernet/packetengines/yellowfin.c @@ -743,11 +743,10 @@ static int yellowfin_init_ring(struct net_device *dev) } for (i = 0; i < RX_RING_SIZE; i++) { - struct sk_buff *skb = dev_alloc_skb(yp->rx_buf_sz + 2); + struct sk_buff *skb = netdev_alloc_skb(dev, yp->rx_buf_sz + 2); yp->rx_skbuff[i] = skb; if (skb == NULL) break; - skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* 16 byte align the IP header. */ yp->rx_ring[i].addr = cpu_to_le32(pci_map_single(yp->pci_dev, skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE)); @@ -1133,7 +1132,7 @@ static int yellowfin_rx(struct net_device *dev) PCI_DMA_FROMDEVICE); yp->rx_skbuff[entry] = NULL; } else { - skb = dev_alloc_skb(pkt_len + 2); + skb = netdev_alloc_skb(dev, pkt_len + 2); if (skb == NULL) break; skb_reserve(skb, 2); /* 16 byte align the IP header */ @@ -1156,11 +1155,10 @@ static int yellowfin_rx(struct net_device *dev) for (; yp->cur_rx - yp->dirty_rx > 0; yp->dirty_rx++) { entry = yp->dirty_rx % RX_RING_SIZE; if (yp->rx_skbuff[entry] == NULL) { - struct sk_buff *skb = dev_alloc_skb(yp->rx_buf_sz + 2); + struct sk_buff *skb = netdev_alloc_skb(dev, yp->rx_buf_sz + 2); if (skb == NULL) break; /* Better luck next round. */ yp->rx_skbuff[entry] = skb; - skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ yp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(yp->pci_dev, skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE)); diff --git a/drivers/net/ethernet/pasemi/pasemi_mac.c b/drivers/net/ethernet/pasemi/pasemi_mac.c index 3bb725ed270..667498ea460 100644 --- a/drivers/net/ethernet/pasemi/pasemi_mac.c +++ b/drivers/net/ethernet/pasemi/pasemi_mac.c @@ -643,7 +643,7 @@ static void pasemi_mac_replenish_rx_ring(const struct net_device *dev, /* Entry in use? */ WARN_ON(*buff); - skb = dev_alloc_skb(mac->bufsz); + skb = netdev_alloc_skb(dev, mac->bufsz); skb_reserve(skb, LOCAL_SKB_ALIGN); if (unlikely(!skb)) diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c index f69ac442c6a..718b2744035 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c @@ -1487,7 +1487,7 @@ netxen_alloc_rx_skb(struct netxen_adapter *adapter, dma_addr_t dma; struct pci_dev *pdev = adapter->pdev; - buffer->skb = dev_alloc_skb(rds_ring->skb_size); + buffer->skb = netdev_alloc_skb(adapter->netdev, rds_ring->skb_size); if (!buffer->skb) return 1; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c index 30dcbfba8f2..89ddf7f7d7d 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c @@ -719,7 +719,7 @@ static int qlcnic_do_lb_test(struct qlcnic_adapter *adapter, u8 mode) int i, loop, cnt = 0; for (i = 0; i < QLCNIC_NUM_ILB_PKT; i++) { - skb = dev_alloc_skb(QLCNIC_ILB_PKT_SIZE); + skb = netdev_alloc_skb(adapter->netdev, QLCNIC_ILB_PKT_SIZE); qlcnic_create_loopback_buff(skb->data, adapter->mac_addr); skb_put(skb, QLCNIC_ILB_PKT_SIZE); diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c index 41d85efee42..d32cf0ddf1b 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c @@ -1440,7 +1440,7 @@ qlcnic_alloc_rx_skb(struct qlcnic_adapter *adapter, dma_addr_t dma; struct pci_dev *pdev = adapter->pdev; - skb = dev_alloc_skb(rds_ring->skb_size); + skb = netdev_alloc_skb(adapter->netdev, rds_ring->skb_size); if (!skb) { adapter->stats.skb_alloc_failure++; return -ENOMEM; diff --git a/drivers/net/ethernet/racal/ni5010.c b/drivers/net/ethernet/racal/ni5010.c index 072810da9a3..80798222005 100644 --- a/drivers/net/ethernet/racal/ni5010.c +++ b/drivers/net/ethernet/racal/ni5010.c @@ -552,7 +552,7 @@ static void ni5010_rx(struct net_device *dev) } /* Malloc up new buffer. */ - skb = dev_alloc_skb(i_pkt_size + 3); + skb = netdev_alloc_skb(dev, i_pkt_size + 3); if (skb == NULL) { printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name); dev->stats.rx_dropped++; diff --git a/drivers/net/ethernet/realtek/atp.c b/drivers/net/ethernet/realtek/atp.c index e3f57fdbf0e..46c1932048c 100644 --- a/drivers/net/ethernet/realtek/atp.c +++ b/drivers/net/ethernet/realtek/atp.c @@ -783,7 +783,7 @@ static void net_rx(struct net_device *dev) int pkt_len = (rx_head.rx_count & 0x7ff) - 4; struct sk_buff *skb; - skb = dev_alloc_skb(pkt_len + 2); + skb = netdev_alloc_skb(dev, pkt_len + 2); if (skb == NULL) { printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n", dev->name); diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index dacd13150b6..1a69504ed9c 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -653,13 +653,12 @@ static void sh_eth_ring_format(struct net_device *ndev) for (i = 0; i < RX_RING_SIZE; i++) { /* skb */ mdp->rx_skbuff[i] = NULL; - skb = dev_alloc_skb(mdp->rx_buf_sz); + skb = netdev_alloc_skb(ndev, mdp->rx_buf_sz); mdp->rx_skbuff[i] = skb; if (skb == NULL) break; dma_map_single(&ndev->dev, skb->data, mdp->rx_buf_sz, DMA_FROM_DEVICE); - skb->dev = ndev; /* Mark as being used by this device. */ sh_eth_set_receive_align(skb); /* RX descriptor */ @@ -953,13 +952,12 @@ static int sh_eth_rx(struct net_device *ndev) rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16); if (mdp->rx_skbuff[entry] == NULL) { - skb = dev_alloc_skb(mdp->rx_buf_sz); + skb = netdev_alloc_skb(ndev, mdp->rx_buf_sz); mdp->rx_skbuff[entry] = skb; if (skb == NULL) break; /* Better luck next round. */ dma_map_single(&ndev->dev, skb->data, mdp->rx_buf_sz, DMA_FROM_DEVICE); - skb->dev = ndev; sh_eth_set_receive_align(skb); skb_checksum_none_assert(skb); diff --git a/drivers/net/ethernet/seeq/ether3.c b/drivers/net/ethernet/seeq/ether3.c index 893c880dadf..7b819bd8c41 100644 --- a/drivers/net/ethernet/seeq/ether3.c +++ b/drivers/net/ethernet/seeq/ether3.c @@ -643,7 +643,7 @@ if (next_ptr < RX_START || next_ptr >= RX_END) { if (next_ptr <= this_ptr) length += RX_END - RX_START; - skb = dev_alloc_skb(length + 2); + skb = netdev_alloc_skb(dev, length + 2); if (skb) { unsigned char *buf; diff --git a/drivers/net/ethernet/seeq/seeq8005.c b/drivers/net/ethernet/seeq/seeq8005.c index 60561451789..79899077444 100644 --- a/drivers/net/ethernet/seeq/seeq8005.c +++ b/drivers/net/ethernet/seeq/seeq8005.c @@ -548,7 +548,7 @@ static void seeq8005_rx(struct net_device *dev) struct sk_buff *skb; unsigned char *buf; - skb = dev_alloc_skb(pkt_len); + skb = netdev_alloc_skb(dev, pkt_len); if (skb == NULL) { printk("%s: Memory squeeze, dropping packet.\n", dev->name); dev->stats.rx_dropped++; diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c index 91c44688bc3..f968898c86d 100644 --- a/drivers/net/ethernet/sis/sis900.c +++ b/drivers/net/ethernet/sis/sis900.c @@ -1166,7 +1166,7 @@ sis900_init_rx_ring(struct net_device *net_dev) for (i = 0; i < NUM_RX_DESC; i++) { struct sk_buff *skb; - if ((skb = dev_alloc_skb(RX_BUF_SIZE)) == NULL) { + if ((skb = netdev_alloc_skb(net_dev, RX_BUF_SIZE)) == NULL) { /* not enough memory for skbuff, this makes a "hole" on the buffer ring, it is not clear how the hardware will react to this kind of degenerated @@ -1769,7 +1769,7 @@ static int sis900_rx(struct net_device *net_dev) /* refill the Rx buffer, what if there is not enough * memory for new socket buffer ?? */ - if ((skb = dev_alloc_skb(RX_BUF_SIZE)) == NULL) { + if ((skb = netdev_alloc_skb(net_dev, RX_BUF_SIZE)) == NULL) { /* * Not enough memory to refill the buffer * so we need to recycle the old one so @@ -1827,7 +1827,7 @@ refill_rx_ring: entry = sis_priv->dirty_rx % NUM_RX_DESC; if (sis_priv->rx_skbuff[entry] == NULL) { - if ((skb = dev_alloc_skb(RX_BUF_SIZE)) == NULL) { + if ((skb = netdev_alloc_skb(net_dev, RX_BUF_SIZE)) == NULL) { /* not enough memory for skbuff, this makes a * "hole" on the buffer ring, it is not clear * how the hardware will react to this kind diff --git a/drivers/net/ethernet/smsc/epic100.c b/drivers/net/ethernet/smsc/epic100.c index 11dcb38b99f..2a662e6112e 100644 --- a/drivers/net/ethernet/smsc/epic100.c +++ b/drivers/net/ethernet/smsc/epic100.c @@ -934,7 +934,7 @@ static void epic_init_ring(struct net_device *dev) /* Fill in the Rx buffers. Handle allocation failure gracefully. */ for (i = 0; i < RX_RING_SIZE; i++) { - struct sk_buff *skb = dev_alloc_skb(ep->rx_buf_sz + 2); + struct sk_buff *skb = netdev_alloc_skb(dev, ep->rx_buf_sz + 2); ep->rx_skbuff[i] = skb; if (skb == NULL) break; @@ -1199,7 +1199,7 @@ static int epic_rx(struct net_device *dev, int budget) /* Check if the packet is long enough to accept without copying to a minimally-sized skbuff. */ if (pkt_len < rx_copybreak && - (skb = dev_alloc_skb(pkt_len + 2)) != NULL) { + (skb = netdev_alloc_skb(dev, pkt_len + 2)) != NULL) { skb_reserve(skb, 2); /* 16 byte align the IP header */ pci_dma_sync_single_for_cpu(ep->pci_dev, ep->rx_ring[entry].bufaddr, @@ -1232,7 +1232,7 @@ static int epic_rx(struct net_device *dev, int budget) entry = ep->dirty_rx % RX_RING_SIZE; if (ep->rx_skbuff[entry] == NULL) { struct sk_buff *skb; - skb = ep->rx_skbuff[entry] = dev_alloc_skb(ep->rx_buf_sz + 2); + skb = ep->rx_skbuff[entry] = netdev_alloc_skb(dev, ep->rx_buf_sz + 2); if (skb == NULL) break; skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ diff --git a/drivers/net/ethernet/smsc/smc911x.c b/drivers/net/ethernet/smsc/smc911x.c index c28230148ef..8814b2f5d46 100644 --- a/drivers/net/ethernet/smsc/smc911x.c +++ b/drivers/net/ethernet/smsc/smc911x.c @@ -401,7 +401,7 @@ static inline void smc911x_rcv(struct net_device *dev) } else { /* Receive a valid packet */ /* Alloc a buffer with extra room for DMA alignment */ - skb=dev_alloc_skb(pkt_len+32); + skb = netdev_alloc_skb(dev, pkt_len+32); if (unlikely(skb == NULL)) { PRINTK( "%s: Low memory, rcvd packet dropped.\n", dev->name); diff --git a/drivers/net/ethernet/smsc/smc9194.c b/drivers/net/ethernet/smsc/smc9194.c index 4e45094efb1..50823da9dc1 100644 --- a/drivers/net/ethernet/smsc/smc9194.c +++ b/drivers/net/ethernet/smsc/smc9194.c @@ -1222,7 +1222,7 @@ static void smc_rcv(struct net_device *dev) if ( status & RS_MULTICAST ) dev->stats.multicast++; - skb = dev_alloc_skb( packet_length + 5); + skb = netdev_alloc_skb(dev, packet_length + 5); if ( skb == NULL ) { printk(KERN_NOTICE CARDNAME ": Low memory, packet dropped.\n"); diff --git a/drivers/net/ethernet/smsc/smc91c92_cs.c b/drivers/net/ethernet/smsc/smc91c92_cs.c index ada927aba7a..d12e48a7861 100644 --- a/drivers/net/ethernet/smsc/smc91c92_cs.c +++ b/drivers/net/ethernet/smsc/smc91c92_cs.c @@ -1500,7 +1500,7 @@ static void smc_rx(struct net_device *dev) struct sk_buff *skb; /* Note: packet_length adds 5 or 6 extra bytes here! */ - skb = dev_alloc_skb(packet_length+2); + skb = netdev_alloc_skb(dev, packet_length+2); if (skb == NULL) { pr_debug("%s: Low memory, packet dropped.\n", dev->name); diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c index 24104a1ee6a..1dc4fad593e 100644 --- a/drivers/net/ethernet/smsc/smc91x.c +++ b/drivers/net/ethernet/smsc/smc91x.c @@ -463,7 +463,7 @@ static inline void smc_rcv(struct net_device *dev) * multiple of 4 bytes on 32 bit buses. * Hence packet_len - 6 + 2 + 2 + 2. */ - skb = dev_alloc_skb(packet_len); + skb = netdev_alloc_skb(dev, packet_len); if (unlikely(skb == NULL)) { printk(KERN_NOTICE "%s: Low memory, packet dropped.\n", dev->name); diff --git a/drivers/net/ethernet/smsc/smsc9420.c b/drivers/net/ethernet/smsc/smsc9420.c index 595f9881e09..ee1a1680b7a 100644 --- a/drivers/net/ethernet/smsc/smsc9420.c +++ b/drivers/net/ethernet/smsc/smsc9420.c @@ -850,8 +850,6 @@ static int smsc9420_alloc_rx_buffer(struct smsc9420_pdata *pd, int index) return -ENOMEM; } - skb->dev = pd->dev; - mapping = pci_map_single(pd->pdev, skb_tail_pointer(skb), PKT_BUF_SZ, PCI_DMA_FROMDEVICE); if (pci_dma_mapping_error(pd->pdev, mapping)) { diff --git a/drivers/net/ethernet/sun/cassini.c b/drivers/net/ethernet/sun/cassini.c index 45292760fce..b36edbd625d 100644 --- a/drivers/net/ethernet/sun/cassini.c +++ b/drivers/net/ethernet/sun/cassini.c @@ -1974,7 +1974,7 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc, else alloclen = max(hlen, RX_COPY_MIN); - skb = dev_alloc_skb(alloclen + swivel + cp->crc_size); + skb = netdev_alloc_skb(cp->dev, alloclen + swivel + cp->crc_size); if (skb == NULL) return -1; diff --git a/drivers/net/ethernet/sun/sunbmac.c b/drivers/net/ethernet/sun/sunbmac.c index 220f724c337..f359863b534 100644 --- a/drivers/net/ethernet/sun/sunbmac.c +++ b/drivers/net/ethernet/sun/sunbmac.c @@ -853,7 +853,7 @@ static void bigmac_rx(struct bigmac *bp) /* Trim the original skb for the netif. */ skb_trim(skb, len); } else { - struct sk_buff *copy_skb = dev_alloc_skb(len + 2); + struct sk_buff *copy_skb = netdev_alloc_skb(bp->dev, len + 2); if (copy_skb == NULL) { drops++; diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c index 09c518655db..8b627e2f798 100644 --- a/drivers/net/ethernet/sun/sunhme.c +++ b/drivers/net/ethernet/sun/sunhme.c @@ -2043,7 +2043,7 @@ static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev) /* Trim the original skb for the netif. */ skb_trim(skb, len); } else { - struct sk_buff *copy_skb = dev_alloc_skb(len + 2); + struct sk_buff *copy_skb = netdev_alloc_skb(dev, len + 2); if (copy_skb == NULL) { drops++; diff --git a/drivers/net/ethernet/sun/sunqe.c b/drivers/net/ethernet/sun/sunqe.c index b28f74367eb..b42d1c5a6ca 100644 --- a/drivers/net/ethernet/sun/sunqe.c +++ b/drivers/net/ethernet/sun/sunqe.c @@ -435,7 +435,7 @@ static void qe_rx(struct sunqe *qep) dev->stats.rx_length_errors++; dev->stats.rx_dropped++; } else { - skb = dev_alloc_skb(len + 2); + skb = netdev_alloc_skb(dev, len + 2); if (skb == NULL) { drops++; dev->stats.rx_dropped++; diff --git a/drivers/net/ethernet/tehuti/tehuti.c b/drivers/net/ethernet/tehuti/tehuti.c index df7febba9ea..ad973ffc9ff 100644 --- a/drivers/net/ethernet/tehuti/tehuti.c +++ b/drivers/net/ethernet/tehuti/tehuti.c @@ -1089,12 +1089,11 @@ static void bdx_rx_alloc_skbs(struct bdx_priv *priv, struct rxf_fifo *f) ENTER; dno = bdx_rxdb_available(db) - 1; while (dno > 0) { - skb = dev_alloc_skb(f->m.pktsz + NET_IP_ALIGN); + skb = netdev_alloc_skb(priv->ndev, f->m.pktsz + NET_IP_ALIGN); if (!skb) { - pr_err("NO MEM: dev_alloc_skb failed\n"); + pr_err("NO MEM: netdev_alloc_skb failed\n"); break; } - skb->dev = priv->ndev; skb_reserve(skb, NET_IP_ALIGN); idx = bdx_rxdb_alloc_elem(db); @@ -1258,7 +1257,7 @@ static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget) skb = dm->skb; if (len < BDX_COPYBREAK && - (skb2 = dev_alloc_skb(len + NET_IP_ALIGN))) { + (skb2 = netdev_alloc_skb(priv->ndev, len + NET_IP_ALIGN))) { skb_reserve(skb2, NET_IP_ALIGN); /*skb_put(skb2, len); */ pci_dma_sync_single_for_cpu(priv->pdev, diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index 922a937e05c..6b0659c59dd 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c @@ -992,10 +992,9 @@ static irqreturn_t emac_irq(int irq, void *dev_id) static struct sk_buff *emac_rx_alloc(struct emac_priv *priv) { - struct sk_buff *skb = dev_alloc_skb(priv->rx_buf_size); + struct sk_buff *skb = netdev_alloc_skb(priv->ndev, priv->rx_buf_size); if (WARN_ON(!skb)) return NULL; - skb->dev = priv->ndev; skb_reserve(skb, NET_IP_ALIGN); return skb; } diff --git a/drivers/net/ethernet/tile/tilepro.c b/drivers/net/ethernet/tile/tilepro.c index d9951afb926..a8e5daaef6f 100644 --- a/drivers/net/ethernet/tile/tilepro.c +++ b/drivers/net/ethernet/tile/tilepro.c @@ -419,7 +419,7 @@ static bool tile_net_provide_needed_buffer(struct tile_net_cpu *info, #endif /* Avoid "false sharing" with last cache line. */ - /* ISSUE: This is already done by "dev_alloc_skb()". */ + /* ISSUE: This is already done by "netdev_alloc_skb()". */ unsigned int len = (((small ? LIPP_SMALL_PACKET_SIZE : large_size) + CHIP_L2_LINE_SIZE() - 1) & -CHIP_L2_LINE_SIZE()); @@ -433,7 +433,7 @@ static bool tile_net_provide_needed_buffer(struct tile_net_cpu *info, struct sk_buff **skb_ptr; /* Request 96 extra bytes for alignment purposes. */ - skb = dev_alloc_skb(len + padding); + skb = netdev_alloc_skb(info->napi->dev, len + padding); if (skb == NULL) return false; diff --git a/drivers/net/ethernet/toshiba/tc35815.c b/drivers/net/ethernet/toshiba/tc35815.c index f5ac603d560..d117ad475c3 100644 --- a/drivers/net/ethernet/toshiba/tc35815.c +++ b/drivers/net/ethernet/toshiba/tc35815.c @@ -453,7 +453,7 @@ static struct sk_buff *alloc_rxbuf_skb(struct net_device *dev, dma_addr_t *dma_handle) { struct sk_buff *skb; - skb = dev_alloc_skb(RX_BUF_SIZE); + skb = netdev_alloc_skb(dev, RX_BUF_SIZE); if (!skb) return NULL; *dma_handle = pci_map_single(hwdev, skb->data, RX_BUF_SIZE, diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c index 1b95daa372c..cb2ff28a060 100644 --- a/drivers/net/ethernet/via/via-rhine.c +++ b/drivers/net/ethernet/via/via-rhine.c @@ -1155,7 +1155,6 @@ static void alloc_rbufs(struct net_device *dev) rp->rx_skbuff[i] = skb; if (skb == NULL) break; - skb->dev = dev; /* Mark as being used by this device. */ rp->rx_skbuff_dma[i] = pci_map_single(rp->pdev, skb->data, rp->rx_buf_sz, @@ -1940,7 +1939,6 @@ static int rhine_rx(struct net_device *dev, int limit) rp->rx_skbuff[entry] = skb; if (skb == NULL) break; /* Better luck next round. */ - skb->dev = dev; /* Mark as being used by this device. */ rp->rx_skbuff_dma[entry] = pci_map_single(rp->pdev, skb->data, rp->rx_buf_sz, diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c index 2776bbc6793..cf69cbf6fec 100644 --- a/drivers/net/ethernet/via/via-velocity.c +++ b/drivers/net/ethernet/via/via-velocity.c @@ -1509,7 +1509,7 @@ static int velocity_alloc_rx_buf(struct velocity_info *vptr, int idx) struct rx_desc *rd = &(vptr->rx.ring[idx]); struct velocity_rd_info *rd_info = &(vptr->rx.info[idx]); - rd_info->skb = dev_alloc_skb(vptr->rx.buf_sz + 64); + rd_info->skb = netdev_alloc_skb(vptr->dev, vptr->rx.buf_sz + 64); if (rd_info->skb == NULL) return -ENOMEM; diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c index 90e611a6f6c..77cfe511031 100644 --- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c +++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c @@ -613,7 +613,7 @@ static void xemaclite_rx_handler(struct net_device *dev) u32 len; len = ETH_FRAME_LEN + ETH_FCS_LEN; - skb = dev_alloc_skb(len + ALIGNMENT); + skb = netdev_alloc_skb(dev, len + ALIGNMENT); if (!skb) { /* Couldn't get memory. */ dev->stats.rx_dropped++; diff --git a/drivers/net/ethernet/xircom/xirc2ps_cs.c b/drivers/net/ethernet/xircom/xirc2ps_cs.c index 33979c3ac94..5c69c6f93fb 100644 --- a/drivers/net/ethernet/xircom/xirc2ps_cs.c +++ b/drivers/net/ethernet/xircom/xirc2ps_cs.c @@ -1039,7 +1039,8 @@ xirc2ps_interrupt(int irq, void *dev_id) pr_debug("rsr=%#02x packet_length=%u\n", rsr, pktlen); - skb = dev_alloc_skb(pktlen+3); /* 1 extra so we can use insw */ + /* 1 extra so we can use insw */ + skb = netdev_alloc_skb(dev, pktlen + 3); if (!skb) { pr_notice("low memory, packet dropped (size=%u)\n", pktlen); dev->stats.rx_dropped++; -- cgit v1.2.3-70-g09d2 From 1ab0d2ec9aeb4489c05158e8a2b00bad89f67e03 Mon Sep 17 00:00:00 2001 From: "Pradeep A. Dalvi" Date: Mon, 6 Feb 2012 11:16:48 +0000 Subject: netdev: ethernet dev_alloc_skb to netdev_alloc_skb Replaced deprecating dev_alloc_skb with netdev_alloc_skb in drivers/net/ethernet - Removed extra skb->dev = dev after netdev_alloc_skb Signed-off-by: Pradeep A Dalvi Signed-off-by: David S. Miller --- drivers/net/ethernet/3com/3c515.c | 10 ++++------ drivers/net/ethernet/adi/bfin_mac.c | 8 ++++---- drivers/net/ethernet/apple/bmac.c | 11 ++++++----- drivers/net/ethernet/dec/tulip/dmfe.c | 20 +++++++++++--------- drivers/net/ethernet/dec/tulip/uli526x.c | 21 ++++++++++++--------- drivers/net/ethernet/s6gmac.c | 9 +++++---- 6 files changed, 42 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/3com/3c515.c b/drivers/net/ethernet/3com/3c515.c index f67a5d3a200..59e1e001bc3 100644 --- a/drivers/net/ethernet/3com/3c515.c +++ b/drivers/net/ethernet/3com/3c515.c @@ -826,11 +826,10 @@ static int corkscrew_open(struct net_device *dev) vp->rx_ring[i].next = 0; vp->rx_ring[i].status = 0; /* Clear complete bit. */ vp->rx_ring[i].length = PKT_BUF_SZ | 0x80000000; - skb = dev_alloc_skb(PKT_BUF_SZ); + skb = netdev_alloc_skb(dev, PKT_BUF_SZ); vp->rx_skbuff[i] = skb; if (skb == NULL) break; /* Bad news! */ - skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ vp->rx_ring[i].addr = isa_virt_to_bus(skb->data); } @@ -1295,7 +1294,7 @@ static int corkscrew_rx(struct net_device *dev) short pkt_len = rx_status & 0x1fff; struct sk_buff *skb; - skb = dev_alloc_skb(pkt_len + 5 + 2); + skb = netdev_alloc_skb(dev, pkt_len + 5 + 2); if (corkscrew_debug > 4) pr_debug("Receiving packet size %d status %4.4x.\n", pkt_len, rx_status); @@ -1368,7 +1367,7 @@ static int boomerang_rx(struct net_device *dev) /* Check if the packet is long enough to just accept without copying to a properly sized skbuff. */ if (pkt_len < rx_copybreak && - (skb = dev_alloc_skb(pkt_len + 4)) != NULL) { + (skb = netdev_alloc_skb(dev, pkt_len + 4)) != NULL) { skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ /* 'skb_put()' points to the start of sk_buff data area. */ memcpy(skb_put(skb, pkt_len), @@ -1403,10 +1402,9 @@ static int boomerang_rx(struct net_device *dev) struct sk_buff *skb; entry = vp->dirty_rx % RX_RING_SIZE; if (vp->rx_skbuff[entry] == NULL) { - skb = dev_alloc_skb(PKT_BUF_SZ); + skb = netdev_alloc_skb(dev, PKT_BUF_SZ); if (skb == NULL) break; /* Bad news! */ - skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ vp->rx_ring[entry].addr = isa_virt_to_bus(skb->data); vp->rx_skbuff[entry] = skb; diff --git a/drivers/net/ethernet/adi/bfin_mac.c b/drivers/net/ethernet/adi/bfin_mac.c index 525a9768bb5..49733696703 100644 --- a/drivers/net/ethernet/adi/bfin_mac.c +++ b/drivers/net/ethernet/adi/bfin_mac.c @@ -113,7 +113,7 @@ static void desc_list_free(void) } } -static int desc_list_init(void) +static int desc_list_init(struct net_device *dev) { int i; struct sk_buff *new_skb; @@ -187,7 +187,7 @@ static int desc_list_init(void) struct dma_descriptor *b = &(r->desc_b); /* allocate a new skb for next time receive */ - new_skb = dev_alloc_skb(PKT_BUF_SZ + NET_IP_ALIGN); + new_skb = netdev_alloc_skb(dev, PKT_BUF_SZ + NET_IP_ALIGN); if (!new_skb) { pr_notice("init: low on mem - packet dropped\n"); goto init_error; @@ -1090,7 +1090,7 @@ static void bfin_mac_rx(struct net_device *dev) /* allocate a new skb for next time receive */ skb = current_rx_ptr->skb; - new_skb = dev_alloc_skb(PKT_BUF_SZ + NET_IP_ALIGN); + new_skb = netdev_alloc_skb(dev, PKT_BUF_SZ + NET_IP_ALIGN); if (!new_skb) { netdev_notice(dev, "rx: low on mem - packet dropped\n"); dev->stats.rx_dropped++; @@ -1397,7 +1397,7 @@ static int bfin_mac_open(struct net_device *dev) } /* initial rx and tx list */ - ret = desc_list_init(); + ret = desc_list_init(dev); if (ret) return ret; diff --git a/drivers/net/ethernet/apple/bmac.c b/drivers/net/ethernet/apple/bmac.c index ebc0dba5ba3..855bdafb1a8 100644 --- a/drivers/net/ethernet/apple/bmac.c +++ b/drivers/net/ethernet/apple/bmac.c @@ -607,8 +607,9 @@ bmac_init_tx_ring(struct bmac_data *bp) } static int -bmac_init_rx_ring(struct bmac_data *bp) +bmac_init_rx_ring(struct net_device *dev) { + struct bmac_data *bp = netdev_priv(dev); volatile struct dbdma_regs __iomem *rd = bp->rx_dma; int i; struct sk_buff *skb; @@ -618,7 +619,7 @@ bmac_init_rx_ring(struct bmac_data *bp) (N_RX_RING + 1) * sizeof(struct dbdma_cmd)); for (i = 0; i < N_RX_RING; i++) { if ((skb = bp->rx_bufs[i]) == NULL) { - bp->rx_bufs[i] = skb = dev_alloc_skb(RX_BUFLEN+2); + bp->rx_bufs[i] = skb = netdev_alloc_skb(dev, RX_BUFLEN + 2); if (skb != NULL) skb_reserve(skb, 2); } @@ -722,7 +723,7 @@ static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id) ++dev->stats.rx_dropped; } if ((skb = bp->rx_bufs[i]) == NULL) { - bp->rx_bufs[i] = skb = dev_alloc_skb(RX_BUFLEN+2); + bp->rx_bufs[i] = skb = netdev_alloc_skb(dev, RX_BUFLEN + 2); if (skb != NULL) skb_reserve(bp->rx_bufs[i], 2); } @@ -1208,7 +1209,7 @@ static void bmac_reset_and_enable(struct net_device *dev) spin_lock_irqsave(&bp->lock, flags); bmac_enable_and_reset_chip(dev); bmac_init_tx_ring(bp); - bmac_init_rx_ring(bp); + bmac_init_rx_ring(dev); bmac_init_chip(dev); bmac_start_chip(dev); bmwrite(dev, INTDISABLE, EnableNormal); @@ -1218,7 +1219,7 @@ static void bmac_reset_and_enable(struct net_device *dev) * It seems that the bmac can't receive until it's transmitted * a packet. So we give it a dummy packet to transmit. */ - skb = dev_alloc_skb(ETHERMINPACKET); + skb = netdev_alloc_skb(dev, ETHERMINPACKET); if (skb != NULL) { data = skb_put(skb, ETHERMINPACKET); memset(data, 0, ETHERMINPACKET); diff --git a/drivers/net/ethernet/dec/tulip/dmfe.c b/drivers/net/ethernet/dec/tulip/dmfe.c index 51f7542eb45..1eccf494548 100644 --- a/drivers/net/ethernet/dec/tulip/dmfe.c +++ b/drivers/net/ethernet/dec/tulip/dmfe.c @@ -325,8 +325,8 @@ static irqreturn_t dmfe_interrupt(int , void *); #ifdef CONFIG_NET_POLL_CONTROLLER static void poll_dmfe (struct net_device *dev); #endif -static void dmfe_descriptor_init(struct dmfe_board_info *, unsigned long); -static void allocate_rx_buffer(struct dmfe_board_info *); +static void dmfe_descriptor_init(struct net_device *, unsigned long); +static void allocate_rx_buffer(struct net_device *); static void update_cr6(u32, unsigned long); static void send_filter_frame(struct DEVICE *); static void dm9132_id_table(struct DEVICE *); @@ -649,7 +649,7 @@ static void dmfe_init_dm910x(struct DEVICE *dev) db->op_mode = db->media_mode; /* Force Mode */ /* Initialize Transmit/Receive decriptor and CR3/4 */ - dmfe_descriptor_init(db, ioaddr); + dmfe_descriptor_init(dev, ioaddr); /* Init CR6 to program DM910x operation */ update_cr6(db->cr6_data, ioaddr); @@ -828,7 +828,7 @@ static irqreturn_t dmfe_interrupt(int irq, void *dev_id) /* reallocate rx descriptor buffer */ if (db->rx_avail_cntcr5_data & 0x01) @@ -1008,7 +1008,7 @@ static void dmfe_rx_packet(struct DEVICE *dev, struct dmfe_board_info * db) /* Good packet, send to upper layer */ /* Shorst packet used new SKB */ if ((rxlen < RX_COPY_SIZE) && - ((newskb = dev_alloc_skb(rxlen + 2)) + ((newskb = netdev_alloc_skb(dev, rxlen + 2)) != NULL)) { skb = newskb; @@ -1364,8 +1364,9 @@ static void dmfe_reuse_skb(struct dmfe_board_info *db, struct sk_buff * skb) * Using Chain structure, and allocate Tx/Rx buffer */ -static void dmfe_descriptor_init(struct dmfe_board_info *db, unsigned long ioaddr) +static void dmfe_descriptor_init(struct net_device *dev, unsigned long ioaddr) { + struct dmfe_board_info *db = netdev_priv(dev); struct tx_desc *tmp_tx; struct rx_desc *tmp_rx; unsigned char *tmp_buf; @@ -1421,7 +1422,7 @@ static void dmfe_descriptor_init(struct dmfe_board_info *db, unsigned long ioadd tmp_rx->next_rx_desc = db->first_rx_desc; /* pre-allocate Rx buffer */ - allocate_rx_buffer(db); + allocate_rx_buffer(dev); } @@ -1551,15 +1552,16 @@ static void send_filter_frame(struct DEVICE *dev) * As possible as allocate maxiumn Rx buffer */ -static void allocate_rx_buffer(struct dmfe_board_info *db) +static void allocate_rx_buffer(struct net_device *dev) { + struct dmfe_board_info *db = netdev_priv(dev); struct rx_desc *rxptr; struct sk_buff *skb; rxptr = db->rx_insert_ptr; while(db->rx_avail_cnt < RX_DESC_CNT) { - if ( ( skb = dev_alloc_skb(RX_ALLOC_SIZE) ) == NULL ) + if ( ( skb = netdev_alloc_skb(dev, RX_ALLOC_SIZE) ) == NULL ) break; rxptr->rx_skb_ptr = skb; /* FIXME (?) */ rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->data, diff --git a/drivers/net/ethernet/dec/tulip/uli526x.c b/drivers/net/ethernet/dec/tulip/uli526x.c index 48b0b6566ee..fc4001f6a5e 100644 --- a/drivers/net/ethernet/dec/tulip/uli526x.c +++ b/drivers/net/ethernet/dec/tulip/uli526x.c @@ -232,8 +232,8 @@ static irqreturn_t uli526x_interrupt(int, void *); #ifdef CONFIG_NET_POLL_CONTROLLER static void uli526x_poll(struct net_device *dev); #endif -static void uli526x_descriptor_init(struct uli526x_board_info *, unsigned long); -static void allocate_rx_buffer(struct uli526x_board_info *); +static void uli526x_descriptor_init(struct net_device *, unsigned long); +static void allocate_rx_buffer(struct net_device *); static void update_cr6(u32, unsigned long); static void send_filter_frame(struct net_device *, int); static u16 phy_read(unsigned long, u8, u8, u32); @@ -549,7 +549,7 @@ static void uli526x_init(struct net_device *dev) db->op_mode = db->media_mode; /* Force Mode */ /* Initialize Transmit/Receive decriptor and CR3/4 */ - uli526x_descriptor_init(db, ioaddr); + uli526x_descriptor_init(dev, ioaddr); /* Init CR6 to program M526X operation */ update_cr6(db->cr6_data, ioaddr); @@ -711,7 +711,7 @@ static irqreturn_t uli526x_interrupt(int irq, void *dev_id) /* reallocate rx descriptor buffer */ if (db->rx_avail_cntcr5_data & 0x01) @@ -844,7 +844,7 @@ static void uli526x_rx_packet(struct net_device *dev, struct uli526x_board_info /* Good packet, send to upper layer */ /* Shorst packet used new SKB */ if ((rxlen < RX_COPY_SIZE) && - (((new_skb = dev_alloc_skb(rxlen + 2)) != NULL))) { + (((new_skb = netdev_alloc_skb(dev, rxlen + 2)) != NULL))) { skb = new_skb; /* size less than COPY_SIZE, allocate a rxlen SKB */ skb_reserve(skb, 2); /* 16byte align */ @@ -1289,8 +1289,9 @@ static void uli526x_reuse_skb(struct uli526x_board_info *db, struct sk_buff * sk * Using Chain structure, and allocate Tx/Rx buffer */ -static void uli526x_descriptor_init(struct uli526x_board_info *db, unsigned long ioaddr) +static void uli526x_descriptor_init(struct net_device *dev, unsigned long ioaddr) { + struct uli526x_board_info *db = netdev_priv(dev); struct tx_desc *tmp_tx; struct rx_desc *tmp_rx; unsigned char *tmp_buf; @@ -1343,7 +1344,7 @@ static void uli526x_descriptor_init(struct uli526x_board_info *db, unsigned long tmp_rx->next_rx_desc = db->first_rx_desc; /* pre-allocate Rx buffer */ - allocate_rx_buffer(db); + allocate_rx_buffer(dev); } @@ -1433,15 +1434,17 @@ static void send_filter_frame(struct net_device *dev, int mc_cnt) * As possible as allocate maxiumn Rx buffer */ -static void allocate_rx_buffer(struct uli526x_board_info *db) +static void allocate_rx_buffer(struct net_device *dev) { + struct uli526x_board_info *db = netdev_priv(dev); struct rx_desc *rxptr; struct sk_buff *skb; rxptr = db->rx_insert_ptr; while(db->rx_avail_cnt < RX_DESC_CNT) { - if ( ( skb = dev_alloc_skb(RX_ALLOC_SIZE) ) == NULL ) + skb = netdev_alloc_skb(dev, RX_ALLOC_SIZE); + if (skb == NULL) break; rxptr->rx_skb_ptr = skb; /* FIXME (?) */ rxptr->rdes2 = cpu_to_le32(pci_map_single(db->pdev, diff --git a/drivers/net/ethernet/s6gmac.c b/drivers/net/ethernet/s6gmac.c index bee97033167..1895605abb3 100644 --- a/drivers/net/ethernet/s6gmac.c +++ b/drivers/net/ethernet/s6gmac.c @@ -370,12 +370,13 @@ struct s6gmac { } link; }; -static void s6gmac_rx_fillfifo(struct s6gmac *pd) +static void s6gmac_rx_fillfifo(struct net_device *dev) { + struct s6gmac *pd = netdev_priv(dev); struct sk_buff *skb; while ((((u8)(pd->rx_skb_i - pd->rx_skb_o)) < S6_NUM_RX_SKB) && (!s6dmac_fifo_full(pd->rx_dma, pd->rx_chan)) && - (skb = dev_alloc_skb(S6_MAX_FRLEN + 2))) { + (skb = netdev_alloc_skb(dev, S6_MAX_FRLEN + 2))) { pd->rx_skb[(pd->rx_skb_i++) % S6_NUM_RX_SKB] = skb; s6dmac_put_fifo_cache(pd->rx_dma, pd->rx_chan, pd->io, (u32)skb->data, S6_MAX_FRLEN); @@ -514,7 +515,7 @@ static irqreturn_t s6gmac_interrupt(int irq, void *dev_id) spin_lock(&pd->lock); if (s6dmac_termcnt_irq(pd->rx_dma, pd->rx_chan)) s6gmac_rx_interrupt(dev); - s6gmac_rx_fillfifo(pd); + s6gmac_rx_fillfifo(dev); if (s6dmac_termcnt_irq(pd->tx_dma, pd->tx_chan)) s6gmac_tx_interrupt(dev); s6gmac_stats_interrupt(pd, 0); @@ -894,7 +895,7 @@ static int s6gmac_open(struct net_device *dev) s6gmac_init_device(dev); s6gmac_init_stats(dev); s6gmac_init_dmac(dev); - s6gmac_rx_fillfifo(pd); + s6gmac_rx_fillfifo(dev); s6dmac_enable_chan(pd->rx_dma, pd->rx_chan, 2, 1, 0, 1, 0, 0, 0, 7, -1, 2, 0, 1); s6dmac_enable_chan(pd->tx_dma, pd->tx_chan, -- cgit v1.2.3-70-g09d2 From c3ab96f36aa308fa5bf432d5a4dafc80b7373805 Mon Sep 17 00:00:00 2001 From: Frank Blaschka Date: Wed, 8 Feb 2012 00:19:49 +0000 Subject: qeth: add query OSA address table support Add qeth device private ioctl to query the OSA address table. This helps debugging hw related problems. Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- arch/s390/include/asm/qeth.h | 7 +++ drivers/s390/net/qeth_core.h | 1 + drivers/s390/net/qeth_core_main.c | 99 +++++++++++++++++++++++++++++++++++++++ drivers/s390/net/qeth_core_mpc.h | 13 +++++ drivers/s390/net/qeth_l2_main.c | 3 ++ drivers/s390/net/qeth_l3_main.c | 3 ++ 6 files changed, 126 insertions(+) (limited to 'drivers') diff --git a/arch/s390/include/asm/qeth.h b/arch/s390/include/asm/qeth.h index 90efda0b137..2c7c898c03e 100644 --- a/arch/s390/include/asm/qeth.h +++ b/arch/s390/include/asm/qeth.h @@ -20,6 +20,7 @@ #define SIOC_QETH_ARP_FLUSH_CACHE (SIOCDEVPRIVATE + 4) #define SIOC_QETH_ADP_SET_SNMP_CONTROL (SIOCDEVPRIVATE + 5) #define SIOC_QETH_GET_CARD_TYPE (SIOCDEVPRIVATE + 6) +#define SIOC_QETH_QUERY_OAT (SIOCDEVPRIVATE + 7) struct qeth_arp_cache_entry { __u8 macaddr[6]; @@ -107,4 +108,10 @@ struct qeth_arp_query_user_data { char *entries; } __attribute__((packed)); +struct qeth_query_oat_data { + __u32 command; + __u32 buffer_len; + __u32 response_len; + __u64 ptr; +}; #endif /* __ASM_S390_QETH_IOCTL_H__ */ diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 4abc79d3963..ec7921b5138 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -906,6 +906,7 @@ void qeth_prepare_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *, char); struct qeth_cmd_buffer *qeth_wait_for_buffer(struct qeth_channel *); int qeth_mdio_read(struct net_device *, int, int); int qeth_snmp_command(struct qeth_card *, char __user *); +int qeth_query_oat_command(struct qeth_card *, char __user *); struct qeth_cmd_buffer *qeth_get_adapter_cmd(struct qeth_card *, __u32, __u32); int qeth_default_setadapterparms_cb(struct qeth_card *, struct qeth_reply *, unsigned long); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 9c3f38da4c0..0565584b52c 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "qeth_core.h" @@ -4402,6 +4403,104 @@ int qeth_snmp_command(struct qeth_card *card, char __user *udata) } EXPORT_SYMBOL_GPL(qeth_snmp_command); +static int qeth_setadpparms_query_oat_cb(struct qeth_card *card, + struct qeth_reply *reply, unsigned long data) +{ + struct qeth_ipa_cmd *cmd; + struct qeth_qoat_priv *priv; + char *resdata; + int resdatalen; + + QETH_CARD_TEXT(card, 3, "qoatcb"); + + cmd = (struct qeth_ipa_cmd *)data; + priv = (struct qeth_qoat_priv *)reply->param; + resdatalen = cmd->data.setadapterparms.hdr.cmdlength; + resdata = (char *)data + 28; + + if (resdatalen > (priv->buffer_len - priv->response_len)) { + cmd->hdr.return_code = IPA_RC_FFFF; + return 0; + } + + memcpy((priv->buffer + priv->response_len), resdata, + resdatalen); + priv->response_len += resdatalen; + + if (cmd->data.setadapterparms.hdr.seq_no < + cmd->data.setadapterparms.hdr.used_total) + return 1; + return 0; +} + +int qeth_query_oat_command(struct qeth_card *card, char __user *udata) +{ + int rc = 0; + struct qeth_cmd_buffer *iob; + struct qeth_ipa_cmd *cmd; + struct qeth_query_oat *oat_req; + struct qeth_query_oat_data oat_data; + struct qeth_qoat_priv priv; + void __user *tmp; + + QETH_CARD_TEXT(card, 3, "qoatcmd"); + + if (!qeth_adp_supported(card, IPA_SETADP_QUERY_OAT)) { + rc = -EOPNOTSUPP; + goto out; + } + + if (copy_from_user(&oat_data, udata, + sizeof(struct qeth_query_oat_data))) { + rc = -EFAULT; + goto out; + } + + priv.buffer_len = oat_data.buffer_len; + priv.response_len = 0; + priv.buffer = kzalloc(oat_data.buffer_len, GFP_KERNEL); + if (!priv.buffer) { + rc = -ENOMEM; + goto out; + } + + iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_OAT, + sizeof(struct qeth_ipacmd_setadpparms_hdr) + + sizeof(struct qeth_query_oat)); + cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); + oat_req = &cmd->data.setadapterparms.data.query_oat; + oat_req->subcmd_code = oat_data.command; + + rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_query_oat_cb, + &priv); + if (!rc) { + if (is_compat_task()) + tmp = compat_ptr(oat_data.ptr); + else + tmp = (void __user *)(unsigned long)oat_data.ptr; + + if (copy_to_user(tmp, priv.buffer, + priv.response_len)) { + rc = -EFAULT; + goto out_free; + } + + oat_data.response_len = priv.response_len; + + if (copy_to_user(udata, &oat_data, + sizeof(struct qeth_query_oat_data))) + rc = -EFAULT; + } else + if (rc == IPA_RC_FFFF) + rc = -EFAULT; + +out_free: + kfree(priv.buffer); +out: + return rc; +} +EXPORT_SYMBOL_GPL(qeth_query_oat_command); + static inline int qeth_get_qdio_q_format(struct qeth_card *card) { switch (card->info.type) { diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h index e5a9d1c0383..578e19a2de6 100644 --- a/drivers/s390/net/qeth_core_mpc.h +++ b/drivers/s390/net/qeth_core_mpc.h @@ -249,6 +249,7 @@ enum qeth_ipa_setadp_cmd { IPA_SETADP_SET_PROMISC_MODE = 0x00000800L, IPA_SETADP_SET_DIAG_ASSIST = 0x00002000L, IPA_SETADP_SET_ACCESS_CONTROL = 0x00010000L, + IPA_SETADP_QUERY_OAT = 0x00080000L, }; enum qeth_ipa_mac_ops { CHANGE_ADDR_READ_MAC = 0, @@ -398,6 +399,17 @@ struct qeth_set_access_ctrl { __u32 subcmd_code; } __attribute__((packed)); +struct qeth_query_oat { + __u32 subcmd_code; + __u8 reserved[12]; +} __packed; + +struct qeth_qoat_priv { + __u32 buffer_len; + __u32 response_len; + char *buffer; +}; + struct qeth_ipacmd_setadpparms_hdr { __u32 supp_hw_cmds; __u32 reserved1; @@ -417,6 +429,7 @@ struct qeth_ipacmd_setadpparms { struct qeth_change_addr change_addr; struct qeth_snmp_cmd snmp; struct qeth_set_access_ctrl set_access_ctrl; + struct qeth_query_oat query_oat; __u32 mode; } data; } __attribute__ ((packed)); diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index c1296713311..e5c9cf15e5c 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -75,6 +75,9 @@ static int qeth_l2_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) mii_data->val_out = qeth_mdio_read(dev, mii_data->phy_id, mii_data->reg_num); break; + case SIOC_QETH_QUERY_OAT: + rc = qeth_query_oat_command(card, rq->ifr_ifru.ifru_data); + break; default: rc = -EOPNOTSUPP; } diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 25cd3799a76..73bf8889984 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2745,6 +2745,9 @@ static int qeth_l3_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) mii_data->phy_id, mii_data->reg_num); break; + case SIOC_QETH_QUERY_OAT: + rc = qeth_query_oat_command(card, rq->ifr_ifru.ifru_data); + break; default: rc = -EOPNOTSUPP; } -- cgit v1.2.3-70-g09d2 From 039055b965b9cfbeacb8cdcd1ef57e18b6374e58 Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Wed, 8 Feb 2012 00:19:50 +0000 Subject: qeth: add wake_up on write channel To send commands on the write channel 8 buffers exist. If all 8 buffers are used, a wait is triggered on the write channel. When such buffer are freed, a wake_up is needed. This patch adds the missing wake_up in qeth_release_buffer(). This fix is especially important when running Communications Controller for Linux on System z. Signed-off-by: Ursula Braun Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core_main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 0565584b52c..cbb101828dc 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -678,6 +678,7 @@ void qeth_release_buffer(struct qeth_channel *channel, iob->callback = qeth_send_control_data_cb; iob->rc = 0; spin_unlock_irqrestore(&channel->iob_lock, flags); + wake_up(&channel->wait_q); } EXPORT_SYMBOL_GPL(qeth_release_buffer); -- cgit v1.2.3-70-g09d2 From 976a0be03a15f1c268e3f569c0ade3e7ff8ce478 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 7 Feb 2012 11:45:57 -0800 Subject: ACPI: remove duplicated lines of merging problems with acpi_processor_start When checking driver-core tree, found crazying warnings on my setups. [ 216.025849] calling acpi_processor_init+0x0/0x81 @ 1 [ 216.045332] ACPI: Requesting acpi_cpufreq [ 216.047454] Monitor-Mwait will be used to enter C-1 state [ 216.047912] Monitor-Mwait will be used to enter C-3 state [ 216.065270] ACPI: acpi_idle registered with cpuidle [ 216.068241] kobject (ffff8870364a1940): tried to init an initialized object, something is seriously wrong. [ 216.085287] Pid: 1, comm: swapper/0 Not tainted 3.3.0-rc2-tip-yh-02428-ge663840-dirty #247 [ 216.105041] Call Trace: [ 216.105192] [] kobject_init+0x33/0x83 [ 216.124880] [] kobject_init_and_add+0x23/0x57 [ 216.125158] [] cpuidle_add_sysfs+0x49/0x62 [ 216.144850] [] __cpuidle_register_device+0xe6/0x10e [ 216.145182] [] cpuidle_register_device+0x25/0x4d [ 216.164912] [] acpi_processor_power_init+0x13e/0x16c [ 216.165205] [] ? acpi_processor_get_throttling_info+0x128/0x158 [ 216.185012] [] acpi_processor_start+0x62/0x11d [ 216.204861] [] acpi_processor_add+0x1b0/0x1e7 [ 216.205144] [] acpi_device_probe+0x4e/0x11c [ 216.225063] [] really_probe+0x99/0x126 [ 216.225328] [] driver_probe_device+0x3b/0x56 [ 216.244846] [] __driver_attach+0x5f/0x82 [ 216.245101] [] ? driver_probe_device+0x56/0x56 [ 216.264668] [] bus_for_each_dev+0x5c/0x88 [ 216.264942] [] driver_attach+0x1e/0x20 [ 216.284639] [] bus_add_driver+0xca/0x21d [ 216.284903] [] ? local_clock+0xf/0x3c [ 216.304580] [] ? acpi_fan_init+0x18/0x18 [ 216.304849] [] driver_register+0x91/0xfe [ 216.324545] [] ? acpi_fan_init+0x18/0x18 [ 216.324813] [] acpi_bus_register_driver+0x43/0x45 [ 216.344563] [] acpi_processor_init+0x30/0x81 [ 216.344845] [] ? acpi_fan_init+0x18/0x18 [ 216.364590] [] do_one_initcall+0x57/0x134 [ 216.364868] [] kernel_init+0x146/0x1c0 [ 216.384512] [] kernel_thread_helper+0x4/0x10 [ 216.384819] [] ? retint_restore_args+0xe/0xe [ 216.404578] [] ? start_kernel+0x3ab/0x3ab [ 216.424530] [] ? gs_change+0xb/0xb [ 216.424793] ------------[ cut here ]------------ [ 216.425038] WARNING: at fs/sysfs/dir.c:502 sysfs_add_one+0x97/0xab() [ 216.444480] Hardware name: Sun Fire X4800 [ 216.444668] sysfs: cannot create duplicate filename '/devices/system/cpu/cpu0/cpuidle' ... It turns out acpi_processor_power_init() get called two time in acpi_processor_add and acpi_processor_start. Found several lines are duplicated in those two functions even related commit move them. The related patches are ok. Not sure how it could happen, looks like git problem. -v2: add back acpi_processor_load_module(pr) to acpi_processor_load_start Signed-off-by: Yinghai Lu Cc: Linus Torvalds Acked-by: Thomas Renninger Cc: Len Brown Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/processor_driver.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index f289d2afbd4..2801b418d7b 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -474,6 +474,7 @@ static __ref int acpi_processor_start(struct acpi_processor *pr) #ifdef CONFIG_CPU_FREQ acpi_processor_ppc_has_changed(pr, 0); + acpi_processor_load_module(pr); #endif acpi_processor_get_throttling_info(pr); acpi_processor_get_limit_info(pr); @@ -579,23 +580,6 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) goto err_free_cpumask; } -#ifdef CONFIG_CPU_FREQ - acpi_processor_ppc_has_changed(pr, 0); - acpi_processor_load_module(pr); -#endif - acpi_processor_get_throttling_info(pr); - acpi_processor_get_limit_info(pr); - - if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver) - acpi_processor_power_init(pr, device); - - pr->cdev = thermal_cooling_device_register("Processor", device, - &processor_cooling_ops); - if (IS_ERR(pr->cdev)) { - result = PTR_ERR(pr->cdev); - goto err_remove_sysfs; - } - /* * Do not start hotplugged CPUs now, but when they * are onlined the first time -- cgit v1.2.3-70-g09d2 From 28aa41fb8d555b120edefd7fdf879b156a1c9f3a Mon Sep 17 00:00:00 2001 From: Greg Dietsche Date: Sun, 15 Jan 2012 14:44:34 -0600 Subject: staging: android: ram_console use kmemdup instead of kmalloc Replace kmalloc + memcpy will kmemdup in ram_console_late_init Signed-off-by: Greg Dietsche Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/ram_console.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c index 6d4d67924f2..0cb3f3c227f 100644 --- a/drivers/staging/android/ram_console.c +++ b/drivers/staging/android/ram_console.c @@ -411,15 +411,14 @@ static int __init ram_console_late_init(void) if (ram_console_old_log == NULL) return 0; #ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT - ram_console_old_log = kmalloc(ram_console_old_log_size, GFP_KERNEL); + ram_console_old_log = kmemdup(ram_console_old_log_init_buffer, + ram_console_old_log_size, GFP_KERNEL); if (ram_console_old_log == NULL) { printk(KERN_ERR "ram_console: failed to allocate buffer for old log\n"); ram_console_old_log_size = 0; return 0; } - memcpy(ram_console_old_log, - ram_console_old_log_init_buffer, ram_console_old_log_size); #endif entry = create_proc_entry("last_kmsg", S_IFREG | S_IRUGO, NULL); if (!entry) { -- cgit v1.2.3-70-g09d2 From 217218f002a669905701cc0baa18a8d6ba1d5e21 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Thu, 12 Jan 2012 06:51:31 -0800 Subject: drivers:staging:android Typos: fix some comments that have typos in them. Below is a patch that fixes some typos in some comments. Signed-off-by: Justin P. Mattock Cc: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/TODO | 2 +- drivers/staging/android/binder.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/TODO b/drivers/staging/android/TODO index e59c5be4be2..b15fb0d6b15 100644 --- a/drivers/staging/android/TODO +++ b/drivers/staging/android/TODO @@ -3,7 +3,7 @@ TODO: - sparse fixes - rename files to be not so "generic" - make sure things build as modules properly - - add proper arch dependancies as needed + - add proper arch dependencies as needed - audit userspace interfaces to make sure they are sane Please send patches to Greg Kroah-Hartman and Cc: diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index 7491801a661..e748756b51d 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -257,7 +257,7 @@ struct binder_ref { }; struct binder_buffer { - struct list_head entry; /* free and allocated entries by addesss */ + struct list_head entry; /* free and allocated entries by address */ struct rb_node rb_node; /* free entry by size or allocated entry */ /* by address */ unsigned free:1; -- cgit v1.2.3-70-g09d2 From 8d438bef6556315a23781fd673f13f7bfb94047d Mon Sep 17 00:00:00 2001 From: Thomas Meyer Date: Sun, 22 Jan 2012 18:34:58 +0100 Subject: Staging: android: ram_console: Use resource_size function The semantic patch that makes this change is available in scripts/coccinelle/api/resource_size.cocci. More information about semantic patching is available at http://coccinelle.lip6.fr/ Signed-off-by: Thomas Meyer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/ram_console.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c index 0cb3f3c227f..fabd398ec1b 100644 --- a/drivers/staging/android/ram_console.c +++ b/drivers/staging/android/ram_console.c @@ -351,7 +351,7 @@ static int ram_console_driver_probe(struct platform_device *pdev) "%lx\n", res, pdev->num_resources, res ? res->flags : 0); return -ENXIO; } - buffer_size = res->end - res->start + 1; + buffer_size = resource_size(res); start = res->start; printk(KERN_INFO "ram_console: got buffer at %zx, size %zx\n", start, buffer_size); -- cgit v1.2.3-70-g09d2 From aa5af974127d317071d6225a0f3678c5f520e7ce Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Sun, 22 Jan 2012 21:28:44 -0500 Subject: drivers/staging/android/ashmem.c: Cleanups Minor cleanups that consist of removal of a whitespace and make file_operations const. Signed-off-by: Tracey Dent Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/ashmem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index 99052bfd3a2..9f1f27e7c86 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c @@ -315,7 +315,7 @@ static int ashmem_mmap(struct file *file, struct vm_area_struct *vma) get_file(asma->file); /* - * XXX - Reworked to use shmem_zero_setup() instead of + * XXX - Reworked to use shmem_zero_setup() instead of * shmem_set_file while we're in staging. -jstultz */ if (vma->vm_flags & VM_SHARED) { @@ -680,7 +680,7 @@ static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return ret; } -static struct file_operations ashmem_fops = { +static const struct file_operations ashmem_fops = { .owner = THIS_MODULE, .open = ashmem_open, .release = ashmem_release, -- cgit v1.2.3-70-g09d2 From e3251e0d7921fbedfe61cb237c6ce6c273bd93a7 Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Sun, 22 Jan 2012 21:28:46 -0500 Subject: drivers/staging/android/timed_gpio.c: Stlye fixes Just made it more neat and not bother scripts/checkpatch.pl Signed-off-by: Tracey Dent Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/timed_gpio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/timed_gpio.c b/drivers/staging/android/timed_gpio.c index a64481c3e86..bc723eff11a 100644 --- a/drivers/staging/android/timed_gpio.c +++ b/drivers/staging/android/timed_gpio.c @@ -29,9 +29,9 @@ struct timed_gpio_data { struct timed_output_dev dev; struct hrtimer timer; spinlock_t lock; - unsigned gpio; - int max_timeout; - u8 active_low; + unsigned gpio; + int max_timeout; + u8 active_low; }; static enum hrtimer_restart gpio_timer_func(struct hrtimer *timer) -- cgit v1.2.3-70-g09d2 From c626224de9370ae783e8b0cb6aaca2ba3d81fe62 Mon Sep 17 00:00:00 2001 From: Tim Bird Date: Tue, 7 Feb 2012 18:26:38 -0800 Subject: staging: android: logger: Change logger_offset() from macro to function Convert to function and add log as a parameter, rather than relying on log in the context of the macro. Signed-off-by: Tim Bird Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/logger.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c index ffc2d043dd8..29ee1372722 100644 --- a/drivers/staging/android/logger.c +++ b/drivers/staging/android/logger.c @@ -60,7 +60,11 @@ struct logger_reader { }; /* logger_offset - returns index 'n' into the log via (optimized) modulus */ -#define logger_offset(n) ((n) & (log->size - 1)) +size_t logger_offset(struct logger_log *log, size_t n) +{ + return n & (log->size-1); +} + /* * file_get_log - Given a file structure, return the associated log @@ -137,7 +141,7 @@ 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(reader->r_off + count); + reader->r_off = logger_offset(log, reader->r_off + count); return count; } @@ -225,7 +229,7 @@ static size_t get_next_entry(struct logger_log *log, size_t off, size_t len) do { size_t nr = get_entry_len(log, off); - off = logger_offset(off + nr); + off = logger_offset(log, off + nr); count += nr; } while (count < len); @@ -260,7 +264,7 @@ static inline int clock_interval(size_t a, size_t b, size_t c) static void fix_up_readers(struct logger_log *log, size_t len) { size_t old = log->w_off; - size_t new = logger_offset(old + len); + size_t new = logger_offset(log, old + len); struct logger_reader *reader; if (clock_interval(old, new, log->head)) @@ -286,7 +290,7 @@ static void do_write_log(struct logger_log *log, const void *buf, size_t count) if (count != len) memcpy(log->buffer, buf + len, count - len); - log->w_off = logger_offset(log->w_off + count); + log->w_off = logger_offset(log, log->w_off + count); } @@ -311,7 +315,7 @@ static ssize_t do_write_log_from_user(struct logger_log *log, if (copy_from_user(log->buffer, buf + len, count - len)) return -EFAULT; - log->w_off = logger_offset(log->w_off + count); + log->w_off = logger_offset(log, log->w_off + count); return count; } -- cgit v1.2.3-70-g09d2 From 3bcfa431334d99fa8bff96c4e7c2108f0b26242e Mon Sep 17 00:00:00 2001 From: Tim Bird Date: Wed, 8 Feb 2012 10:37:57 -0800 Subject: staging: android: logger: simplify and optimize get_entry_len Make this code slightly easier to read, and eliminate calls to sub-routines. Some of these were previously optimized away by the compiler, but one memcpy was not. In my testing, this makes the code about 20% smaller, and has no sub-routine calls and no branches (on ARM). v2 of this patch is, IMHO, easier to read than v1. Compared to that patch it uses __u8 instead of unsigned char, for consistency with the __u16 val data type, simplifies the conditional expression, adds a another comment, and moves a common statement out of the if. Signed-off-by: Tim Bird Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/logger.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c index 29ee1372722..1e9e638cfd7 100644 --- a/drivers/staging/android/logger.c +++ b/drivers/staging/android/logger.c @@ -93,20 +93,24 @@ 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'. * + * 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. + * This function returns the size including the log entry structure. + * * Caller needs to hold log->mutex. */ static __u32 get_entry_len(struct logger_log *log, size_t off) { __u16 val; - switch (log->size - off) { - case 1: - memcpy(&val, log->buffer + off, 1); - memcpy(((char *) &val) + 1, log->buffer, 1); - break; - default: - memcpy(&val, log->buffer + off, 2); - } + /* copy 2 bytes from buffer, in memcpy order, */ + /* handling possible wrap at end of buffer */ + + ((__u8 *)&val)[0] = log->buffer[off]; + if (likely(off+1 < log->size)) + ((__u8 *)&val)[1] = log->buffer[off+1]; + else + ((__u8 *)&val)[1] = log->buffer[0]; return sizeof(struct logger_entry) + val; } -- cgit v1.2.3-70-g09d2 From c76c7ca31f16c9556cad527bfa3504b0aafb3045 Mon Sep 17 00:00:00 2001 From: Tim Bird Date: Tue, 7 Feb 2012 18:30:09 -0800 Subject: staging: android: logger: reorder prepare_to_wait and mutex_lock If mutex_lock waits, it will return in state TASK_RUNNING, rubbing out the effect of prepare_to_wait(). Signed-off-by: Tim Bird Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/logger.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c index 1e9e638cfd7..6dd6f0490c3 100644 --- a/drivers/staging/android/logger.c +++ b/drivers/staging/android/logger.c @@ -172,9 +172,10 @@ static ssize_t logger_read(struct file *file, char __user *buf, start: while (1) { + mutex_lock(&log->mutex); + prepare_to_wait(&log->wq, &wait, TASK_INTERRUPTIBLE); - mutex_lock(&log->mutex); ret = (log->w_off == reader->r_off); mutex_unlock(&log->mutex); if (!ret) -- cgit v1.2.3-70-g09d2 From 169c843afffcb328390ef39ff95227596d6f63c4 Mon Sep 17 00:00:00 2001 From: Tim Bird Date: Tue, 7 Feb 2012 18:32:02 -0800 Subject: staging: android: logger: clarify code in clock_interval Add commentary, rename the function and make the code easier to read. Signed-off-by: Tim Bird Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/logger.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c index 6dd6f0490c3..6d92b7ef0a5 100644 --- a/drivers/staging/android/logger.c +++ b/drivers/staging/android/logger.c @@ -242,16 +242,28 @@ static size_t get_next_entry(struct logger_log *log, size_t off, size_t len) } /* - * clock_interval - is a < c < b in mod-space? Put another way, does the line - * from a to b cross c? + * is_between - is a < c < b, accounting for wrapping of a, b, and c + * positions in the buffer + * + * That is, if ab, check for c outside (not between) a and b + * + * |------- a xxxxxxxx b --------| + * c^ + * + * |xxxxx b --------- a xxxxxxxxx| + * c^ + * or c^ */ -static inline int clock_interval(size_t a, size_t b, size_t c) +static inline int is_between(size_t a, size_t b, size_t c) { - if (b < a) { - if (a < c || b >= c) + if (a < b) { + /* is c between a and b? */ + if (a < c && c <= b) return 1; } else { - if (a < c && b >= c) + /* is c outside of b through a? */ + if (c <= b || a < c) return 1; } @@ -272,11 +284,11 @@ static void fix_up_readers(struct logger_log *log, size_t len) size_t new = logger_offset(log, old + len); struct logger_reader *reader; - if (clock_interval(old, new, log->head)) + if (is_between(old, new, log->head)) log->head = get_next_entry(log, log->head, len); list_for_each_entry(reader, &log->readers, list) - if (clock_interval(old, new, reader->r_off)) + if (is_between(old, new, reader->r_off)) reader->r_off = get_next_entry(log, reader->r_off, len); } -- cgit v1.2.3-70-g09d2 From 350a1955957d73352c043d0f948e3f28bb118c57 Mon Sep 17 00:00:00 2001 From: Tim Bird Date: Tue, 7 Feb 2012 18:34:28 -0800 Subject: staging: android: logger: clarify non-update of w_off in do_write_log_from_user Add comment to explain when w_off is not updated in case of failed second fragment copy to buffer. Signed-off-by: Tim Bird Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/logger.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c index 6d92b7ef0a5..0d2367f2c15 100644 --- a/drivers/staging/android/logger.c +++ b/drivers/staging/android/logger.c @@ -330,6 +330,12 @@ static ssize_t do_write_log_from_user(struct logger_log *log, if (count != len) if (copy_from_user(log->buffer, buf + len, count - len)) + /* + * Note that by not updating w_off, this abandons the + * portion of the new entry that *was* successfully + * copied, just above. This is intentional to avoid + * message corruption from missing fragments. + */ return -EFAULT; log->w_off = logger_offset(log, log->w_off + count); -- cgit v1.2.3-70-g09d2 From 294b27119f2e20643e71a0c1a1b511320a11e4c3 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Mon, 6 Feb 2012 20:29:41 +0400 Subject: staging: android/lowmemorykiller: Don't grab tasklist_lock Grabbing tasklist_lock has its disadvantages, i.e. it blocks process creation and destruction. If there are lots of processes, blocking doesn't sound as a great idea. For LMK, it is sufficient to surround tasks list traverse with rcu_read_{,un}lock(). >From now on using force_sig() is not safe, as it can race with an already exiting task, so we use send_sig() now. As a downside, it won't kill PID namespace init processes, but that's not what we want anyway. Suggested-by: Oleg Nesterov Signed-off-by: Anton Vorontsov Reviewed-by: Oleg Nesterov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/lowmemorykiller.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index 2d8d2b79610..63da8447218 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -132,7 +133,7 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) } selected_oom_adj = min_adj; - read_lock(&tasklist_lock); + rcu_read_lock(); for_each_process(p) { struct mm_struct *mm; struct signal_struct *sig; @@ -180,12 +181,12 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) lowmem_deathpending = selected; task_handoff_register(&task_nb); #endif - force_sig(SIGKILL, selected); + send_sig(SIGKILL, selected, 0); rem -= selected_tasksize; } lowmem_print(4, "lowmem_shrink %lu, %x, return %d\n", sc->nr_to_scan, sc->gfp_mask, rem); - read_unlock(&tasklist_lock); + rcu_read_unlock(); return rem; } -- cgit v1.2.3-70-g09d2 From 95670001188911f9d466875cd68e3681f39df38a Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Mon, 6 Feb 2012 20:29:47 +0400 Subject: staging: android/lowmemorykiller: Better mm handling LMK should not directly check for task->mm. The reason is that the process' threads may exit or detach its mm via use_mm(), but other threads may still have a valid mm. To catch this we use find_lock_task_mm(), which walks up all threads and returns an appropriate task (with lock held). Suggested-by: Oleg Nesterov Reviewed-by: Oleg Nesterov Signed-off-by: Anton Vorontsov Acked-by: KOSAKI Motohiro Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/lowmemorykiller.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index 63da8447218..0755e2f0eb1 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -82,7 +82,7 @@ task_notify_func(struct notifier_block *self, unsigned long val, void *data) static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) { - struct task_struct *p; + struct task_struct *tsk; struct task_struct *selected = NULL; int rem = 0; int tasksize; @@ -134,15 +134,17 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) selected_oom_adj = min_adj; rcu_read_lock(); - for_each_process(p) { - struct mm_struct *mm; + for_each_process(tsk) { + struct task_struct *p; struct signal_struct *sig; int oom_adj; - task_lock(p); - mm = p->mm; + p = find_lock_task_mm(tsk); + if (!p) + continue; + sig = p->signal; - if (!mm || !sig) { + if (!sig) { task_unlock(p); continue; } @@ -151,7 +153,7 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) task_unlock(p); continue; } - tasksize = get_mm_rss(mm); + tasksize = get_mm_rss(p->mm); task_unlock(p); if (tasksize <= 0) continue; -- cgit v1.2.3-70-g09d2 From 353416099128914a684e8bb81e7475d8c2961cc3 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Mon, 6 Feb 2012 20:29:54 +0400 Subject: staging: android/lowmemorykiller: No need for task->signal check task->signal == NULL is not possible, so no need for these checks. Suggested-by: Oleg Nesterov Reviewed-by: Oleg Nesterov Signed-off-by: Anton Vorontsov Acked-by: KOSAKI Motohiro Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/lowmemorykiller.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index 0755e2f0eb1..6e800d35ebd 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -136,19 +136,13 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) rcu_read_lock(); for_each_process(tsk) { struct task_struct *p; - struct signal_struct *sig; int oom_adj; p = find_lock_task_mm(tsk); if (!p) continue; - sig = p->signal; - if (!sig) { - task_unlock(p); - continue; - } - oom_adj = sig->oom_adj; + oom_adj = p->signal->oom_adj; if (oom_adj < min_adj) { task_unlock(p); continue; -- cgit v1.2.3-70-g09d2 From 9823ec9ded836ee7ca4fe5ab7964b9cdc8af010c Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Mon, 6 Feb 2012 20:30:01 +0400 Subject: staging: android/lowmemorykiller: Do not kill kernel threads LMK should not try killing kernel threads. Suggested-by: Oleg Nesterov Reviewed-by: Oleg Nesterov Signed-off-by: Anton Vorontsov Acked-by: KOSAKI Motohiro Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/lowmemorykiller.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index 6e800d35ebd..ae38c39a152 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -138,6 +138,9 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) struct task_struct *p; int oom_adj; + if (tsk->flags & PF_KTHREAD) + continue; + p = find_lock_task_mm(tsk); if (!p) continue; -- cgit v1.2.3-70-g09d2 From a584b7ae4ef01425f6827657abdc3e4db49b3578 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 7 Feb 2012 23:23:36 +0000 Subject: netxen_nic: signedness bug in netxen_md_entry_err_chk() "esize" should be signed because it can be negative here. For example, when we call it in netxen_parse_md_template(), it could be -1 from the return value of netxen_md_L2Cache(). Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c index 0a812285102..6f37470750f 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c @@ -2354,7 +2354,7 @@ netxen_md_rdqueue(struct netxen_adapter *adapter, */ static int netxen_md_entry_err_chk(struct netxen_adapter *adapter, - struct netxen_minidump_entry *entry, u32 esize) + struct netxen_minidump_entry *entry, int esize) { if (esize < 0) { entry->hdr.driver_flags |= NX_DUMP_SKIP; -- cgit v1.2.3-70-g09d2 From 6222d7a17745f6e48fddda7245e4bb0d58bfeaf0 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 30 Jan 2012 14:54:48 -0800 Subject: telephony: Move to staging This stuff is really old and in quite poor shape. Does anyone still use it? If not, I think it's appropriate to let it simmer in staging for a few releases. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/Kconfig | 2 - drivers/staging/Kconfig | 2 + drivers/staging/telephony/Kconfig | 47 + drivers/staging/telephony/Makefile | 7 + drivers/staging/telephony/TODO | 10 + drivers/staging/telephony/ixj-ver.h | 4 + drivers/staging/telephony/ixj.c | 10552 +++++++++++++++++++++++++++++++ drivers/staging/telephony/ixj.h | 1322 ++++ drivers/staging/telephony/ixj_pcmcia.c | 187 + drivers/staging/telephony/phonedev.c | 167 + drivers/telephony/Kconfig | 47 - drivers/telephony/Makefile | 7 - drivers/telephony/ixj-ver.h | 4 - drivers/telephony/ixj.c | 10552 ------------------------------- drivers/telephony/ixj.h | 1322 ---- drivers/telephony/ixj_pcmcia.c | 187 - drivers/telephony/phonedev.c | 167 - 17 files changed, 12298 insertions(+), 12288 deletions(-) create mode 100644 drivers/staging/telephony/Kconfig create mode 100644 drivers/staging/telephony/Makefile create mode 100644 drivers/staging/telephony/TODO create mode 100644 drivers/staging/telephony/ixj-ver.h create mode 100644 drivers/staging/telephony/ixj.c create mode 100644 drivers/staging/telephony/ixj.h create mode 100644 drivers/staging/telephony/ixj_pcmcia.c create mode 100644 drivers/staging/telephony/phonedev.c delete mode 100644 drivers/telephony/Kconfig delete mode 100644 drivers/telephony/Makefile delete mode 100644 drivers/telephony/ixj-ver.h delete mode 100644 drivers/telephony/ixj.c delete mode 100644 drivers/telephony/ixj.h delete mode 100644 drivers/telephony/ixj_pcmcia.c delete mode 100644 drivers/telephony/phonedev.c (limited to 'drivers') diff --git a/drivers/Kconfig b/drivers/Kconfig index 5afe5d1f199..decf8e42085 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -40,8 +40,6 @@ source "drivers/net/Kconfig" source "drivers/isdn/Kconfig" -source "drivers/telephony/Kconfig" - # input before char - char/joystick depends on it. As does USB. source "drivers/input/Kconfig" diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 21e2f4b87f1..aaba36c6f15 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -132,4 +132,6 @@ source "drivers/staging/omapdrm/Kconfig" source "drivers/staging/android/Kconfig" +source "drivers/staging/telephony/Kconfig" + endif # STAGING diff --git a/drivers/staging/telephony/Kconfig b/drivers/staging/telephony/Kconfig new file mode 100644 index 00000000000..b5f78b6ed2b --- /dev/null +++ b/drivers/staging/telephony/Kconfig @@ -0,0 +1,47 @@ +# +# Telephony device configuration +# + +menuconfig PHONE + tristate "Telephony support" + depends on HAS_IOMEM + ---help--- + Say Y here if you have a telephony card, which for example allows + you to use a regular phone for voice-over-IP applications. + + Note: this has nothing to do with modems. You do not need to say Y + here in order to be able to use a modem under Linux. + + To compile this driver as a module, choose M here: the + module will be called phonedev. + +if PHONE + +config PHONE_IXJ + tristate "QuickNet Internet LineJack/PhoneJack support" + depends on ISA || PCI + ---help--- + Say M if you have a telephony card manufactured by Quicknet + Technologies, Inc. These include the Internet PhoneJACK and + Internet LineJACK Telephony Cards. You will get a module called + ixj. + + For the ISA versions of these products, you can configure the + cards using the isapnp tools (pnpdump/isapnp) or you can use the + isapnp support. Please read . + + For more information on these cards, see Quicknet's web site at: + . + + If you do not have any Quicknet telephony cards, you can safely + say N here. + +config PHONE_IXJ_PCMCIA + tristate "QuickNet Internet LineJack/PhoneJack PCMCIA support" + depends on PHONE_IXJ && PCMCIA + help + Say Y here to configure in PCMCIA service support for the Quicknet + cards manufactured by Quicknet Technologies, Inc. This changes the + card initialization code to work with the card manager daemon. + +endif # PHONE diff --git a/drivers/staging/telephony/Makefile b/drivers/staging/telephony/Makefile new file mode 100644 index 00000000000..1206615d69e --- /dev/null +++ b/drivers/staging/telephony/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for drivers/telephony +# + +obj-$(CONFIG_PHONE) += phonedev.o +obj-$(CONFIG_PHONE_IXJ) += ixj.o +obj-$(CONFIG_PHONE_IXJ_PCMCIA) += ixj_pcmcia.o diff --git a/drivers/staging/telephony/TODO b/drivers/staging/telephony/TODO new file mode 100644 index 00000000000..d47dec3508d --- /dev/null +++ b/drivers/staging/telephony/TODO @@ -0,0 +1,10 @@ +TODO +. Determine if the boards are still in use + and move this module back to drivers/telephony if necessary +. Coding style cleanups + +Please send patches to Greg Kroah-Hartman and +cc Joe Perches if the module should be reactivated. + +If no module activity occurs before version 3.6 is released, this +module should be removed. diff --git a/drivers/staging/telephony/ixj-ver.h b/drivers/staging/telephony/ixj-ver.h new file mode 100644 index 00000000000..2031ac6c888 --- /dev/null +++ b/drivers/staging/telephony/ixj-ver.h @@ -0,0 +1,4 @@ +/* configuration management identifiers */ +#define IXJ_VER_MAJOR 1 +#define IXJ_VER_MINOR 0 +#define IXJ_BLD_VER 1 diff --git a/drivers/staging/telephony/ixj.c b/drivers/staging/telephony/ixj.c new file mode 100644 index 00000000000..d5f923bcdff --- /dev/null +++ b/drivers/staging/telephony/ixj.c @@ -0,0 +1,10552 @@ +/**************************************************************************** + * ixj.c + * + * Device Driver for Quicknet Technologies, Inc.'s Telephony cards + * including the Internet PhoneJACK, Internet PhoneJACK Lite, + * Internet PhoneJACK PCI, Internet LineJACK, Internet PhoneCARD and + * SmartCABLE + * + * (c) Copyright 1999-2001 Quicknet Technologies, 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. + * + * Author: Ed Okerson, + * + * Contributors: Greg Herlein, + * David W. Erhart, + * John Sellers, + * Mike Preston, + * + * Fixes: David Huggins-Daines, + * Fabio Ferrari, + * Artis Kugevics, + * Daniele Bellucci, + * + * More information about the hardware related to this driver can be found + * at our website: http://www.quicknet.net + * + * IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF QUICKNET + * TECHNOLOGIES, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * QUICKNET TECHNOLOGIES, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND QUICKNET TECHNOLOGIES, INC. HAS NO OBLIGATION + * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + ***************************************************************************/ + +/* + * Revision 4.8 2003/07/09 19:39:00 Daniele Bellucci + * Audit some copy_*_user and minor cleanup. + * + * Revision 4.7 2001/08/13 06:19:33 craigs + * Added additional changes from Alan Cox and John Anderson for + * 2.2 to 2.4 cleanup and bounds checking + * + * Revision 4.6 2001/08/13 01:05:05 craigs + * Really fixed PHONE_QUERY_CODEC problem this time + * + * Revision 4.5 2001/08/13 00:11:03 craigs + * Fixed problem in handling of PHONE_QUERY_CODEC, thanks to Shane Anderson + * + * Revision 4.4 2001/08/07 07:58:12 craigs + * Changed back to three digit version numbers + * Added tagbuild target to allow automatic and easy tagging of versions + * + * Revision 4.3 2001/08/07 07:24:47 craigs + * Added ixj-ver.h to allow easy configuration management of driver + * Added display of version number in /prox/ixj + * + * Revision 4.2 2001/08/06 07:07:19 craigs + * Reverted IXJCTL_DSP_TYPE and IXJCTL_DSP_VERSION files to original + * behaviour of returning int rather than short * + * + * Revision 4.1 2001/08/05 00:17:37 craigs + * More changes for correct PCMCIA installation + * Start of changes for backward Linux compatibility + * + * Revision 4.0 2001/08/04 12:33:12 craigs + * New version using GNU autoconf + * + * Revision 3.105 2001/07/20 23:14:32 eokerson + * More work on CallerID generation when using ring cadences. + * + * Revision 3.104 2001/07/06 01:33:55 eokerson + * Some bugfixes from Robert Vojta and a few mods to the Makefile. + * + * Revision 3.103 2001/07/05 19:20:16 eokerson + * Updated HOWTO + * Changed mic gain to 30dB on Internet LineJACK mic/speaker port. + * + * Revision 3.102 2001/07/03 23:51:21 eokerson + * Un-mute mic on Internet LineJACK when in speakerphone mode. + * + * Revision 3.101 2001/07/02 19:26:56 eokerson + * Removed initialiazation of ixjdebug and ixj_convert_loaded so they will go in the .bss instead of the .data + * + * Revision 3.100 2001/07/02 19:18:27 eokerson + * Changed driver to make dynamic allocation possible. We now pass IXJ * between functions instead of array indexes. + * Fixed the way the POTS and PSTN ports interact during a PSTN call to allow local answering. + * Fixed speaker mode on Internet LineJACK. + * + * Revision 3.99 2001/05/09 14:11:16 eokerson + * Fixed kmalloc error in ixj_build_filter_cadence. Thanks David Chan . + * + * Revision 3.98 2001/05/08 19:55:33 eokerson + * Fixed POTS hookstate detection while it is connected to PSTN port. + * + * Revision 3.97 2001/05/08 00:01:04 eokerson + * Fixed kernel oops when sending caller ID data. + * + * Revision 3.96 2001/05/04 23:09:30 eokerson + * Now uses one kernel timer for each card, instead of one for the entire driver. + * + * Revision 3.95 2001/04/25 22:06:47 eokerson + * Fixed squawking at beginning of some G.723.1 calls. + * + * Revision 3.94 2001/04/03 23:42:00 eokerson + * Added linear volume ioctls + * Added raw filter load ioctl + * + * Revision 3.93 2001/02/27 01:00:06 eokerson + * Fixed blocking in CallerID. + * Reduced size of ixj structure for smaller driver footprint. + * + * Revision 3.92 2001/02/20 22:02:59 eokerson + * Fixed isapnp and pcmcia module compatibility for 2.4.x kernels. + * Improved PSTN ring detection. + * Fixed wink generation on POTS ports. + * + * Revision 3.91 2001/02/13 00:55:44 eokerson + * Turn AEC back on after changing frame sizes. + * + * Revision 3.90 2001/02/12 16:42:00 eokerson + * Added ALAW codec, thanks to Fabio Ferrari for the table based converters to make ALAW from ULAW. + * + * Revision 3.89 2001/02/12 15:41:16 eokerson + * Fix from Artis Kugevics - Tone gains were not being set correctly. + * + * Revision 3.88 2001/02/05 23:25:42 eokerson + * Fixed lockup bugs with deregister. + * + * Revision 3.87 2001/01/29 21:00:39 eokerson + * Fix from Fabio Ferrari to properly handle EAGAIN and EINTR during non-blocking write. + * Updated copyright date. + * + * Revision 3.86 2001/01/23 23:53:46 eokerson + * Fixes to G.729 compatibility. + * + * Revision 3.85 2001/01/23 21:30:36 eokerson + * Added verbage about cards supported. + * Removed commands that put the card in low power mode at some times that it should not be in low power mode. + * + * Revision 3.84 2001/01/22 23:32:10 eokerson + * Some bugfixes from David Huggins-Daines, and other cleanups. + * + * Revision 3.83 2001/01/19 14:51:41 eokerson + * Fixed ixj_WriteDSPCommand to decrement usage counter when command fails. + * + * Revision 3.82 2001/01/19 00:34:49 eokerson + * Added verbosity to write overlap errors. + * + * Revision 3.81 2001/01/18 23:56:54 eokerson + * Fixed PSTN line test functions. + * + * Revision 3.80 2001/01/18 22:29:27 eokerson + * Updated AEC/AGC values for different cards. + * + * Revision 3.79 2001/01/17 02:58:54 eokerson + * Fixed AEC reset after Caller ID. + * Fixed Codec lockup after Caller ID on Call Waiting when not using 30ms frames. + * + * Revision 3.78 2001/01/16 19:43:09 eokerson + * Added support for Linux 2.4.x kernels. + * + * Revision 3.77 2001/01/09 04:00:52 eokerson + * Linetest will now test the line, even if it has previously succeeded. + * + * Revision 3.76 2001/01/08 19:27:00 eokerson + * Fixed problem with standard cable on Internet PhoneCARD. + * + * Revision 3.75 2000/12/22 16:52:14 eokerson + * Modified to allow hookstate detection on the POTS port when the PSTN port is selected. + * + * Revision 3.74 2000/12/08 22:41:50 eokerson + * Added capability for G729B. + * + * Revision 3.73 2000/12/07 23:35:16 eokerson + * Added capability to have different ring pattern before CallerID data. + * Added hookstate checks in CallerID routines to stop FSK. + * + * Revision 3.72 2000/12/06 19:31:31 eokerson + * Modified signal behavior to only send one signal per event. + * + * Revision 3.71 2000/12/06 03:23:08 eokerson + * Fixed CallerID on Call Waiting. + * + * Revision 3.70 2000/12/04 21:29:37 eokerson + * Added checking to Smart Cable gain functions. + * + * Revision 3.69 2000/12/04 21:05:20 eokerson + * Changed ixjdebug levels. + * Added ioctls to change gains in Internet Phone CARD Smart Cable. + * + * Revision 3.68 2000/12/04 00:17:21 craigs + * Changed mixer voice gain to +6dB rather than 0dB + * + * Revision 3.67 2000/11/30 21:25:51 eokerson + * Fixed write signal errors. + * + * Revision 3.66 2000/11/29 22:42:44 eokerson + * Fixed PSTN ring detect problems. + * + * Revision 3.65 2000/11/29 07:31:55 craigs + * Added new 425Hz filter co-efficients + * Added card-specific DTMF prescaler initialisation + * + * Revision 3.64 2000/11/28 14:03:32 craigs + * Changed certain mixer initialisations to be 0dB rather than 12dB + * Added additional information to /proc/ixj + * + * Revision 3.63 2000/11/28 11:38:41 craigs + * Added display of AEC modes in AUTO and AGC mode + * + * Revision 3.62 2000/11/28 04:05:44 eokerson + * Improved PSTN ring detection routine. + * + * Revision 3.61 2000/11/27 21:53:12 eokerson + * Fixed flash detection. + * + * Revision 3.60 2000/11/27 15:57:29 eokerson + * More work on G.729 load routines. + * + * Revision 3.59 2000/11/25 21:55:12 eokerson + * Fixed errors in G.729 load routine. + * + * Revision 3.58 2000/11/25 04:08:29 eokerson + * Added board locks around G.729 and TS85 load routines. + * + * Revision 3.57 2000/11/24 05:35:17 craigs + * Added ability to retrieve mixer values on LineJACK + * Added complete initialisation of all mixer values at startup + * Fixed spelling mistake + * + * Revision 3.56 2000/11/23 02:52:11 robertj + * Added cvs change log keyword. + * Fixed bug in capabilities list when using G.729 module. + * + */ + +#include "ixj-ver.h" + +#define PERFMON_STATS +#define IXJDEBUG 0 +#define MAXRINGS 5 + +#include + +#include +#include +#include /* printk() */ +#include /* everything... */ +#include /* error codes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "ixj.h" + +#define TYPE(inode) (iminor(inode) >> 4) +#define NUM(inode) (iminor(inode) & 0xf) + +static DEFINE_MUTEX(ixj_mutex); +static int ixjdebug; +static int hertz = HZ; +static int samplerate = 100; + +module_param(ixjdebug, int, 0); + +static DEFINE_PCI_DEVICE_TABLE(ixj_pci_tbl) = { + { PCI_VENDOR_ID_QUICKNET, PCI_DEVICE_ID_QUICKNET_XJ, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { } +}; +MODULE_DEVICE_TABLE(pci, ixj_pci_tbl); + +/************************************************************************ +* +* ixjdebug meanings are now bit mapped instead of level based +* Values can be or'ed together to turn on multiple messages +* +* bit 0 (0x0001) = any failure +* bit 1 (0x0002) = general messages +* bit 2 (0x0004) = POTS ringing related +* bit 3 (0x0008) = PSTN events +* bit 4 (0x0010) = PSTN Cadence state details +* bit 5 (0x0020) = Tone detection triggers +* bit 6 (0x0040) = Tone detection cadence details +* bit 7 (0x0080) = ioctl tracking +* bit 8 (0x0100) = signal tracking +* bit 9 (0x0200) = CallerID generation details +* +************************************************************************/ + +#ifdef IXJ_DYN_ALLOC + +static IXJ *ixj[IXJMAX]; +#define get_ixj(b) ixj[(b)] + +/* + * Allocate a free IXJ device + */ + +static IXJ *ixj_alloc() +{ + for(cnt=0; cntDSPbase) + { + j = kmalloc(sizeof(IXJ), GFP_KERNEL); + if (j == NULL) + return NULL; + ixj[cnt] = j; + return j; + } + } + return NULL; +} + +static void ixj_fsk_free(IXJ *j) +{ + kfree(j->fskdata); + j->fskdata = NULL; +} + +static void ixj_fsk_alloc(IXJ *j) +{ + if(!j->fskdata) { + j->fskdata = kmalloc(8000, GFP_KERNEL); + if (!j->fskdata) { + if(ixjdebug & 0x0200) { + printk("IXJ phone%d - allocate failed\n", j->board); + } + return; + } else { + j->fsksize = 8000; + if(ixjdebug & 0x0200) { + printk("IXJ phone%d - allocate succeeded\n", j->board); + } + } + } +} + +#else + +static IXJ ixj[IXJMAX]; +#define get_ixj(b) (&ixj[(b)]) + +/* + * Allocate a free IXJ device + */ + +static IXJ *ixj_alloc(void) +{ + int cnt; + for(cnt=0; cntfsksize = 8000; +} + +#endif + +#ifdef PERFMON_STATS +#define ixj_perfmon(x) ((x)++) +#else +#define ixj_perfmon(x) do { } while(0) +#endif + +static int ixj_convert_loaded; + +static int ixj_WriteDSPCommand(unsigned short, IXJ *j); + +/************************************************************************ +* +* These are function definitions to allow external modules to register +* enhanced functionality call backs. +* +************************************************************************/ + +static int Stub(IXJ * J, unsigned long arg) +{ + return 0; +} + +static IXJ_REGFUNC ixj_PreRead = &Stub; +static IXJ_REGFUNC ixj_PostRead = &Stub; +static IXJ_REGFUNC ixj_PreWrite = &Stub; +static IXJ_REGFUNC ixj_PostWrite = &Stub; + +static void ixj_read_frame(IXJ *j); +static void ixj_write_frame(IXJ *j); +static void ixj_init_timer(IXJ *j); +static void ixj_add_timer(IXJ * j); +static void ixj_timeout(unsigned long ptr); +static int read_filters(IXJ *j); +static int LineMonitor(IXJ *j); +static int ixj_fasync(int fd, struct file *, int mode); +static int ixj_set_port(IXJ *j, int arg); +static int ixj_set_pots(IXJ *j, int arg); +static int ixj_hookstate(IXJ *j); +static int ixj_record_start(IXJ *j); +static void ixj_record_stop(IXJ *j); +static void set_rec_volume(IXJ *j, int volume); +static int get_rec_volume(IXJ *j); +static int set_rec_codec(IXJ *j, int rate); +static void ixj_vad(IXJ *j, int arg); +static int ixj_play_start(IXJ *j); +static void ixj_play_stop(IXJ *j); +static int ixj_set_tone_on(unsigned short arg, IXJ *j); +static int ixj_set_tone_off(unsigned short, IXJ *j); +static int ixj_play_tone(IXJ *j, char tone); +static void ixj_aec_start(IXJ *j, int level); +static int idle(IXJ *j); +static void ixj_ring_on(IXJ *j); +static void ixj_ring_off(IXJ *j); +static void aec_stop(IXJ *j); +static void ixj_ringback(IXJ *j); +static void ixj_busytone(IXJ *j); +static void ixj_dialtone(IXJ *j); +static void ixj_cpt_stop(IXJ *j); +static char daa_int_read(IXJ *j); +static char daa_CR_read(IXJ *j, int cr); +static int daa_set_mode(IXJ *j, int mode); +static int ixj_linetest(IXJ *j); +static int ixj_daa_write(IXJ *j); +static int ixj_daa_cid_read(IXJ *j); +static void DAA_Coeff_US(IXJ *j); +static void DAA_Coeff_UK(IXJ *j); +static void DAA_Coeff_France(IXJ *j); +static void DAA_Coeff_Germany(IXJ *j); +static void DAA_Coeff_Australia(IXJ *j); +static void DAA_Coeff_Japan(IXJ *j); +static int ixj_init_filter(IXJ *j, IXJ_FILTER * jf); +static int ixj_init_filter_raw(IXJ *j, IXJ_FILTER_RAW * jfr); +static int ixj_init_tone(IXJ *j, IXJ_TONE * ti); +static int ixj_build_cadence(IXJ *j, IXJ_CADENCE __user * cp); +static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE __user * cp); +/* Serial Control Interface funtions */ +static int SCI_Control(IXJ *j, int control); +static int SCI_Prepare(IXJ *j); +static int SCI_WaitHighSCI(IXJ *j); +static int SCI_WaitLowSCI(IXJ *j); +static DWORD PCIEE_GetSerialNumber(WORD wAddress); +static int ixj_PCcontrol_wait(IXJ *j); +static void ixj_pre_cid(IXJ *j); +static void ixj_write_cid(IXJ *j); +static void ixj_write_cid_bit(IXJ *j, int bit); +static int set_base_frame(IXJ *j, int size); +static int set_play_codec(IXJ *j, int rate); +static void set_rec_depth(IXJ *j, int depth); +static int ixj_mixer(long val, IXJ *j); + +/************************************************************************ +CT8020/CT8021 Host Programmers Model +Host address Function Access +DSPbase + +0-1 Aux Software Status Register (reserved) Read Only +2-3 Software Status Register Read Only +4-5 Aux Software Control Register (reserved) Read Write +6-7 Software Control Register Read Write +8-9 Hardware Status Register Read Only +A-B Hardware Control Register Read Write +C-D Host Transmit (Write) Data Buffer Access Port (buffer input)Write Only +E-F Host Receive (Read) Data Buffer Access Port (buffer input) Read Only +************************************************************************/ + +static inline void ixj_read_HSR(IXJ *j) +{ + j->hsr.bytes.low = inb_p(j->DSPbase + 8); + j->hsr.bytes.high = inb_p(j->DSPbase + 9); +} + +static inline int IsControlReady(IXJ *j) +{ + ixj_read_HSR(j); + return j->hsr.bits.controlrdy ? 1 : 0; +} + +static inline int IsPCControlReady(IXJ *j) +{ + j->pccr1.byte = inb_p(j->XILINXbase + 3); + return j->pccr1.bits.crr ? 1 : 0; +} + +static inline int IsStatusReady(IXJ *j) +{ + ixj_read_HSR(j); + return j->hsr.bits.statusrdy ? 1 : 0; +} + +static inline int IsRxReady(IXJ *j) +{ + ixj_read_HSR(j); + ixj_perfmon(j->rxreadycheck); + return j->hsr.bits.rxrdy ? 1 : 0; +} + +static inline int IsTxReady(IXJ *j) +{ + ixj_read_HSR(j); + ixj_perfmon(j->txreadycheck); + return j->hsr.bits.txrdy ? 1 : 0; +} + +static inline void set_play_volume(IXJ *j, int volume) +{ + if (ixjdebug & 0x0002) + printk(KERN_INFO "IXJ: /dev/phone%d Setting Play Volume to 0x%4.4x\n", j->board, volume); + ixj_WriteDSPCommand(0xCF02, j); + ixj_WriteDSPCommand(volume, j); +} + +static int set_play_volume_linear(IXJ *j, int volume) +{ + int newvolume, dspplaymax; + + if (ixjdebug & 0x0002) + printk(KERN_INFO "IXJ: /dev/phone %d Setting Linear Play Volume to 0x%4.4x\n", j->board, volume); + if(volume > 100 || volume < 0) { + return -1; + } + + /* This should normalize the perceived volumes between the different cards caused by differences in the hardware */ + switch (j->cardtype) { + case QTI_PHONEJACK: + dspplaymax = 0x380; + break; + case QTI_LINEJACK: + if(j->port == PORT_PSTN) { + dspplaymax = 0x48; + } else { + dspplaymax = 0x100; + } + break; + case QTI_PHONEJACK_LITE: + dspplaymax = 0x380; + break; + case QTI_PHONEJACK_PCI: + dspplaymax = 0x6C; + break; + case QTI_PHONECARD: + dspplaymax = 0x50; + break; + default: + return -1; + } + newvolume = (dspplaymax * volume) / 100; + set_play_volume(j, newvolume); + return 0; +} + +static inline void set_play_depth(IXJ *j, int depth) +{ + if (depth > 60) + depth = 60; + if (depth < 0) + depth = 0; + ixj_WriteDSPCommand(0x5280 + depth, j); +} + +static inline int get_play_volume(IXJ *j) +{ + ixj_WriteDSPCommand(0xCF00, j); + return j->ssr.high << 8 | j->ssr.low; +} + +static int get_play_volume_linear(IXJ *j) +{ + int volume, newvolume, dspplaymax; + + /* This should normalize the perceived volumes between the different cards caused by differences in the hardware */ + switch (j->cardtype) { + case QTI_PHONEJACK: + dspplaymax = 0x380; + break; + case QTI_LINEJACK: + if(j->port == PORT_PSTN) { + dspplaymax = 0x48; + } else { + dspplaymax = 0x100; + } + break; + case QTI_PHONEJACK_LITE: + dspplaymax = 0x380; + break; + case QTI_PHONEJACK_PCI: + dspplaymax = 0x6C; + break; + case QTI_PHONECARD: + dspplaymax = 100; + break; + default: + return -1; + } + volume = get_play_volume(j); + newvolume = (volume * 100) / dspplaymax; + if(newvolume > 100) + newvolume = 100; + return newvolume; +} + +static inline BYTE SLIC_GetState(IXJ *j) +{ + if (j->cardtype == QTI_PHONECARD) { + j->pccr1.byte = 0; + j->psccr.bits.dev = 3; + j->psccr.bits.rw = 1; + outw_p(j->psccr.byte << 8, j->XILINXbase + 0x00); + ixj_PCcontrol_wait(j); + j->pslic.byte = inw_p(j->XILINXbase + 0x00) & 0xFF; + ixj_PCcontrol_wait(j); + if (j->pslic.bits.powerdown) + return PLD_SLIC_STATE_OC; + else if (!j->pslic.bits.ring0 && !j->pslic.bits.ring1) + return PLD_SLIC_STATE_ACTIVE; + else + return PLD_SLIC_STATE_RINGING; + } else { + j->pld_slicr.byte = inb_p(j->XILINXbase + 0x01); + } + return j->pld_slicr.bits.state; +} + +static bool SLIC_SetState(BYTE byState, IXJ *j) +{ + bool fRetVal = false; + + if (j->cardtype == QTI_PHONECARD) { + if (j->flags.pcmciasct) { + switch (byState) { + case PLD_SLIC_STATE_TIPOPEN: + case PLD_SLIC_STATE_OC: + j->pslic.bits.powerdown = 1; + j->pslic.bits.ring0 = j->pslic.bits.ring1 = 0; + fRetVal = true; + break; + case PLD_SLIC_STATE_RINGING: + if (j->readers || j->writers) { + j->pslic.bits.powerdown = 0; + j->pslic.bits.ring0 = 1; + j->pslic.bits.ring1 = 0; + fRetVal = true; + } + break; + case PLD_SLIC_STATE_OHT: /* On-hook transmit */ + + case PLD_SLIC_STATE_STANDBY: + case PLD_SLIC_STATE_ACTIVE: + if (j->readers || j->writers) { + j->pslic.bits.powerdown = 0; + } else { + j->pslic.bits.powerdown = 1; + } + j->pslic.bits.ring0 = j->pslic.bits.ring1 = 0; + fRetVal = true; + break; + case PLD_SLIC_STATE_APR: /* Active polarity reversal */ + + case PLD_SLIC_STATE_OHTPR: /* OHT polarity reversal */ + + default: + fRetVal = false; + break; + } + j->psccr.bits.dev = 3; + j->psccr.bits.rw = 0; + outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00); + ixj_PCcontrol_wait(j); + } + } else { + /* Set the C1, C2, C3 & B2EN signals. */ + switch (byState) { + case PLD_SLIC_STATE_OC: + j->pld_slicw.bits.c1 = 0; + j->pld_slicw.bits.c2 = 0; + j->pld_slicw.bits.c3 = 0; + j->pld_slicw.bits.b2en = 0; + outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); + fRetVal = true; + break; + case PLD_SLIC_STATE_RINGING: + j->pld_slicw.bits.c1 = 1; + j->pld_slicw.bits.c2 = 0; + j->pld_slicw.bits.c3 = 0; + j->pld_slicw.bits.b2en = 1; + outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); + fRetVal = true; + break; + case PLD_SLIC_STATE_ACTIVE: + j->pld_slicw.bits.c1 = 0; + j->pld_slicw.bits.c2 = 1; + j->pld_slicw.bits.c3 = 0; + j->pld_slicw.bits.b2en = 0; + outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); + fRetVal = true; + break; + case PLD_SLIC_STATE_OHT: /* On-hook transmit */ + + j->pld_slicw.bits.c1 = 1; + j->pld_slicw.bits.c2 = 1; + j->pld_slicw.bits.c3 = 0; + j->pld_slicw.bits.b2en = 0; + outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); + fRetVal = true; + break; + case PLD_SLIC_STATE_TIPOPEN: + j->pld_slicw.bits.c1 = 0; + j->pld_slicw.bits.c2 = 0; + j->pld_slicw.bits.c3 = 1; + j->pld_slicw.bits.b2en = 0; + outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); + fRetVal = true; + break; + case PLD_SLIC_STATE_STANDBY: + j->pld_slicw.bits.c1 = 1; + j->pld_slicw.bits.c2 = 0; + j->pld_slicw.bits.c3 = 1; + j->pld_slicw.bits.b2en = 1; + outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); + fRetVal = true; + break; + case PLD_SLIC_STATE_APR: /* Active polarity reversal */ + + j->pld_slicw.bits.c1 = 0; + j->pld_slicw.bits.c2 = 1; + j->pld_slicw.bits.c3 = 1; + j->pld_slicw.bits.b2en = 0; + outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); + fRetVal = true; + break; + case PLD_SLIC_STATE_OHTPR: /* OHT polarity reversal */ + + j->pld_slicw.bits.c1 = 1; + j->pld_slicw.bits.c2 = 1; + j->pld_slicw.bits.c3 = 1; + j->pld_slicw.bits.b2en = 0; + outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); + fRetVal = true; + break; + default: + fRetVal = false; + break; + } + } + + return fRetVal; +} + +static int ixj_wink(IXJ *j) +{ + BYTE slicnow; + + slicnow = SLIC_GetState(j); + + j->pots_winkstart = jiffies; + SLIC_SetState(PLD_SLIC_STATE_OC, j); + + msleep(jiffies_to_msecs(j->winktime)); + + SLIC_SetState(slicnow, j); + return 0; +} + +static void ixj_init_timer(IXJ *j) +{ + init_timer(&j->timer); + j->timer.function = ixj_timeout; + j->timer.data = (unsigned long)j; +} + +static void ixj_add_timer(IXJ *j) +{ + j->timer.expires = jiffies + (hertz / samplerate); + add_timer(&j->timer); +} + +static void ixj_tone_timeout(IXJ *j) +{ + IXJ_TONE ti; + + j->tone_state++; + if (j->tone_state == 3) { + j->tone_state = 0; + if (j->cadence_t) { + j->tone_cadence_state++; + if (j->tone_cadence_state >= j->cadence_t->elements_used) { + switch (j->cadence_t->termination) { + case PLAY_ONCE: + ixj_cpt_stop(j); + break; + case REPEAT_LAST_ELEMENT: + j->tone_cadence_state--; + ixj_play_tone(j, j->cadence_t->ce[j->tone_cadence_state].index); + break; + case REPEAT_ALL: + j->tone_cadence_state = 0; + if (j->cadence_t->ce[j->tone_cadence_state].freq0) { + ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index; + ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0; + ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0; + ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1; + ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1; + ixj_init_tone(j, &ti); + } + ixj_set_tone_on(j->cadence_t->ce[0].tone_on_time, j); + ixj_set_tone_off(j->cadence_t->ce[0].tone_off_time, j); + ixj_play_tone(j, j->cadence_t->ce[0].index); + break; + } + } else { + if (j->cadence_t->ce[j->tone_cadence_state].gain0) { + ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index; + ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0; + ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0; + ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1; + ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1; + ixj_init_tone(j, &ti); + } + ixj_set_tone_on(j->cadence_t->ce[j->tone_cadence_state].tone_on_time, j); + ixj_set_tone_off(j->cadence_t->ce[j->tone_cadence_state].tone_off_time, j); + ixj_play_tone(j, j->cadence_t->ce[j->tone_cadence_state].index); + } + } + } +} + +static inline void ixj_kill_fasync(IXJ *j, IXJ_SIGEVENT event, int dir) +{ + if(j->ixj_signals[event]) { + if(ixjdebug & 0x0100) + printk("Sending signal for event %d\n", event); + /* Send apps notice of change */ + /* see config.h for macro definition */ + kill_fasync(&(j->async_queue), j->ixj_signals[event], dir); + } +} + +static void ixj_pstn_state(IXJ *j) +{ + int var; + union XOPXR0 XR0, daaint; + + var = 10; + + XR0.reg = j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg; + daaint.reg = 0; + XR0.bitreg.RMR = j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR; + + j->pld_scrr.byte = inb_p(j->XILINXbase); + if (j->pld_scrr.bits.daaflag) { + daa_int_read(j); + if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.RING) { + if(time_after(jiffies, j->pstn_sleeptil) && !(j->flags.pots_pstn && j->hookstate)) { + daaint.bitreg.RING = 1; + if(ixjdebug & 0x0008) { + printk(KERN_INFO "IXJ DAA Ring Interrupt /dev/phone%d at %ld\n", j->board, jiffies); + } + } else { + daa_set_mode(j, SOP_PU_RESET); + } + } + if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Caller_ID) { + daaint.bitreg.Caller_ID = 1; + j->pstn_cid_intr = 1; + j->pstn_cid_received = jiffies; + if(ixjdebug & 0x0008) { + printk(KERN_INFO "IXJ DAA Caller_ID Interrupt /dev/phone%d at %ld\n", j->board, jiffies); + } + } + if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Cadence) { + daaint.bitreg.Cadence = 1; + if(ixjdebug & 0x0008) { + printk(KERN_INFO "IXJ DAA Cadence Interrupt /dev/phone%d at %ld\n", j->board, jiffies); + } + } + if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK != XR0.bitreg.VDD_OK) { + daaint.bitreg.VDD_OK = 1; + daaint.bitreg.SI_0 = j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK; + } + } + daa_CR_read(j, 1); + if(j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR != XR0.bitreg.RMR && time_after(jiffies, j->pstn_sleeptil) && !(j->flags.pots_pstn && j->hookstate)) { + daaint.bitreg.RMR = 1; + daaint.bitreg.SI_1 = j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR; + if(ixjdebug & 0x0008) { + printk(KERN_INFO "IXJ DAA RMR /dev/phone%d was %s for %ld\n", j->board, XR0.bitreg.RMR?"on":"off", jiffies - j->pstn_last_rmr); + } + j->pstn_prev_rmr = j->pstn_last_rmr; + j->pstn_last_rmr = jiffies; + } + switch(j->daa_mode) { + case SOP_PU_SLEEP: + if (daaint.bitreg.RING) { + if (!j->flags.pstn_ringing) { + if (j->daa_mode != SOP_PU_RINGING) { + j->pstn_ring_int = jiffies; + daa_set_mode(j, SOP_PU_RINGING); + } + } + } + break; + case SOP_PU_RINGING: + if (daaint.bitreg.RMR) { + if (ixjdebug & 0x0008) { + printk(KERN_INFO "IXJ Ring Cadence a state = %d /dev/phone%d at %ld\n", j->cadence_f[4].state, j->board, jiffies); + } + if (daaint.bitreg.SI_1) { /* Rising edge of RMR */ + j->flags.pstn_rmr = 1; + j->pstn_ring_start = jiffies; + j->pstn_ring_stop = 0; + j->ex.bits.pstn_ring = 0; + if (j->cadence_f[4].state == 0) { + j->cadence_f[4].state = 1; + j->cadence_f[4].on1min = jiffies + (long)((j->cadence_f[4].on1 * hertz * (100 - var)) / 10000); + j->cadence_f[4].on1dot = jiffies + (long)((j->cadence_f[4].on1 * hertz * (100)) / 10000); + j->cadence_f[4].on1max = jiffies + (long)((j->cadence_f[4].on1 * hertz * (100 + var)) / 10000); + } else if (j->cadence_f[4].state == 2) { + if((time_after(jiffies, j->cadence_f[4].off1min) && + time_before(jiffies, j->cadence_f[4].off1max))) { + if (j->cadence_f[4].on2) { + j->cadence_f[4].state = 3; + j->cadence_f[4].on2min = jiffies + (long)((j->cadence_f[4].on2 * (hertz * (100 - var)) / 10000)); + j->cadence_f[4].on2dot = jiffies + (long)((j->cadence_f[4].on2 * (hertz * (100)) / 10000)); + j->cadence_f[4].on2max = jiffies + (long)((j->cadence_f[4].on2 * (hertz * (100 + var)) / 10000)); + } else { + j->cadence_f[4].state = 7; + } + } else { + if (ixjdebug & 0x0008) { + printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n", + j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr, + j->cadence_f[4].off1); + } + j->cadence_f[4].state = 0; + } + } else if (j->cadence_f[4].state == 4) { + if((time_after(jiffies, j->cadence_f[4].off2min) && + time_before(jiffies, j->cadence_f[4].off2max))) { + if (j->cadence_f[4].on3) { + j->cadence_f[4].state = 5; + j->cadence_f[4].on3min = jiffies + (long)((j->cadence_f[4].on3 * (hertz * (100 - var)) / 10000)); + j->cadence_f[4].on3dot = jiffies + (long)((j->cadence_f[4].on3 * (hertz * (100)) / 10000)); + j->cadence_f[4].on3max = jiffies + (long)((j->cadence_f[4].on3 * (hertz * (100 + var)) / 10000)); + } else { + j->cadence_f[4].state = 7; + } + } else { + if (ixjdebug & 0x0008) { + printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n", + j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr, + j->cadence_f[4].off2); + } + j->cadence_f[4].state = 0; + } + } else if (j->cadence_f[4].state == 6) { + if((time_after(jiffies, j->cadence_f[4].off3min) && + time_before(jiffies, j->cadence_f[4].off3max))) { + j->cadence_f[4].state = 7; + } else { + if (ixjdebug & 0x0008) { + printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n", + j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr, + j->cadence_f[4].off3); + } + j->cadence_f[4].state = 0; + } + } else { + j->cadence_f[4].state = 0; + } + } else { /* Falling edge of RMR */ + j->pstn_ring_start = 0; + j->pstn_ring_stop = jiffies; + if (j->cadence_f[4].state == 1) { + if(!j->cadence_f[4].on1) { + j->cadence_f[4].state = 7; + } else if((time_after(jiffies, j->cadence_f[4].on1min) && + time_before(jiffies, j->cadence_f[4].on1max))) { + if (j->cadence_f[4].off1) { + j->cadence_f[4].state = 2; + j->cadence_f[4].off1min = jiffies + (long)((j->cadence_f[4].off1 * (hertz * (100 - var)) / 10000)); + j->cadence_f[4].off1dot = jiffies + (long)((j->cadence_f[4].off1 * (hertz * (100)) / 10000)); + j->cadence_f[4].off1max = jiffies + (long)((j->cadence_f[4].off1 * (hertz * (100 + var)) / 10000)); + } else { + j->cadence_f[4].state = 7; + } + } else { + if (ixjdebug & 0x0008) { + printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n", + j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr, + j->cadence_f[4].on1); + } + j->cadence_f[4].state = 0; + } + } else if (j->cadence_f[4].state == 3) { + if((time_after(jiffies, j->cadence_f[4].on2min) && + time_before(jiffies, j->cadence_f[4].on2max))) { + if (j->cadence_f[4].off2) { + j->cadence_f[4].state = 4; + j->cadence_f[4].off2min = jiffies + (long)((j->cadence_f[4].off2 * (hertz * (100 - var)) / 10000)); + j->cadence_f[4].off2dot = jiffies + (long)((j->cadence_f[4].off2 * (hertz * (100)) / 10000)); + j->cadence_f[4].off2max = jiffies + (long)((j->cadence_f[4].off2 * (hertz * (100 + var)) / 10000)); + } else { + j->cadence_f[4].state = 7; + } + } else { + if (ixjdebug & 0x0008) { + printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n", + j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr, + j->cadence_f[4].on2); + } + j->cadence_f[4].state = 0; + } + } else if (j->cadence_f[4].state == 5) { + if((time_after(jiffies, j->cadence_f[4].on3min) && + time_before(jiffies, j->cadence_f[4].on3max))) { + if (j->cadence_f[4].off3) { + j->cadence_f[4].state = 6; + j->cadence_f[4].off3min = jiffies + (long)((j->cadence_f[4].off3 * (hertz * (100 - var)) / 10000)); + j->cadence_f[4].off3dot = jiffies + (long)((j->cadence_f[4].off3 * (hertz * (100)) / 10000)); + j->cadence_f[4].off3max = jiffies + (long)((j->cadence_f[4].off3 * (hertz * (100 + var)) / 10000)); + } else { + j->cadence_f[4].state = 7; + } + } else { + j->cadence_f[4].state = 0; + } + } else { + if (ixjdebug & 0x0008) { + printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n", + j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr, + j->cadence_f[4].on3); + } + j->cadence_f[4].state = 0; + } + } + if (ixjdebug & 0x0010) { + printk(KERN_INFO "IXJ Ring Cadence b state = %d /dev/phone%d at %ld\n", j->cadence_f[4].state, j->board, jiffies); + } + if (ixjdebug & 0x0010) { + switch(j->cadence_f[4].state) { + case 1: + printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board, + j->cadence_f[4].on1, j->cadence_f[4].on1min, j->cadence_f[4].on1dot, j->cadence_f[4].on1max); + break; + case 2: + printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board, + j->cadence_f[4].off1, j->cadence_f[4].off1min, j->cadence_f[4].off1dot, j->cadence_f[4].off1max); + break; + case 3: + printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board, + j->cadence_f[4].on2, j->cadence_f[4].on2min, j->cadence_f[4].on2dot, j->cadence_f[4].on2max); + break; + case 4: + printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board, + j->cadence_f[4].off2, j->cadence_f[4].off2min, j->cadence_f[4].off2dot, j->cadence_f[4].off2max); + break; + case 5: + printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board, + j->cadence_f[4].on3, j->cadence_f[4].on3min, j->cadence_f[4].on3dot, j->cadence_f[4].on3max); + break; + case 6: + printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board, + j->cadence_f[4].off3, j->cadence_f[4].off3min, j->cadence_f[4].off3dot, j->cadence_f[4].off3max); + break; + } + } + } + if (j->cadence_f[4].state == 7) { + j->cadence_f[4].state = 0; + j->pstn_ring_stop = jiffies; + j->ex.bits.pstn_ring = 1; + ixj_kill_fasync(j, SIG_PSTN_RING, POLL_IN); + if(ixjdebug & 0x0008) { + printk(KERN_INFO "IXJ Ring int set /dev/phone%d at %ld\n", j->board, jiffies); + } + } + if((j->pstn_ring_int != 0 && time_after(jiffies, j->pstn_ring_int + (hertz * 5)) && !j->flags.pstn_rmr) || + (j->pstn_ring_stop != 0 && time_after(jiffies, j->pstn_ring_stop + (hertz * 5)))) { + if(ixjdebug & 0x0008) { + printk("IXJ DAA no ring in 5 seconds /dev/phone%d at %ld\n", j->board, jiffies); + printk("IXJ DAA pstn ring int /dev/phone%d at %ld\n", j->board, j->pstn_ring_int); + printk("IXJ DAA pstn ring stop /dev/phone%d at %ld\n", j->board, j->pstn_ring_stop); + } + j->pstn_ring_stop = j->pstn_ring_int = 0; + daa_set_mode(j, SOP_PU_SLEEP); + } + outb_p(j->pld_scrw.byte, j->XILINXbase); + if (j->pstn_cid_intr && time_after(jiffies, j->pstn_cid_received + hertz)) { + ixj_daa_cid_read(j); + j->ex.bits.caller_id = 1; + ixj_kill_fasync(j, SIG_CALLER_ID, POLL_IN); + j->pstn_cid_intr = 0; + } + if (daaint.bitreg.Cadence) { + if(ixjdebug & 0x0008) { + printk("IXJ DAA Cadence interrupt going to sleep /dev/phone%d\n", j->board); + } + daa_set_mode(j, SOP_PU_SLEEP); + j->ex.bits.pstn_ring = 0; + } + break; + case SOP_PU_CONVERSATION: + if (daaint.bitreg.VDD_OK) { + if(!daaint.bitreg.SI_0) { + if (!j->pstn_winkstart) { + if(ixjdebug & 0x0008) { + printk("IXJ DAA possible wink /dev/phone%d %ld\n", j->board, jiffies); + } + j->pstn_winkstart = jiffies; + } + } else { + if (j->pstn_winkstart) { + if(ixjdebug & 0x0008) { + printk("IXJ DAA possible wink end /dev/phone%d %ld\n", j->board, jiffies); + } + j->pstn_winkstart = 0; + } + } + } + if (j->pstn_winkstart && time_after(jiffies, j->pstn_winkstart + ((hertz * j->winktime) / 1000))) { + if(ixjdebug & 0x0008) { + printk("IXJ DAA wink detected going to sleep /dev/phone%d %ld\n", j->board, jiffies); + } + daa_set_mode(j, SOP_PU_SLEEP); + j->pstn_winkstart = 0; + j->ex.bits.pstn_wink = 1; + ixj_kill_fasync(j, SIG_PSTN_WINK, POLL_IN); + } + break; + } +} + +static void ixj_timeout(unsigned long ptr) +{ + int board; + unsigned long jifon; + IXJ *j = (IXJ *)ptr; + board = j->board; + + if (j->DSPbase && atomic_read(&j->DSPWrite) == 0 && test_and_set_bit(board, (void *)&j->busyflags) == 0) { + ixj_perfmon(j->timerchecks); + j->hookstate = ixj_hookstate(j); + if (j->tone_state) { + if (!(j->hookstate)) { + ixj_cpt_stop(j); + if (j->m_hook) { + j->m_hook = 0; + j->ex.bits.hookstate = 1; + ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN); + } + clear_bit(board, &j->busyflags); + ixj_add_timer(j); + return; + } + if (j->tone_state == 1) + jifon = ((hertz * j->tone_on_time) * 25 / 100000); + else + jifon = ((hertz * j->tone_on_time) * 25 / 100000) + ((hertz * j->tone_off_time) * 25 / 100000); + if (time_before(jiffies, j->tone_start_jif + jifon)) { + if (j->tone_state == 1) { + ixj_play_tone(j, j->tone_index); + if (j->dsp.low == 0x20) { + clear_bit(board, &j->busyflags); + ixj_add_timer(j); + return; + } + } else { + ixj_play_tone(j, 0); + if (j->dsp.low == 0x20) { + clear_bit(board, &j->busyflags); + ixj_add_timer(j); + return; + } + } + } else { + ixj_tone_timeout(j); + if (j->flags.dialtone) { + ixj_dialtone(j); + } + if (j->flags.busytone) { + ixj_busytone(j); + if (j->dsp.low == 0x20) { + clear_bit(board, &j->busyflags); + ixj_add_timer(j); + return; + } + } + if (j->flags.ringback) { + ixj_ringback(j); + if (j->dsp.low == 0x20) { + clear_bit(board, &j->busyflags); + ixj_add_timer(j); + return; + } + } + if (!j->tone_state) { + ixj_cpt_stop(j); + } + } + } + if (!(j->tone_state && j->dsp.low == 0x20)) { + if (IsRxReady(j)) { + ixj_read_frame(j); + } + if (IsTxReady(j)) { + ixj_write_frame(j); + } + } + if (j->flags.cringing) { + if (j->hookstate & 1) { + j->flags.cringing = 0; + ixj_ring_off(j); + } else if(j->cadence_f[5].enable && ((!j->cadence_f[5].en_filter) || (j->cadence_f[5].en_filter && j->flags.firstring))) { + switch(j->cadence_f[5].state) { + case 0: + j->cadence_f[5].on1dot = jiffies + (long)((j->cadence_f[5].on1 * (hertz * 100) / 10000)); + if (time_before(jiffies, j->cadence_f[5].on1dot)) { + if(ixjdebug & 0x0004) { + printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies); + } + ixj_ring_on(j); + } + j->cadence_f[5].state = 1; + break; + case 1: + if (time_after(jiffies, j->cadence_f[5].on1dot)) { + j->cadence_f[5].off1dot = jiffies + (long)((j->cadence_f[5].off1 * (hertz * 100) / 10000)); + if(ixjdebug & 0x0004) { + printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies); + } + ixj_ring_off(j); + j->cadence_f[5].state = 2; + } + break; + case 2: + if (time_after(jiffies, j->cadence_f[5].off1dot)) { + if(ixjdebug & 0x0004) { + printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies); + } + ixj_ring_on(j); + if (j->cadence_f[5].on2) { + j->cadence_f[5].on2dot = jiffies + (long)((j->cadence_f[5].on2 * (hertz * 100) / 10000)); + j->cadence_f[5].state = 3; + } else { + j->cadence_f[5].state = 7; + } + } + break; + case 3: + if (time_after(jiffies, j->cadence_f[5].on2dot)) { + if(ixjdebug & 0x0004) { + printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies); + } + ixj_ring_off(j); + if (j->cadence_f[5].off2) { + j->cadence_f[5].off2dot = jiffies + (long)((j->cadence_f[5].off2 * (hertz * 100) / 10000)); + j->cadence_f[5].state = 4; + } else { + j->cadence_f[5].state = 7; + } + } + break; + case 4: + if (time_after(jiffies, j->cadence_f[5].off2dot)) { + if(ixjdebug & 0x0004) { + printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies); + } + ixj_ring_on(j); + if (j->cadence_f[5].on3) { + j->cadence_f[5].on3dot = jiffies + (long)((j->cadence_f[5].on3 * (hertz * 100) / 10000)); + j->cadence_f[5].state = 5; + } else { + j->cadence_f[5].state = 7; + } + } + break; + case 5: + if (time_after(jiffies, j->cadence_f[5].on3dot)) { + if(ixjdebug & 0x0004) { + printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies); + } + ixj_ring_off(j); + if (j->cadence_f[5].off3) { + j->cadence_f[5].off3dot = jiffies + (long)((j->cadence_f[5].off3 * (hertz * 100) / 10000)); + j->cadence_f[5].state = 6; + } else { + j->cadence_f[5].state = 7; + } + } + break; + case 6: + if (time_after(jiffies, j->cadence_f[5].off3dot)) { + if(ixjdebug & 0x0004) { + printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies); + } + j->cadence_f[5].state = 7; + } + break; + case 7: + if(ixjdebug & 0x0004) { + printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies); + } + j->flags.cidring = 1; + j->cadence_f[5].state = 0; + break; + } + if (j->flags.cidring && !j->flags.cidsent) { + j->flags.cidsent = 1; + if(j->fskdcnt) { + SLIC_SetState(PLD_SLIC_STATE_OHT, j); + ixj_pre_cid(j); + } + j->flags.cidring = 0; + } + clear_bit(board, &j->busyflags); + ixj_add_timer(j); + return; + } else { + if (time_after(jiffies, j->ring_cadence_jif + (hertz / 2))) { + if (j->flags.cidring && !j->flags.cidsent) { + j->flags.cidsent = 1; + if(j->fskdcnt) { + SLIC_SetState(PLD_SLIC_STATE_OHT, j); + ixj_pre_cid(j); + } + j->flags.cidring = 0; + } + j->ring_cadence_t--; + if (j->ring_cadence_t == -1) + j->ring_cadence_t = 15; + j->ring_cadence_jif = jiffies; + + if (j->ring_cadence & 1 << j->ring_cadence_t) { + if(j->flags.cidsent && j->cadence_f[5].en_filter) + j->flags.firstring = 1; + else + ixj_ring_on(j); + } else { + ixj_ring_off(j); + if(!j->flags.cidsent) + j->flags.cidring = 1; + } + } + clear_bit(board, &j->busyflags); + ixj_add_timer(j); + return; + } + } + if (!j->flags.ringing) { + if (j->hookstate) { /* & 1) { */ + if (j->dsp.low != 0x20 && + SLIC_GetState(j) != PLD_SLIC_STATE_ACTIVE) { + SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); + } + LineMonitor(j); + read_filters(j); + ixj_WriteDSPCommand(0x511B, j); + j->proc_load = j->ssr.high << 8 | j->ssr.low; + if (!j->m_hook && (j->hookstate & 1)) { + j->m_hook = j->ex.bits.hookstate = 1; + ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN); + } + } else { + if (j->ex.bits.dtmf_ready) { + j->dtmf_wp = j->dtmf_rp = j->ex.bits.dtmf_ready = 0; + } + if (j->m_hook) { + j->m_hook = 0; + j->ex.bits.hookstate = 1; + ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN); + } + } + } + if (j->cardtype == QTI_LINEJACK && !j->flags.pstncheck && j->flags.pstn_present) { + ixj_pstn_state(j); + } + if (j->ex.bytes) { + wake_up_interruptible(&j->poll_q); /* Wake any blocked selects */ + } + clear_bit(board, &j->busyflags); + } + ixj_add_timer(j); +} + +static int ixj_status_wait(IXJ *j) +{ + unsigned long jif; + + jif = jiffies + ((60 * hertz) / 100); + while (!IsStatusReady(j)) { + ixj_perfmon(j->statuswait); + if (time_after(jiffies, jif)) { + ixj_perfmon(j->statuswaitfail); + return -1; + } + } + return 0; +} + +static int ixj_PCcontrol_wait(IXJ *j) +{ + unsigned long jif; + + jif = jiffies + ((60 * hertz) / 100); + while (!IsPCControlReady(j)) { + ixj_perfmon(j->pcontrolwait); + if (time_after(jiffies, jif)) { + ixj_perfmon(j->pcontrolwaitfail); + return -1; + } + } + return 0; +} + +static int ixj_WriteDSPCommand(unsigned short cmd, IXJ *j) +{ + BYTES bytes; + unsigned long jif; + + atomic_inc(&j->DSPWrite); + if(atomic_read(&j->DSPWrite) > 1) { + printk("IXJ %d DSP write overlap attempting command 0x%4.4x\n", j->board, cmd); + return -1; + } + bytes.high = (cmd & 0xFF00) >> 8; + bytes.low = cmd & 0x00FF; + jif = jiffies + ((60 * hertz) / 100); + while (!IsControlReady(j)) { + ixj_perfmon(j->iscontrolready); + if (time_after(jiffies, jif)) { + ixj_perfmon(j->iscontrolreadyfail); + atomic_dec(&j->DSPWrite); + if(atomic_read(&j->DSPWrite) > 0) { + printk("IXJ %d DSP overlaped command 0x%4.4x during control ready failure.\n", j->board, cmd); + while(atomic_read(&j->DSPWrite) > 0) { + atomic_dec(&j->DSPWrite); + } + } + return -1; + } + } + outb(bytes.low, j->DSPbase + 6); + outb(bytes.high, j->DSPbase + 7); + + if (ixj_status_wait(j)) { + j->ssr.low = 0xFF; + j->ssr.high = 0xFF; + atomic_dec(&j->DSPWrite); + if(atomic_read(&j->DSPWrite) > 0) { + printk("IXJ %d DSP overlaped command 0x%4.4x during status wait failure.\n", j->board, cmd); + while(atomic_read(&j->DSPWrite) > 0) { + atomic_dec(&j->DSPWrite); + } + } + return -1; + } +/* Read Software Status Register */ + j->ssr.low = inb_p(j->DSPbase + 2); + j->ssr.high = inb_p(j->DSPbase + 3); + atomic_dec(&j->DSPWrite); + if(atomic_read(&j->DSPWrite) > 0) { + printk("IXJ %d DSP overlaped command 0x%4.4x\n", j->board, cmd); + while(atomic_read(&j->DSPWrite) > 0) { + atomic_dec(&j->DSPWrite); + } + } + return 0; +} + +/*************************************************************************** +* +* General Purpose IO Register read routine +* +***************************************************************************/ +static inline int ixj_gpio_read(IXJ *j) +{ + if (ixj_WriteDSPCommand(0x5143, j)) + return -1; + + j->gpio.bytes.low = j->ssr.low; + j->gpio.bytes.high = j->ssr.high; + + return 0; +} + +static inline void LED_SetState(int state, IXJ *j) +{ + if (j->cardtype == QTI_LINEJACK) { + j->pld_scrw.bits.led1 = state & 0x1 ? 1 : 0; + j->pld_scrw.bits.led2 = state & 0x2 ? 1 : 0; + j->pld_scrw.bits.led3 = state & 0x4 ? 1 : 0; + j->pld_scrw.bits.led4 = state & 0x8 ? 1 : 0; + + outb(j->pld_scrw.byte, j->XILINXbase); + } +} + +/********************************************************************* +* GPIO Pins are configured as follows on the Quicknet Internet +* PhoneJACK Telephony Cards +* +* POTS Select GPIO_6=0 GPIO_7=0 +* Mic/Speaker Select GPIO_6=0 GPIO_7=1 +* Handset Select GPIO_6=1 GPIO_7=0 +* +* SLIC Active GPIO_1=0 GPIO_2=1 GPIO_5=0 +* SLIC Ringing GPIO_1=1 GPIO_2=1 GPIO_5=0 +* SLIC Open Circuit GPIO_1=0 GPIO_2=0 GPIO_5=0 +* +* Hook Switch changes reported on GPIO_3 +*********************************************************************/ +static int ixj_set_port(IXJ *j, int arg) +{ + if (j->cardtype == QTI_PHONEJACK_LITE) { + if (arg != PORT_POTS) + return 10; + else + return 0; + } + switch (arg) { + case PORT_POTS: + j->port = PORT_POTS; + switch (j->cardtype) { + case QTI_PHONECARD: + if (j->flags.pcmciasct == 1) + SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); + else + return 11; + break; + case QTI_PHONEJACK_PCI: + j->pld_slicw.pcib.mic = 0; + j->pld_slicw.pcib.spk = 0; + outb(j->pld_slicw.byte, j->XILINXbase + 0x01); + break; + case QTI_LINEJACK: + ixj_set_pots(j, 0); /* Disconnect POTS/PSTN relay */ + if (ixj_WriteDSPCommand(0xC528, j)) /* Write CODEC config to + Software Control Register */ + return 2; + j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ + + outb(j->pld_scrw.byte, j->XILINXbase); + j->pld_clock.byte = 0; + outb(j->pld_clock.byte, j->XILINXbase + 0x04); + j->pld_slicw.bits.rly1 = 1; + j->pld_slicw.bits.spken = 0; + outb(j->pld_slicw.byte, j->XILINXbase + 0x01); + ixj_mixer(0x1200, j); /* Turn Off MIC switch on mixer left */ + ixj_mixer(0x1401, j); /* Turn On Mono1 switch on mixer left */ + ixj_mixer(0x1300, j); /* Turn Off MIC switch on mixer right */ + ixj_mixer(0x1501, j); /* Turn On Mono1 switch on mixer right */ + ixj_mixer(0x0E80, j); /*Mic mute */ + ixj_mixer(0x0F00, j); /* Set mono out (SLIC) to 0dB */ + ixj_mixer(0x0080, j); /* Mute Master Left volume */ + ixj_mixer(0x0180, j); /* Mute Master Right volume */ + SLIC_SetState(PLD_SLIC_STATE_STANDBY, j); +/* SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); */ + break; + case QTI_PHONEJACK: + j->gpio.bytes.high = 0x0B; + j->gpio.bits.gpio6 = 0; + j->gpio.bits.gpio7 = 0; + ixj_WriteDSPCommand(j->gpio.word, j); + break; + } + break; + case PORT_PSTN: + if (j->cardtype == QTI_LINEJACK) { + ixj_WriteDSPCommand(0xC534, j); /* Write CODEC config to Software Control Register */ + + j->pld_slicw.bits.rly3 = 0; + j->pld_slicw.bits.rly1 = 1; + j->pld_slicw.bits.spken = 0; + outb(j->pld_slicw.byte, j->XILINXbase + 0x01); + j->port = PORT_PSTN; + } else { + return 4; + } + break; + case PORT_SPEAKER: + j->port = PORT_SPEAKER; + switch (j->cardtype) { + case QTI_PHONECARD: + if (j->flags.pcmciasct) { + SLIC_SetState(PLD_SLIC_STATE_OC, j); + } + break; + case QTI_PHONEJACK_PCI: + j->pld_slicw.pcib.mic = 1; + j->pld_slicw.pcib.spk = 1; + outb(j->pld_slicw.byte, j->XILINXbase + 0x01); + break; + case QTI_LINEJACK: + ixj_set_pots(j, 0); /* Disconnect POTS/PSTN relay */ + if (ixj_WriteDSPCommand(0xC528, j)) /* Write CODEC config to + Software Control Register */ + return 2; + j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ + + outb(j->pld_scrw.byte, j->XILINXbase); + j->pld_clock.byte = 0; + outb(j->pld_clock.byte, j->XILINXbase + 0x04); + j->pld_slicw.bits.rly1 = 1; + j->pld_slicw.bits.spken = 1; + outb(j->pld_slicw.byte, j->XILINXbase + 0x01); + ixj_mixer(0x1201, j); /* Turn On MIC switch on mixer left */ + ixj_mixer(0x1400, j); /* Turn Off Mono1 switch on mixer left */ + ixj_mixer(0x1301, j); /* Turn On MIC switch on mixer right */ + ixj_mixer(0x1500, j); /* Turn Off Mono1 switch on mixer right */ + ixj_mixer(0x0E06, j); /*Mic un-mute 0dB */ + ixj_mixer(0x0F80, j); /* Mute mono out (SLIC) */ + ixj_mixer(0x0000, j); /* Set Master Left volume to 0dB */ + ixj_mixer(0x0100, j); /* Set Master Right volume to 0dB */ + break; + case QTI_PHONEJACK: + j->gpio.bytes.high = 0x0B; + j->gpio.bits.gpio6 = 0; + j->gpio.bits.gpio7 = 1; + ixj_WriteDSPCommand(j->gpio.word, j); + break; + } + break; + case PORT_HANDSET: + if (j->cardtype != QTI_PHONEJACK) { + return 5; + } else { + j->gpio.bytes.high = 0x0B; + j->gpio.bits.gpio6 = 1; + j->gpio.bits.gpio7 = 0; + ixj_WriteDSPCommand(j->gpio.word, j); + j->port = PORT_HANDSET; + } + break; + default: + return 6; + break; + } + return 0; +} + +static int ixj_set_pots(IXJ *j, int arg) +{ + if (j->cardtype == QTI_LINEJACK) { + if (arg) { + if (j->port == PORT_PSTN) { + j->pld_slicw.bits.rly1 = 0; + outb(j->pld_slicw.byte, j->XILINXbase + 0x01); + j->flags.pots_pstn = 1; + return 1; + } else { + j->flags.pots_pstn = 0; + return 0; + } + } else { + j->pld_slicw.bits.rly1 = 1; + outb(j->pld_slicw.byte, j->XILINXbase + 0x01); + j->flags.pots_pstn = 0; + return 1; + } + } else { + return 0; + } +} + +static void ixj_ring_on(IXJ *j) +{ + if (j->dsp.low == 0x20) /* Internet PhoneJACK */ + { + if (ixjdebug & 0x0004) + printk(KERN_INFO "IXJ Ring On /dev/phone%d\n", j->board); + + j->gpio.bytes.high = 0x0B; + j->gpio.bytes.low = 0x00; + j->gpio.bits.gpio1 = 1; + j->gpio.bits.gpio2 = 1; + j->gpio.bits.gpio5 = 0; + ixj_WriteDSPCommand(j->gpio.word, j); /* send the ring signal */ + } else /* Internet LineJACK, Internet PhoneJACK Lite or Internet PhoneJACK PCI */ + { + if (ixjdebug & 0x0004) + printk(KERN_INFO "IXJ Ring On /dev/phone%d\n", j->board); + + SLIC_SetState(PLD_SLIC_STATE_RINGING, j); + } +} + +static int ixj_siadc(IXJ *j, int val) +{ + if(j->cardtype == QTI_PHONECARD){ + if(j->flags.pcmciascp){ + if(val == -1) + return j->siadc.bits.rxg; + + if(val < 0 || val > 0x1F) + return -1; + + j->siadc.bits.hom = 0; /* Handset Out Mute */ + j->siadc.bits.lom = 0; /* Line Out Mute */ + j->siadc.bits.rxg = val; /*(0xC000 - 0x41C8) / 0x4EF; RX PGA Gain */ + j->psccr.bits.addr = 6; /* R/W Smart Cable Register Address */ + j->psccr.bits.rw = 0; /* Read / Write flag */ + j->psccr.bits.dev = 0; + outb(j->siadc.byte, j->XILINXbase + 0x00); + outb(j->psccr.byte, j->XILINXbase + 0x01); + ixj_PCcontrol_wait(j); + return j->siadc.bits.rxg; + } + } + return -1; +} + +static int ixj_sidac(IXJ *j, int val) +{ + if(j->cardtype == QTI_PHONECARD){ + if(j->flags.pcmciascp){ + if(val == -1) + return j->sidac.bits.txg; + + if(val < 0 || val > 0x1F) + return -1; + + j->sidac.bits.srm = 1; /* Speaker Right Mute */ + j->sidac.bits.slm = 1; /* Speaker Left Mute */ + j->sidac.bits.txg = val; /* (0xC000 - 0x45E4) / 0x5D3; TX PGA Gain */ + j->psccr.bits.addr = 7; /* R/W Smart Cable Register Address */ + j->psccr.bits.rw = 0; /* Read / Write flag */ + j->psccr.bits.dev = 0; + outb(j->sidac.byte, j->XILINXbase + 0x00); + outb(j->psccr.byte, j->XILINXbase + 0x01); + ixj_PCcontrol_wait(j); + return j->sidac.bits.txg; + } + } + return -1; +} + +static int ixj_pcmcia_cable_check(IXJ *j) +{ + j->pccr1.byte = inb_p(j->XILINXbase + 0x03); + if (!j->flags.pcmciastate) { + j->pccr2.byte = inb_p(j->XILINXbase + 0x02); + if (j->pccr1.bits.drf || j->pccr2.bits.rstc) { + j->flags.pcmciastate = 4; + return 0; + } + if (j->pccr1.bits.ed) { + j->pccr1.bits.ed = 0; + j->psccr.bits.dev = 3; + j->psccr.bits.rw = 1; + outw_p(j->psccr.byte << 8, j->XILINXbase + 0x00); + ixj_PCcontrol_wait(j); + j->pslic.byte = inw_p(j->XILINXbase + 0x00) & 0xFF; + j->pslic.bits.led2 = j->pslic.bits.det ? 1 : 0; + j->psccr.bits.dev = 3; + j->psccr.bits.rw = 0; + outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00); + ixj_PCcontrol_wait(j); + return j->pslic.bits.led2 ? 1 : 0; + } else if (j->flags.pcmciasct) { + return j->r_hook; + } else { + return 1; + } + } else if (j->flags.pcmciastate == 4) { + if (!j->pccr1.bits.drf) { + j->flags.pcmciastate = 3; + } + return 0; + } else if (j->flags.pcmciastate == 3) { + j->pccr2.bits.pwr = 0; + j->pccr2.bits.rstc = 1; + outb(j->pccr2.byte, j->XILINXbase + 0x02); + j->checkwait = jiffies + (hertz * 2); + j->flags.incheck = 1; + j->flags.pcmciastate = 2; + return 0; + } else if (j->flags.pcmciastate == 2) { + if (j->flags.incheck) { + if (time_before(jiffies, j->checkwait)) { + return 0; + } else { + j->flags.incheck = 0; + } + } + j->pccr2.bits.pwr = 0; + j->pccr2.bits.rstc = 0; + outb_p(j->pccr2.byte, j->XILINXbase + 0x02); + j->flags.pcmciastate = 1; + return 0; + } else if (j->flags.pcmciastate == 1) { + j->flags.pcmciastate = 0; + if (!j->pccr1.bits.drf) { + j->psccr.bits.dev = 3; + j->psccr.bits.rw = 1; + outb_p(j->psccr.byte, j->XILINXbase + 0x01); + ixj_PCcontrol_wait(j); + j->flags.pcmciascp = 1; /* Set Cable Present Flag */ + + j->flags.pcmciasct = (inw_p(j->XILINXbase + 0x00) >> 8) & 0x03; /* Get Cable Type */ + + if (j->flags.pcmciasct == 3) { + j->flags.pcmciastate = 4; + return 0; + } else if (j->flags.pcmciasct == 0) { + j->pccr2.bits.pwr = 1; + j->pccr2.bits.rstc = 0; + outb_p(j->pccr2.byte, j->XILINXbase + 0x02); + j->port = PORT_SPEAKER; + } else { + j->port = PORT_POTS; + } + j->sic1.bits.cpd = 0; /* Chip Power Down */ + j->sic1.bits.mpd = 0; /* MIC Bias Power Down */ + j->sic1.bits.hpd = 0; /* Handset Bias Power Down */ + j->sic1.bits.lpd = 0; /* Line Bias Power Down */ + j->sic1.bits.spd = 1; /* Speaker Drive Power Down */ + j->psccr.bits.addr = 1; /* R/W Smart Cable Register Address */ + j->psccr.bits.rw = 0; /* Read / Write flag */ + j->psccr.bits.dev = 0; + outb(j->sic1.byte, j->XILINXbase + 0x00); + outb(j->psccr.byte, j->XILINXbase + 0x01); + ixj_PCcontrol_wait(j); + + j->sic2.bits.al = 0; /* Analog Loopback DAC analog -> ADC analog */ + j->sic2.bits.dl2 = 0; /* Digital Loopback DAC -> ADC one bit */ + j->sic2.bits.dl1 = 0; /* Digital Loopback ADC -> DAC one bit */ + j->sic2.bits.pll = 0; /* 1 = div 10, 0 = div 5 */ + j->sic2.bits.hpd = 0; /* HPF disable */ + j->psccr.bits.addr = 2; /* R/W Smart Cable Register Address */ + j->psccr.bits.rw = 0; /* Read / Write flag */ + j->psccr.bits.dev = 0; + outb(j->sic2.byte, j->XILINXbase + 0x00); + outb(j->psccr.byte, j->XILINXbase + 0x01); + ixj_PCcontrol_wait(j); + + j->psccr.bits.addr = 3; /* R/W Smart Cable Register Address */ + j->psccr.bits.rw = 0; /* Read / Write flag */ + j->psccr.bits.dev = 0; + outb(0x00, j->XILINXbase + 0x00); /* PLL Divide N1 */ + outb(j->psccr.byte, j->XILINXbase + 0x01); + ixj_PCcontrol_wait(j); + + j->psccr.bits.addr = 4; /* R/W Smart Cable Register Address */ + j->psccr.bits.rw = 0; /* Read / Write flag */ + j->psccr.bits.dev = 0; + outb(0x09, j->XILINXbase + 0x00); /* PLL Multiply M1 */ + outb(j->psccr.byte, j->XILINXbase + 0x01); + ixj_PCcontrol_wait(j); + + j->sirxg.bits.lig = 1; /* Line In Gain */ + j->sirxg.bits.lim = 1; /* Line In Mute */ + j->sirxg.bits.mcg = 0; /* MIC In Gain was 3 */ + j->sirxg.bits.mcm = 0; /* MIC In Mute */ + j->sirxg.bits.him = 0; /* Handset In Mute */ + j->sirxg.bits.iir = 1; /* IIR */ + j->psccr.bits.addr = 5; /* R/W Smart Cable Register Address */ + j->psccr.bits.rw = 0; /* Read / Write flag */ + j->psccr.bits.dev = 0; + outb(j->sirxg.byte, j->XILINXbase + 0x00); + outb(j->psccr.byte, j->XILINXbase + 0x01); + ixj_PCcontrol_wait(j); + + ixj_siadc(j, 0x17); + ixj_sidac(j, 0x1D); + + j->siaatt.bits.sot = 0; + j->psccr.bits.addr = 9; /* R/W Smart Cable Register Address */ + j->psccr.bits.rw = 0; /* Read / Write flag */ + j->psccr.bits.dev = 0; + outb(j->siaatt.byte, j->XILINXbase + 0x00); + outb(j->psccr.byte, j->XILINXbase + 0x01); + ixj_PCcontrol_wait(j); + + if (j->flags.pcmciasct == 1 && !j->readers && !j->writers) { + j->psccr.byte = j->pslic.byte = 0; + j->pslic.bits.powerdown = 1; + j->psccr.bits.dev = 3; + j->psccr.bits.rw = 0; + outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00); + ixj_PCcontrol_wait(j); + } + } + return 0; + } else { + j->flags.pcmciascp = 0; + return 0; + } + return 0; +} + +static int ixj_hookstate(IXJ *j) +{ + int fOffHook = 0; + + switch (j->cardtype) { + case QTI_PHONEJACK: + ixj_gpio_read(j); + fOffHook = j->gpio.bits.gpio3read ? 1 : 0; + break; + case QTI_LINEJACK: + case QTI_PHONEJACK_LITE: + case QTI_PHONEJACK_PCI: + SLIC_GetState(j); + if(j->cardtype == QTI_LINEJACK && j->flags.pots_pstn == 1 && (j->readers || j->writers)) { + fOffHook = j->pld_slicr.bits.potspstn ? 1 : 0; + if(fOffHook != j->p_hook) { + if(!j->checkwait) { + j->checkwait = jiffies; + } + if(time_before(jiffies, j->checkwait + 2)) { + fOffHook ^= 1; + } else { + j->checkwait = 0; + } + j->p_hook = fOffHook; + printk("IXJ : /dev/phone%d pots-pstn hookstate check %d at %ld\n", j->board, fOffHook, jiffies); + } + } else { + if (j->pld_slicr.bits.state == PLD_SLIC_STATE_ACTIVE || + j->pld_slicr.bits.state == PLD_SLIC_STATE_STANDBY) { + if (j->flags.ringing || j->flags.cringing) { + if (!in_interrupt()) { + msleep(20); + } + SLIC_GetState(j); + if (j->pld_slicr.bits.state == PLD_SLIC_STATE_RINGING) { + ixj_ring_on(j); + } + } + if (j->cardtype == QTI_PHONEJACK_PCI) { + j->pld_scrr.byte = inb_p(j->XILINXbase); + fOffHook = j->pld_scrr.pcib.det ? 1 : 0; + } else + fOffHook = j->pld_slicr.bits.det ? 1 : 0; + } + } + break; + case QTI_PHONECARD: + fOffHook = ixj_pcmcia_cable_check(j); + break; + } + if (j->r_hook != fOffHook) { + j->r_hook = fOffHook; + if (j->port == PORT_SPEAKER || j->port == PORT_HANDSET) { // || (j->port == PORT_PSTN && j->flags.pots_pstn == 0)) { + j->ex.bits.hookstate = 1; + ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN); + } else if (!fOffHook) { + j->flash_end = jiffies + ((60 * hertz) / 100); + } + } + if (fOffHook) { + if(time_before(jiffies, j->flash_end)) { + j->ex.bits.flash = 1; + j->flash_end = 0; + ixj_kill_fasync(j, SIG_FLASH, POLL_IN); + } + } else { + if(time_before(jiffies, j->flash_end)) { + fOffHook = 1; + } + } + + if (j->port == PORT_PSTN && j->daa_mode == SOP_PU_CONVERSATION) + fOffHook |= 2; + + if (j->port == PORT_SPEAKER) { + if(j->cardtype == QTI_PHONECARD) { + if(j->flags.pcmciascp && j->flags.pcmciasct) { + fOffHook |= 2; + } + } else { + fOffHook |= 2; + } + } + + if (j->port == PORT_HANDSET) + fOffHook |= 2; + + return fOffHook; +} + +static void ixj_ring_off(IXJ *j) +{ + if (j->dsp.low == 0x20) /* Internet PhoneJACK */ + { + if (ixjdebug & 0x0004) + printk(KERN_INFO "IXJ Ring Off\n"); + j->gpio.bytes.high = 0x0B; + j->gpio.bytes.low = 0x00; + j->gpio.bits.gpio1 = 0; + j->gpio.bits.gpio2 = 1; + j->gpio.bits.gpio5 = 0; + ixj_WriteDSPCommand(j->gpio.word, j); + } else /* Internet LineJACK */ + { + if (ixjdebug & 0x0004) + printk(KERN_INFO "IXJ Ring Off\n"); + + if(!j->flags.cidplay) + SLIC_SetState(PLD_SLIC_STATE_STANDBY, j); + + SLIC_GetState(j); + } +} + +static void ixj_ring_start(IXJ *j) +{ + j->flags.cringing = 1; + if (ixjdebug & 0x0004) + printk(KERN_INFO "IXJ Cadence Ringing Start /dev/phone%d\n", j->board); + if (ixj_hookstate(j) & 1) { + if (j->port == PORT_POTS) + ixj_ring_off(j); + j->flags.cringing = 0; + if (ixjdebug & 0x0004) + printk(KERN_INFO "IXJ Cadence Ringing Stopped /dev/phone%d off hook\n", j->board); + } else if(j->cadence_f[5].enable && (!j->cadence_f[5].en_filter)) { + j->ring_cadence_jif = jiffies; + j->flags.cidsent = j->flags.cidring = 0; + j->cadence_f[5].state = 0; + if(j->cadence_f[5].on1) + ixj_ring_on(j); + } else { + j->ring_cadence_jif = jiffies; + j->ring_cadence_t = 15; + if (j->ring_cadence & 1 << j->ring_cadence_t) { + ixj_ring_on(j); + } else { + ixj_ring_off(j); + } + j->flags.cidsent = j->flags.cidring = j->flags.firstring = 0; + } +} + +static int ixj_ring(IXJ *j) +{ + char cntr; + unsigned long jif; + + j->flags.ringing = 1; + if (ixj_hookstate(j) & 1) { + ixj_ring_off(j); + j->flags.ringing = 0; + return 1; + } + for (cntr = 0; cntr < j->maxrings; cntr++) { + jif = jiffies + (1 * hertz); + ixj_ring_on(j); + while (time_before(jiffies, jif)) { + if (ixj_hookstate(j) & 1) { + ixj_ring_off(j); + j->flags.ringing = 0; + return 1; + } + schedule_timeout_interruptible(1); + if (signal_pending(current)) + break; + } + jif = jiffies + (3 * hertz); + ixj_ring_off(j); + while (time_before(jiffies, jif)) { + if (ixj_hookstate(j) & 1) { + msleep(10); + if (ixj_hookstate(j) & 1) { + j->flags.ringing = 0; + return 1; + } + } + schedule_timeout_interruptible(1); + if (signal_pending(current)) + break; + } + } + ixj_ring_off(j); + j->flags.ringing = 0; + return 0; +} + +static int ixj_open(struct phone_device *p, struct file *file_p) +{ + IXJ *j = get_ixj(p->board); + file_p->private_data = j; + + if (!j->DSPbase) + return -ENODEV; + + if (file_p->f_mode & FMODE_READ) { + if(!j->readers) { + j->readers++; + } else { + return -EBUSY; + } + } + + if (file_p->f_mode & FMODE_WRITE) { + if(!j->writers) { + j->writers++; + } else { + if (file_p->f_mode & FMODE_READ){ + j->readers--; + } + return -EBUSY; + } + } + + if (j->cardtype == QTI_PHONECARD) { + j->pslic.bits.powerdown = 0; + j->psccr.bits.dev = 3; + j->psccr.bits.rw = 0; + outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00); + ixj_PCcontrol_wait(j); + } + + j->flags.cidplay = 0; + j->flags.cidcw_ack = 0; + + if (ixjdebug & 0x0002) + printk(KERN_INFO "Opening board %d\n", p->board); + + j->framesread = j->frameswritten = 0; + return 0; +} + +static int ixj_release(struct inode *inode, struct file *file_p) +{ + IXJ_TONE ti; + int cnt; + IXJ *j = file_p->private_data; + int board = j->p.board; + + /* + * Set up locks to ensure that only one process is talking to the DSP at a time. + * This is necessary to keep the DSP from locking up. + */ + while(test_and_set_bit(board, (void *)&j->busyflags) != 0) + schedule_timeout_interruptible(1); + if (ixjdebug & 0x0002) + printk(KERN_INFO "Closing board %d\n", NUM(inode)); + + if (j->cardtype == QTI_PHONECARD) + ixj_set_port(j, PORT_SPEAKER); + else + ixj_set_port(j, PORT_POTS); + + aec_stop(j); + ixj_play_stop(j); + ixj_record_stop(j); + set_play_volume(j, 0x100); + set_rec_volume(j, 0x100); + ixj_ring_off(j); + + /* Restore the tone table to default settings. */ + ti.tone_index = 10; + ti.gain0 = 1; + ti.freq0 = hz941; + ti.gain1 = 0; + ti.freq1 = hz1209; + ixj_init_tone(j, &ti); + ti.tone_index = 11; + ti.gain0 = 1; + ti.freq0 = hz941; + ti.gain1 = 0; + ti.freq1 = hz1336; + ixj_init_tone(j, &ti); + ti.tone_index = 12; + ti.gain0 = 1; + ti.freq0 = hz941; + ti.gain1 = 0; + ti.freq1 = hz1477; + ixj_init_tone(j, &ti); + ti.tone_index = 13; + ti.gain0 = 1; + ti.freq0 = hz800; + ti.gain1 = 0; + ti.freq1 = 0; + ixj_init_tone(j, &ti); + ti.tone_index = 14; + ti.gain0 = 1; + ti.freq0 = hz1000; + ti.gain1 = 0; + ti.freq1 = 0; + ixj_init_tone(j, &ti); + ti.tone_index = 15; + ti.gain0 = 1; + ti.freq0 = hz1250; + ti.gain1 = 0; + ti.freq1 = 0; + ixj_init_tone(j, &ti); + ti.tone_index = 16; + ti.gain0 = 1; + ti.freq0 = hz950; + ti.gain1 = 0; + ti.freq1 = 0; + ixj_init_tone(j, &ti); + ti.tone_index = 17; + ti.gain0 = 1; + ti.freq0 = hz1100; + ti.gain1 = 0; + ti.freq1 = 0; + ixj_init_tone(j, &ti); + ti.tone_index = 18; + ti.gain0 = 1; + ti.freq0 = hz1400; + ti.gain1 = 0; + ti.freq1 = 0; + ixj_init_tone(j, &ti); + ti.tone_index = 19; + ti.gain0 = 1; + ti.freq0 = hz1500; + ti.gain1 = 0; + ti.freq1 = 0; + ixj_init_tone(j, &ti); + ti.tone_index = 20; + ti.gain0 = 1; + ti.freq0 = hz1600; + ti.gain1 = 0; + ti.freq1 = 0; + ixj_init_tone(j, &ti); + ti.tone_index = 21; + ti.gain0 = 1; + ti.freq0 = hz1800; + ti.gain1 = 0; + ti.freq1 = 0; + ixj_init_tone(j, &ti); + ti.tone_index = 22; + ti.gain0 = 1; + ti.freq0 = hz2100; + ti.gain1 = 0; + ti.freq1 = 0; + ixj_init_tone(j, &ti); + ti.tone_index = 23; + ti.gain0 = 1; + ti.freq0 = hz1300; + ti.gain1 = 0; + ti.freq1 = 0; + ixj_init_tone(j, &ti); + ti.tone_index = 24; + ti.gain0 = 1; + ti.freq0 = hz2450; + ti.gain1 = 0; + ti.freq1 = 0; + ixj_init_tone(j, &ti); + ti.tone_index = 25; + ti.gain0 = 1; + ti.freq0 = hz350; + ti.gain1 = 0; + ti.freq1 = hz440; + ixj_init_tone(j, &ti); + ti.tone_index = 26; + ti.gain0 = 1; + ti.freq0 = hz440; + ti.gain1 = 0; + ti.freq1 = hz480; + ixj_init_tone(j, &ti); + ti.tone_index = 27; + ti.gain0 = 1; + ti.freq0 = hz480; + ti.gain1 = 0; + ti.freq1 = hz620; + ixj_init_tone(j, &ti); + + set_rec_depth(j, 2); /* Set Record Channel Limit to 2 frames */ + + set_play_depth(j, 2); /* Set Playback Channel Limit to 2 frames */ + + j->ex.bits.dtmf_ready = 0; + j->dtmf_state = 0; + j->dtmf_wp = j->dtmf_rp = 0; + j->rec_mode = j->play_mode = -1; + j->flags.ringing = 0; + j->maxrings = MAXRINGS; + j->ring_cadence = USA_RING_CADENCE; + if(j->cadence_f[5].enable) { + j->cadence_f[5].enable = j->cadence_f[5].en_filter = j->cadence_f[5].state = 0; + } + j->drybuffer = 0; + j->winktime = 320; + j->flags.dtmf_oob = 0; + for (cnt = 0; cnt < 4; cnt++) + j->cadence_f[cnt].enable = 0; + + idle(j); + + if(j->cardtype == QTI_PHONECARD) { + SLIC_SetState(PLD_SLIC_STATE_OC, j); + } + + if (file_p->f_mode & FMODE_READ) + j->readers--; + if (file_p->f_mode & FMODE_WRITE) + j->writers--; + + if (j->read_buffer && !j->readers) { + kfree(j->read_buffer); + j->read_buffer = NULL; + j->read_buffer_size = 0; + } + if (j->write_buffer && !j->writers) { + kfree(j->write_buffer); + j->write_buffer = NULL; + j->write_buffer_size = 0; + } + j->rec_codec = j->play_codec = 0; + j->rec_frame_size = j->play_frame_size = 0; + j->flags.cidsent = j->flags.cidring = 0; + + if(j->cardtype == QTI_LINEJACK && !j->readers && !j->writers) { + ixj_set_port(j, PORT_PSTN); + daa_set_mode(j, SOP_PU_SLEEP); + ixj_set_pots(j, 1); + } + ixj_WriteDSPCommand(0x0FE3, j); /* Put the DSP in 1/5 power mode. */ + + /* Set up the default signals for events */ + for (cnt = 0; cnt < 35; cnt++) + j->ixj_signals[cnt] = SIGIO; + + /* Set the excetion signal enable flags */ + j->ex_sig.bits.dtmf_ready = j->ex_sig.bits.hookstate = j->ex_sig.bits.flash = j->ex_sig.bits.pstn_ring = + j->ex_sig.bits.caller_id = j->ex_sig.bits.pstn_wink = j->ex_sig.bits.f0 = j->ex_sig.bits.f1 = j->ex_sig.bits.f2 = + j->ex_sig.bits.f3 = j->ex_sig.bits.fc0 = j->ex_sig.bits.fc1 = j->ex_sig.bits.fc2 = j->ex_sig.bits.fc3 = 1; + + file_p->private_data = NULL; + clear_bit(board, &j->busyflags); + return 0; +} + +static int read_filters(IXJ *j) +{ + unsigned short fc, cnt, trg; + int var; + + trg = 0; + if (ixj_WriteDSPCommand(0x5144, j)) { + if(ixjdebug & 0x0001) { + printk(KERN_INFO "Read Frame Counter failed!\n"); + } + return -1; + } + fc = j->ssr.high << 8 | j->ssr.low; + if (fc == j->frame_count) + return 1; + + j->frame_count = fc; + + if (j->dtmf_proc) + return 1; + + var = 10; + + for (cnt = 0; cnt < 4; cnt++) { + if (ixj_WriteDSPCommand(0x5154 + cnt, j)) { + if(ixjdebug & 0x0001) { + printk(KERN_INFO "Select Filter %d failed!\n", cnt); + } + return -1; + } + if (ixj_WriteDSPCommand(0x515C, j)) { + if(ixjdebug & 0x0001) { + printk(KERN_INFO "Read Filter History %d failed!\n", cnt); + } + return -1; + } + j->filter_hist[cnt] = j->ssr.high << 8 | j->ssr.low; + + if (j->cadence_f[cnt].enable) { + if (j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12)) { + if (j->cadence_f[cnt].state == 0) { + j->cadence_f[cnt].state = 1; + j->cadence_f[cnt].on1min = jiffies + (long)((j->cadence_f[cnt].on1 * (hertz * (100 - var)) / 10000)); + j->cadence_f[cnt].on1dot = jiffies + (long)((j->cadence_f[cnt].on1 * (hertz * (100)) / 10000)); + j->cadence_f[cnt].on1max = jiffies + (long)((j->cadence_f[cnt].on1 * (hertz * (100 + var)) / 10000)); + } else if (j->cadence_f[cnt].state == 2 && + (time_after(jiffies, j->cadence_f[cnt].off1min) && + time_before(jiffies, j->cadence_f[cnt].off1max))) { + if (j->cadence_f[cnt].on2) { + j->cadence_f[cnt].state = 3; + j->cadence_f[cnt].on2min = jiffies + (long)((j->cadence_f[cnt].on2 * (hertz * (100 - var)) / 10000)); + j->cadence_f[cnt].on2dot = jiffies + (long)((j->cadence_f[cnt].on2 * (hertz * (100)) / 10000)); + j->cadence_f[cnt].on2max = jiffies + (long)((j->cadence_f[cnt].on2 * (hertz * (100 + var)) / 10000)); + } else { + j->cadence_f[cnt].state = 7; + } + } else if (j->cadence_f[cnt].state == 4 && + (time_after(jiffies, j->cadence_f[cnt].off2min) && + time_before(jiffies, j->cadence_f[cnt].off2max))) { + if (j->cadence_f[cnt].on3) { + j->cadence_f[cnt].state = 5; + j->cadence_f[cnt].on3min = jiffies + (long)((j->cadence_f[cnt].on3 * (hertz * (100 - var)) / 10000)); + j->cadence_f[cnt].on3dot = jiffies + (long)((j->cadence_f[cnt].on3 * (hertz * (100)) / 10000)); + j->cadence_f[cnt].on3max = jiffies + (long)((j->cadence_f[cnt].on3 * (hertz * (100 + var)) / 10000)); + } else { + j->cadence_f[cnt].state = 7; + } + } else { + j->cadence_f[cnt].state = 0; + } + } else if (j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3)) { + if (j->cadence_f[cnt].state == 1) { + if(!j->cadence_f[cnt].on1) { + j->cadence_f[cnt].state = 7; + } else if((time_after(jiffies, j->cadence_f[cnt].on1min) && + time_before(jiffies, j->cadence_f[cnt].on1max))) { + if(j->cadence_f[cnt].off1) { + j->cadence_f[cnt].state = 2; + j->cadence_f[cnt].off1min = jiffies + (long)((j->cadence_f[cnt].off1 * (hertz * (100 - var)) / 10000)); + j->cadence_f[cnt].off1dot = jiffies + (long)((j->cadence_f[cnt].off1 * (hertz * (100)) / 10000)); + j->cadence_f[cnt].off1max = jiffies + (long)((j->cadence_f[cnt].off1 * (hertz * (100 + var)) / 10000)); + } else { + j->cadence_f[cnt].state = 7; + } + } else { + j->cadence_f[cnt].state = 0; + } + } else if (j->cadence_f[cnt].state == 3) { + if((time_after(jiffies, j->cadence_f[cnt].on2min) && + time_before(jiffies, j->cadence_f[cnt].on2max))) { + if(j->cadence_f[cnt].off2) { + j->cadence_f[cnt].state = 4; + j->cadence_f[cnt].off2min = jiffies + (long)((j->cadence_f[cnt].off2 * (hertz * (100 - var)) / 10000)); + j->cadence_f[cnt].off2dot = jiffies + (long)((j->cadence_f[cnt].off2 * (hertz * (100)) / 10000)); + j->cadence_f[cnt].off2max = jiffies + (long)((j->cadence_f[cnt].off2 * (hertz * (100 + var)) / 10000)); + } else { + j->cadence_f[cnt].state = 7; + } + } else { + j->cadence_f[cnt].state = 0; + } + } else if (j->cadence_f[cnt].state == 5) { + if ((time_after(jiffies, j->cadence_f[cnt].on3min) && + time_before(jiffies, j->cadence_f[cnt].on3max))) { + if(j->cadence_f[cnt].off3) { + j->cadence_f[cnt].state = 6; + j->cadence_f[cnt].off3min = jiffies + (long)((j->cadence_f[cnt].off3 * (hertz * (100 - var)) / 10000)); + j->cadence_f[cnt].off3dot = jiffies + (long)((j->cadence_f[cnt].off3 * (hertz * (100)) / 10000)); + j->cadence_f[cnt].off3max = jiffies + (long)((j->cadence_f[cnt].off3 * (hertz * (100 + var)) / 10000)); + } else { + j->cadence_f[cnt].state = 7; + } + } else { + j->cadence_f[cnt].state = 0; + } + } else { + j->cadence_f[cnt].state = 0; + } + } else { + switch(j->cadence_f[cnt].state) { + case 1: + if(time_after(jiffies, j->cadence_f[cnt].on1dot) && + !j->cadence_f[cnt].off1 && + !j->cadence_f[cnt].on2 && !j->cadence_f[cnt].off2 && + !j->cadence_f[cnt].on3 && !j->cadence_f[cnt].off3) { + j->cadence_f[cnt].state = 7; + } + break; + case 3: + if(time_after(jiffies, j->cadence_f[cnt].on2dot) && + !j->cadence_f[cnt].off2 && + !j->cadence_f[cnt].on3 && !j->cadence_f[cnt].off3) { + j->cadence_f[cnt].state = 7; + } + break; + case 5: + if(time_after(jiffies, j->cadence_f[cnt].on3dot) && + !j->cadence_f[cnt].off3) { + j->cadence_f[cnt].state = 7; + } + break; + } + } + + if (ixjdebug & 0x0040) { + printk(KERN_INFO "IXJ Tone Cadence state = %d /dev/phone%d at %ld\n", j->cadence_f[cnt].state, j->board, jiffies); + switch(j->cadence_f[cnt].state) { + case 0: + printk(KERN_INFO "IXJ /dev/phone%d No Tone detected\n", j->board); + break; + case 1: + printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %u %ld - %ld - %ld\n", j->board, + j->cadence_f[cnt].on1, j->cadence_f[cnt].on1min, j->cadence_f[cnt].on1dot, j->cadence_f[cnt].on1max); + break; + case 2: + printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off1min, + j->cadence_f[cnt].off1max); + break; + case 3: + printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].on2min, + j->cadence_f[cnt].on2max); + break; + case 4: + printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off2min, + j->cadence_f[cnt].off2max); + break; + case 5: + printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].on3min, + j->cadence_f[cnt].on3max); + break; + case 6: + printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off3min, + j->cadence_f[cnt].off3max); + break; + } + } + } + if (j->cadence_f[cnt].state == 7) { + j->cadence_f[cnt].state = 0; + if (j->cadence_f[cnt].enable == 1) + j->cadence_f[cnt].enable = 0; + switch (cnt) { + case 0: + if(ixjdebug & 0x0020) { + printk(KERN_INFO "Filter Cadence 0 triggered %ld\n", jiffies); + } + j->ex.bits.fc0 = 1; + ixj_kill_fasync(j, SIG_FC0, POLL_IN); + break; + case 1: + if(ixjdebug & 0x0020) { + printk(KERN_INFO "Filter Cadence 1 triggered %ld\n", jiffies); + } + j->ex.bits.fc1 = 1; + ixj_kill_fasync(j, SIG_FC1, POLL_IN); + break; + case 2: + if(ixjdebug & 0x0020) { + printk(KERN_INFO "Filter Cadence 2 triggered %ld\n", jiffies); + } + j->ex.bits.fc2 = 1; + ixj_kill_fasync(j, SIG_FC2, POLL_IN); + break; + case 3: + if(ixjdebug & 0x0020) { + printk(KERN_INFO "Filter Cadence 3 triggered %ld\n", jiffies); + } + j->ex.bits.fc3 = 1; + ixj_kill_fasync(j, SIG_FC3, POLL_IN); + break; + } + } + if (j->filter_en[cnt] && ((j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12)) || + (j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3)))) { + if((j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12))) { + trg = 1; + } else if((j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3))) { + trg = 0; + } + switch (cnt) { + case 0: + if(ixjdebug & 0x0020) { + printk(KERN_INFO "Filter 0 triggered %d at %ld\n", trg, jiffies); + } + j->ex.bits.f0 = 1; + ixj_kill_fasync(j, SIG_F0, POLL_IN); + break; + case 1: + if(ixjdebug & 0x0020) { + printk(KERN_INFO "Filter 1 triggered %d at %ld\n", trg, jiffies); + } + j->ex.bits.f1 = 1; + ixj_kill_fasync(j, SIG_F1, POLL_IN); + break; + case 2: + if(ixjdebug & 0x0020) { + printk(KERN_INFO "Filter 2 triggered %d at %ld\n", trg, jiffies); + } + j->ex.bits.f2 = 1; + ixj_kill_fasync(j, SIG_F2, POLL_IN); + break; + case 3: + if(ixjdebug & 0x0020) { + printk(KERN_INFO "Filter 3 triggered %d at %ld\n", trg, jiffies); + } + j->ex.bits.f3 = 1; + ixj_kill_fasync(j, SIG_F3, POLL_IN); + break; + } + } + } + return 0; +} + +static int LineMonitor(IXJ *j) +{ + if (j->dtmf_proc) { + return -1; + } + j->dtmf_proc = 1; + + if (ixj_WriteDSPCommand(0x7000, j)) /* Line Monitor */ + return -1; + + j->dtmf.bytes.high = j->ssr.high; + j->dtmf.bytes.low = j->ssr.low; + if (!j->dtmf_state && j->dtmf.bits.dtmf_valid) { + j->dtmf_state = 1; + j->dtmf_current = j->dtmf.bits.digit; + } + if (j->dtmf_state && !j->dtmf.bits.dtmf_valid) /* && j->dtmf_wp != j->dtmf_rp) */ + { + if(!j->cidcw_wait) { + j->dtmfbuffer[j->dtmf_wp] = j->dtmf_current; + j->dtmf_wp++; + if (j->dtmf_wp == 79) + j->dtmf_wp = 0; + j->ex.bits.dtmf_ready = 1; + if(j->ex_sig.bits.dtmf_ready) { + ixj_kill_fasync(j, SIG_DTMF_READY, POLL_IN); + } + } + else if(j->dtmf_current == 0x00 || j->dtmf_current == 0x0D) { + if(ixjdebug & 0x0020) { + printk("IXJ phone%d saw CIDCW Ack DTMF %d from display at %ld\n", j->board, j->dtmf_current, jiffies); + } + j->flags.cidcw_ack = 1; + } + j->dtmf_state = 0; + } + j->dtmf_proc = 0; + + return 0; +} + +/************************************************************************ +* +* Functions to allow alaw <-> ulaw conversions. +* +************************************************************************/ + +static void ulaw2alaw(unsigned char *buff, unsigned long len) +{ + static unsigned char table_ulaw2alaw[] = + { + 0x2A, 0x2B, 0x28, 0x29, 0x2E, 0x2F, 0x2C, 0x2D, + 0x22, 0x23, 0x20, 0x21, 0x26, 0x27, 0x24, 0x25, + 0x3A, 0x3B, 0x38, 0x39, 0x3E, 0x3F, 0x3C, 0x3D, + 0x32, 0x33, 0x30, 0x31, 0x36, 0x37, 0x34, 0x35, + 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D, 0x02, + 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, 0x1A, + 0x1B, 0x18, 0x19, 0x1E, 0x1F, 0x1C, 0x1D, 0x12, + 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15, 0x6B, + 0x68, 0x69, 0x6E, 0x6F, 0x6C, 0x6D, 0x62, 0x63, + 0x60, 0x61, 0x66, 0x67, 0x64, 0x65, 0x7B, 0x79, + 0x7E, 0x7F, 0x7C, 0x7D, 0x72, 0x73, 0x70, 0x71, + 0x76, 0x77, 0x74, 0x75, 0x4B, 0x49, 0x4F, 0x4D, + 0x42, 0x43, 0x40, 0x41, 0x46, 0x47, 0x44, 0x45, + 0x5A, 0x5B, 0x58, 0x59, 0x5E, 0x5F, 0x5C, 0x5D, + 0x52, 0x52, 0x53, 0x53, 0x50, 0x50, 0x51, 0x51, + 0x56, 0x56, 0x57, 0x57, 0x54, 0x54, 0x55, 0xD5, + 0xAA, 0xAB, 0xA8, 0xA9, 0xAE, 0xAF, 0xAC, 0xAD, + 0xA2, 0xA3, 0xA0, 0xA1, 0xA6, 0xA7, 0xA4, 0xA5, + 0xBA, 0xBB, 0xB8, 0xB9, 0xBE, 0xBF, 0xBC, 0xBD, + 0xB2, 0xB3, 0xB0, 0xB1, 0xB6, 0xB7, 0xB4, 0xB5, + 0x8B, 0x88, 0x89, 0x8E, 0x8F, 0x8C, 0x8D, 0x82, + 0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85, 0x9A, + 0x9B, 0x98, 0x99, 0x9E, 0x9F, 0x9C, 0x9D, 0x92, + 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95, 0xEB, + 0xE8, 0xE9, 0xEE, 0xEF, 0xEC, 0xED, 0xE2, 0xE3, + 0xE0, 0xE1, 0xE6, 0xE7, 0xE4, 0xE5, 0xFB, 0xF9, + 0xFE, 0xFF, 0xFC, 0xFD, 0xF2, 0xF3, 0xF0, 0xF1, + 0xF6, 0xF7, 0xF4, 0xF5, 0xCB, 0xC9, 0xCF, 0xCD, + 0xC2, 0xC3, 0xC0, 0xC1, 0xC6, 0xC7, 0xC4, 0xC5, + 0xDA, 0xDB, 0xD8, 0xD9, 0xDE, 0xDF, 0xDC, 0xDD, + 0xD2, 0xD2, 0xD3, 0xD3, 0xD0, 0xD0, 0xD1, 0xD1, + 0xD6, 0xD6, 0xD7, 0xD7, 0xD4, 0xD4, 0xD5, 0xD5 + }; + + while (len--) + { + *buff = table_ulaw2alaw[*(unsigned char *)buff]; + buff++; + } +} + +static void alaw2ulaw(unsigned char *buff, unsigned long len) +{ + static unsigned char table_alaw2ulaw[] = + { + 0x29, 0x2A, 0x27, 0x28, 0x2D, 0x2E, 0x2B, 0x2C, + 0x21, 0x22, 0x1F, 0x20, 0x25, 0x26, 0x23, 0x24, + 0x39, 0x3A, 0x37, 0x38, 0x3D, 0x3E, 0x3B, 0x3C, + 0x31, 0x32, 0x2F, 0x30, 0x35, 0x36, 0x33, 0x34, + 0x0A, 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D, + 0x02, 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, + 0x1A, 0x1B, 0x18, 0x19, 0x1E, 0x1F, 0x1C, 0x1D, + 0x12, 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15, + 0x62, 0x63, 0x60, 0x61, 0x66, 0x67, 0x64, 0x65, + 0x5D, 0x5D, 0x5C, 0x5C, 0x5F, 0x5F, 0x5E, 0x5E, + 0x74, 0x76, 0x70, 0x72, 0x7C, 0x7E, 0x78, 0x7A, + 0x6A, 0x6B, 0x68, 0x69, 0x6E, 0x6F, 0x6C, 0x6D, + 0x48, 0x49, 0x46, 0x47, 0x4C, 0x4D, 0x4A, 0x4B, + 0x40, 0x41, 0x3F, 0x3F, 0x44, 0x45, 0x42, 0x43, + 0x56, 0x57, 0x54, 0x55, 0x5A, 0x5B, 0x58, 0x59, + 0x4F, 0x4F, 0x4E, 0x4E, 0x52, 0x53, 0x50, 0x51, + 0xA9, 0xAA, 0xA7, 0xA8, 0xAD, 0xAE, 0xAB, 0xAC, + 0xA1, 0xA2, 0x9F, 0xA0, 0xA5, 0xA6, 0xA3, 0xA4, + 0xB9, 0xBA, 0xB7, 0xB8, 0xBD, 0xBE, 0xBB, 0xBC, + 0xB1, 0xB2, 0xAF, 0xB0, 0xB5, 0xB6, 0xB3, 0xB4, + 0x8A, 0x8B, 0x88, 0x89, 0x8E, 0x8F, 0x8C, 0x8D, + 0x82, 0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85, + 0x9A, 0x9B, 0x98, 0x99, 0x9E, 0x9F, 0x9C, 0x9D, + 0x92, 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95, + 0xE2, 0xE3, 0xE0, 0xE1, 0xE6, 0xE7, 0xE4, 0xE5, + 0xDD, 0xDD, 0xDC, 0xDC, 0xDF, 0xDF, 0xDE, 0xDE, + 0xF4, 0xF6, 0xF0, 0xF2, 0xFC, 0xFE, 0xF8, 0xFA, + 0xEA, 0xEB, 0xE8, 0xE9, 0xEE, 0xEF, 0xEC, 0xED, + 0xC8, 0xC9, 0xC6, 0xC7, 0xCC, 0xCD, 0xCA, 0xCB, + 0xC0, 0xC1, 0xBF, 0xBF, 0xC4, 0xC5, 0xC2, 0xC3, + 0xD6, 0xD7, 0xD4, 0xD5, 0xDA, 0xDB, 0xD8, 0xD9, + 0xCF, 0xCF, 0xCE, 0xCE, 0xD2, 0xD3, 0xD0, 0xD1 + }; + + while (len--) + { + *buff = table_alaw2ulaw[*(unsigned char *)buff]; + buff++; + } +} + +static ssize_t ixj_read(struct file * file_p, char __user *buf, size_t length, loff_t * ppos) +{ + unsigned long i = *ppos; + IXJ * j = get_ixj(NUM(file_p->f_path.dentry->d_inode)); + + DECLARE_WAITQUEUE(wait, current); + + if (j->flags.inread) + return -EALREADY; + + j->flags.inread = 1; + + add_wait_queue(&j->read_q, &wait); + set_current_state(TASK_INTERRUPTIBLE); + mb(); + + while (!j->read_buffer_ready || (j->dtmf_state && j->flags.dtmf_oob)) { + ++j->read_wait; + if (file_p->f_flags & O_NONBLOCK) { + set_current_state(TASK_RUNNING); + remove_wait_queue(&j->read_q, &wait); + j->flags.inread = 0; + return -EAGAIN; + } + if (!ixj_hookstate(j)) { + set_current_state(TASK_RUNNING); + remove_wait_queue(&j->read_q, &wait); + j->flags.inread = 0; + return 0; + } + interruptible_sleep_on(&j->read_q); + if (signal_pending(current)) { + set_current_state(TASK_RUNNING); + remove_wait_queue(&j->read_q, &wait); + j->flags.inread = 0; + return -EINTR; + } + } + + remove_wait_queue(&j->read_q, &wait); + set_current_state(TASK_RUNNING); + /* Don't ever copy more than the user asks */ + if(j->rec_codec == ALAW) + ulaw2alaw(j->read_buffer, min(length, j->read_buffer_size)); + i = copy_to_user(buf, j->read_buffer, min(length, j->read_buffer_size)); + j->read_buffer_ready = 0; + if (i) { + j->flags.inread = 0; + return -EFAULT; + } else { + j->flags.inread = 0; + return min(length, j->read_buffer_size); + } +} + +static ssize_t ixj_enhanced_read(struct file * file_p, char __user *buf, size_t length, + loff_t * ppos) +{ + int pre_retval; + ssize_t read_retval = 0; + IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode)); + + pre_retval = ixj_PreRead(j, 0L); + switch (pre_retval) { + case NORMAL: + read_retval = ixj_read(file_p, buf, length, ppos); + ixj_PostRead(j, 0L); + break; + case NOPOST: + read_retval = ixj_read(file_p, buf, length, ppos); + break; + case POSTONLY: + ixj_PostRead(j, 0L); + break; + default: + read_retval = pre_retval; + } + return read_retval; +} + +static ssize_t ixj_write(struct file *file_p, const char __user *buf, size_t count, loff_t * ppos) +{ + unsigned long i = *ppos; + IXJ *j = file_p->private_data; + + DECLARE_WAITQUEUE(wait, current); + + if (j->flags.inwrite) + return -EALREADY; + + j->flags.inwrite = 1; + + add_wait_queue(&j->write_q, &wait); + set_current_state(TASK_INTERRUPTIBLE); + mb(); + + + while (!j->write_buffers_empty) { + ++j->write_wait; + if (file_p->f_flags & O_NONBLOCK) { + set_current_state(TASK_RUNNING); + remove_wait_queue(&j->write_q, &wait); + j->flags.inwrite = 0; + return -EAGAIN; + } + if (!ixj_hookstate(j)) { + set_current_state(TASK_RUNNING); + remove_wait_queue(&j->write_q, &wait); + j->flags.inwrite = 0; + return 0; + } + interruptible_sleep_on(&j->write_q); + if (signal_pending(current)) { + set_current_state(TASK_RUNNING); + remove_wait_queue(&j->write_q, &wait); + j->flags.inwrite = 0; + return -EINTR; + } + } + set_current_state(TASK_RUNNING); + remove_wait_queue(&j->write_q, &wait); + if (j->write_buffer_wp + count >= j->write_buffer_end) + j->write_buffer_wp = j->write_buffer; + i = copy_from_user(j->write_buffer_wp, buf, min(count, j->write_buffer_size)); + if (i) { + j->flags.inwrite = 0; + return -EFAULT; + } + if(j->play_codec == ALAW) + alaw2ulaw(j->write_buffer_wp, min(count, j->write_buffer_size)); + j->flags.inwrite = 0; + return min(count, j->write_buffer_size); +} + +static ssize_t ixj_enhanced_write(struct file * file_p, const char __user *buf, size_t count, loff_t * ppos) +{ + int pre_retval; + ssize_t write_retval = 0; + + IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode)); + + pre_retval = ixj_PreWrite(j, 0L); + switch (pre_retval) { + case NORMAL: + write_retval = ixj_write(file_p, buf, count, ppos); + if (write_retval > 0) { + ixj_PostWrite(j, 0L); + j->write_buffer_wp += write_retval; + j->write_buffers_empty--; + } + break; + case NOPOST: + write_retval = ixj_write(file_p, buf, count, ppos); + if (write_retval > 0) { + j->write_buffer_wp += write_retval; + j->write_buffers_empty--; + } + break; + case POSTONLY: + ixj_PostWrite(j, 0L); + break; + default: + write_retval = pre_retval; + } + return write_retval; +} + +static void ixj_read_frame(IXJ *j) +{ + int cnt, dly; + + if (j->read_buffer) { + for (cnt = 0; cnt < j->rec_frame_size * 2; cnt += 2) { + if (!(cnt % 16) && !IsRxReady(j)) { + dly = 0; + while (!IsRxReady(j)) { + if (dly++ > 5) { + dly = 0; + break; + } + udelay(10); + } + } + /* Throw away word 0 of the 8021 compressed format to get standard G.729. */ + if (j->rec_codec == G729 && (cnt == 0 || cnt == 10 || cnt == 20)) { + inb_p(j->DSPbase + 0x0E); + inb_p(j->DSPbase + 0x0F); + } + *(j->read_buffer + cnt) = inb_p(j->DSPbase + 0x0E); + *(j->read_buffer + cnt + 1) = inb_p(j->DSPbase + 0x0F); + } + ++j->framesread; + if (j->intercom != -1) { + if (IsTxReady(get_ixj(j->intercom))) { + for (cnt = 0; cnt < j->rec_frame_size * 2; cnt += 2) { + if (!(cnt % 16) && !IsTxReady(j)) { + dly = 0; + while (!IsTxReady(j)) { + if (dly++ > 5) { + dly = 0; + break; + } + udelay(10); + } + } + outb_p(*(j->read_buffer + cnt), get_ixj(j->intercom)->DSPbase + 0x0C); + outb_p(*(j->read_buffer + cnt + 1), get_ixj(j->intercom)->DSPbase + 0x0D); + } + get_ixj(j->intercom)->frameswritten++; + } + } else { + j->read_buffer_ready = 1; + wake_up_interruptible(&j->read_q); /* Wake any blocked readers */ + + wake_up_interruptible(&j->poll_q); /* Wake any blocked selects */ + + if(j->ixj_signals[SIG_READ_READY]) + ixj_kill_fasync(j, SIG_READ_READY, POLL_OUT); + } + } +} + +static short fsk[][6][20] = +{ + { + { + 0, 17846, 29934, 32364, 24351, 8481, -10126, -25465, -32587, -29196, + -16384, 1715, 19260, 30591, 32051, 23170, 6813, -11743, -26509, -32722 + }, + { + -28377, -14876, 3425, 20621, 31163, 31650, 21925, 5126, -13328, -27481, + -32767, -27481, -13328, 5126, 21925, 31650, 31163, 20621, 3425, -14876 + }, + { + -28377, -32722, -26509, -11743, 6813, 23170, 32051, 30591, 19260, 1715, + -16384, -29196, -32587, -25465, -10126, 8481, 24351, 32364, 29934, 17846 + }, + { + 0, -17846, -29934, -32364, -24351, -8481, 10126, 25465, 32587, 29196, + 16384, -1715, -19260, -30591, -32051, -23170, -6813, 11743, 26509, 32722 + }, + { + 28377, 14876, -3425, -20621, -31163, -31650, -21925, -5126, 13328, 27481, + 32767, 27481, 13328, -5126, -21925, -31650, -31163, -20621, -3425, 14876 + }, + { + 28377, 32722, 26509, 11743, -6813, -23170, -32051, -30591, -19260, -1715, + 16384, 29196, 32587, 25465, 10126, -8481, -24351, -32364, -29934, -17846 + } + }, + { + { + 0, 10126, 19260, 26509, 31163, 32767, 31163, 26509, 19260, 10126, + 0, -10126, -19260, -26509, -31163, -32767, -31163, -26509, -19260, -10126 + }, + { + -28377, -21925, -13328, -3425, 6813, 16384, 24351, 29934, 32587, 32051, + 28377, 21925, 13328, 3425, -6813, -16384, -24351, -29934, -32587, -32051 + }, + { + -28377, -32051, -32587, -29934, -24351, -16384, -6813, 3425, 13328, 21925, + 28377, 32051, 32587, 29934, 24351, 16384, 6813, -3425, -13328, -21925 + }, + { + 0, -10126, -19260, -26509, -31163, -32767, -31163, -26509, -19260, -10126, + 0, 10126, 19260, 26509, 31163, 32767, 31163, 26509, 19260, 10126 + }, + { + 28377, 21925, 13328, 3425, -6813, -16383, -24351, -29934, -32587, -32051, + -28377, -21925, -13328, -3425, 6813, 16383, 24351, 29934, 32587, 32051 + }, + { + 28377, 32051, 32587, 29934, 24351, 16384, 6813, -3425, -13328, -21925, + -28377, -32051, -32587, -29934, -24351, -16384, -6813, 3425, 13328, 21925 + } + } +}; + + +static void ixj_write_cid_bit(IXJ *j, int bit) +{ + while (j->fskcnt < 20) { + if(j->fskdcnt < (j->fsksize - 1)) + j->fskdata[j->fskdcnt++] = fsk[bit][j->fskz][j->fskcnt]; + + j->fskcnt += 3; + } + j->fskcnt %= 20; + + if (!bit) + j->fskz++; + if (j->fskz >= 6) + j->fskz = 0; + +} + +static void ixj_write_cid_byte(IXJ *j, char byte) +{ + IXJ_CBYTE cb; + + cb.cbyte = byte; + ixj_write_cid_bit(j, 0); + ixj_write_cid_bit(j, cb.cbits.b0 ? 1 : 0); + ixj_write_cid_bit(j, cb.cbits.b1 ? 1 : 0); + ixj_write_cid_bit(j, cb.cbits.b2 ? 1 : 0); + ixj_write_cid_bit(j, cb.cbits.b3 ? 1 : 0); + ixj_write_cid_bit(j, cb.cbits.b4 ? 1 : 0); + ixj_write_cid_bit(j, cb.cbits.b5 ? 1 : 0); + ixj_write_cid_bit(j, cb.cbits.b6 ? 1 : 0); + ixj_write_cid_bit(j, cb.cbits.b7 ? 1 : 0); + ixj_write_cid_bit(j, 1); +} + +static void ixj_write_cid_seize(IXJ *j) +{ + int cnt; + + for (cnt = 0; cnt < 150; cnt++) { + ixj_write_cid_bit(j, 0); + ixj_write_cid_bit(j, 1); + } + for (cnt = 0; cnt < 180; cnt++) { + ixj_write_cid_bit(j, 1); + } +} + +static void ixj_write_cidcw_seize(IXJ *j) +{ + int cnt; + + for (cnt = 0; cnt < 80; cnt++) { + ixj_write_cid_bit(j, 1); + } +} + +static int ixj_write_cid_string(IXJ *j, char *s, int checksum) +{ + int cnt; + + for (cnt = 0; cnt < strlen(s); cnt++) { + ixj_write_cid_byte(j, s[cnt]); + checksum = (checksum + s[cnt]); + } + return checksum; +} + +static void ixj_pad_fsk(IXJ *j, int pad) +{ + int cnt; + + for (cnt = 0; cnt < pad; cnt++) { + if(j->fskdcnt < (j->fsksize - 1)) + j->fskdata[j->fskdcnt++] = 0x0000; + } + for (cnt = 0; cnt < 720; cnt++) { + if(j->fskdcnt < (j->fsksize - 1)) + j->fskdata[j->fskdcnt++] = 0x0000; + } +} + +static void ixj_pre_cid(IXJ *j) +{ + j->cid_play_codec = j->play_codec; + j->cid_play_frame_size = j->play_frame_size; + j->cid_play_volume = get_play_volume(j); + j->cid_play_flag = j->flags.playing; + + j->cid_rec_codec = j->rec_codec; + j->cid_rec_volume = get_rec_volume(j); + j->cid_rec_flag = j->flags.recording; + + j->cid_play_aec_level = j->aec_level; + + switch(j->baseframe.low) { + case 0xA0: + j->cid_base_frame_size = 20; + break; + case 0x50: + j->cid_base_frame_size = 10; + break; + case 0xF0: + j->cid_base_frame_size = 30; + break; + } + + ixj_play_stop(j); + ixj_cpt_stop(j); + + j->flags.cidplay = 1; + + set_base_frame(j, 30); + set_play_codec(j, LINEAR16); + set_play_volume(j, 0x1B); + ixj_play_start(j); +} + +static void ixj_post_cid(IXJ *j) +{ + ixj_play_stop(j); + + if(j->cidsize > 5000) { + SLIC_SetState(PLD_SLIC_STATE_STANDBY, j); + } + j->flags.cidplay = 0; + if(ixjdebug & 0x0200) { + printk("IXJ phone%d Finished Playing CallerID data %ld\n", j->board, jiffies); + } + + ixj_fsk_free(j); + + j->fskdcnt = 0; + set_base_frame(j, j->cid_base_frame_size); + set_play_codec(j, j->cid_play_codec); + ixj_aec_start(j, j->cid_play_aec_level); + set_play_volume(j, j->cid_play_volume); + + set_rec_codec(j, j->cid_rec_codec); + set_rec_volume(j, j->cid_rec_volume); + + if(j->cid_rec_flag) + ixj_record_start(j); + + if(j->cid_play_flag) + ixj_play_start(j); + + if(j->cid_play_flag) { + wake_up_interruptible(&j->write_q); /* Wake any blocked writers */ + } +} + +static void ixj_write_cid(IXJ *j) +{ + char sdmf1[50]; + char sdmf2[50]; + char sdmf3[80]; + char mdmflen, len1, len2, len3; + int pad; + + int checksum = 0; + + if (j->dsp.low == 0x20 || j->flags.cidplay) + return; + + j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0; + j->cidsize = j->cidcnt = 0; + + ixj_fsk_alloc(j); + + strcpy(sdmf1, j->cid_send.month); + strcat(sdmf1, j->cid_send.day); + strcat(sdmf1, j->cid_send.hour); + strcat(sdmf1, j->cid_send.min); + strcpy(sdmf2, j->cid_send.number); + strcpy(sdmf3, j->cid_send.name); + + len1 = strlen(sdmf1); + len2 = strlen(sdmf2); + len3 = strlen(sdmf3); + mdmflen = len1 + len2 + len3 + 6; + + while(1){ + ixj_write_cid_seize(j); + + ixj_write_cid_byte(j, 0x80); + checksum = 0x80; + ixj_write_cid_byte(j, mdmflen); + checksum = checksum + mdmflen; + + ixj_write_cid_byte(j, 0x01); + checksum = checksum + 0x01; + ixj_write_cid_byte(j, len1); + checksum = checksum + len1; + checksum = ixj_write_cid_string(j, sdmf1, checksum); + if(ixj_hookstate(j) & 1) + break; + + ixj_write_cid_byte(j, 0x02); + checksum = checksum + 0x02; + ixj_write_cid_byte(j, len2); + checksum = checksum + len2; + checksum = ixj_write_cid_string(j, sdmf2, checksum); + if(ixj_hookstate(j) & 1) + break; + + ixj_write_cid_byte(j, 0x07); + checksum = checksum + 0x07; + ixj_write_cid_byte(j, len3); + checksum = checksum + len3; + checksum = ixj_write_cid_string(j, sdmf3, checksum); + if(ixj_hookstate(j) & 1) + break; + + checksum %= 256; + checksum ^= 0xFF; + checksum += 1; + + ixj_write_cid_byte(j, (char) checksum); + + pad = j->fskdcnt % 240; + if (pad) { + pad = 240 - pad; + } + ixj_pad_fsk(j, pad); + break; + } + + ixj_write_frame(j); +} + +static void ixj_write_cidcw(IXJ *j) +{ + IXJ_TONE ti; + + char sdmf1[50]; + char sdmf2[50]; + char sdmf3[80]; + char mdmflen, len1, len2, len3; + int pad; + + int checksum = 0; + + if (j->dsp.low == 0x20 || j->flags.cidplay) + return; + + j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0; + j->cidsize = j->cidcnt = 0; + + ixj_fsk_alloc(j); + + j->flags.cidcw_ack = 0; + + ti.tone_index = 23; + ti.gain0 = 1; + ti.freq0 = hz440; + ti.gain1 = 0; + ti.freq1 = 0; + ixj_init_tone(j, &ti); + + ixj_set_tone_on(1500, j); + ixj_set_tone_off(32, j); + if(ixjdebug & 0x0200) { + printk("IXJ cidcw phone%d first tone start at %ld\n", j->board, jiffies); + } + ixj_play_tone(j, 23); + + clear_bit(j->board, &j->busyflags); + while(j->tone_state) + schedule_timeout_interruptible(1); + while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0) + schedule_timeout_interruptible(1); + if(ixjdebug & 0x0200) { + printk("IXJ cidcw phone%d first tone end at %ld\n", j->board, jiffies); + } + + ti.tone_index = 24; + ti.gain0 = 1; + ti.freq0 = hz2130; + ti.gain1 = 0; + ti.freq1 = hz2750; + ixj_init_tone(j, &ti); + + ixj_set_tone_off(10, j); + ixj_set_tone_on(600, j); + if(ixjdebug & 0x0200) { + printk("IXJ cidcw phone%d second tone start at %ld\n", j->board, jiffies); + } + ixj_play_tone(j, 24); + + clear_bit(j->board, &j->busyflags); + while(j->tone_state) + schedule_timeout_interruptible(1); + while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0) + schedule_timeout_interruptible(1); + if(ixjdebug & 0x0200) { + printk("IXJ cidcw phone%d sent second tone at %ld\n", j->board, jiffies); + } + + j->cidcw_wait = jiffies + ((50 * hertz) / 100); + + clear_bit(j->board, &j->busyflags); + while(!j->flags.cidcw_ack && time_before(jiffies, j->cidcw_wait)) + schedule_timeout_interruptible(1); + while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0) + schedule_timeout_interruptible(1); + j->cidcw_wait = 0; + if(!j->flags.cidcw_ack) { + if(ixjdebug & 0x0200) { + printk("IXJ cidcw phone%d did not receive ACK from display %ld\n", j->board, jiffies); + } + ixj_post_cid(j); + if(j->cid_play_flag) { + wake_up_interruptible(&j->write_q); /* Wake any blocked readers */ + } + return; + } else { + ixj_pre_cid(j); + } + j->flags.cidcw_ack = 0; + strcpy(sdmf1, j->cid_send.month); + strcat(sdmf1, j->cid_send.day); + strcat(sdmf1, j->cid_send.hour); + strcat(sdmf1, j->cid_send.min); + strcpy(sdmf2, j->cid_send.number); + strcpy(sdmf3, j->cid_send.name); + + len1 = strlen(sdmf1); + len2 = strlen(sdmf2); + len3 = strlen(sdmf3); + mdmflen = len1 + len2 + len3 + 6; + + ixj_write_cidcw_seize(j); + + ixj_write_cid_byte(j, 0x80); + checksum = 0x80; + ixj_write_cid_byte(j, mdmflen); + checksum = checksum + mdmflen; + + ixj_write_cid_byte(j, 0x01); + checksum = checksum + 0x01; + ixj_write_cid_byte(j, len1); + checksum = checksum + len1; + checksum = ixj_write_cid_string(j, sdmf1, checksum); + + ixj_write_cid_byte(j, 0x02); + checksum = checksum + 0x02; + ixj_write_cid_byte(j, len2); + checksum = checksum + len2; + checksum = ixj_write_cid_string(j, sdmf2, checksum); + + ixj_write_cid_byte(j, 0x07); + checksum = checksum + 0x07; + ixj_write_cid_byte(j, len3); + checksum = checksum + len3; + checksum = ixj_write_cid_string(j, sdmf3, checksum); + + checksum %= 256; + checksum ^= 0xFF; + checksum += 1; + + ixj_write_cid_byte(j, (char) checksum); + + pad = j->fskdcnt % 240; + if (pad) { + pad = 240 - pad; + } + ixj_pad_fsk(j, pad); + if(ixjdebug & 0x0200) { + printk("IXJ cidcw phone%d sent FSK data at %ld\n", j->board, jiffies); + } +} + +static void ixj_write_vmwi(IXJ *j, int msg) +{ + char mdmflen; + int pad; + + int checksum = 0; + + if (j->dsp.low == 0x20 || j->flags.cidplay) + return; + + j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0; + j->cidsize = j->cidcnt = 0; + + ixj_fsk_alloc(j); + + mdmflen = 3; + + if (j->port == PORT_POTS) + SLIC_SetState(PLD_SLIC_STATE_OHT, j); + + ixj_write_cid_seize(j); + + ixj_write_cid_byte(j, 0x82); + checksum = 0x82; + ixj_write_cid_byte(j, mdmflen); + checksum = checksum + mdmflen; + + ixj_write_cid_byte(j, 0x0B); + checksum = checksum + 0x0B; + ixj_write_cid_byte(j, 1); + checksum = checksum + 1; + + if(msg) { + ixj_write_cid_byte(j, 0xFF); + checksum = checksum + 0xFF; + } + else { + ixj_write_cid_byte(j, 0x00); + checksum = checksum + 0x00; + } + + checksum %= 256; + checksum ^= 0xFF; + checksum += 1; + + ixj_write_cid_byte(j, (char) checksum); + + pad = j->fskdcnt % 240; + if (pad) { + pad = 240 - pad; + } + ixj_pad_fsk(j, pad); +} + +static void ixj_write_frame(IXJ *j) +{ + int cnt, frame_count, dly; + IXJ_WORD dat; + + frame_count = 0; + if(j->flags.cidplay) { + for(cnt = 0; cnt < 480; cnt++) { + if (!(cnt % 16) && !IsTxReady(j)) { + dly = 0; + while (!IsTxReady(j)) { + if (dly++ > 5) { + dly = 0; + break; + } + udelay(10); + } + } + dat.word = j->fskdata[j->cidcnt++]; + outb_p(dat.bytes.low, j->DSPbase + 0x0C); + outb_p(dat.bytes.high, j->DSPbase + 0x0D); + cnt++; + } + if(j->cidcnt >= j->fskdcnt) { + ixj_post_cid(j); + } + /* This may seem rude, but if we just played one frame of FSK data for CallerID + and there is real audio data in the buffer, we need to throw it away because + we just used it's time slot */ + if (j->write_buffer_rp > j->write_buffer_wp) { + j->write_buffer_rp += j->cid_play_frame_size * 2; + if (j->write_buffer_rp >= j->write_buffer_end) { + j->write_buffer_rp = j->write_buffer; + } + j->write_buffers_empty++; + wake_up_interruptible(&j->write_q); /* Wake any blocked writers */ + + wake_up_interruptible(&j->poll_q); /* Wake any blocked selects */ + } + } else if (j->write_buffer && j->write_buffers_empty < 1) { + if (j->write_buffer_wp > j->write_buffer_rp) { + frame_count = + (j->write_buffer_wp - j->write_buffer_rp) / (j->play_frame_size * 2); + } + if (j->write_buffer_rp > j->write_buffer_wp) { + frame_count = + (j->write_buffer_wp - j->write_buffer) / (j->play_frame_size * 2) + + (j->write_buffer_end - j->write_buffer_rp) / (j->play_frame_size * 2); + } + if (frame_count >= 1) { + if (j->ver.low == 0x12 && j->play_mode && j->flags.play_first_frame) { + BYTES blankword; + + switch (j->play_mode) { + case PLAYBACK_MODE_ULAW: + case PLAYBACK_MODE_ALAW: + blankword.low = blankword.high = 0xFF; + break; + case PLAYBACK_MODE_8LINEAR: + case PLAYBACK_MODE_16LINEAR: + default: + blankword.low = blankword.high = 0x00; + break; + case PLAYBACK_MODE_8LINEAR_WSS: + blankword.low = blankword.high = 0x80; + break; + } + for (cnt = 0; cnt < 16; cnt++) { + if (!(cnt % 16) && !IsTxReady(j)) { + dly = 0; + while (!IsTxReady(j)) { + if (dly++ > 5) { + dly = 0; + break; + } + udelay(10); + } + } + outb_p((blankword.low), j->DSPbase + 0x0C); + outb_p((blankword.high), j->DSPbase + 0x0D); + } + j->flags.play_first_frame = 0; + } else if (j->play_codec == G723_63 && j->flags.play_first_frame) { + for (cnt = 0; cnt < 24; cnt++) { + BYTES blankword; + + if(cnt == 12) { + blankword.low = 0x02; + blankword.high = 0x00; + } + else { + blankword.low = blankword.high = 0x00; + } + if (!(cnt % 16) && !IsTxReady(j)) { + dly = 0; + while (!IsTxReady(j)) { + if (dly++ > 5) { + dly = 0; + break; + } + udelay(10); + } + } + outb_p((blankword.low), j->DSPbase + 0x0C); + outb_p((blankword.high), j->DSPbase + 0x0D); + } + j->flags.play_first_frame = 0; + } + for (cnt = 0; cnt < j->play_frame_size * 2; cnt += 2) { + if (!(cnt % 16) && !IsTxReady(j)) { + dly = 0; + while (!IsTxReady(j)) { + if (dly++ > 5) { + dly = 0; + break; + } + udelay(10); + } + } + /* Add word 0 to G.729 frames for the 8021. Right now we don't do VAD/CNG */ + if (j->play_codec == G729 && (cnt == 0 || cnt == 10 || cnt == 20)) { + if (j->write_buffer_rp[cnt] == 0 && + j->write_buffer_rp[cnt + 1] == 0 && + j->write_buffer_rp[cnt + 2] == 0 && + j->write_buffer_rp[cnt + 3] == 0 && + j->write_buffer_rp[cnt + 4] == 0 && + j->write_buffer_rp[cnt + 5] == 0 && + j->write_buffer_rp[cnt + 6] == 0 && + j->write_buffer_rp[cnt + 7] == 0 && + j->write_buffer_rp[cnt + 8] == 0 && + j->write_buffer_rp[cnt + 9] == 0) { + /* someone is trying to write silence lets make this a type 0 frame. */ + outb_p(0x00, j->DSPbase + 0x0C); + outb_p(0x00, j->DSPbase + 0x0D); + } else { + /* so all other frames are type 1. */ + outb_p(0x01, j->DSPbase + 0x0C); + outb_p(0x00, j->DSPbase + 0x0D); + } + } + outb_p(*(j->write_buffer_rp + cnt), j->DSPbase + 0x0C); + outb_p(*(j->write_buffer_rp + cnt + 1), j->DSPbase + 0x0D); + *(j->write_buffer_rp + cnt) = 0; + *(j->write_buffer_rp + cnt + 1) = 0; + } + j->write_buffer_rp += j->play_frame_size * 2; + if (j->write_buffer_rp >= j->write_buffer_end) { + j->write_buffer_rp = j->write_buffer; + } + j->write_buffers_empty++; + wake_up_interruptible(&j->write_q); /* Wake any blocked writers */ + + wake_up_interruptible(&j->poll_q); /* Wake any blocked selects */ + + ++j->frameswritten; + } + } else { + j->drybuffer++; + } + if(j->ixj_signals[SIG_WRITE_READY]) { + ixj_kill_fasync(j, SIG_WRITE_READY, POLL_OUT); + } +} + +static int idle(IXJ *j) +{ + if (ixj_WriteDSPCommand(0x0000, j)) /* DSP Idle */ + + return 0; + + if (j->ssr.high || j->ssr.low) { + return 0; + } else { + j->play_mode = -1; + j->flags.playing = 0; + j->rec_mode = -1; + j->flags.recording = 0; + return 1; + } +} + +static int set_base_frame(IXJ *j, int size) +{ + unsigned short cmd; + int cnt; + + idle(j); + j->cid_play_aec_level = j->aec_level; + aec_stop(j); + for (cnt = 0; cnt < 10; cnt++) { + if (idle(j)) + break; + } + if (j->ssr.high || j->ssr.low) + return -1; + if (j->dsp.low != 0x20) { + switch (size) { + case 30: + cmd = 0x07F0; + /* Set Base Frame Size to 240 pg9-10 8021 */ + break; + case 20: + cmd = 0x07A0; + /* Set Base Frame Size to 160 pg9-10 8021 */ + break; + case 10: + cmd = 0x0750; + /* Set Base Frame Size to 80 pg9-10 8021 */ + break; + default: + return -1; + } + } else { + if (size == 30) + return size; + else + return -1; + } + if (ixj_WriteDSPCommand(cmd, j)) { + j->baseframe.high = j->baseframe.low = 0xFF; + return -1; + } else { + j->baseframe.high = j->ssr.high; + j->baseframe.low = j->ssr.low; + /* If the status returned is 0x0000 (pg9-9 8021) the call failed */ + if(j->baseframe.high == 0x00 && j->baseframe.low == 0x00) { + return -1; + } + } + ixj_aec_start(j, j->cid_play_aec_level); + return size; +} + +static int set_rec_codec(IXJ *j, int rate) +{ + int retval = 0; + + j->rec_codec = rate; + + switch (rate) { + case G723_63: + if (j->ver.low != 0x12 || ixj_convert_loaded) { + j->rec_frame_size = 12; + j->rec_mode = 0; + } else { + retval = 1; + } + break; + case G723_53: + if (j->ver.low != 0x12 || ixj_convert_loaded) { + j->rec_frame_size = 10; + j->rec_mode = 0; + } else { + retval = 1; + } + break; + case TS85: + if (j->dsp.low == 0x20 || j->flags.ts85_loaded) { + j->rec_frame_size = 16; + j->rec_mode = 0; + } else { + retval = 1; + } + break; + case TS48: + if (j->ver.low != 0x12 || ixj_convert_loaded) { + j->rec_frame_size = 9; + j->rec_mode = 0; + } else { + retval = 1; + } + break; + case TS41: + if (j->ver.low != 0x12 || ixj_convert_loaded) { + j->rec_frame_size = 8; + j->rec_mode = 0; + } else { + retval = 1; + } + break; + case G728: + if (j->dsp.low != 0x20) { + j->rec_frame_size = 48; + j->rec_mode = 0; + } else { + retval = 1; + } + break; + case G729: + if (j->dsp.low != 0x20) { + if (!j->flags.g729_loaded) { + retval = 1; + break; + } + switch (j->baseframe.low) { + case 0xA0: + j->rec_frame_size = 10; + break; + case 0x50: + j->rec_frame_size = 5; + break; + default: + j->rec_frame_size = 15; + break; + } + j->rec_mode = 0; + } else { + retval = 1; + } + break; + case G729B: + if (j->dsp.low != 0x20) { + if (!j->flags.g729_loaded) { + retval = 1; + break; + } + switch (j->baseframe.low) { + case 0xA0: + j->rec_frame_size = 12; + break; + case 0x50: + j->rec_frame_size = 6; + break; + default: + j->rec_frame_size = 18; + break; + } + j->rec_mode = 0; + } else { + retval = 1; + } + break; + case ULAW: + switch (j->baseframe.low) { + case 0xA0: + j->rec_frame_size = 80; + break; + case 0x50: + j->rec_frame_size = 40; + break; + default: + j->rec_frame_size = 120; + break; + } + j->rec_mode = 4; + break; + case ALAW: + switch (j->baseframe.low) { + case 0xA0: + j->rec_frame_size = 80; + break; + case 0x50: + j->rec_frame_size = 40; + break; + default: + j->rec_frame_size = 120; + break; + } + j->rec_mode = 4; + break; + case LINEAR16: + switch (j->baseframe.low) { + case 0xA0: + j->rec_frame_size = 160; + break; + case 0x50: + j->rec_frame_size = 80; + break; + default: + j->rec_frame_size = 240; + break; + } + j->rec_mode = 5; + break; + case LINEAR8: + switch (j->baseframe.low) { + case 0xA0: + j->rec_frame_size = 80; + break; + case 0x50: + j->rec_frame_size = 40; + break; + default: + j->rec_frame_size = 120; + break; + } + j->rec_mode = 6; + break; + case WSS: + switch (j->baseframe.low) { + case 0xA0: + j->rec_frame_size = 80; + break; + case 0x50: + j->rec_frame_size = 40; + break; + default: + j->rec_frame_size = 120; + break; + } + j->rec_mode = 7; + break; + default: + kfree(j->read_buffer); + j->rec_frame_size = 0; + j->rec_mode = -1; + j->read_buffer = NULL; + j->read_buffer_size = 0; + retval = 1; + break; + } + return retval; +} + +static int ixj_record_start(IXJ *j) +{ + unsigned short cmd = 0x0000; + + if (j->read_buffer) { + ixj_record_stop(j); + } + j->flags.recording = 1; + ixj_WriteDSPCommand(0x0FE0, j); /* Put the DSP in full power mode. */ + + if(ixjdebug & 0x0002) + printk("IXJ %d Starting Record Codec %d at %ld\n", j->board, j->rec_codec, jiffies); + + if (!j->rec_mode) { + switch (j->rec_codec) { + case G723_63: + cmd = 0x5131; + break; + case G723_53: + cmd = 0x5132; + break; + case TS85: + cmd = 0x5130; /* TrueSpeech 8.5 */ + + break; + case TS48: + cmd = 0x5133; /* TrueSpeech 4.8 */ + + break; + case TS41: + cmd = 0x5134; /* TrueSpeech 4.1 */ + + break; + case G728: + cmd = 0x5135; + break; + case G729: + case G729B: + cmd = 0x5136; + break; + default: + return 1; + } + if (ixj_WriteDSPCommand(cmd, j)) + return -1; + } + if (!j->read_buffer) { + if (!j->read_buffer) + j->read_buffer = kmalloc(j->rec_frame_size * 2, GFP_ATOMIC); + if (!j->read_buffer) { + printk("Read buffer allocation for ixj board %d failed!\n", j->board); + return -ENOMEM; + } + } + j->read_buffer_size = j->rec_frame_size * 2; + + if (ixj_WriteDSPCommand(0x5102, j)) /* Set Poll sync mode */ + + return -1; + + switch (j->rec_mode) { + case 0: + cmd = 0x1C03; /* Record C1 */ + + break; + case 4: + if (j->ver.low == 0x12) { + cmd = 0x1E03; /* Record C1 */ + + } else { + cmd = 0x1E01; /* Record C1 */ + + } + break; + case 5: + if (j->ver.low == 0x12) { + cmd = 0x1E83; /* Record C1 */ + + } else { + cmd = 0x1E81; /* Record C1 */ + + } + break; + case 6: + if (j->ver.low == 0x12) { + cmd = 0x1F03; /* Record C1 */ + + } else { + cmd = 0x1F01; /* Record C1 */ + + } + break; + case 7: + if (j->ver.low == 0x12) { + cmd = 0x1F83; /* Record C1 */ + } else { + cmd = 0x1F81; /* Record C1 */ + } + break; + } + if (ixj_WriteDSPCommand(cmd, j)) + return -1; + + if (j->flags.playing) { + ixj_aec_start(j, j->aec_level); + } + return 0; +} + +static void ixj_record_stop(IXJ *j) +{ + if (ixjdebug & 0x0002) + printk("IXJ %d Stopping Record Codec %d at %ld\n", j->board, j->rec_codec, jiffies); + + kfree(j->read_buffer); + j->read_buffer = NULL; + j->read_buffer_size = 0; + if (j->rec_mode > -1) { + ixj_WriteDSPCommand(0x5120, j); + j->rec_mode = -1; + } + j->flags.recording = 0; +} +static void ixj_vad(IXJ *j, int arg) +{ + if (arg) + ixj_WriteDSPCommand(0x513F, j); + else + ixj_WriteDSPCommand(0x513E, j); +} + +static void set_rec_depth(IXJ *j, int depth) +{ + if (depth > 60) + depth = 60; + if (depth < 0) + depth = 0; + ixj_WriteDSPCommand(0x5180 + depth, j); +} + +static void set_dtmf_prescale(IXJ *j, int volume) +{ + ixj_WriteDSPCommand(0xCF07, j); + ixj_WriteDSPCommand(volume, j); +} + +static int get_dtmf_prescale(IXJ *j) +{ + ixj_WriteDSPCommand(0xCF05, j); + return j->ssr.high << 8 | j->ssr.low; +} + +static void set_rec_volume(IXJ *j, int volume) +{ + if(j->aec_level == AEC_AGC) { + if (ixjdebug & 0x0002) + printk(KERN_INFO "IXJ: /dev/phone%d Setting AGC Threshold to 0x%4.4x\n", j->board, volume); + ixj_WriteDSPCommand(0xCF96, j); + ixj_WriteDSPCommand(volume, j); + } else { + if (ixjdebug & 0x0002) + printk(KERN_INFO "IXJ: /dev/phone %d Setting Record Volume to 0x%4.4x\n", j->board, volume); + ixj_WriteDSPCommand(0xCF03, j); + ixj_WriteDSPCommand(volume, j); + } +} + +static int set_rec_volume_linear(IXJ *j, int volume) +{ + int newvolume, dsprecmax; + + if (ixjdebug & 0x0002) + printk(KERN_INFO "IXJ: /dev/phone %d Setting Linear Record Volume to 0x%4.4x\n", j->board, volume); + if(volume > 100 || volume < 0) { + return -1; + } + + /* This should normalize the perceived volumes between the different cards caused by differences in the hardware */ + switch (j->cardtype) { + case QTI_PHONEJACK: + dsprecmax = 0x440; + break; + case QTI_LINEJACK: + dsprecmax = 0x180; + ixj_mixer(0x0203, j); /*Voice Left Volume unmute 6db */ + ixj_mixer(0x0303, j); /*Voice Right Volume unmute 6db */ + ixj_mixer(0x0C00, j); /*Mono1 unmute 12db */ + break; + case QTI_PHONEJACK_LITE: + dsprecmax = 0x4C0; + break; + case QTI_PHONEJACK_PCI: + dsprecmax = 0x100; + break; + case QTI_PHONECARD: + dsprecmax = 0x400; + break; + default: + return -1; + } + newvolume = (dsprecmax * volume) / 100; + set_rec_volume(j, newvolume); + return 0; +} + +static int get_rec_volume(IXJ *j) +{ + if(j->aec_level == AEC_AGC) { + if (ixjdebug & 0x0002) + printk(KERN_INFO "Getting AGC Threshold\n"); + ixj_WriteDSPCommand(0xCF86, j); + if (ixjdebug & 0x0002) + printk(KERN_INFO "AGC Threshold is 0x%2.2x%2.2x\n", j->ssr.high, j->ssr.low); + return j->ssr.high << 8 | j->ssr.low; + } else { + if (ixjdebug & 0x0002) + printk(KERN_INFO "Getting Record Volume\n"); + ixj_WriteDSPCommand(0xCF01, j); + return j->ssr.high << 8 | j->ssr.low; + } +} + +static int get_rec_volume_linear(IXJ *j) +{ + int volume, newvolume, dsprecmax; + + switch (j->cardtype) { + case QTI_PHONEJACK: + dsprecmax = 0x440; + break; + case QTI_LINEJACK: + dsprecmax = 0x180; + break; + case QTI_PHONEJACK_LITE: + dsprecmax = 0x4C0; + break; + case QTI_PHONEJACK_PCI: + dsprecmax = 0x100; + break; + case QTI_PHONECARD: + dsprecmax = 0x400; + break; + default: + return -1; + } + volume = get_rec_volume(j); + newvolume = (volume * 100) / dsprecmax; + if(newvolume > 100) + newvolume = 100; + return newvolume; +} + +static int get_rec_level(IXJ *j) +{ + int retval; + + ixj_WriteDSPCommand(0xCF88, j); + + retval = j->ssr.high << 8 | j->ssr.low; + retval = (retval * 256) / 240; + return retval; +} + +static void ixj_aec_start(IXJ *j, int level) +{ + j->aec_level = level; + if (ixjdebug & 0x0002) + printk(KERN_INFO "AGC set = 0x%2.2x\n", j->aec_level); + if (!level) { + aec_stop(j); + } else { + if (j->rec_codec == G729 || j->play_codec == G729 || j->rec_codec == G729B || j->play_codec == G729B) { + ixj_WriteDSPCommand(0xE022, j); /* Move AEC filter buffer */ + + ixj_WriteDSPCommand(0x0300, j); + } + ixj_WriteDSPCommand(0xB001, j); /* AEC On */ + + ixj_WriteDSPCommand(0xE013, j); /* Advanced AEC C1 */ + + switch (level) { + case AEC_LOW: + ixj_WriteDSPCommand(0x0000, j); /* Advanced AEC C2 = off */ + + ixj_WriteDSPCommand(0xE011, j); + ixj_WriteDSPCommand(0xFFFF, j); + + ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */ + ixj_WriteDSPCommand(0x0000, j); /* to off */ + + break; + + case AEC_MED: + ixj_WriteDSPCommand(0x0600, j); /* Advanced AEC C2 = on medium */ + + ixj_WriteDSPCommand(0xE011, j); + ixj_WriteDSPCommand(0x0080, j); + + ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */ + ixj_WriteDSPCommand(0x0000, j); /* to off */ + + break; + + case AEC_HIGH: + ixj_WriteDSPCommand(0x0C00, j); /* Advanced AEC C2 = on high */ + + ixj_WriteDSPCommand(0xE011, j); + ixj_WriteDSPCommand(0x0080, j); + + ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */ + ixj_WriteDSPCommand(0x0000, j); /* to off */ + + break; + + case AEC_AGC: + /* First we have to put the AEC into advance auto mode so that AGC will not conflict with it */ + ixj_WriteDSPCommand(0x0002, j); /* Attenuation scaling factor of 2 */ + + ixj_WriteDSPCommand(0xE011, j); + ixj_WriteDSPCommand(0x0100, j); /* Higher Threshold Floor */ + + ixj_WriteDSPCommand(0xE012, j); /* Set Train and Lock */ + + if(j->cardtype == QTI_LINEJACK || j->cardtype == QTI_PHONECARD) + ixj_WriteDSPCommand(0x0224, j); + else + ixj_WriteDSPCommand(0x1224, j); + + ixj_WriteDSPCommand(0xE014, j); + ixj_WriteDSPCommand(0x0003, j); /* Lock threshold at 3dB */ + + ixj_WriteDSPCommand(0xE338, j); /* Set Echo Suppresser Attenuation to 0dB */ + + /* Now we can set the AGC initial parameters and turn it on */ + ixj_WriteDSPCommand(0xCF90, j); /* Set AGC Minimum gain */ + ixj_WriteDSPCommand(0x0020, j); /* to 0.125 (-18dB) */ + + ixj_WriteDSPCommand(0xCF91, j); /* Set AGC Maximum gain */ + ixj_WriteDSPCommand(0x1000, j); /* to 16 (24dB) */ + + ixj_WriteDSPCommand(0xCF92, j); /* Set AGC start gain */ + ixj_WriteDSPCommand(0x0800, j); /* to 8 (+18dB) */ + + ixj_WriteDSPCommand(0xCF93, j); /* Set AGC hold time */ + ixj_WriteDSPCommand(0x1F40, j); /* to 2 seconds (units are 250us) */ + + ixj_WriteDSPCommand(0xCF94, j); /* Set AGC Attack Time Constant */ + ixj_WriteDSPCommand(0x0005, j); /* to 8ms */ + + ixj_WriteDSPCommand(0xCF95, j); /* Set AGC Decay Time Constant */ + ixj_WriteDSPCommand(0x000D, j); /* to 4096ms */ + + ixj_WriteDSPCommand(0xCF96, j); /* Set AGC Attack Threshold */ + ixj_WriteDSPCommand(0x1200, j); /* to 25% */ + + ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */ + ixj_WriteDSPCommand(0x0001, j); /* to on */ + + break; + + case AEC_AUTO: + ixj_WriteDSPCommand(0x0002, j); /* Attenuation scaling factor of 2 */ + + ixj_WriteDSPCommand(0xE011, j); + ixj_WriteDSPCommand(0x0100, j); /* Higher Threshold Floor */ + + ixj_WriteDSPCommand(0xE012, j); /* Set Train and Lock */ + + if(j->cardtype == QTI_LINEJACK || j->cardtype == QTI_PHONECARD) + ixj_WriteDSPCommand(0x0224, j); + else + ixj_WriteDSPCommand(0x1224, j); + + ixj_WriteDSPCommand(0xE014, j); + ixj_WriteDSPCommand(0x0003, j); /* Lock threshold at 3dB */ + + ixj_WriteDSPCommand(0xE338, j); /* Set Echo Suppresser Attenuation to 0dB */ + + break; + } + } +} + +static void aec_stop(IXJ *j) +{ + j->aec_level = AEC_OFF; + if (j->rec_codec == G729 || j->play_codec == G729 || j->rec_codec == G729B || j->play_codec == G729B) { + ixj_WriteDSPCommand(0xE022, j); /* Move AEC filter buffer back */ + + ixj_WriteDSPCommand(0x0700, j); + } + if (j->play_mode != -1 && j->rec_mode != -1) + { + ixj_WriteDSPCommand(0xB002, j); /* AEC Stop */ + } +} + +static int set_play_codec(IXJ *j, int rate) +{ + int retval = 0; + + j->play_codec = rate; + + switch (rate) { + case G723_63: + if (j->ver.low != 0x12 || ixj_convert_loaded) { + j->play_frame_size = 12; + j->play_mode = 0; + } else { + retval = 1; + } + break; + case G723_53: + if (j->ver.low != 0x12 || ixj_convert_loaded) { + j->play_frame_size = 10; + j->play_mode = 0; + } else { + retval = 1; + } + break; + case TS85: + if (j->dsp.low == 0x20 || j->flags.ts85_loaded) { + j->play_frame_size = 16; + j->play_mode = 0; + } else { + retval = 1; + } + break; + case TS48: + if (j->ver.low != 0x12 || ixj_convert_loaded) { + j->play_frame_size = 9; + j->play_mode = 0; + } else { + retval = 1; + } + break; + case TS41: + if (j->ver.low != 0x12 || ixj_convert_loaded) { + j->play_frame_size = 8; + j->play_mode = 0; + } else { + retval = 1; + } + break; + case G728: + if (j->dsp.low != 0x20) { + j->play_frame_size = 48; + j->play_mode = 0; + } else { + retval = 1; + } + break; + case G729: + if (j->dsp.low != 0x20) { + if (!j->flags.g729_loaded) { + retval = 1; + break; + } + switch (j->baseframe.low) { + case 0xA0: + j->play_frame_size = 10; + break; + case 0x50: + j->play_frame_size = 5; + break; + default: + j->play_frame_size = 15; + break; + } + j->play_mode = 0; + } else { + retval = 1; + } + break; + case G729B: + if (j->dsp.low != 0x20) { + if (!j->flags.g729_loaded) { + retval = 1; + break; + } + switch (j->baseframe.low) { + case 0xA0: + j->play_frame_size = 12; + break; + case 0x50: + j->play_frame_size = 6; + break; + default: + j->play_frame_size = 18; + break; + } + j->play_mode = 0; + } else { + retval = 1; + } + break; + case ULAW: + switch (j->baseframe.low) { + case 0xA0: + j->play_frame_size = 80; + break; + case 0x50: + j->play_frame_size = 40; + break; + default: + j->play_frame_size = 120; + break; + } + j->play_mode = 2; + break; + case ALAW: + switch (j->baseframe.low) { + case 0xA0: + j->play_frame_size = 80; + break; + case 0x50: + j->play_frame_size = 40; + break; + default: + j->play_frame_size = 120; + break; + } + j->play_mode = 2; + break; + case LINEAR16: + switch (j->baseframe.low) { + case 0xA0: + j->play_frame_size = 160; + break; + case 0x50: + j->play_frame_size = 80; + break; + default: + j->play_frame_size = 240; + break; + } + j->play_mode = 6; + break; + case LINEAR8: + switch (j->baseframe.low) { + case 0xA0: + j->play_frame_size = 80; + break; + case 0x50: + j->play_frame_size = 40; + break; + default: + j->play_frame_size = 120; + break; + } + j->play_mode = 4; + break; + case WSS: + switch (j->baseframe.low) { + case 0xA0: + j->play_frame_size = 80; + break; + case 0x50: + j->play_frame_size = 40; + break; + default: + j->play_frame_size = 120; + break; + } + j->play_mode = 5; + break; + default: + kfree(j->write_buffer); + j->play_frame_size = 0; + j->play_mode = -1; + j->write_buffer = NULL; + j->write_buffer_size = 0; + retval = 1; + break; + } + return retval; +} + +static int ixj_play_start(IXJ *j) +{ + unsigned short cmd = 0x0000; + + if (j->write_buffer) { + ixj_play_stop(j); + } + + if(ixjdebug & 0x0002) + printk("IXJ %d Starting Play Codec %d at %ld\n", j->board, j->play_codec, jiffies); + + j->flags.playing = 1; + ixj_WriteDSPCommand(0x0FE0, j); /* Put the DSP in full power mode. */ + + j->flags.play_first_frame = 1; + j->drybuffer = 0; + + if (!j->play_mode) { + switch (j->play_codec) { + case G723_63: + cmd = 0x5231; + break; + case G723_53: + cmd = 0x5232; + break; + case TS85: + cmd = 0x5230; /* TrueSpeech 8.5 */ + + break; + case TS48: + cmd = 0x5233; /* TrueSpeech 4.8 */ + + break; + case TS41: + cmd = 0x5234; /* TrueSpeech 4.1 */ + + break; + case G728: + cmd = 0x5235; + break; + case G729: + case G729B: + cmd = 0x5236; + break; + default: + return 1; + } + if (ixj_WriteDSPCommand(cmd, j)) + return -1; + } + j->write_buffer = kmalloc(j->play_frame_size * 2, GFP_ATOMIC); + if (!j->write_buffer) { + printk("Write buffer allocation for ixj board %d failed!\n", j->board); + return -ENOMEM; + } +/* j->write_buffers_empty = 2; */ + j->write_buffers_empty = 1; + j->write_buffer_size = j->play_frame_size * 2; + j->write_buffer_end = j->write_buffer + j->play_frame_size * 2; + j->write_buffer_rp = j->write_buffer_wp = j->write_buffer; + + if (ixj_WriteDSPCommand(0x5202, j)) /* Set Poll sync mode */ + + return -1; + + switch (j->play_mode) { + case 0: + cmd = 0x2C03; + break; + case 2: + if (j->ver.low == 0x12) { + cmd = 0x2C23; + } else { + cmd = 0x2C21; + } + break; + case 4: + if (j->ver.low == 0x12) { + cmd = 0x2C43; + } else { + cmd = 0x2C41; + } + break; + case 5: + if (j->ver.low == 0x12) { + cmd = 0x2C53; + } else { + cmd = 0x2C51; + } + break; + case 6: + if (j->ver.low == 0x12) { + cmd = 0x2C63; + } else { + cmd = 0x2C61; + } + break; + } + if (ixj_WriteDSPCommand(cmd, j)) + return -1; + + if (ixj_WriteDSPCommand(0x2000, j)) /* Playback C2 */ + return -1; + + if (ixj_WriteDSPCommand(0x2000 + j->play_frame_size, j)) /* Playback C3 */ + return -1; + + if (j->flags.recording) { + ixj_aec_start(j, j->aec_level); + } + + return 0; +} + +static void ixj_play_stop(IXJ *j) +{ + if (ixjdebug & 0x0002) + printk("IXJ %d Stopping Play Codec %d at %ld\n", j->board, j->play_codec, jiffies); + + kfree(j->write_buffer); + j->write_buffer = NULL; + j->write_buffer_size = 0; + if (j->play_mode > -1) { + ixj_WriteDSPCommand(0x5221, j); /* Stop playback and flush buffers. 8022 reference page 9-40 */ + + j->play_mode = -1; + } + j->flags.playing = 0; +} + +static inline int get_play_level(IXJ *j) +{ + int retval; + + ixj_WriteDSPCommand(0xCF8F, j); /* 8022 Reference page 9-38 */ + return j->ssr.high << 8 | j->ssr.low; + retval = j->ssr.high << 8 | j->ssr.low; + retval = (retval * 256) / 240; + return retval; +} + +static unsigned int ixj_poll(struct file *file_p, poll_table * wait) +{ + unsigned int mask = 0; + + IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode)); + + poll_wait(file_p, &(j->poll_q), wait); + if (j->read_buffer_ready > 0) + mask |= POLLIN | POLLRDNORM; /* readable */ + if (j->write_buffers_empty > 0) + mask |= POLLOUT | POLLWRNORM; /* writable */ + if (j->ex.bytes) + mask |= POLLPRI; + return mask; +} + +static int ixj_play_tone(IXJ *j, char tone) +{ + if (!j->tone_state) { + if(ixjdebug & 0x0002) { + printk("IXJ %d starting tone %d at %ld\n", j->board, tone, jiffies); + } + if (j->dsp.low == 0x20) { + idle(j); + } + j->tone_start_jif = jiffies; + + j->tone_state = 1; + } + + j->tone_index = tone; + if (ixj_WriteDSPCommand(0x6000 + j->tone_index, j)) + return -1; + + return 0; +} + +static int ixj_set_tone_on(unsigned short arg, IXJ *j) +{ + j->tone_on_time = arg; + + if (ixj_WriteDSPCommand(0x6E04, j)) /* Set Tone On Period */ + + return -1; + + if (ixj_WriteDSPCommand(arg, j)) + return -1; + + return 0; +} + +static int SCI_WaitHighSCI(IXJ *j) +{ + int cnt; + + j->pld_scrr.byte = inb_p(j->XILINXbase); + if (!j->pld_scrr.bits.sci) { + for (cnt = 0; cnt < 10; cnt++) { + udelay(32); + j->pld_scrr.byte = inb_p(j->XILINXbase); + + if ((j->pld_scrr.bits.sci)) + return 1; + } + if (ixjdebug & 0x0001) + printk(KERN_INFO "SCI Wait High failed %x\n", j->pld_scrr.byte); + return 0; + } else + return 1; +} + +static int SCI_WaitLowSCI(IXJ *j) +{ + int cnt; + + j->pld_scrr.byte = inb_p(j->XILINXbase); + if (j->pld_scrr.bits.sci) { + for (cnt = 0; cnt < 10; cnt++) { + udelay(32); + j->pld_scrr.byte = inb_p(j->XILINXbase); + + if (!(j->pld_scrr.bits.sci)) + return 1; + } + if (ixjdebug & 0x0001) + printk(KERN_INFO "SCI Wait Low failed %x\n", j->pld_scrr.byte); + return 0; + } else + return 1; +} + +static int SCI_Control(IXJ *j, int control) +{ + switch (control) { + case SCI_End: + j->pld_scrw.bits.c0 = 0; /* Set PLD Serial control interface */ + + j->pld_scrw.bits.c1 = 0; /* to no selection */ + + break; + case SCI_Enable_DAA: + j->pld_scrw.bits.c0 = 1; /* Set PLD Serial control interface */ + + j->pld_scrw.bits.c1 = 0; /* to write to DAA */ + + break; + case SCI_Enable_Mixer: + j->pld_scrw.bits.c0 = 0; /* Set PLD Serial control interface */ + + j->pld_scrw.bits.c1 = 1; /* to write to mixer */ + + break; + case SCI_Enable_EEPROM: + j->pld_scrw.bits.c0 = 1; /* Set PLD Serial control interface */ + + j->pld_scrw.bits.c1 = 1; /* to write to EEPROM */ + + break; + default: + return 0; + break; + } + outb_p(j->pld_scrw.byte, j->XILINXbase); + + switch (control) { + case SCI_End: + return 1; + break; + case SCI_Enable_DAA: + case SCI_Enable_Mixer: + case SCI_Enable_EEPROM: + if (!SCI_WaitHighSCI(j)) + return 0; + break; + default: + return 0; + break; + } + return 1; +} + +static int SCI_Prepare(IXJ *j) +{ + if (!SCI_Control(j, SCI_End)) + return 0; + + if (!SCI_WaitLowSCI(j)) + return 0; + + return 1; +} + +static int ixj_get_mixer(long val, IXJ *j) +{ + int reg = (val & 0x1F00) >> 8; + return j->mix.vol[reg]; +} + +static int ixj_mixer(long val, IXJ *j) +{ + BYTES bytes; + + bytes.high = (val & 0x1F00) >> 8; + bytes.low = val & 0x00FF; + + /* save mixer value so we can get back later on */ + j->mix.vol[bytes.high] = bytes.low; + + outb_p(bytes.high & 0x1F, j->XILINXbase + 0x03); /* Load Mixer Address */ + + outb_p(bytes.low, j->XILINXbase + 0x02); /* Load Mixer Data */ + + SCI_Control(j, SCI_Enable_Mixer); + + SCI_Control(j, SCI_End); + + return 0; +} + +static int daa_load(BYTES * p_bytes, IXJ *j) +{ + outb_p(p_bytes->high, j->XILINXbase + 0x03); + outb_p(p_bytes->low, j->XILINXbase + 0x02); + if (!SCI_Control(j, SCI_Enable_DAA)) + return 0; + else + return 1; +} + +static int ixj_daa_cr4(IXJ *j, char reg) +{ + BYTES bytes; + + switch (j->daa_mode) { + case SOP_PU_SLEEP: + bytes.high = 0x14; + break; + case SOP_PU_RINGING: + bytes.high = 0x54; + break; + case SOP_PU_CONVERSATION: + bytes.high = 0x94; + break; + case SOP_PU_PULSEDIALING: + bytes.high = 0xD4; + break; + } + + j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = reg; + + switch (j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGX) { + case 0: + j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 0; + break; + case 1: + j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 2; + break; + case 2: + j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 1; + break; + case 3: + j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 3; + break; + } + + bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg; + + if (!daa_load(&bytes, j)) + return 0; + + if (!SCI_Prepare(j)) + return 0; + + return 1; +} + +static char daa_int_read(IXJ *j) +{ + BYTES bytes; + + if (!SCI_Prepare(j)) + return 0; + + bytes.high = 0x38; + bytes.low = 0x00; + outb_p(bytes.high, j->XILINXbase + 0x03); + outb_p(bytes.low, j->XILINXbase + 0x02); + + if (!SCI_Control(j, SCI_Enable_DAA)) + return 0; + + bytes.high = inb_p(j->XILINXbase + 0x03); + bytes.low = inb_p(j->XILINXbase + 0x02); + if (bytes.low != ALISDAA_ID_BYTE) { + if (ixjdebug & 0x0001) + printk("Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low); + return 0; + } + if (!SCI_Control(j, SCI_Enable_DAA)) + return 0; + if (!SCI_Control(j, SCI_End)) + return 0; + + bytes.high = inb_p(j->XILINXbase + 0x03); + bytes.low = inb_p(j->XILINXbase + 0x02); + + j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg = bytes.high; + + return 1; +} + +static char daa_CR_read(IXJ *j, int cr) +{ + IXJ_WORD wdata; + BYTES bytes; + + if (!SCI_Prepare(j)) + return 0; + + switch (j->daa_mode) { + case SOP_PU_SLEEP: + bytes.high = 0x30 + cr; + break; + case SOP_PU_RINGING: + bytes.high = 0x70 + cr; + break; + case SOP_PU_CONVERSATION: + bytes.high = 0xB0 + cr; + break; + case SOP_PU_PULSEDIALING: + default: + bytes.high = 0xF0 + cr; + break; + } + + bytes.low = 0x00; + + outb_p(bytes.high, j->XILINXbase + 0x03); + outb_p(bytes.low, j->XILINXbase + 0x02); + + if (!SCI_Control(j, SCI_Enable_DAA)) + return 0; + + bytes.high = inb_p(j->XILINXbase + 0x03); + bytes.low = inb_p(j->XILINXbase + 0x02); + if (bytes.low != ALISDAA_ID_BYTE) { + if (ixjdebug & 0x0001) + printk("Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low); + return 0; + } + if (!SCI_Control(j, SCI_Enable_DAA)) + return 0; + if (!SCI_Control(j, SCI_End)) + return 0; + + wdata.word = inw_p(j->XILINXbase + 0x02); + + switch(cr){ + case 5: + j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg = wdata.bytes.high; + break; + case 4: + j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = wdata.bytes.high; + break; + case 3: + j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = wdata.bytes.high; + break; + case 2: + j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = wdata.bytes.high; + break; + case 1: + j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = wdata.bytes.high; + break; + case 0: + j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = wdata.bytes.high; + break; + default: + return 0; + } + return 1; +} + +static int ixj_daa_cid_reset(IXJ *j) +{ + int i; + BYTES bytes; + + if (ixjdebug & 0x0002) + printk("DAA Clearing CID ram\n"); + + if (!SCI_Prepare(j)) + return 0; + + bytes.high = 0x58; + bytes.low = 0x00; + outb_p(bytes.high, j->XILINXbase + 0x03); + outb_p(bytes.low, j->XILINXbase + 0x02); + + if (!SCI_Control(j, SCI_Enable_DAA)) + return 0; + + if (!SCI_WaitHighSCI(j)) + return 0; + + for (i = 0; i < ALISDAA_CALLERID_SIZE - 1; i += 2) { + bytes.high = bytes.low = 0x00; + outb_p(bytes.high, j->XILINXbase + 0x03); + + if (i < ALISDAA_CALLERID_SIZE - 1) + outb_p(bytes.low, j->XILINXbase + 0x02); + + if (!SCI_Control(j, SCI_Enable_DAA)) + return 0; + + if (!SCI_WaitHighSCI(j)) + return 0; + + } + + if (!SCI_Control(j, SCI_End)) + return 0; + + if (ixjdebug & 0x0002) + printk("DAA CID ram cleared\n"); + + return 1; +} + +static int ixj_daa_cid_read(IXJ *j) +{ + int i; + BYTES bytes; + char CID[ALISDAA_CALLERID_SIZE]; + bool mContinue; + char *pIn, *pOut; + + if (!SCI_Prepare(j)) + return 0; + + bytes.high = 0x78; + bytes.low = 0x00; + outb_p(bytes.high, j->XILINXbase + 0x03); + outb_p(bytes.low, j->XILINXbase + 0x02); + + if (!SCI_Control(j, SCI_Enable_DAA)) + return 0; + + if (!SCI_WaitHighSCI(j)) + return 0; + + bytes.high = inb_p(j->XILINXbase + 0x03); + bytes.low = inb_p(j->XILINXbase + 0x02); + if (bytes.low != ALISDAA_ID_BYTE) { + if (ixjdebug & 0x0001) + printk("DAA Get Version Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low); + return 0; + } + for (i = 0; i < ALISDAA_CALLERID_SIZE; i += 2) { + bytes.high = bytes.low = 0x00; + outb_p(bytes.high, j->XILINXbase + 0x03); + outb_p(bytes.low, j->XILINXbase + 0x02); + + if (!SCI_Control(j, SCI_Enable_DAA)) + return 0; + + if (!SCI_WaitHighSCI(j)) + return 0; + + CID[i + 0] = inb_p(j->XILINXbase + 0x03); + CID[i + 1] = inb_p(j->XILINXbase + 0x02); + } + + if (!SCI_Control(j, SCI_End)) + return 0; + + pIn = CID; + pOut = j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID; + mContinue = true; + while (mContinue) { + if ((pIn[1] & 0x03) == 0x01) { + pOut[0] = pIn[0]; + } + if ((pIn[2] & 0x0c) == 0x04) { + pOut[1] = ((pIn[2] & 0x03) << 6) | ((pIn[1] & 0xfc) >> 2); + } + if ((pIn[3] & 0x30) == 0x10) { + pOut[2] = ((pIn[3] & 0x0f) << 4) | ((pIn[2] & 0xf0) >> 4); + } + if ((pIn[4] & 0xc0) == 0x40) { + pOut[3] = ((pIn[4] & 0x3f) << 2) | ((pIn[3] & 0xc0) >> 6); + } else { + mContinue = false; + } + pIn += 5, pOut += 4; + } + memset(&j->cid, 0, sizeof(PHONE_CID)); + pOut = j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID; + pOut += 4; + strncpy(j->cid.month, pOut, 2); + pOut += 2; + strncpy(j->cid.day, pOut, 2); + pOut += 2; + strncpy(j->cid.hour, pOut, 2); + pOut += 2; + strncpy(j->cid.min, pOut, 2); + pOut += 3; + j->cid.numlen = *pOut; + pOut += 1; + strncpy(j->cid.number, pOut, j->cid.numlen); + pOut += j->cid.numlen + 1; + j->cid.namelen = *pOut; + pOut += 1; + strncpy(j->cid.name, pOut, j->cid.namelen); + + ixj_daa_cid_reset(j); + return 1; +} + +static char daa_get_version(IXJ *j) +{ + BYTES bytes; + + if (!SCI_Prepare(j)) + return 0; + + bytes.high = 0x35; + bytes.low = 0x00; + outb_p(bytes.high, j->XILINXbase + 0x03); + outb_p(bytes.low, j->XILINXbase + 0x02); + + if (!SCI_Control(j, SCI_Enable_DAA)) + return 0; + + bytes.high = inb_p(j->XILINXbase + 0x03); + bytes.low = inb_p(j->XILINXbase + 0x02); + if (bytes.low != ALISDAA_ID_BYTE) { + if (ixjdebug & 0x0001) + printk("DAA Get Version Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low); + return 0; + } + if (!SCI_Control(j, SCI_Enable_DAA)) + return 0; + + if (!SCI_Control(j, SCI_End)) + return 0; + + bytes.high = inb_p(j->XILINXbase + 0x03); + bytes.low = inb_p(j->XILINXbase + 0x02); + if (ixjdebug & 0x0002) + printk("DAA CR5 Byte high = 0x%x low = 0x%x\n", bytes.high, bytes.low); + j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg = bytes.high; + return bytes.high; +} + +static int daa_set_mode(IXJ *j, int mode) +{ + /* NOTE: + The DAA *MUST* be in the conversation mode if the + PSTN line is to be seized (PSTN line off-hook). + Taking the PSTN line off-hook while the DAA is in + a mode other than conversation mode will cause a + hardware failure of the ALIS-A part. + + NOTE: + The DAA can only go to SLEEP, RINGING or PULSEDIALING modes + if the PSTN line is on-hook. Failure to have the PSTN line + in the on-hook state WILL CAUSE A HARDWARE FAILURE OF THE + ALIS-A part. + */ + + BYTES bytes; + + j->flags.pstn_rmr = 0; + + if (!SCI_Prepare(j)) + return 0; + + switch (mode) { + case SOP_PU_RESET: + j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ + + outb_p(j->pld_scrw.byte, j->XILINXbase); + j->pld_slicw.bits.rly2 = 0; + outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); + bytes.high = 0x10; + bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg; + daa_load(&bytes, j); + if (!SCI_Prepare(j)) + return 0; + + j->daa_mode = SOP_PU_SLEEP; + break; + case SOP_PU_SLEEP: + if(j->daa_mode == SOP_PU_SLEEP) + { + break; + } + if (ixjdebug & 0x0008) + printk(KERN_INFO "phone DAA: SOP_PU_SLEEP at %ld\n", jiffies); +/* if(j->daa_mode == SOP_PU_CONVERSATION) */ + { + j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ + + outb_p(j->pld_scrw.byte, j->XILINXbase); + j->pld_slicw.bits.rly2 = 0; + outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); + bytes.high = 0x10; + bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg; + daa_load(&bytes, j); + if (!SCI_Prepare(j)) + return 0; + } + j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ + + outb_p(j->pld_scrw.byte, j->XILINXbase); + j->pld_slicw.bits.rly2 = 0; + outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); + bytes.high = 0x10; + bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg; + daa_load(&bytes, j); + if (!SCI_Prepare(j)) + return 0; + + j->daa_mode = SOP_PU_SLEEP; + j->flags.pstn_ringing = 0; + j->ex.bits.pstn_ring = 0; + j->pstn_sleeptil = jiffies + (hertz / 4); + wake_up_interruptible(&j->read_q); /* Wake any blocked readers */ + wake_up_interruptible(&j->write_q); /* Wake any blocked writers */ + wake_up_interruptible(&j->poll_q); /* Wake any blocked selects */ + break; + case SOP_PU_RINGING: + if (ixjdebug & 0x0008) + printk(KERN_INFO "phone DAA: SOP_PU_RINGING at %ld\n", jiffies); + j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ + + outb_p(j->pld_scrw.byte, j->XILINXbase); + j->pld_slicw.bits.rly2 = 0; + outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); + bytes.high = 0x50; + bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg; + daa_load(&bytes, j); + if (!SCI_Prepare(j)) + return 0; + j->daa_mode = SOP_PU_RINGING; + break; + case SOP_PU_CONVERSATION: + if (ixjdebug & 0x0008) + printk(KERN_INFO "phone DAA: SOP_PU_CONVERSATION at %ld\n", jiffies); + bytes.high = 0x90; + bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg; + daa_load(&bytes, j); + if (!SCI_Prepare(j)) + return 0; + j->pld_slicw.bits.rly2 = 1; + outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); + j->pld_scrw.bits.daafsyncen = 1; /* Turn on DAA Frame Sync */ + + outb_p(j->pld_scrw.byte, j->XILINXbase); + j->daa_mode = SOP_PU_CONVERSATION; + j->flags.pstn_ringing = 0; + j->ex.bits.pstn_ring = 0; + j->pstn_sleeptil = jiffies; + j->pstn_ring_start = j->pstn_ring_stop = j->pstn_ring_int = 0; + break; + case SOP_PU_PULSEDIALING: + if (ixjdebug & 0x0008) + printk(KERN_INFO "phone DAA: SOP_PU_PULSEDIALING at %ld\n", jiffies); + j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ + + outb_p(j->pld_scrw.byte, j->XILINXbase); + j->pld_slicw.bits.rly2 = 0; + outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); + bytes.high = 0xD0; + bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg; + daa_load(&bytes, j); + if (!SCI_Prepare(j)) + return 0; + j->daa_mode = SOP_PU_PULSEDIALING; + break; + default: + break; + } + return 1; +} + +static int ixj_daa_write(IXJ *j) +{ + BYTES bytes; + + j->flags.pstncheck = 1; + + daa_set_mode(j, SOP_PU_SLEEP); + + if (!SCI_Prepare(j)) + return 0; + + outb_p(j->pld_scrw.byte, j->XILINXbase); + + bytes.high = 0x14; + bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg; + bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg; + bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg; + if (!daa_load(&bytes, j)) + return 0; + + if (!SCI_Prepare(j)) + return 0; + + bytes.high = 0x1F; + bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.XOP_xr6_W.reg; + bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg; + bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg; + bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.XOP_xr0_W.reg; + bytes.low = 0x00; + if (!daa_load(&bytes, j)) + return 0; + + if (!SCI_Prepare(j)) + return 0; + + bytes.high = 0x00; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0]; + bytes.low = 0x00; + if (!daa_load(&bytes, j)) + return 0; + + if (!SCI_Control(j, SCI_End)) + return 0; + if (!SCI_WaitLowSCI(j)) + return 0; + + bytes.high = 0x01; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0]; + bytes.low = 0x00; + if (!daa_load(&bytes, j)) + return 0; + + if (!SCI_Control(j, SCI_End)) + return 0; + if (!SCI_WaitLowSCI(j)) + return 0; + + bytes.high = 0x02; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0]; + bytes.low = 0x00; + if (!daa_load(&bytes, j)) + return 0; + + if (!SCI_Control(j, SCI_End)) + return 0; + if (!SCI_WaitLowSCI(j)) + return 0; + + bytes.high = 0x03; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0]; + bytes.low = 0x00; + if (!daa_load(&bytes, j)) + return 0; + + if (!SCI_Control(j, SCI_End)) + return 0; + if (!SCI_WaitLowSCI(j)) + return 0; + + bytes.high = 0x04; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0]; + bytes.low = 0x00; + if (!daa_load(&bytes, j)) + return 0; + + if (!SCI_Control(j, SCI_End)) + return 0; + if (!SCI_WaitLowSCI(j)) + return 0; + + bytes.high = 0x05; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0]; + bytes.low = 0x00; + if (!daa_load(&bytes, j)) + return 0; + + if (!SCI_Control(j, SCI_End)) + return 0; + if (!SCI_WaitLowSCI(j)) + return 0; + + bytes.high = 0x06; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0]; + bytes.low = 0x00; + if (!daa_load(&bytes, j)) + return 0; + + if (!SCI_Control(j, SCI_End)) + return 0; + if (!SCI_WaitLowSCI(j)) + return 0; + + bytes.high = 0x07; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0]; + bytes.low = 0x00; + if (!daa_load(&bytes, j)) + return 0; + + if (!SCI_Control(j, SCI_End)) + return 0; + if (!SCI_WaitLowSCI(j)) + return 0; + + bytes.high = 0x08; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0]; + bytes.low = 0x00; + if (!daa_load(&bytes, j)) + return 0; + + if (!SCI_Control(j, SCI_End)) + return 0; + if (!SCI_WaitLowSCI(j)) + return 0; + + bytes.high = 0x09; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0]; + bytes.low = 0x00; + if (!daa_load(&bytes, j)) + return 0; + + if (!SCI_Control(j, SCI_End)) + return 0; + if (!SCI_WaitLowSCI(j)) + return 0; + + bytes.high = 0x0A; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0]; + bytes.low = 0x00; + if (!daa_load(&bytes, j)) + return 0; + + if (!SCI_Control(j, SCI_End)) + return 0; + if (!SCI_WaitLowSCI(j)) + return 0; + + bytes.high = 0x0B; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0]; + bytes.low = 0x00; + if (!daa_load(&bytes, j)) + return 0; + + if (!SCI_Control(j, SCI_End)) + return 0; + if (!SCI_WaitLowSCI(j)) + return 0; + + bytes.high = 0x0C; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0]; + bytes.low = 0x00; + if (!daa_load(&bytes, j)) + return 0; + + if (!SCI_Control(j, SCI_End)) + return 0; + if (!SCI_WaitLowSCI(j)) + return 0; + + bytes.high = 0x0D; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0]; + bytes.low = 0x00; + if (!daa_load(&bytes, j)) + return 0; + + if (!SCI_Control(j, SCI_End)) + return 0; + if (!SCI_WaitLowSCI(j)) + return 0; + + bytes.high = 0x0E; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0]; + bytes.low = 0x00; + if (!daa_load(&bytes, j)) + return 0; + + if (!SCI_Control(j, SCI_End)) + return 0; + if (!SCI_WaitLowSCI(j)) + return 0; + + bytes.high = 0x0F; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2]; + bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1]; + if (!daa_load(&bytes, j)) + return 0; + + bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0]; + bytes.low = 0x00; + if (!daa_load(&bytes, j)) + return 0; + + udelay(32); + j->pld_scrr.byte = inb_p(j->XILINXbase); + if (!SCI_Control(j, SCI_End)) + return 0; + + outb_p(j->pld_scrw.byte, j->XILINXbase); + + if (ixjdebug & 0x0002) + printk("DAA Coefficients Loaded\n"); + + j->flags.pstncheck = 0; + return 1; +} + +static int ixj_set_tone_off(unsigned short arg, IXJ *j) +{ + j->tone_off_time = arg; + if (ixj_WriteDSPCommand(0x6E05, j)) /* Set Tone Off Period */ + + return -1; + if (ixj_WriteDSPCommand(arg, j)) + return -1; + return 0; +} + +static int ixj_get_tone_on(IXJ *j) +{ + if (ixj_WriteDSPCommand(0x6E06, j)) /* Get Tone On Period */ + + return -1; + return 0; +} + +static int ixj_get_tone_off(IXJ *j) +{ + if (ixj_WriteDSPCommand(0x6E07, j)) /* Get Tone Off Period */ + + return -1; + return 0; +} + +static void ixj_busytone(IXJ *j) +{ + j->flags.ringback = 0; + j->flags.dialtone = 0; + j->flags.busytone = 1; + ixj_set_tone_on(0x07D0, j); + ixj_set_tone_off(0x07D0, j); + ixj_play_tone(j, 27); +} + +static void ixj_dialtone(IXJ *j) +{ + j->flags.ringback = 0; + j->flags.dialtone = 1; + j->flags.busytone = 0; + if (j->dsp.low == 0x20) { + return; + } else { + ixj_set_tone_on(0xFFFF, j); + ixj_set_tone_off(0x0000, j); + ixj_play_tone(j, 25); + } +} + +static void ixj_cpt_stop(IXJ *j) +{ + if(j->tone_state || j->tone_cadence_state) + { + j->flags.dialtone = 0; + j->flags.busytone = 0; + j->flags.ringback = 0; + ixj_set_tone_on(0x0001, j); + ixj_set_tone_off(0x0000, j); + ixj_play_tone(j, 0); + j->tone_state = j->tone_cadence_state = 0; + if (j->cadence_t) { + kfree(j->cadence_t->ce); + kfree(j->cadence_t); + j->cadence_t = NULL; + } + } + if (j->play_mode == -1 && j->rec_mode == -1) + idle(j); + if (j->play_mode != -1 && j->dsp.low == 0x20) + ixj_play_start(j); + if (j->rec_mode != -1 && j->dsp.low == 0x20) + ixj_record_start(j); +} + +static void ixj_ringback(IXJ *j) +{ + j->flags.busytone = 0; + j->flags.dialtone = 0; + j->flags.ringback = 1; + ixj_set_tone_on(0x0FA0, j); + ixj_set_tone_off(0x2EE0, j); + ixj_play_tone(j, 26); +} + +static void ixj_testram(IXJ *j) +{ + ixj_WriteDSPCommand(0x3001, j); /* Test External SRAM */ +} + +static int ixj_build_cadence(IXJ *j, IXJ_CADENCE __user * cp) +{ + ixj_cadence *lcp; + IXJ_CADENCE_ELEMENT __user *cep; + IXJ_CADENCE_ELEMENT *lcep; + IXJ_TONE ti; + int err; + + lcp = kmalloc(sizeof(ixj_cadence), GFP_KERNEL); + if (lcp == NULL) + return -ENOMEM; + + err = -EFAULT; + if (copy_from_user(&lcp->elements_used, + &cp->elements_used, sizeof(int))) + goto out; + if (copy_from_user(&lcp->termination, + &cp->termination, sizeof(IXJ_CADENCE_TERM))) + goto out; + if (get_user(cep, &cp->ce)) + goto out; + + err = -EINVAL; + if ((unsigned)lcp->elements_used >= ~0U/sizeof(IXJ_CADENCE_ELEMENT)) + goto out; + + err = -ENOMEM; + lcep = kmalloc(sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used, GFP_KERNEL); + if (!lcep) + goto out; + + err = -EFAULT; + if (copy_from_user(lcep, cep, sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used)) + goto out1; + + if (j->cadence_t) { + kfree(j->cadence_t->ce); + kfree(j->cadence_t); + } + lcp->ce = (void *) lcep; + j->cadence_t = lcp; + j->tone_cadence_state = 0; + ixj_set_tone_on(lcp->ce[0].tone_on_time, j); + ixj_set_tone_off(lcp->ce[0].tone_off_time, j); + if (j->cadence_t->ce[j->tone_cadence_state].freq0) { + ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index; + ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0; + ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0; + ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1; + ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1; + ixj_init_tone(j, &ti); + } + ixj_play_tone(j, lcp->ce[0].index); + return 1; +out1: + kfree(lcep); +out: + kfree(lcp); + return err; +} + +static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE __user * cp) +{ + IXJ_FILTER_CADENCE *lcp; + lcp = memdup_user(cp, sizeof(IXJ_FILTER_CADENCE)); + if (IS_ERR(lcp)) { + if(ixjdebug & 0x0001) { + printk(KERN_INFO "Could not allocate memory for cadence or could not copy cadence to kernel\n"); + } + return PTR_ERR(lcp); + } + if (lcp->filter > 5) { + if(ixjdebug & 0x0001) { + printk(KERN_INFO "Cadence out of range\n"); + } + kfree(lcp); + return -1; + } + j->cadence_f[lcp->filter].state = 0; + j->cadence_f[lcp->filter].enable = lcp->enable; + j->filter_en[lcp->filter] = j->cadence_f[lcp->filter].en_filter = lcp->en_filter; + j->cadence_f[lcp->filter].on1 = lcp->on1; + j->cadence_f[lcp->filter].on1min = 0; + j->cadence_f[lcp->filter].on1max = 0; + j->cadence_f[lcp->filter].off1 = lcp->off1; + j->cadence_f[lcp->filter].off1min = 0; + j->cadence_f[lcp->filter].off1max = 0; + j->cadence_f[lcp->filter].on2 = lcp->on2; + j->cadence_f[lcp->filter].on2min = 0; + j->cadence_f[lcp->filter].on2max = 0; + j->cadence_f[lcp->filter].off2 = lcp->off2; + j->cadence_f[lcp->filter].off2min = 0; + j->cadence_f[lcp->filter].off2max = 0; + j->cadence_f[lcp->filter].on3 = lcp->on3; + j->cadence_f[lcp->filter].on3min = 0; + j->cadence_f[lcp->filter].on3max = 0; + j->cadence_f[lcp->filter].off3 = lcp->off3; + j->cadence_f[lcp->filter].off3min = 0; + j->cadence_f[lcp->filter].off3max = 0; + if(ixjdebug & 0x0002) { + printk(KERN_INFO "Cadence %d loaded\n", lcp->filter); + } + kfree(lcp); + return 0; +} + +static void add_caps(IXJ *j) +{ + j->caps = 0; + j->caplist[j->caps].cap = PHONE_VENDOR_QUICKNET; + strcpy(j->caplist[j->caps].desc, "Quicknet Technologies, Inc. (www.quicknet.net)"); + j->caplist[j->caps].captype = vendor; + j->caplist[j->caps].handle = j->caps++; + j->caplist[j->caps].captype = device; + switch (j->cardtype) { + case QTI_PHONEJACK: + strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneJACK"); + break; + case QTI_LINEJACK: + strcpy(j->caplist[j->caps].desc, "Quicknet Internet LineJACK"); + break; + case QTI_PHONEJACK_LITE: + strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneJACK Lite"); + break; + case QTI_PHONEJACK_PCI: + strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneJACK PCI"); + break; + case QTI_PHONECARD: + strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneCARD"); + break; + } + j->caplist[j->caps].cap = j->cardtype; + j->caplist[j->caps].handle = j->caps++; + strcpy(j->caplist[j->caps].desc, "POTS"); + j->caplist[j->caps].captype = port; + j->caplist[j->caps].cap = pots; + j->caplist[j->caps].handle = j->caps++; + + /* add devices that can do speaker/mic */ + switch (j->cardtype) { + case QTI_PHONEJACK: + case QTI_LINEJACK: + case QTI_PHONEJACK_PCI: + case QTI_PHONECARD: + strcpy(j->caplist[j->caps].desc, "SPEAKER"); + j->caplist[j->caps].captype = port; + j->caplist[j->caps].cap = speaker; + j->caplist[j->caps].handle = j->caps++; + default: + break; + } + + /* add devices that can do handset */ + switch (j->cardtype) { + case QTI_PHONEJACK: + strcpy(j->caplist[j->caps].desc, "HANDSET"); + j->caplist[j->caps].captype = port; + j->caplist[j->caps].cap = handset; + j->caplist[j->caps].handle = j->caps++; + break; + default: + break; + } + + /* add devices that can do PSTN */ + switch (j->cardtype) { + case QTI_LINEJACK: + strcpy(j->caplist[j->caps].desc, "PSTN"); + j->caplist[j->caps].captype = port; + j->caplist[j->caps].cap = pstn; + j->caplist[j->caps].handle = j->caps++; + break; + default: + break; + } + + /* add codecs - all cards can do uLaw, linear 8/16, and Windows sound system */ + strcpy(j->caplist[j->caps].desc, "ULAW"); + j->caplist[j->caps].captype = codec; + j->caplist[j->caps].cap = ULAW; + j->caplist[j->caps].handle = j->caps++; + + strcpy(j->caplist[j->caps].desc, "LINEAR 16 bit"); + j->caplist[j->caps].captype = codec; + j->caplist[j->caps].cap = LINEAR16; + j->caplist[j->caps].handle = j->caps++; + + strcpy(j->caplist[j->caps].desc, "LINEAR 8 bit"); + j->caplist[j->caps].captype = codec; + j->caplist[j->caps].cap = LINEAR8; + j->caplist[j->caps].handle = j->caps++; + + strcpy(j->caplist[j->caps].desc, "Windows Sound System"); + j->caplist[j->caps].captype = codec; + j->caplist[j->caps].cap = WSS; + j->caplist[j->caps].handle = j->caps++; + + /* software ALAW codec, made from ULAW */ + strcpy(j->caplist[j->caps].desc, "ALAW"); + j->caplist[j->caps].captype = codec; + j->caplist[j->caps].cap = ALAW; + j->caplist[j->caps].handle = j->caps++; + + /* version 12 of the 8020 does the following codecs in a broken way */ + if (j->dsp.low != 0x20 || j->ver.low != 0x12) { + strcpy(j->caplist[j->caps].desc, "G.723.1 6.3kbps"); + j->caplist[j->caps].captype = codec; + j->caplist[j->caps].cap = G723_63; + j->caplist[j->caps].handle = j->caps++; + + strcpy(j->caplist[j->caps].desc, "G.723.1 5.3kbps"); + j->caplist[j->caps].captype = codec; + j->caplist[j->caps].cap = G723_53; + j->caplist[j->caps].handle = j->caps++; + + strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.8kbps"); + j->caplist[j->caps].captype = codec; + j->caplist[j->caps].cap = TS48; + j->caplist[j->caps].handle = j->caps++; + + strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.1kbps"); + j->caplist[j->caps].captype = codec; + j->caplist[j->caps].cap = TS41; + j->caplist[j->caps].handle = j->caps++; + } + + /* 8020 chips can do TS8.5 native, and 8021/8022 can load it */ + if (j->dsp.low == 0x20 || j->flags.ts85_loaded) { + strcpy(j->caplist[j->caps].desc, "TrueSpeech 8.5kbps"); + j->caplist[j->caps].captype = codec; + j->caplist[j->caps].cap = TS85; + j->caplist[j->caps].handle = j->caps++; + } + + /* 8021 chips can do G728 */ + if (j->dsp.low == 0x21) { + strcpy(j->caplist[j->caps].desc, "G.728 16kbps"); + j->caplist[j->caps].captype = codec; + j->caplist[j->caps].cap = G728; + j->caplist[j->caps].handle = j->caps++; + } + + /* 8021/8022 chips can do G729 if loaded */ + if (j->dsp.low != 0x20 && j->flags.g729_loaded) { + strcpy(j->caplist[j->caps].desc, "G.729A 8kbps"); + j->caplist[j->caps].captype = codec; + j->caplist[j->caps].cap = G729; + j->caplist[j->caps].handle = j->caps++; + } + if (j->dsp.low != 0x20 && j->flags.g729_loaded) { + strcpy(j->caplist[j->caps].desc, "G.729B 8kbps"); + j->caplist[j->caps].captype = codec; + j->caplist[j->caps].cap = G729B; + j->caplist[j->caps].handle = j->caps++; + } +} + +static int capabilities_check(IXJ *j, struct phone_capability *pcreq) +{ + int cnt; + int retval = 0; + for (cnt = 0; cnt < j->caps; cnt++) { + if (pcreq->captype == j->caplist[cnt].captype + && pcreq->cap == j->caplist[cnt].cap) { + retval = 1; + break; + } + } + return retval; +} + +static long do_ixj_ioctl(struct file *file_p, unsigned int cmd, unsigned long arg) +{ + IXJ_TONE ti; + IXJ_FILTER jf; + IXJ_FILTER_RAW jfr; + void __user *argp = (void __user *)arg; + struct inode *inode = file_p->f_path.dentry->d_inode; + unsigned int minor = iminor(inode); + unsigned int raise, mant; + int board = NUM(inode); + + IXJ *j = get_ixj(NUM(inode)); + + int retval = 0; + + /* + * Set up locks to ensure that only one process is talking to the DSP at a time. + * This is necessary to keep the DSP from locking up. + */ + while(test_and_set_bit(board, (void *)&j->busyflags) != 0) + schedule_timeout_interruptible(1); + if (ixjdebug & 0x0040) + printk("phone%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg); + if (minor >= IXJMAX) { + clear_bit(board, &j->busyflags); + return -ENODEV; + } + /* + * Check ioctls only root can use. + */ + if (!capable(CAP_SYS_ADMIN)) { + switch (cmd) { + case IXJCTL_TESTRAM: + case IXJCTL_HZ: + retval = -EPERM; + } + } + switch (cmd) { + case IXJCTL_TESTRAM: + ixj_testram(j); + retval = (j->ssr.high << 8) + j->ssr.low; + break; + case IXJCTL_CARDTYPE: + retval = j->cardtype; + break; + case IXJCTL_SERIAL: + retval = j->serial; + break; + case IXJCTL_VERSION: + { + char arg_str[100]; + snprintf(arg_str, sizeof(arg_str), + "\nDriver version %i.%i.%i", IXJ_VER_MAJOR, + IXJ_VER_MINOR, IXJ_BLD_VER); + if (copy_to_user(argp, arg_str, strlen(arg_str))) + retval = -EFAULT; + } + break; + case PHONE_RING_CADENCE: + j->ring_cadence = arg; + break; + case IXJCTL_CIDCW: + if(arg) { + if (copy_from_user(&j->cid_send, argp, sizeof(PHONE_CID))) { + retval = -EFAULT; + break; + } + } else { + memset(&j->cid_send, 0, sizeof(PHONE_CID)); + } + ixj_write_cidcw(j); + break; + /* Binary compatbility */ + case OLD_PHONE_RING_START: + arg = 0; + /* Fall through */ + case PHONE_RING_START: + if(arg) { + if (copy_from_user(&j->cid_send, argp, sizeof(PHONE_CID))) { + retval = -EFAULT; + break; + } + ixj_write_cid(j); + } else { + memset(&j->cid_send, 0, sizeof(PHONE_CID)); + } + ixj_ring_start(j); + break; + case PHONE_RING_STOP: + j->flags.cringing = 0; + if(j->cadence_f[5].enable) { + j->cadence_f[5].state = 0; + } + ixj_ring_off(j); + break; + case PHONE_RING: + retval = ixj_ring(j); + break; + case PHONE_EXCEPTION: + retval = j->ex.bytes; + if(j->ex.bits.flash) { + j->flash_end = 0; + j->ex.bits.flash = 0; + } + j->ex.bits.pstn_ring = 0; + j->ex.bits.caller_id = 0; + j->ex.bits.pstn_wink = 0; + j->ex.bits.f0 = 0; + j->ex.bits.f1 = 0; + j->ex.bits.f2 = 0; + j->ex.bits.f3 = 0; + j->ex.bits.fc0 = 0; + j->ex.bits.fc1 = 0; + j->ex.bits.fc2 = 0; + j->ex.bits.fc3 = 0; + j->ex.bits.reserved = 0; + break; + case PHONE_HOOKSTATE: + j->ex.bits.hookstate = 0; + retval = j->hookstate; //j->r_hook; + break; + case IXJCTL_SET_LED: + LED_SetState(arg, j); + break; + case PHONE_FRAME: + retval = set_base_frame(j, arg); + break; + case PHONE_REC_CODEC: + retval = set_rec_codec(j, arg); + break; + case PHONE_VAD: + ixj_vad(j, arg); + break; + case PHONE_REC_START: + ixj_record_start(j); + break; + case PHONE_REC_STOP: + ixj_record_stop(j); + break; + case PHONE_REC_DEPTH: + set_rec_depth(j, arg); + break; + case PHONE_REC_VOLUME: + if(arg == -1) { + retval = get_rec_volume(j); + } + else { + set_rec_volume(j, arg); + retval = arg; + } + break; + case PHONE_REC_VOLUME_LINEAR: + if(arg == -1) { + retval = get_rec_volume_linear(j); + } + else { + set_rec_volume_linear(j, arg); + retval = arg; + } + break; + case IXJCTL_DTMF_PRESCALE: + if(arg == -1) { + retval = get_dtmf_prescale(j); + } + else { + set_dtmf_prescale(j, arg); + retval = arg; + } + break; + case PHONE_REC_LEVEL: + retval = get_rec_level(j); + break; + case IXJCTL_SC_RXG: + retval = ixj_siadc(j, arg); + break; + case IXJCTL_SC_TXG: + retval = ixj_sidac(j, arg); + break; + case IXJCTL_AEC_START: + ixj_aec_start(j, arg); + break; + case IXJCTL_AEC_STOP: + aec_stop(j); + break; + case IXJCTL_AEC_GET_LEVEL: + retval = j->aec_level; + break; + case PHONE_PLAY_CODEC: + retval = set_play_codec(j, arg); + break; + case PHONE_PLAY_START: + retval = ixj_play_start(j); + break; + case PHONE_PLAY_STOP: + ixj_play_stop(j); + break; + case PHONE_PLAY_DEPTH: + set_play_depth(j, arg); + break; + case PHONE_PLAY_VOLUME: + if(arg == -1) { + retval = get_play_volume(j); + } + else { + set_play_volume(j, arg); + retval = arg; + } + break; + case PHONE_PLAY_VOLUME_LINEAR: + if(arg == -1) { + retval = get_play_volume_linear(j); + } + else { + set_play_volume_linear(j, arg); + retval = arg; + } + break; + case PHONE_PLAY_LEVEL: + retval = get_play_level(j); + break; + case IXJCTL_DSP_TYPE: + retval = (j->dsp.high << 8) + j->dsp.low; + break; + case IXJCTL_DSP_VERSION: + retval = (j->ver.high << 8) + j->ver.low; + break; + case IXJCTL_HZ: + hertz = arg; + break; + case IXJCTL_RATE: + if (arg > hertz) + retval = -1; + else + samplerate = arg; + break; + case IXJCTL_DRYBUFFER_READ: + put_user(j->drybuffer, (unsigned long __user *) argp); + break; + case IXJCTL_DRYBUFFER_CLEAR: + j->drybuffer = 0; + break; + case IXJCTL_FRAMES_READ: + put_user(j->framesread, (unsigned long __user *) argp); + break; + case IXJCTL_FRAMES_WRITTEN: + put_user(j->frameswritten, (unsigned long __user *) argp); + break; + case IXJCTL_READ_WAIT: + put_user(j->read_wait, (unsigned long __user *) argp); + break; + case IXJCTL_WRITE_WAIT: + put_user(j->write_wait, (unsigned long __user *) argp); + break; + case PHONE_MAXRINGS: + j->maxrings = arg; + break; + case PHONE_SET_TONE_ON_TIME: + ixj_set_tone_on(arg, j); + break; + case PHONE_SET_TONE_OFF_TIME: + ixj_set_tone_off(arg, j); + break; + case PHONE_GET_TONE_ON_TIME: + if (ixj_get_tone_on(j)) { + retval = -1; + } else { + retval = (j->ssr.high << 8) + j->ssr.low; + } + break; + case PHONE_GET_TONE_OFF_TIME: + if (ixj_get_tone_off(j)) { + retval = -1; + } else { + retval = (j->ssr.high << 8) + j->ssr.low; + } + break; + case PHONE_PLAY_TONE: + if (!j->tone_state) + retval = ixj_play_tone(j, arg); + else + retval = -1; + break; + case PHONE_GET_TONE_STATE: + retval = j->tone_state; + break; + case PHONE_DTMF_READY: + retval = j->ex.bits.dtmf_ready; + break; + case PHONE_GET_DTMF: + if (ixj_hookstate(j)) { + if (j->dtmf_rp != j->dtmf_wp) { + retval = j->dtmfbuffer[j->dtmf_rp]; + j->dtmf_rp++; + if (j->dtmf_rp == 79) + j->dtmf_rp = 0; + if (j->dtmf_rp == j->dtmf_wp) { + j->ex.bits.dtmf_ready = j->dtmf_rp = j->dtmf_wp = 0; + } + } + } + break; + case PHONE_GET_DTMF_ASCII: + if (ixj_hookstate(j)) { + if (j->dtmf_rp != j->dtmf_wp) { + switch (j->dtmfbuffer[j->dtmf_rp]) { + case 10: + retval = 42; /* '*'; */ + + break; + case 11: + retval = 48; /*'0'; */ + + break; + case 12: + retval = 35; /*'#'; */ + + break; + case 28: + retval = 65; /*'A'; */ + + break; + case 29: + retval = 66; /*'B'; */ + + break; + case 30: + retval = 67; /*'C'; */ + + break; + case 31: + retval = 68; /*'D'; */ + + break; + default: + retval = 48 + j->dtmfbuffer[j->dtmf_rp]; + break; + } + j->dtmf_rp++; + if (j->dtmf_rp == 79) + j->dtmf_rp = 0; + if(j->dtmf_rp == j->dtmf_wp) + { + j->ex.bits.dtmf_ready = j->dtmf_rp = j->dtmf_wp = 0; + } + } + } + break; + case PHONE_DTMF_OOB: + j->flags.dtmf_oob = arg; + break; + case PHONE_DIALTONE: + ixj_dialtone(j); + break; + case PHONE_BUSY: + ixj_busytone(j); + break; + case PHONE_RINGBACK: + ixj_ringback(j); + break; + case PHONE_WINK: + if(j->cardtype == QTI_PHONEJACK) + retval = -1; + else + retval = ixj_wink(j); + break; + case PHONE_CPT_STOP: + ixj_cpt_stop(j); + break; + case PHONE_QUERY_CODEC: + { + struct phone_codec_data pd; + int val; + int proto_size[] = { + -1, + 12, 10, 16, 9, 8, 48, 5, + 40, 40, 80, 40, 40, 6 + }; + if(copy_from_user(&pd, argp, sizeof(pd))) { + retval = -EFAULT; + break; + } + if(pd.type<1 || pd.type>13) { + retval = -EPROTONOSUPPORT; + break; + } + if(pd.typebaseframe.low) + { + case 0xA0:val=2*proto_size[pd.type];break; + case 0x50:val=proto_size[pd.type];break; + default:val=proto_size[pd.type]*3;break; + } + pd.buf_min=pd.buf_max=pd.buf_opt=val; + if(copy_to_user(argp, &pd, sizeof(pd))) + retval = -EFAULT; + break; + } + case IXJCTL_DSP_IDLE: + idle(j); + break; + case IXJCTL_MIXER: + if ((arg & 0xff) == 0xff) + retval = ixj_get_mixer(arg, j); + else + ixj_mixer(arg, j); + break; + case IXJCTL_DAA_COEFF_SET: + switch (arg) { + case DAA_US: + DAA_Coeff_US(j); + retval = ixj_daa_write(j); + break; + case DAA_UK: + DAA_Coeff_UK(j); + retval = ixj_daa_write(j); + break; + case DAA_FRANCE: + DAA_Coeff_France(j); + retval = ixj_daa_write(j); + break; + case DAA_GERMANY: + DAA_Coeff_Germany(j); + retval = ixj_daa_write(j); + break; + case DAA_AUSTRALIA: + DAA_Coeff_Australia(j); + retval = ixj_daa_write(j); + break; + case DAA_JAPAN: + DAA_Coeff_Japan(j); + retval = ixj_daa_write(j); + break; + default: + retval = 1; + break; + } + break; + case IXJCTL_DAA_AGAIN: + ixj_daa_cr4(j, arg | 0x02); + break; + case IXJCTL_PSTN_LINETEST: + retval = ixj_linetest(j); + break; + case IXJCTL_VMWI: + ixj_write_vmwi(j, arg); + break; + case IXJCTL_CID: + if (copy_to_user(argp, &j->cid, sizeof(PHONE_CID))) + retval = -EFAULT; + j->ex.bits.caller_id = 0; + break; + case IXJCTL_WINK_DURATION: + j->winktime = arg; + break; + case IXJCTL_PORT: + if (arg) + retval = ixj_set_port(j, arg); + else + retval = j->port; + break; + case IXJCTL_POTS_PSTN: + retval = ixj_set_pots(j, arg); + break; + case PHONE_CAPABILITIES: + add_caps(j); + retval = j->caps; + break; + case PHONE_CAPABILITIES_LIST: + add_caps(j); + if (copy_to_user(argp, j->caplist, sizeof(struct phone_capability) * j->caps)) + retval = -EFAULT; + break; + case PHONE_CAPABILITIES_CHECK: + { + struct phone_capability cap; + if (copy_from_user(&cap, argp, sizeof(cap))) + retval = -EFAULT; + else { + add_caps(j); + retval = capabilities_check(j, &cap); + } + } + break; + case PHONE_PSTN_SET_STATE: + daa_set_mode(j, arg); + break; + case PHONE_PSTN_GET_STATE: + retval = j->daa_mode; + j->ex.bits.pstn_ring = 0; + break; + case IXJCTL_SET_FILTER: + if (copy_from_user(&jf, argp, sizeof(jf))) + retval = -EFAULT; + else + retval = ixj_init_filter(j, &jf); + break; + case IXJCTL_SET_FILTER_RAW: + if (copy_from_user(&jfr, argp, sizeof(jfr))) + retval = -EFAULT; + else + retval = ixj_init_filter_raw(j, &jfr); + break; + case IXJCTL_GET_FILTER_HIST: + if(arg<0||arg>3) + retval = -EINVAL; + else + retval = j->filter_hist[arg]; + break; + case IXJCTL_INIT_TONE: + if (copy_from_user(&ti, argp, sizeof(ti))) + retval = -EFAULT; + else + retval = ixj_init_tone(j, &ti); + break; + case IXJCTL_TONE_CADENCE: + retval = ixj_build_cadence(j, argp); + break; + case IXJCTL_FILTER_CADENCE: + retval = ixj_build_filter_cadence(j, argp); + break; + case IXJCTL_SIGCTL: + if (copy_from_user(&j->sigdef, argp, sizeof(IXJ_SIGDEF))) { + retval = -EFAULT; + break; + } + j->ixj_signals[j->sigdef.event] = j->sigdef.signal; + if(j->sigdef.event < 33) { + raise = 1; + for(mant = 0; mant < j->sigdef.event; mant++){ + raise *= 2; + } + if(j->sigdef.signal) + j->ex_sig.bytes |= raise; + else + j->ex_sig.bytes &= (raise^0xffff); + } + break; + case IXJCTL_INTERCOM_STOP: + if(arg < 0 || arg >= IXJMAX) + return -EINVAL; + j->intercom = -1; + ixj_record_stop(j); + ixj_play_stop(j); + idle(j); + get_ixj(arg)->intercom = -1; + ixj_record_stop(get_ixj(arg)); + ixj_play_stop(get_ixj(arg)); + idle(get_ixj(arg)); + break; + case IXJCTL_INTERCOM_START: + if(arg < 0 || arg >= IXJMAX) + return -EINVAL; + j->intercom = arg; + ixj_record_start(j); + ixj_play_start(j); + get_ixj(arg)->intercom = board; + ixj_play_start(get_ixj(arg)); + ixj_record_start(get_ixj(arg)); + break; + } + if (ixjdebug & 0x0040) + printk("phone%d ioctl end, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg); + clear_bit(board, &j->busyflags); + return retval; +} + +static long ixj_ioctl(struct file *file_p, unsigned int cmd, unsigned long arg) +{ + long ret; + mutex_lock(&ixj_mutex); + ret = do_ixj_ioctl(file_p, cmd, arg); + mutex_unlock(&ixj_mutex); + return ret; +} + +static int ixj_fasync(int fd, struct file *file_p, int mode) +{ + IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode)); + + return fasync_helper(fd, file_p, mode, &j->async_queue); +} + +static const struct file_operations ixj_fops = +{ + .owner = THIS_MODULE, + .read = ixj_enhanced_read, + .write = ixj_enhanced_write, + .poll = ixj_poll, + .unlocked_ioctl = ixj_ioctl, + .release = ixj_release, + .fasync = ixj_fasync, + .llseek = default_llseek, +}; + +static int ixj_linetest(IXJ *j) +{ + j->flags.pstncheck = 1; /* Testing */ + j->flags.pstn_present = 0; /* Assume the line is not there */ + + daa_int_read(j); /*Clear DAA Interrupt flags */ + /* */ + /* Hold all relays in the normally de-energized position. */ + /* */ + + j->pld_slicw.bits.rly1 = 0; + j->pld_slicw.bits.rly2 = 0; + j->pld_slicw.bits.rly3 = 0; + outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); + j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ + + outb_p(j->pld_scrw.byte, j->XILINXbase); + j->pld_slicr.byte = inb_p(j->XILINXbase + 0x01); + if (j->pld_slicr.bits.potspstn) { + j->flags.pots_pstn = 1; + j->flags.pots_correct = 0; + LED_SetState(0x4, j); + } else { + j->flags.pots_pstn = 0; + j->pld_slicw.bits.rly1 = 0; + j->pld_slicw.bits.rly2 = 0; + j->pld_slicw.bits.rly3 = 1; + outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); + j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ + + outb_p(j->pld_scrw.byte, j->XILINXbase); + daa_set_mode(j, SOP_PU_CONVERSATION); + msleep(1000); + daa_int_read(j); + daa_set_mode(j, SOP_PU_RESET); + if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) { + j->flags.pots_correct = 0; /* Should not be line voltage on POTS port. */ + LED_SetState(0x4, j); + j->pld_slicw.bits.rly3 = 0; + outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); + } else { + j->flags.pots_correct = 1; + LED_SetState(0x8, j); + j->pld_slicw.bits.rly1 = 1; + j->pld_slicw.bits.rly2 = 0; + j->pld_slicw.bits.rly3 = 0; + outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); + } + } + j->pld_slicw.bits.rly3 = 0; + outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); + daa_set_mode(j, SOP_PU_CONVERSATION); + msleep(1000); + daa_int_read(j); + daa_set_mode(j, SOP_PU_RESET); + if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) { + j->pstn_sleeptil = jiffies + (hertz / 4); + j->flags.pstn_present = 1; + } else { + j->flags.pstn_present = 0; + } + if (j->flags.pstn_present) { + if (j->flags.pots_correct) { + LED_SetState(0xA, j); + } else { + LED_SetState(0x6, j); + } + } else { + if (j->flags.pots_correct) { + LED_SetState(0x9, j); + } else { + LED_SetState(0x5, j); + } + } + j->flags.pstncheck = 0; /* Testing */ + return j->flags.pstn_present; +} + +static int ixj_selfprobe(IXJ *j) +{ + unsigned short cmd; + int cnt; + BYTES bytes; + + init_waitqueue_head(&j->poll_q); + init_waitqueue_head(&j->read_q); + init_waitqueue_head(&j->write_q); + + while(atomic_read(&j->DSPWrite) > 0) + atomic_dec(&j->DSPWrite); + if (ixjdebug & 0x0002) + printk(KERN_INFO "Write IDLE to Software Control Register\n"); + ixj_WriteDSPCommand(0x0FE0, j); /* Put the DSP in full power mode. */ + + if (ixj_WriteDSPCommand(0x0000, j)) /* Write IDLE to Software Control Register */ + return -1; +/* The read values of the SSR should be 0x00 for the IDLE command */ + if (j->ssr.low || j->ssr.high) + return -1; + if (ixjdebug & 0x0002) + printk(KERN_INFO "Get Device ID Code\n"); + if (ixj_WriteDSPCommand(0x3400, j)) /* Get Device ID Code */ + return -1; + j->dsp.low = j->ssr.low; + j->dsp.high = j->ssr.high; + if (ixjdebug & 0x0002) + printk(KERN_INFO "Get Device Version Code\n"); + if (ixj_WriteDSPCommand(0x3800, j)) /* Get Device Version Code */ + return -1; + j->ver.low = j->ssr.low; + j->ver.high = j->ssr.high; + if (!j->cardtype) { + if (j->dsp.low == 0x21) { + bytes.high = bytes.low = inb_p(j->XILINXbase + 0x02); + outb_p(bytes.low ^ 0xFF, j->XILINXbase + 0x02); +/* Test for Internet LineJACK or Internet PhoneJACK Lite */ + bytes.low = inb_p(j->XILINXbase + 0x02); + if (bytes.low == bytes.high) /* Register is read only on */ + /* Internet PhoneJack Lite */ + { + j->cardtype = QTI_PHONEJACK_LITE; + if (!request_region(j->XILINXbase, 4, "ixj control")) { + printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase); + return -1; + } + j->pld_slicw.pcib.e1 = 1; + outb_p(j->pld_slicw.byte, j->XILINXbase); + } else { + j->cardtype = QTI_LINEJACK; + + if (!request_region(j->XILINXbase, 8, "ixj control")) { + printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase); + return -1; + } + } + } else if (j->dsp.low == 0x22) { + j->cardtype = QTI_PHONEJACK_PCI; + request_region(j->XILINXbase, 4, "ixj control"); + j->pld_slicw.pcib.e1 = 1; + outb_p(j->pld_slicw.byte, j->XILINXbase); + } else + j->cardtype = QTI_PHONEJACK; + } else { + switch (j->cardtype) { + case QTI_PHONEJACK: + if (!j->dsp.low != 0x20) { + j->dsp.high = 0x80; + j->dsp.low = 0x20; + ixj_WriteDSPCommand(0x3800, j); + j->ver.low = j->ssr.low; + j->ver.high = j->ssr.high; + } + break; + case QTI_LINEJACK: + if (!request_region(j->XILINXbase, 8, "ixj control")) { + printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase); + return -1; + } + break; + case QTI_PHONEJACK_LITE: + case QTI_PHONEJACK_PCI: + if (!request_region(j->XILINXbase, 4, "ixj control")) { + printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase); + return -1; + } + j->pld_slicw.pcib.e1 = 1; + outb_p(j->pld_slicw.byte, j->XILINXbase); + break; + case QTI_PHONECARD: + break; + } + } + if (j->dsp.low == 0x20 || j->cardtype == QTI_PHONEJACK_LITE || j->cardtype == QTI_PHONEJACK_PCI) { + if (ixjdebug & 0x0002) + printk(KERN_INFO "Write CODEC config to Software Control Register\n"); + if (ixj_WriteDSPCommand(0xC462, j)) /* Write CODEC config to Software Control Register */ + return -1; + if (ixjdebug & 0x0002) + printk(KERN_INFO "Write CODEC timing to Software Control Register\n"); + if (j->cardtype == QTI_PHONEJACK) { + cmd = 0x9FF2; + } else { + cmd = 0x9FF5; + } + if (ixj_WriteDSPCommand(cmd, j)) /* Write CODEC timing to Software Control Register */ + return -1; + } else { + if (set_base_frame(j, 30) != 30) + return -1; + if (ixjdebug & 0x0002) + printk(KERN_INFO "Write CODEC config to Software Control Register\n"); + if (j->cardtype == QTI_PHONECARD) { + if (ixj_WriteDSPCommand(0xC528, j)) /* Write CODEC config to Software Control Register */ + return -1; + } + if (j->cardtype == QTI_LINEJACK) { + if (ixj_WriteDSPCommand(0xC528, j)) /* Write CODEC config to Software Control Register */ + return -1; + if (ixjdebug & 0x0002) + printk(KERN_INFO "Turn on the PLD Clock at 8Khz\n"); + j->pld_clock.byte = 0; + outb_p(j->pld_clock.byte, j->XILINXbase + 0x04); + } + } + + if (j->dsp.low == 0x20) { + if (ixjdebug & 0x0002) + printk(KERN_INFO "Configure GPIO pins\n"); + j->gpio.bytes.high = 0x09; +/* bytes.low = 0xEF; 0xF7 */ + j->gpio.bits.gpio1 = 1; + j->gpio.bits.gpio2 = 1; + j->gpio.bits.gpio3 = 0; + j->gpio.bits.gpio4 = 1; + j->gpio.bits.gpio5 = 1; + j->gpio.bits.gpio6 = 1; + j->gpio.bits.gpio7 = 1; + ixj_WriteDSPCommand(j->gpio.word, j); /* Set GPIO pin directions */ + if (ixjdebug & 0x0002) + printk(KERN_INFO "Enable SLIC\n"); + j->gpio.bytes.high = 0x0B; + j->gpio.bytes.low = 0x00; + j->gpio.bits.gpio1 = 0; + j->gpio.bits.gpio2 = 1; + j->gpio.bits.gpio5 = 0; + ixj_WriteDSPCommand(j->gpio.word, j); /* send the ring stop signal */ + j->port = PORT_POTS; + } else { + if (j->cardtype == QTI_LINEJACK) { + LED_SetState(0x1, j); + msleep(100); + LED_SetState(0x2, j); + msleep(100); + LED_SetState(0x4, j); + msleep(100); + LED_SetState(0x8, j); + msleep(100); + LED_SetState(0x0, j); + daa_get_version(j); + if (ixjdebug & 0x0002) + printk("Loading DAA Coefficients\n"); + DAA_Coeff_US(j); + if (!ixj_daa_write(j)) { + printk("DAA write failed on board %d\n", j->board); + return -1; + } + if(!ixj_daa_cid_reset(j)) { + printk("DAA CID reset failed on board %d\n", j->board); + return -1; + } + j->flags.pots_correct = 0; + j->flags.pstn_present = 0; + ixj_linetest(j); + if (j->flags.pots_correct) { + j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ + + outb_p(j->pld_scrw.byte, j->XILINXbase); + j->pld_slicw.bits.rly1 = 1; + j->pld_slicw.bits.spken = 1; + outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); + SLIC_SetState(PLD_SLIC_STATE_STANDBY, j); +/* SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); */ + j->port = PORT_POTS; + } + ixj_set_port(j, PORT_PSTN); + ixj_set_pots(j, 1); + if (ixjdebug & 0x0002) + printk(KERN_INFO "Enable Mixer\n"); + ixj_mixer(0x0000, j); /*Master Volume Left unmute 0db */ + ixj_mixer(0x0100, j); /*Master Volume Right unmute 0db */ + + ixj_mixer(0x0203, j); /*Voice Left Volume unmute 6db */ + ixj_mixer(0x0303, j); /*Voice Right Volume unmute 6db */ + + ixj_mixer(0x0480, j); /*FM Left mute */ + ixj_mixer(0x0580, j); /*FM Right mute */ + + ixj_mixer(0x0680, j); /*CD Left mute */ + ixj_mixer(0x0780, j); /*CD Right mute */ + + ixj_mixer(0x0880, j); /*Line Left mute */ + ixj_mixer(0x0980, j); /*Line Right mute */ + + ixj_mixer(0x0A80, j); /*Aux left mute */ + ixj_mixer(0x0B80, j); /*Aux right mute */ + + ixj_mixer(0x0C00, j); /*Mono1 unmute 12db */ + ixj_mixer(0x0D80, j); /*Mono2 mute */ + + ixj_mixer(0x0E80, j); /*Mic mute */ + + ixj_mixer(0x0F00, j); /*Mono Out Volume unmute 0db */ + + ixj_mixer(0x1000, j); /*Voice Left and Right out only */ + ixj_mixer(0x110C, j); + + + ixj_mixer(0x1200, j); /*Mono1 switch on mixer left */ + ixj_mixer(0x1401, j); + + ixj_mixer(0x1300, j); /*Mono1 switch on mixer right */ + ixj_mixer(0x1501, j); + + ixj_mixer(0x1700, j); /*Clock select */ + + ixj_mixer(0x1800, j); /*ADC input from mixer */ + + ixj_mixer(0x1901, j); /*Mic gain 30db */ + + if (ixjdebug & 0x0002) + printk(KERN_INFO "Setting Default US Ring Cadence Detection\n"); + j->cadence_f[4].state = 0; + j->cadence_f[4].on1 = 0; /*Cadence Filter 4 is used for PSTN ring cadence */ + j->cadence_f[4].off1 = 0; + j->cadence_f[4].on2 = 0; + j->cadence_f[4].off2 = 0; + j->cadence_f[4].on3 = 0; + j->cadence_f[4].off3 = 0; /* These should represent standard US ring pulse. */ + j->pstn_last_rmr = jiffies; + + } else { + if (j->cardtype == QTI_PHONECARD) { + ixj_WriteDSPCommand(0xCF07, j); + ixj_WriteDSPCommand(0x00B0, j); + ixj_set_port(j, PORT_SPEAKER); + } else { + ixj_set_port(j, PORT_POTS); + SLIC_SetState(PLD_SLIC_STATE_STANDBY, j); +/* SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); */ + } + } + } + + j->intercom = -1; + j->framesread = j->frameswritten = 0; + j->read_wait = j->write_wait = 0; + j->rxreadycheck = j->txreadycheck = 0; + + /* initialise the DTMF prescale to a sensible value */ + if (j->cardtype == QTI_LINEJACK) { + set_dtmf_prescale(j, 0x10); + } else { + set_dtmf_prescale(j, 0x40); + } + set_play_volume(j, 0x100); + set_rec_volume(j, 0x100); + + if (ixj_WriteDSPCommand(0x0000, j)) /* Write IDLE to Software Control Register */ + return -1; +/* The read values of the SSR should be 0x00 for the IDLE command */ + if (j->ssr.low || j->ssr.high) + return -1; + + if (ixjdebug & 0x0002) + printk(KERN_INFO "Enable Line Monitor\n"); + + if (ixjdebug & 0x0002) + printk(KERN_INFO "Set Line Monitor to Asyncronous Mode\n"); + + if (ixj_WriteDSPCommand(0x7E01, j)) /* Asynchronous Line Monitor */ + return -1; + + if (ixjdebug & 0x002) + printk(KERN_INFO "Enable DTMF Detectors\n"); + + if (ixj_WriteDSPCommand(0x5151, j)) /* Enable DTMF detection */ + return -1; + + if (ixj_WriteDSPCommand(0x6E01, j)) /* Set Asyncronous Tone Generation */ + return -1; + + set_rec_depth(j, 2); /* Set Record Channel Limit to 2 frames */ + + set_play_depth(j, 2); /* Set Playback Channel Limit to 2 frames */ + + j->ex.bits.dtmf_ready = 0; + j->dtmf_state = 0; + j->dtmf_wp = j->dtmf_rp = 0; + j->rec_mode = j->play_mode = -1; + j->flags.ringing = 0; + j->maxrings = MAXRINGS; + j->ring_cadence = USA_RING_CADENCE; + j->drybuffer = 0; + j->winktime = 320; + j->flags.dtmf_oob = 0; + for (cnt = 0; cnt < 4; cnt++) + j->cadence_f[cnt].enable = 0; + /* must be a device on the specified address */ + ixj_WriteDSPCommand(0x0FE3, j); /* Put the DSP in 1/5 power mode. */ + + /* Set up the default signals for events */ + for (cnt = 0; cnt < 35; cnt++) + j->ixj_signals[cnt] = SIGIO; + + /* Set the excetion signal enable flags */ + j->ex_sig.bits.dtmf_ready = j->ex_sig.bits.hookstate = j->ex_sig.bits.flash = j->ex_sig.bits.pstn_ring = + j->ex_sig.bits.caller_id = j->ex_sig.bits.pstn_wink = j->ex_sig.bits.f0 = j->ex_sig.bits.f1 = j->ex_sig.bits.f2 = + j->ex_sig.bits.f3 = j->ex_sig.bits.fc0 = j->ex_sig.bits.fc1 = j->ex_sig.bits.fc2 = j->ex_sig.bits.fc3 = 1; +#ifdef IXJ_DYN_ALLOC + j->fskdata = NULL; +#endif + j->fskdcnt = 0; + j->cidcw_wait = 0; + + /* Register with the Telephony for Linux subsystem */ + j->p.f_op = &ixj_fops; + j->p.open = ixj_open; + j->p.board = j->board; + phone_register_device(&j->p, PHONE_UNIT_ANY); + + ixj_init_timer(j); + ixj_add_timer(j); + return 0; +} + +/* + * Exported service for pcmcia card handling + */ + +IXJ *ixj_pcmcia_probe(unsigned long dsp, unsigned long xilinx) +{ + IXJ *j = ixj_alloc(); + + j->board = 0; + + j->DSPbase = dsp; + j->XILINXbase = xilinx; + j->cardtype = QTI_PHONECARD; + ixj_selfprobe(j); + return j; +} + +EXPORT_SYMBOL(ixj_pcmcia_probe); /* Fpr PCMCIA */ + +static int ixj_get_status_proc(char *buf) +{ + int len; + int cnt; + IXJ *j; + len = 0; + len += sprintf(buf + len, "\nDriver version %i.%i.%i", IXJ_VER_MAJOR, IXJ_VER_MINOR, IXJ_BLD_VER); + len += sprintf(buf + len, "\nsizeof IXJ struct %Zd bytes", sizeof(IXJ)); + len += sprintf(buf + len, "\nsizeof DAA struct %Zd bytes", sizeof(DAA_REGS)); + len += sprintf(buf + len, "\nUsing old telephony API"); + len += sprintf(buf + len, "\nDebug Level %d\n", ixjdebug); + + for (cnt = 0; cnt < IXJMAX; cnt++) { + j = get_ixj(cnt); + if(j==NULL) + continue; + if (j->DSPbase) { + len += sprintf(buf + len, "\nCard Num %d", cnt); + len += sprintf(buf + len, "\nDSP Base Address 0x%4.4x", j->DSPbase); + if (j->cardtype != QTI_PHONEJACK) + len += sprintf(buf + len, "\nXILINX Base Address 0x%4.4x", j->XILINXbase); + len += sprintf(buf + len, "\nDSP Type %2.2x%2.2x", j->dsp.high, j->dsp.low); + len += sprintf(buf + len, "\nDSP Version %2.2x.%2.2x", j->ver.high, j->ver.low); + len += sprintf(buf + len, "\nSerial Number %8.8x", j->serial); + switch (j->cardtype) { + case (QTI_PHONEJACK): + len += sprintf(buf + len, "\nCard Type = Internet PhoneJACK"); + break; + case (QTI_LINEJACK): + len += sprintf(buf + len, "\nCard Type = Internet LineJACK"); + if (j->flags.g729_loaded) + len += sprintf(buf + len, " w/G.729 A/B"); + len += sprintf(buf + len, " Country = %d", j->daa_country); + break; + case (QTI_PHONEJACK_LITE): + len += sprintf(buf + len, "\nCard Type = Internet PhoneJACK Lite"); + if (j->flags.g729_loaded) + len += sprintf(buf + len, " w/G.729 A/B"); + break; + case (QTI_PHONEJACK_PCI): + len += sprintf(buf + len, "\nCard Type = Internet PhoneJACK PCI"); + if (j->flags.g729_loaded) + len += sprintf(buf + len, " w/G.729 A/B"); + break; + case (QTI_PHONECARD): + len += sprintf(buf + len, "\nCard Type = Internet PhoneCARD"); + if (j->flags.g729_loaded) + len += sprintf(buf + len, " w/G.729 A/B"); + len += sprintf(buf + len, "\nSmart Cable %spresent", j->pccr1.bits.drf ? "not " : ""); + if (!j->pccr1.bits.drf) + len += sprintf(buf + len, "\nSmart Cable type %d", j->flags.pcmciasct); + len += sprintf(buf + len, "\nSmart Cable state %d", j->flags.pcmciastate); + break; + default: + len += sprintf(buf + len, "\nCard Type = %d", j->cardtype); + break; + } + len += sprintf(buf + len, "\nReaders %d", j->readers); + len += sprintf(buf + len, "\nWriters %d", j->writers); + add_caps(j); + len += sprintf(buf + len, "\nCapabilities %d", j->caps); + if (j->dsp.low != 0x20) + len += sprintf(buf + len, "\nDSP Processor load %d", j->proc_load); + if (j->flags.cidsent) + len += sprintf(buf + len, "\nCaller ID data sent"); + else + len += sprintf(buf + len, "\nCaller ID data not sent"); + + len += sprintf(buf + len, "\nPlay CODEC "); + switch (j->play_codec) { + case G723_63: + len += sprintf(buf + len, "G.723.1 6.3"); + break; + case G723_53: + len += sprintf(buf + len, "G.723.1 5.3"); + break; + case TS85: + len += sprintf(buf + len, "TrueSpeech 8.5"); + break; + case TS48: + len += sprintf(buf + len, "TrueSpeech 4.8"); + break; + case TS41: + len += sprintf(buf + len, "TrueSpeech 4.1"); + break; + case G728: + len += sprintf(buf + len, "G.728"); + break; + case G729: + len += sprintf(buf + len, "G.729"); + break; + case G729B: + len += sprintf(buf + len, "G.729B"); + break; + case ULAW: + len += sprintf(buf + len, "uLaw"); + break; + case ALAW: + len += sprintf(buf + len, "aLaw"); + break; + case LINEAR16: + len += sprintf(buf + len, "16 bit Linear"); + break; + case LINEAR8: + len += sprintf(buf + len, "8 bit Linear"); + break; + case WSS: + len += sprintf(buf + len, "Windows Sound System"); + break; + default: + len += sprintf(buf + len, "NO CODEC CHOSEN"); + break; + } + len += sprintf(buf + len, "\nRecord CODEC "); + switch (j->rec_codec) { + case G723_63: + len += sprintf(buf + len, "G.723.1 6.3"); + break; + case G723_53: + len += sprintf(buf + len, "G.723.1 5.3"); + break; + case TS85: + len += sprintf(buf + len, "TrueSpeech 8.5"); + break; + case TS48: + len += sprintf(buf + len, "TrueSpeech 4.8"); + break; + case TS41: + len += sprintf(buf + len, "TrueSpeech 4.1"); + break; + case G728: + len += sprintf(buf + len, "G.728"); + break; + case G729: + len += sprintf(buf + len, "G.729"); + break; + case G729B: + len += sprintf(buf + len, "G.729B"); + break; + case ULAW: + len += sprintf(buf + len, "uLaw"); + break; + case ALAW: + len += sprintf(buf + len, "aLaw"); + break; + case LINEAR16: + len += sprintf(buf + len, "16 bit Linear"); + break; + case LINEAR8: + len += sprintf(buf + len, "8 bit Linear"); + break; + case WSS: + len += sprintf(buf + len, "Windows Sound System"); + break; + default: + len += sprintf(buf + len, "NO CODEC CHOSEN"); + break; + } + len += sprintf(buf + len, "\nAEC "); + switch (j->aec_level) { + case AEC_OFF: + len += sprintf(buf + len, "Off"); + break; + case AEC_LOW: + len += sprintf(buf + len, "Low"); + break; + case AEC_MED: + len += sprintf(buf + len, "Med"); + break; + case AEC_HIGH: + len += sprintf(buf + len, "High"); + break; + case AEC_AUTO: + len += sprintf(buf + len, "Auto"); + break; + case AEC_AGC: + len += sprintf(buf + len, "AEC/AGC"); + break; + default: + len += sprintf(buf + len, "unknown(%i)", j->aec_level); + break; + } + + len += sprintf(buf + len, "\nRec volume 0x%x", get_rec_volume(j)); + len += sprintf(buf + len, "\nPlay volume 0x%x", get_play_volume(j)); + len += sprintf(buf + len, "\nDTMF prescale 0x%x", get_dtmf_prescale(j)); + + len += sprintf(buf + len, "\nHook state %d", j->hookstate); /* j->r_hook); */ + + if (j->cardtype == QTI_LINEJACK) { + len += sprintf(buf + len, "\nPOTS Correct %d", j->flags.pots_correct); + len += sprintf(buf + len, "\nPSTN Present %d", j->flags.pstn_present); + len += sprintf(buf + len, "\nPSTN Check %d", j->flags.pstncheck); + len += sprintf(buf + len, "\nPOTS to PSTN %d", j->flags.pots_pstn); + switch (j->daa_mode) { + case SOP_PU_SLEEP: + len += sprintf(buf + len, "\nDAA PSTN On Hook"); + break; + case SOP_PU_RINGING: + len += sprintf(buf + len, "\nDAA PSTN Ringing"); + len += sprintf(buf + len, "\nRinging state = %d", j->cadence_f[4].state); + break; + case SOP_PU_CONVERSATION: + len += sprintf(buf + len, "\nDAA PSTN Off Hook"); + break; + case SOP_PU_PULSEDIALING: + len += sprintf(buf + len, "\nDAA PSTN Pulse Dialing"); + break; + } + len += sprintf(buf + len, "\nDAA RMR = %d", j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR); + len += sprintf(buf + len, "\nDAA VDD OK = %d", j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK); + len += sprintf(buf + len, "\nDAA CR0 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg); + len += sprintf(buf + len, "\nDAA CR1 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg); + len += sprintf(buf + len, "\nDAA CR2 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg); + len += sprintf(buf + len, "\nDAA CR3 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg); + len += sprintf(buf + len, "\nDAA CR4 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg); + len += sprintf(buf + len, "\nDAA CR5 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg); + len += sprintf(buf + len, "\nDAA XR0 = 0x%02x", j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg); + len += sprintf(buf + len, "\nDAA ringstop %ld - jiffies %ld", j->pstn_ring_stop, jiffies); + } + switch (j->port) { + case PORT_POTS: + len += sprintf(buf + len, "\nPort POTS"); + break; + case PORT_PSTN: + len += sprintf(buf + len, "\nPort PSTN"); + break; + case PORT_SPEAKER: + len += sprintf(buf + len, "\nPort SPEAKER/MIC"); + break; + case PORT_HANDSET: + len += sprintf(buf + len, "\nPort HANDSET"); + break; + } + if (j->dsp.low == 0x21 || j->dsp.low == 0x22) { + len += sprintf(buf + len, "\nSLIC state "); + switch (SLIC_GetState(j)) { + case PLD_SLIC_STATE_OC: + len += sprintf(buf + len, "OC"); + break; + case PLD_SLIC_STATE_RINGING: + len += sprintf(buf + len, "RINGING"); + break; + case PLD_SLIC_STATE_ACTIVE: + len += sprintf(buf + len, "ACTIVE"); + break; + case PLD_SLIC_STATE_OHT: /* On-hook transmit */ + len += sprintf(buf + len, "OHT"); + break; + case PLD_SLIC_STATE_TIPOPEN: + len += sprintf(buf + len, "TIPOPEN"); + break; + case PLD_SLIC_STATE_STANDBY: + len += sprintf(buf + len, "STANDBY"); + break; + case PLD_SLIC_STATE_APR: /* Active polarity reversal */ + len += sprintf(buf + len, "APR"); + break; + case PLD_SLIC_STATE_OHTPR: /* OHT polarity reversal */ + len += sprintf(buf + len, "OHTPR"); + break; + default: + len += sprintf(buf + len, "%d", SLIC_GetState(j)); + break; + } + } + len += sprintf(buf + len, "\nBase Frame %2.2x.%2.2x", j->baseframe.high, j->baseframe.low); + len += sprintf(buf + len, "\nCID Base Frame %2d", j->cid_base_frame_size); +#ifdef PERFMON_STATS + len += sprintf(buf + len, "\nTimer Checks %ld", j->timerchecks); + len += sprintf(buf + len, "\nRX Ready Checks %ld", j->rxreadycheck); + len += sprintf(buf + len, "\nTX Ready Checks %ld", j->txreadycheck); + len += sprintf(buf + len, "\nFrames Read %ld", j->framesread); + len += sprintf(buf + len, "\nFrames Written %ld", j->frameswritten); + len += sprintf(buf + len, "\nDry Buffer %ld", j->drybuffer); + len += sprintf(buf + len, "\nRead Waits %ld", j->read_wait); + len += sprintf(buf + len, "\nWrite Waits %ld", j->write_wait); + len += sprintf(buf + len, "\nStatus Waits %ld", j->statuswait); + len += sprintf(buf + len, "\nStatus Wait Fails %ld", j->statuswaitfail); + len += sprintf(buf + len, "\nPControl Waits %ld", j->pcontrolwait); + len += sprintf(buf + len, "\nPControl Wait Fails %ld", j->pcontrolwaitfail); + len += sprintf(buf + len, "\nIs Control Ready Checks %ld", j->iscontrolready); + len += sprintf(buf + len, "\nIs Control Ready Check failures %ld", j->iscontrolreadyfail); + +#endif + len += sprintf(buf + len, "\n"); + } + } + return len; +} + +static int ixj_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = ixj_get_status_proc(page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + return len; +} + + +static void cleanup(void) +{ + int cnt; + IXJ *j; + + for (cnt = 0; cnt < IXJMAX; cnt++) { + j = get_ixj(cnt); + if(j != NULL && j->DSPbase) { + if (ixjdebug & 0x0002) + printk(KERN_INFO "IXJ: Deleting timer for /dev/phone%d\n", cnt); + del_timer(&j->timer); + if (j->cardtype == QTI_LINEJACK) { + j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ + + outb_p(j->pld_scrw.byte, j->XILINXbase); + j->pld_slicw.bits.rly1 = 0; + j->pld_slicw.bits.rly2 = 0; + j->pld_slicw.bits.rly3 = 0; + outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); + LED_SetState(0x0, j); + if (ixjdebug & 0x0002) + printk(KERN_INFO "IXJ: Releasing XILINX address for /dev/phone%d\n", cnt); + release_region(j->XILINXbase, 8); + } else if (j->cardtype == QTI_PHONEJACK_LITE || j->cardtype == QTI_PHONEJACK_PCI) { + if (ixjdebug & 0x0002) + printk(KERN_INFO "IXJ: Releasing XILINX address for /dev/phone%d\n", cnt); + release_region(j->XILINXbase, 4); + } + kfree(j->read_buffer); + kfree(j->write_buffer); + if (j->dev) + pnp_device_detach(j->dev); + if (ixjdebug & 0x0002) + printk(KERN_INFO "IXJ: Unregistering /dev/phone%d from LTAPI\n", cnt); + phone_unregister_device(&j->p); + if (ixjdebug & 0x0002) + printk(KERN_INFO "IXJ: Releasing DSP address for /dev/phone%d\n", cnt); + release_region(j->DSPbase, 16); +#ifdef IXJ_DYN_ALLOC + if (ixjdebug & 0x0002) + printk(KERN_INFO "IXJ: Freeing memory for /dev/phone%d\n", cnt); + kfree(j); + ixj[cnt] = NULL; +#endif + } + } + if (ixjdebug & 0x0002) + printk(KERN_INFO "IXJ: Removing /proc/ixj\n"); + remove_proc_entry ("ixj", NULL); +} + +/* Typedefs */ +typedef struct { + BYTE length; + DWORD bits; +} DATABLOCK; + +static void PCIEE_WriteBit(WORD wEEPROMAddress, BYTE lastLCC, BYTE byData) +{ + lastLCC = lastLCC & 0xfb; + lastLCC = lastLCC | (byData ? 4 : 0); + outb(lastLCC, wEEPROMAddress); /*set data out bit as appropriate */ + + mdelay(1); + lastLCC = lastLCC | 0x01; + outb(lastLCC, wEEPROMAddress); /*SK rising edge */ + + byData = byData << 1; + lastLCC = lastLCC & 0xfe; + mdelay(1); + outb(lastLCC, wEEPROMAddress); /*after delay, SK falling edge */ + +} + +static BYTE PCIEE_ReadBit(WORD wEEPROMAddress, BYTE lastLCC) +{ + mdelay(1); + lastLCC = lastLCC | 0x01; + outb(lastLCC, wEEPROMAddress); /*SK rising edge */ + + lastLCC = lastLCC & 0xfe; + mdelay(1); + outb(lastLCC, wEEPROMAddress); /*after delay, SK falling edge */ + + return ((inb(wEEPROMAddress) >> 3) & 1); +} + +static bool PCIEE_ReadWord(WORD wAddress, WORD wLoc, WORD * pwResult) +{ + BYTE lastLCC; + WORD wEEPROMAddress = wAddress + 3; + DWORD i; + BYTE byResult; + *pwResult = 0; + lastLCC = inb(wEEPROMAddress); + lastLCC = lastLCC | 0x02; + lastLCC = lastLCC & 0xfe; + outb(lastLCC, wEEPROMAddress); /* CS hi, SK lo */ + + mdelay(1); /* delay */ + + PCIEE_WriteBit(wEEPROMAddress, lastLCC, 1); + PCIEE_WriteBit(wEEPROMAddress, lastLCC, 1); + PCIEE_WriteBit(wEEPROMAddress, lastLCC, 0); + for (i = 0; i < 8; i++) { + PCIEE_WriteBit(wEEPROMAddress, lastLCC, wLoc & 0x80 ? 1 : 0); + wLoc <<= 1; + } + + for (i = 0; i < 16; i++) { + byResult = PCIEE_ReadBit(wEEPROMAddress, lastLCC); + *pwResult = (*pwResult << 1) | byResult; + } + + mdelay(1); /* another delay */ + + lastLCC = lastLCC & 0xfd; + outb(lastLCC, wEEPROMAddress); /* negate CS */ + + return 0; +} + +static DWORD PCIEE_GetSerialNumber(WORD wAddress) +{ + WORD wLo, wHi; + if (PCIEE_ReadWord(wAddress, 62, &wLo)) + return 0; + if (PCIEE_ReadWord(wAddress, 63, &wHi)) + return 0; + return (((DWORD) wHi << 16) | wLo); +} + +static int dspio[IXJMAX + 1] = +{ + 0, +}; +static int xio[IXJMAX + 1] = +{ + 0, +}; + +module_param_array(dspio, int, NULL, 0); +module_param_array(xio, int, NULL, 0); +MODULE_DESCRIPTION("Quicknet VoIP Telephony card module - www.quicknet.net"); +MODULE_AUTHOR("Ed Okerson "); +MODULE_LICENSE("GPL"); + +static void __exit ixj_exit(void) +{ + cleanup(); +} + +static IXJ *new_ixj(unsigned long port) +{ + IXJ *res; + if (!request_region(port, 16, "ixj DSP")) { + printk(KERN_INFO "ixj: can't get I/O address 0x%lx\n", port); + return NULL; + } + res = ixj_alloc(); + if (!res) { + release_region(port, 16); + printk(KERN_INFO "ixj: out of memory\n"); + return NULL; + } + res->DSPbase = port; + return res; +} + +static int __init ixj_probe_isapnp(int *cnt) +{ + int probe = 0; + int func = 0x110; + struct pnp_dev *dev = NULL, *old_dev = NULL; + + while (1) { + do { + IXJ *j; + int result; + + old_dev = dev; + dev = pnp_find_dev(NULL, ISAPNP_VENDOR('Q', 'T', 'I'), + ISAPNP_FUNCTION(func), old_dev); + if (!dev || !dev->card) + break; + result = pnp_device_attach(dev); + if (result < 0) { + printk("pnp attach failed %d \n", result); + break; + } + if (pnp_activate_dev(dev) < 0) { + printk("pnp activate failed (out of resources?)\n"); + pnp_device_detach(dev); + return -ENOMEM; + } + + if (!pnp_port_valid(dev, 0)) { + pnp_device_detach(dev); + return -ENODEV; + } + + j = new_ixj(pnp_port_start(dev, 0)); + if (!j) + break; + + if (func != 0x110) + j->XILINXbase = pnp_port_start(dev, 1); /* get real port */ + + switch (func) { + case (0x110): + j->cardtype = QTI_PHONEJACK; + break; + case (0x310): + j->cardtype = QTI_LINEJACK; + break; + case (0x410): + j->cardtype = QTI_PHONEJACK_LITE; + break; + } + j->board = *cnt; + probe = ixj_selfprobe(j); + if(!probe) { + j->serial = dev->card->serial; + j->dev = dev; + switch (func) { + case 0x110: + printk(KERN_INFO "ixj: found Internet PhoneJACK at 0x%x\n", j->DSPbase); + break; + case 0x310: + printk(KERN_INFO "ixj: found Internet LineJACK at 0x%x\n", j->DSPbase); + break; + case 0x410: + printk(KERN_INFO "ixj: found Internet PhoneJACK Lite at 0x%x\n", j->DSPbase); + break; + } + } + ++*cnt; + } while (dev); + if (func == 0x410) + break; + if (func == 0x310) + func = 0x410; + if (func == 0x110) + func = 0x310; + dev = NULL; + } + return probe; +} + +static int __init ixj_probe_isa(int *cnt) +{ + int i, probe; + + /* Use passed parameters for older kernels without PnP */ + for (i = 0; i < IXJMAX; i++) { + if (dspio[i]) { + IXJ *j = new_ixj(dspio[i]); + + if (!j) + break; + + j->XILINXbase = xio[i]; + j->cardtype = 0; + + j->board = *cnt; + probe = ixj_selfprobe(j); + j->dev = NULL; + ++*cnt; + } + } + return 0; +} + +static int __init ixj_probe_pci(int *cnt) +{ + struct pci_dev *pci = NULL; + int i, probe = 0; + IXJ *j = NULL; + + for (i = 0; i < IXJMAX - *cnt; i++) { + pci = pci_get_device(PCI_VENDOR_ID_QUICKNET, + PCI_DEVICE_ID_QUICKNET_XJ, pci); + if (!pci) + break; + + if (pci_enable_device(pci)) + break; + j = new_ixj(pci_resource_start(pci, 0)); + if (!j) + break; + + j->serial = (PCIEE_GetSerialNumber)pci_resource_start(pci, 2); + j->XILINXbase = j->DSPbase + 0x10; + j->cardtype = QTI_PHONEJACK_PCI; + j->board = *cnt; + probe = ixj_selfprobe(j); + if (!probe) + printk(KERN_INFO "ixj: found Internet PhoneJACK PCI at 0x%x\n", j->DSPbase); + ++*cnt; + } + pci_dev_put(pci); + return probe; +} + +static int __init ixj_init(void) +{ + int cnt = 0; + int probe = 0; + + cnt = 0; + + /* These might be no-ops, see above. */ + if ((probe = ixj_probe_isapnp(&cnt)) < 0) { + return probe; + } + if ((probe = ixj_probe_isa(&cnt)) < 0) { + return probe; + } + if ((probe = ixj_probe_pci(&cnt)) < 0) { + return probe; + } + printk(KERN_INFO "ixj driver initialized.\n"); + create_proc_read_entry ("ixj", 0, NULL, ixj_read_proc, NULL); + return probe; +} + +module_init(ixj_init); +module_exit(ixj_exit); + +static void DAA_Coeff_US(IXJ *j) +{ + int i; + + j->daa_country = DAA_US; + /*----------------------------------------------- */ + /* CAO */ + for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) { + j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0; + } + +/* Bytes for IM-filter part 1 (04): 0E,32,E2,2F,C2,5A,C0,00 */ + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x03; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0x4B; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0x5D; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0xCD; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0x24; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xC5; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00; +/* Bytes for IM-filter part 2 (05): 72,85,00,0E,2B,3A,D0,08 */ + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x71; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x1A; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0A; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0xB5; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08; +/* Bytes for FRX-filter (08): 03,8F,48,F2,8F,48,70,08 */ + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x05; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0xA3; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0x72; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x34; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x3F; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x3B; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x30; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08; +/* Bytes for FRR-filter (07): 04,8F,38,7F,9B,EA,B0,08 */ + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x05; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x87; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xF9; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x3E; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x32; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xDA; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xB0; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08; +/* Bytes for AX-filter (0A): 16,55,DD,CA */ + j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x41; + j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xB5; + j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD; + j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA; +/* Bytes for AR-filter (09): 52,D3,11,42 */ + j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x25; + j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xC7; + j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10; + j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6; +/* Bytes for TH-filter part 1 (00): 00,42,48,81,B3,80,00,98 */ + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xA5; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98; +/* Bytes for TH-filter part 2 (01): 02,F2,33,A0,68,AB,8A,AD */ + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xA2; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x2B; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0xB0; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0xE8; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0xAB; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x81; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xCC; +/* Bytes for TH-filter part 3 (02): 00,88,DA,54,A4,BA,2D,BB */ + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0xD2; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x24; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0xBA; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xA9; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x3B; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xA6; +/* ; (10K, 0.68uF) */ + /* */ + /* Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23 */ + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23; + /* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */ + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5; + + /* Levelmetering Ringing (0D):B2,45,0F,8E */ + j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA; + j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35; + j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F; + j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E; + + /* Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23 */ +/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1C; */ +/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0xB3; */ +/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0xAB; */ +/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0xAB; */ +/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x54; */ +/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x2D; */ +/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0x62; */ +/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x2D; */ + /* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */ +/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x2D; */ +/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0x62; */ +/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; */ +/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBB; */ +/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x2A; */ +/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7D; */ +/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A; */ +/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD4; */ +/* */ + /* Levelmetering Ringing (0D):B2,45,0F,8E */ +/* j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA; */ +/* j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x05; */ +/* j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F; */ +/* j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E; */ + + /* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */ + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99; +/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */ + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00; +/* */ + /* ;CR Registers */ + /* Config. Reg. 0 (filters) (cr0):FE ; CLK gen. by crystal */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF; +/* Config. Reg. 1 (dialing) (cr1):05 */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05; +/* Config. Reg. 2 (caller ID) (cr2):04 */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04; +/* Config. Reg. 3 (testloops) (cr3):03 ; SEL Bit==0, HP-disabled */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00; +/* Config. Reg. 4 (analog gain) (cr4):02 */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; + /* Config. Reg. 5 (Version) (cr5):02 */ + /* Config. Reg. 6 (Reserved) (cr6):00 */ + /* Config. Reg. 7 (Reserved) (cr7):00 */ + /* */ + /* ;xr Registers */ + /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */ + + j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */ + /* Ext. Reg. 1 (Interrupt enable) (xr1):3C Cadence, RING, Caller ID, VDD_OK */ + + j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x3C; +/* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */ + j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D; +/* Ext. Reg. 3 (DC Char) (xr3):32 ; B-Filter Off == 1 */ + j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x3B; /*0x32; */ + /* Ext. Reg. 4 (Cadence) (xr4):00 */ + + j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00; +/* Ext. Reg. 5 (Ring timer) (xr5):22 */ + j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22; +/* Ext. Reg. 6 (Power State) (xr6):00 */ + j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00; +/* Ext. Reg. 7 (Vdd) (xr7):40 */ + j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; /* 0x40 ??? Should it be 0x00? */ + /* */ + /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */ + /* 12,33,5A,C3 ; 770 Hz */ + /* 13,3C,5B,32 ; 852 Hz */ + /* 1D,1B,5C,CC ; 941 Hz */ + + j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11; + j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3; + j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A; + j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C; +/* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */ + /* EC,1D,52,22 ; 1336 Hz */ + /* AA,AC,51,D2 ; 1477 Hz */ + /* 9B,3B,51,25 ; 1633 Hz */ + j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32; + j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32; + j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52; + j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3; +} + +static void DAA_Coeff_UK(IXJ *j) +{ + int i; + + j->daa_country = DAA_UK; + /*----------------------------------------------- */ + /* CAO */ + for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) { + j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0; + } + +/* Bytes for IM-filter part 1 (04): 00,C2,BB,A8,CB,81,A0,00 */ + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xC2; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xBB; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0xA8; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0xCB; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x81; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00; +/* Bytes for IM-filter part 2 (05): 40,00,00,0A,A4,33,E0,08 */ + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x40; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0A; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0xA4; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08; +/* Bytes for FRX-filter (08): 07,9B,ED,24,B2,A2,A0,08 */ + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x9B; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0xED; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x24; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0xB2; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0xA2; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xA0; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08; +/* Bytes for FRR-filter (07): 0F,92,F2,B2,87,D2,30,08 */ + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x0F; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x92; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xF2; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0xB2; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x87; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xD2; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x30; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08; +/* Bytes for AX-filter (0A): 1B,A5,DD,CA */ + j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x1B; + j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xA5; + j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD; + j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA; +/* Bytes for AR-filter (09): E2,27,10,D6 */ + j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0xE2; + j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x27; + j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10; + j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6; +/* Bytes for TH-filter part 1 (00): 80,2D,38,8B,D0,00,00,98 */ + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x2D; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x38; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x8B; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xD0; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98; +/* Bytes for TH-filter part 2 (01): 02,5A,53,F0,0B,5F,84,D4 */ + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0x5A; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x53; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0xF0; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0x0B; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x5F; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x84; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xD4; +/* Bytes for TH-filter part 3 (02): 00,88,6A,A4,8F,52,F5,32 */ + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0x6A; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0xA4; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0x8F; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x52; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0xF5; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x32; +/* ; idle */ + /* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */ + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23; +/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */ + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5; +/* Levelmetering Ringing (0D):AA,35,0F,8E ; 25Hz 30V less possible? */ + j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA; + j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35; + j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F; + j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E; +/* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */ + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99; +/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */ + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00; +/* ;CR Registers */ + /* Config. Reg. 0 (filters) (cr0):FF */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF; +/* Config. Reg. 1 (dialing) (cr1):05 */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05; +/* Config. Reg. 2 (caller ID) (cr2):04 */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04; +/* Config. Reg. 3 (testloops) (cr3):00 ; */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00; +/* Config. Reg. 4 (analog gain) (cr4):02 */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; + /* Config. Reg. 5 (Version) (cr5):02 */ + /* Config. Reg. 6 (Reserved) (cr6):00 */ + /* Config. Reg. 7 (Reserved) (cr7):00 */ + /* ;xr Registers */ + /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */ + + j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */ + /* Ext. Reg. 1 (Interrupt enable) (xr1):1C */ + + j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; /* RING, Caller ID, VDD_OK */ + /* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */ + + j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D; +/* Ext. Reg. 3 (DC Char) (xr3):36 ; */ + j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x36; +/* Ext. Reg. 4 (Cadence) (xr4):00 */ + j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00; +/* Ext. Reg. 5 (Ring timer) (xr5):22 */ + j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22; +/* Ext. Reg. 6 (Power State) (xr6):00 */ + j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00; +/* Ext. Reg. 7 (Vdd) (xr7):46 */ + j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x46; /* 0x46 ??? Should it be 0x00? */ + /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */ + /* 12,33,5A,C3 ; 770 Hz */ + /* 13,3C,5B,32 ; 852 Hz */ + /* 1D,1B,5C,CC ; 941 Hz */ + + j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11; + j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3; + j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A; + j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C; +/* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */ + /* EC,1D,52,22 ; 1336 Hz */ + /* AA,AC,51,D2 ; 1477 Hz */ + /* 9B,3B,51,25 ; 1633 Hz */ + j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32; + j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32; + j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52; + j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3; +} + + +static void DAA_Coeff_France(IXJ *j) +{ + int i; + + j->daa_country = DAA_FRANCE; + /*----------------------------------------------- */ + /* CAO */ + for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) { + j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0; + } + +/* Bytes for IM-filter part 1 (04): 02,A2,43,2C,22,AF,A0,00 */ + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x02; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xA2; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0x43; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x2C; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0x22; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xAF; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00; +/* Bytes for IM-filter part 2 (05): 67,CE,00,0C,22,33,E0,08 */ + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x67; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0xCE; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x2C; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0x22; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08; +/* Bytes for FRX-filter (08): 07,9A,28,F6,23,4A,B0,08 */ + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x9A; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0x28; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0xF6; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x23; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x4A; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xB0; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08; +/* Bytes for FRR-filter (07): 03,8F,F9,2F,9E,FA,20,08 */ + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x03; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x8F; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xF9; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x2F; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x9E; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xFA; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x20; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08; +/* Bytes for AX-filter (0A): 16,B5,DD,CA */ + j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x16; + j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xB5; + j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD; + j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA; +/* Bytes for AR-filter (09): 52,C7,10,D6 */ + j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0xE2; + j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xC7; + j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10; + j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6; +/* Bytes for TH-filter part 1 (00): 00,42,48,81,A6,80,00,98 */ + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xA6; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98; +/* Bytes for TH-filter part 2 (01): 02,AC,2A,30,78,AC,8A,2C */ + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xAC; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x2A; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0x30; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0x78; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0xAC; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x8A; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x2C; +/* Bytes for TH-filter part 3 (02): 00,88,DA,A5,22,BA,2C,45 */ + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0xDA; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0xA5; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0x22; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xBA; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x2C; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x45; +/* ; idle */ + /* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */ + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23; +/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */ + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5; +/* Levelmetering Ringing (0D):32,45,B5,84 ; 50Hz 20V */ + j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0x32; + j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45; + j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0xB5; + j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x84; +/* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */ + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99; +/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */ + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00; +/* ;CR Registers */ + /* Config. Reg. 0 (filters) (cr0):FF */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF; +/* Config. Reg. 1 (dialing) (cr1):05 */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05; +/* Config. Reg. 2 (caller ID) (cr2):04 */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04; +/* Config. Reg. 3 (testloops) (cr3):00 ; */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00; +/* Config. Reg. 4 (analog gain) (cr4):02 */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; + /* Config. Reg. 5 (Version) (cr5):02 */ + /* Config. Reg. 6 (Reserved) (cr6):00 */ + /* Config. Reg. 7 (Reserved) (cr7):00 */ + /* ;xr Registers */ + /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */ + + j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */ + /* Ext. Reg. 1 (Interrupt enable) (xr1):1C */ + + j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; /* RING, Caller ID, VDD_OK */ + /* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */ + + j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D; +/* Ext. Reg. 3 (DC Char) (xr3):36 ; */ + j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x36; +/* Ext. Reg. 4 (Cadence) (xr4):00 */ + j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00; +/* Ext. Reg. 5 (Ring timer) (xr5):22 */ + j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22; +/* Ext. Reg. 6 (Power State) (xr6):00 */ + j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00; +/* Ext. Reg. 7 (Vdd) (xr7):46 */ + j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x46; /* 0x46 ??? Should it be 0x00? */ + /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */ + /* 12,33,5A,C3 ; 770 Hz */ + /* 13,3C,5B,32 ; 852 Hz */ + /* 1D,1B,5C,CC ; 941 Hz */ + + j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11; + j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3; + j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A; + j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C; +/* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */ + /* EC,1D,52,22 ; 1336 Hz */ + /* AA,AC,51,D2 ; 1477 Hz */ + /* 9B,3B,51,25 ; 1633 Hz */ + j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32; + j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32; + j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52; + j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3; +} + + +static void DAA_Coeff_Germany(IXJ *j) +{ + int i; + + j->daa_country = DAA_GERMANY; + /*----------------------------------------------- */ + /* CAO */ + for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) { + j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0; + } + +/* Bytes for IM-filter part 1 (04): 00,CE,BB,B8,D2,81,B0,00 */ + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xCE; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xBB; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0xB8; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0xD2; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x81; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xB0; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00; +/* Bytes for IM-filter part 2 (05): 45,8F,00,0C,D2,3A,D0,08 */ + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x45; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x8F; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0C; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0xD2; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x3A; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xD0; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08; +/* Bytes for FRX-filter (08): 07,AA,E2,34,24,89,20,08 */ + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0xAA; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0xE2; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x34; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x24; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x89; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x20; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08; +/* Bytes for FRR-filter (07): 02,87,FA,37,9A,CA,B0,08 */ + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x02; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x87; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xFA; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x37; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x9A; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xCA; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xB0; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08; +/* Bytes for AX-filter (0A): 72,D5,DD,CA */ + j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x72; + j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xD5; + j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD; + j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA; +/* Bytes for AR-filter (09): 72,42,13,4B */ + j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x72; + j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x42; + j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x13; + j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0x4B; +/* Bytes for TH-filter part 1 (00): 80,52,48,81,AD,80,00,98 */ + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x52; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xAD; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98; +/* Bytes for TH-filter part 2 (01): 02,42,5A,20,E8,1A,81,27 */ + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0x42; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x5A; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0x20; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0xE8; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x1A; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x81; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x27; +/* Bytes for TH-filter part 3 (02): 00,88,63,26,BD,4B,A3,C2 */ + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0x63; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x26; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0xBD; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x4B; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0xA3; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xC2; +/* ; (10K, 0.68uF) */ + /* Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23 */ + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3B; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x9B; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0xBA; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0xD4; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x1C; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xB3; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23; +/* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */ + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x13; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0x42; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0xD4; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x73; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0xCA; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5; +/* Levelmetering Ringing (0D):B2,45,0F,8E */ + j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xB2; + j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45; + j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F; + j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E; +/* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */ + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99; +/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */ + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00; +/* ;CR Registers */ + /* Config. Reg. 0 (filters) (cr0):FF ; all Filters enabled, CLK from ext. source */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF; +/* Config. Reg. 1 (dialing) (cr1):05 ; Manual Ring, Ring metering enabled */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05; +/* Config. Reg. 2 (caller ID) (cr2):04 ; Analog Gain 0dB, FSC internal */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04; +/* Config. Reg. 3 (testloops) (cr3):00 ; SEL Bit==0, HP-enabled */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00; +/* Config. Reg. 4 (analog gain) (cr4):02 */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; + /* Config. Reg. 5 (Version) (cr5):02 */ + /* Config. Reg. 6 (Reserved) (cr6):00 */ + /* Config. Reg. 7 (Reserved) (cr7):00 */ + /* ;xr Registers */ + /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */ + + j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */ + /* Ext. Reg. 1 (Interrupt enable) (xr1):1C ; Ring, CID, VDDOK Interrupts enabled */ + + j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; /* RING, Caller ID, VDD_OK */ + /* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */ + + j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D; +/* Ext. Reg. 3 (DC Char) (xr3):32 ; B-Filter Off==1, U0=3.5V, R=200Ohm */ + j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x32; +/* Ext. Reg. 4 (Cadence) (xr4):00 */ + j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00; +/* Ext. Reg. 5 (Ring timer) (xr5):22 */ + j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22; +/* Ext. Reg. 6 (Power State) (xr6):00 */ + j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00; +/* Ext. Reg. 7 (Vdd) (xr7):40 ; VDD=4.25 V */ + j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; /* 0x40 ??? Should it be 0x00? */ + /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */ + /* 12,33,5A,C3 ; 770 Hz */ + /* 13,3C,5B,32 ; 852 Hz */ + /* 1D,1B,5C,CC ; 941 Hz */ + + j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11; + j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3; + j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A; + j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C; +/* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */ + /* EC,1D,52,22 ; 1336 Hz */ + /* AA,AC,51,D2 ; 1477 Hz */ + /* 9B,3B,51,25 ; 1633 Hz */ + j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32; + j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32; + j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52; + j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3; +} + + +static void DAA_Coeff_Australia(IXJ *j) +{ + int i; + + j->daa_country = DAA_AUSTRALIA; + /*----------------------------------------------- */ + /* CAO */ + for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) { + j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0; + } + +/* Bytes for IM-filter part 1 (04): 00,A3,AA,28,B3,82,D0,00 */ + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xA3; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xAA; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x28; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0xB3; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x82; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xD0; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00; +/* Bytes for IM-filter part 2 (05): 70,96,00,09,32,6B,C0,08 */ + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x70; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x96; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x09; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0x32; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x6B; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xC0; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08; +/* Bytes for FRX-filter (08): 07,96,E2,34,32,9B,30,08 */ + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x96; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0xE2; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x34; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x32; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x9B; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x30; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08; +/* Bytes for FRR-filter (07): 0F,9A,E9,2F,22,CC,A0,08 */ + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x0F; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x9A; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xE9; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x2F; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x22; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xCC; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xA0; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08; +/* Bytes for AX-filter (0A): CB,45,DD,CA */ + j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0xCB; + j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0x45; + j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD; + j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA; +/* Bytes for AR-filter (09): 1B,67,10,D6 */ + j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x1B; + j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x67; + j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10; + j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6; +/* Bytes for TH-filter part 1 (00): 80,52,48,81,AF,80,00,98 */ + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x52; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xAF; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98; +/* Bytes for TH-filter part 2 (01): 02,DB,52,B0,38,01,82,AC */ + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xDB; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x52; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0xB0; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0x38; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x01; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x82; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xAC; +/* Bytes for TH-filter part 3 (02): 00,88,4A,3E,2C,3B,24,46 */ + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0x4A; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x3E; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0x2C; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x3B; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x24; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x46; +/* ; idle */ + /* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */ + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23; +/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */ + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5; +/* Levelmetering Ringing (0D):32,45,B5,84 ; 50Hz 20V */ + j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0x32; + j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45; + j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0xB5; + j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x84; +/* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */ + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99; +/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */ + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00; +/* ;CR Registers */ + /* Config. Reg. 0 (filters) (cr0):FF */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF; +/* Config. Reg. 1 (dialing) (cr1):05 */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05; +/* Config. Reg. 2 (caller ID) (cr2):04 */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04; +/* Config. Reg. 3 (testloops) (cr3):00 ; */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00; +/* Config. Reg. 4 (analog gain) (cr4):02 */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; + /* Config. Reg. 5 (Version) (cr5):02 */ + /* Config. Reg. 6 (Reserved) (cr6):00 */ + /* Config. Reg. 7 (Reserved) (cr7):00 */ + /* ;xr Registers */ + /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */ + + j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */ + /* Ext. Reg. 1 (Interrupt enable) (xr1):1C */ + + j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; /* RING, Caller ID, VDD_OK */ + /* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */ + + j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D; +/* Ext. Reg. 3 (DC Char) (xr3):2B ; */ + j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x2B; +/* Ext. Reg. 4 (Cadence) (xr4):00 */ + j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00; +/* Ext. Reg. 5 (Ring timer) (xr5):22 */ + j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22; +/* Ext. Reg. 6 (Power State) (xr6):00 */ + j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00; +/* Ext. Reg. 7 (Vdd) (xr7):40 */ + j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; /* 0x40 ??? Should it be 0x00? */ + + /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */ + /* 12,33,5A,C3 ; 770 Hz */ + /* 13,3C,5B,32 ; 852 Hz */ + /* 1D,1B,5C,CC ; 941 Hz */ + j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11; + j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3; + j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A; + j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C; + + /* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */ + /* EC,1D,52,22 ; 1336 Hz */ + /* AA,AC,51,D2 ; 1477 Hz */ + /* 9B,3B,51,25 ; 1633 Hz */ + j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32; + j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32; + j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52; + j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3; +} + +static void DAA_Coeff_Japan(IXJ *j) +{ + int i; + + j->daa_country = DAA_JAPAN; + /*----------------------------------------------- */ + /* CAO */ + for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) { + j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0; + } + +/* Bytes for IM-filter part 1 (04): 06,BD,E2,2D,BA,F9,A0,00 */ + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x06; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xBD; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xE2; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x2D; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0xBA; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xF9; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00; +/* Bytes for IM-filter part 2 (05): 6F,F7,00,0E,34,33,E0,08 */ + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x6F; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0xF7; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0E; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0x34; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0; + j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08; +/* Bytes for FRX-filter (08): 02,8F,68,77,9C,58,F0,08 */ + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x02; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x8F; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0x68; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x77; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x9C; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x58; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xF0; + j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08; +/* Bytes for FRR-filter (07): 03,8F,38,73,87,EA,20,08 */ + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x03; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x8F; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0x38; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x73; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x87; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xEA; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x20; + j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08; +/* Bytes for AX-filter (0A): 51,C5,DD,CA */ + j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x51; + j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xC5; + j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD; + j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA; +/* Bytes for AR-filter (09): 25,A7,10,D6 */ + j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x25; + j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xA7; + j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10; + j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6; +/* Bytes for TH-filter part 1 (00): 00,42,48,81,AE,80,00,98 */ + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xAE; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98; +/* Bytes for TH-filter part 2 (01): 02,AB,2A,20,99,5B,89,28 */ + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xAB; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x2A; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0x20; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0x99; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x5B; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x89; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x28; +/* Bytes for TH-filter part 3 (02): 00,88,DA,25,34,C5,4C,BA */ + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0xDA; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x25; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0x34; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xC5; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x4C; + j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xBA; +/* ; idle */ + /* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */ + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23; +/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */ + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A; + j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5; +/* Levelmetering Ringing (0D):AA,35,0F,8E ; 25Hz 30V ????????? */ + j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA; + j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35; + j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F; + j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E; +/* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */ + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99; +/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */ + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00; + j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00; +/* ;CR Registers */ + /* Config. Reg. 0 (filters) (cr0):FF */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF; +/* Config. Reg. 1 (dialing) (cr1):05 */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05; +/* Config. Reg. 2 (caller ID) (cr2):04 */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04; +/* Config. Reg. 3 (testloops) (cr3):00 ; */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00; +/* Config. Reg. 4 (analog gain) (cr4):02 */ + j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; + /* Config. Reg. 5 (Version) (cr5):02 */ + /* Config. Reg. 6 (Reserved) (cr6):00 */ + /* Config. Reg. 7 (Reserved) (cr7):00 */ + /* ;xr Registers */ + /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */ + + j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */ + /* Ext. Reg. 1 (Interrupt enable) (xr1):1C */ + + j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; /* RING, Caller ID, VDD_OK */ + /* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */ + + j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D; +/* Ext. Reg. 3 (DC Char) (xr3):22 ; */ + j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x22; +/* Ext. Reg. 4 (Cadence) (xr4):00 */ + j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00; +/* Ext. Reg. 5 (Ring timer) (xr5):22 */ + j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22; +/* Ext. Reg. 6 (Power State) (xr6):00 */ + j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00; +/* Ext. Reg. 7 (Vdd) (xr7):40 */ + j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; /* 0x40 ??? Should it be 0x00? */ + /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */ + /* 12,33,5A,C3 ; 770 Hz */ + /* 13,3C,5B,32 ; 852 Hz */ + /* 1D,1B,5C,CC ; 941 Hz */ + + j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11; + j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3; + j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A; + j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C; +/* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */ + /* EC,1D,52,22 ; 1336 Hz */ + /* AA,AC,51,D2 ; 1477 Hz */ + /* 9B,3B,51,25 ; 1633 Hz */ + j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32; + j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32; + j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52; + j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3; +} + +static s16 tone_table[][19] = +{ + { /* f20_50[] 11 */ + 32538, /* A1 = 1.985962 */ + -32325, /* A2 = -0.986511 */ + -343, /* B2 = -0.010493 */ + 0, /* B1 = 0 */ + 343, /* B0 = 0.010493 */ + 32619, /* A1 = 1.990906 */ + -32520, /* A2 = -0.992462 */ + 19179, /* B2 = 0.585327 */ + -19178, /* B1 = -1.170593 */ + 19179, /* B0 = 0.585327 */ + 32723, /* A1 = 1.997314 */ + -32686, /* A2 = -0.997528 */ + 9973, /* B2 = 0.304352 */ + -9955, /* B1 = -0.607605 */ + 9973, /* B0 = 0.304352 */ + 7, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f133_200[] 12 */ + 32072, /* A1 = 1.95752 */ + -31896, /* A2 = -0.973419 */ + -435, /* B2 = -0.013294 */ + 0, /* B1 = 0 */ + 435, /* B0 = 0.013294 */ + 32188, /* A1 = 1.9646 */ + -32400, /* A2 = -0.98877 */ + 15139, /* B2 = 0.462036 */ + -14882, /* B1 = -0.908356 */ + 15139, /* B0 = 0.462036 */ + 32473, /* A1 = 1.981995 */ + -32524, /* A2 = -0.992584 */ + 23200, /* B2 = 0.708008 */ + -23113, /* B1 = -1.410706 */ + 23200, /* B0 = 0.708008 */ + 7, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f300 13 */ + 31769, /* A1 = -1.939026 */ + -32584, /* A2 = 0.994385 */ + -475, /* B2 = -0.014522 */ + 0, /* B1 = 0.000000 */ + 475, /* B0 = 0.014522 */ + 31789, /* A1 = -1.940247 */ + -32679, /* A2 = 0.997284 */ + 17280, /* B2 = 0.527344 */ + -16865, /* B1 = -1.029358 */ + 17280, /* B0 = 0.527344 */ + 31841, /* A1 = -1.943481 */ + -32681, /* A2 = 0.997345 */ + 543, /* B2 = 0.016579 */ + -525, /* B1 = -0.032097 */ + 543, /* B0 = 0.016579 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f300_420[] 14 */ + 30750, /* A1 = 1.876892 */ + -31212, /* A2 = -0.952515 */ + -804, /* B2 = -0.024541 */ + 0, /* B1 = 0 */ + 804, /* B0 = 0.024541 */ + 30686, /* A1 = 1.872925 */ + -32145, /* A2 = -0.980988 */ + 14747, /* B2 = 0.450043 */ + -13703, /* B1 = -0.836395 */ + 14747, /* B0 = 0.450043 */ + 31651, /* A1 = 1.931824 */ + -32321, /* A2 = -0.986389 */ + 24425, /* B2 = 0.745422 */ + -23914, /* B1 = -1.459595 */ + 24427, /* B0 = 0.745483 */ + 7, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f330 15 */ + 31613, /* A1 = -1.929565 */ + -32646, /* A2 = 0.996277 */ + -185, /* B2 = -0.005657 */ + 0, /* B1 = 0.000000 */ + 185, /* B0 = 0.005657 */ + 31620, /* A1 = -1.929932 */ + -32713, /* A2 = 0.998352 */ + 19253, /* B2 = 0.587585 */ + -18566, /* B1 = -1.133179 */ + 19253, /* B0 = 0.587585 */ + 31674, /* A1 = -1.933228 */ + -32715, /* A2 = 0.998413 */ + 2575, /* B2 = 0.078590 */ + -2495, /* B1 = -0.152283 */ + 2575, /* B0 = 0.078590 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f300_425[] 16 */ + 30741, /* A1 = 1.876282 */ + -31475, /* A2 = -0.960541 */ + -703, /* B2 = -0.021484 */ + 0, /* B1 = 0 */ + 703, /* B0 = 0.021484 */ + 30688, /* A1 = 1.873047 */ + -32248, /* A2 = -0.984161 */ + 14542, /* B2 = 0.443787 */ + -13523, /* B1 = -0.825439 */ + 14542, /* B0 = 0.443817 */ + 31494, /* A1 = 1.922302 */ + -32366, /* A2 = -0.987762 */ + 21577, /* B2 = 0.658508 */ + -21013, /* B1 = -1.282532 */ + 21577, /* B0 = 0.658508 */ + 7, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f330_440[] 17 */ + 30627, /* A1 = 1.869324 */ + -31338, /* A2 = -0.95636 */ + -843, /* B2 = -0.025749 */ + 0, /* B1 = 0 */ + 843, /* B0 = 0.025749 */ + 30550, /* A1 = 1.864685 */ + -32221, /* A2 = -0.983337 */ + 13594, /* B2 = 0.414886 */ + -12589, /* B1 = -0.768402 */ + 13594, /* B0 = 0.414886 */ + 31488, /* A1 = 1.921936 */ + -32358, /* A2 = -0.987518 */ + 24684, /* B2 = 0.753296 */ + -24029, /* B1 = -1.466614 */ + 24684, /* B0 = 0.753296 */ + 7, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f340 18 */ + 31546, /* A1 = -1.925476 */ + -32646, /* A2 = 0.996277 */ + -445, /* B2 = -0.013588 */ + 0, /* B1 = 0.000000 */ + 445, /* B0 = 0.013588 */ + 31551, /* A1 = -1.925781 */ + -32713, /* A2 = 0.998352 */ + 23884, /* B2 = 0.728882 */ + -22979, /* B1 = -1.402527 */ + 23884, /* B0 = 0.728882 */ + 31606, /* A1 = -1.929138 */ + -32715, /* A2 = 0.998413 */ + 863, /* B2 = 0.026367 */ + -835, /* B1 = -0.050985 */ + 863, /* B0 = 0.026367 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f350_400[] 19 */ + 31006, /* A1 = 1.892517 */ + -32029, /* A2 = -0.977448 */ + -461, /* B2 = -0.014096 */ + 0, /* B1 = 0 */ + 461, /* B0 = 0.014096 */ + 30999, /* A1 = 1.892029 */ + -32487, /* A2 = -0.991455 */ + 11325, /* B2 = 0.345612 */ + -10682, /* B1 = -0.651978 */ + 11325, /* B0 = 0.345612 */ + 31441, /* A1 = 1.919067 */ + -32526, /* A2 = -0.992615 */ + 24324, /* B2 = 0.74231 */ + -23535, /* B1 = -1.436523 */ + 24324, /* B0 = 0.74231 */ + 7, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f350_440[] */ + 30634, /* A1 = 1.869751 */ + -31533, /* A2 = -0.962341 */ + -680, /* B2 = -0.020782 */ + 0, /* B1 = 0 */ + 680, /* B0 = 0.020782 */ + 30571, /* A1 = 1.865906 */ + -32277, /* A2 = -0.985016 */ + 12894, /* B2 = 0.393524 */ + -11945, /* B1 = -0.729065 */ + 12894, /* B0 = 0.393524 */ + 31367, /* A1 = 1.91449 */ + -32379, /* A2 = -0.988129 */ + 23820, /* B2 = 0.726929 */ + -23104, /* B1 = -1.410217 */ + 23820, /* B0 = 0.726929 */ + 7, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f350_450[] */ + 30552, /* A1 = 1.864807 */ + -31434, /* A2 = -0.95929 */ + -690, /* B2 = -0.021066 */ + 0, /* B1 = 0 */ + 690, /* B0 = 0.021066 */ + 30472, /* A1 = 1.859924 */ + -32248, /* A2 = -0.984161 */ + 13385, /* B2 = 0.408478 */ + -12357, /* B1 = -0.754242 */ + 13385, /* B0 = 0.408478 */ + 31358, /* A1 = 1.914001 */ + -32366, /* A2 = -0.987732 */ + 26488, /* B2 = 0.80835 */ + -25692, /* B1 = -1.568176 */ + 26490, /* B0 = 0.808411 */ + 7, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f360 */ + 31397, /* A1 = -1.916321 */ + -32623, /* A2 = 0.995605 */ + -117, /* B2 = -0.003598 */ + 0, /* B1 = 0.000000 */ + 117, /* B0 = 0.003598 */ + 31403, /* A1 = -1.916687 */ + -32700, /* A2 = 0.997925 */ + 3388, /* B2 = 0.103401 */ + -3240, /* B1 = -0.197784 */ + 3388, /* B0 = 0.103401 */ + 31463, /* A1 = -1.920410 */ + -32702, /* A2 = 0.997986 */ + 13346, /* B2 = 0.407288 */ + -12863, /* B1 = -0.785126 */ + 13346, /* B0 = 0.407288 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f380_420[] */ + 30831, /* A1 = 1.881775 */ + -32064, /* A2 = -0.978546 */ + -367, /* B2 = -0.01122 */ + 0, /* B1 = 0 */ + 367, /* B0 = 0.01122 */ + 30813, /* A1 = 1.880737 */ + -32456, /* A2 = -0.990509 */ + 11068, /* B2 = 0.337769 */ + -10338, /* B1 = -0.631042 */ + 11068, /* B0 = 0.337769 */ + 31214, /* A1 = 1.905212 */ + -32491, /* A2 = -0.991577 */ + 16374, /* B2 = 0.499695 */ + -15781, /* B1 = -0.963196 */ + 16374, /* B0 = 0.499695 */ + 7, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f392 */ + 31152, /* A1 = -1.901428 */ + -32613, /* A2 = 0.995300 */ + -314, /* B2 = -0.009605 */ + 0, /* B1 = 0.000000 */ + 314, /* B0 = 0.009605 */ + 31156, /* A1 = -1.901672 */ + -32694, /* A2 = 0.997742 */ + 28847, /* B2 = 0.880371 */ + -2734, /* B1 = -0.166901 */ + 28847, /* B0 = 0.880371 */ + 31225, /* A1 = -1.905823 */ + -32696, /* A2 = 0.997803 */ + 462, /* B2 = 0.014108 */ + -442, /* B1 = -0.027019 */ + 462, /* B0 = 0.014108 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f400_425[] */ + 30836, /* A1 = 1.882141 */ + -32296, /* A2 = -0.985596 */ + -324, /* B2 = -0.009903 */ + 0, /* B1 = 0 */ + 324, /* B0 = 0.009903 */ + 30825, /* A1 = 1.881409 */ + -32570, /* A2 = -0.993958 */ + 16847, /* B2 = 0.51416 */ + -15792, /* B1 = -0.963898 */ + 16847, /* B0 = 0.51416 */ + 31106, /* A1 = 1.89856 */ + -32584, /* A2 = -0.994415 */ + 9579, /* B2 = 0.292328 */ + -9164, /* B1 = -0.559357 */ + 9579, /* B0 = 0.292328 */ + 7, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f400_440[] */ + 30702, /* A1 = 1.873962 */ + -32134, /* A2 = -0.980682 */ + -517, /* B2 = -0.015793 */ + 0, /* B1 = 0 */ + 517, /* B0 = 0.015793 */ + 30676, /* A1 = 1.872375 */ + -32520, /* A2 = -0.992462 */ + 8144, /* B2 = 0.24855 */ + -7596, /* B1 = -0.463684 */ + 8144, /* B0 = 0.24855 */ + 31084, /* A1 = 1.897217 */ + -32547, /* A2 = -0.993256 */ + 22713, /* B2 = 0.693176 */ + -21734, /* B1 = -1.326599 */ + 22713, /* B0 = 0.693176 */ + 7, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f400_450[] */ + 30613, /* A1 = 1.86853 */ + -32031, /* A2 = -0.977509 */ + -618, /* B2 = -0.018866 */ + 0, /* B1 = 0 */ + 618, /* B0 = 0.018866 */ + 30577, /* A1 = 1.866272 */ + -32491, /* A2 = -0.991577 */ + 9612, /* B2 = 0.293335 */ + -8935, /* B1 = -0.54541 */ + 9612, /* B0 = 0.293335 */ + 31071, /* A1 = 1.896484 */ + -32524, /* A2 = -0.992584 */ + 21596, /* B2 = 0.659058 */ + -20667, /* B1 = -1.261414 */ + 21596, /* B0 = 0.659058 */ + 7, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f420 */ + 30914, /* A1 = -1.886841 */ + -32584, /* A2 = 0.994385 */ + -426, /* B2 = -0.013020 */ + 0, /* B1 = 0.000000 */ + 426, /* B0 = 0.013020 */ + 30914, /* A1 = -1.886841 */ + -32679, /* A2 = 0.997314 */ + 17520, /* B2 = 0.534668 */ + -16471, /* B1 = -1.005310 */ + 17520, /* B0 = 0.534668 */ + 31004, /* A1 = -1.892334 */ + -32683, /* A2 = 0.997406 */ + 819, /* B2 = 0.025023 */ + -780, /* B1 = -0.047619 */ + 819, /* B0 = 0.025023 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, +#if 0 + { /* f425 */ + 30881, /* A1 = -1.884827 */ + -32603, /* A2 = 0.994965 */ + -496, /* B2 = -0.015144 */ + 0, /* B1 = 0.000000 */ + 496, /* B0 = 0.015144 */ + 30880, /* A1 = -1.884766 */ + -32692, /* A2 = 0.997711 */ + 24767, /* B2 = 0.755859 */ + -23290, /* B1 = -1.421509 */ + 24767, /* B0 = 0.755859 */ + 30967, /* A1 = -1.890076 */ + -32694, /* A2 = 0.997772 */ + 728, /* B2 = 0.022232 */ + -691, /* B1 = -0.042194 */ + 728, /* B0 = 0.022232 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, +#else + { + 30850, + -32534, + -504, + 0, + 504, + 30831, + -32669, + 24303, + -22080, + 24303, + 30994, + -32673, + 1905, + -1811, + 1905, + 5, + 129, + 17, + 0xff5 + }, +#endif + { /* f425_450[] */ + 30646, /* A1 = 1.870544 */ + -32327, /* A2 = -0.986572 */ + -287, /* B2 = -0.008769 */ + 0, /* B1 = 0 */ + 287, /* B0 = 0.008769 */ + 30627, /* A1 = 1.869324 */ + -32607, /* A2 = -0.995087 */ + 13269, /* B2 = 0.404968 */ + -12376, /* B1 = -0.755432 */ + 13269, /* B0 = 0.404968 */ + 30924, /* A1 = 1.887512 */ + -32619, /* A2 = -0.995453 */ + 19950, /* B2 = 0.608826 */ + -18940, /* B1 = -1.156006 */ + 19950, /* B0 = 0.608826 */ + 7, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f425_475[] */ + 30396, /* A1 = 1.855225 */ + -32014, /* A2 = -0.97699 */ + -395, /* B2 = -0.012055 */ + 0, /* B1 = 0 */ + 395, /* B0 = 0.012055 */ + 30343, /* A1 = 1.85199 */ + -32482, /* A2 = -0.991302 */ + 17823, /* B2 = 0.543945 */ + -16431, /* B1 = -1.002869 */ + 17823, /* B0 = 0.543945 */ + 30872, /* A1 = 1.884338 */ + -32516, /* A2 = -0.99231 */ + 18124, /* B2 = 0.553101 */ + -17246, /* B1 = -1.052673 */ + 18124, /* B0 = 0.553101 */ + 7, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f435 */ + 30796, /* A1 = -1.879639 */ + -32603, /* A2 = 0.994965 */ + -254, /* B2 = -0.007762 */ + 0, /* B1 = 0.000000 */ + 254, /* B0 = 0.007762 */ + 30793, /* A1 = -1.879456 */ + -32692, /* A2 = 0.997711 */ + 18934, /* B2 = 0.577820 */ + -17751, /* B1 = -1.083496 */ + 18934, /* B0 = 0.577820 */ + 30882, /* A1 = -1.884888 */ + -32694, /* A2 = 0.997772 */ + 1858, /* B2 = 0.056713 */ + -1758, /* B1 = -0.107357 */ + 1858, /* B0 = 0.056713 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f440_450[] */ + 30641, /* A1 = 1.870239 */ + -32458, /* A2 = -0.99057 */ + -155, /* B2 = -0.004735 */ + 0, /* B1 = 0 */ + 155, /* B0 = 0.004735 */ + 30631, /* A1 = 1.869568 */ + -32630, /* A2 = -0.995789 */ + 11453, /* B2 = 0.349548 */ + -10666, /* B1 = -0.651001 */ + 11453, /* B0 = 0.349548 */ + 30810, /* A1 = 1.880554 */ + -32634, /* A2 = -0.995941 */ + 12237, /* B2 = 0.373474 */ + -11588, /* B1 = -0.707336 */ + 12237, /* B0 = 0.373474 */ + 7, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f440_480[] */ + 30367, /* A1 = 1.853455 */ + -32147, /* A2 = -0.981079 */ + -495, /* B2 = -0.015113 */ + 0, /* B1 = 0 */ + 495, /* B0 = 0.015113 */ + 30322, /* A1 = 1.850769 */ + -32543, /* A2 = -0.993134 */ + 10031, /* B2 = 0.306152 */ + -9252, /* B1 = -0.564728 */ + 10031, /* B0 = 0.306152 */ + 30770, /* A1 = 1.878052 */ + -32563, /* A2 = -0.993774 */ + 22674, /* B2 = 0.691956 */ + -21465, /* B1 = -1.31012 */ + 22674, /* B0 = 0.691956 */ + 7, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f445 */ + 30709, /* A1 = -1.874329 */ + -32603, /* A2 = 0.994965 */ + -83, /* B2 = -0.002545 */ + 0, /* B1 = 0.000000 */ + 83, /* B0 = 0.002545 */ + 30704, /* A1 = -1.874084 */ + -32692, /* A2 = 0.997711 */ + 10641, /* B2 = 0.324738 */ + -9947, /* B1 = -0.607147 */ + 10641, /* B0 = 0.324738 */ + 30796, /* A1 = -1.879639 */ + -32694, /* A2 = 0.997772 */ + 10079, /* B2 = 0.307587 */ + 9513, /* B1 = 0.580688 */ + 10079, /* B0 = 0.307587 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f450 */ + 30664, /* A1 = -1.871643 */ + -32603, /* A2 = 0.994965 */ + -164, /* B2 = -0.005029 */ + 0, /* B1 = 0.000000 */ + 164, /* B0 = 0.005029 */ + 30661, /* A1 = -1.871399 */ + -32692, /* A2 = 0.997711 */ + 15294, /* B2 = 0.466736 */ + -14275, /* B1 = -0.871307 */ + 15294, /* B0 = 0.466736 */ + 30751, /* A1 = -1.876953 */ + -32694, /* A2 = 0.997772 */ + 3548, /* B2 = 0.108284 */ + -3344, /* B1 = -0.204155 */ + 3548, /* B0 = 0.108284 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f452 */ + 30653, /* A1 = -1.870911 */ + -32615, /* A2 = 0.995361 */ + -209, /* B2 = -0.006382 */ + 0, /* B1 = 0.000000 */ + 209, /* B0 = 0.006382 */ + 30647, /* A1 = -1.870605 */ + -32702, /* A2 = 0.997986 */ + 18971, /* B2 = 0.578979 */ + -17716, /* B1 = -1.081299 */ + 18971, /* B0 = 0.578979 */ + 30738, /* A1 = -1.876099 */ + -32702, /* A2 = 0.998016 */ + 2967, /* B2 = 0.090561 */ + -2793, /* B1 = -0.170502 */ + 2967, /* B0 = 0.090561 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f475 */ + 30437, /* A1 = -1.857727 */ + -32603, /* A2 = 0.994965 */ + -264, /* B2 = -0.008062 */ + 0, /* B1 = 0.000000 */ + 264, /* B0 = 0.008062 */ + 30430, /* A1 = -1.857300 */ + -32692, /* A2 = 0.997711 */ + 21681, /* B2 = 0.661682 */ + -20082, /* B1 = -1.225708 */ + 21681, /* B0 = 0.661682 */ + 30526, /* A1 = -1.863220 */ + -32694, /* A2 = 0.997742 */ + 1559, /* B2 = 0.047600 */ + -1459, /* B1 = -0.089096 */ + 1559, /* B0 = 0.047600 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f480_620[] */ + 28975, /* A1 = 1.768494 */ + -30955, /* A2 = -0.944672 */ + -1026, /* B2 = -0.03133 */ + 0, /* B1 = 0 */ + 1026, /* B0 = 0.03133 */ + 28613, /* A1 = 1.746399 */ + -32089, /* A2 = -0.979309 */ + 14214, /* B2 = 0.433807 */ + -12202, /* B1 = -0.744812 */ + 14214, /* B0 = 0.433807 */ + 30243, /* A1 = 1.845947 */ + -32238, /* A2 = -0.983856 */ + 24825, /* B2 = 0.757629 */ + -23402, /* B1 = -1.428345 */ + 24825, /* B0 = 0.757629 */ + 7, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f494 */ + 30257, /* A1 = -1.846741 */ + -32605, /* A2 = 0.995056 */ + -249, /* B2 = -0.007625 */ + 0, /* B1 = 0.000000 */ + 249, /* B0 = 0.007625 */ + 30247, /* A1 = -1.846191 */ + -32694, /* A2 = 0.997772 */ + 18088, /* B2 = 0.552002 */ + -16652, /* B1 = -1.016418 */ + 18088, /* B0 = 0.552002 */ + 30348, /* A1 = -1.852295 */ + -32696, /* A2 = 0.997803 */ + 2099, /* B2 = 0.064064 */ + -1953, /* B1 = -0.119202 */ + 2099, /* B0 = 0.064064 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f500 */ + 30202, /* A1 = -1.843431 */ + -32624, /* A2 = 0.995622 */ + -413, /* B2 = -0.012622 */ + 0, /* B1 = 0.000000 */ + 413, /* B0 = 0.012622 */ + 30191, /* A1 = -1.842721 */ + -32714, /* A2 = 0.998364 */ + 25954, /* B2 = 0.792057 */ + -23890, /* B1 = -1.458131 */ + 25954, /* B0 = 0.792057 */ + 30296, /* A1 = -1.849172 */ + -32715, /* A2 = 0.998397 */ + 2007, /* B2 = 0.061264 */ + -1860, /* B1 = -0.113568 */ + 2007, /* B0 = 0.061264 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f520 */ + 30001, /* A1 = -1.831116 */ + -32613, /* A2 = 0.995270 */ + -155, /* B2 = -0.004750 */ + 0, /* B1 = 0.000000 */ + 155, /* B0 = 0.004750 */ + 29985, /* A1 = -1.830200 */ + -32710, /* A2 = 0.998260 */ + 6584, /* B2 = 0.200928 */ + -6018, /* B1 = -0.367355 */ + 6584, /* B0 = 0.200928 */ + 30105, /* A1 = -1.837524 */ + -32712, /* A2 = 0.998291 */ + 23812, /* B2 = 0.726685 */ + -21936, /* B1 = -1.338928 */ + 23812, /* B0 = 0.726685 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f523 */ + 29964, /* A1 = -1.828918 */ + -32601, /* A2 = 0.994904 */ + -101, /* B2 = -0.003110 */ + 0, /* B1 = 0.000000 */ + 101, /* B0 = 0.003110 */ + 29949, /* A1 = -1.827942 */ + -32700, /* A2 = 0.997925 */ + 11041, /* B2 = 0.336975 */ + -10075, /* B1 = -0.614960 */ + 11041, /* B0 = 0.336975 */ + 30070, /* A1 = -1.835388 */ + -32702, /* A2 = 0.997986 */ + 16762, /* B2 = 0.511536 */ + -15437, /* B1 = -0.942230 */ + 16762, /* B0 = 0.511536 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f525 */ + 29936, /* A1 = -1.827209 */ + -32584, /* A2 = 0.994415 */ + -91, /* B2 = -0.002806 */ + 0, /* B1 = 0.000000 */ + 91, /* B0 = 0.002806 */ + 29921, /* A1 = -1.826233 */ + -32688, /* A2 = 0.997559 */ + 11449, /* B2 = 0.349396 */ + -10426, /* B1 = -0.636383 */ + 11449, /* B0 = 0.349396 */ + 30045, /* A1 = -1.833862 */ + -32688, /* A2 = 0.997589 */ + 13055, /* B2 = 0.398407 */ + -12028, /* B1 = -0.734161 */ + 13055, /* B0 = 0.398407 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f540_660[] */ + 28499, /* A1 = 1.739441 */ + -31129, /* A2 = -0.949982 */ + -849, /* B2 = -0.025922 */ + 0, /* B1 = 0 */ + 849, /* B0 = 0.025922 */ + 28128, /* A1 = 1.716797 */ + -32130, /* A2 = -0.98056 */ + 14556, /* B2 = 0.444214 */ + -12251, /* B1 = -0.747772 */ + 14556, /* B0 = 0.444244 */ + 29667, /* A1 = 1.81073 */ + -32244, /* A2 = -0.984039 */ + 23038, /* B2 = 0.703064 */ + -21358, /* B1 = -1.303589 */ + 23040, /* B0 = 0.703125 */ + 7, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f587 */ + 29271, /* A1 = -1.786560 */ + -32599, /* A2 = 0.994873 */ + -490, /* B2 = -0.014957 */ + 0, /* B1 = 0.000000 */ + 490, /* B0 = 0.014957 */ + 29246, /* A1 = -1.785095 */ + -32700, /* A2 = 0.997925 */ + 28961, /* B2 = 0.883850 */ + -25796, /* B1 = -1.574463 */ + 28961, /* B0 = 0.883850 */ + 29383, /* A1 = -1.793396 */ + -32700, /* A2 = 0.997955 */ + 1299, /* B2 = 0.039650 */ + -1169, /* B1 = -0.071396 */ + 1299, /* B0 = 0.039650 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f590 */ + 29230, /* A1 = -1.784058 */ + -32584, /* A2 = 0.994415 */ + -418, /* B2 = -0.012757 */ + 0, /* B1 = 0.000000 */ + 418, /* B0 = 0.012757 */ + 29206, /* A1 = -1.782593 */ + -32688, /* A2 = 0.997559 */ + 36556, /* B2 = 1.115601 */ + -32478, /* B1 = -1.982300 */ + 36556, /* B0 = 1.115601 */ + 29345, /* A1 = -1.791077 */ + -32688, /* A2 = 0.997589 */ + 897, /* B2 = 0.027397 */ + -808, /* B1 = -0.049334 */ + 897, /* B0 = 0.027397 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f600 */ + 29116, /* A1 = -1.777100 */ + -32603, /* A2 = 0.994965 */ + -165, /* B2 = -0.005039 */ + 0, /* B1 = 0.000000 */ + 165, /* B0 = 0.005039 */ + 29089, /* A1 = -1.775452 */ + -32708, /* A2 = 0.998199 */ + 6963, /* B2 = 0.212494 */ + -6172, /* B1 = -0.376770 */ + 6963, /* B0 = 0.212494 */ + 29237, /* A1 = -1.784485 */ + -32710, /* A2 = 0.998230 */ + 24197, /* B2 = 0.738464 */ + -21657, /* B1 = -1.321899 */ + 24197, /* B0 = 0.738464 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f660 */ + 28376, /* A1 = -1.731934 */ + -32567, /* A2 = 0.993896 */ + -363, /* B2 = -0.011102 */ + 0, /* B1 = 0.000000 */ + 363, /* B0 = 0.011102 */ + 28337, /* A1 = -1.729614 */ + -32683, /* A2 = 0.997434 */ + 21766, /* B2 = 0.664246 */ + -18761, /* B1 = -1.145081 */ + 21766, /* B0 = 0.664246 */ + 28513, /* A1 = -1.740356 */ + -32686, /* A2 = 0.997498 */ + 2509, /* B2 = 0.076584 */ + -2196, /* B1 = -0.134041 */ + 2509, /* B0 = 0.076584 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f700 */ + 27844, /* A1 = -1.699463 */ + -32563, /* A2 = 0.993744 */ + -366, /* B2 = -0.011187 */ + 0, /* B1 = 0.000000 */ + 366, /* B0 = 0.011187 */ + 27797, /* A1 = -1.696655 */ + -32686, /* A2 = 0.997498 */ + 22748, /* B2 = 0.694214 */ + -19235, /* B1 = -1.174072 */ + 22748, /* B0 = 0.694214 */ + 27995, /* A1 = -1.708740 */ + -32688, /* A2 = 0.997559 */ + 2964, /* B2 = 0.090477 */ + -2546, /* B1 = -0.155449 */ + 2964, /* B0 = 0.090477 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f740 */ + 27297, /* A1 = -1.666077 */ + -32551, /* A2 = 0.993408 */ + -345, /* B2 = -0.010540 */ + 0, /* B1 = 0.000000 */ + 345, /* B0 = 0.010540 */ + 27240, /* A1 = -1.662598 */ + -32683, /* A2 = 0.997406 */ + 22560, /* B2 = 0.688477 */ + -18688, /* B1 = -1.140625 */ + 22560, /* B0 = 0.688477 */ + 27461, /* A1 = -1.676147 */ + -32684, /* A2 = 0.997467 */ + 3541, /* B2 = 0.108086 */ + -2985, /* B1 = -0.182220 */ + 3541, /* B0 = 0.108086 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f750 */ + 27155, /* A1 = -1.657410 */ + -32551, /* A2 = 0.993408 */ + -462, /* B2 = -0.014117 */ + 0, /* B1 = 0.000000 */ + 462, /* B0 = 0.014117 */ + 27097, /* A1 = -1.653870 */ + -32683, /* A2 = 0.997406 */ + 32495, /* B2 = 0.991699 */ + -26776, /* B1 = -1.634338 */ + 32495, /* B0 = 0.991699 */ + 27321, /* A1 = -1.667542 */ + -32684, /* A2 = 0.997467 */ + 1835, /* B2 = 0.056007 */ + -1539, /* B1 = -0.093948 */ + 1835, /* B0 = 0.056007 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f750_1450[] */ + 19298, /* A1 = 1.177917 */ + -24471, /* A2 = -0.746796 */ + -4152, /* B2 = -0.126709 */ + 0, /* B1 = 0 */ + 4152, /* B0 = 0.126709 */ + 12902, /* A1 = 0.787476 */ + -29091, /* A2 = -0.887817 */ + 12491, /* B2 = 0.38121 */ + -1794, /* B1 = -0.109528 */ + 12494, /* B0 = 0.381317 */ + 26291, /* A1 = 1.604736 */ + -30470, /* A2 = -0.929901 */ + 28859, /* B2 = 0.880737 */ + -26084, /* B1 = -1.592102 */ + 28861, /* B0 = 0.880798 */ + 7, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f770 */ + 26867, /* A1 = -1.639832 */ + -32551, /* A2 = 0.993408 */ + -123, /* B2 = -0.003755 */ + 0, /* B1 = 0.000000 */ + 123, /* B0 = 0.003755 */ + 26805, /* A1 = -1.636108 */ + -32683, /* A2 = 0.997406 */ + 17297, /* B2 = 0.527863 */ + -14096, /* B1 = -0.860382 */ + 17297, /* B0 = 0.527863 */ + 27034, /* A1 = -1.650085 */ + -32684, /* A2 = 0.997467 */ + 12958, /* B2 = 0.395477 */ + -10756, /* B1 = -0.656525 */ + 12958, /* B0 = 0.395477 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f800 */ + 26413, /* A1 = -1.612122 */ + -32547, /* A2 = 0.993286 */ + -223, /* B2 = -0.006825 */ + 0, /* B1 = 0.000000 */ + 223, /* B0 = 0.006825 */ + 26342, /* A1 = -1.607849 */ + -32686, /* A2 = 0.997498 */ + 6391, /* B2 = 0.195053 */ + -5120, /* B1 = -0.312531 */ + 6391, /* B0 = 0.195053 */ + 26593, /* A1 = -1.623108 */ + -32688, /* A2 = 0.997559 */ + 23681, /* B2 = 0.722717 */ + -19328, /* B1 = -1.179688 */ + 23681, /* B0 = 0.722717 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f816 */ + 26168, /* A1 = -1.597209 */ + -32528, /* A2 = 0.992706 */ + -235, /* B2 = -0.007182 */ + 0, /* B1 = 0.000000 */ + 235, /* B0 = 0.007182 */ + 26092, /* A1 = -1.592590 */ + -32675, /* A2 = 0.997192 */ + 20823, /* B2 = 0.635498 */ + -16510, /* B1 = -1.007751 */ + 20823, /* B0 = 0.635498 */ + 26363, /* A1 = -1.609070 */ + -32677, /* A2 = 0.997253 */ + 6739, /* B2 = 0.205688 */ + -5459, /* B1 = -0.333206 */ + 6739, /* B0 = 0.205688 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f850 */ + 25641, /* A1 = -1.565063 */ + -32536, /* A2 = 0.992950 */ + -121, /* B2 = -0.003707 */ + 0, /* B1 = 0.000000 */ + 121, /* B0 = 0.003707 */ + 25560, /* A1 = -1.560059 */ + -32684, /* A2 = 0.997437 */ + 18341, /* B2 = 0.559753 */ + -14252, /* B1 = -0.869904 */ + 18341, /* B0 = 0.559753 */ + 25837, /* A1 = -1.577026 */ + -32684, /* A2 = 0.997467 */ + 16679, /* B2 = 0.509003 */ + -13232, /* B1 = -0.807648 */ + 16679, /* B0 = 0.509003 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f857_1645[] */ + 16415, /* A1 = 1.001953 */ + -23669, /* A2 = -0.722321 */ + -4549, /* B2 = -0.138847 */ + 0, /* B1 = 0 */ + 4549, /* B0 = 0.138847 */ + 8456, /* A1 = 0.516174 */ + -28996, /* A2 = -0.884918 */ + 13753, /* B2 = 0.419724 */ + -12, /* B1 = -0.000763 */ + 13757, /* B0 = 0.419846 */ + 24632, /* A1 = 1.503418 */ + -30271, /* A2 = -0.923828 */ + 29070, /* B2 = 0.887146 */ + -25265, /* B1 = -1.542114 */ + 29073, /* B0 = 0.887268 */ + 7, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f900 */ + 24806, /* A1 = -1.514099 */ + -32501, /* A2 = 0.991852 */ + -326, /* B2 = -0.009969 */ + 0, /* B1 = 0.000000 */ + 326, /* B0 = 0.009969 */ + 24709, /* A1 = -1.508118 */ + -32659, /* A2 = 0.996674 */ + 20277, /* B2 = 0.618835 */ + -15182, /* B1 = -0.926636 */ + 20277, /* B0 = 0.618835 */ + 25022, /* A1 = -1.527222 */ + -32661, /* A2 = 0.996735 */ + 4320, /* B2 = 0.131836 */ + -3331, /* B1 = -0.203339 */ + 4320, /* B0 = 0.131836 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f900_1300[] */ + 19776, /* A1 = 1.207092 */ + -27437, /* A2 = -0.837341 */ + -2666, /* B2 = -0.081371 */ + 0, /* B1 = 0 */ + 2666, /* B0 = 0.081371 */ + 16302, /* A1 = 0.995026 */ + -30354, /* A2 = -0.926361 */ + 10389, /* B2 = 0.317062 */ + -3327, /* B1 = -0.203064 */ + 10389, /* B0 = 0.317062 */ + 24299, /* A1 = 1.483154 */ + -30930, /* A2 = -0.943909 */ + 25016, /* B2 = 0.763428 */ + -21171, /* B1 = -1.292236 */ + 25016, /* B0 = 0.763428 */ + 7, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f935_1215[] */ + 20554, /* A1 = 1.254517 */ + -28764, /* A2 = -0.877838 */ + -2048, /* B2 = -0.062515 */ + 0, /* B1 = 0 */ + 2048, /* B0 = 0.062515 */ + 18209, /* A1 = 1.11145 */ + -30951, /* A2 = -0.94458 */ + 9390, /* B2 = 0.286575 */ + -3955, /* B1 = -0.241455 */ + 9390, /* B0 = 0.286575 */ + 23902, /* A1 = 1.458923 */ + -31286, /* A2 = -0.954803 */ + 23252, /* B2 = 0.709595 */ + -19132, /* B1 = -1.167725 */ + 23252, /* B0 = 0.709595 */ + 7, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f941_1477[] */ + 17543, /* A1 = 1.07074 */ + -26220, /* A2 = -0.800201 */ + -3298, /* B2 = -0.100647 */ + 0, /* B1 = 0 */ + 3298, /* B0 = 0.100647 */ + 12423, /* A1 = 0.75827 */ + -30036, /* A2 = -0.916626 */ + 12651, /* B2 = 0.386078 */ + -2444, /* B1 = -0.14917 */ + 12653, /* B0 = 0.386154 */ + 23518, /* A1 = 1.435425 */ + -30745, /* A2 = -0.938293 */ + 27282, /* B2 = 0.832581 */ + -22529, /* B1 = -1.375122 */ + 27286, /* B0 = 0.832703 */ + 7, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f942 */ + 24104, /* A1 = -1.471252 */ + -32507, /* A2 = 0.992065 */ + -351, /* B2 = -0.010722 */ + 0, /* B1 = 0.000000 */ + 351, /* B0 = 0.010722 */ + 23996, /* A1 = -1.464600 */ + -32671, /* A2 = 0.997040 */ + 22848, /* B2 = 0.697266 */ + -16639, /* B1 = -1.015564 */ + 22848, /* B0 = 0.697266 */ + 24332, /* A1 = -1.485168 */ + -32673, /* A2 = 0.997101 */ + 4906, /* B2 = 0.149727 */ + -3672, /* B1 = -0.224174 */ + 4906, /* B0 = 0.149727 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f950 */ + 23967, /* A1 = -1.462830 */ + -32507, /* A2 = 0.992065 */ + -518, /* B2 = -0.015821 */ + 0, /* B1 = 0.000000 */ + 518, /* B0 = 0.015821 */ + 23856, /* A1 = -1.456055 */ + -32671, /* A2 = 0.997040 */ + 26287, /* B2 = 0.802246 */ + -19031, /* B1 = -1.161560 */ + 26287, /* B0 = 0.802246 */ + 24195, /* A1 = -1.476746 */ + -32673, /* A2 = 0.997101 */ + 2890, /* B2 = 0.088196 */ + -2151, /* B1 = -0.131317 */ + 2890, /* B0 = 0.088196 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f950_1400[] */ + 18294, /* A1 = 1.116638 */ + -26962, /* A2 = -0.822845 */ + -2914, /* B2 = -0.088936 */ + 0, /* B1 = 0 */ + 2914, /* B0 = 0.088936 */ + 14119, /* A1 = 0.861786 */ + -30227, /* A2 = -0.922455 */ + 11466, /* B2 = 0.349945 */ + -2833, /* B1 = -0.172943 */ + 11466, /* B0 = 0.349945 */ + 23431, /* A1 = 1.430115 */ + -30828, /* A2 = -0.940796 */ + 25331, /* B2 = 0.773071 */ + -20911, /* B1 = -1.276367 */ + 25331, /* B0 = 0.773071 */ + 7, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f975 */ + 23521, /* A1 = -1.435608 */ + -32489, /* A2 = 0.991516 */ + -193, /* B2 = -0.005915 */ + 0, /* B1 = 0.000000 */ + 193, /* B0 = 0.005915 */ + 23404, /* A1 = -1.428467 */ + -32655, /* A2 = 0.996582 */ + 17740, /* B2 = 0.541412 */ + -12567, /* B1 = -0.767029 */ + 17740, /* B0 = 0.541412 */ + 23753, /* A1 = -1.449829 */ + -32657, /* A2 = 0.996613 */ + 9090, /* B2 = 0.277405 */ + -6662, /* B1 = -0.406647 */ + 9090, /* B0 = 0.277405 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f1000 */ + 23071, /* A1 = -1.408203 */ + -32489, /* A2 = 0.991516 */ + -293, /* B2 = -0.008965 */ + 0, /* B1 = 0.000000 */ + 293, /* B0 = 0.008965 */ + 22951, /* A1 = -1.400818 */ + -32655, /* A2 = 0.996582 */ + 5689, /* B2 = 0.173645 */ + -3951, /* B1 = -0.241150 */ + 5689, /* B0 = 0.173645 */ + 23307, /* A1 = -1.422607 */ + -32657, /* A2 = 0.996613 */ + 18692, /* B2 = 0.570435 */ + -13447, /* B1 = -0.820770 */ + 18692, /* B0 = 0.570435 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f1020 */ + 22701, /* A1 = -1.385620 */ + -32474, /* A2 = 0.991058 */ + -292, /* B2 = -0.008933 */ + 0, /*163840 , B1 = 10.000000 */ + 292, /* B0 = 0.008933 */ + 22564, /* A1 = -1.377258 */ + -32655, /* A2 = 0.996552 */ + 20756, /* B2 = 0.633423 */ + -14176, /* B1 = -0.865295 */ + 20756, /* B0 = 0.633423 */ + 22960, /* A1 = -1.401428 */ + -32657, /* A2 = 0.996613 */ + 6520, /* B2 = 0.198990 */ + -4619, /* B1 = -0.281937 */ + 6520, /* B0 = 0.198990 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f1050 */ + 22142, /* A1 = -1.351501 */ + -32474, /* A2 = 0.991058 */ + -147, /* B2 = -0.004493 */ + 0, /* B1 = 0.000000 */ + 147, /* B0 = 0.004493 */ + 22000, /* A1 = -1.342834 */ + -32655, /* A2 = 0.996552 */ + 15379, /* B2 = 0.469360 */ + -10237, /* B1 = -0.624847 */ + 15379, /* B0 = 0.469360 */ + 22406, /* A1 = -1.367554 */ + -32657, /* A2 = 0.996613 */ + 17491, /* B2 = 0.533783 */ + -12096, /* B1 = -0.738312 */ + 17491, /* B0 = 0.533783 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f1100_1750[] */ + 12973, /* A1 = 0.79184 */ + -24916, /* A2 = -0.760376 */ + 6655, /* B2 = 0.203102 */ + 367, /* B1 = 0.0224 */ + 6657, /* B0 = 0.203171 */ + 5915, /* A1 = 0.361053 */ + -29560, /* A2 = -0.90213 */ + -7777, /* B2 = -0.23735 */ + 0, /* B1 = 0 */ + 7777, /* B0 = 0.23735 */ + 20510, /* A1 = 1.251892 */ + -30260, /* A2 = -0.923462 */ + 26662, /* B2 = 0.81366 */ + -20573, /* B1 = -1.255737 */ + 26668, /* B0 = 0.813843 */ + 7, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f1140 */ + 20392, /* A1 = -1.244629 */ + -32460, /* A2 = 0.990601 */ + -270, /* B2 = -0.008240 */ + 0, /* B1 = 0.000000 */ + 270, /* B0 = 0.008240 */ + 20218, /* A1 = -1.234009 */ + -32655, /* A2 = 0.996582 */ + 21337, /* B2 = 0.651154 */ + -13044, /* B1 = -0.796143 */ + 21337, /* B0 = 0.651154 */ + 20684, /* A1 = -1.262512 */ + -32657, /* A2 = 0.996643 */ + 8572, /* B2 = 0.261612 */ + -5476, /* B1 = -0.334244 */ + 8572, /* B0 = 0.261612 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f1200 */ + 19159, /* A1 = -1.169373 */ + -32456, /* A2 = 0.990509 */ + -335, /* B2 = -0.010252 */ + 0, /* B1 = 0.000000 */ + 335, /* B0 = 0.010252 */ + 18966, /* A1 = -1.157593 */ + -32661, /* A2 = 0.996735 */ + 6802, /* B2 = 0.207588 */ + -3900, /* B1 = -0.238098 */ + 6802, /* B0 = 0.207588 */ + 19467, /* A1 = -1.188232 */ + -32661, /* A2 = 0.996765 */ + 25035, /* B2 = 0.764008 */ + -15049, /* B1 = -0.918579 */ + 25035, /* B0 = 0.764008 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f1209 */ + 18976, /* A1 = -1.158264 */ + -32439, /* A2 = 0.989990 */ + -183, /* B2 = -0.005588 */ + 0, /* B1 = 0.000000 */ + 183, /* B0 = 0.005588 */ + 18774, /* A1 = -1.145874 */ + -32650, /* A2 = 0.996429 */ + 15468, /* B2 = 0.472076 */ + -8768, /* B1 = -0.535217 */ + 15468, /* B0 = 0.472076 */ + 19300, /* A1 = -1.177979 */ + -32652, /* A2 = 0.996490 */ + 19840, /* B2 = 0.605499 */ + -11842, /* B1 = -0.722809 */ + 19840, /* B0 = 0.605499 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f1330 */ + 16357, /* A1 = -0.998413 */ + -32368, /* A2 = 0.987793 */ + -217, /* B2 = -0.006652 */ + 0, /* B1 = 0.000000 */ + 217, /* B0 = 0.006652 */ + 16107, /* A1 = -0.983126 */ + -32601, /* A2 = 0.994904 */ + 11602, /* B2 = 0.354065 */ + -5555, /* B1 = -0.339111 */ + 11602, /* B0 = 0.354065 */ + 16722, /* A1 = -1.020630 */ + -32603, /* A2 = 0.994965 */ + 15574, /* B2 = 0.475311 */ + -8176, /* B1 = -0.499069 */ + 15574, /* B0 = 0.475311 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f1336 */ + 16234, /* A1 = -0.990875 */ + 32404, /* A2 = -0.988922 */ + -193, /* B2 = -0.005908 */ + 0, /* B1 = 0.000000 */ + 193, /* B0 = 0.005908 */ + 15986, /* A1 = -0.975769 */ + -32632, /* A2 = 0.995880 */ + 18051, /* B2 = 0.550903 */ + -8658, /* B1 = -0.528473 */ + 18051, /* B0 = 0.550903 */ + 16591, /* A1 = -1.012695 */ + -32634, /* A2 = 0.995941 */ + 15736, /* B2 = 0.480240 */ + -8125, /* B1 = -0.495926 */ + 15736, /* B0 = 0.480240 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f1366 */ + 15564, /* A1 = -0.949982 */ + -32404, /* A2 = 0.988922 */ + -269, /* B2 = -0.008216 */ + 0, /* B1 = 0.000000 */ + 269, /* B0 = 0.008216 */ + 15310, /* A1 = -0.934479 */ + -32632, /* A2 = 0.995880 */ + 10815, /* B2 = 0.330063 */ + -4962, /* B1 = -0.302887 */ + 10815, /* B0 = 0.330063 */ + 15924, /* A1 = -0.971924 */ + -32634, /* A2 = 0.995941 */ + 18880, /* B2 = 0.576172 */ + -9364, /* B1 = -0.571594 */ + 18880, /* B0 = 0.576172 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f1380 */ + 15247, /* A1 = -0.930603 */ + -32397, /* A2 = 0.988708 */ + -244, /* B2 = -0.007451 */ + 0, /* B1 = 0.000000 */ + 244, /* B0 = 0.007451 */ + 14989, /* A1 = -0.914886 */ + -32627, /* A2 = 0.995697 */ + 18961, /* B2 = 0.578644 */ + -8498, /* B1 = -0.518707 */ + 18961, /* B0 = 0.578644 */ + 15608, /* A1 = -0.952667 */ + -32628, /* A2 = 0.995758 */ + 11145, /* B2 = 0.340134 */ + -5430, /* B1 = -0.331467 */ + 11145, /* B0 = 0.340134 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f1400 */ + 14780, /* A1 = -0.902130 */ + -32393, /* A2 = 0.988586 */ + -396, /* B2 = -0.012086 */ + 0, /* B1 = 0.000000 */ + 396, /* B0 = 0.012086 */ + 14510, /* A1 = -0.885651 */ + -32630, /* A2 = 0.995819 */ + 6326, /* B2 = 0.193069 */ + -2747, /* B1 = -0.167671 */ + 6326, /* B0 = 0.193069 */ + 15154, /* A1 = -0.924957 */ + -32632, /* A2 = 0.995850 */ + 23235, /* B2 = 0.709076 */ + -10983, /* B1 = -0.670380 */ + 23235, /* B0 = 0.709076 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f1477 */ + 13005, /* A1 = -0.793793 */ + -32368, /* A2 = 0.987823 */ + -500, /* B2 = -0.015265 */ + 0, /* B1 = 0.000000 */ + 500, /* B0 = 0.015265 */ + 12708, /* A1 = -0.775665 */ + -32615, /* A2 = 0.995331 */ + 11420, /* B2 = 0.348526 */ + -4306, /* B1 = -0.262833 */ + 11420, /* B0 = 0.348526 */ + 13397, /* A1 = -0.817688 */ + -32615, /* A2 = 0.995361 */ + 9454, /* B2 = 0.288528 */ + -3981, /* B1 = -0.243027 */ + 9454, /* B0 = 0.288528 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f1600 */ + 10046, /* A1 = -0.613190 */ + -32331, /* A2 = 0.986694 */ + -455, /* B2 = -0.013915 */ + 0, /* B1 = 0.000000 */ + 455, /* B0 = 0.013915 */ + 9694, /* A1 = -0.591705 */ + -32601, /* A2 = 0.994934 */ + 6023, /* B2 = 0.183815 */ + -1708, /* B1 = -0.104279 */ + 6023, /* B0 = 0.183815 */ + 10478, /* A1 = -0.639587 */ + -32603, /* A2 = 0.994965 */ + 22031, /* B2 = 0.672333 */ + -7342, /* B1 = -0.448151 */ + 22031, /* B0 = 0.672333 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f1633_1638[] */ + 9181, /* A1 = 0.560394 */ + -32256, /* A2 = -0.984375 */ + -556, /* B2 = -0.016975 */ + 0, /* B1 = 0 */ + 556, /* B0 = 0.016975 */ + 8757, /* A1 = 0.534515 */ + -32574, /* A2 = -0.99408 */ + 8443, /* B2 = 0.25769 */ + -2135, /* B1 = -0.130341 */ + 8443, /* B0 = 0.25769 */ + 9691, /* A1 = 0.591522 */ + -32574, /* A2 = -0.99411 */ + 15446, /* B2 = 0.471375 */ + -4809, /* B1 = -0.293579 */ + 15446, /* B0 = 0.471375 */ + 7, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f1800 */ + 5076, /* A1 = -0.309875 */ + -32304, /* A2 = 0.985840 */ + -508, /* B2 = -0.015503 */ + 0, /* B1 = 0.000000 */ + 508, /* B0 = 0.015503 */ + 4646, /* A1 = -0.283600 */ + -32605, /* A2 = 0.995026 */ + 6742, /* B2 = 0.205780 */ + -878, /* B1 = -0.053635 */ + 6742, /* B0 = 0.205780 */ + 5552, /* A1 = -0.338928 */ + -32605, /* A2 = 0.995056 */ + 23667, /* B2 = 0.722260 */ + -4297, /* B1 = -0.262329 */ + 23667, /* B0 = 0.722260 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, + { /* f1860 */ + 3569, /* A1 = -0.217865 */ + -32292, /* A2 = 0.985504 */ + -239, /* B2 = -0.007322 */ + 0, /* B1 = 0.000000 */ + 239, /* B0 = 0.007322 */ + 3117, /* A1 = -0.190277 */ + -32603, /* A2 = 0.994965 */ + 18658, /* B2 = 0.569427 */ + -1557, /* B1 = -0.095032 */ + 18658, /* B0 = 0.569427 */ + 4054, /* A1 = -0.247437 */ + -32603, /* A2 = 0.994965 */ + 18886, /* B2 = 0.576385 */ + -2566, /* B1 = -0.156647 */ + 18886, /* B0 = 0.576385 */ + 5, /* Internal filter scaling */ + 159, /* Minimum in-band energy threshold */ + 21, /* 21/32 in-band to broad-band ratio */ + 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ + }, +}; +static int ixj_init_filter(IXJ *j, IXJ_FILTER * jf) +{ + unsigned short cmd; + int cnt, max; + + if (jf->filter > 3) { + return -1; + } + if (ixj_WriteDSPCommand(0x5154 + jf->filter, j)) /* Select Filter */ + + return -1; + if (!jf->enable) { + if (ixj_WriteDSPCommand(0x5152, j)) /* Disable Filter */ + + return -1; + else + return 0; + } else { + if (ixj_WriteDSPCommand(0x5153, j)) /* Enable Filter */ + + return -1; + /* Select the filter (f0 - f3) to use. */ + if (ixj_WriteDSPCommand(0x5154 + jf->filter, j)) + return -1; + } + if (jf->freq < 12 && jf->freq > 3) { + /* Select the frequency for the selected filter. */ + if (ixj_WriteDSPCommand(0x5170 + jf->freq, j)) + return -1; + } else if (jf->freq > 11) { + /* We need to load a programmable filter set for undefined */ + /* frequencies. So we will point the filter to a programmable set. */ + /* Since there are only 4 filters and 4 programmable sets, we will */ + /* just point the filter to the same number set and program it for the */ + /* frequency we want. */ + if (ixj_WriteDSPCommand(0x5170 + jf->filter, j)) + return -1; + if (j->ver.low != 0x12) { + cmd = 0x515B; + max = 19; + } else { + cmd = 0x515E; + max = 15; + } + if (ixj_WriteDSPCommand(cmd, j)) + return -1; + for (cnt = 0; cnt < max; cnt++) { + if (ixj_WriteDSPCommand(tone_table[jf->freq - 12][cnt], j)) + return -1; + } + } + j->filter_en[jf->filter] = jf->enable; + return 0; +} + +static int ixj_init_filter_raw(IXJ *j, IXJ_FILTER_RAW * jfr) +{ + unsigned short cmd; + int cnt, max; + if (jfr->filter > 3) { + return -1; + } + if (ixj_WriteDSPCommand(0x5154 + jfr->filter, j)) /* Select Filter */ + return -1; + + if (!jfr->enable) { + if (ixj_WriteDSPCommand(0x5152, j)) /* Disable Filter */ + return -1; + else + return 0; + } else { + if (ixj_WriteDSPCommand(0x5153, j)) /* Enable Filter */ + return -1; + /* Select the filter (f0 - f3) to use. */ + if (ixj_WriteDSPCommand(0x5154 + jfr->filter, j)) + return -1; + } + /* We need to load a programmable filter set for undefined */ + /* frequencies. So we will point the filter to a programmable set. */ + /* Since there are only 4 filters and 4 programmable sets, we will */ + /* just point the filter to the same number set and program it for the */ + /* frequency we want. */ + if (ixj_WriteDSPCommand(0x5170 + jfr->filter, j)) + return -1; + if (j->ver.low != 0x12) { + cmd = 0x515B; + max = 19; + } else { + cmd = 0x515E; + max = 15; + } + if (ixj_WriteDSPCommand(cmd, j)) + return -1; + for (cnt = 0; cnt < max; cnt++) { + if (ixj_WriteDSPCommand(jfr->coeff[cnt], j)) + return -1; + } + j->filter_en[jfr->filter] = jfr->enable; + return 0; +} + +static int ixj_init_tone(IXJ *j, IXJ_TONE * ti) +{ + int freq0, freq1; + unsigned short data; + if (ti->freq0) { + freq0 = ti->freq0; + } else { + freq0 = 0x7FFF; + } + + if (ti->freq1) { + freq1 = ti->freq1; + } else { + freq1 = 0x7FFF; + } + + if(ti->tone_index > 12 && ti->tone_index < 28) + { + if (ixj_WriteDSPCommand(0x6800 + ti->tone_index, j)) + return -1; + if (ixj_WriteDSPCommand(0x6000 + (ti->gain1 << 4) + ti->gain0, j)) + return -1; + data = freq0; + if (ixj_WriteDSPCommand(data, j)) + return -1; + data = freq1; + if (ixj_WriteDSPCommand(data, j)) + return -1; + } + return freq0; +} + diff --git a/drivers/staging/telephony/ixj.h b/drivers/staging/telephony/ixj.h new file mode 100644 index 00000000000..2c841134f61 --- /dev/null +++ b/drivers/staging/telephony/ixj.h @@ -0,0 +1,1322 @@ +/****************************************************************************** + * ixj.h + * + * + * Device Driver for Quicknet Technologies, Inc.'s Telephony cards + * including the Internet PhoneJACK, Internet PhoneJACK Lite, + * Internet PhoneJACK PCI, Internet LineJACK, Internet PhoneCARD and + * SmartCABLE + * + * (c) Copyright 1999-2001 Quicknet Technologies, 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. + * + * Author: Ed Okerson, + * + * Contributors: Greg Herlein, + * David W. Erhart, + * John Sellers, + * Mike Preston, + * + * More information about the hardware related to this driver can be found + * at our website: http://www.quicknet.net + * + * Fixes: + * + * IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF QUICKNET + * TECHNOLOGIES, INC.HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * QUICKNET TECHNOLOGIES, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND QUICKNET TECHNOLOGIES, INC. HAS NO OBLIGATION + * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + *****************************************************************************/ +#define IXJ_VERSION 3031 + +#include + +#include +#include + +typedef __u16 WORD; +typedef __u32 DWORD; +typedef __u8 BYTE; + +#ifndef IXJMAX +#define IXJMAX 16 +#endif + +/****************************************************************************** +* +* This structure when unioned with the structures below makes simple byte +* access to the registers easier. +* +******************************************************************************/ +typedef struct { + unsigned char low; + unsigned char high; +} BYTES; + +typedef union { + BYTES bytes; + short word; +} IXJ_WORD; + +typedef struct{ + unsigned int b0:1; + unsigned int b1:1; + unsigned int b2:1; + unsigned int b3:1; + unsigned int b4:1; + unsigned int b5:1; + unsigned int b6:1; + unsigned int b7:1; +} IXJ_CBITS; + +typedef union{ + IXJ_CBITS cbits; + char cbyte; +} IXJ_CBYTE; + +/****************************************************************************** +* +* This structure represents the Hardware Control Register of the CT8020/8021 +* The CT8020 is used in the Internet PhoneJACK, and the 8021 in the +* Internet LineJACK +* +******************************************************************************/ +typedef struct { + unsigned int rxrdy:1; + unsigned int txrdy:1; + unsigned int status:1; + unsigned int auxstatus:1; + unsigned int rxdma:1; + unsigned int txdma:1; + unsigned int rxburst:1; + unsigned int txburst:1; + unsigned int dmadir:1; + unsigned int cont:1; + unsigned int irqn:1; + unsigned int t:5; +} HCRBIT; + +typedef union { + HCRBIT bits; + BYTES bytes; +} HCR; + +/****************************************************************************** +* +* This structure represents the Hardware Status Register of the CT8020/8021 +* The CT8020 is used in the Internet PhoneJACK, and the 8021 in the +* Internet LineJACK +* +******************************************************************************/ +typedef struct { + unsigned int controlrdy:1; + unsigned int auxctlrdy:1; + unsigned int statusrdy:1; + unsigned int auxstatusrdy:1; + unsigned int rxrdy:1; + unsigned int txrdy:1; + unsigned int restart:1; + unsigned int irqn:1; + unsigned int rxdma:1; + unsigned int txdma:1; + unsigned int cohostshutdown:1; + unsigned int t:5; +} HSRBIT; + +typedef union { + HSRBIT bits; + BYTES bytes; +} HSR; + +/****************************************************************************** +* +* This structure represents the General Purpose IO Register of the CT8020/8021 +* The CT8020 is used in the Internet PhoneJACK, and the 8021 in the +* Internet LineJACK +* +******************************************************************************/ +typedef struct { + unsigned int x:1; + unsigned int gpio1:1; + unsigned int gpio2:1; + unsigned int gpio3:1; + unsigned int gpio4:1; + unsigned int gpio5:1; + unsigned int gpio6:1; + unsigned int gpio7:1; + unsigned int xread:1; + unsigned int gpio1read:1; + unsigned int gpio2read:1; + unsigned int gpio3read:1; + unsigned int gpio4read:1; + unsigned int gpio5read:1; + unsigned int gpio6read:1; + unsigned int gpio7read:1; +} GPIOBIT; + +typedef union { + GPIOBIT bits; + BYTES bytes; + unsigned short word; +} GPIO; + +/****************************************************************************** +* +* This structure represents the Line Monitor status response +* +******************************************************************************/ +typedef struct { + unsigned int digit:4; + unsigned int cpf_valid:1; + unsigned int dtmf_valid:1; + unsigned int peak:1; + unsigned int z:1; + unsigned int f0:1; + unsigned int f1:1; + unsigned int f2:1; + unsigned int f3:1; + unsigned int frame:4; +} LMON; + +typedef union { + LMON bits; + BYTES bytes; +} DTMF; + +typedef struct { + unsigned int z:7; + unsigned int dtmf_en:1; + unsigned int y:4; + unsigned int F3:1; + unsigned int F2:1; + unsigned int F1:1; + unsigned int F0:1; +} CP; + +typedef union { + CP bits; + BYTES bytes; +} CPTF; + +/****************************************************************************** +* +* This structure represents the Status Control Register on the Internet +* LineJACK +* +******************************************************************************/ +typedef struct { + unsigned int c0:1; + unsigned int c1:1; + unsigned int stereo:1; + unsigned int daafsyncen:1; + unsigned int led1:1; + unsigned int led2:1; + unsigned int led3:1; + unsigned int led4:1; +} PSCRWI; /* Internet LineJACK and Internet PhoneJACK Lite */ + +typedef struct { + unsigned int eidp:1; + unsigned int eisd:1; + unsigned int x:6; +} PSCRWP; /* Internet PhoneJACK PCI */ + +typedef union { + PSCRWI bits; + PSCRWP pcib; + char byte; +} PLD_SCRW; + +typedef struct { + unsigned int c0:1; + unsigned int c1:1; + unsigned int x:1; + unsigned int d0ee:1; + unsigned int mixerbusy:1; + unsigned int sci:1; + unsigned int dspflag:1; + unsigned int daaflag:1; +} PSCRRI; + +typedef struct { + unsigned int eidp:1; + unsigned int eisd:1; + unsigned int x:4; + unsigned int dspflag:1; + unsigned int det:1; +} PSCRRP; + +typedef union { + PSCRRI bits; + PSCRRP pcib; + char byte; +} PLD_SCRR; + +/****************************************************************************** +* +* These structures represents the SLIC Control Register on the +* Internet LineJACK +* +******************************************************************************/ +typedef struct { + unsigned int c1:1; + unsigned int c2:1; + unsigned int c3:1; + unsigned int b2en:1; + unsigned int spken:1; + unsigned int rly1:1; + unsigned int rly2:1; + unsigned int rly3:1; +} PSLICWRITE; + +typedef struct { + unsigned int state:3; + unsigned int b2en:1; + unsigned int spken:1; + unsigned int c3:1; + unsigned int potspstn:1; + unsigned int det:1; +} PSLICREAD; + +typedef struct { + unsigned int c1:1; + unsigned int c2:1; + unsigned int c3:1; + unsigned int b2en:1; + unsigned int e1:1; + unsigned int mic:1; + unsigned int spk:1; + unsigned int x:1; +} PSLICPCI; + +typedef union { + PSLICPCI pcib; + PSLICWRITE bits; + PSLICREAD slic; + char byte; +} PLD_SLICW; + +typedef union { + PSLICPCI pcib; + PSLICREAD bits; + char byte; +} PLD_SLICR; + +/****************************************************************************** +* +* These structures represents the Clock Control Register on the +* Internet LineJACK +* +******************************************************************************/ +typedef struct { + unsigned int clk0:1; + unsigned int clk1:1; + unsigned int clk2:1; + unsigned int x0:1; + unsigned int slic_e1:1; + unsigned int x1:1; + unsigned int x2:1; + unsigned int x3:1; +} PCLOCK; + +typedef union { + PCLOCK bits; + char byte; +} PLD_CLOCK; + +/****************************************************************************** +* +* These structures deal with the mixer on the Internet LineJACK +* +******************************************************************************/ + +typedef struct { + unsigned short vol[10]; + unsigned int recsrc; + unsigned int modcnt; + unsigned short micpreamp; +} MIX; + +/****************************************************************************** +* +* These structures deal with the control logic on the Internet PhoneCARD +* +******************************************************************************/ +typedef struct { + unsigned int x0:4; /* unused bits */ + + unsigned int ed:1; /* Event Detect */ + + unsigned int drf:1; /* SmartCABLE Removal Flag 1=no cable */ + + unsigned int dspf:1; /* DSP Flag 1=DSP Ready */ + + unsigned int crr:1; /* Control Register Ready */ + +} COMMAND_REG1; + +typedef union { + COMMAND_REG1 bits; + unsigned char byte; +} PCMCIA_CR1; + +typedef struct { + unsigned int x0:4; /* unused bits */ + + unsigned int rstc:1; /* SmartCABLE Reset */ + + unsigned int pwr:1; /* SmartCABLE Power */ + + unsigned int x1:2; /* unused bits */ + +} COMMAND_REG2; + +typedef union { + COMMAND_REG2 bits; + unsigned char byte; +} PCMCIA_CR2; + +typedef struct { + unsigned int addr:5; /* R/W SmartCABLE Register Address */ + + unsigned int rw:1; /* Read / Write flag */ + + unsigned int dev:2; /* 2 bit SmartCABLE Device Address */ + +} CONTROL_REG; + +typedef union { + CONTROL_REG bits; + unsigned char byte; +} PCMCIA_SCCR; + +typedef struct { + unsigned int hsw:1; + unsigned int det:1; + unsigned int led2:1; + unsigned int led1:1; + unsigned int ring1:1; + unsigned int ring0:1; + unsigned int x:1; + unsigned int powerdown:1; +} PCMCIA_SLIC_REG; + +typedef union { + PCMCIA_SLIC_REG bits; + unsigned char byte; +} PCMCIA_SLIC; + +typedef struct { + unsigned int cpd:1; /* Chip Power Down */ + + unsigned int mpd:1; /* MIC Bias Power Down */ + + unsigned int hpd:1; /* Handset Drive Power Down */ + + unsigned int lpd:1; /* Line Drive Power Down */ + + unsigned int spd:1; /* Speaker Drive Power Down */ + + unsigned int x:2; /* unused bits */ + + unsigned int sr:1; /* Software Reset */ + +} Si3CONTROL1; + +typedef union { + Si3CONTROL1 bits; + unsigned char byte; +} Si3C1; + +typedef struct { + unsigned int al:1; /* Analog Loopback DAC analog -> ADC analog */ + + unsigned int dl2:1; /* Digital Loopback DAC -> ADC one bit */ + + unsigned int dl1:1; /* Digital Loopback ADC -> DAC one bit */ + + unsigned int pll:1; /* 1 = div 10, 0 = div 5 */ + + unsigned int hpd:1; /* HPF disable */ + + unsigned int x:3; /* unused bits */ + +} Si3CONTROL2; + +typedef union { + Si3CONTROL2 bits; + unsigned char byte; +} Si3C2; + +typedef struct { + unsigned int iir:1; /* 1 enables IIR, 0 enables FIR */ + + unsigned int him:1; /* Handset Input Mute */ + + unsigned int mcm:1; /* MIC In Mute */ + + unsigned int mcg:2; /* MIC In Gain */ + + unsigned int lim:1; /* Line In Mute */ + + unsigned int lig:2; /* Line In Gain */ + +} Si3RXGAIN; + +typedef union { + Si3RXGAIN bits; + unsigned char byte; +} Si3RXG; + +typedef struct { + unsigned int hom:1; /* Handset Out Mute */ + + unsigned int lom:1; /* Line Out Mute */ + + unsigned int rxg:5; /* RX PGA Gain */ + + unsigned int x:1; /* unused bit */ + +} Si3ADCVOLUME; + +typedef union { + Si3ADCVOLUME bits; + unsigned char byte; +} Si3ADC; + +typedef struct { + unsigned int srm:1; /* Speaker Right Mute */ + + unsigned int slm:1; /* Speaker Left Mute */ + + unsigned int txg:5; /* TX PGA Gain */ + + unsigned int x:1; /* unused bit */ + +} Si3DACVOLUME; + +typedef union { + Si3DACVOLUME bits; + unsigned char byte; +} Si3DAC; + +typedef struct { + unsigned int x:5; /* unused bit */ + + unsigned int losc:1; /* Line Out Short Circuit */ + + unsigned int srsc:1; /* Speaker Right Short Circuit */ + + unsigned int slsc:1; /* Speaker Left Short Circuit */ + +} Si3STATUSREPORT; + +typedef union { + Si3STATUSREPORT bits; + unsigned char byte; +} Si3STAT; + +typedef struct { + unsigned int sot:2; /* Speaker Out Attenuation */ + + unsigned int lot:2; /* Line Out Attenuation */ + + unsigned int x:4; /* unused bits */ + +} Si3ANALOGATTN; + +typedef union { + Si3ANALOGATTN bits; + unsigned char byte; +} Si3AATT; + +/****************************************************************************** +* +* These structures deal with the DAA on the Internet LineJACK +* +******************************************************************************/ + +typedef struct _DAA_REGS { + /*----------------------------------------------- */ + /* SOP Registers */ + /* */ + BYTE bySOP; + + union _SOP_REGS { + struct _SOP { + union /* SOP - CR0 Register */ + { + BYTE reg; + struct _CR0_BITREGS { + BYTE CLK_EXT:1; /* cr0[0:0] */ + + BYTE RIP:1; /* cr0[1:1] */ + + BYTE AR:1; /* cr0[2:2] */ + + BYTE AX:1; /* cr0[3:3] */ + + BYTE FRR:1; /* cr0[4:4] */ + + BYTE FRX:1; /* cr0[5:5] */ + + BYTE IM:1; /* cr0[6:6] */ + + BYTE TH:1; /* cr0[7:7] */ + + } bitreg; + } cr0; + + union /* SOP - CR1 Register */ + { + BYTE reg; + struct _CR1_REGS { + BYTE RM:1; /* cr1[0:0] */ + + BYTE RMR:1; /* cr1[1:1] */ + + BYTE No_auto:1; /* cr1[2:2] */ + + BYTE Pulse:1; /* cr1[3:3] */ + + BYTE P_Tone1:1; /* cr1[4:4] */ + + BYTE P_Tone2:1; /* cr1[5:5] */ + + BYTE E_Tone1:1; /* cr1[6:6] */ + + BYTE E_Tone2:1; /* cr1[7:7] */ + + } bitreg; + } cr1; + + union /* SOP - CR2 Register */ + { + BYTE reg; + struct _CR2_REGS { + BYTE Call_II:1; /* CR2[0:0] */ + + BYTE Call_I:1; /* CR2[1:1] */ + + BYTE Call_en:1; /* CR2[2:2] */ + + BYTE Call_pon:1; /* CR2[3:3] */ + + BYTE IDR:1; /* CR2[4:4] */ + + BYTE COT_R:3; /* CR2[5:7] */ + + } bitreg; + } cr2; + + union /* SOP - CR3 Register */ + { + BYTE reg; + struct _CR3_REGS { + BYTE DHP_X:1; /* CR3[0:0] */ + + BYTE DHP_R:1; /* CR3[1:1] */ + + BYTE Cal_pctl:1; /* CR3[2:2] */ + + BYTE SEL:1; /* CR3[3:3] */ + + BYTE TestLoops:4; /* CR3[4:7] */ + + } bitreg; + } cr3; + + union /* SOP - CR4 Register */ + { + BYTE reg; + struct _CR4_REGS { + BYTE Fsc_en:1; /* CR4[0:0] */ + + BYTE Int_en:1; /* CR4[1:1] */ + + BYTE AGX:2; /* CR4[2:3] */ + + BYTE AGR_R:2; /* CR4[4:5] */ + + BYTE AGR_Z:2; /* CR4[6:7] */ + + } bitreg; + } cr4; + + union /* SOP - CR5 Register */ + { + BYTE reg; + struct _CR5_REGS { + BYTE V_0:1; /* CR5[0:0] */ + + BYTE V_1:1; /* CR5[1:1] */ + + BYTE V_2:1; /* CR5[2:2] */ + + BYTE V_3:1; /* CR5[3:3] */ + + BYTE V_4:1; /* CR5[4:4] */ + + BYTE V_5:1; /* CR5[5:5] */ + + BYTE V_6:1; /* CR5[6:6] */ + + BYTE V_7:1; /* CR5[7:7] */ + + } bitreg; + } cr5; + + union /* SOP - CR6 Register */ + { + BYTE reg; + struct _CR6_REGS { + BYTE reserved:8; /* CR6[0:7] */ + + } bitreg; + } cr6; + + union /* SOP - CR7 Register */ + { + BYTE reg; + struct _CR7_REGS { + BYTE reserved:8; /* CR7[0:7] */ + + } bitreg; + } cr7; + } SOP; + + BYTE ByteRegs[sizeof(struct _SOP)]; + + } SOP_REGS; + + /* DAA_REGS.SOP_REGS.SOP.CR5.reg */ + /* DAA_REGS.SOP_REGS.SOP.CR5.bitreg */ + /* DAA_REGS.SOP_REGS.SOP.CR5.bitreg.V_2 */ + /* DAA_REGS.SOP_REGS.ByteRegs[5] */ + + /*----------------------------------------------- */ + /* XOP Registers */ + /* */ + BYTE byXOP; + + union _XOP_REGS { + struct _XOP { + union XOPXR0/* XOP - XR0 Register - Read values */ + { + BYTE reg; + struct _XR0_BITREGS { + BYTE SI_0:1; /* XR0[0:0] - Read */ + + BYTE SI_1:1; /* XR0[1:1] - Read */ + + BYTE VDD_OK:1; /* XR0[2:2] - Read */ + + BYTE Caller_ID:1; /* XR0[3:3] - Read */ + + BYTE RING:1; /* XR0[4:4] - Read */ + + BYTE Cadence:1; /* XR0[5:5] - Read */ + + BYTE Wake_up:1; /* XR0[6:6] - Read */ + + BYTE RMR:1; /* XR0[7:7] - Read */ + + } bitreg; + } xr0; + + union /* XOP - XR1 Register */ + { + BYTE reg; + struct _XR1_BITREGS { + BYTE M_SI_0:1; /* XR1[0:0] */ + + BYTE M_SI_1:1; /* XR1[1:1] */ + + BYTE M_VDD_OK:1; /* XR1[2:2] */ + + BYTE M_Caller_ID:1; /* XR1[3:3] */ + + BYTE M_RING:1; /* XR1[4:4] */ + + BYTE M_Cadence:1; /* XR1[5:5] */ + + BYTE M_Wake_up:1; /* XR1[6:6] */ + + BYTE unused:1; /* XR1[7:7] */ + + } bitreg; + } xr1; + + union /* XOP - XR2 Register */ + { + BYTE reg; + struct _XR2_BITREGS { + BYTE CTO0:1; /* XR2[0:0] */ + + BYTE CTO1:1; /* XR2[1:1] */ + + BYTE CTO2:1; /* XR2[2:2] */ + + BYTE CTO3:1; /* XR2[3:3] */ + + BYTE CTO4:1; /* XR2[4:4] */ + + BYTE CTO5:1; /* XR2[5:5] */ + + BYTE CTO6:1; /* XR2[6:6] */ + + BYTE CTO7:1; /* XR2[7:7] */ + + } bitreg; + } xr2; + + union /* XOP - XR3 Register */ + { + BYTE reg; + struct _XR3_BITREGS { + BYTE DCR0:1; /* XR3[0:0] */ + + BYTE DCR1:1; /* XR3[1:1] */ + + BYTE DCI:1; /* XR3[2:2] */ + + BYTE DCU0:1; /* XR3[3:3] */ + + BYTE DCU1:1; /* XR3[4:4] */ + + BYTE B_off:1; /* XR3[5:5] */ + + BYTE AGB0:1; /* XR3[6:6] */ + + BYTE AGB1:1; /* XR3[7:7] */ + + } bitreg; + } xr3; + + union /* XOP - XR4 Register */ + { + BYTE reg; + struct _XR4_BITREGS { + BYTE C_0:1; /* XR4[0:0] */ + + BYTE C_1:1; /* XR4[1:1] */ + + BYTE C_2:1; /* XR4[2:2] */ + + BYTE C_3:1; /* XR4[3:3] */ + + BYTE C_4:1; /* XR4[4:4] */ + + BYTE C_5:1; /* XR4[5:5] */ + + BYTE C_6:1; /* XR4[6:6] */ + + BYTE C_7:1; /* XR4[7:7] */ + + } bitreg; + } xr4; + + union /* XOP - XR5 Register */ + { + BYTE reg; + struct _XR5_BITREGS { + BYTE T_0:1; /* XR5[0:0] */ + + BYTE T_1:1; /* XR5[1:1] */ + + BYTE T_2:1; /* XR5[2:2] */ + + BYTE T_3:1; /* XR5[3:3] */ + + BYTE T_4:1; /* XR5[4:4] */ + + BYTE T_5:1; /* XR5[5:5] */ + + BYTE T_6:1; /* XR5[6:6] */ + + BYTE T_7:1; /* XR5[7:7] */ + + } bitreg; + } xr5; + + union /* XOP - XR6 Register - Read Values */ + { + BYTE reg; + struct _XR6_BITREGS { + BYTE CPS0:1; /* XR6[0:0] */ + + BYTE CPS1:1; /* XR6[1:1] */ + + BYTE unused1:2; /* XR6[2:3] */ + + BYTE CLK_OFF:1; /* XR6[4:4] */ + + BYTE unused2:3; /* XR6[5:7] */ + + } bitreg; + } xr6; + + union /* XOP - XR7 Register */ + { + BYTE reg; + struct _XR7_BITREGS { + BYTE unused1:1; /* XR7[0:0] */ + + BYTE Vdd0:1; /* XR7[1:1] */ + + BYTE Vdd1:1; /* XR7[2:2] */ + + BYTE unused2:5; /* XR7[3:7] */ + + } bitreg; + } xr7; + } XOP; + + BYTE ByteRegs[sizeof(struct _XOP)]; + + } XOP_REGS; + + /* DAA_REGS.XOP_REGS.XOP.XR7.reg */ + /* DAA_REGS.XOP_REGS.XOP.XR7.bitreg */ + /* DAA_REGS.XOP_REGS.XOP.XR7.bitreg.Vdd0 */ + /* DAA_REGS.XOP_REGS.ByteRegs[7] */ + + /*----------------------------------------------- */ + /* COP Registers */ + /* */ + BYTE byCOP; + + union _COP_REGS { + struct _COP { + BYTE THFilterCoeff_1[8]; /* COP - TH Filter Coefficients, CODE=0, Part 1 */ + + BYTE THFilterCoeff_2[8]; /* COP - TH Filter Coefficients, CODE=1, Part 2 */ + + BYTE THFilterCoeff_3[8]; /* COP - TH Filter Coefficients, CODE=2, Part 3 */ + + BYTE RingerImpendance_1[8]; /* COP - Ringer Impendance Coefficients, CODE=3, Part 1 */ + + BYTE IMFilterCoeff_1[8]; /* COP - IM Filter Coefficients, CODE=4, Part 1 */ + + BYTE IMFilterCoeff_2[8]; /* COP - IM Filter Coefficients, CODE=5, Part 2 */ + + BYTE RingerImpendance_2[8]; /* COP - Ringer Impendance Coefficients, CODE=6, Part 2 */ + + BYTE FRRFilterCoeff[8]; /* COP - FRR Filter Coefficients, CODE=7 */ + + BYTE FRXFilterCoeff[8]; /* COP - FRX Filter Coefficients, CODE=8 */ + + BYTE ARFilterCoeff[4]; /* COP - AR Filter Coefficients, CODE=9 */ + + BYTE AXFilterCoeff[4]; /* COP - AX Filter Coefficients, CODE=10 */ + + BYTE Tone1Coeff[4]; /* COP - Tone1 Coefficients, CODE=11 */ + + BYTE Tone2Coeff[4]; /* COP - Tone2 Coefficients, CODE=12 */ + + BYTE LevelmeteringRinging[4]; /* COP - Levelmetering Ringing, CODE=13 */ + + BYTE CallerID1stTone[8]; /* COP - Caller ID 1st Tone, CODE=14 */ + + BYTE CallerID2ndTone[8]; /* COP - Caller ID 2nd Tone, CODE=15 */ + + } COP; + + BYTE ByteRegs[sizeof(struct _COP)]; + + } COP_REGS; + + /* DAA_REGS.COP_REGS.COP.XR7.Tone1Coeff[3] */ + /* DAA_REGS.COP_REGS.COP.XR7.bitreg */ + /* DAA_REGS.COP_REGS.COP.XR7.bitreg.Vdd0 */ + /* DAA_REGS.COP_REGS.ByteRegs[57] */ + + /*----------------------------------------------- */ + /* CAO Registers */ + /* */ + BYTE byCAO; + + union _CAO_REGS { + struct _CAO { + BYTE CallerID[512]; /* CAO - Caller ID Bytes */ + + } CAO; + + BYTE ByteRegs[sizeof(struct _CAO)]; + } CAO_REGS; + + union /* XOP - XR0 Register - Write values */ + { + BYTE reg; + struct _XR0_BITREGSW { + BYTE SO_0:1; /* XR1[0:0] - Write */ + + BYTE SO_1:1; /* XR1[1:1] - Write */ + + BYTE SO_2:1; /* XR1[2:2] - Write */ + + BYTE unused:5; /* XR1[3:7] - Write */ + + } bitreg; + } XOP_xr0_W; + + union /* XOP - XR6 Register - Write values */ + { + BYTE reg; + struct _XR6_BITREGSW { + BYTE unused1:4; /* XR6[0:3] */ + + BYTE CLK_OFF:1; /* XR6[4:4] */ + + BYTE unused2:3; /* XR6[5:7] */ + + } bitreg; + } XOP_xr6_W; + +} DAA_REGS; + +#define ALISDAA_ID_BYTE 0x81 +#define ALISDAA_CALLERID_SIZE 512 + +/*------------------------------ */ +/* */ +/* Misc definitions */ +/* */ + +/* Power Up Operation */ +#define SOP_PU_SLEEP 0 +#define SOP_PU_RINGING 1 +#define SOP_PU_CONVERSATION 2 +#define SOP_PU_PULSEDIALING 3 +#define SOP_PU_RESET 4 + +#define ALISDAA_CALLERID_SIZE 512 + +#define PLAYBACK_MODE_COMPRESSED 0 /* Selects: Compressed modes, TrueSpeech 8.5-4.1, G.723.1, G.722, G.728, G.729 */ +#define PLAYBACK_MODE_TRUESPEECH_V40 0 /* Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps */ +#define PLAYBACK_MODE_TRUESPEECH 8 /* Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps Version 5.1 */ +#define PLAYBACK_MODE_ULAW 2 /* Selects: 64 Kbit/sec MuA-law PCM */ +#define PLAYBACK_MODE_ALAW 10 /* Selects: 64 Kbit/sec A-law PCM */ +#define PLAYBACK_MODE_16LINEAR 6 /* Selects: 128 Kbit/sec 16-bit linear */ +#define PLAYBACK_MODE_8LINEAR 4 /* Selects: 64 Kbit/sec 8-bit signed linear */ +#define PLAYBACK_MODE_8LINEAR_WSS 5 /* Selects: 64 Kbit/sec WSS 8-bit unsigned linear */ + +#define RECORD_MODE_COMPRESSED 0 /* Selects: Compressed modes, TrueSpeech 8.5-4.1, G.723.1, G.722, G.728, G.729 */ +#define RECORD_MODE_TRUESPEECH 0 /* Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps */ +#define RECORD_MODE_ULAW 4 /* Selects: 64 Kbit/sec Mu-law PCM */ +#define RECORD_MODE_ALAW 12 /* Selects: 64 Kbit/sec A-law PCM */ +#define RECORD_MODE_16LINEAR 5 /* Selects: 128 Kbit/sec 16-bit linear */ +#define RECORD_MODE_8LINEAR 6 /* Selects: 64 Kbit/sec 8-bit signed linear */ +#define RECORD_MODE_8LINEAR_WSS 7 /* Selects: 64 Kbit/sec WSS 8-bit unsigned linear */ + +enum SLIC_STATES { + PLD_SLIC_STATE_OC = 0, + PLD_SLIC_STATE_RINGING, + PLD_SLIC_STATE_ACTIVE, + PLD_SLIC_STATE_OHT, + PLD_SLIC_STATE_TIPOPEN, + PLD_SLIC_STATE_STANDBY, + PLD_SLIC_STATE_APR, + PLD_SLIC_STATE_OHTPR +}; + +enum SCI_CONTROL { + SCI_End = 0, + SCI_Enable_DAA, + SCI_Enable_Mixer, + SCI_Enable_EEPROM +}; + +enum Mode { + T63, T53, T48, T40 +}; +enum Dir { + V3_TO_V4, V4_TO_V3, V4_TO_V5, V5_TO_V4 +}; + +typedef struct Proc_Info_Tag { + enum Mode convert_mode; + enum Dir convert_dir; + int Prev_Frame_Type; + int Current_Frame_Type; +} Proc_Info_Type; + +enum PREVAL { + NORMAL = 0, + NOPOST, + POSTONLY, + PREERROR +}; + +enum IXJ_EXTENSIONS { + G729LOADER = 0, + TS85LOADER, + PRE_READ, + POST_READ, + PRE_WRITE, + POST_WRITE, + PRE_IOCTL, + POST_IOCTL +}; + +typedef struct { + char enable; + char en_filter; + unsigned int filter; + unsigned int state; /* State 0 when cadence has not started. */ + + unsigned int on1; /* State 1 */ + + unsigned long on1min; /* State 1 - 10% + jiffies */ + unsigned long on1dot; /* State 1 + jiffies */ + + unsigned long on1max; /* State 1 + 10% + jiffies */ + + unsigned int off1; /* State 2 */ + + unsigned long off1min; + unsigned long off1dot; /* State 2 + jiffies */ + unsigned long off1max; + unsigned int on2; /* State 3 */ + + unsigned long on2min; + unsigned long on2dot; + unsigned long on2max; + unsigned int off2; /* State 4 */ + + unsigned long off2min; + unsigned long off2dot; /* State 4 + jiffies */ + unsigned long off2max; + unsigned int on3; /* State 5 */ + + unsigned long on3min; + unsigned long on3dot; + unsigned long on3max; + unsigned int off3; /* State 6 */ + + unsigned long off3min; + unsigned long off3dot; /* State 6 + jiffies */ + unsigned long off3max; +} IXJ_CADENCE_F; + +typedef struct { + unsigned int busytone:1; + unsigned int dialtone:1; + unsigned int ringback:1; + unsigned int ringing:1; + unsigned int playing:1; + unsigned int recording:1; + unsigned int cringing:1; + unsigned int play_first_frame:1; + unsigned int pstn_present:1; + unsigned int pstn_ringing:1; + unsigned int pots_correct:1; + unsigned int pots_pstn:1; + unsigned int g729_loaded:1; + unsigned int ts85_loaded:1; + unsigned int dtmf_oob:1; /* DTMF Out-Of-Band */ + + unsigned int pcmciascp:1; /* SmartCABLE Present */ + + unsigned int pcmciasct:2; /* SmartCABLE Type */ + + unsigned int pcmciastate:3; /* SmartCABLE Init State */ + + unsigned int inwrite:1; /* Currently writing */ + + unsigned int inread:1; /* Currently reading */ + + unsigned int incheck:1; /* Currently checking the SmartCABLE */ + + unsigned int cidplay:1; /* Currently playing Caller ID */ + + unsigned int cidring:1; /* This is the ring for Caller ID */ + + unsigned int cidsent:1; /* Caller ID has been sent */ + + unsigned int cidcw_ack:1; /* Caller ID CW ACK (from CPE) */ + unsigned int firstring:1; /* First ring cadence is complete */ + unsigned int pstncheck:1; /* Currently checking the PSTN Line */ + unsigned int pstn_rmr:1; + unsigned int x:3; /* unused bits */ + +} IXJ_FLAGS; + +/****************************************************************************** +* +* This structure holds the state of all of the Quicknet cards +* +******************************************************************************/ + +typedef struct { + int elements_used; + IXJ_CADENCE_TERM termination; + IXJ_CADENCE_ELEMENT *ce; +} ixj_cadence; + +typedef struct { + struct phone_device p; + struct timer_list timer; + unsigned int board; + unsigned int DSPbase; + unsigned int XILINXbase; + unsigned int serial; + atomic_t DSPWrite; + struct phone_capability caplist[30]; + unsigned int caps; + struct pnp_dev *dev; + unsigned int cardtype; + unsigned int rec_codec; + unsigned int cid_rec_codec; + unsigned int cid_rec_volume; + unsigned char cid_rec_flag; + signed char rec_mode; + unsigned int play_codec; + unsigned int cid_play_codec; + unsigned int cid_play_volume; + unsigned char cid_play_flag; + signed char play_mode; + IXJ_FLAGS flags; + unsigned long busyflags; + unsigned int rec_frame_size; + unsigned int play_frame_size; + unsigned int cid_play_frame_size; + unsigned int cid_base_frame_size; + unsigned long cidcw_wait; + int aec_level; + int cid_play_aec_level; + int readers, writers; + wait_queue_head_t poll_q; + wait_queue_head_t read_q; + char *read_buffer, *read_buffer_end; + char *read_convert_buffer; + size_t read_buffer_size; + unsigned int read_buffer_ready; + wait_queue_head_t write_q; + char *write_buffer, *write_buffer_end; + char *write_convert_buffer; + size_t write_buffer_size; + unsigned int write_buffers_empty; + unsigned long drybuffer; + char *write_buffer_rp, *write_buffer_wp; + char dtmfbuffer[80]; + char dtmf_current; + int dtmf_wp, dtmf_rp, dtmf_state, dtmf_proc; + int tone_off_time, tone_on_time; + struct fasync_struct *async_queue; + unsigned long tone_start_jif; + char tone_index; + char tone_state; + char maxrings; + ixj_cadence *cadence_t; + ixj_cadence *cadence_r; + int tone_cadence_state; + IXJ_CADENCE_F cadence_f[6]; + DTMF dtmf; + CPTF cptf; + BYTES dsp; + BYTES ver; + BYTES scr; + BYTES ssr; + BYTES baseframe; + HSR hsr; + GPIO gpio; + PLD_SCRR pld_scrr; + PLD_SCRW pld_scrw; + PLD_SLICW pld_slicw; + PLD_SLICR pld_slicr; + PLD_CLOCK pld_clock; + PCMCIA_CR1 pccr1; + PCMCIA_CR2 pccr2; + PCMCIA_SCCR psccr; + PCMCIA_SLIC pslic; + char pscdd; + Si3C1 sic1; + Si3C2 sic2; + Si3RXG sirxg; + Si3ADC siadc; + Si3DAC sidac; + Si3STAT sistat; + Si3AATT siaatt; + MIX mix; + unsigned short ring_cadence; + int ring_cadence_t; + unsigned long ring_cadence_jif; + unsigned long checkwait; + int intercom; + int m_hook; + int r_hook; + int p_hook; + char pstn_envelope; + char pstn_cid_intr; + unsigned char fskz; + unsigned char fskphase; + unsigned char fskcnt; + unsigned int cidsize; + unsigned int cidcnt; + unsigned long pstn_cid_received; + PHONE_CID cid; + PHONE_CID cid_send; + unsigned long pstn_ring_int; + unsigned long pstn_ring_start; + unsigned long pstn_ring_stop; + unsigned long pstn_winkstart; + unsigned long pstn_last_rmr; + unsigned long pstn_prev_rmr; + unsigned long pots_winkstart; + unsigned int winktime; + unsigned long flash_end; + char port; + char hookstate; + union telephony_exception ex; + union telephony_exception ex_sig; + int ixj_signals[35]; + IXJ_SIGDEF sigdef; + char daa_mode; + char daa_country; + unsigned long pstn_sleeptil; + DAA_REGS m_DAAShadowRegs; + Proc_Info_Type Info_read; + Proc_Info_Type Info_write; + unsigned short frame_count; + unsigned int filter_hist[4]; + unsigned char filter_en[6]; + unsigned short proc_load; + unsigned long framesread; + unsigned long frameswritten; + unsigned long read_wait; + unsigned long write_wait; + unsigned long timerchecks; + unsigned long txreadycheck; + unsigned long rxreadycheck; + unsigned long statuswait; + unsigned long statuswaitfail; + unsigned long pcontrolwait; + unsigned long pcontrolwaitfail; + unsigned long iscontrolready; + unsigned long iscontrolreadyfail; + unsigned long pstnstatecheck; +#ifdef IXJ_DYN_ALLOC + short *fskdata; +#else + short fskdata[8000]; +#endif + int fsksize; + int fskdcnt; +} IXJ; + +typedef int (*IXJ_REGFUNC) (IXJ * j, unsigned long arg); + +extern IXJ *ixj_pcmcia_probe(unsigned long, unsigned long); + diff --git a/drivers/staging/telephony/ixj_pcmcia.c b/drivers/staging/telephony/ixj_pcmcia.c new file mode 100644 index 00000000000..05032e2cc95 --- /dev/null +++ b/drivers/staging/telephony/ixj_pcmcia.c @@ -0,0 +1,187 @@ +#include "ixj-ver.h" + +#include + +#include +#include /* printk() */ +#include /* everything... */ +#include /* error codes */ +#include + +#include +#include + +#include "ixj.h" + +/* + * PCMCIA service support for Quicknet cards + */ + + +typedef struct ixj_info_t { + int ndev; + struct ixj *port; +} ixj_info_t; + +static void ixj_detach(struct pcmcia_device *p_dev); +static int ixj_config(struct pcmcia_device * link); +static void ixj_cs_release(struct pcmcia_device * link); + +static int ixj_probe(struct pcmcia_device *p_dev) +{ + dev_dbg(&p_dev->dev, "ixj_attach()\n"); + /* Create new ixj device */ + p_dev->priv = kzalloc(sizeof(struct ixj_info_t), GFP_KERNEL); + if (!p_dev->priv) { + return -ENOMEM; + } + + return ixj_config(p_dev); +} + +static void ixj_detach(struct pcmcia_device *link) +{ + dev_dbg(&link->dev, "ixj_detach\n"); + + ixj_cs_release(link); + + kfree(link->priv); +} + +static void ixj_get_serial(struct pcmcia_device * link, IXJ * j) +{ + char *str; + int i, place; + dev_dbg(&link->dev, "ixj_get_serial\n"); + + str = link->prod_id[0]; + if (!str) + goto failed; + printk("%s", str); + str = link->prod_id[1]; + if (!str) + goto failed; + printk(" %s", str); + str = link->prod_id[2]; + if (!str) + goto failed; + place = 1; + for (i = strlen(str) - 1; i >= 0; i--) { + switch (str[i]) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + j->serial += (str[i] - 48) * place; + break; + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + j->serial += (str[i] - 55) * place; + break; + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + j->serial += (str[i] - 87) * place; + break; + } + place = place * 0x10; + } + str = link->prod_id[3]; + if (!str) + goto failed; + printk(" version %s\n", str); +failed: + return; +} + +static int ixj_config_check(struct pcmcia_device *p_dev, void *priv_data) +{ + p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; + p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; + p_dev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH; + p_dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; + p_dev->io_lines = 3; + + return pcmcia_request_io(p_dev); +} + +static int ixj_config(struct pcmcia_device * link) +{ + IXJ *j; + ixj_info_t *info; + + info = link->priv; + dev_dbg(&link->dev, "ixj_config\n"); + + link->config_flags = CONF_AUTO_SET_IO; + + if (pcmcia_loop_config(link, ixj_config_check, NULL)) + goto failed; + + if (pcmcia_enable_device(link)) + goto failed; + + /* + * Register the card with the core. + */ + j = ixj_pcmcia_probe(link->resource[0]->start, + link->resource[0]->start + 0x10); + + info->ndev = 1; + ixj_get_serial(link, j); + return 0; + +failed: + ixj_cs_release(link); + return -ENODEV; +} + +static void ixj_cs_release(struct pcmcia_device *link) +{ + ixj_info_t *info = link->priv; + dev_dbg(&link->dev, "ixj_cs_release\n"); + info->ndev = 0; + pcmcia_disable_device(link); +} + +static const struct pcmcia_device_id ixj_ids[] = { + PCMCIA_DEVICE_MANF_CARD(0x0257, 0x0600), + PCMCIA_DEVICE_NULL +}; +MODULE_DEVICE_TABLE(pcmcia, ixj_ids); + +static struct pcmcia_driver ixj_driver = { + .owner = THIS_MODULE, + .name = "ixj_cs", + .probe = ixj_probe, + .remove = ixj_detach, + .id_table = ixj_ids, +}; + +static int __init ixj_pcmcia_init(void) +{ + return pcmcia_register_driver(&ixj_driver); +} + +static void ixj_pcmcia_exit(void) +{ + pcmcia_unregister_driver(&ixj_driver); +} + +module_init(ixj_pcmcia_init); +module_exit(ixj_pcmcia_exit); + +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/telephony/phonedev.c b/drivers/staging/telephony/phonedev.c new file mode 100644 index 00000000000..1915af20117 --- /dev/null +++ b/drivers/staging/telephony/phonedev.c @@ -0,0 +1,167 @@ +/* + * Telephony registration for Linux + * + * (c) Copyright 1999 Red Hat Software 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. + * + * Author: Alan Cox, + * + * Fixes: Mar 01 2000 Thomas Sparr, + * phone_register_device now works with unit!=PHONE_UNIT_ANY + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define PHONE_NUM_DEVICES 256 + +/* + * Active devices + */ + +static struct phone_device *phone_device[PHONE_NUM_DEVICES]; +static DEFINE_MUTEX(phone_lock); + +/* + * Open a phone device. + */ + +static int phone_open(struct inode *inode, struct file *file) +{ + unsigned int minor = iminor(inode); + int err = 0; + struct phone_device *p; + const struct file_operations *old_fops, *new_fops = NULL; + + if (minor >= PHONE_NUM_DEVICES) + return -ENODEV; + + mutex_lock(&phone_lock); + p = phone_device[minor]; + if (p) + new_fops = fops_get(p->f_op); + if (!new_fops) { + mutex_unlock(&phone_lock); + request_module("char-major-%d-%d", PHONE_MAJOR, minor); + mutex_lock(&phone_lock); + p = phone_device[minor]; + if (p == NULL || (new_fops = fops_get(p->f_op)) == NULL) + { + err=-ENODEV; + goto end; + } + } + old_fops = file->f_op; + file->f_op = new_fops; + if (p->open) + err = p->open(p, file); /* Tell the device it is open */ + if (err) { + fops_put(file->f_op); + file->f_op = fops_get(old_fops); + } + fops_put(old_fops); +end: + mutex_unlock(&phone_lock); + return err; +} + +/* + * Telephony For Linux device drivers request registration here. + */ + +int phone_register_device(struct phone_device *p, int unit) +{ + int base; + int end; + int i; + + base = 0; + end = PHONE_NUM_DEVICES - 1; + + if (unit != PHONE_UNIT_ANY) { + base = unit; + end = unit + 1; /* enter the loop at least one time */ + } + + mutex_lock(&phone_lock); + for (i = base; i < end; i++) { + if (phone_device[i] == NULL) { + phone_device[i] = p; + p->minor = i; + mutex_unlock(&phone_lock); + return 0; + } + } + mutex_unlock(&phone_lock); + return -ENFILE; +} + +/* + * Unregister an unused Telephony for linux device + */ + +void phone_unregister_device(struct phone_device *pfd) +{ + mutex_lock(&phone_lock); + if (likely(phone_device[pfd->minor] == pfd)) + phone_device[pfd->minor] = NULL; + mutex_unlock(&phone_lock); +} + + +static const struct file_operations phone_fops = +{ + .owner = THIS_MODULE, + .open = phone_open, + .llseek = noop_llseek, +}; + +/* + * Board init functions + */ + + +/* + * Initialise Telephony for linux + */ + +static int __init telephony_init(void) +{ + printk(KERN_INFO "Linux telephony interface: v1.00\n"); + if (register_chrdev(PHONE_MAJOR, "telephony", &phone_fops)) { + printk("phonedev: unable to get major %d\n", PHONE_MAJOR); + return -EIO; + } + + return 0; +} + +static void __exit telephony_exit(void) +{ + unregister_chrdev(PHONE_MAJOR, "telephony"); +} + +module_init(telephony_init); +module_exit(telephony_exit); + +MODULE_LICENSE("GPL"); + +EXPORT_SYMBOL(phone_register_device); +EXPORT_SYMBOL(phone_unregister_device); diff --git a/drivers/telephony/Kconfig b/drivers/telephony/Kconfig deleted file mode 100644 index b5f78b6ed2b..00000000000 --- a/drivers/telephony/Kconfig +++ /dev/null @@ -1,47 +0,0 @@ -# -# Telephony device configuration -# - -menuconfig PHONE - tristate "Telephony support" - depends on HAS_IOMEM - ---help--- - Say Y here if you have a telephony card, which for example allows - you to use a regular phone for voice-over-IP applications. - - Note: this has nothing to do with modems. You do not need to say Y - here in order to be able to use a modem under Linux. - - To compile this driver as a module, choose M here: the - module will be called phonedev. - -if PHONE - -config PHONE_IXJ - tristate "QuickNet Internet LineJack/PhoneJack support" - depends on ISA || PCI - ---help--- - Say M if you have a telephony card manufactured by Quicknet - Technologies, Inc. These include the Internet PhoneJACK and - Internet LineJACK Telephony Cards. You will get a module called - ixj. - - For the ISA versions of these products, you can configure the - cards using the isapnp tools (pnpdump/isapnp) or you can use the - isapnp support. Please read . - - For more information on these cards, see Quicknet's web site at: - . - - If you do not have any Quicknet telephony cards, you can safely - say N here. - -config PHONE_IXJ_PCMCIA - tristate "QuickNet Internet LineJack/PhoneJack PCMCIA support" - depends on PHONE_IXJ && PCMCIA - help - Say Y here to configure in PCMCIA service support for the Quicknet - cards manufactured by Quicknet Technologies, Inc. This changes the - card initialization code to work with the card manager daemon. - -endif # PHONE diff --git a/drivers/telephony/Makefile b/drivers/telephony/Makefile deleted file mode 100644 index 1206615d69e..00000000000 --- a/drivers/telephony/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile for drivers/telephony -# - -obj-$(CONFIG_PHONE) += phonedev.o -obj-$(CONFIG_PHONE_IXJ) += ixj.o -obj-$(CONFIG_PHONE_IXJ_PCMCIA) += ixj_pcmcia.o diff --git a/drivers/telephony/ixj-ver.h b/drivers/telephony/ixj-ver.h deleted file mode 100644 index 2031ac6c888..00000000000 --- a/drivers/telephony/ixj-ver.h +++ /dev/null @@ -1,4 +0,0 @@ -/* configuration management identifiers */ -#define IXJ_VER_MAJOR 1 -#define IXJ_VER_MINOR 0 -#define IXJ_BLD_VER 1 diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c deleted file mode 100644 index d5f923bcdff..00000000000 --- a/drivers/telephony/ixj.c +++ /dev/null @@ -1,10552 +0,0 @@ -/**************************************************************************** - * ixj.c - * - * Device Driver for Quicknet Technologies, Inc.'s Telephony cards - * including the Internet PhoneJACK, Internet PhoneJACK Lite, - * Internet PhoneJACK PCI, Internet LineJACK, Internet PhoneCARD and - * SmartCABLE - * - * (c) Copyright 1999-2001 Quicknet Technologies, 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. - * - * Author: Ed Okerson, - * - * Contributors: Greg Herlein, - * David W. Erhart, - * John Sellers, - * Mike Preston, - * - * Fixes: David Huggins-Daines, - * Fabio Ferrari, - * Artis Kugevics, - * Daniele Bellucci, - * - * More information about the hardware related to this driver can be found - * at our website: http://www.quicknet.net - * - * IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT - * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF QUICKNET - * TECHNOLOGIES, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * QUICKNET TECHNOLOGIES, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND QUICKNET TECHNOLOGIES, INC. HAS NO OBLIGATION - * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - ***************************************************************************/ - -/* - * Revision 4.8 2003/07/09 19:39:00 Daniele Bellucci - * Audit some copy_*_user and minor cleanup. - * - * Revision 4.7 2001/08/13 06:19:33 craigs - * Added additional changes from Alan Cox and John Anderson for - * 2.2 to 2.4 cleanup and bounds checking - * - * Revision 4.6 2001/08/13 01:05:05 craigs - * Really fixed PHONE_QUERY_CODEC problem this time - * - * Revision 4.5 2001/08/13 00:11:03 craigs - * Fixed problem in handling of PHONE_QUERY_CODEC, thanks to Shane Anderson - * - * Revision 4.4 2001/08/07 07:58:12 craigs - * Changed back to three digit version numbers - * Added tagbuild target to allow automatic and easy tagging of versions - * - * Revision 4.3 2001/08/07 07:24:47 craigs - * Added ixj-ver.h to allow easy configuration management of driver - * Added display of version number in /prox/ixj - * - * Revision 4.2 2001/08/06 07:07:19 craigs - * Reverted IXJCTL_DSP_TYPE and IXJCTL_DSP_VERSION files to original - * behaviour of returning int rather than short * - * - * Revision 4.1 2001/08/05 00:17:37 craigs - * More changes for correct PCMCIA installation - * Start of changes for backward Linux compatibility - * - * Revision 4.0 2001/08/04 12:33:12 craigs - * New version using GNU autoconf - * - * Revision 3.105 2001/07/20 23:14:32 eokerson - * More work on CallerID generation when using ring cadences. - * - * Revision 3.104 2001/07/06 01:33:55 eokerson - * Some bugfixes from Robert Vojta and a few mods to the Makefile. - * - * Revision 3.103 2001/07/05 19:20:16 eokerson - * Updated HOWTO - * Changed mic gain to 30dB on Internet LineJACK mic/speaker port. - * - * Revision 3.102 2001/07/03 23:51:21 eokerson - * Un-mute mic on Internet LineJACK when in speakerphone mode. - * - * Revision 3.101 2001/07/02 19:26:56 eokerson - * Removed initialiazation of ixjdebug and ixj_convert_loaded so they will go in the .bss instead of the .data - * - * Revision 3.100 2001/07/02 19:18:27 eokerson - * Changed driver to make dynamic allocation possible. We now pass IXJ * between functions instead of array indexes. - * Fixed the way the POTS and PSTN ports interact during a PSTN call to allow local answering. - * Fixed speaker mode on Internet LineJACK. - * - * Revision 3.99 2001/05/09 14:11:16 eokerson - * Fixed kmalloc error in ixj_build_filter_cadence. Thanks David Chan . - * - * Revision 3.98 2001/05/08 19:55:33 eokerson - * Fixed POTS hookstate detection while it is connected to PSTN port. - * - * Revision 3.97 2001/05/08 00:01:04 eokerson - * Fixed kernel oops when sending caller ID data. - * - * Revision 3.96 2001/05/04 23:09:30 eokerson - * Now uses one kernel timer for each card, instead of one for the entire driver. - * - * Revision 3.95 2001/04/25 22:06:47 eokerson - * Fixed squawking at beginning of some G.723.1 calls. - * - * Revision 3.94 2001/04/03 23:42:00 eokerson - * Added linear volume ioctls - * Added raw filter load ioctl - * - * Revision 3.93 2001/02/27 01:00:06 eokerson - * Fixed blocking in CallerID. - * Reduced size of ixj structure for smaller driver footprint. - * - * Revision 3.92 2001/02/20 22:02:59 eokerson - * Fixed isapnp and pcmcia module compatibility for 2.4.x kernels. - * Improved PSTN ring detection. - * Fixed wink generation on POTS ports. - * - * Revision 3.91 2001/02/13 00:55:44 eokerson - * Turn AEC back on after changing frame sizes. - * - * Revision 3.90 2001/02/12 16:42:00 eokerson - * Added ALAW codec, thanks to Fabio Ferrari for the table based converters to make ALAW from ULAW. - * - * Revision 3.89 2001/02/12 15:41:16 eokerson - * Fix from Artis Kugevics - Tone gains were not being set correctly. - * - * Revision 3.88 2001/02/05 23:25:42 eokerson - * Fixed lockup bugs with deregister. - * - * Revision 3.87 2001/01/29 21:00:39 eokerson - * Fix from Fabio Ferrari to properly handle EAGAIN and EINTR during non-blocking write. - * Updated copyright date. - * - * Revision 3.86 2001/01/23 23:53:46 eokerson - * Fixes to G.729 compatibility. - * - * Revision 3.85 2001/01/23 21:30:36 eokerson - * Added verbage about cards supported. - * Removed commands that put the card in low power mode at some times that it should not be in low power mode. - * - * Revision 3.84 2001/01/22 23:32:10 eokerson - * Some bugfixes from David Huggins-Daines, and other cleanups. - * - * Revision 3.83 2001/01/19 14:51:41 eokerson - * Fixed ixj_WriteDSPCommand to decrement usage counter when command fails. - * - * Revision 3.82 2001/01/19 00:34:49 eokerson - * Added verbosity to write overlap errors. - * - * Revision 3.81 2001/01/18 23:56:54 eokerson - * Fixed PSTN line test functions. - * - * Revision 3.80 2001/01/18 22:29:27 eokerson - * Updated AEC/AGC values for different cards. - * - * Revision 3.79 2001/01/17 02:58:54 eokerson - * Fixed AEC reset after Caller ID. - * Fixed Codec lockup after Caller ID on Call Waiting when not using 30ms frames. - * - * Revision 3.78 2001/01/16 19:43:09 eokerson - * Added support for Linux 2.4.x kernels. - * - * Revision 3.77 2001/01/09 04:00:52 eokerson - * Linetest will now test the line, even if it has previously succeeded. - * - * Revision 3.76 2001/01/08 19:27:00 eokerson - * Fixed problem with standard cable on Internet PhoneCARD. - * - * Revision 3.75 2000/12/22 16:52:14 eokerson - * Modified to allow hookstate detection on the POTS port when the PSTN port is selected. - * - * Revision 3.74 2000/12/08 22:41:50 eokerson - * Added capability for G729B. - * - * Revision 3.73 2000/12/07 23:35:16 eokerson - * Added capability to have different ring pattern before CallerID data. - * Added hookstate checks in CallerID routines to stop FSK. - * - * Revision 3.72 2000/12/06 19:31:31 eokerson - * Modified signal behavior to only send one signal per event. - * - * Revision 3.71 2000/12/06 03:23:08 eokerson - * Fixed CallerID on Call Waiting. - * - * Revision 3.70 2000/12/04 21:29:37 eokerson - * Added checking to Smart Cable gain functions. - * - * Revision 3.69 2000/12/04 21:05:20 eokerson - * Changed ixjdebug levels. - * Added ioctls to change gains in Internet Phone CARD Smart Cable. - * - * Revision 3.68 2000/12/04 00:17:21 craigs - * Changed mixer voice gain to +6dB rather than 0dB - * - * Revision 3.67 2000/11/30 21:25:51 eokerson - * Fixed write signal errors. - * - * Revision 3.66 2000/11/29 22:42:44 eokerson - * Fixed PSTN ring detect problems. - * - * Revision 3.65 2000/11/29 07:31:55 craigs - * Added new 425Hz filter co-efficients - * Added card-specific DTMF prescaler initialisation - * - * Revision 3.64 2000/11/28 14:03:32 craigs - * Changed certain mixer initialisations to be 0dB rather than 12dB - * Added additional information to /proc/ixj - * - * Revision 3.63 2000/11/28 11:38:41 craigs - * Added display of AEC modes in AUTO and AGC mode - * - * Revision 3.62 2000/11/28 04:05:44 eokerson - * Improved PSTN ring detection routine. - * - * Revision 3.61 2000/11/27 21:53:12 eokerson - * Fixed flash detection. - * - * Revision 3.60 2000/11/27 15:57:29 eokerson - * More work on G.729 load routines. - * - * Revision 3.59 2000/11/25 21:55:12 eokerson - * Fixed errors in G.729 load routine. - * - * Revision 3.58 2000/11/25 04:08:29 eokerson - * Added board locks around G.729 and TS85 load routines. - * - * Revision 3.57 2000/11/24 05:35:17 craigs - * Added ability to retrieve mixer values on LineJACK - * Added complete initialisation of all mixer values at startup - * Fixed spelling mistake - * - * Revision 3.56 2000/11/23 02:52:11 robertj - * Added cvs change log keyword. - * Fixed bug in capabilities list when using G.729 module. - * - */ - -#include "ixj-ver.h" - -#define PERFMON_STATS -#define IXJDEBUG 0 -#define MAXRINGS 5 - -#include - -#include -#include -#include /* printk() */ -#include /* everything... */ -#include /* error codes */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include "ixj.h" - -#define TYPE(inode) (iminor(inode) >> 4) -#define NUM(inode) (iminor(inode) & 0xf) - -static DEFINE_MUTEX(ixj_mutex); -static int ixjdebug; -static int hertz = HZ; -static int samplerate = 100; - -module_param(ixjdebug, int, 0); - -static DEFINE_PCI_DEVICE_TABLE(ixj_pci_tbl) = { - { PCI_VENDOR_ID_QUICKNET, PCI_DEVICE_ID_QUICKNET_XJ, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { } -}; -MODULE_DEVICE_TABLE(pci, ixj_pci_tbl); - -/************************************************************************ -* -* ixjdebug meanings are now bit mapped instead of level based -* Values can be or'ed together to turn on multiple messages -* -* bit 0 (0x0001) = any failure -* bit 1 (0x0002) = general messages -* bit 2 (0x0004) = POTS ringing related -* bit 3 (0x0008) = PSTN events -* bit 4 (0x0010) = PSTN Cadence state details -* bit 5 (0x0020) = Tone detection triggers -* bit 6 (0x0040) = Tone detection cadence details -* bit 7 (0x0080) = ioctl tracking -* bit 8 (0x0100) = signal tracking -* bit 9 (0x0200) = CallerID generation details -* -************************************************************************/ - -#ifdef IXJ_DYN_ALLOC - -static IXJ *ixj[IXJMAX]; -#define get_ixj(b) ixj[(b)] - -/* - * Allocate a free IXJ device - */ - -static IXJ *ixj_alloc() -{ - for(cnt=0; cntDSPbase) - { - j = kmalloc(sizeof(IXJ), GFP_KERNEL); - if (j == NULL) - return NULL; - ixj[cnt] = j; - return j; - } - } - return NULL; -} - -static void ixj_fsk_free(IXJ *j) -{ - kfree(j->fskdata); - j->fskdata = NULL; -} - -static void ixj_fsk_alloc(IXJ *j) -{ - if(!j->fskdata) { - j->fskdata = kmalloc(8000, GFP_KERNEL); - if (!j->fskdata) { - if(ixjdebug & 0x0200) { - printk("IXJ phone%d - allocate failed\n", j->board); - } - return; - } else { - j->fsksize = 8000; - if(ixjdebug & 0x0200) { - printk("IXJ phone%d - allocate succeeded\n", j->board); - } - } - } -} - -#else - -static IXJ ixj[IXJMAX]; -#define get_ixj(b) (&ixj[(b)]) - -/* - * Allocate a free IXJ device - */ - -static IXJ *ixj_alloc(void) -{ - int cnt; - for(cnt=0; cntfsksize = 8000; -} - -#endif - -#ifdef PERFMON_STATS -#define ixj_perfmon(x) ((x)++) -#else -#define ixj_perfmon(x) do { } while(0) -#endif - -static int ixj_convert_loaded; - -static int ixj_WriteDSPCommand(unsigned short, IXJ *j); - -/************************************************************************ -* -* These are function definitions to allow external modules to register -* enhanced functionality call backs. -* -************************************************************************/ - -static int Stub(IXJ * J, unsigned long arg) -{ - return 0; -} - -static IXJ_REGFUNC ixj_PreRead = &Stub; -static IXJ_REGFUNC ixj_PostRead = &Stub; -static IXJ_REGFUNC ixj_PreWrite = &Stub; -static IXJ_REGFUNC ixj_PostWrite = &Stub; - -static void ixj_read_frame(IXJ *j); -static void ixj_write_frame(IXJ *j); -static void ixj_init_timer(IXJ *j); -static void ixj_add_timer(IXJ * j); -static void ixj_timeout(unsigned long ptr); -static int read_filters(IXJ *j); -static int LineMonitor(IXJ *j); -static int ixj_fasync(int fd, struct file *, int mode); -static int ixj_set_port(IXJ *j, int arg); -static int ixj_set_pots(IXJ *j, int arg); -static int ixj_hookstate(IXJ *j); -static int ixj_record_start(IXJ *j); -static void ixj_record_stop(IXJ *j); -static void set_rec_volume(IXJ *j, int volume); -static int get_rec_volume(IXJ *j); -static int set_rec_codec(IXJ *j, int rate); -static void ixj_vad(IXJ *j, int arg); -static int ixj_play_start(IXJ *j); -static void ixj_play_stop(IXJ *j); -static int ixj_set_tone_on(unsigned short arg, IXJ *j); -static int ixj_set_tone_off(unsigned short, IXJ *j); -static int ixj_play_tone(IXJ *j, char tone); -static void ixj_aec_start(IXJ *j, int level); -static int idle(IXJ *j); -static void ixj_ring_on(IXJ *j); -static void ixj_ring_off(IXJ *j); -static void aec_stop(IXJ *j); -static void ixj_ringback(IXJ *j); -static void ixj_busytone(IXJ *j); -static void ixj_dialtone(IXJ *j); -static void ixj_cpt_stop(IXJ *j); -static char daa_int_read(IXJ *j); -static char daa_CR_read(IXJ *j, int cr); -static int daa_set_mode(IXJ *j, int mode); -static int ixj_linetest(IXJ *j); -static int ixj_daa_write(IXJ *j); -static int ixj_daa_cid_read(IXJ *j); -static void DAA_Coeff_US(IXJ *j); -static void DAA_Coeff_UK(IXJ *j); -static void DAA_Coeff_France(IXJ *j); -static void DAA_Coeff_Germany(IXJ *j); -static void DAA_Coeff_Australia(IXJ *j); -static void DAA_Coeff_Japan(IXJ *j); -static int ixj_init_filter(IXJ *j, IXJ_FILTER * jf); -static int ixj_init_filter_raw(IXJ *j, IXJ_FILTER_RAW * jfr); -static int ixj_init_tone(IXJ *j, IXJ_TONE * ti); -static int ixj_build_cadence(IXJ *j, IXJ_CADENCE __user * cp); -static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE __user * cp); -/* Serial Control Interface funtions */ -static int SCI_Control(IXJ *j, int control); -static int SCI_Prepare(IXJ *j); -static int SCI_WaitHighSCI(IXJ *j); -static int SCI_WaitLowSCI(IXJ *j); -static DWORD PCIEE_GetSerialNumber(WORD wAddress); -static int ixj_PCcontrol_wait(IXJ *j); -static void ixj_pre_cid(IXJ *j); -static void ixj_write_cid(IXJ *j); -static void ixj_write_cid_bit(IXJ *j, int bit); -static int set_base_frame(IXJ *j, int size); -static int set_play_codec(IXJ *j, int rate); -static void set_rec_depth(IXJ *j, int depth); -static int ixj_mixer(long val, IXJ *j); - -/************************************************************************ -CT8020/CT8021 Host Programmers Model -Host address Function Access -DSPbase + -0-1 Aux Software Status Register (reserved) Read Only -2-3 Software Status Register Read Only -4-5 Aux Software Control Register (reserved) Read Write -6-7 Software Control Register Read Write -8-9 Hardware Status Register Read Only -A-B Hardware Control Register Read Write -C-D Host Transmit (Write) Data Buffer Access Port (buffer input)Write Only -E-F Host Receive (Read) Data Buffer Access Port (buffer input) Read Only -************************************************************************/ - -static inline void ixj_read_HSR(IXJ *j) -{ - j->hsr.bytes.low = inb_p(j->DSPbase + 8); - j->hsr.bytes.high = inb_p(j->DSPbase + 9); -} - -static inline int IsControlReady(IXJ *j) -{ - ixj_read_HSR(j); - return j->hsr.bits.controlrdy ? 1 : 0; -} - -static inline int IsPCControlReady(IXJ *j) -{ - j->pccr1.byte = inb_p(j->XILINXbase + 3); - return j->pccr1.bits.crr ? 1 : 0; -} - -static inline int IsStatusReady(IXJ *j) -{ - ixj_read_HSR(j); - return j->hsr.bits.statusrdy ? 1 : 0; -} - -static inline int IsRxReady(IXJ *j) -{ - ixj_read_HSR(j); - ixj_perfmon(j->rxreadycheck); - return j->hsr.bits.rxrdy ? 1 : 0; -} - -static inline int IsTxReady(IXJ *j) -{ - ixj_read_HSR(j); - ixj_perfmon(j->txreadycheck); - return j->hsr.bits.txrdy ? 1 : 0; -} - -static inline void set_play_volume(IXJ *j, int volume) -{ - if (ixjdebug & 0x0002) - printk(KERN_INFO "IXJ: /dev/phone%d Setting Play Volume to 0x%4.4x\n", j->board, volume); - ixj_WriteDSPCommand(0xCF02, j); - ixj_WriteDSPCommand(volume, j); -} - -static int set_play_volume_linear(IXJ *j, int volume) -{ - int newvolume, dspplaymax; - - if (ixjdebug & 0x0002) - printk(KERN_INFO "IXJ: /dev/phone %d Setting Linear Play Volume to 0x%4.4x\n", j->board, volume); - if(volume > 100 || volume < 0) { - return -1; - } - - /* This should normalize the perceived volumes between the different cards caused by differences in the hardware */ - switch (j->cardtype) { - case QTI_PHONEJACK: - dspplaymax = 0x380; - break; - case QTI_LINEJACK: - if(j->port == PORT_PSTN) { - dspplaymax = 0x48; - } else { - dspplaymax = 0x100; - } - break; - case QTI_PHONEJACK_LITE: - dspplaymax = 0x380; - break; - case QTI_PHONEJACK_PCI: - dspplaymax = 0x6C; - break; - case QTI_PHONECARD: - dspplaymax = 0x50; - break; - default: - return -1; - } - newvolume = (dspplaymax * volume) / 100; - set_play_volume(j, newvolume); - return 0; -} - -static inline void set_play_depth(IXJ *j, int depth) -{ - if (depth > 60) - depth = 60; - if (depth < 0) - depth = 0; - ixj_WriteDSPCommand(0x5280 + depth, j); -} - -static inline int get_play_volume(IXJ *j) -{ - ixj_WriteDSPCommand(0xCF00, j); - return j->ssr.high << 8 | j->ssr.low; -} - -static int get_play_volume_linear(IXJ *j) -{ - int volume, newvolume, dspplaymax; - - /* This should normalize the perceived volumes between the different cards caused by differences in the hardware */ - switch (j->cardtype) { - case QTI_PHONEJACK: - dspplaymax = 0x380; - break; - case QTI_LINEJACK: - if(j->port == PORT_PSTN) { - dspplaymax = 0x48; - } else { - dspplaymax = 0x100; - } - break; - case QTI_PHONEJACK_LITE: - dspplaymax = 0x380; - break; - case QTI_PHONEJACK_PCI: - dspplaymax = 0x6C; - break; - case QTI_PHONECARD: - dspplaymax = 100; - break; - default: - return -1; - } - volume = get_play_volume(j); - newvolume = (volume * 100) / dspplaymax; - if(newvolume > 100) - newvolume = 100; - return newvolume; -} - -static inline BYTE SLIC_GetState(IXJ *j) -{ - if (j->cardtype == QTI_PHONECARD) { - j->pccr1.byte = 0; - j->psccr.bits.dev = 3; - j->psccr.bits.rw = 1; - outw_p(j->psccr.byte << 8, j->XILINXbase + 0x00); - ixj_PCcontrol_wait(j); - j->pslic.byte = inw_p(j->XILINXbase + 0x00) & 0xFF; - ixj_PCcontrol_wait(j); - if (j->pslic.bits.powerdown) - return PLD_SLIC_STATE_OC; - else if (!j->pslic.bits.ring0 && !j->pslic.bits.ring1) - return PLD_SLIC_STATE_ACTIVE; - else - return PLD_SLIC_STATE_RINGING; - } else { - j->pld_slicr.byte = inb_p(j->XILINXbase + 0x01); - } - return j->pld_slicr.bits.state; -} - -static bool SLIC_SetState(BYTE byState, IXJ *j) -{ - bool fRetVal = false; - - if (j->cardtype == QTI_PHONECARD) { - if (j->flags.pcmciasct) { - switch (byState) { - case PLD_SLIC_STATE_TIPOPEN: - case PLD_SLIC_STATE_OC: - j->pslic.bits.powerdown = 1; - j->pslic.bits.ring0 = j->pslic.bits.ring1 = 0; - fRetVal = true; - break; - case PLD_SLIC_STATE_RINGING: - if (j->readers || j->writers) { - j->pslic.bits.powerdown = 0; - j->pslic.bits.ring0 = 1; - j->pslic.bits.ring1 = 0; - fRetVal = true; - } - break; - case PLD_SLIC_STATE_OHT: /* On-hook transmit */ - - case PLD_SLIC_STATE_STANDBY: - case PLD_SLIC_STATE_ACTIVE: - if (j->readers || j->writers) { - j->pslic.bits.powerdown = 0; - } else { - j->pslic.bits.powerdown = 1; - } - j->pslic.bits.ring0 = j->pslic.bits.ring1 = 0; - fRetVal = true; - break; - case PLD_SLIC_STATE_APR: /* Active polarity reversal */ - - case PLD_SLIC_STATE_OHTPR: /* OHT polarity reversal */ - - default: - fRetVal = false; - break; - } - j->psccr.bits.dev = 3; - j->psccr.bits.rw = 0; - outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00); - ixj_PCcontrol_wait(j); - } - } else { - /* Set the C1, C2, C3 & B2EN signals. */ - switch (byState) { - case PLD_SLIC_STATE_OC: - j->pld_slicw.bits.c1 = 0; - j->pld_slicw.bits.c2 = 0; - j->pld_slicw.bits.c3 = 0; - j->pld_slicw.bits.b2en = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - fRetVal = true; - break; - case PLD_SLIC_STATE_RINGING: - j->pld_slicw.bits.c1 = 1; - j->pld_slicw.bits.c2 = 0; - j->pld_slicw.bits.c3 = 0; - j->pld_slicw.bits.b2en = 1; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - fRetVal = true; - break; - case PLD_SLIC_STATE_ACTIVE: - j->pld_slicw.bits.c1 = 0; - j->pld_slicw.bits.c2 = 1; - j->pld_slicw.bits.c3 = 0; - j->pld_slicw.bits.b2en = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - fRetVal = true; - break; - case PLD_SLIC_STATE_OHT: /* On-hook transmit */ - - j->pld_slicw.bits.c1 = 1; - j->pld_slicw.bits.c2 = 1; - j->pld_slicw.bits.c3 = 0; - j->pld_slicw.bits.b2en = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - fRetVal = true; - break; - case PLD_SLIC_STATE_TIPOPEN: - j->pld_slicw.bits.c1 = 0; - j->pld_slicw.bits.c2 = 0; - j->pld_slicw.bits.c3 = 1; - j->pld_slicw.bits.b2en = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - fRetVal = true; - break; - case PLD_SLIC_STATE_STANDBY: - j->pld_slicw.bits.c1 = 1; - j->pld_slicw.bits.c2 = 0; - j->pld_slicw.bits.c3 = 1; - j->pld_slicw.bits.b2en = 1; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - fRetVal = true; - break; - case PLD_SLIC_STATE_APR: /* Active polarity reversal */ - - j->pld_slicw.bits.c1 = 0; - j->pld_slicw.bits.c2 = 1; - j->pld_slicw.bits.c3 = 1; - j->pld_slicw.bits.b2en = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - fRetVal = true; - break; - case PLD_SLIC_STATE_OHTPR: /* OHT polarity reversal */ - - j->pld_slicw.bits.c1 = 1; - j->pld_slicw.bits.c2 = 1; - j->pld_slicw.bits.c3 = 1; - j->pld_slicw.bits.b2en = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - fRetVal = true; - break; - default: - fRetVal = false; - break; - } - } - - return fRetVal; -} - -static int ixj_wink(IXJ *j) -{ - BYTE slicnow; - - slicnow = SLIC_GetState(j); - - j->pots_winkstart = jiffies; - SLIC_SetState(PLD_SLIC_STATE_OC, j); - - msleep(jiffies_to_msecs(j->winktime)); - - SLIC_SetState(slicnow, j); - return 0; -} - -static void ixj_init_timer(IXJ *j) -{ - init_timer(&j->timer); - j->timer.function = ixj_timeout; - j->timer.data = (unsigned long)j; -} - -static void ixj_add_timer(IXJ *j) -{ - j->timer.expires = jiffies + (hertz / samplerate); - add_timer(&j->timer); -} - -static void ixj_tone_timeout(IXJ *j) -{ - IXJ_TONE ti; - - j->tone_state++; - if (j->tone_state == 3) { - j->tone_state = 0; - if (j->cadence_t) { - j->tone_cadence_state++; - if (j->tone_cadence_state >= j->cadence_t->elements_used) { - switch (j->cadence_t->termination) { - case PLAY_ONCE: - ixj_cpt_stop(j); - break; - case REPEAT_LAST_ELEMENT: - j->tone_cadence_state--; - ixj_play_tone(j, j->cadence_t->ce[j->tone_cadence_state].index); - break; - case REPEAT_ALL: - j->tone_cadence_state = 0; - if (j->cadence_t->ce[j->tone_cadence_state].freq0) { - ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index; - ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0; - ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0; - ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1; - ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1; - ixj_init_tone(j, &ti); - } - ixj_set_tone_on(j->cadence_t->ce[0].tone_on_time, j); - ixj_set_tone_off(j->cadence_t->ce[0].tone_off_time, j); - ixj_play_tone(j, j->cadence_t->ce[0].index); - break; - } - } else { - if (j->cadence_t->ce[j->tone_cadence_state].gain0) { - ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index; - ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0; - ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0; - ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1; - ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1; - ixj_init_tone(j, &ti); - } - ixj_set_tone_on(j->cadence_t->ce[j->tone_cadence_state].tone_on_time, j); - ixj_set_tone_off(j->cadence_t->ce[j->tone_cadence_state].tone_off_time, j); - ixj_play_tone(j, j->cadence_t->ce[j->tone_cadence_state].index); - } - } - } -} - -static inline void ixj_kill_fasync(IXJ *j, IXJ_SIGEVENT event, int dir) -{ - if(j->ixj_signals[event]) { - if(ixjdebug & 0x0100) - printk("Sending signal for event %d\n", event); - /* Send apps notice of change */ - /* see config.h for macro definition */ - kill_fasync(&(j->async_queue), j->ixj_signals[event], dir); - } -} - -static void ixj_pstn_state(IXJ *j) -{ - int var; - union XOPXR0 XR0, daaint; - - var = 10; - - XR0.reg = j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg; - daaint.reg = 0; - XR0.bitreg.RMR = j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR; - - j->pld_scrr.byte = inb_p(j->XILINXbase); - if (j->pld_scrr.bits.daaflag) { - daa_int_read(j); - if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.RING) { - if(time_after(jiffies, j->pstn_sleeptil) && !(j->flags.pots_pstn && j->hookstate)) { - daaint.bitreg.RING = 1; - if(ixjdebug & 0x0008) { - printk(KERN_INFO "IXJ DAA Ring Interrupt /dev/phone%d at %ld\n", j->board, jiffies); - } - } else { - daa_set_mode(j, SOP_PU_RESET); - } - } - if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Caller_ID) { - daaint.bitreg.Caller_ID = 1; - j->pstn_cid_intr = 1; - j->pstn_cid_received = jiffies; - if(ixjdebug & 0x0008) { - printk(KERN_INFO "IXJ DAA Caller_ID Interrupt /dev/phone%d at %ld\n", j->board, jiffies); - } - } - if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Cadence) { - daaint.bitreg.Cadence = 1; - if(ixjdebug & 0x0008) { - printk(KERN_INFO "IXJ DAA Cadence Interrupt /dev/phone%d at %ld\n", j->board, jiffies); - } - } - if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK != XR0.bitreg.VDD_OK) { - daaint.bitreg.VDD_OK = 1; - daaint.bitreg.SI_0 = j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK; - } - } - daa_CR_read(j, 1); - if(j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR != XR0.bitreg.RMR && time_after(jiffies, j->pstn_sleeptil) && !(j->flags.pots_pstn && j->hookstate)) { - daaint.bitreg.RMR = 1; - daaint.bitreg.SI_1 = j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR; - if(ixjdebug & 0x0008) { - printk(KERN_INFO "IXJ DAA RMR /dev/phone%d was %s for %ld\n", j->board, XR0.bitreg.RMR?"on":"off", jiffies - j->pstn_last_rmr); - } - j->pstn_prev_rmr = j->pstn_last_rmr; - j->pstn_last_rmr = jiffies; - } - switch(j->daa_mode) { - case SOP_PU_SLEEP: - if (daaint.bitreg.RING) { - if (!j->flags.pstn_ringing) { - if (j->daa_mode != SOP_PU_RINGING) { - j->pstn_ring_int = jiffies; - daa_set_mode(j, SOP_PU_RINGING); - } - } - } - break; - case SOP_PU_RINGING: - if (daaint.bitreg.RMR) { - if (ixjdebug & 0x0008) { - printk(KERN_INFO "IXJ Ring Cadence a state = %d /dev/phone%d at %ld\n", j->cadence_f[4].state, j->board, jiffies); - } - if (daaint.bitreg.SI_1) { /* Rising edge of RMR */ - j->flags.pstn_rmr = 1; - j->pstn_ring_start = jiffies; - j->pstn_ring_stop = 0; - j->ex.bits.pstn_ring = 0; - if (j->cadence_f[4].state == 0) { - j->cadence_f[4].state = 1; - j->cadence_f[4].on1min = jiffies + (long)((j->cadence_f[4].on1 * hertz * (100 - var)) / 10000); - j->cadence_f[4].on1dot = jiffies + (long)((j->cadence_f[4].on1 * hertz * (100)) / 10000); - j->cadence_f[4].on1max = jiffies + (long)((j->cadence_f[4].on1 * hertz * (100 + var)) / 10000); - } else if (j->cadence_f[4].state == 2) { - if((time_after(jiffies, j->cadence_f[4].off1min) && - time_before(jiffies, j->cadence_f[4].off1max))) { - if (j->cadence_f[4].on2) { - j->cadence_f[4].state = 3; - j->cadence_f[4].on2min = jiffies + (long)((j->cadence_f[4].on2 * (hertz * (100 - var)) / 10000)); - j->cadence_f[4].on2dot = jiffies + (long)((j->cadence_f[4].on2 * (hertz * (100)) / 10000)); - j->cadence_f[4].on2max = jiffies + (long)((j->cadence_f[4].on2 * (hertz * (100 + var)) / 10000)); - } else { - j->cadence_f[4].state = 7; - } - } else { - if (ixjdebug & 0x0008) { - printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n", - j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr, - j->cadence_f[4].off1); - } - j->cadence_f[4].state = 0; - } - } else if (j->cadence_f[4].state == 4) { - if((time_after(jiffies, j->cadence_f[4].off2min) && - time_before(jiffies, j->cadence_f[4].off2max))) { - if (j->cadence_f[4].on3) { - j->cadence_f[4].state = 5; - j->cadence_f[4].on3min = jiffies + (long)((j->cadence_f[4].on3 * (hertz * (100 - var)) / 10000)); - j->cadence_f[4].on3dot = jiffies + (long)((j->cadence_f[4].on3 * (hertz * (100)) / 10000)); - j->cadence_f[4].on3max = jiffies + (long)((j->cadence_f[4].on3 * (hertz * (100 + var)) / 10000)); - } else { - j->cadence_f[4].state = 7; - } - } else { - if (ixjdebug & 0x0008) { - printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n", - j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr, - j->cadence_f[4].off2); - } - j->cadence_f[4].state = 0; - } - } else if (j->cadence_f[4].state == 6) { - if((time_after(jiffies, j->cadence_f[4].off3min) && - time_before(jiffies, j->cadence_f[4].off3max))) { - j->cadence_f[4].state = 7; - } else { - if (ixjdebug & 0x0008) { - printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n", - j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr, - j->cadence_f[4].off3); - } - j->cadence_f[4].state = 0; - } - } else { - j->cadence_f[4].state = 0; - } - } else { /* Falling edge of RMR */ - j->pstn_ring_start = 0; - j->pstn_ring_stop = jiffies; - if (j->cadence_f[4].state == 1) { - if(!j->cadence_f[4].on1) { - j->cadence_f[4].state = 7; - } else if((time_after(jiffies, j->cadence_f[4].on1min) && - time_before(jiffies, j->cadence_f[4].on1max))) { - if (j->cadence_f[4].off1) { - j->cadence_f[4].state = 2; - j->cadence_f[4].off1min = jiffies + (long)((j->cadence_f[4].off1 * (hertz * (100 - var)) / 10000)); - j->cadence_f[4].off1dot = jiffies + (long)((j->cadence_f[4].off1 * (hertz * (100)) / 10000)); - j->cadence_f[4].off1max = jiffies + (long)((j->cadence_f[4].off1 * (hertz * (100 + var)) / 10000)); - } else { - j->cadence_f[4].state = 7; - } - } else { - if (ixjdebug & 0x0008) { - printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n", - j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr, - j->cadence_f[4].on1); - } - j->cadence_f[4].state = 0; - } - } else if (j->cadence_f[4].state == 3) { - if((time_after(jiffies, j->cadence_f[4].on2min) && - time_before(jiffies, j->cadence_f[4].on2max))) { - if (j->cadence_f[4].off2) { - j->cadence_f[4].state = 4; - j->cadence_f[4].off2min = jiffies + (long)((j->cadence_f[4].off2 * (hertz * (100 - var)) / 10000)); - j->cadence_f[4].off2dot = jiffies + (long)((j->cadence_f[4].off2 * (hertz * (100)) / 10000)); - j->cadence_f[4].off2max = jiffies + (long)((j->cadence_f[4].off2 * (hertz * (100 + var)) / 10000)); - } else { - j->cadence_f[4].state = 7; - } - } else { - if (ixjdebug & 0x0008) { - printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n", - j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr, - j->cadence_f[4].on2); - } - j->cadence_f[4].state = 0; - } - } else if (j->cadence_f[4].state == 5) { - if((time_after(jiffies, j->cadence_f[4].on3min) && - time_before(jiffies, j->cadence_f[4].on3max))) { - if (j->cadence_f[4].off3) { - j->cadence_f[4].state = 6; - j->cadence_f[4].off3min = jiffies + (long)((j->cadence_f[4].off3 * (hertz * (100 - var)) / 10000)); - j->cadence_f[4].off3dot = jiffies + (long)((j->cadence_f[4].off3 * (hertz * (100)) / 10000)); - j->cadence_f[4].off3max = jiffies + (long)((j->cadence_f[4].off3 * (hertz * (100 + var)) / 10000)); - } else { - j->cadence_f[4].state = 7; - } - } else { - j->cadence_f[4].state = 0; - } - } else { - if (ixjdebug & 0x0008) { - printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n", - j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr, - j->cadence_f[4].on3); - } - j->cadence_f[4].state = 0; - } - } - if (ixjdebug & 0x0010) { - printk(KERN_INFO "IXJ Ring Cadence b state = %d /dev/phone%d at %ld\n", j->cadence_f[4].state, j->board, jiffies); - } - if (ixjdebug & 0x0010) { - switch(j->cadence_f[4].state) { - case 1: - printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board, - j->cadence_f[4].on1, j->cadence_f[4].on1min, j->cadence_f[4].on1dot, j->cadence_f[4].on1max); - break; - case 2: - printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board, - j->cadence_f[4].off1, j->cadence_f[4].off1min, j->cadence_f[4].off1dot, j->cadence_f[4].off1max); - break; - case 3: - printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board, - j->cadence_f[4].on2, j->cadence_f[4].on2min, j->cadence_f[4].on2dot, j->cadence_f[4].on2max); - break; - case 4: - printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board, - j->cadence_f[4].off2, j->cadence_f[4].off2min, j->cadence_f[4].off2dot, j->cadence_f[4].off2max); - break; - case 5: - printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board, - j->cadence_f[4].on3, j->cadence_f[4].on3min, j->cadence_f[4].on3dot, j->cadence_f[4].on3max); - break; - case 6: - printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board, - j->cadence_f[4].off3, j->cadence_f[4].off3min, j->cadence_f[4].off3dot, j->cadence_f[4].off3max); - break; - } - } - } - if (j->cadence_f[4].state == 7) { - j->cadence_f[4].state = 0; - j->pstn_ring_stop = jiffies; - j->ex.bits.pstn_ring = 1; - ixj_kill_fasync(j, SIG_PSTN_RING, POLL_IN); - if(ixjdebug & 0x0008) { - printk(KERN_INFO "IXJ Ring int set /dev/phone%d at %ld\n", j->board, jiffies); - } - } - if((j->pstn_ring_int != 0 && time_after(jiffies, j->pstn_ring_int + (hertz * 5)) && !j->flags.pstn_rmr) || - (j->pstn_ring_stop != 0 && time_after(jiffies, j->pstn_ring_stop + (hertz * 5)))) { - if(ixjdebug & 0x0008) { - printk("IXJ DAA no ring in 5 seconds /dev/phone%d at %ld\n", j->board, jiffies); - printk("IXJ DAA pstn ring int /dev/phone%d at %ld\n", j->board, j->pstn_ring_int); - printk("IXJ DAA pstn ring stop /dev/phone%d at %ld\n", j->board, j->pstn_ring_stop); - } - j->pstn_ring_stop = j->pstn_ring_int = 0; - daa_set_mode(j, SOP_PU_SLEEP); - } - outb_p(j->pld_scrw.byte, j->XILINXbase); - if (j->pstn_cid_intr && time_after(jiffies, j->pstn_cid_received + hertz)) { - ixj_daa_cid_read(j); - j->ex.bits.caller_id = 1; - ixj_kill_fasync(j, SIG_CALLER_ID, POLL_IN); - j->pstn_cid_intr = 0; - } - if (daaint.bitreg.Cadence) { - if(ixjdebug & 0x0008) { - printk("IXJ DAA Cadence interrupt going to sleep /dev/phone%d\n", j->board); - } - daa_set_mode(j, SOP_PU_SLEEP); - j->ex.bits.pstn_ring = 0; - } - break; - case SOP_PU_CONVERSATION: - if (daaint.bitreg.VDD_OK) { - if(!daaint.bitreg.SI_0) { - if (!j->pstn_winkstart) { - if(ixjdebug & 0x0008) { - printk("IXJ DAA possible wink /dev/phone%d %ld\n", j->board, jiffies); - } - j->pstn_winkstart = jiffies; - } - } else { - if (j->pstn_winkstart) { - if(ixjdebug & 0x0008) { - printk("IXJ DAA possible wink end /dev/phone%d %ld\n", j->board, jiffies); - } - j->pstn_winkstart = 0; - } - } - } - if (j->pstn_winkstart && time_after(jiffies, j->pstn_winkstart + ((hertz * j->winktime) / 1000))) { - if(ixjdebug & 0x0008) { - printk("IXJ DAA wink detected going to sleep /dev/phone%d %ld\n", j->board, jiffies); - } - daa_set_mode(j, SOP_PU_SLEEP); - j->pstn_winkstart = 0; - j->ex.bits.pstn_wink = 1; - ixj_kill_fasync(j, SIG_PSTN_WINK, POLL_IN); - } - break; - } -} - -static void ixj_timeout(unsigned long ptr) -{ - int board; - unsigned long jifon; - IXJ *j = (IXJ *)ptr; - board = j->board; - - if (j->DSPbase && atomic_read(&j->DSPWrite) == 0 && test_and_set_bit(board, (void *)&j->busyflags) == 0) { - ixj_perfmon(j->timerchecks); - j->hookstate = ixj_hookstate(j); - if (j->tone_state) { - if (!(j->hookstate)) { - ixj_cpt_stop(j); - if (j->m_hook) { - j->m_hook = 0; - j->ex.bits.hookstate = 1; - ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN); - } - clear_bit(board, &j->busyflags); - ixj_add_timer(j); - return; - } - if (j->tone_state == 1) - jifon = ((hertz * j->tone_on_time) * 25 / 100000); - else - jifon = ((hertz * j->tone_on_time) * 25 / 100000) + ((hertz * j->tone_off_time) * 25 / 100000); - if (time_before(jiffies, j->tone_start_jif + jifon)) { - if (j->tone_state == 1) { - ixj_play_tone(j, j->tone_index); - if (j->dsp.low == 0x20) { - clear_bit(board, &j->busyflags); - ixj_add_timer(j); - return; - } - } else { - ixj_play_tone(j, 0); - if (j->dsp.low == 0x20) { - clear_bit(board, &j->busyflags); - ixj_add_timer(j); - return; - } - } - } else { - ixj_tone_timeout(j); - if (j->flags.dialtone) { - ixj_dialtone(j); - } - if (j->flags.busytone) { - ixj_busytone(j); - if (j->dsp.low == 0x20) { - clear_bit(board, &j->busyflags); - ixj_add_timer(j); - return; - } - } - if (j->flags.ringback) { - ixj_ringback(j); - if (j->dsp.low == 0x20) { - clear_bit(board, &j->busyflags); - ixj_add_timer(j); - return; - } - } - if (!j->tone_state) { - ixj_cpt_stop(j); - } - } - } - if (!(j->tone_state && j->dsp.low == 0x20)) { - if (IsRxReady(j)) { - ixj_read_frame(j); - } - if (IsTxReady(j)) { - ixj_write_frame(j); - } - } - if (j->flags.cringing) { - if (j->hookstate & 1) { - j->flags.cringing = 0; - ixj_ring_off(j); - } else if(j->cadence_f[5].enable && ((!j->cadence_f[5].en_filter) || (j->cadence_f[5].en_filter && j->flags.firstring))) { - switch(j->cadence_f[5].state) { - case 0: - j->cadence_f[5].on1dot = jiffies + (long)((j->cadence_f[5].on1 * (hertz * 100) / 10000)); - if (time_before(jiffies, j->cadence_f[5].on1dot)) { - if(ixjdebug & 0x0004) { - printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies); - } - ixj_ring_on(j); - } - j->cadence_f[5].state = 1; - break; - case 1: - if (time_after(jiffies, j->cadence_f[5].on1dot)) { - j->cadence_f[5].off1dot = jiffies + (long)((j->cadence_f[5].off1 * (hertz * 100) / 10000)); - if(ixjdebug & 0x0004) { - printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies); - } - ixj_ring_off(j); - j->cadence_f[5].state = 2; - } - break; - case 2: - if (time_after(jiffies, j->cadence_f[5].off1dot)) { - if(ixjdebug & 0x0004) { - printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies); - } - ixj_ring_on(j); - if (j->cadence_f[5].on2) { - j->cadence_f[5].on2dot = jiffies + (long)((j->cadence_f[5].on2 * (hertz * 100) / 10000)); - j->cadence_f[5].state = 3; - } else { - j->cadence_f[5].state = 7; - } - } - break; - case 3: - if (time_after(jiffies, j->cadence_f[5].on2dot)) { - if(ixjdebug & 0x0004) { - printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies); - } - ixj_ring_off(j); - if (j->cadence_f[5].off2) { - j->cadence_f[5].off2dot = jiffies + (long)((j->cadence_f[5].off2 * (hertz * 100) / 10000)); - j->cadence_f[5].state = 4; - } else { - j->cadence_f[5].state = 7; - } - } - break; - case 4: - if (time_after(jiffies, j->cadence_f[5].off2dot)) { - if(ixjdebug & 0x0004) { - printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies); - } - ixj_ring_on(j); - if (j->cadence_f[5].on3) { - j->cadence_f[5].on3dot = jiffies + (long)((j->cadence_f[5].on3 * (hertz * 100) / 10000)); - j->cadence_f[5].state = 5; - } else { - j->cadence_f[5].state = 7; - } - } - break; - case 5: - if (time_after(jiffies, j->cadence_f[5].on3dot)) { - if(ixjdebug & 0x0004) { - printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies); - } - ixj_ring_off(j); - if (j->cadence_f[5].off3) { - j->cadence_f[5].off3dot = jiffies + (long)((j->cadence_f[5].off3 * (hertz * 100) / 10000)); - j->cadence_f[5].state = 6; - } else { - j->cadence_f[5].state = 7; - } - } - break; - case 6: - if (time_after(jiffies, j->cadence_f[5].off3dot)) { - if(ixjdebug & 0x0004) { - printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies); - } - j->cadence_f[5].state = 7; - } - break; - case 7: - if(ixjdebug & 0x0004) { - printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies); - } - j->flags.cidring = 1; - j->cadence_f[5].state = 0; - break; - } - if (j->flags.cidring && !j->flags.cidsent) { - j->flags.cidsent = 1; - if(j->fskdcnt) { - SLIC_SetState(PLD_SLIC_STATE_OHT, j); - ixj_pre_cid(j); - } - j->flags.cidring = 0; - } - clear_bit(board, &j->busyflags); - ixj_add_timer(j); - return; - } else { - if (time_after(jiffies, j->ring_cadence_jif + (hertz / 2))) { - if (j->flags.cidring && !j->flags.cidsent) { - j->flags.cidsent = 1; - if(j->fskdcnt) { - SLIC_SetState(PLD_SLIC_STATE_OHT, j); - ixj_pre_cid(j); - } - j->flags.cidring = 0; - } - j->ring_cadence_t--; - if (j->ring_cadence_t == -1) - j->ring_cadence_t = 15; - j->ring_cadence_jif = jiffies; - - if (j->ring_cadence & 1 << j->ring_cadence_t) { - if(j->flags.cidsent && j->cadence_f[5].en_filter) - j->flags.firstring = 1; - else - ixj_ring_on(j); - } else { - ixj_ring_off(j); - if(!j->flags.cidsent) - j->flags.cidring = 1; - } - } - clear_bit(board, &j->busyflags); - ixj_add_timer(j); - return; - } - } - if (!j->flags.ringing) { - if (j->hookstate) { /* & 1) { */ - if (j->dsp.low != 0x20 && - SLIC_GetState(j) != PLD_SLIC_STATE_ACTIVE) { - SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); - } - LineMonitor(j); - read_filters(j); - ixj_WriteDSPCommand(0x511B, j); - j->proc_load = j->ssr.high << 8 | j->ssr.low; - if (!j->m_hook && (j->hookstate & 1)) { - j->m_hook = j->ex.bits.hookstate = 1; - ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN); - } - } else { - if (j->ex.bits.dtmf_ready) { - j->dtmf_wp = j->dtmf_rp = j->ex.bits.dtmf_ready = 0; - } - if (j->m_hook) { - j->m_hook = 0; - j->ex.bits.hookstate = 1; - ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN); - } - } - } - if (j->cardtype == QTI_LINEJACK && !j->flags.pstncheck && j->flags.pstn_present) { - ixj_pstn_state(j); - } - if (j->ex.bytes) { - wake_up_interruptible(&j->poll_q); /* Wake any blocked selects */ - } - clear_bit(board, &j->busyflags); - } - ixj_add_timer(j); -} - -static int ixj_status_wait(IXJ *j) -{ - unsigned long jif; - - jif = jiffies + ((60 * hertz) / 100); - while (!IsStatusReady(j)) { - ixj_perfmon(j->statuswait); - if (time_after(jiffies, jif)) { - ixj_perfmon(j->statuswaitfail); - return -1; - } - } - return 0; -} - -static int ixj_PCcontrol_wait(IXJ *j) -{ - unsigned long jif; - - jif = jiffies + ((60 * hertz) / 100); - while (!IsPCControlReady(j)) { - ixj_perfmon(j->pcontrolwait); - if (time_after(jiffies, jif)) { - ixj_perfmon(j->pcontrolwaitfail); - return -1; - } - } - return 0; -} - -static int ixj_WriteDSPCommand(unsigned short cmd, IXJ *j) -{ - BYTES bytes; - unsigned long jif; - - atomic_inc(&j->DSPWrite); - if(atomic_read(&j->DSPWrite) > 1) { - printk("IXJ %d DSP write overlap attempting command 0x%4.4x\n", j->board, cmd); - return -1; - } - bytes.high = (cmd & 0xFF00) >> 8; - bytes.low = cmd & 0x00FF; - jif = jiffies + ((60 * hertz) / 100); - while (!IsControlReady(j)) { - ixj_perfmon(j->iscontrolready); - if (time_after(jiffies, jif)) { - ixj_perfmon(j->iscontrolreadyfail); - atomic_dec(&j->DSPWrite); - if(atomic_read(&j->DSPWrite) > 0) { - printk("IXJ %d DSP overlaped command 0x%4.4x during control ready failure.\n", j->board, cmd); - while(atomic_read(&j->DSPWrite) > 0) { - atomic_dec(&j->DSPWrite); - } - } - return -1; - } - } - outb(bytes.low, j->DSPbase + 6); - outb(bytes.high, j->DSPbase + 7); - - if (ixj_status_wait(j)) { - j->ssr.low = 0xFF; - j->ssr.high = 0xFF; - atomic_dec(&j->DSPWrite); - if(atomic_read(&j->DSPWrite) > 0) { - printk("IXJ %d DSP overlaped command 0x%4.4x during status wait failure.\n", j->board, cmd); - while(atomic_read(&j->DSPWrite) > 0) { - atomic_dec(&j->DSPWrite); - } - } - return -1; - } -/* Read Software Status Register */ - j->ssr.low = inb_p(j->DSPbase + 2); - j->ssr.high = inb_p(j->DSPbase + 3); - atomic_dec(&j->DSPWrite); - if(atomic_read(&j->DSPWrite) > 0) { - printk("IXJ %d DSP overlaped command 0x%4.4x\n", j->board, cmd); - while(atomic_read(&j->DSPWrite) > 0) { - atomic_dec(&j->DSPWrite); - } - } - return 0; -} - -/*************************************************************************** -* -* General Purpose IO Register read routine -* -***************************************************************************/ -static inline int ixj_gpio_read(IXJ *j) -{ - if (ixj_WriteDSPCommand(0x5143, j)) - return -1; - - j->gpio.bytes.low = j->ssr.low; - j->gpio.bytes.high = j->ssr.high; - - return 0; -} - -static inline void LED_SetState(int state, IXJ *j) -{ - if (j->cardtype == QTI_LINEJACK) { - j->pld_scrw.bits.led1 = state & 0x1 ? 1 : 0; - j->pld_scrw.bits.led2 = state & 0x2 ? 1 : 0; - j->pld_scrw.bits.led3 = state & 0x4 ? 1 : 0; - j->pld_scrw.bits.led4 = state & 0x8 ? 1 : 0; - - outb(j->pld_scrw.byte, j->XILINXbase); - } -} - -/********************************************************************* -* GPIO Pins are configured as follows on the Quicknet Internet -* PhoneJACK Telephony Cards -* -* POTS Select GPIO_6=0 GPIO_7=0 -* Mic/Speaker Select GPIO_6=0 GPIO_7=1 -* Handset Select GPIO_6=1 GPIO_7=0 -* -* SLIC Active GPIO_1=0 GPIO_2=1 GPIO_5=0 -* SLIC Ringing GPIO_1=1 GPIO_2=1 GPIO_5=0 -* SLIC Open Circuit GPIO_1=0 GPIO_2=0 GPIO_5=0 -* -* Hook Switch changes reported on GPIO_3 -*********************************************************************/ -static int ixj_set_port(IXJ *j, int arg) -{ - if (j->cardtype == QTI_PHONEJACK_LITE) { - if (arg != PORT_POTS) - return 10; - else - return 0; - } - switch (arg) { - case PORT_POTS: - j->port = PORT_POTS; - switch (j->cardtype) { - case QTI_PHONECARD: - if (j->flags.pcmciasct == 1) - SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); - else - return 11; - break; - case QTI_PHONEJACK_PCI: - j->pld_slicw.pcib.mic = 0; - j->pld_slicw.pcib.spk = 0; - outb(j->pld_slicw.byte, j->XILINXbase + 0x01); - break; - case QTI_LINEJACK: - ixj_set_pots(j, 0); /* Disconnect POTS/PSTN relay */ - if (ixj_WriteDSPCommand(0xC528, j)) /* Write CODEC config to - Software Control Register */ - return 2; - j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ - - outb(j->pld_scrw.byte, j->XILINXbase); - j->pld_clock.byte = 0; - outb(j->pld_clock.byte, j->XILINXbase + 0x04); - j->pld_slicw.bits.rly1 = 1; - j->pld_slicw.bits.spken = 0; - outb(j->pld_slicw.byte, j->XILINXbase + 0x01); - ixj_mixer(0x1200, j); /* Turn Off MIC switch on mixer left */ - ixj_mixer(0x1401, j); /* Turn On Mono1 switch on mixer left */ - ixj_mixer(0x1300, j); /* Turn Off MIC switch on mixer right */ - ixj_mixer(0x1501, j); /* Turn On Mono1 switch on mixer right */ - ixj_mixer(0x0E80, j); /*Mic mute */ - ixj_mixer(0x0F00, j); /* Set mono out (SLIC) to 0dB */ - ixj_mixer(0x0080, j); /* Mute Master Left volume */ - ixj_mixer(0x0180, j); /* Mute Master Right volume */ - SLIC_SetState(PLD_SLIC_STATE_STANDBY, j); -/* SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); */ - break; - case QTI_PHONEJACK: - j->gpio.bytes.high = 0x0B; - j->gpio.bits.gpio6 = 0; - j->gpio.bits.gpio7 = 0; - ixj_WriteDSPCommand(j->gpio.word, j); - break; - } - break; - case PORT_PSTN: - if (j->cardtype == QTI_LINEJACK) { - ixj_WriteDSPCommand(0xC534, j); /* Write CODEC config to Software Control Register */ - - j->pld_slicw.bits.rly3 = 0; - j->pld_slicw.bits.rly1 = 1; - j->pld_slicw.bits.spken = 0; - outb(j->pld_slicw.byte, j->XILINXbase + 0x01); - j->port = PORT_PSTN; - } else { - return 4; - } - break; - case PORT_SPEAKER: - j->port = PORT_SPEAKER; - switch (j->cardtype) { - case QTI_PHONECARD: - if (j->flags.pcmciasct) { - SLIC_SetState(PLD_SLIC_STATE_OC, j); - } - break; - case QTI_PHONEJACK_PCI: - j->pld_slicw.pcib.mic = 1; - j->pld_slicw.pcib.spk = 1; - outb(j->pld_slicw.byte, j->XILINXbase + 0x01); - break; - case QTI_LINEJACK: - ixj_set_pots(j, 0); /* Disconnect POTS/PSTN relay */ - if (ixj_WriteDSPCommand(0xC528, j)) /* Write CODEC config to - Software Control Register */ - return 2; - j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ - - outb(j->pld_scrw.byte, j->XILINXbase); - j->pld_clock.byte = 0; - outb(j->pld_clock.byte, j->XILINXbase + 0x04); - j->pld_slicw.bits.rly1 = 1; - j->pld_slicw.bits.spken = 1; - outb(j->pld_slicw.byte, j->XILINXbase + 0x01); - ixj_mixer(0x1201, j); /* Turn On MIC switch on mixer left */ - ixj_mixer(0x1400, j); /* Turn Off Mono1 switch on mixer left */ - ixj_mixer(0x1301, j); /* Turn On MIC switch on mixer right */ - ixj_mixer(0x1500, j); /* Turn Off Mono1 switch on mixer right */ - ixj_mixer(0x0E06, j); /*Mic un-mute 0dB */ - ixj_mixer(0x0F80, j); /* Mute mono out (SLIC) */ - ixj_mixer(0x0000, j); /* Set Master Left volume to 0dB */ - ixj_mixer(0x0100, j); /* Set Master Right volume to 0dB */ - break; - case QTI_PHONEJACK: - j->gpio.bytes.high = 0x0B; - j->gpio.bits.gpio6 = 0; - j->gpio.bits.gpio7 = 1; - ixj_WriteDSPCommand(j->gpio.word, j); - break; - } - break; - case PORT_HANDSET: - if (j->cardtype != QTI_PHONEJACK) { - return 5; - } else { - j->gpio.bytes.high = 0x0B; - j->gpio.bits.gpio6 = 1; - j->gpio.bits.gpio7 = 0; - ixj_WriteDSPCommand(j->gpio.word, j); - j->port = PORT_HANDSET; - } - break; - default: - return 6; - break; - } - return 0; -} - -static int ixj_set_pots(IXJ *j, int arg) -{ - if (j->cardtype == QTI_LINEJACK) { - if (arg) { - if (j->port == PORT_PSTN) { - j->pld_slicw.bits.rly1 = 0; - outb(j->pld_slicw.byte, j->XILINXbase + 0x01); - j->flags.pots_pstn = 1; - return 1; - } else { - j->flags.pots_pstn = 0; - return 0; - } - } else { - j->pld_slicw.bits.rly1 = 1; - outb(j->pld_slicw.byte, j->XILINXbase + 0x01); - j->flags.pots_pstn = 0; - return 1; - } - } else { - return 0; - } -} - -static void ixj_ring_on(IXJ *j) -{ - if (j->dsp.low == 0x20) /* Internet PhoneJACK */ - { - if (ixjdebug & 0x0004) - printk(KERN_INFO "IXJ Ring On /dev/phone%d\n", j->board); - - j->gpio.bytes.high = 0x0B; - j->gpio.bytes.low = 0x00; - j->gpio.bits.gpio1 = 1; - j->gpio.bits.gpio2 = 1; - j->gpio.bits.gpio5 = 0; - ixj_WriteDSPCommand(j->gpio.word, j); /* send the ring signal */ - } else /* Internet LineJACK, Internet PhoneJACK Lite or Internet PhoneJACK PCI */ - { - if (ixjdebug & 0x0004) - printk(KERN_INFO "IXJ Ring On /dev/phone%d\n", j->board); - - SLIC_SetState(PLD_SLIC_STATE_RINGING, j); - } -} - -static int ixj_siadc(IXJ *j, int val) -{ - if(j->cardtype == QTI_PHONECARD){ - if(j->flags.pcmciascp){ - if(val == -1) - return j->siadc.bits.rxg; - - if(val < 0 || val > 0x1F) - return -1; - - j->siadc.bits.hom = 0; /* Handset Out Mute */ - j->siadc.bits.lom = 0; /* Line Out Mute */ - j->siadc.bits.rxg = val; /*(0xC000 - 0x41C8) / 0x4EF; RX PGA Gain */ - j->psccr.bits.addr = 6; /* R/W Smart Cable Register Address */ - j->psccr.bits.rw = 0; /* Read / Write flag */ - j->psccr.bits.dev = 0; - outb(j->siadc.byte, j->XILINXbase + 0x00); - outb(j->psccr.byte, j->XILINXbase + 0x01); - ixj_PCcontrol_wait(j); - return j->siadc.bits.rxg; - } - } - return -1; -} - -static int ixj_sidac(IXJ *j, int val) -{ - if(j->cardtype == QTI_PHONECARD){ - if(j->flags.pcmciascp){ - if(val == -1) - return j->sidac.bits.txg; - - if(val < 0 || val > 0x1F) - return -1; - - j->sidac.bits.srm = 1; /* Speaker Right Mute */ - j->sidac.bits.slm = 1; /* Speaker Left Mute */ - j->sidac.bits.txg = val; /* (0xC000 - 0x45E4) / 0x5D3; TX PGA Gain */ - j->psccr.bits.addr = 7; /* R/W Smart Cable Register Address */ - j->psccr.bits.rw = 0; /* Read / Write flag */ - j->psccr.bits.dev = 0; - outb(j->sidac.byte, j->XILINXbase + 0x00); - outb(j->psccr.byte, j->XILINXbase + 0x01); - ixj_PCcontrol_wait(j); - return j->sidac.bits.txg; - } - } - return -1; -} - -static int ixj_pcmcia_cable_check(IXJ *j) -{ - j->pccr1.byte = inb_p(j->XILINXbase + 0x03); - if (!j->flags.pcmciastate) { - j->pccr2.byte = inb_p(j->XILINXbase + 0x02); - if (j->pccr1.bits.drf || j->pccr2.bits.rstc) { - j->flags.pcmciastate = 4; - return 0; - } - if (j->pccr1.bits.ed) { - j->pccr1.bits.ed = 0; - j->psccr.bits.dev = 3; - j->psccr.bits.rw = 1; - outw_p(j->psccr.byte << 8, j->XILINXbase + 0x00); - ixj_PCcontrol_wait(j); - j->pslic.byte = inw_p(j->XILINXbase + 0x00) & 0xFF; - j->pslic.bits.led2 = j->pslic.bits.det ? 1 : 0; - j->psccr.bits.dev = 3; - j->psccr.bits.rw = 0; - outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00); - ixj_PCcontrol_wait(j); - return j->pslic.bits.led2 ? 1 : 0; - } else if (j->flags.pcmciasct) { - return j->r_hook; - } else { - return 1; - } - } else if (j->flags.pcmciastate == 4) { - if (!j->pccr1.bits.drf) { - j->flags.pcmciastate = 3; - } - return 0; - } else if (j->flags.pcmciastate == 3) { - j->pccr2.bits.pwr = 0; - j->pccr2.bits.rstc = 1; - outb(j->pccr2.byte, j->XILINXbase + 0x02); - j->checkwait = jiffies + (hertz * 2); - j->flags.incheck = 1; - j->flags.pcmciastate = 2; - return 0; - } else if (j->flags.pcmciastate == 2) { - if (j->flags.incheck) { - if (time_before(jiffies, j->checkwait)) { - return 0; - } else { - j->flags.incheck = 0; - } - } - j->pccr2.bits.pwr = 0; - j->pccr2.bits.rstc = 0; - outb_p(j->pccr2.byte, j->XILINXbase + 0x02); - j->flags.pcmciastate = 1; - return 0; - } else if (j->flags.pcmciastate == 1) { - j->flags.pcmciastate = 0; - if (!j->pccr1.bits.drf) { - j->psccr.bits.dev = 3; - j->psccr.bits.rw = 1; - outb_p(j->psccr.byte, j->XILINXbase + 0x01); - ixj_PCcontrol_wait(j); - j->flags.pcmciascp = 1; /* Set Cable Present Flag */ - - j->flags.pcmciasct = (inw_p(j->XILINXbase + 0x00) >> 8) & 0x03; /* Get Cable Type */ - - if (j->flags.pcmciasct == 3) { - j->flags.pcmciastate = 4; - return 0; - } else if (j->flags.pcmciasct == 0) { - j->pccr2.bits.pwr = 1; - j->pccr2.bits.rstc = 0; - outb_p(j->pccr2.byte, j->XILINXbase + 0x02); - j->port = PORT_SPEAKER; - } else { - j->port = PORT_POTS; - } - j->sic1.bits.cpd = 0; /* Chip Power Down */ - j->sic1.bits.mpd = 0; /* MIC Bias Power Down */ - j->sic1.bits.hpd = 0; /* Handset Bias Power Down */ - j->sic1.bits.lpd = 0; /* Line Bias Power Down */ - j->sic1.bits.spd = 1; /* Speaker Drive Power Down */ - j->psccr.bits.addr = 1; /* R/W Smart Cable Register Address */ - j->psccr.bits.rw = 0; /* Read / Write flag */ - j->psccr.bits.dev = 0; - outb(j->sic1.byte, j->XILINXbase + 0x00); - outb(j->psccr.byte, j->XILINXbase + 0x01); - ixj_PCcontrol_wait(j); - - j->sic2.bits.al = 0; /* Analog Loopback DAC analog -> ADC analog */ - j->sic2.bits.dl2 = 0; /* Digital Loopback DAC -> ADC one bit */ - j->sic2.bits.dl1 = 0; /* Digital Loopback ADC -> DAC one bit */ - j->sic2.bits.pll = 0; /* 1 = div 10, 0 = div 5 */ - j->sic2.bits.hpd = 0; /* HPF disable */ - j->psccr.bits.addr = 2; /* R/W Smart Cable Register Address */ - j->psccr.bits.rw = 0; /* Read / Write flag */ - j->psccr.bits.dev = 0; - outb(j->sic2.byte, j->XILINXbase + 0x00); - outb(j->psccr.byte, j->XILINXbase + 0x01); - ixj_PCcontrol_wait(j); - - j->psccr.bits.addr = 3; /* R/W Smart Cable Register Address */ - j->psccr.bits.rw = 0; /* Read / Write flag */ - j->psccr.bits.dev = 0; - outb(0x00, j->XILINXbase + 0x00); /* PLL Divide N1 */ - outb(j->psccr.byte, j->XILINXbase + 0x01); - ixj_PCcontrol_wait(j); - - j->psccr.bits.addr = 4; /* R/W Smart Cable Register Address */ - j->psccr.bits.rw = 0; /* Read / Write flag */ - j->psccr.bits.dev = 0; - outb(0x09, j->XILINXbase + 0x00); /* PLL Multiply M1 */ - outb(j->psccr.byte, j->XILINXbase + 0x01); - ixj_PCcontrol_wait(j); - - j->sirxg.bits.lig = 1; /* Line In Gain */ - j->sirxg.bits.lim = 1; /* Line In Mute */ - j->sirxg.bits.mcg = 0; /* MIC In Gain was 3 */ - j->sirxg.bits.mcm = 0; /* MIC In Mute */ - j->sirxg.bits.him = 0; /* Handset In Mute */ - j->sirxg.bits.iir = 1; /* IIR */ - j->psccr.bits.addr = 5; /* R/W Smart Cable Register Address */ - j->psccr.bits.rw = 0; /* Read / Write flag */ - j->psccr.bits.dev = 0; - outb(j->sirxg.byte, j->XILINXbase + 0x00); - outb(j->psccr.byte, j->XILINXbase + 0x01); - ixj_PCcontrol_wait(j); - - ixj_siadc(j, 0x17); - ixj_sidac(j, 0x1D); - - j->siaatt.bits.sot = 0; - j->psccr.bits.addr = 9; /* R/W Smart Cable Register Address */ - j->psccr.bits.rw = 0; /* Read / Write flag */ - j->psccr.bits.dev = 0; - outb(j->siaatt.byte, j->XILINXbase + 0x00); - outb(j->psccr.byte, j->XILINXbase + 0x01); - ixj_PCcontrol_wait(j); - - if (j->flags.pcmciasct == 1 && !j->readers && !j->writers) { - j->psccr.byte = j->pslic.byte = 0; - j->pslic.bits.powerdown = 1; - j->psccr.bits.dev = 3; - j->psccr.bits.rw = 0; - outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00); - ixj_PCcontrol_wait(j); - } - } - return 0; - } else { - j->flags.pcmciascp = 0; - return 0; - } - return 0; -} - -static int ixj_hookstate(IXJ *j) -{ - int fOffHook = 0; - - switch (j->cardtype) { - case QTI_PHONEJACK: - ixj_gpio_read(j); - fOffHook = j->gpio.bits.gpio3read ? 1 : 0; - break; - case QTI_LINEJACK: - case QTI_PHONEJACK_LITE: - case QTI_PHONEJACK_PCI: - SLIC_GetState(j); - if(j->cardtype == QTI_LINEJACK && j->flags.pots_pstn == 1 && (j->readers || j->writers)) { - fOffHook = j->pld_slicr.bits.potspstn ? 1 : 0; - if(fOffHook != j->p_hook) { - if(!j->checkwait) { - j->checkwait = jiffies; - } - if(time_before(jiffies, j->checkwait + 2)) { - fOffHook ^= 1; - } else { - j->checkwait = 0; - } - j->p_hook = fOffHook; - printk("IXJ : /dev/phone%d pots-pstn hookstate check %d at %ld\n", j->board, fOffHook, jiffies); - } - } else { - if (j->pld_slicr.bits.state == PLD_SLIC_STATE_ACTIVE || - j->pld_slicr.bits.state == PLD_SLIC_STATE_STANDBY) { - if (j->flags.ringing || j->flags.cringing) { - if (!in_interrupt()) { - msleep(20); - } - SLIC_GetState(j); - if (j->pld_slicr.bits.state == PLD_SLIC_STATE_RINGING) { - ixj_ring_on(j); - } - } - if (j->cardtype == QTI_PHONEJACK_PCI) { - j->pld_scrr.byte = inb_p(j->XILINXbase); - fOffHook = j->pld_scrr.pcib.det ? 1 : 0; - } else - fOffHook = j->pld_slicr.bits.det ? 1 : 0; - } - } - break; - case QTI_PHONECARD: - fOffHook = ixj_pcmcia_cable_check(j); - break; - } - if (j->r_hook != fOffHook) { - j->r_hook = fOffHook; - if (j->port == PORT_SPEAKER || j->port == PORT_HANDSET) { // || (j->port == PORT_PSTN && j->flags.pots_pstn == 0)) { - j->ex.bits.hookstate = 1; - ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN); - } else if (!fOffHook) { - j->flash_end = jiffies + ((60 * hertz) / 100); - } - } - if (fOffHook) { - if(time_before(jiffies, j->flash_end)) { - j->ex.bits.flash = 1; - j->flash_end = 0; - ixj_kill_fasync(j, SIG_FLASH, POLL_IN); - } - } else { - if(time_before(jiffies, j->flash_end)) { - fOffHook = 1; - } - } - - if (j->port == PORT_PSTN && j->daa_mode == SOP_PU_CONVERSATION) - fOffHook |= 2; - - if (j->port == PORT_SPEAKER) { - if(j->cardtype == QTI_PHONECARD) { - if(j->flags.pcmciascp && j->flags.pcmciasct) { - fOffHook |= 2; - } - } else { - fOffHook |= 2; - } - } - - if (j->port == PORT_HANDSET) - fOffHook |= 2; - - return fOffHook; -} - -static void ixj_ring_off(IXJ *j) -{ - if (j->dsp.low == 0x20) /* Internet PhoneJACK */ - { - if (ixjdebug & 0x0004) - printk(KERN_INFO "IXJ Ring Off\n"); - j->gpio.bytes.high = 0x0B; - j->gpio.bytes.low = 0x00; - j->gpio.bits.gpio1 = 0; - j->gpio.bits.gpio2 = 1; - j->gpio.bits.gpio5 = 0; - ixj_WriteDSPCommand(j->gpio.word, j); - } else /* Internet LineJACK */ - { - if (ixjdebug & 0x0004) - printk(KERN_INFO "IXJ Ring Off\n"); - - if(!j->flags.cidplay) - SLIC_SetState(PLD_SLIC_STATE_STANDBY, j); - - SLIC_GetState(j); - } -} - -static void ixj_ring_start(IXJ *j) -{ - j->flags.cringing = 1; - if (ixjdebug & 0x0004) - printk(KERN_INFO "IXJ Cadence Ringing Start /dev/phone%d\n", j->board); - if (ixj_hookstate(j) & 1) { - if (j->port == PORT_POTS) - ixj_ring_off(j); - j->flags.cringing = 0; - if (ixjdebug & 0x0004) - printk(KERN_INFO "IXJ Cadence Ringing Stopped /dev/phone%d off hook\n", j->board); - } else if(j->cadence_f[5].enable && (!j->cadence_f[5].en_filter)) { - j->ring_cadence_jif = jiffies; - j->flags.cidsent = j->flags.cidring = 0; - j->cadence_f[5].state = 0; - if(j->cadence_f[5].on1) - ixj_ring_on(j); - } else { - j->ring_cadence_jif = jiffies; - j->ring_cadence_t = 15; - if (j->ring_cadence & 1 << j->ring_cadence_t) { - ixj_ring_on(j); - } else { - ixj_ring_off(j); - } - j->flags.cidsent = j->flags.cidring = j->flags.firstring = 0; - } -} - -static int ixj_ring(IXJ *j) -{ - char cntr; - unsigned long jif; - - j->flags.ringing = 1; - if (ixj_hookstate(j) & 1) { - ixj_ring_off(j); - j->flags.ringing = 0; - return 1; - } - for (cntr = 0; cntr < j->maxrings; cntr++) { - jif = jiffies + (1 * hertz); - ixj_ring_on(j); - while (time_before(jiffies, jif)) { - if (ixj_hookstate(j) & 1) { - ixj_ring_off(j); - j->flags.ringing = 0; - return 1; - } - schedule_timeout_interruptible(1); - if (signal_pending(current)) - break; - } - jif = jiffies + (3 * hertz); - ixj_ring_off(j); - while (time_before(jiffies, jif)) { - if (ixj_hookstate(j) & 1) { - msleep(10); - if (ixj_hookstate(j) & 1) { - j->flags.ringing = 0; - return 1; - } - } - schedule_timeout_interruptible(1); - if (signal_pending(current)) - break; - } - } - ixj_ring_off(j); - j->flags.ringing = 0; - return 0; -} - -static int ixj_open(struct phone_device *p, struct file *file_p) -{ - IXJ *j = get_ixj(p->board); - file_p->private_data = j; - - if (!j->DSPbase) - return -ENODEV; - - if (file_p->f_mode & FMODE_READ) { - if(!j->readers) { - j->readers++; - } else { - return -EBUSY; - } - } - - if (file_p->f_mode & FMODE_WRITE) { - if(!j->writers) { - j->writers++; - } else { - if (file_p->f_mode & FMODE_READ){ - j->readers--; - } - return -EBUSY; - } - } - - if (j->cardtype == QTI_PHONECARD) { - j->pslic.bits.powerdown = 0; - j->psccr.bits.dev = 3; - j->psccr.bits.rw = 0; - outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00); - ixj_PCcontrol_wait(j); - } - - j->flags.cidplay = 0; - j->flags.cidcw_ack = 0; - - if (ixjdebug & 0x0002) - printk(KERN_INFO "Opening board %d\n", p->board); - - j->framesread = j->frameswritten = 0; - return 0; -} - -static int ixj_release(struct inode *inode, struct file *file_p) -{ - IXJ_TONE ti; - int cnt; - IXJ *j = file_p->private_data; - int board = j->p.board; - - /* - * Set up locks to ensure that only one process is talking to the DSP at a time. - * This is necessary to keep the DSP from locking up. - */ - while(test_and_set_bit(board, (void *)&j->busyflags) != 0) - schedule_timeout_interruptible(1); - if (ixjdebug & 0x0002) - printk(KERN_INFO "Closing board %d\n", NUM(inode)); - - if (j->cardtype == QTI_PHONECARD) - ixj_set_port(j, PORT_SPEAKER); - else - ixj_set_port(j, PORT_POTS); - - aec_stop(j); - ixj_play_stop(j); - ixj_record_stop(j); - set_play_volume(j, 0x100); - set_rec_volume(j, 0x100); - ixj_ring_off(j); - - /* Restore the tone table to default settings. */ - ti.tone_index = 10; - ti.gain0 = 1; - ti.freq0 = hz941; - ti.gain1 = 0; - ti.freq1 = hz1209; - ixj_init_tone(j, &ti); - ti.tone_index = 11; - ti.gain0 = 1; - ti.freq0 = hz941; - ti.gain1 = 0; - ti.freq1 = hz1336; - ixj_init_tone(j, &ti); - ti.tone_index = 12; - ti.gain0 = 1; - ti.freq0 = hz941; - ti.gain1 = 0; - ti.freq1 = hz1477; - ixj_init_tone(j, &ti); - ti.tone_index = 13; - ti.gain0 = 1; - ti.freq0 = hz800; - ti.gain1 = 0; - ti.freq1 = 0; - ixj_init_tone(j, &ti); - ti.tone_index = 14; - ti.gain0 = 1; - ti.freq0 = hz1000; - ti.gain1 = 0; - ti.freq1 = 0; - ixj_init_tone(j, &ti); - ti.tone_index = 15; - ti.gain0 = 1; - ti.freq0 = hz1250; - ti.gain1 = 0; - ti.freq1 = 0; - ixj_init_tone(j, &ti); - ti.tone_index = 16; - ti.gain0 = 1; - ti.freq0 = hz950; - ti.gain1 = 0; - ti.freq1 = 0; - ixj_init_tone(j, &ti); - ti.tone_index = 17; - ti.gain0 = 1; - ti.freq0 = hz1100; - ti.gain1 = 0; - ti.freq1 = 0; - ixj_init_tone(j, &ti); - ti.tone_index = 18; - ti.gain0 = 1; - ti.freq0 = hz1400; - ti.gain1 = 0; - ti.freq1 = 0; - ixj_init_tone(j, &ti); - ti.tone_index = 19; - ti.gain0 = 1; - ti.freq0 = hz1500; - ti.gain1 = 0; - ti.freq1 = 0; - ixj_init_tone(j, &ti); - ti.tone_index = 20; - ti.gain0 = 1; - ti.freq0 = hz1600; - ti.gain1 = 0; - ti.freq1 = 0; - ixj_init_tone(j, &ti); - ti.tone_index = 21; - ti.gain0 = 1; - ti.freq0 = hz1800; - ti.gain1 = 0; - ti.freq1 = 0; - ixj_init_tone(j, &ti); - ti.tone_index = 22; - ti.gain0 = 1; - ti.freq0 = hz2100; - ti.gain1 = 0; - ti.freq1 = 0; - ixj_init_tone(j, &ti); - ti.tone_index = 23; - ti.gain0 = 1; - ti.freq0 = hz1300; - ti.gain1 = 0; - ti.freq1 = 0; - ixj_init_tone(j, &ti); - ti.tone_index = 24; - ti.gain0 = 1; - ti.freq0 = hz2450; - ti.gain1 = 0; - ti.freq1 = 0; - ixj_init_tone(j, &ti); - ti.tone_index = 25; - ti.gain0 = 1; - ti.freq0 = hz350; - ti.gain1 = 0; - ti.freq1 = hz440; - ixj_init_tone(j, &ti); - ti.tone_index = 26; - ti.gain0 = 1; - ti.freq0 = hz440; - ti.gain1 = 0; - ti.freq1 = hz480; - ixj_init_tone(j, &ti); - ti.tone_index = 27; - ti.gain0 = 1; - ti.freq0 = hz480; - ti.gain1 = 0; - ti.freq1 = hz620; - ixj_init_tone(j, &ti); - - set_rec_depth(j, 2); /* Set Record Channel Limit to 2 frames */ - - set_play_depth(j, 2); /* Set Playback Channel Limit to 2 frames */ - - j->ex.bits.dtmf_ready = 0; - j->dtmf_state = 0; - j->dtmf_wp = j->dtmf_rp = 0; - j->rec_mode = j->play_mode = -1; - j->flags.ringing = 0; - j->maxrings = MAXRINGS; - j->ring_cadence = USA_RING_CADENCE; - if(j->cadence_f[5].enable) { - j->cadence_f[5].enable = j->cadence_f[5].en_filter = j->cadence_f[5].state = 0; - } - j->drybuffer = 0; - j->winktime = 320; - j->flags.dtmf_oob = 0; - for (cnt = 0; cnt < 4; cnt++) - j->cadence_f[cnt].enable = 0; - - idle(j); - - if(j->cardtype == QTI_PHONECARD) { - SLIC_SetState(PLD_SLIC_STATE_OC, j); - } - - if (file_p->f_mode & FMODE_READ) - j->readers--; - if (file_p->f_mode & FMODE_WRITE) - j->writers--; - - if (j->read_buffer && !j->readers) { - kfree(j->read_buffer); - j->read_buffer = NULL; - j->read_buffer_size = 0; - } - if (j->write_buffer && !j->writers) { - kfree(j->write_buffer); - j->write_buffer = NULL; - j->write_buffer_size = 0; - } - j->rec_codec = j->play_codec = 0; - j->rec_frame_size = j->play_frame_size = 0; - j->flags.cidsent = j->flags.cidring = 0; - - if(j->cardtype == QTI_LINEJACK && !j->readers && !j->writers) { - ixj_set_port(j, PORT_PSTN); - daa_set_mode(j, SOP_PU_SLEEP); - ixj_set_pots(j, 1); - } - ixj_WriteDSPCommand(0x0FE3, j); /* Put the DSP in 1/5 power mode. */ - - /* Set up the default signals for events */ - for (cnt = 0; cnt < 35; cnt++) - j->ixj_signals[cnt] = SIGIO; - - /* Set the excetion signal enable flags */ - j->ex_sig.bits.dtmf_ready = j->ex_sig.bits.hookstate = j->ex_sig.bits.flash = j->ex_sig.bits.pstn_ring = - j->ex_sig.bits.caller_id = j->ex_sig.bits.pstn_wink = j->ex_sig.bits.f0 = j->ex_sig.bits.f1 = j->ex_sig.bits.f2 = - j->ex_sig.bits.f3 = j->ex_sig.bits.fc0 = j->ex_sig.bits.fc1 = j->ex_sig.bits.fc2 = j->ex_sig.bits.fc3 = 1; - - file_p->private_data = NULL; - clear_bit(board, &j->busyflags); - return 0; -} - -static int read_filters(IXJ *j) -{ - unsigned short fc, cnt, trg; - int var; - - trg = 0; - if (ixj_WriteDSPCommand(0x5144, j)) { - if(ixjdebug & 0x0001) { - printk(KERN_INFO "Read Frame Counter failed!\n"); - } - return -1; - } - fc = j->ssr.high << 8 | j->ssr.low; - if (fc == j->frame_count) - return 1; - - j->frame_count = fc; - - if (j->dtmf_proc) - return 1; - - var = 10; - - for (cnt = 0; cnt < 4; cnt++) { - if (ixj_WriteDSPCommand(0x5154 + cnt, j)) { - if(ixjdebug & 0x0001) { - printk(KERN_INFO "Select Filter %d failed!\n", cnt); - } - return -1; - } - if (ixj_WriteDSPCommand(0x515C, j)) { - if(ixjdebug & 0x0001) { - printk(KERN_INFO "Read Filter History %d failed!\n", cnt); - } - return -1; - } - j->filter_hist[cnt] = j->ssr.high << 8 | j->ssr.low; - - if (j->cadence_f[cnt].enable) { - if (j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12)) { - if (j->cadence_f[cnt].state == 0) { - j->cadence_f[cnt].state = 1; - j->cadence_f[cnt].on1min = jiffies + (long)((j->cadence_f[cnt].on1 * (hertz * (100 - var)) / 10000)); - j->cadence_f[cnt].on1dot = jiffies + (long)((j->cadence_f[cnt].on1 * (hertz * (100)) / 10000)); - j->cadence_f[cnt].on1max = jiffies + (long)((j->cadence_f[cnt].on1 * (hertz * (100 + var)) / 10000)); - } else if (j->cadence_f[cnt].state == 2 && - (time_after(jiffies, j->cadence_f[cnt].off1min) && - time_before(jiffies, j->cadence_f[cnt].off1max))) { - if (j->cadence_f[cnt].on2) { - j->cadence_f[cnt].state = 3; - j->cadence_f[cnt].on2min = jiffies + (long)((j->cadence_f[cnt].on2 * (hertz * (100 - var)) / 10000)); - j->cadence_f[cnt].on2dot = jiffies + (long)((j->cadence_f[cnt].on2 * (hertz * (100)) / 10000)); - j->cadence_f[cnt].on2max = jiffies + (long)((j->cadence_f[cnt].on2 * (hertz * (100 + var)) / 10000)); - } else { - j->cadence_f[cnt].state = 7; - } - } else if (j->cadence_f[cnt].state == 4 && - (time_after(jiffies, j->cadence_f[cnt].off2min) && - time_before(jiffies, j->cadence_f[cnt].off2max))) { - if (j->cadence_f[cnt].on3) { - j->cadence_f[cnt].state = 5; - j->cadence_f[cnt].on3min = jiffies + (long)((j->cadence_f[cnt].on3 * (hertz * (100 - var)) / 10000)); - j->cadence_f[cnt].on3dot = jiffies + (long)((j->cadence_f[cnt].on3 * (hertz * (100)) / 10000)); - j->cadence_f[cnt].on3max = jiffies + (long)((j->cadence_f[cnt].on3 * (hertz * (100 + var)) / 10000)); - } else { - j->cadence_f[cnt].state = 7; - } - } else { - j->cadence_f[cnt].state = 0; - } - } else if (j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3)) { - if (j->cadence_f[cnt].state == 1) { - if(!j->cadence_f[cnt].on1) { - j->cadence_f[cnt].state = 7; - } else if((time_after(jiffies, j->cadence_f[cnt].on1min) && - time_before(jiffies, j->cadence_f[cnt].on1max))) { - if(j->cadence_f[cnt].off1) { - j->cadence_f[cnt].state = 2; - j->cadence_f[cnt].off1min = jiffies + (long)((j->cadence_f[cnt].off1 * (hertz * (100 - var)) / 10000)); - j->cadence_f[cnt].off1dot = jiffies + (long)((j->cadence_f[cnt].off1 * (hertz * (100)) / 10000)); - j->cadence_f[cnt].off1max = jiffies + (long)((j->cadence_f[cnt].off1 * (hertz * (100 + var)) / 10000)); - } else { - j->cadence_f[cnt].state = 7; - } - } else { - j->cadence_f[cnt].state = 0; - } - } else if (j->cadence_f[cnt].state == 3) { - if((time_after(jiffies, j->cadence_f[cnt].on2min) && - time_before(jiffies, j->cadence_f[cnt].on2max))) { - if(j->cadence_f[cnt].off2) { - j->cadence_f[cnt].state = 4; - j->cadence_f[cnt].off2min = jiffies + (long)((j->cadence_f[cnt].off2 * (hertz * (100 - var)) / 10000)); - j->cadence_f[cnt].off2dot = jiffies + (long)((j->cadence_f[cnt].off2 * (hertz * (100)) / 10000)); - j->cadence_f[cnt].off2max = jiffies + (long)((j->cadence_f[cnt].off2 * (hertz * (100 + var)) / 10000)); - } else { - j->cadence_f[cnt].state = 7; - } - } else { - j->cadence_f[cnt].state = 0; - } - } else if (j->cadence_f[cnt].state == 5) { - if ((time_after(jiffies, j->cadence_f[cnt].on3min) && - time_before(jiffies, j->cadence_f[cnt].on3max))) { - if(j->cadence_f[cnt].off3) { - j->cadence_f[cnt].state = 6; - j->cadence_f[cnt].off3min = jiffies + (long)((j->cadence_f[cnt].off3 * (hertz * (100 - var)) / 10000)); - j->cadence_f[cnt].off3dot = jiffies + (long)((j->cadence_f[cnt].off3 * (hertz * (100)) / 10000)); - j->cadence_f[cnt].off3max = jiffies + (long)((j->cadence_f[cnt].off3 * (hertz * (100 + var)) / 10000)); - } else { - j->cadence_f[cnt].state = 7; - } - } else { - j->cadence_f[cnt].state = 0; - } - } else { - j->cadence_f[cnt].state = 0; - } - } else { - switch(j->cadence_f[cnt].state) { - case 1: - if(time_after(jiffies, j->cadence_f[cnt].on1dot) && - !j->cadence_f[cnt].off1 && - !j->cadence_f[cnt].on2 && !j->cadence_f[cnt].off2 && - !j->cadence_f[cnt].on3 && !j->cadence_f[cnt].off3) { - j->cadence_f[cnt].state = 7; - } - break; - case 3: - if(time_after(jiffies, j->cadence_f[cnt].on2dot) && - !j->cadence_f[cnt].off2 && - !j->cadence_f[cnt].on3 && !j->cadence_f[cnt].off3) { - j->cadence_f[cnt].state = 7; - } - break; - case 5: - if(time_after(jiffies, j->cadence_f[cnt].on3dot) && - !j->cadence_f[cnt].off3) { - j->cadence_f[cnt].state = 7; - } - break; - } - } - - if (ixjdebug & 0x0040) { - printk(KERN_INFO "IXJ Tone Cadence state = %d /dev/phone%d at %ld\n", j->cadence_f[cnt].state, j->board, jiffies); - switch(j->cadence_f[cnt].state) { - case 0: - printk(KERN_INFO "IXJ /dev/phone%d No Tone detected\n", j->board); - break; - case 1: - printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %u %ld - %ld - %ld\n", j->board, - j->cadence_f[cnt].on1, j->cadence_f[cnt].on1min, j->cadence_f[cnt].on1dot, j->cadence_f[cnt].on1max); - break; - case 2: - printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off1min, - j->cadence_f[cnt].off1max); - break; - case 3: - printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].on2min, - j->cadence_f[cnt].on2max); - break; - case 4: - printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off2min, - j->cadence_f[cnt].off2max); - break; - case 5: - printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].on3min, - j->cadence_f[cnt].on3max); - break; - case 6: - printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off3min, - j->cadence_f[cnt].off3max); - break; - } - } - } - if (j->cadence_f[cnt].state == 7) { - j->cadence_f[cnt].state = 0; - if (j->cadence_f[cnt].enable == 1) - j->cadence_f[cnt].enable = 0; - switch (cnt) { - case 0: - if(ixjdebug & 0x0020) { - printk(KERN_INFO "Filter Cadence 0 triggered %ld\n", jiffies); - } - j->ex.bits.fc0 = 1; - ixj_kill_fasync(j, SIG_FC0, POLL_IN); - break; - case 1: - if(ixjdebug & 0x0020) { - printk(KERN_INFO "Filter Cadence 1 triggered %ld\n", jiffies); - } - j->ex.bits.fc1 = 1; - ixj_kill_fasync(j, SIG_FC1, POLL_IN); - break; - case 2: - if(ixjdebug & 0x0020) { - printk(KERN_INFO "Filter Cadence 2 triggered %ld\n", jiffies); - } - j->ex.bits.fc2 = 1; - ixj_kill_fasync(j, SIG_FC2, POLL_IN); - break; - case 3: - if(ixjdebug & 0x0020) { - printk(KERN_INFO "Filter Cadence 3 triggered %ld\n", jiffies); - } - j->ex.bits.fc3 = 1; - ixj_kill_fasync(j, SIG_FC3, POLL_IN); - break; - } - } - if (j->filter_en[cnt] && ((j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12)) || - (j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3)))) { - if((j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12))) { - trg = 1; - } else if((j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3))) { - trg = 0; - } - switch (cnt) { - case 0: - if(ixjdebug & 0x0020) { - printk(KERN_INFO "Filter 0 triggered %d at %ld\n", trg, jiffies); - } - j->ex.bits.f0 = 1; - ixj_kill_fasync(j, SIG_F0, POLL_IN); - break; - case 1: - if(ixjdebug & 0x0020) { - printk(KERN_INFO "Filter 1 triggered %d at %ld\n", trg, jiffies); - } - j->ex.bits.f1 = 1; - ixj_kill_fasync(j, SIG_F1, POLL_IN); - break; - case 2: - if(ixjdebug & 0x0020) { - printk(KERN_INFO "Filter 2 triggered %d at %ld\n", trg, jiffies); - } - j->ex.bits.f2 = 1; - ixj_kill_fasync(j, SIG_F2, POLL_IN); - break; - case 3: - if(ixjdebug & 0x0020) { - printk(KERN_INFO "Filter 3 triggered %d at %ld\n", trg, jiffies); - } - j->ex.bits.f3 = 1; - ixj_kill_fasync(j, SIG_F3, POLL_IN); - break; - } - } - } - return 0; -} - -static int LineMonitor(IXJ *j) -{ - if (j->dtmf_proc) { - return -1; - } - j->dtmf_proc = 1; - - if (ixj_WriteDSPCommand(0x7000, j)) /* Line Monitor */ - return -1; - - j->dtmf.bytes.high = j->ssr.high; - j->dtmf.bytes.low = j->ssr.low; - if (!j->dtmf_state && j->dtmf.bits.dtmf_valid) { - j->dtmf_state = 1; - j->dtmf_current = j->dtmf.bits.digit; - } - if (j->dtmf_state && !j->dtmf.bits.dtmf_valid) /* && j->dtmf_wp != j->dtmf_rp) */ - { - if(!j->cidcw_wait) { - j->dtmfbuffer[j->dtmf_wp] = j->dtmf_current; - j->dtmf_wp++; - if (j->dtmf_wp == 79) - j->dtmf_wp = 0; - j->ex.bits.dtmf_ready = 1; - if(j->ex_sig.bits.dtmf_ready) { - ixj_kill_fasync(j, SIG_DTMF_READY, POLL_IN); - } - } - else if(j->dtmf_current == 0x00 || j->dtmf_current == 0x0D) { - if(ixjdebug & 0x0020) { - printk("IXJ phone%d saw CIDCW Ack DTMF %d from display at %ld\n", j->board, j->dtmf_current, jiffies); - } - j->flags.cidcw_ack = 1; - } - j->dtmf_state = 0; - } - j->dtmf_proc = 0; - - return 0; -} - -/************************************************************************ -* -* Functions to allow alaw <-> ulaw conversions. -* -************************************************************************/ - -static void ulaw2alaw(unsigned char *buff, unsigned long len) -{ - static unsigned char table_ulaw2alaw[] = - { - 0x2A, 0x2B, 0x28, 0x29, 0x2E, 0x2F, 0x2C, 0x2D, - 0x22, 0x23, 0x20, 0x21, 0x26, 0x27, 0x24, 0x25, - 0x3A, 0x3B, 0x38, 0x39, 0x3E, 0x3F, 0x3C, 0x3D, - 0x32, 0x33, 0x30, 0x31, 0x36, 0x37, 0x34, 0x35, - 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D, 0x02, - 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, 0x1A, - 0x1B, 0x18, 0x19, 0x1E, 0x1F, 0x1C, 0x1D, 0x12, - 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15, 0x6B, - 0x68, 0x69, 0x6E, 0x6F, 0x6C, 0x6D, 0x62, 0x63, - 0x60, 0x61, 0x66, 0x67, 0x64, 0x65, 0x7B, 0x79, - 0x7E, 0x7F, 0x7C, 0x7D, 0x72, 0x73, 0x70, 0x71, - 0x76, 0x77, 0x74, 0x75, 0x4B, 0x49, 0x4F, 0x4D, - 0x42, 0x43, 0x40, 0x41, 0x46, 0x47, 0x44, 0x45, - 0x5A, 0x5B, 0x58, 0x59, 0x5E, 0x5F, 0x5C, 0x5D, - 0x52, 0x52, 0x53, 0x53, 0x50, 0x50, 0x51, 0x51, - 0x56, 0x56, 0x57, 0x57, 0x54, 0x54, 0x55, 0xD5, - 0xAA, 0xAB, 0xA8, 0xA9, 0xAE, 0xAF, 0xAC, 0xAD, - 0xA2, 0xA3, 0xA0, 0xA1, 0xA6, 0xA7, 0xA4, 0xA5, - 0xBA, 0xBB, 0xB8, 0xB9, 0xBE, 0xBF, 0xBC, 0xBD, - 0xB2, 0xB3, 0xB0, 0xB1, 0xB6, 0xB7, 0xB4, 0xB5, - 0x8B, 0x88, 0x89, 0x8E, 0x8F, 0x8C, 0x8D, 0x82, - 0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85, 0x9A, - 0x9B, 0x98, 0x99, 0x9E, 0x9F, 0x9C, 0x9D, 0x92, - 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95, 0xEB, - 0xE8, 0xE9, 0xEE, 0xEF, 0xEC, 0xED, 0xE2, 0xE3, - 0xE0, 0xE1, 0xE6, 0xE7, 0xE4, 0xE5, 0xFB, 0xF9, - 0xFE, 0xFF, 0xFC, 0xFD, 0xF2, 0xF3, 0xF0, 0xF1, - 0xF6, 0xF7, 0xF4, 0xF5, 0xCB, 0xC9, 0xCF, 0xCD, - 0xC2, 0xC3, 0xC0, 0xC1, 0xC6, 0xC7, 0xC4, 0xC5, - 0xDA, 0xDB, 0xD8, 0xD9, 0xDE, 0xDF, 0xDC, 0xDD, - 0xD2, 0xD2, 0xD3, 0xD3, 0xD0, 0xD0, 0xD1, 0xD1, - 0xD6, 0xD6, 0xD7, 0xD7, 0xD4, 0xD4, 0xD5, 0xD5 - }; - - while (len--) - { - *buff = table_ulaw2alaw[*(unsigned char *)buff]; - buff++; - } -} - -static void alaw2ulaw(unsigned char *buff, unsigned long len) -{ - static unsigned char table_alaw2ulaw[] = - { - 0x29, 0x2A, 0x27, 0x28, 0x2D, 0x2E, 0x2B, 0x2C, - 0x21, 0x22, 0x1F, 0x20, 0x25, 0x26, 0x23, 0x24, - 0x39, 0x3A, 0x37, 0x38, 0x3D, 0x3E, 0x3B, 0x3C, - 0x31, 0x32, 0x2F, 0x30, 0x35, 0x36, 0x33, 0x34, - 0x0A, 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D, - 0x02, 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, - 0x1A, 0x1B, 0x18, 0x19, 0x1E, 0x1F, 0x1C, 0x1D, - 0x12, 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15, - 0x62, 0x63, 0x60, 0x61, 0x66, 0x67, 0x64, 0x65, - 0x5D, 0x5D, 0x5C, 0x5C, 0x5F, 0x5F, 0x5E, 0x5E, - 0x74, 0x76, 0x70, 0x72, 0x7C, 0x7E, 0x78, 0x7A, - 0x6A, 0x6B, 0x68, 0x69, 0x6E, 0x6F, 0x6C, 0x6D, - 0x48, 0x49, 0x46, 0x47, 0x4C, 0x4D, 0x4A, 0x4B, - 0x40, 0x41, 0x3F, 0x3F, 0x44, 0x45, 0x42, 0x43, - 0x56, 0x57, 0x54, 0x55, 0x5A, 0x5B, 0x58, 0x59, - 0x4F, 0x4F, 0x4E, 0x4E, 0x52, 0x53, 0x50, 0x51, - 0xA9, 0xAA, 0xA7, 0xA8, 0xAD, 0xAE, 0xAB, 0xAC, - 0xA1, 0xA2, 0x9F, 0xA0, 0xA5, 0xA6, 0xA3, 0xA4, - 0xB9, 0xBA, 0xB7, 0xB8, 0xBD, 0xBE, 0xBB, 0xBC, - 0xB1, 0xB2, 0xAF, 0xB0, 0xB5, 0xB6, 0xB3, 0xB4, - 0x8A, 0x8B, 0x88, 0x89, 0x8E, 0x8F, 0x8C, 0x8D, - 0x82, 0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85, - 0x9A, 0x9B, 0x98, 0x99, 0x9E, 0x9F, 0x9C, 0x9D, - 0x92, 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95, - 0xE2, 0xE3, 0xE0, 0xE1, 0xE6, 0xE7, 0xE4, 0xE5, - 0xDD, 0xDD, 0xDC, 0xDC, 0xDF, 0xDF, 0xDE, 0xDE, - 0xF4, 0xF6, 0xF0, 0xF2, 0xFC, 0xFE, 0xF8, 0xFA, - 0xEA, 0xEB, 0xE8, 0xE9, 0xEE, 0xEF, 0xEC, 0xED, - 0xC8, 0xC9, 0xC6, 0xC7, 0xCC, 0xCD, 0xCA, 0xCB, - 0xC0, 0xC1, 0xBF, 0xBF, 0xC4, 0xC5, 0xC2, 0xC3, - 0xD6, 0xD7, 0xD4, 0xD5, 0xDA, 0xDB, 0xD8, 0xD9, - 0xCF, 0xCF, 0xCE, 0xCE, 0xD2, 0xD3, 0xD0, 0xD1 - }; - - while (len--) - { - *buff = table_alaw2ulaw[*(unsigned char *)buff]; - buff++; - } -} - -static ssize_t ixj_read(struct file * file_p, char __user *buf, size_t length, loff_t * ppos) -{ - unsigned long i = *ppos; - IXJ * j = get_ixj(NUM(file_p->f_path.dentry->d_inode)); - - DECLARE_WAITQUEUE(wait, current); - - if (j->flags.inread) - return -EALREADY; - - j->flags.inread = 1; - - add_wait_queue(&j->read_q, &wait); - set_current_state(TASK_INTERRUPTIBLE); - mb(); - - while (!j->read_buffer_ready || (j->dtmf_state && j->flags.dtmf_oob)) { - ++j->read_wait; - if (file_p->f_flags & O_NONBLOCK) { - set_current_state(TASK_RUNNING); - remove_wait_queue(&j->read_q, &wait); - j->flags.inread = 0; - return -EAGAIN; - } - if (!ixj_hookstate(j)) { - set_current_state(TASK_RUNNING); - remove_wait_queue(&j->read_q, &wait); - j->flags.inread = 0; - return 0; - } - interruptible_sleep_on(&j->read_q); - if (signal_pending(current)) { - set_current_state(TASK_RUNNING); - remove_wait_queue(&j->read_q, &wait); - j->flags.inread = 0; - return -EINTR; - } - } - - remove_wait_queue(&j->read_q, &wait); - set_current_state(TASK_RUNNING); - /* Don't ever copy more than the user asks */ - if(j->rec_codec == ALAW) - ulaw2alaw(j->read_buffer, min(length, j->read_buffer_size)); - i = copy_to_user(buf, j->read_buffer, min(length, j->read_buffer_size)); - j->read_buffer_ready = 0; - if (i) { - j->flags.inread = 0; - return -EFAULT; - } else { - j->flags.inread = 0; - return min(length, j->read_buffer_size); - } -} - -static ssize_t ixj_enhanced_read(struct file * file_p, char __user *buf, size_t length, - loff_t * ppos) -{ - int pre_retval; - ssize_t read_retval = 0; - IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode)); - - pre_retval = ixj_PreRead(j, 0L); - switch (pre_retval) { - case NORMAL: - read_retval = ixj_read(file_p, buf, length, ppos); - ixj_PostRead(j, 0L); - break; - case NOPOST: - read_retval = ixj_read(file_p, buf, length, ppos); - break; - case POSTONLY: - ixj_PostRead(j, 0L); - break; - default: - read_retval = pre_retval; - } - return read_retval; -} - -static ssize_t ixj_write(struct file *file_p, const char __user *buf, size_t count, loff_t * ppos) -{ - unsigned long i = *ppos; - IXJ *j = file_p->private_data; - - DECLARE_WAITQUEUE(wait, current); - - if (j->flags.inwrite) - return -EALREADY; - - j->flags.inwrite = 1; - - add_wait_queue(&j->write_q, &wait); - set_current_state(TASK_INTERRUPTIBLE); - mb(); - - - while (!j->write_buffers_empty) { - ++j->write_wait; - if (file_p->f_flags & O_NONBLOCK) { - set_current_state(TASK_RUNNING); - remove_wait_queue(&j->write_q, &wait); - j->flags.inwrite = 0; - return -EAGAIN; - } - if (!ixj_hookstate(j)) { - set_current_state(TASK_RUNNING); - remove_wait_queue(&j->write_q, &wait); - j->flags.inwrite = 0; - return 0; - } - interruptible_sleep_on(&j->write_q); - if (signal_pending(current)) { - set_current_state(TASK_RUNNING); - remove_wait_queue(&j->write_q, &wait); - j->flags.inwrite = 0; - return -EINTR; - } - } - set_current_state(TASK_RUNNING); - remove_wait_queue(&j->write_q, &wait); - if (j->write_buffer_wp + count >= j->write_buffer_end) - j->write_buffer_wp = j->write_buffer; - i = copy_from_user(j->write_buffer_wp, buf, min(count, j->write_buffer_size)); - if (i) { - j->flags.inwrite = 0; - return -EFAULT; - } - if(j->play_codec == ALAW) - alaw2ulaw(j->write_buffer_wp, min(count, j->write_buffer_size)); - j->flags.inwrite = 0; - return min(count, j->write_buffer_size); -} - -static ssize_t ixj_enhanced_write(struct file * file_p, const char __user *buf, size_t count, loff_t * ppos) -{ - int pre_retval; - ssize_t write_retval = 0; - - IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode)); - - pre_retval = ixj_PreWrite(j, 0L); - switch (pre_retval) { - case NORMAL: - write_retval = ixj_write(file_p, buf, count, ppos); - if (write_retval > 0) { - ixj_PostWrite(j, 0L); - j->write_buffer_wp += write_retval; - j->write_buffers_empty--; - } - break; - case NOPOST: - write_retval = ixj_write(file_p, buf, count, ppos); - if (write_retval > 0) { - j->write_buffer_wp += write_retval; - j->write_buffers_empty--; - } - break; - case POSTONLY: - ixj_PostWrite(j, 0L); - break; - default: - write_retval = pre_retval; - } - return write_retval; -} - -static void ixj_read_frame(IXJ *j) -{ - int cnt, dly; - - if (j->read_buffer) { - for (cnt = 0; cnt < j->rec_frame_size * 2; cnt += 2) { - if (!(cnt % 16) && !IsRxReady(j)) { - dly = 0; - while (!IsRxReady(j)) { - if (dly++ > 5) { - dly = 0; - break; - } - udelay(10); - } - } - /* Throw away word 0 of the 8021 compressed format to get standard G.729. */ - if (j->rec_codec == G729 && (cnt == 0 || cnt == 10 || cnt == 20)) { - inb_p(j->DSPbase + 0x0E); - inb_p(j->DSPbase + 0x0F); - } - *(j->read_buffer + cnt) = inb_p(j->DSPbase + 0x0E); - *(j->read_buffer + cnt + 1) = inb_p(j->DSPbase + 0x0F); - } - ++j->framesread; - if (j->intercom != -1) { - if (IsTxReady(get_ixj(j->intercom))) { - for (cnt = 0; cnt < j->rec_frame_size * 2; cnt += 2) { - if (!(cnt % 16) && !IsTxReady(j)) { - dly = 0; - while (!IsTxReady(j)) { - if (dly++ > 5) { - dly = 0; - break; - } - udelay(10); - } - } - outb_p(*(j->read_buffer + cnt), get_ixj(j->intercom)->DSPbase + 0x0C); - outb_p(*(j->read_buffer + cnt + 1), get_ixj(j->intercom)->DSPbase + 0x0D); - } - get_ixj(j->intercom)->frameswritten++; - } - } else { - j->read_buffer_ready = 1; - wake_up_interruptible(&j->read_q); /* Wake any blocked readers */ - - wake_up_interruptible(&j->poll_q); /* Wake any blocked selects */ - - if(j->ixj_signals[SIG_READ_READY]) - ixj_kill_fasync(j, SIG_READ_READY, POLL_OUT); - } - } -} - -static short fsk[][6][20] = -{ - { - { - 0, 17846, 29934, 32364, 24351, 8481, -10126, -25465, -32587, -29196, - -16384, 1715, 19260, 30591, 32051, 23170, 6813, -11743, -26509, -32722 - }, - { - -28377, -14876, 3425, 20621, 31163, 31650, 21925, 5126, -13328, -27481, - -32767, -27481, -13328, 5126, 21925, 31650, 31163, 20621, 3425, -14876 - }, - { - -28377, -32722, -26509, -11743, 6813, 23170, 32051, 30591, 19260, 1715, - -16384, -29196, -32587, -25465, -10126, 8481, 24351, 32364, 29934, 17846 - }, - { - 0, -17846, -29934, -32364, -24351, -8481, 10126, 25465, 32587, 29196, - 16384, -1715, -19260, -30591, -32051, -23170, -6813, 11743, 26509, 32722 - }, - { - 28377, 14876, -3425, -20621, -31163, -31650, -21925, -5126, 13328, 27481, - 32767, 27481, 13328, -5126, -21925, -31650, -31163, -20621, -3425, 14876 - }, - { - 28377, 32722, 26509, 11743, -6813, -23170, -32051, -30591, -19260, -1715, - 16384, 29196, 32587, 25465, 10126, -8481, -24351, -32364, -29934, -17846 - } - }, - { - { - 0, 10126, 19260, 26509, 31163, 32767, 31163, 26509, 19260, 10126, - 0, -10126, -19260, -26509, -31163, -32767, -31163, -26509, -19260, -10126 - }, - { - -28377, -21925, -13328, -3425, 6813, 16384, 24351, 29934, 32587, 32051, - 28377, 21925, 13328, 3425, -6813, -16384, -24351, -29934, -32587, -32051 - }, - { - -28377, -32051, -32587, -29934, -24351, -16384, -6813, 3425, 13328, 21925, - 28377, 32051, 32587, 29934, 24351, 16384, 6813, -3425, -13328, -21925 - }, - { - 0, -10126, -19260, -26509, -31163, -32767, -31163, -26509, -19260, -10126, - 0, 10126, 19260, 26509, 31163, 32767, 31163, 26509, 19260, 10126 - }, - { - 28377, 21925, 13328, 3425, -6813, -16383, -24351, -29934, -32587, -32051, - -28377, -21925, -13328, -3425, 6813, 16383, 24351, 29934, 32587, 32051 - }, - { - 28377, 32051, 32587, 29934, 24351, 16384, 6813, -3425, -13328, -21925, - -28377, -32051, -32587, -29934, -24351, -16384, -6813, 3425, 13328, 21925 - } - } -}; - - -static void ixj_write_cid_bit(IXJ *j, int bit) -{ - while (j->fskcnt < 20) { - if(j->fskdcnt < (j->fsksize - 1)) - j->fskdata[j->fskdcnt++] = fsk[bit][j->fskz][j->fskcnt]; - - j->fskcnt += 3; - } - j->fskcnt %= 20; - - if (!bit) - j->fskz++; - if (j->fskz >= 6) - j->fskz = 0; - -} - -static void ixj_write_cid_byte(IXJ *j, char byte) -{ - IXJ_CBYTE cb; - - cb.cbyte = byte; - ixj_write_cid_bit(j, 0); - ixj_write_cid_bit(j, cb.cbits.b0 ? 1 : 0); - ixj_write_cid_bit(j, cb.cbits.b1 ? 1 : 0); - ixj_write_cid_bit(j, cb.cbits.b2 ? 1 : 0); - ixj_write_cid_bit(j, cb.cbits.b3 ? 1 : 0); - ixj_write_cid_bit(j, cb.cbits.b4 ? 1 : 0); - ixj_write_cid_bit(j, cb.cbits.b5 ? 1 : 0); - ixj_write_cid_bit(j, cb.cbits.b6 ? 1 : 0); - ixj_write_cid_bit(j, cb.cbits.b7 ? 1 : 0); - ixj_write_cid_bit(j, 1); -} - -static void ixj_write_cid_seize(IXJ *j) -{ - int cnt; - - for (cnt = 0; cnt < 150; cnt++) { - ixj_write_cid_bit(j, 0); - ixj_write_cid_bit(j, 1); - } - for (cnt = 0; cnt < 180; cnt++) { - ixj_write_cid_bit(j, 1); - } -} - -static void ixj_write_cidcw_seize(IXJ *j) -{ - int cnt; - - for (cnt = 0; cnt < 80; cnt++) { - ixj_write_cid_bit(j, 1); - } -} - -static int ixj_write_cid_string(IXJ *j, char *s, int checksum) -{ - int cnt; - - for (cnt = 0; cnt < strlen(s); cnt++) { - ixj_write_cid_byte(j, s[cnt]); - checksum = (checksum + s[cnt]); - } - return checksum; -} - -static void ixj_pad_fsk(IXJ *j, int pad) -{ - int cnt; - - for (cnt = 0; cnt < pad; cnt++) { - if(j->fskdcnt < (j->fsksize - 1)) - j->fskdata[j->fskdcnt++] = 0x0000; - } - for (cnt = 0; cnt < 720; cnt++) { - if(j->fskdcnt < (j->fsksize - 1)) - j->fskdata[j->fskdcnt++] = 0x0000; - } -} - -static void ixj_pre_cid(IXJ *j) -{ - j->cid_play_codec = j->play_codec; - j->cid_play_frame_size = j->play_frame_size; - j->cid_play_volume = get_play_volume(j); - j->cid_play_flag = j->flags.playing; - - j->cid_rec_codec = j->rec_codec; - j->cid_rec_volume = get_rec_volume(j); - j->cid_rec_flag = j->flags.recording; - - j->cid_play_aec_level = j->aec_level; - - switch(j->baseframe.low) { - case 0xA0: - j->cid_base_frame_size = 20; - break; - case 0x50: - j->cid_base_frame_size = 10; - break; - case 0xF0: - j->cid_base_frame_size = 30; - break; - } - - ixj_play_stop(j); - ixj_cpt_stop(j); - - j->flags.cidplay = 1; - - set_base_frame(j, 30); - set_play_codec(j, LINEAR16); - set_play_volume(j, 0x1B); - ixj_play_start(j); -} - -static void ixj_post_cid(IXJ *j) -{ - ixj_play_stop(j); - - if(j->cidsize > 5000) { - SLIC_SetState(PLD_SLIC_STATE_STANDBY, j); - } - j->flags.cidplay = 0; - if(ixjdebug & 0x0200) { - printk("IXJ phone%d Finished Playing CallerID data %ld\n", j->board, jiffies); - } - - ixj_fsk_free(j); - - j->fskdcnt = 0; - set_base_frame(j, j->cid_base_frame_size); - set_play_codec(j, j->cid_play_codec); - ixj_aec_start(j, j->cid_play_aec_level); - set_play_volume(j, j->cid_play_volume); - - set_rec_codec(j, j->cid_rec_codec); - set_rec_volume(j, j->cid_rec_volume); - - if(j->cid_rec_flag) - ixj_record_start(j); - - if(j->cid_play_flag) - ixj_play_start(j); - - if(j->cid_play_flag) { - wake_up_interruptible(&j->write_q); /* Wake any blocked writers */ - } -} - -static void ixj_write_cid(IXJ *j) -{ - char sdmf1[50]; - char sdmf2[50]; - char sdmf3[80]; - char mdmflen, len1, len2, len3; - int pad; - - int checksum = 0; - - if (j->dsp.low == 0x20 || j->flags.cidplay) - return; - - j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0; - j->cidsize = j->cidcnt = 0; - - ixj_fsk_alloc(j); - - strcpy(sdmf1, j->cid_send.month); - strcat(sdmf1, j->cid_send.day); - strcat(sdmf1, j->cid_send.hour); - strcat(sdmf1, j->cid_send.min); - strcpy(sdmf2, j->cid_send.number); - strcpy(sdmf3, j->cid_send.name); - - len1 = strlen(sdmf1); - len2 = strlen(sdmf2); - len3 = strlen(sdmf3); - mdmflen = len1 + len2 + len3 + 6; - - while(1){ - ixj_write_cid_seize(j); - - ixj_write_cid_byte(j, 0x80); - checksum = 0x80; - ixj_write_cid_byte(j, mdmflen); - checksum = checksum + mdmflen; - - ixj_write_cid_byte(j, 0x01); - checksum = checksum + 0x01; - ixj_write_cid_byte(j, len1); - checksum = checksum + len1; - checksum = ixj_write_cid_string(j, sdmf1, checksum); - if(ixj_hookstate(j) & 1) - break; - - ixj_write_cid_byte(j, 0x02); - checksum = checksum + 0x02; - ixj_write_cid_byte(j, len2); - checksum = checksum + len2; - checksum = ixj_write_cid_string(j, sdmf2, checksum); - if(ixj_hookstate(j) & 1) - break; - - ixj_write_cid_byte(j, 0x07); - checksum = checksum + 0x07; - ixj_write_cid_byte(j, len3); - checksum = checksum + len3; - checksum = ixj_write_cid_string(j, sdmf3, checksum); - if(ixj_hookstate(j) & 1) - break; - - checksum %= 256; - checksum ^= 0xFF; - checksum += 1; - - ixj_write_cid_byte(j, (char) checksum); - - pad = j->fskdcnt % 240; - if (pad) { - pad = 240 - pad; - } - ixj_pad_fsk(j, pad); - break; - } - - ixj_write_frame(j); -} - -static void ixj_write_cidcw(IXJ *j) -{ - IXJ_TONE ti; - - char sdmf1[50]; - char sdmf2[50]; - char sdmf3[80]; - char mdmflen, len1, len2, len3; - int pad; - - int checksum = 0; - - if (j->dsp.low == 0x20 || j->flags.cidplay) - return; - - j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0; - j->cidsize = j->cidcnt = 0; - - ixj_fsk_alloc(j); - - j->flags.cidcw_ack = 0; - - ti.tone_index = 23; - ti.gain0 = 1; - ti.freq0 = hz440; - ti.gain1 = 0; - ti.freq1 = 0; - ixj_init_tone(j, &ti); - - ixj_set_tone_on(1500, j); - ixj_set_tone_off(32, j); - if(ixjdebug & 0x0200) { - printk("IXJ cidcw phone%d first tone start at %ld\n", j->board, jiffies); - } - ixj_play_tone(j, 23); - - clear_bit(j->board, &j->busyflags); - while(j->tone_state) - schedule_timeout_interruptible(1); - while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0) - schedule_timeout_interruptible(1); - if(ixjdebug & 0x0200) { - printk("IXJ cidcw phone%d first tone end at %ld\n", j->board, jiffies); - } - - ti.tone_index = 24; - ti.gain0 = 1; - ti.freq0 = hz2130; - ti.gain1 = 0; - ti.freq1 = hz2750; - ixj_init_tone(j, &ti); - - ixj_set_tone_off(10, j); - ixj_set_tone_on(600, j); - if(ixjdebug & 0x0200) { - printk("IXJ cidcw phone%d second tone start at %ld\n", j->board, jiffies); - } - ixj_play_tone(j, 24); - - clear_bit(j->board, &j->busyflags); - while(j->tone_state) - schedule_timeout_interruptible(1); - while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0) - schedule_timeout_interruptible(1); - if(ixjdebug & 0x0200) { - printk("IXJ cidcw phone%d sent second tone at %ld\n", j->board, jiffies); - } - - j->cidcw_wait = jiffies + ((50 * hertz) / 100); - - clear_bit(j->board, &j->busyflags); - while(!j->flags.cidcw_ack && time_before(jiffies, j->cidcw_wait)) - schedule_timeout_interruptible(1); - while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0) - schedule_timeout_interruptible(1); - j->cidcw_wait = 0; - if(!j->flags.cidcw_ack) { - if(ixjdebug & 0x0200) { - printk("IXJ cidcw phone%d did not receive ACK from display %ld\n", j->board, jiffies); - } - ixj_post_cid(j); - if(j->cid_play_flag) { - wake_up_interruptible(&j->write_q); /* Wake any blocked readers */ - } - return; - } else { - ixj_pre_cid(j); - } - j->flags.cidcw_ack = 0; - strcpy(sdmf1, j->cid_send.month); - strcat(sdmf1, j->cid_send.day); - strcat(sdmf1, j->cid_send.hour); - strcat(sdmf1, j->cid_send.min); - strcpy(sdmf2, j->cid_send.number); - strcpy(sdmf3, j->cid_send.name); - - len1 = strlen(sdmf1); - len2 = strlen(sdmf2); - len3 = strlen(sdmf3); - mdmflen = len1 + len2 + len3 + 6; - - ixj_write_cidcw_seize(j); - - ixj_write_cid_byte(j, 0x80); - checksum = 0x80; - ixj_write_cid_byte(j, mdmflen); - checksum = checksum + mdmflen; - - ixj_write_cid_byte(j, 0x01); - checksum = checksum + 0x01; - ixj_write_cid_byte(j, len1); - checksum = checksum + len1; - checksum = ixj_write_cid_string(j, sdmf1, checksum); - - ixj_write_cid_byte(j, 0x02); - checksum = checksum + 0x02; - ixj_write_cid_byte(j, len2); - checksum = checksum + len2; - checksum = ixj_write_cid_string(j, sdmf2, checksum); - - ixj_write_cid_byte(j, 0x07); - checksum = checksum + 0x07; - ixj_write_cid_byte(j, len3); - checksum = checksum + len3; - checksum = ixj_write_cid_string(j, sdmf3, checksum); - - checksum %= 256; - checksum ^= 0xFF; - checksum += 1; - - ixj_write_cid_byte(j, (char) checksum); - - pad = j->fskdcnt % 240; - if (pad) { - pad = 240 - pad; - } - ixj_pad_fsk(j, pad); - if(ixjdebug & 0x0200) { - printk("IXJ cidcw phone%d sent FSK data at %ld\n", j->board, jiffies); - } -} - -static void ixj_write_vmwi(IXJ *j, int msg) -{ - char mdmflen; - int pad; - - int checksum = 0; - - if (j->dsp.low == 0x20 || j->flags.cidplay) - return; - - j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0; - j->cidsize = j->cidcnt = 0; - - ixj_fsk_alloc(j); - - mdmflen = 3; - - if (j->port == PORT_POTS) - SLIC_SetState(PLD_SLIC_STATE_OHT, j); - - ixj_write_cid_seize(j); - - ixj_write_cid_byte(j, 0x82); - checksum = 0x82; - ixj_write_cid_byte(j, mdmflen); - checksum = checksum + mdmflen; - - ixj_write_cid_byte(j, 0x0B); - checksum = checksum + 0x0B; - ixj_write_cid_byte(j, 1); - checksum = checksum + 1; - - if(msg) { - ixj_write_cid_byte(j, 0xFF); - checksum = checksum + 0xFF; - } - else { - ixj_write_cid_byte(j, 0x00); - checksum = checksum + 0x00; - } - - checksum %= 256; - checksum ^= 0xFF; - checksum += 1; - - ixj_write_cid_byte(j, (char) checksum); - - pad = j->fskdcnt % 240; - if (pad) { - pad = 240 - pad; - } - ixj_pad_fsk(j, pad); -} - -static void ixj_write_frame(IXJ *j) -{ - int cnt, frame_count, dly; - IXJ_WORD dat; - - frame_count = 0; - if(j->flags.cidplay) { - for(cnt = 0; cnt < 480; cnt++) { - if (!(cnt % 16) && !IsTxReady(j)) { - dly = 0; - while (!IsTxReady(j)) { - if (dly++ > 5) { - dly = 0; - break; - } - udelay(10); - } - } - dat.word = j->fskdata[j->cidcnt++]; - outb_p(dat.bytes.low, j->DSPbase + 0x0C); - outb_p(dat.bytes.high, j->DSPbase + 0x0D); - cnt++; - } - if(j->cidcnt >= j->fskdcnt) { - ixj_post_cid(j); - } - /* This may seem rude, but if we just played one frame of FSK data for CallerID - and there is real audio data in the buffer, we need to throw it away because - we just used it's time slot */ - if (j->write_buffer_rp > j->write_buffer_wp) { - j->write_buffer_rp += j->cid_play_frame_size * 2; - if (j->write_buffer_rp >= j->write_buffer_end) { - j->write_buffer_rp = j->write_buffer; - } - j->write_buffers_empty++; - wake_up_interruptible(&j->write_q); /* Wake any blocked writers */ - - wake_up_interruptible(&j->poll_q); /* Wake any blocked selects */ - } - } else if (j->write_buffer && j->write_buffers_empty < 1) { - if (j->write_buffer_wp > j->write_buffer_rp) { - frame_count = - (j->write_buffer_wp - j->write_buffer_rp) / (j->play_frame_size * 2); - } - if (j->write_buffer_rp > j->write_buffer_wp) { - frame_count = - (j->write_buffer_wp - j->write_buffer) / (j->play_frame_size * 2) + - (j->write_buffer_end - j->write_buffer_rp) / (j->play_frame_size * 2); - } - if (frame_count >= 1) { - if (j->ver.low == 0x12 && j->play_mode && j->flags.play_first_frame) { - BYTES blankword; - - switch (j->play_mode) { - case PLAYBACK_MODE_ULAW: - case PLAYBACK_MODE_ALAW: - blankword.low = blankword.high = 0xFF; - break; - case PLAYBACK_MODE_8LINEAR: - case PLAYBACK_MODE_16LINEAR: - default: - blankword.low = blankword.high = 0x00; - break; - case PLAYBACK_MODE_8LINEAR_WSS: - blankword.low = blankword.high = 0x80; - break; - } - for (cnt = 0; cnt < 16; cnt++) { - if (!(cnt % 16) && !IsTxReady(j)) { - dly = 0; - while (!IsTxReady(j)) { - if (dly++ > 5) { - dly = 0; - break; - } - udelay(10); - } - } - outb_p((blankword.low), j->DSPbase + 0x0C); - outb_p((blankword.high), j->DSPbase + 0x0D); - } - j->flags.play_first_frame = 0; - } else if (j->play_codec == G723_63 && j->flags.play_first_frame) { - for (cnt = 0; cnt < 24; cnt++) { - BYTES blankword; - - if(cnt == 12) { - blankword.low = 0x02; - blankword.high = 0x00; - } - else { - blankword.low = blankword.high = 0x00; - } - if (!(cnt % 16) && !IsTxReady(j)) { - dly = 0; - while (!IsTxReady(j)) { - if (dly++ > 5) { - dly = 0; - break; - } - udelay(10); - } - } - outb_p((blankword.low), j->DSPbase + 0x0C); - outb_p((blankword.high), j->DSPbase + 0x0D); - } - j->flags.play_first_frame = 0; - } - for (cnt = 0; cnt < j->play_frame_size * 2; cnt += 2) { - if (!(cnt % 16) && !IsTxReady(j)) { - dly = 0; - while (!IsTxReady(j)) { - if (dly++ > 5) { - dly = 0; - break; - } - udelay(10); - } - } - /* Add word 0 to G.729 frames for the 8021. Right now we don't do VAD/CNG */ - if (j->play_codec == G729 && (cnt == 0 || cnt == 10 || cnt == 20)) { - if (j->write_buffer_rp[cnt] == 0 && - j->write_buffer_rp[cnt + 1] == 0 && - j->write_buffer_rp[cnt + 2] == 0 && - j->write_buffer_rp[cnt + 3] == 0 && - j->write_buffer_rp[cnt + 4] == 0 && - j->write_buffer_rp[cnt + 5] == 0 && - j->write_buffer_rp[cnt + 6] == 0 && - j->write_buffer_rp[cnt + 7] == 0 && - j->write_buffer_rp[cnt + 8] == 0 && - j->write_buffer_rp[cnt + 9] == 0) { - /* someone is trying to write silence lets make this a type 0 frame. */ - outb_p(0x00, j->DSPbase + 0x0C); - outb_p(0x00, j->DSPbase + 0x0D); - } else { - /* so all other frames are type 1. */ - outb_p(0x01, j->DSPbase + 0x0C); - outb_p(0x00, j->DSPbase + 0x0D); - } - } - outb_p(*(j->write_buffer_rp + cnt), j->DSPbase + 0x0C); - outb_p(*(j->write_buffer_rp + cnt + 1), j->DSPbase + 0x0D); - *(j->write_buffer_rp + cnt) = 0; - *(j->write_buffer_rp + cnt + 1) = 0; - } - j->write_buffer_rp += j->play_frame_size * 2; - if (j->write_buffer_rp >= j->write_buffer_end) { - j->write_buffer_rp = j->write_buffer; - } - j->write_buffers_empty++; - wake_up_interruptible(&j->write_q); /* Wake any blocked writers */ - - wake_up_interruptible(&j->poll_q); /* Wake any blocked selects */ - - ++j->frameswritten; - } - } else { - j->drybuffer++; - } - if(j->ixj_signals[SIG_WRITE_READY]) { - ixj_kill_fasync(j, SIG_WRITE_READY, POLL_OUT); - } -} - -static int idle(IXJ *j) -{ - if (ixj_WriteDSPCommand(0x0000, j)) /* DSP Idle */ - - return 0; - - if (j->ssr.high || j->ssr.low) { - return 0; - } else { - j->play_mode = -1; - j->flags.playing = 0; - j->rec_mode = -1; - j->flags.recording = 0; - return 1; - } -} - -static int set_base_frame(IXJ *j, int size) -{ - unsigned short cmd; - int cnt; - - idle(j); - j->cid_play_aec_level = j->aec_level; - aec_stop(j); - for (cnt = 0; cnt < 10; cnt++) { - if (idle(j)) - break; - } - if (j->ssr.high || j->ssr.low) - return -1; - if (j->dsp.low != 0x20) { - switch (size) { - case 30: - cmd = 0x07F0; - /* Set Base Frame Size to 240 pg9-10 8021 */ - break; - case 20: - cmd = 0x07A0; - /* Set Base Frame Size to 160 pg9-10 8021 */ - break; - case 10: - cmd = 0x0750; - /* Set Base Frame Size to 80 pg9-10 8021 */ - break; - default: - return -1; - } - } else { - if (size == 30) - return size; - else - return -1; - } - if (ixj_WriteDSPCommand(cmd, j)) { - j->baseframe.high = j->baseframe.low = 0xFF; - return -1; - } else { - j->baseframe.high = j->ssr.high; - j->baseframe.low = j->ssr.low; - /* If the status returned is 0x0000 (pg9-9 8021) the call failed */ - if(j->baseframe.high == 0x00 && j->baseframe.low == 0x00) { - return -1; - } - } - ixj_aec_start(j, j->cid_play_aec_level); - return size; -} - -static int set_rec_codec(IXJ *j, int rate) -{ - int retval = 0; - - j->rec_codec = rate; - - switch (rate) { - case G723_63: - if (j->ver.low != 0x12 || ixj_convert_loaded) { - j->rec_frame_size = 12; - j->rec_mode = 0; - } else { - retval = 1; - } - break; - case G723_53: - if (j->ver.low != 0x12 || ixj_convert_loaded) { - j->rec_frame_size = 10; - j->rec_mode = 0; - } else { - retval = 1; - } - break; - case TS85: - if (j->dsp.low == 0x20 || j->flags.ts85_loaded) { - j->rec_frame_size = 16; - j->rec_mode = 0; - } else { - retval = 1; - } - break; - case TS48: - if (j->ver.low != 0x12 || ixj_convert_loaded) { - j->rec_frame_size = 9; - j->rec_mode = 0; - } else { - retval = 1; - } - break; - case TS41: - if (j->ver.low != 0x12 || ixj_convert_loaded) { - j->rec_frame_size = 8; - j->rec_mode = 0; - } else { - retval = 1; - } - break; - case G728: - if (j->dsp.low != 0x20) { - j->rec_frame_size = 48; - j->rec_mode = 0; - } else { - retval = 1; - } - break; - case G729: - if (j->dsp.low != 0x20) { - if (!j->flags.g729_loaded) { - retval = 1; - break; - } - switch (j->baseframe.low) { - case 0xA0: - j->rec_frame_size = 10; - break; - case 0x50: - j->rec_frame_size = 5; - break; - default: - j->rec_frame_size = 15; - break; - } - j->rec_mode = 0; - } else { - retval = 1; - } - break; - case G729B: - if (j->dsp.low != 0x20) { - if (!j->flags.g729_loaded) { - retval = 1; - break; - } - switch (j->baseframe.low) { - case 0xA0: - j->rec_frame_size = 12; - break; - case 0x50: - j->rec_frame_size = 6; - break; - default: - j->rec_frame_size = 18; - break; - } - j->rec_mode = 0; - } else { - retval = 1; - } - break; - case ULAW: - switch (j->baseframe.low) { - case 0xA0: - j->rec_frame_size = 80; - break; - case 0x50: - j->rec_frame_size = 40; - break; - default: - j->rec_frame_size = 120; - break; - } - j->rec_mode = 4; - break; - case ALAW: - switch (j->baseframe.low) { - case 0xA0: - j->rec_frame_size = 80; - break; - case 0x50: - j->rec_frame_size = 40; - break; - default: - j->rec_frame_size = 120; - break; - } - j->rec_mode = 4; - break; - case LINEAR16: - switch (j->baseframe.low) { - case 0xA0: - j->rec_frame_size = 160; - break; - case 0x50: - j->rec_frame_size = 80; - break; - default: - j->rec_frame_size = 240; - break; - } - j->rec_mode = 5; - break; - case LINEAR8: - switch (j->baseframe.low) { - case 0xA0: - j->rec_frame_size = 80; - break; - case 0x50: - j->rec_frame_size = 40; - break; - default: - j->rec_frame_size = 120; - break; - } - j->rec_mode = 6; - break; - case WSS: - switch (j->baseframe.low) { - case 0xA0: - j->rec_frame_size = 80; - break; - case 0x50: - j->rec_frame_size = 40; - break; - default: - j->rec_frame_size = 120; - break; - } - j->rec_mode = 7; - break; - default: - kfree(j->read_buffer); - j->rec_frame_size = 0; - j->rec_mode = -1; - j->read_buffer = NULL; - j->read_buffer_size = 0; - retval = 1; - break; - } - return retval; -} - -static int ixj_record_start(IXJ *j) -{ - unsigned short cmd = 0x0000; - - if (j->read_buffer) { - ixj_record_stop(j); - } - j->flags.recording = 1; - ixj_WriteDSPCommand(0x0FE0, j); /* Put the DSP in full power mode. */ - - if(ixjdebug & 0x0002) - printk("IXJ %d Starting Record Codec %d at %ld\n", j->board, j->rec_codec, jiffies); - - if (!j->rec_mode) { - switch (j->rec_codec) { - case G723_63: - cmd = 0x5131; - break; - case G723_53: - cmd = 0x5132; - break; - case TS85: - cmd = 0x5130; /* TrueSpeech 8.5 */ - - break; - case TS48: - cmd = 0x5133; /* TrueSpeech 4.8 */ - - break; - case TS41: - cmd = 0x5134; /* TrueSpeech 4.1 */ - - break; - case G728: - cmd = 0x5135; - break; - case G729: - case G729B: - cmd = 0x5136; - break; - default: - return 1; - } - if (ixj_WriteDSPCommand(cmd, j)) - return -1; - } - if (!j->read_buffer) { - if (!j->read_buffer) - j->read_buffer = kmalloc(j->rec_frame_size * 2, GFP_ATOMIC); - if (!j->read_buffer) { - printk("Read buffer allocation for ixj board %d failed!\n", j->board); - return -ENOMEM; - } - } - j->read_buffer_size = j->rec_frame_size * 2; - - if (ixj_WriteDSPCommand(0x5102, j)) /* Set Poll sync mode */ - - return -1; - - switch (j->rec_mode) { - case 0: - cmd = 0x1C03; /* Record C1 */ - - break; - case 4: - if (j->ver.low == 0x12) { - cmd = 0x1E03; /* Record C1 */ - - } else { - cmd = 0x1E01; /* Record C1 */ - - } - break; - case 5: - if (j->ver.low == 0x12) { - cmd = 0x1E83; /* Record C1 */ - - } else { - cmd = 0x1E81; /* Record C1 */ - - } - break; - case 6: - if (j->ver.low == 0x12) { - cmd = 0x1F03; /* Record C1 */ - - } else { - cmd = 0x1F01; /* Record C1 */ - - } - break; - case 7: - if (j->ver.low == 0x12) { - cmd = 0x1F83; /* Record C1 */ - } else { - cmd = 0x1F81; /* Record C1 */ - } - break; - } - if (ixj_WriteDSPCommand(cmd, j)) - return -1; - - if (j->flags.playing) { - ixj_aec_start(j, j->aec_level); - } - return 0; -} - -static void ixj_record_stop(IXJ *j) -{ - if (ixjdebug & 0x0002) - printk("IXJ %d Stopping Record Codec %d at %ld\n", j->board, j->rec_codec, jiffies); - - kfree(j->read_buffer); - j->read_buffer = NULL; - j->read_buffer_size = 0; - if (j->rec_mode > -1) { - ixj_WriteDSPCommand(0x5120, j); - j->rec_mode = -1; - } - j->flags.recording = 0; -} -static void ixj_vad(IXJ *j, int arg) -{ - if (arg) - ixj_WriteDSPCommand(0x513F, j); - else - ixj_WriteDSPCommand(0x513E, j); -} - -static void set_rec_depth(IXJ *j, int depth) -{ - if (depth > 60) - depth = 60; - if (depth < 0) - depth = 0; - ixj_WriteDSPCommand(0x5180 + depth, j); -} - -static void set_dtmf_prescale(IXJ *j, int volume) -{ - ixj_WriteDSPCommand(0xCF07, j); - ixj_WriteDSPCommand(volume, j); -} - -static int get_dtmf_prescale(IXJ *j) -{ - ixj_WriteDSPCommand(0xCF05, j); - return j->ssr.high << 8 | j->ssr.low; -} - -static void set_rec_volume(IXJ *j, int volume) -{ - if(j->aec_level == AEC_AGC) { - if (ixjdebug & 0x0002) - printk(KERN_INFO "IXJ: /dev/phone%d Setting AGC Threshold to 0x%4.4x\n", j->board, volume); - ixj_WriteDSPCommand(0xCF96, j); - ixj_WriteDSPCommand(volume, j); - } else { - if (ixjdebug & 0x0002) - printk(KERN_INFO "IXJ: /dev/phone %d Setting Record Volume to 0x%4.4x\n", j->board, volume); - ixj_WriteDSPCommand(0xCF03, j); - ixj_WriteDSPCommand(volume, j); - } -} - -static int set_rec_volume_linear(IXJ *j, int volume) -{ - int newvolume, dsprecmax; - - if (ixjdebug & 0x0002) - printk(KERN_INFO "IXJ: /dev/phone %d Setting Linear Record Volume to 0x%4.4x\n", j->board, volume); - if(volume > 100 || volume < 0) { - return -1; - } - - /* This should normalize the perceived volumes between the different cards caused by differences in the hardware */ - switch (j->cardtype) { - case QTI_PHONEJACK: - dsprecmax = 0x440; - break; - case QTI_LINEJACK: - dsprecmax = 0x180; - ixj_mixer(0x0203, j); /*Voice Left Volume unmute 6db */ - ixj_mixer(0x0303, j); /*Voice Right Volume unmute 6db */ - ixj_mixer(0x0C00, j); /*Mono1 unmute 12db */ - break; - case QTI_PHONEJACK_LITE: - dsprecmax = 0x4C0; - break; - case QTI_PHONEJACK_PCI: - dsprecmax = 0x100; - break; - case QTI_PHONECARD: - dsprecmax = 0x400; - break; - default: - return -1; - } - newvolume = (dsprecmax * volume) / 100; - set_rec_volume(j, newvolume); - return 0; -} - -static int get_rec_volume(IXJ *j) -{ - if(j->aec_level == AEC_AGC) { - if (ixjdebug & 0x0002) - printk(KERN_INFO "Getting AGC Threshold\n"); - ixj_WriteDSPCommand(0xCF86, j); - if (ixjdebug & 0x0002) - printk(KERN_INFO "AGC Threshold is 0x%2.2x%2.2x\n", j->ssr.high, j->ssr.low); - return j->ssr.high << 8 | j->ssr.low; - } else { - if (ixjdebug & 0x0002) - printk(KERN_INFO "Getting Record Volume\n"); - ixj_WriteDSPCommand(0xCF01, j); - return j->ssr.high << 8 | j->ssr.low; - } -} - -static int get_rec_volume_linear(IXJ *j) -{ - int volume, newvolume, dsprecmax; - - switch (j->cardtype) { - case QTI_PHONEJACK: - dsprecmax = 0x440; - break; - case QTI_LINEJACK: - dsprecmax = 0x180; - break; - case QTI_PHONEJACK_LITE: - dsprecmax = 0x4C0; - break; - case QTI_PHONEJACK_PCI: - dsprecmax = 0x100; - break; - case QTI_PHONECARD: - dsprecmax = 0x400; - break; - default: - return -1; - } - volume = get_rec_volume(j); - newvolume = (volume * 100) / dsprecmax; - if(newvolume > 100) - newvolume = 100; - return newvolume; -} - -static int get_rec_level(IXJ *j) -{ - int retval; - - ixj_WriteDSPCommand(0xCF88, j); - - retval = j->ssr.high << 8 | j->ssr.low; - retval = (retval * 256) / 240; - return retval; -} - -static void ixj_aec_start(IXJ *j, int level) -{ - j->aec_level = level; - if (ixjdebug & 0x0002) - printk(KERN_INFO "AGC set = 0x%2.2x\n", j->aec_level); - if (!level) { - aec_stop(j); - } else { - if (j->rec_codec == G729 || j->play_codec == G729 || j->rec_codec == G729B || j->play_codec == G729B) { - ixj_WriteDSPCommand(0xE022, j); /* Move AEC filter buffer */ - - ixj_WriteDSPCommand(0x0300, j); - } - ixj_WriteDSPCommand(0xB001, j); /* AEC On */ - - ixj_WriteDSPCommand(0xE013, j); /* Advanced AEC C1 */ - - switch (level) { - case AEC_LOW: - ixj_WriteDSPCommand(0x0000, j); /* Advanced AEC C2 = off */ - - ixj_WriteDSPCommand(0xE011, j); - ixj_WriteDSPCommand(0xFFFF, j); - - ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */ - ixj_WriteDSPCommand(0x0000, j); /* to off */ - - break; - - case AEC_MED: - ixj_WriteDSPCommand(0x0600, j); /* Advanced AEC C2 = on medium */ - - ixj_WriteDSPCommand(0xE011, j); - ixj_WriteDSPCommand(0x0080, j); - - ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */ - ixj_WriteDSPCommand(0x0000, j); /* to off */ - - break; - - case AEC_HIGH: - ixj_WriteDSPCommand(0x0C00, j); /* Advanced AEC C2 = on high */ - - ixj_WriteDSPCommand(0xE011, j); - ixj_WriteDSPCommand(0x0080, j); - - ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */ - ixj_WriteDSPCommand(0x0000, j); /* to off */ - - break; - - case AEC_AGC: - /* First we have to put the AEC into advance auto mode so that AGC will not conflict with it */ - ixj_WriteDSPCommand(0x0002, j); /* Attenuation scaling factor of 2 */ - - ixj_WriteDSPCommand(0xE011, j); - ixj_WriteDSPCommand(0x0100, j); /* Higher Threshold Floor */ - - ixj_WriteDSPCommand(0xE012, j); /* Set Train and Lock */ - - if(j->cardtype == QTI_LINEJACK || j->cardtype == QTI_PHONECARD) - ixj_WriteDSPCommand(0x0224, j); - else - ixj_WriteDSPCommand(0x1224, j); - - ixj_WriteDSPCommand(0xE014, j); - ixj_WriteDSPCommand(0x0003, j); /* Lock threshold at 3dB */ - - ixj_WriteDSPCommand(0xE338, j); /* Set Echo Suppresser Attenuation to 0dB */ - - /* Now we can set the AGC initial parameters and turn it on */ - ixj_WriteDSPCommand(0xCF90, j); /* Set AGC Minimum gain */ - ixj_WriteDSPCommand(0x0020, j); /* to 0.125 (-18dB) */ - - ixj_WriteDSPCommand(0xCF91, j); /* Set AGC Maximum gain */ - ixj_WriteDSPCommand(0x1000, j); /* to 16 (24dB) */ - - ixj_WriteDSPCommand(0xCF92, j); /* Set AGC start gain */ - ixj_WriteDSPCommand(0x0800, j); /* to 8 (+18dB) */ - - ixj_WriteDSPCommand(0xCF93, j); /* Set AGC hold time */ - ixj_WriteDSPCommand(0x1F40, j); /* to 2 seconds (units are 250us) */ - - ixj_WriteDSPCommand(0xCF94, j); /* Set AGC Attack Time Constant */ - ixj_WriteDSPCommand(0x0005, j); /* to 8ms */ - - ixj_WriteDSPCommand(0xCF95, j); /* Set AGC Decay Time Constant */ - ixj_WriteDSPCommand(0x000D, j); /* to 4096ms */ - - ixj_WriteDSPCommand(0xCF96, j); /* Set AGC Attack Threshold */ - ixj_WriteDSPCommand(0x1200, j); /* to 25% */ - - ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */ - ixj_WriteDSPCommand(0x0001, j); /* to on */ - - break; - - case AEC_AUTO: - ixj_WriteDSPCommand(0x0002, j); /* Attenuation scaling factor of 2 */ - - ixj_WriteDSPCommand(0xE011, j); - ixj_WriteDSPCommand(0x0100, j); /* Higher Threshold Floor */ - - ixj_WriteDSPCommand(0xE012, j); /* Set Train and Lock */ - - if(j->cardtype == QTI_LINEJACK || j->cardtype == QTI_PHONECARD) - ixj_WriteDSPCommand(0x0224, j); - else - ixj_WriteDSPCommand(0x1224, j); - - ixj_WriteDSPCommand(0xE014, j); - ixj_WriteDSPCommand(0x0003, j); /* Lock threshold at 3dB */ - - ixj_WriteDSPCommand(0xE338, j); /* Set Echo Suppresser Attenuation to 0dB */ - - break; - } - } -} - -static void aec_stop(IXJ *j) -{ - j->aec_level = AEC_OFF; - if (j->rec_codec == G729 || j->play_codec == G729 || j->rec_codec == G729B || j->play_codec == G729B) { - ixj_WriteDSPCommand(0xE022, j); /* Move AEC filter buffer back */ - - ixj_WriteDSPCommand(0x0700, j); - } - if (j->play_mode != -1 && j->rec_mode != -1) - { - ixj_WriteDSPCommand(0xB002, j); /* AEC Stop */ - } -} - -static int set_play_codec(IXJ *j, int rate) -{ - int retval = 0; - - j->play_codec = rate; - - switch (rate) { - case G723_63: - if (j->ver.low != 0x12 || ixj_convert_loaded) { - j->play_frame_size = 12; - j->play_mode = 0; - } else { - retval = 1; - } - break; - case G723_53: - if (j->ver.low != 0x12 || ixj_convert_loaded) { - j->play_frame_size = 10; - j->play_mode = 0; - } else { - retval = 1; - } - break; - case TS85: - if (j->dsp.low == 0x20 || j->flags.ts85_loaded) { - j->play_frame_size = 16; - j->play_mode = 0; - } else { - retval = 1; - } - break; - case TS48: - if (j->ver.low != 0x12 || ixj_convert_loaded) { - j->play_frame_size = 9; - j->play_mode = 0; - } else { - retval = 1; - } - break; - case TS41: - if (j->ver.low != 0x12 || ixj_convert_loaded) { - j->play_frame_size = 8; - j->play_mode = 0; - } else { - retval = 1; - } - break; - case G728: - if (j->dsp.low != 0x20) { - j->play_frame_size = 48; - j->play_mode = 0; - } else { - retval = 1; - } - break; - case G729: - if (j->dsp.low != 0x20) { - if (!j->flags.g729_loaded) { - retval = 1; - break; - } - switch (j->baseframe.low) { - case 0xA0: - j->play_frame_size = 10; - break; - case 0x50: - j->play_frame_size = 5; - break; - default: - j->play_frame_size = 15; - break; - } - j->play_mode = 0; - } else { - retval = 1; - } - break; - case G729B: - if (j->dsp.low != 0x20) { - if (!j->flags.g729_loaded) { - retval = 1; - break; - } - switch (j->baseframe.low) { - case 0xA0: - j->play_frame_size = 12; - break; - case 0x50: - j->play_frame_size = 6; - break; - default: - j->play_frame_size = 18; - break; - } - j->play_mode = 0; - } else { - retval = 1; - } - break; - case ULAW: - switch (j->baseframe.low) { - case 0xA0: - j->play_frame_size = 80; - break; - case 0x50: - j->play_frame_size = 40; - break; - default: - j->play_frame_size = 120; - break; - } - j->play_mode = 2; - break; - case ALAW: - switch (j->baseframe.low) { - case 0xA0: - j->play_frame_size = 80; - break; - case 0x50: - j->play_frame_size = 40; - break; - default: - j->play_frame_size = 120; - break; - } - j->play_mode = 2; - break; - case LINEAR16: - switch (j->baseframe.low) { - case 0xA0: - j->play_frame_size = 160; - break; - case 0x50: - j->play_frame_size = 80; - break; - default: - j->play_frame_size = 240; - break; - } - j->play_mode = 6; - break; - case LINEAR8: - switch (j->baseframe.low) { - case 0xA0: - j->play_frame_size = 80; - break; - case 0x50: - j->play_frame_size = 40; - break; - default: - j->play_frame_size = 120; - break; - } - j->play_mode = 4; - break; - case WSS: - switch (j->baseframe.low) { - case 0xA0: - j->play_frame_size = 80; - break; - case 0x50: - j->play_frame_size = 40; - break; - default: - j->play_frame_size = 120; - break; - } - j->play_mode = 5; - break; - default: - kfree(j->write_buffer); - j->play_frame_size = 0; - j->play_mode = -1; - j->write_buffer = NULL; - j->write_buffer_size = 0; - retval = 1; - break; - } - return retval; -} - -static int ixj_play_start(IXJ *j) -{ - unsigned short cmd = 0x0000; - - if (j->write_buffer) { - ixj_play_stop(j); - } - - if(ixjdebug & 0x0002) - printk("IXJ %d Starting Play Codec %d at %ld\n", j->board, j->play_codec, jiffies); - - j->flags.playing = 1; - ixj_WriteDSPCommand(0x0FE0, j); /* Put the DSP in full power mode. */ - - j->flags.play_first_frame = 1; - j->drybuffer = 0; - - if (!j->play_mode) { - switch (j->play_codec) { - case G723_63: - cmd = 0x5231; - break; - case G723_53: - cmd = 0x5232; - break; - case TS85: - cmd = 0x5230; /* TrueSpeech 8.5 */ - - break; - case TS48: - cmd = 0x5233; /* TrueSpeech 4.8 */ - - break; - case TS41: - cmd = 0x5234; /* TrueSpeech 4.1 */ - - break; - case G728: - cmd = 0x5235; - break; - case G729: - case G729B: - cmd = 0x5236; - break; - default: - return 1; - } - if (ixj_WriteDSPCommand(cmd, j)) - return -1; - } - j->write_buffer = kmalloc(j->play_frame_size * 2, GFP_ATOMIC); - if (!j->write_buffer) { - printk("Write buffer allocation for ixj board %d failed!\n", j->board); - return -ENOMEM; - } -/* j->write_buffers_empty = 2; */ - j->write_buffers_empty = 1; - j->write_buffer_size = j->play_frame_size * 2; - j->write_buffer_end = j->write_buffer + j->play_frame_size * 2; - j->write_buffer_rp = j->write_buffer_wp = j->write_buffer; - - if (ixj_WriteDSPCommand(0x5202, j)) /* Set Poll sync mode */ - - return -1; - - switch (j->play_mode) { - case 0: - cmd = 0x2C03; - break; - case 2: - if (j->ver.low == 0x12) { - cmd = 0x2C23; - } else { - cmd = 0x2C21; - } - break; - case 4: - if (j->ver.low == 0x12) { - cmd = 0x2C43; - } else { - cmd = 0x2C41; - } - break; - case 5: - if (j->ver.low == 0x12) { - cmd = 0x2C53; - } else { - cmd = 0x2C51; - } - break; - case 6: - if (j->ver.low == 0x12) { - cmd = 0x2C63; - } else { - cmd = 0x2C61; - } - break; - } - if (ixj_WriteDSPCommand(cmd, j)) - return -1; - - if (ixj_WriteDSPCommand(0x2000, j)) /* Playback C2 */ - return -1; - - if (ixj_WriteDSPCommand(0x2000 + j->play_frame_size, j)) /* Playback C3 */ - return -1; - - if (j->flags.recording) { - ixj_aec_start(j, j->aec_level); - } - - return 0; -} - -static void ixj_play_stop(IXJ *j) -{ - if (ixjdebug & 0x0002) - printk("IXJ %d Stopping Play Codec %d at %ld\n", j->board, j->play_codec, jiffies); - - kfree(j->write_buffer); - j->write_buffer = NULL; - j->write_buffer_size = 0; - if (j->play_mode > -1) { - ixj_WriteDSPCommand(0x5221, j); /* Stop playback and flush buffers. 8022 reference page 9-40 */ - - j->play_mode = -1; - } - j->flags.playing = 0; -} - -static inline int get_play_level(IXJ *j) -{ - int retval; - - ixj_WriteDSPCommand(0xCF8F, j); /* 8022 Reference page 9-38 */ - return j->ssr.high << 8 | j->ssr.low; - retval = j->ssr.high << 8 | j->ssr.low; - retval = (retval * 256) / 240; - return retval; -} - -static unsigned int ixj_poll(struct file *file_p, poll_table * wait) -{ - unsigned int mask = 0; - - IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode)); - - poll_wait(file_p, &(j->poll_q), wait); - if (j->read_buffer_ready > 0) - mask |= POLLIN | POLLRDNORM; /* readable */ - if (j->write_buffers_empty > 0) - mask |= POLLOUT | POLLWRNORM; /* writable */ - if (j->ex.bytes) - mask |= POLLPRI; - return mask; -} - -static int ixj_play_tone(IXJ *j, char tone) -{ - if (!j->tone_state) { - if(ixjdebug & 0x0002) { - printk("IXJ %d starting tone %d at %ld\n", j->board, tone, jiffies); - } - if (j->dsp.low == 0x20) { - idle(j); - } - j->tone_start_jif = jiffies; - - j->tone_state = 1; - } - - j->tone_index = tone; - if (ixj_WriteDSPCommand(0x6000 + j->tone_index, j)) - return -1; - - return 0; -} - -static int ixj_set_tone_on(unsigned short arg, IXJ *j) -{ - j->tone_on_time = arg; - - if (ixj_WriteDSPCommand(0x6E04, j)) /* Set Tone On Period */ - - return -1; - - if (ixj_WriteDSPCommand(arg, j)) - return -1; - - return 0; -} - -static int SCI_WaitHighSCI(IXJ *j) -{ - int cnt; - - j->pld_scrr.byte = inb_p(j->XILINXbase); - if (!j->pld_scrr.bits.sci) { - for (cnt = 0; cnt < 10; cnt++) { - udelay(32); - j->pld_scrr.byte = inb_p(j->XILINXbase); - - if ((j->pld_scrr.bits.sci)) - return 1; - } - if (ixjdebug & 0x0001) - printk(KERN_INFO "SCI Wait High failed %x\n", j->pld_scrr.byte); - return 0; - } else - return 1; -} - -static int SCI_WaitLowSCI(IXJ *j) -{ - int cnt; - - j->pld_scrr.byte = inb_p(j->XILINXbase); - if (j->pld_scrr.bits.sci) { - for (cnt = 0; cnt < 10; cnt++) { - udelay(32); - j->pld_scrr.byte = inb_p(j->XILINXbase); - - if (!(j->pld_scrr.bits.sci)) - return 1; - } - if (ixjdebug & 0x0001) - printk(KERN_INFO "SCI Wait Low failed %x\n", j->pld_scrr.byte); - return 0; - } else - return 1; -} - -static int SCI_Control(IXJ *j, int control) -{ - switch (control) { - case SCI_End: - j->pld_scrw.bits.c0 = 0; /* Set PLD Serial control interface */ - - j->pld_scrw.bits.c1 = 0; /* to no selection */ - - break; - case SCI_Enable_DAA: - j->pld_scrw.bits.c0 = 1; /* Set PLD Serial control interface */ - - j->pld_scrw.bits.c1 = 0; /* to write to DAA */ - - break; - case SCI_Enable_Mixer: - j->pld_scrw.bits.c0 = 0; /* Set PLD Serial control interface */ - - j->pld_scrw.bits.c1 = 1; /* to write to mixer */ - - break; - case SCI_Enable_EEPROM: - j->pld_scrw.bits.c0 = 1; /* Set PLD Serial control interface */ - - j->pld_scrw.bits.c1 = 1; /* to write to EEPROM */ - - break; - default: - return 0; - break; - } - outb_p(j->pld_scrw.byte, j->XILINXbase); - - switch (control) { - case SCI_End: - return 1; - break; - case SCI_Enable_DAA: - case SCI_Enable_Mixer: - case SCI_Enable_EEPROM: - if (!SCI_WaitHighSCI(j)) - return 0; - break; - default: - return 0; - break; - } - return 1; -} - -static int SCI_Prepare(IXJ *j) -{ - if (!SCI_Control(j, SCI_End)) - return 0; - - if (!SCI_WaitLowSCI(j)) - return 0; - - return 1; -} - -static int ixj_get_mixer(long val, IXJ *j) -{ - int reg = (val & 0x1F00) >> 8; - return j->mix.vol[reg]; -} - -static int ixj_mixer(long val, IXJ *j) -{ - BYTES bytes; - - bytes.high = (val & 0x1F00) >> 8; - bytes.low = val & 0x00FF; - - /* save mixer value so we can get back later on */ - j->mix.vol[bytes.high] = bytes.low; - - outb_p(bytes.high & 0x1F, j->XILINXbase + 0x03); /* Load Mixer Address */ - - outb_p(bytes.low, j->XILINXbase + 0x02); /* Load Mixer Data */ - - SCI_Control(j, SCI_Enable_Mixer); - - SCI_Control(j, SCI_End); - - return 0; -} - -static int daa_load(BYTES * p_bytes, IXJ *j) -{ - outb_p(p_bytes->high, j->XILINXbase + 0x03); - outb_p(p_bytes->low, j->XILINXbase + 0x02); - if (!SCI_Control(j, SCI_Enable_DAA)) - return 0; - else - return 1; -} - -static int ixj_daa_cr4(IXJ *j, char reg) -{ - BYTES bytes; - - switch (j->daa_mode) { - case SOP_PU_SLEEP: - bytes.high = 0x14; - break; - case SOP_PU_RINGING: - bytes.high = 0x54; - break; - case SOP_PU_CONVERSATION: - bytes.high = 0x94; - break; - case SOP_PU_PULSEDIALING: - bytes.high = 0xD4; - break; - } - - j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = reg; - - switch (j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGX) { - case 0: - j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 0; - break; - case 1: - j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 2; - break; - case 2: - j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 1; - break; - case 3: - j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 3; - break; - } - - bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg; - - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Prepare(j)) - return 0; - - return 1; -} - -static char daa_int_read(IXJ *j) -{ - BYTES bytes; - - if (!SCI_Prepare(j)) - return 0; - - bytes.high = 0x38; - bytes.low = 0x00; - outb_p(bytes.high, j->XILINXbase + 0x03); - outb_p(bytes.low, j->XILINXbase + 0x02); - - if (!SCI_Control(j, SCI_Enable_DAA)) - return 0; - - bytes.high = inb_p(j->XILINXbase + 0x03); - bytes.low = inb_p(j->XILINXbase + 0x02); - if (bytes.low != ALISDAA_ID_BYTE) { - if (ixjdebug & 0x0001) - printk("Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low); - return 0; - } - if (!SCI_Control(j, SCI_Enable_DAA)) - return 0; - if (!SCI_Control(j, SCI_End)) - return 0; - - bytes.high = inb_p(j->XILINXbase + 0x03); - bytes.low = inb_p(j->XILINXbase + 0x02); - - j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg = bytes.high; - - return 1; -} - -static char daa_CR_read(IXJ *j, int cr) -{ - IXJ_WORD wdata; - BYTES bytes; - - if (!SCI_Prepare(j)) - return 0; - - switch (j->daa_mode) { - case SOP_PU_SLEEP: - bytes.high = 0x30 + cr; - break; - case SOP_PU_RINGING: - bytes.high = 0x70 + cr; - break; - case SOP_PU_CONVERSATION: - bytes.high = 0xB0 + cr; - break; - case SOP_PU_PULSEDIALING: - default: - bytes.high = 0xF0 + cr; - break; - } - - bytes.low = 0x00; - - outb_p(bytes.high, j->XILINXbase + 0x03); - outb_p(bytes.low, j->XILINXbase + 0x02); - - if (!SCI_Control(j, SCI_Enable_DAA)) - return 0; - - bytes.high = inb_p(j->XILINXbase + 0x03); - bytes.low = inb_p(j->XILINXbase + 0x02); - if (bytes.low != ALISDAA_ID_BYTE) { - if (ixjdebug & 0x0001) - printk("Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low); - return 0; - } - if (!SCI_Control(j, SCI_Enable_DAA)) - return 0; - if (!SCI_Control(j, SCI_End)) - return 0; - - wdata.word = inw_p(j->XILINXbase + 0x02); - - switch(cr){ - case 5: - j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg = wdata.bytes.high; - break; - case 4: - j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = wdata.bytes.high; - break; - case 3: - j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = wdata.bytes.high; - break; - case 2: - j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = wdata.bytes.high; - break; - case 1: - j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = wdata.bytes.high; - break; - case 0: - j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = wdata.bytes.high; - break; - default: - return 0; - } - return 1; -} - -static int ixj_daa_cid_reset(IXJ *j) -{ - int i; - BYTES bytes; - - if (ixjdebug & 0x0002) - printk("DAA Clearing CID ram\n"); - - if (!SCI_Prepare(j)) - return 0; - - bytes.high = 0x58; - bytes.low = 0x00; - outb_p(bytes.high, j->XILINXbase + 0x03); - outb_p(bytes.low, j->XILINXbase + 0x02); - - if (!SCI_Control(j, SCI_Enable_DAA)) - return 0; - - if (!SCI_WaitHighSCI(j)) - return 0; - - for (i = 0; i < ALISDAA_CALLERID_SIZE - 1; i += 2) { - bytes.high = bytes.low = 0x00; - outb_p(bytes.high, j->XILINXbase + 0x03); - - if (i < ALISDAA_CALLERID_SIZE - 1) - outb_p(bytes.low, j->XILINXbase + 0x02); - - if (!SCI_Control(j, SCI_Enable_DAA)) - return 0; - - if (!SCI_WaitHighSCI(j)) - return 0; - - } - - if (!SCI_Control(j, SCI_End)) - return 0; - - if (ixjdebug & 0x0002) - printk("DAA CID ram cleared\n"); - - return 1; -} - -static int ixj_daa_cid_read(IXJ *j) -{ - int i; - BYTES bytes; - char CID[ALISDAA_CALLERID_SIZE]; - bool mContinue; - char *pIn, *pOut; - - if (!SCI_Prepare(j)) - return 0; - - bytes.high = 0x78; - bytes.low = 0x00; - outb_p(bytes.high, j->XILINXbase + 0x03); - outb_p(bytes.low, j->XILINXbase + 0x02); - - if (!SCI_Control(j, SCI_Enable_DAA)) - return 0; - - if (!SCI_WaitHighSCI(j)) - return 0; - - bytes.high = inb_p(j->XILINXbase + 0x03); - bytes.low = inb_p(j->XILINXbase + 0x02); - if (bytes.low != ALISDAA_ID_BYTE) { - if (ixjdebug & 0x0001) - printk("DAA Get Version Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low); - return 0; - } - for (i = 0; i < ALISDAA_CALLERID_SIZE; i += 2) { - bytes.high = bytes.low = 0x00; - outb_p(bytes.high, j->XILINXbase + 0x03); - outb_p(bytes.low, j->XILINXbase + 0x02); - - if (!SCI_Control(j, SCI_Enable_DAA)) - return 0; - - if (!SCI_WaitHighSCI(j)) - return 0; - - CID[i + 0] = inb_p(j->XILINXbase + 0x03); - CID[i + 1] = inb_p(j->XILINXbase + 0x02); - } - - if (!SCI_Control(j, SCI_End)) - return 0; - - pIn = CID; - pOut = j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID; - mContinue = true; - while (mContinue) { - if ((pIn[1] & 0x03) == 0x01) { - pOut[0] = pIn[0]; - } - if ((pIn[2] & 0x0c) == 0x04) { - pOut[1] = ((pIn[2] & 0x03) << 6) | ((pIn[1] & 0xfc) >> 2); - } - if ((pIn[3] & 0x30) == 0x10) { - pOut[2] = ((pIn[3] & 0x0f) << 4) | ((pIn[2] & 0xf0) >> 4); - } - if ((pIn[4] & 0xc0) == 0x40) { - pOut[3] = ((pIn[4] & 0x3f) << 2) | ((pIn[3] & 0xc0) >> 6); - } else { - mContinue = false; - } - pIn += 5, pOut += 4; - } - memset(&j->cid, 0, sizeof(PHONE_CID)); - pOut = j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID; - pOut += 4; - strncpy(j->cid.month, pOut, 2); - pOut += 2; - strncpy(j->cid.day, pOut, 2); - pOut += 2; - strncpy(j->cid.hour, pOut, 2); - pOut += 2; - strncpy(j->cid.min, pOut, 2); - pOut += 3; - j->cid.numlen = *pOut; - pOut += 1; - strncpy(j->cid.number, pOut, j->cid.numlen); - pOut += j->cid.numlen + 1; - j->cid.namelen = *pOut; - pOut += 1; - strncpy(j->cid.name, pOut, j->cid.namelen); - - ixj_daa_cid_reset(j); - return 1; -} - -static char daa_get_version(IXJ *j) -{ - BYTES bytes; - - if (!SCI_Prepare(j)) - return 0; - - bytes.high = 0x35; - bytes.low = 0x00; - outb_p(bytes.high, j->XILINXbase + 0x03); - outb_p(bytes.low, j->XILINXbase + 0x02); - - if (!SCI_Control(j, SCI_Enable_DAA)) - return 0; - - bytes.high = inb_p(j->XILINXbase + 0x03); - bytes.low = inb_p(j->XILINXbase + 0x02); - if (bytes.low != ALISDAA_ID_BYTE) { - if (ixjdebug & 0x0001) - printk("DAA Get Version Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low); - return 0; - } - if (!SCI_Control(j, SCI_Enable_DAA)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - - bytes.high = inb_p(j->XILINXbase + 0x03); - bytes.low = inb_p(j->XILINXbase + 0x02); - if (ixjdebug & 0x0002) - printk("DAA CR5 Byte high = 0x%x low = 0x%x\n", bytes.high, bytes.low); - j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg = bytes.high; - return bytes.high; -} - -static int daa_set_mode(IXJ *j, int mode) -{ - /* NOTE: - The DAA *MUST* be in the conversation mode if the - PSTN line is to be seized (PSTN line off-hook). - Taking the PSTN line off-hook while the DAA is in - a mode other than conversation mode will cause a - hardware failure of the ALIS-A part. - - NOTE: - The DAA can only go to SLEEP, RINGING or PULSEDIALING modes - if the PSTN line is on-hook. Failure to have the PSTN line - in the on-hook state WILL CAUSE A HARDWARE FAILURE OF THE - ALIS-A part. - */ - - BYTES bytes; - - j->flags.pstn_rmr = 0; - - if (!SCI_Prepare(j)) - return 0; - - switch (mode) { - case SOP_PU_RESET: - j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ - - outb_p(j->pld_scrw.byte, j->XILINXbase); - j->pld_slicw.bits.rly2 = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - bytes.high = 0x10; - bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg; - daa_load(&bytes, j); - if (!SCI_Prepare(j)) - return 0; - - j->daa_mode = SOP_PU_SLEEP; - break; - case SOP_PU_SLEEP: - if(j->daa_mode == SOP_PU_SLEEP) - { - break; - } - if (ixjdebug & 0x0008) - printk(KERN_INFO "phone DAA: SOP_PU_SLEEP at %ld\n", jiffies); -/* if(j->daa_mode == SOP_PU_CONVERSATION) */ - { - j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ - - outb_p(j->pld_scrw.byte, j->XILINXbase); - j->pld_slicw.bits.rly2 = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - bytes.high = 0x10; - bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg; - daa_load(&bytes, j); - if (!SCI_Prepare(j)) - return 0; - } - j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ - - outb_p(j->pld_scrw.byte, j->XILINXbase); - j->pld_slicw.bits.rly2 = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - bytes.high = 0x10; - bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg; - daa_load(&bytes, j); - if (!SCI_Prepare(j)) - return 0; - - j->daa_mode = SOP_PU_SLEEP; - j->flags.pstn_ringing = 0; - j->ex.bits.pstn_ring = 0; - j->pstn_sleeptil = jiffies + (hertz / 4); - wake_up_interruptible(&j->read_q); /* Wake any blocked readers */ - wake_up_interruptible(&j->write_q); /* Wake any blocked writers */ - wake_up_interruptible(&j->poll_q); /* Wake any blocked selects */ - break; - case SOP_PU_RINGING: - if (ixjdebug & 0x0008) - printk(KERN_INFO "phone DAA: SOP_PU_RINGING at %ld\n", jiffies); - j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ - - outb_p(j->pld_scrw.byte, j->XILINXbase); - j->pld_slicw.bits.rly2 = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - bytes.high = 0x50; - bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg; - daa_load(&bytes, j); - if (!SCI_Prepare(j)) - return 0; - j->daa_mode = SOP_PU_RINGING; - break; - case SOP_PU_CONVERSATION: - if (ixjdebug & 0x0008) - printk(KERN_INFO "phone DAA: SOP_PU_CONVERSATION at %ld\n", jiffies); - bytes.high = 0x90; - bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg; - daa_load(&bytes, j); - if (!SCI_Prepare(j)) - return 0; - j->pld_slicw.bits.rly2 = 1; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - j->pld_scrw.bits.daafsyncen = 1; /* Turn on DAA Frame Sync */ - - outb_p(j->pld_scrw.byte, j->XILINXbase); - j->daa_mode = SOP_PU_CONVERSATION; - j->flags.pstn_ringing = 0; - j->ex.bits.pstn_ring = 0; - j->pstn_sleeptil = jiffies; - j->pstn_ring_start = j->pstn_ring_stop = j->pstn_ring_int = 0; - break; - case SOP_PU_PULSEDIALING: - if (ixjdebug & 0x0008) - printk(KERN_INFO "phone DAA: SOP_PU_PULSEDIALING at %ld\n", jiffies); - j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ - - outb_p(j->pld_scrw.byte, j->XILINXbase); - j->pld_slicw.bits.rly2 = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - bytes.high = 0xD0; - bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg; - daa_load(&bytes, j); - if (!SCI_Prepare(j)) - return 0; - j->daa_mode = SOP_PU_PULSEDIALING; - break; - default: - break; - } - return 1; -} - -static int ixj_daa_write(IXJ *j) -{ - BYTES bytes; - - j->flags.pstncheck = 1; - - daa_set_mode(j, SOP_PU_SLEEP); - - if (!SCI_Prepare(j)) - return 0; - - outb_p(j->pld_scrw.byte, j->XILINXbase); - - bytes.high = 0x14; - bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg; - bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg; - bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Prepare(j)) - return 0; - - bytes.high = 0x1F; - bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.XOP_xr6_W.reg; - bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg; - bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg; - bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.XOP_xr0_W.reg; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Prepare(j)) - return 0; - - bytes.high = 0x00; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x01; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x02; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x03; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x04; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x05; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x06; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x07; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x08; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x09; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x0A; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x0B; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x0C; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x0D; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x0E; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x0F; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - udelay(32); - j->pld_scrr.byte = inb_p(j->XILINXbase); - if (!SCI_Control(j, SCI_End)) - return 0; - - outb_p(j->pld_scrw.byte, j->XILINXbase); - - if (ixjdebug & 0x0002) - printk("DAA Coefficients Loaded\n"); - - j->flags.pstncheck = 0; - return 1; -} - -static int ixj_set_tone_off(unsigned short arg, IXJ *j) -{ - j->tone_off_time = arg; - if (ixj_WriteDSPCommand(0x6E05, j)) /* Set Tone Off Period */ - - return -1; - if (ixj_WriteDSPCommand(arg, j)) - return -1; - return 0; -} - -static int ixj_get_tone_on(IXJ *j) -{ - if (ixj_WriteDSPCommand(0x6E06, j)) /* Get Tone On Period */ - - return -1; - return 0; -} - -static int ixj_get_tone_off(IXJ *j) -{ - if (ixj_WriteDSPCommand(0x6E07, j)) /* Get Tone Off Period */ - - return -1; - return 0; -} - -static void ixj_busytone(IXJ *j) -{ - j->flags.ringback = 0; - j->flags.dialtone = 0; - j->flags.busytone = 1; - ixj_set_tone_on(0x07D0, j); - ixj_set_tone_off(0x07D0, j); - ixj_play_tone(j, 27); -} - -static void ixj_dialtone(IXJ *j) -{ - j->flags.ringback = 0; - j->flags.dialtone = 1; - j->flags.busytone = 0; - if (j->dsp.low == 0x20) { - return; - } else { - ixj_set_tone_on(0xFFFF, j); - ixj_set_tone_off(0x0000, j); - ixj_play_tone(j, 25); - } -} - -static void ixj_cpt_stop(IXJ *j) -{ - if(j->tone_state || j->tone_cadence_state) - { - j->flags.dialtone = 0; - j->flags.busytone = 0; - j->flags.ringback = 0; - ixj_set_tone_on(0x0001, j); - ixj_set_tone_off(0x0000, j); - ixj_play_tone(j, 0); - j->tone_state = j->tone_cadence_state = 0; - if (j->cadence_t) { - kfree(j->cadence_t->ce); - kfree(j->cadence_t); - j->cadence_t = NULL; - } - } - if (j->play_mode == -1 && j->rec_mode == -1) - idle(j); - if (j->play_mode != -1 && j->dsp.low == 0x20) - ixj_play_start(j); - if (j->rec_mode != -1 && j->dsp.low == 0x20) - ixj_record_start(j); -} - -static void ixj_ringback(IXJ *j) -{ - j->flags.busytone = 0; - j->flags.dialtone = 0; - j->flags.ringback = 1; - ixj_set_tone_on(0x0FA0, j); - ixj_set_tone_off(0x2EE0, j); - ixj_play_tone(j, 26); -} - -static void ixj_testram(IXJ *j) -{ - ixj_WriteDSPCommand(0x3001, j); /* Test External SRAM */ -} - -static int ixj_build_cadence(IXJ *j, IXJ_CADENCE __user * cp) -{ - ixj_cadence *lcp; - IXJ_CADENCE_ELEMENT __user *cep; - IXJ_CADENCE_ELEMENT *lcep; - IXJ_TONE ti; - int err; - - lcp = kmalloc(sizeof(ixj_cadence), GFP_KERNEL); - if (lcp == NULL) - return -ENOMEM; - - err = -EFAULT; - if (copy_from_user(&lcp->elements_used, - &cp->elements_used, sizeof(int))) - goto out; - if (copy_from_user(&lcp->termination, - &cp->termination, sizeof(IXJ_CADENCE_TERM))) - goto out; - if (get_user(cep, &cp->ce)) - goto out; - - err = -EINVAL; - if ((unsigned)lcp->elements_used >= ~0U/sizeof(IXJ_CADENCE_ELEMENT)) - goto out; - - err = -ENOMEM; - lcep = kmalloc(sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used, GFP_KERNEL); - if (!lcep) - goto out; - - err = -EFAULT; - if (copy_from_user(lcep, cep, sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used)) - goto out1; - - if (j->cadence_t) { - kfree(j->cadence_t->ce); - kfree(j->cadence_t); - } - lcp->ce = (void *) lcep; - j->cadence_t = lcp; - j->tone_cadence_state = 0; - ixj_set_tone_on(lcp->ce[0].tone_on_time, j); - ixj_set_tone_off(lcp->ce[0].tone_off_time, j); - if (j->cadence_t->ce[j->tone_cadence_state].freq0) { - ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index; - ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0; - ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0; - ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1; - ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1; - ixj_init_tone(j, &ti); - } - ixj_play_tone(j, lcp->ce[0].index); - return 1; -out1: - kfree(lcep); -out: - kfree(lcp); - return err; -} - -static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE __user * cp) -{ - IXJ_FILTER_CADENCE *lcp; - lcp = memdup_user(cp, sizeof(IXJ_FILTER_CADENCE)); - if (IS_ERR(lcp)) { - if(ixjdebug & 0x0001) { - printk(KERN_INFO "Could not allocate memory for cadence or could not copy cadence to kernel\n"); - } - return PTR_ERR(lcp); - } - if (lcp->filter > 5) { - if(ixjdebug & 0x0001) { - printk(KERN_INFO "Cadence out of range\n"); - } - kfree(lcp); - return -1; - } - j->cadence_f[lcp->filter].state = 0; - j->cadence_f[lcp->filter].enable = lcp->enable; - j->filter_en[lcp->filter] = j->cadence_f[lcp->filter].en_filter = lcp->en_filter; - j->cadence_f[lcp->filter].on1 = lcp->on1; - j->cadence_f[lcp->filter].on1min = 0; - j->cadence_f[lcp->filter].on1max = 0; - j->cadence_f[lcp->filter].off1 = lcp->off1; - j->cadence_f[lcp->filter].off1min = 0; - j->cadence_f[lcp->filter].off1max = 0; - j->cadence_f[lcp->filter].on2 = lcp->on2; - j->cadence_f[lcp->filter].on2min = 0; - j->cadence_f[lcp->filter].on2max = 0; - j->cadence_f[lcp->filter].off2 = lcp->off2; - j->cadence_f[lcp->filter].off2min = 0; - j->cadence_f[lcp->filter].off2max = 0; - j->cadence_f[lcp->filter].on3 = lcp->on3; - j->cadence_f[lcp->filter].on3min = 0; - j->cadence_f[lcp->filter].on3max = 0; - j->cadence_f[lcp->filter].off3 = lcp->off3; - j->cadence_f[lcp->filter].off3min = 0; - j->cadence_f[lcp->filter].off3max = 0; - if(ixjdebug & 0x0002) { - printk(KERN_INFO "Cadence %d loaded\n", lcp->filter); - } - kfree(lcp); - return 0; -} - -static void add_caps(IXJ *j) -{ - j->caps = 0; - j->caplist[j->caps].cap = PHONE_VENDOR_QUICKNET; - strcpy(j->caplist[j->caps].desc, "Quicknet Technologies, Inc. (www.quicknet.net)"); - j->caplist[j->caps].captype = vendor; - j->caplist[j->caps].handle = j->caps++; - j->caplist[j->caps].captype = device; - switch (j->cardtype) { - case QTI_PHONEJACK: - strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneJACK"); - break; - case QTI_LINEJACK: - strcpy(j->caplist[j->caps].desc, "Quicknet Internet LineJACK"); - break; - case QTI_PHONEJACK_LITE: - strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneJACK Lite"); - break; - case QTI_PHONEJACK_PCI: - strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneJACK PCI"); - break; - case QTI_PHONECARD: - strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneCARD"); - break; - } - j->caplist[j->caps].cap = j->cardtype; - j->caplist[j->caps].handle = j->caps++; - strcpy(j->caplist[j->caps].desc, "POTS"); - j->caplist[j->caps].captype = port; - j->caplist[j->caps].cap = pots; - j->caplist[j->caps].handle = j->caps++; - - /* add devices that can do speaker/mic */ - switch (j->cardtype) { - case QTI_PHONEJACK: - case QTI_LINEJACK: - case QTI_PHONEJACK_PCI: - case QTI_PHONECARD: - strcpy(j->caplist[j->caps].desc, "SPEAKER"); - j->caplist[j->caps].captype = port; - j->caplist[j->caps].cap = speaker; - j->caplist[j->caps].handle = j->caps++; - default: - break; - } - - /* add devices that can do handset */ - switch (j->cardtype) { - case QTI_PHONEJACK: - strcpy(j->caplist[j->caps].desc, "HANDSET"); - j->caplist[j->caps].captype = port; - j->caplist[j->caps].cap = handset; - j->caplist[j->caps].handle = j->caps++; - break; - default: - break; - } - - /* add devices that can do PSTN */ - switch (j->cardtype) { - case QTI_LINEJACK: - strcpy(j->caplist[j->caps].desc, "PSTN"); - j->caplist[j->caps].captype = port; - j->caplist[j->caps].cap = pstn; - j->caplist[j->caps].handle = j->caps++; - break; - default: - break; - } - - /* add codecs - all cards can do uLaw, linear 8/16, and Windows sound system */ - strcpy(j->caplist[j->caps].desc, "ULAW"); - j->caplist[j->caps].captype = codec; - j->caplist[j->caps].cap = ULAW; - j->caplist[j->caps].handle = j->caps++; - - strcpy(j->caplist[j->caps].desc, "LINEAR 16 bit"); - j->caplist[j->caps].captype = codec; - j->caplist[j->caps].cap = LINEAR16; - j->caplist[j->caps].handle = j->caps++; - - strcpy(j->caplist[j->caps].desc, "LINEAR 8 bit"); - j->caplist[j->caps].captype = codec; - j->caplist[j->caps].cap = LINEAR8; - j->caplist[j->caps].handle = j->caps++; - - strcpy(j->caplist[j->caps].desc, "Windows Sound System"); - j->caplist[j->caps].captype = codec; - j->caplist[j->caps].cap = WSS; - j->caplist[j->caps].handle = j->caps++; - - /* software ALAW codec, made from ULAW */ - strcpy(j->caplist[j->caps].desc, "ALAW"); - j->caplist[j->caps].captype = codec; - j->caplist[j->caps].cap = ALAW; - j->caplist[j->caps].handle = j->caps++; - - /* version 12 of the 8020 does the following codecs in a broken way */ - if (j->dsp.low != 0x20 || j->ver.low != 0x12) { - strcpy(j->caplist[j->caps].desc, "G.723.1 6.3kbps"); - j->caplist[j->caps].captype = codec; - j->caplist[j->caps].cap = G723_63; - j->caplist[j->caps].handle = j->caps++; - - strcpy(j->caplist[j->caps].desc, "G.723.1 5.3kbps"); - j->caplist[j->caps].captype = codec; - j->caplist[j->caps].cap = G723_53; - j->caplist[j->caps].handle = j->caps++; - - strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.8kbps"); - j->caplist[j->caps].captype = codec; - j->caplist[j->caps].cap = TS48; - j->caplist[j->caps].handle = j->caps++; - - strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.1kbps"); - j->caplist[j->caps].captype = codec; - j->caplist[j->caps].cap = TS41; - j->caplist[j->caps].handle = j->caps++; - } - - /* 8020 chips can do TS8.5 native, and 8021/8022 can load it */ - if (j->dsp.low == 0x20 || j->flags.ts85_loaded) { - strcpy(j->caplist[j->caps].desc, "TrueSpeech 8.5kbps"); - j->caplist[j->caps].captype = codec; - j->caplist[j->caps].cap = TS85; - j->caplist[j->caps].handle = j->caps++; - } - - /* 8021 chips can do G728 */ - if (j->dsp.low == 0x21) { - strcpy(j->caplist[j->caps].desc, "G.728 16kbps"); - j->caplist[j->caps].captype = codec; - j->caplist[j->caps].cap = G728; - j->caplist[j->caps].handle = j->caps++; - } - - /* 8021/8022 chips can do G729 if loaded */ - if (j->dsp.low != 0x20 && j->flags.g729_loaded) { - strcpy(j->caplist[j->caps].desc, "G.729A 8kbps"); - j->caplist[j->caps].captype = codec; - j->caplist[j->caps].cap = G729; - j->caplist[j->caps].handle = j->caps++; - } - if (j->dsp.low != 0x20 && j->flags.g729_loaded) { - strcpy(j->caplist[j->caps].desc, "G.729B 8kbps"); - j->caplist[j->caps].captype = codec; - j->caplist[j->caps].cap = G729B; - j->caplist[j->caps].handle = j->caps++; - } -} - -static int capabilities_check(IXJ *j, struct phone_capability *pcreq) -{ - int cnt; - int retval = 0; - for (cnt = 0; cnt < j->caps; cnt++) { - if (pcreq->captype == j->caplist[cnt].captype - && pcreq->cap == j->caplist[cnt].cap) { - retval = 1; - break; - } - } - return retval; -} - -static long do_ixj_ioctl(struct file *file_p, unsigned int cmd, unsigned long arg) -{ - IXJ_TONE ti; - IXJ_FILTER jf; - IXJ_FILTER_RAW jfr; - void __user *argp = (void __user *)arg; - struct inode *inode = file_p->f_path.dentry->d_inode; - unsigned int minor = iminor(inode); - unsigned int raise, mant; - int board = NUM(inode); - - IXJ *j = get_ixj(NUM(inode)); - - int retval = 0; - - /* - * Set up locks to ensure that only one process is talking to the DSP at a time. - * This is necessary to keep the DSP from locking up. - */ - while(test_and_set_bit(board, (void *)&j->busyflags) != 0) - schedule_timeout_interruptible(1); - if (ixjdebug & 0x0040) - printk("phone%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg); - if (minor >= IXJMAX) { - clear_bit(board, &j->busyflags); - return -ENODEV; - } - /* - * Check ioctls only root can use. - */ - if (!capable(CAP_SYS_ADMIN)) { - switch (cmd) { - case IXJCTL_TESTRAM: - case IXJCTL_HZ: - retval = -EPERM; - } - } - switch (cmd) { - case IXJCTL_TESTRAM: - ixj_testram(j); - retval = (j->ssr.high << 8) + j->ssr.low; - break; - case IXJCTL_CARDTYPE: - retval = j->cardtype; - break; - case IXJCTL_SERIAL: - retval = j->serial; - break; - case IXJCTL_VERSION: - { - char arg_str[100]; - snprintf(arg_str, sizeof(arg_str), - "\nDriver version %i.%i.%i", IXJ_VER_MAJOR, - IXJ_VER_MINOR, IXJ_BLD_VER); - if (copy_to_user(argp, arg_str, strlen(arg_str))) - retval = -EFAULT; - } - break; - case PHONE_RING_CADENCE: - j->ring_cadence = arg; - break; - case IXJCTL_CIDCW: - if(arg) { - if (copy_from_user(&j->cid_send, argp, sizeof(PHONE_CID))) { - retval = -EFAULT; - break; - } - } else { - memset(&j->cid_send, 0, sizeof(PHONE_CID)); - } - ixj_write_cidcw(j); - break; - /* Binary compatbility */ - case OLD_PHONE_RING_START: - arg = 0; - /* Fall through */ - case PHONE_RING_START: - if(arg) { - if (copy_from_user(&j->cid_send, argp, sizeof(PHONE_CID))) { - retval = -EFAULT; - break; - } - ixj_write_cid(j); - } else { - memset(&j->cid_send, 0, sizeof(PHONE_CID)); - } - ixj_ring_start(j); - break; - case PHONE_RING_STOP: - j->flags.cringing = 0; - if(j->cadence_f[5].enable) { - j->cadence_f[5].state = 0; - } - ixj_ring_off(j); - break; - case PHONE_RING: - retval = ixj_ring(j); - break; - case PHONE_EXCEPTION: - retval = j->ex.bytes; - if(j->ex.bits.flash) { - j->flash_end = 0; - j->ex.bits.flash = 0; - } - j->ex.bits.pstn_ring = 0; - j->ex.bits.caller_id = 0; - j->ex.bits.pstn_wink = 0; - j->ex.bits.f0 = 0; - j->ex.bits.f1 = 0; - j->ex.bits.f2 = 0; - j->ex.bits.f3 = 0; - j->ex.bits.fc0 = 0; - j->ex.bits.fc1 = 0; - j->ex.bits.fc2 = 0; - j->ex.bits.fc3 = 0; - j->ex.bits.reserved = 0; - break; - case PHONE_HOOKSTATE: - j->ex.bits.hookstate = 0; - retval = j->hookstate; //j->r_hook; - break; - case IXJCTL_SET_LED: - LED_SetState(arg, j); - break; - case PHONE_FRAME: - retval = set_base_frame(j, arg); - break; - case PHONE_REC_CODEC: - retval = set_rec_codec(j, arg); - break; - case PHONE_VAD: - ixj_vad(j, arg); - break; - case PHONE_REC_START: - ixj_record_start(j); - break; - case PHONE_REC_STOP: - ixj_record_stop(j); - break; - case PHONE_REC_DEPTH: - set_rec_depth(j, arg); - break; - case PHONE_REC_VOLUME: - if(arg == -1) { - retval = get_rec_volume(j); - } - else { - set_rec_volume(j, arg); - retval = arg; - } - break; - case PHONE_REC_VOLUME_LINEAR: - if(arg == -1) { - retval = get_rec_volume_linear(j); - } - else { - set_rec_volume_linear(j, arg); - retval = arg; - } - break; - case IXJCTL_DTMF_PRESCALE: - if(arg == -1) { - retval = get_dtmf_prescale(j); - } - else { - set_dtmf_prescale(j, arg); - retval = arg; - } - break; - case PHONE_REC_LEVEL: - retval = get_rec_level(j); - break; - case IXJCTL_SC_RXG: - retval = ixj_siadc(j, arg); - break; - case IXJCTL_SC_TXG: - retval = ixj_sidac(j, arg); - break; - case IXJCTL_AEC_START: - ixj_aec_start(j, arg); - break; - case IXJCTL_AEC_STOP: - aec_stop(j); - break; - case IXJCTL_AEC_GET_LEVEL: - retval = j->aec_level; - break; - case PHONE_PLAY_CODEC: - retval = set_play_codec(j, arg); - break; - case PHONE_PLAY_START: - retval = ixj_play_start(j); - break; - case PHONE_PLAY_STOP: - ixj_play_stop(j); - break; - case PHONE_PLAY_DEPTH: - set_play_depth(j, arg); - break; - case PHONE_PLAY_VOLUME: - if(arg == -1) { - retval = get_play_volume(j); - } - else { - set_play_volume(j, arg); - retval = arg; - } - break; - case PHONE_PLAY_VOLUME_LINEAR: - if(arg == -1) { - retval = get_play_volume_linear(j); - } - else { - set_play_volume_linear(j, arg); - retval = arg; - } - break; - case PHONE_PLAY_LEVEL: - retval = get_play_level(j); - break; - case IXJCTL_DSP_TYPE: - retval = (j->dsp.high << 8) + j->dsp.low; - break; - case IXJCTL_DSP_VERSION: - retval = (j->ver.high << 8) + j->ver.low; - break; - case IXJCTL_HZ: - hertz = arg; - break; - case IXJCTL_RATE: - if (arg > hertz) - retval = -1; - else - samplerate = arg; - break; - case IXJCTL_DRYBUFFER_READ: - put_user(j->drybuffer, (unsigned long __user *) argp); - break; - case IXJCTL_DRYBUFFER_CLEAR: - j->drybuffer = 0; - break; - case IXJCTL_FRAMES_READ: - put_user(j->framesread, (unsigned long __user *) argp); - break; - case IXJCTL_FRAMES_WRITTEN: - put_user(j->frameswritten, (unsigned long __user *) argp); - break; - case IXJCTL_READ_WAIT: - put_user(j->read_wait, (unsigned long __user *) argp); - break; - case IXJCTL_WRITE_WAIT: - put_user(j->write_wait, (unsigned long __user *) argp); - break; - case PHONE_MAXRINGS: - j->maxrings = arg; - break; - case PHONE_SET_TONE_ON_TIME: - ixj_set_tone_on(arg, j); - break; - case PHONE_SET_TONE_OFF_TIME: - ixj_set_tone_off(arg, j); - break; - case PHONE_GET_TONE_ON_TIME: - if (ixj_get_tone_on(j)) { - retval = -1; - } else { - retval = (j->ssr.high << 8) + j->ssr.low; - } - break; - case PHONE_GET_TONE_OFF_TIME: - if (ixj_get_tone_off(j)) { - retval = -1; - } else { - retval = (j->ssr.high << 8) + j->ssr.low; - } - break; - case PHONE_PLAY_TONE: - if (!j->tone_state) - retval = ixj_play_tone(j, arg); - else - retval = -1; - break; - case PHONE_GET_TONE_STATE: - retval = j->tone_state; - break; - case PHONE_DTMF_READY: - retval = j->ex.bits.dtmf_ready; - break; - case PHONE_GET_DTMF: - if (ixj_hookstate(j)) { - if (j->dtmf_rp != j->dtmf_wp) { - retval = j->dtmfbuffer[j->dtmf_rp]; - j->dtmf_rp++; - if (j->dtmf_rp == 79) - j->dtmf_rp = 0; - if (j->dtmf_rp == j->dtmf_wp) { - j->ex.bits.dtmf_ready = j->dtmf_rp = j->dtmf_wp = 0; - } - } - } - break; - case PHONE_GET_DTMF_ASCII: - if (ixj_hookstate(j)) { - if (j->dtmf_rp != j->dtmf_wp) { - switch (j->dtmfbuffer[j->dtmf_rp]) { - case 10: - retval = 42; /* '*'; */ - - break; - case 11: - retval = 48; /*'0'; */ - - break; - case 12: - retval = 35; /*'#'; */ - - break; - case 28: - retval = 65; /*'A'; */ - - break; - case 29: - retval = 66; /*'B'; */ - - break; - case 30: - retval = 67; /*'C'; */ - - break; - case 31: - retval = 68; /*'D'; */ - - break; - default: - retval = 48 + j->dtmfbuffer[j->dtmf_rp]; - break; - } - j->dtmf_rp++; - if (j->dtmf_rp == 79) - j->dtmf_rp = 0; - if(j->dtmf_rp == j->dtmf_wp) - { - j->ex.bits.dtmf_ready = j->dtmf_rp = j->dtmf_wp = 0; - } - } - } - break; - case PHONE_DTMF_OOB: - j->flags.dtmf_oob = arg; - break; - case PHONE_DIALTONE: - ixj_dialtone(j); - break; - case PHONE_BUSY: - ixj_busytone(j); - break; - case PHONE_RINGBACK: - ixj_ringback(j); - break; - case PHONE_WINK: - if(j->cardtype == QTI_PHONEJACK) - retval = -1; - else - retval = ixj_wink(j); - break; - case PHONE_CPT_STOP: - ixj_cpt_stop(j); - break; - case PHONE_QUERY_CODEC: - { - struct phone_codec_data pd; - int val; - int proto_size[] = { - -1, - 12, 10, 16, 9, 8, 48, 5, - 40, 40, 80, 40, 40, 6 - }; - if(copy_from_user(&pd, argp, sizeof(pd))) { - retval = -EFAULT; - break; - } - if(pd.type<1 || pd.type>13) { - retval = -EPROTONOSUPPORT; - break; - } - if(pd.typebaseframe.low) - { - case 0xA0:val=2*proto_size[pd.type];break; - case 0x50:val=proto_size[pd.type];break; - default:val=proto_size[pd.type]*3;break; - } - pd.buf_min=pd.buf_max=pd.buf_opt=val; - if(copy_to_user(argp, &pd, sizeof(pd))) - retval = -EFAULT; - break; - } - case IXJCTL_DSP_IDLE: - idle(j); - break; - case IXJCTL_MIXER: - if ((arg & 0xff) == 0xff) - retval = ixj_get_mixer(arg, j); - else - ixj_mixer(arg, j); - break; - case IXJCTL_DAA_COEFF_SET: - switch (arg) { - case DAA_US: - DAA_Coeff_US(j); - retval = ixj_daa_write(j); - break; - case DAA_UK: - DAA_Coeff_UK(j); - retval = ixj_daa_write(j); - break; - case DAA_FRANCE: - DAA_Coeff_France(j); - retval = ixj_daa_write(j); - break; - case DAA_GERMANY: - DAA_Coeff_Germany(j); - retval = ixj_daa_write(j); - break; - case DAA_AUSTRALIA: - DAA_Coeff_Australia(j); - retval = ixj_daa_write(j); - break; - case DAA_JAPAN: - DAA_Coeff_Japan(j); - retval = ixj_daa_write(j); - break; - default: - retval = 1; - break; - } - break; - case IXJCTL_DAA_AGAIN: - ixj_daa_cr4(j, arg | 0x02); - break; - case IXJCTL_PSTN_LINETEST: - retval = ixj_linetest(j); - break; - case IXJCTL_VMWI: - ixj_write_vmwi(j, arg); - break; - case IXJCTL_CID: - if (copy_to_user(argp, &j->cid, sizeof(PHONE_CID))) - retval = -EFAULT; - j->ex.bits.caller_id = 0; - break; - case IXJCTL_WINK_DURATION: - j->winktime = arg; - break; - case IXJCTL_PORT: - if (arg) - retval = ixj_set_port(j, arg); - else - retval = j->port; - break; - case IXJCTL_POTS_PSTN: - retval = ixj_set_pots(j, arg); - break; - case PHONE_CAPABILITIES: - add_caps(j); - retval = j->caps; - break; - case PHONE_CAPABILITIES_LIST: - add_caps(j); - if (copy_to_user(argp, j->caplist, sizeof(struct phone_capability) * j->caps)) - retval = -EFAULT; - break; - case PHONE_CAPABILITIES_CHECK: - { - struct phone_capability cap; - if (copy_from_user(&cap, argp, sizeof(cap))) - retval = -EFAULT; - else { - add_caps(j); - retval = capabilities_check(j, &cap); - } - } - break; - case PHONE_PSTN_SET_STATE: - daa_set_mode(j, arg); - break; - case PHONE_PSTN_GET_STATE: - retval = j->daa_mode; - j->ex.bits.pstn_ring = 0; - break; - case IXJCTL_SET_FILTER: - if (copy_from_user(&jf, argp, sizeof(jf))) - retval = -EFAULT; - else - retval = ixj_init_filter(j, &jf); - break; - case IXJCTL_SET_FILTER_RAW: - if (copy_from_user(&jfr, argp, sizeof(jfr))) - retval = -EFAULT; - else - retval = ixj_init_filter_raw(j, &jfr); - break; - case IXJCTL_GET_FILTER_HIST: - if(arg<0||arg>3) - retval = -EINVAL; - else - retval = j->filter_hist[arg]; - break; - case IXJCTL_INIT_TONE: - if (copy_from_user(&ti, argp, sizeof(ti))) - retval = -EFAULT; - else - retval = ixj_init_tone(j, &ti); - break; - case IXJCTL_TONE_CADENCE: - retval = ixj_build_cadence(j, argp); - break; - case IXJCTL_FILTER_CADENCE: - retval = ixj_build_filter_cadence(j, argp); - break; - case IXJCTL_SIGCTL: - if (copy_from_user(&j->sigdef, argp, sizeof(IXJ_SIGDEF))) { - retval = -EFAULT; - break; - } - j->ixj_signals[j->sigdef.event] = j->sigdef.signal; - if(j->sigdef.event < 33) { - raise = 1; - for(mant = 0; mant < j->sigdef.event; mant++){ - raise *= 2; - } - if(j->sigdef.signal) - j->ex_sig.bytes |= raise; - else - j->ex_sig.bytes &= (raise^0xffff); - } - break; - case IXJCTL_INTERCOM_STOP: - if(arg < 0 || arg >= IXJMAX) - return -EINVAL; - j->intercom = -1; - ixj_record_stop(j); - ixj_play_stop(j); - idle(j); - get_ixj(arg)->intercom = -1; - ixj_record_stop(get_ixj(arg)); - ixj_play_stop(get_ixj(arg)); - idle(get_ixj(arg)); - break; - case IXJCTL_INTERCOM_START: - if(arg < 0 || arg >= IXJMAX) - return -EINVAL; - j->intercom = arg; - ixj_record_start(j); - ixj_play_start(j); - get_ixj(arg)->intercom = board; - ixj_play_start(get_ixj(arg)); - ixj_record_start(get_ixj(arg)); - break; - } - if (ixjdebug & 0x0040) - printk("phone%d ioctl end, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg); - clear_bit(board, &j->busyflags); - return retval; -} - -static long ixj_ioctl(struct file *file_p, unsigned int cmd, unsigned long arg) -{ - long ret; - mutex_lock(&ixj_mutex); - ret = do_ixj_ioctl(file_p, cmd, arg); - mutex_unlock(&ixj_mutex); - return ret; -} - -static int ixj_fasync(int fd, struct file *file_p, int mode) -{ - IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode)); - - return fasync_helper(fd, file_p, mode, &j->async_queue); -} - -static const struct file_operations ixj_fops = -{ - .owner = THIS_MODULE, - .read = ixj_enhanced_read, - .write = ixj_enhanced_write, - .poll = ixj_poll, - .unlocked_ioctl = ixj_ioctl, - .release = ixj_release, - .fasync = ixj_fasync, - .llseek = default_llseek, -}; - -static int ixj_linetest(IXJ *j) -{ - j->flags.pstncheck = 1; /* Testing */ - j->flags.pstn_present = 0; /* Assume the line is not there */ - - daa_int_read(j); /*Clear DAA Interrupt flags */ - /* */ - /* Hold all relays in the normally de-energized position. */ - /* */ - - j->pld_slicw.bits.rly1 = 0; - j->pld_slicw.bits.rly2 = 0; - j->pld_slicw.bits.rly3 = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ - - outb_p(j->pld_scrw.byte, j->XILINXbase); - j->pld_slicr.byte = inb_p(j->XILINXbase + 0x01); - if (j->pld_slicr.bits.potspstn) { - j->flags.pots_pstn = 1; - j->flags.pots_correct = 0; - LED_SetState(0x4, j); - } else { - j->flags.pots_pstn = 0; - j->pld_slicw.bits.rly1 = 0; - j->pld_slicw.bits.rly2 = 0; - j->pld_slicw.bits.rly3 = 1; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ - - outb_p(j->pld_scrw.byte, j->XILINXbase); - daa_set_mode(j, SOP_PU_CONVERSATION); - msleep(1000); - daa_int_read(j); - daa_set_mode(j, SOP_PU_RESET); - if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) { - j->flags.pots_correct = 0; /* Should not be line voltage on POTS port. */ - LED_SetState(0x4, j); - j->pld_slicw.bits.rly3 = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - } else { - j->flags.pots_correct = 1; - LED_SetState(0x8, j); - j->pld_slicw.bits.rly1 = 1; - j->pld_slicw.bits.rly2 = 0; - j->pld_slicw.bits.rly3 = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - } - } - j->pld_slicw.bits.rly3 = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - daa_set_mode(j, SOP_PU_CONVERSATION); - msleep(1000); - daa_int_read(j); - daa_set_mode(j, SOP_PU_RESET); - if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) { - j->pstn_sleeptil = jiffies + (hertz / 4); - j->flags.pstn_present = 1; - } else { - j->flags.pstn_present = 0; - } - if (j->flags.pstn_present) { - if (j->flags.pots_correct) { - LED_SetState(0xA, j); - } else { - LED_SetState(0x6, j); - } - } else { - if (j->flags.pots_correct) { - LED_SetState(0x9, j); - } else { - LED_SetState(0x5, j); - } - } - j->flags.pstncheck = 0; /* Testing */ - return j->flags.pstn_present; -} - -static int ixj_selfprobe(IXJ *j) -{ - unsigned short cmd; - int cnt; - BYTES bytes; - - init_waitqueue_head(&j->poll_q); - init_waitqueue_head(&j->read_q); - init_waitqueue_head(&j->write_q); - - while(atomic_read(&j->DSPWrite) > 0) - atomic_dec(&j->DSPWrite); - if (ixjdebug & 0x0002) - printk(KERN_INFO "Write IDLE to Software Control Register\n"); - ixj_WriteDSPCommand(0x0FE0, j); /* Put the DSP in full power mode. */ - - if (ixj_WriteDSPCommand(0x0000, j)) /* Write IDLE to Software Control Register */ - return -1; -/* The read values of the SSR should be 0x00 for the IDLE command */ - if (j->ssr.low || j->ssr.high) - return -1; - if (ixjdebug & 0x0002) - printk(KERN_INFO "Get Device ID Code\n"); - if (ixj_WriteDSPCommand(0x3400, j)) /* Get Device ID Code */ - return -1; - j->dsp.low = j->ssr.low; - j->dsp.high = j->ssr.high; - if (ixjdebug & 0x0002) - printk(KERN_INFO "Get Device Version Code\n"); - if (ixj_WriteDSPCommand(0x3800, j)) /* Get Device Version Code */ - return -1; - j->ver.low = j->ssr.low; - j->ver.high = j->ssr.high; - if (!j->cardtype) { - if (j->dsp.low == 0x21) { - bytes.high = bytes.low = inb_p(j->XILINXbase + 0x02); - outb_p(bytes.low ^ 0xFF, j->XILINXbase + 0x02); -/* Test for Internet LineJACK or Internet PhoneJACK Lite */ - bytes.low = inb_p(j->XILINXbase + 0x02); - if (bytes.low == bytes.high) /* Register is read only on */ - /* Internet PhoneJack Lite */ - { - j->cardtype = QTI_PHONEJACK_LITE; - if (!request_region(j->XILINXbase, 4, "ixj control")) { - printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase); - return -1; - } - j->pld_slicw.pcib.e1 = 1; - outb_p(j->pld_slicw.byte, j->XILINXbase); - } else { - j->cardtype = QTI_LINEJACK; - - if (!request_region(j->XILINXbase, 8, "ixj control")) { - printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase); - return -1; - } - } - } else if (j->dsp.low == 0x22) { - j->cardtype = QTI_PHONEJACK_PCI; - request_region(j->XILINXbase, 4, "ixj control"); - j->pld_slicw.pcib.e1 = 1; - outb_p(j->pld_slicw.byte, j->XILINXbase); - } else - j->cardtype = QTI_PHONEJACK; - } else { - switch (j->cardtype) { - case QTI_PHONEJACK: - if (!j->dsp.low != 0x20) { - j->dsp.high = 0x80; - j->dsp.low = 0x20; - ixj_WriteDSPCommand(0x3800, j); - j->ver.low = j->ssr.low; - j->ver.high = j->ssr.high; - } - break; - case QTI_LINEJACK: - if (!request_region(j->XILINXbase, 8, "ixj control")) { - printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase); - return -1; - } - break; - case QTI_PHONEJACK_LITE: - case QTI_PHONEJACK_PCI: - if (!request_region(j->XILINXbase, 4, "ixj control")) { - printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase); - return -1; - } - j->pld_slicw.pcib.e1 = 1; - outb_p(j->pld_slicw.byte, j->XILINXbase); - break; - case QTI_PHONECARD: - break; - } - } - if (j->dsp.low == 0x20 || j->cardtype == QTI_PHONEJACK_LITE || j->cardtype == QTI_PHONEJACK_PCI) { - if (ixjdebug & 0x0002) - printk(KERN_INFO "Write CODEC config to Software Control Register\n"); - if (ixj_WriteDSPCommand(0xC462, j)) /* Write CODEC config to Software Control Register */ - return -1; - if (ixjdebug & 0x0002) - printk(KERN_INFO "Write CODEC timing to Software Control Register\n"); - if (j->cardtype == QTI_PHONEJACK) { - cmd = 0x9FF2; - } else { - cmd = 0x9FF5; - } - if (ixj_WriteDSPCommand(cmd, j)) /* Write CODEC timing to Software Control Register */ - return -1; - } else { - if (set_base_frame(j, 30) != 30) - return -1; - if (ixjdebug & 0x0002) - printk(KERN_INFO "Write CODEC config to Software Control Register\n"); - if (j->cardtype == QTI_PHONECARD) { - if (ixj_WriteDSPCommand(0xC528, j)) /* Write CODEC config to Software Control Register */ - return -1; - } - if (j->cardtype == QTI_LINEJACK) { - if (ixj_WriteDSPCommand(0xC528, j)) /* Write CODEC config to Software Control Register */ - return -1; - if (ixjdebug & 0x0002) - printk(KERN_INFO "Turn on the PLD Clock at 8Khz\n"); - j->pld_clock.byte = 0; - outb_p(j->pld_clock.byte, j->XILINXbase + 0x04); - } - } - - if (j->dsp.low == 0x20) { - if (ixjdebug & 0x0002) - printk(KERN_INFO "Configure GPIO pins\n"); - j->gpio.bytes.high = 0x09; -/* bytes.low = 0xEF; 0xF7 */ - j->gpio.bits.gpio1 = 1; - j->gpio.bits.gpio2 = 1; - j->gpio.bits.gpio3 = 0; - j->gpio.bits.gpio4 = 1; - j->gpio.bits.gpio5 = 1; - j->gpio.bits.gpio6 = 1; - j->gpio.bits.gpio7 = 1; - ixj_WriteDSPCommand(j->gpio.word, j); /* Set GPIO pin directions */ - if (ixjdebug & 0x0002) - printk(KERN_INFO "Enable SLIC\n"); - j->gpio.bytes.high = 0x0B; - j->gpio.bytes.low = 0x00; - j->gpio.bits.gpio1 = 0; - j->gpio.bits.gpio2 = 1; - j->gpio.bits.gpio5 = 0; - ixj_WriteDSPCommand(j->gpio.word, j); /* send the ring stop signal */ - j->port = PORT_POTS; - } else { - if (j->cardtype == QTI_LINEJACK) { - LED_SetState(0x1, j); - msleep(100); - LED_SetState(0x2, j); - msleep(100); - LED_SetState(0x4, j); - msleep(100); - LED_SetState(0x8, j); - msleep(100); - LED_SetState(0x0, j); - daa_get_version(j); - if (ixjdebug & 0x0002) - printk("Loading DAA Coefficients\n"); - DAA_Coeff_US(j); - if (!ixj_daa_write(j)) { - printk("DAA write failed on board %d\n", j->board); - return -1; - } - if(!ixj_daa_cid_reset(j)) { - printk("DAA CID reset failed on board %d\n", j->board); - return -1; - } - j->flags.pots_correct = 0; - j->flags.pstn_present = 0; - ixj_linetest(j); - if (j->flags.pots_correct) { - j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ - - outb_p(j->pld_scrw.byte, j->XILINXbase); - j->pld_slicw.bits.rly1 = 1; - j->pld_slicw.bits.spken = 1; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - SLIC_SetState(PLD_SLIC_STATE_STANDBY, j); -/* SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); */ - j->port = PORT_POTS; - } - ixj_set_port(j, PORT_PSTN); - ixj_set_pots(j, 1); - if (ixjdebug & 0x0002) - printk(KERN_INFO "Enable Mixer\n"); - ixj_mixer(0x0000, j); /*Master Volume Left unmute 0db */ - ixj_mixer(0x0100, j); /*Master Volume Right unmute 0db */ - - ixj_mixer(0x0203, j); /*Voice Left Volume unmute 6db */ - ixj_mixer(0x0303, j); /*Voice Right Volume unmute 6db */ - - ixj_mixer(0x0480, j); /*FM Left mute */ - ixj_mixer(0x0580, j); /*FM Right mute */ - - ixj_mixer(0x0680, j); /*CD Left mute */ - ixj_mixer(0x0780, j); /*CD Right mute */ - - ixj_mixer(0x0880, j); /*Line Left mute */ - ixj_mixer(0x0980, j); /*Line Right mute */ - - ixj_mixer(0x0A80, j); /*Aux left mute */ - ixj_mixer(0x0B80, j); /*Aux right mute */ - - ixj_mixer(0x0C00, j); /*Mono1 unmute 12db */ - ixj_mixer(0x0D80, j); /*Mono2 mute */ - - ixj_mixer(0x0E80, j); /*Mic mute */ - - ixj_mixer(0x0F00, j); /*Mono Out Volume unmute 0db */ - - ixj_mixer(0x1000, j); /*Voice Left and Right out only */ - ixj_mixer(0x110C, j); - - - ixj_mixer(0x1200, j); /*Mono1 switch on mixer left */ - ixj_mixer(0x1401, j); - - ixj_mixer(0x1300, j); /*Mono1 switch on mixer right */ - ixj_mixer(0x1501, j); - - ixj_mixer(0x1700, j); /*Clock select */ - - ixj_mixer(0x1800, j); /*ADC input from mixer */ - - ixj_mixer(0x1901, j); /*Mic gain 30db */ - - if (ixjdebug & 0x0002) - printk(KERN_INFO "Setting Default US Ring Cadence Detection\n"); - j->cadence_f[4].state = 0; - j->cadence_f[4].on1 = 0; /*Cadence Filter 4 is used for PSTN ring cadence */ - j->cadence_f[4].off1 = 0; - j->cadence_f[4].on2 = 0; - j->cadence_f[4].off2 = 0; - j->cadence_f[4].on3 = 0; - j->cadence_f[4].off3 = 0; /* These should represent standard US ring pulse. */ - j->pstn_last_rmr = jiffies; - - } else { - if (j->cardtype == QTI_PHONECARD) { - ixj_WriteDSPCommand(0xCF07, j); - ixj_WriteDSPCommand(0x00B0, j); - ixj_set_port(j, PORT_SPEAKER); - } else { - ixj_set_port(j, PORT_POTS); - SLIC_SetState(PLD_SLIC_STATE_STANDBY, j); -/* SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); */ - } - } - } - - j->intercom = -1; - j->framesread = j->frameswritten = 0; - j->read_wait = j->write_wait = 0; - j->rxreadycheck = j->txreadycheck = 0; - - /* initialise the DTMF prescale to a sensible value */ - if (j->cardtype == QTI_LINEJACK) { - set_dtmf_prescale(j, 0x10); - } else { - set_dtmf_prescale(j, 0x40); - } - set_play_volume(j, 0x100); - set_rec_volume(j, 0x100); - - if (ixj_WriteDSPCommand(0x0000, j)) /* Write IDLE to Software Control Register */ - return -1; -/* The read values of the SSR should be 0x00 for the IDLE command */ - if (j->ssr.low || j->ssr.high) - return -1; - - if (ixjdebug & 0x0002) - printk(KERN_INFO "Enable Line Monitor\n"); - - if (ixjdebug & 0x0002) - printk(KERN_INFO "Set Line Monitor to Asyncronous Mode\n"); - - if (ixj_WriteDSPCommand(0x7E01, j)) /* Asynchronous Line Monitor */ - return -1; - - if (ixjdebug & 0x002) - printk(KERN_INFO "Enable DTMF Detectors\n"); - - if (ixj_WriteDSPCommand(0x5151, j)) /* Enable DTMF detection */ - return -1; - - if (ixj_WriteDSPCommand(0x6E01, j)) /* Set Asyncronous Tone Generation */ - return -1; - - set_rec_depth(j, 2); /* Set Record Channel Limit to 2 frames */ - - set_play_depth(j, 2); /* Set Playback Channel Limit to 2 frames */ - - j->ex.bits.dtmf_ready = 0; - j->dtmf_state = 0; - j->dtmf_wp = j->dtmf_rp = 0; - j->rec_mode = j->play_mode = -1; - j->flags.ringing = 0; - j->maxrings = MAXRINGS; - j->ring_cadence = USA_RING_CADENCE; - j->drybuffer = 0; - j->winktime = 320; - j->flags.dtmf_oob = 0; - for (cnt = 0; cnt < 4; cnt++) - j->cadence_f[cnt].enable = 0; - /* must be a device on the specified address */ - ixj_WriteDSPCommand(0x0FE3, j); /* Put the DSP in 1/5 power mode. */ - - /* Set up the default signals for events */ - for (cnt = 0; cnt < 35; cnt++) - j->ixj_signals[cnt] = SIGIO; - - /* Set the excetion signal enable flags */ - j->ex_sig.bits.dtmf_ready = j->ex_sig.bits.hookstate = j->ex_sig.bits.flash = j->ex_sig.bits.pstn_ring = - j->ex_sig.bits.caller_id = j->ex_sig.bits.pstn_wink = j->ex_sig.bits.f0 = j->ex_sig.bits.f1 = j->ex_sig.bits.f2 = - j->ex_sig.bits.f3 = j->ex_sig.bits.fc0 = j->ex_sig.bits.fc1 = j->ex_sig.bits.fc2 = j->ex_sig.bits.fc3 = 1; -#ifdef IXJ_DYN_ALLOC - j->fskdata = NULL; -#endif - j->fskdcnt = 0; - j->cidcw_wait = 0; - - /* Register with the Telephony for Linux subsystem */ - j->p.f_op = &ixj_fops; - j->p.open = ixj_open; - j->p.board = j->board; - phone_register_device(&j->p, PHONE_UNIT_ANY); - - ixj_init_timer(j); - ixj_add_timer(j); - return 0; -} - -/* - * Exported service for pcmcia card handling - */ - -IXJ *ixj_pcmcia_probe(unsigned long dsp, unsigned long xilinx) -{ - IXJ *j = ixj_alloc(); - - j->board = 0; - - j->DSPbase = dsp; - j->XILINXbase = xilinx; - j->cardtype = QTI_PHONECARD; - ixj_selfprobe(j); - return j; -} - -EXPORT_SYMBOL(ixj_pcmcia_probe); /* Fpr PCMCIA */ - -static int ixj_get_status_proc(char *buf) -{ - int len; - int cnt; - IXJ *j; - len = 0; - len += sprintf(buf + len, "\nDriver version %i.%i.%i", IXJ_VER_MAJOR, IXJ_VER_MINOR, IXJ_BLD_VER); - len += sprintf(buf + len, "\nsizeof IXJ struct %Zd bytes", sizeof(IXJ)); - len += sprintf(buf + len, "\nsizeof DAA struct %Zd bytes", sizeof(DAA_REGS)); - len += sprintf(buf + len, "\nUsing old telephony API"); - len += sprintf(buf + len, "\nDebug Level %d\n", ixjdebug); - - for (cnt = 0; cnt < IXJMAX; cnt++) { - j = get_ixj(cnt); - if(j==NULL) - continue; - if (j->DSPbase) { - len += sprintf(buf + len, "\nCard Num %d", cnt); - len += sprintf(buf + len, "\nDSP Base Address 0x%4.4x", j->DSPbase); - if (j->cardtype != QTI_PHONEJACK) - len += sprintf(buf + len, "\nXILINX Base Address 0x%4.4x", j->XILINXbase); - len += sprintf(buf + len, "\nDSP Type %2.2x%2.2x", j->dsp.high, j->dsp.low); - len += sprintf(buf + len, "\nDSP Version %2.2x.%2.2x", j->ver.high, j->ver.low); - len += sprintf(buf + len, "\nSerial Number %8.8x", j->serial); - switch (j->cardtype) { - case (QTI_PHONEJACK): - len += sprintf(buf + len, "\nCard Type = Internet PhoneJACK"); - break; - case (QTI_LINEJACK): - len += sprintf(buf + len, "\nCard Type = Internet LineJACK"); - if (j->flags.g729_loaded) - len += sprintf(buf + len, " w/G.729 A/B"); - len += sprintf(buf + len, " Country = %d", j->daa_country); - break; - case (QTI_PHONEJACK_LITE): - len += sprintf(buf + len, "\nCard Type = Internet PhoneJACK Lite"); - if (j->flags.g729_loaded) - len += sprintf(buf + len, " w/G.729 A/B"); - break; - case (QTI_PHONEJACK_PCI): - len += sprintf(buf + len, "\nCard Type = Internet PhoneJACK PCI"); - if (j->flags.g729_loaded) - len += sprintf(buf + len, " w/G.729 A/B"); - break; - case (QTI_PHONECARD): - len += sprintf(buf + len, "\nCard Type = Internet PhoneCARD"); - if (j->flags.g729_loaded) - len += sprintf(buf + len, " w/G.729 A/B"); - len += sprintf(buf + len, "\nSmart Cable %spresent", j->pccr1.bits.drf ? "not " : ""); - if (!j->pccr1.bits.drf) - len += sprintf(buf + len, "\nSmart Cable type %d", j->flags.pcmciasct); - len += sprintf(buf + len, "\nSmart Cable state %d", j->flags.pcmciastate); - break; - default: - len += sprintf(buf + len, "\nCard Type = %d", j->cardtype); - break; - } - len += sprintf(buf + len, "\nReaders %d", j->readers); - len += sprintf(buf + len, "\nWriters %d", j->writers); - add_caps(j); - len += sprintf(buf + len, "\nCapabilities %d", j->caps); - if (j->dsp.low != 0x20) - len += sprintf(buf + len, "\nDSP Processor load %d", j->proc_load); - if (j->flags.cidsent) - len += sprintf(buf + len, "\nCaller ID data sent"); - else - len += sprintf(buf + len, "\nCaller ID data not sent"); - - len += sprintf(buf + len, "\nPlay CODEC "); - switch (j->play_codec) { - case G723_63: - len += sprintf(buf + len, "G.723.1 6.3"); - break; - case G723_53: - len += sprintf(buf + len, "G.723.1 5.3"); - break; - case TS85: - len += sprintf(buf + len, "TrueSpeech 8.5"); - break; - case TS48: - len += sprintf(buf + len, "TrueSpeech 4.8"); - break; - case TS41: - len += sprintf(buf + len, "TrueSpeech 4.1"); - break; - case G728: - len += sprintf(buf + len, "G.728"); - break; - case G729: - len += sprintf(buf + len, "G.729"); - break; - case G729B: - len += sprintf(buf + len, "G.729B"); - break; - case ULAW: - len += sprintf(buf + len, "uLaw"); - break; - case ALAW: - len += sprintf(buf + len, "aLaw"); - break; - case LINEAR16: - len += sprintf(buf + len, "16 bit Linear"); - break; - case LINEAR8: - len += sprintf(buf + len, "8 bit Linear"); - break; - case WSS: - len += sprintf(buf + len, "Windows Sound System"); - break; - default: - len += sprintf(buf + len, "NO CODEC CHOSEN"); - break; - } - len += sprintf(buf + len, "\nRecord CODEC "); - switch (j->rec_codec) { - case G723_63: - len += sprintf(buf + len, "G.723.1 6.3"); - break; - case G723_53: - len += sprintf(buf + len, "G.723.1 5.3"); - break; - case TS85: - len += sprintf(buf + len, "TrueSpeech 8.5"); - break; - case TS48: - len += sprintf(buf + len, "TrueSpeech 4.8"); - break; - case TS41: - len += sprintf(buf + len, "TrueSpeech 4.1"); - break; - case G728: - len += sprintf(buf + len, "G.728"); - break; - case G729: - len += sprintf(buf + len, "G.729"); - break; - case G729B: - len += sprintf(buf + len, "G.729B"); - break; - case ULAW: - len += sprintf(buf + len, "uLaw"); - break; - case ALAW: - len += sprintf(buf + len, "aLaw"); - break; - case LINEAR16: - len += sprintf(buf + len, "16 bit Linear"); - break; - case LINEAR8: - len += sprintf(buf + len, "8 bit Linear"); - break; - case WSS: - len += sprintf(buf + len, "Windows Sound System"); - break; - default: - len += sprintf(buf + len, "NO CODEC CHOSEN"); - break; - } - len += sprintf(buf + len, "\nAEC "); - switch (j->aec_level) { - case AEC_OFF: - len += sprintf(buf + len, "Off"); - break; - case AEC_LOW: - len += sprintf(buf + len, "Low"); - break; - case AEC_MED: - len += sprintf(buf + len, "Med"); - break; - case AEC_HIGH: - len += sprintf(buf + len, "High"); - break; - case AEC_AUTO: - len += sprintf(buf + len, "Auto"); - break; - case AEC_AGC: - len += sprintf(buf + len, "AEC/AGC"); - break; - default: - len += sprintf(buf + len, "unknown(%i)", j->aec_level); - break; - } - - len += sprintf(buf + len, "\nRec volume 0x%x", get_rec_volume(j)); - len += sprintf(buf + len, "\nPlay volume 0x%x", get_play_volume(j)); - len += sprintf(buf + len, "\nDTMF prescale 0x%x", get_dtmf_prescale(j)); - - len += sprintf(buf + len, "\nHook state %d", j->hookstate); /* j->r_hook); */ - - if (j->cardtype == QTI_LINEJACK) { - len += sprintf(buf + len, "\nPOTS Correct %d", j->flags.pots_correct); - len += sprintf(buf + len, "\nPSTN Present %d", j->flags.pstn_present); - len += sprintf(buf + len, "\nPSTN Check %d", j->flags.pstncheck); - len += sprintf(buf + len, "\nPOTS to PSTN %d", j->flags.pots_pstn); - switch (j->daa_mode) { - case SOP_PU_SLEEP: - len += sprintf(buf + len, "\nDAA PSTN On Hook"); - break; - case SOP_PU_RINGING: - len += sprintf(buf + len, "\nDAA PSTN Ringing"); - len += sprintf(buf + len, "\nRinging state = %d", j->cadence_f[4].state); - break; - case SOP_PU_CONVERSATION: - len += sprintf(buf + len, "\nDAA PSTN Off Hook"); - break; - case SOP_PU_PULSEDIALING: - len += sprintf(buf + len, "\nDAA PSTN Pulse Dialing"); - break; - } - len += sprintf(buf + len, "\nDAA RMR = %d", j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR); - len += sprintf(buf + len, "\nDAA VDD OK = %d", j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK); - len += sprintf(buf + len, "\nDAA CR0 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg); - len += sprintf(buf + len, "\nDAA CR1 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg); - len += sprintf(buf + len, "\nDAA CR2 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg); - len += sprintf(buf + len, "\nDAA CR3 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg); - len += sprintf(buf + len, "\nDAA CR4 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg); - len += sprintf(buf + len, "\nDAA CR5 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg); - len += sprintf(buf + len, "\nDAA XR0 = 0x%02x", j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg); - len += sprintf(buf + len, "\nDAA ringstop %ld - jiffies %ld", j->pstn_ring_stop, jiffies); - } - switch (j->port) { - case PORT_POTS: - len += sprintf(buf + len, "\nPort POTS"); - break; - case PORT_PSTN: - len += sprintf(buf + len, "\nPort PSTN"); - break; - case PORT_SPEAKER: - len += sprintf(buf + len, "\nPort SPEAKER/MIC"); - break; - case PORT_HANDSET: - len += sprintf(buf + len, "\nPort HANDSET"); - break; - } - if (j->dsp.low == 0x21 || j->dsp.low == 0x22) { - len += sprintf(buf + len, "\nSLIC state "); - switch (SLIC_GetState(j)) { - case PLD_SLIC_STATE_OC: - len += sprintf(buf + len, "OC"); - break; - case PLD_SLIC_STATE_RINGING: - len += sprintf(buf + len, "RINGING"); - break; - case PLD_SLIC_STATE_ACTIVE: - len += sprintf(buf + len, "ACTIVE"); - break; - case PLD_SLIC_STATE_OHT: /* On-hook transmit */ - len += sprintf(buf + len, "OHT"); - break; - case PLD_SLIC_STATE_TIPOPEN: - len += sprintf(buf + len, "TIPOPEN"); - break; - case PLD_SLIC_STATE_STANDBY: - len += sprintf(buf + len, "STANDBY"); - break; - case PLD_SLIC_STATE_APR: /* Active polarity reversal */ - len += sprintf(buf + len, "APR"); - break; - case PLD_SLIC_STATE_OHTPR: /* OHT polarity reversal */ - len += sprintf(buf + len, "OHTPR"); - break; - default: - len += sprintf(buf + len, "%d", SLIC_GetState(j)); - break; - } - } - len += sprintf(buf + len, "\nBase Frame %2.2x.%2.2x", j->baseframe.high, j->baseframe.low); - len += sprintf(buf + len, "\nCID Base Frame %2d", j->cid_base_frame_size); -#ifdef PERFMON_STATS - len += sprintf(buf + len, "\nTimer Checks %ld", j->timerchecks); - len += sprintf(buf + len, "\nRX Ready Checks %ld", j->rxreadycheck); - len += sprintf(buf + len, "\nTX Ready Checks %ld", j->txreadycheck); - len += sprintf(buf + len, "\nFrames Read %ld", j->framesread); - len += sprintf(buf + len, "\nFrames Written %ld", j->frameswritten); - len += sprintf(buf + len, "\nDry Buffer %ld", j->drybuffer); - len += sprintf(buf + len, "\nRead Waits %ld", j->read_wait); - len += sprintf(buf + len, "\nWrite Waits %ld", j->write_wait); - len += sprintf(buf + len, "\nStatus Waits %ld", j->statuswait); - len += sprintf(buf + len, "\nStatus Wait Fails %ld", j->statuswaitfail); - len += sprintf(buf + len, "\nPControl Waits %ld", j->pcontrolwait); - len += sprintf(buf + len, "\nPControl Wait Fails %ld", j->pcontrolwaitfail); - len += sprintf(buf + len, "\nIs Control Ready Checks %ld", j->iscontrolready); - len += sprintf(buf + len, "\nIs Control Ready Check failures %ld", j->iscontrolreadyfail); - -#endif - len += sprintf(buf + len, "\n"); - } - } - return len; -} - -static int ixj_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len = ixj_get_status_proc(page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - return len; -} - - -static void cleanup(void) -{ - int cnt; - IXJ *j; - - for (cnt = 0; cnt < IXJMAX; cnt++) { - j = get_ixj(cnt); - if(j != NULL && j->DSPbase) { - if (ixjdebug & 0x0002) - printk(KERN_INFO "IXJ: Deleting timer for /dev/phone%d\n", cnt); - del_timer(&j->timer); - if (j->cardtype == QTI_LINEJACK) { - j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ - - outb_p(j->pld_scrw.byte, j->XILINXbase); - j->pld_slicw.bits.rly1 = 0; - j->pld_slicw.bits.rly2 = 0; - j->pld_slicw.bits.rly3 = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - LED_SetState(0x0, j); - if (ixjdebug & 0x0002) - printk(KERN_INFO "IXJ: Releasing XILINX address for /dev/phone%d\n", cnt); - release_region(j->XILINXbase, 8); - } else if (j->cardtype == QTI_PHONEJACK_LITE || j->cardtype == QTI_PHONEJACK_PCI) { - if (ixjdebug & 0x0002) - printk(KERN_INFO "IXJ: Releasing XILINX address for /dev/phone%d\n", cnt); - release_region(j->XILINXbase, 4); - } - kfree(j->read_buffer); - kfree(j->write_buffer); - if (j->dev) - pnp_device_detach(j->dev); - if (ixjdebug & 0x0002) - printk(KERN_INFO "IXJ: Unregistering /dev/phone%d from LTAPI\n", cnt); - phone_unregister_device(&j->p); - if (ixjdebug & 0x0002) - printk(KERN_INFO "IXJ: Releasing DSP address for /dev/phone%d\n", cnt); - release_region(j->DSPbase, 16); -#ifdef IXJ_DYN_ALLOC - if (ixjdebug & 0x0002) - printk(KERN_INFO "IXJ: Freeing memory for /dev/phone%d\n", cnt); - kfree(j); - ixj[cnt] = NULL; -#endif - } - } - if (ixjdebug & 0x0002) - printk(KERN_INFO "IXJ: Removing /proc/ixj\n"); - remove_proc_entry ("ixj", NULL); -} - -/* Typedefs */ -typedef struct { - BYTE length; - DWORD bits; -} DATABLOCK; - -static void PCIEE_WriteBit(WORD wEEPROMAddress, BYTE lastLCC, BYTE byData) -{ - lastLCC = lastLCC & 0xfb; - lastLCC = lastLCC | (byData ? 4 : 0); - outb(lastLCC, wEEPROMAddress); /*set data out bit as appropriate */ - - mdelay(1); - lastLCC = lastLCC | 0x01; - outb(lastLCC, wEEPROMAddress); /*SK rising edge */ - - byData = byData << 1; - lastLCC = lastLCC & 0xfe; - mdelay(1); - outb(lastLCC, wEEPROMAddress); /*after delay, SK falling edge */ - -} - -static BYTE PCIEE_ReadBit(WORD wEEPROMAddress, BYTE lastLCC) -{ - mdelay(1); - lastLCC = lastLCC | 0x01; - outb(lastLCC, wEEPROMAddress); /*SK rising edge */ - - lastLCC = lastLCC & 0xfe; - mdelay(1); - outb(lastLCC, wEEPROMAddress); /*after delay, SK falling edge */ - - return ((inb(wEEPROMAddress) >> 3) & 1); -} - -static bool PCIEE_ReadWord(WORD wAddress, WORD wLoc, WORD * pwResult) -{ - BYTE lastLCC; - WORD wEEPROMAddress = wAddress + 3; - DWORD i; - BYTE byResult; - *pwResult = 0; - lastLCC = inb(wEEPROMAddress); - lastLCC = lastLCC | 0x02; - lastLCC = lastLCC & 0xfe; - outb(lastLCC, wEEPROMAddress); /* CS hi, SK lo */ - - mdelay(1); /* delay */ - - PCIEE_WriteBit(wEEPROMAddress, lastLCC, 1); - PCIEE_WriteBit(wEEPROMAddress, lastLCC, 1); - PCIEE_WriteBit(wEEPROMAddress, lastLCC, 0); - for (i = 0; i < 8; i++) { - PCIEE_WriteBit(wEEPROMAddress, lastLCC, wLoc & 0x80 ? 1 : 0); - wLoc <<= 1; - } - - for (i = 0; i < 16; i++) { - byResult = PCIEE_ReadBit(wEEPROMAddress, lastLCC); - *pwResult = (*pwResult << 1) | byResult; - } - - mdelay(1); /* another delay */ - - lastLCC = lastLCC & 0xfd; - outb(lastLCC, wEEPROMAddress); /* negate CS */ - - return 0; -} - -static DWORD PCIEE_GetSerialNumber(WORD wAddress) -{ - WORD wLo, wHi; - if (PCIEE_ReadWord(wAddress, 62, &wLo)) - return 0; - if (PCIEE_ReadWord(wAddress, 63, &wHi)) - return 0; - return (((DWORD) wHi << 16) | wLo); -} - -static int dspio[IXJMAX + 1] = -{ - 0, -}; -static int xio[IXJMAX + 1] = -{ - 0, -}; - -module_param_array(dspio, int, NULL, 0); -module_param_array(xio, int, NULL, 0); -MODULE_DESCRIPTION("Quicknet VoIP Telephony card module - www.quicknet.net"); -MODULE_AUTHOR("Ed Okerson "); -MODULE_LICENSE("GPL"); - -static void __exit ixj_exit(void) -{ - cleanup(); -} - -static IXJ *new_ixj(unsigned long port) -{ - IXJ *res; - if (!request_region(port, 16, "ixj DSP")) { - printk(KERN_INFO "ixj: can't get I/O address 0x%lx\n", port); - return NULL; - } - res = ixj_alloc(); - if (!res) { - release_region(port, 16); - printk(KERN_INFO "ixj: out of memory\n"); - return NULL; - } - res->DSPbase = port; - return res; -} - -static int __init ixj_probe_isapnp(int *cnt) -{ - int probe = 0; - int func = 0x110; - struct pnp_dev *dev = NULL, *old_dev = NULL; - - while (1) { - do { - IXJ *j; - int result; - - old_dev = dev; - dev = pnp_find_dev(NULL, ISAPNP_VENDOR('Q', 'T', 'I'), - ISAPNP_FUNCTION(func), old_dev); - if (!dev || !dev->card) - break; - result = pnp_device_attach(dev); - if (result < 0) { - printk("pnp attach failed %d \n", result); - break; - } - if (pnp_activate_dev(dev) < 0) { - printk("pnp activate failed (out of resources?)\n"); - pnp_device_detach(dev); - return -ENOMEM; - } - - if (!pnp_port_valid(dev, 0)) { - pnp_device_detach(dev); - return -ENODEV; - } - - j = new_ixj(pnp_port_start(dev, 0)); - if (!j) - break; - - if (func != 0x110) - j->XILINXbase = pnp_port_start(dev, 1); /* get real port */ - - switch (func) { - case (0x110): - j->cardtype = QTI_PHONEJACK; - break; - case (0x310): - j->cardtype = QTI_LINEJACK; - break; - case (0x410): - j->cardtype = QTI_PHONEJACK_LITE; - break; - } - j->board = *cnt; - probe = ixj_selfprobe(j); - if(!probe) { - j->serial = dev->card->serial; - j->dev = dev; - switch (func) { - case 0x110: - printk(KERN_INFO "ixj: found Internet PhoneJACK at 0x%x\n", j->DSPbase); - break; - case 0x310: - printk(KERN_INFO "ixj: found Internet LineJACK at 0x%x\n", j->DSPbase); - break; - case 0x410: - printk(KERN_INFO "ixj: found Internet PhoneJACK Lite at 0x%x\n", j->DSPbase); - break; - } - } - ++*cnt; - } while (dev); - if (func == 0x410) - break; - if (func == 0x310) - func = 0x410; - if (func == 0x110) - func = 0x310; - dev = NULL; - } - return probe; -} - -static int __init ixj_probe_isa(int *cnt) -{ - int i, probe; - - /* Use passed parameters for older kernels without PnP */ - for (i = 0; i < IXJMAX; i++) { - if (dspio[i]) { - IXJ *j = new_ixj(dspio[i]); - - if (!j) - break; - - j->XILINXbase = xio[i]; - j->cardtype = 0; - - j->board = *cnt; - probe = ixj_selfprobe(j); - j->dev = NULL; - ++*cnt; - } - } - return 0; -} - -static int __init ixj_probe_pci(int *cnt) -{ - struct pci_dev *pci = NULL; - int i, probe = 0; - IXJ *j = NULL; - - for (i = 0; i < IXJMAX - *cnt; i++) { - pci = pci_get_device(PCI_VENDOR_ID_QUICKNET, - PCI_DEVICE_ID_QUICKNET_XJ, pci); - if (!pci) - break; - - if (pci_enable_device(pci)) - break; - j = new_ixj(pci_resource_start(pci, 0)); - if (!j) - break; - - j->serial = (PCIEE_GetSerialNumber)pci_resource_start(pci, 2); - j->XILINXbase = j->DSPbase + 0x10; - j->cardtype = QTI_PHONEJACK_PCI; - j->board = *cnt; - probe = ixj_selfprobe(j); - if (!probe) - printk(KERN_INFO "ixj: found Internet PhoneJACK PCI at 0x%x\n", j->DSPbase); - ++*cnt; - } - pci_dev_put(pci); - return probe; -} - -static int __init ixj_init(void) -{ - int cnt = 0; - int probe = 0; - - cnt = 0; - - /* These might be no-ops, see above. */ - if ((probe = ixj_probe_isapnp(&cnt)) < 0) { - return probe; - } - if ((probe = ixj_probe_isa(&cnt)) < 0) { - return probe; - } - if ((probe = ixj_probe_pci(&cnt)) < 0) { - return probe; - } - printk(KERN_INFO "ixj driver initialized.\n"); - create_proc_read_entry ("ixj", 0, NULL, ixj_read_proc, NULL); - return probe; -} - -module_init(ixj_init); -module_exit(ixj_exit); - -static void DAA_Coeff_US(IXJ *j) -{ - int i; - - j->daa_country = DAA_US; - /*----------------------------------------------- */ - /* CAO */ - for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) { - j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0; - } - -/* Bytes for IM-filter part 1 (04): 0E,32,E2,2F,C2,5A,C0,00 */ - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x03; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0x4B; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0x5D; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0xCD; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0x24; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xC5; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00; -/* Bytes for IM-filter part 2 (05): 72,85,00,0E,2B,3A,D0,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x71; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x1A; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0A; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0xB5; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08; -/* Bytes for FRX-filter (08): 03,8F,48,F2,8F,48,70,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x05; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0xA3; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0x72; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x34; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x3F; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x3B; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x30; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08; -/* Bytes for FRR-filter (07): 04,8F,38,7F,9B,EA,B0,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x05; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x87; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xF9; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x3E; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xDA; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xB0; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08; -/* Bytes for AX-filter (0A): 16,55,DD,CA */ - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x41; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xB5; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA; -/* Bytes for AR-filter (09): 52,D3,11,42 */ - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x25; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xC7; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6; -/* Bytes for TH-filter part 1 (00): 00,42,48,81,B3,80,00,98 */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xA5; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98; -/* Bytes for TH-filter part 2 (01): 02,F2,33,A0,68,AB,8A,AD */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xA2; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x2B; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0xB0; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0xE8; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0xAB; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x81; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xCC; -/* Bytes for TH-filter part 3 (02): 00,88,DA,54,A4,BA,2D,BB */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0xD2; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x24; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xA9; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x3B; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xA6; -/* ; (10K, 0.68uF) */ - /* */ - /* Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23 */ - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23; - /* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */ - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5; - - /* Levelmetering Ringing (0D):B2,45,0F,8E */ - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E; - - /* Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23 */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1C; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0xB3; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0xAB; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0xAB; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x54; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x2D; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0x62; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x2D; */ - /* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x2D; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0x62; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBB; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x2A; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7D; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD4; */ -/* */ - /* Levelmetering Ringing (0D):B2,45,0F,8E */ -/* j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x05; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E; */ - - /* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */ - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99; -/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */ - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00; -/* */ - /* ;CR Registers */ - /* Config. Reg. 0 (filters) (cr0):FE ; CLK gen. by crystal */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF; -/* Config. Reg. 1 (dialing) (cr1):05 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05; -/* Config. Reg. 2 (caller ID) (cr2):04 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04; -/* Config. Reg. 3 (testloops) (cr3):03 ; SEL Bit==0, HP-disabled */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00; -/* Config. Reg. 4 (analog gain) (cr4):02 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; - /* Config. Reg. 5 (Version) (cr5):02 */ - /* Config. Reg. 6 (Reserved) (cr6):00 */ - /* Config. Reg. 7 (Reserved) (cr7):00 */ - /* */ - /* ;xr Registers */ - /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */ - - j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */ - /* Ext. Reg. 1 (Interrupt enable) (xr1):3C Cadence, RING, Caller ID, VDD_OK */ - - j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x3C; -/* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D; -/* Ext. Reg. 3 (DC Char) (xr3):32 ; B-Filter Off == 1 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x3B; /*0x32; */ - /* Ext. Reg. 4 (Cadence) (xr4):00 */ - - j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00; -/* Ext. Reg. 5 (Ring timer) (xr5):22 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22; -/* Ext. Reg. 6 (Power State) (xr6):00 */ - j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00; -/* Ext. Reg. 7 (Vdd) (xr7):40 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; /* 0x40 ??? Should it be 0x00? */ - /* */ - /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */ - /* 12,33,5A,C3 ; 770 Hz */ - /* 13,3C,5B,32 ; 852 Hz */ - /* 1D,1B,5C,CC ; 941 Hz */ - - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C; -/* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */ - /* EC,1D,52,22 ; 1336 Hz */ - /* AA,AC,51,D2 ; 1477 Hz */ - /* 9B,3B,51,25 ; 1633 Hz */ - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3; -} - -static void DAA_Coeff_UK(IXJ *j) -{ - int i; - - j->daa_country = DAA_UK; - /*----------------------------------------------- */ - /* CAO */ - for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) { - j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0; - } - -/* Bytes for IM-filter part 1 (04): 00,C2,BB,A8,CB,81,A0,00 */ - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xC2; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xBB; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0xA8; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0xCB; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x81; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00; -/* Bytes for IM-filter part 2 (05): 40,00,00,0A,A4,33,E0,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x40; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0A; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0xA4; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08; -/* Bytes for FRX-filter (08): 07,9B,ED,24,B2,A2,A0,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x9B; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0xED; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x24; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0xB2; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0xA2; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xA0; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08; -/* Bytes for FRR-filter (07): 0F,92,F2,B2,87,D2,30,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x0F; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x92; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xF2; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0xB2; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x87; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xD2; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x30; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08; -/* Bytes for AX-filter (0A): 1B,A5,DD,CA */ - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x1B; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xA5; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA; -/* Bytes for AR-filter (09): E2,27,10,D6 */ - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0xE2; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x27; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6; -/* Bytes for TH-filter part 1 (00): 80,2D,38,8B,D0,00,00,98 */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x2D; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x38; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x8B; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xD0; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98; -/* Bytes for TH-filter part 2 (01): 02,5A,53,F0,0B,5F,84,D4 */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0x5A; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x53; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0xF0; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0x0B; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x5F; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x84; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xD4; -/* Bytes for TH-filter part 3 (02): 00,88,6A,A4,8F,52,F5,32 */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0x6A; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0xA4; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0x8F; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x52; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0xF5; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x32; -/* ; idle */ - /* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */ - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23; -/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */ - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5; -/* Levelmetering Ringing (0D):AA,35,0F,8E ; 25Hz 30V less possible? */ - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E; -/* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */ - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99; -/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */ - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00; -/* ;CR Registers */ - /* Config. Reg. 0 (filters) (cr0):FF */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF; -/* Config. Reg. 1 (dialing) (cr1):05 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05; -/* Config. Reg. 2 (caller ID) (cr2):04 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04; -/* Config. Reg. 3 (testloops) (cr3):00 ; */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00; -/* Config. Reg. 4 (analog gain) (cr4):02 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; - /* Config. Reg. 5 (Version) (cr5):02 */ - /* Config. Reg. 6 (Reserved) (cr6):00 */ - /* Config. Reg. 7 (Reserved) (cr7):00 */ - /* ;xr Registers */ - /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */ - - j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */ - /* Ext. Reg. 1 (Interrupt enable) (xr1):1C */ - - j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; /* RING, Caller ID, VDD_OK */ - /* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */ - - j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D; -/* Ext. Reg. 3 (DC Char) (xr3):36 ; */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x36; -/* Ext. Reg. 4 (Cadence) (xr4):00 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00; -/* Ext. Reg. 5 (Ring timer) (xr5):22 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22; -/* Ext. Reg. 6 (Power State) (xr6):00 */ - j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00; -/* Ext. Reg. 7 (Vdd) (xr7):46 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x46; /* 0x46 ??? Should it be 0x00? */ - /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */ - /* 12,33,5A,C3 ; 770 Hz */ - /* 13,3C,5B,32 ; 852 Hz */ - /* 1D,1B,5C,CC ; 941 Hz */ - - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C; -/* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */ - /* EC,1D,52,22 ; 1336 Hz */ - /* AA,AC,51,D2 ; 1477 Hz */ - /* 9B,3B,51,25 ; 1633 Hz */ - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3; -} - - -static void DAA_Coeff_France(IXJ *j) -{ - int i; - - j->daa_country = DAA_FRANCE; - /*----------------------------------------------- */ - /* CAO */ - for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) { - j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0; - } - -/* Bytes for IM-filter part 1 (04): 02,A2,43,2C,22,AF,A0,00 */ - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x02; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xA2; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0x43; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x2C; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xAF; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00; -/* Bytes for IM-filter part 2 (05): 67,CE,00,0C,22,33,E0,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x67; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0xCE; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x2C; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08; -/* Bytes for FRX-filter (08): 07,9A,28,F6,23,4A,B0,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x9A; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0x28; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0xF6; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x23; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x4A; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xB0; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08; -/* Bytes for FRR-filter (07): 03,8F,F9,2F,9E,FA,20,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x03; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x8F; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xF9; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x2F; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x9E; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xFA; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x20; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08; -/* Bytes for AX-filter (0A): 16,B5,DD,CA */ - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x16; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xB5; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA; -/* Bytes for AR-filter (09): 52,C7,10,D6 */ - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0xE2; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xC7; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6; -/* Bytes for TH-filter part 1 (00): 00,42,48,81,A6,80,00,98 */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xA6; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98; -/* Bytes for TH-filter part 2 (01): 02,AC,2A,30,78,AC,8A,2C */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xAC; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x2A; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0x30; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0x78; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0xAC; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x8A; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x2C; -/* Bytes for TH-filter part 3 (02): 00,88,DA,A5,22,BA,2C,45 */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0xDA; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0xA5; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x2C; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x45; -/* ; idle */ - /* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */ - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23; -/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */ - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5; -/* Levelmetering Ringing (0D):32,45,B5,84 ; 50Hz 20V */ - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0xB5; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x84; -/* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */ - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99; -/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */ - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00; -/* ;CR Registers */ - /* Config. Reg. 0 (filters) (cr0):FF */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF; -/* Config. Reg. 1 (dialing) (cr1):05 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05; -/* Config. Reg. 2 (caller ID) (cr2):04 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04; -/* Config. Reg. 3 (testloops) (cr3):00 ; */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00; -/* Config. Reg. 4 (analog gain) (cr4):02 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; - /* Config. Reg. 5 (Version) (cr5):02 */ - /* Config. Reg. 6 (Reserved) (cr6):00 */ - /* Config. Reg. 7 (Reserved) (cr7):00 */ - /* ;xr Registers */ - /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */ - - j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */ - /* Ext. Reg. 1 (Interrupt enable) (xr1):1C */ - - j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; /* RING, Caller ID, VDD_OK */ - /* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */ - - j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D; -/* Ext. Reg. 3 (DC Char) (xr3):36 ; */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x36; -/* Ext. Reg. 4 (Cadence) (xr4):00 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00; -/* Ext. Reg. 5 (Ring timer) (xr5):22 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22; -/* Ext. Reg. 6 (Power State) (xr6):00 */ - j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00; -/* Ext. Reg. 7 (Vdd) (xr7):46 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x46; /* 0x46 ??? Should it be 0x00? */ - /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */ - /* 12,33,5A,C3 ; 770 Hz */ - /* 13,3C,5B,32 ; 852 Hz */ - /* 1D,1B,5C,CC ; 941 Hz */ - - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C; -/* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */ - /* EC,1D,52,22 ; 1336 Hz */ - /* AA,AC,51,D2 ; 1477 Hz */ - /* 9B,3B,51,25 ; 1633 Hz */ - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3; -} - - -static void DAA_Coeff_Germany(IXJ *j) -{ - int i; - - j->daa_country = DAA_GERMANY; - /*----------------------------------------------- */ - /* CAO */ - for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) { - j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0; - } - -/* Bytes for IM-filter part 1 (04): 00,CE,BB,B8,D2,81,B0,00 */ - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xCE; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xBB; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0xB8; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0xD2; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x81; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xB0; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00; -/* Bytes for IM-filter part 2 (05): 45,8F,00,0C,D2,3A,D0,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x45; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x8F; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0C; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0xD2; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x3A; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xD0; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08; -/* Bytes for FRX-filter (08): 07,AA,E2,34,24,89,20,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0xAA; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0xE2; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x34; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x24; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x89; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x20; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08; -/* Bytes for FRR-filter (07): 02,87,FA,37,9A,CA,B0,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x02; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x87; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xFA; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x37; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x9A; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xB0; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08; -/* Bytes for AX-filter (0A): 72,D5,DD,CA */ - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x72; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xD5; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA; -/* Bytes for AR-filter (09): 72,42,13,4B */ - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x72; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x42; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x13; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0x4B; -/* Bytes for TH-filter part 1 (00): 80,52,48,81,AD,80,00,98 */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x52; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xAD; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98; -/* Bytes for TH-filter part 2 (01): 02,42,5A,20,E8,1A,81,27 */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0x42; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x5A; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0x20; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0xE8; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x1A; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x81; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x27; -/* Bytes for TH-filter part 3 (02): 00,88,63,26,BD,4B,A3,C2 */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0x63; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x26; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0xBD; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x4B; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0xA3; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xC2; -/* ; (10K, 0.68uF) */ - /* Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23 */ - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3B; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x9B; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0xD4; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x1C; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xB3; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23; -/* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */ - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x13; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0x42; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0xD4; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x73; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5; -/* Levelmetering Ringing (0D):B2,45,0F,8E */ - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xB2; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E; -/* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */ - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99; -/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */ - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00; -/* ;CR Registers */ - /* Config. Reg. 0 (filters) (cr0):FF ; all Filters enabled, CLK from ext. source */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF; -/* Config. Reg. 1 (dialing) (cr1):05 ; Manual Ring, Ring metering enabled */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05; -/* Config. Reg. 2 (caller ID) (cr2):04 ; Analog Gain 0dB, FSC internal */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04; -/* Config. Reg. 3 (testloops) (cr3):00 ; SEL Bit==0, HP-enabled */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00; -/* Config. Reg. 4 (analog gain) (cr4):02 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; - /* Config. Reg. 5 (Version) (cr5):02 */ - /* Config. Reg. 6 (Reserved) (cr6):00 */ - /* Config. Reg. 7 (Reserved) (cr7):00 */ - /* ;xr Registers */ - /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */ - - j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */ - /* Ext. Reg. 1 (Interrupt enable) (xr1):1C ; Ring, CID, VDDOK Interrupts enabled */ - - j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; /* RING, Caller ID, VDD_OK */ - /* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */ - - j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D; -/* Ext. Reg. 3 (DC Char) (xr3):32 ; B-Filter Off==1, U0=3.5V, R=200Ohm */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x32; -/* Ext. Reg. 4 (Cadence) (xr4):00 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00; -/* Ext. Reg. 5 (Ring timer) (xr5):22 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22; -/* Ext. Reg. 6 (Power State) (xr6):00 */ - j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00; -/* Ext. Reg. 7 (Vdd) (xr7):40 ; VDD=4.25 V */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; /* 0x40 ??? Should it be 0x00? */ - /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */ - /* 12,33,5A,C3 ; 770 Hz */ - /* 13,3C,5B,32 ; 852 Hz */ - /* 1D,1B,5C,CC ; 941 Hz */ - - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C; -/* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */ - /* EC,1D,52,22 ; 1336 Hz */ - /* AA,AC,51,D2 ; 1477 Hz */ - /* 9B,3B,51,25 ; 1633 Hz */ - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3; -} - - -static void DAA_Coeff_Australia(IXJ *j) -{ - int i; - - j->daa_country = DAA_AUSTRALIA; - /*----------------------------------------------- */ - /* CAO */ - for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) { - j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0; - } - -/* Bytes for IM-filter part 1 (04): 00,A3,AA,28,B3,82,D0,00 */ - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xA3; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xAA; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x28; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0xB3; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x82; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xD0; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00; -/* Bytes for IM-filter part 2 (05): 70,96,00,09,32,6B,C0,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x70; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x96; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x09; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x6B; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xC0; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08; -/* Bytes for FRX-filter (08): 07,96,E2,34,32,9B,30,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x96; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0xE2; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x34; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x9B; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x30; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08; -/* Bytes for FRR-filter (07): 0F,9A,E9,2F,22,CC,A0,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x0F; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x9A; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xE9; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x2F; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xCC; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xA0; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08; -/* Bytes for AX-filter (0A): CB,45,DD,CA */ - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0xCB; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0x45; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA; -/* Bytes for AR-filter (09): 1B,67,10,D6 */ - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x1B; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x67; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6; -/* Bytes for TH-filter part 1 (00): 80,52,48,81,AF,80,00,98 */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x52; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xAF; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98; -/* Bytes for TH-filter part 2 (01): 02,DB,52,B0,38,01,82,AC */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xDB; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x52; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0xB0; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0x38; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x01; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x82; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xAC; -/* Bytes for TH-filter part 3 (02): 00,88,4A,3E,2C,3B,24,46 */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0x4A; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x3E; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0x2C; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x3B; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x24; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x46; -/* ; idle */ - /* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */ - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23; -/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */ - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5; -/* Levelmetering Ringing (0D):32,45,B5,84 ; 50Hz 20V */ - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0xB5; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x84; -/* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */ - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99; -/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */ - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00; -/* ;CR Registers */ - /* Config. Reg. 0 (filters) (cr0):FF */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF; -/* Config. Reg. 1 (dialing) (cr1):05 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05; -/* Config. Reg. 2 (caller ID) (cr2):04 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04; -/* Config. Reg. 3 (testloops) (cr3):00 ; */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00; -/* Config. Reg. 4 (analog gain) (cr4):02 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; - /* Config. Reg. 5 (Version) (cr5):02 */ - /* Config. Reg. 6 (Reserved) (cr6):00 */ - /* Config. Reg. 7 (Reserved) (cr7):00 */ - /* ;xr Registers */ - /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */ - - j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */ - /* Ext. Reg. 1 (Interrupt enable) (xr1):1C */ - - j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; /* RING, Caller ID, VDD_OK */ - /* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */ - - j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D; -/* Ext. Reg. 3 (DC Char) (xr3):2B ; */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x2B; -/* Ext. Reg. 4 (Cadence) (xr4):00 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00; -/* Ext. Reg. 5 (Ring timer) (xr5):22 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22; -/* Ext. Reg. 6 (Power State) (xr6):00 */ - j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00; -/* Ext. Reg. 7 (Vdd) (xr7):40 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; /* 0x40 ??? Should it be 0x00? */ - - /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */ - /* 12,33,5A,C3 ; 770 Hz */ - /* 13,3C,5B,32 ; 852 Hz */ - /* 1D,1B,5C,CC ; 941 Hz */ - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C; - - /* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */ - /* EC,1D,52,22 ; 1336 Hz */ - /* AA,AC,51,D2 ; 1477 Hz */ - /* 9B,3B,51,25 ; 1633 Hz */ - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3; -} - -static void DAA_Coeff_Japan(IXJ *j) -{ - int i; - - j->daa_country = DAA_JAPAN; - /*----------------------------------------------- */ - /* CAO */ - for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) { - j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0; - } - -/* Bytes for IM-filter part 1 (04): 06,BD,E2,2D,BA,F9,A0,00 */ - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x06; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xBD; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xE2; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x2D; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xF9; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00; -/* Bytes for IM-filter part 2 (05): 6F,F7,00,0E,34,33,E0,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x6F; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0xF7; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0E; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0x34; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08; -/* Bytes for FRX-filter (08): 02,8F,68,77,9C,58,F0,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x02; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x8F; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0x68; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x77; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x9C; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x58; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xF0; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08; -/* Bytes for FRR-filter (07): 03,8F,38,73,87,EA,20,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x03; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x8F; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0x38; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x73; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x87; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xEA; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x20; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08; -/* Bytes for AX-filter (0A): 51,C5,DD,CA */ - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x51; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xC5; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA; -/* Bytes for AR-filter (09): 25,A7,10,D6 */ - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x25; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xA7; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6; -/* Bytes for TH-filter part 1 (00): 00,42,48,81,AE,80,00,98 */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xAE; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98; -/* Bytes for TH-filter part 2 (01): 02,AB,2A,20,99,5B,89,28 */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xAB; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x2A; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0x20; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x5B; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x89; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x28; -/* Bytes for TH-filter part 3 (02): 00,88,DA,25,34,C5,4C,BA */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0xDA; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x25; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0x34; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xC5; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x4C; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xBA; -/* ; idle */ - /* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */ - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23; -/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */ - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5; -/* Levelmetering Ringing (0D):AA,35,0F,8E ; 25Hz 30V ????????? */ - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E; -/* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */ - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99; -/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */ - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00; -/* ;CR Registers */ - /* Config. Reg. 0 (filters) (cr0):FF */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF; -/* Config. Reg. 1 (dialing) (cr1):05 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05; -/* Config. Reg. 2 (caller ID) (cr2):04 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04; -/* Config. Reg. 3 (testloops) (cr3):00 ; */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00; -/* Config. Reg. 4 (analog gain) (cr4):02 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; - /* Config. Reg. 5 (Version) (cr5):02 */ - /* Config. Reg. 6 (Reserved) (cr6):00 */ - /* Config. Reg. 7 (Reserved) (cr7):00 */ - /* ;xr Registers */ - /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */ - - j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */ - /* Ext. Reg. 1 (Interrupt enable) (xr1):1C */ - - j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; /* RING, Caller ID, VDD_OK */ - /* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */ - - j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D; -/* Ext. Reg. 3 (DC Char) (xr3):22 ; */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x22; -/* Ext. Reg. 4 (Cadence) (xr4):00 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00; -/* Ext. Reg. 5 (Ring timer) (xr5):22 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22; -/* Ext. Reg. 6 (Power State) (xr6):00 */ - j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00; -/* Ext. Reg. 7 (Vdd) (xr7):40 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; /* 0x40 ??? Should it be 0x00? */ - /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */ - /* 12,33,5A,C3 ; 770 Hz */ - /* 13,3C,5B,32 ; 852 Hz */ - /* 1D,1B,5C,CC ; 941 Hz */ - - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C; -/* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */ - /* EC,1D,52,22 ; 1336 Hz */ - /* AA,AC,51,D2 ; 1477 Hz */ - /* 9B,3B,51,25 ; 1633 Hz */ - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3; -} - -static s16 tone_table[][19] = -{ - { /* f20_50[] 11 */ - 32538, /* A1 = 1.985962 */ - -32325, /* A2 = -0.986511 */ - -343, /* B2 = -0.010493 */ - 0, /* B1 = 0 */ - 343, /* B0 = 0.010493 */ - 32619, /* A1 = 1.990906 */ - -32520, /* A2 = -0.992462 */ - 19179, /* B2 = 0.585327 */ - -19178, /* B1 = -1.170593 */ - 19179, /* B0 = 0.585327 */ - 32723, /* A1 = 1.997314 */ - -32686, /* A2 = -0.997528 */ - 9973, /* B2 = 0.304352 */ - -9955, /* B1 = -0.607605 */ - 9973, /* B0 = 0.304352 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f133_200[] 12 */ - 32072, /* A1 = 1.95752 */ - -31896, /* A2 = -0.973419 */ - -435, /* B2 = -0.013294 */ - 0, /* B1 = 0 */ - 435, /* B0 = 0.013294 */ - 32188, /* A1 = 1.9646 */ - -32400, /* A2 = -0.98877 */ - 15139, /* B2 = 0.462036 */ - -14882, /* B1 = -0.908356 */ - 15139, /* B0 = 0.462036 */ - 32473, /* A1 = 1.981995 */ - -32524, /* A2 = -0.992584 */ - 23200, /* B2 = 0.708008 */ - -23113, /* B1 = -1.410706 */ - 23200, /* B0 = 0.708008 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f300 13 */ - 31769, /* A1 = -1.939026 */ - -32584, /* A2 = 0.994385 */ - -475, /* B2 = -0.014522 */ - 0, /* B1 = 0.000000 */ - 475, /* B0 = 0.014522 */ - 31789, /* A1 = -1.940247 */ - -32679, /* A2 = 0.997284 */ - 17280, /* B2 = 0.527344 */ - -16865, /* B1 = -1.029358 */ - 17280, /* B0 = 0.527344 */ - 31841, /* A1 = -1.943481 */ - -32681, /* A2 = 0.997345 */ - 543, /* B2 = 0.016579 */ - -525, /* B1 = -0.032097 */ - 543, /* B0 = 0.016579 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f300_420[] 14 */ - 30750, /* A1 = 1.876892 */ - -31212, /* A2 = -0.952515 */ - -804, /* B2 = -0.024541 */ - 0, /* B1 = 0 */ - 804, /* B0 = 0.024541 */ - 30686, /* A1 = 1.872925 */ - -32145, /* A2 = -0.980988 */ - 14747, /* B2 = 0.450043 */ - -13703, /* B1 = -0.836395 */ - 14747, /* B0 = 0.450043 */ - 31651, /* A1 = 1.931824 */ - -32321, /* A2 = -0.986389 */ - 24425, /* B2 = 0.745422 */ - -23914, /* B1 = -1.459595 */ - 24427, /* B0 = 0.745483 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f330 15 */ - 31613, /* A1 = -1.929565 */ - -32646, /* A2 = 0.996277 */ - -185, /* B2 = -0.005657 */ - 0, /* B1 = 0.000000 */ - 185, /* B0 = 0.005657 */ - 31620, /* A1 = -1.929932 */ - -32713, /* A2 = 0.998352 */ - 19253, /* B2 = 0.587585 */ - -18566, /* B1 = -1.133179 */ - 19253, /* B0 = 0.587585 */ - 31674, /* A1 = -1.933228 */ - -32715, /* A2 = 0.998413 */ - 2575, /* B2 = 0.078590 */ - -2495, /* B1 = -0.152283 */ - 2575, /* B0 = 0.078590 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f300_425[] 16 */ - 30741, /* A1 = 1.876282 */ - -31475, /* A2 = -0.960541 */ - -703, /* B2 = -0.021484 */ - 0, /* B1 = 0 */ - 703, /* B0 = 0.021484 */ - 30688, /* A1 = 1.873047 */ - -32248, /* A2 = -0.984161 */ - 14542, /* B2 = 0.443787 */ - -13523, /* B1 = -0.825439 */ - 14542, /* B0 = 0.443817 */ - 31494, /* A1 = 1.922302 */ - -32366, /* A2 = -0.987762 */ - 21577, /* B2 = 0.658508 */ - -21013, /* B1 = -1.282532 */ - 21577, /* B0 = 0.658508 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f330_440[] 17 */ - 30627, /* A1 = 1.869324 */ - -31338, /* A2 = -0.95636 */ - -843, /* B2 = -0.025749 */ - 0, /* B1 = 0 */ - 843, /* B0 = 0.025749 */ - 30550, /* A1 = 1.864685 */ - -32221, /* A2 = -0.983337 */ - 13594, /* B2 = 0.414886 */ - -12589, /* B1 = -0.768402 */ - 13594, /* B0 = 0.414886 */ - 31488, /* A1 = 1.921936 */ - -32358, /* A2 = -0.987518 */ - 24684, /* B2 = 0.753296 */ - -24029, /* B1 = -1.466614 */ - 24684, /* B0 = 0.753296 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f340 18 */ - 31546, /* A1 = -1.925476 */ - -32646, /* A2 = 0.996277 */ - -445, /* B2 = -0.013588 */ - 0, /* B1 = 0.000000 */ - 445, /* B0 = 0.013588 */ - 31551, /* A1 = -1.925781 */ - -32713, /* A2 = 0.998352 */ - 23884, /* B2 = 0.728882 */ - -22979, /* B1 = -1.402527 */ - 23884, /* B0 = 0.728882 */ - 31606, /* A1 = -1.929138 */ - -32715, /* A2 = 0.998413 */ - 863, /* B2 = 0.026367 */ - -835, /* B1 = -0.050985 */ - 863, /* B0 = 0.026367 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f350_400[] 19 */ - 31006, /* A1 = 1.892517 */ - -32029, /* A2 = -0.977448 */ - -461, /* B2 = -0.014096 */ - 0, /* B1 = 0 */ - 461, /* B0 = 0.014096 */ - 30999, /* A1 = 1.892029 */ - -32487, /* A2 = -0.991455 */ - 11325, /* B2 = 0.345612 */ - -10682, /* B1 = -0.651978 */ - 11325, /* B0 = 0.345612 */ - 31441, /* A1 = 1.919067 */ - -32526, /* A2 = -0.992615 */ - 24324, /* B2 = 0.74231 */ - -23535, /* B1 = -1.436523 */ - 24324, /* B0 = 0.74231 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f350_440[] */ - 30634, /* A1 = 1.869751 */ - -31533, /* A2 = -0.962341 */ - -680, /* B2 = -0.020782 */ - 0, /* B1 = 0 */ - 680, /* B0 = 0.020782 */ - 30571, /* A1 = 1.865906 */ - -32277, /* A2 = -0.985016 */ - 12894, /* B2 = 0.393524 */ - -11945, /* B1 = -0.729065 */ - 12894, /* B0 = 0.393524 */ - 31367, /* A1 = 1.91449 */ - -32379, /* A2 = -0.988129 */ - 23820, /* B2 = 0.726929 */ - -23104, /* B1 = -1.410217 */ - 23820, /* B0 = 0.726929 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f350_450[] */ - 30552, /* A1 = 1.864807 */ - -31434, /* A2 = -0.95929 */ - -690, /* B2 = -0.021066 */ - 0, /* B1 = 0 */ - 690, /* B0 = 0.021066 */ - 30472, /* A1 = 1.859924 */ - -32248, /* A2 = -0.984161 */ - 13385, /* B2 = 0.408478 */ - -12357, /* B1 = -0.754242 */ - 13385, /* B0 = 0.408478 */ - 31358, /* A1 = 1.914001 */ - -32366, /* A2 = -0.987732 */ - 26488, /* B2 = 0.80835 */ - -25692, /* B1 = -1.568176 */ - 26490, /* B0 = 0.808411 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f360 */ - 31397, /* A1 = -1.916321 */ - -32623, /* A2 = 0.995605 */ - -117, /* B2 = -0.003598 */ - 0, /* B1 = 0.000000 */ - 117, /* B0 = 0.003598 */ - 31403, /* A1 = -1.916687 */ - -32700, /* A2 = 0.997925 */ - 3388, /* B2 = 0.103401 */ - -3240, /* B1 = -0.197784 */ - 3388, /* B0 = 0.103401 */ - 31463, /* A1 = -1.920410 */ - -32702, /* A2 = 0.997986 */ - 13346, /* B2 = 0.407288 */ - -12863, /* B1 = -0.785126 */ - 13346, /* B0 = 0.407288 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f380_420[] */ - 30831, /* A1 = 1.881775 */ - -32064, /* A2 = -0.978546 */ - -367, /* B2 = -0.01122 */ - 0, /* B1 = 0 */ - 367, /* B0 = 0.01122 */ - 30813, /* A1 = 1.880737 */ - -32456, /* A2 = -0.990509 */ - 11068, /* B2 = 0.337769 */ - -10338, /* B1 = -0.631042 */ - 11068, /* B0 = 0.337769 */ - 31214, /* A1 = 1.905212 */ - -32491, /* A2 = -0.991577 */ - 16374, /* B2 = 0.499695 */ - -15781, /* B1 = -0.963196 */ - 16374, /* B0 = 0.499695 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f392 */ - 31152, /* A1 = -1.901428 */ - -32613, /* A2 = 0.995300 */ - -314, /* B2 = -0.009605 */ - 0, /* B1 = 0.000000 */ - 314, /* B0 = 0.009605 */ - 31156, /* A1 = -1.901672 */ - -32694, /* A2 = 0.997742 */ - 28847, /* B2 = 0.880371 */ - -2734, /* B1 = -0.166901 */ - 28847, /* B0 = 0.880371 */ - 31225, /* A1 = -1.905823 */ - -32696, /* A2 = 0.997803 */ - 462, /* B2 = 0.014108 */ - -442, /* B1 = -0.027019 */ - 462, /* B0 = 0.014108 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f400_425[] */ - 30836, /* A1 = 1.882141 */ - -32296, /* A2 = -0.985596 */ - -324, /* B2 = -0.009903 */ - 0, /* B1 = 0 */ - 324, /* B0 = 0.009903 */ - 30825, /* A1 = 1.881409 */ - -32570, /* A2 = -0.993958 */ - 16847, /* B2 = 0.51416 */ - -15792, /* B1 = -0.963898 */ - 16847, /* B0 = 0.51416 */ - 31106, /* A1 = 1.89856 */ - -32584, /* A2 = -0.994415 */ - 9579, /* B2 = 0.292328 */ - -9164, /* B1 = -0.559357 */ - 9579, /* B0 = 0.292328 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f400_440[] */ - 30702, /* A1 = 1.873962 */ - -32134, /* A2 = -0.980682 */ - -517, /* B2 = -0.015793 */ - 0, /* B1 = 0 */ - 517, /* B0 = 0.015793 */ - 30676, /* A1 = 1.872375 */ - -32520, /* A2 = -0.992462 */ - 8144, /* B2 = 0.24855 */ - -7596, /* B1 = -0.463684 */ - 8144, /* B0 = 0.24855 */ - 31084, /* A1 = 1.897217 */ - -32547, /* A2 = -0.993256 */ - 22713, /* B2 = 0.693176 */ - -21734, /* B1 = -1.326599 */ - 22713, /* B0 = 0.693176 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f400_450[] */ - 30613, /* A1 = 1.86853 */ - -32031, /* A2 = -0.977509 */ - -618, /* B2 = -0.018866 */ - 0, /* B1 = 0 */ - 618, /* B0 = 0.018866 */ - 30577, /* A1 = 1.866272 */ - -32491, /* A2 = -0.991577 */ - 9612, /* B2 = 0.293335 */ - -8935, /* B1 = -0.54541 */ - 9612, /* B0 = 0.293335 */ - 31071, /* A1 = 1.896484 */ - -32524, /* A2 = -0.992584 */ - 21596, /* B2 = 0.659058 */ - -20667, /* B1 = -1.261414 */ - 21596, /* B0 = 0.659058 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f420 */ - 30914, /* A1 = -1.886841 */ - -32584, /* A2 = 0.994385 */ - -426, /* B2 = -0.013020 */ - 0, /* B1 = 0.000000 */ - 426, /* B0 = 0.013020 */ - 30914, /* A1 = -1.886841 */ - -32679, /* A2 = 0.997314 */ - 17520, /* B2 = 0.534668 */ - -16471, /* B1 = -1.005310 */ - 17520, /* B0 = 0.534668 */ - 31004, /* A1 = -1.892334 */ - -32683, /* A2 = 0.997406 */ - 819, /* B2 = 0.025023 */ - -780, /* B1 = -0.047619 */ - 819, /* B0 = 0.025023 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, -#if 0 - { /* f425 */ - 30881, /* A1 = -1.884827 */ - -32603, /* A2 = 0.994965 */ - -496, /* B2 = -0.015144 */ - 0, /* B1 = 0.000000 */ - 496, /* B0 = 0.015144 */ - 30880, /* A1 = -1.884766 */ - -32692, /* A2 = 0.997711 */ - 24767, /* B2 = 0.755859 */ - -23290, /* B1 = -1.421509 */ - 24767, /* B0 = 0.755859 */ - 30967, /* A1 = -1.890076 */ - -32694, /* A2 = 0.997772 */ - 728, /* B2 = 0.022232 */ - -691, /* B1 = -0.042194 */ - 728, /* B0 = 0.022232 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, -#else - { - 30850, - -32534, - -504, - 0, - 504, - 30831, - -32669, - 24303, - -22080, - 24303, - 30994, - -32673, - 1905, - -1811, - 1905, - 5, - 129, - 17, - 0xff5 - }, -#endif - { /* f425_450[] */ - 30646, /* A1 = 1.870544 */ - -32327, /* A2 = -0.986572 */ - -287, /* B2 = -0.008769 */ - 0, /* B1 = 0 */ - 287, /* B0 = 0.008769 */ - 30627, /* A1 = 1.869324 */ - -32607, /* A2 = -0.995087 */ - 13269, /* B2 = 0.404968 */ - -12376, /* B1 = -0.755432 */ - 13269, /* B0 = 0.404968 */ - 30924, /* A1 = 1.887512 */ - -32619, /* A2 = -0.995453 */ - 19950, /* B2 = 0.608826 */ - -18940, /* B1 = -1.156006 */ - 19950, /* B0 = 0.608826 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f425_475[] */ - 30396, /* A1 = 1.855225 */ - -32014, /* A2 = -0.97699 */ - -395, /* B2 = -0.012055 */ - 0, /* B1 = 0 */ - 395, /* B0 = 0.012055 */ - 30343, /* A1 = 1.85199 */ - -32482, /* A2 = -0.991302 */ - 17823, /* B2 = 0.543945 */ - -16431, /* B1 = -1.002869 */ - 17823, /* B0 = 0.543945 */ - 30872, /* A1 = 1.884338 */ - -32516, /* A2 = -0.99231 */ - 18124, /* B2 = 0.553101 */ - -17246, /* B1 = -1.052673 */ - 18124, /* B0 = 0.553101 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f435 */ - 30796, /* A1 = -1.879639 */ - -32603, /* A2 = 0.994965 */ - -254, /* B2 = -0.007762 */ - 0, /* B1 = 0.000000 */ - 254, /* B0 = 0.007762 */ - 30793, /* A1 = -1.879456 */ - -32692, /* A2 = 0.997711 */ - 18934, /* B2 = 0.577820 */ - -17751, /* B1 = -1.083496 */ - 18934, /* B0 = 0.577820 */ - 30882, /* A1 = -1.884888 */ - -32694, /* A2 = 0.997772 */ - 1858, /* B2 = 0.056713 */ - -1758, /* B1 = -0.107357 */ - 1858, /* B0 = 0.056713 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f440_450[] */ - 30641, /* A1 = 1.870239 */ - -32458, /* A2 = -0.99057 */ - -155, /* B2 = -0.004735 */ - 0, /* B1 = 0 */ - 155, /* B0 = 0.004735 */ - 30631, /* A1 = 1.869568 */ - -32630, /* A2 = -0.995789 */ - 11453, /* B2 = 0.349548 */ - -10666, /* B1 = -0.651001 */ - 11453, /* B0 = 0.349548 */ - 30810, /* A1 = 1.880554 */ - -32634, /* A2 = -0.995941 */ - 12237, /* B2 = 0.373474 */ - -11588, /* B1 = -0.707336 */ - 12237, /* B0 = 0.373474 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f440_480[] */ - 30367, /* A1 = 1.853455 */ - -32147, /* A2 = -0.981079 */ - -495, /* B2 = -0.015113 */ - 0, /* B1 = 0 */ - 495, /* B0 = 0.015113 */ - 30322, /* A1 = 1.850769 */ - -32543, /* A2 = -0.993134 */ - 10031, /* B2 = 0.306152 */ - -9252, /* B1 = -0.564728 */ - 10031, /* B0 = 0.306152 */ - 30770, /* A1 = 1.878052 */ - -32563, /* A2 = -0.993774 */ - 22674, /* B2 = 0.691956 */ - -21465, /* B1 = -1.31012 */ - 22674, /* B0 = 0.691956 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f445 */ - 30709, /* A1 = -1.874329 */ - -32603, /* A2 = 0.994965 */ - -83, /* B2 = -0.002545 */ - 0, /* B1 = 0.000000 */ - 83, /* B0 = 0.002545 */ - 30704, /* A1 = -1.874084 */ - -32692, /* A2 = 0.997711 */ - 10641, /* B2 = 0.324738 */ - -9947, /* B1 = -0.607147 */ - 10641, /* B0 = 0.324738 */ - 30796, /* A1 = -1.879639 */ - -32694, /* A2 = 0.997772 */ - 10079, /* B2 = 0.307587 */ - 9513, /* B1 = 0.580688 */ - 10079, /* B0 = 0.307587 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f450 */ - 30664, /* A1 = -1.871643 */ - -32603, /* A2 = 0.994965 */ - -164, /* B2 = -0.005029 */ - 0, /* B1 = 0.000000 */ - 164, /* B0 = 0.005029 */ - 30661, /* A1 = -1.871399 */ - -32692, /* A2 = 0.997711 */ - 15294, /* B2 = 0.466736 */ - -14275, /* B1 = -0.871307 */ - 15294, /* B0 = 0.466736 */ - 30751, /* A1 = -1.876953 */ - -32694, /* A2 = 0.997772 */ - 3548, /* B2 = 0.108284 */ - -3344, /* B1 = -0.204155 */ - 3548, /* B0 = 0.108284 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f452 */ - 30653, /* A1 = -1.870911 */ - -32615, /* A2 = 0.995361 */ - -209, /* B2 = -0.006382 */ - 0, /* B1 = 0.000000 */ - 209, /* B0 = 0.006382 */ - 30647, /* A1 = -1.870605 */ - -32702, /* A2 = 0.997986 */ - 18971, /* B2 = 0.578979 */ - -17716, /* B1 = -1.081299 */ - 18971, /* B0 = 0.578979 */ - 30738, /* A1 = -1.876099 */ - -32702, /* A2 = 0.998016 */ - 2967, /* B2 = 0.090561 */ - -2793, /* B1 = -0.170502 */ - 2967, /* B0 = 0.090561 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f475 */ - 30437, /* A1 = -1.857727 */ - -32603, /* A2 = 0.994965 */ - -264, /* B2 = -0.008062 */ - 0, /* B1 = 0.000000 */ - 264, /* B0 = 0.008062 */ - 30430, /* A1 = -1.857300 */ - -32692, /* A2 = 0.997711 */ - 21681, /* B2 = 0.661682 */ - -20082, /* B1 = -1.225708 */ - 21681, /* B0 = 0.661682 */ - 30526, /* A1 = -1.863220 */ - -32694, /* A2 = 0.997742 */ - 1559, /* B2 = 0.047600 */ - -1459, /* B1 = -0.089096 */ - 1559, /* B0 = 0.047600 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f480_620[] */ - 28975, /* A1 = 1.768494 */ - -30955, /* A2 = -0.944672 */ - -1026, /* B2 = -0.03133 */ - 0, /* B1 = 0 */ - 1026, /* B0 = 0.03133 */ - 28613, /* A1 = 1.746399 */ - -32089, /* A2 = -0.979309 */ - 14214, /* B2 = 0.433807 */ - -12202, /* B1 = -0.744812 */ - 14214, /* B0 = 0.433807 */ - 30243, /* A1 = 1.845947 */ - -32238, /* A2 = -0.983856 */ - 24825, /* B2 = 0.757629 */ - -23402, /* B1 = -1.428345 */ - 24825, /* B0 = 0.757629 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f494 */ - 30257, /* A1 = -1.846741 */ - -32605, /* A2 = 0.995056 */ - -249, /* B2 = -0.007625 */ - 0, /* B1 = 0.000000 */ - 249, /* B0 = 0.007625 */ - 30247, /* A1 = -1.846191 */ - -32694, /* A2 = 0.997772 */ - 18088, /* B2 = 0.552002 */ - -16652, /* B1 = -1.016418 */ - 18088, /* B0 = 0.552002 */ - 30348, /* A1 = -1.852295 */ - -32696, /* A2 = 0.997803 */ - 2099, /* B2 = 0.064064 */ - -1953, /* B1 = -0.119202 */ - 2099, /* B0 = 0.064064 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f500 */ - 30202, /* A1 = -1.843431 */ - -32624, /* A2 = 0.995622 */ - -413, /* B2 = -0.012622 */ - 0, /* B1 = 0.000000 */ - 413, /* B0 = 0.012622 */ - 30191, /* A1 = -1.842721 */ - -32714, /* A2 = 0.998364 */ - 25954, /* B2 = 0.792057 */ - -23890, /* B1 = -1.458131 */ - 25954, /* B0 = 0.792057 */ - 30296, /* A1 = -1.849172 */ - -32715, /* A2 = 0.998397 */ - 2007, /* B2 = 0.061264 */ - -1860, /* B1 = -0.113568 */ - 2007, /* B0 = 0.061264 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f520 */ - 30001, /* A1 = -1.831116 */ - -32613, /* A2 = 0.995270 */ - -155, /* B2 = -0.004750 */ - 0, /* B1 = 0.000000 */ - 155, /* B0 = 0.004750 */ - 29985, /* A1 = -1.830200 */ - -32710, /* A2 = 0.998260 */ - 6584, /* B2 = 0.200928 */ - -6018, /* B1 = -0.367355 */ - 6584, /* B0 = 0.200928 */ - 30105, /* A1 = -1.837524 */ - -32712, /* A2 = 0.998291 */ - 23812, /* B2 = 0.726685 */ - -21936, /* B1 = -1.338928 */ - 23812, /* B0 = 0.726685 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f523 */ - 29964, /* A1 = -1.828918 */ - -32601, /* A2 = 0.994904 */ - -101, /* B2 = -0.003110 */ - 0, /* B1 = 0.000000 */ - 101, /* B0 = 0.003110 */ - 29949, /* A1 = -1.827942 */ - -32700, /* A2 = 0.997925 */ - 11041, /* B2 = 0.336975 */ - -10075, /* B1 = -0.614960 */ - 11041, /* B0 = 0.336975 */ - 30070, /* A1 = -1.835388 */ - -32702, /* A2 = 0.997986 */ - 16762, /* B2 = 0.511536 */ - -15437, /* B1 = -0.942230 */ - 16762, /* B0 = 0.511536 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f525 */ - 29936, /* A1 = -1.827209 */ - -32584, /* A2 = 0.994415 */ - -91, /* B2 = -0.002806 */ - 0, /* B1 = 0.000000 */ - 91, /* B0 = 0.002806 */ - 29921, /* A1 = -1.826233 */ - -32688, /* A2 = 0.997559 */ - 11449, /* B2 = 0.349396 */ - -10426, /* B1 = -0.636383 */ - 11449, /* B0 = 0.349396 */ - 30045, /* A1 = -1.833862 */ - -32688, /* A2 = 0.997589 */ - 13055, /* B2 = 0.398407 */ - -12028, /* B1 = -0.734161 */ - 13055, /* B0 = 0.398407 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f540_660[] */ - 28499, /* A1 = 1.739441 */ - -31129, /* A2 = -0.949982 */ - -849, /* B2 = -0.025922 */ - 0, /* B1 = 0 */ - 849, /* B0 = 0.025922 */ - 28128, /* A1 = 1.716797 */ - -32130, /* A2 = -0.98056 */ - 14556, /* B2 = 0.444214 */ - -12251, /* B1 = -0.747772 */ - 14556, /* B0 = 0.444244 */ - 29667, /* A1 = 1.81073 */ - -32244, /* A2 = -0.984039 */ - 23038, /* B2 = 0.703064 */ - -21358, /* B1 = -1.303589 */ - 23040, /* B0 = 0.703125 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f587 */ - 29271, /* A1 = -1.786560 */ - -32599, /* A2 = 0.994873 */ - -490, /* B2 = -0.014957 */ - 0, /* B1 = 0.000000 */ - 490, /* B0 = 0.014957 */ - 29246, /* A1 = -1.785095 */ - -32700, /* A2 = 0.997925 */ - 28961, /* B2 = 0.883850 */ - -25796, /* B1 = -1.574463 */ - 28961, /* B0 = 0.883850 */ - 29383, /* A1 = -1.793396 */ - -32700, /* A2 = 0.997955 */ - 1299, /* B2 = 0.039650 */ - -1169, /* B1 = -0.071396 */ - 1299, /* B0 = 0.039650 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f590 */ - 29230, /* A1 = -1.784058 */ - -32584, /* A2 = 0.994415 */ - -418, /* B2 = -0.012757 */ - 0, /* B1 = 0.000000 */ - 418, /* B0 = 0.012757 */ - 29206, /* A1 = -1.782593 */ - -32688, /* A2 = 0.997559 */ - 36556, /* B2 = 1.115601 */ - -32478, /* B1 = -1.982300 */ - 36556, /* B0 = 1.115601 */ - 29345, /* A1 = -1.791077 */ - -32688, /* A2 = 0.997589 */ - 897, /* B2 = 0.027397 */ - -808, /* B1 = -0.049334 */ - 897, /* B0 = 0.027397 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f600 */ - 29116, /* A1 = -1.777100 */ - -32603, /* A2 = 0.994965 */ - -165, /* B2 = -0.005039 */ - 0, /* B1 = 0.000000 */ - 165, /* B0 = 0.005039 */ - 29089, /* A1 = -1.775452 */ - -32708, /* A2 = 0.998199 */ - 6963, /* B2 = 0.212494 */ - -6172, /* B1 = -0.376770 */ - 6963, /* B0 = 0.212494 */ - 29237, /* A1 = -1.784485 */ - -32710, /* A2 = 0.998230 */ - 24197, /* B2 = 0.738464 */ - -21657, /* B1 = -1.321899 */ - 24197, /* B0 = 0.738464 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f660 */ - 28376, /* A1 = -1.731934 */ - -32567, /* A2 = 0.993896 */ - -363, /* B2 = -0.011102 */ - 0, /* B1 = 0.000000 */ - 363, /* B0 = 0.011102 */ - 28337, /* A1 = -1.729614 */ - -32683, /* A2 = 0.997434 */ - 21766, /* B2 = 0.664246 */ - -18761, /* B1 = -1.145081 */ - 21766, /* B0 = 0.664246 */ - 28513, /* A1 = -1.740356 */ - -32686, /* A2 = 0.997498 */ - 2509, /* B2 = 0.076584 */ - -2196, /* B1 = -0.134041 */ - 2509, /* B0 = 0.076584 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f700 */ - 27844, /* A1 = -1.699463 */ - -32563, /* A2 = 0.993744 */ - -366, /* B2 = -0.011187 */ - 0, /* B1 = 0.000000 */ - 366, /* B0 = 0.011187 */ - 27797, /* A1 = -1.696655 */ - -32686, /* A2 = 0.997498 */ - 22748, /* B2 = 0.694214 */ - -19235, /* B1 = -1.174072 */ - 22748, /* B0 = 0.694214 */ - 27995, /* A1 = -1.708740 */ - -32688, /* A2 = 0.997559 */ - 2964, /* B2 = 0.090477 */ - -2546, /* B1 = -0.155449 */ - 2964, /* B0 = 0.090477 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f740 */ - 27297, /* A1 = -1.666077 */ - -32551, /* A2 = 0.993408 */ - -345, /* B2 = -0.010540 */ - 0, /* B1 = 0.000000 */ - 345, /* B0 = 0.010540 */ - 27240, /* A1 = -1.662598 */ - -32683, /* A2 = 0.997406 */ - 22560, /* B2 = 0.688477 */ - -18688, /* B1 = -1.140625 */ - 22560, /* B0 = 0.688477 */ - 27461, /* A1 = -1.676147 */ - -32684, /* A2 = 0.997467 */ - 3541, /* B2 = 0.108086 */ - -2985, /* B1 = -0.182220 */ - 3541, /* B0 = 0.108086 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f750 */ - 27155, /* A1 = -1.657410 */ - -32551, /* A2 = 0.993408 */ - -462, /* B2 = -0.014117 */ - 0, /* B1 = 0.000000 */ - 462, /* B0 = 0.014117 */ - 27097, /* A1 = -1.653870 */ - -32683, /* A2 = 0.997406 */ - 32495, /* B2 = 0.991699 */ - -26776, /* B1 = -1.634338 */ - 32495, /* B0 = 0.991699 */ - 27321, /* A1 = -1.667542 */ - -32684, /* A2 = 0.997467 */ - 1835, /* B2 = 0.056007 */ - -1539, /* B1 = -0.093948 */ - 1835, /* B0 = 0.056007 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f750_1450[] */ - 19298, /* A1 = 1.177917 */ - -24471, /* A2 = -0.746796 */ - -4152, /* B2 = -0.126709 */ - 0, /* B1 = 0 */ - 4152, /* B0 = 0.126709 */ - 12902, /* A1 = 0.787476 */ - -29091, /* A2 = -0.887817 */ - 12491, /* B2 = 0.38121 */ - -1794, /* B1 = -0.109528 */ - 12494, /* B0 = 0.381317 */ - 26291, /* A1 = 1.604736 */ - -30470, /* A2 = -0.929901 */ - 28859, /* B2 = 0.880737 */ - -26084, /* B1 = -1.592102 */ - 28861, /* B0 = 0.880798 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f770 */ - 26867, /* A1 = -1.639832 */ - -32551, /* A2 = 0.993408 */ - -123, /* B2 = -0.003755 */ - 0, /* B1 = 0.000000 */ - 123, /* B0 = 0.003755 */ - 26805, /* A1 = -1.636108 */ - -32683, /* A2 = 0.997406 */ - 17297, /* B2 = 0.527863 */ - -14096, /* B1 = -0.860382 */ - 17297, /* B0 = 0.527863 */ - 27034, /* A1 = -1.650085 */ - -32684, /* A2 = 0.997467 */ - 12958, /* B2 = 0.395477 */ - -10756, /* B1 = -0.656525 */ - 12958, /* B0 = 0.395477 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f800 */ - 26413, /* A1 = -1.612122 */ - -32547, /* A2 = 0.993286 */ - -223, /* B2 = -0.006825 */ - 0, /* B1 = 0.000000 */ - 223, /* B0 = 0.006825 */ - 26342, /* A1 = -1.607849 */ - -32686, /* A2 = 0.997498 */ - 6391, /* B2 = 0.195053 */ - -5120, /* B1 = -0.312531 */ - 6391, /* B0 = 0.195053 */ - 26593, /* A1 = -1.623108 */ - -32688, /* A2 = 0.997559 */ - 23681, /* B2 = 0.722717 */ - -19328, /* B1 = -1.179688 */ - 23681, /* B0 = 0.722717 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f816 */ - 26168, /* A1 = -1.597209 */ - -32528, /* A2 = 0.992706 */ - -235, /* B2 = -0.007182 */ - 0, /* B1 = 0.000000 */ - 235, /* B0 = 0.007182 */ - 26092, /* A1 = -1.592590 */ - -32675, /* A2 = 0.997192 */ - 20823, /* B2 = 0.635498 */ - -16510, /* B1 = -1.007751 */ - 20823, /* B0 = 0.635498 */ - 26363, /* A1 = -1.609070 */ - -32677, /* A2 = 0.997253 */ - 6739, /* B2 = 0.205688 */ - -5459, /* B1 = -0.333206 */ - 6739, /* B0 = 0.205688 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f850 */ - 25641, /* A1 = -1.565063 */ - -32536, /* A2 = 0.992950 */ - -121, /* B2 = -0.003707 */ - 0, /* B1 = 0.000000 */ - 121, /* B0 = 0.003707 */ - 25560, /* A1 = -1.560059 */ - -32684, /* A2 = 0.997437 */ - 18341, /* B2 = 0.559753 */ - -14252, /* B1 = -0.869904 */ - 18341, /* B0 = 0.559753 */ - 25837, /* A1 = -1.577026 */ - -32684, /* A2 = 0.997467 */ - 16679, /* B2 = 0.509003 */ - -13232, /* B1 = -0.807648 */ - 16679, /* B0 = 0.509003 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f857_1645[] */ - 16415, /* A1 = 1.001953 */ - -23669, /* A2 = -0.722321 */ - -4549, /* B2 = -0.138847 */ - 0, /* B1 = 0 */ - 4549, /* B0 = 0.138847 */ - 8456, /* A1 = 0.516174 */ - -28996, /* A2 = -0.884918 */ - 13753, /* B2 = 0.419724 */ - -12, /* B1 = -0.000763 */ - 13757, /* B0 = 0.419846 */ - 24632, /* A1 = 1.503418 */ - -30271, /* A2 = -0.923828 */ - 29070, /* B2 = 0.887146 */ - -25265, /* B1 = -1.542114 */ - 29073, /* B0 = 0.887268 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f900 */ - 24806, /* A1 = -1.514099 */ - -32501, /* A2 = 0.991852 */ - -326, /* B2 = -0.009969 */ - 0, /* B1 = 0.000000 */ - 326, /* B0 = 0.009969 */ - 24709, /* A1 = -1.508118 */ - -32659, /* A2 = 0.996674 */ - 20277, /* B2 = 0.618835 */ - -15182, /* B1 = -0.926636 */ - 20277, /* B0 = 0.618835 */ - 25022, /* A1 = -1.527222 */ - -32661, /* A2 = 0.996735 */ - 4320, /* B2 = 0.131836 */ - -3331, /* B1 = -0.203339 */ - 4320, /* B0 = 0.131836 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f900_1300[] */ - 19776, /* A1 = 1.207092 */ - -27437, /* A2 = -0.837341 */ - -2666, /* B2 = -0.081371 */ - 0, /* B1 = 0 */ - 2666, /* B0 = 0.081371 */ - 16302, /* A1 = 0.995026 */ - -30354, /* A2 = -0.926361 */ - 10389, /* B2 = 0.317062 */ - -3327, /* B1 = -0.203064 */ - 10389, /* B0 = 0.317062 */ - 24299, /* A1 = 1.483154 */ - -30930, /* A2 = -0.943909 */ - 25016, /* B2 = 0.763428 */ - -21171, /* B1 = -1.292236 */ - 25016, /* B0 = 0.763428 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f935_1215[] */ - 20554, /* A1 = 1.254517 */ - -28764, /* A2 = -0.877838 */ - -2048, /* B2 = -0.062515 */ - 0, /* B1 = 0 */ - 2048, /* B0 = 0.062515 */ - 18209, /* A1 = 1.11145 */ - -30951, /* A2 = -0.94458 */ - 9390, /* B2 = 0.286575 */ - -3955, /* B1 = -0.241455 */ - 9390, /* B0 = 0.286575 */ - 23902, /* A1 = 1.458923 */ - -31286, /* A2 = -0.954803 */ - 23252, /* B2 = 0.709595 */ - -19132, /* B1 = -1.167725 */ - 23252, /* B0 = 0.709595 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f941_1477[] */ - 17543, /* A1 = 1.07074 */ - -26220, /* A2 = -0.800201 */ - -3298, /* B2 = -0.100647 */ - 0, /* B1 = 0 */ - 3298, /* B0 = 0.100647 */ - 12423, /* A1 = 0.75827 */ - -30036, /* A2 = -0.916626 */ - 12651, /* B2 = 0.386078 */ - -2444, /* B1 = -0.14917 */ - 12653, /* B0 = 0.386154 */ - 23518, /* A1 = 1.435425 */ - -30745, /* A2 = -0.938293 */ - 27282, /* B2 = 0.832581 */ - -22529, /* B1 = -1.375122 */ - 27286, /* B0 = 0.832703 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f942 */ - 24104, /* A1 = -1.471252 */ - -32507, /* A2 = 0.992065 */ - -351, /* B2 = -0.010722 */ - 0, /* B1 = 0.000000 */ - 351, /* B0 = 0.010722 */ - 23996, /* A1 = -1.464600 */ - -32671, /* A2 = 0.997040 */ - 22848, /* B2 = 0.697266 */ - -16639, /* B1 = -1.015564 */ - 22848, /* B0 = 0.697266 */ - 24332, /* A1 = -1.485168 */ - -32673, /* A2 = 0.997101 */ - 4906, /* B2 = 0.149727 */ - -3672, /* B1 = -0.224174 */ - 4906, /* B0 = 0.149727 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f950 */ - 23967, /* A1 = -1.462830 */ - -32507, /* A2 = 0.992065 */ - -518, /* B2 = -0.015821 */ - 0, /* B1 = 0.000000 */ - 518, /* B0 = 0.015821 */ - 23856, /* A1 = -1.456055 */ - -32671, /* A2 = 0.997040 */ - 26287, /* B2 = 0.802246 */ - -19031, /* B1 = -1.161560 */ - 26287, /* B0 = 0.802246 */ - 24195, /* A1 = -1.476746 */ - -32673, /* A2 = 0.997101 */ - 2890, /* B2 = 0.088196 */ - -2151, /* B1 = -0.131317 */ - 2890, /* B0 = 0.088196 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f950_1400[] */ - 18294, /* A1 = 1.116638 */ - -26962, /* A2 = -0.822845 */ - -2914, /* B2 = -0.088936 */ - 0, /* B1 = 0 */ - 2914, /* B0 = 0.088936 */ - 14119, /* A1 = 0.861786 */ - -30227, /* A2 = -0.922455 */ - 11466, /* B2 = 0.349945 */ - -2833, /* B1 = -0.172943 */ - 11466, /* B0 = 0.349945 */ - 23431, /* A1 = 1.430115 */ - -30828, /* A2 = -0.940796 */ - 25331, /* B2 = 0.773071 */ - -20911, /* B1 = -1.276367 */ - 25331, /* B0 = 0.773071 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f975 */ - 23521, /* A1 = -1.435608 */ - -32489, /* A2 = 0.991516 */ - -193, /* B2 = -0.005915 */ - 0, /* B1 = 0.000000 */ - 193, /* B0 = 0.005915 */ - 23404, /* A1 = -1.428467 */ - -32655, /* A2 = 0.996582 */ - 17740, /* B2 = 0.541412 */ - -12567, /* B1 = -0.767029 */ - 17740, /* B0 = 0.541412 */ - 23753, /* A1 = -1.449829 */ - -32657, /* A2 = 0.996613 */ - 9090, /* B2 = 0.277405 */ - -6662, /* B1 = -0.406647 */ - 9090, /* B0 = 0.277405 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1000 */ - 23071, /* A1 = -1.408203 */ - -32489, /* A2 = 0.991516 */ - -293, /* B2 = -0.008965 */ - 0, /* B1 = 0.000000 */ - 293, /* B0 = 0.008965 */ - 22951, /* A1 = -1.400818 */ - -32655, /* A2 = 0.996582 */ - 5689, /* B2 = 0.173645 */ - -3951, /* B1 = -0.241150 */ - 5689, /* B0 = 0.173645 */ - 23307, /* A1 = -1.422607 */ - -32657, /* A2 = 0.996613 */ - 18692, /* B2 = 0.570435 */ - -13447, /* B1 = -0.820770 */ - 18692, /* B0 = 0.570435 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1020 */ - 22701, /* A1 = -1.385620 */ - -32474, /* A2 = 0.991058 */ - -292, /* B2 = -0.008933 */ - 0, /*163840 , B1 = 10.000000 */ - 292, /* B0 = 0.008933 */ - 22564, /* A1 = -1.377258 */ - -32655, /* A2 = 0.996552 */ - 20756, /* B2 = 0.633423 */ - -14176, /* B1 = -0.865295 */ - 20756, /* B0 = 0.633423 */ - 22960, /* A1 = -1.401428 */ - -32657, /* A2 = 0.996613 */ - 6520, /* B2 = 0.198990 */ - -4619, /* B1 = -0.281937 */ - 6520, /* B0 = 0.198990 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1050 */ - 22142, /* A1 = -1.351501 */ - -32474, /* A2 = 0.991058 */ - -147, /* B2 = -0.004493 */ - 0, /* B1 = 0.000000 */ - 147, /* B0 = 0.004493 */ - 22000, /* A1 = -1.342834 */ - -32655, /* A2 = 0.996552 */ - 15379, /* B2 = 0.469360 */ - -10237, /* B1 = -0.624847 */ - 15379, /* B0 = 0.469360 */ - 22406, /* A1 = -1.367554 */ - -32657, /* A2 = 0.996613 */ - 17491, /* B2 = 0.533783 */ - -12096, /* B1 = -0.738312 */ - 17491, /* B0 = 0.533783 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1100_1750[] */ - 12973, /* A1 = 0.79184 */ - -24916, /* A2 = -0.760376 */ - 6655, /* B2 = 0.203102 */ - 367, /* B1 = 0.0224 */ - 6657, /* B0 = 0.203171 */ - 5915, /* A1 = 0.361053 */ - -29560, /* A2 = -0.90213 */ - -7777, /* B2 = -0.23735 */ - 0, /* B1 = 0 */ - 7777, /* B0 = 0.23735 */ - 20510, /* A1 = 1.251892 */ - -30260, /* A2 = -0.923462 */ - 26662, /* B2 = 0.81366 */ - -20573, /* B1 = -1.255737 */ - 26668, /* B0 = 0.813843 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1140 */ - 20392, /* A1 = -1.244629 */ - -32460, /* A2 = 0.990601 */ - -270, /* B2 = -0.008240 */ - 0, /* B1 = 0.000000 */ - 270, /* B0 = 0.008240 */ - 20218, /* A1 = -1.234009 */ - -32655, /* A2 = 0.996582 */ - 21337, /* B2 = 0.651154 */ - -13044, /* B1 = -0.796143 */ - 21337, /* B0 = 0.651154 */ - 20684, /* A1 = -1.262512 */ - -32657, /* A2 = 0.996643 */ - 8572, /* B2 = 0.261612 */ - -5476, /* B1 = -0.334244 */ - 8572, /* B0 = 0.261612 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1200 */ - 19159, /* A1 = -1.169373 */ - -32456, /* A2 = 0.990509 */ - -335, /* B2 = -0.010252 */ - 0, /* B1 = 0.000000 */ - 335, /* B0 = 0.010252 */ - 18966, /* A1 = -1.157593 */ - -32661, /* A2 = 0.996735 */ - 6802, /* B2 = 0.207588 */ - -3900, /* B1 = -0.238098 */ - 6802, /* B0 = 0.207588 */ - 19467, /* A1 = -1.188232 */ - -32661, /* A2 = 0.996765 */ - 25035, /* B2 = 0.764008 */ - -15049, /* B1 = -0.918579 */ - 25035, /* B0 = 0.764008 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1209 */ - 18976, /* A1 = -1.158264 */ - -32439, /* A2 = 0.989990 */ - -183, /* B2 = -0.005588 */ - 0, /* B1 = 0.000000 */ - 183, /* B0 = 0.005588 */ - 18774, /* A1 = -1.145874 */ - -32650, /* A2 = 0.996429 */ - 15468, /* B2 = 0.472076 */ - -8768, /* B1 = -0.535217 */ - 15468, /* B0 = 0.472076 */ - 19300, /* A1 = -1.177979 */ - -32652, /* A2 = 0.996490 */ - 19840, /* B2 = 0.605499 */ - -11842, /* B1 = -0.722809 */ - 19840, /* B0 = 0.605499 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1330 */ - 16357, /* A1 = -0.998413 */ - -32368, /* A2 = 0.987793 */ - -217, /* B2 = -0.006652 */ - 0, /* B1 = 0.000000 */ - 217, /* B0 = 0.006652 */ - 16107, /* A1 = -0.983126 */ - -32601, /* A2 = 0.994904 */ - 11602, /* B2 = 0.354065 */ - -5555, /* B1 = -0.339111 */ - 11602, /* B0 = 0.354065 */ - 16722, /* A1 = -1.020630 */ - -32603, /* A2 = 0.994965 */ - 15574, /* B2 = 0.475311 */ - -8176, /* B1 = -0.499069 */ - 15574, /* B0 = 0.475311 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1336 */ - 16234, /* A1 = -0.990875 */ - 32404, /* A2 = -0.988922 */ - -193, /* B2 = -0.005908 */ - 0, /* B1 = 0.000000 */ - 193, /* B0 = 0.005908 */ - 15986, /* A1 = -0.975769 */ - -32632, /* A2 = 0.995880 */ - 18051, /* B2 = 0.550903 */ - -8658, /* B1 = -0.528473 */ - 18051, /* B0 = 0.550903 */ - 16591, /* A1 = -1.012695 */ - -32634, /* A2 = 0.995941 */ - 15736, /* B2 = 0.480240 */ - -8125, /* B1 = -0.495926 */ - 15736, /* B0 = 0.480240 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1366 */ - 15564, /* A1 = -0.949982 */ - -32404, /* A2 = 0.988922 */ - -269, /* B2 = -0.008216 */ - 0, /* B1 = 0.000000 */ - 269, /* B0 = 0.008216 */ - 15310, /* A1 = -0.934479 */ - -32632, /* A2 = 0.995880 */ - 10815, /* B2 = 0.330063 */ - -4962, /* B1 = -0.302887 */ - 10815, /* B0 = 0.330063 */ - 15924, /* A1 = -0.971924 */ - -32634, /* A2 = 0.995941 */ - 18880, /* B2 = 0.576172 */ - -9364, /* B1 = -0.571594 */ - 18880, /* B0 = 0.576172 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1380 */ - 15247, /* A1 = -0.930603 */ - -32397, /* A2 = 0.988708 */ - -244, /* B2 = -0.007451 */ - 0, /* B1 = 0.000000 */ - 244, /* B0 = 0.007451 */ - 14989, /* A1 = -0.914886 */ - -32627, /* A2 = 0.995697 */ - 18961, /* B2 = 0.578644 */ - -8498, /* B1 = -0.518707 */ - 18961, /* B0 = 0.578644 */ - 15608, /* A1 = -0.952667 */ - -32628, /* A2 = 0.995758 */ - 11145, /* B2 = 0.340134 */ - -5430, /* B1 = -0.331467 */ - 11145, /* B0 = 0.340134 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1400 */ - 14780, /* A1 = -0.902130 */ - -32393, /* A2 = 0.988586 */ - -396, /* B2 = -0.012086 */ - 0, /* B1 = 0.000000 */ - 396, /* B0 = 0.012086 */ - 14510, /* A1 = -0.885651 */ - -32630, /* A2 = 0.995819 */ - 6326, /* B2 = 0.193069 */ - -2747, /* B1 = -0.167671 */ - 6326, /* B0 = 0.193069 */ - 15154, /* A1 = -0.924957 */ - -32632, /* A2 = 0.995850 */ - 23235, /* B2 = 0.709076 */ - -10983, /* B1 = -0.670380 */ - 23235, /* B0 = 0.709076 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1477 */ - 13005, /* A1 = -0.793793 */ - -32368, /* A2 = 0.987823 */ - -500, /* B2 = -0.015265 */ - 0, /* B1 = 0.000000 */ - 500, /* B0 = 0.015265 */ - 12708, /* A1 = -0.775665 */ - -32615, /* A2 = 0.995331 */ - 11420, /* B2 = 0.348526 */ - -4306, /* B1 = -0.262833 */ - 11420, /* B0 = 0.348526 */ - 13397, /* A1 = -0.817688 */ - -32615, /* A2 = 0.995361 */ - 9454, /* B2 = 0.288528 */ - -3981, /* B1 = -0.243027 */ - 9454, /* B0 = 0.288528 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1600 */ - 10046, /* A1 = -0.613190 */ - -32331, /* A2 = 0.986694 */ - -455, /* B2 = -0.013915 */ - 0, /* B1 = 0.000000 */ - 455, /* B0 = 0.013915 */ - 9694, /* A1 = -0.591705 */ - -32601, /* A2 = 0.994934 */ - 6023, /* B2 = 0.183815 */ - -1708, /* B1 = -0.104279 */ - 6023, /* B0 = 0.183815 */ - 10478, /* A1 = -0.639587 */ - -32603, /* A2 = 0.994965 */ - 22031, /* B2 = 0.672333 */ - -7342, /* B1 = -0.448151 */ - 22031, /* B0 = 0.672333 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1633_1638[] */ - 9181, /* A1 = 0.560394 */ - -32256, /* A2 = -0.984375 */ - -556, /* B2 = -0.016975 */ - 0, /* B1 = 0 */ - 556, /* B0 = 0.016975 */ - 8757, /* A1 = 0.534515 */ - -32574, /* A2 = -0.99408 */ - 8443, /* B2 = 0.25769 */ - -2135, /* B1 = -0.130341 */ - 8443, /* B0 = 0.25769 */ - 9691, /* A1 = 0.591522 */ - -32574, /* A2 = -0.99411 */ - 15446, /* B2 = 0.471375 */ - -4809, /* B1 = -0.293579 */ - 15446, /* B0 = 0.471375 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1800 */ - 5076, /* A1 = -0.309875 */ - -32304, /* A2 = 0.985840 */ - -508, /* B2 = -0.015503 */ - 0, /* B1 = 0.000000 */ - 508, /* B0 = 0.015503 */ - 4646, /* A1 = -0.283600 */ - -32605, /* A2 = 0.995026 */ - 6742, /* B2 = 0.205780 */ - -878, /* B1 = -0.053635 */ - 6742, /* B0 = 0.205780 */ - 5552, /* A1 = -0.338928 */ - -32605, /* A2 = 0.995056 */ - 23667, /* B2 = 0.722260 */ - -4297, /* B1 = -0.262329 */ - 23667, /* B0 = 0.722260 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1860 */ - 3569, /* A1 = -0.217865 */ - -32292, /* A2 = 0.985504 */ - -239, /* B2 = -0.007322 */ - 0, /* B1 = 0.000000 */ - 239, /* B0 = 0.007322 */ - 3117, /* A1 = -0.190277 */ - -32603, /* A2 = 0.994965 */ - 18658, /* B2 = 0.569427 */ - -1557, /* B1 = -0.095032 */ - 18658, /* B0 = 0.569427 */ - 4054, /* A1 = -0.247437 */ - -32603, /* A2 = 0.994965 */ - 18886, /* B2 = 0.576385 */ - -2566, /* B1 = -0.156647 */ - 18886, /* B0 = 0.576385 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, -}; -static int ixj_init_filter(IXJ *j, IXJ_FILTER * jf) -{ - unsigned short cmd; - int cnt, max; - - if (jf->filter > 3) { - return -1; - } - if (ixj_WriteDSPCommand(0x5154 + jf->filter, j)) /* Select Filter */ - - return -1; - if (!jf->enable) { - if (ixj_WriteDSPCommand(0x5152, j)) /* Disable Filter */ - - return -1; - else - return 0; - } else { - if (ixj_WriteDSPCommand(0x5153, j)) /* Enable Filter */ - - return -1; - /* Select the filter (f0 - f3) to use. */ - if (ixj_WriteDSPCommand(0x5154 + jf->filter, j)) - return -1; - } - if (jf->freq < 12 && jf->freq > 3) { - /* Select the frequency for the selected filter. */ - if (ixj_WriteDSPCommand(0x5170 + jf->freq, j)) - return -1; - } else if (jf->freq > 11) { - /* We need to load a programmable filter set for undefined */ - /* frequencies. So we will point the filter to a programmable set. */ - /* Since there are only 4 filters and 4 programmable sets, we will */ - /* just point the filter to the same number set and program it for the */ - /* frequency we want. */ - if (ixj_WriteDSPCommand(0x5170 + jf->filter, j)) - return -1; - if (j->ver.low != 0x12) { - cmd = 0x515B; - max = 19; - } else { - cmd = 0x515E; - max = 15; - } - if (ixj_WriteDSPCommand(cmd, j)) - return -1; - for (cnt = 0; cnt < max; cnt++) { - if (ixj_WriteDSPCommand(tone_table[jf->freq - 12][cnt], j)) - return -1; - } - } - j->filter_en[jf->filter] = jf->enable; - return 0; -} - -static int ixj_init_filter_raw(IXJ *j, IXJ_FILTER_RAW * jfr) -{ - unsigned short cmd; - int cnt, max; - if (jfr->filter > 3) { - return -1; - } - if (ixj_WriteDSPCommand(0x5154 + jfr->filter, j)) /* Select Filter */ - return -1; - - if (!jfr->enable) { - if (ixj_WriteDSPCommand(0x5152, j)) /* Disable Filter */ - return -1; - else - return 0; - } else { - if (ixj_WriteDSPCommand(0x5153, j)) /* Enable Filter */ - return -1; - /* Select the filter (f0 - f3) to use. */ - if (ixj_WriteDSPCommand(0x5154 + jfr->filter, j)) - return -1; - } - /* We need to load a programmable filter set for undefined */ - /* frequencies. So we will point the filter to a programmable set. */ - /* Since there are only 4 filters and 4 programmable sets, we will */ - /* just point the filter to the same number set and program it for the */ - /* frequency we want. */ - if (ixj_WriteDSPCommand(0x5170 + jfr->filter, j)) - return -1; - if (j->ver.low != 0x12) { - cmd = 0x515B; - max = 19; - } else { - cmd = 0x515E; - max = 15; - } - if (ixj_WriteDSPCommand(cmd, j)) - return -1; - for (cnt = 0; cnt < max; cnt++) { - if (ixj_WriteDSPCommand(jfr->coeff[cnt], j)) - return -1; - } - j->filter_en[jfr->filter] = jfr->enable; - return 0; -} - -static int ixj_init_tone(IXJ *j, IXJ_TONE * ti) -{ - int freq0, freq1; - unsigned short data; - if (ti->freq0) { - freq0 = ti->freq0; - } else { - freq0 = 0x7FFF; - } - - if (ti->freq1) { - freq1 = ti->freq1; - } else { - freq1 = 0x7FFF; - } - - if(ti->tone_index > 12 && ti->tone_index < 28) - { - if (ixj_WriteDSPCommand(0x6800 + ti->tone_index, j)) - return -1; - if (ixj_WriteDSPCommand(0x6000 + (ti->gain1 << 4) + ti->gain0, j)) - return -1; - data = freq0; - if (ixj_WriteDSPCommand(data, j)) - return -1; - data = freq1; - if (ixj_WriteDSPCommand(data, j)) - return -1; - } - return freq0; -} - diff --git a/drivers/telephony/ixj.h b/drivers/telephony/ixj.h deleted file mode 100644 index 2c841134f61..00000000000 --- a/drivers/telephony/ixj.h +++ /dev/null @@ -1,1322 +0,0 @@ -/****************************************************************************** - * ixj.h - * - * - * Device Driver for Quicknet Technologies, Inc.'s Telephony cards - * including the Internet PhoneJACK, Internet PhoneJACK Lite, - * Internet PhoneJACK PCI, Internet LineJACK, Internet PhoneCARD and - * SmartCABLE - * - * (c) Copyright 1999-2001 Quicknet Technologies, 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. - * - * Author: Ed Okerson, - * - * Contributors: Greg Herlein, - * David W. Erhart, - * John Sellers, - * Mike Preston, - * - * More information about the hardware related to this driver can be found - * at our website: http://www.quicknet.net - * - * Fixes: - * - * IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT - * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF QUICKNET - * TECHNOLOGIES, INC.HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * QUICKNET TECHNOLOGIES, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND QUICKNET TECHNOLOGIES, INC. HAS NO OBLIGATION - * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - *****************************************************************************/ -#define IXJ_VERSION 3031 - -#include - -#include -#include - -typedef __u16 WORD; -typedef __u32 DWORD; -typedef __u8 BYTE; - -#ifndef IXJMAX -#define IXJMAX 16 -#endif - -/****************************************************************************** -* -* This structure when unioned with the structures below makes simple byte -* access to the registers easier. -* -******************************************************************************/ -typedef struct { - unsigned char low; - unsigned char high; -} BYTES; - -typedef union { - BYTES bytes; - short word; -} IXJ_WORD; - -typedef struct{ - unsigned int b0:1; - unsigned int b1:1; - unsigned int b2:1; - unsigned int b3:1; - unsigned int b4:1; - unsigned int b5:1; - unsigned int b6:1; - unsigned int b7:1; -} IXJ_CBITS; - -typedef union{ - IXJ_CBITS cbits; - char cbyte; -} IXJ_CBYTE; - -/****************************************************************************** -* -* This structure represents the Hardware Control Register of the CT8020/8021 -* The CT8020 is used in the Internet PhoneJACK, and the 8021 in the -* Internet LineJACK -* -******************************************************************************/ -typedef struct { - unsigned int rxrdy:1; - unsigned int txrdy:1; - unsigned int status:1; - unsigned int auxstatus:1; - unsigned int rxdma:1; - unsigned int txdma:1; - unsigned int rxburst:1; - unsigned int txburst:1; - unsigned int dmadir:1; - unsigned int cont:1; - unsigned int irqn:1; - unsigned int t:5; -} HCRBIT; - -typedef union { - HCRBIT bits; - BYTES bytes; -} HCR; - -/****************************************************************************** -* -* This structure represents the Hardware Status Register of the CT8020/8021 -* The CT8020 is used in the Internet PhoneJACK, and the 8021 in the -* Internet LineJACK -* -******************************************************************************/ -typedef struct { - unsigned int controlrdy:1; - unsigned int auxctlrdy:1; - unsigned int statusrdy:1; - unsigned int auxstatusrdy:1; - unsigned int rxrdy:1; - unsigned int txrdy:1; - unsigned int restart:1; - unsigned int irqn:1; - unsigned int rxdma:1; - unsigned int txdma:1; - unsigned int cohostshutdown:1; - unsigned int t:5; -} HSRBIT; - -typedef union { - HSRBIT bits; - BYTES bytes; -} HSR; - -/****************************************************************************** -* -* This structure represents the General Purpose IO Register of the CT8020/8021 -* The CT8020 is used in the Internet PhoneJACK, and the 8021 in the -* Internet LineJACK -* -******************************************************************************/ -typedef struct { - unsigned int x:1; - unsigned int gpio1:1; - unsigned int gpio2:1; - unsigned int gpio3:1; - unsigned int gpio4:1; - unsigned int gpio5:1; - unsigned int gpio6:1; - unsigned int gpio7:1; - unsigned int xread:1; - unsigned int gpio1read:1; - unsigned int gpio2read:1; - unsigned int gpio3read:1; - unsigned int gpio4read:1; - unsigned int gpio5read:1; - unsigned int gpio6read:1; - unsigned int gpio7read:1; -} GPIOBIT; - -typedef union { - GPIOBIT bits; - BYTES bytes; - unsigned short word; -} GPIO; - -/****************************************************************************** -* -* This structure represents the Line Monitor status response -* -******************************************************************************/ -typedef struct { - unsigned int digit:4; - unsigned int cpf_valid:1; - unsigned int dtmf_valid:1; - unsigned int peak:1; - unsigned int z:1; - unsigned int f0:1; - unsigned int f1:1; - unsigned int f2:1; - unsigned int f3:1; - unsigned int frame:4; -} LMON; - -typedef union { - LMON bits; - BYTES bytes; -} DTMF; - -typedef struct { - unsigned int z:7; - unsigned int dtmf_en:1; - unsigned int y:4; - unsigned int F3:1; - unsigned int F2:1; - unsigned int F1:1; - unsigned int F0:1; -} CP; - -typedef union { - CP bits; - BYTES bytes; -} CPTF; - -/****************************************************************************** -* -* This structure represents the Status Control Register on the Internet -* LineJACK -* -******************************************************************************/ -typedef struct { - unsigned int c0:1; - unsigned int c1:1; - unsigned int stereo:1; - unsigned int daafsyncen:1; - unsigned int led1:1; - unsigned int led2:1; - unsigned int led3:1; - unsigned int led4:1; -} PSCRWI; /* Internet LineJACK and Internet PhoneJACK Lite */ - -typedef struct { - unsigned int eidp:1; - unsigned int eisd:1; - unsigned int x:6; -} PSCRWP; /* Internet PhoneJACK PCI */ - -typedef union { - PSCRWI bits; - PSCRWP pcib; - char byte; -} PLD_SCRW; - -typedef struct { - unsigned int c0:1; - unsigned int c1:1; - unsigned int x:1; - unsigned int d0ee:1; - unsigned int mixerbusy:1; - unsigned int sci:1; - unsigned int dspflag:1; - unsigned int daaflag:1; -} PSCRRI; - -typedef struct { - unsigned int eidp:1; - unsigned int eisd:1; - unsigned int x:4; - unsigned int dspflag:1; - unsigned int det:1; -} PSCRRP; - -typedef union { - PSCRRI bits; - PSCRRP pcib; - char byte; -} PLD_SCRR; - -/****************************************************************************** -* -* These structures represents the SLIC Control Register on the -* Internet LineJACK -* -******************************************************************************/ -typedef struct { - unsigned int c1:1; - unsigned int c2:1; - unsigned int c3:1; - unsigned int b2en:1; - unsigned int spken:1; - unsigned int rly1:1; - unsigned int rly2:1; - unsigned int rly3:1; -} PSLICWRITE; - -typedef struct { - unsigned int state:3; - unsigned int b2en:1; - unsigned int spken:1; - unsigned int c3:1; - unsigned int potspstn:1; - unsigned int det:1; -} PSLICREAD; - -typedef struct { - unsigned int c1:1; - unsigned int c2:1; - unsigned int c3:1; - unsigned int b2en:1; - unsigned int e1:1; - unsigned int mic:1; - unsigned int spk:1; - unsigned int x:1; -} PSLICPCI; - -typedef union { - PSLICPCI pcib; - PSLICWRITE bits; - PSLICREAD slic; - char byte; -} PLD_SLICW; - -typedef union { - PSLICPCI pcib; - PSLICREAD bits; - char byte; -} PLD_SLICR; - -/****************************************************************************** -* -* These structures represents the Clock Control Register on the -* Internet LineJACK -* -******************************************************************************/ -typedef struct { - unsigned int clk0:1; - unsigned int clk1:1; - unsigned int clk2:1; - unsigned int x0:1; - unsigned int slic_e1:1; - unsigned int x1:1; - unsigned int x2:1; - unsigned int x3:1; -} PCLOCK; - -typedef union { - PCLOCK bits; - char byte; -} PLD_CLOCK; - -/****************************************************************************** -* -* These structures deal with the mixer on the Internet LineJACK -* -******************************************************************************/ - -typedef struct { - unsigned short vol[10]; - unsigned int recsrc; - unsigned int modcnt; - unsigned short micpreamp; -} MIX; - -/****************************************************************************** -* -* These structures deal with the control logic on the Internet PhoneCARD -* -******************************************************************************/ -typedef struct { - unsigned int x0:4; /* unused bits */ - - unsigned int ed:1; /* Event Detect */ - - unsigned int drf:1; /* SmartCABLE Removal Flag 1=no cable */ - - unsigned int dspf:1; /* DSP Flag 1=DSP Ready */ - - unsigned int crr:1; /* Control Register Ready */ - -} COMMAND_REG1; - -typedef union { - COMMAND_REG1 bits; - unsigned char byte; -} PCMCIA_CR1; - -typedef struct { - unsigned int x0:4; /* unused bits */ - - unsigned int rstc:1; /* SmartCABLE Reset */ - - unsigned int pwr:1; /* SmartCABLE Power */ - - unsigned int x1:2; /* unused bits */ - -} COMMAND_REG2; - -typedef union { - COMMAND_REG2 bits; - unsigned char byte; -} PCMCIA_CR2; - -typedef struct { - unsigned int addr:5; /* R/W SmartCABLE Register Address */ - - unsigned int rw:1; /* Read / Write flag */ - - unsigned int dev:2; /* 2 bit SmartCABLE Device Address */ - -} CONTROL_REG; - -typedef union { - CONTROL_REG bits; - unsigned char byte; -} PCMCIA_SCCR; - -typedef struct { - unsigned int hsw:1; - unsigned int det:1; - unsigned int led2:1; - unsigned int led1:1; - unsigned int ring1:1; - unsigned int ring0:1; - unsigned int x:1; - unsigned int powerdown:1; -} PCMCIA_SLIC_REG; - -typedef union { - PCMCIA_SLIC_REG bits; - unsigned char byte; -} PCMCIA_SLIC; - -typedef struct { - unsigned int cpd:1; /* Chip Power Down */ - - unsigned int mpd:1; /* MIC Bias Power Down */ - - unsigned int hpd:1; /* Handset Drive Power Down */ - - unsigned int lpd:1; /* Line Drive Power Down */ - - unsigned int spd:1; /* Speaker Drive Power Down */ - - unsigned int x:2; /* unused bits */ - - unsigned int sr:1; /* Software Reset */ - -} Si3CONTROL1; - -typedef union { - Si3CONTROL1 bits; - unsigned char byte; -} Si3C1; - -typedef struct { - unsigned int al:1; /* Analog Loopback DAC analog -> ADC analog */ - - unsigned int dl2:1; /* Digital Loopback DAC -> ADC one bit */ - - unsigned int dl1:1; /* Digital Loopback ADC -> DAC one bit */ - - unsigned int pll:1; /* 1 = div 10, 0 = div 5 */ - - unsigned int hpd:1; /* HPF disable */ - - unsigned int x:3; /* unused bits */ - -} Si3CONTROL2; - -typedef union { - Si3CONTROL2 bits; - unsigned char byte; -} Si3C2; - -typedef struct { - unsigned int iir:1; /* 1 enables IIR, 0 enables FIR */ - - unsigned int him:1; /* Handset Input Mute */ - - unsigned int mcm:1; /* MIC In Mute */ - - unsigned int mcg:2; /* MIC In Gain */ - - unsigned int lim:1; /* Line In Mute */ - - unsigned int lig:2; /* Line In Gain */ - -} Si3RXGAIN; - -typedef union { - Si3RXGAIN bits; - unsigned char byte; -} Si3RXG; - -typedef struct { - unsigned int hom:1; /* Handset Out Mute */ - - unsigned int lom:1; /* Line Out Mute */ - - unsigned int rxg:5; /* RX PGA Gain */ - - unsigned int x:1; /* unused bit */ - -} Si3ADCVOLUME; - -typedef union { - Si3ADCVOLUME bits; - unsigned char byte; -} Si3ADC; - -typedef struct { - unsigned int srm:1; /* Speaker Right Mute */ - - unsigned int slm:1; /* Speaker Left Mute */ - - unsigned int txg:5; /* TX PGA Gain */ - - unsigned int x:1; /* unused bit */ - -} Si3DACVOLUME; - -typedef union { - Si3DACVOLUME bits; - unsigned char byte; -} Si3DAC; - -typedef struct { - unsigned int x:5; /* unused bit */ - - unsigned int losc:1; /* Line Out Short Circuit */ - - unsigned int srsc:1; /* Speaker Right Short Circuit */ - - unsigned int slsc:1; /* Speaker Left Short Circuit */ - -} Si3STATUSREPORT; - -typedef union { - Si3STATUSREPORT bits; - unsigned char byte; -} Si3STAT; - -typedef struct { - unsigned int sot:2; /* Speaker Out Attenuation */ - - unsigned int lot:2; /* Line Out Attenuation */ - - unsigned int x:4; /* unused bits */ - -} Si3ANALOGATTN; - -typedef union { - Si3ANALOGATTN bits; - unsigned char byte; -} Si3AATT; - -/****************************************************************************** -* -* These structures deal with the DAA on the Internet LineJACK -* -******************************************************************************/ - -typedef struct _DAA_REGS { - /*----------------------------------------------- */ - /* SOP Registers */ - /* */ - BYTE bySOP; - - union _SOP_REGS { - struct _SOP { - union /* SOP - CR0 Register */ - { - BYTE reg; - struct _CR0_BITREGS { - BYTE CLK_EXT:1; /* cr0[0:0] */ - - BYTE RIP:1; /* cr0[1:1] */ - - BYTE AR:1; /* cr0[2:2] */ - - BYTE AX:1; /* cr0[3:3] */ - - BYTE FRR:1; /* cr0[4:4] */ - - BYTE FRX:1; /* cr0[5:5] */ - - BYTE IM:1; /* cr0[6:6] */ - - BYTE TH:1; /* cr0[7:7] */ - - } bitreg; - } cr0; - - union /* SOP - CR1 Register */ - { - BYTE reg; - struct _CR1_REGS { - BYTE RM:1; /* cr1[0:0] */ - - BYTE RMR:1; /* cr1[1:1] */ - - BYTE No_auto:1; /* cr1[2:2] */ - - BYTE Pulse:1; /* cr1[3:3] */ - - BYTE P_Tone1:1; /* cr1[4:4] */ - - BYTE P_Tone2:1; /* cr1[5:5] */ - - BYTE E_Tone1:1; /* cr1[6:6] */ - - BYTE E_Tone2:1; /* cr1[7:7] */ - - } bitreg; - } cr1; - - union /* SOP - CR2 Register */ - { - BYTE reg; - struct _CR2_REGS { - BYTE Call_II:1; /* CR2[0:0] */ - - BYTE Call_I:1; /* CR2[1:1] */ - - BYTE Call_en:1; /* CR2[2:2] */ - - BYTE Call_pon:1; /* CR2[3:3] */ - - BYTE IDR:1; /* CR2[4:4] */ - - BYTE COT_R:3; /* CR2[5:7] */ - - } bitreg; - } cr2; - - union /* SOP - CR3 Register */ - { - BYTE reg; - struct _CR3_REGS { - BYTE DHP_X:1; /* CR3[0:0] */ - - BYTE DHP_R:1; /* CR3[1:1] */ - - BYTE Cal_pctl:1; /* CR3[2:2] */ - - BYTE SEL:1; /* CR3[3:3] */ - - BYTE TestLoops:4; /* CR3[4:7] */ - - } bitreg; - } cr3; - - union /* SOP - CR4 Register */ - { - BYTE reg; - struct _CR4_REGS { - BYTE Fsc_en:1; /* CR4[0:0] */ - - BYTE Int_en:1; /* CR4[1:1] */ - - BYTE AGX:2; /* CR4[2:3] */ - - BYTE AGR_R:2; /* CR4[4:5] */ - - BYTE AGR_Z:2; /* CR4[6:7] */ - - } bitreg; - } cr4; - - union /* SOP - CR5 Register */ - { - BYTE reg; - struct _CR5_REGS { - BYTE V_0:1; /* CR5[0:0] */ - - BYTE V_1:1; /* CR5[1:1] */ - - BYTE V_2:1; /* CR5[2:2] */ - - BYTE V_3:1; /* CR5[3:3] */ - - BYTE V_4:1; /* CR5[4:4] */ - - BYTE V_5:1; /* CR5[5:5] */ - - BYTE V_6:1; /* CR5[6:6] */ - - BYTE V_7:1; /* CR5[7:7] */ - - } bitreg; - } cr5; - - union /* SOP - CR6 Register */ - { - BYTE reg; - struct _CR6_REGS { - BYTE reserved:8; /* CR6[0:7] */ - - } bitreg; - } cr6; - - union /* SOP - CR7 Register */ - { - BYTE reg; - struct _CR7_REGS { - BYTE reserved:8; /* CR7[0:7] */ - - } bitreg; - } cr7; - } SOP; - - BYTE ByteRegs[sizeof(struct _SOP)]; - - } SOP_REGS; - - /* DAA_REGS.SOP_REGS.SOP.CR5.reg */ - /* DAA_REGS.SOP_REGS.SOP.CR5.bitreg */ - /* DAA_REGS.SOP_REGS.SOP.CR5.bitreg.V_2 */ - /* DAA_REGS.SOP_REGS.ByteRegs[5] */ - - /*----------------------------------------------- */ - /* XOP Registers */ - /* */ - BYTE byXOP; - - union _XOP_REGS { - struct _XOP { - union XOPXR0/* XOP - XR0 Register - Read values */ - { - BYTE reg; - struct _XR0_BITREGS { - BYTE SI_0:1; /* XR0[0:0] - Read */ - - BYTE SI_1:1; /* XR0[1:1] - Read */ - - BYTE VDD_OK:1; /* XR0[2:2] - Read */ - - BYTE Caller_ID:1; /* XR0[3:3] - Read */ - - BYTE RING:1; /* XR0[4:4] - Read */ - - BYTE Cadence:1; /* XR0[5:5] - Read */ - - BYTE Wake_up:1; /* XR0[6:6] - Read */ - - BYTE RMR:1; /* XR0[7:7] - Read */ - - } bitreg; - } xr0; - - union /* XOP - XR1 Register */ - { - BYTE reg; - struct _XR1_BITREGS { - BYTE M_SI_0:1; /* XR1[0:0] */ - - BYTE M_SI_1:1; /* XR1[1:1] */ - - BYTE M_VDD_OK:1; /* XR1[2:2] */ - - BYTE M_Caller_ID:1; /* XR1[3:3] */ - - BYTE M_RING:1; /* XR1[4:4] */ - - BYTE M_Cadence:1; /* XR1[5:5] */ - - BYTE M_Wake_up:1; /* XR1[6:6] */ - - BYTE unused:1; /* XR1[7:7] */ - - } bitreg; - } xr1; - - union /* XOP - XR2 Register */ - { - BYTE reg; - struct _XR2_BITREGS { - BYTE CTO0:1; /* XR2[0:0] */ - - BYTE CTO1:1; /* XR2[1:1] */ - - BYTE CTO2:1; /* XR2[2:2] */ - - BYTE CTO3:1; /* XR2[3:3] */ - - BYTE CTO4:1; /* XR2[4:4] */ - - BYTE CTO5:1; /* XR2[5:5] */ - - BYTE CTO6:1; /* XR2[6:6] */ - - BYTE CTO7:1; /* XR2[7:7] */ - - } bitreg; - } xr2; - - union /* XOP - XR3 Register */ - { - BYTE reg; - struct _XR3_BITREGS { - BYTE DCR0:1; /* XR3[0:0] */ - - BYTE DCR1:1; /* XR3[1:1] */ - - BYTE DCI:1; /* XR3[2:2] */ - - BYTE DCU0:1; /* XR3[3:3] */ - - BYTE DCU1:1; /* XR3[4:4] */ - - BYTE B_off:1; /* XR3[5:5] */ - - BYTE AGB0:1; /* XR3[6:6] */ - - BYTE AGB1:1; /* XR3[7:7] */ - - } bitreg; - } xr3; - - union /* XOP - XR4 Register */ - { - BYTE reg; - struct _XR4_BITREGS { - BYTE C_0:1; /* XR4[0:0] */ - - BYTE C_1:1; /* XR4[1:1] */ - - BYTE C_2:1; /* XR4[2:2] */ - - BYTE C_3:1; /* XR4[3:3] */ - - BYTE C_4:1; /* XR4[4:4] */ - - BYTE C_5:1; /* XR4[5:5] */ - - BYTE C_6:1; /* XR4[6:6] */ - - BYTE C_7:1; /* XR4[7:7] */ - - } bitreg; - } xr4; - - union /* XOP - XR5 Register */ - { - BYTE reg; - struct _XR5_BITREGS { - BYTE T_0:1; /* XR5[0:0] */ - - BYTE T_1:1; /* XR5[1:1] */ - - BYTE T_2:1; /* XR5[2:2] */ - - BYTE T_3:1; /* XR5[3:3] */ - - BYTE T_4:1; /* XR5[4:4] */ - - BYTE T_5:1; /* XR5[5:5] */ - - BYTE T_6:1; /* XR5[6:6] */ - - BYTE T_7:1; /* XR5[7:7] */ - - } bitreg; - } xr5; - - union /* XOP - XR6 Register - Read Values */ - { - BYTE reg; - struct _XR6_BITREGS { - BYTE CPS0:1; /* XR6[0:0] */ - - BYTE CPS1:1; /* XR6[1:1] */ - - BYTE unused1:2; /* XR6[2:3] */ - - BYTE CLK_OFF:1; /* XR6[4:4] */ - - BYTE unused2:3; /* XR6[5:7] */ - - } bitreg; - } xr6; - - union /* XOP - XR7 Register */ - { - BYTE reg; - struct _XR7_BITREGS { - BYTE unused1:1; /* XR7[0:0] */ - - BYTE Vdd0:1; /* XR7[1:1] */ - - BYTE Vdd1:1; /* XR7[2:2] */ - - BYTE unused2:5; /* XR7[3:7] */ - - } bitreg; - } xr7; - } XOP; - - BYTE ByteRegs[sizeof(struct _XOP)]; - - } XOP_REGS; - - /* DAA_REGS.XOP_REGS.XOP.XR7.reg */ - /* DAA_REGS.XOP_REGS.XOP.XR7.bitreg */ - /* DAA_REGS.XOP_REGS.XOP.XR7.bitreg.Vdd0 */ - /* DAA_REGS.XOP_REGS.ByteRegs[7] */ - - /*----------------------------------------------- */ - /* COP Registers */ - /* */ - BYTE byCOP; - - union _COP_REGS { - struct _COP { - BYTE THFilterCoeff_1[8]; /* COP - TH Filter Coefficients, CODE=0, Part 1 */ - - BYTE THFilterCoeff_2[8]; /* COP - TH Filter Coefficients, CODE=1, Part 2 */ - - BYTE THFilterCoeff_3[8]; /* COP - TH Filter Coefficients, CODE=2, Part 3 */ - - BYTE RingerImpendance_1[8]; /* COP - Ringer Impendance Coefficients, CODE=3, Part 1 */ - - BYTE IMFilterCoeff_1[8]; /* COP - IM Filter Coefficients, CODE=4, Part 1 */ - - BYTE IMFilterCoeff_2[8]; /* COP - IM Filter Coefficients, CODE=5, Part 2 */ - - BYTE RingerImpendance_2[8]; /* COP - Ringer Impendance Coefficients, CODE=6, Part 2 */ - - BYTE FRRFilterCoeff[8]; /* COP - FRR Filter Coefficients, CODE=7 */ - - BYTE FRXFilterCoeff[8]; /* COP - FRX Filter Coefficients, CODE=8 */ - - BYTE ARFilterCoeff[4]; /* COP - AR Filter Coefficients, CODE=9 */ - - BYTE AXFilterCoeff[4]; /* COP - AX Filter Coefficients, CODE=10 */ - - BYTE Tone1Coeff[4]; /* COP - Tone1 Coefficients, CODE=11 */ - - BYTE Tone2Coeff[4]; /* COP - Tone2 Coefficients, CODE=12 */ - - BYTE LevelmeteringRinging[4]; /* COP - Levelmetering Ringing, CODE=13 */ - - BYTE CallerID1stTone[8]; /* COP - Caller ID 1st Tone, CODE=14 */ - - BYTE CallerID2ndTone[8]; /* COP - Caller ID 2nd Tone, CODE=15 */ - - } COP; - - BYTE ByteRegs[sizeof(struct _COP)]; - - } COP_REGS; - - /* DAA_REGS.COP_REGS.COP.XR7.Tone1Coeff[3] */ - /* DAA_REGS.COP_REGS.COP.XR7.bitreg */ - /* DAA_REGS.COP_REGS.COP.XR7.bitreg.Vdd0 */ - /* DAA_REGS.COP_REGS.ByteRegs[57] */ - - /*----------------------------------------------- */ - /* CAO Registers */ - /* */ - BYTE byCAO; - - union _CAO_REGS { - struct _CAO { - BYTE CallerID[512]; /* CAO - Caller ID Bytes */ - - } CAO; - - BYTE ByteRegs[sizeof(struct _CAO)]; - } CAO_REGS; - - union /* XOP - XR0 Register - Write values */ - { - BYTE reg; - struct _XR0_BITREGSW { - BYTE SO_0:1; /* XR1[0:0] - Write */ - - BYTE SO_1:1; /* XR1[1:1] - Write */ - - BYTE SO_2:1; /* XR1[2:2] - Write */ - - BYTE unused:5; /* XR1[3:7] - Write */ - - } bitreg; - } XOP_xr0_W; - - union /* XOP - XR6 Register - Write values */ - { - BYTE reg; - struct _XR6_BITREGSW { - BYTE unused1:4; /* XR6[0:3] */ - - BYTE CLK_OFF:1; /* XR6[4:4] */ - - BYTE unused2:3; /* XR6[5:7] */ - - } bitreg; - } XOP_xr6_W; - -} DAA_REGS; - -#define ALISDAA_ID_BYTE 0x81 -#define ALISDAA_CALLERID_SIZE 512 - -/*------------------------------ */ -/* */ -/* Misc definitions */ -/* */ - -/* Power Up Operation */ -#define SOP_PU_SLEEP 0 -#define SOP_PU_RINGING 1 -#define SOP_PU_CONVERSATION 2 -#define SOP_PU_PULSEDIALING 3 -#define SOP_PU_RESET 4 - -#define ALISDAA_CALLERID_SIZE 512 - -#define PLAYBACK_MODE_COMPRESSED 0 /* Selects: Compressed modes, TrueSpeech 8.5-4.1, G.723.1, G.722, G.728, G.729 */ -#define PLAYBACK_MODE_TRUESPEECH_V40 0 /* Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps */ -#define PLAYBACK_MODE_TRUESPEECH 8 /* Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps Version 5.1 */ -#define PLAYBACK_MODE_ULAW 2 /* Selects: 64 Kbit/sec MuA-law PCM */ -#define PLAYBACK_MODE_ALAW 10 /* Selects: 64 Kbit/sec A-law PCM */ -#define PLAYBACK_MODE_16LINEAR 6 /* Selects: 128 Kbit/sec 16-bit linear */ -#define PLAYBACK_MODE_8LINEAR 4 /* Selects: 64 Kbit/sec 8-bit signed linear */ -#define PLAYBACK_MODE_8LINEAR_WSS 5 /* Selects: 64 Kbit/sec WSS 8-bit unsigned linear */ - -#define RECORD_MODE_COMPRESSED 0 /* Selects: Compressed modes, TrueSpeech 8.5-4.1, G.723.1, G.722, G.728, G.729 */ -#define RECORD_MODE_TRUESPEECH 0 /* Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps */ -#define RECORD_MODE_ULAW 4 /* Selects: 64 Kbit/sec Mu-law PCM */ -#define RECORD_MODE_ALAW 12 /* Selects: 64 Kbit/sec A-law PCM */ -#define RECORD_MODE_16LINEAR 5 /* Selects: 128 Kbit/sec 16-bit linear */ -#define RECORD_MODE_8LINEAR 6 /* Selects: 64 Kbit/sec 8-bit signed linear */ -#define RECORD_MODE_8LINEAR_WSS 7 /* Selects: 64 Kbit/sec WSS 8-bit unsigned linear */ - -enum SLIC_STATES { - PLD_SLIC_STATE_OC = 0, - PLD_SLIC_STATE_RINGING, - PLD_SLIC_STATE_ACTIVE, - PLD_SLIC_STATE_OHT, - PLD_SLIC_STATE_TIPOPEN, - PLD_SLIC_STATE_STANDBY, - PLD_SLIC_STATE_APR, - PLD_SLIC_STATE_OHTPR -}; - -enum SCI_CONTROL { - SCI_End = 0, - SCI_Enable_DAA, - SCI_Enable_Mixer, - SCI_Enable_EEPROM -}; - -enum Mode { - T63, T53, T48, T40 -}; -enum Dir { - V3_TO_V4, V4_TO_V3, V4_TO_V5, V5_TO_V4 -}; - -typedef struct Proc_Info_Tag { - enum Mode convert_mode; - enum Dir convert_dir; - int Prev_Frame_Type; - int Current_Frame_Type; -} Proc_Info_Type; - -enum PREVAL { - NORMAL = 0, - NOPOST, - POSTONLY, - PREERROR -}; - -enum IXJ_EXTENSIONS { - G729LOADER = 0, - TS85LOADER, - PRE_READ, - POST_READ, - PRE_WRITE, - POST_WRITE, - PRE_IOCTL, - POST_IOCTL -}; - -typedef struct { - char enable; - char en_filter; - unsigned int filter; - unsigned int state; /* State 0 when cadence has not started. */ - - unsigned int on1; /* State 1 */ - - unsigned long on1min; /* State 1 - 10% + jiffies */ - unsigned long on1dot; /* State 1 + jiffies */ - - unsigned long on1max; /* State 1 + 10% + jiffies */ - - unsigned int off1; /* State 2 */ - - unsigned long off1min; - unsigned long off1dot; /* State 2 + jiffies */ - unsigned long off1max; - unsigned int on2; /* State 3 */ - - unsigned long on2min; - unsigned long on2dot; - unsigned long on2max; - unsigned int off2; /* State 4 */ - - unsigned long off2min; - unsigned long off2dot; /* State 4 + jiffies */ - unsigned long off2max; - unsigned int on3; /* State 5 */ - - unsigned long on3min; - unsigned long on3dot; - unsigned long on3max; - unsigned int off3; /* State 6 */ - - unsigned long off3min; - unsigned long off3dot; /* State 6 + jiffies */ - unsigned long off3max; -} IXJ_CADENCE_F; - -typedef struct { - unsigned int busytone:1; - unsigned int dialtone:1; - unsigned int ringback:1; - unsigned int ringing:1; - unsigned int playing:1; - unsigned int recording:1; - unsigned int cringing:1; - unsigned int play_first_frame:1; - unsigned int pstn_present:1; - unsigned int pstn_ringing:1; - unsigned int pots_correct:1; - unsigned int pots_pstn:1; - unsigned int g729_loaded:1; - unsigned int ts85_loaded:1; - unsigned int dtmf_oob:1; /* DTMF Out-Of-Band */ - - unsigned int pcmciascp:1; /* SmartCABLE Present */ - - unsigned int pcmciasct:2; /* SmartCABLE Type */ - - unsigned int pcmciastate:3; /* SmartCABLE Init State */ - - unsigned int inwrite:1; /* Currently writing */ - - unsigned int inread:1; /* Currently reading */ - - unsigned int incheck:1; /* Currently checking the SmartCABLE */ - - unsigned int cidplay:1; /* Currently playing Caller ID */ - - unsigned int cidring:1; /* This is the ring for Caller ID */ - - unsigned int cidsent:1; /* Caller ID has been sent */ - - unsigned int cidcw_ack:1; /* Caller ID CW ACK (from CPE) */ - unsigned int firstring:1; /* First ring cadence is complete */ - unsigned int pstncheck:1; /* Currently checking the PSTN Line */ - unsigned int pstn_rmr:1; - unsigned int x:3; /* unused bits */ - -} IXJ_FLAGS; - -/****************************************************************************** -* -* This structure holds the state of all of the Quicknet cards -* -******************************************************************************/ - -typedef struct { - int elements_used; - IXJ_CADENCE_TERM termination; - IXJ_CADENCE_ELEMENT *ce; -} ixj_cadence; - -typedef struct { - struct phone_device p; - struct timer_list timer; - unsigned int board; - unsigned int DSPbase; - unsigned int XILINXbase; - unsigned int serial; - atomic_t DSPWrite; - struct phone_capability caplist[30]; - unsigned int caps; - struct pnp_dev *dev; - unsigned int cardtype; - unsigned int rec_codec; - unsigned int cid_rec_codec; - unsigned int cid_rec_volume; - unsigned char cid_rec_flag; - signed char rec_mode; - unsigned int play_codec; - unsigned int cid_play_codec; - unsigned int cid_play_volume; - unsigned char cid_play_flag; - signed char play_mode; - IXJ_FLAGS flags; - unsigned long busyflags; - unsigned int rec_frame_size; - unsigned int play_frame_size; - unsigned int cid_play_frame_size; - unsigned int cid_base_frame_size; - unsigned long cidcw_wait; - int aec_level; - int cid_play_aec_level; - int readers, writers; - wait_queue_head_t poll_q; - wait_queue_head_t read_q; - char *read_buffer, *read_buffer_end; - char *read_convert_buffer; - size_t read_buffer_size; - unsigned int read_buffer_ready; - wait_queue_head_t write_q; - char *write_buffer, *write_buffer_end; - char *write_convert_buffer; - size_t write_buffer_size; - unsigned int write_buffers_empty; - unsigned long drybuffer; - char *write_buffer_rp, *write_buffer_wp; - char dtmfbuffer[80]; - char dtmf_current; - int dtmf_wp, dtmf_rp, dtmf_state, dtmf_proc; - int tone_off_time, tone_on_time; - struct fasync_struct *async_queue; - unsigned long tone_start_jif; - char tone_index; - char tone_state; - char maxrings; - ixj_cadence *cadence_t; - ixj_cadence *cadence_r; - int tone_cadence_state; - IXJ_CADENCE_F cadence_f[6]; - DTMF dtmf; - CPTF cptf; - BYTES dsp; - BYTES ver; - BYTES scr; - BYTES ssr; - BYTES baseframe; - HSR hsr; - GPIO gpio; - PLD_SCRR pld_scrr; - PLD_SCRW pld_scrw; - PLD_SLICW pld_slicw; - PLD_SLICR pld_slicr; - PLD_CLOCK pld_clock; - PCMCIA_CR1 pccr1; - PCMCIA_CR2 pccr2; - PCMCIA_SCCR psccr; - PCMCIA_SLIC pslic; - char pscdd; - Si3C1 sic1; - Si3C2 sic2; - Si3RXG sirxg; - Si3ADC siadc; - Si3DAC sidac; - Si3STAT sistat; - Si3AATT siaatt; - MIX mix; - unsigned short ring_cadence; - int ring_cadence_t; - unsigned long ring_cadence_jif; - unsigned long checkwait; - int intercom; - int m_hook; - int r_hook; - int p_hook; - char pstn_envelope; - char pstn_cid_intr; - unsigned char fskz; - unsigned char fskphase; - unsigned char fskcnt; - unsigned int cidsize; - unsigned int cidcnt; - unsigned long pstn_cid_received; - PHONE_CID cid; - PHONE_CID cid_send; - unsigned long pstn_ring_int; - unsigned long pstn_ring_start; - unsigned long pstn_ring_stop; - unsigned long pstn_winkstart; - unsigned long pstn_last_rmr; - unsigned long pstn_prev_rmr; - unsigned long pots_winkstart; - unsigned int winktime; - unsigned long flash_end; - char port; - char hookstate; - union telephony_exception ex; - union telephony_exception ex_sig; - int ixj_signals[35]; - IXJ_SIGDEF sigdef; - char daa_mode; - char daa_country; - unsigned long pstn_sleeptil; - DAA_REGS m_DAAShadowRegs; - Proc_Info_Type Info_read; - Proc_Info_Type Info_write; - unsigned short frame_count; - unsigned int filter_hist[4]; - unsigned char filter_en[6]; - unsigned short proc_load; - unsigned long framesread; - unsigned long frameswritten; - unsigned long read_wait; - unsigned long write_wait; - unsigned long timerchecks; - unsigned long txreadycheck; - unsigned long rxreadycheck; - unsigned long statuswait; - unsigned long statuswaitfail; - unsigned long pcontrolwait; - unsigned long pcontrolwaitfail; - unsigned long iscontrolready; - unsigned long iscontrolreadyfail; - unsigned long pstnstatecheck; -#ifdef IXJ_DYN_ALLOC - short *fskdata; -#else - short fskdata[8000]; -#endif - int fsksize; - int fskdcnt; -} IXJ; - -typedef int (*IXJ_REGFUNC) (IXJ * j, unsigned long arg); - -extern IXJ *ixj_pcmcia_probe(unsigned long, unsigned long); - diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c deleted file mode 100644 index 05032e2cc95..00000000000 --- a/drivers/telephony/ixj_pcmcia.c +++ /dev/null @@ -1,187 +0,0 @@ -#include "ixj-ver.h" - -#include - -#include -#include /* printk() */ -#include /* everything... */ -#include /* error codes */ -#include - -#include -#include - -#include "ixj.h" - -/* - * PCMCIA service support for Quicknet cards - */ - - -typedef struct ixj_info_t { - int ndev; - struct ixj *port; -} ixj_info_t; - -static void ixj_detach(struct pcmcia_device *p_dev); -static int ixj_config(struct pcmcia_device * link); -static void ixj_cs_release(struct pcmcia_device * link); - -static int ixj_probe(struct pcmcia_device *p_dev) -{ - dev_dbg(&p_dev->dev, "ixj_attach()\n"); - /* Create new ixj device */ - p_dev->priv = kzalloc(sizeof(struct ixj_info_t), GFP_KERNEL); - if (!p_dev->priv) { - return -ENOMEM; - } - - return ixj_config(p_dev); -} - -static void ixj_detach(struct pcmcia_device *link) -{ - dev_dbg(&link->dev, "ixj_detach\n"); - - ixj_cs_release(link); - - kfree(link->priv); -} - -static void ixj_get_serial(struct pcmcia_device * link, IXJ * j) -{ - char *str; - int i, place; - dev_dbg(&link->dev, "ixj_get_serial\n"); - - str = link->prod_id[0]; - if (!str) - goto failed; - printk("%s", str); - str = link->prod_id[1]; - if (!str) - goto failed; - printk(" %s", str); - str = link->prod_id[2]; - if (!str) - goto failed; - place = 1; - for (i = strlen(str) - 1; i >= 0; i--) { - switch (str[i]) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - j->serial += (str[i] - 48) * place; - break; - case 'A': - case 'B': - case 'C': - case 'D': - case 'E': - case 'F': - j->serial += (str[i] - 55) * place; - break; - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - j->serial += (str[i] - 87) * place; - break; - } - place = place * 0x10; - } - str = link->prod_id[3]; - if (!str) - goto failed; - printk(" version %s\n", str); -failed: - return; -} - -static int ixj_config_check(struct pcmcia_device *p_dev, void *priv_data) -{ - p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; - p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; - p_dev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH; - p_dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; - p_dev->io_lines = 3; - - return pcmcia_request_io(p_dev); -} - -static int ixj_config(struct pcmcia_device * link) -{ - IXJ *j; - ixj_info_t *info; - - info = link->priv; - dev_dbg(&link->dev, "ixj_config\n"); - - link->config_flags = CONF_AUTO_SET_IO; - - if (pcmcia_loop_config(link, ixj_config_check, NULL)) - goto failed; - - if (pcmcia_enable_device(link)) - goto failed; - - /* - * Register the card with the core. - */ - j = ixj_pcmcia_probe(link->resource[0]->start, - link->resource[0]->start + 0x10); - - info->ndev = 1; - ixj_get_serial(link, j); - return 0; - -failed: - ixj_cs_release(link); - return -ENODEV; -} - -static void ixj_cs_release(struct pcmcia_device *link) -{ - ixj_info_t *info = link->priv; - dev_dbg(&link->dev, "ixj_cs_release\n"); - info->ndev = 0; - pcmcia_disable_device(link); -} - -static const struct pcmcia_device_id ixj_ids[] = { - PCMCIA_DEVICE_MANF_CARD(0x0257, 0x0600), - PCMCIA_DEVICE_NULL -}; -MODULE_DEVICE_TABLE(pcmcia, ixj_ids); - -static struct pcmcia_driver ixj_driver = { - .owner = THIS_MODULE, - .name = "ixj_cs", - .probe = ixj_probe, - .remove = ixj_detach, - .id_table = ixj_ids, -}; - -static int __init ixj_pcmcia_init(void) -{ - return pcmcia_register_driver(&ixj_driver); -} - -static void ixj_pcmcia_exit(void) -{ - pcmcia_unregister_driver(&ixj_driver); -} - -module_init(ixj_pcmcia_init); -module_exit(ixj_pcmcia_exit); - -MODULE_LICENSE("GPL"); diff --git a/drivers/telephony/phonedev.c b/drivers/telephony/phonedev.c deleted file mode 100644 index 1915af20117..00000000000 --- a/drivers/telephony/phonedev.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Telephony registration for Linux - * - * (c) Copyright 1999 Red Hat Software 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. - * - * Author: Alan Cox, - * - * Fixes: Mar 01 2000 Thomas Sparr, - * phone_register_device now works with unit!=PHONE_UNIT_ANY - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define PHONE_NUM_DEVICES 256 - -/* - * Active devices - */ - -static struct phone_device *phone_device[PHONE_NUM_DEVICES]; -static DEFINE_MUTEX(phone_lock); - -/* - * Open a phone device. - */ - -static int phone_open(struct inode *inode, struct file *file) -{ - unsigned int minor = iminor(inode); - int err = 0; - struct phone_device *p; - const struct file_operations *old_fops, *new_fops = NULL; - - if (minor >= PHONE_NUM_DEVICES) - return -ENODEV; - - mutex_lock(&phone_lock); - p = phone_device[minor]; - if (p) - new_fops = fops_get(p->f_op); - if (!new_fops) { - mutex_unlock(&phone_lock); - request_module("char-major-%d-%d", PHONE_MAJOR, minor); - mutex_lock(&phone_lock); - p = phone_device[minor]; - if (p == NULL || (new_fops = fops_get(p->f_op)) == NULL) - { - err=-ENODEV; - goto end; - } - } - old_fops = file->f_op; - file->f_op = new_fops; - if (p->open) - err = p->open(p, file); /* Tell the device it is open */ - if (err) { - fops_put(file->f_op); - file->f_op = fops_get(old_fops); - } - fops_put(old_fops); -end: - mutex_unlock(&phone_lock); - return err; -} - -/* - * Telephony For Linux device drivers request registration here. - */ - -int phone_register_device(struct phone_device *p, int unit) -{ - int base; - int end; - int i; - - base = 0; - end = PHONE_NUM_DEVICES - 1; - - if (unit != PHONE_UNIT_ANY) { - base = unit; - end = unit + 1; /* enter the loop at least one time */ - } - - mutex_lock(&phone_lock); - for (i = base; i < end; i++) { - if (phone_device[i] == NULL) { - phone_device[i] = p; - p->minor = i; - mutex_unlock(&phone_lock); - return 0; - } - } - mutex_unlock(&phone_lock); - return -ENFILE; -} - -/* - * Unregister an unused Telephony for linux device - */ - -void phone_unregister_device(struct phone_device *pfd) -{ - mutex_lock(&phone_lock); - if (likely(phone_device[pfd->minor] == pfd)) - phone_device[pfd->minor] = NULL; - mutex_unlock(&phone_lock); -} - - -static const struct file_operations phone_fops = -{ - .owner = THIS_MODULE, - .open = phone_open, - .llseek = noop_llseek, -}; - -/* - * Board init functions - */ - - -/* - * Initialise Telephony for linux - */ - -static int __init telephony_init(void) -{ - printk(KERN_INFO "Linux telephony interface: v1.00\n"); - if (register_chrdev(PHONE_MAJOR, "telephony", &phone_fops)) { - printk("phonedev: unable to get major %d\n", PHONE_MAJOR); - return -EIO; - } - - return 0; -} - -static void __exit telephony_exit(void) -{ - unregister_chrdev(PHONE_MAJOR, "telephony"); -} - -module_init(telephony_init); -module_exit(telephony_exit); - -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(phone_register_device); -EXPORT_SYMBOL(phone_unregister_device); -- cgit v1.2.3-70-g09d2 From 32de21f75d0152571eb3710f170cddb5db3d0336 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Wed, 25 Jan 2012 23:14:56 +0900 Subject: staging: Fix typo in mei/interrupt.c Correct spelling "reseting" to "resetting" in drivers/staging/mei/interrupt.c Signed-off-by: Masanari Iida Signed-off-by: Greg Kroah-Hartman --- drivers/staging/mei/interrupt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/mei/interrupt.c b/drivers/staging/mei/interrupt.c index 3544fee34e4..e85a85a9603 100644 --- a/drivers/staging/mei/interrupt.c +++ b/drivers/staging/mei/interrupt.c @@ -1423,7 +1423,7 @@ void mei_timer(struct work_struct *work) if (dev->iamthif_stall_timer) { if (--dev->iamthif_stall_timer == 0) { - dev_dbg(&dev->pdev->dev, "reseting because of hang to amthi.\n"); + dev_dbg(&dev->pdev->dev, "resetting because of hang to amthi.\n"); mei_reset(dev, 1); dev->iamthif_msg_buf_size = 0; dev->iamthif_msg_buf_index = 0; -- cgit v1.2.3-70-g09d2 From 1135ca9c869fff55a32fdce2171b33f36e44ea0c Mon Sep 17 00:00:00 2001 From: Dan Magenheimer Date: Mon, 30 Jan 2012 14:39:18 -0800 Subject: staging: ramster: cluster/messaging foundation Copy cluster subdirectory from ocfs2. These files implement the basic cluster discovery, mapping, heartbeat / keepalive, and messaging ("o2net") that ramster requires for internode communication. Note: there are NO ramster-specific changes yet; this commit does NOT pass checkpatch since the copied source files do not. (Why copy? This particular part of ocfs2 has never been broken out for non-ocfs2 use before, some (small) changes are required for ramster to use that code, and ramster is currently incompatible with real ocfs2 anyway (requires !CONFIG_OCFS2_FS). Before ramster can be promoted out of staging, we will need to work with the ocfs2 maintainers to see if the code interdependencies can be merged, but for now, for staging, this seemed to be an expedient way to make use of the ocfs2 core cluster code while still incorporating necessary changes for ramster.) Signed-off-by: Dan Magenheimer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ramster/cluster/Makefile | 4 + drivers/staging/ramster/cluster/heartbeat.c | 2678 ++++++++++++++++++++ drivers/staging/ramster/cluster/heartbeat.h | 89 + drivers/staging/ramster/cluster/masklog.c | 155 ++ drivers/staging/ramster/cluster/masklog.h | 219 ++ drivers/staging/ramster/cluster/netdebug.c | 579 +++++ drivers/staging/ramster/cluster/nodemanager.c | 989 ++++++++ drivers/staging/ramster/cluster/nodemanager.h | 88 + drivers/staging/ramster/cluster/ocfs2_heartbeat.h | 38 + .../staging/ramster/cluster/ocfs2_nodemanager.h | 45 + drivers/staging/ramster/cluster/quorum.c | 331 +++ drivers/staging/ramster/cluster/quorum.h | 36 + drivers/staging/ramster/cluster/sys.c | 82 + drivers/staging/ramster/cluster/sys.h | 33 + drivers/staging/ramster/cluster/tcp.c | 2150 ++++++++++++++++ drivers/staging/ramster/cluster/tcp.h | 154 ++ drivers/staging/ramster/cluster/tcp_internal.h | 242 ++ drivers/staging/ramster/cluster/ver.c | 42 + drivers/staging/ramster/cluster/ver.h | 31 + 19 files changed, 7985 insertions(+) create mode 100644 drivers/staging/ramster/cluster/Makefile create mode 100644 drivers/staging/ramster/cluster/heartbeat.c create mode 100644 drivers/staging/ramster/cluster/heartbeat.h create mode 100644 drivers/staging/ramster/cluster/masklog.c create mode 100644 drivers/staging/ramster/cluster/masklog.h create mode 100644 drivers/staging/ramster/cluster/netdebug.c create mode 100644 drivers/staging/ramster/cluster/nodemanager.c create mode 100644 drivers/staging/ramster/cluster/nodemanager.h create mode 100644 drivers/staging/ramster/cluster/ocfs2_heartbeat.h create mode 100644 drivers/staging/ramster/cluster/ocfs2_nodemanager.h create mode 100644 drivers/staging/ramster/cluster/quorum.c create mode 100644 drivers/staging/ramster/cluster/quorum.h create mode 100644 drivers/staging/ramster/cluster/sys.c create mode 100644 drivers/staging/ramster/cluster/sys.h create mode 100644 drivers/staging/ramster/cluster/tcp.c create mode 100644 drivers/staging/ramster/cluster/tcp.h create mode 100644 drivers/staging/ramster/cluster/tcp_internal.h create mode 100644 drivers/staging/ramster/cluster/ver.c create mode 100644 drivers/staging/ramster/cluster/ver.h (limited to 'drivers') diff --git a/drivers/staging/ramster/cluster/Makefile b/drivers/staging/ramster/cluster/Makefile new file mode 100644 index 00000000000..bc8c5e7d860 --- /dev/null +++ b/drivers/staging/ramster/cluster/Makefile @@ -0,0 +1,4 @@ +obj-$(CONFIG_OCFS2_FS) += ocfs2_nodemanager.o + +ocfs2_nodemanager-objs := heartbeat.o masklog.o sys.o nodemanager.o \ + quorum.o tcp.o netdebug.o ver.o diff --git a/drivers/staging/ramster/cluster/heartbeat.c b/drivers/staging/ramster/cluster/heartbeat.c new file mode 100644 index 00000000000..a4e855e3690 --- /dev/null +++ b/drivers/staging/ramster/cluster/heartbeat.c @@ -0,0 +1,2678 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * Copyright (C) 2004, 2005 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "heartbeat.h" +#include "tcp.h" +#include "nodemanager.h" +#include "quorum.h" + +#include "masklog.h" + + +/* + * The first heartbeat pass had one global thread that would serialize all hb + * callback calls. This global serializing sem should only be removed once + * we've made sure that all callees can deal with being called concurrently + * from multiple hb region threads. + */ +static DECLARE_RWSEM(o2hb_callback_sem); + +/* + * multiple hb threads are watching multiple regions. A node is live + * whenever any of the threads sees activity from the node in its region. + */ +static DEFINE_SPINLOCK(o2hb_live_lock); +static struct list_head o2hb_live_slots[O2NM_MAX_NODES]; +static unsigned long o2hb_live_node_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)]; +static LIST_HEAD(o2hb_node_events); +static DECLARE_WAIT_QUEUE_HEAD(o2hb_steady_queue); + +/* + * In global heartbeat, we maintain a series of region bitmaps. + * - o2hb_region_bitmap allows us to limit the region number to max region. + * - o2hb_live_region_bitmap tracks live regions (seen steady iterations). + * - o2hb_quorum_region_bitmap tracks live regions that have seen all nodes + * heartbeat on it. + * - o2hb_failed_region_bitmap tracks the regions that have seen io timeouts. + */ +static unsigned long o2hb_region_bitmap[BITS_TO_LONGS(O2NM_MAX_REGIONS)]; +static unsigned long o2hb_live_region_bitmap[BITS_TO_LONGS(O2NM_MAX_REGIONS)]; +static unsigned long o2hb_quorum_region_bitmap[BITS_TO_LONGS(O2NM_MAX_REGIONS)]; +static unsigned long o2hb_failed_region_bitmap[BITS_TO_LONGS(O2NM_MAX_REGIONS)]; + +#define O2HB_DB_TYPE_LIVENODES 0 +#define O2HB_DB_TYPE_LIVEREGIONS 1 +#define O2HB_DB_TYPE_QUORUMREGIONS 2 +#define O2HB_DB_TYPE_FAILEDREGIONS 3 +#define O2HB_DB_TYPE_REGION_LIVENODES 4 +#define O2HB_DB_TYPE_REGION_NUMBER 5 +#define O2HB_DB_TYPE_REGION_ELAPSED_TIME 6 +#define O2HB_DB_TYPE_REGION_PINNED 7 +struct o2hb_debug_buf { + int db_type; + int db_size; + int db_len; + void *db_data; +}; + +static struct o2hb_debug_buf *o2hb_db_livenodes; +static struct o2hb_debug_buf *o2hb_db_liveregions; +static struct o2hb_debug_buf *o2hb_db_quorumregions; +static struct o2hb_debug_buf *o2hb_db_failedregions; + +#define O2HB_DEBUG_DIR "o2hb" +#define O2HB_DEBUG_LIVENODES "livenodes" +#define O2HB_DEBUG_LIVEREGIONS "live_regions" +#define O2HB_DEBUG_QUORUMREGIONS "quorum_regions" +#define O2HB_DEBUG_FAILEDREGIONS "failed_regions" +#define O2HB_DEBUG_REGION_NUMBER "num" +#define O2HB_DEBUG_REGION_ELAPSED_TIME "elapsed_time_in_ms" +#define O2HB_DEBUG_REGION_PINNED "pinned" + +static struct dentry *o2hb_debug_dir; +static struct dentry *o2hb_debug_livenodes; +static struct dentry *o2hb_debug_liveregions; +static struct dentry *o2hb_debug_quorumregions; +static struct dentry *o2hb_debug_failedregions; + +static LIST_HEAD(o2hb_all_regions); + +static struct o2hb_callback { + struct list_head list; +} o2hb_callbacks[O2HB_NUM_CB]; + +static struct o2hb_callback *hbcall_from_type(enum o2hb_callback_type type); + +#define O2HB_DEFAULT_BLOCK_BITS 9 + +enum o2hb_heartbeat_modes { + O2HB_HEARTBEAT_LOCAL = 0, + O2HB_HEARTBEAT_GLOBAL, + O2HB_HEARTBEAT_NUM_MODES, +}; + +char *o2hb_heartbeat_mode_desc[O2HB_HEARTBEAT_NUM_MODES] = { + "local", /* O2HB_HEARTBEAT_LOCAL */ + "global", /* O2HB_HEARTBEAT_GLOBAL */ +}; + +unsigned int o2hb_dead_threshold = O2HB_DEFAULT_DEAD_THRESHOLD; +unsigned int o2hb_heartbeat_mode = O2HB_HEARTBEAT_LOCAL; + +/* + * o2hb_dependent_users tracks the number of registered callbacks that depend + * on heartbeat. o2net and o2dlm are two entities that register this callback. + * However only o2dlm depends on the heartbeat. It does not want the heartbeat + * to stop while a dlm domain is still active. + */ +unsigned int o2hb_dependent_users; + +/* + * In global heartbeat mode, all regions are pinned if there are one or more + * dependent users and the quorum region count is <= O2HB_PIN_CUT_OFF. All + * regions are unpinned if the region count exceeds the cut off or the number + * of dependent users falls to zero. + */ +#define O2HB_PIN_CUT_OFF 3 + +/* + * In local heartbeat mode, we assume the dlm domain name to be the same as + * region uuid. This is true for domains created for the file system but not + * necessarily true for userdlm domains. This is a known limitation. + * + * In global heartbeat mode, we pin/unpin all o2hb regions. This solution + * works for both file system and userdlm domains. + */ +static int o2hb_region_pin(const char *region_uuid); +static void o2hb_region_unpin(const char *region_uuid); + +/* Only sets a new threshold if there are no active regions. + * + * No locking or otherwise interesting code is required for reading + * o2hb_dead_threshold as it can't change once regions are active and + * it's not interesting to anyone until then anyway. */ +static void o2hb_dead_threshold_set(unsigned int threshold) +{ + if (threshold > O2HB_MIN_DEAD_THRESHOLD) { + spin_lock(&o2hb_live_lock); + if (list_empty(&o2hb_all_regions)) + o2hb_dead_threshold = threshold; + spin_unlock(&o2hb_live_lock); + } +} + +static int o2hb_global_hearbeat_mode_set(unsigned int hb_mode) +{ + int ret = -1; + + if (hb_mode < O2HB_HEARTBEAT_NUM_MODES) { + spin_lock(&o2hb_live_lock); + if (list_empty(&o2hb_all_regions)) { + o2hb_heartbeat_mode = hb_mode; + ret = 0; + } + spin_unlock(&o2hb_live_lock); + } + + return ret; +} + +struct o2hb_node_event { + struct list_head hn_item; + enum o2hb_callback_type hn_event_type; + struct o2nm_node *hn_node; + int hn_node_num; +}; + +struct o2hb_disk_slot { + struct o2hb_disk_heartbeat_block *ds_raw_block; + u8 ds_node_num; + u64 ds_last_time; + u64 ds_last_generation; + u16 ds_equal_samples; + u16 ds_changed_samples; + struct list_head ds_live_item; +}; + +/* each thread owns a region.. when we're asked to tear down the region + * we ask the thread to stop, who cleans up the region */ +struct o2hb_region { + struct config_item hr_item; + + struct list_head hr_all_item; + unsigned hr_unclean_stop:1, + hr_aborted_start:1, + hr_item_pinned:1, + hr_item_dropped:1; + + /* protected by the hr_callback_sem */ + struct task_struct *hr_task; + + unsigned int hr_blocks; + unsigned long long hr_start_block; + + unsigned int hr_block_bits; + unsigned int hr_block_bytes; + + unsigned int hr_slots_per_page; + unsigned int hr_num_pages; + + struct page **hr_slot_data; + struct block_device *hr_bdev; + struct o2hb_disk_slot *hr_slots; + + /* live node map of this region */ + unsigned long hr_live_node_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)]; + unsigned int hr_region_num; + + struct dentry *hr_debug_dir; + struct dentry *hr_debug_livenodes; + struct dentry *hr_debug_regnum; + struct dentry *hr_debug_elapsed_time; + struct dentry *hr_debug_pinned; + struct o2hb_debug_buf *hr_db_livenodes; + struct o2hb_debug_buf *hr_db_regnum; + struct o2hb_debug_buf *hr_db_elapsed_time; + struct o2hb_debug_buf *hr_db_pinned; + + /* let the person setting up hb wait for it to return until it + * has reached a 'steady' state. This will be fixed when we have + * a more complete api that doesn't lead to this sort of fragility. */ + atomic_t hr_steady_iterations; + + /* terminate o2hb thread if it does not reach steady state + * (hr_steady_iterations == 0) within hr_unsteady_iterations */ + atomic_t hr_unsteady_iterations; + + char hr_dev_name[BDEVNAME_SIZE]; + + unsigned int hr_timeout_ms; + + /* randomized as the region goes up and down so that a node + * recognizes a node going up and down in one iteration */ + u64 hr_generation; + + struct delayed_work hr_write_timeout_work; + unsigned long hr_last_timeout_start; + + /* Used during o2hb_check_slot to hold a copy of the block + * being checked because we temporarily have to zero out the + * crc field. */ + struct o2hb_disk_heartbeat_block *hr_tmp_block; +}; + +struct o2hb_bio_wait_ctxt { + atomic_t wc_num_reqs; + struct completion wc_io_complete; + int wc_error; +}; + +static int o2hb_pop_count(void *map, int count) +{ + int i = -1, pop = 0; + + while ((i = find_next_bit(map, count, i + 1)) < count) + pop++; + return pop; +} + +static void o2hb_write_timeout(struct work_struct *work) +{ + int failed, quorum; + unsigned long flags; + struct o2hb_region *reg = + container_of(work, struct o2hb_region, + hr_write_timeout_work.work); + + mlog(ML_ERROR, "Heartbeat write timeout to device %s after %u " + "milliseconds\n", reg->hr_dev_name, + jiffies_to_msecs(jiffies - reg->hr_last_timeout_start)); + + if (o2hb_global_heartbeat_active()) { + spin_lock_irqsave(&o2hb_live_lock, flags); + if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap)) + set_bit(reg->hr_region_num, o2hb_failed_region_bitmap); + failed = o2hb_pop_count(&o2hb_failed_region_bitmap, + O2NM_MAX_REGIONS); + quorum = o2hb_pop_count(&o2hb_quorum_region_bitmap, + O2NM_MAX_REGIONS); + spin_unlock_irqrestore(&o2hb_live_lock, flags); + + mlog(ML_HEARTBEAT, "Number of regions %d, failed regions %d\n", + quorum, failed); + + /* + * Fence if the number of failed regions >= half the number + * of quorum regions + */ + if ((failed << 1) < quorum) + return; + } + + o2quo_disk_timeout(); +} + +static void o2hb_arm_write_timeout(struct o2hb_region *reg) +{ + /* Arm writeout only after thread reaches steady state */ + if (atomic_read(®->hr_steady_iterations) != 0) + return; + + mlog(ML_HEARTBEAT, "Queue write timeout for %u ms\n", + O2HB_MAX_WRITE_TIMEOUT_MS); + + if (o2hb_global_heartbeat_active()) { + spin_lock(&o2hb_live_lock); + clear_bit(reg->hr_region_num, o2hb_failed_region_bitmap); + spin_unlock(&o2hb_live_lock); + } + cancel_delayed_work(®->hr_write_timeout_work); + reg->hr_last_timeout_start = jiffies; + schedule_delayed_work(®->hr_write_timeout_work, + msecs_to_jiffies(O2HB_MAX_WRITE_TIMEOUT_MS)); +} + +static void o2hb_disarm_write_timeout(struct o2hb_region *reg) +{ + cancel_delayed_work_sync(®->hr_write_timeout_work); +} + +static inline void o2hb_bio_wait_init(struct o2hb_bio_wait_ctxt *wc) +{ + atomic_set(&wc->wc_num_reqs, 1); + init_completion(&wc->wc_io_complete); + wc->wc_error = 0; +} + +/* Used in error paths too */ +static inline void o2hb_bio_wait_dec(struct o2hb_bio_wait_ctxt *wc, + unsigned int num) +{ + /* sadly atomic_sub_and_test() isn't available on all platforms. The + * good news is that the fast path only completes one at a time */ + while(num--) { + if (atomic_dec_and_test(&wc->wc_num_reqs)) { + BUG_ON(num > 0); + complete(&wc->wc_io_complete); + } + } +} + +static void o2hb_wait_on_io(struct o2hb_region *reg, + struct o2hb_bio_wait_ctxt *wc) +{ + o2hb_bio_wait_dec(wc, 1); + wait_for_completion(&wc->wc_io_complete); +} + +static void o2hb_bio_end_io(struct bio *bio, + int error) +{ + struct o2hb_bio_wait_ctxt *wc = bio->bi_private; + + if (error) { + mlog(ML_ERROR, "IO Error %d\n", error); + wc->wc_error = error; + } + + o2hb_bio_wait_dec(wc, 1); + bio_put(bio); +} + +/* Setup a Bio to cover I/O against num_slots slots starting at + * start_slot. */ +static struct bio *o2hb_setup_one_bio(struct o2hb_region *reg, + struct o2hb_bio_wait_ctxt *wc, + unsigned int *current_slot, + unsigned int max_slots) +{ + int len, current_page; + unsigned int vec_len, vec_start; + unsigned int bits = reg->hr_block_bits; + unsigned int spp = reg->hr_slots_per_page; + unsigned int cs = *current_slot; + struct bio *bio; + struct page *page; + + /* Testing has shown this allocation to take long enough under + * GFP_KERNEL that the local node can get fenced. It would be + * nicest if we could pre-allocate these bios and avoid this + * all together. */ + bio = bio_alloc(GFP_ATOMIC, 16); + if (!bio) { + mlog(ML_ERROR, "Could not alloc slots BIO!\n"); + bio = ERR_PTR(-ENOMEM); + goto bail; + } + + /* Must put everything in 512 byte sectors for the bio... */ + bio->bi_sector = (reg->hr_start_block + cs) << (bits - 9); + bio->bi_bdev = reg->hr_bdev; + bio->bi_private = wc; + bio->bi_end_io = o2hb_bio_end_io; + + vec_start = (cs << bits) % PAGE_CACHE_SIZE; + while(cs < max_slots) { + current_page = cs / spp; + page = reg->hr_slot_data[current_page]; + + vec_len = min(PAGE_CACHE_SIZE - vec_start, + (max_slots-cs) * (PAGE_CACHE_SIZE/spp) ); + + mlog(ML_HB_BIO, "page %d, vec_len = %u, vec_start = %u\n", + current_page, vec_len, vec_start); + + len = bio_add_page(bio, page, vec_len, vec_start); + if (len != vec_len) break; + + cs += vec_len / (PAGE_CACHE_SIZE/spp); + vec_start = 0; + } + +bail: + *current_slot = cs; + return bio; +} + +static int o2hb_read_slots(struct o2hb_region *reg, + unsigned int max_slots) +{ + unsigned int current_slot=0; + int status; + struct o2hb_bio_wait_ctxt wc; + struct bio *bio; + + o2hb_bio_wait_init(&wc); + + while(current_slot < max_slots) { + bio = o2hb_setup_one_bio(reg, &wc, ¤t_slot, max_slots); + if (IS_ERR(bio)) { + status = PTR_ERR(bio); + mlog_errno(status); + goto bail_and_wait; + } + + atomic_inc(&wc.wc_num_reqs); + submit_bio(READ, bio); + } + + status = 0; + +bail_and_wait: + o2hb_wait_on_io(reg, &wc); + if (wc.wc_error && !status) + status = wc.wc_error; + + return status; +} + +static int o2hb_issue_node_write(struct o2hb_region *reg, + struct o2hb_bio_wait_ctxt *write_wc) +{ + int status; + unsigned int slot; + struct bio *bio; + + o2hb_bio_wait_init(write_wc); + + slot = o2nm_this_node(); + + bio = o2hb_setup_one_bio(reg, write_wc, &slot, slot+1); + if (IS_ERR(bio)) { + status = PTR_ERR(bio); + mlog_errno(status); + goto bail; + } + + atomic_inc(&write_wc->wc_num_reqs); + submit_bio(WRITE, bio); + + status = 0; +bail: + return status; +} + +static u32 o2hb_compute_block_crc_le(struct o2hb_region *reg, + struct o2hb_disk_heartbeat_block *hb_block) +{ + __le32 old_cksum; + u32 ret; + + /* We want to compute the block crc with a 0 value in the + * hb_cksum field. Save it off here and replace after the + * crc. */ + old_cksum = hb_block->hb_cksum; + hb_block->hb_cksum = 0; + + ret = crc32_le(0, (unsigned char *) hb_block, reg->hr_block_bytes); + + hb_block->hb_cksum = old_cksum; + + return ret; +} + +static void o2hb_dump_slot(struct o2hb_disk_heartbeat_block *hb_block) +{ + mlog(ML_ERROR, "Dump slot information: seq = 0x%llx, node = %u, " + "cksum = 0x%x, generation 0x%llx\n", + (long long)le64_to_cpu(hb_block->hb_seq), + hb_block->hb_node, le32_to_cpu(hb_block->hb_cksum), + (long long)le64_to_cpu(hb_block->hb_generation)); +} + +static int o2hb_verify_crc(struct o2hb_region *reg, + struct o2hb_disk_heartbeat_block *hb_block) +{ + u32 read, computed; + + read = le32_to_cpu(hb_block->hb_cksum); + computed = o2hb_compute_block_crc_le(reg, hb_block); + + return read == computed; +} + +/* + * Compare the slot data with what we wrote in the last iteration. + * If the match fails, print an appropriate error message. This is to + * detect errors like... another node hearting on the same slot, + * flaky device that is losing writes, etc. + * Returns 1 if check succeeds, 0 otherwise. + */ +static int o2hb_check_own_slot(struct o2hb_region *reg) +{ + struct o2hb_disk_slot *slot; + struct o2hb_disk_heartbeat_block *hb_block; + char *errstr; + + slot = ®->hr_slots[o2nm_this_node()]; + /* Don't check on our 1st timestamp */ + if (!slot->ds_last_time) + return 0; + + hb_block = slot->ds_raw_block; + if (le64_to_cpu(hb_block->hb_seq) == slot->ds_last_time && + le64_to_cpu(hb_block->hb_generation) == slot->ds_last_generation && + hb_block->hb_node == slot->ds_node_num) + return 1; + +#define ERRSTR1 "Another node is heartbeating on device" +#define ERRSTR2 "Heartbeat generation mismatch on device" +#define ERRSTR3 "Heartbeat sequence mismatch on device" + + if (hb_block->hb_node != slot->ds_node_num) + errstr = ERRSTR1; + else if (le64_to_cpu(hb_block->hb_generation) != + slot->ds_last_generation) + errstr = ERRSTR2; + else + errstr = ERRSTR3; + + mlog(ML_ERROR, "%s (%s): expected(%u:0x%llx, 0x%llx), " + "ondisk(%u:0x%llx, 0x%llx)\n", errstr, reg->hr_dev_name, + slot->ds_node_num, (unsigned long long)slot->ds_last_generation, + (unsigned long long)slot->ds_last_time, hb_block->hb_node, + (unsigned long long)le64_to_cpu(hb_block->hb_generation), + (unsigned long long)le64_to_cpu(hb_block->hb_seq)); + + return 0; +} + +static inline void o2hb_prepare_block(struct o2hb_region *reg, + u64 generation) +{ + int node_num; + u64 cputime; + struct o2hb_disk_slot *slot; + struct o2hb_disk_heartbeat_block *hb_block; + + node_num = o2nm_this_node(); + slot = ®->hr_slots[node_num]; + + hb_block = (struct o2hb_disk_heartbeat_block *)slot->ds_raw_block; + memset(hb_block, 0, reg->hr_block_bytes); + /* TODO: time stuff */ + cputime = CURRENT_TIME.tv_sec; + if (!cputime) + cputime = 1; + + hb_block->hb_seq = cpu_to_le64(cputime); + hb_block->hb_node = node_num; + hb_block->hb_generation = cpu_to_le64(generation); + hb_block->hb_dead_ms = cpu_to_le32(o2hb_dead_threshold * O2HB_REGION_TIMEOUT_MS); + + /* This step must always happen last! */ + hb_block->hb_cksum = cpu_to_le32(o2hb_compute_block_crc_le(reg, + hb_block)); + + mlog(ML_HB_BIO, "our node generation = 0x%llx, cksum = 0x%x\n", + (long long)generation, + le32_to_cpu(hb_block->hb_cksum)); +} + +static void o2hb_fire_callbacks(struct o2hb_callback *hbcall, + struct o2nm_node *node, + int idx) +{ + struct list_head *iter; + struct o2hb_callback_func *f; + + list_for_each(iter, &hbcall->list) { + f = list_entry(iter, struct o2hb_callback_func, hc_item); + mlog(ML_HEARTBEAT, "calling funcs %p\n", f); + (f->hc_func)(node, idx, f->hc_data); + } +} + +/* Will run the list in order until we process the passed event */ +static void o2hb_run_event_list(struct o2hb_node_event *queued_event) +{ + int empty; + struct o2hb_callback *hbcall; + struct o2hb_node_event *event; + + spin_lock(&o2hb_live_lock); + empty = list_empty(&queued_event->hn_item); + spin_unlock(&o2hb_live_lock); + if (empty) + return; + + /* Holding callback sem assures we don't alter the callback + * lists when doing this, and serializes ourselves with other + * processes wanting callbacks. */ + down_write(&o2hb_callback_sem); + + spin_lock(&o2hb_live_lock); + while (!list_empty(&o2hb_node_events) + && !list_empty(&queued_event->hn_item)) { + event = list_entry(o2hb_node_events.next, + struct o2hb_node_event, + hn_item); + list_del_init(&event->hn_item); + spin_unlock(&o2hb_live_lock); + + mlog(ML_HEARTBEAT, "Node %s event for %d\n", + event->hn_event_type == O2HB_NODE_UP_CB ? "UP" : "DOWN", + event->hn_node_num); + + hbcall = hbcall_from_type(event->hn_event_type); + + /* We should *never* have gotten on to the list with a + * bad type... This isn't something that we should try + * to recover from. */ + BUG_ON(IS_ERR(hbcall)); + + o2hb_fire_callbacks(hbcall, event->hn_node, event->hn_node_num); + + spin_lock(&o2hb_live_lock); + } + spin_unlock(&o2hb_live_lock); + + up_write(&o2hb_callback_sem); +} + +static void o2hb_queue_node_event(struct o2hb_node_event *event, + enum o2hb_callback_type type, + struct o2nm_node *node, + int node_num) +{ + assert_spin_locked(&o2hb_live_lock); + + BUG_ON((!node) && (type != O2HB_NODE_DOWN_CB)); + + event->hn_event_type = type; + event->hn_node = node; + event->hn_node_num = node_num; + + mlog(ML_HEARTBEAT, "Queue node %s event for node %d\n", + type == O2HB_NODE_UP_CB ? "UP" : "DOWN", node_num); + + list_add_tail(&event->hn_item, &o2hb_node_events); +} + +static void o2hb_shutdown_slot(struct o2hb_disk_slot *slot) +{ + struct o2hb_node_event event = + { .hn_item = LIST_HEAD_INIT(event.hn_item), }; + struct o2nm_node *node; + + node = o2nm_get_node_by_num(slot->ds_node_num); + if (!node) + return; + + spin_lock(&o2hb_live_lock); + if (!list_empty(&slot->ds_live_item)) { + mlog(ML_HEARTBEAT, "Shutdown, node %d leaves region\n", + slot->ds_node_num); + + list_del_init(&slot->ds_live_item); + + if (list_empty(&o2hb_live_slots[slot->ds_node_num])) { + clear_bit(slot->ds_node_num, o2hb_live_node_bitmap); + + o2hb_queue_node_event(&event, O2HB_NODE_DOWN_CB, node, + slot->ds_node_num); + } + } + spin_unlock(&o2hb_live_lock); + + o2hb_run_event_list(&event); + + o2nm_node_put(node); +} + +static void o2hb_set_quorum_device(struct o2hb_region *reg) +{ + if (!o2hb_global_heartbeat_active()) + return; + + /* Prevent race with o2hb_heartbeat_group_drop_item() */ + if (kthread_should_stop()) + return; + + /* Tag region as quorum only after thread reaches steady state */ + if (atomic_read(®->hr_steady_iterations) != 0) + return; + + spin_lock(&o2hb_live_lock); + + if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap)) + goto unlock; + + /* + * A region can be added to the quorum only when it sees all + * live nodes heartbeat on it. In other words, the region has been + * added to all nodes. + */ + if (memcmp(reg->hr_live_node_bitmap, o2hb_live_node_bitmap, + sizeof(o2hb_live_node_bitmap))) + goto unlock; + + printk(KERN_NOTICE "o2hb: Region %s (%s) is now a quorum device\n", + config_item_name(®->hr_item), reg->hr_dev_name); + + set_bit(reg->hr_region_num, o2hb_quorum_region_bitmap); + + /* + * If global heartbeat active, unpin all regions if the + * region count > CUT_OFF + */ + if (o2hb_pop_count(&o2hb_quorum_region_bitmap, + O2NM_MAX_REGIONS) > O2HB_PIN_CUT_OFF) + o2hb_region_unpin(NULL); +unlock: + spin_unlock(&o2hb_live_lock); +} + +static int o2hb_check_slot(struct o2hb_region *reg, + struct o2hb_disk_slot *slot) +{ + int changed = 0, gen_changed = 0; + struct o2hb_node_event event = + { .hn_item = LIST_HEAD_INIT(event.hn_item), }; + struct o2nm_node *node; + struct o2hb_disk_heartbeat_block *hb_block = reg->hr_tmp_block; + u64 cputime; + unsigned int dead_ms = o2hb_dead_threshold * O2HB_REGION_TIMEOUT_MS; + unsigned int slot_dead_ms; + int tmp; + + memcpy(hb_block, slot->ds_raw_block, reg->hr_block_bytes); + + /* + * If a node is no longer configured but is still in the livemap, we + * may need to clear that bit from the livemap. + */ + node = o2nm_get_node_by_num(slot->ds_node_num); + if (!node) { + spin_lock(&o2hb_live_lock); + tmp = test_bit(slot->ds_node_num, o2hb_live_node_bitmap); + spin_unlock(&o2hb_live_lock); + if (!tmp) + return 0; + } + + if (!o2hb_verify_crc(reg, hb_block)) { + /* all paths from here will drop o2hb_live_lock for + * us. */ + spin_lock(&o2hb_live_lock); + + /* Don't print an error on the console in this case - + * a freshly formatted heartbeat area will not have a + * crc set on it. */ + if (list_empty(&slot->ds_live_item)) + goto out; + + /* The node is live but pushed out a bad crc. We + * consider it a transient miss but don't populate any + * other values as they may be junk. */ + mlog(ML_ERROR, "Node %d has written a bad crc to %s\n", + slot->ds_node_num, reg->hr_dev_name); + o2hb_dump_slot(hb_block); + + slot->ds_equal_samples++; + goto fire_callbacks; + } + + /* we don't care if these wrap.. the state transitions below + * clear at the right places */ + cputime = le64_to_cpu(hb_block->hb_seq); + if (slot->ds_last_time != cputime) + slot->ds_changed_samples++; + else + slot->ds_equal_samples++; + slot->ds_last_time = cputime; + + /* The node changed heartbeat generations. We assume this to + * mean it dropped off but came back before we timed out. We + * want to consider it down for the time being but don't want + * to lose any changed_samples state we might build up to + * considering it live again. */ + if (slot->ds_last_generation != le64_to_cpu(hb_block->hb_generation)) { + gen_changed = 1; + slot->ds_equal_samples = 0; + mlog(ML_HEARTBEAT, "Node %d changed generation (0x%llx " + "to 0x%llx)\n", slot->ds_node_num, + (long long)slot->ds_last_generation, + (long long)le64_to_cpu(hb_block->hb_generation)); + } + + slot->ds_last_generation = le64_to_cpu(hb_block->hb_generation); + + mlog(ML_HEARTBEAT, "Slot %d gen 0x%llx cksum 0x%x " + "seq %llu last %llu changed %u equal %u\n", + slot->ds_node_num, (long long)slot->ds_last_generation, + le32_to_cpu(hb_block->hb_cksum), + (unsigned long long)le64_to_cpu(hb_block->hb_seq), + (unsigned long long)slot->ds_last_time, slot->ds_changed_samples, + slot->ds_equal_samples); + + spin_lock(&o2hb_live_lock); + +fire_callbacks: + /* dead nodes only come to life after some number of + * changes at any time during their dead time */ + if (list_empty(&slot->ds_live_item) && + slot->ds_changed_samples >= O2HB_LIVE_THRESHOLD) { + mlog(ML_HEARTBEAT, "Node %d (id 0x%llx) joined my region\n", + slot->ds_node_num, (long long)slot->ds_last_generation); + + set_bit(slot->ds_node_num, reg->hr_live_node_bitmap); + + /* first on the list generates a callback */ + if (list_empty(&o2hb_live_slots[slot->ds_node_num])) { + mlog(ML_HEARTBEAT, "o2hb: Add node %d to live nodes " + "bitmap\n", slot->ds_node_num); + set_bit(slot->ds_node_num, o2hb_live_node_bitmap); + + o2hb_queue_node_event(&event, O2HB_NODE_UP_CB, node, + slot->ds_node_num); + + changed = 1; + } + + list_add_tail(&slot->ds_live_item, + &o2hb_live_slots[slot->ds_node_num]); + + slot->ds_equal_samples = 0; + + /* We want to be sure that all nodes agree on the + * number of milliseconds before a node will be + * considered dead. The self-fencing timeout is + * computed from this value, and a discrepancy might + * result in heartbeat calling a node dead when it + * hasn't self-fenced yet. */ + slot_dead_ms = le32_to_cpu(hb_block->hb_dead_ms); + if (slot_dead_ms && slot_dead_ms != dead_ms) { + /* TODO: Perhaps we can fail the region here. */ + mlog(ML_ERROR, "Node %d on device %s has a dead count " + "of %u ms, but our count is %u ms.\n" + "Please double check your configuration values " + "for 'O2CB_HEARTBEAT_THRESHOLD'\n", + slot->ds_node_num, reg->hr_dev_name, slot_dead_ms, + dead_ms); + } + goto out; + } + + /* if the list is dead, we're done.. */ + if (list_empty(&slot->ds_live_item)) + goto out; + + /* live nodes only go dead after enough consequtive missed + * samples.. reset the missed counter whenever we see + * activity */ + if (slot->ds_equal_samples >= o2hb_dead_threshold || gen_changed) { + mlog(ML_HEARTBEAT, "Node %d left my region\n", + slot->ds_node_num); + + clear_bit(slot->ds_node_num, reg->hr_live_node_bitmap); + + /* last off the live_slot generates a callback */ + list_del_init(&slot->ds_live_item); + if (list_empty(&o2hb_live_slots[slot->ds_node_num])) { + mlog(ML_HEARTBEAT, "o2hb: Remove node %d from live " + "nodes bitmap\n", slot->ds_node_num); + clear_bit(slot->ds_node_num, o2hb_live_node_bitmap); + + /* node can be null */ + o2hb_queue_node_event(&event, O2HB_NODE_DOWN_CB, + node, slot->ds_node_num); + + changed = 1; + } + + /* We don't clear this because the node is still + * actually writing new blocks. */ + if (!gen_changed) + slot->ds_changed_samples = 0; + goto out; + } + if (slot->ds_changed_samples) { + slot->ds_changed_samples = 0; + slot->ds_equal_samples = 0; + } +out: + spin_unlock(&o2hb_live_lock); + + o2hb_run_event_list(&event); + + if (node) + o2nm_node_put(node); + return changed; +} + +/* This could be faster if we just implmented a find_last_bit, but I + * don't think the circumstances warrant it. */ +static int o2hb_highest_node(unsigned long *nodes, + int numbits) +{ + int highest, node; + + highest = numbits; + node = -1; + while ((node = find_next_bit(nodes, numbits, node + 1)) != -1) { + if (node >= numbits) + break; + + highest = node; + } + + return highest; +} + +static int o2hb_do_disk_heartbeat(struct o2hb_region *reg) +{ + int i, ret, highest_node; + int membership_change = 0, own_slot_ok = 0; + unsigned long configured_nodes[BITS_TO_LONGS(O2NM_MAX_NODES)]; + unsigned long live_node_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)]; + struct o2hb_bio_wait_ctxt write_wc; + + ret = o2nm_configured_node_map(configured_nodes, + sizeof(configured_nodes)); + if (ret) { + mlog_errno(ret); + goto bail; + } + + /* + * If a node is not configured but is in the livemap, we still need + * to read the slot so as to be able to remove it from the livemap. + */ + o2hb_fill_node_map(live_node_bitmap, sizeof(live_node_bitmap)); + i = -1; + while ((i = find_next_bit(live_node_bitmap, + O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES) { + set_bit(i, configured_nodes); + } + + highest_node = o2hb_highest_node(configured_nodes, O2NM_MAX_NODES); + if (highest_node >= O2NM_MAX_NODES) { + mlog(ML_NOTICE, "o2hb: No configured nodes found!\n"); + ret = -EINVAL; + goto bail; + } + + /* No sense in reading the slots of nodes that don't exist + * yet. Of course, if the node definitions have holes in them + * then we're reading an empty slot anyway... Consider this + * best-effort. */ + ret = o2hb_read_slots(reg, highest_node + 1); + if (ret < 0) { + mlog_errno(ret); + goto bail; + } + + /* With an up to date view of the slots, we can check that no + * other node has been improperly configured to heartbeat in + * our slot. */ + own_slot_ok = o2hb_check_own_slot(reg); + + /* fill in the proper info for our next heartbeat */ + o2hb_prepare_block(reg, reg->hr_generation); + + ret = o2hb_issue_node_write(reg, &write_wc); + if (ret < 0) { + mlog_errno(ret); + goto bail; + } + + i = -1; + while((i = find_next_bit(configured_nodes, + O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES) { + membership_change |= o2hb_check_slot(reg, ®->hr_slots[i]); + } + + /* + * We have to be sure we've advertised ourselves on disk + * before we can go to steady state. This ensures that + * people we find in our steady state have seen us. + */ + o2hb_wait_on_io(reg, &write_wc); + if (write_wc.wc_error) { + /* Do not re-arm the write timeout on I/O error - we + * can't be sure that the new block ever made it to + * disk */ + mlog(ML_ERROR, "Write error %d on device \"%s\"\n", + write_wc.wc_error, reg->hr_dev_name); + ret = write_wc.wc_error; + goto bail; + } + + /* Skip disarming the timeout if own slot has stale/bad data */ + if (own_slot_ok) { + o2hb_set_quorum_device(reg); + o2hb_arm_write_timeout(reg); + } + +bail: + /* let the person who launched us know when things are steady */ + if (atomic_read(®->hr_steady_iterations) != 0) { + if (!ret && own_slot_ok && !membership_change) { + if (atomic_dec_and_test(®->hr_steady_iterations)) + wake_up(&o2hb_steady_queue); + } + } + + if (atomic_read(®->hr_steady_iterations) != 0) { + if (atomic_dec_and_test(®->hr_unsteady_iterations)) { + printk(KERN_NOTICE "o2hb: Unable to stabilize " + "heartbeart on region %s (%s)\n", + config_item_name(®->hr_item), + reg->hr_dev_name); + atomic_set(®->hr_steady_iterations, 0); + reg->hr_aborted_start = 1; + wake_up(&o2hb_steady_queue); + ret = -EIO; + } + } + + return ret; +} + +/* Subtract b from a, storing the result in a. a *must* have a larger + * value than b. */ +static void o2hb_tv_subtract(struct timeval *a, + struct timeval *b) +{ + /* just return 0 when a is after b */ + if (a->tv_sec < b->tv_sec || + (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec)) { + a->tv_sec = 0; + a->tv_usec = 0; + return; + } + + a->tv_sec -= b->tv_sec; + a->tv_usec -= b->tv_usec; + while ( a->tv_usec < 0 ) { + a->tv_sec--; + a->tv_usec += 1000000; + } +} + +static unsigned int o2hb_elapsed_msecs(struct timeval *start, + struct timeval *end) +{ + struct timeval res = *end; + + o2hb_tv_subtract(&res, start); + + return res.tv_sec * 1000 + res.tv_usec / 1000; +} + +/* + * we ride the region ref that the region dir holds. before the region + * dir is removed and drops it ref it will wait to tear down this + * thread. + */ +static int o2hb_thread(void *data) +{ + int i, ret; + struct o2hb_region *reg = data; + struct o2hb_bio_wait_ctxt write_wc; + struct timeval before_hb, after_hb; + unsigned int elapsed_msec; + + mlog(ML_HEARTBEAT|ML_KTHREAD, "hb thread running\n"); + + set_user_nice(current, -20); + + /* Pin node */ + o2nm_depend_this_node(); + + while (!kthread_should_stop() && + !reg->hr_unclean_stop && !reg->hr_aborted_start) { + /* We track the time spent inside + * o2hb_do_disk_heartbeat so that we avoid more than + * hr_timeout_ms between disk writes. On busy systems + * this should result in a heartbeat which is less + * likely to time itself out. */ + do_gettimeofday(&before_hb); + + ret = o2hb_do_disk_heartbeat(reg); + + do_gettimeofday(&after_hb); + elapsed_msec = o2hb_elapsed_msecs(&before_hb, &after_hb); + + mlog(ML_HEARTBEAT, + "start = %lu.%lu, end = %lu.%lu, msec = %u\n", + before_hb.tv_sec, (unsigned long) before_hb.tv_usec, + after_hb.tv_sec, (unsigned long) after_hb.tv_usec, + elapsed_msec); + + if (!kthread_should_stop() && + elapsed_msec < reg->hr_timeout_ms) { + /* the kthread api has blocked signals for us so no + * need to record the return value. */ + msleep_interruptible(reg->hr_timeout_ms - elapsed_msec); + } + } + + o2hb_disarm_write_timeout(reg); + + /* unclean stop is only used in very bad situation */ + for(i = 0; !reg->hr_unclean_stop && i < reg->hr_blocks; i++) + o2hb_shutdown_slot(®->hr_slots[i]); + + /* Explicit down notification - avoid forcing the other nodes + * to timeout on this region when we could just as easily + * write a clear generation - thus indicating to them that + * this node has left this region. + */ + if (!reg->hr_unclean_stop && !reg->hr_aborted_start) { + o2hb_prepare_block(reg, 0); + ret = o2hb_issue_node_write(reg, &write_wc); + if (ret == 0) + o2hb_wait_on_io(reg, &write_wc); + else + mlog_errno(ret); + } + + /* Unpin node */ + o2nm_undepend_this_node(); + + mlog(ML_HEARTBEAT|ML_KTHREAD, "o2hb thread exiting\n"); + + return 0; +} + +#ifdef CONFIG_DEBUG_FS +static int o2hb_debug_open(struct inode *inode, struct file *file) +{ + struct o2hb_debug_buf *db = inode->i_private; + struct o2hb_region *reg; + unsigned long map[BITS_TO_LONGS(O2NM_MAX_NODES)]; + unsigned long lts; + char *buf = NULL; + int i = -1; + int out = 0; + + /* max_nodes should be the largest bitmap we pass here */ + BUG_ON(sizeof(map) < db->db_size); + + buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!buf) + goto bail; + + switch (db->db_type) { + case O2HB_DB_TYPE_LIVENODES: + case O2HB_DB_TYPE_LIVEREGIONS: + case O2HB_DB_TYPE_QUORUMREGIONS: + case O2HB_DB_TYPE_FAILEDREGIONS: + spin_lock(&o2hb_live_lock); + memcpy(map, db->db_data, db->db_size); + spin_unlock(&o2hb_live_lock); + break; + + case O2HB_DB_TYPE_REGION_LIVENODES: + spin_lock(&o2hb_live_lock); + reg = (struct o2hb_region *)db->db_data; + memcpy(map, reg->hr_live_node_bitmap, db->db_size); + spin_unlock(&o2hb_live_lock); + break; + + case O2HB_DB_TYPE_REGION_NUMBER: + reg = (struct o2hb_region *)db->db_data; + out += snprintf(buf + out, PAGE_SIZE - out, "%d\n", + reg->hr_region_num); + goto done; + + case O2HB_DB_TYPE_REGION_ELAPSED_TIME: + reg = (struct o2hb_region *)db->db_data; + lts = reg->hr_last_timeout_start; + /* If 0, it has never been set before */ + if (lts) + lts = jiffies_to_msecs(jiffies - lts); + out += snprintf(buf + out, PAGE_SIZE - out, "%lu\n", lts); + goto done; + + case O2HB_DB_TYPE_REGION_PINNED: + reg = (struct o2hb_region *)db->db_data; + out += snprintf(buf + out, PAGE_SIZE - out, "%u\n", + !!reg->hr_item_pinned); + goto done; + + default: + goto done; + } + + while ((i = find_next_bit(map, db->db_len, i + 1)) < db->db_len) + out += snprintf(buf + out, PAGE_SIZE - out, "%d ", i); + out += snprintf(buf + out, PAGE_SIZE - out, "\n"); + +done: + i_size_write(inode, out); + + file->private_data = buf; + + return 0; +bail: + return -ENOMEM; +} + +static int o2hb_debug_release(struct inode *inode, struct file *file) +{ + kfree(file->private_data); + return 0; +} + +static ssize_t o2hb_debug_read(struct file *file, char __user *buf, + size_t nbytes, loff_t *ppos) +{ + return simple_read_from_buffer(buf, nbytes, ppos, file->private_data, + i_size_read(file->f_mapping->host)); +} +#else +static int o2hb_debug_open(struct inode *inode, struct file *file) +{ + return 0; +} +static int o2hb_debug_release(struct inode *inode, struct file *file) +{ + return 0; +} +static ssize_t o2hb_debug_read(struct file *file, char __user *buf, + size_t nbytes, loff_t *ppos) +{ + return 0; +} +#endif /* CONFIG_DEBUG_FS */ + +static const struct file_operations o2hb_debug_fops = { + .open = o2hb_debug_open, + .release = o2hb_debug_release, + .read = o2hb_debug_read, + .llseek = generic_file_llseek, +}; + +void o2hb_exit(void) +{ + kfree(o2hb_db_livenodes); + kfree(o2hb_db_liveregions); + kfree(o2hb_db_quorumregions); + kfree(o2hb_db_failedregions); + debugfs_remove(o2hb_debug_failedregions); + debugfs_remove(o2hb_debug_quorumregions); + debugfs_remove(o2hb_debug_liveregions); + debugfs_remove(o2hb_debug_livenodes); + debugfs_remove(o2hb_debug_dir); +} + +static struct dentry *o2hb_debug_create(const char *name, struct dentry *dir, + struct o2hb_debug_buf **db, int db_len, + int type, int size, int len, void *data) +{ + *db = kmalloc(db_len, GFP_KERNEL); + if (!*db) + return NULL; + + (*db)->db_type = type; + (*db)->db_size = size; + (*db)->db_len = len; + (*db)->db_data = data; + + return debugfs_create_file(name, S_IFREG|S_IRUSR, dir, *db, + &o2hb_debug_fops); +} + +static int o2hb_debug_init(void) +{ + int ret = -ENOMEM; + + o2hb_debug_dir = debugfs_create_dir(O2HB_DEBUG_DIR, NULL); + if (!o2hb_debug_dir) { + mlog_errno(ret); + goto bail; + } + + o2hb_debug_livenodes = o2hb_debug_create(O2HB_DEBUG_LIVENODES, + o2hb_debug_dir, + &o2hb_db_livenodes, + sizeof(*o2hb_db_livenodes), + O2HB_DB_TYPE_LIVENODES, + sizeof(o2hb_live_node_bitmap), + O2NM_MAX_NODES, + o2hb_live_node_bitmap); + if (!o2hb_debug_livenodes) { + mlog_errno(ret); + goto bail; + } + + o2hb_debug_liveregions = o2hb_debug_create(O2HB_DEBUG_LIVEREGIONS, + o2hb_debug_dir, + &o2hb_db_liveregions, + sizeof(*o2hb_db_liveregions), + O2HB_DB_TYPE_LIVEREGIONS, + sizeof(o2hb_live_region_bitmap), + O2NM_MAX_REGIONS, + o2hb_live_region_bitmap); + if (!o2hb_debug_liveregions) { + mlog_errno(ret); + goto bail; + } + + o2hb_debug_quorumregions = + o2hb_debug_create(O2HB_DEBUG_QUORUMREGIONS, + o2hb_debug_dir, + &o2hb_db_quorumregions, + sizeof(*o2hb_db_quorumregions), + O2HB_DB_TYPE_QUORUMREGIONS, + sizeof(o2hb_quorum_region_bitmap), + O2NM_MAX_REGIONS, + o2hb_quorum_region_bitmap); + if (!o2hb_debug_quorumregions) { + mlog_errno(ret); + goto bail; + } + + o2hb_debug_failedregions = + o2hb_debug_create(O2HB_DEBUG_FAILEDREGIONS, + o2hb_debug_dir, + &o2hb_db_failedregions, + sizeof(*o2hb_db_failedregions), + O2HB_DB_TYPE_FAILEDREGIONS, + sizeof(o2hb_failed_region_bitmap), + O2NM_MAX_REGIONS, + o2hb_failed_region_bitmap); + if (!o2hb_debug_failedregions) { + mlog_errno(ret); + goto bail; + } + + ret = 0; +bail: + if (ret) + o2hb_exit(); + + return ret; +} + +int o2hb_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(o2hb_callbacks); i++) + INIT_LIST_HEAD(&o2hb_callbacks[i].list); + + for (i = 0; i < ARRAY_SIZE(o2hb_live_slots); i++) + INIT_LIST_HEAD(&o2hb_live_slots[i]); + + INIT_LIST_HEAD(&o2hb_node_events); + + memset(o2hb_live_node_bitmap, 0, sizeof(o2hb_live_node_bitmap)); + memset(o2hb_region_bitmap, 0, sizeof(o2hb_region_bitmap)); + memset(o2hb_live_region_bitmap, 0, sizeof(o2hb_live_region_bitmap)); + memset(o2hb_quorum_region_bitmap, 0, sizeof(o2hb_quorum_region_bitmap)); + memset(o2hb_failed_region_bitmap, 0, sizeof(o2hb_failed_region_bitmap)); + + o2hb_dependent_users = 0; + + return o2hb_debug_init(); +} + +/* if we're already in a callback then we're already serialized by the sem */ +static void o2hb_fill_node_map_from_callback(unsigned long *map, + unsigned bytes) +{ + BUG_ON(bytes < (BITS_TO_LONGS(O2NM_MAX_NODES) * sizeof(unsigned long))); + + memcpy(map, &o2hb_live_node_bitmap, bytes); +} + +/* + * get a map of all nodes that are heartbeating in any regions + */ +void o2hb_fill_node_map(unsigned long *map, unsigned bytes) +{ + /* callers want to serialize this map and callbacks so that they + * can trust that they don't miss nodes coming to the party */ + down_read(&o2hb_callback_sem); + spin_lock(&o2hb_live_lock); + o2hb_fill_node_map_from_callback(map, bytes); + spin_unlock(&o2hb_live_lock); + up_read(&o2hb_callback_sem); +} +EXPORT_SYMBOL_GPL(o2hb_fill_node_map); + +/* + * heartbeat configfs bits. The heartbeat set is a default set under + * the cluster set in nodemanager.c. + */ + +static struct o2hb_region *to_o2hb_region(struct config_item *item) +{ + return item ? container_of(item, struct o2hb_region, hr_item) : NULL; +} + +/* drop_item only drops its ref after killing the thread, nothing should + * be using the region anymore. this has to clean up any state that + * attributes might have built up. */ +static void o2hb_region_release(struct config_item *item) +{ + int i; + struct page *page; + struct o2hb_region *reg = to_o2hb_region(item); + + mlog(ML_HEARTBEAT, "hb region release (%s)\n", reg->hr_dev_name); + + if (reg->hr_tmp_block) + kfree(reg->hr_tmp_block); + + if (reg->hr_slot_data) { + for (i = 0; i < reg->hr_num_pages; i++) { + page = reg->hr_slot_data[i]; + if (page) + __free_page(page); + } + kfree(reg->hr_slot_data); + } + + if (reg->hr_bdev) + blkdev_put(reg->hr_bdev, FMODE_READ|FMODE_WRITE); + + if (reg->hr_slots) + kfree(reg->hr_slots); + + kfree(reg->hr_db_regnum); + kfree(reg->hr_db_livenodes); + debugfs_remove(reg->hr_debug_livenodes); + debugfs_remove(reg->hr_debug_regnum); + debugfs_remove(reg->hr_debug_elapsed_time); + debugfs_remove(reg->hr_debug_pinned); + debugfs_remove(reg->hr_debug_dir); + + spin_lock(&o2hb_live_lock); + list_del(®->hr_all_item); + spin_unlock(&o2hb_live_lock); + + kfree(reg); +} + +static int o2hb_read_block_input(struct o2hb_region *reg, + const char *page, + size_t count, + unsigned long *ret_bytes, + unsigned int *ret_bits) +{ + unsigned long bytes; + char *p = (char *)page; + + bytes = simple_strtoul(p, &p, 0); + if (!p || (*p && (*p != '\n'))) + return -EINVAL; + + /* Heartbeat and fs min / max block sizes are the same. */ + if (bytes > 4096 || bytes < 512) + return -ERANGE; + if (hweight16(bytes) != 1) + return -EINVAL; + + if (ret_bytes) + *ret_bytes = bytes; + if (ret_bits) + *ret_bits = ffs(bytes) - 1; + + return 0; +} + +static ssize_t o2hb_region_block_bytes_read(struct o2hb_region *reg, + char *page) +{ + return sprintf(page, "%u\n", reg->hr_block_bytes); +} + +static ssize_t o2hb_region_block_bytes_write(struct o2hb_region *reg, + const char *page, + size_t count) +{ + int status; + unsigned long block_bytes; + unsigned int block_bits; + + if (reg->hr_bdev) + return -EINVAL; + + status = o2hb_read_block_input(reg, page, count, + &block_bytes, &block_bits); + if (status) + return status; + + reg->hr_block_bytes = (unsigned int)block_bytes; + reg->hr_block_bits = block_bits; + + return count; +} + +static ssize_t o2hb_region_start_block_read(struct o2hb_region *reg, + char *page) +{ + return sprintf(page, "%llu\n", reg->hr_start_block); +} + +static ssize_t o2hb_region_start_block_write(struct o2hb_region *reg, + const char *page, + size_t count) +{ + unsigned long long tmp; + char *p = (char *)page; + + if (reg->hr_bdev) + return -EINVAL; + + tmp = simple_strtoull(p, &p, 0); + if (!p || (*p && (*p != '\n'))) + return -EINVAL; + + reg->hr_start_block = tmp; + + return count; +} + +static ssize_t o2hb_region_blocks_read(struct o2hb_region *reg, + char *page) +{ + return sprintf(page, "%d\n", reg->hr_blocks); +} + +static ssize_t o2hb_region_blocks_write(struct o2hb_region *reg, + const char *page, + size_t count) +{ + unsigned long tmp; + char *p = (char *)page; + + if (reg->hr_bdev) + return -EINVAL; + + tmp = simple_strtoul(p, &p, 0); + if (!p || (*p && (*p != '\n'))) + return -EINVAL; + + if (tmp > O2NM_MAX_NODES || tmp == 0) + return -ERANGE; + + reg->hr_blocks = (unsigned int)tmp; + + return count; +} + +static ssize_t o2hb_region_dev_read(struct o2hb_region *reg, + char *page) +{ + unsigned int ret = 0; + + if (reg->hr_bdev) + ret = sprintf(page, "%s\n", reg->hr_dev_name); + + return ret; +} + +static void o2hb_init_region_params(struct o2hb_region *reg) +{ + reg->hr_slots_per_page = PAGE_CACHE_SIZE >> reg->hr_block_bits; + reg->hr_timeout_ms = O2HB_REGION_TIMEOUT_MS; + + mlog(ML_HEARTBEAT, "hr_start_block = %llu, hr_blocks = %u\n", + reg->hr_start_block, reg->hr_blocks); + mlog(ML_HEARTBEAT, "hr_block_bytes = %u, hr_block_bits = %u\n", + reg->hr_block_bytes, reg->hr_block_bits); + mlog(ML_HEARTBEAT, "hr_timeout_ms = %u\n", reg->hr_timeout_ms); + mlog(ML_HEARTBEAT, "dead threshold = %u\n", o2hb_dead_threshold); +} + +static int o2hb_map_slot_data(struct o2hb_region *reg) +{ + int i, j; + unsigned int last_slot; + unsigned int spp = reg->hr_slots_per_page; + struct page *page; + char *raw; + struct o2hb_disk_slot *slot; + + reg->hr_tmp_block = kmalloc(reg->hr_block_bytes, GFP_KERNEL); + if (reg->hr_tmp_block == NULL) { + mlog_errno(-ENOMEM); + return -ENOMEM; + } + + reg->hr_slots = kcalloc(reg->hr_blocks, + sizeof(struct o2hb_disk_slot), GFP_KERNEL); + if (reg->hr_slots == NULL) { + mlog_errno(-ENOMEM); + return -ENOMEM; + } + + for(i = 0; i < reg->hr_blocks; i++) { + slot = ®->hr_slots[i]; + slot->ds_node_num = i; + INIT_LIST_HEAD(&slot->ds_live_item); + slot->ds_raw_block = NULL; + } + + reg->hr_num_pages = (reg->hr_blocks + spp - 1) / spp; + mlog(ML_HEARTBEAT, "Going to require %u pages to cover %u blocks " + "at %u blocks per page\n", + reg->hr_num_pages, reg->hr_blocks, spp); + + reg->hr_slot_data = kcalloc(reg->hr_num_pages, sizeof(struct page *), + GFP_KERNEL); + if (!reg->hr_slot_data) { + mlog_errno(-ENOMEM); + return -ENOMEM; + } + + for(i = 0; i < reg->hr_num_pages; i++) { + page = alloc_page(GFP_KERNEL); + if (!page) { + mlog_errno(-ENOMEM); + return -ENOMEM; + } + + reg->hr_slot_data[i] = page; + + last_slot = i * spp; + raw = page_address(page); + for (j = 0; + (j < spp) && ((j + last_slot) < reg->hr_blocks); + j++) { + BUG_ON((j + last_slot) >= reg->hr_blocks); + + slot = ®->hr_slots[j + last_slot]; + slot->ds_raw_block = + (struct o2hb_disk_heartbeat_block *) raw; + + raw += reg->hr_block_bytes; + } + } + + return 0; +} + +/* Read in all the slots available and populate the tracking + * structures so that we can start with a baseline idea of what's + * there. */ +static int o2hb_populate_slot_data(struct o2hb_region *reg) +{ + int ret, i; + struct o2hb_disk_slot *slot; + struct o2hb_disk_heartbeat_block *hb_block; + + ret = o2hb_read_slots(reg, reg->hr_blocks); + if (ret) { + mlog_errno(ret); + goto out; + } + + /* We only want to get an idea of the values initially in each + * slot, so we do no verification - o2hb_check_slot will + * actually determine if each configured slot is valid and + * whether any values have changed. */ + for(i = 0; i < reg->hr_blocks; i++) { + slot = ®->hr_slots[i]; + hb_block = (struct o2hb_disk_heartbeat_block *) slot->ds_raw_block; + + /* Only fill the values that o2hb_check_slot uses to + * determine changing slots */ + slot->ds_last_time = le64_to_cpu(hb_block->hb_seq); + slot->ds_last_generation = le64_to_cpu(hb_block->hb_generation); + } + +out: + return ret; +} + +/* this is acting as commit; we set up all of hr_bdev and hr_task or nothing */ +static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, + const char *page, + size_t count) +{ + struct task_struct *hb_task; + long fd; + int sectsize; + char *p = (char *)page; + struct file *filp = NULL; + struct inode *inode = NULL; + ssize_t ret = -EINVAL; + int live_threshold; + + if (reg->hr_bdev) + goto out; + + /* We can't heartbeat without having had our node number + * configured yet. */ + if (o2nm_this_node() == O2NM_MAX_NODES) + goto out; + + fd = simple_strtol(p, &p, 0); + if (!p || (*p && (*p != '\n'))) + goto out; + + if (fd < 0 || fd >= INT_MAX) + goto out; + + filp = fget(fd); + if (filp == NULL) + goto out; + + if (reg->hr_blocks == 0 || reg->hr_start_block == 0 || + reg->hr_block_bytes == 0) + goto out; + + inode = igrab(filp->f_mapping->host); + if (inode == NULL) + goto out; + + if (!S_ISBLK(inode->i_mode)) + goto out; + + reg->hr_bdev = I_BDEV(filp->f_mapping->host); + ret = blkdev_get(reg->hr_bdev, FMODE_WRITE | FMODE_READ, NULL); + if (ret) { + reg->hr_bdev = NULL; + goto out; + } + inode = NULL; + + bdevname(reg->hr_bdev, reg->hr_dev_name); + + sectsize = bdev_logical_block_size(reg->hr_bdev); + if (sectsize != reg->hr_block_bytes) { + mlog(ML_ERROR, + "blocksize %u incorrect for device, expected %d", + reg->hr_block_bytes, sectsize); + ret = -EINVAL; + goto out; + } + + o2hb_init_region_params(reg); + + /* Generation of zero is invalid */ + do { + get_random_bytes(®->hr_generation, + sizeof(reg->hr_generation)); + } while (reg->hr_generation == 0); + + ret = o2hb_map_slot_data(reg); + if (ret) { + mlog_errno(ret); + goto out; + } + + ret = o2hb_populate_slot_data(reg); + if (ret) { + mlog_errno(ret); + goto out; + } + + INIT_DELAYED_WORK(®->hr_write_timeout_work, o2hb_write_timeout); + + /* + * A node is considered live after it has beat LIVE_THRESHOLD + * times. We're not steady until we've given them a chance + * _after_ our first read. + * The default threshold is bare minimum so as to limit the delay + * during mounts. For global heartbeat, the threshold doubled for the + * first region. + */ + live_threshold = O2HB_LIVE_THRESHOLD; + if (o2hb_global_heartbeat_active()) { + spin_lock(&o2hb_live_lock); + if (o2hb_pop_count(&o2hb_region_bitmap, O2NM_MAX_REGIONS) == 1) + live_threshold <<= 1; + spin_unlock(&o2hb_live_lock); + } + ++live_threshold; + atomic_set(®->hr_steady_iterations, live_threshold); + /* unsteady_iterations is double the steady_iterations */ + atomic_set(®->hr_unsteady_iterations, (live_threshold << 1)); + + hb_task = kthread_run(o2hb_thread, reg, "o2hb-%s", + reg->hr_item.ci_name); + if (IS_ERR(hb_task)) { + ret = PTR_ERR(hb_task); + mlog_errno(ret); + goto out; + } + + spin_lock(&o2hb_live_lock); + reg->hr_task = hb_task; + spin_unlock(&o2hb_live_lock); + + ret = wait_event_interruptible(o2hb_steady_queue, + atomic_read(®->hr_steady_iterations) == 0); + if (ret) { + atomic_set(®->hr_steady_iterations, 0); + reg->hr_aborted_start = 1; + } + + if (reg->hr_aborted_start) { + ret = -EIO; + goto out; + } + + /* Ok, we were woken. Make sure it wasn't by drop_item() */ + spin_lock(&o2hb_live_lock); + hb_task = reg->hr_task; + if (o2hb_global_heartbeat_active()) + set_bit(reg->hr_region_num, o2hb_live_region_bitmap); + spin_unlock(&o2hb_live_lock); + + if (hb_task) + ret = count; + else + ret = -EIO; + + if (hb_task && o2hb_global_heartbeat_active()) + printk(KERN_NOTICE "o2hb: Heartbeat started on region %s (%s)\n", + config_item_name(®->hr_item), reg->hr_dev_name); + +out: + if (filp) + fput(filp); + if (inode) + iput(inode); + if (ret < 0) { + if (reg->hr_bdev) { + blkdev_put(reg->hr_bdev, FMODE_READ|FMODE_WRITE); + reg->hr_bdev = NULL; + } + } + return ret; +} + +static ssize_t o2hb_region_pid_read(struct o2hb_region *reg, + char *page) +{ + pid_t pid = 0; + + spin_lock(&o2hb_live_lock); + if (reg->hr_task) + pid = task_pid_nr(reg->hr_task); + spin_unlock(&o2hb_live_lock); + + if (!pid) + return 0; + + return sprintf(page, "%u\n", pid); +} + +struct o2hb_region_attribute { + struct configfs_attribute attr; + ssize_t (*show)(struct o2hb_region *, char *); + ssize_t (*store)(struct o2hb_region *, const char *, size_t); +}; + +static struct o2hb_region_attribute o2hb_region_attr_block_bytes = { + .attr = { .ca_owner = THIS_MODULE, + .ca_name = "block_bytes", + .ca_mode = S_IRUGO | S_IWUSR }, + .show = o2hb_region_block_bytes_read, + .store = o2hb_region_block_bytes_write, +}; + +static struct o2hb_region_attribute o2hb_region_attr_start_block = { + .attr = { .ca_owner = THIS_MODULE, + .ca_name = "start_block", + .ca_mode = S_IRUGO | S_IWUSR }, + .show = o2hb_region_start_block_read, + .store = o2hb_region_start_block_write, +}; + +static struct o2hb_region_attribute o2hb_region_attr_blocks = { + .attr = { .ca_owner = THIS_MODULE, + .ca_name = "blocks", + .ca_mode = S_IRUGO | S_IWUSR }, + .show = o2hb_region_blocks_read, + .store = o2hb_region_blocks_write, +}; + +static struct o2hb_region_attribute o2hb_region_attr_dev = { + .attr = { .ca_owner = THIS_MODULE, + .ca_name = "dev", + .ca_mode = S_IRUGO | S_IWUSR }, + .show = o2hb_region_dev_read, + .store = o2hb_region_dev_write, +}; + +static struct o2hb_region_attribute o2hb_region_attr_pid = { + .attr = { .ca_owner = THIS_MODULE, + .ca_name = "pid", + .ca_mode = S_IRUGO | S_IRUSR }, + .show = o2hb_region_pid_read, +}; + +static struct configfs_attribute *o2hb_region_attrs[] = { + &o2hb_region_attr_block_bytes.attr, + &o2hb_region_attr_start_block.attr, + &o2hb_region_attr_blocks.attr, + &o2hb_region_attr_dev.attr, + &o2hb_region_attr_pid.attr, + NULL, +}; + +static ssize_t o2hb_region_show(struct config_item *item, + struct configfs_attribute *attr, + char *page) +{ + struct o2hb_region *reg = to_o2hb_region(item); + struct o2hb_region_attribute *o2hb_region_attr = + container_of(attr, struct o2hb_region_attribute, attr); + ssize_t ret = 0; + + if (o2hb_region_attr->show) + ret = o2hb_region_attr->show(reg, page); + return ret; +} + +static ssize_t o2hb_region_store(struct config_item *item, + struct configfs_attribute *attr, + const char *page, size_t count) +{ + struct o2hb_region *reg = to_o2hb_region(item); + struct o2hb_region_attribute *o2hb_region_attr = + container_of(attr, struct o2hb_region_attribute, attr); + ssize_t ret = -EINVAL; + + if (o2hb_region_attr->store) + ret = o2hb_region_attr->store(reg, page, count); + return ret; +} + +static struct configfs_item_operations o2hb_region_item_ops = { + .release = o2hb_region_release, + .show_attribute = o2hb_region_show, + .store_attribute = o2hb_region_store, +}; + +static struct config_item_type o2hb_region_type = { + .ct_item_ops = &o2hb_region_item_ops, + .ct_attrs = o2hb_region_attrs, + .ct_owner = THIS_MODULE, +}; + +/* heartbeat set */ + +struct o2hb_heartbeat_group { + struct config_group hs_group; + /* some stuff? */ +}; + +static struct o2hb_heartbeat_group *to_o2hb_heartbeat_group(struct config_group *group) +{ + return group ? + container_of(group, struct o2hb_heartbeat_group, hs_group) + : NULL; +} + +static int o2hb_debug_region_init(struct o2hb_region *reg, struct dentry *dir) +{ + int ret = -ENOMEM; + + reg->hr_debug_dir = + debugfs_create_dir(config_item_name(®->hr_item), dir); + if (!reg->hr_debug_dir) { + mlog_errno(ret); + goto bail; + } + + reg->hr_debug_livenodes = + o2hb_debug_create(O2HB_DEBUG_LIVENODES, + reg->hr_debug_dir, + &(reg->hr_db_livenodes), + sizeof(*(reg->hr_db_livenodes)), + O2HB_DB_TYPE_REGION_LIVENODES, + sizeof(reg->hr_live_node_bitmap), + O2NM_MAX_NODES, reg); + if (!reg->hr_debug_livenodes) { + mlog_errno(ret); + goto bail; + } + + reg->hr_debug_regnum = + o2hb_debug_create(O2HB_DEBUG_REGION_NUMBER, + reg->hr_debug_dir, + &(reg->hr_db_regnum), + sizeof(*(reg->hr_db_regnum)), + O2HB_DB_TYPE_REGION_NUMBER, + 0, O2NM_MAX_NODES, reg); + if (!reg->hr_debug_regnum) { + mlog_errno(ret); + goto bail; + } + + reg->hr_debug_elapsed_time = + o2hb_debug_create(O2HB_DEBUG_REGION_ELAPSED_TIME, + reg->hr_debug_dir, + &(reg->hr_db_elapsed_time), + sizeof(*(reg->hr_db_elapsed_time)), + O2HB_DB_TYPE_REGION_ELAPSED_TIME, + 0, 0, reg); + if (!reg->hr_debug_elapsed_time) { + mlog_errno(ret); + goto bail; + } + + reg->hr_debug_pinned = + o2hb_debug_create(O2HB_DEBUG_REGION_PINNED, + reg->hr_debug_dir, + &(reg->hr_db_pinned), + sizeof(*(reg->hr_db_pinned)), + O2HB_DB_TYPE_REGION_PINNED, + 0, 0, reg); + if (!reg->hr_debug_pinned) { + mlog_errno(ret); + goto bail; + } + + ret = 0; +bail: + return ret; +} + +static struct config_item *o2hb_heartbeat_group_make_item(struct config_group *group, + const char *name) +{ + struct o2hb_region *reg = NULL; + int ret; + + reg = kzalloc(sizeof(struct o2hb_region), GFP_KERNEL); + if (reg == NULL) + return ERR_PTR(-ENOMEM); + + if (strlen(name) > O2HB_MAX_REGION_NAME_LEN) { + ret = -ENAMETOOLONG; + goto free; + } + + spin_lock(&o2hb_live_lock); + reg->hr_region_num = 0; + if (o2hb_global_heartbeat_active()) { + reg->hr_region_num = find_first_zero_bit(o2hb_region_bitmap, + O2NM_MAX_REGIONS); + if (reg->hr_region_num >= O2NM_MAX_REGIONS) { + spin_unlock(&o2hb_live_lock); + ret = -EFBIG; + goto free; + } + set_bit(reg->hr_region_num, o2hb_region_bitmap); + } + list_add_tail(®->hr_all_item, &o2hb_all_regions); + spin_unlock(&o2hb_live_lock); + + config_item_init_type_name(®->hr_item, name, &o2hb_region_type); + + ret = o2hb_debug_region_init(reg, o2hb_debug_dir); + if (ret) { + config_item_put(®->hr_item); + goto free; + } + + return ®->hr_item; +free: + kfree(reg); + return ERR_PTR(ret); +} + +static void o2hb_heartbeat_group_drop_item(struct config_group *group, + struct config_item *item) +{ + struct task_struct *hb_task; + struct o2hb_region *reg = to_o2hb_region(item); + int quorum_region = 0; + + /* stop the thread when the user removes the region dir */ + spin_lock(&o2hb_live_lock); + hb_task = reg->hr_task; + reg->hr_task = NULL; + reg->hr_item_dropped = 1; + spin_unlock(&o2hb_live_lock); + + if (hb_task) + kthread_stop(hb_task); + + if (o2hb_global_heartbeat_active()) { + spin_lock(&o2hb_live_lock); + clear_bit(reg->hr_region_num, o2hb_region_bitmap); + clear_bit(reg->hr_region_num, o2hb_live_region_bitmap); + if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap)) + quorum_region = 1; + clear_bit(reg->hr_region_num, o2hb_quorum_region_bitmap); + spin_unlock(&o2hb_live_lock); + printk(KERN_NOTICE "o2hb: Heartbeat %s on region %s (%s)\n", + ((atomic_read(®->hr_steady_iterations) == 0) ? + "stopped" : "start aborted"), config_item_name(item), + reg->hr_dev_name); + } + + /* + * If we're racing a dev_write(), we need to wake them. They will + * check reg->hr_task + */ + if (atomic_read(®->hr_steady_iterations) != 0) { + reg->hr_aborted_start = 1; + atomic_set(®->hr_steady_iterations, 0); + wake_up(&o2hb_steady_queue); + } + + config_item_put(item); + + if (!o2hb_global_heartbeat_active() || !quorum_region) + return; + + /* + * If global heartbeat active and there are dependent users, + * pin all regions if quorum region count <= CUT_OFF + */ + spin_lock(&o2hb_live_lock); + + if (!o2hb_dependent_users) + goto unlock; + + if (o2hb_pop_count(&o2hb_quorum_region_bitmap, + O2NM_MAX_REGIONS) <= O2HB_PIN_CUT_OFF) + o2hb_region_pin(NULL); + +unlock: + spin_unlock(&o2hb_live_lock); +} + +struct o2hb_heartbeat_group_attribute { + struct configfs_attribute attr; + ssize_t (*show)(struct o2hb_heartbeat_group *, char *); + ssize_t (*store)(struct o2hb_heartbeat_group *, const char *, size_t); +}; + +static ssize_t o2hb_heartbeat_group_show(struct config_item *item, + struct configfs_attribute *attr, + char *page) +{ + struct o2hb_heartbeat_group *reg = to_o2hb_heartbeat_group(to_config_group(item)); + struct o2hb_heartbeat_group_attribute *o2hb_heartbeat_group_attr = + container_of(attr, struct o2hb_heartbeat_group_attribute, attr); + ssize_t ret = 0; + + if (o2hb_heartbeat_group_attr->show) + ret = o2hb_heartbeat_group_attr->show(reg, page); + return ret; +} + +static ssize_t o2hb_heartbeat_group_store(struct config_item *item, + struct configfs_attribute *attr, + const char *page, size_t count) +{ + struct o2hb_heartbeat_group *reg = to_o2hb_heartbeat_group(to_config_group(item)); + struct o2hb_heartbeat_group_attribute *o2hb_heartbeat_group_attr = + container_of(attr, struct o2hb_heartbeat_group_attribute, attr); + ssize_t ret = -EINVAL; + + if (o2hb_heartbeat_group_attr->store) + ret = o2hb_heartbeat_group_attr->store(reg, page, count); + return ret; +} + +static ssize_t o2hb_heartbeat_group_threshold_show(struct o2hb_heartbeat_group *group, + char *page) +{ + return sprintf(page, "%u\n", o2hb_dead_threshold); +} + +static ssize_t o2hb_heartbeat_group_threshold_store(struct o2hb_heartbeat_group *group, + const char *page, + size_t count) +{ + unsigned long tmp; + char *p = (char *)page; + + tmp = simple_strtoul(p, &p, 10); + if (!p || (*p && (*p != '\n'))) + return -EINVAL; + + /* this will validate ranges for us. */ + o2hb_dead_threshold_set((unsigned int) tmp); + + return count; +} + +static +ssize_t o2hb_heartbeat_group_mode_show(struct o2hb_heartbeat_group *group, + char *page) +{ + return sprintf(page, "%s\n", + o2hb_heartbeat_mode_desc[o2hb_heartbeat_mode]); +} + +static +ssize_t o2hb_heartbeat_group_mode_store(struct o2hb_heartbeat_group *group, + const char *page, size_t count) +{ + unsigned int i; + int ret; + size_t len; + + len = (page[count - 1] == '\n') ? count - 1 : count; + if (!len) + return -EINVAL; + + for (i = 0; i < O2HB_HEARTBEAT_NUM_MODES; ++i) { + if (strnicmp(page, o2hb_heartbeat_mode_desc[i], len)) + continue; + + ret = o2hb_global_hearbeat_mode_set(i); + if (!ret) + printk(KERN_NOTICE "o2hb: Heartbeat mode set to %s\n", + o2hb_heartbeat_mode_desc[i]); + return count; + } + + return -EINVAL; + +} + +static struct o2hb_heartbeat_group_attribute o2hb_heartbeat_group_attr_threshold = { + .attr = { .ca_owner = THIS_MODULE, + .ca_name = "dead_threshold", + .ca_mode = S_IRUGO | S_IWUSR }, + .show = o2hb_heartbeat_group_threshold_show, + .store = o2hb_heartbeat_group_threshold_store, +}; + +static struct o2hb_heartbeat_group_attribute o2hb_heartbeat_group_attr_mode = { + .attr = { .ca_owner = THIS_MODULE, + .ca_name = "mode", + .ca_mode = S_IRUGO | S_IWUSR }, + .show = o2hb_heartbeat_group_mode_show, + .store = o2hb_heartbeat_group_mode_store, +}; + +static struct configfs_attribute *o2hb_heartbeat_group_attrs[] = { + &o2hb_heartbeat_group_attr_threshold.attr, + &o2hb_heartbeat_group_attr_mode.attr, + NULL, +}; + +static struct configfs_item_operations o2hb_hearbeat_group_item_ops = { + .show_attribute = o2hb_heartbeat_group_show, + .store_attribute = o2hb_heartbeat_group_store, +}; + +static struct configfs_group_operations o2hb_heartbeat_group_group_ops = { + .make_item = o2hb_heartbeat_group_make_item, + .drop_item = o2hb_heartbeat_group_drop_item, +}; + +static struct config_item_type o2hb_heartbeat_group_type = { + .ct_group_ops = &o2hb_heartbeat_group_group_ops, + .ct_item_ops = &o2hb_hearbeat_group_item_ops, + .ct_attrs = o2hb_heartbeat_group_attrs, + .ct_owner = THIS_MODULE, +}; + +/* this is just here to avoid touching group in heartbeat.h which the + * entire damn world #includes */ +struct config_group *o2hb_alloc_hb_set(void) +{ + struct o2hb_heartbeat_group *hs = NULL; + struct config_group *ret = NULL; + + hs = kzalloc(sizeof(struct o2hb_heartbeat_group), GFP_KERNEL); + if (hs == NULL) + goto out; + + config_group_init_type_name(&hs->hs_group, "heartbeat", + &o2hb_heartbeat_group_type); + + ret = &hs->hs_group; +out: + if (ret == NULL) + kfree(hs); + return ret; +} + +void o2hb_free_hb_set(struct config_group *group) +{ + struct o2hb_heartbeat_group *hs = to_o2hb_heartbeat_group(group); + kfree(hs); +} + +/* hb callback registration and issuing */ + +static struct o2hb_callback *hbcall_from_type(enum o2hb_callback_type type) +{ + if (type == O2HB_NUM_CB) + return ERR_PTR(-EINVAL); + + return &o2hb_callbacks[type]; +} + +void o2hb_setup_callback(struct o2hb_callback_func *hc, + enum o2hb_callback_type type, + o2hb_cb_func *func, + void *data, + int priority) +{ + INIT_LIST_HEAD(&hc->hc_item); + hc->hc_func = func; + hc->hc_data = data; + hc->hc_priority = priority; + hc->hc_type = type; + hc->hc_magic = O2HB_CB_MAGIC; +} +EXPORT_SYMBOL_GPL(o2hb_setup_callback); + +/* + * In local heartbeat mode, region_uuid passed matches the dlm domain name. + * In global heartbeat mode, region_uuid passed is NULL. + * + * In local, we only pin the matching region. In global we pin all the active + * regions. + */ +static int o2hb_region_pin(const char *region_uuid) +{ + int ret = 0, found = 0; + struct o2hb_region *reg; + char *uuid; + + assert_spin_locked(&o2hb_live_lock); + + list_for_each_entry(reg, &o2hb_all_regions, hr_all_item) { + uuid = config_item_name(®->hr_item); + + /* local heartbeat */ + if (region_uuid) { + if (strcmp(region_uuid, uuid)) + continue; + found = 1; + } + + if (reg->hr_item_pinned || reg->hr_item_dropped) + goto skip_pin; + + /* Ignore ENOENT only for local hb (userdlm domain) */ + ret = o2nm_depend_item(®->hr_item); + if (!ret) { + mlog(ML_CLUSTER, "Pin region %s\n", uuid); + reg->hr_item_pinned = 1; + } else { + if (ret == -ENOENT && found) + ret = 0; + else { + mlog(ML_ERROR, "Pin region %s fails with %d\n", + uuid, ret); + break; + } + } +skip_pin: + if (found) + break; + } + + return ret; +} + +/* + * In local heartbeat mode, region_uuid passed matches the dlm domain name. + * In global heartbeat mode, region_uuid passed is NULL. + * + * In local, we only unpin the matching region. In global we unpin all the + * active regions. + */ +static void o2hb_region_unpin(const char *region_uuid) +{ + struct o2hb_region *reg; + char *uuid; + int found = 0; + + assert_spin_locked(&o2hb_live_lock); + + list_for_each_entry(reg, &o2hb_all_regions, hr_all_item) { + uuid = config_item_name(®->hr_item); + if (region_uuid) { + if (strcmp(region_uuid, uuid)) + continue; + found = 1; + } + + if (reg->hr_item_pinned) { + mlog(ML_CLUSTER, "Unpin region %s\n", uuid); + o2nm_undepend_item(®->hr_item); + reg->hr_item_pinned = 0; + } + if (found) + break; + } +} + +static int o2hb_region_inc_user(const char *region_uuid) +{ + int ret = 0; + + spin_lock(&o2hb_live_lock); + + /* local heartbeat */ + if (!o2hb_global_heartbeat_active()) { + ret = o2hb_region_pin(region_uuid); + goto unlock; + } + + /* + * if global heartbeat active and this is the first dependent user, + * pin all regions if quorum region count <= CUT_OFF + */ + o2hb_dependent_users++; + if (o2hb_dependent_users > 1) + goto unlock; + + if (o2hb_pop_count(&o2hb_quorum_region_bitmap, + O2NM_MAX_REGIONS) <= O2HB_PIN_CUT_OFF) + ret = o2hb_region_pin(NULL); + +unlock: + spin_unlock(&o2hb_live_lock); + return ret; +} + +void o2hb_region_dec_user(const char *region_uuid) +{ + spin_lock(&o2hb_live_lock); + + /* local heartbeat */ + if (!o2hb_global_heartbeat_active()) { + o2hb_region_unpin(region_uuid); + goto unlock; + } + + /* + * if global heartbeat active and there are no dependent users, + * unpin all quorum regions + */ + o2hb_dependent_users--; + if (!o2hb_dependent_users) + o2hb_region_unpin(NULL); + +unlock: + spin_unlock(&o2hb_live_lock); +} + +int o2hb_register_callback(const char *region_uuid, + struct o2hb_callback_func *hc) +{ + struct o2hb_callback_func *tmp; + struct list_head *iter; + struct o2hb_callback *hbcall; + int ret; + + BUG_ON(hc->hc_magic != O2HB_CB_MAGIC); + BUG_ON(!list_empty(&hc->hc_item)); + + hbcall = hbcall_from_type(hc->hc_type); + if (IS_ERR(hbcall)) { + ret = PTR_ERR(hbcall); + goto out; + } + + if (region_uuid) { + ret = o2hb_region_inc_user(region_uuid); + if (ret) { + mlog_errno(ret); + goto out; + } + } + + down_write(&o2hb_callback_sem); + + list_for_each(iter, &hbcall->list) { + tmp = list_entry(iter, struct o2hb_callback_func, hc_item); + if (hc->hc_priority < tmp->hc_priority) { + list_add_tail(&hc->hc_item, iter); + break; + } + } + if (list_empty(&hc->hc_item)) + list_add_tail(&hc->hc_item, &hbcall->list); + + up_write(&o2hb_callback_sem); + ret = 0; +out: + mlog(ML_CLUSTER, "returning %d on behalf of %p for funcs %p\n", + ret, __builtin_return_address(0), hc); + return ret; +} +EXPORT_SYMBOL_GPL(o2hb_register_callback); + +void o2hb_unregister_callback(const char *region_uuid, + struct o2hb_callback_func *hc) +{ + BUG_ON(hc->hc_magic != O2HB_CB_MAGIC); + + mlog(ML_CLUSTER, "on behalf of %p for funcs %p\n", + __builtin_return_address(0), hc); + + /* XXX Can this happen _with_ a region reference? */ + if (list_empty(&hc->hc_item)) + return; + + if (region_uuid) + o2hb_region_dec_user(region_uuid); + + down_write(&o2hb_callback_sem); + + list_del_init(&hc->hc_item); + + up_write(&o2hb_callback_sem); +} +EXPORT_SYMBOL_GPL(o2hb_unregister_callback); + +int o2hb_check_node_heartbeating(u8 node_num) +{ + unsigned long testing_map[BITS_TO_LONGS(O2NM_MAX_NODES)]; + + o2hb_fill_node_map(testing_map, sizeof(testing_map)); + if (!test_bit(node_num, testing_map)) { + mlog(ML_HEARTBEAT, + "node (%u) does not have heartbeating enabled.\n", + node_num); + return 0; + } + + return 1; +} +EXPORT_SYMBOL_GPL(o2hb_check_node_heartbeating); + +int o2hb_check_node_heartbeating_from_callback(u8 node_num) +{ + unsigned long testing_map[BITS_TO_LONGS(O2NM_MAX_NODES)]; + + o2hb_fill_node_map_from_callback(testing_map, sizeof(testing_map)); + if (!test_bit(node_num, testing_map)) { + mlog(ML_HEARTBEAT, + "node (%u) does not have heartbeating enabled.\n", + node_num); + return 0; + } + + return 1; +} +EXPORT_SYMBOL_GPL(o2hb_check_node_heartbeating_from_callback); + +/* Makes sure our local node is configured with a node number, and is + * heartbeating. */ +int o2hb_check_local_node_heartbeating(void) +{ + u8 node_num; + + /* if this node was set then we have networking */ + node_num = o2nm_this_node(); + if (node_num == O2NM_MAX_NODES) { + mlog(ML_HEARTBEAT, "this node has not been configured.\n"); + return 0; + } + + return o2hb_check_node_heartbeating(node_num); +} +EXPORT_SYMBOL_GPL(o2hb_check_local_node_heartbeating); + +/* + * this is just a hack until we get the plumbing which flips file systems + * read only and drops the hb ref instead of killing the node dead. + */ +void o2hb_stop_all_regions(void) +{ + struct o2hb_region *reg; + + mlog(ML_ERROR, "stopping heartbeat on all active regions.\n"); + + spin_lock(&o2hb_live_lock); + + list_for_each_entry(reg, &o2hb_all_regions, hr_all_item) + reg->hr_unclean_stop = 1; + + spin_unlock(&o2hb_live_lock); +} +EXPORT_SYMBOL_GPL(o2hb_stop_all_regions); + +int o2hb_get_all_regions(char *region_uuids, u8 max_regions) +{ + struct o2hb_region *reg; + int numregs = 0; + char *p; + + spin_lock(&o2hb_live_lock); + + p = region_uuids; + list_for_each_entry(reg, &o2hb_all_regions, hr_all_item) { + mlog(0, "Region: %s\n", config_item_name(®->hr_item)); + if (numregs < max_regions) { + memcpy(p, config_item_name(®->hr_item), + O2HB_MAX_REGION_NAME_LEN); + p += O2HB_MAX_REGION_NAME_LEN; + } + numregs++; + } + + spin_unlock(&o2hb_live_lock); + + return numregs; +} +EXPORT_SYMBOL_GPL(o2hb_get_all_regions); + +int o2hb_global_heartbeat_active(void) +{ + return (o2hb_heartbeat_mode == O2HB_HEARTBEAT_GLOBAL); +} +EXPORT_SYMBOL(o2hb_global_heartbeat_active); diff --git a/drivers/staging/ramster/cluster/heartbeat.h b/drivers/staging/ramster/cluster/heartbeat.h new file mode 100644 index 00000000000..00ad8e8fea5 --- /dev/null +++ b/drivers/staging/ramster/cluster/heartbeat.h @@ -0,0 +1,89 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * heartbeat.h + * + * Function prototypes + * + * Copyright (C) 2004 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + * + */ + +#ifndef O2CLUSTER_HEARTBEAT_H +#define O2CLUSTER_HEARTBEAT_H + +#include "ocfs2_heartbeat.h" + +#define O2HB_REGION_TIMEOUT_MS 2000 + +#define O2HB_MAX_REGION_NAME_LEN 32 + +/* number of changes to be seen as live */ +#define O2HB_LIVE_THRESHOLD 2 +/* number of equal samples to be seen as dead */ +extern unsigned int o2hb_dead_threshold; +#define O2HB_DEFAULT_DEAD_THRESHOLD 31 +/* Otherwise MAX_WRITE_TIMEOUT will be zero... */ +#define O2HB_MIN_DEAD_THRESHOLD 2 +#define O2HB_MAX_WRITE_TIMEOUT_MS (O2HB_REGION_TIMEOUT_MS * (o2hb_dead_threshold - 1)) + +#define O2HB_CB_MAGIC 0x51d1e4ec + +/* callback stuff */ +enum o2hb_callback_type { + O2HB_NODE_DOWN_CB = 0, + O2HB_NODE_UP_CB, + O2HB_NUM_CB +}; + +struct o2nm_node; +typedef void (o2hb_cb_func)(struct o2nm_node *, int, void *); + +struct o2hb_callback_func { + u32 hc_magic; + struct list_head hc_item; + o2hb_cb_func *hc_func; + void *hc_data; + int hc_priority; + enum o2hb_callback_type hc_type; +}; + +struct config_group *o2hb_alloc_hb_set(void); +void o2hb_free_hb_set(struct config_group *group); + +void o2hb_setup_callback(struct o2hb_callback_func *hc, + enum o2hb_callback_type type, + o2hb_cb_func *func, + void *data, + int priority); +int o2hb_register_callback(const char *region_uuid, + struct o2hb_callback_func *hc); +void o2hb_unregister_callback(const char *region_uuid, + struct o2hb_callback_func *hc); +void o2hb_fill_node_map(unsigned long *map, + unsigned bytes); +void o2hb_exit(void); +int o2hb_init(void); +int o2hb_check_node_heartbeating(u8 node_num); +int o2hb_check_node_heartbeating_from_callback(u8 node_num); +int o2hb_check_local_node_heartbeating(void); +void o2hb_stop_all_regions(void); +int o2hb_get_all_regions(char *region_uuids, u8 numregions); +int o2hb_global_heartbeat_active(void); + +#endif /* O2CLUSTER_HEARTBEAT_H */ diff --git a/drivers/staging/ramster/cluster/masklog.c b/drivers/staging/ramster/cluster/masklog.c new file mode 100644 index 00000000000..07ac24fd925 --- /dev/null +++ b/drivers/staging/ramster/cluster/masklog.c @@ -0,0 +1,155 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * Copyright (C) 2004, 2005 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include "masklog.h" + +struct mlog_bits mlog_and_bits = MLOG_BITS_RHS(MLOG_INITIAL_AND_MASK); +EXPORT_SYMBOL_GPL(mlog_and_bits); +struct mlog_bits mlog_not_bits = MLOG_BITS_RHS(0); +EXPORT_SYMBOL_GPL(mlog_not_bits); + +static ssize_t mlog_mask_show(u64 mask, char *buf) +{ + char *state; + + if (__mlog_test_u64(mask, mlog_and_bits)) + state = "allow"; + else if (__mlog_test_u64(mask, mlog_not_bits)) + state = "deny"; + else + state = "off"; + + return snprintf(buf, PAGE_SIZE, "%s\n", state); +} + +static ssize_t mlog_mask_store(u64 mask, const char *buf, size_t count) +{ + if (!strnicmp(buf, "allow", 5)) { + __mlog_set_u64(mask, mlog_and_bits); + __mlog_clear_u64(mask, mlog_not_bits); + } else if (!strnicmp(buf, "deny", 4)) { + __mlog_set_u64(mask, mlog_not_bits); + __mlog_clear_u64(mask, mlog_and_bits); + } else if (!strnicmp(buf, "off", 3)) { + __mlog_clear_u64(mask, mlog_not_bits); + __mlog_clear_u64(mask, mlog_and_bits); + } else + return -EINVAL; + + return count; +} + +struct mlog_attribute { + struct attribute attr; + u64 mask; +}; + +#define to_mlog_attr(_attr) container_of(_attr, struct mlog_attribute, attr) + +#define define_mask(_name) { \ + .attr = { \ + .name = #_name, \ + .mode = S_IRUGO | S_IWUSR, \ + }, \ + .mask = ML_##_name, \ +} + +static struct mlog_attribute mlog_attrs[MLOG_MAX_BITS] = { + define_mask(TCP), + define_mask(MSG), + define_mask(SOCKET), + define_mask(HEARTBEAT), + define_mask(HB_BIO), + define_mask(DLMFS), + define_mask(DLM), + define_mask(DLM_DOMAIN), + define_mask(DLM_THREAD), + define_mask(DLM_MASTER), + define_mask(DLM_RECOVERY), + define_mask(DLM_GLUE), + define_mask(VOTE), + define_mask(CONN), + define_mask(QUORUM), + define_mask(BASTS), + define_mask(CLUSTER), + define_mask(ERROR), + define_mask(NOTICE), + define_mask(KTHREAD), +}; + +static struct attribute *mlog_attr_ptrs[MLOG_MAX_BITS] = {NULL, }; + +static ssize_t mlog_show(struct kobject *obj, struct attribute *attr, + char *buf) +{ + struct mlog_attribute *mlog_attr = to_mlog_attr(attr); + + return mlog_mask_show(mlog_attr->mask, buf); +} + +static ssize_t mlog_store(struct kobject *obj, struct attribute *attr, + const char *buf, size_t count) +{ + struct mlog_attribute *mlog_attr = to_mlog_attr(attr); + + return mlog_mask_store(mlog_attr->mask, buf, count); +} + +static const struct sysfs_ops mlog_attr_ops = { + .show = mlog_show, + .store = mlog_store, +}; + +static struct kobj_type mlog_ktype = { + .default_attrs = mlog_attr_ptrs, + .sysfs_ops = &mlog_attr_ops, +}; + +static struct kset mlog_kset = { + .kobj = {.ktype = &mlog_ktype}, +}; + +int mlog_sys_init(struct kset *o2cb_kset) +{ + int i = 0; + + while (mlog_attrs[i].attr.mode) { + mlog_attr_ptrs[i] = &mlog_attrs[i].attr; + i++; + } + mlog_attr_ptrs[i] = NULL; + + kobject_set_name(&mlog_kset.kobj, "logmask"); + mlog_kset.kobj.kset = o2cb_kset; + return kset_register(&mlog_kset); +} + +void mlog_sys_shutdown(void) +{ + kset_unregister(&mlog_kset); +} diff --git a/drivers/staging/ramster/cluster/masklog.h b/drivers/staging/ramster/cluster/masklog.h new file mode 100644 index 00000000000..baa2b9ef7ee --- /dev/null +++ b/drivers/staging/ramster/cluster/masklog.h @@ -0,0 +1,219 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * Copyright (C) 2005 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ + +#ifndef O2CLUSTER_MASKLOG_H +#define O2CLUSTER_MASKLOG_H + +/* + * For now this is a trivial wrapper around printk() that gives the critical + * ability to enable sets of debugging output at run-time. In the future this + * will almost certainly be redirected to relayfs so that it can pay a + * substantially lower heisenberg tax. + * + * Callers associate the message with a bitmask and a global bitmask is + * maintained with help from /proc. If any of the bits match the message is + * output. + * + * We must have efficient bit tests on i386 and it seems gcc still emits crazy + * code for the 64bit compare. It emits very good code for the dual unsigned + * long tests, though, completely avoiding tests that can never pass if the + * caller gives a constant bitmask that fills one of the longs with all 0s. So + * the desire is to have almost all of the calls decided on by comparing just + * one of the longs. This leads to having infrequently given bits that are + * frequently matched in the high bits. + * + * _ERROR and _NOTICE are used for messages that always go to the console and + * have appropriate KERN_ prefixes. We wrap these in our function instead of + * just calling printk() so that this can eventually make its way through + * relayfs along with the debugging messages. Everything else gets KERN_DEBUG. + * The inline tests and macro dance give GCC the opportunity to quite cleverly + * only emit the appropriage printk() when the caller passes in a constant + * mask, as is almost always the case. + * + * All this bitmask nonsense is managed from the files under + * /sys/fs/o2cb/logmask/. Reading the files gives a straightforward + * indication of which bits are allowed (allow) or denied (off/deny). + * ENTRY deny + * EXIT deny + * TCP off + * MSG off + * SOCKET off + * ERROR allow + * NOTICE allow + * + * Writing changes the state of a given bit and requires a strictly formatted + * single write() call: + * + * write(fd, "allow", 5); + * + * Echoing allow/deny/off string into the logmask files can flip the bits + * on or off as expected; here is the bash script for example: + * + * log_mask="/sys/fs/o2cb/log_mask" + * for node in ENTRY EXIT TCP MSG SOCKET ERROR NOTICE; do + * echo allow >"$log_mask"/"$node" + * done + * + * The debugfs.ocfs2 tool can also flip the bits with the -l option: + * + * debugfs.ocfs2 -l TCP allow + */ + +/* for task_struct */ +#include + +/* bits that are frequently given and infrequently matched in the low word */ +/* NOTE: If you add a flag, you need to also update masklog.c! */ +#define ML_TCP 0x0000000000000001ULL /* net cluster/tcp.c */ +#define ML_MSG 0x0000000000000002ULL /* net network messages */ +#define ML_SOCKET 0x0000000000000004ULL /* net socket lifetime */ +#define ML_HEARTBEAT 0x0000000000000008ULL /* hb all heartbeat tracking */ +#define ML_HB_BIO 0x0000000000000010ULL /* hb io tracing */ +#define ML_DLMFS 0x0000000000000020ULL /* dlm user dlmfs */ +#define ML_DLM 0x0000000000000040ULL /* dlm general debugging */ +#define ML_DLM_DOMAIN 0x0000000000000080ULL /* dlm domain debugging */ +#define ML_DLM_THREAD 0x0000000000000100ULL /* dlm domain thread */ +#define ML_DLM_MASTER 0x0000000000000200ULL /* dlm master functions */ +#define ML_DLM_RECOVERY 0x0000000000000400ULL /* dlm master functions */ +#define ML_DLM_GLUE 0x0000000000000800ULL /* ocfs2 dlm glue layer */ +#define ML_VOTE 0x0000000000001000ULL /* ocfs2 node messaging */ +#define ML_CONN 0x0000000000002000ULL /* net connection management */ +#define ML_QUORUM 0x0000000000004000ULL /* net connection quorum */ +#define ML_BASTS 0x0000000000008000ULL /* dlmglue asts and basts */ +#define ML_CLUSTER 0x0000000000010000ULL /* cluster stack */ + +/* bits that are infrequently given and frequently matched in the high word */ +#define ML_ERROR 0x1000000000000000ULL /* sent to KERN_ERR */ +#define ML_NOTICE 0x2000000000000000ULL /* setn to KERN_NOTICE */ +#define ML_KTHREAD 0x4000000000000000ULL /* kernel thread activity */ + +#define MLOG_INITIAL_AND_MASK (ML_ERROR|ML_NOTICE) +#ifndef MLOG_MASK_PREFIX +#define MLOG_MASK_PREFIX 0 +#endif + +/* + * When logging is disabled, force the bit test to 0 for anything other + * than errors and notices, allowing gcc to remove the code completely. + * When enabled, allow all masks. + */ +#if defined(CONFIG_OCFS2_DEBUG_MASKLOG) +#define ML_ALLOWED_BITS ~0 +#else +#define ML_ALLOWED_BITS (ML_ERROR|ML_NOTICE) +#endif + +#define MLOG_MAX_BITS 64 + +struct mlog_bits { + unsigned long words[MLOG_MAX_BITS / BITS_PER_LONG]; +}; + +extern struct mlog_bits mlog_and_bits, mlog_not_bits; + +#if BITS_PER_LONG == 32 + +#define __mlog_test_u64(mask, bits) \ + ( (u32)(mask & 0xffffffff) & bits.words[0] || \ + ((u64)(mask) >> 32) & bits.words[1] ) +#define __mlog_set_u64(mask, bits) do { \ + bits.words[0] |= (u32)(mask & 0xffffffff); \ + bits.words[1] |= (u64)(mask) >> 32; \ +} while (0) +#define __mlog_clear_u64(mask, bits) do { \ + bits.words[0] &= ~((u32)(mask & 0xffffffff)); \ + bits.words[1] &= ~((u64)(mask) >> 32); \ +} while (0) +#define MLOG_BITS_RHS(mask) { \ + { \ + [0] = (u32)(mask & 0xffffffff), \ + [1] = (u64)(mask) >> 32, \ + } \ +} + +#else /* 32bit long above, 64bit long below */ + +#define __mlog_test_u64(mask, bits) ((mask) & bits.words[0]) +#define __mlog_set_u64(mask, bits) do { \ + bits.words[0] |= (mask); \ +} while (0) +#define __mlog_clear_u64(mask, bits) do { \ + bits.words[0] &= ~(mask); \ +} while (0) +#define MLOG_BITS_RHS(mask) { { (mask) } } + +#endif + +/* + * smp_processor_id() "helpfully" screams when called outside preemptible + * regions in current kernels. sles doesn't have the variants that don't + * scream. just do this instead of trying to guess which we're building + * against.. *sigh*. + */ +#define __mlog_cpu_guess ({ \ + unsigned long _cpu = get_cpu(); \ + put_cpu(); \ + _cpu; \ +}) + +/* In the following two macros, the whitespace after the ',' just + * before ##args is intentional. Otherwise, gcc 2.95 will eat the + * previous token if args expands to nothing. + */ +#define __mlog_printk(level, fmt, args...) \ + printk(level "(%s,%u,%lu):%s:%d " fmt, current->comm, \ + task_pid_nr(current), __mlog_cpu_guess, \ + __PRETTY_FUNCTION__, __LINE__ , ##args) + +#define mlog(mask, fmt, args...) do { \ + u64 __m = MLOG_MASK_PREFIX | (mask); \ + if ((__m & ML_ALLOWED_BITS) && \ + __mlog_test_u64(__m, mlog_and_bits) && \ + !__mlog_test_u64(__m, mlog_not_bits)) { \ + if (__m & ML_ERROR) \ + __mlog_printk(KERN_ERR, "ERROR: "fmt , ##args); \ + else if (__m & ML_NOTICE) \ + __mlog_printk(KERN_NOTICE, fmt , ##args); \ + else __mlog_printk(KERN_INFO, fmt , ##args); \ + } \ +} while (0) + +#define mlog_errno(st) do { \ + int _st = (st); \ + if (_st != -ERESTARTSYS && _st != -EINTR && \ + _st != AOP_TRUNCATED_PAGE && _st != -ENOSPC) \ + mlog(ML_ERROR, "status = %lld\n", (long long)_st); \ +} while (0) + +#define mlog_bug_on_msg(cond, fmt, args...) do { \ + if (cond) { \ + mlog(ML_ERROR, "bug expression: " #cond "\n"); \ + mlog(ML_ERROR, fmt, ##args); \ + BUG(); \ + } \ +} while (0) + +#include +#include +int mlog_sys_init(struct kset *o2cb_subsys); +void mlog_sys_shutdown(void); + +#endif /* O2CLUSTER_MASKLOG_H */ diff --git a/drivers/staging/ramster/cluster/netdebug.c b/drivers/staging/ramster/cluster/netdebug.c new file mode 100644 index 00000000000..dc45deb19e6 --- /dev/null +++ b/drivers/staging/ramster/cluster/netdebug.c @@ -0,0 +1,579 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * netdebug.c + * + * debug functionality for o2net + * + * Copyright (C) 2005, 2008 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + * + */ + +#ifdef CONFIG_DEBUG_FS + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "tcp.h" +#include "nodemanager.h" +#define MLOG_MASK_PREFIX ML_TCP +#include "masklog.h" + +#include "tcp_internal.h" + +#define O2NET_DEBUG_DIR "o2net" +#define SC_DEBUG_NAME "sock_containers" +#define NST_DEBUG_NAME "send_tracking" +#define STATS_DEBUG_NAME "stats" +#define NODES_DEBUG_NAME "connected_nodes" + +#define SHOW_SOCK_CONTAINERS 0 +#define SHOW_SOCK_STATS 1 + +static struct dentry *o2net_dentry; +static struct dentry *sc_dentry; +static struct dentry *nst_dentry; +static struct dentry *stats_dentry; +static struct dentry *nodes_dentry; + +static DEFINE_SPINLOCK(o2net_debug_lock); + +static LIST_HEAD(sock_containers); +static LIST_HEAD(send_tracking); + +void o2net_debug_add_nst(struct o2net_send_tracking *nst) +{ + spin_lock(&o2net_debug_lock); + list_add(&nst->st_net_debug_item, &send_tracking); + spin_unlock(&o2net_debug_lock); +} + +void o2net_debug_del_nst(struct o2net_send_tracking *nst) +{ + spin_lock(&o2net_debug_lock); + if (!list_empty(&nst->st_net_debug_item)) + list_del_init(&nst->st_net_debug_item); + spin_unlock(&o2net_debug_lock); +} + +static struct o2net_send_tracking + *next_nst(struct o2net_send_tracking *nst_start) +{ + struct o2net_send_tracking *nst, *ret = NULL; + + assert_spin_locked(&o2net_debug_lock); + + list_for_each_entry(nst, &nst_start->st_net_debug_item, + st_net_debug_item) { + /* discover the head of the list */ + if (&nst->st_net_debug_item == &send_tracking) + break; + + /* use st_task to detect real nsts in the list */ + if (nst->st_task != NULL) { + ret = nst; + break; + } + } + + return ret; +} + +static void *nst_seq_start(struct seq_file *seq, loff_t *pos) +{ + struct o2net_send_tracking *nst, *dummy_nst = seq->private; + + spin_lock(&o2net_debug_lock); + nst = next_nst(dummy_nst); + spin_unlock(&o2net_debug_lock); + + return nst; +} + +static void *nst_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + struct o2net_send_tracking *nst, *dummy_nst = seq->private; + + spin_lock(&o2net_debug_lock); + nst = next_nst(dummy_nst); + list_del_init(&dummy_nst->st_net_debug_item); + if (nst) + list_add(&dummy_nst->st_net_debug_item, + &nst->st_net_debug_item); + spin_unlock(&o2net_debug_lock); + + return nst; /* unused, just needs to be null when done */ +} + +static int nst_seq_show(struct seq_file *seq, void *v) +{ + struct o2net_send_tracking *nst, *dummy_nst = seq->private; + ktime_t now; + s64 sock, send, status; + + spin_lock(&o2net_debug_lock); + nst = next_nst(dummy_nst); + if (!nst) + goto out; + + now = ktime_get(); + sock = ktime_to_us(ktime_sub(now, nst->st_sock_time)); + send = ktime_to_us(ktime_sub(now, nst->st_send_time)); + status = ktime_to_us(ktime_sub(now, nst->st_status_time)); + + /* get_task_comm isn't exported. oh well. */ + seq_printf(seq, "%p:\n" + " pid: %lu\n" + " tgid: %lu\n" + " process name: %s\n" + " node: %u\n" + " sc: %p\n" + " message id: %d\n" + " message type: %u\n" + " message key: 0x%08x\n" + " sock acquiry: %lld usecs ago\n" + " send start: %lld usecs ago\n" + " wait start: %lld usecs ago\n", + nst, (unsigned long)task_pid_nr(nst->st_task), + (unsigned long)nst->st_task->tgid, + nst->st_task->comm, nst->st_node, + nst->st_sc, nst->st_id, nst->st_msg_type, + nst->st_msg_key, + (long long)sock, + (long long)send, + (long long)status); + +out: + spin_unlock(&o2net_debug_lock); + + return 0; +} + +static void nst_seq_stop(struct seq_file *seq, void *v) +{ +} + +static const struct seq_operations nst_seq_ops = { + .start = nst_seq_start, + .next = nst_seq_next, + .stop = nst_seq_stop, + .show = nst_seq_show, +}; + +static int nst_fop_open(struct inode *inode, struct file *file) +{ + struct o2net_send_tracking *dummy_nst; + struct seq_file *seq; + int ret; + + dummy_nst = kmalloc(sizeof(struct o2net_send_tracking), GFP_KERNEL); + if (dummy_nst == NULL) { + ret = -ENOMEM; + goto out; + } + dummy_nst->st_task = NULL; + + ret = seq_open(file, &nst_seq_ops); + if (ret) + goto out; + + seq = file->private_data; + seq->private = dummy_nst; + o2net_debug_add_nst(dummy_nst); + + dummy_nst = NULL; + +out: + kfree(dummy_nst); + return ret; +} + +static int nst_fop_release(struct inode *inode, struct file *file) +{ + struct seq_file *seq = file->private_data; + struct o2net_send_tracking *dummy_nst = seq->private; + + o2net_debug_del_nst(dummy_nst); + return seq_release_private(inode, file); +} + +static const struct file_operations nst_seq_fops = { + .open = nst_fop_open, + .read = seq_read, + .llseek = seq_lseek, + .release = nst_fop_release, +}; + +void o2net_debug_add_sc(struct o2net_sock_container *sc) +{ + spin_lock(&o2net_debug_lock); + list_add(&sc->sc_net_debug_item, &sock_containers); + spin_unlock(&o2net_debug_lock); +} + +void o2net_debug_del_sc(struct o2net_sock_container *sc) +{ + spin_lock(&o2net_debug_lock); + list_del_init(&sc->sc_net_debug_item); + spin_unlock(&o2net_debug_lock); +} + +struct o2net_sock_debug { + int dbg_ctxt; + struct o2net_sock_container *dbg_sock; +}; + +static struct o2net_sock_container + *next_sc(struct o2net_sock_container *sc_start) +{ + struct o2net_sock_container *sc, *ret = NULL; + + assert_spin_locked(&o2net_debug_lock); + + list_for_each_entry(sc, &sc_start->sc_net_debug_item, + sc_net_debug_item) { + /* discover the head of the list miscast as a sc */ + if (&sc->sc_net_debug_item == &sock_containers) + break; + + /* use sc_page to detect real scs in the list */ + if (sc->sc_page != NULL) { + ret = sc; + break; + } + } + + return ret; +} + +static void *sc_seq_start(struct seq_file *seq, loff_t *pos) +{ + struct o2net_sock_debug *sd = seq->private; + struct o2net_sock_container *sc, *dummy_sc = sd->dbg_sock; + + spin_lock(&o2net_debug_lock); + sc = next_sc(dummy_sc); + spin_unlock(&o2net_debug_lock); + + return sc; +} + +static void *sc_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + struct o2net_sock_debug *sd = seq->private; + struct o2net_sock_container *sc, *dummy_sc = sd->dbg_sock; + + spin_lock(&o2net_debug_lock); + sc = next_sc(dummy_sc); + list_del_init(&dummy_sc->sc_net_debug_item); + if (sc) + list_add(&dummy_sc->sc_net_debug_item, &sc->sc_net_debug_item); + spin_unlock(&o2net_debug_lock); + + return sc; /* unused, just needs to be null when done */ +} + +#ifdef CONFIG_OCFS2_FS_STATS +# define sc_send_count(_s) ((_s)->sc_send_count) +# define sc_recv_count(_s) ((_s)->sc_recv_count) +# define sc_tv_acquiry_total_ns(_s) (ktime_to_ns((_s)->sc_tv_acquiry_total)) +# define sc_tv_send_total_ns(_s) (ktime_to_ns((_s)->sc_tv_send_total)) +# define sc_tv_status_total_ns(_s) (ktime_to_ns((_s)->sc_tv_status_total)) +# define sc_tv_process_total_ns(_s) (ktime_to_ns((_s)->sc_tv_process_total)) +#else +# define sc_send_count(_s) (0U) +# define sc_recv_count(_s) (0U) +# define sc_tv_acquiry_total_ns(_s) (0LL) +# define sc_tv_send_total_ns(_s) (0LL) +# define sc_tv_status_total_ns(_s) (0LL) +# define sc_tv_process_total_ns(_s) (0LL) +#endif + +/* So that debugfs.ocfs2 can determine which format is being used */ +#define O2NET_STATS_STR_VERSION 1 +static void sc_show_sock_stats(struct seq_file *seq, + struct o2net_sock_container *sc) +{ + if (!sc) + return; + + seq_printf(seq, "%d,%u,%lu,%lld,%lld,%lld,%lu,%lld\n", O2NET_STATS_STR_VERSION, + sc->sc_node->nd_num, (unsigned long)sc_send_count(sc), + (long long)sc_tv_acquiry_total_ns(sc), + (long long)sc_tv_send_total_ns(sc), + (long long)sc_tv_status_total_ns(sc), + (unsigned long)sc_recv_count(sc), + (long long)sc_tv_process_total_ns(sc)); +} + +static void sc_show_sock_container(struct seq_file *seq, + struct o2net_sock_container *sc) +{ + struct inet_sock *inet = NULL; + __be32 saddr = 0, daddr = 0; + __be16 sport = 0, dport = 0; + + if (!sc) + return; + + if (sc->sc_sock) { + inet = inet_sk(sc->sc_sock->sk); + /* the stack's structs aren't sparse endian clean */ + saddr = (__force __be32)inet->inet_saddr; + daddr = (__force __be32)inet->inet_daddr; + sport = (__force __be16)inet->inet_sport; + dport = (__force __be16)inet->inet_dport; + } + + /* XXX sigh, inet-> doesn't have sparse annotation so any + * use of it here generates a warning with -Wbitwise */ + seq_printf(seq, "%p:\n" + " krefs: %d\n" + " sock: %pI4:%u -> " + "%pI4:%u\n" + " remote node: %s\n" + " page off: %zu\n" + " handshake ok: %u\n" + " timer: %lld usecs\n" + " data ready: %lld usecs\n" + " advance start: %lld usecs\n" + " advance stop: %lld usecs\n" + " func start: %lld usecs\n" + " func stop: %lld usecs\n" + " func key: 0x%08x\n" + " func type: %u\n", + sc, + atomic_read(&sc->sc_kref.refcount), + &saddr, inet ? ntohs(sport) : 0, + &daddr, inet ? ntohs(dport) : 0, + sc->sc_node->nd_name, + sc->sc_page_off, + sc->sc_handshake_ok, + (long long)ktime_to_us(sc->sc_tv_timer), + (long long)ktime_to_us(sc->sc_tv_data_ready), + (long long)ktime_to_us(sc->sc_tv_advance_start), + (long long)ktime_to_us(sc->sc_tv_advance_stop), + (long long)ktime_to_us(sc->sc_tv_func_start), + (long long)ktime_to_us(sc->sc_tv_func_stop), + sc->sc_msg_key, + sc->sc_msg_type); +} + +static int sc_seq_show(struct seq_file *seq, void *v) +{ + struct o2net_sock_debug *sd = seq->private; + struct o2net_sock_container *sc, *dummy_sc = sd->dbg_sock; + + spin_lock(&o2net_debug_lock); + sc = next_sc(dummy_sc); + + if (sc) { + if (sd->dbg_ctxt == SHOW_SOCK_CONTAINERS) + sc_show_sock_container(seq, sc); + else + sc_show_sock_stats(seq, sc); + } + + spin_unlock(&o2net_debug_lock); + + return 0; +} + +static void sc_seq_stop(struct seq_file *seq, void *v) +{ +} + +static const struct seq_operations sc_seq_ops = { + .start = sc_seq_start, + .next = sc_seq_next, + .stop = sc_seq_stop, + .show = sc_seq_show, +}; + +static int sc_common_open(struct file *file, struct o2net_sock_debug *sd) +{ + struct o2net_sock_container *dummy_sc; + struct seq_file *seq; + int ret; + + dummy_sc = kmalloc(sizeof(struct o2net_sock_container), GFP_KERNEL); + if (dummy_sc == NULL) { + ret = -ENOMEM; + goto out; + } + dummy_sc->sc_page = NULL; + + ret = seq_open(file, &sc_seq_ops); + if (ret) + goto out; + + seq = file->private_data; + seq->private = sd; + sd->dbg_sock = dummy_sc; + o2net_debug_add_sc(dummy_sc); + + dummy_sc = NULL; + +out: + kfree(dummy_sc); + return ret; +} + +static int sc_fop_release(struct inode *inode, struct file *file) +{ + struct seq_file *seq = file->private_data; + struct o2net_sock_debug *sd = seq->private; + struct o2net_sock_container *dummy_sc = sd->dbg_sock; + + o2net_debug_del_sc(dummy_sc); + return seq_release_private(inode, file); +} + +static int stats_fop_open(struct inode *inode, struct file *file) +{ + struct o2net_sock_debug *sd; + + sd = kmalloc(sizeof(struct o2net_sock_debug), GFP_KERNEL); + if (sd == NULL) + return -ENOMEM; + + sd->dbg_ctxt = SHOW_SOCK_STATS; + sd->dbg_sock = NULL; + + return sc_common_open(file, sd); +} + +static const struct file_operations stats_seq_fops = { + .open = stats_fop_open, + .read = seq_read, + .llseek = seq_lseek, + .release = sc_fop_release, +}; + +static int sc_fop_open(struct inode *inode, struct file *file) +{ + struct o2net_sock_debug *sd; + + sd = kmalloc(sizeof(struct o2net_sock_debug), GFP_KERNEL); + if (sd == NULL) + return -ENOMEM; + + sd->dbg_ctxt = SHOW_SOCK_CONTAINERS; + sd->dbg_sock = NULL; + + return sc_common_open(file, sd); +} + +static const struct file_operations sc_seq_fops = { + .open = sc_fop_open, + .read = seq_read, + .llseek = seq_lseek, + .release = sc_fop_release, +}; + +static int o2net_fill_bitmap(char *buf, int len) +{ + unsigned long map[BITS_TO_LONGS(O2NM_MAX_NODES)]; + int i = -1, out = 0; + + o2net_fill_node_map(map, sizeof(map)); + + while ((i = find_next_bit(map, O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES) + out += snprintf(buf + out, PAGE_SIZE - out, "%d ", i); + out += snprintf(buf + out, PAGE_SIZE - out, "\n"); + + return out; +} + +static int nodes_fop_open(struct inode *inode, struct file *file) +{ + char *buf; + + buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + i_size_write(inode, o2net_fill_bitmap(buf, PAGE_SIZE)); + + file->private_data = buf; + + return 0; +} + +static int o2net_debug_release(struct inode *inode, struct file *file) +{ + kfree(file->private_data); + return 0; +} + +static ssize_t o2net_debug_read(struct file *file, char __user *buf, + size_t nbytes, loff_t *ppos) +{ + return simple_read_from_buffer(buf, nbytes, ppos, file->private_data, + i_size_read(file->f_mapping->host)); +} + +static const struct file_operations nodes_fops = { + .open = nodes_fop_open, + .release = o2net_debug_release, + .read = o2net_debug_read, + .llseek = generic_file_llseek, +}; + +void o2net_debugfs_exit(void) +{ + debugfs_remove(nodes_dentry); + debugfs_remove(stats_dentry); + debugfs_remove(sc_dentry); + debugfs_remove(nst_dentry); + debugfs_remove(o2net_dentry); +} + +int o2net_debugfs_init(void) +{ + mode_t mode = S_IFREG|S_IRUSR; + + o2net_dentry = debugfs_create_dir(O2NET_DEBUG_DIR, NULL); + if (o2net_dentry) + nst_dentry = debugfs_create_file(NST_DEBUG_NAME, mode, + o2net_dentry, NULL, &nst_seq_fops); + if (nst_dentry) + sc_dentry = debugfs_create_file(SC_DEBUG_NAME, mode, + o2net_dentry, NULL, &sc_seq_fops); + if (sc_dentry) + stats_dentry = debugfs_create_file(STATS_DEBUG_NAME, mode, + o2net_dentry, NULL, &stats_seq_fops); + if (stats_dentry) + nodes_dentry = debugfs_create_file(NODES_DEBUG_NAME, mode, + o2net_dentry, NULL, &nodes_fops); + if (nodes_dentry) + return 0; + + o2net_debugfs_exit(); + mlog_errno(-ENOMEM); + return -ENOMEM; +} + +#endif /* CONFIG_DEBUG_FS */ diff --git a/drivers/staging/ramster/cluster/nodemanager.c b/drivers/staging/ramster/cluster/nodemanager.c new file mode 100644 index 00000000000..bb240647ca5 --- /dev/null +++ b/drivers/staging/ramster/cluster/nodemanager.c @@ -0,0 +1,989 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * Copyright (C) 2004, 2005 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ + +#include +#include +#include +#include + +#include "tcp.h" +#include "nodemanager.h" +#include "heartbeat.h" +#include "masklog.h" +#include "sys.h" +#include "ver.h" + +/* for now we operate under the assertion that there can be only one + * cluster active at a time. Changing this will require trickling + * cluster references throughout where nodes are looked up */ +struct o2nm_cluster *o2nm_single_cluster = NULL; + +char *o2nm_fence_method_desc[O2NM_FENCE_METHODS] = { + "reset", /* O2NM_FENCE_RESET */ + "panic", /* O2NM_FENCE_PANIC */ +}; + +struct o2nm_node *o2nm_get_node_by_num(u8 node_num) +{ + struct o2nm_node *node = NULL; + + if (node_num >= O2NM_MAX_NODES || o2nm_single_cluster == NULL) + goto out; + + read_lock(&o2nm_single_cluster->cl_nodes_lock); + node = o2nm_single_cluster->cl_nodes[node_num]; + if (node) + config_item_get(&node->nd_item); + read_unlock(&o2nm_single_cluster->cl_nodes_lock); +out: + return node; +} +EXPORT_SYMBOL_GPL(o2nm_get_node_by_num); + +int o2nm_configured_node_map(unsigned long *map, unsigned bytes) +{ + struct o2nm_cluster *cluster = o2nm_single_cluster; + + BUG_ON(bytes < (sizeof(cluster->cl_nodes_bitmap))); + + if (cluster == NULL) + return -EINVAL; + + read_lock(&cluster->cl_nodes_lock); + memcpy(map, cluster->cl_nodes_bitmap, sizeof(cluster->cl_nodes_bitmap)); + read_unlock(&cluster->cl_nodes_lock); + + return 0; +} +EXPORT_SYMBOL_GPL(o2nm_configured_node_map); + +static struct o2nm_node *o2nm_node_ip_tree_lookup(struct o2nm_cluster *cluster, + __be32 ip_needle, + struct rb_node ***ret_p, + struct rb_node **ret_parent) +{ + struct rb_node **p = &cluster->cl_node_ip_tree.rb_node; + struct rb_node *parent = NULL; + struct o2nm_node *node, *ret = NULL; + + while (*p) { + int cmp; + + parent = *p; + node = rb_entry(parent, struct o2nm_node, nd_ip_node); + + cmp = memcmp(&ip_needle, &node->nd_ipv4_address, + sizeof(ip_needle)); + if (cmp < 0) + p = &(*p)->rb_left; + else if (cmp > 0) + p = &(*p)->rb_right; + else { + ret = node; + break; + } + } + + if (ret_p != NULL) + *ret_p = p; + if (ret_parent != NULL) + *ret_parent = parent; + + return ret; +} + +struct o2nm_node *o2nm_get_node_by_ip(__be32 addr) +{ + struct o2nm_node *node = NULL; + struct o2nm_cluster *cluster = o2nm_single_cluster; + + if (cluster == NULL) + goto out; + + read_lock(&cluster->cl_nodes_lock); + node = o2nm_node_ip_tree_lookup(cluster, addr, NULL, NULL); + if (node) + config_item_get(&node->nd_item); + read_unlock(&cluster->cl_nodes_lock); + +out: + return node; +} +EXPORT_SYMBOL_GPL(o2nm_get_node_by_ip); + +void o2nm_node_put(struct o2nm_node *node) +{ + config_item_put(&node->nd_item); +} +EXPORT_SYMBOL_GPL(o2nm_node_put); + +void o2nm_node_get(struct o2nm_node *node) +{ + config_item_get(&node->nd_item); +} +EXPORT_SYMBOL_GPL(o2nm_node_get); + +u8 o2nm_this_node(void) +{ + u8 node_num = O2NM_MAX_NODES; + + if (o2nm_single_cluster && o2nm_single_cluster->cl_has_local) + node_num = o2nm_single_cluster->cl_local_node; + + return node_num; +} +EXPORT_SYMBOL_GPL(o2nm_this_node); + +/* node configfs bits */ + +static struct o2nm_cluster *to_o2nm_cluster(struct config_item *item) +{ + return item ? + container_of(to_config_group(item), struct o2nm_cluster, + cl_group) + : NULL; +} + +static struct o2nm_node *to_o2nm_node(struct config_item *item) +{ + return item ? container_of(item, struct o2nm_node, nd_item) : NULL; +} + +static void o2nm_node_release(struct config_item *item) +{ + struct o2nm_node *node = to_o2nm_node(item); + kfree(node); +} + +static ssize_t o2nm_node_num_read(struct o2nm_node *node, char *page) +{ + return sprintf(page, "%d\n", node->nd_num); +} + +static struct o2nm_cluster *to_o2nm_cluster_from_node(struct o2nm_node *node) +{ + /* through the first node_set .parent + * mycluster/nodes/mynode == o2nm_cluster->o2nm_node_group->o2nm_node */ + return to_o2nm_cluster(node->nd_item.ci_parent->ci_parent); +} + +enum { + O2NM_NODE_ATTR_NUM = 0, + O2NM_NODE_ATTR_PORT, + O2NM_NODE_ATTR_ADDRESS, + O2NM_NODE_ATTR_LOCAL, +}; + +static ssize_t o2nm_node_num_write(struct o2nm_node *node, const char *page, + size_t count) +{ + struct o2nm_cluster *cluster = to_o2nm_cluster_from_node(node); + unsigned long tmp; + char *p = (char *)page; + + tmp = simple_strtoul(p, &p, 0); + if (!p || (*p && (*p != '\n'))) + return -EINVAL; + + if (tmp >= O2NM_MAX_NODES) + return -ERANGE; + + /* once we're in the cl_nodes tree networking can look us up by + * node number and try to use our address and port attributes + * to connect to this node.. make sure that they've been set + * before writing the node attribute? */ + if (!test_bit(O2NM_NODE_ATTR_ADDRESS, &node->nd_set_attributes) || + !test_bit(O2NM_NODE_ATTR_PORT, &node->nd_set_attributes)) + return -EINVAL; /* XXX */ + + write_lock(&cluster->cl_nodes_lock); + if (cluster->cl_nodes[tmp]) + p = NULL; + else { + cluster->cl_nodes[tmp] = node; + node->nd_num = tmp; + set_bit(tmp, cluster->cl_nodes_bitmap); + } + write_unlock(&cluster->cl_nodes_lock); + if (p == NULL) + return -EEXIST; + + return count; +} +static ssize_t o2nm_node_ipv4_port_read(struct o2nm_node *node, char *page) +{ + return sprintf(page, "%u\n", ntohs(node->nd_ipv4_port)); +} + +static ssize_t o2nm_node_ipv4_port_write(struct o2nm_node *node, + const char *page, size_t count) +{ + unsigned long tmp; + char *p = (char *)page; + + tmp = simple_strtoul(p, &p, 0); + if (!p || (*p && (*p != '\n'))) + return -EINVAL; + + if (tmp == 0) + return -EINVAL; + if (tmp >= (u16)-1) + return -ERANGE; + + node->nd_ipv4_port = htons(tmp); + + return count; +} + +static ssize_t o2nm_node_ipv4_address_read(struct o2nm_node *node, char *page) +{ + return sprintf(page, "%pI4\n", &node->nd_ipv4_address); +} + +static ssize_t o2nm_node_ipv4_address_write(struct o2nm_node *node, + const char *page, + size_t count) +{ + struct o2nm_cluster *cluster = to_o2nm_cluster_from_node(node); + int ret, i; + struct rb_node **p, *parent; + unsigned int octets[4]; + __be32 ipv4_addr = 0; + + ret = sscanf(page, "%3u.%3u.%3u.%3u", &octets[3], &octets[2], + &octets[1], &octets[0]); + if (ret != 4) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(octets); i++) { + if (octets[i] > 255) + return -ERANGE; + be32_add_cpu(&ipv4_addr, octets[i] << (i * 8)); + } + + ret = 0; + write_lock(&cluster->cl_nodes_lock); + if (o2nm_node_ip_tree_lookup(cluster, ipv4_addr, &p, &parent)) + ret = -EEXIST; + else { + rb_link_node(&node->nd_ip_node, parent, p); + rb_insert_color(&node->nd_ip_node, &cluster->cl_node_ip_tree); + } + write_unlock(&cluster->cl_nodes_lock); + if (ret) + return ret; + + memcpy(&node->nd_ipv4_address, &ipv4_addr, sizeof(ipv4_addr)); + + return count; +} + +static ssize_t o2nm_node_local_read(struct o2nm_node *node, char *page) +{ + return sprintf(page, "%d\n", node->nd_local); +} + +static ssize_t o2nm_node_local_write(struct o2nm_node *node, const char *page, + size_t count) +{ + struct o2nm_cluster *cluster = to_o2nm_cluster_from_node(node); + unsigned long tmp; + char *p = (char *)page; + ssize_t ret; + + tmp = simple_strtoul(p, &p, 0); + if (!p || (*p && (*p != '\n'))) + return -EINVAL; + + tmp = !!tmp; /* boolean of whether this node wants to be local */ + + /* setting local turns on networking rx for now so we require having + * set everything else first */ + if (!test_bit(O2NM_NODE_ATTR_ADDRESS, &node->nd_set_attributes) || + !test_bit(O2NM_NODE_ATTR_NUM, &node->nd_set_attributes) || + !test_bit(O2NM_NODE_ATTR_PORT, &node->nd_set_attributes)) + return -EINVAL; /* XXX */ + + /* the only failure case is trying to set a new local node + * when a different one is already set */ + if (tmp && tmp == cluster->cl_has_local && + cluster->cl_local_node != node->nd_num) + return -EBUSY; + + /* bring up the rx thread if we're setting the new local node. */ + if (tmp && !cluster->cl_has_local) { + ret = o2net_start_listening(node); + if (ret) + return ret; + } + + if (!tmp && cluster->cl_has_local && + cluster->cl_local_node == node->nd_num) { + o2net_stop_listening(node); + cluster->cl_local_node = O2NM_INVALID_NODE_NUM; + } + + node->nd_local = tmp; + if (node->nd_local) { + cluster->cl_has_local = tmp; + cluster->cl_local_node = node->nd_num; + } + + return count; +} + +struct o2nm_node_attribute { + struct configfs_attribute attr; + ssize_t (*show)(struct o2nm_node *, char *); + ssize_t (*store)(struct o2nm_node *, const char *, size_t); +}; + +static struct o2nm_node_attribute o2nm_node_attr_num = { + .attr = { .ca_owner = THIS_MODULE, + .ca_name = "num", + .ca_mode = S_IRUGO | S_IWUSR }, + .show = o2nm_node_num_read, + .store = o2nm_node_num_write, +}; + +static struct o2nm_node_attribute o2nm_node_attr_ipv4_port = { + .attr = { .ca_owner = THIS_MODULE, + .ca_name = "ipv4_port", + .ca_mode = S_IRUGO | S_IWUSR }, + .show = o2nm_node_ipv4_port_read, + .store = o2nm_node_ipv4_port_write, +}; + +static struct o2nm_node_attribute o2nm_node_attr_ipv4_address = { + .attr = { .ca_owner = THIS_MODULE, + .ca_name = "ipv4_address", + .ca_mode = S_IRUGO | S_IWUSR }, + .show = o2nm_node_ipv4_address_read, + .store = o2nm_node_ipv4_address_write, +}; + +static struct o2nm_node_attribute o2nm_node_attr_local = { + .attr = { .ca_owner = THIS_MODULE, + .ca_name = "local", + .ca_mode = S_IRUGO | S_IWUSR }, + .show = o2nm_node_local_read, + .store = o2nm_node_local_write, +}; + +static struct configfs_attribute *o2nm_node_attrs[] = { + [O2NM_NODE_ATTR_NUM] = &o2nm_node_attr_num.attr, + [O2NM_NODE_ATTR_PORT] = &o2nm_node_attr_ipv4_port.attr, + [O2NM_NODE_ATTR_ADDRESS] = &o2nm_node_attr_ipv4_address.attr, + [O2NM_NODE_ATTR_LOCAL] = &o2nm_node_attr_local.attr, + NULL, +}; + +static int o2nm_attr_index(struct configfs_attribute *attr) +{ + int i; + for (i = 0; i < ARRAY_SIZE(o2nm_node_attrs); i++) { + if (attr == o2nm_node_attrs[i]) + return i; + } + BUG(); + return 0; +} + +static ssize_t o2nm_node_show(struct config_item *item, + struct configfs_attribute *attr, + char *page) +{ + struct o2nm_node *node = to_o2nm_node(item); + struct o2nm_node_attribute *o2nm_node_attr = + container_of(attr, struct o2nm_node_attribute, attr); + ssize_t ret = 0; + + if (o2nm_node_attr->show) + ret = o2nm_node_attr->show(node, page); + return ret; +} + +static ssize_t o2nm_node_store(struct config_item *item, + struct configfs_attribute *attr, + const char *page, size_t count) +{ + struct o2nm_node *node = to_o2nm_node(item); + struct o2nm_node_attribute *o2nm_node_attr = + container_of(attr, struct o2nm_node_attribute, attr); + ssize_t ret; + int attr_index = o2nm_attr_index(attr); + + if (o2nm_node_attr->store == NULL) { + ret = -EINVAL; + goto out; + } + + if (test_bit(attr_index, &node->nd_set_attributes)) + return -EBUSY; + + ret = o2nm_node_attr->store(node, page, count); + if (ret < count) + goto out; + + set_bit(attr_index, &node->nd_set_attributes); +out: + return ret; +} + +static struct configfs_item_operations o2nm_node_item_ops = { + .release = o2nm_node_release, + .show_attribute = o2nm_node_show, + .store_attribute = o2nm_node_store, +}; + +static struct config_item_type o2nm_node_type = { + .ct_item_ops = &o2nm_node_item_ops, + .ct_attrs = o2nm_node_attrs, + .ct_owner = THIS_MODULE, +}; + +/* node set */ + +struct o2nm_node_group { + struct config_group ns_group; + /* some stuff? */ +}; + +#if 0 +static struct o2nm_node_group *to_o2nm_node_group(struct config_group *group) +{ + return group ? + container_of(group, struct o2nm_node_group, ns_group) + : NULL; +} +#endif + +struct o2nm_cluster_attribute { + struct configfs_attribute attr; + ssize_t (*show)(struct o2nm_cluster *, char *); + ssize_t (*store)(struct o2nm_cluster *, const char *, size_t); +}; + +static ssize_t o2nm_cluster_attr_write(const char *page, ssize_t count, + unsigned int *val) +{ + unsigned long tmp; + char *p = (char *)page; + + tmp = simple_strtoul(p, &p, 0); + if (!p || (*p && (*p != '\n'))) + return -EINVAL; + + if (tmp == 0) + return -EINVAL; + if (tmp >= (u32)-1) + return -ERANGE; + + *val = tmp; + + return count; +} + +static ssize_t o2nm_cluster_attr_idle_timeout_ms_read( + struct o2nm_cluster *cluster, char *page) +{ + return sprintf(page, "%u\n", cluster->cl_idle_timeout_ms); +} + +static ssize_t o2nm_cluster_attr_idle_timeout_ms_write( + struct o2nm_cluster *cluster, const char *page, size_t count) +{ + ssize_t ret; + unsigned int val; + + ret = o2nm_cluster_attr_write(page, count, &val); + + if (ret > 0) { + if (cluster->cl_idle_timeout_ms != val + && o2net_num_connected_peers()) { + mlog(ML_NOTICE, + "o2net: cannot change idle timeout after " + "the first peer has agreed to it." + " %d connected peers\n", + o2net_num_connected_peers()); + ret = -EINVAL; + } else if (val <= cluster->cl_keepalive_delay_ms) { + mlog(ML_NOTICE, "o2net: idle timeout must be larger " + "than keepalive delay\n"); + ret = -EINVAL; + } else { + cluster->cl_idle_timeout_ms = val; + } + } + + return ret; +} + +static ssize_t o2nm_cluster_attr_keepalive_delay_ms_read( + struct o2nm_cluster *cluster, char *page) +{ + return sprintf(page, "%u\n", cluster->cl_keepalive_delay_ms); +} + +static ssize_t o2nm_cluster_attr_keepalive_delay_ms_write( + struct o2nm_cluster *cluster, const char *page, size_t count) +{ + ssize_t ret; + unsigned int val; + + ret = o2nm_cluster_attr_write(page, count, &val); + + if (ret > 0) { + if (cluster->cl_keepalive_delay_ms != val + && o2net_num_connected_peers()) { + mlog(ML_NOTICE, + "o2net: cannot change keepalive delay after" + " the first peer has agreed to it." + " %d connected peers\n", + o2net_num_connected_peers()); + ret = -EINVAL; + } else if (val >= cluster->cl_idle_timeout_ms) { + mlog(ML_NOTICE, "o2net: keepalive delay must be " + "smaller than idle timeout\n"); + ret = -EINVAL; + } else { + cluster->cl_keepalive_delay_ms = val; + } + } + + return ret; +} + +static ssize_t o2nm_cluster_attr_reconnect_delay_ms_read( + struct o2nm_cluster *cluster, char *page) +{ + return sprintf(page, "%u\n", cluster->cl_reconnect_delay_ms); +} + +static ssize_t o2nm_cluster_attr_reconnect_delay_ms_write( + struct o2nm_cluster *cluster, const char *page, size_t count) +{ + return o2nm_cluster_attr_write(page, count, + &cluster->cl_reconnect_delay_ms); +} + +static ssize_t o2nm_cluster_attr_fence_method_read( + struct o2nm_cluster *cluster, char *page) +{ + ssize_t ret = 0; + + if (cluster) + ret = sprintf(page, "%s\n", + o2nm_fence_method_desc[cluster->cl_fence_method]); + return ret; +} + +static ssize_t o2nm_cluster_attr_fence_method_write( + struct o2nm_cluster *cluster, const char *page, size_t count) +{ + unsigned int i; + + if (page[count - 1] != '\n') + goto bail; + + for (i = 0; i < O2NM_FENCE_METHODS; ++i) { + if (count != strlen(o2nm_fence_method_desc[i]) + 1) + continue; + if (strncasecmp(page, o2nm_fence_method_desc[i], count - 1)) + continue; + if (cluster->cl_fence_method != i) { + printk(KERN_INFO "ocfs2: Changing fence method to %s\n", + o2nm_fence_method_desc[i]); + cluster->cl_fence_method = i; + } + return count; + } + +bail: + return -EINVAL; +} + +static struct o2nm_cluster_attribute o2nm_cluster_attr_idle_timeout_ms = { + .attr = { .ca_owner = THIS_MODULE, + .ca_name = "idle_timeout_ms", + .ca_mode = S_IRUGO | S_IWUSR }, + .show = o2nm_cluster_attr_idle_timeout_ms_read, + .store = o2nm_cluster_attr_idle_timeout_ms_write, +}; + +static struct o2nm_cluster_attribute o2nm_cluster_attr_keepalive_delay_ms = { + .attr = { .ca_owner = THIS_MODULE, + .ca_name = "keepalive_delay_ms", + .ca_mode = S_IRUGO | S_IWUSR }, + .show = o2nm_cluster_attr_keepalive_delay_ms_read, + .store = o2nm_cluster_attr_keepalive_delay_ms_write, +}; + +static struct o2nm_cluster_attribute o2nm_cluster_attr_reconnect_delay_ms = { + .attr = { .ca_owner = THIS_MODULE, + .ca_name = "reconnect_delay_ms", + .ca_mode = S_IRUGO | S_IWUSR }, + .show = o2nm_cluster_attr_reconnect_delay_ms_read, + .store = o2nm_cluster_attr_reconnect_delay_ms_write, +}; + +static struct o2nm_cluster_attribute o2nm_cluster_attr_fence_method = { + .attr = { .ca_owner = THIS_MODULE, + .ca_name = "fence_method", + .ca_mode = S_IRUGO | S_IWUSR }, + .show = o2nm_cluster_attr_fence_method_read, + .store = o2nm_cluster_attr_fence_method_write, +}; + +static struct configfs_attribute *o2nm_cluster_attrs[] = { + &o2nm_cluster_attr_idle_timeout_ms.attr, + &o2nm_cluster_attr_keepalive_delay_ms.attr, + &o2nm_cluster_attr_reconnect_delay_ms.attr, + &o2nm_cluster_attr_fence_method.attr, + NULL, +}; +static ssize_t o2nm_cluster_show(struct config_item *item, + struct configfs_attribute *attr, + char *page) +{ + struct o2nm_cluster *cluster = to_o2nm_cluster(item); + struct o2nm_cluster_attribute *o2nm_cluster_attr = + container_of(attr, struct o2nm_cluster_attribute, attr); + ssize_t ret = 0; + + if (o2nm_cluster_attr->show) + ret = o2nm_cluster_attr->show(cluster, page); + return ret; +} + +static ssize_t o2nm_cluster_store(struct config_item *item, + struct configfs_attribute *attr, + const char *page, size_t count) +{ + struct o2nm_cluster *cluster = to_o2nm_cluster(item); + struct o2nm_cluster_attribute *o2nm_cluster_attr = + container_of(attr, struct o2nm_cluster_attribute, attr); + ssize_t ret; + + if (o2nm_cluster_attr->store == NULL) { + ret = -EINVAL; + goto out; + } + + ret = o2nm_cluster_attr->store(cluster, page, count); + if (ret < count) + goto out; +out: + return ret; +} + +static struct config_item *o2nm_node_group_make_item(struct config_group *group, + const char *name) +{ + struct o2nm_node *node = NULL; + + if (strlen(name) > O2NM_MAX_NAME_LEN) + return ERR_PTR(-ENAMETOOLONG); + + node = kzalloc(sizeof(struct o2nm_node), GFP_KERNEL); + if (node == NULL) + return ERR_PTR(-ENOMEM); + + strcpy(node->nd_name, name); /* use item.ci_namebuf instead? */ + config_item_init_type_name(&node->nd_item, name, &o2nm_node_type); + spin_lock_init(&node->nd_lock); + + mlog(ML_CLUSTER, "o2nm: Registering node %s\n", name); + + return &node->nd_item; +} + +static void o2nm_node_group_drop_item(struct config_group *group, + struct config_item *item) +{ + struct o2nm_node *node = to_o2nm_node(item); + struct o2nm_cluster *cluster = to_o2nm_cluster(group->cg_item.ci_parent); + + o2net_disconnect_node(node); + + if (cluster->cl_has_local && + (cluster->cl_local_node == node->nd_num)) { + cluster->cl_has_local = 0; + cluster->cl_local_node = O2NM_INVALID_NODE_NUM; + o2net_stop_listening(node); + } + + /* XXX call into net to stop this node from trading messages */ + + write_lock(&cluster->cl_nodes_lock); + + /* XXX sloppy */ + if (node->nd_ipv4_address) + rb_erase(&node->nd_ip_node, &cluster->cl_node_ip_tree); + + /* nd_num might be 0 if the node number hasn't been set.. */ + if (cluster->cl_nodes[node->nd_num] == node) { + cluster->cl_nodes[node->nd_num] = NULL; + clear_bit(node->nd_num, cluster->cl_nodes_bitmap); + } + write_unlock(&cluster->cl_nodes_lock); + + mlog(ML_CLUSTER, "o2nm: Unregistered node %s\n", + config_item_name(&node->nd_item)); + + config_item_put(item); +} + +static struct configfs_group_operations o2nm_node_group_group_ops = { + .make_item = o2nm_node_group_make_item, + .drop_item = o2nm_node_group_drop_item, +}; + +static struct config_item_type o2nm_node_group_type = { + .ct_group_ops = &o2nm_node_group_group_ops, + .ct_owner = THIS_MODULE, +}; + +/* cluster */ + +static void o2nm_cluster_release(struct config_item *item) +{ + struct o2nm_cluster *cluster = to_o2nm_cluster(item); + + kfree(cluster->cl_group.default_groups); + kfree(cluster); +} + +static struct configfs_item_operations o2nm_cluster_item_ops = { + .release = o2nm_cluster_release, + .show_attribute = o2nm_cluster_show, + .store_attribute = o2nm_cluster_store, +}; + +static struct config_item_type o2nm_cluster_type = { + .ct_item_ops = &o2nm_cluster_item_ops, + .ct_attrs = o2nm_cluster_attrs, + .ct_owner = THIS_MODULE, +}; + +/* cluster set */ + +struct o2nm_cluster_group { + struct configfs_subsystem cs_subsys; + /* some stuff? */ +}; + +#if 0 +static struct o2nm_cluster_group *to_o2nm_cluster_group(struct config_group *group) +{ + return group ? + container_of(to_configfs_subsystem(group), struct o2nm_cluster_group, cs_subsys) + : NULL; +} +#endif + +static struct config_group *o2nm_cluster_group_make_group(struct config_group *group, + const char *name) +{ + struct o2nm_cluster *cluster = NULL; + struct o2nm_node_group *ns = NULL; + struct config_group *o2hb_group = NULL, *ret = NULL; + void *defs = NULL; + + /* this runs under the parent dir's i_mutex; there can be only + * one caller in here at a time */ + if (o2nm_single_cluster) + return ERR_PTR(-ENOSPC); + + cluster = kzalloc(sizeof(struct o2nm_cluster), GFP_KERNEL); + ns = kzalloc(sizeof(struct o2nm_node_group), GFP_KERNEL); + defs = kcalloc(3, sizeof(struct config_group *), GFP_KERNEL); + o2hb_group = o2hb_alloc_hb_set(); + if (cluster == NULL || ns == NULL || o2hb_group == NULL || defs == NULL) + goto out; + + config_group_init_type_name(&cluster->cl_group, name, + &o2nm_cluster_type); + config_group_init_type_name(&ns->ns_group, "node", + &o2nm_node_group_type); + + cluster->cl_group.default_groups = defs; + cluster->cl_group.default_groups[0] = &ns->ns_group; + cluster->cl_group.default_groups[1] = o2hb_group; + cluster->cl_group.default_groups[2] = NULL; + rwlock_init(&cluster->cl_nodes_lock); + cluster->cl_node_ip_tree = RB_ROOT; + cluster->cl_reconnect_delay_ms = O2NET_RECONNECT_DELAY_MS_DEFAULT; + cluster->cl_idle_timeout_ms = O2NET_IDLE_TIMEOUT_MS_DEFAULT; + cluster->cl_keepalive_delay_ms = O2NET_KEEPALIVE_DELAY_MS_DEFAULT; + cluster->cl_fence_method = O2NM_FENCE_RESET; + + ret = &cluster->cl_group; + o2nm_single_cluster = cluster; + +out: + if (ret == NULL) { + kfree(cluster); + kfree(ns); + o2hb_free_hb_set(o2hb_group); + kfree(defs); + ret = ERR_PTR(-ENOMEM); + } + + return ret; +} + +static void o2nm_cluster_group_drop_item(struct config_group *group, struct config_item *item) +{ + struct o2nm_cluster *cluster = to_o2nm_cluster(item); + int i; + struct config_item *killme; + + BUG_ON(o2nm_single_cluster != cluster); + o2nm_single_cluster = NULL; + + for (i = 0; cluster->cl_group.default_groups[i]; i++) { + killme = &cluster->cl_group.default_groups[i]->cg_item; + cluster->cl_group.default_groups[i] = NULL; + config_item_put(killme); + } + + config_item_put(item); +} + +static struct configfs_group_operations o2nm_cluster_group_group_ops = { + .make_group = o2nm_cluster_group_make_group, + .drop_item = o2nm_cluster_group_drop_item, +}; + +static struct config_item_type o2nm_cluster_group_type = { + .ct_group_ops = &o2nm_cluster_group_group_ops, + .ct_owner = THIS_MODULE, +}; + +static struct o2nm_cluster_group o2nm_cluster_group = { + .cs_subsys = { + .su_group = { + .cg_item = { + .ci_namebuf = "cluster", + .ci_type = &o2nm_cluster_group_type, + }, + }, + }, +}; + +int o2nm_depend_item(struct config_item *item) +{ + return configfs_depend_item(&o2nm_cluster_group.cs_subsys, item); +} + +void o2nm_undepend_item(struct config_item *item) +{ + configfs_undepend_item(&o2nm_cluster_group.cs_subsys, item); +} + +int o2nm_depend_this_node(void) +{ + int ret = 0; + struct o2nm_node *local_node; + + local_node = o2nm_get_node_by_num(o2nm_this_node()); + if (!local_node) { + ret = -EINVAL; + goto out; + } + + ret = o2nm_depend_item(&local_node->nd_item); + o2nm_node_put(local_node); + +out: + return ret; +} + +void o2nm_undepend_this_node(void) +{ + struct o2nm_node *local_node; + + local_node = o2nm_get_node_by_num(o2nm_this_node()); + BUG_ON(!local_node); + + o2nm_undepend_item(&local_node->nd_item); + o2nm_node_put(local_node); +} + + +static void __exit exit_o2nm(void) +{ + /* XXX sync with hb callbacks and shut down hb? */ + o2net_unregister_hb_callbacks(); + configfs_unregister_subsystem(&o2nm_cluster_group.cs_subsys); + o2cb_sys_shutdown(); + + o2net_exit(); + o2hb_exit(); +} + +static int __init init_o2nm(void) +{ + int ret = -1; + + cluster_print_version(); + + ret = o2hb_init(); + if (ret) + goto out; + + ret = o2net_init(); + if (ret) + goto out_o2hb; + + ret = o2net_register_hb_callbacks(); + if (ret) + goto out_o2net; + + config_group_init(&o2nm_cluster_group.cs_subsys.su_group); + mutex_init(&o2nm_cluster_group.cs_subsys.su_mutex); + ret = configfs_register_subsystem(&o2nm_cluster_group.cs_subsys); + if (ret) { + printk(KERN_ERR "nodemanager: Registration returned %d\n", ret); + goto out_callbacks; + } + + ret = o2cb_sys_init(); + if (!ret) + goto out; + + configfs_unregister_subsystem(&o2nm_cluster_group.cs_subsys); +out_callbacks: + o2net_unregister_hb_callbacks(); +out_o2net: + o2net_exit(); +out_o2hb: + o2hb_exit(); +out: + return ret; +} + +MODULE_AUTHOR("Oracle"); +MODULE_LICENSE("GPL"); + +module_init(init_o2nm) +module_exit(exit_o2nm) diff --git a/drivers/staging/ramster/cluster/nodemanager.h b/drivers/staging/ramster/cluster/nodemanager.h new file mode 100644 index 00000000000..09ea2d388bb --- /dev/null +++ b/drivers/staging/ramster/cluster/nodemanager.h @@ -0,0 +1,88 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * nodemanager.h + * + * Function prototypes + * + * Copyright (C) 2004 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + * + */ + +#ifndef O2CLUSTER_NODEMANAGER_H +#define O2CLUSTER_NODEMANAGER_H + +#include "ocfs2_nodemanager.h" + +/* This totally doesn't belong here. */ +#include +#include + +enum o2nm_fence_method { + O2NM_FENCE_RESET = 0, + O2NM_FENCE_PANIC, + O2NM_FENCE_METHODS, /* Number of fence methods */ +}; + +struct o2nm_node { + spinlock_t nd_lock; + struct config_item nd_item; + char nd_name[O2NM_MAX_NAME_LEN+1]; /* replace? */ + __u8 nd_num; + /* only one address per node, as attributes, for now. */ + __be32 nd_ipv4_address; + __be16 nd_ipv4_port; + struct rb_node nd_ip_node; + /* there can be only one local node for now */ + int nd_local; + + unsigned long nd_set_attributes; +}; + +struct o2nm_cluster { + struct config_group cl_group; + unsigned cl_has_local:1; + u8 cl_local_node; + rwlock_t cl_nodes_lock; + struct o2nm_node *cl_nodes[O2NM_MAX_NODES]; + struct rb_root cl_node_ip_tree; + unsigned int cl_idle_timeout_ms; + unsigned int cl_keepalive_delay_ms; + unsigned int cl_reconnect_delay_ms; + enum o2nm_fence_method cl_fence_method; + + /* this bitmap is part of a hack for disk bitmap.. will go eventually. - zab */ + unsigned long cl_nodes_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)]; +}; + +extern struct o2nm_cluster *o2nm_single_cluster; + +u8 o2nm_this_node(void); + +int o2nm_configured_node_map(unsigned long *map, unsigned bytes); +struct o2nm_node *o2nm_get_node_by_num(u8 node_num); +struct o2nm_node *o2nm_get_node_by_ip(__be32 addr); +void o2nm_node_get(struct o2nm_node *node); +void o2nm_node_put(struct o2nm_node *node); + +int o2nm_depend_item(struct config_item *item); +void o2nm_undepend_item(struct config_item *item); +int o2nm_depend_this_node(void); +void o2nm_undepend_this_node(void); + +#endif /* O2CLUSTER_NODEMANAGER_H */ diff --git a/drivers/staging/ramster/cluster/ocfs2_heartbeat.h b/drivers/staging/ramster/cluster/ocfs2_heartbeat.h new file mode 100644 index 00000000000..3f4151da970 --- /dev/null +++ b/drivers/staging/ramster/cluster/ocfs2_heartbeat.h @@ -0,0 +1,38 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * ocfs2_heartbeat.h + * + * On-disk structures for ocfs2_heartbeat + * + * Copyright (C) 2002, 2004 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ + +#ifndef _OCFS2_HEARTBEAT_H +#define _OCFS2_HEARTBEAT_H + +struct o2hb_disk_heartbeat_block { + __le64 hb_seq; + __u8 hb_node; + __u8 hb_pad1[3]; + __le32 hb_cksum; + __le64 hb_generation; + __le32 hb_dead_ms; +}; + +#endif /* _OCFS2_HEARTBEAT_H */ diff --git a/drivers/staging/ramster/cluster/ocfs2_nodemanager.h b/drivers/staging/ramster/cluster/ocfs2_nodemanager.h new file mode 100644 index 00000000000..49b594325be --- /dev/null +++ b/drivers/staging/ramster/cluster/ocfs2_nodemanager.h @@ -0,0 +1,45 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * ocfs2_nodemanager.h + * + * Header describing the interface between userspace and the kernel + * for the ocfs2_nodemanager module. + * + * Copyright (C) 2002, 2004 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + * + */ + +#ifndef _OCFS2_NODEMANAGER_H +#define _OCFS2_NODEMANAGER_H + +#define O2NM_API_VERSION 5 + +#define O2NM_MAX_NODES 255 +#define O2NM_INVALID_NODE_NUM 255 + +/* host name, group name, cluster name all 64 bytes */ +#define O2NM_MAX_NAME_LEN 64 // __NEW_UTS_LEN + +/* + * Maximum number of global heartbeat regions allowed. + * **CAUTION** Changing this number will break dlm compatibility. + */ +#define O2NM_MAX_REGIONS 32 + +#endif /* _OCFS2_NODEMANAGER_H */ diff --git a/drivers/staging/ramster/cluster/quorum.c b/drivers/staging/ramster/cluster/quorum.c new file mode 100644 index 00000000000..8f9cea1597a --- /dev/null +++ b/drivers/staging/ramster/cluster/quorum.c @@ -0,0 +1,331 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * Copyright (C) 2005 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ + +/* This quorum hack is only here until we transition to some more rational + * approach that is driven from userspace. Honest. No foolin'. + * + * Imagine two nodes lose network connectivity to each other but they're still + * up and operating in every other way. Presumably a network timeout indicates + * that a node is broken and should be recovered. They can't both recover each + * other and both carry on without serialising their access to the file system. + * They need to decide who is authoritative. Now extend that problem to + * arbitrary groups of nodes losing connectivity between each other. + * + * So we declare that a node which has given up on connecting to a majority + * of nodes who are still heartbeating will fence itself. + * + * There are huge opportunities for races here. After we give up on a node's + * connection we need to wait long enough to give heartbeat an opportunity + * to declare the node as truly dead. We also need to be careful with the + * race between when we see a node start heartbeating and when we connect + * to it. + * + * So nodes that are in this transtion put a hold on the quorum decision + * with a counter. As they fall out of this transition they drop the count + * and if they're the last, they fire off the decision. + */ +#include +#include +#include + +#include "heartbeat.h" +#include "nodemanager.h" +#define MLOG_MASK_PREFIX ML_QUORUM +#include "masklog.h" +#include "quorum.h" + +static struct o2quo_state { + spinlock_t qs_lock; + struct work_struct qs_work; + int qs_pending; + int qs_heartbeating; + unsigned long qs_hb_bm[BITS_TO_LONGS(O2NM_MAX_NODES)]; + int qs_connected; + unsigned long qs_conn_bm[BITS_TO_LONGS(O2NM_MAX_NODES)]; + int qs_holds; + unsigned long qs_hold_bm[BITS_TO_LONGS(O2NM_MAX_NODES)]; +} o2quo_state; + +/* this is horribly heavy-handed. It should instead flip the file + * system RO and call some userspace script. */ +static void o2quo_fence_self(void) +{ + /* panic spins with interrupts enabled. with preempt + * threads can still schedule, etc, etc */ + o2hb_stop_all_regions(); + + switch (o2nm_single_cluster->cl_fence_method) { + case O2NM_FENCE_PANIC: + panic("*** ocfs2 is very sorry to be fencing this system by " + "panicing ***\n"); + break; + default: + WARN_ON(o2nm_single_cluster->cl_fence_method >= + O2NM_FENCE_METHODS); + case O2NM_FENCE_RESET: + printk(KERN_ERR "*** ocfs2 is very sorry to be fencing this " + "system by restarting ***\n"); + emergency_restart(); + break; + }; +} + +/* Indicate that a timeout occurred on a hearbeat region write. The + * other nodes in the cluster may consider us dead at that time so we + * want to "fence" ourselves so that we don't scribble on the disk + * after they think they've recovered us. This can't solve all + * problems related to writeout after recovery but this hack can at + * least close some of those gaps. When we have real fencing, this can + * go away as our node would be fenced externally before other nodes + * begin recovery. */ +void o2quo_disk_timeout(void) +{ + o2quo_fence_self(); +} + +static void o2quo_make_decision(struct work_struct *work) +{ + int quorum; + int lowest_hb, lowest_reachable = 0, fence = 0; + struct o2quo_state *qs = &o2quo_state; + + spin_lock(&qs->qs_lock); + + lowest_hb = find_first_bit(qs->qs_hb_bm, O2NM_MAX_NODES); + if (lowest_hb != O2NM_MAX_NODES) + lowest_reachable = test_bit(lowest_hb, qs->qs_conn_bm); + + mlog(0, "heartbeating: %d, connected: %d, " + "lowest: %d (%sreachable)\n", qs->qs_heartbeating, + qs->qs_connected, lowest_hb, lowest_reachable ? "" : "un"); + + if (!test_bit(o2nm_this_node(), qs->qs_hb_bm) || + qs->qs_heartbeating == 1) + goto out; + + if (qs->qs_heartbeating & 1) { + /* the odd numbered cluster case is straight forward -- + * if we can't talk to the majority we're hosed */ + quorum = (qs->qs_heartbeating + 1)/2; + if (qs->qs_connected < quorum) { + mlog(ML_ERROR, "fencing this node because it is " + "only connected to %u nodes and %u is needed " + "to make a quorum out of %u heartbeating nodes\n", + qs->qs_connected, quorum, + qs->qs_heartbeating); + fence = 1; + } + } else { + /* the even numbered cluster adds the possibility of each half + * of the cluster being able to talk amongst themselves.. in + * that case we're hosed if we can't talk to the group that has + * the lowest numbered node */ + quorum = qs->qs_heartbeating / 2; + if (qs->qs_connected < quorum) { + mlog(ML_ERROR, "fencing this node because it is " + "only connected to %u nodes and %u is needed " + "to make a quorum out of %u heartbeating nodes\n", + qs->qs_connected, quorum, + qs->qs_heartbeating); + fence = 1; + } + else if ((qs->qs_connected == quorum) && + !lowest_reachable) { + mlog(ML_ERROR, "fencing this node because it is " + "connected to a half-quorum of %u out of %u " + "nodes which doesn't include the lowest active " + "node %u\n", quorum, qs->qs_heartbeating, + lowest_hb); + fence = 1; + } + } + +out: + spin_unlock(&qs->qs_lock); + if (fence) + o2quo_fence_self(); +} + +static void o2quo_set_hold(struct o2quo_state *qs, u8 node) +{ + assert_spin_locked(&qs->qs_lock); + + if (!test_and_set_bit(node, qs->qs_hold_bm)) { + qs->qs_holds++; + mlog_bug_on_msg(qs->qs_holds == O2NM_MAX_NODES, + "node %u\n", node); + mlog(0, "node %u, %d total\n", node, qs->qs_holds); + } +} + +static void o2quo_clear_hold(struct o2quo_state *qs, u8 node) +{ + assert_spin_locked(&qs->qs_lock); + + if (test_and_clear_bit(node, qs->qs_hold_bm)) { + mlog(0, "node %u, %d total\n", node, qs->qs_holds - 1); + if (--qs->qs_holds == 0) { + if (qs->qs_pending) { + qs->qs_pending = 0; + schedule_work(&qs->qs_work); + } + } + mlog_bug_on_msg(qs->qs_holds < 0, "node %u, holds %d\n", + node, qs->qs_holds); + } +} + +/* as a node comes up we delay the quorum decision until we know the fate of + * the connection. the hold will be droped in conn_up or hb_down. it might be + * perpetuated by con_err until hb_down. if we already have a conn, we might + * be dropping a hold that conn_up got. */ +void o2quo_hb_up(u8 node) +{ + struct o2quo_state *qs = &o2quo_state; + + spin_lock(&qs->qs_lock); + + qs->qs_heartbeating++; + mlog_bug_on_msg(qs->qs_heartbeating == O2NM_MAX_NODES, + "node %u\n", node); + mlog_bug_on_msg(test_bit(node, qs->qs_hb_bm), "node %u\n", node); + set_bit(node, qs->qs_hb_bm); + + mlog(0, "node %u, %d total\n", node, qs->qs_heartbeating); + + if (!test_bit(node, qs->qs_conn_bm)) + o2quo_set_hold(qs, node); + else + o2quo_clear_hold(qs, node); + + spin_unlock(&qs->qs_lock); +} + +/* hb going down releases any holds we might have had due to this node from + * conn_up, conn_err, or hb_up */ +void o2quo_hb_down(u8 node) +{ + struct o2quo_state *qs = &o2quo_state; + + spin_lock(&qs->qs_lock); + + qs->qs_heartbeating--; + mlog_bug_on_msg(qs->qs_heartbeating < 0, + "node %u, %d heartbeating\n", + node, qs->qs_heartbeating); + mlog_bug_on_msg(!test_bit(node, qs->qs_hb_bm), "node %u\n", node); + clear_bit(node, qs->qs_hb_bm); + + mlog(0, "node %u, %d total\n", node, qs->qs_heartbeating); + + o2quo_clear_hold(qs, node); + + spin_unlock(&qs->qs_lock); +} + +/* this tells us that we've decided that the node is still heartbeating + * even though we've lost it's conn. it must only be called after conn_err + * and indicates that we must now make a quorum decision in the future, + * though we might be doing so after waiting for holds to drain. Here + * we'll be dropping the hold from conn_err. */ +void o2quo_hb_still_up(u8 node) +{ + struct o2quo_state *qs = &o2quo_state; + + spin_lock(&qs->qs_lock); + + mlog(0, "node %u\n", node); + + qs->qs_pending = 1; + o2quo_clear_hold(qs, node); + + spin_unlock(&qs->qs_lock); +} + +/* This is analogous to hb_up. as a node's connection comes up we delay the + * quorum decision until we see it heartbeating. the hold will be droped in + * hb_up or hb_down. it might be perpetuated by con_err until hb_down. if + * it's already heartbeating we we might be dropping a hold that conn_up got. + * */ +void o2quo_conn_up(u8 node) +{ + struct o2quo_state *qs = &o2quo_state; + + spin_lock(&qs->qs_lock); + + qs->qs_connected++; + mlog_bug_on_msg(qs->qs_connected == O2NM_MAX_NODES, + "node %u\n", node); + mlog_bug_on_msg(test_bit(node, qs->qs_conn_bm), "node %u\n", node); + set_bit(node, qs->qs_conn_bm); + + mlog(0, "node %u, %d total\n", node, qs->qs_connected); + + if (!test_bit(node, qs->qs_hb_bm)) + o2quo_set_hold(qs, node); + else + o2quo_clear_hold(qs, node); + + spin_unlock(&qs->qs_lock); +} + +/* we've decided that we won't ever be connecting to the node again. if it's + * still heartbeating we grab a hold that will delay decisions until either the + * node stops heartbeating from hb_down or the caller decides that the node is + * still up and calls still_up */ +void o2quo_conn_err(u8 node) +{ + struct o2quo_state *qs = &o2quo_state; + + spin_lock(&qs->qs_lock); + + if (test_bit(node, qs->qs_conn_bm)) { + qs->qs_connected--; + mlog_bug_on_msg(qs->qs_connected < 0, + "node %u, connected %d\n", + node, qs->qs_connected); + + clear_bit(node, qs->qs_conn_bm); + } + + mlog(0, "node %u, %d total\n", node, qs->qs_connected); + + if (test_bit(node, qs->qs_hb_bm)) + o2quo_set_hold(qs, node); + + spin_unlock(&qs->qs_lock); +} + +void o2quo_init(void) +{ + struct o2quo_state *qs = &o2quo_state; + + spin_lock_init(&qs->qs_lock); + INIT_WORK(&qs->qs_work, o2quo_make_decision); +} + +void o2quo_exit(void) +{ + struct o2quo_state *qs = &o2quo_state; + + flush_work_sync(&qs->qs_work); +} diff --git a/drivers/staging/ramster/cluster/quorum.h b/drivers/staging/ramster/cluster/quorum.h new file mode 100644 index 00000000000..6649cc6f67c --- /dev/null +++ b/drivers/staging/ramster/cluster/quorum.h @@ -0,0 +1,36 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * Copyright (C) 2005 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + * + */ + +#ifndef O2CLUSTER_QUORUM_H +#define O2CLUSTER_QUORUM_H + +void o2quo_init(void); +void o2quo_exit(void); + +void o2quo_hb_up(u8 node); +void o2quo_hb_down(u8 node); +void o2quo_hb_still_up(u8 node); +void o2quo_conn_up(u8 node); +void o2quo_conn_err(u8 node); +void o2quo_disk_timeout(void); + +#endif /* O2CLUSTER_QUORUM_H */ diff --git a/drivers/staging/ramster/cluster/sys.c b/drivers/staging/ramster/cluster/sys.c new file mode 100644 index 00000000000..a4b07730b2e --- /dev/null +++ b/drivers/staging/ramster/cluster/sys.c @@ -0,0 +1,82 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * sys.c + * + * OCFS2 cluster sysfs interface + * + * Copyright (C) 2005 Oracle. 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, + * version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + * + */ + +#include +#include +#include +#include +#include + +#include "ocfs2_nodemanager.h" +#include "masklog.h" +#include "sys.h" + + +static ssize_t version_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%u\n", O2NM_API_VERSION); +} +static struct kobj_attribute attr_version = + __ATTR(interface_revision, S_IFREG | S_IRUGO, version_show, NULL); + +static struct attribute *o2cb_attrs[] = { + &attr_version.attr, + NULL, +}; + +static struct attribute_group o2cb_attr_group = { + .attrs = o2cb_attrs, +}; + +static struct kset *o2cb_kset; + +void o2cb_sys_shutdown(void) +{ + mlog_sys_shutdown(); + kset_unregister(o2cb_kset); +} + +int o2cb_sys_init(void) +{ + int ret; + + o2cb_kset = kset_create_and_add("o2cb", NULL, fs_kobj); + if (!o2cb_kset) + return -ENOMEM; + + ret = sysfs_create_group(&o2cb_kset->kobj, &o2cb_attr_group); + if (ret) + goto error; + + ret = mlog_sys_init(o2cb_kset); + if (ret) + goto error; + return 0; +error: + kset_unregister(o2cb_kset); + return ret; +} diff --git a/drivers/staging/ramster/cluster/sys.h b/drivers/staging/ramster/cluster/sys.h new file mode 100644 index 00000000000..d66b8ab0045 --- /dev/null +++ b/drivers/staging/ramster/cluster/sys.h @@ -0,0 +1,33 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * sys.h + * + * Function prototypes for o2cb sysfs interface + * + * Copyright (C) 2005 Oracle. 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, + * version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + * + */ + +#ifndef O2CLUSTER_SYS_H +#define O2CLUSTER_SYS_H + +void o2cb_sys_shutdown(void); +int o2cb_sys_init(void); + +#endif /* O2CLUSTER_SYS_H */ diff --git a/drivers/staging/ramster/cluster/tcp.c b/drivers/staging/ramster/cluster/tcp.c new file mode 100644 index 00000000000..044e7b58d31 --- /dev/null +++ b/drivers/staging/ramster/cluster/tcp.c @@ -0,0 +1,2150 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * Copyright (C) 2004 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + * + * ---- + * + * Callers for this were originally written against a very simple synchronus + * API. This implementation reflects those simple callers. Some day I'm sure + * we'll need to move to a more robust posting/callback mechanism. + * + * Transmit calls pass in kernel virtual addresses and block copying this into + * the socket's tx buffers via a usual blocking sendmsg. They'll block waiting + * for a failed socket to timeout. TX callers can also pass in a poniter to an + * 'int' which gets filled with an errno off the wire in response to the + * message they send. + * + * Handlers for unsolicited messages are registered. Each socket has a page + * that incoming data is copied into. First the header, then the data. + * Handlers are called from only one thread with a reference to this per-socket + * page. This page is destroyed after the handler call, so it can't be + * referenced beyond the call. Handlers may block but are discouraged from + * doing so. + * + * Any framing errors (bad magic, large payload lengths) close a connection. + * + * Our sock_container holds the state we associate with a socket. It's current + * framing state is held there as well as the refcounting we do around when it + * is safe to tear down the socket. The socket is only finally torn down from + * the container when the container loses all of its references -- so as long + * as you hold a ref on the container you can trust that the socket is valid + * for use with kernel socket APIs. + * + * Connections are initiated between a pair of nodes when the node with the + * higher node number gets a heartbeat callback which indicates that the lower + * numbered node has started heartbeating. The lower numbered node is passive + * and only accepts the connection if the higher numbered node is heartbeating. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "heartbeat.h" +#include "tcp.h" +#include "nodemanager.h" +#define MLOG_MASK_PREFIX ML_TCP +#include "masklog.h" +#include "quorum.h" + +#include "tcp_internal.h" + +#define SC_NODEF_FMT "node %s (num %u) at %pI4:%u" +#define SC_NODEF_ARGS(sc) sc->sc_node->nd_name, sc->sc_node->nd_num, \ + &sc->sc_node->nd_ipv4_address, \ + ntohs(sc->sc_node->nd_ipv4_port) + +/* + * In the following two log macros, the whitespace after the ',' just + * before ##args is intentional. Otherwise, gcc 2.95 will eat the + * previous token if args expands to nothing. + */ +#define msglog(hdr, fmt, args...) do { \ + typeof(hdr) __hdr = (hdr); \ + mlog(ML_MSG, "[mag %u len %u typ %u stat %d sys_stat %d " \ + "key %08x num %u] " fmt, \ + be16_to_cpu(__hdr->magic), be16_to_cpu(__hdr->data_len), \ + be16_to_cpu(__hdr->msg_type), be32_to_cpu(__hdr->status), \ + be32_to_cpu(__hdr->sys_status), be32_to_cpu(__hdr->key), \ + be32_to_cpu(__hdr->msg_num) , ##args); \ +} while (0) + +#define sclog(sc, fmt, args...) do { \ + typeof(sc) __sc = (sc); \ + mlog(ML_SOCKET, "[sc %p refs %d sock %p node %u page %p " \ + "pg_off %zu] " fmt, __sc, \ + atomic_read(&__sc->sc_kref.refcount), __sc->sc_sock, \ + __sc->sc_node->nd_num, __sc->sc_page, __sc->sc_page_off , \ + ##args); \ +} while (0) + +static DEFINE_RWLOCK(o2net_handler_lock); +static struct rb_root o2net_handler_tree = RB_ROOT; + +static struct o2net_node o2net_nodes[O2NM_MAX_NODES]; + +/* XXX someday we'll need better accounting */ +static struct socket *o2net_listen_sock = NULL; + +/* + * listen work is only queued by the listening socket callbacks on the + * o2net_wq. teardown detaches the callbacks before destroying the workqueue. + * quorum work is queued as sock containers are shutdown.. stop_listening + * tears down all the node's sock containers, preventing future shutdowns + * and queued quroum work, before canceling delayed quorum work and + * destroying the work queue. + */ +static struct workqueue_struct *o2net_wq; +static struct work_struct o2net_listen_work; + +static struct o2hb_callback_func o2net_hb_up, o2net_hb_down; +#define O2NET_HB_PRI 0x1 + +static struct o2net_handshake *o2net_hand; +static struct o2net_msg *o2net_keep_req, *o2net_keep_resp; + +static int o2net_sys_err_translations[O2NET_ERR_MAX] = + {[O2NET_ERR_NONE] = 0, + [O2NET_ERR_NO_HNDLR] = -ENOPROTOOPT, + [O2NET_ERR_OVERFLOW] = -EOVERFLOW, + [O2NET_ERR_DIED] = -EHOSTDOWN,}; + +/* can't quite avoid *all* internal declarations :/ */ +static void o2net_sc_connect_completed(struct work_struct *work); +static void o2net_rx_until_empty(struct work_struct *work); +static void o2net_shutdown_sc(struct work_struct *work); +static void o2net_listen_data_ready(struct sock *sk, int bytes); +static void o2net_sc_send_keep_req(struct work_struct *work); +static void o2net_idle_timer(unsigned long data); +static void o2net_sc_postpone_idle(struct o2net_sock_container *sc); +static void o2net_sc_reset_idle_timer(struct o2net_sock_container *sc); + +#ifdef CONFIG_DEBUG_FS +static void o2net_init_nst(struct o2net_send_tracking *nst, u32 msgtype, + u32 msgkey, struct task_struct *task, u8 node) +{ + INIT_LIST_HEAD(&nst->st_net_debug_item); + nst->st_task = task; + nst->st_msg_type = msgtype; + nst->st_msg_key = msgkey; + nst->st_node = node; +} + +static inline void o2net_set_nst_sock_time(struct o2net_send_tracking *nst) +{ + nst->st_sock_time = ktime_get(); +} + +static inline void o2net_set_nst_send_time(struct o2net_send_tracking *nst) +{ + nst->st_send_time = ktime_get(); +} + +static inline void o2net_set_nst_status_time(struct o2net_send_tracking *nst) +{ + nst->st_status_time = ktime_get(); +} + +static inline void o2net_set_nst_sock_container(struct o2net_send_tracking *nst, + struct o2net_sock_container *sc) +{ + nst->st_sc = sc; +} + +static inline void o2net_set_nst_msg_id(struct o2net_send_tracking *nst, + u32 msg_id) +{ + nst->st_id = msg_id; +} + +static inline void o2net_set_sock_timer(struct o2net_sock_container *sc) +{ + sc->sc_tv_timer = ktime_get(); +} + +static inline void o2net_set_data_ready_time(struct o2net_sock_container *sc) +{ + sc->sc_tv_data_ready = ktime_get(); +} + +static inline void o2net_set_advance_start_time(struct o2net_sock_container *sc) +{ + sc->sc_tv_advance_start = ktime_get(); +} + +static inline void o2net_set_advance_stop_time(struct o2net_sock_container *sc) +{ + sc->sc_tv_advance_stop = ktime_get(); +} + +static inline void o2net_set_func_start_time(struct o2net_sock_container *sc) +{ + sc->sc_tv_func_start = ktime_get(); +} + +static inline void o2net_set_func_stop_time(struct o2net_sock_container *sc) +{ + sc->sc_tv_func_stop = ktime_get(); +} + +#else /* CONFIG_DEBUG_FS */ +# define o2net_init_nst(a, b, c, d, e) +# define o2net_set_nst_sock_time(a) +# define o2net_set_nst_send_time(a) +# define o2net_set_nst_status_time(a) +# define o2net_set_nst_sock_container(a, b) +# define o2net_set_nst_msg_id(a, b) +# define o2net_set_sock_timer(a) +# define o2net_set_data_ready_time(a) +# define o2net_set_advance_start_time(a) +# define o2net_set_advance_stop_time(a) +# define o2net_set_func_start_time(a) +# define o2net_set_func_stop_time(a) +#endif /* CONFIG_DEBUG_FS */ + +#ifdef CONFIG_OCFS2_FS_STATS +static ktime_t o2net_get_func_run_time(struct o2net_sock_container *sc) +{ + return ktime_sub(sc->sc_tv_func_stop, sc->sc_tv_func_start); +} + +static void o2net_update_send_stats(struct o2net_send_tracking *nst, + struct o2net_sock_container *sc) +{ + sc->sc_tv_status_total = ktime_add(sc->sc_tv_status_total, + ktime_sub(ktime_get(), + nst->st_status_time)); + sc->sc_tv_send_total = ktime_add(sc->sc_tv_send_total, + ktime_sub(nst->st_status_time, + nst->st_send_time)); + sc->sc_tv_acquiry_total = ktime_add(sc->sc_tv_acquiry_total, + ktime_sub(nst->st_send_time, + nst->st_sock_time)); + sc->sc_send_count++; +} + +static void o2net_update_recv_stats(struct o2net_sock_container *sc) +{ + sc->sc_tv_process_total = ktime_add(sc->sc_tv_process_total, + o2net_get_func_run_time(sc)); + sc->sc_recv_count++; +} + +#else + +# define o2net_update_send_stats(a, b) + +# define o2net_update_recv_stats(sc) + +#endif /* CONFIG_OCFS2_FS_STATS */ + +static inline int o2net_reconnect_delay(void) +{ + return o2nm_single_cluster->cl_reconnect_delay_ms; +} + +static inline int o2net_keepalive_delay(void) +{ + return o2nm_single_cluster->cl_keepalive_delay_ms; +} + +static inline int o2net_idle_timeout(void) +{ + return o2nm_single_cluster->cl_idle_timeout_ms; +} + +static inline int o2net_sys_err_to_errno(enum o2net_system_error err) +{ + int trans; + BUG_ON(err >= O2NET_ERR_MAX); + trans = o2net_sys_err_translations[err]; + + /* Just in case we mess up the translation table above */ + BUG_ON(err != O2NET_ERR_NONE && trans == 0); + return trans; +} + +static struct o2net_node * o2net_nn_from_num(u8 node_num) +{ + BUG_ON(node_num >= ARRAY_SIZE(o2net_nodes)); + return &o2net_nodes[node_num]; +} + +static u8 o2net_num_from_nn(struct o2net_node *nn) +{ + BUG_ON(nn == NULL); + return nn - o2net_nodes; +} + +/* ------------------------------------------------------------ */ + +static int o2net_prep_nsw(struct o2net_node *nn, struct o2net_status_wait *nsw) +{ + int ret = 0; + + 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); + + if (ret == 0) { + init_waitqueue_head(&nsw->ns_wq); + nsw->ns_sys_status = O2NET_ERR_NONE; + nsw->ns_status = 0; + } + + return ret; +} + +static void o2net_complete_nsw_locked(struct o2net_node *nn, + struct o2net_status_wait *nsw, + enum o2net_system_error sys_status, + s32 status) +{ + assert_spin_locked(&nn->nn_lock); + + if (!list_empty(&nsw->ns_node_item)) { + list_del_init(&nsw->ns_node_item); + nsw->ns_sys_status = sys_status; + nsw->ns_status = status; + idr_remove(&nn->nn_status_idr, nsw->ns_id); + wake_up(&nsw->ns_wq); + } +} + +static void o2net_complete_nsw(struct o2net_node *nn, + struct o2net_status_wait *nsw, + u64 id, enum o2net_system_error sys_status, + s32 status) +{ + spin_lock(&nn->nn_lock); + if (nsw == NULL) { + if (id > INT_MAX) + goto out; + + nsw = idr_find(&nn->nn_status_idr, id); + if (nsw == NULL) + goto out; + } + + o2net_complete_nsw_locked(nn, nsw, sys_status, status); + +out: + spin_unlock(&nn->nn_lock); + return; +} + +static void o2net_complete_nodes_nsw(struct o2net_node *nn) +{ + struct o2net_status_wait *nsw, *tmp; + unsigned int num_kills = 0; + + assert_spin_locked(&nn->nn_lock); + + list_for_each_entry_safe(nsw, tmp, &nn->nn_status_list, ns_node_item) { + o2net_complete_nsw_locked(nn, nsw, O2NET_ERR_DIED, 0); + num_kills++; + } + + mlog(0, "completed %d messages for node %u\n", num_kills, + o2net_num_from_nn(nn)); +} + +static int o2net_nsw_completed(struct o2net_node *nn, + struct o2net_status_wait *nsw) +{ + int completed; + spin_lock(&nn->nn_lock); + completed = list_empty(&nsw->ns_node_item); + spin_unlock(&nn->nn_lock); + return completed; +} + +/* ------------------------------------------------------------ */ + +static void sc_kref_release(struct kref *kref) +{ + struct o2net_sock_container *sc = container_of(kref, + struct o2net_sock_container, sc_kref); + BUG_ON(timer_pending(&sc->sc_idle_timeout)); + + sclog(sc, "releasing\n"); + + if (sc->sc_sock) { + sock_release(sc->sc_sock); + sc->sc_sock = NULL; + } + + o2nm_undepend_item(&sc->sc_node->nd_item); + o2nm_node_put(sc->sc_node); + sc->sc_node = NULL; + + o2net_debug_del_sc(sc); + kfree(sc); +} + +static void sc_put(struct o2net_sock_container *sc) +{ + sclog(sc, "put\n"); + kref_put(&sc->sc_kref, sc_kref_release); +} +static void sc_get(struct o2net_sock_container *sc) +{ + sclog(sc, "get\n"); + kref_get(&sc->sc_kref); +} +static struct o2net_sock_container *sc_alloc(struct o2nm_node *node) +{ + struct o2net_sock_container *sc, *ret = NULL; + struct page *page = NULL; + int status = 0; + + page = alloc_page(GFP_NOFS); + sc = kzalloc(sizeof(*sc), GFP_NOFS); + if (sc == NULL || page == NULL) + goto out; + + kref_init(&sc->sc_kref); + o2nm_node_get(node); + sc->sc_node = node; + + /* pin the node item of the remote node */ + status = o2nm_depend_item(&node->nd_item); + if (status) { + mlog_errno(status); + o2nm_node_put(node); + goto out; + } + INIT_WORK(&sc->sc_connect_work, o2net_sc_connect_completed); + INIT_WORK(&sc->sc_rx_work, o2net_rx_until_empty); + INIT_WORK(&sc->sc_shutdown_work, o2net_shutdown_sc); + INIT_DELAYED_WORK(&sc->sc_keepalive_work, o2net_sc_send_keep_req); + + init_timer(&sc->sc_idle_timeout); + sc->sc_idle_timeout.function = o2net_idle_timer; + sc->sc_idle_timeout.data = (unsigned long)sc; + + sclog(sc, "alloced\n"); + + ret = sc; + sc->sc_page = page; + o2net_debug_add_sc(sc); + sc = NULL; + page = NULL; + +out: + if (page) + __free_page(page); + kfree(sc); + + return ret; +} + +/* ------------------------------------------------------------ */ + +static void o2net_sc_queue_work(struct o2net_sock_container *sc, + struct work_struct *work) +{ + sc_get(sc); + if (!queue_work(o2net_wq, work)) + sc_put(sc); +} +static void o2net_sc_queue_delayed_work(struct o2net_sock_container *sc, + struct delayed_work *work, + int delay) +{ + sc_get(sc); + if (!queue_delayed_work(o2net_wq, work, delay)) + sc_put(sc); +} +static void o2net_sc_cancel_delayed_work(struct o2net_sock_container *sc, + struct delayed_work *work) +{ + if (cancel_delayed_work(work)) + sc_put(sc); +} + +static atomic_t o2net_connected_peers = ATOMIC_INIT(0); + +int o2net_num_connected_peers(void) +{ + return atomic_read(&o2net_connected_peers); +} + +static void o2net_set_nn_state(struct o2net_node *nn, + struct o2net_sock_container *sc, + unsigned valid, int err) +{ + int was_valid = nn->nn_sc_valid; + int was_err = nn->nn_persistent_error; + struct o2net_sock_container *old_sc = nn->nn_sc; + + assert_spin_locked(&nn->nn_lock); + + if (old_sc && !sc) + atomic_dec(&o2net_connected_peers); + else if (!old_sc && sc) + atomic_inc(&o2net_connected_peers); + + /* the node num comparison and single connect/accept path should stop + * an non-null sc from being overwritten with another */ + BUG_ON(sc && nn->nn_sc && nn->nn_sc != sc); + mlog_bug_on_msg(err && valid, "err %d valid %u\n", err, valid); + mlog_bug_on_msg(valid && !sc, "valid %u sc %p\n", valid, sc); + + if (was_valid && !valid && err == 0) + err = -ENOTCONN; + + mlog(ML_CONN, "node %u sc: %p -> %p, valid %u -> %u, err %d -> %d\n", + o2net_num_from_nn(nn), nn->nn_sc, sc, nn->nn_sc_valid, valid, + nn->nn_persistent_error, err); + + nn->nn_sc = sc; + nn->nn_sc_valid = valid ? 1 : 0; + nn->nn_persistent_error = err; + + /* mirrors o2net_tx_can_proceed() */ + if (nn->nn_persistent_error || nn->nn_sc_valid) + wake_up(&nn->nn_sc_wq); + + if (!was_err && nn->nn_persistent_error) { + o2quo_conn_err(o2net_num_from_nn(nn)); + queue_delayed_work(o2net_wq, &nn->nn_still_up, + msecs_to_jiffies(O2NET_QUORUM_DELAY_MS)); + } + + if (was_valid && !valid) { + printk(KERN_NOTICE "o2net: No longer connected to " + SC_NODEF_FMT "\n", SC_NODEF_ARGS(old_sc)); + o2net_complete_nodes_nsw(nn); + } + + if (!was_valid && valid) { + o2quo_conn_up(o2net_num_from_nn(nn)); + cancel_delayed_work(&nn->nn_connect_expired); + printk(KERN_NOTICE "o2net: %s " SC_NODEF_FMT "\n", + o2nm_this_node() > sc->sc_node->nd_num ? + "Connected to" : "Accepted connection from", + SC_NODEF_ARGS(sc)); + } + + /* trigger the connecting worker func as long as we're not valid, + * it will back off if it shouldn't connect. This can be called + * from node config teardown and so needs to be careful about + * the work queue actually being up. */ + if (!valid && o2net_wq) { + unsigned long delay; + /* delay if we're within a RECONNECT_DELAY of the + * last attempt */ + delay = (nn->nn_last_connect_attempt + + msecs_to_jiffies(o2net_reconnect_delay())) + - jiffies; + if (delay > msecs_to_jiffies(o2net_reconnect_delay())) + delay = 0; + mlog(ML_CONN, "queueing conn attempt in %lu jiffies\n", delay); + queue_delayed_work(o2net_wq, &nn->nn_connect_work, delay); + + /* + * Delay the expired work after idle timeout. + * + * We might have lots of failed connection attempts that run + * through here but we only cancel the connect_expired work when + * a connection attempt succeeds. So only the first enqueue of + * the connect_expired work will do anything. The rest will see + * that it's already queued and do nothing. + */ + delay += msecs_to_jiffies(o2net_idle_timeout()); + queue_delayed_work(o2net_wq, &nn->nn_connect_expired, delay); + } + + /* keep track of the nn's sc ref for the caller */ + if ((old_sc == NULL) && sc) + sc_get(sc); + if (old_sc && (old_sc != sc)) { + o2net_sc_queue_work(old_sc, &old_sc->sc_shutdown_work); + sc_put(old_sc); + } +} + +/* see o2net_register_callbacks() */ +static void o2net_data_ready(struct sock *sk, int bytes) +{ + void (*ready)(struct sock *sk, int bytes); + + read_lock(&sk->sk_callback_lock); + if (sk->sk_user_data) { + struct o2net_sock_container *sc = sk->sk_user_data; + sclog(sc, "data_ready hit\n"); + o2net_set_data_ready_time(sc); + o2net_sc_queue_work(sc, &sc->sc_rx_work); + ready = sc->sc_data_ready; + } else { + ready = sk->sk_data_ready; + } + read_unlock(&sk->sk_callback_lock); + + ready(sk, bytes); +} + +/* see o2net_register_callbacks() */ +static void o2net_state_change(struct sock *sk) +{ + void (*state_change)(struct sock *sk); + struct o2net_sock_container *sc; + + read_lock(&sk->sk_callback_lock); + sc = sk->sk_user_data; + if (sc == NULL) { + state_change = sk->sk_state_change; + goto out; + } + + sclog(sc, "state_change to %d\n", sk->sk_state); + + state_change = sc->sc_state_change; + + switch(sk->sk_state) { + /* ignore connecting sockets as they make progress */ + case TCP_SYN_SENT: + case TCP_SYN_RECV: + break; + case TCP_ESTABLISHED: + o2net_sc_queue_work(sc, &sc->sc_connect_work); + break; + default: + printk(KERN_INFO "o2net: Connection to " SC_NODEF_FMT + " shutdown, state %d\n", + SC_NODEF_ARGS(sc), sk->sk_state); + o2net_sc_queue_work(sc, &sc->sc_shutdown_work); + break; + } +out: + read_unlock(&sk->sk_callback_lock); + state_change(sk); +} + +/* + * we register callbacks so we can queue work on events before calling + * the original callbacks. our callbacks our careful to test user_data + * to discover when they've reaced with o2net_unregister_callbacks(). + */ +static void o2net_register_callbacks(struct sock *sk, + struct o2net_sock_container *sc) +{ + write_lock_bh(&sk->sk_callback_lock); + + /* accepted sockets inherit the old listen socket data ready */ + if (sk->sk_data_ready == o2net_listen_data_ready) { + sk->sk_data_ready = sk->sk_user_data; + sk->sk_user_data = NULL; + } + + BUG_ON(sk->sk_user_data != NULL); + sk->sk_user_data = sc; + sc_get(sc); + + sc->sc_data_ready = sk->sk_data_ready; + sc->sc_state_change = sk->sk_state_change; + sk->sk_data_ready = o2net_data_ready; + sk->sk_state_change = o2net_state_change; + + mutex_init(&sc->sc_send_lock); + + write_unlock_bh(&sk->sk_callback_lock); +} + +static int o2net_unregister_callbacks(struct sock *sk, + struct o2net_sock_container *sc) +{ + int ret = 0; + + write_lock_bh(&sk->sk_callback_lock); + if (sk->sk_user_data == sc) { + ret = 1; + sk->sk_user_data = NULL; + sk->sk_data_ready = sc->sc_data_ready; + sk->sk_state_change = sc->sc_state_change; + } + write_unlock_bh(&sk->sk_callback_lock); + + return ret; +} + +/* + * this is a little helper that is called by callers who have seen a problem + * with an sc and want to detach it from the nn if someone already hasn't beat + * them to it. if an error is given then the shutdown will be persistent + * and pending transmits will be canceled. + */ +static void o2net_ensure_shutdown(struct o2net_node *nn, + struct o2net_sock_container *sc, + int err) +{ + spin_lock(&nn->nn_lock); + if (nn->nn_sc == sc) + o2net_set_nn_state(nn, NULL, 0, err); + spin_unlock(&nn->nn_lock); +} + +/* + * This work queue function performs the blocking parts of socket shutdown. A + * few paths lead here. set_nn_state will trigger this callback if it sees an + * sc detached from the nn. state_change will also trigger this callback + * directly when it sees errors. In that case we need to call set_nn_state + * ourselves as state_change couldn't get the nn_lock and call set_nn_state + * itself. + */ +static void o2net_shutdown_sc(struct work_struct *work) +{ + struct o2net_sock_container *sc = + container_of(work, struct o2net_sock_container, + sc_shutdown_work); + struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num); + + sclog(sc, "shutting down\n"); + + /* drop the callbacks ref and call shutdown only once */ + if (o2net_unregister_callbacks(sc->sc_sock->sk, sc)) { + /* we shouldn't flush as we're in the thread, the + * races with pending sc work structs are harmless */ + del_timer_sync(&sc->sc_idle_timeout); + o2net_sc_cancel_delayed_work(sc, &sc->sc_keepalive_work); + sc_put(sc); + kernel_sock_shutdown(sc->sc_sock, SHUT_RDWR); + } + + /* not fatal so failed connects before the other guy has our + * heartbeat can be retried */ + o2net_ensure_shutdown(nn, sc, 0); + sc_put(sc); +} + +/* ------------------------------------------------------------ */ + +static int o2net_handler_cmp(struct o2net_msg_handler *nmh, u32 msg_type, + u32 key) +{ + int ret = memcmp(&nmh->nh_key, &key, sizeof(key)); + + if (ret == 0) + ret = memcmp(&nmh->nh_msg_type, &msg_type, sizeof(msg_type)); + + return ret; +} + +static struct o2net_msg_handler * +o2net_handler_tree_lookup(u32 msg_type, u32 key, struct rb_node ***ret_p, + struct rb_node **ret_parent) +{ + struct rb_node **p = &o2net_handler_tree.rb_node; + struct rb_node *parent = NULL; + struct o2net_msg_handler *nmh, *ret = NULL; + int cmp; + + while (*p) { + parent = *p; + nmh = rb_entry(parent, struct o2net_msg_handler, nh_node); + cmp = o2net_handler_cmp(nmh, msg_type, key); + + if (cmp < 0) + p = &(*p)->rb_left; + else if (cmp > 0) + p = &(*p)->rb_right; + else { + ret = nmh; + break; + } + } + + if (ret_p != NULL) + *ret_p = p; + if (ret_parent != NULL) + *ret_parent = parent; + + return ret; +} + +static void o2net_handler_kref_release(struct kref *kref) +{ + struct o2net_msg_handler *nmh; + nmh = container_of(kref, struct o2net_msg_handler, nh_kref); + + kfree(nmh); +} + +static void o2net_handler_put(struct o2net_msg_handler *nmh) +{ + kref_put(&nmh->nh_kref, o2net_handler_kref_release); +} + +/* max_len is protection for the handler func. incoming messages won't + * be given to the handler if their payload is longer than the max. */ +int o2net_register_handler(u32 msg_type, u32 key, u32 max_len, + o2net_msg_handler_func *func, void *data, + o2net_post_msg_handler_func *post_func, + struct list_head *unreg_list) +{ + struct o2net_msg_handler *nmh = NULL; + struct rb_node **p, *parent; + int ret = 0; + + if (max_len > O2NET_MAX_PAYLOAD_BYTES) { + mlog(0, "max_len for message handler out of range: %u\n", + max_len); + ret = -EINVAL; + goto out; + } + + if (!msg_type) { + mlog(0, "no message type provided: %u, %p\n", msg_type, func); + ret = -EINVAL; + goto out; + + } + if (!func) { + mlog(0, "no message handler provided: %u, %p\n", + msg_type, func); + ret = -EINVAL; + goto out; + } + + nmh = kzalloc(sizeof(struct o2net_msg_handler), GFP_NOFS); + if (nmh == NULL) { + ret = -ENOMEM; + goto out; + } + + nmh->nh_func = func; + nmh->nh_func_data = data; + nmh->nh_post_func = post_func; + nmh->nh_msg_type = msg_type; + nmh->nh_max_len = max_len; + nmh->nh_key = key; + /* the tree and list get this ref.. they're both removed in + * unregister when this ref is dropped */ + kref_init(&nmh->nh_kref); + INIT_LIST_HEAD(&nmh->nh_unregister_item); + + write_lock(&o2net_handler_lock); + if (o2net_handler_tree_lookup(msg_type, key, &p, &parent)) + ret = -EEXIST; + else { + rb_link_node(&nmh->nh_node, parent, p); + rb_insert_color(&nmh->nh_node, &o2net_handler_tree); + list_add_tail(&nmh->nh_unregister_item, unreg_list); + + mlog(ML_TCP, "registered handler func %p type %u key %08x\n", + func, msg_type, key); + /* we've had some trouble with handlers seemingly vanishing. */ + mlog_bug_on_msg(o2net_handler_tree_lookup(msg_type, key, &p, + &parent) == NULL, + "couldn't find handler we *just* registerd " + "for type %u key %08x\n", msg_type, key); + } + write_unlock(&o2net_handler_lock); + if (ret) + goto out; + +out: + if (ret) + kfree(nmh); + + return ret; +} +EXPORT_SYMBOL_GPL(o2net_register_handler); + +void o2net_unregister_handler_list(struct list_head *list) +{ + struct o2net_msg_handler *nmh, *n; + + write_lock(&o2net_handler_lock); + list_for_each_entry_safe(nmh, n, list, nh_unregister_item) { + mlog(ML_TCP, "unregistering handler func %p type %u key %08x\n", + nmh->nh_func, nmh->nh_msg_type, nmh->nh_key); + rb_erase(&nmh->nh_node, &o2net_handler_tree); + list_del_init(&nmh->nh_unregister_item); + kref_put(&nmh->nh_kref, o2net_handler_kref_release); + } + write_unlock(&o2net_handler_lock); +} +EXPORT_SYMBOL_GPL(o2net_unregister_handler_list); + +static struct o2net_msg_handler *o2net_handler_get(u32 msg_type, u32 key) +{ + struct o2net_msg_handler *nmh; + + read_lock(&o2net_handler_lock); + nmh = o2net_handler_tree_lookup(msg_type, key, NULL, NULL); + if (nmh) + kref_get(&nmh->nh_kref); + read_unlock(&o2net_handler_lock); + + return nmh; +} + +/* ------------------------------------------------------------ */ + +static int o2net_recv_tcp_msg(struct socket *sock, void *data, size_t len) +{ + int ret; + mm_segment_t oldfs; + struct kvec vec = { + .iov_len = len, + .iov_base = data, + }; + struct msghdr msg = { + .msg_iovlen = 1, + .msg_iov = (struct iovec *)&vec, + .msg_flags = MSG_DONTWAIT, + }; + + oldfs = get_fs(); + set_fs(get_ds()); + ret = sock_recvmsg(sock, &msg, len, msg.msg_flags); + set_fs(oldfs); + + return ret; +} + +static int o2net_send_tcp_msg(struct socket *sock, struct kvec *vec, + size_t veclen, size_t total) +{ + int ret; + mm_segment_t oldfs; + struct msghdr msg = { + .msg_iov = (struct iovec *)vec, + .msg_iovlen = veclen, + }; + + if (sock == NULL) { + ret = -EINVAL; + goto out; + } + + oldfs = get_fs(); + set_fs(get_ds()); + ret = sock_sendmsg(sock, &msg, total); + set_fs(oldfs); + if (ret != total) { + mlog(ML_ERROR, "sendmsg returned %d instead of %zu\n", ret, + total); + if (ret >= 0) + ret = -EPIPE; /* should be smarter, I bet */ + goto out; + } + + ret = 0; +out: + if (ret < 0) + mlog(0, "returning error: %d\n", ret); + return ret; +} + +static void o2net_sendpage(struct o2net_sock_container *sc, + void *kmalloced_virt, + size_t size) +{ + struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num); + ssize_t ret; + + while (1) { + mutex_lock(&sc->sc_send_lock); + ret = sc->sc_sock->ops->sendpage(sc->sc_sock, + virt_to_page(kmalloced_virt), + (long)kmalloced_virt & ~PAGE_MASK, + size, MSG_DONTWAIT); + mutex_unlock(&sc->sc_send_lock); + if (ret == size) + break; + if (ret == (ssize_t)-EAGAIN) { + mlog(0, "sendpage of size %zu to " SC_NODEF_FMT + " returned EAGAIN\n", size, SC_NODEF_ARGS(sc)); + cond_resched(); + continue; + } + mlog(ML_ERROR, "sendpage of size %zu to " SC_NODEF_FMT + " failed with %zd\n", size, SC_NODEF_ARGS(sc), ret); + o2net_ensure_shutdown(nn, sc, 0); + break; + } +} + +static void o2net_init_msg(struct o2net_msg *msg, u16 data_len, u16 msg_type, u32 key) +{ + memset(msg, 0, sizeof(struct o2net_msg)); + msg->magic = cpu_to_be16(O2NET_MSG_MAGIC); + msg->data_len = cpu_to_be16(data_len); + msg->msg_type = cpu_to_be16(msg_type); + msg->sys_status = cpu_to_be32(O2NET_ERR_NONE); + msg->status = 0; + msg->key = cpu_to_be32(key); +} + +static int o2net_tx_can_proceed(struct o2net_node *nn, + struct o2net_sock_container **sc_ret, + int *error) +{ + int ret = 0; + + spin_lock(&nn->nn_lock); + if (nn->nn_persistent_error) { + ret = 1; + *sc_ret = NULL; + *error = nn->nn_persistent_error; + } else if (nn->nn_sc_valid) { + kref_get(&nn->nn_sc->sc_kref); + + ret = 1; + *sc_ret = nn->nn_sc; + *error = 0; + } + spin_unlock(&nn->nn_lock); + + return ret; +} + +/* Get a map of all nodes to which this node is currently connected to */ +void o2net_fill_node_map(unsigned long *map, unsigned bytes) +{ + struct o2net_sock_container *sc; + int node, ret; + + BUG_ON(bytes < (BITS_TO_LONGS(O2NM_MAX_NODES) * sizeof(unsigned long))); + + memset(map, 0, bytes); + for (node = 0; node < O2NM_MAX_NODES; ++node) { + o2net_tx_can_proceed(o2net_nn_from_num(node), &sc, &ret); + if (!ret) { + set_bit(node, map); + sc_put(sc); + } + } +} +EXPORT_SYMBOL_GPL(o2net_fill_node_map); + +int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec, + size_t caller_veclen, u8 target_node, int *status) +{ + int ret = 0; + struct o2net_msg *msg = NULL; + size_t veclen, caller_bytes = 0; + struct kvec *vec = NULL; + struct o2net_sock_container *sc = NULL; + struct o2net_node *nn = o2net_nn_from_num(target_node); + struct o2net_status_wait nsw = { + .ns_node_item = LIST_HEAD_INIT(nsw.ns_node_item), + }; + struct o2net_send_tracking nst; + + o2net_init_nst(&nst, msg_type, key, current, target_node); + + if (o2net_wq == NULL) { + mlog(0, "attempt to tx without o2netd running\n"); + ret = -ESRCH; + goto out; + } + + if (caller_veclen == 0) { + mlog(0, "bad kvec array length\n"); + ret = -EINVAL; + goto out; + } + + caller_bytes = iov_length((struct iovec *)caller_vec, caller_veclen); + if (caller_bytes > O2NET_MAX_PAYLOAD_BYTES) { + mlog(0, "total payload len %zu too large\n", caller_bytes); + ret = -EINVAL; + goto out; + } + + if (target_node == o2nm_this_node()) { + ret = -ELOOP; + goto out; + } + + o2net_debug_add_nst(&nst); + + o2net_set_nst_sock_time(&nst); + + wait_event(nn->nn_sc_wq, o2net_tx_can_proceed(nn, &sc, &ret)); + if (ret) + goto out; + + o2net_set_nst_sock_container(&nst, sc); + + veclen = caller_veclen + 1; + vec = kmalloc(sizeof(struct kvec) * veclen, GFP_ATOMIC); + if (vec == NULL) { + mlog(0, "failed to %zu element kvec!\n", veclen); + ret = -ENOMEM; + goto out; + } + + msg = kmalloc(sizeof(struct o2net_msg), GFP_ATOMIC); + if (!msg) { + mlog(0, "failed to allocate a o2net_msg!\n"); + ret = -ENOMEM; + goto out; + } + + o2net_init_msg(msg, caller_bytes, msg_type, key); + + vec[0].iov_len = sizeof(struct o2net_msg); + vec[0].iov_base = msg; + memcpy(&vec[1], caller_vec, caller_veclen * sizeof(struct kvec)); + + ret = o2net_prep_nsw(nn, &nsw); + if (ret) + goto out; + + msg->msg_num = cpu_to_be32(nsw.ns_id); + o2net_set_nst_msg_id(&nst, nsw.ns_id); + + o2net_set_nst_send_time(&nst); + + /* finally, convert the message header to network byte-order + * and send */ + mutex_lock(&sc->sc_send_lock); + ret = o2net_send_tcp_msg(sc->sc_sock, vec, veclen, + sizeof(struct o2net_msg) + caller_bytes); + mutex_unlock(&sc->sc_send_lock); + msglog(msg, "sending returned %d\n", ret); + if (ret < 0) { + mlog(0, "error returned from o2net_send_tcp_msg=%d\n", ret); + goto out; + } + + /* wait on other node's handler */ + o2net_set_nst_status_time(&nst); + wait_event(nsw.ns_wq, o2net_nsw_completed(nn, &nsw)); + + o2net_update_send_stats(&nst, sc); + + /* Note that we avoid overwriting the callers status return + * variable if a system error was reported on the other + * side. Callers beware. */ + ret = o2net_sys_err_to_errno(nsw.ns_sys_status); + if (status && !ret) + *status = nsw.ns_status; + + mlog(0, "woken, returning system status %d, user status %d\n", + ret, nsw.ns_status); +out: + o2net_debug_del_nst(&nst); /* must be before dropping sc and node */ + if (sc) + sc_put(sc); + if (vec) + kfree(vec); + if (msg) + kfree(msg); + o2net_complete_nsw(nn, &nsw, 0, 0, 0); + return ret; +} +EXPORT_SYMBOL_GPL(o2net_send_message_vec); + +int o2net_send_message(u32 msg_type, u32 key, void *data, u32 len, + u8 target_node, int *status) +{ + struct kvec vec = { + .iov_base = data, + .iov_len = len, + }; + return o2net_send_message_vec(msg_type, key, &vec, 1, + target_node, status); +} +EXPORT_SYMBOL_GPL(o2net_send_message); + +static int o2net_send_status_magic(struct socket *sock, struct o2net_msg *hdr, + enum o2net_system_error syserr, int err) +{ + struct kvec vec = { + .iov_base = hdr, + .iov_len = sizeof(struct o2net_msg), + }; + + BUG_ON(syserr >= O2NET_ERR_MAX); + + /* leave other fields intact from the incoming message, msg_num + * in particular */ + hdr->sys_status = cpu_to_be32(syserr); + hdr->status = cpu_to_be32(err); + hdr->magic = cpu_to_be16(O2NET_MSG_STATUS_MAGIC); // twiddle the magic + hdr->data_len = 0; + + msglog(hdr, "about to send status magic %d\n", err); + /* hdr has been in host byteorder this whole time */ + return o2net_send_tcp_msg(sock, &vec, 1, sizeof(struct o2net_msg)); +} + +/* this returns -errno if the header was unknown or too large, etc. + * after this is called the buffer us reused for the next message */ +static int o2net_process_message(struct o2net_sock_container *sc, + struct o2net_msg *hdr) +{ + struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num); + int ret = 0, handler_status; + enum o2net_system_error syserr; + struct o2net_msg_handler *nmh = NULL; + void *ret_data = NULL; + + msglog(hdr, "processing message\n"); + + o2net_sc_postpone_idle(sc); + + switch(be16_to_cpu(hdr->magic)) { + case O2NET_MSG_STATUS_MAGIC: + /* special type for returning message status */ + o2net_complete_nsw(nn, NULL, + be32_to_cpu(hdr->msg_num), + be32_to_cpu(hdr->sys_status), + be32_to_cpu(hdr->status)); + goto out; + case O2NET_MSG_KEEP_REQ_MAGIC: + o2net_sendpage(sc, o2net_keep_resp, + sizeof(*o2net_keep_resp)); + goto out; + case O2NET_MSG_KEEP_RESP_MAGIC: + goto out; + case O2NET_MSG_MAGIC: + break; + default: + msglog(hdr, "bad magic\n"); + ret = -EINVAL; + goto out; + break; + } + + /* find a handler for it */ + handler_status = 0; + nmh = o2net_handler_get(be16_to_cpu(hdr->msg_type), + be32_to_cpu(hdr->key)); + if (!nmh) { + mlog(ML_TCP, "couldn't find handler for type %u key %08x\n", + be16_to_cpu(hdr->msg_type), be32_to_cpu(hdr->key)); + syserr = O2NET_ERR_NO_HNDLR; + goto out_respond; + } + + syserr = O2NET_ERR_NONE; + + if (be16_to_cpu(hdr->data_len) > nmh->nh_max_len) + syserr = O2NET_ERR_OVERFLOW; + + if (syserr != O2NET_ERR_NONE) + goto out_respond; + + o2net_set_func_start_time(sc); + sc->sc_msg_key = be32_to_cpu(hdr->key); + sc->sc_msg_type = be16_to_cpu(hdr->msg_type); + handler_status = (nmh->nh_func)(hdr, sizeof(struct o2net_msg) + + be16_to_cpu(hdr->data_len), + nmh->nh_func_data, &ret_data); + o2net_set_func_stop_time(sc); + + o2net_update_recv_stats(sc); + +out_respond: + /* this destroys the hdr, so don't use it after this */ + mutex_lock(&sc->sc_send_lock); + ret = o2net_send_status_magic(sc->sc_sock, hdr, syserr, + handler_status); + mutex_unlock(&sc->sc_send_lock); + hdr = NULL; + mlog(0, "sending handler status %d, syserr %d returned %d\n", + handler_status, syserr, ret); + + if (nmh) { + BUG_ON(ret_data != NULL && nmh->nh_post_func == NULL); + if (nmh->nh_post_func) + (nmh->nh_post_func)(handler_status, nmh->nh_func_data, + ret_data); + } + +out: + if (nmh) + o2net_handler_put(nmh); + return ret; +} + +static int o2net_check_handshake(struct o2net_sock_container *sc) +{ + struct o2net_handshake *hand = page_address(sc->sc_page); + struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num); + + if (hand->protocol_version != cpu_to_be64(O2NET_PROTOCOL_VERSION)) { + printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " Advertised net " + "protocol version %llu but %llu is required. " + "Disconnecting.\n", SC_NODEF_ARGS(sc), + (unsigned long long)be64_to_cpu(hand->protocol_version), + O2NET_PROTOCOL_VERSION); + + /* don't bother reconnecting if its the wrong version. */ + o2net_ensure_shutdown(nn, sc, -ENOTCONN); + return -1; + } + + /* + * Ensure timeouts are consistent with other nodes, otherwise + * we can end up with one node thinking that the other must be down, + * but isn't. This can ultimately cause corruption. + */ + if (be32_to_cpu(hand->o2net_idle_timeout_ms) != + o2net_idle_timeout()) { + printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " uses a network " + "idle timeout of %u ms, but we use %u ms locally. " + "Disconnecting.\n", SC_NODEF_ARGS(sc), + be32_to_cpu(hand->o2net_idle_timeout_ms), + o2net_idle_timeout()); + o2net_ensure_shutdown(nn, sc, -ENOTCONN); + return -1; + } + + if (be32_to_cpu(hand->o2net_keepalive_delay_ms) != + o2net_keepalive_delay()) { + printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " uses a keepalive " + "delay of %u ms, but we use %u ms locally. " + "Disconnecting.\n", SC_NODEF_ARGS(sc), + be32_to_cpu(hand->o2net_keepalive_delay_ms), + o2net_keepalive_delay()); + o2net_ensure_shutdown(nn, sc, -ENOTCONN); + return -1; + } + + if (be32_to_cpu(hand->o2hb_heartbeat_timeout_ms) != + O2HB_MAX_WRITE_TIMEOUT_MS) { + printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " uses a heartbeat " + "timeout of %u ms, but we use %u ms locally. " + "Disconnecting.\n", SC_NODEF_ARGS(sc), + be32_to_cpu(hand->o2hb_heartbeat_timeout_ms), + O2HB_MAX_WRITE_TIMEOUT_MS); + o2net_ensure_shutdown(nn, sc, -ENOTCONN); + return -1; + } + + sc->sc_handshake_ok = 1; + + spin_lock(&nn->nn_lock); + /* set valid and queue the idle timers only if it hasn't been + * shut down already */ + if (nn->nn_sc == sc) { + o2net_sc_reset_idle_timer(sc); + atomic_set(&nn->nn_timeout, 0); + o2net_set_nn_state(nn, sc, 1, 0); + } + spin_unlock(&nn->nn_lock); + + /* shift everything up as though it wasn't there */ + sc->sc_page_off -= sizeof(struct o2net_handshake); + if (sc->sc_page_off) + memmove(hand, hand + 1, sc->sc_page_off); + + return 0; +} + +/* this demuxes the queued rx bytes into header or payload bits and calls + * handlers as each full message is read off the socket. it returns -error, + * == 0 eof, or > 0 for progress made.*/ +static int o2net_advance_rx(struct o2net_sock_container *sc) +{ + struct o2net_msg *hdr; + int ret = 0; + void *data; + size_t datalen; + + sclog(sc, "receiving\n"); + o2net_set_advance_start_time(sc); + + if (unlikely(sc->sc_handshake_ok == 0)) { + if(sc->sc_page_off < sizeof(struct o2net_handshake)) { + data = page_address(sc->sc_page) + sc->sc_page_off; + datalen = sizeof(struct o2net_handshake) - sc->sc_page_off; + ret = o2net_recv_tcp_msg(sc->sc_sock, data, datalen); + if (ret > 0) + sc->sc_page_off += ret; + } + + if (sc->sc_page_off == sizeof(struct o2net_handshake)) { + o2net_check_handshake(sc); + if (unlikely(sc->sc_handshake_ok == 0)) + ret = -EPROTO; + } + goto out; + } + + /* do we need more header? */ + if (sc->sc_page_off < sizeof(struct o2net_msg)) { + data = page_address(sc->sc_page) + sc->sc_page_off; + datalen = sizeof(struct o2net_msg) - sc->sc_page_off; + ret = o2net_recv_tcp_msg(sc->sc_sock, data, datalen); + if (ret > 0) { + sc->sc_page_off += ret; + /* only swab incoming here.. we can + * only get here once as we cross from + * being under to over */ + if (sc->sc_page_off == sizeof(struct o2net_msg)) { + hdr = page_address(sc->sc_page); + if (be16_to_cpu(hdr->data_len) > + O2NET_MAX_PAYLOAD_BYTES) + ret = -EOVERFLOW; + } + } + if (ret <= 0) + goto out; + } + + if (sc->sc_page_off < sizeof(struct o2net_msg)) { + /* oof, still don't have a header */ + goto out; + } + + /* this was swabbed above when we first read it */ + hdr = page_address(sc->sc_page); + + msglog(hdr, "at page_off %zu\n", sc->sc_page_off); + + /* do we need more payload? */ + if (sc->sc_page_off - sizeof(struct o2net_msg) < be16_to_cpu(hdr->data_len)) { + /* need more payload */ + data = page_address(sc->sc_page) + sc->sc_page_off; + datalen = (sizeof(struct o2net_msg) + be16_to_cpu(hdr->data_len)) - + sc->sc_page_off; + ret = o2net_recv_tcp_msg(sc->sc_sock, data, datalen); + if (ret > 0) + sc->sc_page_off += ret; + if (ret <= 0) + goto out; + } + + if (sc->sc_page_off - sizeof(struct o2net_msg) == be16_to_cpu(hdr->data_len)) { + /* we can only get here once, the first time we read + * the payload.. so set ret to progress if the handler + * works out. after calling this the message is toast */ + ret = o2net_process_message(sc, hdr); + if (ret == 0) + ret = 1; + sc->sc_page_off = 0; + } + +out: + sclog(sc, "ret = %d\n", ret); + o2net_set_advance_stop_time(sc); + return ret; +} + +/* this work func is triggerd by data ready. it reads until it can read no + * more. it interprets 0, eof, as fatal. if data_ready hits while we're doing + * our work the work struct will be marked and we'll be called again. */ +static void o2net_rx_until_empty(struct work_struct *work) +{ + struct o2net_sock_container *sc = + container_of(work, struct o2net_sock_container, sc_rx_work); + int ret; + + do { + ret = o2net_advance_rx(sc); + } while (ret > 0); + + if (ret <= 0 && ret != -EAGAIN) { + struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num); + sclog(sc, "saw error %d, closing\n", ret); + /* not permanent so read failed handshake can retry */ + o2net_ensure_shutdown(nn, sc, 0); + } + + sc_put(sc); +} + +static int o2net_set_nodelay(struct socket *sock) +{ + int ret, val = 1; + mm_segment_t oldfs; + + oldfs = get_fs(); + set_fs(KERNEL_DS); + + /* + * Dear unsuspecting programmer, + * + * Don't use sock_setsockopt() for SOL_TCP. It doesn't check its level + * argument and assumes SOL_SOCKET so, say, your TCP_NODELAY will + * silently turn into SO_DEBUG. + * + * Yours, + * Keeper of hilariously fragile interfaces. + */ + ret = sock->ops->setsockopt(sock, SOL_TCP, TCP_NODELAY, + (char __user *)&val, sizeof(val)); + + set_fs(oldfs); + return ret; +} + +static void o2net_initialize_handshake(void) +{ + o2net_hand->o2hb_heartbeat_timeout_ms = cpu_to_be32( + O2HB_MAX_WRITE_TIMEOUT_MS); + o2net_hand->o2net_idle_timeout_ms = cpu_to_be32(o2net_idle_timeout()); + o2net_hand->o2net_keepalive_delay_ms = cpu_to_be32( + o2net_keepalive_delay()); + o2net_hand->o2net_reconnect_delay_ms = cpu_to_be32( + o2net_reconnect_delay()); +} + +/* ------------------------------------------------------------ */ + +/* called when a connect completes and after a sock is accepted. the + * rx path will see the response and mark the sc valid */ +static void o2net_sc_connect_completed(struct work_struct *work) +{ + struct o2net_sock_container *sc = + container_of(work, struct o2net_sock_container, + sc_connect_work); + + mlog(ML_MSG, "sc sending handshake with ver %llu id %llx\n", + (unsigned long long)O2NET_PROTOCOL_VERSION, + (unsigned long long)be64_to_cpu(o2net_hand->connector_id)); + + o2net_initialize_handshake(); + o2net_sendpage(sc, o2net_hand, sizeof(*o2net_hand)); + sc_put(sc); +} + +/* this is called as a work_struct func. */ +static void o2net_sc_send_keep_req(struct work_struct *work) +{ + struct o2net_sock_container *sc = + container_of(work, struct o2net_sock_container, + sc_keepalive_work.work); + + o2net_sendpage(sc, o2net_keep_req, sizeof(*o2net_keep_req)); + sc_put(sc); +} + +/* socket shutdown does a del_timer_sync against this as it tears down. + * we can't start this timer until we've got to the point in sc buildup + * where shutdown is going to be involved */ +static void o2net_idle_timer(unsigned long data) +{ + struct o2net_sock_container *sc = (struct o2net_sock_container *)data; + struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num); +#ifdef CONFIG_DEBUG_FS + unsigned long msecs = ktime_to_ms(ktime_get()) - + ktime_to_ms(sc->sc_tv_timer); +#else + unsigned long msecs = o2net_idle_timeout(); +#endif + + printk(KERN_NOTICE "o2net: Connection to " SC_NODEF_FMT " has been " + "idle for %lu.%lu secs, shutting it down.\n", SC_NODEF_ARGS(sc), + msecs / 1000, msecs % 1000); + + /* + * Initialize the nn_timeout so that the next connection attempt + * will continue in o2net_start_connect. + */ + atomic_set(&nn->nn_timeout, 1); + + o2net_sc_queue_work(sc, &sc->sc_shutdown_work); +} + +static void o2net_sc_reset_idle_timer(struct o2net_sock_container *sc) +{ + o2net_sc_cancel_delayed_work(sc, &sc->sc_keepalive_work); + o2net_sc_queue_delayed_work(sc, &sc->sc_keepalive_work, + msecs_to_jiffies(o2net_keepalive_delay())); + o2net_set_sock_timer(sc); + mod_timer(&sc->sc_idle_timeout, + jiffies + msecs_to_jiffies(o2net_idle_timeout())); +} + +static void o2net_sc_postpone_idle(struct o2net_sock_container *sc) +{ + /* Only push out an existing timer */ + if (timer_pending(&sc->sc_idle_timeout)) + o2net_sc_reset_idle_timer(sc); +} + +/* this work func is kicked whenever a path sets the nn state which doesn't + * have valid set. This includes seeing hb come up, losing a connection, + * having a connect attempt fail, etc. This centralizes the logic which decides + * if a connect attempt should be made or if we should give up and all future + * transmit attempts should fail */ +static void o2net_start_connect(struct work_struct *work) +{ + struct o2net_node *nn = + container_of(work, struct o2net_node, nn_connect_work.work); + struct o2net_sock_container *sc = NULL; + struct o2nm_node *node = NULL, *mynode = NULL; + struct socket *sock = NULL; + struct sockaddr_in myaddr = {0, }, remoteaddr = {0, }; + int ret = 0, stop; + unsigned int timeout; + + /* if we're greater we initiate tx, otherwise we accept */ + if (o2nm_this_node() <= o2net_num_from_nn(nn)) + goto out; + + /* watch for racing with tearing a node down */ + node = o2nm_get_node_by_num(o2net_num_from_nn(nn)); + if (node == NULL) { + ret = 0; + goto out; + } + + mynode = o2nm_get_node_by_num(o2nm_this_node()); + if (mynode == NULL) { + ret = 0; + goto out; + } + + spin_lock(&nn->nn_lock); + /* + * see if we already have one pending or have given up. + * For nn_timeout, it is set when we close the connection + * because of the idle time out. So it means that we have + * at least connected to that node successfully once, + * now try to connect to it again. + */ + timeout = atomic_read(&nn->nn_timeout); + stop = (nn->nn_sc || + (nn->nn_persistent_error && + (nn->nn_persistent_error != -ENOTCONN || timeout == 0))); + spin_unlock(&nn->nn_lock); + if (stop) + goto out; + + nn->nn_last_connect_attempt = jiffies; + + sc = sc_alloc(node); + if (sc == NULL) { + mlog(0, "couldn't allocate sc\n"); + ret = -ENOMEM; + goto out; + } + + ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock); + if (ret < 0) { + mlog(0, "can't create socket: %d\n", ret); + goto out; + } + sc->sc_sock = sock; /* freed by sc_kref_release */ + + sock->sk->sk_allocation = GFP_ATOMIC; + + myaddr.sin_family = AF_INET; + myaddr.sin_addr.s_addr = mynode->nd_ipv4_address; + myaddr.sin_port = htons(0); /* any port */ + + ret = sock->ops->bind(sock, (struct sockaddr *)&myaddr, + sizeof(myaddr)); + if (ret) { + mlog(ML_ERROR, "bind failed with %d at address %pI4\n", + ret, &mynode->nd_ipv4_address); + goto out; + } + + ret = o2net_set_nodelay(sc->sc_sock); + if (ret) { + mlog(ML_ERROR, "setting TCP_NODELAY failed with %d\n", ret); + goto out; + } + + o2net_register_callbacks(sc->sc_sock->sk, sc); + + spin_lock(&nn->nn_lock); + /* handshake completion will set nn->nn_sc_valid */ + o2net_set_nn_state(nn, sc, 0, 0); + spin_unlock(&nn->nn_lock); + + remoteaddr.sin_family = AF_INET; + remoteaddr.sin_addr.s_addr = node->nd_ipv4_address; + remoteaddr.sin_port = node->nd_ipv4_port; + + ret = sc->sc_sock->ops->connect(sc->sc_sock, + (struct sockaddr *)&remoteaddr, + sizeof(remoteaddr), + O_NONBLOCK); + if (ret == -EINPROGRESS) + ret = 0; + +out: + if (ret) { + printk(KERN_NOTICE "o2net: Connect attempt to " SC_NODEF_FMT + " failed with errno %d\n", SC_NODEF_ARGS(sc), ret); + /* 0 err so that another will be queued and attempted + * from set_nn_state */ + if (sc) + o2net_ensure_shutdown(nn, sc, 0); + } + if (sc) + sc_put(sc); + if (node) + o2nm_node_put(node); + if (mynode) + o2nm_node_put(mynode); + + return; +} + +static void o2net_connect_expired(struct work_struct *work) +{ + struct o2net_node *nn = + container_of(work, struct o2net_node, nn_connect_expired.work); + + spin_lock(&nn->nn_lock); + if (!nn->nn_sc_valid) { + printk(KERN_NOTICE "o2net: No connection established with " + "node %u after %u.%u seconds, giving up.\n", + o2net_num_from_nn(nn), + o2net_idle_timeout() / 1000, + o2net_idle_timeout() % 1000); + + o2net_set_nn_state(nn, NULL, 0, -ENOTCONN); + } + spin_unlock(&nn->nn_lock); +} + +static void o2net_still_up(struct work_struct *work) +{ + struct o2net_node *nn = + container_of(work, struct o2net_node, nn_still_up.work); + + o2quo_hb_still_up(o2net_num_from_nn(nn)); +} + +/* ------------------------------------------------------------ */ + +void o2net_disconnect_node(struct o2nm_node *node) +{ + struct o2net_node *nn = o2net_nn_from_num(node->nd_num); + + /* don't reconnect until it's heartbeating again */ + spin_lock(&nn->nn_lock); + atomic_set(&nn->nn_timeout, 0); + o2net_set_nn_state(nn, NULL, 0, -ENOTCONN); + spin_unlock(&nn->nn_lock); + + if (o2net_wq) { + cancel_delayed_work(&nn->nn_connect_expired); + cancel_delayed_work(&nn->nn_connect_work); + cancel_delayed_work(&nn->nn_still_up); + flush_workqueue(o2net_wq); + } +} + +static void o2net_hb_node_down_cb(struct o2nm_node *node, int node_num, + void *data) +{ + o2quo_hb_down(node_num); + + if (!node) + return; + + if (node_num != o2nm_this_node()) + o2net_disconnect_node(node); + + BUG_ON(atomic_read(&o2net_connected_peers) < 0); +} + +static void o2net_hb_node_up_cb(struct o2nm_node *node, int node_num, + void *data) +{ + struct o2net_node *nn = o2net_nn_from_num(node_num); + + o2quo_hb_up(node_num); + + BUG_ON(!node); + + /* ensure an immediate connect attempt */ + nn->nn_last_connect_attempt = jiffies - + (msecs_to_jiffies(o2net_reconnect_delay()) + 1); + + if (node_num != o2nm_this_node()) { + /* believe it or not, accept and node hearbeating testing + * can succeed for this node before we got here.. so + * only use set_nn_state to clear the persistent error + * if that hasn't already happened */ + spin_lock(&nn->nn_lock); + atomic_set(&nn->nn_timeout, 0); + if (nn->nn_persistent_error) + o2net_set_nn_state(nn, NULL, 0, 0); + spin_unlock(&nn->nn_lock); + } +} + +void o2net_unregister_hb_callbacks(void) +{ + o2hb_unregister_callback(NULL, &o2net_hb_up); + o2hb_unregister_callback(NULL, &o2net_hb_down); +} + +int o2net_register_hb_callbacks(void) +{ + int ret; + + o2hb_setup_callback(&o2net_hb_down, O2HB_NODE_DOWN_CB, + o2net_hb_node_down_cb, NULL, O2NET_HB_PRI); + o2hb_setup_callback(&o2net_hb_up, O2HB_NODE_UP_CB, + o2net_hb_node_up_cb, NULL, O2NET_HB_PRI); + + ret = o2hb_register_callback(NULL, &o2net_hb_up); + if (ret == 0) + ret = o2hb_register_callback(NULL, &o2net_hb_down); + + if (ret) + o2net_unregister_hb_callbacks(); + + return ret; +} + +/* ------------------------------------------------------------ */ + +static int o2net_accept_one(struct socket *sock) +{ + int ret, slen; + struct sockaddr_in sin; + struct socket *new_sock = NULL; + struct o2nm_node *node = NULL; + struct o2nm_node *local_node = NULL; + struct o2net_sock_container *sc = NULL; + struct o2net_node *nn; + + BUG_ON(sock == NULL); + ret = sock_create_lite(sock->sk->sk_family, sock->sk->sk_type, + sock->sk->sk_protocol, &new_sock); + if (ret) + goto out; + + new_sock->type = sock->type; + new_sock->ops = sock->ops; + ret = sock->ops->accept(sock, new_sock, O_NONBLOCK); + if (ret < 0) + goto out; + + new_sock->sk->sk_allocation = GFP_ATOMIC; + + ret = o2net_set_nodelay(new_sock); + if (ret) { + mlog(ML_ERROR, "setting TCP_NODELAY failed with %d\n", ret); + goto out; + } + + slen = sizeof(sin); + ret = new_sock->ops->getname(new_sock, (struct sockaddr *) &sin, + &slen, 1); + if (ret < 0) + goto out; + + node = o2nm_get_node_by_ip(sin.sin_addr.s_addr); + if (node == NULL) { + printk(KERN_NOTICE "o2net: Attempt to connect from unknown " + "node at %pI4:%d\n", &sin.sin_addr.s_addr, + ntohs(sin.sin_port)); + ret = -EINVAL; + goto out; + } + + if (o2nm_this_node() >= node->nd_num) { + local_node = o2nm_get_node_by_num(o2nm_this_node()); + printk(KERN_NOTICE "o2net: Unexpected connect attempt seen " + "at node '%s' (%u, %pI4:%d) from node '%s' (%u, " + "%pI4:%d)\n", local_node->nd_name, local_node->nd_num, + &(local_node->nd_ipv4_address), + ntohs(local_node->nd_ipv4_port), node->nd_name, + node->nd_num, &sin.sin_addr.s_addr, ntohs(sin.sin_port)); + ret = -EINVAL; + goto out; + } + + /* this happens all the time when the other node sees our heartbeat + * and tries to connect before we see their heartbeat */ + if (!o2hb_check_node_heartbeating_from_callback(node->nd_num)) { + mlog(ML_CONN, "attempt to connect from node '%s' at " + "%pI4:%d but it isn't heartbeating\n", + node->nd_name, &sin.sin_addr.s_addr, + ntohs(sin.sin_port)); + ret = -EINVAL; + goto out; + } + + nn = o2net_nn_from_num(node->nd_num); + + spin_lock(&nn->nn_lock); + if (nn->nn_sc) + ret = -EBUSY; + else + ret = 0; + spin_unlock(&nn->nn_lock); + if (ret) { + printk(KERN_NOTICE "o2net: Attempt to connect from node '%s' " + "at %pI4:%d but it already has an open connection\n", + node->nd_name, &sin.sin_addr.s_addr, + ntohs(sin.sin_port)); + goto out; + } + + sc = sc_alloc(node); + if (sc == NULL) { + ret = -ENOMEM; + goto out; + } + + sc->sc_sock = new_sock; + new_sock = NULL; + + spin_lock(&nn->nn_lock); + atomic_set(&nn->nn_timeout, 0); + o2net_set_nn_state(nn, sc, 0, 0); + spin_unlock(&nn->nn_lock); + + o2net_register_callbacks(sc->sc_sock->sk, sc); + o2net_sc_queue_work(sc, &sc->sc_rx_work); + + o2net_initialize_handshake(); + o2net_sendpage(sc, o2net_hand, sizeof(*o2net_hand)); + +out: + if (new_sock) + sock_release(new_sock); + if (node) + o2nm_node_put(node); + if (local_node) + o2nm_node_put(local_node); + if (sc) + sc_put(sc); + return ret; +} + +static void o2net_accept_many(struct work_struct *work) +{ + struct socket *sock = o2net_listen_sock; + while (o2net_accept_one(sock) == 0) + cond_resched(); +} + +static void o2net_listen_data_ready(struct sock *sk, int bytes) +{ + void (*ready)(struct sock *sk, int bytes); + + read_lock(&sk->sk_callback_lock); + ready = sk->sk_user_data; + if (ready == NULL) { /* check for teardown race */ + ready = sk->sk_data_ready; + goto out; + } + + /* ->sk_data_ready is also called for a newly established child socket + * before it has been accepted and the acceptor has set up their + * data_ready.. we only want to queue listen work for our listening + * socket */ + if (sk->sk_state == TCP_LISTEN) { + mlog(ML_TCP, "bytes: %d\n", bytes); + queue_work(o2net_wq, &o2net_listen_work); + } + +out: + read_unlock(&sk->sk_callback_lock); + ready(sk, bytes); +} + +static int o2net_open_listening_sock(__be32 addr, __be16 port) +{ + struct socket *sock = NULL; + int ret; + struct sockaddr_in sin = { + .sin_family = PF_INET, + .sin_addr = { .s_addr = addr }, + .sin_port = port, + }; + + ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock); + if (ret < 0) { + printk(KERN_ERR "o2net: Error %d while creating socket\n", ret); + goto out; + } + + sock->sk->sk_allocation = GFP_ATOMIC; + + write_lock_bh(&sock->sk->sk_callback_lock); + sock->sk->sk_user_data = sock->sk->sk_data_ready; + sock->sk->sk_data_ready = o2net_listen_data_ready; + write_unlock_bh(&sock->sk->sk_callback_lock); + + o2net_listen_sock = sock; + INIT_WORK(&o2net_listen_work, o2net_accept_many); + + sock->sk->sk_reuse = 1; + ret = sock->ops->bind(sock, (struct sockaddr *)&sin, sizeof(sin)); + if (ret < 0) { + printk(KERN_ERR "o2net: Error %d while binding socket at " + "%pI4:%u\n", ret, &addr, ntohs(port)); + goto out; + } + + ret = sock->ops->listen(sock, 64); + if (ret < 0) + printk(KERN_ERR "o2net: Error %d while listening on %pI4:%u\n", + ret, &addr, ntohs(port)); + +out: + if (ret) { + o2net_listen_sock = NULL; + if (sock) + sock_release(sock); + } + return ret; +} + +/* + * called from node manager when we should bring up our network listening + * socket. node manager handles all the serialization to only call this + * once and to match it with o2net_stop_listening(). note, + * o2nm_this_node() doesn't work yet as we're being called while it + * is being set up. + */ +int o2net_start_listening(struct o2nm_node *node) +{ + int ret = 0; + + BUG_ON(o2net_wq != NULL); + BUG_ON(o2net_listen_sock != NULL); + + mlog(ML_KTHREAD, "starting o2net thread...\n"); + o2net_wq = create_singlethread_workqueue("o2net"); + if (o2net_wq == NULL) { + mlog(ML_ERROR, "unable to launch o2net thread\n"); + return -ENOMEM; /* ? */ + } + + ret = o2net_open_listening_sock(node->nd_ipv4_address, + node->nd_ipv4_port); + if (ret) { + destroy_workqueue(o2net_wq); + o2net_wq = NULL; + } else + o2quo_conn_up(node->nd_num); + + return ret; +} + +/* again, o2nm_this_node() doesn't work here as we're involved in + * tearing it down */ +void o2net_stop_listening(struct o2nm_node *node) +{ + struct socket *sock = o2net_listen_sock; + size_t i; + + BUG_ON(o2net_wq == NULL); + BUG_ON(o2net_listen_sock == NULL); + + /* stop the listening socket from generating work */ + write_lock_bh(&sock->sk->sk_callback_lock); + sock->sk->sk_data_ready = sock->sk->sk_user_data; + sock->sk->sk_user_data = NULL; + write_unlock_bh(&sock->sk->sk_callback_lock); + + for (i = 0; i < ARRAY_SIZE(o2net_nodes); i++) { + struct o2nm_node *node = o2nm_get_node_by_num(i); + if (node) { + o2net_disconnect_node(node); + o2nm_node_put(node); + } + } + + /* finish all work and tear down the work queue */ + mlog(ML_KTHREAD, "waiting for o2net thread to exit....\n"); + destroy_workqueue(o2net_wq); + o2net_wq = NULL; + + sock_release(o2net_listen_sock); + o2net_listen_sock = NULL; + + o2quo_conn_err(node->nd_num); +} + +/* ------------------------------------------------------------ */ + +int o2net_init(void) +{ + unsigned long i; + + o2quo_init(); + + if (o2net_debugfs_init()) + return -ENOMEM; + + o2net_hand = kzalloc(sizeof(struct o2net_handshake), GFP_KERNEL); + o2net_keep_req = kzalloc(sizeof(struct o2net_msg), GFP_KERNEL); + o2net_keep_resp = kzalloc(sizeof(struct o2net_msg), GFP_KERNEL); + if (!o2net_hand || !o2net_keep_req || !o2net_keep_resp) { + kfree(o2net_hand); + kfree(o2net_keep_req); + kfree(o2net_keep_resp); + return -ENOMEM; + } + + o2net_hand->protocol_version = cpu_to_be64(O2NET_PROTOCOL_VERSION); + o2net_hand->connector_id = cpu_to_be64(1); + + o2net_keep_req->magic = cpu_to_be16(O2NET_MSG_KEEP_REQ_MAGIC); + o2net_keep_resp->magic = cpu_to_be16(O2NET_MSG_KEEP_RESP_MAGIC); + + for (i = 0; i < ARRAY_SIZE(o2net_nodes); i++) { + struct o2net_node *nn = o2net_nn_from_num(i); + + atomic_set(&nn->nn_timeout, 0); + spin_lock_init(&nn->nn_lock); + INIT_DELAYED_WORK(&nn->nn_connect_work, o2net_start_connect); + INIT_DELAYED_WORK(&nn->nn_connect_expired, + o2net_connect_expired); + INIT_DELAYED_WORK(&nn->nn_still_up, o2net_still_up); + /* until we see hb from a node we'll return einval */ + nn->nn_persistent_error = -ENOTCONN; + init_waitqueue_head(&nn->nn_sc_wq); + idr_init(&nn->nn_status_idr); + INIT_LIST_HEAD(&nn->nn_status_list); + } + + return 0; +} + +void o2net_exit(void) +{ + o2quo_exit(); + kfree(o2net_hand); + kfree(o2net_keep_req); + kfree(o2net_keep_resp); + o2net_debugfs_exit(); +} diff --git a/drivers/staging/ramster/cluster/tcp.h b/drivers/staging/ramster/cluster/tcp.h new file mode 100644 index 00000000000..5bada2a69b5 --- /dev/null +++ b/drivers/staging/ramster/cluster/tcp.h @@ -0,0 +1,154 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * tcp.h + * + * Function prototypes + * + * Copyright (C) 2004 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + * + */ + +#ifndef O2CLUSTER_TCP_H +#define O2CLUSTER_TCP_H + +#include +#ifdef __KERNEL__ +#include +#include +#else +#include +#endif +#include +#include + +struct o2net_msg +{ + __be16 magic; + __be16 data_len; + __be16 msg_type; + __be16 pad1; + __be32 sys_status; + __be32 status; + __be32 key; + __be32 msg_num; + __u8 buf[0]; +}; + +typedef int (o2net_msg_handler_func)(struct o2net_msg *msg, u32 len, void *data, + void **ret_data); +typedef void (o2net_post_msg_handler_func)(int status, void *data, + void *ret_data); + +#define O2NET_MAX_PAYLOAD_BYTES (4096 - sizeof(struct o2net_msg)) + +/* same as hb delay, we're waiting for another node to recognize our hb */ +#define O2NET_RECONNECT_DELAY_MS_DEFAULT 2000 + +#define O2NET_KEEPALIVE_DELAY_MS_DEFAULT 2000 +#define O2NET_IDLE_TIMEOUT_MS_DEFAULT 30000 + + +/* TODO: figure this out.... */ +static inline int o2net_link_down(int err, struct socket *sock) +{ + if (sock) { + if (sock->sk->sk_state != TCP_ESTABLISHED && + sock->sk->sk_state != TCP_CLOSE_WAIT) + return 1; + } + + if (err >= 0) + return 0; + switch (err) { + /* ????????????????????????? */ + case -ERESTARTSYS: + case -EBADF: + /* When the server has died, an ICMP port unreachable + * message prompts ECONNREFUSED. */ + case -ECONNREFUSED: + case -ENOTCONN: + case -ECONNRESET: + case -EPIPE: + return 1; + } + return 0; +} + +enum { + O2NET_DRIVER_UNINITED, + O2NET_DRIVER_READY, +}; + +int o2net_send_message(u32 msg_type, u32 key, void *data, u32 len, + u8 target_node, int *status); +int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *vec, + size_t veclen, u8 target_node, int *status); + +int o2net_register_handler(u32 msg_type, u32 key, u32 max_len, + o2net_msg_handler_func *func, void *data, + o2net_post_msg_handler_func *post_func, + struct list_head *unreg_list); +void o2net_unregister_handler_list(struct list_head *list); + +void o2net_fill_node_map(unsigned long *map, unsigned bytes); + +struct o2nm_node; +int o2net_register_hb_callbacks(void); +void o2net_unregister_hb_callbacks(void); +int o2net_start_listening(struct o2nm_node *node); +void o2net_stop_listening(struct o2nm_node *node); +void o2net_disconnect_node(struct o2nm_node *node); +int o2net_num_connected_peers(void); + +int o2net_init(void); +void o2net_exit(void); + +struct o2net_send_tracking; +struct o2net_sock_container; + +#ifdef CONFIG_DEBUG_FS +int o2net_debugfs_init(void); +void o2net_debugfs_exit(void); +void o2net_debug_add_nst(struct o2net_send_tracking *nst); +void o2net_debug_del_nst(struct o2net_send_tracking *nst); +void o2net_debug_add_sc(struct o2net_sock_container *sc); +void o2net_debug_del_sc(struct o2net_sock_container *sc); +#else +static inline int o2net_debugfs_init(void) +{ + return 0; +} +static inline void o2net_debugfs_exit(void) +{ +} +static inline void o2net_debug_add_nst(struct o2net_send_tracking *nst) +{ +} +static inline void o2net_debug_del_nst(struct o2net_send_tracking *nst) +{ +} +static inline void o2net_debug_add_sc(struct o2net_sock_container *sc) +{ +} +static inline void o2net_debug_del_sc(struct o2net_sock_container *sc) +{ +} +#endif /* CONFIG_DEBUG_FS */ + +#endif /* O2CLUSTER_TCP_H */ diff --git a/drivers/staging/ramster/cluster/tcp_internal.h b/drivers/staging/ramster/cluster/tcp_internal.h new file mode 100644 index 00000000000..4cbcb65784a --- /dev/null +++ b/drivers/staging/ramster/cluster/tcp_internal.h @@ -0,0 +1,242 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * Copyright (C) 2005 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ + +#ifndef O2CLUSTER_TCP_INTERNAL_H +#define O2CLUSTER_TCP_INTERNAL_H + +#define O2NET_MSG_MAGIC ((u16)0xfa55) +#define O2NET_MSG_STATUS_MAGIC ((u16)0xfa56) +#define O2NET_MSG_KEEP_REQ_MAGIC ((u16)0xfa57) +#define O2NET_MSG_KEEP_RESP_MAGIC ((u16)0xfa58) + +/* we're delaying our quorum decision so that heartbeat will have timed + * out truly dead nodes by the time we come around to making decisions + * on their number */ +#define O2NET_QUORUM_DELAY_MS ((o2hb_dead_threshold + 2) * O2HB_REGION_TIMEOUT_MS) + +/* + * This version number represents quite a lot, unfortunately. It not + * only represents the raw network message protocol on the wire but also + * locking semantics of the file system using the protocol. It should + * be somewhere else, I'm sure, but right now it isn't. + * + * With version 11, we separate out the filesystem locking portion. The + * filesystem now has a major.minor version it negotiates. Version 11 + * introduces this negotiation to the o2dlm protocol, and as such the + * version here in tcp_internal.h should not need to be bumped for + * filesystem locking changes. + * + * New in version 11 + * - Negotiation of filesystem locking in the dlm join. + * + * New in version 10: + * - Meta/data locks combined + * + * New in version 9: + * - All votes removed + * + * New in version 8: + * - Replace delete inode votes with a cluster lock + * + * New in version 7: + * - DLM join domain includes the live nodemap + * + * New in version 6: + * - DLM lockres remote refcount fixes. + * + * New in version 5: + * - Network timeout checking protocol + * + * New in version 4: + * - Remove i_generation from lock names for better stat performance. + * + * New in version 3: + * - Replace dentry votes with a cluster lock + * + * New in version 2: + * - full 64 bit i_size in the metadata lock lvbs + * - introduction of "rw" lock and pushing meta/data locking down + */ +#define O2NET_PROTOCOL_VERSION 11ULL +struct o2net_handshake { + __be64 protocol_version; + __be64 connector_id; + __be32 o2hb_heartbeat_timeout_ms; + __be32 o2net_idle_timeout_ms; + __be32 o2net_keepalive_delay_ms; + __be32 o2net_reconnect_delay_ms; +}; + +struct o2net_node { + /* this is never called from int/bh */ + spinlock_t nn_lock; + + /* set the moment an sc is allocated and a connect is started */ + struct o2net_sock_container *nn_sc; + /* _valid is only set after the handshake passes and tx can happen */ + unsigned nn_sc_valid:1; + /* if this is set tx just returns it */ + int nn_persistent_error; + /* It is only set to 1 after the idle time out. */ + atomic_t nn_timeout; + + /* threads waiting for an sc to arrive wait on the wq for generation + * to increase. it is increased when a connecting socket succeeds + * or fails or when an accepted socket is attached. */ + wait_queue_head_t nn_sc_wq; + + struct idr nn_status_idr; + struct list_head nn_status_list; + + /* connects are attempted from when heartbeat comes up until either hb + * goes down, the node is unconfigured, no connect attempts succeed + * before O2NET_CONN_IDLE_DELAY, or a connect succeeds. connect_work + * is queued from set_nn_state both from hb up and from itself if a + * connect attempt fails and so can be self-arming. shutdown is + * careful to first mark the nn such that no connects will be attempted + * before canceling delayed connect work and flushing the queue. */ + struct delayed_work nn_connect_work; + unsigned long nn_last_connect_attempt; + + /* this is queued as nodes come up and is canceled when a connection is + * established. this expiring gives up on the node and errors out + * transmits */ + struct delayed_work nn_connect_expired; + + /* after we give up on a socket we wait a while before deciding + * that it is still heartbeating and that we should do some + * quorum work */ + struct delayed_work nn_still_up; +}; + +struct o2net_sock_container { + struct kref sc_kref; + /* the next two are valid for the life time of the sc */ + struct socket *sc_sock; + struct o2nm_node *sc_node; + + /* all of these sc work structs hold refs on the sc while they are + * queued. they should not be able to ref a freed sc. the teardown + * race is with o2net_wq destruction in o2net_stop_listening() */ + + /* rx and connect work are generated from socket callbacks. sc + * shutdown removes the callbacks and then flushes the work queue */ + struct work_struct sc_rx_work; + struct work_struct sc_connect_work; + /* shutdown work is triggered in two ways. the simple way is + * for a code path calls ensure_shutdown which gets a lock, removes + * the sc from the nn, and queues the work. in this case the + * work is single-shot. the work is also queued from a sock + * callback, though, and in this case the work will find the sc + * still on the nn and will call ensure_shutdown itself.. this + * ends up triggering the shutdown work again, though nothing + * will be done in that second iteration. so work queue teardown + * has to be careful to remove the sc from the nn before waiting + * on the work queue so that the shutdown work doesn't remove the + * sc and rearm itself. + */ + struct work_struct sc_shutdown_work; + + struct timer_list sc_idle_timeout; + struct delayed_work sc_keepalive_work; + + unsigned sc_handshake_ok:1; + + struct page *sc_page; + size_t sc_page_off; + + /* original handlers for the sockets */ + void (*sc_state_change)(struct sock *sk); + void (*sc_data_ready)(struct sock *sk, int bytes); + + u32 sc_msg_key; + u16 sc_msg_type; + +#ifdef CONFIG_DEBUG_FS + struct list_head sc_net_debug_item; + ktime_t sc_tv_timer; + ktime_t sc_tv_data_ready; + ktime_t sc_tv_advance_start; + ktime_t sc_tv_advance_stop; + ktime_t sc_tv_func_start; + ktime_t sc_tv_func_stop; +#endif +#ifdef CONFIG_OCFS2_FS_STATS + ktime_t sc_tv_acquiry_total; + ktime_t sc_tv_send_total; + ktime_t sc_tv_status_total; + u32 sc_send_count; + u32 sc_recv_count; + ktime_t sc_tv_process_total; +#endif + struct mutex sc_send_lock; +}; + +struct o2net_msg_handler { + struct rb_node nh_node; + u32 nh_max_len; + u32 nh_msg_type; + u32 nh_key; + o2net_msg_handler_func *nh_func; + o2net_msg_handler_func *nh_func_data; + o2net_post_msg_handler_func + *nh_post_func; + struct kref nh_kref; + struct list_head nh_unregister_item; +}; + +enum o2net_system_error { + O2NET_ERR_NONE = 0, + O2NET_ERR_NO_HNDLR, + O2NET_ERR_OVERFLOW, + O2NET_ERR_DIED, + O2NET_ERR_MAX +}; + +struct o2net_status_wait { + enum o2net_system_error ns_sys_status; + s32 ns_status; + int ns_id; + wait_queue_head_t ns_wq; + struct list_head ns_node_item; +}; + +#ifdef CONFIG_DEBUG_FS +/* just for state dumps */ +struct o2net_send_tracking { + struct list_head st_net_debug_item; + struct task_struct *st_task; + struct o2net_sock_container *st_sc; + u32 st_id; + u32 st_msg_type; + u32 st_msg_key; + u8 st_node; + ktime_t st_sock_time; + ktime_t st_send_time; + ktime_t st_status_time; +}; +#else +struct o2net_send_tracking { + u32 dummy; +}; +#endif /* CONFIG_DEBUG_FS */ + +#endif /* O2CLUSTER_TCP_INTERNAL_H */ diff --git a/drivers/staging/ramster/cluster/ver.c b/drivers/staging/ramster/cluster/ver.c new file mode 100644 index 00000000000..a56eee6abad --- /dev/null +++ b/drivers/staging/ramster/cluster/ver.c @@ -0,0 +1,42 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * ver.c + * + * version string + * + * Copyright (C) 2002, 2005 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ + +#include +#include + +#include "ver.h" + +#define CLUSTER_BUILD_VERSION "1.5.0" + +#define VERSION_STR "OCFS2 Node Manager " CLUSTER_BUILD_VERSION + +void cluster_print_version(void) +{ + printk(KERN_INFO "%s\n", VERSION_STR); +} + +MODULE_DESCRIPTION(VERSION_STR); + +MODULE_VERSION(CLUSTER_BUILD_VERSION); diff --git a/drivers/staging/ramster/cluster/ver.h b/drivers/staging/ramster/cluster/ver.h new file mode 100644 index 00000000000..32554c3382c --- /dev/null +++ b/drivers/staging/ramster/cluster/ver.h @@ -0,0 +1,31 @@ +/* -*- mode: c; c-basic-offset: 8; -*- + * vim: noexpandtab sw=8 ts=8 sts=0: + * + * ver.h + * + * Function prototypes + * + * Copyright (C) 2005 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ + +#ifndef O2CLUSTER_VER_H +#define O2CLUSTER_VER_H + +void cluster_print_version(void); + +#endif /* O2CLUSTER_VER_H */ -- cgit v1.2.3-70-g09d2 From ba351b02ab11616b08b9220dacd49b20415b1f80 Mon Sep 17 00:00:00 2001 From: Dan Magenheimer Date: Mon, 30 Jan 2012 14:39:18 -0800 Subject: staging: ramster: local compression + tmem Copy files from drivers/staging/zcache. Ramster compresses pages locally before transmitting them to another node, so we can leverage the zcache and tmem code directly. Note: there are no ramster-specific changes yet to these files. (Why copy? The ramster tmem.c/tmem.h changes are definitely shareable between zcache and ramster; the eventual destination for tmem.c is the linux lib directory. Ramster changes to zcache are more substantial and zcache is currently undergoing some significant unrelated changes (including a new allocator and breaking zcache-main.c into smaller files), so it seemed best to branch temporarily and merge later.) Signed-off-by: Dan Magenheimer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ramster/Kconfig | 13 + drivers/staging/ramster/Makefile | 3 + drivers/staging/ramster/tmem.c | 770 +++++++++++++ drivers/staging/ramster/tmem.h | 206 ++++ drivers/staging/ramster/zcache-main.c | 1988 +++++++++++++++++++++++++++++++++ 5 files changed, 2980 insertions(+) create mode 100644 drivers/staging/ramster/Kconfig create mode 100644 drivers/staging/ramster/Makefile create mode 100644 drivers/staging/ramster/tmem.c create mode 100644 drivers/staging/ramster/tmem.h create mode 100644 drivers/staging/ramster/zcache-main.c (limited to 'drivers') diff --git a/drivers/staging/ramster/Kconfig b/drivers/staging/ramster/Kconfig new file mode 100644 index 00000000000..7fabcb2bc80 --- /dev/null +++ b/drivers/staging/ramster/Kconfig @@ -0,0 +1,13 @@ +config ZCACHE + tristate "Dynamic compression of swap pages and clean pagecache pages" + depends on CLEANCACHE || FRONTSWAP + select XVMALLOC + select LZO_COMPRESS + select LZO_DECOMPRESS + default n + help + Zcache doubles RAM efficiency while providing a significant + performance boosts on many workloads. Zcache uses lzo1x + compression and an in-kernel implementation of transcendent + memory to store clean page cache pages and swap in RAM, + providing a noticeable reduction in disk I/O. diff --git a/drivers/staging/ramster/Makefile b/drivers/staging/ramster/Makefile new file mode 100644 index 00000000000..60daa272c20 --- /dev/null +++ b/drivers/staging/ramster/Makefile @@ -0,0 +1,3 @@ +zcache-y := zcache-main.o tmem.o + +obj-$(CONFIG_ZCACHE) += zcache.o diff --git a/drivers/staging/ramster/tmem.c b/drivers/staging/ramster/tmem.c new file mode 100644 index 00000000000..1ca66ea9b28 --- /dev/null +++ b/drivers/staging/ramster/tmem.c @@ -0,0 +1,770 @@ +/* + * In-kernel transcendent memory (generic implementation) + * + * Copyright (c) 2009-2011, Dan Magenheimer, Oracle Corp. + * + * The primary purpose of Transcedent Memory ("tmem") is to map object-oriented + * "handles" (triples containing a pool id, and object id, and an index), to + * pages in a page-accessible memory (PAM). Tmem references the PAM pages via + * an abstract "pampd" (PAM page-descriptor), which can be operated on by a + * set of functions (pamops). Each pampd contains some representation of + * PAGE_SIZE bytes worth of data. Tmem must support potentially millions of + * pages and must be able to insert, find, and delete these pages at a + * potential frequency of thousands per second concurrently across many CPUs, + * (and, if used with KVM, across many vcpus across many guests). + * Tmem is tracked with a hierarchy of data structures, organized by + * the elements in a handle-tuple: pool_id, object_id, and page index. + * One or more "clients" (e.g. guests) each provide one or more tmem_pools. + * Each pool, contains a hash table of rb_trees of tmem_objs. Each + * tmem_obj contains a radix-tree-like tree of pointers, with intermediate + * nodes called tmem_objnodes. Each leaf pointer in this tree points to + * a pampd, which is accessible only through a small set of callbacks + * registered by the PAM implementation (see tmem_register_pamops). Tmem + * does all memory allocation via a set of callbacks registered by the tmem + * host implementation (e.g. see tmem_register_hostops). + */ + +#include +#include +#include + +#include "tmem.h" + +/* data structure sentinels used for debugging... see tmem.h */ +#define POOL_SENTINEL 0x87658765 +#define OBJ_SENTINEL 0x12345678 +#define OBJNODE_SENTINEL 0xfedcba09 + +/* + * A tmem host implementation must use this function to register callbacks + * for memory allocation. + */ +static struct tmem_hostops tmem_hostops; + +static void tmem_objnode_tree_init(void); + +void tmem_register_hostops(struct tmem_hostops *m) +{ + tmem_objnode_tree_init(); + tmem_hostops = *m; +} + +/* + * A tmem host implementation must use this function to register + * callbacks for a page-accessible memory (PAM) implementation + */ +static struct tmem_pamops tmem_pamops; + +void tmem_register_pamops(struct tmem_pamops *m) +{ + tmem_pamops = *m; +} + +/* + * Oid's are potentially very sparse and tmem_objs may have an indeterminately + * short life, being added and deleted at a relatively high frequency. + * So an rb_tree is an ideal data structure to manage tmem_objs. But because + * of the potentially huge number of tmem_objs, each pool manages a hashtable + * of rb_trees to reduce search, insert, delete, and rebalancing time. + * Each hashbucket also has a lock to manage concurrent access. + * + * The following routines manage tmem_objs. When any tmem_obj is accessed, + * the hashbucket lock must be held. + */ + +/* searches for object==oid in pool, returns locked object if found */ +static struct tmem_obj *tmem_obj_find(struct tmem_hashbucket *hb, + struct tmem_oid *oidp) +{ + struct rb_node *rbnode; + struct tmem_obj *obj; + + rbnode = hb->obj_rb_root.rb_node; + while (rbnode) { + BUG_ON(RB_EMPTY_NODE(rbnode)); + obj = rb_entry(rbnode, struct tmem_obj, rb_tree_node); + switch (tmem_oid_compare(oidp, &obj->oid)) { + case 0: /* equal */ + goto out; + case -1: + rbnode = rbnode->rb_left; + break; + case 1: + rbnode = rbnode->rb_right; + break; + } + } + obj = NULL; +out: + return obj; +} + +static void tmem_pampd_destroy_all_in_obj(struct tmem_obj *); + +/* free an object that has no more pampds in it */ +static void tmem_obj_free(struct tmem_obj *obj, struct tmem_hashbucket *hb) +{ + struct tmem_pool *pool; + + BUG_ON(obj == NULL); + ASSERT_SENTINEL(obj, OBJ); + BUG_ON(obj->pampd_count > 0); + pool = obj->pool; + BUG_ON(pool == NULL); + if (obj->objnode_tree_root != NULL) /* may be "stump" with no leaves */ + tmem_pampd_destroy_all_in_obj(obj); + BUG_ON(obj->objnode_tree_root != NULL); + BUG_ON((long)obj->objnode_count != 0); + atomic_dec(&pool->obj_count); + BUG_ON(atomic_read(&pool->obj_count) < 0); + INVERT_SENTINEL(obj, OBJ); + obj->pool = NULL; + tmem_oid_set_invalid(&obj->oid); + rb_erase(&obj->rb_tree_node, &hb->obj_rb_root); +} + +/* + * initialize, and insert an tmem_object_root (called only if find failed) + */ +static void tmem_obj_init(struct tmem_obj *obj, struct tmem_hashbucket *hb, + struct tmem_pool *pool, + struct tmem_oid *oidp) +{ + struct rb_root *root = &hb->obj_rb_root; + struct rb_node **new = &(root->rb_node), *parent = NULL; + struct tmem_obj *this; + + BUG_ON(pool == NULL); + atomic_inc(&pool->obj_count); + obj->objnode_tree_height = 0; + obj->objnode_tree_root = NULL; + obj->pool = pool; + obj->oid = *oidp; + obj->objnode_count = 0; + obj->pampd_count = 0; + (*tmem_pamops.new_obj)(obj); + SET_SENTINEL(obj, OBJ); + while (*new) { + BUG_ON(RB_EMPTY_NODE(*new)); + this = rb_entry(*new, struct tmem_obj, rb_tree_node); + parent = *new; + switch (tmem_oid_compare(oidp, &this->oid)) { + case 0: + BUG(); /* already present; should never happen! */ + break; + case -1: + new = &(*new)->rb_left; + break; + case 1: + new = &(*new)->rb_right; + break; + } + } + rb_link_node(&obj->rb_tree_node, parent, new); + rb_insert_color(&obj->rb_tree_node, root); +} + +/* + * Tmem is managed as a set of tmem_pools with certain attributes, such as + * "ephemeral" vs "persistent". These attributes apply to all tmem_objs + * and all pampds that belong to a tmem_pool. A tmem_pool is created + * or deleted relatively rarely (for example, when a filesystem is + * mounted or unmounted. + */ + +/* flush all data from a pool and, optionally, free it */ +static void tmem_pool_flush(struct tmem_pool *pool, bool destroy) +{ + struct rb_node *rbnode; + struct tmem_obj *obj; + struct tmem_hashbucket *hb = &pool->hashbucket[0]; + int i; + + BUG_ON(pool == NULL); + for (i = 0; i < TMEM_HASH_BUCKETS; i++, hb++) { + spin_lock(&hb->lock); + rbnode = rb_first(&hb->obj_rb_root); + while (rbnode != NULL) { + obj = rb_entry(rbnode, struct tmem_obj, rb_tree_node); + rbnode = rb_next(rbnode); + tmem_pampd_destroy_all_in_obj(obj); + tmem_obj_free(obj, hb); + (*tmem_hostops.obj_free)(obj, pool); + } + spin_unlock(&hb->lock); + } + if (destroy) + list_del(&pool->pool_list); +} + +/* + * A tmem_obj contains a radix-tree-like tree in which the intermediate + * nodes are called tmem_objnodes. (The kernel lib/radix-tree.c implementation + * is very specialized and tuned for specific uses and is not particularly + * suited for use from this code, though some code from the core algorithms has + * been reused, thus the copyright notices below). Each tmem_objnode contains + * a set of pointers which point to either a set of intermediate tmem_objnodes + * or a set of of pampds. + * + * Portions Copyright (C) 2001 Momchil Velikov + * Portions Copyright (C) 2001 Christoph Hellwig + * Portions Copyright (C) 2005 SGI, Christoph Lameter + */ + +struct tmem_objnode_tree_path { + struct tmem_objnode *objnode; + int offset; +}; + +/* objnode height_to_maxindex translation */ +static unsigned long tmem_objnode_tree_h2max[OBJNODE_TREE_MAX_PATH + 1]; + +static void tmem_objnode_tree_init(void) +{ + unsigned int ht, tmp; + + for (ht = 0; ht < ARRAY_SIZE(tmem_objnode_tree_h2max); ht++) { + tmp = ht * OBJNODE_TREE_MAP_SHIFT; + if (tmp >= OBJNODE_TREE_INDEX_BITS) + tmem_objnode_tree_h2max[ht] = ~0UL; + else + tmem_objnode_tree_h2max[ht] = + (~0UL >> (OBJNODE_TREE_INDEX_BITS - tmp - 1)) >> 1; + } +} + +static struct tmem_objnode *tmem_objnode_alloc(struct tmem_obj *obj) +{ + struct tmem_objnode *objnode; + + ASSERT_SENTINEL(obj, OBJ); + BUG_ON(obj->pool == NULL); + ASSERT_SENTINEL(obj->pool, POOL); + objnode = (*tmem_hostops.objnode_alloc)(obj->pool); + if (unlikely(objnode == NULL)) + goto out; + objnode->obj = obj; + SET_SENTINEL(objnode, OBJNODE); + memset(&objnode->slots, 0, sizeof(objnode->slots)); + objnode->slots_in_use = 0; + obj->objnode_count++; +out: + return objnode; +} + +static void tmem_objnode_free(struct tmem_objnode *objnode) +{ + struct tmem_pool *pool; + int i; + + BUG_ON(objnode == NULL); + for (i = 0; i < OBJNODE_TREE_MAP_SIZE; i++) + BUG_ON(objnode->slots[i] != NULL); + ASSERT_SENTINEL(objnode, OBJNODE); + INVERT_SENTINEL(objnode, OBJNODE); + BUG_ON(objnode->obj == NULL); + ASSERT_SENTINEL(objnode->obj, OBJ); + pool = objnode->obj->pool; + BUG_ON(pool == NULL); + ASSERT_SENTINEL(pool, POOL); + objnode->obj->objnode_count--; + objnode->obj = NULL; + (*tmem_hostops.objnode_free)(objnode, pool); +} + +/* + * lookup index in object and return associated pampd (or NULL if not found) + */ +static void **__tmem_pampd_lookup_in_obj(struct tmem_obj *obj, uint32_t index) +{ + unsigned int height, shift; + struct tmem_objnode **slot = NULL; + + BUG_ON(obj == NULL); + ASSERT_SENTINEL(obj, OBJ); + BUG_ON(obj->pool == NULL); + ASSERT_SENTINEL(obj->pool, POOL); + + height = obj->objnode_tree_height; + if (index > tmem_objnode_tree_h2max[obj->objnode_tree_height]) + goto out; + if (height == 0 && obj->objnode_tree_root) { + slot = &obj->objnode_tree_root; + goto out; + } + shift = (height-1) * OBJNODE_TREE_MAP_SHIFT; + slot = &obj->objnode_tree_root; + while (height > 0) { + if (*slot == NULL) + goto out; + slot = (struct tmem_objnode **) + ((*slot)->slots + + ((index >> shift) & OBJNODE_TREE_MAP_MASK)); + shift -= OBJNODE_TREE_MAP_SHIFT; + height--; + } +out: + return slot != NULL ? (void **)slot : NULL; +} + +static void *tmem_pampd_lookup_in_obj(struct tmem_obj *obj, uint32_t index) +{ + struct tmem_objnode **slot; + + slot = (struct tmem_objnode **)__tmem_pampd_lookup_in_obj(obj, index); + return slot != NULL ? *slot : NULL; +} + +static void *tmem_pampd_replace_in_obj(struct tmem_obj *obj, uint32_t index, + void *new_pampd) +{ + struct tmem_objnode **slot; + void *ret = NULL; + + slot = (struct tmem_objnode **)__tmem_pampd_lookup_in_obj(obj, index); + if ((slot != NULL) && (*slot != NULL)) { + void *old_pampd = *(void **)slot; + *(void **)slot = new_pampd; + (*tmem_pamops.free)(old_pampd, obj->pool, NULL, 0); + ret = new_pampd; + } + return ret; +} + +static int tmem_pampd_add_to_obj(struct tmem_obj *obj, uint32_t index, + void *pampd) +{ + int ret = 0; + struct tmem_objnode *objnode = NULL, *newnode, *slot; + unsigned int height, shift; + int offset = 0; + + /* if necessary, extend the tree to be higher */ + if (index > tmem_objnode_tree_h2max[obj->objnode_tree_height]) { + height = obj->objnode_tree_height + 1; + if (index > tmem_objnode_tree_h2max[height]) + while (index > tmem_objnode_tree_h2max[height]) + height++; + if (obj->objnode_tree_root == NULL) { + obj->objnode_tree_height = height; + goto insert; + } + do { + newnode = tmem_objnode_alloc(obj); + if (!newnode) { + ret = -ENOMEM; + goto out; + } + newnode->slots[0] = obj->objnode_tree_root; + newnode->slots_in_use = 1; + obj->objnode_tree_root = newnode; + obj->objnode_tree_height++; + } while (height > obj->objnode_tree_height); + } +insert: + slot = obj->objnode_tree_root; + height = obj->objnode_tree_height; + shift = (height-1) * OBJNODE_TREE_MAP_SHIFT; + while (height > 0) { + if (slot == NULL) { + /* add a child objnode. */ + slot = tmem_objnode_alloc(obj); + if (!slot) { + ret = -ENOMEM; + goto out; + } + if (objnode) { + + objnode->slots[offset] = slot; + objnode->slots_in_use++; + } else + obj->objnode_tree_root = slot; + } + /* go down a level */ + offset = (index >> shift) & OBJNODE_TREE_MAP_MASK; + objnode = slot; + slot = objnode->slots[offset]; + shift -= OBJNODE_TREE_MAP_SHIFT; + height--; + } + BUG_ON(slot != NULL); + if (objnode) { + objnode->slots_in_use++; + objnode->slots[offset] = pampd; + } else + obj->objnode_tree_root = pampd; + obj->pampd_count++; +out: + return ret; +} + +static void *tmem_pampd_delete_from_obj(struct tmem_obj *obj, uint32_t index) +{ + struct tmem_objnode_tree_path path[OBJNODE_TREE_MAX_PATH + 1]; + struct tmem_objnode_tree_path *pathp = path; + struct tmem_objnode *slot = NULL; + unsigned int height, shift; + int offset; + + BUG_ON(obj == NULL); + ASSERT_SENTINEL(obj, OBJ); + BUG_ON(obj->pool == NULL); + ASSERT_SENTINEL(obj->pool, POOL); + height = obj->objnode_tree_height; + if (index > tmem_objnode_tree_h2max[height]) + goto out; + slot = obj->objnode_tree_root; + if (height == 0 && obj->objnode_tree_root) { + obj->objnode_tree_root = NULL; + goto out; + } + shift = (height - 1) * OBJNODE_TREE_MAP_SHIFT; + pathp->objnode = NULL; + do { + if (slot == NULL) + goto out; + pathp++; + offset = (index >> shift) & OBJNODE_TREE_MAP_MASK; + pathp->offset = offset; + pathp->objnode = slot; + slot = slot->slots[offset]; + shift -= OBJNODE_TREE_MAP_SHIFT; + height--; + } while (height > 0); + if (slot == NULL) + goto out; + while (pathp->objnode) { + pathp->objnode->slots[pathp->offset] = NULL; + pathp->objnode->slots_in_use--; + if (pathp->objnode->slots_in_use) { + if (pathp->objnode == obj->objnode_tree_root) { + while (obj->objnode_tree_height > 0 && + obj->objnode_tree_root->slots_in_use == 1 && + obj->objnode_tree_root->slots[0]) { + struct tmem_objnode *to_free = + obj->objnode_tree_root; + + obj->objnode_tree_root = + to_free->slots[0]; + obj->objnode_tree_height--; + to_free->slots[0] = NULL; + to_free->slots_in_use = 0; + tmem_objnode_free(to_free); + } + } + goto out; + } + tmem_objnode_free(pathp->objnode); /* 0 slots used, free it */ + pathp--; + } + obj->objnode_tree_height = 0; + obj->objnode_tree_root = NULL; + +out: + if (slot != NULL) + obj->pampd_count--; + BUG_ON(obj->pampd_count < 0); + return slot; +} + +/* recursively walk the objnode_tree destroying pampds and objnodes */ +static void tmem_objnode_node_destroy(struct tmem_obj *obj, + struct tmem_objnode *objnode, + unsigned int ht) +{ + int i; + + if (ht == 0) + return; + for (i = 0; i < OBJNODE_TREE_MAP_SIZE; i++) { + if (objnode->slots[i]) { + if (ht == 1) { + obj->pampd_count--; + (*tmem_pamops.free)(objnode->slots[i], + obj->pool, NULL, 0); + objnode->slots[i] = NULL; + continue; + } + tmem_objnode_node_destroy(obj, objnode->slots[i], ht-1); + tmem_objnode_free(objnode->slots[i]); + objnode->slots[i] = NULL; + } + } +} + +static void tmem_pampd_destroy_all_in_obj(struct tmem_obj *obj) +{ + if (obj->objnode_tree_root == NULL) + return; + if (obj->objnode_tree_height == 0) { + obj->pampd_count--; + (*tmem_pamops.free)(obj->objnode_tree_root, obj->pool, NULL, 0); + } else { + tmem_objnode_node_destroy(obj, obj->objnode_tree_root, + obj->objnode_tree_height); + tmem_objnode_free(obj->objnode_tree_root); + obj->objnode_tree_height = 0; + } + obj->objnode_tree_root = NULL; + (*tmem_pamops.free_obj)(obj->pool, obj); +} + +/* + * Tmem is operated on by a set of well-defined actions: + * "put", "get", "flush", "flush_object", "new pool" and "destroy pool". + * (The tmem ABI allows for subpages and exchanges but these operations + * are not included in this implementation.) + * + * These "tmem core" operations are implemented in the following functions. + */ + +/* + * "Put" a page, e.g. copy a page from the kernel into newly allocated + * PAM space (if such space is available). Tmem_put is complicated by + * a corner case: What if a page with matching handle already exists in + * tmem? To guarantee coherency, one of two actions is necessary: Either + * the data for the page must be overwritten, or the page must be + * "flushed" so that the data is not accessible to a subsequent "get". + * Since these "duplicate puts" are relatively rare, this implementation + * always flushes for simplicity. + */ +int tmem_put(struct tmem_pool *pool, struct tmem_oid *oidp, uint32_t index, + char *data, size_t size, bool raw, bool ephemeral) +{ + struct tmem_obj *obj = NULL, *objfound = NULL, *objnew = NULL; + void *pampd = NULL, *pampd_del = NULL; + int ret = -ENOMEM; + struct tmem_hashbucket *hb; + + hb = &pool->hashbucket[tmem_oid_hash(oidp)]; + spin_lock(&hb->lock); + obj = objfound = tmem_obj_find(hb, oidp); + if (obj != NULL) { + pampd = tmem_pampd_lookup_in_obj(objfound, index); + if (pampd != NULL) { + /* if found, is a dup put, flush the old one */ + pampd_del = tmem_pampd_delete_from_obj(obj, index); + BUG_ON(pampd_del != pampd); + (*tmem_pamops.free)(pampd, pool, oidp, index); + if (obj->pampd_count == 0) { + objnew = obj; + objfound = NULL; + } + pampd = NULL; + } + } else { + obj = objnew = (*tmem_hostops.obj_alloc)(pool); + if (unlikely(obj == NULL)) { + ret = -ENOMEM; + goto out; + } + tmem_obj_init(obj, hb, pool, oidp); + } + BUG_ON(obj == NULL); + BUG_ON(((objnew != obj) && (objfound != obj)) || (objnew == objfound)); + pampd = (*tmem_pamops.create)(data, size, raw, ephemeral, + obj->pool, &obj->oid, index); + if (unlikely(pampd == NULL)) + goto free; + ret = tmem_pampd_add_to_obj(obj, index, pampd); + if (unlikely(ret == -ENOMEM)) + /* may have partially built objnode tree ("stump") */ + goto delete_and_free; + goto out; + +delete_and_free: + (void)tmem_pampd_delete_from_obj(obj, index); +free: + if (pampd) + (*tmem_pamops.free)(pampd, pool, NULL, 0); + if (objnew) { + tmem_obj_free(objnew, hb); + (*tmem_hostops.obj_free)(objnew, pool); + } +out: + spin_unlock(&hb->lock); + return ret; +} + +/* + * "Get" a page, e.g. if one can be found, copy the tmem page with the + * matching handle from PAM space to the kernel. By tmem definition, + * when a "get" is successful on an ephemeral page, the page is "flushed", + * and when a "get" is successful on a persistent page, the page is retained + * in tmem. Note that to preserve + * coherency, "get" can never be skipped if tmem contains the data. + * That is, if a get is done with a certain handle and fails, any + * subsequent "get" must also fail (unless of course there is a + * "put" done with the same handle). + + */ +int tmem_get(struct tmem_pool *pool, struct tmem_oid *oidp, uint32_t index, + char *data, size_t *size, bool raw, int get_and_free) +{ + struct tmem_obj *obj; + void *pampd; + bool ephemeral = is_ephemeral(pool); + int ret = -1; + struct tmem_hashbucket *hb; + bool free = (get_and_free == 1) || ((get_and_free == 0) && ephemeral); + bool lock_held = false; + + hb = &pool->hashbucket[tmem_oid_hash(oidp)]; + spin_lock(&hb->lock); + lock_held = true; + obj = tmem_obj_find(hb, oidp); + if (obj == NULL) + goto out; + if (free) + pampd = tmem_pampd_delete_from_obj(obj, index); + else + pampd = tmem_pampd_lookup_in_obj(obj, index); + if (pampd == NULL) + goto out; + if (free) { + if (obj->pampd_count == 0) { + tmem_obj_free(obj, hb); + (*tmem_hostops.obj_free)(obj, pool); + obj = NULL; + } + } + if (tmem_pamops.is_remote(pampd)) { + lock_held = false; + spin_unlock(&hb->lock); + } + if (free) + ret = (*tmem_pamops.get_data_and_free)( + data, size, raw, pampd, pool, oidp, index); + else + ret = (*tmem_pamops.get_data)( + data, size, raw, pampd, pool, oidp, index); + if (ret < 0) + goto out; + ret = 0; +out: + if (lock_held) + spin_unlock(&hb->lock); + return ret; +} + +/* + * If a page in tmem matches the handle, "flush" this page from tmem such + * that any subsequent "get" does not succeed (unless, of course, there + * was another "put" with the same handle). + */ +int tmem_flush_page(struct tmem_pool *pool, + struct tmem_oid *oidp, uint32_t index) +{ + struct tmem_obj *obj; + void *pampd; + int ret = -1; + struct tmem_hashbucket *hb; + + hb = &pool->hashbucket[tmem_oid_hash(oidp)]; + spin_lock(&hb->lock); + obj = tmem_obj_find(hb, oidp); + if (obj == NULL) + goto out; + pampd = tmem_pampd_delete_from_obj(obj, index); + if (pampd == NULL) + goto out; + (*tmem_pamops.free)(pampd, pool, oidp, index); + if (obj->pampd_count == 0) { + tmem_obj_free(obj, hb); + (*tmem_hostops.obj_free)(obj, pool); + } + ret = 0; + +out: + spin_unlock(&hb->lock); + return ret; +} + +/* + * If a page in tmem matches the handle, replace the page so that any + * subsequent "get" gets the new page. Returns 0 if + * there was a page to replace, else returns -1. + */ +int tmem_replace(struct tmem_pool *pool, struct tmem_oid *oidp, + uint32_t index, void *new_pampd) +{ + struct tmem_obj *obj; + int ret = -1; + struct tmem_hashbucket *hb; + + hb = &pool->hashbucket[tmem_oid_hash(oidp)]; + spin_lock(&hb->lock); + obj = tmem_obj_find(hb, oidp); + if (obj == NULL) + goto out; + new_pampd = tmem_pampd_replace_in_obj(obj, index, new_pampd); + ret = (*tmem_pamops.replace_in_obj)(new_pampd, obj); +out: + spin_unlock(&hb->lock); + return ret; +} + +/* + * "Flush" all pages in tmem matching this oid. + */ +int tmem_flush_object(struct tmem_pool *pool, struct tmem_oid *oidp) +{ + struct tmem_obj *obj; + struct tmem_hashbucket *hb; + int ret = -1; + + hb = &pool->hashbucket[tmem_oid_hash(oidp)]; + spin_lock(&hb->lock); + obj = tmem_obj_find(hb, oidp); + if (obj == NULL) + goto out; + tmem_pampd_destroy_all_in_obj(obj); + tmem_obj_free(obj, hb); + (*tmem_hostops.obj_free)(obj, pool); + ret = 0; + +out: + spin_unlock(&hb->lock); + return ret; +} + +/* + * "Flush" all pages (and tmem_objs) from this tmem_pool and disable + * all subsequent access to this tmem_pool. + */ +int tmem_destroy_pool(struct tmem_pool *pool) +{ + int ret = -1; + + if (pool == NULL) + goto out; + tmem_pool_flush(pool, 1); + ret = 0; +out: + return ret; +} + +static LIST_HEAD(tmem_global_pool_list); + +/* + * Create a new tmem_pool with the provided flag and return + * a pool id provided by the tmem host implementation. + */ +void tmem_new_pool(struct tmem_pool *pool, uint32_t flags) +{ + int persistent = flags & TMEM_POOL_PERSIST; + int shared = flags & TMEM_POOL_SHARED; + struct tmem_hashbucket *hb = &pool->hashbucket[0]; + int i; + + for (i = 0; i < TMEM_HASH_BUCKETS; i++, hb++) { + hb->obj_rb_root = RB_ROOT; + spin_lock_init(&hb->lock); + } + INIT_LIST_HEAD(&pool->pool_list); + atomic_set(&pool->obj_count, 0); + SET_SENTINEL(pool, POOL); + list_add_tail(&pool->pool_list, &tmem_global_pool_list); + pool->persistent = persistent; + pool->shared = shared; +} diff --git a/drivers/staging/ramster/tmem.h b/drivers/staging/ramster/tmem.h new file mode 100644 index 00000000000..ed147c4b110 --- /dev/null +++ b/drivers/staging/ramster/tmem.h @@ -0,0 +1,206 @@ +/* + * tmem.h + * + * Transcendent memory + * + * Copyright (c) 2009-2011, Dan Magenheimer, Oracle Corp. + */ + +#ifndef _TMEM_H_ +#define _TMEM_H_ + +#include +#include +#include +#include + +/* + * These are pre-defined by the Xen<->Linux ABI + */ +#define TMEM_PUT_PAGE 4 +#define TMEM_GET_PAGE 5 +#define TMEM_FLUSH_PAGE 6 +#define TMEM_FLUSH_OBJECT 7 +#define TMEM_POOL_PERSIST 1 +#define TMEM_POOL_SHARED 2 +#define TMEM_POOL_PRECOMPRESSED 4 +#define TMEM_POOL_PAGESIZE_SHIFT 4 +#define TMEM_POOL_PAGESIZE_MASK 0xf +#define TMEM_POOL_RESERVED_BITS 0x00ffff00 + +/* + * sentinels have proven very useful for debugging but can be removed + * or disabled before final merge. + */ +#define SENTINELS +#ifdef SENTINELS +#define DECL_SENTINEL uint32_t sentinel; +#define SET_SENTINEL(_x, _y) (_x->sentinel = _y##_SENTINEL) +#define INVERT_SENTINEL(_x, _y) (_x->sentinel = ~_y##_SENTINEL) +#define ASSERT_SENTINEL(_x, _y) WARN_ON(_x->sentinel != _y##_SENTINEL) +#define ASSERT_INVERTED_SENTINEL(_x, _y) WARN_ON(_x->sentinel != ~_y##_SENTINEL) +#else +#define DECL_SENTINEL +#define SET_SENTINEL(_x, _y) do { } while (0) +#define INVERT_SENTINEL(_x, _y) do { } while (0) +#define ASSERT_SENTINEL(_x, _y) do { } while (0) +#define ASSERT_INVERTED_SENTINEL(_x, _y) do { } while (0) +#endif + +#define ASSERT_SPINLOCK(_l) WARN_ON(!spin_is_locked(_l)) + +/* + * A pool is the highest-level data structure managed by tmem and + * usually corresponds to a large independent set of pages such as + * a filesystem. Each pool has an id, and certain attributes and counters. + * It also contains a set of hash buckets, each of which contains an rbtree + * of objects and a lock to manage concurrency within the pool. + */ + +#define TMEM_HASH_BUCKET_BITS 8 +#define TMEM_HASH_BUCKETS (1<persistent) +#define is_ephemeral(_p) (!(_p->persistent)) + +/* + * An object id ("oid") is large: 192-bits (to ensure, for example, files + * in a modern filesystem can be uniquely identified). + */ + +struct tmem_oid { + uint64_t oid[3]; +}; + +static inline void tmem_oid_set_invalid(struct tmem_oid *oidp) +{ + oidp->oid[0] = oidp->oid[1] = oidp->oid[2] = -1UL; +} + +static inline bool tmem_oid_valid(struct tmem_oid *oidp) +{ + return oidp->oid[0] != -1UL || oidp->oid[1] != -1UL || + oidp->oid[2] != -1UL; +} + +static inline int tmem_oid_compare(struct tmem_oid *left, + struct tmem_oid *right) +{ + int ret; + + if (left->oid[2] == right->oid[2]) { + if (left->oid[1] == right->oid[1]) { + if (left->oid[0] == right->oid[0]) + ret = 0; + else if (left->oid[0] < right->oid[0]) + ret = -1; + else + return 1; + } else if (left->oid[1] < right->oid[1]) + ret = -1; + else + ret = 1; + } else if (left->oid[2] < right->oid[2]) + ret = -1; + else + ret = 1; + return ret; +} + +static inline unsigned tmem_oid_hash(struct tmem_oid *oidp) +{ + return hash_long(oidp->oid[0] ^ oidp->oid[1] ^ oidp->oid[2], + TMEM_HASH_BUCKET_BITS); +} + +/* + * A tmem_obj contains an identifier (oid), pointers to the parent + * pool and the rb_tree to which it belongs, counters, and an ordered + * set of pampds, structured in a radix-tree-like tree. The intermediate + * nodes of the tree are called tmem_objnodes. + */ + +struct tmem_objnode; + +struct tmem_obj { + struct tmem_oid oid; + struct tmem_pool *pool; + struct rb_node rb_tree_node; + struct tmem_objnode *objnode_tree_root; + unsigned int objnode_tree_height; + unsigned long objnode_count; + long pampd_count; + void *extra; /* for private use by pampd implementation */ + DECL_SENTINEL +}; + +#define OBJNODE_TREE_MAP_SHIFT 6 +#define OBJNODE_TREE_MAP_SIZE (1UL << OBJNODE_TREE_MAP_SHIFT) +#define OBJNODE_TREE_MAP_MASK (OBJNODE_TREE_MAP_SIZE-1) +#define OBJNODE_TREE_INDEX_BITS (8 /* CHAR_BIT */ * sizeof(unsigned long)) +#define OBJNODE_TREE_MAX_PATH \ + (OBJNODE_TREE_INDEX_BITS/OBJNODE_TREE_MAP_SHIFT + 2) + +struct tmem_objnode { + struct tmem_obj *obj; + DECL_SENTINEL + void *slots[OBJNODE_TREE_MAP_SIZE]; + unsigned int slots_in_use; +}; + +/* pampd abstract datatype methods provided by the PAM implementation */ +struct tmem_pamops { + void *(*create)(char *, size_t, bool, int, + struct tmem_pool *, struct tmem_oid *, uint32_t); + int (*get_data)(char *, size_t *, bool, void *, struct tmem_pool *, + struct tmem_oid *, uint32_t); + int (*get_data_and_free)(char *, size_t *, bool, void *, + struct tmem_pool *, struct tmem_oid *, + uint32_t); + void (*free)(void *, struct tmem_pool *, struct tmem_oid *, uint32_t); + void (*free_obj)(struct tmem_pool *, struct tmem_obj *); + bool (*is_remote)(void *); + void (*new_obj)(struct tmem_obj *); + int (*replace_in_obj)(void *, struct tmem_obj *); +}; +extern void tmem_register_pamops(struct tmem_pamops *m); + +/* memory allocation methods provided by the host implementation */ +struct tmem_hostops { + struct tmem_obj *(*obj_alloc)(struct tmem_pool *); + void (*obj_free)(struct tmem_obj *, struct tmem_pool *); + struct tmem_objnode *(*objnode_alloc)(struct tmem_pool *); + void (*objnode_free)(struct tmem_objnode *, struct tmem_pool *); +}; +extern void tmem_register_hostops(struct tmem_hostops *m); + +/* core tmem accessor functions */ +extern int tmem_put(struct tmem_pool *, struct tmem_oid *, uint32_t index, + char *, size_t, bool, bool); +extern int tmem_get(struct tmem_pool *, struct tmem_oid *, uint32_t index, + char *, size_t *, bool, int); +extern int tmem_replace(struct tmem_pool *, struct tmem_oid *, uint32_t index, + void *); +extern int tmem_flush_page(struct tmem_pool *, struct tmem_oid *, + uint32_t index); +extern int tmem_flush_object(struct tmem_pool *, struct tmem_oid *); +extern int tmem_destroy_pool(struct tmem_pool *); +extern void tmem_new_pool(struct tmem_pool *, uint32_t); +#endif /* _TMEM_H */ diff --git a/drivers/staging/ramster/zcache-main.c b/drivers/staging/ramster/zcache-main.c new file mode 100644 index 00000000000..49c8791462f --- /dev/null +++ b/drivers/staging/ramster/zcache-main.c @@ -0,0 +1,1988 @@ +/* + * zcache.c + * + * Copyright (c) 2010,2011, Dan Magenheimer, Oracle Corp. + * Copyright (c) 2010,2011, Nitin Gupta + * + * Zcache provides an in-kernel "host implementation" for transcendent memory + * and, thus indirectly, for cleancache and frontswap. Zcache includes two + * page-accessible memory [1] interfaces, both utilizing lzo1x compression: + * 1) "compression buddies" ("zbud") is used for ephemeral pages + * 2) xvmalloc is used for persistent pages. + * Xvmalloc (based on the TLSF allocator) has very low fragmentation + * so maximizes space efficiency, while zbud allows pairs (and potentially, + * in the future, more than a pair of) compressed pages to be closely linked + * so that reclaiming can be done via the kernel's physical-page-oriented + * "shrinker" interface. + * + * [1] For a definition of page-accessible memory (aka PAM), see: + * http://marc.info/?l=linux-mm&m=127811271605009 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tmem.h" + +#include "../zram/xvmalloc.h" /* if built in drivers/staging */ + +#if (!defined(CONFIG_CLEANCACHE) && !defined(CONFIG_FRONTSWAP)) +#error "zcache is useless without CONFIG_CLEANCACHE or CONFIG_FRONTSWAP" +#endif +#ifdef CONFIG_CLEANCACHE +#include +#endif +#ifdef CONFIG_FRONTSWAP +#include +#endif + +#if 0 +/* this is more aggressive but may cause other problems? */ +#define ZCACHE_GFP_MASK (GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN) +#else +#define ZCACHE_GFP_MASK \ + (__GFP_FS | __GFP_NORETRY | __GFP_NOWARN | __GFP_NOMEMALLOC) +#endif + +#define MAX_POOLS_PER_CLIENT 16 + +#define MAX_CLIENTS 16 +#define LOCAL_CLIENT ((uint16_t)-1) + +MODULE_LICENSE("GPL"); + +struct zcache_client { + struct tmem_pool *tmem_pools[MAX_POOLS_PER_CLIENT]; + struct xv_pool *xvpool; + bool allocated; + atomic_t refcount; +}; + +static struct zcache_client zcache_host; +static struct zcache_client zcache_clients[MAX_CLIENTS]; + +static inline uint16_t get_client_id_from_client(struct zcache_client *cli) +{ + BUG_ON(cli == NULL); + if (cli == &zcache_host) + return LOCAL_CLIENT; + return cli - &zcache_clients[0]; +} + +static inline bool is_local_client(struct zcache_client *cli) +{ + return cli == &zcache_host; +} + +/********** + * Compression buddies ("zbud") provides for packing two (or, possibly + * in the future, more) compressed ephemeral pages into a single "raw" + * (physical) page and tracking them with data structures so that + * the raw pages can be easily reclaimed. + * + * A zbud page ("zbpg") is an aligned page containing a list_head, + * a lock, and two "zbud headers". The remainder of the physical + * page is divided up into aligned 64-byte "chunks" which contain + * the compressed data for zero, one, or two zbuds. Each zbpg + * resides on: (1) an "unused list" if it has no zbuds; (2) a + * "buddied" list if it is fully populated with two zbuds; or + * (3) one of PAGE_SIZE/64 "unbuddied" lists indexed by how many chunks + * the one unbuddied zbud uses. The data inside a zbpg cannot be + * read or written unless the zbpg's lock is held. + */ + +#define ZBH_SENTINEL 0x43214321 +#define ZBPG_SENTINEL 0xdeadbeef + +#define ZBUD_MAX_BUDS 2 + +struct zbud_hdr { + uint16_t client_id; + uint16_t pool_id; + struct tmem_oid oid; + uint32_t index; + uint16_t size; /* compressed size in bytes, zero means unused */ + DECL_SENTINEL +}; + +struct zbud_page { + struct list_head bud_list; + spinlock_t lock; + struct zbud_hdr buddy[ZBUD_MAX_BUDS]; + DECL_SENTINEL + /* followed by NUM_CHUNK aligned CHUNK_SIZE-byte chunks */ +}; + +#define CHUNK_SHIFT 6 +#define CHUNK_SIZE (1 << CHUNK_SHIFT) +#define CHUNK_MASK (~(CHUNK_SIZE-1)) +#define NCHUNKS (((PAGE_SIZE - sizeof(struct zbud_page)) & \ + CHUNK_MASK) >> CHUNK_SHIFT) +#define MAX_CHUNK (NCHUNKS-1) + +static struct { + struct list_head list; + unsigned count; +} zbud_unbuddied[NCHUNKS]; +/* list N contains pages with N chunks USED and NCHUNKS-N unused */ +/* element 0 is never used but optimizing that isn't worth it */ +static unsigned long zbud_cumul_chunk_counts[NCHUNKS]; + +struct list_head zbud_buddied_list; +static unsigned long zcache_zbud_buddied_count; + +/* protects the buddied list and all unbuddied lists */ +static DEFINE_SPINLOCK(zbud_budlists_spinlock); + +static LIST_HEAD(zbpg_unused_list); +static unsigned long zcache_zbpg_unused_list_count; + +/* protects the unused page list */ +static DEFINE_SPINLOCK(zbpg_unused_list_spinlock); + +static atomic_t zcache_zbud_curr_raw_pages; +static atomic_t zcache_zbud_curr_zpages; +static unsigned long zcache_zbud_curr_zbytes; +static unsigned long zcache_zbud_cumul_zpages; +static unsigned long zcache_zbud_cumul_zbytes; +static unsigned long zcache_compress_poor; +static unsigned long zcache_mean_compress_poor; + +/* forward references */ +static void *zcache_get_free_page(void); +static void zcache_free_page(void *p); + +/* + * zbud helper functions + */ + +static inline unsigned zbud_max_buddy_size(void) +{ + return MAX_CHUNK << CHUNK_SHIFT; +} + +static inline unsigned zbud_size_to_chunks(unsigned size) +{ + BUG_ON(size == 0 || size > zbud_max_buddy_size()); + return (size + CHUNK_SIZE - 1) >> CHUNK_SHIFT; +} + +static inline int zbud_budnum(struct zbud_hdr *zh) +{ + unsigned offset = (unsigned long)zh & (PAGE_SIZE - 1); + struct zbud_page *zbpg = NULL; + unsigned budnum = -1U; + int i; + + for (i = 0; i < ZBUD_MAX_BUDS; i++) + if (offset == offsetof(typeof(*zbpg), buddy[i])) { + budnum = i; + break; + } + BUG_ON(budnum == -1U); + return budnum; +} + +static char *zbud_data(struct zbud_hdr *zh, unsigned size) +{ + struct zbud_page *zbpg; + char *p; + unsigned budnum; + + ASSERT_SENTINEL(zh, ZBH); + budnum = zbud_budnum(zh); + BUG_ON(size == 0 || size > zbud_max_buddy_size()); + zbpg = container_of(zh, struct zbud_page, buddy[budnum]); + ASSERT_SPINLOCK(&zbpg->lock); + p = (char *)zbpg; + if (budnum == 0) + p += ((sizeof(struct zbud_page) + CHUNK_SIZE - 1) & + CHUNK_MASK); + else if (budnum == 1) + p += PAGE_SIZE - ((size + CHUNK_SIZE - 1) & CHUNK_MASK); + return p; +} + +/* + * zbud raw page management + */ + +static struct zbud_page *zbud_alloc_raw_page(void) +{ + struct zbud_page *zbpg = NULL; + struct zbud_hdr *zh0, *zh1; + bool recycled = 0; + + /* if any pages on the zbpg list, use one */ + spin_lock(&zbpg_unused_list_spinlock); + if (!list_empty(&zbpg_unused_list)) { + zbpg = list_first_entry(&zbpg_unused_list, + struct zbud_page, bud_list); + list_del_init(&zbpg->bud_list); + zcache_zbpg_unused_list_count--; + recycled = 1; + } + spin_unlock(&zbpg_unused_list_spinlock); + if (zbpg == NULL) + /* none on zbpg list, try to get a kernel page */ + zbpg = zcache_get_free_page(); + if (likely(zbpg != NULL)) { + INIT_LIST_HEAD(&zbpg->bud_list); + zh0 = &zbpg->buddy[0]; zh1 = &zbpg->buddy[1]; + spin_lock_init(&zbpg->lock); + if (recycled) { + ASSERT_INVERTED_SENTINEL(zbpg, ZBPG); + SET_SENTINEL(zbpg, ZBPG); + BUG_ON(zh0->size != 0 || tmem_oid_valid(&zh0->oid)); + BUG_ON(zh1->size != 0 || tmem_oid_valid(&zh1->oid)); + } else { + atomic_inc(&zcache_zbud_curr_raw_pages); + INIT_LIST_HEAD(&zbpg->bud_list); + SET_SENTINEL(zbpg, ZBPG); + zh0->size = 0; zh1->size = 0; + tmem_oid_set_invalid(&zh0->oid); + tmem_oid_set_invalid(&zh1->oid); + } + } + return zbpg; +} + +static void zbud_free_raw_page(struct zbud_page *zbpg) +{ + struct zbud_hdr *zh0 = &zbpg->buddy[0], *zh1 = &zbpg->buddy[1]; + + ASSERT_SENTINEL(zbpg, ZBPG); + BUG_ON(!list_empty(&zbpg->bud_list)); + ASSERT_SPINLOCK(&zbpg->lock); + BUG_ON(zh0->size != 0 || tmem_oid_valid(&zh0->oid)); + BUG_ON(zh1->size != 0 || tmem_oid_valid(&zh1->oid)); + INVERT_SENTINEL(zbpg, ZBPG); + spin_unlock(&zbpg->lock); + spin_lock(&zbpg_unused_list_spinlock); + list_add(&zbpg->bud_list, &zbpg_unused_list); + zcache_zbpg_unused_list_count++; + spin_unlock(&zbpg_unused_list_spinlock); +} + +/* + * core zbud handling routines + */ + +static unsigned zbud_free(struct zbud_hdr *zh) +{ + unsigned size; + + ASSERT_SENTINEL(zh, ZBH); + BUG_ON(!tmem_oid_valid(&zh->oid)); + size = zh->size; + BUG_ON(zh->size == 0 || zh->size > zbud_max_buddy_size()); + zh->size = 0; + tmem_oid_set_invalid(&zh->oid); + INVERT_SENTINEL(zh, ZBH); + zcache_zbud_curr_zbytes -= size; + atomic_dec(&zcache_zbud_curr_zpages); + return size; +} + +static void zbud_free_and_delist(struct zbud_hdr *zh) +{ + unsigned chunks; + struct zbud_hdr *zh_other; + unsigned budnum = zbud_budnum(zh), size; + struct zbud_page *zbpg = + container_of(zh, struct zbud_page, buddy[budnum]); + + spin_lock(&zbpg->lock); + if (list_empty(&zbpg->bud_list)) { + /* ignore zombie page... see zbud_evict_pages() */ + spin_unlock(&zbpg->lock); + return; + } + size = zbud_free(zh); + ASSERT_SPINLOCK(&zbpg->lock); + zh_other = &zbpg->buddy[(budnum == 0) ? 1 : 0]; + if (zh_other->size == 0) { /* was unbuddied: unlist and free */ + chunks = zbud_size_to_chunks(size) ; + spin_lock(&zbud_budlists_spinlock); + BUG_ON(list_empty(&zbud_unbuddied[chunks].list)); + list_del_init(&zbpg->bud_list); + zbud_unbuddied[chunks].count--; + spin_unlock(&zbud_budlists_spinlock); + zbud_free_raw_page(zbpg); + } else { /* was buddied: move remaining buddy to unbuddied list */ + chunks = zbud_size_to_chunks(zh_other->size) ; + spin_lock(&zbud_budlists_spinlock); + list_del_init(&zbpg->bud_list); + zcache_zbud_buddied_count--; + list_add_tail(&zbpg->bud_list, &zbud_unbuddied[chunks].list); + zbud_unbuddied[chunks].count++; + spin_unlock(&zbud_budlists_spinlock); + spin_unlock(&zbpg->lock); + } +} + +static struct zbud_hdr *zbud_create(uint16_t client_id, uint16_t pool_id, + struct tmem_oid *oid, + uint32_t index, struct page *page, + void *cdata, unsigned size) +{ + struct zbud_hdr *zh0, *zh1, *zh = NULL; + struct zbud_page *zbpg = NULL, *ztmp; + unsigned nchunks; + char *to; + int i, found_good_buddy = 0; + + nchunks = zbud_size_to_chunks(size) ; + for (i = MAX_CHUNK - nchunks + 1; i > 0; i--) { + spin_lock(&zbud_budlists_spinlock); + if (!list_empty(&zbud_unbuddied[i].list)) { + list_for_each_entry_safe(zbpg, ztmp, + &zbud_unbuddied[i].list, bud_list) { + if (spin_trylock(&zbpg->lock)) { + found_good_buddy = i; + goto found_unbuddied; + } + } + } + spin_unlock(&zbud_budlists_spinlock); + } + /* didn't find a good buddy, try allocating a new page */ + zbpg = zbud_alloc_raw_page(); + if (unlikely(zbpg == NULL)) + goto out; + /* ok, have a page, now compress the data before taking locks */ + spin_lock(&zbpg->lock); + spin_lock(&zbud_budlists_spinlock); + list_add_tail(&zbpg->bud_list, &zbud_unbuddied[nchunks].list); + zbud_unbuddied[nchunks].count++; + zh = &zbpg->buddy[0]; + goto init_zh; + +found_unbuddied: + ASSERT_SPINLOCK(&zbpg->lock); + zh0 = &zbpg->buddy[0]; zh1 = &zbpg->buddy[1]; + BUG_ON(!((zh0->size == 0) ^ (zh1->size == 0))); + if (zh0->size != 0) { /* buddy0 in use, buddy1 is vacant */ + ASSERT_SENTINEL(zh0, ZBH); + zh = zh1; + } else if (zh1->size != 0) { /* buddy1 in use, buddy0 is vacant */ + ASSERT_SENTINEL(zh1, ZBH); + zh = zh0; + } else + BUG(); + list_del_init(&zbpg->bud_list); + zbud_unbuddied[found_good_buddy].count--; + list_add_tail(&zbpg->bud_list, &zbud_buddied_list); + zcache_zbud_buddied_count++; + +init_zh: + SET_SENTINEL(zh, ZBH); + zh->size = size; + zh->index = index; + zh->oid = *oid; + zh->pool_id = pool_id; + zh->client_id = client_id; + /* can wait to copy the data until the list locks are dropped */ + spin_unlock(&zbud_budlists_spinlock); + + to = zbud_data(zh, size); + memcpy(to, cdata, size); + spin_unlock(&zbpg->lock); + zbud_cumul_chunk_counts[nchunks]++; + atomic_inc(&zcache_zbud_curr_zpages); + zcache_zbud_cumul_zpages++; + zcache_zbud_curr_zbytes += size; + zcache_zbud_cumul_zbytes += size; +out: + return zh; +} + +static int zbud_decompress(struct page *page, struct zbud_hdr *zh) +{ + struct zbud_page *zbpg; + unsigned budnum = zbud_budnum(zh); + size_t out_len = PAGE_SIZE; + char *to_va, *from_va; + unsigned size; + int ret = 0; + + zbpg = container_of(zh, struct zbud_page, buddy[budnum]); + spin_lock(&zbpg->lock); + if (list_empty(&zbpg->bud_list)) { + /* ignore zombie page... see zbud_evict_pages() */ + ret = -EINVAL; + goto out; + } + ASSERT_SENTINEL(zh, ZBH); + BUG_ON(zh->size == 0 || zh->size > zbud_max_buddy_size()); + to_va = kmap_atomic(page, KM_USER0); + size = zh->size; + from_va = zbud_data(zh, size); + ret = lzo1x_decompress_safe(from_va, size, to_va, &out_len); + BUG_ON(ret != LZO_E_OK); + BUG_ON(out_len != PAGE_SIZE); + kunmap_atomic(to_va, KM_USER0); +out: + spin_unlock(&zbpg->lock); + return ret; +} + +/* + * The following routines handle shrinking of ephemeral pages by evicting + * pages "least valuable" first. + */ + +static unsigned long zcache_evicted_raw_pages; +static unsigned long zcache_evicted_buddied_pages; +static unsigned long zcache_evicted_unbuddied_pages; + +static struct tmem_pool *zcache_get_pool_by_id(uint16_t cli_id, + uint16_t poolid); +static void zcache_put_pool(struct tmem_pool *pool); + +/* + * Flush and free all zbuds in a zbpg, then free the pageframe + */ +static void zbud_evict_zbpg(struct zbud_page *zbpg) +{ + struct zbud_hdr *zh; + int i, j; + uint32_t pool_id[ZBUD_MAX_BUDS], client_id[ZBUD_MAX_BUDS]; + uint32_t index[ZBUD_MAX_BUDS]; + struct tmem_oid oid[ZBUD_MAX_BUDS]; + struct tmem_pool *pool; + + ASSERT_SPINLOCK(&zbpg->lock); + BUG_ON(!list_empty(&zbpg->bud_list)); + for (i = 0, j = 0; i < ZBUD_MAX_BUDS; i++) { + zh = &zbpg->buddy[i]; + if (zh->size) { + client_id[j] = zh->client_id; + pool_id[j] = zh->pool_id; + oid[j] = zh->oid; + index[j] = zh->index; + j++; + zbud_free(zh); + } + } + spin_unlock(&zbpg->lock); + for (i = 0; i < j; i++) { + pool = zcache_get_pool_by_id(client_id[i], pool_id[i]); + if (pool != NULL) { + tmem_flush_page(pool, &oid[i], index[i]); + zcache_put_pool(pool); + } + } + ASSERT_SENTINEL(zbpg, ZBPG); + spin_lock(&zbpg->lock); + zbud_free_raw_page(zbpg); +} + +/* + * Free nr pages. This code is funky because we want to hold the locks + * protecting various lists for as short a time as possible, and in some + * circumstances the list may change asynchronously when the list lock is + * not held. In some cases we also trylock not only to avoid waiting on a + * page in use by another cpu, but also to avoid potential deadlock due to + * lock inversion. + */ +static void zbud_evict_pages(int nr) +{ + struct zbud_page *zbpg; + int i; + + /* first try freeing any pages on unused list */ +retry_unused_list: + spin_lock_bh(&zbpg_unused_list_spinlock); + if (!list_empty(&zbpg_unused_list)) { + /* can't walk list here, since it may change when unlocked */ + zbpg = list_first_entry(&zbpg_unused_list, + struct zbud_page, bud_list); + list_del_init(&zbpg->bud_list); + zcache_zbpg_unused_list_count--; + atomic_dec(&zcache_zbud_curr_raw_pages); + spin_unlock_bh(&zbpg_unused_list_spinlock); + zcache_free_page(zbpg); + zcache_evicted_raw_pages++; + if (--nr <= 0) + goto out; + goto retry_unused_list; + } + spin_unlock_bh(&zbpg_unused_list_spinlock); + + /* now try freeing unbuddied pages, starting with least space avail */ + for (i = 0; i < MAX_CHUNK; i++) { +retry_unbud_list_i: + spin_lock_bh(&zbud_budlists_spinlock); + if (list_empty(&zbud_unbuddied[i].list)) { + spin_unlock_bh(&zbud_budlists_spinlock); + continue; + } + list_for_each_entry(zbpg, &zbud_unbuddied[i].list, bud_list) { + if (unlikely(!spin_trylock(&zbpg->lock))) + continue; + list_del_init(&zbpg->bud_list); + zbud_unbuddied[i].count--; + spin_unlock(&zbud_budlists_spinlock); + zcache_evicted_unbuddied_pages++; + /* want budlists unlocked when doing zbpg eviction */ + zbud_evict_zbpg(zbpg); + local_bh_enable(); + if (--nr <= 0) + goto out; + goto retry_unbud_list_i; + } + spin_unlock_bh(&zbud_budlists_spinlock); + } + + /* as a last resort, free buddied pages */ +retry_bud_list: + spin_lock_bh(&zbud_budlists_spinlock); + if (list_empty(&zbud_buddied_list)) { + spin_unlock_bh(&zbud_budlists_spinlock); + goto out; + } + list_for_each_entry(zbpg, &zbud_buddied_list, bud_list) { + if (unlikely(!spin_trylock(&zbpg->lock))) + continue; + list_del_init(&zbpg->bud_list); + zcache_zbud_buddied_count--; + spin_unlock(&zbud_budlists_spinlock); + zcache_evicted_buddied_pages++; + /* want budlists unlocked when doing zbpg eviction */ + zbud_evict_zbpg(zbpg); + local_bh_enable(); + if (--nr <= 0) + goto out; + goto retry_bud_list; + } + spin_unlock_bh(&zbud_budlists_spinlock); +out: + return; +} + +static void zbud_init(void) +{ + int i; + + INIT_LIST_HEAD(&zbud_buddied_list); + zcache_zbud_buddied_count = 0; + for (i = 0; i < NCHUNKS; i++) { + INIT_LIST_HEAD(&zbud_unbuddied[i].list); + zbud_unbuddied[i].count = 0; + } +} + +#ifdef CONFIG_SYSFS +/* + * These sysfs routines show a nice distribution of how many zbpg's are + * currently (and have ever been placed) in each unbuddied list. It's fun + * to watch but can probably go away before final merge. + */ +static int zbud_show_unbuddied_list_counts(char *buf) +{ + int i; + char *p = buf; + + for (i = 0; i < NCHUNKS; i++) + p += sprintf(p, "%u ", zbud_unbuddied[i].count); + return p - buf; +} + +static int zbud_show_cumul_chunk_counts(char *buf) +{ + unsigned long i, chunks = 0, total_chunks = 0, sum_total_chunks = 0; + unsigned long total_chunks_lte_21 = 0, total_chunks_lte_32 = 0; + unsigned long total_chunks_lte_42 = 0; + char *p = buf; + + for (i = 0; i < NCHUNKS; i++) { + p += sprintf(p, "%lu ", zbud_cumul_chunk_counts[i]); + chunks += zbud_cumul_chunk_counts[i]; + total_chunks += zbud_cumul_chunk_counts[i]; + sum_total_chunks += i * zbud_cumul_chunk_counts[i]; + if (i == 21) + total_chunks_lte_21 = total_chunks; + if (i == 32) + total_chunks_lte_32 = total_chunks; + if (i == 42) + total_chunks_lte_42 = total_chunks; + } + p += sprintf(p, "<=21:%lu <=32:%lu <=42:%lu, mean:%lu\n", + total_chunks_lte_21, total_chunks_lte_32, total_chunks_lte_42, + chunks == 0 ? 0 : sum_total_chunks / chunks); + return p - buf; +} +#endif + +/********** + * This "zv" PAM implementation combines the TLSF-based xvMalloc + * with lzo1x compression to maximize the amount of data that can + * be packed into a physical page. + * + * Zv represents a PAM page with the index and object (plus a "size" value + * necessary for decompression) immediately preceding the compressed data. + */ + +#define ZVH_SENTINEL 0x43214321 + +struct zv_hdr { + uint32_t pool_id; + struct tmem_oid oid; + uint32_t index; + DECL_SENTINEL +}; + +/* rudimentary policy limits */ +/* total number of persistent pages may not exceed this percentage */ +static unsigned int zv_page_count_policy_percent = 75; +/* + * byte count defining poor compression; pages with greater zsize will be + * rejected + */ +static unsigned int zv_max_zsize = (PAGE_SIZE / 8) * 7; +/* + * byte count defining poor *mean* compression; pages with greater zsize + * will be rejected until sufficient better-compressed pages are accepted + * driving the mean below this threshold + */ +static unsigned int zv_max_mean_zsize = (PAGE_SIZE / 8) * 5; + +static unsigned long zv_curr_dist_counts[NCHUNKS]; +static unsigned long zv_cumul_dist_counts[NCHUNKS]; + +static struct zv_hdr *zv_create(struct xv_pool *xvpool, uint32_t pool_id, + struct tmem_oid *oid, uint32_t index, + void *cdata, unsigned clen) +{ + struct page *page; + struct zv_hdr *zv = NULL; + uint32_t offset; + int alloc_size = clen + sizeof(struct zv_hdr); + int chunks = (alloc_size + (CHUNK_SIZE - 1)) >> CHUNK_SHIFT; + int ret; + + BUG_ON(!irqs_disabled()); + BUG_ON(chunks >= NCHUNKS); + ret = xv_malloc(xvpool, alloc_size, + &page, &offset, ZCACHE_GFP_MASK); + if (unlikely(ret)) + goto out; + zv_curr_dist_counts[chunks]++; + zv_cumul_dist_counts[chunks]++; + zv = kmap_atomic(page, KM_USER0) + offset; + zv->index = index; + zv->oid = *oid; + zv->pool_id = pool_id; + SET_SENTINEL(zv, ZVH); + memcpy((char *)zv + sizeof(struct zv_hdr), cdata, clen); + kunmap_atomic(zv, KM_USER0); +out: + return zv; +} + +static void zv_free(struct xv_pool *xvpool, struct zv_hdr *zv) +{ + unsigned long flags; + struct page *page; + uint32_t offset; + uint16_t size = xv_get_object_size(zv); + int chunks = (size + (CHUNK_SIZE - 1)) >> CHUNK_SHIFT; + + ASSERT_SENTINEL(zv, ZVH); + BUG_ON(chunks >= NCHUNKS); + zv_curr_dist_counts[chunks]--; + size -= sizeof(*zv); + BUG_ON(size == 0); + INVERT_SENTINEL(zv, ZVH); + page = virt_to_page(zv); + offset = (unsigned long)zv & ~PAGE_MASK; + local_irq_save(flags); + xv_free(xvpool, page, offset); + local_irq_restore(flags); +} + +static void zv_decompress(struct page *page, struct zv_hdr *zv) +{ + size_t clen = PAGE_SIZE; + char *to_va; + unsigned size; + int ret; + + ASSERT_SENTINEL(zv, ZVH); + size = xv_get_object_size(zv) - sizeof(*zv); + BUG_ON(size == 0); + to_va = kmap_atomic(page, KM_USER0); + ret = lzo1x_decompress_safe((char *)zv + sizeof(*zv), + size, to_va, &clen); + kunmap_atomic(to_va, KM_USER0); + BUG_ON(ret != LZO_E_OK); + BUG_ON(clen != PAGE_SIZE); +} + +#ifdef CONFIG_SYSFS +/* + * show a distribution of compression stats for zv pages. + */ + +static int zv_curr_dist_counts_show(char *buf) +{ + unsigned long i, n, chunks = 0, sum_total_chunks = 0; + char *p = buf; + + for (i = 0; i < NCHUNKS; i++) { + n = zv_curr_dist_counts[i]; + p += sprintf(p, "%lu ", n); + chunks += n; + sum_total_chunks += i * n; + } + p += sprintf(p, "mean:%lu\n", + chunks == 0 ? 0 : sum_total_chunks / chunks); + return p - buf; +} + +static int zv_cumul_dist_counts_show(char *buf) +{ + unsigned long i, n, chunks = 0, sum_total_chunks = 0; + char *p = buf; + + for (i = 0; i < NCHUNKS; i++) { + n = zv_cumul_dist_counts[i]; + p += sprintf(p, "%lu ", n); + chunks += n; + sum_total_chunks += i * n; + } + p += sprintf(p, "mean:%lu\n", + chunks == 0 ? 0 : sum_total_chunks / chunks); + return p - buf; +} + +/* + * setting zv_max_zsize via sysfs causes all persistent (e.g. swap) + * pages that don't compress to less than this value (including metadata + * overhead) to be rejected. We don't allow the value to get too close + * to PAGE_SIZE. + */ +static ssize_t zv_max_zsize_show(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + return sprintf(buf, "%u\n", zv_max_zsize); +} + +static ssize_t zv_max_zsize_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + unsigned long val; + int err; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + err = strict_strtoul(buf, 10, &val); + if (err || (val == 0) || (val > (PAGE_SIZE / 8) * 7)) + return -EINVAL; + zv_max_zsize = val; + return count; +} + +/* + * setting zv_max_mean_zsize via sysfs causes all persistent (e.g. swap) + * pages that don't compress to less than this value (including metadata + * overhead) to be rejected UNLESS the mean compression is also smaller + * than this value. In other words, we are load-balancing-by-zsize the + * accepted pages. Again, we don't allow the value to get too close + * to PAGE_SIZE. + */ +static ssize_t zv_max_mean_zsize_show(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + return sprintf(buf, "%u\n", zv_max_mean_zsize); +} + +static ssize_t zv_max_mean_zsize_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + unsigned long val; + int err; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + err = strict_strtoul(buf, 10, &val); + if (err || (val == 0) || (val > (PAGE_SIZE / 8) * 7)) + return -EINVAL; + zv_max_mean_zsize = val; + return count; +} + +/* + * setting zv_page_count_policy_percent via sysfs sets an upper bound of + * persistent (e.g. swap) pages that will be retained according to: + * (zv_page_count_policy_percent * totalram_pages) / 100) + * when that limit is reached, further puts will be rejected (until + * some pages have been flushed). Note that, due to compression, + * this number may exceed 100; it defaults to 75 and we set an + * arbitary limit of 150. A poor choice will almost certainly result + * in OOM's, so this value should only be changed prudently. + */ +static ssize_t zv_page_count_policy_percent_show(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + return sprintf(buf, "%u\n", zv_page_count_policy_percent); +} + +static ssize_t zv_page_count_policy_percent_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + unsigned long val; + int err; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + err = strict_strtoul(buf, 10, &val); + if (err || (val == 0) || (val > 150)) + return -EINVAL; + zv_page_count_policy_percent = val; + return count; +} + +static struct kobj_attribute zcache_zv_max_zsize_attr = { + .attr = { .name = "zv_max_zsize", .mode = 0644 }, + .show = zv_max_zsize_show, + .store = zv_max_zsize_store, +}; + +static struct kobj_attribute zcache_zv_max_mean_zsize_attr = { + .attr = { .name = "zv_max_mean_zsize", .mode = 0644 }, + .show = zv_max_mean_zsize_show, + .store = zv_max_mean_zsize_store, +}; + +static struct kobj_attribute zcache_zv_page_count_policy_percent_attr = { + .attr = { .name = "zv_page_count_policy_percent", + .mode = 0644 }, + .show = zv_page_count_policy_percent_show, + .store = zv_page_count_policy_percent_store, +}; +#endif + +/* + * zcache core code starts here + */ + +/* useful stats not collected by cleancache or frontswap */ +static unsigned long zcache_flush_total; +static unsigned long zcache_flush_found; +static unsigned long zcache_flobj_total; +static unsigned long zcache_flobj_found; +static unsigned long zcache_failed_eph_puts; +static unsigned long zcache_failed_pers_puts; + +/* + * Tmem operations assume the poolid implies the invoking client. + * Zcache only has one client (the kernel itself): LOCAL_CLIENT. + * RAMster has each client numbered by cluster node, and a KVM version + * of zcache would have one client per guest and each client might + * have a poolid==N. + */ +static struct tmem_pool *zcache_get_pool_by_id(uint16_t cli_id, uint16_t poolid) +{ + struct tmem_pool *pool = NULL; + struct zcache_client *cli = NULL; + + if (cli_id == LOCAL_CLIENT) + cli = &zcache_host; + else { + if (cli_id >= MAX_CLIENTS) + goto out; + cli = &zcache_clients[cli_id]; + if (cli == NULL) + goto out; + atomic_inc(&cli->refcount); + } + if (poolid < MAX_POOLS_PER_CLIENT) { + pool = cli->tmem_pools[poolid]; + if (pool != NULL) + atomic_inc(&pool->refcount); + } +out: + return pool; +} + +static void zcache_put_pool(struct tmem_pool *pool) +{ + struct zcache_client *cli = NULL; + + if (pool == NULL) + BUG(); + cli = pool->client; + atomic_dec(&pool->refcount); + atomic_dec(&cli->refcount); +} + +int zcache_new_client(uint16_t cli_id) +{ + struct zcache_client *cli = NULL; + int ret = -1; + + if (cli_id == LOCAL_CLIENT) + cli = &zcache_host; + else if ((unsigned int)cli_id < MAX_CLIENTS) + cli = &zcache_clients[cli_id]; + if (cli == NULL) + goto out; + if (cli->allocated) + goto out; + cli->allocated = 1; +#ifdef CONFIG_FRONTSWAP + cli->xvpool = xv_create_pool(); + if (cli->xvpool == NULL) + goto out; +#endif + ret = 0; +out: + return ret; +} + +/* counters for debugging */ +static unsigned long zcache_failed_get_free_pages; +static unsigned long zcache_failed_alloc; +static unsigned long zcache_put_to_flush; + +/* + * for now, used named slabs so can easily track usage; later can + * either just use kmalloc, or perhaps add a slab-like allocator + * to more carefully manage total memory utilization + */ +static struct kmem_cache *zcache_objnode_cache; +static struct kmem_cache *zcache_obj_cache; +static atomic_t zcache_curr_obj_count = ATOMIC_INIT(0); +static unsigned long zcache_curr_obj_count_max; +static atomic_t zcache_curr_objnode_count = ATOMIC_INIT(0); +static unsigned long zcache_curr_objnode_count_max; + +/* + * to avoid memory allocation recursion (e.g. due to direct reclaim), we + * preload all necessary data structures so the hostops callbacks never + * actually do a malloc + */ +struct zcache_preload { + void *page; + struct tmem_obj *obj; + int nr; + struct tmem_objnode *objnodes[OBJNODE_TREE_MAX_PATH]; +}; +static DEFINE_PER_CPU(struct zcache_preload, zcache_preloads) = { 0, }; + +static int zcache_do_preload(struct tmem_pool *pool) +{ + struct zcache_preload *kp; + struct tmem_objnode *objnode; + struct tmem_obj *obj; + void *page; + int ret = -ENOMEM; + + if (unlikely(zcache_objnode_cache == NULL)) + goto out; + if (unlikely(zcache_obj_cache == NULL)) + goto out; + preempt_disable(); + kp = &__get_cpu_var(zcache_preloads); + while (kp->nr < ARRAY_SIZE(kp->objnodes)) { + preempt_enable_no_resched(); + objnode = kmem_cache_alloc(zcache_objnode_cache, + ZCACHE_GFP_MASK); + if (unlikely(objnode == NULL)) { + zcache_failed_alloc++; + goto out; + } + preempt_disable(); + kp = &__get_cpu_var(zcache_preloads); + if (kp->nr < ARRAY_SIZE(kp->objnodes)) + kp->objnodes[kp->nr++] = objnode; + else + kmem_cache_free(zcache_objnode_cache, objnode); + } + preempt_enable_no_resched(); + obj = kmem_cache_alloc(zcache_obj_cache, ZCACHE_GFP_MASK); + if (unlikely(obj == NULL)) { + zcache_failed_alloc++; + goto out; + } + page = (void *)__get_free_page(ZCACHE_GFP_MASK); + if (unlikely(page == NULL)) { + zcache_failed_get_free_pages++; + kmem_cache_free(zcache_obj_cache, obj); + goto out; + } + preempt_disable(); + kp = &__get_cpu_var(zcache_preloads); + if (kp->obj == NULL) + kp->obj = obj; + else + kmem_cache_free(zcache_obj_cache, obj); + if (kp->page == NULL) + kp->page = page; + else + free_page((unsigned long)page); + ret = 0; +out: + return ret; +} + +static void *zcache_get_free_page(void) +{ + struct zcache_preload *kp; + void *page; + + kp = &__get_cpu_var(zcache_preloads); + page = kp->page; + BUG_ON(page == NULL); + kp->page = NULL; + return page; +} + +static void zcache_free_page(void *p) +{ + free_page((unsigned long)p); +} + +/* + * zcache implementation for tmem host ops + */ + +static struct tmem_objnode *zcache_objnode_alloc(struct tmem_pool *pool) +{ + struct tmem_objnode *objnode = NULL; + unsigned long count; + struct zcache_preload *kp; + + kp = &__get_cpu_var(zcache_preloads); + if (kp->nr <= 0) + goto out; + objnode = kp->objnodes[kp->nr - 1]; + BUG_ON(objnode == NULL); + kp->objnodes[kp->nr - 1] = NULL; + kp->nr--; + count = atomic_inc_return(&zcache_curr_objnode_count); + if (count > zcache_curr_objnode_count_max) + zcache_curr_objnode_count_max = count; +out: + return objnode; +} + +static void zcache_objnode_free(struct tmem_objnode *objnode, + struct tmem_pool *pool) +{ + atomic_dec(&zcache_curr_objnode_count); + BUG_ON(atomic_read(&zcache_curr_objnode_count) < 0); + kmem_cache_free(zcache_objnode_cache, objnode); +} + +static struct tmem_obj *zcache_obj_alloc(struct tmem_pool *pool) +{ + struct tmem_obj *obj = NULL; + unsigned long count; + struct zcache_preload *kp; + + kp = &__get_cpu_var(zcache_preloads); + obj = kp->obj; + BUG_ON(obj == NULL); + kp->obj = NULL; + count = atomic_inc_return(&zcache_curr_obj_count); + if (count > zcache_curr_obj_count_max) + zcache_curr_obj_count_max = count; + return obj; +} + +static void zcache_obj_free(struct tmem_obj *obj, struct tmem_pool *pool) +{ + atomic_dec(&zcache_curr_obj_count); + BUG_ON(atomic_read(&zcache_curr_obj_count) < 0); + kmem_cache_free(zcache_obj_cache, obj); +} + +static struct tmem_hostops zcache_hostops = { + .obj_alloc = zcache_obj_alloc, + .obj_free = zcache_obj_free, + .objnode_alloc = zcache_objnode_alloc, + .objnode_free = zcache_objnode_free, +}; + +/* + * zcache implementations for PAM page descriptor ops + */ + +static atomic_t zcache_curr_eph_pampd_count = ATOMIC_INIT(0); +static unsigned long zcache_curr_eph_pampd_count_max; +static atomic_t zcache_curr_pers_pampd_count = ATOMIC_INIT(0); +static unsigned long zcache_curr_pers_pampd_count_max; + +/* forward reference */ +static int zcache_compress(struct page *from, void **out_va, size_t *out_len); + +static void *zcache_pampd_create(char *data, size_t size, bool raw, int eph, + struct tmem_pool *pool, struct tmem_oid *oid, + uint32_t index) +{ + void *pampd = NULL, *cdata; + size_t clen; + int ret; + unsigned long count; + struct page *page = (struct page *)(data); + struct zcache_client *cli = pool->client; + uint16_t client_id = get_client_id_from_client(cli); + unsigned long zv_mean_zsize; + unsigned long curr_pers_pampd_count; + u64 total_zsize; + + if (eph) { + ret = zcache_compress(page, &cdata, &clen); + if (ret == 0) + goto out; + if (clen == 0 || clen > zbud_max_buddy_size()) { + zcache_compress_poor++; + goto out; + } + pampd = (void *)zbud_create(client_id, pool->pool_id, oid, + index, page, cdata, clen); + if (pampd != NULL) { + count = atomic_inc_return(&zcache_curr_eph_pampd_count); + if (count > zcache_curr_eph_pampd_count_max) + zcache_curr_eph_pampd_count_max = count; + } + } else { + curr_pers_pampd_count = + atomic_read(&zcache_curr_pers_pampd_count); + if (curr_pers_pampd_count > + (zv_page_count_policy_percent * totalram_pages) / 100) + goto out; + ret = zcache_compress(page, &cdata, &clen); + if (ret == 0) + goto out; + /* reject if compression is too poor */ + if (clen > zv_max_zsize) { + zcache_compress_poor++; + goto out; + } + /* reject if mean compression is too poor */ + if ((clen > zv_max_mean_zsize) && (curr_pers_pampd_count > 0)) { + total_zsize = xv_get_total_size_bytes(cli->xvpool); + zv_mean_zsize = div_u64(total_zsize, + curr_pers_pampd_count); + if (zv_mean_zsize > zv_max_mean_zsize) { + zcache_mean_compress_poor++; + goto out; + } + } + pampd = (void *)zv_create(cli->xvpool, pool->pool_id, + oid, index, cdata, clen); + if (pampd == NULL) + goto out; + count = atomic_inc_return(&zcache_curr_pers_pampd_count); + if (count > zcache_curr_pers_pampd_count_max) + zcache_curr_pers_pampd_count_max = count; + } +out: + return pampd; +} + +/* + * fill the pageframe corresponding to the struct page with the data + * from the passed pampd + */ +static int zcache_pampd_get_data(char *data, size_t *bufsize, bool raw, + void *pampd, struct tmem_pool *pool, + struct tmem_oid *oid, uint32_t index) +{ + int ret = 0; + + BUG_ON(is_ephemeral(pool)); + zv_decompress((struct page *)(data), pampd); + return ret; +} + +/* + * fill the pageframe corresponding to the struct page with the data + * from the passed pampd + */ +static int zcache_pampd_get_data_and_free(char *data, size_t *bufsize, bool raw, + void *pampd, struct tmem_pool *pool, + struct tmem_oid *oid, uint32_t index) +{ + int ret = 0; + + BUG_ON(!is_ephemeral(pool)); + zbud_decompress((struct page *)(data), pampd); + zbud_free_and_delist((struct zbud_hdr *)pampd); + atomic_dec(&zcache_curr_eph_pampd_count); + return ret; +} + +/* + * free the pampd and remove it from any zcache lists + * pampd must no longer be pointed to from any tmem data structures! + */ +static void zcache_pampd_free(void *pampd, struct tmem_pool *pool, + struct tmem_oid *oid, uint32_t index) +{ + struct zcache_client *cli = pool->client; + + if (is_ephemeral(pool)) { + zbud_free_and_delist((struct zbud_hdr *)pampd); + atomic_dec(&zcache_curr_eph_pampd_count); + BUG_ON(atomic_read(&zcache_curr_eph_pampd_count) < 0); + } else { + zv_free(cli->xvpool, (struct zv_hdr *)pampd); + atomic_dec(&zcache_curr_pers_pampd_count); + BUG_ON(atomic_read(&zcache_curr_pers_pampd_count) < 0); + } +} + +static void zcache_pampd_free_obj(struct tmem_pool *pool, struct tmem_obj *obj) +{ +} + +static void zcache_pampd_new_obj(struct tmem_obj *obj) +{ +} + +static int zcache_pampd_replace_in_obj(void *pampd, struct tmem_obj *obj) +{ + return -1; +} + +static bool zcache_pampd_is_remote(void *pampd) +{ + return 0; +} + +static struct tmem_pamops zcache_pamops = { + .create = zcache_pampd_create, + .get_data = zcache_pampd_get_data, + .get_data_and_free = zcache_pampd_get_data_and_free, + .free = zcache_pampd_free, + .free_obj = zcache_pampd_free_obj, + .new_obj = zcache_pampd_new_obj, + .replace_in_obj = zcache_pampd_replace_in_obj, + .is_remote = zcache_pampd_is_remote, +}; + +/* + * zcache compression/decompression and related per-cpu stuff + */ + +#define LZO_WORKMEM_BYTES LZO1X_1_MEM_COMPRESS +#define LZO_DSTMEM_PAGE_ORDER 1 +static DEFINE_PER_CPU(unsigned char *, zcache_workmem); +static DEFINE_PER_CPU(unsigned char *, zcache_dstmem); + +static int zcache_compress(struct page *from, void **out_va, size_t *out_len) +{ + int ret = 0; + unsigned char *dmem = __get_cpu_var(zcache_dstmem); + unsigned char *wmem = __get_cpu_var(zcache_workmem); + char *from_va; + + BUG_ON(!irqs_disabled()); + if (unlikely(dmem == NULL || wmem == NULL)) + goto out; /* no buffer, so can't compress */ + from_va = kmap_atomic(from, KM_USER0); + mb(); + ret = lzo1x_1_compress(from_va, PAGE_SIZE, dmem, out_len, wmem); + BUG_ON(ret != LZO_E_OK); + *out_va = dmem; + kunmap_atomic(from_va, KM_USER0); + ret = 1; +out: + return ret; +} + + +static int zcache_cpu_notifier(struct notifier_block *nb, + unsigned long action, void *pcpu) +{ + int cpu = (long)pcpu; + struct zcache_preload *kp; + + switch (action) { + case CPU_UP_PREPARE: + per_cpu(zcache_dstmem, cpu) = (void *)__get_free_pages( + GFP_KERNEL | __GFP_REPEAT, + LZO_DSTMEM_PAGE_ORDER), + per_cpu(zcache_workmem, cpu) = + kzalloc(LZO1X_MEM_COMPRESS, + GFP_KERNEL | __GFP_REPEAT); + break; + case CPU_DEAD: + case CPU_UP_CANCELED: + free_pages((unsigned long)per_cpu(zcache_dstmem, cpu), + LZO_DSTMEM_PAGE_ORDER); + per_cpu(zcache_dstmem, cpu) = NULL; + kfree(per_cpu(zcache_workmem, cpu)); + per_cpu(zcache_workmem, cpu) = NULL; + kp = &per_cpu(zcache_preloads, cpu); + while (kp->nr) { + kmem_cache_free(zcache_objnode_cache, + kp->objnodes[kp->nr - 1]); + kp->objnodes[kp->nr - 1] = NULL; + kp->nr--; + } + if (kp->obj) { + kmem_cache_free(zcache_obj_cache, kp->obj); + kp->obj = NULL; + } + if (kp->page) { + free_page((unsigned long)kp->page); + kp->page = NULL; + } + break; + default: + break; + } + return NOTIFY_OK; +} + +static struct notifier_block zcache_cpu_notifier_block = { + .notifier_call = zcache_cpu_notifier +}; + +#ifdef CONFIG_SYSFS +#define ZCACHE_SYSFS_RO(_name) \ + static ssize_t zcache_##_name##_show(struct kobject *kobj, \ + struct kobj_attribute *attr, char *buf) \ + { \ + return sprintf(buf, "%lu\n", zcache_##_name); \ + } \ + static struct kobj_attribute zcache_##_name##_attr = { \ + .attr = { .name = __stringify(_name), .mode = 0444 }, \ + .show = zcache_##_name##_show, \ + } + +#define ZCACHE_SYSFS_RO_ATOMIC(_name) \ + static ssize_t zcache_##_name##_show(struct kobject *kobj, \ + struct kobj_attribute *attr, char *buf) \ + { \ + return sprintf(buf, "%d\n", atomic_read(&zcache_##_name)); \ + } \ + static struct kobj_attribute zcache_##_name##_attr = { \ + .attr = { .name = __stringify(_name), .mode = 0444 }, \ + .show = zcache_##_name##_show, \ + } + +#define ZCACHE_SYSFS_RO_CUSTOM(_name, _func) \ + static ssize_t zcache_##_name##_show(struct kobject *kobj, \ + struct kobj_attribute *attr, char *buf) \ + { \ + return _func(buf); \ + } \ + static struct kobj_attribute zcache_##_name##_attr = { \ + .attr = { .name = __stringify(_name), .mode = 0444 }, \ + .show = zcache_##_name##_show, \ + } + +ZCACHE_SYSFS_RO(curr_obj_count_max); +ZCACHE_SYSFS_RO(curr_objnode_count_max); +ZCACHE_SYSFS_RO(flush_total); +ZCACHE_SYSFS_RO(flush_found); +ZCACHE_SYSFS_RO(flobj_total); +ZCACHE_SYSFS_RO(flobj_found); +ZCACHE_SYSFS_RO(failed_eph_puts); +ZCACHE_SYSFS_RO(failed_pers_puts); +ZCACHE_SYSFS_RO(zbud_curr_zbytes); +ZCACHE_SYSFS_RO(zbud_cumul_zpages); +ZCACHE_SYSFS_RO(zbud_cumul_zbytes); +ZCACHE_SYSFS_RO(zbud_buddied_count); +ZCACHE_SYSFS_RO(zbpg_unused_list_count); +ZCACHE_SYSFS_RO(evicted_raw_pages); +ZCACHE_SYSFS_RO(evicted_unbuddied_pages); +ZCACHE_SYSFS_RO(evicted_buddied_pages); +ZCACHE_SYSFS_RO(failed_get_free_pages); +ZCACHE_SYSFS_RO(failed_alloc); +ZCACHE_SYSFS_RO(put_to_flush); +ZCACHE_SYSFS_RO(compress_poor); +ZCACHE_SYSFS_RO(mean_compress_poor); +ZCACHE_SYSFS_RO_ATOMIC(zbud_curr_raw_pages); +ZCACHE_SYSFS_RO_ATOMIC(zbud_curr_zpages); +ZCACHE_SYSFS_RO_ATOMIC(curr_obj_count); +ZCACHE_SYSFS_RO_ATOMIC(curr_objnode_count); +ZCACHE_SYSFS_RO_CUSTOM(zbud_unbuddied_list_counts, + zbud_show_unbuddied_list_counts); +ZCACHE_SYSFS_RO_CUSTOM(zbud_cumul_chunk_counts, + zbud_show_cumul_chunk_counts); +ZCACHE_SYSFS_RO_CUSTOM(zv_curr_dist_counts, + zv_curr_dist_counts_show); +ZCACHE_SYSFS_RO_CUSTOM(zv_cumul_dist_counts, + zv_cumul_dist_counts_show); + +static struct attribute *zcache_attrs[] = { + &zcache_curr_obj_count_attr.attr, + &zcache_curr_obj_count_max_attr.attr, + &zcache_curr_objnode_count_attr.attr, + &zcache_curr_objnode_count_max_attr.attr, + &zcache_flush_total_attr.attr, + &zcache_flobj_total_attr.attr, + &zcache_flush_found_attr.attr, + &zcache_flobj_found_attr.attr, + &zcache_failed_eph_puts_attr.attr, + &zcache_failed_pers_puts_attr.attr, + &zcache_compress_poor_attr.attr, + &zcache_mean_compress_poor_attr.attr, + &zcache_zbud_curr_raw_pages_attr.attr, + &zcache_zbud_curr_zpages_attr.attr, + &zcache_zbud_curr_zbytes_attr.attr, + &zcache_zbud_cumul_zpages_attr.attr, + &zcache_zbud_cumul_zbytes_attr.attr, + &zcache_zbud_buddied_count_attr.attr, + &zcache_zbpg_unused_list_count_attr.attr, + &zcache_evicted_raw_pages_attr.attr, + &zcache_evicted_unbuddied_pages_attr.attr, + &zcache_evicted_buddied_pages_attr.attr, + &zcache_failed_get_free_pages_attr.attr, + &zcache_failed_alloc_attr.attr, + &zcache_put_to_flush_attr.attr, + &zcache_zbud_unbuddied_list_counts_attr.attr, + &zcache_zbud_cumul_chunk_counts_attr.attr, + &zcache_zv_curr_dist_counts_attr.attr, + &zcache_zv_cumul_dist_counts_attr.attr, + &zcache_zv_max_zsize_attr.attr, + &zcache_zv_max_mean_zsize_attr.attr, + &zcache_zv_page_count_policy_percent_attr.attr, + NULL, +}; + +static struct attribute_group zcache_attr_group = { + .attrs = zcache_attrs, + .name = "zcache", +}; + +#endif /* CONFIG_SYSFS */ +/* + * When zcache is disabled ("frozen"), pools can be created and destroyed, + * but all puts (and thus all other operations that require memory allocation) + * must fail. If zcache is unfrozen, accepts puts, then frozen again, + * data consistency requires all puts while frozen to be converted into + * flushes. + */ +static bool zcache_freeze; + +/* + * zcache shrinker interface (only useful for ephemeral pages, so zbud only) + */ +static int shrink_zcache_memory(struct shrinker *shrink, + struct shrink_control *sc) +{ + int ret = -1; + int nr = sc->nr_to_scan; + gfp_t gfp_mask = sc->gfp_mask; + + if (nr >= 0) { + if (!(gfp_mask & __GFP_FS)) + /* does this case really need to be skipped? */ + goto out; + zbud_evict_pages(nr); + } + ret = (int)atomic_read(&zcache_zbud_curr_raw_pages); +out: + return ret; +} + +static struct shrinker zcache_shrinker = { + .shrink = shrink_zcache_memory, + .seeks = DEFAULT_SEEKS, +}; + +/* + * zcache shims between cleancache/frontswap ops and tmem + */ + +static int zcache_put_page(int cli_id, int pool_id, struct tmem_oid *oidp, + uint32_t index, struct page *page) +{ + struct tmem_pool *pool; + int ret = -1; + + BUG_ON(!irqs_disabled()); + pool = zcache_get_pool_by_id(cli_id, pool_id); + if (unlikely(pool == NULL)) + goto out; + if (!zcache_freeze && zcache_do_preload(pool) == 0) { + /* preload does preempt_disable on success */ + ret = tmem_put(pool, oidp, index, (char *)(page), + PAGE_SIZE, 0, is_ephemeral(pool)); + if (ret < 0) { + if (is_ephemeral(pool)) + zcache_failed_eph_puts++; + else + zcache_failed_pers_puts++; + } + zcache_put_pool(pool); + preempt_enable_no_resched(); + } else { + zcache_put_to_flush++; + if (atomic_read(&pool->obj_count) > 0) + /* the put fails whether the flush succeeds or not */ + (void)tmem_flush_page(pool, oidp, index); + zcache_put_pool(pool); + } +out: + return ret; +} + +static int zcache_get_page(int cli_id, int pool_id, struct tmem_oid *oidp, + uint32_t index, struct page *page) +{ + struct tmem_pool *pool; + int ret = -1; + unsigned long flags; + size_t size = PAGE_SIZE; + + local_irq_save(flags); + pool = zcache_get_pool_by_id(cli_id, pool_id); + if (likely(pool != NULL)) { + if (atomic_read(&pool->obj_count) > 0) + ret = tmem_get(pool, oidp, index, (char *)(page), + &size, 0, is_ephemeral(pool)); + zcache_put_pool(pool); + } + local_irq_restore(flags); + return ret; +} + +static int zcache_flush_page(int cli_id, int pool_id, + struct tmem_oid *oidp, uint32_t index) +{ + struct tmem_pool *pool; + int ret = -1; + unsigned long flags; + + local_irq_save(flags); + zcache_flush_total++; + pool = zcache_get_pool_by_id(cli_id, pool_id); + if (likely(pool != NULL)) { + if (atomic_read(&pool->obj_count) > 0) + ret = tmem_flush_page(pool, oidp, index); + zcache_put_pool(pool); + } + if (ret >= 0) + zcache_flush_found++; + local_irq_restore(flags); + return ret; +} + +static int zcache_flush_object(int cli_id, int pool_id, + struct tmem_oid *oidp) +{ + struct tmem_pool *pool; + int ret = -1; + unsigned long flags; + + local_irq_save(flags); + zcache_flobj_total++; + pool = zcache_get_pool_by_id(cli_id, pool_id); + if (likely(pool != NULL)) { + if (atomic_read(&pool->obj_count) > 0) + ret = tmem_flush_object(pool, oidp); + zcache_put_pool(pool); + } + if (ret >= 0) + zcache_flobj_found++; + local_irq_restore(flags); + return ret; +} + +static int zcache_destroy_pool(int cli_id, int pool_id) +{ + struct tmem_pool *pool = NULL; + struct zcache_client *cli = NULL; + int ret = -1; + + if (pool_id < 0) + goto out; + if (cli_id == LOCAL_CLIENT) + cli = &zcache_host; + else if ((unsigned int)cli_id < MAX_CLIENTS) + cli = &zcache_clients[cli_id]; + if (cli == NULL) + goto out; + atomic_inc(&cli->refcount); + pool = cli->tmem_pools[pool_id]; + if (pool == NULL) + goto out; + cli->tmem_pools[pool_id] = NULL; + /* wait for pool activity on other cpus to quiesce */ + while (atomic_read(&pool->refcount) != 0) + ; + atomic_dec(&cli->refcount); + local_bh_disable(); + ret = tmem_destroy_pool(pool); + local_bh_enable(); + kfree(pool); + pr_info("zcache: destroyed pool id=%d, cli_id=%d\n", + pool_id, cli_id); +out: + return ret; +} + +static int zcache_new_pool(uint16_t cli_id, uint32_t flags) +{ + int poolid = -1; + struct tmem_pool *pool; + struct zcache_client *cli = NULL; + + if (cli_id == LOCAL_CLIENT) + cli = &zcache_host; + else if ((unsigned int)cli_id < MAX_CLIENTS) + cli = &zcache_clients[cli_id]; + if (cli == NULL) + goto out; + atomic_inc(&cli->refcount); + pool = kmalloc(sizeof(struct tmem_pool), GFP_ATOMIC); + if (pool == NULL) { + pr_info("zcache: pool creation failed: out of memory\n"); + goto out; + } + + for (poolid = 0; poolid < MAX_POOLS_PER_CLIENT; poolid++) + if (cli->tmem_pools[poolid] == NULL) + break; + if (poolid >= MAX_POOLS_PER_CLIENT) { + pr_info("zcache: pool creation failed: max exceeded\n"); + kfree(pool); + poolid = -1; + goto out; + } + atomic_set(&pool->refcount, 0); + pool->client = cli; + pool->pool_id = poolid; + tmem_new_pool(pool, flags); + cli->tmem_pools[poolid] = pool; + pr_info("zcache: created %s tmem pool, id=%d, client=%d\n", + flags & TMEM_POOL_PERSIST ? "persistent" : "ephemeral", + poolid, cli_id); +out: + if (cli != NULL) + atomic_dec(&cli->refcount); + return poolid; +} + +/********** + * Two kernel functionalities currently can be layered on top of tmem. + * These are "cleancache" which is used as a second-chance cache for clean + * page cache pages; and "frontswap" which is used for swap pages + * to avoid writes to disk. A generic "shim" is provided here for each + * to translate in-kernel semantics to zcache semantics. + */ + +#ifdef CONFIG_CLEANCACHE +static void zcache_cleancache_put_page(int pool_id, + struct cleancache_filekey key, + pgoff_t index, struct page *page) +{ + u32 ind = (u32) index; + struct tmem_oid oid = *(struct tmem_oid *)&key; + + if (likely(ind == index)) + (void)zcache_put_page(LOCAL_CLIENT, pool_id, &oid, index, page); +} + +static int zcache_cleancache_get_page(int pool_id, + struct cleancache_filekey key, + pgoff_t index, struct page *page) +{ + u32 ind = (u32) index; + struct tmem_oid oid = *(struct tmem_oid *)&key; + int ret = -1; + + if (likely(ind == index)) + ret = zcache_get_page(LOCAL_CLIENT, pool_id, &oid, index, page); + return ret; +} + +static void zcache_cleancache_flush_page(int pool_id, + struct cleancache_filekey key, + pgoff_t index) +{ + u32 ind = (u32) index; + struct tmem_oid oid = *(struct tmem_oid *)&key; + + if (likely(ind == index)) + (void)zcache_flush_page(LOCAL_CLIENT, pool_id, &oid, ind); +} + +static void zcache_cleancache_flush_inode(int pool_id, + struct cleancache_filekey key) +{ + struct tmem_oid oid = *(struct tmem_oid *)&key; + + (void)zcache_flush_object(LOCAL_CLIENT, pool_id, &oid); +} + +static void zcache_cleancache_flush_fs(int pool_id) +{ + if (pool_id >= 0) + (void)zcache_destroy_pool(LOCAL_CLIENT, pool_id); +} + +static int zcache_cleancache_init_fs(size_t pagesize) +{ + BUG_ON(sizeof(struct cleancache_filekey) != + sizeof(struct tmem_oid)); + BUG_ON(pagesize != PAGE_SIZE); + return zcache_new_pool(LOCAL_CLIENT, 0); +} + +static int zcache_cleancache_init_shared_fs(char *uuid, size_t pagesize) +{ + /* shared pools are unsupported and map to private */ + BUG_ON(sizeof(struct cleancache_filekey) != + sizeof(struct tmem_oid)); + BUG_ON(pagesize != PAGE_SIZE); + return zcache_new_pool(LOCAL_CLIENT, 0); +} + +static struct cleancache_ops zcache_cleancache_ops = { + .put_page = zcache_cleancache_put_page, + .get_page = zcache_cleancache_get_page, + .invalidate_page = zcache_cleancache_flush_page, + .invalidate_inode = zcache_cleancache_flush_inode, + .invalidate_fs = zcache_cleancache_flush_fs, + .init_shared_fs = zcache_cleancache_init_shared_fs, + .init_fs = zcache_cleancache_init_fs +}; + +struct cleancache_ops zcache_cleancache_register_ops(void) +{ + struct cleancache_ops old_ops = + cleancache_register_ops(&zcache_cleancache_ops); + + return old_ops; +} +#endif + +#ifdef CONFIG_FRONTSWAP +/* a single tmem poolid is used for all frontswap "types" (swapfiles) */ +static int zcache_frontswap_poolid = -1; + +/* + * Swizzling increases objects per swaptype, increasing tmem concurrency + * for heavy swaploads. Later, larger nr_cpus -> larger SWIZ_BITS + * Setting SWIZ_BITS to 27 basically reconstructs the swap entry from + * frontswap_get_page() + */ +#define SWIZ_BITS 27 +#define SWIZ_MASK ((1 << SWIZ_BITS) - 1) +#define _oswiz(_type, _ind) ((_type << SWIZ_BITS) | (_ind & SWIZ_MASK)) +#define iswiz(_ind) (_ind >> SWIZ_BITS) + +static inline struct tmem_oid oswiz(unsigned type, u32 ind) +{ + struct tmem_oid oid = { .oid = { 0 } }; + oid.oid[0] = _oswiz(type, ind); + return oid; +} + +static int zcache_frontswap_put_page(unsigned type, pgoff_t offset, + struct page *page) +{ + u64 ind64 = (u64)offset; + u32 ind = (u32)offset; + struct tmem_oid oid = oswiz(type, ind); + int ret = -1; + unsigned long flags; + + BUG_ON(!PageLocked(page)); + if (likely(ind64 == ind)) { + local_irq_save(flags); + ret = zcache_put_page(LOCAL_CLIENT, zcache_frontswap_poolid, + &oid, iswiz(ind), page); + local_irq_restore(flags); + } + return ret; +} + +/* returns 0 if the page was successfully gotten from frontswap, -1 if + * was not present (should never happen!) */ +static int zcache_frontswap_get_page(unsigned type, pgoff_t offset, + struct page *page) +{ + u64 ind64 = (u64)offset; + u32 ind = (u32)offset; + struct tmem_oid oid = oswiz(type, ind); + int ret = -1; + + BUG_ON(!PageLocked(page)); + if (likely(ind64 == ind)) + ret = zcache_get_page(LOCAL_CLIENT, zcache_frontswap_poolid, + &oid, iswiz(ind), page); + return ret; +} + +/* flush a single page from frontswap */ +static void zcache_frontswap_flush_page(unsigned type, pgoff_t offset) +{ + u64 ind64 = (u64)offset; + u32 ind = (u32)offset; + struct tmem_oid oid = oswiz(type, ind); + + if (likely(ind64 == ind)) + (void)zcache_flush_page(LOCAL_CLIENT, zcache_frontswap_poolid, + &oid, iswiz(ind)); +} + +/* flush all pages from the passed swaptype */ +static void zcache_frontswap_flush_area(unsigned type) +{ + struct tmem_oid oid; + int ind; + + for (ind = SWIZ_MASK; ind >= 0; ind--) { + oid = oswiz(type, ind); + (void)zcache_flush_object(LOCAL_CLIENT, + zcache_frontswap_poolid, &oid); + } +} + +static void zcache_frontswap_init(unsigned ignored) +{ + /* a single tmem poolid is used for all frontswap "types" (swapfiles) */ + if (zcache_frontswap_poolid < 0) + zcache_frontswap_poolid = + zcache_new_pool(LOCAL_CLIENT, TMEM_POOL_PERSIST); +} + +static struct frontswap_ops zcache_frontswap_ops = { + .put_page = zcache_frontswap_put_page, + .get_page = zcache_frontswap_get_page, + .invalidate_page = zcache_frontswap_flush_page, + .invalidate_area = zcache_frontswap_flush_area, + .init = zcache_frontswap_init +}; + +struct frontswap_ops zcache_frontswap_register_ops(void) +{ + struct frontswap_ops old_ops = + frontswap_register_ops(&zcache_frontswap_ops); + + return old_ops; +} +#endif + +/* + * zcache initialization + * NOTE FOR NOW zcache MUST BE PROVIDED AS A KERNEL BOOT PARAMETER OR + * NOTHING HAPPENS! + */ + +static int zcache_enabled; + +static int __init enable_zcache(char *s) +{ + zcache_enabled = 1; + return 1; +} +__setup("zcache", enable_zcache); + +/* allow independent dynamic disabling of cleancache and frontswap */ + +static int use_cleancache = 1; + +static int __init no_cleancache(char *s) +{ + use_cleancache = 0; + return 1; +} + +__setup("nocleancache", no_cleancache); + +static int use_frontswap = 1; + +static int __init no_frontswap(char *s) +{ + use_frontswap = 0; + return 1; +} + +__setup("nofrontswap", no_frontswap); + +static int __init zcache_init(void) +{ + int ret = 0; + +#ifdef CONFIG_SYSFS + ret = sysfs_create_group(mm_kobj, &zcache_attr_group); + if (ret) { + pr_err("zcache: can't create sysfs\n"); + goto out; + } +#endif /* CONFIG_SYSFS */ +#if defined(CONFIG_CLEANCACHE) || defined(CONFIG_FRONTSWAP) + if (zcache_enabled) { + unsigned int cpu; + + tmem_register_hostops(&zcache_hostops); + tmem_register_pamops(&zcache_pamops); + ret = register_cpu_notifier(&zcache_cpu_notifier_block); + if (ret) { + pr_err("zcache: can't register cpu notifier\n"); + goto out; + } + for_each_online_cpu(cpu) { + void *pcpu = (void *)(long)cpu; + zcache_cpu_notifier(&zcache_cpu_notifier_block, + CPU_UP_PREPARE, pcpu); + } + } + zcache_objnode_cache = kmem_cache_create("zcache_objnode", + sizeof(struct tmem_objnode), 0, 0, NULL); + zcache_obj_cache = kmem_cache_create("zcache_obj", + sizeof(struct tmem_obj), 0, 0, NULL); + ret = zcache_new_client(LOCAL_CLIENT); + if (ret) { + pr_err("zcache: can't create client\n"); + goto out; + } +#endif +#ifdef CONFIG_CLEANCACHE + if (zcache_enabled && use_cleancache) { + struct cleancache_ops old_ops; + + zbud_init(); + register_shrinker(&zcache_shrinker); + old_ops = zcache_cleancache_register_ops(); + pr_info("zcache: cleancache enabled using kernel " + "transcendent memory and compression buddies\n"); + if (old_ops.init_fs != NULL) + pr_warning("zcache: cleancache_ops overridden"); + } +#endif +#ifdef CONFIG_FRONTSWAP + if (zcache_enabled && use_frontswap) { + struct frontswap_ops old_ops; + + old_ops = zcache_frontswap_register_ops(); + pr_info("zcache: frontswap enabled using kernel " + "transcendent memory and xvmalloc\n"); + if (old_ops.init != NULL) + pr_warning("zcache: frontswap_ops overridden"); + } +#endif +out: + return ret; +} + +module_init(zcache_init) -- cgit v1.2.3-70-g09d2 From b083e8619c84503e80e681504cabfb647e715edc Mon Sep 17 00:00:00 2001 From: Dan Magenheimer Date: Mon, 30 Jan 2012 14:39:18 -0800 Subject: staging: ramster: ramster-specific changes to cluster code Ramster-specific changes to ocfs2 cluster foundation, including: A method for fooling the o2 heartbeat into starting without an ocfs2 filesystem; a new message mechanism ("data magic") for handling a reply to a message requesting data; a hack for keeping the cluster alive even after timeouts so cluster machines can be rebooted separately. Signed-off-by: Dan Magenheimer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ramster/cluster/Makefile | 3 +- drivers/staging/ramster/cluster/heartbeat.c | 9 ++ drivers/staging/ramster/cluster/heartbeat.h | 3 + drivers/staging/ramster/cluster/tcp.c | 112 +++++++++++++++++++++++++ drivers/staging/ramster/cluster/tcp.h | 6 ++ drivers/staging/ramster/cluster/tcp_internal.h | 7 ++ 6 files changed, 139 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/ramster/cluster/Makefile b/drivers/staging/ramster/cluster/Makefile index bc8c5e7d860..3fc85508cf8 100644 --- a/drivers/staging/ramster/cluster/Makefile +++ b/drivers/staging/ramster/cluster/Makefile @@ -1,4 +1,5 @@ -obj-$(CONFIG_OCFS2_FS) += ocfs2_nodemanager.o +#obj-$(CONFIG_OCFS2_FS) += ocfs2_nodemanager.o +obj-$(CONFIG_RAMSTER) += ocfs2_nodemanager.o ocfs2_nodemanager-objs := heartbeat.o masklog.o sys.o nodemanager.o \ quorum.o tcp.o netdebug.o ver.o diff --git a/drivers/staging/ramster/cluster/heartbeat.c b/drivers/staging/ramster/cluster/heartbeat.c index a4e855e3690..1f72143e2d3 100644 --- a/drivers/staging/ramster/cluster/heartbeat.c +++ b/drivers/staging/ramster/cluster/heartbeat.c @@ -2676,3 +2676,12 @@ int o2hb_global_heartbeat_active(void) return (o2hb_heartbeat_mode == O2HB_HEARTBEAT_GLOBAL); } EXPORT_SYMBOL(o2hb_global_heartbeat_active); + +#ifdef CONFIG_RAMSTER +void o2hb_manual_set_node_heartbeating(int node_num) +{ + if (node_num < O2NM_MAX_NODES) + set_bit(node_num, o2hb_live_node_bitmap); +} +EXPORT_SYMBOL(o2hb_manual_set_node_heartbeating); +#endif diff --git a/drivers/staging/ramster/cluster/heartbeat.h b/drivers/staging/ramster/cluster/heartbeat.h index 00ad8e8fea5..cf1a16426d9 100644 --- a/drivers/staging/ramster/cluster/heartbeat.h +++ b/drivers/staging/ramster/cluster/heartbeat.h @@ -85,5 +85,8 @@ int o2hb_check_local_node_heartbeating(void); void o2hb_stop_all_regions(void); int o2hb_get_all_regions(char *region_uuids, u8 numregions); int o2hb_global_heartbeat_active(void); +#ifdef CONFIG_RAMSTER +void o2hb_manual_set_node_heartbeating(int); +#endif #endif /* O2CLUSTER_HEARTBEAT_H */ diff --git a/drivers/staging/ramster/cluster/tcp.c b/drivers/staging/ramster/cluster/tcp.c index 044e7b58d31..e9bd00eb405 100644 --- a/drivers/staging/ramster/cluster/tcp.c +++ b/drivers/staging/ramster/cluster/tcp.c @@ -288,7 +288,11 @@ static inline int o2net_sys_err_to_errno(enum o2net_system_error err) return trans; } +#ifdef CONFIG_RAMSTER +struct o2net_node *o2net_nn_from_num(u8 node_num) +#else static struct o2net_node * o2net_nn_from_num(u8 node_num) +#endif { BUG_ON(node_num >= ARRAY_SIZE(o2net_nodes)); return &o2net_nodes[node_num]; @@ -1068,6 +1072,11 @@ int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec, }; struct o2net_send_tracking nst; +#ifdef CONFIG_RAMSTER + /* this may be a general bug fix */ + init_waitqueue_head(&nsw.ns_wq); +#endif + o2net_init_nst(&nst, msg_type, key, current, target_node); if (o2net_wq == NULL) { @@ -1208,6 +1217,52 @@ static int o2net_send_status_magic(struct socket *sock, struct o2net_msg *hdr, return o2net_send_tcp_msg(sock, &vec, 1, sizeof(struct o2net_msg)); } +#ifdef CONFIG_RAMSTER +/* + * "data magic" is a long version of "status magic" where the message + * payload actually contains data to be passed in reply to certain messages + */ +static int o2net_send_data_magic(struct o2net_sock_container *sc, + struct o2net_msg *hdr, + void *data, size_t data_len, + enum o2net_system_error syserr, int err) +{ + struct kvec vec[2]; + int ret; + + vec[0].iov_base = hdr; + vec[0].iov_len = sizeof(struct o2net_msg); + vec[1].iov_base = data; + vec[1].iov_len = data_len; + + BUG_ON(syserr >= O2NET_ERR_MAX); + + /* leave other fields intact from the incoming message, msg_num + * in particular */ + hdr->sys_status = cpu_to_be32(syserr); + hdr->status = cpu_to_be32(err); + hdr->magic = cpu_to_be16(O2NET_MSG_DATA_MAGIC); /* twiddle magic */ + hdr->data_len = cpu_to_be16(data_len); + + msglog(hdr, "about to send data magic %d\n", err); + /* hdr has been in host byteorder this whole time */ + ret = o2net_send_tcp_msg(sc->sc_sock, vec, 2, + sizeof(struct o2net_msg) + data_len); + return ret; +} + +/* + * called by a message handler to convert an otherwise normal reply + * message into a "data magic" message + */ +void o2net_force_data_magic(struct o2net_msg *hdr, u16 msgtype, u32 msgkey) +{ + hdr->magic = cpu_to_be16(O2NET_MSG_DATA_MAGIC); + hdr->msg_type = cpu_to_be16(msgtype); + hdr->key = cpu_to_be32(msgkey); +} +#endif + /* this returns -errno if the header was unknown or too large, etc. * after this is called the buffer us reused for the next message */ static int o2net_process_message(struct o2net_sock_container *sc, @@ -1218,6 +1273,9 @@ static int o2net_process_message(struct o2net_sock_container *sc, enum o2net_system_error syserr; struct o2net_msg_handler *nmh = NULL; void *ret_data = NULL; +#ifdef CONFIG_RAMSTER + int data_magic = 0; +#endif msglog(hdr, "processing message\n"); @@ -1239,6 +1297,16 @@ static int o2net_process_message(struct o2net_sock_container *sc, goto out; case O2NET_MSG_MAGIC: break; +#ifdef CONFIG_RAMSTER + case O2NET_MSG_DATA_MAGIC: + /* + * unlike a normal status magic, a data magic DOES + * (MUST) have a handler, so the control flow is + * a little funky here as a result + */ + data_magic = 1; + break; +#endif default: msglog(hdr, "bad magic\n"); ret = -EINVAL; @@ -1271,6 +1339,34 @@ static int o2net_process_message(struct o2net_sock_container *sc, handler_status = (nmh->nh_func)(hdr, sizeof(struct o2net_msg) + be16_to_cpu(hdr->data_len), nmh->nh_func_data, &ret_data); +#ifdef CONFIG_RAMSTER + if (data_magic) { + /* + * handler handled data sent in reply to request + * so complete the transaction + */ + o2net_complete_nsw(nn, NULL, be32_to_cpu(hdr->msg_num), + be32_to_cpu(hdr->sys_status), handler_status); + goto out; + } + /* + * handler changed magic to DATA_MAGIC to reply to request for data, + * implies ret_data points to data to return and handler_status + * is the number of bytes of data + */ + if (be16_to_cpu(hdr->magic) == O2NET_MSG_DATA_MAGIC) { + ret = o2net_send_data_magic(sc, hdr, + ret_data, handler_status, + syserr, 0); + hdr = NULL; + mlog(0, "sending data reply %d, syserr %d returned %d\n", + handler_status, syserr, ret); + o2net_set_func_stop_time(sc); + + o2net_update_recv_stats(sc); + goto out; + } +#endif o2net_set_func_stop_time(sc); o2net_update_recv_stats(sc); @@ -1558,7 +1654,9 @@ static void o2net_sc_send_keep_req(struct work_struct *work) static void o2net_idle_timer(unsigned long data) { struct o2net_sock_container *sc = (struct o2net_sock_container *)data; +#ifndef CONFIG_RAMSTER struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num); +#endif #ifdef CONFIG_DEBUG_FS unsigned long msecs = ktime_to_ms(ktime_get()) - ktime_to_ms(sc->sc_tv_timer); @@ -1574,9 +1672,14 @@ static void o2net_idle_timer(unsigned long data) * Initialize the nn_timeout so that the next connection attempt * will continue in o2net_start_connect. */ +#ifdef CONFIG_RAMSTER + /* Avoid spurious shutdowns... not sure if this is still necessary */ + pr_err("o2net_idle_timer, skipping shutdown work\n"); +#else atomic_set(&nn->nn_timeout, 1); o2net_sc_queue_work(sc, &sc->sc_shutdown_work); +#endif } static void o2net_sc_reset_idle_timer(struct o2net_sock_container *sc) @@ -2094,6 +2197,15 @@ void o2net_stop_listening(struct o2nm_node *node) o2quo_conn_err(node->nd_num); } +#ifdef CONFIG_RAMSTER +void o2net_hb_node_up_manual(int node_num) +{ + struct o2nm_node dummy; + o2hb_manual_set_node_heartbeating(node_num); + o2net_hb_node_up_cb(&dummy, node_num, NULL); +} +#endif + /* ------------------------------------------------------------ */ int o2net_init(void) diff --git a/drivers/staging/ramster/cluster/tcp.h b/drivers/staging/ramster/cluster/tcp.h index 5bada2a69b5..95a991f2f63 100644 --- a/drivers/staging/ramster/cluster/tcp.h +++ b/drivers/staging/ramster/cluster/tcp.h @@ -108,6 +108,12 @@ void o2net_unregister_handler_list(struct list_head *list); void o2net_fill_node_map(unsigned long *map, unsigned bytes); +#ifdef CONFIG_RAMSTER +void o2net_force_data_magic(struct o2net_msg *, u16, u32); +void o2net_hb_node_up_manual(int); +struct o2net_node *o2net_nn_from_num(u8); +#endif + struct o2nm_node; int o2net_register_hb_callbacks(void); void o2net_unregister_hb_callbacks(void); diff --git a/drivers/staging/ramster/cluster/tcp_internal.h b/drivers/staging/ramster/cluster/tcp_internal.h index 4cbcb65784a..ce171350c31 100644 --- a/drivers/staging/ramster/cluster/tcp_internal.h +++ b/drivers/staging/ramster/cluster/tcp_internal.h @@ -26,6 +26,13 @@ #define O2NET_MSG_STATUS_MAGIC ((u16)0xfa56) #define O2NET_MSG_KEEP_REQ_MAGIC ((u16)0xfa57) #define O2NET_MSG_KEEP_RESP_MAGIC ((u16)0xfa58) +#ifdef CONFIG_RAMSTER +/* + * "data magic" is a long version of "status magic" where the message + * payload actually contains data to be passed in reply to certain messages + */ +#define O2NET_MSG_DATA_MAGIC ((u16)0xfa59) +#endif /* we're delaying our quorum decision so that heartbeat will have timed * out truly dead nodes by the time we come around to making decisions -- cgit v1.2.3-70-g09d2 From 0fb3860a8212bfce09e4c53ab342b84adb934159 Mon Sep 17 00:00:00 2001 From: Dan Magenheimer Date: Mon, 30 Jan 2012 14:39:19 -0800 Subject: staging: ramster: ramster-specific changes to zcache/tmem In tmem.[ch], new "repatriate" (provoke async get) and "localify" (handle incoming data resulting from an async get) routines combine with a handful of changes to existing pamops interfaces allow the generic tmem code to support asynchronous operations. Also, a new tmem_xhandle struct groups together key information that must be passed to remote tmem stores. Zcache-main.c is augmented with a large amount of ramster-specific code to handle remote operations and "foreign" pages on both ends of the "remotify" protocol. New "foreign" pools are auto-created on demand. A "selfshrinker" thread periodically repatriates remote persistent pages when local memory conditions allow. For certain operations, a queue is necessary to guarantee strict ordering as out-of-order puts/flushes can cause strange race conditions. Pampd pointers now either point to local memory OR describe a remote page; to allow the same 64-bits to describe either, the LSB is used to differentiate. Some acrobatics must be performed to ensure local memory is available to handle a remote persistent get, or deal with the data directly anyway if the malloc failed. Lots of ramster-specific statistics are available via sysfs. Note: Some debug ifdefs left in for now. Signed-off-by: Dan Magenheimer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ramster/Kconfig | 17 +- drivers/staging/ramster/Makefile | 5 +- drivers/staging/ramster/tmem.c | 115 ++- drivers/staging/ramster/tmem.h | 46 +- drivers/staging/ramster/zcache-main.c | 1776 ++++++++++++++++++++++++++++----- 5 files changed, 1677 insertions(+), 282 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ramster/Kconfig b/drivers/staging/ramster/Kconfig index 7fabcb2bc80..3957b875afc 100644 --- a/drivers/staging/ramster/Kconfig +++ b/drivers/staging/ramster/Kconfig @@ -1,13 +1,14 @@ -config ZCACHE - tristate "Dynamic compression of swap pages and clean pagecache pages" - depends on CLEANCACHE || FRONTSWAP +config RAMSTER + tristate "Cross-machine RAM capacity sharing, aka peer-to-peer tmem" + depends on (CLEANCACHE || FRONTSWAP) && CONFIGFS_FS && !OCFS2_FS && !ZCACHE && !HIGHMEM select XVMALLOC select LZO_COMPRESS select LZO_DECOMPRESS default n help - Zcache doubles RAM efficiency while providing a significant - performance boosts on many workloads. Zcache uses lzo1x - compression and an in-kernel implementation of transcendent - memory to store clean page cache pages and swap in RAM, - providing a noticeable reduction in disk I/O. + RAMster allows RAM on other machines in a cluster to be utilized + dynamically and symmetrically instead of swapping to a local swap + disk, thus improving performance on memory-constrained workloads + while minimizing total RAM across the cluster. RAMster, like + zcache, compresses swap pages into local RAM, but then remotifies + the compressed pages to another node in the RAMster cluster. diff --git a/drivers/staging/ramster/Makefile b/drivers/staging/ramster/Makefile index 60daa272c20..e6c4a2eb14d 100644 --- a/drivers/staging/ramster/Makefile +++ b/drivers/staging/ramster/Makefile @@ -1,3 +1,2 @@ -zcache-y := zcache-main.o tmem.o - -obj-$(CONFIG_ZCACHE) += zcache.o +obj-$(CONFIG_RAMSTER) += zcache-main.o tmem.o +obj-$(CONFIG_RAMSTER) += ramster_o2net.o cluster/ diff --git a/drivers/staging/ramster/tmem.c b/drivers/staging/ramster/tmem.c index 1ca66ea9b28..8f2f6892d8d 100644 --- a/drivers/staging/ramster/tmem.c +++ b/drivers/staging/ramster/tmem.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "tmem.h" @@ -316,7 +317,7 @@ static void *tmem_pampd_lookup_in_obj(struct tmem_obj *obj, uint32_t index) } static void *tmem_pampd_replace_in_obj(struct tmem_obj *obj, uint32_t index, - void *new_pampd) + void *new_pampd, bool no_free) { struct tmem_objnode **slot; void *ret = NULL; @@ -325,7 +326,9 @@ static void *tmem_pampd_replace_in_obj(struct tmem_obj *obj, uint32_t index, if ((slot != NULL) && (*slot != NULL)) { void *old_pampd = *(void **)slot; *(void **)slot = new_pampd; - (*tmem_pamops.free)(old_pampd, obj->pool, NULL, 0); + if (!no_free) + (*tmem_pamops.free)(old_pampd, obj->pool, + NULL, 0, false); ret = new_pampd; } return ret; @@ -481,7 +484,7 @@ static void tmem_objnode_node_destroy(struct tmem_obj *obj, if (ht == 1) { obj->pampd_count--; (*tmem_pamops.free)(objnode->slots[i], - obj->pool, NULL, 0); + obj->pool, NULL, 0, true); objnode->slots[i] = NULL; continue; } @@ -498,7 +501,8 @@ static void tmem_pampd_destroy_all_in_obj(struct tmem_obj *obj) return; if (obj->objnode_tree_height == 0) { obj->pampd_count--; - (*tmem_pamops.free)(obj->objnode_tree_root, obj->pool, NULL, 0); + (*tmem_pamops.free)(obj->objnode_tree_root, + obj->pool, NULL, 0, true); } else { tmem_objnode_node_destroy(obj, obj->objnode_tree_root, obj->objnode_tree_height); @@ -529,7 +533,7 @@ static void tmem_pampd_destroy_all_in_obj(struct tmem_obj *obj) * always flushes for simplicity. */ int tmem_put(struct tmem_pool *pool, struct tmem_oid *oidp, uint32_t index, - char *data, size_t size, bool raw, bool ephemeral) + char *data, size_t size, bool raw, int ephemeral) { struct tmem_obj *obj = NULL, *objfound = NULL, *objnew = NULL; void *pampd = NULL, *pampd_del = NULL; @@ -545,7 +549,7 @@ int tmem_put(struct tmem_pool *pool, struct tmem_oid *oidp, uint32_t index, /* if found, is a dup put, flush the old one */ pampd_del = tmem_pampd_delete_from_obj(obj, index); BUG_ON(pampd_del != pampd); - (*tmem_pamops.free)(pampd, pool, oidp, index); + (*tmem_pamops.free)(pampd, pool, oidp, index, true); if (obj->pampd_count == 0) { objnew = obj; objfound = NULL; @@ -576,7 +580,7 @@ delete_and_free: (void)tmem_pampd_delete_from_obj(obj, index); free: if (pampd) - (*tmem_pamops.free)(pampd, pool, NULL, 0); + (*tmem_pamops.free)(pampd, pool, NULL, 0, true); if (objnew) { tmem_obj_free(objnew, hb); (*tmem_hostops.obj_free)(objnew, pool); @@ -586,6 +590,65 @@ out: return ret; } +void *tmem_localify_get_pampd(struct tmem_pool *pool, struct tmem_oid *oidp, + uint32_t index, struct tmem_obj **ret_obj, + void **saved_hb) +{ + struct tmem_hashbucket *hb; + struct tmem_obj *obj = NULL; + void *pampd = NULL; + + hb = &pool->hashbucket[tmem_oid_hash(oidp)]; + spin_lock(&hb->lock); + obj = tmem_obj_find(hb, oidp); + if (likely(obj != NULL)) + pampd = tmem_pampd_lookup_in_obj(obj, index); + *ret_obj = obj; + *saved_hb = (void *)hb; + /* note, hashbucket remains locked */ + return pampd; +} + +void tmem_localify_finish(struct tmem_obj *obj, uint32_t index, + void *pampd, void *saved_hb, bool delete) +{ + struct tmem_hashbucket *hb = (struct tmem_hashbucket *)saved_hb; + + BUG_ON(!spin_is_locked(&hb->lock)); + if (pampd != NULL) { + BUG_ON(obj == NULL); + (void)tmem_pampd_replace_in_obj(obj, index, pampd, 1); + } else if (delete) { + BUG_ON(obj == NULL); + (void)tmem_pampd_delete_from_obj(obj, index); + } + spin_unlock(&hb->lock); +} + +static int tmem_repatriate(void **ppampd, struct tmem_hashbucket *hb, + struct tmem_pool *pool, struct tmem_oid *oidp, + uint32_t index, bool free, char *data) +{ + void *old_pampd = *ppampd, *new_pampd = NULL; + bool intransit = false; + int ret = 0; + + + if (!is_ephemeral(pool)) + new_pampd = (*tmem_pamops.repatriate_preload)( + old_pampd, pool, oidp, index, &intransit); + if (intransit) + ret = -EAGAIN; + else if (new_pampd != NULL) + *ppampd = new_pampd; + /* must release the hb->lock else repatriate can't sleep */ + spin_unlock(&hb->lock); + if (!intransit) + ret = (*tmem_pamops.repatriate)(old_pampd, new_pampd, pool, + oidp, index, free, data); + return ret; +} + /* * "Get" a page, e.g. if one can be found, copy the tmem page with the * matching handle from PAM space to the kernel. By tmem definition, @@ -607,14 +670,36 @@ int tmem_get(struct tmem_pool *pool, struct tmem_oid *oidp, uint32_t index, int ret = -1; struct tmem_hashbucket *hb; bool free = (get_and_free == 1) || ((get_and_free == 0) && ephemeral); - bool lock_held = false; + bool lock_held = 0; + void **ppampd; +again: hb = &pool->hashbucket[tmem_oid_hash(oidp)]; spin_lock(&hb->lock); - lock_held = true; + lock_held = 1; obj = tmem_obj_find(hb, oidp); if (obj == NULL) goto out; + ppampd = __tmem_pampd_lookup_in_obj(obj, index); + if (ppampd == NULL) + goto out; + if (tmem_pamops.is_remote(*ppampd)) { + ret = tmem_repatriate(ppampd, hb, pool, oidp, + index, free, data); + lock_held = 0; /* note hb->lock has been unlocked */ + if (ret == -EAGAIN) { + /* rare I think, but should cond_resched()??? */ + usleep_range(10, 1000); + goto again; + } else if (ret != 0) { + if (ret != -ENOENT) + pr_err("UNTESTED case in tmem_get, ret=%d\n", + ret); + ret = -1; + goto out; + } + goto out; + } if (free) pampd = tmem_pampd_delete_from_obj(obj, index); else @@ -628,10 +713,6 @@ int tmem_get(struct tmem_pool *pool, struct tmem_oid *oidp, uint32_t index, obj = NULL; } } - if (tmem_pamops.is_remote(pampd)) { - lock_held = false; - spin_unlock(&hb->lock); - } if (free) ret = (*tmem_pamops.get_data_and_free)( data, size, raw, pampd, pool, oidp, index); @@ -668,7 +749,7 @@ int tmem_flush_page(struct tmem_pool *pool, pampd = tmem_pampd_delete_from_obj(obj, index); if (pampd == NULL) goto out; - (*tmem_pamops.free)(pampd, pool, oidp, index); + (*tmem_pamops.free)(pampd, pool, oidp, index, true); if (obj->pampd_count == 0) { tmem_obj_free(obj, hb); (*tmem_hostops.obj_free)(obj, pool); @@ -682,8 +763,8 @@ out: /* * If a page in tmem matches the handle, replace the page so that any - * subsequent "get" gets the new page. Returns 0 if - * there was a page to replace, else returns -1. + * subsequent "get" gets the new page. Returns the new page if + * there was a page to replace, else returns NULL. */ int tmem_replace(struct tmem_pool *pool, struct tmem_oid *oidp, uint32_t index, void *new_pampd) @@ -697,7 +778,7 @@ int tmem_replace(struct tmem_pool *pool, struct tmem_oid *oidp, obj = tmem_obj_find(hb, oidp); if (obj == NULL) goto out; - new_pampd = tmem_pampd_replace_in_obj(obj, index, new_pampd); + new_pampd = tmem_pampd_replace_in_obj(obj, index, new_pampd, 0); ret = (*tmem_pamops.replace_in_obj)(new_pampd, obj); out: spin_unlock(&hb->lock); diff --git a/drivers/staging/ramster/tmem.h b/drivers/staging/ramster/tmem.h index ed147c4b110..47f1918c831 100644 --- a/drivers/staging/ramster/tmem.h +++ b/drivers/staging/ramster/tmem.h @@ -9,7 +9,6 @@ #ifndef _TMEM_H_ #define _TMEM_H_ -#include #include #include #include @@ -89,6 +88,31 @@ struct tmem_oid { uint64_t oid[3]; }; +struct tmem_xhandle { + uint8_t client_id; + uint8_t xh_data_cksum; + uint16_t xh_data_size; + uint16_t pool_id; + struct tmem_oid oid; + uint32_t index; + void *extra; +}; + +static inline struct tmem_xhandle tmem_xhandle_fill(uint16_t client_id, + struct tmem_pool *pool, + struct tmem_oid *oidp, + uint32_t index) +{ + struct tmem_xhandle xh; + xh.client_id = client_id; + xh.xh_data_cksum = (uint8_t)-1; + xh.xh_data_size = (uint16_t)-1; + xh.pool_id = pool->pool_id; + xh.oid = *oidp; + xh.index = index; + return xh; +} + static inline void tmem_oid_set_invalid(struct tmem_oid *oidp) { oidp->oid[0] = oidp->oid[1] = oidp->oid[2] = -1UL; @@ -147,7 +171,11 @@ struct tmem_obj { unsigned int objnode_tree_height; unsigned long objnode_count; long pampd_count; - void *extra; /* for private use by pampd implementation */ + /* for current design of ramster, all pages belonging to + * an object reside on the same remotenode and extra is + * used to record the number of the remotenode so a + * flush-object operation can specify it */ + void *extra; /* for use by pampd implementation */ DECL_SENTINEL }; @@ -174,9 +202,14 @@ struct tmem_pamops { int (*get_data_and_free)(char *, size_t *, bool, void *, struct tmem_pool *, struct tmem_oid *, uint32_t); - void (*free)(void *, struct tmem_pool *, struct tmem_oid *, uint32_t); + void (*free)(void *, struct tmem_pool *, + struct tmem_oid *, uint32_t, bool); void (*free_obj)(struct tmem_pool *, struct tmem_obj *); bool (*is_remote)(void *); + void *(*repatriate_preload)(void *, struct tmem_pool *, + struct tmem_oid *, uint32_t, bool *); + int (*repatriate)(void *, void *, struct tmem_pool *, + struct tmem_oid *, uint32_t, bool, void *); void (*new_obj)(struct tmem_obj *); int (*replace_in_obj)(void *, struct tmem_obj *); }; @@ -193,11 +226,16 @@ extern void tmem_register_hostops(struct tmem_hostops *m); /* core tmem accessor functions */ extern int tmem_put(struct tmem_pool *, struct tmem_oid *, uint32_t index, - char *, size_t, bool, bool); + char *, size_t, bool, int); extern int tmem_get(struct tmem_pool *, struct tmem_oid *, uint32_t index, char *, size_t *, bool, int); extern int tmem_replace(struct tmem_pool *, struct tmem_oid *, uint32_t index, void *); +extern void *tmem_localify_get_pampd(struct tmem_pool *, struct tmem_oid *, + uint32_t index, struct tmem_obj **, + void **); +extern void tmem_localify_finish(struct tmem_obj *, uint32_t index, + void *, void *, bool); extern int tmem_flush_page(struct tmem_pool *, struct tmem_oid *, uint32_t index); extern int tmem_flush_object(struct tmem_pool *, struct tmem_oid *); diff --git a/drivers/staging/ramster/zcache-main.c b/drivers/staging/ramster/zcache-main.c index 49c8791462f..851e94af8ec 100644 --- a/drivers/staging/ramster/zcache-main.c +++ b/drivers/staging/ramster/zcache-main.c @@ -1,7 +1,7 @@ /* * zcache.c * - * Copyright (c) 2010,2011, Dan Magenheimer, Oracle Corp. + * Copyright (c) 2010-2012, Dan Magenheimer, Oracle Corp. * Copyright (c) 2010,2011, Nitin Gupta * * Zcache provides an in-kernel "host implementation" for transcendent memory @@ -17,6 +17,9 @@ * * [1] For a definition of page-accessible memory (aka PAM), see: * http://marc.info/?l=linux-mm&m=127811271605009 + * RAMSTER TODO: + * - handle remotifying of buddied pages (see zbud_remotify_zbpg) + * - kernel boot params: nocleancache/nofrontswap don't always work?!? */ #include @@ -30,11 +33,16 @@ #include #include #include "tmem.h" +#include "zcache.h" +#include "ramster.h" +#include "cluster/tcp.h" #include "../zram/xvmalloc.h" /* if built in drivers/staging */ +#define RAMSTER_TESTING + #if (!defined(CONFIG_CLEANCACHE) && !defined(CONFIG_FRONTSWAP)) -#error "zcache is useless without CONFIG_CLEANCACHE or CONFIG_FRONTSWAP" +#error "ramster is useless without CONFIG_CLEANCACHE or CONFIG_FRONTSWAP" #endif #ifdef CONFIG_CLEANCACHE #include @@ -43,6 +51,61 @@ #include #endif +enum ramster_remotify_op { + RAMSTER_REMOTIFY_EPH_PUT, + RAMSTER_REMOTIFY_PERS_PUT, + RAMSTER_REMOTIFY_FLUSH_PAGE, + RAMSTER_REMOTIFY_FLUSH_OBJ, + RAMSTER_INTRANSIT_PERS +}; + +struct ramster_remotify_hdr { + enum ramster_remotify_op op; + struct list_head list; +}; + +#define ZBH_SENTINEL 0x43214321 +#define ZBPG_SENTINEL 0xdeadbeef + +#define ZBUD_MAX_BUDS 2 + +struct zbud_hdr { + struct ramster_remotify_hdr rem_op; + uint16_t client_id; + uint16_t pool_id; + struct tmem_oid oid; + uint32_t index; + uint16_t size; /* compressed size in bytes, zero means unused */ + DECL_SENTINEL +}; + +#define ZVH_SENTINEL 0x43214321 +static const int zv_max_page_size = (PAGE_SIZE / 8) * 7; + +struct zv_hdr { + struct ramster_remotify_hdr rem_op; + uint16_t client_id; + uint16_t pool_id; + struct tmem_oid oid; + uint32_t index; + DECL_SENTINEL +}; + +struct flushlist_node { + struct ramster_remotify_hdr rem_op; + struct tmem_xhandle xh; +}; + +union { + struct ramster_remotify_hdr rem_op; + struct zv_hdr zv; + struct zbud_hdr zbud; + struct flushlist_node flist; +} remotify_list_node; + +static LIST_HEAD(zcache_rem_op_list); +static DEFINE_SPINLOCK(zcache_rem_op_list_lock); + #if 0 /* this is more aggressive but may cause other problems? */ #define ZCACHE_GFP_MASK (GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN) @@ -98,20 +161,6 @@ static inline bool is_local_client(struct zcache_client *cli) * read or written unless the zbpg's lock is held. */ -#define ZBH_SENTINEL 0x43214321 -#define ZBPG_SENTINEL 0xdeadbeef - -#define ZBUD_MAX_BUDS 2 - -struct zbud_hdr { - uint16_t client_id; - uint16_t pool_id; - struct tmem_oid oid; - uint32_t index; - uint16_t size; /* compressed size in bytes, zero means unused */ - DECL_SENTINEL -}; - struct zbud_page { struct list_head bud_list; spinlock_t lock; @@ -141,20 +190,43 @@ static unsigned long zcache_zbud_buddied_count; /* protects the buddied list and all unbuddied lists */ static DEFINE_SPINLOCK(zbud_budlists_spinlock); -static LIST_HEAD(zbpg_unused_list); -static unsigned long zcache_zbpg_unused_list_count; - -/* protects the unused page list */ -static DEFINE_SPINLOCK(zbpg_unused_list_spinlock); - static atomic_t zcache_zbud_curr_raw_pages; static atomic_t zcache_zbud_curr_zpages; static unsigned long zcache_zbud_curr_zbytes; static unsigned long zcache_zbud_cumul_zpages; static unsigned long zcache_zbud_cumul_zbytes; static unsigned long zcache_compress_poor; +static unsigned long zcache_policy_percent_exceeded; static unsigned long zcache_mean_compress_poor; +/* + * RAMster counters + * - Remote pages are pages with a local pampd but the data is remote + * - Foreign pages are pages stored locally but belonging to another node + */ +static atomic_t ramster_remote_pers_pages = ATOMIC_INIT(0); +static unsigned long ramster_pers_remotify_enable; +static unsigned long ramster_eph_remotify_enable; +static unsigned long ramster_eph_pages_remoted; +static unsigned long ramster_eph_pages_remote_failed; +static unsigned long ramster_pers_pages_remoted; +static unsigned long ramster_pers_pages_remote_failed; +static unsigned long ramster_pers_pages_remote_nomem; +static unsigned long ramster_remote_objects_flushed; +static unsigned long ramster_remote_object_flushes_failed; +static unsigned long ramster_remote_pages_flushed; +static unsigned long ramster_remote_page_flushes_failed; +static unsigned long ramster_remote_eph_pages_succ_get; +static unsigned long ramster_remote_pers_pages_succ_get; +static unsigned long ramster_remote_eph_pages_unsucc_get; +static unsigned long ramster_remote_pers_pages_unsucc_get; +static atomic_t ramster_curr_flnode_count = ATOMIC_INIT(0); +static unsigned long ramster_curr_flnode_count_max; +static atomic_t ramster_foreign_eph_pampd_count = ATOMIC_INIT(0); +static unsigned long ramster_foreign_eph_pampd_count_max; +static atomic_t ramster_foreign_pers_pampd_count = ATOMIC_INIT(0); +static unsigned long ramster_foreign_pers_pampd_count_max; + /* forward references */ static void *zcache_get_free_page(void); static void zcache_free_page(void *p); @@ -210,6 +282,29 @@ static char *zbud_data(struct zbud_hdr *zh, unsigned size) return p; } +static void zbud_copy_from_pampd(char *data, size_t *size, struct zbud_hdr *zh) +{ + struct zbud_page *zbpg; + char *p; + unsigned budnum; + + ASSERT_SENTINEL(zh, ZBH); + budnum = zbud_budnum(zh); + zbpg = container_of(zh, struct zbud_page, buddy[budnum]); + spin_lock(&zbpg->lock); + BUG_ON(zh->size > *size); + p = (char *)zbpg; + if (budnum == 0) + p += ((sizeof(struct zbud_page) + CHUNK_SIZE - 1) & + CHUNK_MASK); + else if (budnum == 1) + p += PAGE_SIZE - ((zh->size + CHUNK_SIZE - 1) & CHUNK_MASK); + /* client should be filled in by caller */ + memcpy(data, p, zh->size); + *size = zh->size; + spin_unlock(&zbpg->lock); +} + /* * zbud raw page management */ @@ -218,38 +313,17 @@ static struct zbud_page *zbud_alloc_raw_page(void) { struct zbud_page *zbpg = NULL; struct zbud_hdr *zh0, *zh1; - bool recycled = 0; - - /* if any pages on the zbpg list, use one */ - spin_lock(&zbpg_unused_list_spinlock); - if (!list_empty(&zbpg_unused_list)) { - zbpg = list_first_entry(&zbpg_unused_list, - struct zbud_page, bud_list); - list_del_init(&zbpg->bud_list); - zcache_zbpg_unused_list_count--; - recycled = 1; - } - spin_unlock(&zbpg_unused_list_spinlock); - if (zbpg == NULL) - /* none on zbpg list, try to get a kernel page */ zbpg = zcache_get_free_page(); if (likely(zbpg != NULL)) { INIT_LIST_HEAD(&zbpg->bud_list); zh0 = &zbpg->buddy[0]; zh1 = &zbpg->buddy[1]; spin_lock_init(&zbpg->lock); - if (recycled) { - ASSERT_INVERTED_SENTINEL(zbpg, ZBPG); - SET_SENTINEL(zbpg, ZBPG); - BUG_ON(zh0->size != 0 || tmem_oid_valid(&zh0->oid)); - BUG_ON(zh1->size != 0 || tmem_oid_valid(&zh1->oid)); - } else { - atomic_inc(&zcache_zbud_curr_raw_pages); - INIT_LIST_HEAD(&zbpg->bud_list); - SET_SENTINEL(zbpg, ZBPG); - zh0->size = 0; zh1->size = 0; - tmem_oid_set_invalid(&zh0->oid); - tmem_oid_set_invalid(&zh1->oid); - } + atomic_inc(&zcache_zbud_curr_raw_pages); + INIT_LIST_HEAD(&zbpg->bud_list); + SET_SENTINEL(zbpg, ZBPG); + zh0->size = 0; zh1->size = 0; + tmem_oid_set_invalid(&zh0->oid); + tmem_oid_set_invalid(&zh1->oid); } return zbpg; } @@ -265,10 +339,8 @@ static void zbud_free_raw_page(struct zbud_page *zbpg) BUG_ON(zh1->size != 0 || tmem_oid_valid(&zh1->oid)); INVERT_SENTINEL(zbpg, ZBPG); spin_unlock(&zbpg->lock); - spin_lock(&zbpg_unused_list_spinlock); - list_add(&zbpg->bud_list, &zbpg_unused_list); - zcache_zbpg_unused_list_count++; - spin_unlock(&zbpg_unused_list_spinlock); + atomic_dec(&zcache_zbud_curr_raw_pages); + zcache_free_page(zbpg); } /* @@ -299,6 +371,10 @@ static void zbud_free_and_delist(struct zbud_hdr *zh) struct zbud_page *zbpg = container_of(zh, struct zbud_page, buddy[budnum]); + /* FIXME, should be BUG_ON, pool destruction path doesn't disable + * interrupts tmem_destroy_pool()->tmem_pampd_destroy_all_in_obj()-> + * tmem_objnode_node_destroy()-> zcache_pampd_free() */ + WARN_ON(!irqs_disabled()); spin_lock(&zbpg->lock); if (list_empty(&zbpg->bud_list)) { /* ignore zombie page... see zbud_evict_pages() */ @@ -358,8 +434,8 @@ static struct zbud_hdr *zbud_create(uint16_t client_id, uint16_t pool_id, if (unlikely(zbpg == NULL)) goto out; /* ok, have a page, now compress the data before taking locks */ - spin_lock(&zbpg->lock); spin_lock(&zbud_budlists_spinlock); + spin_lock(&zbpg->lock); list_add_tail(&zbpg->bud_list, &zbud_unbuddied[nchunks].list); zbud_unbuddied[nchunks].count++; zh = &zbpg->buddy[0]; @@ -389,12 +465,10 @@ init_zh: zh->oid = *oid; zh->pool_id = pool_id; zh->client_id = client_id; - /* can wait to copy the data until the list locks are dropped */ - spin_unlock(&zbud_budlists_spinlock); - to = zbud_data(zh, size); memcpy(to, cdata, size); spin_unlock(&zbpg->lock); + spin_unlock(&zbud_budlists_spinlock); zbud_cumul_chunk_counts[nchunks]++; atomic_inc(&zcache_zbud_curr_zpages); zcache_zbud_cumul_zpages++; @@ -458,9 +532,9 @@ static void zbud_evict_zbpg(struct zbud_page *zbpg) uint32_t index[ZBUD_MAX_BUDS]; struct tmem_oid oid[ZBUD_MAX_BUDS]; struct tmem_pool *pool; + unsigned long flags; ASSERT_SPINLOCK(&zbpg->lock); - BUG_ON(!list_empty(&zbpg->bud_list)); for (i = 0, j = 0; i < ZBUD_MAX_BUDS; i++) { zh = &zbpg->buddy[i]; if (zh->size) { @@ -469,20 +543,18 @@ static void zbud_evict_zbpg(struct zbud_page *zbpg) oid[j] = zh->oid; index[j] = zh->index; j++; - zbud_free(zh); } } spin_unlock(&zbpg->lock); for (i = 0; i < j; i++) { pool = zcache_get_pool_by_id(client_id[i], pool_id[i]); - if (pool != NULL) { - tmem_flush_page(pool, &oid[i], index[i]); - zcache_put_pool(pool); - } + BUG_ON(pool == NULL); + local_irq_save(flags); + /* these flushes should dispose of any local storage */ + tmem_flush_page(pool, &oid[i], index[i]); + local_irq_restore(flags); + zcache_put_pool(pool); } - ASSERT_SENTINEL(zbpg, ZBPG); - spin_lock(&zbpg->lock); - zbud_free_raw_page(zbpg); } /* @@ -496,26 +568,8 @@ static void zbud_evict_zbpg(struct zbud_page *zbpg) static void zbud_evict_pages(int nr) { struct zbud_page *zbpg; - int i; + int i, newly_unused_pages = 0; - /* first try freeing any pages on unused list */ -retry_unused_list: - spin_lock_bh(&zbpg_unused_list_spinlock); - if (!list_empty(&zbpg_unused_list)) { - /* can't walk list here, since it may change when unlocked */ - zbpg = list_first_entry(&zbpg_unused_list, - struct zbud_page, bud_list); - list_del_init(&zbpg->bud_list); - zcache_zbpg_unused_list_count--; - atomic_dec(&zcache_zbud_curr_raw_pages); - spin_unlock_bh(&zbpg_unused_list_spinlock); - zcache_free_page(zbpg); - zcache_evicted_raw_pages++; - if (--nr <= 0) - goto out; - goto retry_unused_list; - } - spin_unlock_bh(&zbpg_unused_list_spinlock); /* now try freeing unbuddied pages, starting with least space avail */ for (i = 0; i < MAX_CHUNK; i++) { @@ -528,15 +582,15 @@ retry_unbud_list_i: list_for_each_entry(zbpg, &zbud_unbuddied[i].list, bud_list) { if (unlikely(!spin_trylock(&zbpg->lock))) continue; - list_del_init(&zbpg->bud_list); zbud_unbuddied[i].count--; spin_unlock(&zbud_budlists_spinlock); zcache_evicted_unbuddied_pages++; /* want budlists unlocked when doing zbpg eviction */ zbud_evict_zbpg(zbpg); + newly_unused_pages++; local_bh_enable(); if (--nr <= 0) - goto out; + goto evict_unused; goto retry_unbud_list_i; } spin_unlock_bh(&zbud_budlists_spinlock); @@ -547,27 +601,406 @@ retry_bud_list: spin_lock_bh(&zbud_budlists_spinlock); if (list_empty(&zbud_buddied_list)) { spin_unlock_bh(&zbud_budlists_spinlock); - goto out; + goto evict_unused; } list_for_each_entry(zbpg, &zbud_buddied_list, bud_list) { if (unlikely(!spin_trylock(&zbpg->lock))) continue; - list_del_init(&zbpg->bud_list); zcache_zbud_buddied_count--; spin_unlock(&zbud_budlists_spinlock); zcache_evicted_buddied_pages++; /* want budlists unlocked when doing zbpg eviction */ zbud_evict_zbpg(zbpg); + newly_unused_pages++; local_bh_enable(); if (--nr <= 0) - goto out; + goto evict_unused; goto retry_bud_list; } spin_unlock_bh(&zbud_budlists_spinlock); + +evict_unused: + return; +} + +static DEFINE_PER_CPU(unsigned char *, zcache_remoteputmem); + +static int zbud_remotify_zbud(struct tmem_xhandle *xh, char *data, + size_t size) +{ + struct tmem_pool *pool; + int i, remotenode, ret = -1; + unsigned char cksum, *p; + unsigned long flags; + + for (p = data, cksum = 0, i = 0; i < size; i++) + cksum += *p; + ret = ramster_remote_put(xh, data, size, true, &remotenode); + if (ret == 0) { + /* data was successfully remoted so change the local version + * to point to the remote node where it landed */ + pool = zcache_get_pool_by_id(LOCAL_CLIENT, xh->pool_id); + BUG_ON(pool == NULL); + local_irq_save(flags); + /* tmem_replace will also free up any local space */ + (void)tmem_replace(pool, &xh->oid, xh->index, + pampd_make_remote(remotenode, size, cksum)); + local_irq_restore(flags); + zcache_put_pool(pool); + ramster_eph_pages_remoted++; + ret = 0; + } else + ramster_eph_pages_remote_failed++; + return ret; +} + +static int zbud_remotify_zbpg(struct zbud_page *zbpg) +{ + struct zbud_hdr *zh1, *zh2 = NULL; + struct tmem_xhandle xh1, xh2 = { 0 }; + char *data1 = NULL, *data2 = NULL; + size_t size1 = 0, size2 = 0; + int ret = 0; + unsigned char *tmpmem = __get_cpu_var(zcache_remoteputmem); + + ASSERT_SPINLOCK(&zbpg->lock); + if (zbpg->buddy[0].size == 0) + zh1 = &zbpg->buddy[1]; + else if (zbpg->buddy[1].size == 0) + zh1 = &zbpg->buddy[0]; + else { + zh1 = &zbpg->buddy[0]; + zh2 = &zbpg->buddy[1]; + } + /* don't remotify pages that are already remotified */ + if (zh1->client_id != LOCAL_CLIENT) + zh1 = NULL; + if ((zh2 != NULL) && (zh2->client_id != LOCAL_CLIENT)) + zh2 = NULL; + + /* copy the data and metadata so can release lock */ + if (zh1 != NULL) { + xh1.client_id = zh1->client_id; + xh1.pool_id = zh1->pool_id; + xh1.oid = zh1->oid; + xh1.index = zh1->index; + size1 = zh1->size; + data1 = zbud_data(zh1, size1); + memcpy(tmpmem, zbud_data(zh1, size1), size1); + data1 = tmpmem; + tmpmem += size1; + } + if (zh2 != NULL) { + xh2.client_id = zh2->client_id; + xh2.pool_id = zh2->pool_id; + xh2.oid = zh2->oid; + xh2.index = zh2->index; + size2 = zh2->size; + memcpy(tmpmem, zbud_data(zh2, size2), size2); + data2 = tmpmem; + } + spin_unlock(&zbpg->lock); + preempt_enable(); + + /* OK, no locks held anymore, remotify one or both zbuds */ + if (zh1 != NULL) + ret = zbud_remotify_zbud(&xh1, data1, size1); + if (zh2 != NULL) + ret |= zbud_remotify_zbud(&xh2, data2, size2); + return ret; +} + +void zbud_remotify_pages(int nr) +{ + struct zbud_page *zbpg; + int i, ret; + + /* + * for now just try remotifying unbuddied pages, starting with + * least space avail + */ + for (i = 0; i < MAX_CHUNK; i++) { +retry_unbud_list_i: + preempt_disable(); /* enable in zbud_remotify_zbpg */ + spin_lock_bh(&zbud_budlists_spinlock); + if (list_empty(&zbud_unbuddied[i].list)) { + spin_unlock_bh(&zbud_budlists_spinlock); + preempt_enable(); + continue; /* next i in for loop */ + } + list_for_each_entry(zbpg, &zbud_unbuddied[i].list, bud_list) { + if (unlikely(!spin_trylock(&zbpg->lock))) + continue; /* next list_for_each_entry */ + zbud_unbuddied[i].count--; + /* want budlists unlocked when doing zbpg remotify */ + spin_unlock_bh(&zbud_budlists_spinlock); + ret = zbud_remotify_zbpg(zbpg); + /* preemption is re-enabled in zbud_remotify_zbpg */ + if (ret == 0) { + if (--nr <= 0) + goto out; + goto retry_unbud_list_i; + } + /* if fail to remotify any page, quit */ + pr_err("TESTING zbud_remotify_pages failed on page," + " trying to re-add\n"); + spin_lock_bh(&zbud_budlists_spinlock); + spin_lock(&zbpg->lock); + list_add_tail(&zbpg->bud_list, &zbud_unbuddied[i].list); + zbud_unbuddied[i].count++; + spin_unlock(&zbpg->lock); + spin_unlock_bh(&zbud_budlists_spinlock); + pr_err("TESTING zbud_remotify_pages failed on page," + " finished re-add\n"); + goto out; + } + spin_unlock_bh(&zbud_budlists_spinlock); + preempt_enable(); + } + +next_buddied_zbpg: + preempt_disable(); /* enable in zbud_remotify_zbpg */ + spin_lock_bh(&zbud_budlists_spinlock); + if (list_empty(&zbud_buddied_list)) + goto unlock_out; + list_for_each_entry(zbpg, &zbud_buddied_list, bud_list) { + if (unlikely(!spin_trylock(&zbpg->lock))) + continue; /* next list_for_each_entry */ + zcache_zbud_buddied_count--; + /* want budlists unlocked when doing zbpg remotify */ + spin_unlock_bh(&zbud_budlists_spinlock); + ret = zbud_remotify_zbpg(zbpg); + /* preemption is re-enabled in zbud_remotify_zbpg */ + if (ret == 0) { + if (--nr <= 0) + goto out; + goto next_buddied_zbpg; + } + /* if fail to remotify any page, quit */ + pr_err("TESTING zbud_remotify_pages failed on BUDDIED page," + " trying to re-add\n"); + spin_lock_bh(&zbud_budlists_spinlock); + spin_lock(&zbpg->lock); + list_add_tail(&zbpg->bud_list, &zbud_buddied_list); + zcache_zbud_buddied_count++; + spin_unlock(&zbpg->lock); + spin_unlock_bh(&zbud_budlists_spinlock); + pr_err("TESTING zbud_remotify_pages failed on BUDDIED page," + " finished re-add\n"); + goto out; + } +unlock_out: + spin_unlock_bh(&zbud_budlists_spinlock); + preempt_enable(); out: return; } +/* the "flush list" asynchronously collects pages to remotely flush */ +#define FLUSH_ENTIRE_OBJECT ((uint32_t)-1) +static void ramster_flnode_free(struct flushlist_node *, + struct tmem_pool *); + +static void zcache_remote_flush_page(struct flushlist_node *flnode) +{ + struct tmem_xhandle *xh; + int remotenode, ret; + + preempt_disable(); + xh = &flnode->xh; + remotenode = flnode->xh.client_id; + ret = ramster_remote_flush(xh, remotenode); + if (ret >= 0) + ramster_remote_pages_flushed++; + else + ramster_remote_page_flushes_failed++; + preempt_enable_no_resched(); + ramster_flnode_free(flnode, NULL); +} + +static void zcache_remote_flush_object(struct flushlist_node *flnode) +{ + struct tmem_xhandle *xh; + int remotenode, ret; + + preempt_disable(); + xh = &flnode->xh; + remotenode = flnode->xh.client_id; + ret = ramster_remote_flush_object(xh, remotenode); + if (ret >= 0) + ramster_remote_objects_flushed++; + else + ramster_remote_object_flushes_failed++; + preempt_enable_no_resched(); + ramster_flnode_free(flnode, NULL); +} + +static void zcache_remote_eph_put(struct zbud_hdr *zbud) +{ + /* FIXME */ +} + +static void zcache_remote_pers_put(struct zv_hdr *zv) +{ + struct tmem_xhandle xh; + uint16_t size; + bool ephemeral; + int remotenode, ret = -1; + char *data; + struct tmem_pool *pool; + unsigned long flags; + unsigned char cksum; + char *p; + int i; + unsigned char *tmpmem = __get_cpu_var(zcache_remoteputmem); + + ASSERT_SENTINEL(zv, ZVH); + BUG_ON(zv->client_id != LOCAL_CLIENT); + local_bh_disable(); + xh.client_id = zv->client_id; + xh.pool_id = zv->pool_id; + xh.oid = zv->oid; + xh.index = zv->index; + size = xv_get_object_size(zv) - sizeof(*zv); + BUG_ON(size == 0 || size > zv_max_page_size); + data = (char *)zv + sizeof(*zv); + for (p = data, cksum = 0, i = 0; i < size; i++) + cksum += *p; + memcpy(tmpmem, data, size); + data = tmpmem; + pool = zcache_get_pool_by_id(zv->client_id, zv->pool_id); + ephemeral = is_ephemeral(pool); + zcache_put_pool(pool); + /* now OK to release lock set in caller */ + spin_unlock(&zcache_rem_op_list_lock); + local_bh_enable(); + preempt_disable(); + ret = ramster_remote_put(&xh, data, size, ephemeral, &remotenode); + preempt_enable_no_resched(); + if (ret != 0) { + /* + * This is some form of a memory leak... if the remote put + * fails, there will never be another attempt to remotify + * this page. But since we've dropped the zv pointer, + * the page may have been freed or the data replaced + * so we can't just "put it back" in the remote op list. + * Even if we could, not sure where to put it in the list + * because there may be flushes that must be strictly + * ordered vs the put. So leave this as a FIXME for now. + * But count them so we know if it becomes a problem. + */ + ramster_pers_pages_remote_failed++; + goto out; + } else + atomic_inc(&ramster_remote_pers_pages); + ramster_pers_pages_remoted++; + /* + * data was successfully remoted so change the local version to + * point to the remote node where it landed + */ + local_bh_disable(); + pool = zcache_get_pool_by_id(LOCAL_CLIENT, xh.pool_id); + local_irq_save(flags); + (void)tmem_replace(pool, &xh.oid, xh.index, + pampd_make_remote(remotenode, size, cksum)); + local_irq_restore(flags); + zcache_put_pool(pool); + local_bh_enable(); +out: + return; +} + +static void zcache_do_remotify_ops(int nr) +{ + struct ramster_remotify_hdr *rem_op; + union remotify_list_node *u; + + while (1) { + if (!nr) + goto out; + spin_lock(&zcache_rem_op_list_lock); + if (list_empty(&zcache_rem_op_list)) { + spin_unlock(&zcache_rem_op_list_lock); + goto out; + } + rem_op = list_first_entry(&zcache_rem_op_list, + struct ramster_remotify_hdr, list); + list_del_init(&rem_op->list); + if (rem_op->op != RAMSTER_REMOTIFY_PERS_PUT) + spin_unlock(&zcache_rem_op_list_lock); + u = (union remotify_list_node *)rem_op; + switch (rem_op->op) { + case RAMSTER_REMOTIFY_EPH_PUT: +BUG(); + zcache_remote_eph_put((struct zbud_hdr *)rem_op); + break; + case RAMSTER_REMOTIFY_PERS_PUT: + zcache_remote_pers_put((struct zv_hdr *)rem_op); + break; + case RAMSTER_REMOTIFY_FLUSH_PAGE: + zcache_remote_flush_page((struct flushlist_node *)u); + break; + case RAMSTER_REMOTIFY_FLUSH_OBJ: + zcache_remote_flush_object((struct flushlist_node *)u); + break; + default: + BUG(); + } + } +out: + return; +} + +/* + * For now, just push over a few pages every few seconds to + * ensure that it basically works + */ +static struct workqueue_struct *ramster_remotify_workqueue; +static void ramster_remotify_process(struct work_struct *work); +static DECLARE_DELAYED_WORK(ramster_remotify_worker, + ramster_remotify_process); + +static void ramster_remotify_queue_delayed_work(unsigned long delay) +{ + if (!queue_delayed_work(ramster_remotify_workqueue, + &ramster_remotify_worker, delay)) + pr_err("ramster_remotify: bad workqueue\n"); +} + + +static int use_frontswap; +static int use_cleancache; +static void ramster_remotify_process(struct work_struct *work) +{ + static bool remotify_in_progress; + + BUG_ON(irqs_disabled()); + if (remotify_in_progress) + ramster_remotify_queue_delayed_work(HZ); + else { + remotify_in_progress = true; +#ifdef CONFIG_CLEANCACHE + if (use_cleancache && ramster_eph_remotify_enable) + zbud_remotify_pages(5000); /* FIXME is this a good number? */ +#endif +#ifdef CONFIG_FRONTSWAP + if (use_frontswap && ramster_pers_remotify_enable) + zcache_do_remotify_ops(500); /* FIXME is this a good number? */ +#endif + remotify_in_progress = false; + ramster_remotify_queue_delayed_work(HZ); + } +} + +static void ramster_remotify_init(void) +{ + unsigned long n = 60UL; + ramster_remotify_workqueue = + create_singlethread_workqueue("ramster_remotify"); + ramster_remotify_queue_delayed_work(n * HZ); +} + + static void zbud_init(void) { int i; @@ -631,15 +1064,6 @@ static int zbud_show_cumul_chunk_counts(char *buf) * necessary for decompression) immediately preceding the compressed data. */ -#define ZVH_SENTINEL 0x43214321 - -struct zv_hdr { - uint32_t pool_id; - struct tmem_oid oid; - uint32_t index; - DECL_SENTINEL -}; - /* rudimentary policy limits */ /* total number of persistent pages may not exceed this percentage */ static unsigned int zv_page_count_policy_percent = 75; @@ -655,10 +1079,11 @@ static unsigned int zv_max_zsize = (PAGE_SIZE / 8) * 7; */ static unsigned int zv_max_mean_zsize = (PAGE_SIZE / 8) * 5; -static unsigned long zv_curr_dist_counts[NCHUNKS]; -static unsigned long zv_cumul_dist_counts[NCHUNKS]; +static atomic_t zv_curr_dist_counts[NCHUNKS]; +static atomic_t zv_cumul_dist_counts[NCHUNKS]; + -static struct zv_hdr *zv_create(struct xv_pool *xvpool, uint32_t pool_id, +static struct zv_hdr *zv_create(struct zcache_client *cli, uint32_t pool_id, struct tmem_oid *oid, uint32_t index, void *cdata, unsigned clen) { @@ -671,23 +1096,61 @@ static struct zv_hdr *zv_create(struct xv_pool *xvpool, uint32_t pool_id, BUG_ON(!irqs_disabled()); BUG_ON(chunks >= NCHUNKS); - ret = xv_malloc(xvpool, alloc_size, + ret = xv_malloc(cli->xvpool, clen + sizeof(struct zv_hdr), &page, &offset, ZCACHE_GFP_MASK); if (unlikely(ret)) goto out; - zv_curr_dist_counts[chunks]++; - zv_cumul_dist_counts[chunks]++; + atomic_inc(&zv_curr_dist_counts[chunks]); + atomic_inc(&zv_cumul_dist_counts[chunks]); zv = kmap_atomic(page, KM_USER0) + offset; zv->index = index; zv->oid = *oid; zv->pool_id = pool_id; SET_SENTINEL(zv, ZVH); + INIT_LIST_HEAD(&zv->rem_op.list); + zv->client_id = get_client_id_from_client(cli); + zv->rem_op.op = RAMSTER_REMOTIFY_PERS_PUT; + if (zv->client_id == LOCAL_CLIENT) { + spin_lock(&zcache_rem_op_list_lock); + list_add_tail(&zv->rem_op.list, &zcache_rem_op_list); + spin_unlock(&zcache_rem_op_list_lock); + } memcpy((char *)zv + sizeof(struct zv_hdr), cdata, clen); kunmap_atomic(zv, KM_USER0); out: return zv; } +/* similar to zv_create, but just reserve space, no data yet */ +static struct zv_hdr *zv_alloc(struct tmem_pool *pool, + struct tmem_oid *oid, uint32_t index, + unsigned clen) +{ + struct zcache_client *cli = pool->client; + struct page *page; + struct zv_hdr *zv = NULL; + uint32_t offset; + int ret; + + BUG_ON(!irqs_disabled()); + BUG_ON(!is_local_client(pool->client)); + ret = xv_malloc(cli->xvpool, clen + sizeof(struct zv_hdr), + &page, &offset, ZCACHE_GFP_MASK); + if (unlikely(ret)) + goto out; + zv = kmap_atomic(page, KM_USER0) + offset; + SET_SENTINEL(zv, ZVH); + INIT_LIST_HEAD(&zv->rem_op.list); + zv->client_id = LOCAL_CLIENT; + zv->rem_op.op = RAMSTER_INTRANSIT_PERS; + zv->index = index; + zv->oid = *oid; + zv->pool_id = pool->pool_id; + kunmap_atomic(zv, KM_USER0); +out: + return zv; +} + static void zv_free(struct xv_pool *xvpool, struct zv_hdr *zv) { unsigned long flags; @@ -698,10 +1161,15 @@ static void zv_free(struct xv_pool *xvpool, struct zv_hdr *zv) ASSERT_SENTINEL(zv, ZVH); BUG_ON(chunks >= NCHUNKS); - zv_curr_dist_counts[chunks]--; + atomic_dec(&zv_curr_dist_counts[chunks]); size -= sizeof(*zv); + spin_lock(&zcache_rem_op_list_lock); + size = xv_get_object_size(zv) - sizeof(*zv); BUG_ON(size == 0); INVERT_SENTINEL(zv, ZVH); + if (!list_empty(&zv->rem_op.list)) + list_del_init(&zv->rem_op.list); + spin_unlock(&zcache_rem_op_list_lock); page = virt_to_page(zv); offset = (unsigned long)zv & ~PAGE_MASK; local_irq_save(flags); @@ -727,6 +1195,29 @@ static void zv_decompress(struct page *page, struct zv_hdr *zv) BUG_ON(clen != PAGE_SIZE); } +static void zv_copy_from_pampd(char *data, size_t *bufsize, struct zv_hdr *zv) +{ + unsigned size; + + ASSERT_SENTINEL(zv, ZVH); + size = xv_get_object_size(zv) - sizeof(*zv); + BUG_ON(size == 0 || size > zv_max_page_size); + BUG_ON(size > *bufsize); + memcpy(data, (char *)zv + sizeof(*zv), size); + *bufsize = size; +} + +static void zv_copy_to_pampd(struct zv_hdr *zv, char *data, size_t size) +{ + unsigned zv_size; + + ASSERT_SENTINEL(zv, ZVH); + zv_size = xv_get_object_size(zv) - sizeof(*zv); + BUG_ON(zv_size != size); + BUG_ON(zv_size == 0 || zv_size > zv_max_page_size); + memcpy((char *)zv + sizeof(*zv), data, size); +} + #ifdef CONFIG_SYSFS /* * show a distribution of compression stats for zv pages. @@ -738,7 +1229,7 @@ static int zv_curr_dist_counts_show(char *buf) char *p = buf; for (i = 0; i < NCHUNKS; i++) { - n = zv_curr_dist_counts[i]; + n = atomic_read(&zv_curr_dist_counts[i]); p += sprintf(p, "%lu ", n); chunks += n; sum_total_chunks += i * n; @@ -754,7 +1245,7 @@ static int zv_cumul_dist_counts_show(char *buf) char *p = buf; for (i = 0; i < NCHUNKS; i++) { - n = zv_cumul_dist_counts[i]; + n = atomic_read(&zv_cumul_dist_counts[i]); p += sprintf(p, "%lu ", n); chunks += n; sum_total_chunks += i * n; @@ -890,6 +1381,7 @@ static unsigned long zcache_flush_found; static unsigned long zcache_flobj_total; static unsigned long zcache_flobj_found; static unsigned long zcache_failed_eph_puts; +static unsigned long zcache_nonactive_puts; static unsigned long zcache_failed_pers_puts; /* @@ -970,6 +1462,7 @@ static unsigned long zcache_put_to_flush; */ static struct kmem_cache *zcache_objnode_cache; static struct kmem_cache *zcache_obj_cache; +static struct kmem_cache *ramster_flnode_cache; static atomic_t zcache_curr_obj_count = ATOMIC_INIT(0); static unsigned long zcache_curr_obj_count_max; static atomic_t zcache_curr_objnode_count = ATOMIC_INIT(0); @@ -985,6 +1478,7 @@ struct zcache_preload { struct tmem_obj *obj; int nr; struct tmem_objnode *objnodes[OBJNODE_TREE_MAX_PATH]; + struct flushlist_node *flnode; }; static DEFINE_PER_CPU(struct zcache_preload, zcache_preloads) = { 0, }; @@ -993,6 +1487,7 @@ static int zcache_do_preload(struct tmem_pool *pool) struct zcache_preload *kp; struct tmem_objnode *objnode; struct tmem_obj *obj; + struct flushlist_node *flnode; void *page; int ret = -ENOMEM; @@ -1023,27 +1518,61 @@ static int zcache_do_preload(struct tmem_pool *pool) zcache_failed_alloc++; goto out; } - page = (void *)__get_free_page(ZCACHE_GFP_MASK); - if (unlikely(page == NULL)) { - zcache_failed_get_free_pages++; - kmem_cache_free(zcache_obj_cache, obj); + flnode = kmem_cache_alloc(ramster_flnode_cache, ZCACHE_GFP_MASK); + if (unlikely(flnode == NULL)) { + zcache_failed_alloc++; goto out; } + if (is_ephemeral(pool)) { + page = (void *)__get_free_page(ZCACHE_GFP_MASK); + if (unlikely(page == NULL)) { + zcache_failed_get_free_pages++; + kmem_cache_free(zcache_obj_cache, obj); + kmem_cache_free(ramster_flnode_cache, flnode); + goto out; + } + } preempt_disable(); kp = &__get_cpu_var(zcache_preloads); if (kp->obj == NULL) kp->obj = obj; else kmem_cache_free(zcache_obj_cache, obj); - if (kp->page == NULL) - kp->page = page; + if (kp->flnode == NULL) + kp->flnode = flnode; else - free_page((unsigned long)page); + kmem_cache_free(ramster_flnode_cache, flnode); + if (is_ephemeral(pool)) { + if (kp->page == NULL) + kp->page = page; + else + free_page((unsigned long)page); + } ret = 0; out: return ret; } +static int ramster_do_preload_flnode_only(struct tmem_pool *pool) +{ + struct zcache_preload *kp; + struct flushlist_node *flnode; + int ret = -ENOMEM; + + BUG_ON(!irqs_disabled()); + if (unlikely(ramster_flnode_cache == NULL)) + BUG(); + kp = &__get_cpu_var(zcache_preloads); + flnode = kmem_cache_alloc(ramster_flnode_cache, GFP_ATOMIC); + if (unlikely(flnode == NULL) && kp->flnode == NULL) + BUG(); /* FIXME handle more gracefully, but how??? */ + else if (kp->flnode == NULL) + kp->flnode = flnode; + else + kmem_cache_free(ramster_flnode_cache, flnode); + return ret; +} + static void *zcache_get_free_page(void) { struct zcache_preload *kp; @@ -1116,6 +1645,30 @@ static void zcache_obj_free(struct tmem_obj *obj, struct tmem_pool *pool) kmem_cache_free(zcache_obj_cache, obj); } +static struct flushlist_node *ramster_flnode_alloc(struct tmem_pool *pool) +{ + struct flushlist_node *flnode = NULL; + struct zcache_preload *kp; + int count; + + kp = &__get_cpu_var(zcache_preloads); + flnode = kp->flnode; + BUG_ON(flnode == NULL); + kp->flnode = NULL; + count = atomic_inc_return(&ramster_curr_flnode_count); + if (count > ramster_curr_flnode_count_max) + ramster_curr_flnode_count_max = count; + return flnode; +} + +static void ramster_flnode_free(struct flushlist_node *flnode, + struct tmem_pool *pool) +{ + atomic_dec(&ramster_curr_flnode_count); + BUG_ON(atomic_read(&ramster_curr_flnode_count) < 0); + kmem_cache_free(ramster_flnode_cache, flnode); +} + static struct tmem_hostops zcache_hostops = { .obj_alloc = zcache_obj_alloc, .obj_free = zcache_obj_free, @@ -1135,22 +1688,20 @@ static unsigned long zcache_curr_pers_pampd_count_max; /* forward reference */ static int zcache_compress(struct page *from, void **out_va, size_t *out_len); -static void *zcache_pampd_create(char *data, size_t size, bool raw, int eph, +static int zcache_pampd_eph_create(char *data, size_t size, bool raw, struct tmem_pool *pool, struct tmem_oid *oid, - uint32_t index) + uint32_t index, void **pampd) { - void *pampd = NULL, *cdata; - size_t clen; - int ret; - unsigned long count; - struct page *page = (struct page *)(data); + int ret = -1; + void *cdata = data; + size_t clen = size; struct zcache_client *cli = pool->client; uint16_t client_id = get_client_id_from_client(cli); - unsigned long zv_mean_zsize; - unsigned long curr_pers_pampd_count; - u64 total_zsize; + struct page *page = NULL; + unsigned long count; - if (eph) { + if (!raw) { + page = virt_to_page(data); ret = zcache_compress(page, &cdata, &clen); if (ret == 0) goto out; @@ -1158,46 +1709,114 @@ static void *zcache_pampd_create(char *data, size_t size, bool raw, int eph, zcache_compress_poor++; goto out; } - pampd = (void *)zbud_create(client_id, pool->pool_id, oid, - index, page, cdata, clen); - if (pampd != NULL) { - count = atomic_inc_return(&zcache_curr_eph_pampd_count); - if (count > zcache_curr_eph_pampd_count_max) - zcache_curr_eph_pampd_count_max = count; - } - } else { - curr_pers_pampd_count = - atomic_read(&zcache_curr_pers_pampd_count); - if (curr_pers_pampd_count > - (zv_page_count_policy_percent * totalram_pages) / 100) - goto out; - ret = zcache_compress(page, &cdata, &clen); - if (ret == 0) - goto out; - /* reject if compression is too poor */ - if (clen > zv_max_zsize) { - zcache_compress_poor++; + } + *pampd = (void *)zbud_create(client_id, pool->pool_id, oid, + index, page, cdata, clen); + if (*pampd == NULL) { + ret = -ENOMEM; + goto out; + } + ret = 0; + count = atomic_inc_return(&zcache_curr_eph_pampd_count); + if (count > zcache_curr_eph_pampd_count_max) + zcache_curr_eph_pampd_count_max = count; + if (client_id != LOCAL_CLIENT) { + count = atomic_inc_return(&ramster_foreign_eph_pampd_count); + if (count > ramster_foreign_eph_pampd_count_max) + ramster_foreign_eph_pampd_count_max = count; + } +out: + return ret; +} + +static int zcache_pampd_pers_create(char *data, size_t size, bool raw, + struct tmem_pool *pool, struct tmem_oid *oid, + uint32_t index, void **pampd) +{ + int ret = -1; + void *cdata = data; + size_t clen = size; + struct zcache_client *cli = pool->client; + struct page *page; + unsigned long count; + unsigned long zv_mean_zsize; + struct zv_hdr *zv; + long curr_pers_pampd_count; + u64 total_zsize; +#ifdef RAMSTER_TESTING + static bool pampd_neg_warned; +#endif + + curr_pers_pampd_count = atomic_read(&zcache_curr_pers_pampd_count) - + atomic_read(&ramster_remote_pers_pages); +#ifdef RAMSTER_TESTING + /* should always be positive, but warn if accounting is off */ + if (!pampd_neg_warned) { + pr_warn("ramster: bad accounting for curr_pers_pampd_count\n"); + pampd_neg_warned = true; + } +#endif + if (curr_pers_pampd_count > + (zv_page_count_policy_percent * totalram_pages) / 100) { + zcache_policy_percent_exceeded++; + goto out; + } + if (raw) + goto ok_to_create; + page = virt_to_page(data); + if (zcache_compress(page, &cdata, &clen) == 0) + goto out; + /* reject if compression is too poor */ + if (clen > zv_max_zsize) { + zcache_compress_poor++; + goto out; + } + /* reject if mean compression is too poor */ + if ((clen > zv_max_mean_zsize) && (curr_pers_pampd_count > 0)) { + total_zsize = xv_get_total_size_bytes(cli->xvpool); + zv_mean_zsize = div_u64(total_zsize, curr_pers_pampd_count); + if (zv_mean_zsize > zv_max_mean_zsize) { + zcache_mean_compress_poor++; goto out; } - /* reject if mean compression is too poor */ - if ((clen > zv_max_mean_zsize) && (curr_pers_pampd_count > 0)) { - total_zsize = xv_get_total_size_bytes(cli->xvpool); - zv_mean_zsize = div_u64(total_zsize, - curr_pers_pampd_count); - if (zv_mean_zsize > zv_max_mean_zsize) { - zcache_mean_compress_poor++; - goto out; - } - } - pampd = (void *)zv_create(cli->xvpool, pool->pool_id, - oid, index, cdata, clen); - if (pampd == NULL) - goto out; - count = atomic_inc_return(&zcache_curr_pers_pampd_count); - if (count > zcache_curr_pers_pampd_count_max) - zcache_curr_pers_pampd_count_max = count; } +ok_to_create: + *pampd = (void *)zv_create(cli, pool->pool_id, oid, index, cdata, clen); + if (*pampd == NULL) { + ret = -ENOMEM; + goto out; + } + ret = 0; + count = atomic_inc_return(&zcache_curr_pers_pampd_count); + if (count > zcache_curr_pers_pampd_count_max) + zcache_curr_pers_pampd_count_max = count; + if (is_local_client(cli)) + goto out; + zv = *(struct zv_hdr **)pampd; + count = atomic_inc_return(&ramster_foreign_pers_pampd_count); + if (count > ramster_foreign_pers_pampd_count_max) + ramster_foreign_pers_pampd_count_max = count; out: + return ret; +} + +static void *zcache_pampd_create(char *data, size_t size, bool raw, int eph, + struct tmem_pool *pool, struct tmem_oid *oid, + uint32_t index) +{ + void *pampd = NULL; + int ret; + bool ephemeral; + + BUG_ON(preemptible()); + ephemeral = (eph == 1) || ((eph == 0) && is_ephemeral(pool)); + if (ephemeral) + ret = zcache_pampd_eph_create(data, size, raw, pool, + oid, index, &pampd); + else + ret = zcache_pampd_pers_create(data, size, raw, pool, + oid, index, &pampd); + /* FIXME add some counters here for failed creates? */ return pampd; } @@ -1211,75 +1830,359 @@ static int zcache_pampd_get_data(char *data, size_t *bufsize, bool raw, { int ret = 0; - BUG_ON(is_ephemeral(pool)); - zv_decompress((struct page *)(data), pampd); + BUG_ON(preemptible()); + BUG_ON(is_ephemeral(pool)); /* Fix later for shared pools? */ + BUG_ON(pampd_is_remote(pampd)); + if (raw) + zv_copy_from_pampd(data, bufsize, pampd); + else + zv_decompress(virt_to_page(data), pampd); return ret; } -/* - * fill the pageframe corresponding to the struct page with the data - * from the passed pampd - */ static int zcache_pampd_get_data_and_free(char *data, size_t *bufsize, bool raw, void *pampd, struct tmem_pool *pool, struct tmem_oid *oid, uint32_t index) { int ret = 0; + unsigned long flags; + struct zcache_client *cli = pool->client; - BUG_ON(!is_ephemeral(pool)); - zbud_decompress((struct page *)(data), pampd); - zbud_free_and_delist((struct zbud_hdr *)pampd); - atomic_dec(&zcache_curr_eph_pampd_count); + BUG_ON(preemptible()); + BUG_ON(pampd_is_remote(pampd)); + if (is_ephemeral(pool)) { + local_irq_save(flags); + if (raw) + zbud_copy_from_pampd(data, bufsize, pampd); + else + ret = zbud_decompress(virt_to_page(data), pampd); + zbud_free_and_delist((struct zbud_hdr *)pampd); + local_irq_restore(flags); + if (!is_local_client(cli)) { + atomic_dec(&ramster_foreign_eph_pampd_count); + WARN_ON_ONCE(atomic_read(&ramster_foreign_eph_pampd_count) < 0); + } + atomic_dec(&zcache_curr_eph_pampd_count); + WARN_ON_ONCE(atomic_read(&zcache_curr_eph_pampd_count) < 0); + } else { + if (is_local_client(cli)) + BUG(); + if (raw) + zv_copy_from_pampd(data, bufsize, pampd); + else + zv_decompress(virt_to_page(data), pampd); + zv_free(cli->xvpool, pampd); + if (!is_local_client(cli)) { + atomic_dec(&ramster_foreign_pers_pampd_count); + WARN_ON_ONCE(atomic_read(&ramster_foreign_pers_pampd_count) < 0); + } + atomic_dec(&zcache_curr_pers_pampd_count); + WARN_ON_ONCE(atomic_read(&zcache_curr_pers_pampd_count) < 0); + ret = 0; + } return ret; } +static bool zcache_pampd_is_remote(void *pampd) +{ + return pampd_is_remote(pampd); +} + /* * free the pampd and remove it from any zcache lists * pampd must no longer be pointed to from any tmem data structures! */ static void zcache_pampd_free(void *pampd, struct tmem_pool *pool, - struct tmem_oid *oid, uint32_t index) + struct tmem_oid *oid, uint32_t index, bool acct) { struct zcache_client *cli = pool->client; - - if (is_ephemeral(pool)) { + bool eph = is_ephemeral(pool); + struct zv_hdr *zv; + + BUG_ON(preemptible()); + if (pampd_is_remote(pampd)) { + WARN_ON(acct == false); + if (oid == NULL) { + /* + * a NULL oid means to ignore this pampd free + * as the remote freeing will be handled elsewhere + */ + } else if (eph) { + /* FIXME remote flush optional but probably good idea */ + /* FIXME get these working properly again */ + atomic_dec(&zcache_curr_eph_pampd_count); + WARN_ON_ONCE(atomic_read(&zcache_curr_eph_pampd_count) < 0); + } else if (pampd_is_intransit(pampd)) { + /* did a pers remote get_and_free, so just free local */ + pampd = pampd_mask_intransit_and_remote(pampd); + goto local_pers; + } else { + struct flushlist_node *flnode = + ramster_flnode_alloc(pool); + + flnode->xh.client_id = pampd_remote_node(pampd); + flnode->xh.pool_id = pool->pool_id; + flnode->xh.oid = *oid; + flnode->xh.index = index; + flnode->rem_op.op = RAMSTER_REMOTIFY_FLUSH_PAGE; + spin_lock(&zcache_rem_op_list_lock); + list_add(&flnode->rem_op.list, &zcache_rem_op_list); + spin_unlock(&zcache_rem_op_list_lock); + atomic_dec(&zcache_curr_pers_pampd_count); + WARN_ON_ONCE(atomic_read(&zcache_curr_pers_pampd_count) < 0); + atomic_dec(&ramster_remote_pers_pages); + WARN_ON_ONCE(atomic_read(&ramster_remote_pers_pages) < 0); + } + } else if (eph) { zbud_free_and_delist((struct zbud_hdr *)pampd); - atomic_dec(&zcache_curr_eph_pampd_count); - BUG_ON(atomic_read(&zcache_curr_eph_pampd_count) < 0); + if (!is_local_client(pool->client)) { + atomic_dec(&ramster_foreign_eph_pampd_count); + WARN_ON_ONCE(atomic_read(&ramster_foreign_eph_pampd_count) < 0); + } + if (acct) + atomic_dec(&zcache_curr_eph_pampd_count); + /* FIXME get these working properly again */ + WARN_ON_ONCE(atomic_read(&zcache_curr_eph_pampd_count) < 0); } else { - zv_free(cli->xvpool, (struct zv_hdr *)pampd); - atomic_dec(&zcache_curr_pers_pampd_count); - BUG_ON(atomic_read(&zcache_curr_pers_pampd_count) < 0); +local_pers: + zv = (struct zv_hdr *)pampd; + if (!is_local_client(pool->client)) { + atomic_dec(&ramster_foreign_pers_pampd_count); + WARN_ON_ONCE(atomic_read(&ramster_foreign_pers_pampd_count) < 0); + } + zv_free(cli->xvpool, zv); + if (acct) + atomic_dec(&zcache_curr_pers_pampd_count); + /* FIXME get these working properly again */ + WARN_ON_ONCE(atomic_read(&zcache_curr_pers_pampd_count) < 0); } } -static void zcache_pampd_free_obj(struct tmem_pool *pool, struct tmem_obj *obj) +static void zcache_pampd_free_obj(struct tmem_pool *pool, + struct tmem_obj *obj) { + struct flushlist_node *flnode; + + BUG_ON(preemptible()); + if (obj->extra == NULL) + return; + BUG_ON(!pampd_is_remote(obj->extra)); + flnode = ramster_flnode_alloc(pool); + flnode->xh.client_id = pampd_remote_node(obj->extra); + flnode->xh.pool_id = pool->pool_id; + flnode->xh.oid = obj->oid; + flnode->xh.index = FLUSH_ENTIRE_OBJECT; + flnode->rem_op.op = RAMSTER_REMOTIFY_FLUSH_OBJ; + spin_lock(&zcache_rem_op_list_lock); + list_add(&flnode->rem_op.list, &zcache_rem_op_list); + spin_unlock(&zcache_rem_op_list_lock); } -static void zcache_pampd_new_obj(struct tmem_obj *obj) +void zcache_pampd_new_obj(struct tmem_obj *obj) { + obj->extra = NULL; } -static int zcache_pampd_replace_in_obj(void *pampd, struct tmem_obj *obj) +int zcache_pampd_replace_in_obj(void *new_pampd, struct tmem_obj *obj) { - return -1; + int ret = -1; + + if (new_pampd != NULL) { + if (obj->extra == NULL) + obj->extra = new_pampd; + /* enforce that all remote pages in an object reside + * in the same node! */ + else if (pampd_remote_node(new_pampd) != + pampd_remote_node((void *)(obj->extra))) + BUG(); + ret = 0; + } + return ret; } -static bool zcache_pampd_is_remote(void *pampd) +/* + * Called by the message handler after a (still compressed) page has been + * fetched from the remote machine in response to an "is_remote" tmem_get + * or persistent tmem_localify. For a tmem_get, "extra" is the address of + * the page that is to be filled to succesfully resolve the tmem_get; for + * a (persistent) tmem_localify, "extra" is NULL (as the data is placed only + * in the local zcache). "data" points to "size" bytes of (compressed) data + * passed in the message. In the case of a persistent remote get, if + * pre-allocation was successful (see zcache_repatriate_preload), the page + * is placed into both local zcache and at "extra". + */ +int zcache_localify(int pool_id, struct tmem_oid *oidp, + uint32_t index, char *data, size_t size, + void *extra) { - return 0; + int ret = -ENOENT; + unsigned long flags; + struct tmem_pool *pool; + bool ephemeral, delete = false; + size_t clen = PAGE_SIZE; + void *pampd, *saved_hb; + struct tmem_obj *obj; + + pool = zcache_get_pool_by_id(LOCAL_CLIENT, pool_id); + if (unlikely(pool == NULL)) + /* pool doesn't exist anymore */ + goto out; + ephemeral = is_ephemeral(pool); + local_irq_save(flags); /* FIXME: maybe only disable softirqs? */ + pampd = tmem_localify_get_pampd(pool, oidp, index, &obj, &saved_hb); + if (pampd == NULL) { + /* hmmm... must have been a flush while waiting */ +#ifdef RAMSTER_TESTING + pr_err("UNTESTED pampd==NULL in zcache_localify\n"); +#endif + if (ephemeral) + ramster_remote_eph_pages_unsucc_get++; + else + ramster_remote_pers_pages_unsucc_get++; + obj = NULL; + goto finish; + } else if (unlikely(!pampd_is_remote(pampd))) { + /* hmmm... must have been a dup put while waiting */ +#ifdef RAMSTER_TESTING + pr_err("UNTESTED dup while waiting in zcache_localify\n"); +#endif + if (ephemeral) + ramster_remote_eph_pages_unsucc_get++; + else + ramster_remote_pers_pages_unsucc_get++; + obj = NULL; + pampd = NULL; + ret = -EEXIST; + goto finish; + } else if (size == 0) { + /* no remote data, delete the local is_remote pampd */ + pampd = NULL; + if (ephemeral) + ramster_remote_eph_pages_unsucc_get++; + else + BUG(); + delete = true; + goto finish; + } + if (!ephemeral && pampd_is_intransit(pampd)) { + /* localify to zcache */ + pampd = pampd_mask_intransit_and_remote(pampd); + zv_copy_to_pampd(pampd, data, size); + } else { + pampd = NULL; + obj = NULL; + } + if (extra != NULL) { + /* decompress direct-to-memory to complete remotify */ + ret = lzo1x_decompress_safe((char *)data, size, + (char *)extra, &clen); + BUG_ON(ret != LZO_E_OK); + BUG_ON(clen != PAGE_SIZE); + } + if (ephemeral) + ramster_remote_eph_pages_succ_get++; + else + ramster_remote_pers_pages_succ_get++; + ret = 0; +finish: + tmem_localify_finish(obj, index, pampd, saved_hb, delete); + zcache_put_pool(pool); + local_irq_restore(flags); +out: + return ret; +} + +/* + * Called on a remote persistent tmem_get to attempt to preallocate + * local storage for the data contained in the remote persistent page. + * If succesfully preallocated, returns the pampd, marked as remote and + * in_transit. Else returns NULL. Note that the appropriate tmem data + * structure must be locked. + */ +static void *zcache_pampd_repatriate_preload(void *pampd, + struct tmem_pool *pool, + struct tmem_oid *oid, + uint32_t index, + bool *intransit) +{ + int clen = pampd_remote_size(pampd); + void *ret_pampd = NULL; + unsigned long flags; + + if (!pampd_is_remote(pampd)) + BUG(); + if (is_ephemeral(pool)) + BUG(); + if (pampd_is_intransit(pampd)) { + /* + * to avoid multiple allocations (and maybe a memory leak) + * don't preallocate if already in the process of being + * repatriated + */ + *intransit = true; + goto out; + } + *intransit = false; + local_irq_save(flags); + ret_pampd = (void *)zv_alloc(pool, oid, index, clen); + if (ret_pampd != NULL) { + /* + * a pampd is marked intransit if it is remote and space has + * been allocated for it locally (note, only happens for + * persistent pages, in which case the remote copy is freed) + */ + ret_pampd = pampd_mark_intransit(ret_pampd); + atomic_dec(&ramster_remote_pers_pages); + WARN_ON_ONCE(atomic_read(&ramster_remote_pers_pages) < 0); + } else + ramster_pers_pages_remote_nomem++; + local_irq_restore(flags); +out: + return ret_pampd; +} + +/* + * Called on a remote tmem_get to invoke a message to fetch the page. + * Might sleep so no tmem locks can be held. "extra" is passed + * all the way through the round-trip messaging to zcache_localify. + */ +static int zcache_pampd_repatriate(void *fake_pampd, void *real_pampd, + struct tmem_pool *pool, + struct tmem_oid *oid, uint32_t index, + bool free, void *extra) +{ + struct tmem_xhandle xh; + int ret; + + if (pampd_is_intransit(real_pampd)) + /* have local space pre-reserved, so free remote copy */ + free = true; + xh = tmem_xhandle_fill(LOCAL_CLIENT, pool, oid, index); + /* unreliable request/response for now */ + ret = ramster_remote_async_get(&xh, free, + pampd_remote_node(fake_pampd), + pampd_remote_size(fake_pampd), + pampd_remote_cksum(fake_pampd), + extra); +#ifdef RAMSTER_TESTING + if (ret != 0 && ret != -ENOENT) + pr_err("TESTING zcache_pampd_repatriate returns, ret=%d\n", + ret); +#endif + return ret; } static struct tmem_pamops zcache_pamops = { .create = zcache_pampd_create, .get_data = zcache_pampd_get_data, - .get_data_and_free = zcache_pampd_get_data_and_free, .free = zcache_pampd_free, + .get_data_and_free = zcache_pampd_get_data_and_free, .free_obj = zcache_pampd_free_obj, + .is_remote = zcache_pampd_is_remote, + .repatriate_preload = zcache_pampd_repatriate_preload, + .repatriate = zcache_pampd_repatriate, .new_obj = zcache_pampd_new_obj, .replace_in_obj = zcache_pampd_replace_in_obj, - .is_remote = zcache_pampd_is_remote, }; /* @@ -1327,9 +2230,13 @@ static int zcache_cpu_notifier(struct notifier_block *nb, per_cpu(zcache_workmem, cpu) = kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL | __GFP_REPEAT); + per_cpu(zcache_remoteputmem, cpu) = + kzalloc(PAGE_SIZE, GFP_KERNEL | __GFP_REPEAT); break; case CPU_DEAD: case CPU_UP_CANCELED: + kfree(per_cpu(zcache_remoteputmem, cpu)); + per_cpu(zcache_remoteputmem, cpu) = NULL; free_pages((unsigned long)per_cpu(zcache_dstmem, cpu), LZO_DSTMEM_PAGE_ORDER); per_cpu(zcache_dstmem, cpu) = NULL; @@ -1346,6 +2253,10 @@ static int zcache_cpu_notifier(struct notifier_block *nb, kmem_cache_free(zcache_obj_cache, kp->obj); kp->obj = NULL; } + if (kp->flnode) { + kmem_cache_free(ramster_flnode_cache, kp->flnode); + kp->flnode = NULL; + } if (kp->page) { free_page((unsigned long)kp->page); kp->page = NULL; @@ -1402,12 +2313,12 @@ ZCACHE_SYSFS_RO(flush_found); ZCACHE_SYSFS_RO(flobj_total); ZCACHE_SYSFS_RO(flobj_found); ZCACHE_SYSFS_RO(failed_eph_puts); +ZCACHE_SYSFS_RO(nonactive_puts); ZCACHE_SYSFS_RO(failed_pers_puts); ZCACHE_SYSFS_RO(zbud_curr_zbytes); ZCACHE_SYSFS_RO(zbud_cumul_zpages); ZCACHE_SYSFS_RO(zbud_cumul_zbytes); ZCACHE_SYSFS_RO(zbud_buddied_count); -ZCACHE_SYSFS_RO(zbpg_unused_list_count); ZCACHE_SYSFS_RO(evicted_raw_pages); ZCACHE_SYSFS_RO(evicted_unbuddied_pages); ZCACHE_SYSFS_RO(evicted_buddied_pages); @@ -1416,6 +2327,7 @@ ZCACHE_SYSFS_RO(failed_alloc); ZCACHE_SYSFS_RO(put_to_flush); ZCACHE_SYSFS_RO(compress_poor); ZCACHE_SYSFS_RO(mean_compress_poor); +ZCACHE_SYSFS_RO(policy_percent_exceeded); ZCACHE_SYSFS_RO_ATOMIC(zbud_curr_raw_pages); ZCACHE_SYSFS_RO_ATOMIC(zbud_curr_zpages); ZCACHE_SYSFS_RO_ATOMIC(curr_obj_count); @@ -1439,7 +2351,9 @@ static struct attribute *zcache_attrs[] = { &zcache_flush_found_attr.attr, &zcache_flobj_found_attr.attr, &zcache_failed_eph_puts_attr.attr, + &zcache_nonactive_puts_attr.attr, &zcache_failed_pers_puts_attr.attr, + &zcache_policy_percent_exceeded_attr.attr, &zcache_compress_poor_attr.attr, &zcache_mean_compress_poor_attr.attr, &zcache_zbud_curr_raw_pages_attr.attr, @@ -1448,7 +2362,6 @@ static struct attribute *zcache_attrs[] = { &zcache_zbud_cumul_zpages_attr.attr, &zcache_zbud_cumul_zbytes_attr.attr, &zcache_zbud_buddied_count_attr.attr, - &zcache_zbpg_unused_list_count_attr.attr, &zcache_evicted_raw_pages_attr.attr, &zcache_evicted_unbuddied_pages_attr.attr, &zcache_evicted_buddied_pages_attr.attr, @@ -1470,6 +2383,150 @@ static struct attribute_group zcache_attr_group = { .name = "zcache", }; +#define RAMSTER_SYSFS_RO(_name) \ + static ssize_t ramster_##_name##_show(struct kobject *kobj, \ + struct kobj_attribute *attr, char *buf) \ + { \ + return sprintf(buf, "%lu\n", ramster_##_name); \ + } \ + static struct kobj_attribute ramster_##_name##_attr = { \ + .attr = { .name = __stringify(_name), .mode = 0444 }, \ + .show = ramster_##_name##_show, \ + } + +#define RAMSTER_SYSFS_RW(_name) \ + static ssize_t ramster_##_name##_show(struct kobject *kobj, \ + struct kobj_attribute *attr, char *buf) \ + { \ + return sprintf(buf, "%lu\n", ramster_##_name); \ + } \ + static ssize_t ramster_##_name##_store(struct kobject *kobj, \ + struct kobj_attribute *attr, const char *buf, size_t count) \ + { \ + int err; \ + unsigned long enable; \ + err = strict_strtoul(buf, 10, &enable); \ + if (err) \ + return -EINVAL; \ + ramster_##_name = enable; \ + return count; \ + } \ + static struct kobj_attribute ramster_##_name##_attr = { \ + .attr = { .name = __stringify(_name), .mode = 0644 }, \ + .show = ramster_##_name##_show, \ + .store = ramster_##_name##_store, \ + } + +#define RAMSTER_SYSFS_RO_ATOMIC(_name) \ + static ssize_t ramster_##_name##_show(struct kobject *kobj, \ + struct kobj_attribute *attr, char *buf) \ + { \ + return sprintf(buf, "%d\n", atomic_read(&ramster_##_name)); \ + } \ + static struct kobj_attribute ramster_##_name##_attr = { \ + .attr = { .name = __stringify(_name), .mode = 0444 }, \ + .show = ramster_##_name##_show, \ + } + +RAMSTER_SYSFS_RO_ATOMIC(remote_pers_pages); +RAMSTER_SYSFS_RW(pers_remotify_enable); +RAMSTER_SYSFS_RW(eph_remotify_enable); +RAMSTER_SYSFS_RO(eph_pages_remoted); +RAMSTER_SYSFS_RO(eph_pages_remote_failed); +RAMSTER_SYSFS_RO(pers_pages_remoted); +RAMSTER_SYSFS_RO(pers_pages_remote_failed); +RAMSTER_SYSFS_RO(pers_pages_remote_nomem); +RAMSTER_SYSFS_RO(remote_pages_flushed); +RAMSTER_SYSFS_RO(remote_page_flushes_failed); +RAMSTER_SYSFS_RO(remote_objects_flushed); +RAMSTER_SYSFS_RO(remote_object_flushes_failed); +RAMSTER_SYSFS_RO(remote_eph_pages_succ_get); +RAMSTER_SYSFS_RO(remote_eph_pages_unsucc_get); +RAMSTER_SYSFS_RO(remote_pers_pages_succ_get); +RAMSTER_SYSFS_RO(remote_pers_pages_unsucc_get); +RAMSTER_SYSFS_RO_ATOMIC(foreign_eph_pampd_count); +RAMSTER_SYSFS_RO(foreign_eph_pampd_count_max); +RAMSTER_SYSFS_RO_ATOMIC(foreign_pers_pampd_count); +RAMSTER_SYSFS_RO(foreign_pers_pampd_count_max); +RAMSTER_SYSFS_RO_ATOMIC(curr_flnode_count); +RAMSTER_SYSFS_RO(curr_flnode_count_max); + +#define MANUAL_NODES 8 +static bool ramster_nodes_manual_up[MANUAL_NODES]; +static ssize_t ramster_manual_node_up_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + int i; + char *p = buf; + for (i = 0; i < MANUAL_NODES; i++) + if (ramster_nodes_manual_up[i]) + p += sprintf(p, "%d ", i); + p += sprintf(p, "\n"); + return p - buf; +} + +static ssize_t ramster_manual_node_up_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) +{ + int err; + unsigned long node_num; + + err = strict_strtoul(buf, 10, &node_num); + if (err) { + pr_err("bad strtoul?\n"); + return -EINVAL; + } + if (node_num >= MANUAL_NODES) { + pr_err("bad node_num=%lu?\n", node_num); + return -EINVAL; + } + if (ramster_nodes_manual_up[node_num]) { + pr_err("node %d already up, ignoring\n", (int)node_num); + } else { + ramster_nodes_manual_up[node_num] = true; + o2net_hb_node_up_manual((int)node_num); + } + return count; +} + +static struct kobj_attribute ramster_manual_node_up_attr = { + .attr = { .name = "manual_node_up", .mode = 0644 }, + .show = ramster_manual_node_up_show, + .store = ramster_manual_node_up_store, +}; + +static struct attribute *ramster_attrs[] = { + &ramster_pers_remotify_enable_attr.attr, + &ramster_eph_remotify_enable_attr.attr, + &ramster_remote_pers_pages_attr.attr, + &ramster_eph_pages_remoted_attr.attr, + &ramster_eph_pages_remote_failed_attr.attr, + &ramster_pers_pages_remoted_attr.attr, + &ramster_pers_pages_remote_failed_attr.attr, + &ramster_pers_pages_remote_nomem_attr.attr, + &ramster_remote_pages_flushed_attr.attr, + &ramster_remote_page_flushes_failed_attr.attr, + &ramster_remote_objects_flushed_attr.attr, + &ramster_remote_object_flushes_failed_attr.attr, + &ramster_remote_eph_pages_succ_get_attr.attr, + &ramster_remote_eph_pages_unsucc_get_attr.attr, + &ramster_remote_pers_pages_succ_get_attr.attr, + &ramster_remote_pers_pages_unsucc_get_attr.attr, + &ramster_foreign_eph_pampd_count_attr.attr, + &ramster_foreign_eph_pampd_count_max_attr.attr, + &ramster_foreign_pers_pampd_count_attr.attr, + &ramster_foreign_pers_pampd_count_max_attr.attr, + &ramster_curr_flnode_count_attr.attr, + &ramster_curr_flnode_count_max_attr.attr, + &ramster_manual_node_up_attr.attr, + NULL, +}; + +static struct attribute_group ramster_attr_group = { + .attrs = ramster_attrs, + .name = "ramster", +}; + #endif /* CONFIG_SYSFS */ /* * When zcache is disabled ("frozen"), pools can be created and destroyed, @@ -1510,8 +2567,9 @@ static struct shrinker zcache_shrinker = { * zcache shims between cleancache/frontswap ops and tmem */ -static int zcache_put_page(int cli_id, int pool_id, struct tmem_oid *oidp, - uint32_t index, struct page *page) +int zcache_put(int cli_id, int pool_id, struct tmem_oid *oidp, + uint32_t index, char *data, size_t size, + bool raw, int ephemeral) { struct tmem_pool *pool; int ret = -1; @@ -1522,8 +2580,7 @@ static int zcache_put_page(int cli_id, int pool_id, struct tmem_oid *oidp, goto out; if (!zcache_freeze && zcache_do_preload(pool) == 0) { /* preload does preempt_disable on success */ - ret = tmem_put(pool, oidp, index, (char *)(page), - PAGE_SIZE, 0, is_ephemeral(pool)); + ret = tmem_put(pool, oidp, index, data, size, raw, ephemeral); if (ret < 0) { if (is_ephemeral(pool)) zcache_failed_eph_puts++; @@ -1543,27 +2600,38 @@ out: return ret; } -static int zcache_get_page(int cli_id, int pool_id, struct tmem_oid *oidp, - uint32_t index, struct page *page) +int zcache_get(int cli_id, int pool_id, struct tmem_oid *oidp, + uint32_t index, char *data, size_t *sizep, + bool raw, int get_and_free) { struct tmem_pool *pool; int ret = -1; - unsigned long flags; - size_t size = PAGE_SIZE; + bool eph; - local_irq_save(flags); + if (!raw) { + BUG_ON(irqs_disabled()); + BUG_ON(in_softirq()); + } pool = zcache_get_pool_by_id(cli_id, pool_id); + eph = is_ephemeral(pool); if (likely(pool != NULL)) { if (atomic_read(&pool->obj_count) > 0) - ret = tmem_get(pool, oidp, index, (char *)(page), - &size, 0, is_ephemeral(pool)); + ret = tmem_get(pool, oidp, index, data, sizep, + raw, get_and_free); zcache_put_pool(pool); } - local_irq_restore(flags); + WARN_ONCE((!eph && (ret != 0)), "zcache_get fails on persistent pool, " + "bad things are very likely to happen soon\n"); +#ifdef RAMSTER_TESTING + if (ret != 0 && ret != -1 && !(ret == -EINVAL && is_ephemeral(pool))) + pr_err("TESTING zcache_get tmem_get returns ret=%d\n", ret); +#endif + if (ret == -EAGAIN) + BUG(); /* FIXME... don't need this anymore??? let's ensure */ return ret; } -static int zcache_flush_page(int cli_id, int pool_id, +int zcache_flush(int cli_id, int pool_id, struct tmem_oid *oidp, uint32_t index) { struct tmem_pool *pool; @@ -1573,6 +2641,7 @@ static int zcache_flush_page(int cli_id, int pool_id, local_irq_save(flags); zcache_flush_total++; pool = zcache_get_pool_by_id(cli_id, pool_id); + ramster_do_preload_flnode_only(pool); if (likely(pool != NULL)) { if (atomic_read(&pool->obj_count) > 0) ret = tmem_flush_page(pool, oidp, index); @@ -1584,8 +2653,7 @@ static int zcache_flush_page(int cli_id, int pool_id, return ret; } -static int zcache_flush_object(int cli_id, int pool_id, - struct tmem_oid *oidp) +int zcache_flush_object(int cli_id, int pool_id, struct tmem_oid *oidp) { struct tmem_pool *pool; int ret = -1; @@ -1594,6 +2662,7 @@ static int zcache_flush_object(int cli_id, int pool_id, local_irq_save(flags); zcache_flobj_total++; pool = zcache_get_pool_by_id(cli_id, pool_id); + ramster_do_preload_flnode_only(pool); if (likely(pool != NULL)) { if (atomic_read(&pool->obj_count) > 0) ret = tmem_flush_object(pool, oidp); @@ -1605,7 +2674,7 @@ static int zcache_flush_object(int cli_id, int pool_id, return ret; } -static int zcache_destroy_pool(int cli_id, int pool_id) +int zcache_client_destroy_pool(int cli_id, int pool_id) { struct tmem_pool *pool = NULL; struct zcache_client *cli = NULL; @@ -1632,13 +2701,17 @@ static int zcache_destroy_pool(int cli_id, int pool_id) ret = tmem_destroy_pool(pool); local_bh_enable(); kfree(pool); - pr_info("zcache: destroyed pool id=%d, cli_id=%d\n", - pool_id, cli_id); + pr_info("ramster: destroyed pool id=%d cli_id=%d\n", pool_id, cli_id); out: return ret; } -static int zcache_new_pool(uint16_t cli_id, uint32_t flags) +static int zcache_destroy_pool(int pool_id) +{ + return zcache_client_destroy_pool(LOCAL_CLIENT, pool_id); +} + +int zcache_new_pool(uint16_t cli_id, uint32_t flags) { int poolid = -1; struct tmem_pool *pool; @@ -1653,7 +2726,7 @@ static int zcache_new_pool(uint16_t cli_id, uint32_t flags) atomic_inc(&cli->refcount); pool = kmalloc(sizeof(struct tmem_pool), GFP_ATOMIC); if (pool == NULL) { - pr_info("zcache: pool creation failed: out of memory\n"); + pr_info("ramster: pool creation failed: out of memory\n"); goto out; } @@ -1661,7 +2734,7 @@ static int zcache_new_pool(uint16_t cli_id, uint32_t flags) if (cli->tmem_pools[poolid] == NULL) break; if (poolid >= MAX_POOLS_PER_CLIENT) { - pr_info("zcache: pool creation failed: max exceeded\n"); + pr_info("ramster: pool creation failed: max exceeded\n"); kfree(pool); poolid = -1; goto out; @@ -1671,7 +2744,7 @@ static int zcache_new_pool(uint16_t cli_id, uint32_t flags) pool->pool_id = poolid; tmem_new_pool(pool, flags); cli->tmem_pools[poolid] = pool; - pr_info("zcache: created %s tmem pool, id=%d, client=%d\n", + pr_info("ramster: created %s tmem pool, id=%d, client=%d\n", flags & TMEM_POOL_PERSIST ? "persistent" : "ephemeral", poolid, cli_id); out: @@ -1680,6 +2753,64 @@ out: return poolid; } +static int zcache_local_new_pool(uint32_t flags) +{ + return zcache_new_pool(LOCAL_CLIENT, flags); +} + +int zcache_autocreate_pool(int cli_id, int pool_id, bool ephemeral) +{ + struct tmem_pool *pool; + struct zcache_client *cli = NULL; + uint32_t flags = ephemeral ? 0 : TMEM_POOL_PERSIST; + int ret = -1; + + if (cli_id == LOCAL_CLIENT) + goto out; + if (pool_id >= MAX_POOLS_PER_CLIENT) + goto out; + else if ((unsigned int)cli_id < MAX_CLIENTS) + cli = &zcache_clients[cli_id]; + if ((ephemeral && !use_cleancache) || (!ephemeral && !use_frontswap)) + BUG(); /* FIXME, handle more gracefully later */ + if (!cli->allocated) { + if (zcache_new_client(cli_id)) + BUG(); /* FIXME, handle more gracefully later */ + cli = &zcache_clients[cli_id]; + } + atomic_inc(&cli->refcount); + pool = cli->tmem_pools[pool_id]; + if (pool != NULL) { + if (pool->persistent && ephemeral) { + pr_err("zcache_autocreate_pool: type mismatch\n"); + goto out; + } + ret = 0; + goto out; + } + pool = kmalloc(sizeof(struct tmem_pool), GFP_KERNEL); + if (pool == NULL) { + pr_info("ramster: pool creation failed: out of memory\n"); + goto out; + } + atomic_set(&pool->refcount, 0); + pool->client = cli; + pool->pool_id = pool_id; + tmem_new_pool(pool, flags); + cli->tmem_pools[pool_id] = pool; + pr_info("ramster: AUTOcreated %s tmem poolid=%d, for remote client=%d\n", + flags & TMEM_POOL_PERSIST ? "persistent" : "ephemeral", + pool_id, cli_id); + ret = 0; +out: + if (cli == NULL) + BUG(); /* FIXME, handle more gracefully later */ + /* pr_err("zcache_autocreate_pool: failed\n"); */ + if (cli != NULL) + atomic_dec(&cli->refcount); + return ret; +} + /********** * Two kernel functionalities currently can be layered on top of tmem. * These are "cleancache" which is used as a second-chance cache for clean @@ -1696,8 +2827,18 @@ static void zcache_cleancache_put_page(int pool_id, u32 ind = (u32) index; struct tmem_oid oid = *(struct tmem_oid *)&key; - if (likely(ind == index)) - (void)zcache_put_page(LOCAL_CLIENT, pool_id, &oid, index, page); +#ifdef __PG_WAS_ACTIVE + if (!PageWasActive(page)) { + zcache_nonactive_puts++; + return; + } +#endif + if (likely(ind == index)) { + char *kva = page_address(page); + + (void)zcache_put(LOCAL_CLIENT, pool_id, &oid, index, + kva, PAGE_SIZE, 0, 1); + } } static int zcache_cleancache_get_page(int pool_id, @@ -1708,8 +2849,19 @@ static int zcache_cleancache_get_page(int pool_id, struct tmem_oid oid = *(struct tmem_oid *)&key; int ret = -1; - if (likely(ind == index)) - ret = zcache_get_page(LOCAL_CLIENT, pool_id, &oid, index, page); + preempt_disable(); + if (likely(ind == index)) { + char *kva = page_address(page); + size_t size = PAGE_SIZE; + + ret = zcache_get(LOCAL_CLIENT, pool_id, &oid, index, + kva, &size, 0, 0); +#ifdef __PG_WAS_ACTIVE + if (ret == 0) + SetPageWasActive(page); +#endif + } + preempt_enable(); return ret; } @@ -1721,7 +2873,7 @@ static void zcache_cleancache_flush_page(int pool_id, struct tmem_oid oid = *(struct tmem_oid *)&key; if (likely(ind == index)) - (void)zcache_flush_page(LOCAL_CLIENT, pool_id, &oid, ind); + (void)zcache_flush(LOCAL_CLIENT, pool_id, &oid, ind); } static void zcache_cleancache_flush_inode(int pool_id, @@ -1735,7 +2887,7 @@ static void zcache_cleancache_flush_inode(int pool_id, static void zcache_cleancache_flush_fs(int pool_id) { if (pool_id >= 0) - (void)zcache_destroy_pool(LOCAL_CLIENT, pool_id); + (void)zcache_destroy_pool(pool_id); } static int zcache_cleancache_init_fs(size_t pagesize) @@ -1743,7 +2895,7 @@ static int zcache_cleancache_init_fs(size_t pagesize) BUG_ON(sizeof(struct cleancache_filekey) != sizeof(struct tmem_oid)); BUG_ON(pagesize != PAGE_SIZE); - return zcache_new_pool(LOCAL_CLIENT, 0); + return zcache_local_new_pool(0); } static int zcache_cleancache_init_shared_fs(char *uuid, size_t pagesize) @@ -1752,7 +2904,7 @@ static int zcache_cleancache_init_shared_fs(char *uuid, size_t pagesize) BUG_ON(sizeof(struct cleancache_filekey) != sizeof(struct tmem_oid)); BUG_ON(pagesize != PAGE_SIZE); - return zcache_new_pool(LOCAL_CLIENT, 0); + return zcache_local_new_pool(0); } static struct cleancache_ops zcache_cleancache_ops = { @@ -1781,10 +2933,8 @@ static int zcache_frontswap_poolid = -1; /* * Swizzling increases objects per swaptype, increasing tmem concurrency * for heavy swaploads. Later, larger nr_cpus -> larger SWIZ_BITS - * Setting SWIZ_BITS to 27 basically reconstructs the swap entry from - * frontswap_get_page() */ -#define SWIZ_BITS 27 +#define SWIZ_BITS 8 #define SWIZ_MASK ((1 << SWIZ_BITS) - 1) #define _oswiz(_type, _ind) ((_type << SWIZ_BITS) | (_ind & SWIZ_MASK)) #define iswiz(_ind) (_ind >> SWIZ_BITS) @@ -1804,12 +2954,14 @@ static int zcache_frontswap_put_page(unsigned type, pgoff_t offset, struct tmem_oid oid = oswiz(type, ind); int ret = -1; unsigned long flags; + char *kva; BUG_ON(!PageLocked(page)); if (likely(ind64 == ind)) { local_irq_save(flags); - ret = zcache_put_page(LOCAL_CLIENT, zcache_frontswap_poolid, - &oid, iswiz(ind), page); + kva = page_address(page); + ret = zcache_put(LOCAL_CLIENT, zcache_frontswap_poolid, + &oid, iswiz(ind), kva, PAGE_SIZE, 0, 0); local_irq_restore(flags); } return ret; @@ -1825,10 +2977,16 @@ static int zcache_frontswap_get_page(unsigned type, pgoff_t offset, struct tmem_oid oid = oswiz(type, ind); int ret = -1; + preempt_disable(); /* FIXME, remove this? */ BUG_ON(!PageLocked(page)); - if (likely(ind64 == ind)) - ret = zcache_get_page(LOCAL_CLIENT, zcache_frontswap_poolid, - &oid, iswiz(ind), page); + if (likely(ind64 == ind)) { + char *kva = page_address(page); + size_t size = PAGE_SIZE; + + ret = zcache_get(LOCAL_CLIENT, zcache_frontswap_poolid, + &oid, iswiz(ind), kva, &size, 0, -1); + } + preempt_enable(); /* FIXME, remove this? */ return ret; } @@ -1840,7 +2998,7 @@ static void zcache_frontswap_flush_page(unsigned type, pgoff_t offset) struct tmem_oid oid = oswiz(type, ind); if (likely(ind64 == ind)) - (void)zcache_flush_page(LOCAL_CLIENT, zcache_frontswap_poolid, + (void)zcache_flush(LOCAL_CLIENT, zcache_frontswap_poolid, &oid, iswiz(ind)); } @@ -1862,7 +3020,7 @@ static void zcache_frontswap_init(unsigned ignored) /* a single tmem poolid is used for all frontswap "types" (swapfiles) */ if (zcache_frontswap_poolid < 0) zcache_frontswap_poolid = - zcache_new_pool(LOCAL_CLIENT, TMEM_POOL_PERSIST); + zcache_local_new_pool(TMEM_POOL_PERSIST); } static struct frontswap_ops zcache_frontswap_ops = { @@ -1882,20 +3040,126 @@ struct frontswap_ops zcache_frontswap_register_ops(void) } #endif +/* + * frontswap selfshrinking + */ + +#ifdef CONFIG_FRONTSWAP +/* In HZ, controls frequency of worker invocation. */ +static unsigned int selfshrink_interval __read_mostly = 5; + +static void selfshrink_process(struct work_struct *work); +static DECLARE_DELAYED_WORK(selfshrink_worker, selfshrink_process); + +/* Enable/disable with sysfs. */ +static bool frontswap_selfshrinking __read_mostly; + +/* Enable/disable with kernel boot option. */ +static bool use_frontswap_selfshrink __initdata = true; + +/* + * The default values for the following parameters were deemed reasonable + * by experimentation, may be workload-dependent, and can all be + * adjusted via sysfs. + */ + +/* Control rate for frontswap shrinking. Higher hysteresis is slower. */ +static unsigned int frontswap_hysteresis __read_mostly = 20; + +/* + * Number of selfshrink worker invocations to wait before observing that + * frontswap selfshrinking should commence. Note that selfshrinking does + * not use a separate worker thread. + */ +static unsigned int frontswap_inertia __read_mostly = 3; + +/* Countdown to next invocation of frontswap_shrink() */ +static unsigned long frontswap_inertia_counter; + +/* + * Invoked by the selfshrink worker thread, uses current number of pages + * in frontswap (frontswap_curr_pages()), previous status, and control + * values (hysteresis and inertia) to determine if frontswap should be + * shrunk and what the new frontswap size should be. Note that + * frontswap_shrink is essentially a partial swapoff that immediately + * transfers pages from the "swap device" (frontswap) back into kernel + * RAM; despite the name, frontswap "shrinking" is very different from + * the "shrinker" interface used by the kernel MM subsystem to reclaim + * memory. + */ +static void frontswap_selfshrink(void) +{ + static unsigned long cur_frontswap_pages; + static unsigned long last_frontswap_pages; + static unsigned long tgt_frontswap_pages; + + last_frontswap_pages = cur_frontswap_pages; + cur_frontswap_pages = frontswap_curr_pages(); + if (!cur_frontswap_pages || + (cur_frontswap_pages > last_frontswap_pages)) { + frontswap_inertia_counter = frontswap_inertia; + return; + } + if (frontswap_inertia_counter && --frontswap_inertia_counter) + return; + if (cur_frontswap_pages <= frontswap_hysteresis) + tgt_frontswap_pages = 0; + else + tgt_frontswap_pages = cur_frontswap_pages - + (cur_frontswap_pages / frontswap_hysteresis); + frontswap_shrink(tgt_frontswap_pages); +} + +static int __init ramster_nofrontswap_selfshrink_setup(char *s) +{ + use_frontswap_selfshrink = false; + return 1; +} + +__setup("noselfshrink", ramster_nofrontswap_selfshrink_setup); + +static void selfshrink_process(struct work_struct *work) +{ + if (frontswap_selfshrinking && frontswap_enabled) { + frontswap_selfshrink(); + schedule_delayed_work(&selfshrink_worker, + selfshrink_interval * HZ); + } +} + +static int ramster_enabled; + +static int __init ramster_selfshrink_init(void) +{ + frontswap_selfshrinking = ramster_enabled && use_frontswap_selfshrink; + if (frontswap_selfshrinking) + pr_info("ramster: Initializing frontswap " + "selfshrinking driver.\n"); + else + return -ENODEV; + + schedule_delayed_work(&selfshrink_worker, selfshrink_interval * HZ); + + return 0; +} + +subsys_initcall(ramster_selfshrink_init); +#endif + /* * zcache initialization - * NOTE FOR NOW zcache MUST BE PROVIDED AS A KERNEL BOOT PARAMETER OR + * NOTE FOR NOW ramster MUST BE PROVIDED AS A KERNEL BOOT PARAMETER OR * NOTHING HAPPENS! */ -static int zcache_enabled; +static int ramster_enabled; -static int __init enable_zcache(char *s) +static int __init enable_ramster(char *s) { - zcache_enabled = 1; + ramster_enabled = 1; return 1; } -__setup("zcache", enable_zcache); +__setup("ramster", enable_ramster); /* allow independent dynamic disabling of cleancache and frontswap */ @@ -1903,16 +3167,22 @@ static int use_cleancache = 1; static int __init no_cleancache(char *s) { + pr_info("INIT no_cleancache called\n"); use_cleancache = 0; return 1; } -__setup("nocleancache", no_cleancache); +/* + * FIXME: need to guarantee this gets checked before zcache_init is called + * What is the correct way to achieve this? + */ +early_param("nocleancache", no_cleancache); static int use_frontswap = 1; static int __init no_frontswap(char *s) { + pr_info("INIT no_frontswap called\n"); use_frontswap = 0; return 1; } @@ -1925,20 +3195,22 @@ static int __init zcache_init(void) #ifdef CONFIG_SYSFS ret = sysfs_create_group(mm_kobj, &zcache_attr_group); + ret = sysfs_create_group(mm_kobj, &ramster_attr_group); if (ret) { - pr_err("zcache: can't create sysfs\n"); + pr_err("ramster: can't create sysfs\n"); goto out; } #endif /* CONFIG_SYSFS */ #if defined(CONFIG_CLEANCACHE) || defined(CONFIG_FRONTSWAP) - if (zcache_enabled) { + if (ramster_enabled) { unsigned int cpu; + (void)ramster_o2net_register_handlers(); tmem_register_hostops(&zcache_hostops); tmem_register_pamops(&zcache_pamops); ret = register_cpu_notifier(&zcache_cpu_notifier_block); if (ret) { - pr_err("zcache: can't register cpu notifier\n"); + pr_err("ramster: can't register cpu notifier\n"); goto out; } for_each_online_cpu(cpu) { @@ -1951,35 +3223,39 @@ static int __init zcache_init(void) sizeof(struct tmem_objnode), 0, 0, NULL); zcache_obj_cache = kmem_cache_create("zcache_obj", sizeof(struct tmem_obj), 0, 0, NULL); - ret = zcache_new_client(LOCAL_CLIENT); - if (ret) { - pr_err("zcache: can't create client\n"); - goto out; - } + ramster_flnode_cache = kmem_cache_create("ramster_flnode", + sizeof(struct flushlist_node), 0, 0, NULL); #endif #ifdef CONFIG_CLEANCACHE - if (zcache_enabled && use_cleancache) { + pr_info("INIT ramster_enabled=%d use_cleancache=%d\n", + ramster_enabled, use_cleancache); + if (ramster_enabled && use_cleancache) { struct cleancache_ops old_ops; zbud_init(); register_shrinker(&zcache_shrinker); old_ops = zcache_cleancache_register_ops(); - pr_info("zcache: cleancache enabled using kernel " + pr_info("ramster: cleancache enabled using kernel " "transcendent memory and compression buddies\n"); if (old_ops.init_fs != NULL) - pr_warning("zcache: cleancache_ops overridden"); + pr_warning("ramster: cleancache_ops overridden"); } #endif #ifdef CONFIG_FRONTSWAP - if (zcache_enabled && use_frontswap) { + pr_info("INIT ramster_enabled=%d use_frontswap=%d\n", + ramster_enabled, use_frontswap); + if (ramster_enabled && use_frontswap) { struct frontswap_ops old_ops; + zcache_new_client(LOCAL_CLIENT); old_ops = zcache_frontswap_register_ops(); - pr_info("zcache: frontswap enabled using kernel " + pr_info("ramster: frontswap enabled using kernel " "transcendent memory and xvmalloc\n"); if (old_ops.init != NULL) - pr_warning("zcache: frontswap_ops overridden"); + pr_warning("ramster: frontswap_ops overridden"); } + if (ramster_enabled && (use_frontswap || use_cleancache)) + ramster_remotify_init(); #endif out: return ret; -- cgit v1.2.3-70-g09d2 From 14a3cd58dd4fa10df8d84b37efae1e92962ad372 Mon Sep 17 00:00:00 2001 From: Dan Magenheimer Date: Mon, 30 Jan 2012 14:39:19 -0800 Subject: staging: ramster: ramster-specific new files New files for ramster support: The file ramster.h declares externs and some pampd bitfield manipulation. The file zcache.h declares some zcache functions that now must be accessed from the ramster glue code. The file ramster_o2net.c is the glue between zcache and the o2net messaging code, providing routines called from zcache that initiate messages, and routines that handle messages by calling zcache. TODO explains future plans for merging. Signed-off-by: Dan Magenheimer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ramster/TODO | 9 + drivers/staging/ramster/ramster.h | 117 ++++++++++ drivers/staging/ramster/ramster_o2net.c | 402 ++++++++++++++++++++++++++++++++ drivers/staging/ramster/zcache.h | 22 ++ 4 files changed, 550 insertions(+) create mode 100644 drivers/staging/ramster/TODO create mode 100644 drivers/staging/ramster/ramster.h create mode 100644 drivers/staging/ramster/ramster_o2net.c create mode 100644 drivers/staging/ramster/zcache.h (limited to 'drivers') diff --git a/drivers/staging/ramster/TODO b/drivers/staging/ramster/TODO new file mode 100644 index 00000000000..d4268f06514 --- /dev/null +++ b/drivers/staging/ramster/TODO @@ -0,0 +1,9 @@ +For this staging driver, RAMster duplicates code from fs/ocfs2/cluster +and from drivers/staging/zcache, then incorporates changes to the local +copy of the code. Before RAMster can be promoted from staging, this code +duplication must be resolved. Specifically, we will first need to work with +the ocfs2 maintainers to split out the ocfs2 core cluster code so that +it can be easily included by another subsystem, even if ocfs2 is not +configured, and also to merge the handful of functional changes required. +Second, the zcache and RAMster drivers should be either merged or reorganized +to separate out common code. diff --git a/drivers/staging/ramster/ramster.h b/drivers/staging/ramster/ramster.h new file mode 100644 index 00000000000..329351253b3 --- /dev/null +++ b/drivers/staging/ramster/ramster.h @@ -0,0 +1,117 @@ +/* + * ramster.h + * + * Peer-to-peer transcendent memory + * + * Copyright (c) 2009-2012, Dan Magenheimer, Oracle Corp. + */ + +#ifndef _RAMSTER_H_ +#define _RAMSTER_H_ + +/* + * format of remote pampd: + * bit 0 == intransit + * bit 1 == is_remote... if this bit is set, then + * bit 2-9 == remotenode + * bit 10-22 == size + * bit 23-30 == cksum + */ +#define FAKE_PAMPD_INTRANSIT_BITS 1 +#define FAKE_PAMPD_ISREMOTE_BITS 1 +#define FAKE_PAMPD_REMOTENODE_BITS 8 +#define FAKE_PAMPD_REMOTESIZE_BITS 13 +#define FAKE_PAMPD_CHECKSUM_BITS 8 + +#define FAKE_PAMPD_INTRANSIT_SHIFT 0 +#define FAKE_PAMPD_ISREMOTE_SHIFT (FAKE_PAMPD_INTRANSIT_SHIFT + \ + FAKE_PAMPD_INTRANSIT_BITS) +#define FAKE_PAMPD_REMOTENODE_SHIFT (FAKE_PAMPD_ISREMOTE_SHIFT + \ + FAKE_PAMPD_ISREMOTE_BITS) +#define FAKE_PAMPD_REMOTESIZE_SHIFT (FAKE_PAMPD_REMOTENODE_SHIFT + \ + FAKE_PAMPD_REMOTENODE_BITS) +#define FAKE_PAMPD_CHECKSUM_SHIFT (FAKE_PAMPD_REMOTESIZE_SHIFT + \ + FAKE_PAMPD_REMOTESIZE_BITS) + +#define FAKE_PAMPD_MASK(x) ((1UL << (x)) - 1) + +static inline void *pampd_make_remote(int remotenode, size_t size, + unsigned char cksum) +{ + unsigned long fake_pampd = 0; + fake_pampd |= 1UL << FAKE_PAMPD_ISREMOTE_SHIFT; + fake_pampd |= ((unsigned long)remotenode & + FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTENODE_BITS)) << + FAKE_PAMPD_REMOTENODE_SHIFT; + fake_pampd |= ((unsigned long)size & + FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTESIZE_BITS)) << + FAKE_PAMPD_REMOTESIZE_SHIFT; + fake_pampd |= ((unsigned long)cksum & + FAKE_PAMPD_MASK(FAKE_PAMPD_CHECKSUM_BITS)) << + FAKE_PAMPD_CHECKSUM_SHIFT; + return (void *)fake_pampd; +} + +static inline unsigned int pampd_remote_node(void *pampd) +{ + unsigned long fake_pampd = (unsigned long)pampd; + return (fake_pampd >> FAKE_PAMPD_REMOTENODE_SHIFT) & + FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTENODE_BITS); +} + +static inline unsigned int pampd_remote_size(void *pampd) +{ + unsigned long fake_pampd = (unsigned long)pampd; + return (fake_pampd >> FAKE_PAMPD_REMOTESIZE_SHIFT) & + FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTESIZE_BITS); +} + +static inline unsigned char pampd_remote_cksum(void *pampd) +{ + unsigned long fake_pampd = (unsigned long)pampd; + return (fake_pampd >> FAKE_PAMPD_CHECKSUM_SHIFT) & + FAKE_PAMPD_MASK(FAKE_PAMPD_CHECKSUM_BITS); +} + +static inline bool pampd_is_remote(void *pampd) +{ + unsigned long fake_pampd = (unsigned long)pampd; + return (fake_pampd >> FAKE_PAMPD_ISREMOTE_SHIFT) & + FAKE_PAMPD_MASK(FAKE_PAMPD_ISREMOTE_BITS); +} + +static inline bool pampd_is_intransit(void *pampd) +{ + unsigned long fake_pampd = (unsigned long)pampd; + return (fake_pampd >> FAKE_PAMPD_INTRANSIT_SHIFT) & + FAKE_PAMPD_MASK(FAKE_PAMPD_INTRANSIT_BITS); +} + +/* note that it is a BUG for intransit to be set without isremote also set */ +static inline void *pampd_mark_intransit(void *pampd) +{ + unsigned long fake_pampd = (unsigned long)pampd; + + fake_pampd |= 1UL << FAKE_PAMPD_ISREMOTE_SHIFT; + fake_pampd |= 1UL << FAKE_PAMPD_INTRANSIT_SHIFT; + return (void *)fake_pampd; +} + +static inline void *pampd_mask_intransit_and_remote(void *marked_pampd) +{ + unsigned long pampd = (unsigned long)marked_pampd; + + pampd &= ~(1UL << FAKE_PAMPD_INTRANSIT_SHIFT); + pampd &= ~(1UL << FAKE_PAMPD_ISREMOTE_SHIFT); + return (void *)pampd; +} + +extern int ramster_remote_async_get(struct tmem_xhandle *, + bool, int, size_t, uint8_t, void *extra); +extern int ramster_remote_put(struct tmem_xhandle *, char *, size_t, + bool, int *); +extern int ramster_remote_flush(struct tmem_xhandle *, int); +extern int ramster_remote_flush_object(struct tmem_xhandle *, int); +extern int ramster_o2net_register_handlers(void); + +#endif /* _TMEM_H */ diff --git a/drivers/staging/ramster/ramster_o2net.c b/drivers/staging/ramster/ramster_o2net.c new file mode 100644 index 00000000000..c5a47cc4540 --- /dev/null +++ b/drivers/staging/ramster/ramster_o2net.c @@ -0,0 +1,402 @@ +/* + * ramster_o2net.c + * + * Copyright (c) 2011, Dan Magenheimer, Oracle Corp. + * + * Ramster_o2net provides an interface between zcache and o2net. + * + * FIXME: support more than two nodes + */ + +#include +#include "cluster/tcp.h" +#include "cluster/nodemanager.h" +#include "tmem.h" +#include "zcache.h" +#include "ramster.h" + +#define RAMSTER_TESTING + +#define RMSTR_KEY 0x77347734 + +enum { + RMSTR_TMEM_PUT_EPH = 100, + RMSTR_TMEM_PUT_PERS, + RMSTR_TMEM_ASYNC_GET_REQUEST, + RMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST, + RMSTR_TMEM_ASYNC_GET_REPLY, + RMSTR_TMEM_FLUSH, + RMSTR_TMEM_FLOBJ, + RMSTR_TMEM_DESTROY_POOL, +}; + +#define RMSTR_O2NET_MAX_LEN \ + (O2NET_MAX_PAYLOAD_BYTES - sizeof(struct tmem_xhandle)) + +#include "cluster/tcp_internal.h" + +static struct o2nm_node *ramster_choose_node(int *nodenum, + struct tmem_xhandle *xh) +{ + struct o2nm_node *node = NULL; + int i; + +/* FIXME reproducibly pick a node based on xh that is NOT this node */ + i = o2nm_this_node(); + i = !i; /* FIXME ONLY FOR TWO NODES */ + node = o2nm_get_node_by_num(i); + /* WARNING: THIS DOES NOT CHECK TO ENSURE CONNECTED */ + if (node != NULL) + *nodenum = i; + return node; +} + +static void ramster_put_node(struct o2nm_node *node) +{ + o2nm_node_put(node); +} + +/* FIXME following buffer should be per-cpu, protected by preempt_disable */ +static char ramster_async_get_buf[O2NET_MAX_PAYLOAD_BYTES]; + +static int ramster_remote_async_get_request_handler(struct o2net_msg *msg, + u32 len, void *data, void **ret_data) +{ + char *pdata; + struct tmem_xhandle xh; + int found; + size_t size = RMSTR_O2NET_MAX_LEN; + u16 msgtype = be16_to_cpu(msg->msg_type); + bool get_and_free = (msgtype == RMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST); + unsigned long flags; + + xh = *(struct tmem_xhandle *)msg->buf; + if (xh.xh_data_size > RMSTR_O2NET_MAX_LEN) + BUG(); + pdata = ramster_async_get_buf; + *(struct tmem_xhandle *)pdata = xh; + pdata += sizeof(struct tmem_xhandle); + local_irq_save(flags); + found = zcache_get(xh.client_id, xh.pool_id, &xh.oid, xh.index, + pdata, &size, 1, get_and_free ? 1 : -1); + local_irq_restore(flags); + if (found < 0) { + /* a zero size indicates the get failed */ + size = 0; + } + if (size > RMSTR_O2NET_MAX_LEN) + BUG(); + *ret_data = pdata - sizeof(struct tmem_xhandle); + /* now make caller (o2net_process_message) handle specially */ + o2net_force_data_magic(msg, RMSTR_TMEM_ASYNC_GET_REPLY, RMSTR_KEY); + return size + sizeof(struct tmem_xhandle); +} + +static int ramster_remote_async_get_reply_handler(struct o2net_msg *msg, + u32 len, void *data, void **ret_data) +{ + char *in = (char *)msg->buf; + int datalen = len - sizeof(struct o2net_msg); + int ret = -1; + struct tmem_xhandle *xh = (struct tmem_xhandle *)in; + + in += sizeof(struct tmem_xhandle); + datalen -= sizeof(struct tmem_xhandle); + BUG_ON(datalen < 0 || datalen > PAGE_SIZE); + ret = zcache_localify(xh->pool_id, &xh->oid, xh->index, + in, datalen, xh->extra); +#ifdef RAMSTER_TESTING + if (ret == -EEXIST) + pr_err("TESTING ArrgREP, aborted overwrite on racy put\n"); +#endif + return ret; +} + +int ramster_remote_put_handler(struct o2net_msg *msg, + u32 len, void *data, void **ret_data) +{ + struct tmem_xhandle *xh; + char *p = (char *)msg->buf; + int datalen = len - sizeof(struct o2net_msg) - + sizeof(struct tmem_xhandle); + u16 msgtype = be16_to_cpu(msg->msg_type); + bool ephemeral = (msgtype == RMSTR_TMEM_PUT_EPH); + unsigned long flags; + int ret; + + xh = (struct tmem_xhandle *)p; + p += sizeof(struct tmem_xhandle); + zcache_autocreate_pool(xh->client_id, xh->pool_id, ephemeral); + local_irq_save(flags); + ret = zcache_put(xh->client_id, xh->pool_id, &xh->oid, xh->index, + p, datalen, 1, ephemeral ? 1 : -1); + local_irq_restore(flags); + return ret; +} + +int ramster_remote_flush_handler(struct o2net_msg *msg, + u32 len, void *data, void **ret_data) +{ + struct tmem_xhandle *xh; + char *p = (char *)msg->buf; + + xh = (struct tmem_xhandle *)p; + p += sizeof(struct tmem_xhandle); + (void)zcache_flush(xh->client_id, xh->pool_id, &xh->oid, xh->index); + return 0; +} + +int ramster_remote_flobj_handler(struct o2net_msg *msg, + u32 len, void *data, void **ret_data) +{ + struct tmem_xhandle *xh; + char *p = (char *)msg->buf; + + xh = (struct tmem_xhandle *)p; + p += sizeof(struct tmem_xhandle); + (void)zcache_flush_object(xh->client_id, xh->pool_id, &xh->oid); + return 0; +} + +int ramster_remote_async_get(struct tmem_xhandle *xh, bool free, int remotenode, + size_t expect_size, uint8_t expect_cksum, + void *extra) +{ + int ret = -1, status; + struct o2nm_node *node = NULL; + struct kvec vec[1]; + size_t veclen = 1; + u32 msg_type; + + node = o2nm_get_node_by_num(remotenode); + if (node == NULL) + goto out; + xh->client_id = o2nm_this_node(); /* which node is getting */ + xh->xh_data_cksum = expect_cksum; + xh->xh_data_size = expect_size; + xh->extra = extra; + vec[0].iov_len = sizeof(*xh); + vec[0].iov_base = xh; + if (free) + msg_type = RMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST; + else + msg_type = RMSTR_TMEM_ASYNC_GET_REQUEST; + ret = o2net_send_message_vec(msg_type, RMSTR_KEY, + vec, veclen, remotenode, &status); + ramster_put_node(node); + if (ret < 0) { + /* FIXME handle bad message possibilities here? */ + pr_err("UNTESTED ret<0 in ramster_remote_async_get\n"); + } + ret = status; +out: + return ret; +} + +#ifdef RAMSTER_TESTING +/* leave me here to see if it catches a weird crash */ +static void ramster_check_irq_counts(void) +{ + static int last_hardirq_cnt, last_softirq_cnt, last_preempt_cnt; + int cur_hardirq_cnt, cur_softirq_cnt, cur_preempt_cnt; + + cur_hardirq_cnt = hardirq_count() >> HARDIRQ_SHIFT; + if (cur_hardirq_cnt > last_hardirq_cnt) { + last_hardirq_cnt = cur_hardirq_cnt; + if (!(last_hardirq_cnt&(last_hardirq_cnt-1))) + pr_err("RAMSTER TESTING RRP hardirq_count=%d\n", + last_hardirq_cnt); + } + cur_softirq_cnt = softirq_count() >> SOFTIRQ_SHIFT; + if (cur_softirq_cnt > last_softirq_cnt) { + last_softirq_cnt = cur_softirq_cnt; + if (!(last_softirq_cnt&(last_softirq_cnt-1))) + pr_err("RAMSTER TESTING RRP softirq_count=%d\n", + last_softirq_cnt); + } + cur_preempt_cnt = preempt_count() & PREEMPT_MASK; + if (cur_preempt_cnt > last_preempt_cnt) { + last_preempt_cnt = cur_preempt_cnt; + if (!(last_preempt_cnt&(last_preempt_cnt-1))) + pr_err("RAMSTER TESTING RRP preempt_count=%d\n", + last_preempt_cnt); + } +} +#endif + +int ramster_remote_put(struct tmem_xhandle *xh, char *data, size_t size, + bool ephemeral, int *remotenode) +{ + int nodenum, ret = -1, status; + struct o2nm_node *node = NULL; + struct kvec vec[2]; + size_t veclen = 2; + u32 msg_type; +#ifdef RAMSTER_TESTING + struct o2net_node *nn; +#endif + + BUG_ON(size > RMSTR_O2NET_MAX_LEN); + xh->client_id = o2nm_this_node(); /* which node is putting */ + vec[0].iov_len = sizeof(*xh); + vec[0].iov_base = xh; + vec[1].iov_len = size; + vec[1].iov_base = data; + node = ramster_choose_node(&nodenum, xh); + if (!node) + goto out; + +#ifdef RAMSTER_TESTING + nn = o2net_nn_from_num(nodenum); + WARN_ON_ONCE(nn->nn_persistent_error || !nn->nn_sc_valid); +#endif + + if (ephemeral) + msg_type = RMSTR_TMEM_PUT_EPH; + else + msg_type = RMSTR_TMEM_PUT_PERS; +#ifdef RAMSTER_TESTING + /* leave me here to see if it catches a weird crash */ + ramster_check_irq_counts(); +#endif + + ret = o2net_send_message_vec(msg_type, RMSTR_KEY, + vec, veclen, nodenum, &status); +#ifdef RAMSTER_TESTING + if (ret != 0) { + static unsigned long cnt; + cnt++; + if (!(cnt&(cnt-1))) + pr_err("ramster_remote_put: message failed, " + "ret=%d, cnt=%lu\n", ret, cnt); + ret = -1; + } +#endif + if (ret < 0) + ret = -1; + else { + ret = status; + *remotenode = nodenum; + } + + ramster_put_node(node); +out: + return ret; +} + +int ramster_remote_flush(struct tmem_xhandle *xh, int remotenode) +{ + int ret = -1, status; + struct o2nm_node *node = NULL; + struct kvec vec[1]; + size_t veclen = 1; + + node = o2nm_get_node_by_num(remotenode); + BUG_ON(node == NULL); + xh->client_id = o2nm_this_node(); /* which node is flushing */ + vec[0].iov_len = sizeof(*xh); + vec[0].iov_base = xh; + BUG_ON(irqs_disabled()); + BUG_ON(in_softirq()); + ret = o2net_send_message_vec(RMSTR_TMEM_FLUSH, RMSTR_KEY, + vec, veclen, remotenode, &status); + ramster_put_node(node); + return ret; +} + +int ramster_remote_flush_object(struct tmem_xhandle *xh, int remotenode) +{ + int ret = -1, status; + struct o2nm_node *node = NULL; + struct kvec vec[1]; + size_t veclen = 1; + + node = o2nm_get_node_by_num(remotenode); + BUG_ON(node == NULL); + xh->client_id = o2nm_this_node(); /* which node is flobjing */ + vec[0].iov_len = sizeof(*xh); + vec[0].iov_base = xh; + ret = o2net_send_message_vec(RMSTR_TMEM_FLOBJ, RMSTR_KEY, + vec, veclen, remotenode, &status); + ramster_put_node(node); + return ret; +} + +/* + * Handler registration + */ + +static LIST_HEAD(ramster_o2net_unreg_list); + +static void ramster_o2net_unregister_handlers(void) +{ + o2net_unregister_handler_list(&ramster_o2net_unreg_list); +} + +int ramster_o2net_register_handlers(void) +{ + int status; + + status = o2net_register_handler(RMSTR_TMEM_PUT_EPH, RMSTR_KEY, + RMSTR_O2NET_MAX_LEN, + ramster_remote_put_handler, + NULL, NULL, &ramster_o2net_unreg_list); + if (status) + goto bail; + + status = o2net_register_handler(RMSTR_TMEM_PUT_PERS, RMSTR_KEY, + RMSTR_O2NET_MAX_LEN, + ramster_remote_put_handler, + NULL, NULL, &ramster_o2net_unreg_list); + if (status) + goto bail; + + status = o2net_register_handler(RMSTR_TMEM_ASYNC_GET_REQUEST, RMSTR_KEY, + RMSTR_O2NET_MAX_LEN, + ramster_remote_async_get_request_handler, + NULL, NULL, + &ramster_o2net_unreg_list); + if (status) + goto bail; + + status = o2net_register_handler(RMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST, + RMSTR_KEY, RMSTR_O2NET_MAX_LEN, + ramster_remote_async_get_request_handler, + NULL, NULL, + &ramster_o2net_unreg_list); + if (status) + goto bail; + + status = o2net_register_handler(RMSTR_TMEM_ASYNC_GET_REPLY, RMSTR_KEY, + RMSTR_O2NET_MAX_LEN, + ramster_remote_async_get_reply_handler, + NULL, NULL, + &ramster_o2net_unreg_list); + if (status) + goto bail; + + status = o2net_register_handler(RMSTR_TMEM_FLUSH, RMSTR_KEY, + RMSTR_O2NET_MAX_LEN, + ramster_remote_flush_handler, + NULL, NULL, + &ramster_o2net_unreg_list); + if (status) + goto bail; + + status = o2net_register_handler(RMSTR_TMEM_FLOBJ, RMSTR_KEY, + RMSTR_O2NET_MAX_LEN, + ramster_remote_flobj_handler, + NULL, NULL, + &ramster_o2net_unreg_list); + if (status) + goto bail; + + pr_info("ramster_o2net: handlers registered\n"); + +bail: + if (status) { + ramster_o2net_unregister_handlers(); + pr_err("ramster_o2net: couldn't register handlers\n"); + } + return status; +} diff --git a/drivers/staging/ramster/zcache.h b/drivers/staging/ramster/zcache.h new file mode 100644 index 00000000000..250b121c22e --- /dev/null +++ b/drivers/staging/ramster/zcache.h @@ -0,0 +1,22 @@ +/* + * zcache.h + * + * External zcache functions + * + * Copyright (c) 2009-2012, Dan Magenheimer, Oracle Corp. + */ + +#ifndef _ZCACHE_H_ +#define _ZCACHE_H_ + +extern int zcache_put(int, int, struct tmem_oid *, uint32_t, + char *, size_t, bool, int); +extern int zcache_autocreate_pool(int, int, bool); +extern int zcache_get(int, int, struct tmem_oid *, uint32_t, + char *, size_t *, bool, int); +extern int zcache_flush(int, int, struct tmem_oid *, uint32_t); +extern int zcache_flush_object(int, int, struct tmem_oid *); +extern int zcache_localify(int, struct tmem_oid *, uint32_t, + char *, size_t, void *); + +#endif /* _ZCACHE_H */ -- cgit v1.2.3-70-g09d2 From 1739441c29e09706a1f82e6e0fecfd946b6f4328 Mon Sep 17 00:00:00 2001 From: Dan Magenheimer Date: Mon, 30 Jan 2012 14:39:19 -0800 Subject: staging: ramster: enable as staging driver Enable build of ramster as a staging driver Signed-off-by: Dan Magenheimer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 ++ drivers/staging/Makefile | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index aaba36c6f15..76a4c4a4717 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -134,4 +134,6 @@ source "drivers/staging/android/Kconfig" source "drivers/staging/telephony/Kconfig" +source "drivers/staging/ramster/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 7c5808d7212..c061be8419c 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -57,3 +57,4 @@ obj-$(CONFIG_INTEL_MEI) += mei/ obj-$(CONFIG_MFD_NVEC) += nvec/ obj-$(CONFIG_DRM_OMAP) += omapdrm/ obj-$(CONFIG_ANDROID) += android/ +obj-$(CONFIG_RAMSTER) += ramster/ -- cgit v1.2.3-70-g09d2 From 09f0355f0612520820ae4b2c342a26e048bef6e7 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 12 Jan 2012 12:37:54 -0800 Subject: Staging: hv: storvsc: Cleanup some comments Use consistent format for comments and get rid of some unnecessary comments. Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc_drv.c | 57 ++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index eb853f71089..1633b032b5f 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -50,8 +50,10 @@ static int storvsc_ringbuffer_size = STORVSC_RING_BUFFER_SIZE; module_param(storvsc_ringbuffer_size, int, S_IRUGO); MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)"); -/* to alert the user that structure sizes may be mismatched even though the */ -/* protocol versions match. */ +/* + * To alert the user that structure sizes may be mismatched even though the + * protocol versions match. + */ #define REVISION_STRING(REVISION_) #REVISION_ @@ -68,26 +70,36 @@ MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)"); } \ } while (0) -/* Major/minor macros. Minor version is in LSB, meaning that earlier flat */ -/* version numbers will be interpreted as "0.x" (i.e., 1 becomes 0.1). */ +/* + * Major/minor macros. Minor version is in LSB, meaning that earlier flat + * version numbers will be interpreted as "0.x" (i.e., 1 becomes 0.1). + */ + #define VMSTOR_PROTOCOL_MAJOR(VERSION_) (((VERSION_) >> 8) & 0xff) #define VMSTOR_PROTOCOL_MINOR(VERSION_) (((VERSION_)) & 0xff) #define VMSTOR_PROTOCOL_VERSION(MAJOR_, MINOR_) ((((MAJOR_) & 0xff) << 8) | \ (((MINOR_) & 0xff))) #define VMSTOR_INVALID_PROTOCOL_VERSION (-1) -/* Version history: */ -/* V1 Beta 0.1 */ -/* V1 RC < 2008/1/31 1.0 */ -/* V1 RC > 2008/1/31 2.0 */ +/* + * Version history: + * V1 Beta: 0.1 + * V1 RC < 2008/1/31: 1.0 + * V1 RC > 2008/1/31: 2.0 + * Win7: 4.2 + */ + #define VMSTOR_PROTOCOL_VERSION_CURRENT VMSTOR_PROTOCOL_VERSION(4, 2) -/* This will get replaced with the max transfer length that is possible on */ -/* the host adapter. */ -/* The max transfer length will be published when we offer a vmbus channel. */ +/* + * This will get replaced with the max transfer length that is possible on + * the host adapter. + * The max transfer length will be published when we offer a vmbus channel. + */ + #define MAX_TRANSFER_LENGTH 0x40000 #define DEFAULT_PACKET_SIZE (sizeof(struct vmdata_gpa_direct) + \ sizeof(struct vstor_packet) + \ @@ -211,18 +223,19 @@ struct vstor_packet { }; } __packed; -/* Packet flags */ /* + * Packet Flags: + * * This flag indicates that the server should send back a completion for this * packet. */ + #define REQUEST_COMPLETION_FLAG 0x1 /* This is the set of flags that the vsc can set in any packets it sends */ #define VSC_LEGAL_FLAGS (REQUEST_COMPLETION_FLAG) -/* Defines */ #define STORVSC_MAX_IO_REQUESTS 128 @@ -674,7 +687,6 @@ static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size) memset(&props, 0, sizeof(struct vmstorage_channel_properties)); - /* Open the channel */ ret = vmbus_open(device->channel, ring_size, ring_size, @@ -1154,9 +1166,6 @@ static int storvsc_host_reset(struct hv_device *device) } -/* - * storvsc_host_reset_handler - Reset the scsi HBA - */ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd) { struct hv_host_device *host_dev = shost_priv(scmnd->device->host); @@ -1166,9 +1175,6 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd) } -/* - * storvsc_command_completion - Command completion processing - */ static void storvsc_command_completion(struct hv_storvsc_request *request) { struct storvsc_cmd_request *cmd_request = @@ -1262,9 +1268,6 @@ static bool storvsc_check_scsi_cmd(struct scsi_cmnd *scmnd) return allowed; } -/* - * storvsc_queuecommand - Initiate command processing - */ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) { int ret; @@ -1407,7 +1410,6 @@ retry_request: return ret; } -/* Scsi driver */ static struct scsi_host_template scsi_driver = { .module = THIS_MODULE, .name = "storvsc_host_t", @@ -1448,11 +1450,6 @@ static const struct hv_vmbus_device_id id_table[] = { MODULE_DEVICE_TABLE(vmbus, id_table); - -/* - * storvsc_probe - Add a new device for this driver - */ - static int storvsc_probe(struct hv_device *device, const struct hv_vmbus_device_id *dev_id) { @@ -1542,8 +1539,6 @@ err_out0: return ret; } -/* The one and only one */ - static struct hv_driver storvsc_drv = { .name = KBUILD_MODNAME, .id_table = id_table, -- cgit v1.2.3-70-g09d2 From 59d22950b274182b006e4071d6690bfbc94d7267 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 12 Jan 2012 12:37:55 -0800 Subject: Staging: hv: storvsc: Cleanup storvsc_probe() Cleanup storvsc_probe(). As part of this cleanup, get rid of storvsc_get_ide_info() by inlining the necessary code. Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc_drv.c | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 1633b032b5f..7561d298f6d 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -791,18 +791,6 @@ static int storvsc_do_io(struct hv_device *device, return ret; } -static void storvsc_get_ide_info(struct hv_device *dev, int *target, int *path) -{ - *target = - dev->dev_instance.b[5] << 8 | dev->dev_instance.b[4]; - - *path = - dev->dev_instance.b[3] << 24 | - dev->dev_instance.b[2] << 16 | - dev->dev_instance.b[1] << 8 | dev->dev_instance.b[0]; -} - - static int storvsc_device_alloc(struct scsi_device *sdevice) { struct stor_mem_pools *memp; @@ -1457,7 +1445,6 @@ static int storvsc_probe(struct hv_device *device, struct Scsi_Host *host; struct hv_host_device *host_dev; bool dev_is_ide = ((dev_id->driver_data == IDE_GUID) ? true : false); - int path = 0; int target = 0; struct storvsc_device *stor_device; @@ -1490,9 +1477,6 @@ static int storvsc_probe(struct hv_device *device, if (ret) goto err_out1; - if (dev_is_ide) - storvsc_get_ide_info(device, &target, &path); - host_dev->path = stor_device->path_id; host_dev->target = stor_device->target_id; @@ -1512,12 +1496,14 @@ static int storvsc_probe(struct hv_device *device, if (!dev_is_ide) { scsi_scan_host(host); - return 0; - } - ret = scsi_add_device(host, 0, target, 0); - if (ret) { - scsi_remove_host(host); - goto err_out2; + } else { + target = (device->dev_instance.b[5] << 8 | + device->dev_instance.b[4]); + ret = scsi_add_device(host, 0, target, 0); + if (ret) { + scsi_remove_host(host); + goto err_out2; + } } return 0; -- cgit v1.2.3-70-g09d2 From c77b63b639f52b2e92d0bbaa94f33a78939f3e7c Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 12 Jan 2012 12:37:56 -0800 Subject: Staging: hv: storvsc: Cleanup storvsc_queuecommand() Cleanup storvsc_queuecommand(). As part of this cleanup, rename the function to check if the scsi command can be sent to the host, consolidate error recovery and get rid of some dead code. Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc_drv.c | 48 ++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 7561d298f6d..71e50c333b8 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -1239,13 +1239,16 @@ static void storvsc_command_completion(struct hv_storvsc_request *request) mempool_free(cmd_request, memp->request_mempool); } -static bool storvsc_check_scsi_cmd(struct scsi_cmnd *scmnd) +static bool storvsc_scsi_cmd_ok(struct scsi_cmnd *scmnd) { bool allowed = true; u8 scsi_op = scmnd->cmnd[0]; switch (scsi_op) { - /* smartd sends this command, which will offline the device */ + /* + * smartd sends this command and the host does not handle + * this. So, don't send it. + */ case SET_WINDOW: scmnd->result = ILLEGAL_REQUEST << 16; allowed = false; @@ -1270,32 +1273,26 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) struct vmscsi_request *vm_srb; struct stor_mem_pools *memp = scmnd->device->hostdata; - if (storvsc_check_scsi_cmd(scmnd) == false) { + if (!storvsc_scsi_cmd_ok(scmnd)) { scmnd->scsi_done(scmnd); return 0; } - /* If retrying, no need to prep the cmd */ - if (scmnd->host_scribble) { - - cmd_request = - (struct storvsc_cmd_request *)scmnd->host_scribble; - - goto retry_request; - } - request_size = sizeof(struct storvsc_cmd_request); cmd_request = mempool_alloc(memp->request_mempool, GFP_ATOMIC); + + /* + * We might be invoked in an interrupt context; hence + * mempool_alloc() can fail. + */ if (!cmd_request) return SCSI_MLQUEUE_DEVICE_BUSY; memset(cmd_request, 0, sizeof(struct storvsc_cmd_request)); /* Setup the cmd request */ - cmd_request->bounce_sgl_count = 0; - cmd_request->bounce_sgl = NULL; cmd_request->cmd = scmnd; scmnd->host_scribble = (unsigned char *)cmd_request; @@ -1344,11 +1341,8 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) scsi_bufflen(scmnd), vm_srb->data_in); if (!cmd_request->bounce_sgl) { - scmnd->host_scribble = NULL; - mempool_free(cmd_request, - memp->request_mempool); - - return SCSI_MLQUEUE_HOST_BUSY; + ret = SCSI_MLQUEUE_HOST_BUSY; + goto queue_error; } cmd_request->bounce_sgl_count = @@ -1377,24 +1371,26 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) virt_to_phys(scsi_sglist(scmnd)) >> PAGE_SHIFT; } -retry_request: /* Invokes the vsc to start an IO */ ret = storvsc_do_io(dev, &cmd_request->request); if (ret == -EAGAIN) { /* no more space */ - if (cmd_request->bounce_sgl_count) + if (cmd_request->bounce_sgl_count) { destroy_bounce_buffer(cmd_request->bounce_sgl, cmd_request->bounce_sgl_count); - mempool_free(cmd_request, memp->request_mempool); - - scmnd->host_scribble = NULL; - - ret = SCSI_MLQUEUE_DEVICE_BUSY; + ret = SCSI_MLQUEUE_DEVICE_BUSY; + goto queue_error; + } } + return 0; + +queue_error: + mempool_free(cmd_request, memp->request_mempool); + scmnd->host_scribble = NULL; return ret; } -- cgit v1.2.3-70-g09d2 From 160463204f541cea112fd4d68422f297bd98ec51 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 12 Jan 2012 12:37:57 -0800 Subject: Staging: hv: storvsc: Introduce defines for srb status codes Introduce defines for srb status codes. Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc_drv.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 71e50c333b8..979f25b3385 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -257,6 +257,16 @@ enum storvsc_request_type { UNKNOWN_TYPE, }; +/* + * SRB status codes and masks; a subset of the codes used here. + */ + +#define SRB_STATUS_AUTOSENSE_VALID 0x80 +#define SRB_STATUS_INVALID_LUN 0x20 +#define SRB_STATUS_SUCCESS 0x01 +#define SRB_STATUS_ERROR 0x04 + + struct hv_storvsc_request { struct hv_device *device; @@ -561,7 +571,7 @@ static void storvsc_on_io_completion(struct hv_device *device, if ((stor_pkt->vm_srb.cdb[0] == INQUIRY) || (stor_pkt->vm_srb.cdb[0] == MODE_SENSE)) { vstor_packet->vm_srb.scsi_status = 0; - vstor_packet->vm_srb.srb_status = 0x1; + vstor_packet->vm_srb.srb_status = SRB_STATUS_SUCCESS; } @@ -572,7 +582,7 @@ static void storvsc_on_io_completion(struct hv_device *device, vstor_packet->vm_srb.sense_info_length; if (vstor_packet->vm_srb.scsi_status != 0 || - vstor_packet->vm_srb.srb_status != 1){ + vstor_packet->vm_srb.srb_status != SRB_STATUS_SUCCESS){ dev_warn(&device->device, "cmd 0x%x scsi status 0x%x srb status 0x%x\n", stor_pkt->vm_srb.cdb[0], @@ -582,7 +592,8 @@ static void storvsc_on_io_completion(struct hv_device *device, if ((vstor_packet->vm_srb.scsi_status & 0xFF) == 0x02) { /* CHECK_CONDITION */ - if (vstor_packet->vm_srb.srb_status & 0x80) { + if (vstor_packet->vm_srb.srb_status & + SRB_STATUS_AUTOSENSE_VALID) { /* autosense data available */ dev_warn(&device->device, "stor pkt %p autosense data valid - len %d\n", @@ -1191,7 +1202,7 @@ static void storvsc_command_completion(struct hv_storvsc_request *request) * error recovery strategies would have already been * deployed on the host side. */ - if (vm_srb->srb_status == 0x4) + if (vm_srb->srb_status == SRB_STATUS_ERROR) scmnd->result = DID_TARGET_FAILURE << 16; else scmnd->result = vm_srb->scsi_status; @@ -1199,7 +1210,7 @@ static void storvsc_command_completion(struct hv_storvsc_request *request) /* * If the LUN is invalid; remove the device. */ - if (vm_srb->srb_status == 0x20) { + if (vm_srb->srb_status == SRB_STATUS_INVALID_LUN) { struct storvsc_device *stor_dev; struct hv_device *dev = host_dev->dev; struct Scsi_Host *host; -- cgit v1.2.3-70-g09d2 From 4b270c8b23722128adedb5694097aea367284ce1 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 12 Jan 2012 12:37:58 -0800 Subject: Staging: hv: storvsc: Cleanup storvsc_host_reset_handler() Cleanup storvsc_host_reset_handler() by getting rid of storvsc_host_reset(). Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc_drv.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 979f25b3385..8340387b378 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -1122,8 +1122,11 @@ static int storvsc_get_chs(struct scsi_device *sdev, struct block_device * bdev, return 0; } -static int storvsc_host_reset(struct hv_device *device) +static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd) { + struct hv_host_device *host_dev = shost_priv(scmnd->device->host); + struct hv_device *device = host_dev->dev; + struct storvsc_device *stor_device; struct hv_storvsc_request *request; struct vstor_packet *vstor_packet; @@ -1165,15 +1168,6 @@ static int storvsc_host_reset(struct hv_device *device) } -static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd) -{ - struct hv_host_device *host_dev = shost_priv(scmnd->device->host); - struct hv_device *dev = host_dev->dev; - - return storvsc_host_reset(dev); -} - - static void storvsc_command_completion(struct hv_storvsc_request *request) { struct storvsc_cmd_request *cmd_request = -- cgit v1.2.3-70-g09d2 From ddcbf65e484c3473d3e808718ddb6c8166822c4c Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 12 Jan 2012 12:37:59 -0800 Subject: Staging: hv: storvsc: Move and cleanup storvsc_remove() Relocate the storvsc_remove() function to a different location in the file and invoke scsi_host_put() only after all the cleanup. Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc_drv.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 8340387b378..e0e471cedca 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -1083,22 +1083,6 @@ static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl, return total_copied; } - -static int storvsc_remove(struct hv_device *dev) -{ - struct storvsc_device *stor_device = hv_get_drvdata(dev); - struct Scsi_Host *host = stor_device->host; - - scsi_remove_host(host); - - scsi_host_put(host); - - storvsc_dev_remove(dev); - - return 0; -} - - static int storvsc_get_chs(struct scsi_device *sdev, struct block_device * bdev, sector_t capacity, int *info) { @@ -1526,6 +1510,18 @@ err_out0: return ret; } +static int storvsc_remove(struct hv_device *dev) +{ + struct storvsc_device *stor_device = hv_get_drvdata(dev); + struct Scsi_Host *host = stor_device->host; + + scsi_remove_host(host); + storvsc_dev_remove(dev); + scsi_host_put(host); + + return 0; +} + static struct hv_driver storvsc_drv = { .name = KBUILD_MODNAME, .id_table = id_table, -- cgit v1.2.3-70-g09d2 From a8c18c573bf896f81dbcd68fdb81d81d4200dcad Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 12 Jan 2012 12:38:00 -0800 Subject: Staging: hv: storvsc: Add a comment to explain life-cycle management Add a comment to explain life-cycle management and fix format issue. Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc_drv.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index e0e471cedca..204b3ca5a19 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -375,6 +375,21 @@ done: kfree(wrk); } +/* + * We can get incoming messages from the host that are not in response to + * messages that we have sent out. An example of this would be messages + * received by the guest to notify dynamic addition/removal of LUNs. To + * deal with potential race conditions where the driver may be in the + * midst of being unloaded when we might receive an unsolicited message + * from the host, we have implemented a mechanism to gurantee sequential + * consistency: + * + * 1) Once the device is marked as being destroyed, we will fail all + * outgoing messages. + * 2) We permit incoming messages when the device is being destroyed, + * only to properly account for messages already sent out. + */ + static inline struct storvsc_device *get_out_stor_device( struct hv_device *device) { @@ -569,7 +584,7 @@ static void storvsc_on_io_completion(struct hv_device *device, */ if ((stor_pkt->vm_srb.cdb[0] == INQUIRY) || - (stor_pkt->vm_srb.cdb[0] == MODE_SENSE)) { + (stor_pkt->vm_srb.cdb[0] == MODE_SENSE)) { vstor_packet->vm_srb.scsi_status = 0; vstor_packet->vm_srb.srb_status = SRB_STATUS_SUCCESS; } -- cgit v1.2.3-70-g09d2 From 2707388c7c5c6edf4e646a9013f6b7aa195fb174 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 12 Jan 2012 12:38:01 -0800 Subject: Staging: hv: storvsc: Get rid of the on_io_completion in hv_storvsc_request Get rid of the on_io_completion field in struct hv_storvsc_request. As part of this relocate the bounce buffer handling code (to avoid having forward declarations). Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc_drv.c | 630 +++++++++++++++++++-------------------- 1 file changed, 313 insertions(+), 317 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 204b3ca5a19..7c9fa19c9e5 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -276,7 +276,6 @@ struct hv_storvsc_request { unsigned char *sense_buffer; void *context; - void (*on_io_completion)(struct hv_storvsc_request *request); struct hv_multipage_buffer data_buffer; struct vstor_packet vstor_packet; @@ -436,6 +435,227 @@ get_in_err: } +static void destroy_bounce_buffer(struct scatterlist *sgl, + unsigned int sg_count) +{ + int i; + struct page *page_buf; + + for (i = 0; i < sg_count; i++) { + page_buf = sg_page((&sgl[i])); + if (page_buf != NULL) + __free_page(page_buf); + } + + kfree(sgl); +} + +static int do_bounce_buffer(struct scatterlist *sgl, unsigned int sg_count) +{ + int i; + + /* No need to check */ + if (sg_count < 2) + return -1; + + /* We have at least 2 sg entries */ + for (i = 0; i < sg_count; i++) { + if (i == 0) { + /* make sure 1st one does not have hole */ + if (sgl[i].offset + sgl[i].length != PAGE_SIZE) + return i; + } else if (i == sg_count - 1) { + /* make sure last one does not have hole */ + if (sgl[i].offset != 0) + return i; + } else { + /* make sure no hole in the middle */ + if (sgl[i].length != PAGE_SIZE || sgl[i].offset != 0) + return i; + } + } + return -1; +} + +static struct scatterlist *create_bounce_buffer(struct scatterlist *sgl, + unsigned int sg_count, + unsigned int len, + int write) +{ + int i; + int num_pages; + struct scatterlist *bounce_sgl; + struct page *page_buf; + unsigned int buf_len = ((write == WRITE_TYPE) ? 0 : PAGE_SIZE); + + num_pages = ALIGN(len, PAGE_SIZE) >> PAGE_SHIFT; + + bounce_sgl = kcalloc(num_pages, sizeof(struct scatterlist), GFP_ATOMIC); + if (!bounce_sgl) + return NULL; + + for (i = 0; i < num_pages; i++) { + page_buf = alloc_page(GFP_ATOMIC); + if (!page_buf) + goto cleanup; + sg_set_page(&bounce_sgl[i], page_buf, buf_len, 0); + } + + return bounce_sgl; + +cleanup: + destroy_bounce_buffer(bounce_sgl, num_pages); + return NULL; +} + +/* Assume the original sgl has enough room */ +static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl, + struct scatterlist *bounce_sgl, + unsigned int orig_sgl_count, + unsigned int bounce_sgl_count) +{ + int i; + int j = 0; + unsigned long src, dest; + unsigned int srclen, destlen, copylen; + unsigned int total_copied = 0; + unsigned long bounce_addr = 0; + unsigned long dest_addr = 0; + unsigned long flags; + + local_irq_save(flags); + + for (i = 0; i < orig_sgl_count; i++) { + dest_addr = (unsigned long)kmap_atomic(sg_page((&orig_sgl[i])), + KM_IRQ0) + orig_sgl[i].offset; + dest = dest_addr; + destlen = orig_sgl[i].length; + + if (bounce_addr == 0) + bounce_addr = + (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), + KM_IRQ0); + + while (destlen) { + src = bounce_addr + bounce_sgl[j].offset; + srclen = bounce_sgl[j].length - bounce_sgl[j].offset; + + copylen = min(srclen, destlen); + memcpy((void *)dest, (void *)src, copylen); + + total_copied += copylen; + bounce_sgl[j].offset += copylen; + destlen -= copylen; + dest += copylen; + + if (bounce_sgl[j].offset == bounce_sgl[j].length) { + /* full */ + kunmap_atomic((void *)bounce_addr, KM_IRQ0); + j++; + + /* + * It is possible that the number of elements + * in the bounce buffer may not be equal to + * the number of elements in the original + * scatter list. Handle this correctly. + */ + + if (j == bounce_sgl_count) { + /* + * We are done; cleanup and return. + */ + kunmap_atomic((void *)(dest_addr - + orig_sgl[i].offset), + KM_IRQ0); + local_irq_restore(flags); + return total_copied; + } + + /* if we need to use another bounce buffer */ + if (destlen || i != orig_sgl_count - 1) + bounce_addr = + (unsigned long)kmap_atomic( + sg_page((&bounce_sgl[j])), KM_IRQ0); + } else if (destlen == 0 && i == orig_sgl_count - 1) { + /* unmap the last bounce that is < PAGE_SIZE */ + kunmap_atomic((void *)bounce_addr, KM_IRQ0); + } + } + + kunmap_atomic((void *)(dest_addr - orig_sgl[i].offset), + KM_IRQ0); + } + + local_irq_restore(flags); + + return total_copied; +} + +/* Assume the bounce_sgl has enough room ie using the create_bounce_buffer() */ +static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl, + struct scatterlist *bounce_sgl, + unsigned int orig_sgl_count) +{ + int i; + int j = 0; + unsigned long src, dest; + unsigned int srclen, destlen, copylen; + unsigned int total_copied = 0; + unsigned long bounce_addr = 0; + unsigned long src_addr = 0; + unsigned long flags; + + local_irq_save(flags); + + for (i = 0; i < orig_sgl_count; i++) { + src_addr = (unsigned long)kmap_atomic(sg_page((&orig_sgl[i])), + KM_IRQ0) + orig_sgl[i].offset; + src = src_addr; + srclen = orig_sgl[i].length; + + if (bounce_addr == 0) + bounce_addr = + (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), + KM_IRQ0); + + while (srclen) { + /* assume bounce offset always == 0 */ + dest = bounce_addr + bounce_sgl[j].length; + destlen = PAGE_SIZE - bounce_sgl[j].length; + + copylen = min(srclen, destlen); + memcpy((void *)dest, (void *)src, copylen); + + total_copied += copylen; + bounce_sgl[j].length += copylen; + srclen -= copylen; + src += copylen; + + if (bounce_sgl[j].length == PAGE_SIZE) { + /* full..move to next entry */ + kunmap_atomic((void *)bounce_addr, KM_IRQ0); + j++; + + /* if we need to use another bounce buffer */ + if (srclen || i != orig_sgl_count - 1) + bounce_addr = + (unsigned long)kmap_atomic( + sg_page((&bounce_sgl[j])), KM_IRQ0); + + } else if (srclen == 0 && i == orig_sgl_count - 1) { + /* unmap the last bounce that is < PAGE_SIZE */ + kunmap_atomic((void *)bounce_addr, KM_IRQ0); + } + } + + kunmap_atomic((void *)(src_addr - orig_sgl[i].offset), KM_IRQ0); + } + + local_irq_restore(flags); + + return total_copied; +} + static int storvsc_channel_init(struct hv_device *device) { struct storvsc_device *stor_device; @@ -562,24 +782,101 @@ cleanup: return ret; } -static void storvsc_on_io_completion(struct hv_device *device, - struct vstor_packet *vstor_packet, - struct hv_storvsc_request *request) + +static void storvsc_command_completion(struct hv_storvsc_request *request) { - struct storvsc_device *stor_device; - struct vstor_packet *stor_pkt; + struct storvsc_cmd_request *cmd_request = + (struct storvsc_cmd_request *)request->context; + struct scsi_cmnd *scmnd = cmd_request->cmd; + struct hv_host_device *host_dev = shost_priv(scmnd->device->host); + void (*scsi_done_fn)(struct scsi_cmnd *); + struct scsi_sense_hdr sense_hdr; + struct vmscsi_request *vm_srb; + struct storvsc_scan_work *wrk; + struct stor_mem_pools *memp = scmnd->device->hostdata; - stor_device = hv_get_drvdata(device); - stor_pkt = &request->vstor_packet; + vm_srb = &request->vstor_packet.vm_srb; + if (cmd_request->bounce_sgl_count) { + if (vm_srb->data_in == READ_TYPE) + copy_from_bounce_buffer(scsi_sglist(scmnd), + cmd_request->bounce_sgl, + scsi_sg_count(scmnd), + cmd_request->bounce_sgl_count); + destroy_bounce_buffer(cmd_request->bounce_sgl, + cmd_request->bounce_sgl_count); + } /* - * The current SCSI handling on the host side does - * not correctly handle: - * INQUIRY command with page code parameter set to 0x80 - * MODE_SENSE command with cmd[2] == 0x1c - * - * Setup srb and scsi status so this won't be fatal. - * We do this so we can distinguish truly fatal failues + * If there is an error; offline the device since all + * error recovery strategies would have already been + * deployed on the host side. + */ + if (vm_srb->srb_status == SRB_STATUS_ERROR) + scmnd->result = DID_TARGET_FAILURE << 16; + else + scmnd->result = vm_srb->scsi_status; + + /* + * If the LUN is invalid; remove the device. + */ + if (vm_srb->srb_status == SRB_STATUS_INVALID_LUN) { + struct storvsc_device *stor_dev; + struct hv_device *dev = host_dev->dev; + struct Scsi_Host *host; + + stor_dev = get_in_stor_device(dev); + host = stor_dev->host; + + wrk = kmalloc(sizeof(struct storvsc_scan_work), + GFP_ATOMIC); + if (!wrk) { + scmnd->result = DID_TARGET_FAILURE << 16; + } else { + wrk->host = host; + wrk->lun = vm_srb->lun; + INIT_WORK(&wrk->work, storvsc_remove_lun); + schedule_work(&wrk->work); + } + } + + if (scmnd->result) { + if (scsi_normalize_sense(scmnd->sense_buffer, + SCSI_SENSE_BUFFERSIZE, &sense_hdr)) + scsi_print_sense_hdr("storvsc", &sense_hdr); + } + + scsi_set_resid(scmnd, + request->data_buffer.len - + vm_srb->data_transfer_length); + + scsi_done_fn = scmnd->scsi_done; + + scmnd->host_scribble = NULL; + scmnd->scsi_done = NULL; + + scsi_done_fn(scmnd); + + mempool_free(cmd_request, memp->request_mempool); +} + +static void storvsc_on_io_completion(struct hv_device *device, + struct vstor_packet *vstor_packet, + struct hv_storvsc_request *request) +{ + struct storvsc_device *stor_device; + struct vstor_packet *stor_pkt; + + stor_device = hv_get_drvdata(device); + stor_pkt = &request->vstor_packet; + + /* + * The current SCSI handling on the host side does + * not correctly handle: + * INQUIRY command with page code parameter set to 0x80 + * MODE_SENSE command with cmd[2] == 0x1c + * + * Setup srb and scsi status so this won't be fatal. + * We do this so we can distinguish truly fatal failues * (srb status == 0x4) and off-line the device in that case. */ @@ -625,7 +922,7 @@ static void storvsc_on_io_completion(struct hv_device *device, stor_pkt->vm_srb.data_transfer_length = vstor_packet->vm_srb.data_transfer_length; - request->on_io_completion(request); + storvsc_command_completion(request); if (atomic_dec_and_test(&stor_device->num_outstanding_req) && stor_device->drain_notify) @@ -875,229 +1172,6 @@ static int storvsc_device_configure(struct scsi_device *sdevice) return 0; } -static void destroy_bounce_buffer(struct scatterlist *sgl, - unsigned int sg_count) -{ - int i; - struct page *page_buf; - - for (i = 0; i < sg_count; i++) { - page_buf = sg_page((&sgl[i])); - if (page_buf != NULL) - __free_page(page_buf); - } - - kfree(sgl); -} - -static int do_bounce_buffer(struct scatterlist *sgl, unsigned int sg_count) -{ - int i; - - /* No need to check */ - if (sg_count < 2) - return -1; - - /* We have at least 2 sg entries */ - for (i = 0; i < sg_count; i++) { - if (i == 0) { - /* make sure 1st one does not have hole */ - if (sgl[i].offset + sgl[i].length != PAGE_SIZE) - return i; - } else if (i == sg_count - 1) { - /* make sure last one does not have hole */ - if (sgl[i].offset != 0) - return i; - } else { - /* make sure no hole in the middle */ - if (sgl[i].length != PAGE_SIZE || sgl[i].offset != 0) - return i; - } - } - return -1; -} - -static struct scatterlist *create_bounce_buffer(struct scatterlist *sgl, - unsigned int sg_count, - unsigned int len, - int write) -{ - int i; - int num_pages; - struct scatterlist *bounce_sgl; - struct page *page_buf; - unsigned int buf_len = ((write == WRITE_TYPE) ? 0 : PAGE_SIZE); - - num_pages = ALIGN(len, PAGE_SIZE) >> PAGE_SHIFT; - - bounce_sgl = kcalloc(num_pages, sizeof(struct scatterlist), GFP_ATOMIC); - if (!bounce_sgl) - return NULL; - - for (i = 0; i < num_pages; i++) { - page_buf = alloc_page(GFP_ATOMIC); - if (!page_buf) - goto cleanup; - sg_set_page(&bounce_sgl[i], page_buf, buf_len, 0); - } - - return bounce_sgl; - -cleanup: - destroy_bounce_buffer(bounce_sgl, num_pages); - return NULL; -} - - -/* Assume the original sgl has enough room */ -static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl, - struct scatterlist *bounce_sgl, - unsigned int orig_sgl_count, - unsigned int bounce_sgl_count) -{ - int i; - int j = 0; - unsigned long src, dest; - unsigned int srclen, destlen, copylen; - unsigned int total_copied = 0; - unsigned long bounce_addr = 0; - unsigned long dest_addr = 0; - unsigned long flags; - - local_irq_save(flags); - - for (i = 0; i < orig_sgl_count; i++) { - dest_addr = (unsigned long)kmap_atomic(sg_page((&orig_sgl[i])), - KM_IRQ0) + orig_sgl[i].offset; - dest = dest_addr; - destlen = orig_sgl[i].length; - - if (bounce_addr == 0) - bounce_addr = - (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), - KM_IRQ0); - - while (destlen) { - src = bounce_addr + bounce_sgl[j].offset; - srclen = bounce_sgl[j].length - bounce_sgl[j].offset; - - copylen = min(srclen, destlen); - memcpy((void *)dest, (void *)src, copylen); - - total_copied += copylen; - bounce_sgl[j].offset += copylen; - destlen -= copylen; - dest += copylen; - - if (bounce_sgl[j].offset == bounce_sgl[j].length) { - /* full */ - kunmap_atomic((void *)bounce_addr, KM_IRQ0); - j++; - - /* - * It is possible that the number of elements - * in the bounce buffer may not be equal to - * the number of elements in the original - * scatter list. Handle this correctly. - */ - - if (j == bounce_sgl_count) { - /* - * We are done; cleanup and return. - */ - kunmap_atomic((void *)(dest_addr - - orig_sgl[i].offset), - KM_IRQ0); - local_irq_restore(flags); - return total_copied; - } - - /* if we need to use another bounce buffer */ - if (destlen || i != orig_sgl_count - 1) - bounce_addr = - (unsigned long)kmap_atomic( - sg_page((&bounce_sgl[j])), KM_IRQ0); - } else if (destlen == 0 && i == orig_sgl_count - 1) { - /* unmap the last bounce that is < PAGE_SIZE */ - kunmap_atomic((void *)bounce_addr, KM_IRQ0); - } - } - - kunmap_atomic((void *)(dest_addr - orig_sgl[i].offset), - KM_IRQ0); - } - - local_irq_restore(flags); - - return total_copied; -} - - -/* Assume the bounce_sgl has enough room ie using the create_bounce_buffer() */ -static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl, - struct scatterlist *bounce_sgl, - unsigned int orig_sgl_count) -{ - int i; - int j = 0; - unsigned long src, dest; - unsigned int srclen, destlen, copylen; - unsigned int total_copied = 0; - unsigned long bounce_addr = 0; - unsigned long src_addr = 0; - unsigned long flags; - - local_irq_save(flags); - - for (i = 0; i < orig_sgl_count; i++) { - src_addr = (unsigned long)kmap_atomic(sg_page((&orig_sgl[i])), - KM_IRQ0) + orig_sgl[i].offset; - src = src_addr; - srclen = orig_sgl[i].length; - - if (bounce_addr == 0) - bounce_addr = - (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), - KM_IRQ0); - - while (srclen) { - /* assume bounce offset always == 0 */ - dest = bounce_addr + bounce_sgl[j].length; - destlen = PAGE_SIZE - bounce_sgl[j].length; - - copylen = min(srclen, destlen); - memcpy((void *)dest, (void *)src, copylen); - - total_copied += copylen; - bounce_sgl[j].length += copylen; - srclen -= copylen; - src += copylen; - - if (bounce_sgl[j].length == PAGE_SIZE) { - /* full..move to next entry */ - kunmap_atomic((void *)bounce_addr, KM_IRQ0); - j++; - - /* if we need to use another bounce buffer */ - if (srclen || i != orig_sgl_count - 1) - bounce_addr = - (unsigned long)kmap_atomic( - sg_page((&bounce_sgl[j])), KM_IRQ0); - - } else if (srclen == 0 && i == orig_sgl_count - 1) { - /* unmap the last bounce that is < PAGE_SIZE */ - kunmap_atomic((void *)bounce_addr, KM_IRQ0); - } - } - - kunmap_atomic((void *)(src_addr - orig_sgl[i].offset), KM_IRQ0); - } - - local_irq_restore(flags); - - return total_copied; -} - static int storvsc_get_chs(struct scsi_device *sdev, struct block_device * bdev, sector_t capacity, int *info) { @@ -1166,83 +1240,6 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd) return SUCCESS; } - -static void storvsc_command_completion(struct hv_storvsc_request *request) -{ - struct storvsc_cmd_request *cmd_request = - (struct storvsc_cmd_request *)request->context; - struct scsi_cmnd *scmnd = cmd_request->cmd; - struct hv_host_device *host_dev = shost_priv(scmnd->device->host); - void (*scsi_done_fn)(struct scsi_cmnd *); - struct scsi_sense_hdr sense_hdr; - struct vmscsi_request *vm_srb; - struct storvsc_scan_work *wrk; - struct stor_mem_pools *memp = scmnd->device->hostdata; - - vm_srb = &request->vstor_packet.vm_srb; - if (cmd_request->bounce_sgl_count) { - if (vm_srb->data_in == READ_TYPE) - copy_from_bounce_buffer(scsi_sglist(scmnd), - cmd_request->bounce_sgl, - scsi_sg_count(scmnd), - cmd_request->bounce_sgl_count); - destroy_bounce_buffer(cmd_request->bounce_sgl, - cmd_request->bounce_sgl_count); - } - - /* - * If there is an error; offline the device since all - * error recovery strategies would have already been - * deployed on the host side. - */ - if (vm_srb->srb_status == SRB_STATUS_ERROR) - scmnd->result = DID_TARGET_FAILURE << 16; - else - scmnd->result = vm_srb->scsi_status; - - /* - * If the LUN is invalid; remove the device. - */ - if (vm_srb->srb_status == SRB_STATUS_INVALID_LUN) { - struct storvsc_device *stor_dev; - struct hv_device *dev = host_dev->dev; - struct Scsi_Host *host; - - stor_dev = get_in_stor_device(dev); - host = stor_dev->host; - - wrk = kmalloc(sizeof(struct storvsc_scan_work), - GFP_ATOMIC); - if (!wrk) { - scmnd->result = DID_TARGET_FAILURE << 16; - } else { - wrk->host = host; - wrk->lun = vm_srb->lun; - INIT_WORK(&wrk->work, storvsc_remove_lun); - schedule_work(&wrk->work); - } - } - - if (scmnd->result) { - if (scsi_normalize_sense(scmnd->sense_buffer, - SCSI_SENSE_BUFFERSIZE, &sense_hdr)) - scsi_print_sense_hdr("storvsc", &sense_hdr); - } - - scsi_set_resid(scmnd, - request->data_buffer.len - - vm_srb->data_transfer_length); - - scsi_done_fn = scmnd->scsi_done; - - scmnd->host_scribble = NULL; - scmnd->scsi_done = NULL; - - scsi_done_fn(scmnd); - - mempool_free(cmd_request, memp->request_mempool); -} - static bool storvsc_scsi_cmd_ok(struct scsi_cmnd *scmnd) { bool allowed = true; @@ -1318,7 +1315,6 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) break; } - request->on_io_completion = storvsc_command_completion; request->context = cmd_request;/* scmnd; */ vm_srb->port_number = host_dev->port; -- cgit v1.2.3-70-g09d2 From 93a1bf4dd018af2a4931b916dd46fdfb963fa4ad Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 12 Jan 2012 12:38:02 -0800 Subject: Staging: hv: storvsc: Rename the context field in hv_storvsc_request Rename the context field in hv_storvsc_request. As part of this change fix the type of this field. Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc_drv.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 7c9fa19c9e5..051570777c0 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -275,7 +275,7 @@ struct hv_storvsc_request { struct completion wait_event; unsigned char *sense_buffer; - void *context; + struct storvsc_cmd_request *cmd; struct hv_multipage_buffer data_buffer; struct vstor_packet vstor_packet; @@ -785,8 +785,7 @@ cleanup: static void storvsc_command_completion(struct hv_storvsc_request *request) { - struct storvsc_cmd_request *cmd_request = - (struct storvsc_cmd_request *)request->context; + struct storvsc_cmd_request *cmd_request = request->cmd; struct scsi_cmnd *scmnd = cmd_request->cmd; struct hv_host_device *host_dev = shost_priv(scmnd->device->host); void (*scsi_done_fn)(struct scsi_cmnd *); @@ -1315,7 +1314,7 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) break; } - request->context = cmd_request;/* scmnd; */ + request->cmd = cmd_request; vm_srb->port_number = host_dev->port; vm_srb->path_id = scmnd->device->channel; -- cgit v1.2.3-70-g09d2 From c649114a5d99eb10e58f977f82018b1d77191aa7 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 12 Jan 2012 12:38:03 -0800 Subject: Staging: hv: storvsc: Miscellaneous cleanup of storvsc driver Miscellaneous cleanup of storvsc driver - get rid of unnecessary defines and use fixed size types for structures used for communication with the host. Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc_drv.c | 94 +++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 051570777c0..da71294bf41 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -43,32 +43,18 @@ #include +/* + * We setup a mempool to allocate request structures for this driver + * on a per-lun basis. The following define specifies the number of + * elements in the pool. + */ + #define STORVSC_MIN_BUF_NR 64 -#define STORVSC_RING_BUFFER_SIZE (20*PAGE_SIZE) -static int storvsc_ringbuffer_size = STORVSC_RING_BUFFER_SIZE; +static int storvsc_ringbuffer_size = (20 * PAGE_SIZE); module_param(storvsc_ringbuffer_size, int, S_IRUGO); MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)"); -/* - * To alert the user that structure sizes may be mismatched even though the - * protocol versions match. - */ - - -#define REVISION_STRING(REVISION_) #REVISION_ -#define FILL_VMSTOR_REVISION(RESULT_LVALUE_) \ - do { \ - char *revision_string \ - = REVISION_STRING($Rev : 6 $) + 6; \ - RESULT_LVALUE_ = 0; \ - while (*revision_string >= '0' \ - && *revision_string <= '9') { \ - RESULT_LVALUE_ *= 10; \ - RESULT_LVALUE_ += *revision_string - '0'; \ - revision_string++; \ - } \ - } while (0) /* * Major/minor macros. Minor version is in LSB, meaning that earlier flat @@ -79,7 +65,6 @@ MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)"); #define VMSTOR_PROTOCOL_MINOR(VERSION_) (((VERSION_)) & 0xff) #define VMSTOR_PROTOCOL_VERSION(MAJOR_, MINOR_) ((((MAJOR_) & 0xff) << 8) | \ (((MINOR_) & 0xff))) -#define VMSTOR_INVALID_PROTOCOL_VERSION (-1) /* * Version history: @@ -136,26 +121,26 @@ enum vstor_packet_operation { #define MAX_DATA_BUF_LEN_WITH_PADDING 0x14 struct vmscsi_request { - unsigned short length; - unsigned char srb_status; - unsigned char scsi_status; + u16 length; + u8 srb_status; + u8 scsi_status; - unsigned char port_number; - unsigned char path_id; - unsigned char target_id; - unsigned char lun; + u8 port_number; + u8 path_id; + u8 target_id; + u8 lun; - unsigned char cdb_length; - unsigned char sense_info_length; - unsigned char data_in; - unsigned char reserved; + u8 cdb_length; + u8 sense_info_length; + u8 data_in; + u8 reserved; - unsigned int data_transfer_length; + u32 data_transfer_length; union { - unsigned char cdb[CDB16GENERIC_LENGTH]; - unsigned char sense_data[SENSE_BUFFER_SIZE]; - unsigned char reserved_array[MAX_DATA_BUF_LEN_WITH_PADDING]; + u8 cdb[CDB16GENERIC_LENGTH]; + u8 sense_data[SENSE_BUFFER_SIZE]; + u8 reserved_array[MAX_DATA_BUF_LEN_WITH_PADDING]; }; } __attribute((packed)); @@ -165,18 +150,21 @@ struct vmscsi_request { * properties of the channel. */ struct vmstorage_channel_properties { - unsigned short protocol_version; - unsigned char path_id; - unsigned char target_id; + u16 protocol_version; + u8 path_id; + u8 target_id; /* Note: port number is only really known on the client side */ - unsigned int port_number; - unsigned int flags; - unsigned int max_transfer_bytes; + u32 port_number; + u32 flags; + u32 max_transfer_bytes; - /* This id is unique for each channel and will correspond with */ - /* vendor specific data in the inquirydata */ - unsigned long long unique_id; + /* + * This id is unique for each channel and will correspond with + * vendor specific data in the inquiry data. + */ + + u64 unique_id; } __packed; /* This structure is sent during the storage protocol negotiations. */ @@ -189,6 +177,7 @@ struct vmstorage_protocol_version { * (See FILL_VMSTOR_REVISION macro above). Mismatch does not * definitely indicate incompatibility--but it does indicate mismatched * builds. + * This is only used on the windows side. Just set it to 0. */ unsigned short revision; } __packed; @@ -202,10 +191,10 @@ struct vstor_packet { enum vstor_packet_operation operation; /* Flags - see below for values */ - unsigned int flags; + u32 flags; /* Status of the request returned from the server side. */ - unsigned int status; + u32 status; /* Data payload area */ union { @@ -232,11 +221,6 @@ struct vstor_packet { #define REQUEST_COMPLETION_FLAG 0x1 -/* This is the set of flags that the vsc can set in any packets it sends */ -#define VSC_LEGAL_FLAGS (REQUEST_COMPLETION_FLAG) - - - #define STORVSC_MAX_IO_REQUESTS 128 /* @@ -252,7 +236,7 @@ struct vstor_packet { /* Matches Windows-end */ enum storvsc_request_type { - WRITE_TYPE, + WRITE_TYPE = 0, READ_TYPE, UNKNOWN_TYPE, }; @@ -704,7 +688,7 @@ static int storvsc_channel_init(struct hv_device *device) vstor_packet->flags = REQUEST_COMPLETION_FLAG; vstor_packet->version.major_minor = VMSTOR_PROTOCOL_VERSION_CURRENT; - FILL_VMSTOR_REVISION(vstor_packet->version.revision); + vstor_packet->version.revision = 0; ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), -- cgit v1.2.3-70-g09d2 From 85904a5e553f343243e5cf59f150174159e2e5ea Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 12 Jan 2012 12:38:04 -0800 Subject: Staging: hv: storvsc: Cleanup the code for generating protocol version Cleanup the code for generating protocol version. Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc_drv.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index da71294bf41..629edd17fd9 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -61,10 +61,13 @@ MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)"); * version numbers will be interpreted as "0.x" (i.e., 1 becomes 0.1). */ -#define VMSTOR_PROTOCOL_MAJOR(VERSION_) (((VERSION_) >> 8) & 0xff) -#define VMSTOR_PROTOCOL_MINOR(VERSION_) (((VERSION_)) & 0xff) -#define VMSTOR_PROTOCOL_VERSION(MAJOR_, MINOR_) ((((MAJOR_) & 0xff) << 8) | \ - (((MINOR_) & 0xff))) +static inline u16 storvsc_get_version(u8 major, u8 minor) +{ + u16 version; + + version = ((major << 8) | minor); + return version; +} /* * Version history: @@ -74,9 +77,8 @@ MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)"); * Win7: 4.2 */ -#define VMSTOR_PROTOCOL_VERSION_CURRENT VMSTOR_PROTOCOL_VERSION(4, 2) - - +#define VMSTOR_CURRENT_MAJOR 4 +#define VMSTOR_CURRENT_MINOR 2 /* @@ -170,7 +172,7 @@ struct vmstorage_channel_properties { /* This structure is sent during the storage protocol negotiations. */ struct vmstorage_protocol_version { /* Major (MSW) and minor (LSW) version numbers. */ - unsigned short major_minor; + u16 major_minor; /* * Revision number is auto-incremented whenever this file is changed @@ -179,7 +181,7 @@ struct vmstorage_protocol_version { * builds. * This is only used on the windows side. Just set it to 0. */ - unsigned short revision; + u16 revision; } __packed; /* Channel Property Flags */ @@ -687,7 +689,12 @@ static int storvsc_channel_init(struct hv_device *device) vstor_packet->operation = VSTOR_OPERATION_QUERY_PROTOCOL_VERSION; vstor_packet->flags = REQUEST_COMPLETION_FLAG; - vstor_packet->version.major_minor = VMSTOR_PROTOCOL_VERSION_CURRENT; + vstor_packet->version.major_minor = + storvsc_get_version(VMSTOR_CURRENT_MAJOR, VMSTOR_CURRENT_MINOR); + + /* + * The revision number is only used in Windows; set it to 0. + */ vstor_packet->version.revision = 0; ret = vmbus_sendpacket(device->channel, vstor_packet, -- cgit v1.2.3-70-g09d2 From 6b2f949559b26448cc6d161d62341281db42c909 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 12 Jan 2012 12:38:05 -0800 Subject: Staging: hv: storvsc: Cleanup some protocol related constants Cleanup some protocol related constants. Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc_drv.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 629edd17fd9..9f074580004 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -114,13 +114,9 @@ enum vstor_packet_operation { * this remains the same across the write regardless of 32/64 bit * note: it's patterned off the SCSI_PASS_THROUGH structure */ -#define CDB16GENERIC_LENGTH 0x10 - -#ifndef SENSE_BUFFER_SIZE -#define SENSE_BUFFER_SIZE 0x12 -#endif - -#define MAX_DATA_BUF_LEN_WITH_PADDING 0x14 +#define STORVSC_MAX_CMD_LEN 0x10 +#define STORVSC_SENSE_BUFFER_SIZE 0x12 +#define STORVSC_MAX_BUF_LEN_WITH_PADDING 0x14 struct vmscsi_request { u16 length; @@ -140,9 +136,9 @@ struct vmscsi_request { u32 data_transfer_length; union { - u8 cdb[CDB16GENERIC_LENGTH]; - u8 sense_data[SENSE_BUFFER_SIZE]; - u8 reserved_array[MAX_DATA_BUF_LEN_WITH_PADDING]; + u8 cdb[STORVSC_MAX_CMD_LEN]; + u8 sense_data[STORVSC_SENSE_BUFFER_SIZE]; + u8 reserved_array[STORVSC_MAX_BUF_LEN_WITH_PADDING]; }; } __attribute((packed)); @@ -234,7 +230,6 @@ struct vstor_packet { #define STORVSC_MAX_LUNS_PER_TARGET 64 #define STORVSC_MAX_TARGETS 1 #define STORVSC_MAX_CHANNELS 1 -#define STORVSC_MAX_CMD_LEN 16 /* Matches Windows-end */ enum storvsc_request_type { @@ -1074,7 +1069,7 @@ static int storvsc_do_io(struct hv_device *device, vstor_packet->vm_srb.length = sizeof(struct vmscsi_request); - vstor_packet->vm_srb.sense_info_length = SENSE_BUFFER_SIZE; + vstor_packet->vm_srb.sense_info_length = STORVSC_SENSE_BUFFER_SIZE; vstor_packet->vm_srb.data_transfer_length = -- cgit v1.2.3-70-g09d2 From 410c52ed66cabd1837a87b37348d92a17f01c199 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 12 Jan 2012 12:38:06 -0800 Subject: Staging: hv: storvsc: Get rid of some unused defines Get rid of some unused defines. Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc_drv.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 9f074580004..d34e3ca4b95 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -81,18 +81,6 @@ static inline u16 storvsc_get_version(u8 major, u8 minor) #define VMSTOR_CURRENT_MINOR 2 -/* - * This will get replaced with the max transfer length that is possible on - * the host adapter. - * The max transfer length will be published when we offer a vmbus channel. - */ - -#define MAX_TRANSFER_LENGTH 0x40000 -#define DEFAULT_PACKET_SIZE (sizeof(struct vmdata_gpa_direct) + \ - sizeof(struct vstor_packet) + \ - sizesizeof(u64) * (MAX_TRANSFER_LENGTH / PAGE_SIZE))) - - /* Packet structure describing virtual storage requests. */ enum vstor_packet_operation { VSTOR_OPERATION_COMPLETE_IO = 1, -- cgit v1.2.3-70-g09d2 From 61eaffc91d375e02bc12c2c831478841f5ce4757 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 12 Jan 2012 12:38:07 -0800 Subject: Staging: hv: storvsc: Consolidate the request structure Consolidate the request structure by getting rid of struct hv_storvsc_request. Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc_drv.c | 65 +++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index d34e3ca4b95..9ccc1c48bd3 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -236,17 +236,20 @@ enum storvsc_request_type { #define SRB_STATUS_ERROR 0x04 +struct storvsc_cmd_request { + struct list_head entry; + struct scsi_cmnd *cmd; + + unsigned int bounce_sgl_count; + struct scatterlist *bounce_sgl; -struct hv_storvsc_request { struct hv_device *device; /* Synchronize the request/response if needed */ struct completion wait_event; unsigned char *sense_buffer; - struct storvsc_cmd_request *cmd; struct hv_multipage_buffer data_buffer; - struct vstor_packet vstor_packet; }; @@ -272,8 +275,8 @@ struct storvsc_device { unsigned char target_id; /* Used for vsc/vsp channel reset process */ - struct hv_storvsc_request init_request; - struct hv_storvsc_request reset_request; + struct storvsc_cmd_request init_request; + struct storvsc_cmd_request reset_request; }; struct stor_mem_pools { @@ -288,16 +291,6 @@ struct hv_host_device { unsigned char target; }; -struct storvsc_cmd_request { - struct list_head entry; - struct scsi_cmnd *cmd; - - unsigned int bounce_sgl_count; - struct scatterlist *bounce_sgl; - - struct hv_storvsc_request request; -}; - struct storvsc_scan_work { struct work_struct work; struct Scsi_Host *host; @@ -628,7 +621,7 @@ static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl, static int storvsc_channel_init(struct hv_device *device) { struct storvsc_device *stor_device; - struct hv_storvsc_request *request; + struct storvsc_cmd_request *request; struct vstor_packet *vstor_packet; int ret, t; @@ -643,7 +636,7 @@ static int storvsc_channel_init(struct hv_device *device) * Now, initiate the vsc/vsp initialization protocol on the open * channel */ - memset(request, 0, sizeof(struct hv_storvsc_request)); + memset(request, 0, sizeof(struct storvsc_cmd_request)); init_completion(&request->wait_event); vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION; vstor_packet->flags = REQUEST_COMPLETION_FLAG; @@ -757,9 +750,8 @@ cleanup: } -static void storvsc_command_completion(struct hv_storvsc_request *request) +static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request) { - struct storvsc_cmd_request *cmd_request = request->cmd; struct scsi_cmnd *scmnd = cmd_request->cmd; struct hv_host_device *host_dev = shost_priv(scmnd->device->host); void (*scsi_done_fn)(struct scsi_cmnd *); @@ -768,7 +760,7 @@ static void storvsc_command_completion(struct hv_storvsc_request *request) struct storvsc_scan_work *wrk; struct stor_mem_pools *memp = scmnd->device->hostdata; - vm_srb = &request->vstor_packet.vm_srb; + vm_srb = &cmd_request->vstor_packet.vm_srb; if (cmd_request->bounce_sgl_count) { if (vm_srb->data_in == READ_TYPE) copy_from_bounce_buffer(scsi_sglist(scmnd), @@ -819,7 +811,7 @@ static void storvsc_command_completion(struct hv_storvsc_request *request) } scsi_set_resid(scmnd, - request->data_buffer.len - + cmd_request->data_buffer.len - vm_srb->data_transfer_length); scsi_done_fn = scmnd->scsi_done; @@ -834,7 +826,7 @@ static void storvsc_command_completion(struct hv_storvsc_request *request) static void storvsc_on_io_completion(struct hv_device *device, struct vstor_packet *vstor_packet, - struct hv_storvsc_request *request) + struct storvsc_cmd_request *request) { struct storvsc_device *stor_device; struct vstor_packet *stor_pkt; @@ -906,7 +898,7 @@ static void storvsc_on_io_completion(struct hv_device *device, static void storvsc_on_receive(struct hv_device *device, struct vstor_packet *vstor_packet, - struct hv_storvsc_request *request) + struct storvsc_cmd_request *request) { struct storvsc_scan_work *work; struct storvsc_device *stor_device; @@ -940,7 +932,7 @@ static void storvsc_on_channel_callback(void *context) u32 bytes_recvd; u64 request_id; unsigned char packet[ALIGN(sizeof(struct vstor_packet), 8)]; - struct hv_storvsc_request *request; + struct storvsc_cmd_request *request; int ret; @@ -954,7 +946,7 @@ static void storvsc_on_channel_callback(void *context) &bytes_recvd, &request_id); if (ret == 0 && bytes_recvd > 0) { - request = (struct hv_storvsc_request *) + request = (struct storvsc_cmd_request *) (unsigned long)request_id; if ((request == &stor_device->init_request) || @@ -1036,7 +1028,7 @@ static int storvsc_dev_remove(struct hv_device *device) } static int storvsc_do_io(struct hv_device *device, - struct hv_storvsc_request *request) + struct storvsc_cmd_request *request) { struct storvsc_device *stor_device; struct vstor_packet *vstor_packet; @@ -1174,7 +1166,7 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd) struct hv_device *device = host_dev->dev; struct storvsc_device *stor_device; - struct hv_storvsc_request *request; + struct storvsc_cmd_request *request; struct vstor_packet *vstor_packet; int ret, t; @@ -1238,7 +1230,6 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) int ret; struct hv_host_device *host_dev = shost_priv(host); struct hv_device *dev = host_dev->dev; - struct hv_storvsc_request *request; struct storvsc_cmd_request *cmd_request; unsigned int request_size = 0; int i; @@ -1271,8 +1262,7 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) scmnd->host_scribble = (unsigned char *)cmd_request; - request = &cmd_request->request; - vm_srb = &request->vstor_packet.vm_srb; + vm_srb = &cmd_request->vstor_packet.vm_srb; /* Build the SRB */ @@ -1288,7 +1278,6 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) break; } - request->cmd = cmd_request; vm_srb->port_number = host_dev->port; vm_srb->path_id = scmnd->device->channel; @@ -1299,10 +1288,10 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) memcpy(vm_srb->cdb, scmnd->cmnd, vm_srb->cdb_length); - request->sense_buffer = scmnd->sense_buffer; + cmd_request->sense_buffer = scmnd->sense_buffer; - request->data_buffer.len = scsi_bufflen(scmnd); + cmd_request->data_buffer.len = scsi_bufflen(scmnd); if (scsi_sg_count(scmnd)) { sgl = (struct scatterlist *)scsi_sglist(scmnd); sg_count = scsi_sg_count(scmnd); @@ -1331,21 +1320,21 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) sg_count = cmd_request->bounce_sgl_count; } - request->data_buffer.offset = sgl[0].offset; + cmd_request->data_buffer.offset = sgl[0].offset; for (i = 0; i < sg_count; i++) - request->data_buffer.pfn_array[i] = + cmd_request->data_buffer.pfn_array[i] = page_to_pfn(sg_page((&sgl[i]))); } else if (scsi_sglist(scmnd)) { - request->data_buffer.offset = + cmd_request->data_buffer.offset = virt_to_phys(scsi_sglist(scmnd)) & (PAGE_SIZE-1); - request->data_buffer.pfn_array[0] = + cmd_request->data_buffer.pfn_array[0] = virt_to_phys(scsi_sglist(scmnd)) >> PAGE_SHIFT; } /* Invokes the vsc to start an IO */ - ret = storvsc_do_io(dev, &cmd_request->request); + ret = storvsc_do_io(dev, cmd_request); if (ret == -EAGAIN) { /* no more space */ -- cgit v1.2.3-70-g09d2 From af9584b82df77751710db45043cf8d7d7740056d Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 12 Jan 2012 12:38:08 -0800 Subject: Staging: hv: storvsc: Consolidate all the wire protocol definitions Consolidate all definitions that support communication with the host. Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc_drv.c | 83 +++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 9ccc1c48bd3..695ffc36e02 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -42,33 +42,13 @@ #include #include - -/* - * We setup a mempool to allocate request structures for this driver - * on a per-lun basis. The following define specifies the number of - * elements in the pool. - */ - -#define STORVSC_MIN_BUF_NR 64 -static int storvsc_ringbuffer_size = (20 * PAGE_SIZE); - -module_param(storvsc_ringbuffer_size, int, S_IRUGO); -MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)"); - - /* - * Major/minor macros. Minor version is in LSB, meaning that earlier flat - * version numbers will be interpreted as "0.x" (i.e., 1 becomes 0.1). + * All wire protocol details (storage protocol between the guest and the host) + * are consolidated here. + * + * Begin protocol definitions. */ -static inline u16 storvsc_get_version(u8 major, u8 minor) -{ - u16 version; - - version = ((major << 8) | minor); - return version; -} - /* * Version history: * V1 Beta: 0.1 @@ -207,18 +187,6 @@ struct vstor_packet { #define REQUEST_COMPLETION_FLAG 0x1 -#define STORVSC_MAX_IO_REQUESTS 128 - -/* - * In Hyper-V, each port/path/target maps to 1 scsi host adapter. In - * reality, the path/target is not used (ie always set to 0) so our - * scsi host adapter essentially has 1 bus with 1 target that contains - * up to 256 luns. - */ -#define STORVSC_MAX_LUNS_PER_TARGET 64 -#define STORVSC_MAX_TARGETS 1 -#define STORVSC_MAX_CHANNELS 1 - /* Matches Windows-end */ enum storvsc_request_type { WRITE_TYPE = 0, @@ -235,6 +203,36 @@ enum storvsc_request_type { #define SRB_STATUS_SUCCESS 0x01 #define SRB_STATUS_ERROR 0x04 +/* + * This is the end of Protocol specific defines. + */ + + +/* + * We setup a mempool to allocate request structures for this driver + * on a per-lun basis. The following define specifies the number of + * elements in the pool. + */ + +#define STORVSC_MIN_BUF_NR 64 +static int storvsc_ringbuffer_size = (20 * PAGE_SIZE); + +module_param(storvsc_ringbuffer_size, int, S_IRUGO); +MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)"); + +#define STORVSC_MAX_IO_REQUESTS 128 + +/* + * In Hyper-V, each port/path/target maps to 1 scsi host adapter. In + * reality, the path/target is not used (ie always set to 0) so our + * scsi host adapter essentially has 1 bus with 1 target that contains + * up to 256 luns. + */ +#define STORVSC_MAX_LUNS_PER_TARGET 64 +#define STORVSC_MAX_TARGETS 1 +#define STORVSC_MAX_CHANNELS 1 + + struct storvsc_cmd_request { struct list_head entry; @@ -336,6 +334,19 @@ done: kfree(wrk); } +/* + * Major/minor macros. Minor version is in LSB, meaning that earlier flat + * version numbers will be interpreted as "0.x" (i.e., 1 becomes 0.1). + */ + +static inline u16 storvsc_get_version(u8 major, u8 minor) +{ + u16 version; + + version = ((major << 8) | minor); + return version; +} + /* * We can get incoming messages from the host that are not in response to * messages that we have sent out. An example of this would be messages -- cgit v1.2.3-70-g09d2 From 17dd9f831a3c70588d54cc3a24594f274f9ec3a1 Mon Sep 17 00:00:00 2001 From: Seth Jennings Date: Tue, 3 Jan 2012 16:31:34 -0600 Subject: staging: zcache: crypto API support This patch allow zcache to use the crypto API for page compression. It replaces the direct LZO compress/decompress calls with calls into the crypto compression API. The compressor to be used is specified in the kernel boot line with the zcache parameter like: zcache=lzo or zcache=deflate. If the specified compressor can't be loaded, zcache uses lzo as the default compressor. Signed-off-by: Seth Jennings Acked-by: Dan Magenheimer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zcache/Kconfig | 7 +- drivers/staging/zcache/zcache-main.c | 150 ++++++++++++++++++++++++++++------- 2 files changed, 126 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zcache/Kconfig b/drivers/staging/zcache/Kconfig index 7fabcb2bc80..1b7bba7b1a3 100644 --- a/drivers/staging/zcache/Kconfig +++ b/drivers/staging/zcache/Kconfig @@ -1,13 +1,12 @@ config ZCACHE tristate "Dynamic compression of swap pages and clean pagecache pages" - depends on CLEANCACHE || FRONTSWAP + depends on (CLEANCACHE || FRONTSWAP) && CRYPTO select XVMALLOC - select LZO_COMPRESS - select LZO_DECOMPRESS + select CRYPTO_LZO default n help Zcache doubles RAM efficiency while providing a significant - performance boosts on many workloads. Zcache uses lzo1x + performance boosts on many workloads. Zcache uses compression and an in-kernel implementation of transcendent memory to store clean page cache pages and swap in RAM, providing a noticeable reduction in disk I/O. diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index 642840c612a..da222c28a12 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c @@ -6,7 +6,8 @@ * * Zcache provides an in-kernel "host implementation" for transcendent memory * and, thus indirectly, for cleancache and frontswap. Zcache includes two - * page-accessible memory [1] interfaces, both utilizing lzo1x compression: + * page-accessible memory [1] interfaces, both utilizing the crypto compression + * API: * 1) "compression buddies" ("zbud") is used for ephemeral pages * 2) xvmalloc is used for persistent pages. * Xvmalloc (based on the TLSF allocator) has very low fragmentation @@ -23,12 +24,13 @@ #include #include #include -#include #include #include #include #include #include +#include +#include #include "tmem.h" #include "../zram/xvmalloc.h" /* if built in drivers/staging */ @@ -81,6 +83,38 @@ static inline bool is_local_client(struct zcache_client *cli) return cli == &zcache_host; } +/* crypto API for zcache */ +#define ZCACHE_COMP_NAME_SZ CRYPTO_MAX_ALG_NAME +static char zcache_comp_name[ZCACHE_COMP_NAME_SZ]; +static struct crypto_comp * __percpu *zcache_comp_pcpu_tfms; + +enum comp_op { + ZCACHE_COMPOP_COMPRESS, + ZCACHE_COMPOP_DECOMPRESS +}; + +static inline int zcache_comp_op(enum comp_op op, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) +{ + struct crypto_comp *tfm; + int ret; + + BUG_ON(!zcache_comp_pcpu_tfms); + tfm = *per_cpu_ptr(zcache_comp_pcpu_tfms, get_cpu()); + BUG_ON(!tfm); + switch (op) { + case ZCACHE_COMPOP_COMPRESS: + ret = crypto_comp_compress(tfm, src, slen, dst, dlen); + break; + case ZCACHE_COMPOP_DECOMPRESS: + ret = crypto_comp_decompress(tfm, src, slen, dst, dlen); + break; + } + put_cpu(); + return ret; +} + /********** * Compression buddies ("zbud") provides for packing two (or, possibly * in the future, more) compressed ephemeral pages into a single "raw" @@ -408,7 +442,7 @@ static int zbud_decompress(struct page *page, struct zbud_hdr *zh) { struct zbud_page *zbpg; unsigned budnum = zbud_budnum(zh); - size_t out_len = PAGE_SIZE; + unsigned int out_len = PAGE_SIZE; char *to_va, *from_va; unsigned size; int ret = 0; @@ -425,8 +459,9 @@ static int zbud_decompress(struct page *page, struct zbud_hdr *zh) to_va = kmap_atomic(page, KM_USER0); size = zh->size; from_va = zbud_data(zh, size); - ret = lzo1x_decompress_safe(from_va, size, to_va, &out_len); - BUG_ON(ret != LZO_E_OK); + ret = zcache_comp_op(ZCACHE_COMPOP_DECOMPRESS, from_va, size, + to_va, &out_len); + BUG_ON(ret); BUG_ON(out_len != PAGE_SIZE); kunmap_atomic(to_va, KM_USER0); out: @@ -624,7 +659,7 @@ static int zbud_show_cumul_chunk_counts(char *buf) /********** * This "zv" PAM implementation combines the TLSF-based xvMalloc - * with lzo1x compression to maximize the amount of data that can + * with the crypto compression API to maximize the amount of data that can * be packed into a physical page. * * Zv represents a PAM page with the index and object (plus a "size" value @@ -711,7 +746,7 @@ static void zv_free(struct xv_pool *xvpool, struct zv_hdr *zv) static void zv_decompress(struct page *page, struct zv_hdr *zv) { - size_t clen = PAGE_SIZE; + unsigned int clen = PAGE_SIZE; char *to_va; unsigned size; int ret; @@ -720,10 +755,10 @@ static void zv_decompress(struct page *page, struct zv_hdr *zv) size = xv_get_object_size(zv) - sizeof(*zv); BUG_ON(size == 0); to_va = kmap_atomic(page, KM_USER0); - ret = lzo1x_decompress_safe((char *)zv + sizeof(*zv), - size, to_va, &clen); + ret = zcache_comp_op(ZCACHE_COMPOP_DECOMPRESS, (char *)zv + sizeof(*zv), + size, to_va, &clen); kunmap_atomic(to_va, KM_USER0); - BUG_ON(ret != LZO_E_OK); + BUG_ON(ret); BUG_ON(clen != PAGE_SIZE); } @@ -1286,25 +1321,24 @@ static struct tmem_pamops zcache_pamops = { * zcache compression/decompression and related per-cpu stuff */ -#define LZO_WORKMEM_BYTES LZO1X_1_MEM_COMPRESS -#define LZO_DSTMEM_PAGE_ORDER 1 -static DEFINE_PER_CPU(unsigned char *, zcache_workmem); static DEFINE_PER_CPU(unsigned char *, zcache_dstmem); +#define ZCACHE_DSTMEM_ORDER 1 static int zcache_compress(struct page *from, void **out_va, size_t *out_len) { int ret = 0; unsigned char *dmem = __get_cpu_var(zcache_dstmem); - unsigned char *wmem = __get_cpu_var(zcache_workmem); char *from_va; BUG_ON(!irqs_disabled()); - if (unlikely(dmem == NULL || wmem == NULL)) - goto out; /* no buffer, so can't compress */ + if (unlikely(dmem == NULL)) + goto out; /* no buffer or no compressor so can't compress */ + *out_len = PAGE_SIZE << ZCACHE_DSTMEM_ORDER; from_va = kmap_atomic(from, KM_USER0); mb(); - ret = lzo1x_1_compress(from_va, PAGE_SIZE, dmem, out_len, wmem); - BUG_ON(ret != LZO_E_OK); + ret = zcache_comp_op(ZCACHE_COMPOP_COMPRESS, from_va, PAGE_SIZE, dmem, + (unsigned int *)out_len); + BUG_ON(ret); *out_va = dmem; kunmap_atomic(from_va, KM_USER0); ret = 1; @@ -1312,29 +1346,48 @@ out: return ret; } +static int zcache_comp_cpu_up(int cpu) +{ + struct crypto_comp *tfm; + + tfm = crypto_alloc_comp(zcache_comp_name, 0, 0); + if (IS_ERR(tfm)) + return NOTIFY_BAD; + *per_cpu_ptr(zcache_comp_pcpu_tfms, cpu) = tfm; + return NOTIFY_OK; +} + +static void zcache_comp_cpu_down(int cpu) +{ + struct crypto_comp *tfm; + + tfm = *per_cpu_ptr(zcache_comp_pcpu_tfms, cpu); + crypto_free_comp(tfm); + *per_cpu_ptr(zcache_comp_pcpu_tfms, cpu) = NULL; +} static int zcache_cpu_notifier(struct notifier_block *nb, unsigned long action, void *pcpu) { - int cpu = (long)pcpu; + int ret, cpu = (long)pcpu; struct zcache_preload *kp; switch (action) { case CPU_UP_PREPARE: + ret = zcache_comp_cpu_up(cpu); + if (ret != NOTIFY_OK) { + pr_err("zcache: can't allocate compressor transform\n"); + return ret; + } per_cpu(zcache_dstmem, cpu) = (void *)__get_free_pages( - GFP_KERNEL | __GFP_REPEAT, - LZO_DSTMEM_PAGE_ORDER), - per_cpu(zcache_workmem, cpu) = - kzalloc(LZO1X_MEM_COMPRESS, - GFP_KERNEL | __GFP_REPEAT); + GFP_KERNEL | __GFP_REPEAT, ZCACHE_DSTMEM_ORDER); break; case CPU_DEAD: case CPU_UP_CANCELED: + zcache_comp_cpu_down(cpu); free_pages((unsigned long)per_cpu(zcache_dstmem, cpu), - LZO_DSTMEM_PAGE_ORDER); + ZCACHE_DSTMEM_ORDER); per_cpu(zcache_dstmem, cpu) = NULL; - kfree(per_cpu(zcache_workmem, cpu)); - per_cpu(zcache_workmem, cpu) = NULL; kp = &per_cpu(zcache_preloads, cpu); while (kp->nr) { kmem_cache_free(zcache_objnode_cache, @@ -1919,6 +1972,44 @@ static int __init no_frontswap(char *s) __setup("nofrontswap", no_frontswap); +static int __init enable_zcache_compressor(char *s) +{ + strncpy(zcache_comp_name, s, ZCACHE_COMP_NAME_SZ); + zcache_enabled = 1; + return 1; +} +__setup("zcache=", enable_zcache_compressor); + + +static int zcache_comp_init(void) +{ + int ret = 0; + + /* check crypto algorithm */ + if (*zcache_comp_name != '\0') { + ret = crypto_has_comp(zcache_comp_name, 0, 0); + if (!ret) + pr_info("zcache: %s not supported\n", + zcache_comp_name); + } + if (!ret) + strcpy(zcache_comp_name, "lzo"); + ret = crypto_has_comp(zcache_comp_name, 0, 0); + if (!ret) { + ret = 1; + goto out; + } + pr_info("zcache: using %s compressor\n", zcache_comp_name); + + /* alloc percpu transforms */ + ret = 0; + zcache_comp_pcpu_tfms = alloc_percpu(struct crypto_comp *); + if (!zcache_comp_pcpu_tfms) + ret = 1; +out: + return ret; +} + static int __init zcache_init(void) { int ret = 0; @@ -1941,6 +2032,11 @@ static int __init zcache_init(void) pr_err("zcache: can't register cpu notifier\n"); goto out; } + ret = zcache_comp_init(); + if (ret) { + pr_err("zcache: compressor initialization failed\n"); + goto out; + } for_each_online_cpu(cpu) { void *pcpu = (void *)(long)cpu; zcache_cpu_notifier(&zcache_cpu_notifier_block, -- cgit v1.2.3-70-g09d2 From 61989a80fb3ac9d7837d03053624d5ea034a0d02 Mon Sep 17 00:00:00 2001 From: Nitin Gupta Date: Mon, 9 Jan 2012 16:51:56 -0600 Subject: staging: zsmalloc: zsmalloc memory allocation library This patch creates a new memory allocation library named zsmalloc. NOTE: zsmalloc currently depends on SPARSEMEM for the MAX_PHYSMEM_BITS value needed to determine the format of the object handle. There may be a better way to do this. Feedback is welcome. Signed-off-by: Nitin Gupta Signed-off-by: Seth Jennings Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zsmalloc/Kconfig | 11 + drivers/staging/zsmalloc/Makefile | 3 + drivers/staging/zsmalloc/zsmalloc-main.c | 756 +++++++++++++++++++++++++++++++ drivers/staging/zsmalloc/zsmalloc.h | 31 ++ drivers/staging/zsmalloc/zsmalloc_int.h | 126 ++++++ 5 files changed, 927 insertions(+) create mode 100644 drivers/staging/zsmalloc/Kconfig create mode 100644 drivers/staging/zsmalloc/Makefile create mode 100644 drivers/staging/zsmalloc/zsmalloc-main.c create mode 100644 drivers/staging/zsmalloc/zsmalloc.h create mode 100644 drivers/staging/zsmalloc/zsmalloc_int.h (limited to 'drivers') diff --git a/drivers/staging/zsmalloc/Kconfig b/drivers/staging/zsmalloc/Kconfig new file mode 100644 index 00000000000..3e7a8d4d217 --- /dev/null +++ b/drivers/staging/zsmalloc/Kconfig @@ -0,0 +1,11 @@ +config ZSMALLOC + tristate "Memory allocator for compressed pages" + depends on SPARSEMEM + default n + help + zsmalloc is a slab-based memory allocator designed to store + compressed RAM pages. zsmalloc uses virtual memory mapping + in order to reduce fragmentation. However, this results in a + non-standard allocator interface where a handle, not a pointer, is + returned by an alloc(). This handle must be mapped in order to + access the allocated space. diff --git a/drivers/staging/zsmalloc/Makefile b/drivers/staging/zsmalloc/Makefile new file mode 100644 index 00000000000..b134848a590 --- /dev/null +++ b/drivers/staging/zsmalloc/Makefile @@ -0,0 +1,3 @@ +zsmalloc-y := zsmalloc-main.o + +obj-$(CONFIG_ZSMALLOC) += zsmalloc.o diff --git a/drivers/staging/zsmalloc/zsmalloc-main.c b/drivers/staging/zsmalloc/zsmalloc-main.c new file mode 100644 index 00000000000..189fb42313b --- /dev/null +++ b/drivers/staging/zsmalloc/zsmalloc-main.c @@ -0,0 +1,756 @@ +/* + * zsmalloc memory allocator + * + * Copyright (C) 2011 Nitin Gupta + * + * This code is released using a dual license strategy: BSD/GPL + * You can choose the license that better fits your requirements. + * + * Released under the terms of 3-clause BSD License + * Released under the terms of GNU General Public License Version 2.0 + */ + +#ifdef CONFIG_ZSMALLOC_DEBUG +#define DEBUG +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "zsmalloc.h" +#include "zsmalloc_int.h" + +/* + * A zspage's class index and fullness group + * are encoded in its (first)page->mapping + */ +#define CLASS_IDX_BITS 28 +#define FULLNESS_BITS 4 +#define CLASS_IDX_MASK ((1 << CLASS_IDX_BITS) - 1) +#define FULLNESS_MASK ((1 << FULLNESS_BITS) - 1) + +/* + * Object location (, ) is encoded as + * as single (void *) handle value. + * + * Note that object index is relative to system + * page it is stored in, so for each sub-page belonging + * to a zspage, obj_idx starts with 0. + */ +#define _PFN_BITS (MAX_PHYSMEM_BITS - PAGE_SHIFT) +#define OBJ_INDEX_BITS (BITS_PER_LONG - _PFN_BITS) +#define OBJ_INDEX_MASK ((_AC(1, UL) << OBJ_INDEX_BITS) - 1) + +/* per-cpu VM mapping areas for zspage accesses that cross page boundaries */ +static DEFINE_PER_CPU(struct mapping_area, zs_map_area); + +static int is_first_page(struct page *page) +{ + return test_bit(PG_private, &page->flags); +} + +static int is_last_page(struct page *page) +{ + return test_bit(PG_private_2, &page->flags); +} + +static void get_zspage_mapping(struct page *page, unsigned int *class_idx, + enum fullness_group *fullness) +{ + unsigned long m; + BUG_ON(!is_first_page(page)); + + m = (unsigned long)page->mapping; + *fullness = m & FULLNESS_MASK; + *class_idx = (m >> FULLNESS_BITS) & CLASS_IDX_MASK; +} + +static void set_zspage_mapping(struct page *page, unsigned int class_idx, + enum fullness_group fullness) +{ + unsigned long m; + BUG_ON(!is_first_page(page)); + + m = ((class_idx & CLASS_IDX_MASK) << FULLNESS_BITS) | + (fullness & FULLNESS_MASK); + page->mapping = (struct address_space *)m; +} + +static int get_size_class_index(int size) +{ + int idx = 0; + + if (likely(size > ZS_MIN_ALLOC_SIZE)) + idx = DIV_ROUND_UP(size - ZS_MIN_ALLOC_SIZE, + ZS_SIZE_CLASS_DELTA); + + return idx; +} + +static enum fullness_group get_fullness_group(struct page *page) +{ + int inuse, max_objects; + enum fullness_group fg; + BUG_ON(!is_first_page(page)); + + inuse = page->inuse; + max_objects = page->objects; + + if (inuse == 0) + fg = ZS_EMPTY; + else if (inuse == max_objects) + fg = ZS_FULL; + else if (inuse <= max_objects / fullness_threshold_frac) + fg = ZS_ALMOST_EMPTY; + else + fg = ZS_ALMOST_FULL; + + return fg; +} + +static void insert_zspage(struct page *page, struct size_class *class, + enum fullness_group fullness) +{ + struct page **head; + + BUG_ON(!is_first_page(page)); + + if (fullness >= _ZS_NR_FULLNESS_GROUPS) + return; + + head = &class->fullness_list[fullness]; + if (*head) + list_add_tail(&page->lru, &(*head)->lru); + + *head = page; +} + +static void remove_zspage(struct page *page, struct size_class *class, + enum fullness_group fullness) +{ + struct page **head; + + BUG_ON(!is_first_page(page)); + + if (fullness >= _ZS_NR_FULLNESS_GROUPS) + return; + + head = &class->fullness_list[fullness]; + BUG_ON(!*head); + if (list_empty(&(*head)->lru)) + *head = NULL; + else if (*head == page) + *head = (struct page *)list_entry((*head)->lru.next, + struct page, lru); + + list_del_init(&page->lru); +} + +static enum fullness_group fix_fullness_group(struct zs_pool *pool, + struct page *page) +{ + int class_idx; + struct size_class *class; + enum fullness_group currfg, newfg; + + BUG_ON(!is_first_page(page)); + + get_zspage_mapping(page, &class_idx, &currfg); + newfg = get_fullness_group(page); + if (newfg == currfg) + goto out; + + class = &pool->size_class[class_idx]; + remove_zspage(page, class, currfg); + insert_zspage(page, class, newfg); + set_zspage_mapping(page, class_idx, newfg); + +out: + return newfg; +} + +/* + * We have to decide on how many pages to link together + * to form a zspage for each size class. This is important + * to reduce wastage due to unusable space left at end of + * each zspage which is given as: + * wastage = Zp - Zp % size_class + * where Zp = zspage size = k * PAGE_SIZE where k = 1, 2, ... + * + * For example, for size class of 3/8 * PAGE_SIZE, we should + * link together 3 PAGE_SIZE sized pages to form a zspage + * since then we can perfectly fit in 8 such objects. + */ +static int get_zspage_order(int class_size) +{ + int i, max_usedpc = 0; + /* zspage order which gives maximum used size per KB */ + int max_usedpc_order = 1; + + for (i = 1; i <= max_zspage_order; i++) { + int zspage_size; + int waste, usedpc; + + zspage_size = i * PAGE_SIZE; + waste = zspage_size % class_size; + usedpc = (zspage_size - waste) * 100 / zspage_size; + + if (usedpc > max_usedpc) { + max_usedpc = usedpc; + max_usedpc_order = i; + } + } + + return max_usedpc_order; +} + +/* + * A single 'zspage' is composed of many system pages which are + * linked together using fields in struct page. This function finds + * the first/head page, given any component page of a zspage. + */ +static struct page *get_first_page(struct page *page) +{ + if (is_first_page(page)) + return page; + else + return page->first_page; +} + +static struct page *get_next_page(struct page *page) +{ + struct page *next; + + if (is_last_page(page)) + next = NULL; + else if (is_first_page(page)) + next = (struct page *)page->private; + else + next = list_entry(page->lru.next, struct page, lru); + + return next; +} + +/* Encode as a single handle value */ +static void *obj_location_to_handle(struct page *page, unsigned long obj_idx) +{ + unsigned long handle; + + if (!page) { + BUG_ON(obj_idx); + return NULL; + } + + handle = page_to_pfn(page) << OBJ_INDEX_BITS; + handle |= (obj_idx & OBJ_INDEX_MASK); + + return (void *)handle; +} + +/* Decode pair from the given object handle */ +static void obj_handle_to_location(void *handle, struct page **page, + unsigned long *obj_idx) +{ + unsigned long hval = (unsigned long)handle; + + *page = pfn_to_page(hval >> OBJ_INDEX_BITS); + *obj_idx = hval & OBJ_INDEX_MASK; +} + +static unsigned long obj_idx_to_offset(struct page *page, + unsigned long obj_idx, int class_size) +{ + unsigned long off = 0; + + if (!is_first_page(page)) + off = page->index; + + return off + obj_idx * class_size; +} + +static void free_zspage(struct page *first_page) +{ + struct page *nextp, *tmp; + + BUG_ON(!is_first_page(first_page)); + BUG_ON(first_page->inuse); + + nextp = (struct page *)page_private(first_page); + + clear_bit(PG_private, &first_page->flags); + clear_bit(PG_private_2, &first_page->flags); + set_page_private(first_page, 0); + first_page->mapping = NULL; + first_page->freelist = NULL; + reset_page_mapcount(first_page); + __free_page(first_page); + + /* zspage with only 1 system page */ + if (!nextp) + return; + + list_for_each_entry_safe(nextp, tmp, &nextp->lru, lru) { + list_del(&nextp->lru); + clear_bit(PG_private_2, &nextp->flags); + nextp->index = 0; + __free_page(nextp); + } +} + +/* Initialize a newly allocated zspage */ +static void init_zspage(struct page *first_page, struct size_class *class) +{ + unsigned long off = 0; + struct page *page = first_page; + + BUG_ON(!is_first_page(first_page)); + while (page) { + struct page *next_page; + struct link_free *link; + unsigned int i, objs_on_page; + + /* + * page->index stores offset of first object starting + * in the page. For the first page, this is always 0, + * so we use first_page->index (aka ->freelist) to store + * head of corresponding zspage's freelist. + */ + if (page != first_page) + page->index = off; + + link = (struct link_free *)kmap_atomic(page) + + off / sizeof(*link); + objs_on_page = (PAGE_SIZE - off) / class->size; + + for (i = 1; i <= objs_on_page; i++) { + off += class->size; + if (off < PAGE_SIZE) { + link->next = obj_location_to_handle(page, i); + link += class->size / sizeof(*link); + } + } + + /* + * We now come to the last (full or partial) object on this + * page, which must point to the first object on the next + * page (if present) + */ + next_page = get_next_page(page); + link->next = obj_location_to_handle(next_page, 0); + kunmap_atomic(link); + page = next_page; + off = (off + class->size) % PAGE_SIZE; + } +} + +/* + * Allocate a zspage for the given size class + */ +static struct page *alloc_zspage(struct size_class *class, gfp_t flags) +{ + int i, error; + struct page *first_page = NULL; + + /* + * Allocate individual pages and link them together as: + * 1. first page->private = first sub-page + * 2. all sub-pages are linked together using page->lru + * 3. each sub-page is linked to the first page using page->first_page + * + * For each size class, First/Head pages are linked together using + * page->lru. Also, we set PG_private to identify the first page + * (i.e. no other sub-page has this flag set) and PG_private_2 to + * identify the last page. + */ + error = -ENOMEM; + for (i = 0; i < class->zspage_order; i++) { + struct page *page, *prev_page; + + page = alloc_page(flags); + if (!page) + goto cleanup; + + INIT_LIST_HEAD(&page->lru); + if (i == 0) { /* first page */ + set_bit(PG_private, &page->flags); + set_page_private(page, 0); + first_page = page; + first_page->inuse = 0; + } + if (i == 1) + first_page->private = (unsigned long)page; + if (i >= 1) + page->first_page = first_page; + if (i >= 2) + list_add(&page->lru, &prev_page->lru); + if (i == class->zspage_order - 1) /* last page */ + set_bit(PG_private_2, &page->flags); + + prev_page = page; + } + + init_zspage(first_page, class); + + first_page->freelist = obj_location_to_handle(first_page, 0); + /* Maximum number of objects we can store in this zspage */ + first_page->objects = class->zspage_order * PAGE_SIZE / class->size; + + error = 0; /* Success */ + +cleanup: + if (unlikely(error) && first_page) { + free_zspage(first_page); + first_page = NULL; + } + + return first_page; +} + +static struct page *find_get_zspage(struct size_class *class) +{ + int i; + struct page *page; + + for (i = 0; i < _ZS_NR_FULLNESS_GROUPS; i++) { + page = class->fullness_list[i]; + if (page) + break; + } + + return page; +} + + +/* + * If this becomes a separate module, register zs_init() with + * module_init(), zs_exit with module_exit(), and remove zs_initialized +*/ +static int zs_initialized; + +static int zs_cpu_notifier(struct notifier_block *nb, unsigned long action, + void *pcpu) +{ + int cpu = (long)pcpu; + struct mapping_area *area; + + switch (action) { + case CPU_UP_PREPARE: + area = &per_cpu(zs_map_area, cpu); + if (area->vm) + break; + area->vm = alloc_vm_area(2 * PAGE_SIZE, area->vm_ptes); + if (!area->vm) + return notifier_from_errno(-ENOMEM); + break; + case CPU_DEAD: + case CPU_UP_CANCELED: + area = &per_cpu(zs_map_area, cpu); + if (area->vm) + free_vm_area(area->vm); + area->vm = NULL; + break; + } + + return NOTIFY_OK; +} + +static struct notifier_block zs_cpu_nb = { + .notifier_call = zs_cpu_notifier +}; + +static void zs_exit(void) +{ + int cpu; + + for_each_online_cpu(cpu) + zs_cpu_notifier(NULL, CPU_DEAD, (void *)(long)cpu); + unregister_cpu_notifier(&zs_cpu_nb); +} + +static int zs_init(void) +{ + int cpu, ret; + + register_cpu_notifier(&zs_cpu_nb); + for_each_online_cpu(cpu) { + ret = zs_cpu_notifier(NULL, CPU_UP_PREPARE, (void *)(long)cpu); + if (notifier_to_errno(ret)) + goto fail; + } + return 0; +fail: + zs_exit(); + return notifier_to_errno(ret); +} + +struct zs_pool *zs_create_pool(const char *name, gfp_t flags) +{ + int i, error, ovhd_size; + struct zs_pool *pool; + + if (!name) + return NULL; + + ovhd_size = roundup(sizeof(*pool), PAGE_SIZE); + pool = kzalloc(ovhd_size, GFP_KERNEL); + if (!pool) + return NULL; + + for (i = 0; i < ZS_SIZE_CLASSES; i++) { + int size; + struct size_class *class; + + size = ZS_MIN_ALLOC_SIZE + i * ZS_SIZE_CLASS_DELTA; + if (size > ZS_MAX_ALLOC_SIZE) + size = ZS_MAX_ALLOC_SIZE; + + class = &pool->size_class[i]; + class->size = size; + class->index = i; + spin_lock_init(&class->lock); + class->zspage_order = get_zspage_order(size); + + } + + /* + * If this becomes a separate module, register zs_init with + * module_init, and remove this block + */ + if (!zs_initialized) { + error = zs_init(); + if (error) + goto cleanup; + zs_initialized = 1; + } + + pool->flags = flags; + pool->name = name; + + error = 0; /* Success */ + +cleanup: + if (error) { + zs_destroy_pool(pool); + pool = NULL; + } + + return pool; +} +EXPORT_SYMBOL_GPL(zs_create_pool); + +void zs_destroy_pool(struct zs_pool *pool) +{ + int i; + + for (i = 0; i < ZS_SIZE_CLASSES; i++) { + int fg; + struct size_class *class = &pool->size_class[i]; + + for (fg = 0; fg < _ZS_NR_FULLNESS_GROUPS; fg++) { + if (class->fullness_list[fg]) { + pr_info("Freeing non-empty class with size " + "%db, fullness group %d\n", + class->size, fg); + } + } + } + kfree(pool); +} +EXPORT_SYMBOL_GPL(zs_destroy_pool); + +/** + * zs_malloc - Allocate block of given size from pool. + * @pool: pool to allocate from + * @size: size of block to allocate + * @page: page no. that holds the object + * @offset: location of object within page + * + * On success, identifies block allocated + * and 0 is returned. On failure, is set to + * 0 and -ENOMEM is returned. + * + * Allocation requests with size > ZS_MAX_ALLOC_SIZE will fail. + */ +void *zs_malloc(struct zs_pool *pool, size_t size) +{ + void *obj; + struct link_free *link; + int class_idx; + struct size_class *class; + + struct page *first_page, *m_page; + unsigned long m_objidx, m_offset; + + if (unlikely(!size || size > ZS_MAX_ALLOC_SIZE)) + return NULL; + + class_idx = get_size_class_index(size); + class = &pool->size_class[class_idx]; + BUG_ON(class_idx != class->index); + + spin_lock(&class->lock); + first_page = find_get_zspage(class); + + if (!first_page) { + spin_unlock(&class->lock); + first_page = alloc_zspage(class, pool->flags); + if (unlikely(!first_page)) + return NULL; + + set_zspage_mapping(first_page, class->index, ZS_EMPTY); + spin_lock(&class->lock); + class->pages_allocated += class->zspage_order; + } + + obj = first_page->freelist; + obj_handle_to_location(obj, &m_page, &m_objidx); + m_offset = obj_idx_to_offset(m_page, m_objidx, class->size); + + link = (struct link_free *)kmap_atomic(m_page) + + m_offset / sizeof(*link); + first_page->freelist = link->next; + memset(link, POISON_INUSE, sizeof(*link)); + kunmap_atomic(link); + + first_page->inuse++; + /* Now move the zspage to another fullness group, if required */ + fix_fullness_group(pool, first_page); + spin_unlock(&class->lock); + + return obj; +} +EXPORT_SYMBOL_GPL(zs_malloc); + +void zs_free(struct zs_pool *pool, void *obj) +{ + struct link_free *link; + struct page *first_page, *f_page; + unsigned long f_objidx, f_offset; + + int class_idx; + struct size_class *class; + enum fullness_group fullness; + + if (unlikely(!obj)) + return; + + obj_handle_to_location(obj, &f_page, &f_objidx); + first_page = get_first_page(f_page); + + get_zspage_mapping(first_page, &class_idx, &fullness); + class = &pool->size_class[class_idx]; + f_offset = obj_idx_to_offset(f_page, f_objidx, class->size); + + spin_lock(&class->lock); + + /* Insert this object in containing zspage's freelist */ + link = (struct link_free *)((unsigned char *)kmap_atomic(f_page) + + f_offset); + link->next = first_page->freelist; + kunmap_atomic(link); + first_page->freelist = obj; + + first_page->inuse--; + fullness = fix_fullness_group(pool, first_page); + + if (fullness == ZS_EMPTY) + class->pages_allocated -= class->zspage_order; + + spin_unlock(&class->lock); + + if (fullness == ZS_EMPTY) + free_zspage(first_page); +} +EXPORT_SYMBOL_GPL(zs_free); + +void *zs_map_object(struct zs_pool *pool, void *handle) +{ + struct page *page; + unsigned long obj_idx, off; + + unsigned int class_idx; + enum fullness_group fg; + struct size_class *class; + struct mapping_area *area; + + BUG_ON(!handle); + + obj_handle_to_location(handle, &page, &obj_idx); + get_zspage_mapping(get_first_page(page), &class_idx, &fg); + class = &pool->size_class[class_idx]; + off = obj_idx_to_offset(page, obj_idx, class->size); + + area = &get_cpu_var(zs_map_area); + if (off + class->size <= PAGE_SIZE) { + /* this object is contained entirely within a page */ + area->vm_addr = kmap_atomic(page); + } else { + /* this object spans two pages */ + struct page *nextp; + + nextp = get_next_page(page); + BUG_ON(!nextp); + + + set_pte(area->vm_ptes[0], mk_pte(page, PAGE_KERNEL)); + set_pte(area->vm_ptes[1], mk_pte(nextp, PAGE_KERNEL)); + + /* We pre-allocated VM area so mapping can never fail */ + area->vm_addr = area->vm->addr; + } + + return area->vm_addr + off; +} +EXPORT_SYMBOL_GPL(zs_map_object); + +void zs_unmap_object(struct zs_pool *pool, void *handle) +{ + struct page *page; + unsigned long obj_idx, off; + + unsigned int class_idx; + enum fullness_group fg; + struct size_class *class; + struct mapping_area *area; + + BUG_ON(!handle); + + obj_handle_to_location(handle, &page, &obj_idx); + get_zspage_mapping(get_first_page(page), &class_idx, &fg); + class = &pool->size_class[class_idx]; + off = obj_idx_to_offset(page, obj_idx, class->size); + + area = &__get_cpu_var(zs_map_area); + if (off + class->size <= PAGE_SIZE) { + kunmap_atomic(area->vm_addr); + } else { + set_pte(area->vm_ptes[0], __pte(0)); + set_pte(area->vm_ptes[1], __pte(0)); + __flush_tlb_one((unsigned long)area->vm_addr); + __flush_tlb_one((unsigned long)area->vm_addr + PAGE_SIZE); + } + put_cpu_var(zs_map_area); +} +EXPORT_SYMBOL_GPL(zs_unmap_object); + +u64 zs_get_total_size_bytes(struct zs_pool *pool) +{ + int i; + u64 npages = 0; + + for (i = 0; i < ZS_SIZE_CLASSES; i++) + npages += pool->size_class[i].pages_allocated; + + return npages << PAGE_SHIFT; +} +EXPORT_SYMBOL_GPL(zs_get_total_size_bytes); diff --git a/drivers/staging/zsmalloc/zsmalloc.h b/drivers/staging/zsmalloc/zsmalloc.h new file mode 100644 index 00000000000..949384ee749 --- /dev/null +++ b/drivers/staging/zsmalloc/zsmalloc.h @@ -0,0 +1,31 @@ +/* + * zsmalloc memory allocator + * + * Copyright (C) 2011 Nitin Gupta + * + * This code is released using a dual license strategy: BSD/GPL + * You can choose the license that better fits your requirements. + * + * Released under the terms of 3-clause BSD License + * Released under the terms of GNU General Public License Version 2.0 + */ + +#ifndef _ZS_MALLOC_H_ +#define _ZS_MALLOC_H_ + +#include + +struct zs_pool; + +struct zs_pool *zs_create_pool(const char *name, gfp_t flags); +void zs_destroy_pool(struct zs_pool *pool); + +void *zs_malloc(struct zs_pool *pool, size_t size); +void zs_free(struct zs_pool *pool, void *obj); + +void *zs_map_object(struct zs_pool *pool, void *handle); +void zs_unmap_object(struct zs_pool *pool, void *handle); + +u64 zs_get_total_size_bytes(struct zs_pool *pool); + +#endif diff --git a/drivers/staging/zsmalloc/zsmalloc_int.h b/drivers/staging/zsmalloc/zsmalloc_int.h new file mode 100644 index 00000000000..354a0200143 --- /dev/null +++ b/drivers/staging/zsmalloc/zsmalloc_int.h @@ -0,0 +1,126 @@ +/* + * zsmalloc memory allocator + * + * Copyright (C) 2011 Nitin Gupta + * + * This code is released using a dual license strategy: BSD/GPL + * You can choose the license that better fits your requirements. + * + * Released under the terms of 3-clause BSD License + * Released under the terms of GNU General Public License Version 2.0 + */ + +#ifndef _ZS_MALLOC_INT_H_ +#define _ZS_MALLOC_INT_H_ + +#include +#include +#include + +/* + * This must be power of 2 and greater than of equal to sizeof(link_free). + * These two conditions ensure that any 'struct link_free' itself doesn't + * span more than 1 page which avoids complex case of mapping 2 pages simply + * to restore link_free pointer values. + */ +#define ZS_ALIGN 8 + +/* ZS_MIN_ALLOC_SIZE must be multiple of ZS_ALIGN */ +#define ZS_MIN_ALLOC_SIZE 32 +#define ZS_MAX_ALLOC_SIZE PAGE_SIZE + +/* + * On systems with 4K page size, this gives 254 size classes! There is a + * trader-off here: + * - Large number of size classes is potentially wasteful as free page are + * spread across these classes + * - Small number of size classes causes large internal fragmentation + * - Probably its better to use specific size classes (empirically + * determined). NOTE: all those class sizes must be set as multiple of + * ZS_ALIGN to make sure link_free itself never has to span 2 pages. + * + * ZS_MIN_ALLOC_SIZE and ZS_SIZE_CLASS_DELTA must be multiple of ZS_ALIGN + * (reason above) + */ +#define ZS_SIZE_CLASS_DELTA 16 +#define ZS_SIZE_CLASSES ((ZS_MAX_ALLOC_SIZE - ZS_MIN_ALLOC_SIZE) / \ + ZS_SIZE_CLASS_DELTA + 1) + +/* + * A single 'zspage' is composed of N discontiguous 0-order (single) pages. + * This defines upper limit on N. + */ +static const int max_zspage_order = 4; + +/* + * We do not maintain any list for completely empty or full pages + */ +enum fullness_group { + ZS_ALMOST_FULL, + ZS_ALMOST_EMPTY, + _ZS_NR_FULLNESS_GROUPS, + + ZS_EMPTY, + ZS_FULL +}; + +/* + * We assign a page to ZS_ALMOST_EMPTY fullness group when: + * n <= N / f, where + * n = number of allocated objects + * N = total number of objects zspage can store + * f = 1/fullness_threshold_frac + * + * Similarly, we assign zspage to: + * ZS_ALMOST_FULL when n > N / f + * ZS_EMPTY when n == 0 + * ZS_FULL when n == N + * + * (see: fix_fullness_group()) + */ +static const int fullness_threshold_frac = 4; + +struct mapping_area { + struct vm_struct *vm; + pte_t *vm_ptes[2]; + char *vm_addr; +}; + +struct size_class { + /* + * Size of objects stored in this class. Must be multiple + * of ZS_ALIGN. + */ + int size; + unsigned int index; + + /* Number of PAGE_SIZE sized pages to combine to form a 'zspage' */ + int zspage_order; + + spinlock_t lock; + + /* stats */ + u64 pages_allocated; + + struct page *fullness_list[_ZS_NR_FULLNESS_GROUPS]; +}; + +/* + * Placed within free objects to form a singly linked list. + * For every zspage, first_page->freelist gives head of this list. + * + * This must be power of 2 and less than or equal to ZS_ALIGN + */ +struct link_free { + /* Handle of next free chunk (encodes ) */ + void *next; +}; + +struct zs_pool { + struct size_class size_class[ZS_SIZE_CLASSES]; + + gfp_t flags; /* allocation flags used when growing pool */ + const char *name; +}; + +#endif -- cgit v1.2.3-70-g09d2 From 94add674a78c379fe352eacb5137ed77ccb0a979 Mon Sep 17 00:00:00 2001 From: Seth Jennings Date: Mon, 9 Jan 2012 16:51:57 -0600 Subject: staging: add zsmalloc to Kconfig/Makefile Adds the new zsmalloc library to the staging Kconfig and Makefile Signed-off-by: Seth Jennings Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 ++ drivers/staging/Makefile | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 76a4c4a4717..783bc0a9121 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -90,6 +90,8 @@ source "drivers/staging/zram/Kconfig" source "drivers/staging/zcache/Kconfig" +source "drivers/staging/zsmalloc/Kconfig" + source "drivers/staging/wlags49_h2/Kconfig" source "drivers/staging/wlags49_h25/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index c061be8419c..4fa1e5e5b8e 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_IIO) += iio/ obj-$(CONFIG_ZRAM) += zram/ obj-$(CONFIG_XVMALLOC) += zram/ obj-$(CONFIG_ZCACHE) += zcache/ +obj-$(CONFIG_ZSMALLOC) += zsmalloc/ obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/ obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/ obj-$(CONFIG_FB_SM7XX) += sm7xx/ -- cgit v1.2.3-70-g09d2 From fd1a30dea194002c061503af8425688dcc6f3970 Mon Sep 17 00:00:00 2001 From: Nitin Gupta Date: Mon, 9 Jan 2012 16:51:59 -0600 Subject: staging: zram: replace xvmalloc with zsmalloc Replaces xvmalloc with zsmalloc as the compressed page allocator for zram Signed-off-by: Nitin Gupta Acked-by: Seth Jennings Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zram/Kconfig | 6 +-- drivers/staging/zram/Makefile | 1 - drivers/staging/zram/zram_drv.c | 89 +++++++++++++++++---------------------- drivers/staging/zram/zram_drv.h | 10 ++--- drivers/staging/zram/zram_sysfs.c | 2 +- 5 files changed, 46 insertions(+), 62 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zram/Kconfig b/drivers/staging/zram/Kconfig index 3bec4dba3fe..ee23a86ea7d 100644 --- a/drivers/staging/zram/Kconfig +++ b/drivers/staging/zram/Kconfig @@ -1,11 +1,7 @@ -config XVMALLOC - bool - default n - config ZRAM tristate "Compressed RAM block device support" depends on BLOCK && SYSFS - select XVMALLOC + select ZSMALLOC select LZO_COMPRESS select LZO_DECOMPRESS default n diff --git a/drivers/staging/zram/Makefile b/drivers/staging/zram/Makefile index 2a6d3213a75..7f4a3019e9c 100644 --- a/drivers/staging/zram/Makefile +++ b/drivers/staging/zram/Makefile @@ -1,4 +1,3 @@ zram-y := zram_drv.o zram_sysfs.o obj-$(CONFIG_ZRAM) += zram.o -obj-$(CONFIG_XVMALLOC) += xvmalloc.o \ No newline at end of file diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index 2a2a92d389e..5833156d228 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c @@ -135,13 +135,9 @@ static void zram_set_disksize(struct zram *zram, size_t totalram_bytes) static void zram_free_page(struct zram *zram, size_t index) { - u32 clen; - void *obj; + void *handle = zram->table[index].handle; - struct page *page = zram->table[index].page; - u32 offset = zram->table[index].offset; - - if (unlikely(!page)) { + if (unlikely(!handle)) { /* * No memory is allocated for zero filled pages. * Simply clear zero page flag. @@ -154,27 +150,24 @@ static void zram_free_page(struct zram *zram, size_t index) } if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) { - clen = PAGE_SIZE; - __free_page(page); + __free_page(handle); zram_clear_flag(zram, index, ZRAM_UNCOMPRESSED); zram_stat_dec(&zram->stats.pages_expand); goto out; } - obj = kmap_atomic(page, KM_USER0) + offset; - clen = xv_get_object_size(obj) - sizeof(struct zobj_header); - kunmap_atomic(obj, KM_USER0); + zs_free(zram->mem_pool, handle); - xv_free(zram->mem_pool, page, offset); - if (clen <= PAGE_SIZE / 2) + if (zram->table[index].size <= PAGE_SIZE / 2) zram_stat_dec(&zram->stats.good_compress); out: - zram_stat64_sub(zram, &zram->stats.compr_size, clen); + zram_stat64_sub(zram, &zram->stats.compr_size, + zram->table[index].size); zram_stat_dec(&zram->stats.pages_stored); - zram->table[index].page = NULL; - zram->table[index].offset = 0; + zram->table[index].handle = NULL; + zram->table[index].size = 0; } static void handle_zero_page(struct bio_vec *bvec) @@ -196,7 +189,7 @@ static void handle_uncompressed_page(struct zram *zram, struct bio_vec *bvec, unsigned char *user_mem, *cmem; user_mem = kmap_atomic(page, KM_USER0); - cmem = kmap_atomic(zram->table[index].page, KM_USER1); + cmem = kmap_atomic(zram->table[index].handle, KM_USER1); memcpy(user_mem + bvec->bv_offset, cmem + offset, bvec->bv_len); kunmap_atomic(cmem, KM_USER1); @@ -227,7 +220,7 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, } /* Requested page is not present in compressed area */ - if (unlikely(!zram->table[index].page)) { + if (unlikely(!zram->table[index].handle)) { pr_debug("Read before write: sector=%lu, size=%u", (ulong)(bio->bi_sector), bio->bi_size); handle_zero_page(bvec); @@ -254,11 +247,10 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, uncmem = user_mem; clen = PAGE_SIZE; - cmem = kmap_atomic(zram->table[index].page, KM_USER1) + - zram->table[index].offset; + cmem = zs_map_object(zram->mem_pool, zram->table[index].handle); ret = lzo1x_decompress_safe(cmem + sizeof(*zheader), - xv_get_object_size(cmem) - sizeof(*zheader), + zram->table[index].size, uncmem, &clen); if (is_partial_io(bvec)) { @@ -267,7 +259,7 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, kfree(uncmem); } - kunmap_atomic(cmem, KM_USER1); + zs_unmap_object(zram->mem_pool, zram->table[index].handle); kunmap_atomic(user_mem, KM_USER0); /* Should NEVER happen. Return bio error if it does. */ @@ -290,13 +282,12 @@ static int zram_read_before_write(struct zram *zram, char *mem, u32 index) unsigned char *cmem; if (zram_test_flag(zram, index, ZRAM_ZERO) || - !zram->table[index].page) { + !zram->table[index].handle) { memset(mem, 0, PAGE_SIZE); return 0; } - cmem = kmap_atomic(zram->table[index].page, KM_USER0) + - zram->table[index].offset; + cmem = zs_map_object(zram->mem_pool, zram->table[index].handle); /* Page is stored uncompressed since it's incompressible */ if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) { @@ -306,9 +297,9 @@ static int zram_read_before_write(struct zram *zram, char *mem, u32 index) } ret = lzo1x_decompress_safe(cmem + sizeof(*zheader), - xv_get_object_size(cmem) - sizeof(*zheader), + zram->table[index].size, mem, &clen); - kunmap_atomic(cmem, KM_USER0); + zs_unmap_object(zram->mem_pool, zram->table[index].handle); /* Should NEVER happen. Return bio error if it does. */ if (unlikely(ret != LZO_E_OK)) { @@ -326,6 +317,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, int ret; u32 store_offset; size_t clen; + void *handle; struct zobj_header *zheader; struct page *page, *page_store; unsigned char *user_mem, *cmem, *src, *uncmem = NULL; @@ -355,7 +347,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, * System overwrites unused sectors. Free memory associated * with this sector now. */ - if (zram->table[index].page || + if (zram->table[index].handle || zram_test_flag(zram, index, ZRAM_ZERO)) zram_free_page(zram, index); @@ -407,26 +399,22 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, store_offset = 0; zram_set_flag(zram, index, ZRAM_UNCOMPRESSED); zram_stat_inc(&zram->stats.pages_expand); - zram->table[index].page = page_store; + handle = page_store; src = kmap_atomic(page, KM_USER0); + cmem = kmap_atomic(page_store, KM_USER1); goto memstore; } - if (xv_malloc(zram->mem_pool, clen + sizeof(*zheader), - &zram->table[index].page, &store_offset, - GFP_NOIO | __GFP_HIGHMEM)) { + handle = zs_malloc(zram->mem_pool, clen + sizeof(*zheader)); + if (!handle) { pr_info("Error allocating memory for compressed " "page: %u, size=%zu\n", index, clen); ret = -ENOMEM; goto out; } + cmem = zs_map_object(zram->mem_pool, handle); memstore: - zram->table[index].offset = store_offset; - - cmem = kmap_atomic(zram->table[index].page, KM_USER1) + - zram->table[index].offset; - #if 0 /* Back-reference needed for memory defragmentation */ if (!zram_test_flag(zram, index, ZRAM_UNCOMPRESSED)) { @@ -438,9 +426,15 @@ memstore: memcpy(cmem, src, clen); - kunmap_atomic(cmem, KM_USER1); - if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) + if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) { + kunmap_atomic(cmem, KM_USER1); kunmap_atomic(src, KM_USER0); + } else { + zs_unmap_object(zram->mem_pool, handle); + } + + zram->table[index].handle = handle; + zram->table[index].size = clen; /* Update stats */ zram_stat64_add(zram, &zram->stats.compr_size, clen); @@ -598,25 +592,20 @@ void __zram_reset_device(struct zram *zram) /* Free all pages that are still in this zram device */ for (index = 0; index < zram->disksize >> PAGE_SHIFT; index++) { - struct page *page; - u16 offset; - - page = zram->table[index].page; - offset = zram->table[index].offset; - - if (!page) + void *handle = zram->table[index].handle; + if (!handle) continue; if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) - __free_page(page); + __free_page(handle); else - xv_free(zram->mem_pool, page, offset); + zs_free(zram->mem_pool, handle); } vfree(zram->table); zram->table = NULL; - xv_destroy_pool(zram->mem_pool); + zs_destroy_pool(zram->mem_pool); zram->mem_pool = NULL; /* Reset stats */ @@ -674,7 +663,7 @@ int zram_init_device(struct zram *zram) /* zram devices sort of resembles non-rotational disks */ queue_flag_set_unlocked(QUEUE_FLAG_NONROT, zram->disk->queue); - zram->mem_pool = xv_create_pool(); + zram->mem_pool = zs_create_pool("zram", GFP_NOIO | __GFP_HIGHMEM); if (!zram->mem_pool) { pr_err("Error creating memory pool\n"); ret = -ENOMEM; diff --git a/drivers/staging/zram/zram_drv.h b/drivers/staging/zram/zram_drv.h index e5cd2469b6a..572faa8762b 100644 --- a/drivers/staging/zram/zram_drv.h +++ b/drivers/staging/zram/zram_drv.h @@ -18,7 +18,7 @@ #include #include -#include "xvmalloc.h" +#include "../zsmalloc/zsmalloc.h" /* * Some arbitrary value. This is just to catch @@ -51,7 +51,7 @@ static const size_t max_zpage_size = PAGE_SIZE / 4 * 3; /* * NOTE: max_zpage_size must be less than or equal to: - * XV_MAX_ALLOC_SIZE - sizeof(struct zobj_header) + * ZS_MAX_ALLOC_SIZE - sizeof(struct zobj_header) * otherwise, xv_malloc() would always return failure. */ @@ -81,8 +81,8 @@ enum zram_pageflags { /* Allocated for each disk page */ struct table { - struct page *page; - u16 offset; + void *handle; + u16 size; /* object size (excluding header) */ u8 count; /* object ref count (not yet used) */ u8 flags; } __attribute__((aligned(4))); @@ -102,7 +102,7 @@ struct zram_stats { }; struct zram { - struct xv_pool *mem_pool; + struct zs_pool *mem_pool; void *compress_workmem; void *compress_buffer; struct table *table; diff --git a/drivers/staging/zram/zram_sysfs.c b/drivers/staging/zram/zram_sysfs.c index d521122826f..d2875c5690e 100644 --- a/drivers/staging/zram/zram_sysfs.c +++ b/drivers/staging/zram/zram_sysfs.c @@ -187,7 +187,7 @@ static ssize_t mem_used_total_show(struct device *dev, struct zram *zram = dev_to_zram(dev); if (zram->init_done) { - val = xv_get_total_size_bytes(zram->mem_pool) + + val = zs_get_total_size_bytes(zram->mem_pool) + ((u64)(zram->stats.pages_expand) << PAGE_SHIFT); } -- cgit v1.2.3-70-g09d2 From b154ff05e1b0d749231a71896c90e38657f8e675 Mon Sep 17 00:00:00 2001 From: Nitin Gupta Date: Mon, 9 Jan 2012 16:52:00 -0600 Subject: staging: zram: remove xvmalloc Removes the xvmalloc allocator code from the zram driver Signed-off-by: Nitin Gupta Acked-by: Seth Jennings Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Makefile | 1 - drivers/staging/zram/xvmalloc.c | 510 ------------------------------------ drivers/staging/zram/xvmalloc.h | 30 --- drivers/staging/zram/xvmalloc_int.h | 95 ------- 4 files changed, 636 deletions(-) delete mode 100644 drivers/staging/zram/xvmalloc.c delete mode 100644 drivers/staging/zram/xvmalloc.h delete mode 100644 drivers/staging/zram/xvmalloc_int.h (limited to 'drivers') diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 4fa1e5e5b8e..31c81fabfc3 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -35,7 +35,6 @@ obj-$(CONFIG_VME_BUS) += vme/ obj-$(CONFIG_DX_SEP) += sep/ obj-$(CONFIG_IIO) += iio/ obj-$(CONFIG_ZRAM) += zram/ -obj-$(CONFIG_XVMALLOC) += zram/ obj-$(CONFIG_ZCACHE) += zcache/ obj-$(CONFIG_ZSMALLOC) += zsmalloc/ obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/ diff --git a/drivers/staging/zram/xvmalloc.c b/drivers/staging/zram/xvmalloc.c deleted file mode 100644 index 1f9c5082b6d..00000000000 --- a/drivers/staging/zram/xvmalloc.c +++ /dev/null @@ -1,510 +0,0 @@ -/* - * xvmalloc memory allocator - * - * Copyright (C) 2008, 2009, 2010 Nitin Gupta - * - * This code is released using a dual license strategy: BSD/GPL - * You can choose the licence that better fits your requirements. - * - * Released under the terms of 3-clause BSD License - * Released under the terms of GNU General Public License Version 2.0 - */ - -#ifdef CONFIG_ZRAM_DEBUG -#define DEBUG -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "xvmalloc.h" -#include "xvmalloc_int.h" - -static void stat_inc(u64 *value) -{ - *value = *value + 1; -} - -static void stat_dec(u64 *value) -{ - *value = *value - 1; -} - -static int test_flag(struct block_header *block, enum blockflags flag) -{ - return block->prev & BIT(flag); -} - -static void set_flag(struct block_header *block, enum blockflags flag) -{ - block->prev |= BIT(flag); -} - -static void clear_flag(struct block_header *block, enum blockflags flag) -{ - block->prev &= ~BIT(flag); -} - -/* - * Given pair, provide a dereferencable pointer. - * This is called from xv_malloc/xv_free path, so it - * needs to be fast. - */ -static void *get_ptr_atomic(struct page *page, u16 offset, enum km_type type) -{ - unsigned char *base; - - base = kmap_atomic(page, type); - return base + offset; -} - -static void put_ptr_atomic(void *ptr, enum km_type type) -{ - kunmap_atomic(ptr, type); -} - -static u32 get_blockprev(struct block_header *block) -{ - return block->prev & PREV_MASK; -} - -static void set_blockprev(struct block_header *block, u16 new_offset) -{ - block->prev = new_offset | (block->prev & FLAGS_MASK); -} - -static struct block_header *BLOCK_NEXT(struct block_header *block) -{ - return (struct block_header *) - ((char *)block + block->size + XV_ALIGN); -} - -/* - * Get index of free list containing blocks of maximum size - * which is less than or equal to given size. - */ -static u32 get_index_for_insert(u32 size) -{ - if (unlikely(size > XV_MAX_ALLOC_SIZE)) - size = XV_MAX_ALLOC_SIZE; - size &= ~FL_DELTA_MASK; - return (size - XV_MIN_ALLOC_SIZE) >> FL_DELTA_SHIFT; -} - -/* - * Get index of free list having blocks of size greater than - * or equal to requested size. - */ -static u32 get_index(u32 size) -{ - if (unlikely(size < XV_MIN_ALLOC_SIZE)) - size = XV_MIN_ALLOC_SIZE; - size = ALIGN(size, FL_DELTA); - return (size - XV_MIN_ALLOC_SIZE) >> FL_DELTA_SHIFT; -} - -/** - * find_block - find block of at least given size - * @pool: memory pool to search from - * @size: size of block required - * @page: page containing required block - * @offset: offset within the page where block is located. - * - * Searches two level bitmap to locate block of at least - * the given size. If such a block is found, it provides - * to identify this block and returns index - * in freelist where we found this block. - * Otherwise, returns 0 and params are not touched. - */ -static u32 find_block(struct xv_pool *pool, u32 size, - struct page **page, u32 *offset) -{ - ulong flbitmap, slbitmap; - u32 flindex, slindex, slbitstart; - - /* There are no free blocks in this pool */ - if (!pool->flbitmap) - return 0; - - /* Get freelist index correspoding to this size */ - slindex = get_index(size); - slbitmap = pool->slbitmap[slindex / BITS_PER_LONG]; - slbitstart = slindex % BITS_PER_LONG; - - /* - * If freelist is not empty at this index, we found the - * block - head of this list. This is approximate best-fit match. - */ - if (test_bit(slbitstart, &slbitmap)) { - *page = pool->freelist[slindex].page; - *offset = pool->freelist[slindex].offset; - return slindex; - } - - /* - * No best-fit found. Search a bit further in bitmap for a free block. - * Second level bitmap consists of series of 32-bit chunks. Search - * further in the chunk where we expected a best-fit, starting from - * index location found above. - */ - slbitstart++; - slbitmap >>= slbitstart; - - /* Skip this search if we were already at end of this bitmap chunk */ - if ((slbitstart != BITS_PER_LONG) && slbitmap) { - slindex += __ffs(slbitmap) + 1; - *page = pool->freelist[slindex].page; - *offset = pool->freelist[slindex].offset; - return slindex; - } - - /* Now do a full two-level bitmap search to find next nearest fit */ - flindex = slindex / BITS_PER_LONG; - - flbitmap = (pool->flbitmap) >> (flindex + 1); - if (!flbitmap) - return 0; - - flindex += __ffs(flbitmap) + 1; - slbitmap = pool->slbitmap[flindex]; - slindex = (flindex * BITS_PER_LONG) + __ffs(slbitmap); - *page = pool->freelist[slindex].page; - *offset = pool->freelist[slindex].offset; - - return slindex; -} - -/* - * Insert block at in freelist of given pool. - * freelist used depends on block size. - */ -static void insert_block(struct xv_pool *pool, struct page *page, u32 offset, - struct block_header *block) -{ - u32 flindex, slindex; - struct block_header *nextblock; - - slindex = get_index_for_insert(block->size); - flindex = slindex / BITS_PER_LONG; - - block->link.prev_page = NULL; - block->link.prev_offset = 0; - block->link.next_page = pool->freelist[slindex].page; - block->link.next_offset = pool->freelist[slindex].offset; - pool->freelist[slindex].page = page; - pool->freelist[slindex].offset = offset; - - if (block->link.next_page) { - nextblock = get_ptr_atomic(block->link.next_page, - block->link.next_offset, KM_USER1); - nextblock->link.prev_page = page; - nextblock->link.prev_offset = offset; - put_ptr_atomic(nextblock, KM_USER1); - /* If there was a next page then the free bits are set. */ - return; - } - - __set_bit(slindex % BITS_PER_LONG, &pool->slbitmap[flindex]); - __set_bit(flindex, &pool->flbitmap); -} - -/* - * Remove block from freelist. Index 'slindex' identifies the freelist. - */ -static void remove_block(struct xv_pool *pool, struct page *page, u32 offset, - struct block_header *block, u32 slindex) -{ - u32 flindex = slindex / BITS_PER_LONG; - struct block_header *tmpblock; - - if (block->link.prev_page) { - tmpblock = get_ptr_atomic(block->link.prev_page, - block->link.prev_offset, KM_USER1); - tmpblock->link.next_page = block->link.next_page; - tmpblock->link.next_offset = block->link.next_offset; - put_ptr_atomic(tmpblock, KM_USER1); - } - - if (block->link.next_page) { - tmpblock = get_ptr_atomic(block->link.next_page, - block->link.next_offset, KM_USER1); - tmpblock->link.prev_page = block->link.prev_page; - tmpblock->link.prev_offset = block->link.prev_offset; - put_ptr_atomic(tmpblock, KM_USER1); - } - - /* Is this block is at the head of the freelist? */ - if (pool->freelist[slindex].page == page - && pool->freelist[slindex].offset == offset) { - - pool->freelist[slindex].page = block->link.next_page; - pool->freelist[slindex].offset = block->link.next_offset; - - if (pool->freelist[slindex].page) { - struct block_header *tmpblock; - tmpblock = get_ptr_atomic(pool->freelist[slindex].page, - pool->freelist[slindex].offset, - KM_USER1); - tmpblock->link.prev_page = NULL; - tmpblock->link.prev_offset = 0; - put_ptr_atomic(tmpblock, KM_USER1); - } else { - /* This freelist bucket is empty */ - __clear_bit(slindex % BITS_PER_LONG, - &pool->slbitmap[flindex]); - if (!pool->slbitmap[flindex]) - __clear_bit(flindex, &pool->flbitmap); - } - } - - block->link.prev_page = NULL; - block->link.prev_offset = 0; - block->link.next_page = NULL; - block->link.next_offset = 0; -} - -/* - * Allocate a page and add it to freelist of given pool. - */ -static int grow_pool(struct xv_pool *pool, gfp_t flags) -{ - struct page *page; - struct block_header *block; - - page = alloc_page(flags); - if (unlikely(!page)) - return -ENOMEM; - - stat_inc(&pool->total_pages); - - spin_lock(&pool->lock); - block = get_ptr_atomic(page, 0, KM_USER0); - - block->size = PAGE_SIZE - XV_ALIGN; - set_flag(block, BLOCK_FREE); - clear_flag(block, PREV_FREE); - set_blockprev(block, 0); - - insert_block(pool, page, 0, block); - - put_ptr_atomic(block, KM_USER0); - spin_unlock(&pool->lock); - - return 0; -} - -/* - * Create a memory pool. Allocates freelist, bitmaps and other - * per-pool metadata. - */ -struct xv_pool *xv_create_pool(void) -{ - u32 ovhd_size; - struct xv_pool *pool; - - ovhd_size = roundup(sizeof(*pool), PAGE_SIZE); - pool = kzalloc(ovhd_size, GFP_KERNEL); - if (!pool) - return NULL; - - spin_lock_init(&pool->lock); - - return pool; -} -EXPORT_SYMBOL_GPL(xv_create_pool); - -void xv_destroy_pool(struct xv_pool *pool) -{ - kfree(pool); -} -EXPORT_SYMBOL_GPL(xv_destroy_pool); - -/** - * xv_malloc - Allocate block of given size from pool. - * @pool: pool to allocate from - * @size: size of block to allocate - * @page: page no. that holds the object - * @offset: location of object within page - * - * On success, identifies block allocated - * and 0 is returned. On failure, is set to - * 0 and -ENOMEM is returned. - * - * Allocation requests with size > XV_MAX_ALLOC_SIZE will fail. - */ -int xv_malloc(struct xv_pool *pool, u32 size, struct page **page, - u32 *offset, gfp_t flags) -{ - int error; - u32 index, tmpsize, origsize, tmpoffset; - struct block_header *block, *tmpblock; - - *page = NULL; - *offset = 0; - origsize = size; - - if (unlikely(!size || size > XV_MAX_ALLOC_SIZE)) - return -ENOMEM; - - size = ALIGN(size, XV_ALIGN); - - spin_lock(&pool->lock); - - index = find_block(pool, size, page, offset); - - if (!*page) { - spin_unlock(&pool->lock); - if (flags & GFP_NOWAIT) - return -ENOMEM; - error = grow_pool(pool, flags); - if (unlikely(error)) - return error; - - spin_lock(&pool->lock); - index = find_block(pool, size, page, offset); - } - - if (!*page) { - spin_unlock(&pool->lock); - return -ENOMEM; - } - - block = get_ptr_atomic(*page, *offset, KM_USER0); - - remove_block(pool, *page, *offset, block, index); - - /* Split the block if required */ - tmpoffset = *offset + size + XV_ALIGN; - tmpsize = block->size - size; - tmpblock = (struct block_header *)((char *)block + size + XV_ALIGN); - if (tmpsize) { - tmpblock->size = tmpsize - XV_ALIGN; - set_flag(tmpblock, BLOCK_FREE); - clear_flag(tmpblock, PREV_FREE); - - set_blockprev(tmpblock, *offset); - if (tmpblock->size >= XV_MIN_ALLOC_SIZE) - insert_block(pool, *page, tmpoffset, tmpblock); - - if (tmpoffset + XV_ALIGN + tmpblock->size != PAGE_SIZE) { - tmpblock = BLOCK_NEXT(tmpblock); - set_blockprev(tmpblock, tmpoffset); - } - } else { - /* This block is exact fit */ - if (tmpoffset != PAGE_SIZE) - clear_flag(tmpblock, PREV_FREE); - } - - block->size = origsize; - clear_flag(block, BLOCK_FREE); - - put_ptr_atomic(block, KM_USER0); - spin_unlock(&pool->lock); - - *offset += XV_ALIGN; - - return 0; -} -EXPORT_SYMBOL_GPL(xv_malloc); - -/* - * Free block identified with - */ -void xv_free(struct xv_pool *pool, struct page *page, u32 offset) -{ - void *page_start; - struct block_header *block, *tmpblock; - - offset -= XV_ALIGN; - - spin_lock(&pool->lock); - - page_start = get_ptr_atomic(page, 0, KM_USER0); - block = (struct block_header *)((char *)page_start + offset); - - /* Catch double free bugs */ - BUG_ON(test_flag(block, BLOCK_FREE)); - - block->size = ALIGN(block->size, XV_ALIGN); - - tmpblock = BLOCK_NEXT(block); - if (offset + block->size + XV_ALIGN == PAGE_SIZE) - tmpblock = NULL; - - /* Merge next block if its free */ - if (tmpblock && test_flag(tmpblock, BLOCK_FREE)) { - /* - * Blocks smaller than XV_MIN_ALLOC_SIZE - * are not inserted in any free list. - */ - if (tmpblock->size >= XV_MIN_ALLOC_SIZE) { - remove_block(pool, page, - offset + block->size + XV_ALIGN, tmpblock, - get_index_for_insert(tmpblock->size)); - } - block->size += tmpblock->size + XV_ALIGN; - } - - /* Merge previous block if its free */ - if (test_flag(block, PREV_FREE)) { - tmpblock = (struct block_header *)((char *)(page_start) + - get_blockprev(block)); - offset = offset - tmpblock->size - XV_ALIGN; - - if (tmpblock->size >= XV_MIN_ALLOC_SIZE) - remove_block(pool, page, offset, tmpblock, - get_index_for_insert(tmpblock->size)); - - tmpblock->size += block->size + XV_ALIGN; - block = tmpblock; - } - - /* No used objects in this page. Free it. */ - if (block->size == PAGE_SIZE - XV_ALIGN) { - put_ptr_atomic(page_start, KM_USER0); - spin_unlock(&pool->lock); - - __free_page(page); - stat_dec(&pool->total_pages); - return; - } - - set_flag(block, BLOCK_FREE); - if (block->size >= XV_MIN_ALLOC_SIZE) - insert_block(pool, page, offset, block); - - if (offset + block->size + XV_ALIGN != PAGE_SIZE) { - tmpblock = BLOCK_NEXT(block); - set_flag(tmpblock, PREV_FREE); - set_blockprev(tmpblock, offset); - } - - put_ptr_atomic(page_start, KM_USER0); - spin_unlock(&pool->lock); -} -EXPORT_SYMBOL_GPL(xv_free); - -u32 xv_get_object_size(void *obj) -{ - struct block_header *blk; - - blk = (struct block_header *)((char *)(obj) - XV_ALIGN); - return blk->size; -} -EXPORT_SYMBOL_GPL(xv_get_object_size); - -/* - * Returns total memory used by allocator (userdata + metadata) - */ -u64 xv_get_total_size_bytes(struct xv_pool *pool) -{ - return pool->total_pages << PAGE_SHIFT; -} -EXPORT_SYMBOL_GPL(xv_get_total_size_bytes); diff --git a/drivers/staging/zram/xvmalloc.h b/drivers/staging/zram/xvmalloc.h deleted file mode 100644 index 5b1a81aa5fa..00000000000 --- a/drivers/staging/zram/xvmalloc.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * xvmalloc memory allocator - * - * Copyright (C) 2008, 2009, 2010 Nitin Gupta - * - * This code is released using a dual license strategy: BSD/GPL - * You can choose the licence that better fits your requirements. - * - * Released under the terms of 3-clause BSD License - * Released under the terms of GNU General Public License Version 2.0 - */ - -#ifndef _XV_MALLOC_H_ -#define _XV_MALLOC_H_ - -#include - -struct xv_pool; - -struct xv_pool *xv_create_pool(void); -void xv_destroy_pool(struct xv_pool *pool); - -int xv_malloc(struct xv_pool *pool, u32 size, struct page **page, - u32 *offset, gfp_t flags); -void xv_free(struct xv_pool *pool, struct page *page, u32 offset); - -u32 xv_get_object_size(void *obj); -u64 xv_get_total_size_bytes(struct xv_pool *pool); - -#endif diff --git a/drivers/staging/zram/xvmalloc_int.h b/drivers/staging/zram/xvmalloc_int.h deleted file mode 100644 index b5f1f7febcf..00000000000 --- a/drivers/staging/zram/xvmalloc_int.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * xvmalloc memory allocator - * - * Copyright (C) 2008, 2009, 2010 Nitin Gupta - * - * This code is released using a dual license strategy: BSD/GPL - * You can choose the licence that better fits your requirements. - * - * Released under the terms of 3-clause BSD License - * Released under the terms of GNU General Public License Version 2.0 - */ - -#ifndef _XV_MALLOC_INT_H_ -#define _XV_MALLOC_INT_H_ - -#include -#include - -/* User configurable params */ - -/* Must be power of two */ -#ifdef CONFIG_64BIT -#define XV_ALIGN_SHIFT 3 -#else -#define XV_ALIGN_SHIFT 2 -#endif -#define XV_ALIGN (1 << XV_ALIGN_SHIFT) -#define XV_ALIGN_MASK (XV_ALIGN - 1) - -/* This must be greater than sizeof(link_free) */ -#define XV_MIN_ALLOC_SIZE 32 -#define XV_MAX_ALLOC_SIZE (PAGE_SIZE - XV_ALIGN) - -/* - * Free lists are separated by FL_DELTA bytes - * This value is 3 for 4k pages and 4 for 64k pages, for any - * other page size, a conservative (PAGE_SHIFT - 9) is used. - */ -#if PAGE_SHIFT == 16 -#define FL_DELTA_SHIFT 4 -#else -#define FL_DELTA_SHIFT (PAGE_SHIFT - 9) -#endif -#define FL_DELTA (1 << FL_DELTA_SHIFT) -#define FL_DELTA_MASK (FL_DELTA - 1) -#define NUM_FREE_LISTS ((XV_MAX_ALLOC_SIZE - XV_MIN_ALLOC_SIZE) \ - / FL_DELTA + 1) - -#define MAX_FLI DIV_ROUND_UP(NUM_FREE_LISTS, BITS_PER_LONG) - -/* End of user params */ - -enum blockflags { - BLOCK_FREE, - PREV_FREE, - __NR_BLOCKFLAGS, -}; - -#define FLAGS_MASK XV_ALIGN_MASK -#define PREV_MASK (~FLAGS_MASK) - -struct freelist_entry { - struct page *page; - u16 offset; - u16 pad; -}; - -struct link_free { - struct page *prev_page; - struct page *next_page; - u16 prev_offset; - u16 next_offset; -}; - -struct block_header { - union { - /* This common header must be XV_ALIGN bytes */ - u8 common[XV_ALIGN]; - struct { - u16 size; - u16 prev; - }; - }; - struct link_free link; -}; - -struct xv_pool { - ulong flbitmap; - ulong slbitmap[MAX_FLI]; - u64 total_pages; /* stats */ - struct freelist_entry freelist[NUM_FREE_LISTS]; - spinlock_t lock; -}; - -#endif -- cgit v1.2.3-70-g09d2 From 5c9ed5bedf973ab7f4e428f7418d1e72ba3bcbe4 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 11 Jan 2012 23:22:36 +0100 Subject: Staging: quickstart: Some style, whitespaces and typos fixes Signed-off-by: Szymon Janc Signed-off-by: Greg Kroah-Hartman --- drivers/staging/quickstart/quickstart.c | 80 ++++++++++++++++----------------- 1 file changed, 39 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/quickstart/quickstart.c b/drivers/staging/quickstart/quickstart.c index c60911c6ab3..d03b89d2c9a 100644 --- a/drivers/staging/quickstart/quickstart.c +++ b/drivers/staging/quickstart/quickstart.c @@ -4,7 +4,7 @@ * * Copyright (C) 2007-2010 Angelo Arrifano * - * Information gathered from disassebled dsdt and from here: + * Information gathered from disassembled dsdt and from here: * * * This program is free software; you can redistribute it and/or modify @@ -37,21 +37,23 @@ MODULE_AUTHOR("Angelo Arrifano"); MODULE_DESCRIPTION("ACPI Direct App Launch driver"); MODULE_LICENSE("GPL"); -#define QUICKSTART_ACPI_DEVICE_NAME "quickstart" -#define QUICKSTART_ACPI_CLASS "quickstart" -#define QUICKSTART_ACPI_HID "PNP0C32" +#define QUICKSTART_ACPI_DEVICE_NAME "quickstart" +#define QUICKSTART_ACPI_CLASS "quickstart" +#define QUICKSTART_ACPI_HID "PNP0C32" -#define QUICKSTART_PF_DRIVER_NAME "quickstart" -#define QUICKSTART_PF_DEVICE_NAME "quickstart" -#define QUICKSTART_PF_DEVATTR_NAME "pressed_button" +#define QUICKSTART_PF_DRIVER_NAME "quickstart" +#define QUICKSTART_PF_DEVICE_NAME "quickstart" +#define QUICKSTART_PF_DEVATTR_NAME "pressed_button" -#define QUICKSTART_MAX_BTN_NAME_LEN 16 +#define QUICKSTART_MAX_BTN_NAME_LEN 16 -/* There will be two events: - * 0x02 - A hot button was pressed while device was off/sleeping. - * 0x80 - A hot button was pressed while device was up. */ -#define QUICKSTART_EVENT_WAKE 0x02 -#define QUICKSTART_EVENT_RUNTIME 0x80 +/* + * There will be two events: + * 0x02 - A hot button was pressed while device was off/sleeping. + * 0x80 - A hot button was pressed while device was up. + */ +#define QUICKSTART_EVENT_WAKE 0x02 +#define QUICKSTART_EVENT_RUNTIME 0x80 struct quickstart_btn { char *name; @@ -64,14 +66,14 @@ static struct quickstart_driver_data { struct quickstart_btn *pressed; } quickstart_data; -/* ACPI driver Structs */ +/* ACPI driver structs */ struct quickstart_acpi { struct acpi_device *device; struct quickstart_btn *btn; }; static int quickstart_acpi_add(struct acpi_device *device); static int quickstart_acpi_remove(struct acpi_device *device, int type); -static const struct acpi_device_id quickstart_device_ids[] = { +static const struct acpi_device_id quickstart_device_ids[] = { {QUICKSTART_ACPI_HID, 0}, {"", 0}, }; @@ -111,12 +113,10 @@ static struct platform_driver pf_driver = { } }; -/* - * Platform driver functions - */ +/* Platform driver functions */ static ssize_t buttons_show(struct device *dev, - struct device_attribute *attr, - char *buf) + struct device_attribute *attr, + char *buf) { int count = 0; struct quickstart_btn *ptr = quickstart_data.btn_lst; @@ -137,8 +137,8 @@ static ssize_t buttons_show(struct device *dev, } static ssize_t pressed_button_show(struct device *dev, - struct device_attribute *attr, - char *buf) + struct device_attribute *attr, + char *buf) { return snprintf(buf, PAGE_SIZE, "%s\n", (quickstart_data.pressed ? @@ -147,8 +147,8 @@ static ssize_t pressed_button_show(struct device *dev, static ssize_t pressed_button_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) + struct device_attribute *attr, + const char *buf, size_t count) { if (count < 2) return -EINVAL; @@ -160,7 +160,7 @@ static ssize_t pressed_button_store(struct device *dev, return count; } -/* Hotstart Helper functions */ +/* Helper functions */ static int quickstart_btnlst_add(struct quickstart_btn **data) { struct quickstart_btn **ptr = &quickstart_data.btn_lst; @@ -240,22 +240,26 @@ static void quickstart_acpi_ghid(struct quickstart_acpi *quickstart) if (!quickstart) return; - /* This returns a buffer telling the button usage ID, - * and triggers pending notify events (The ones before booting). */ - status = acpi_evaluate_object(quickstart->device->handle, - "GHID", NULL, &buffer); + /* + * This returns a buffer telling the button usage ID, + * and triggers pending notify events (The ones before booting). + */ + status = acpi_evaluate_object(quickstart->device->handle, "GHID", NULL, + &buffer); if (ACPI_FAILURE(status) || !buffer.pointer) { printk(KERN_ERR "quickstart: %s GHID method failed.\n", - quickstart->btn->name); + quickstart->btn->name); return; } if (buffer.length < 8) return; - /* <> */ + * order (least significant byte first).>> + */ usageid = *((uint32_t *)(buffer.pointer + (buffer.length - 8))); quickstart->btn->id = usageid; @@ -339,20 +343,17 @@ static int quickstart_acpi_remove(struct acpi_device *device, int type) quickstart = acpi_driver_data(device); - status = acpi_remove_notify_handler(device->handle, - ACPI_ALL_NOTIFY, - quickstart_acpi_notify); + status = acpi_remove_notify_handler(device->handle, ACPI_ALL_NOTIFY, + quickstart_acpi_notify); if (ACPI_FAILURE(status)) printk(KERN_ERR "quickstart: Error removing notify handler\n"); - kfree(quickstart); return 0; } /* Module functions */ - static void quickstart_exit(void) { input_unregister_device(quickstart_input); @@ -367,8 +368,6 @@ static void quickstart_exit(void) acpi_bus_unregister_driver(&quickstart_acpi_driver); quickstart_btnlst_free(); - - return; } static int __init quickstart_init_input(void) @@ -444,14 +443,13 @@ static int __init quickstart_init(void) if (ret) goto fail_dev_file2; - /* Input device */ ret = quickstart_init_input(); if (ret) goto fail_input; printk(KERN_INFO "quickstart: ACPI Direct App Launch ver %s\n", - QUICKSTART_VERSION); + QUICKSTART_VERSION); return 0; fail_input: -- cgit v1.2.3-70-g09d2 From 7267d2610a7ed3f56a1f20f58b9ee0d944025b01 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 11 Jan 2012 23:22:37 +0100 Subject: Staging: quickstart: Prefix remaining functions names with quickstart_ Signed-off-by: Szymon Janc Signed-off-by: Greg Kroah-Hartman --- drivers/staging/quickstart/quickstart.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/quickstart/quickstart.c b/drivers/staging/quickstart/quickstart.c index d03b89d2c9a..adce56be2b9 100644 --- a/drivers/staging/quickstart/quickstart.c +++ b/drivers/staging/quickstart/quickstart.c @@ -92,19 +92,19 @@ static struct acpi_driver quickstart_acpi_driver = { struct input_dev *quickstart_input; /* Platform driver structs */ -static ssize_t buttons_show(struct device *dev, +static ssize_t quickstart_buttons_show(struct device *dev, struct device_attribute *attr, char *buf); -static ssize_t pressed_button_show(struct device *dev, +static ssize_t quickstart_pressed_button_show(struct device *dev, struct device_attribute *attr, char *buf); -static ssize_t pressed_button_store(struct device *dev, +static ssize_t quickstart_pressed_button_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); -static DEVICE_ATTR(pressed_button, 0666, pressed_button_show, - pressed_button_store); -static DEVICE_ATTR(buttons, 0444, buttons_show, NULL); +static DEVICE_ATTR(pressed_button, 0666, quickstart_pressed_button_show, + quickstart_pressed_button_store); +static DEVICE_ATTR(buttons, 0444, quickstart_buttons_show, NULL); static struct platform_device *pf_device; static struct platform_driver pf_driver = { .driver = { @@ -114,7 +114,7 @@ static struct platform_driver pf_driver = { }; /* Platform driver functions */ -static ssize_t buttons_show(struct device *dev, +static ssize_t quickstart_buttons_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -136,7 +136,7 @@ static ssize_t buttons_show(struct device *dev, return count; } -static ssize_t pressed_button_show(struct device *dev, +static ssize_t quickstart_pressed_button_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -146,7 +146,7 @@ static ssize_t pressed_button_show(struct device *dev, } -static ssize_t pressed_button_store(struct device *dev, +static ssize_t quickstart_pressed_button_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { -- cgit v1.2.3-70-g09d2 From 605926ef5a8a7f9d778b974c96e90e8f8368a595 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 11 Jan 2012 23:22:38 +0100 Subject: Staging: quickstart: Move some code to avoid forward declarations Signed-off-by: Szymon Janc Signed-off-by: Greg Kroah-Hartman --- drivers/staging/quickstart/quickstart.c | 75 ++++++++++++++------------------- 1 file changed, 31 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/quickstart/quickstart.c b/drivers/staging/quickstart/quickstart.c index adce56be2b9..6617761f32f 100644 --- a/drivers/staging/quickstart/quickstart.c +++ b/drivers/staging/quickstart/quickstart.c @@ -61,58 +61,18 @@ struct quickstart_btn { struct quickstart_btn *next; }; -static struct quickstart_driver_data { - struct quickstart_btn *btn_lst; - struct quickstart_btn *pressed; -} quickstart_data; - -/* ACPI driver structs */ struct quickstart_acpi { struct acpi_device *device; struct quickstart_btn *btn; }; -static int quickstart_acpi_add(struct acpi_device *device); -static int quickstart_acpi_remove(struct acpi_device *device, int type); -static const struct acpi_device_id quickstart_device_ids[] = { - {QUICKSTART_ACPI_HID, 0}, - {"", 0}, -}; -static struct acpi_driver quickstart_acpi_driver = { - .name = "quickstart", - .class = QUICKSTART_ACPI_CLASS, - .ids = quickstart_device_ids, - .ops = { - .add = quickstart_acpi_add, - .remove = quickstart_acpi_remove, - }, -}; +static struct quickstart_driver_data { + struct quickstart_btn *btn_lst; + struct quickstart_btn *pressed; +} quickstart_data; -/* Input device structs */ struct input_dev *quickstart_input; -/* Platform driver structs */ -static ssize_t quickstart_buttons_show(struct device *dev, - struct device_attribute *attr, - char *buf); -static ssize_t quickstart_pressed_button_show(struct device *dev, - struct device_attribute *attr, - char *buf); -static ssize_t quickstart_pressed_button_store(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t count); -static DEVICE_ATTR(pressed_button, 0666, quickstart_pressed_button_show, - quickstart_pressed_button_store); -static DEVICE_ATTR(buttons, 0444, quickstart_buttons_show, NULL); -static struct platform_device *pf_device; -static struct platform_driver pf_driver = { - .driver = { - .name = QUICKSTART_PF_DRIVER_NAME, - .owner = THIS_MODULE, - } -}; - /* Platform driver functions */ static ssize_t quickstart_buttons_show(struct device *dev, struct device_attribute *attr, @@ -353,6 +313,33 @@ static int quickstart_acpi_remove(struct acpi_device *device, int type) return 0; } +/* Platform driver structs */ +static DEVICE_ATTR(pressed_button, 0666, quickstart_pressed_button_show, + quickstart_pressed_button_store); +static DEVICE_ATTR(buttons, 0444, quickstart_buttons_show, NULL); +static struct platform_device *pf_device; +static struct platform_driver pf_driver = { + .driver = { + .name = QUICKSTART_PF_DRIVER_NAME, + .owner = THIS_MODULE, + } +}; + +static const struct acpi_device_id quickstart_device_ids[] = { + {QUICKSTART_ACPI_HID, 0}, + {"", 0}, +}; + +static struct acpi_driver quickstart_acpi_driver = { + .name = "quickstart", + .class = QUICKSTART_ACPI_CLASS, + .ids = quickstart_device_ids, + .ops = { + .add = quickstart_acpi_add, + .remove = quickstart_acpi_remove, + }, +}; + /* Module functions */ static void quickstart_exit(void) { -- cgit v1.2.3-70-g09d2 From 1692caa949728d866238020fe2214bd48f825d62 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 11 Jan 2012 23:22:39 +0100 Subject: Staging: quickstart: Make quickstart_input static Signed-off-by: Szymon Janc Signed-off-by: Greg Kroah-Hartman --- drivers/staging/quickstart/quickstart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/quickstart/quickstart.c b/drivers/staging/quickstart/quickstart.c index 6617761f32f..7b0deb65cf4 100644 --- a/drivers/staging/quickstart/quickstart.c +++ b/drivers/staging/quickstart/quickstart.c @@ -71,7 +71,7 @@ static struct quickstart_driver_data { struct quickstart_btn *pressed; } quickstart_data; -struct input_dev *quickstart_input; +static struct input_dev *quickstart_input; /* Platform driver functions */ static ssize_t quickstart_buttons_show(struct device *dev, -- cgit v1.2.3-70-g09d2 From 2ac16967b8de55ec1cfb596717b3a68b0d5b42f7 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 11 Jan 2012 23:22:40 +0100 Subject: Staging: quickstart: Cleanup quickstart_acpi_ghid Also fix memory leak (buffer.pointer) when returned buffer of length less than 8. Signed-off-by: Szymon Janc Signed-off-by: Greg Kroah-Hartman --- drivers/staging/quickstart/quickstart.c | 38 ++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/quickstart/quickstart.c b/drivers/staging/quickstart/quickstart.c index 7b0deb65cf4..3bae5e75659 100644 --- a/drivers/staging/quickstart/quickstart.c +++ b/drivers/staging/quickstart/quickstart.c @@ -191,14 +191,11 @@ static void quickstart_acpi_notify(acpi_handle handle, u32 event, void *data) return; } -static void quickstart_acpi_ghid(struct quickstart_acpi *quickstart) +static int quickstart_acpi_ghid(struct quickstart_acpi *quickstart) { acpi_status status; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - uint32_t usageid = 0; - - if (!quickstart) - return; + int ret = 0; /* * This returns a buffer telling the button usage ID, @@ -206,24 +203,41 @@ static void quickstart_acpi_ghid(struct quickstart_acpi *quickstart) */ status = acpi_evaluate_object(quickstart->device->handle, "GHID", NULL, &buffer); - if (ACPI_FAILURE(status) || !buffer.pointer) { + if (ACPI_FAILURE(status)) { printk(KERN_ERR "quickstart: %s GHID method failed.\n", quickstart->btn->name); - return; + return -EINVAL; } - if (buffer.length < 8) - return; - /* * <> */ - usageid = *((uint32_t *)(buffer.pointer + (buffer.length - 8))); - quickstart->btn->id = usageid; + switch (buffer.length) { + case 1: + quickstart->btn->id = *(uint8_t *)buffer.pointer; + break; + case 2: + quickstart->btn->id = *(uint16_t *)buffer.pointer; + break; + case 4: + quickstart->btn->id = *(uint32_t *)buffer.pointer; + break; + case 8: + quickstart->btn->id = *(uint64_t *)buffer.pointer; + break; + default: + printk(KERN_ERR "quickstart: %s GHID method returned buffer " + "of unexpected length %u\n", + quickstart->btn->name, buffer.length); + ret = -EINVAL; + break; + } kfree(buffer.pointer); + + return ret; } static int quickstart_acpi_config(struct quickstart_acpi *quickstart, char *bid) -- cgit v1.2.3-70-g09d2 From 60955f15d93198ef33081e01f46223c7bd534f1e Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 11 Jan 2012 23:22:41 +0100 Subject: Staging: quickstart: Cleanup quickstart_acpi_remove Signed-off-by: Szymon Janc Signed-off-by: Greg Kroah-Hartman --- drivers/staging/quickstart/quickstart.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/quickstart/quickstart.c b/drivers/staging/quickstart/quickstart.c index 3bae5e75659..de98e18f9b4 100644 --- a/drivers/staging/quickstart/quickstart.c +++ b/drivers/staging/quickstart/quickstart.c @@ -309,13 +309,15 @@ fail_config: static int quickstart_acpi_remove(struct acpi_device *device, int type) { - acpi_status status = 0; - struct quickstart_acpi *quickstart = NULL; + acpi_status status; + struct quickstart_acpi *quickstart; - if (!device || !acpi_driver_data(device)) + if (!device) return -EINVAL; quickstart = acpi_driver_data(device); + if (!quickstart) + return -EINVAL; status = acpi_remove_notify_handler(device->handle, ACPI_ALL_NOTIFY, quickstart_acpi_notify); -- cgit v1.2.3-70-g09d2 From f27a551968bb8780c8a5255c0ea6c3a2fcaf4a47 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 11 Jan 2012 23:22:42 +0100 Subject: Staging: quickstart: Cleanup quickstart_acpi_add Signed-off-by: Szymon Janc Signed-off-by: Greg Kroah-Hartman --- drivers/staging/quickstart/quickstart.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/quickstart/quickstart.c b/drivers/staging/quickstart/quickstart.c index de98e18f9b4..97e62e9faf6 100644 --- a/drivers/staging/quickstart/quickstart.c +++ b/drivers/staging/quickstart/quickstart.c @@ -262,29 +262,29 @@ static int quickstart_acpi_config(struct quickstart_acpi *quickstart, char *bid) static int quickstart_acpi_add(struct acpi_device *device) { - int ret = 0; - acpi_status status = AE_OK; - struct quickstart_acpi *quickstart = NULL; + int ret; + acpi_status status; + struct quickstart_acpi *quickstart; if (!device) return -EINVAL; - quickstart = kzalloc(sizeof(struct quickstart_acpi), GFP_KERNEL); + quickstart = kzalloc(sizeof(*quickstart), GFP_KERNEL); if (!quickstart) return -ENOMEM; quickstart->device = device; + strcpy(acpi_device_name(device), QUICKSTART_ACPI_DEVICE_NAME); strcpy(acpi_device_class(device), QUICKSTART_ACPI_CLASS); device->driver_data = quickstart; /* Add button to list and initialize some stuff */ ret = quickstart_acpi_config(quickstart, acpi_device_bid(device)); - if (ret) + if (ret < 0) goto fail_config; - status = acpi_install_notify_handler(device->handle, - ACPI_ALL_NOTIFY, + status = acpi_install_notify_handler(device->handle, ACPI_ALL_NOTIFY, quickstart_acpi_notify, quickstart); if (ACPI_FAILURE(status)) { @@ -293,10 +293,16 @@ static int quickstart_acpi_add(struct acpi_device *device) goto fail_installnotify; } - quickstart_acpi_ghid(quickstart); + ret = quickstart_acpi_ghid(quickstart); + if (ret < 0) + goto fail_ghid; return 0; +fail_ghid: + acpi_remove_notify_handler(device->handle, ACPI_ALL_NOTIFY, + quickstart_acpi_notify); + fail_installnotify: quickstart_btnlst_del(quickstart->btn); -- cgit v1.2.3-70-g09d2 From ffe1c0565c27324f6e23a5b47ae5ff873553c62f Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 11 Jan 2012 23:22:43 +0100 Subject: Staging: quickstart: Cleanup quickstart_acpi_config Signed-off-by: Szymon Janc Signed-off-by: Greg Kroah-Hartman --- drivers/staging/quickstart/quickstart.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/quickstart/quickstart.c b/drivers/staging/quickstart/quickstart.c index 97e62e9faf6..b183d215336 100644 --- a/drivers/staging/quickstart/quickstart.c +++ b/drivers/staging/quickstart/quickstart.c @@ -240,21 +240,24 @@ static int quickstart_acpi_ghid(struct quickstart_acpi *quickstart) return ret; } -static int quickstart_acpi_config(struct quickstart_acpi *quickstart, char *bid) +static int quickstart_acpi_config(struct quickstart_acpi *quickstart) { - int len = strlen(bid); + char *bid = acpi_device_bid(quickstart->device); + char *name; int ret; + name = kmalloc(strlen(bid) + 1, GFP_KERNEL); + if (!name) + return -ENOMEM; + /* Add button to list */ ret = quickstart_btnlst_add(&quickstart->btn); - if (ret) + if (ret < 0) { + kfree(name); return ret; - - quickstart->btn->name = kzalloc(len + 1, GFP_KERNEL); - if (!quickstart->btn->name) { - quickstart_btnlst_free(); - return -ENOMEM; } + + quickstart->btn->name = name; strcpy(quickstart->btn->name, bid); return 0; @@ -280,7 +283,7 @@ static int quickstart_acpi_add(struct acpi_device *device) device->driver_data = quickstart; /* Add button to list and initialize some stuff */ - ret = quickstart_acpi_config(quickstart, acpi_device_bid(device)); + ret = quickstart_acpi_config(quickstart); if (ret < 0) goto fail_config; -- cgit v1.2.3-70-g09d2 From 55e403698642fc39e37c2a8d30aa6fa55c9ae116 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 11 Jan 2012 23:22:44 +0100 Subject: Staging: quickstart: Use switch-case in quickstart_acpi_notify Signed-off-by: Szymon Janc Signed-off-by: Greg Kroah-Hartman --- drivers/staging/quickstart/quickstart.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/quickstart/quickstart.c b/drivers/staging/quickstart/quickstart.c index b183d215336..17e57c037e0 100644 --- a/drivers/staging/quickstart/quickstart.c +++ b/drivers/staging/quickstart/quickstart.c @@ -180,15 +180,19 @@ static void quickstart_acpi_notify(acpi_handle handle, u32 event, void *data) if (!quickstart) return; - if (event == QUICKSTART_EVENT_WAKE) + switch (event) { + case QUICKSTART_EVENT_WAKE: quickstart_data.pressed = quickstart->btn; - else if (event == QUICKSTART_EVENT_RUNTIME) { + break; + case QUICKSTART_EVENT_RUNTIME: input_report_key(quickstart_input, quickstart->btn->id, 1); input_sync(quickstart_input); input_report_key(quickstart_input, quickstart->btn->id, 0); input_sync(quickstart_input); + break; + default: + break; } - return; } static int quickstart_acpi_ghid(struct quickstart_acpi *quickstart) -- cgit v1.2.3-70-g09d2 From 4a0908322a916d15269f2ced8f548ebee9aebd28 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 11 Jan 2012 23:22:45 +0100 Subject: Staging: quickstart: Remove unused defines Signed-off-by: Szymon Janc Signed-off-by: Greg Kroah-Hartman --- drivers/staging/quickstart/quickstart.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/quickstart/quickstart.c b/drivers/staging/quickstart/quickstart.c index 17e57c037e0..9d827f2850d 100644 --- a/drivers/staging/quickstart/quickstart.c +++ b/drivers/staging/quickstart/quickstart.c @@ -43,9 +43,6 @@ MODULE_LICENSE("GPL"); #define QUICKSTART_PF_DRIVER_NAME "quickstart" #define QUICKSTART_PF_DEVICE_NAME "quickstart" -#define QUICKSTART_PF_DEVATTR_NAME "pressed_button" - -#define QUICKSTART_MAX_BTN_NAME_LEN 16 /* * There will be two events: -- cgit v1.2.3-70-g09d2 From 3991eae9437b14454881b64ba5627c3aef9a1ba5 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 11 Jan 2012 23:22:46 +0100 Subject: Staging: quickstart: Get rid of quickstart_data struct Signed-off-by: Szymon Janc Signed-off-by: Greg Kroah-Hartman --- drivers/staging/quickstart/quickstart.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/quickstart/quickstart.c b/drivers/staging/quickstart/quickstart.c index 9d827f2850d..03cb6752e06 100644 --- a/drivers/staging/quickstart/quickstart.c +++ b/drivers/staging/quickstart/quickstart.c @@ -63,10 +63,8 @@ struct quickstart_acpi { struct quickstart_btn *btn; }; -static struct quickstart_driver_data { - struct quickstart_btn *btn_lst; - struct quickstart_btn *pressed; -} quickstart_data; +static struct quickstart_btn *btn_list; +static struct quickstart_btn *pressed; static struct input_dev *quickstart_input; @@ -76,7 +74,7 @@ static ssize_t quickstart_buttons_show(struct device *dev, char *buf) { int count = 0; - struct quickstart_btn *ptr = quickstart_data.btn_lst; + struct quickstart_btn *ptr = btn_list; if (!ptr) return snprintf(buf, PAGE_SIZE, "none"); @@ -98,8 +96,7 @@ static ssize_t quickstart_pressed_button_show(struct device *dev, char *buf) { return snprintf(buf, PAGE_SIZE, "%s\n", - (quickstart_data.pressed ? - quickstart_data.pressed->name : "none")); + (pressed ? pressed->name : "none")); } @@ -113,14 +110,14 @@ static ssize_t quickstart_pressed_button_store(struct device *dev, if (strncasecmp(buf, "none", 4) != 0) return -EINVAL; - quickstart_data.pressed = NULL; + pressed = NULL; return count; } /* Helper functions */ static int quickstart_btnlst_add(struct quickstart_btn **data) { - struct quickstart_btn **ptr = &quickstart_data.btn_lst; + struct quickstart_btn **ptr = &btn_list; while (*ptr) ptr = &((*ptr)->next); @@ -137,7 +134,7 @@ static int quickstart_btnlst_add(struct quickstart_btn **data) static void quickstart_btnlst_del(struct quickstart_btn *data) { - struct quickstart_btn **ptr = &quickstart_data.btn_lst; + struct quickstart_btn **ptr = &btn_list; if (!data) return; @@ -156,7 +153,7 @@ static void quickstart_btnlst_del(struct quickstart_btn *data) static void quickstart_btnlst_free(void) { - struct quickstart_btn *ptr = quickstart_data.btn_lst; + struct quickstart_btn *ptr = btn_list; struct quickstart_btn *lptr = NULL; while (ptr) { @@ -179,7 +176,7 @@ static void quickstart_acpi_notify(acpi_handle handle, u32 event, void *data) switch (event) { case QUICKSTART_EVENT_WAKE: - quickstart_data.pressed = quickstart->btn; + pressed = quickstart->btn; break; case QUICKSTART_EVENT_RUNTIME: input_report_key(quickstart_input, quickstart->btn->id, 1); @@ -385,7 +382,7 @@ static void quickstart_exit(void) static int __init quickstart_init_input(void) { - struct quickstart_btn **ptr = &quickstart_data.btn_lst; + struct quickstart_btn **ptr = &btn_list; int count; int ret; @@ -427,7 +424,7 @@ static int __init quickstart_init(void) return ret; /* If existing bus with no devices */ - if (!quickstart_data.btn_lst) { + if (!btn_list) { ret = -ENODEV; goto fail_pfdrv_reg; } -- cgit v1.2.3-70-g09d2 From 505d2ad2277950ee67e8ed4a12a349f18925c0f4 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 11 Jan 2012 23:22:47 +0100 Subject: Staging: quickstart: Use list.h API for buttons list Signed-off-by: Szymon Janc Signed-off-by: Greg Kroah-Hartman --- drivers/staging/quickstart/quickstart.c | 95 +++++++++++++-------------------- 1 file changed, 36 insertions(+), 59 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/quickstart/quickstart.c b/drivers/staging/quickstart/quickstart.c index 03cb6752e06..dbed79fefb8 100644 --- a/drivers/staging/quickstart/quickstart.c +++ b/drivers/staging/quickstart/quickstart.c @@ -55,7 +55,7 @@ MODULE_LICENSE("GPL"); struct quickstart_btn { char *name; unsigned int id; - struct quickstart_btn *next; + struct list_head list; }; struct quickstart_acpi { @@ -63,7 +63,7 @@ struct quickstart_acpi { struct quickstart_btn *btn; }; -static struct quickstart_btn *btn_list; +static LIST_HEAD(buttons); static struct quickstart_btn *pressed; static struct input_dev *quickstart_input; @@ -74,18 +74,19 @@ static ssize_t quickstart_buttons_show(struct device *dev, char *buf) { int count = 0; - struct quickstart_btn *ptr = btn_list; + struct quickstart_btn *b; - if (!ptr) + if (list_empty(&buttons)) return snprintf(buf, PAGE_SIZE, "none"); - while (ptr && (count < PAGE_SIZE)) { - if (ptr->name) { - count += snprintf(buf + count, - PAGE_SIZE - count, - "%d\t%s\n", ptr->id, ptr->name); + list_for_each_entry(b, &buttons, list) { + count += snprintf(buf + count, PAGE_SIZE - count, "%d\t%s\n", + b->id, b->name); + + if (count >= PAGE_SIZE) { + count = PAGE_SIZE; + break; } - ptr = ptr->next; } return count; @@ -115,55 +116,35 @@ static ssize_t quickstart_pressed_button_store(struct device *dev, } /* Helper functions */ -static int quickstart_btnlst_add(struct quickstart_btn **data) +static struct quickstart_btn *quickstart_buttons_add(void) { - struct quickstart_btn **ptr = &btn_list; + struct quickstart_btn *b; - while (*ptr) - ptr = &((*ptr)->next); + b = kzalloc(sizeof(*b), GFP_KERNEL); + if (!b) + return NULL; - *ptr = kzalloc(sizeof(struct quickstart_btn), GFP_KERNEL); - if (!*ptr) { - *data = NULL; - return -ENOMEM; - } - *data = *ptr; + list_add_tail(&b->list, &buttons); - return 0; + return b; } -static void quickstart_btnlst_del(struct quickstart_btn *data) +static void quickstart_button_del(struct quickstart_btn *data) { - struct quickstart_btn **ptr = &btn_list; - if (!data) return; - while (*ptr) { - if (*ptr == data) { - *ptr = (*ptr)->next; - kfree(data); - return; - } - ptr = &((*ptr)->next); - } - - return; + list_del(&data->list); + kfree(data->name); + kfree(data); } -static void quickstart_btnlst_free(void) +static void quickstart_buttons_free(void) { - struct quickstart_btn *ptr = btn_list; - struct quickstart_btn *lptr = NULL; - - while (ptr) { - lptr = ptr; - ptr = ptr->next; - kfree(lptr->name); - kfree(lptr); - } + struct quickstart_btn *b, *n; - return; + list_for_each_entry_safe(b, n, &buttons, list) + quickstart_button_del(b); } /* ACPI Driver functions */ @@ -242,17 +223,16 @@ static int quickstart_acpi_config(struct quickstart_acpi *quickstart) { char *bid = acpi_device_bid(quickstart->device); char *name; - int ret; name = kmalloc(strlen(bid) + 1, GFP_KERNEL); if (!name) return -ENOMEM; - /* Add button to list */ - ret = quickstart_btnlst_add(&quickstart->btn); - if (ret < 0) { + /* Add new button to list */ + quickstart->btn = quickstart_buttons_add(); + if (!quickstart->btn) { kfree(name); - return ret; + return -ENOMEM; } quickstart->btn->name = name; @@ -305,7 +285,7 @@ fail_ghid: quickstart_acpi_notify); fail_installnotify: - quickstart_btnlst_del(quickstart->btn); + quickstart_button_del(quickstart->btn); fail_config: @@ -377,13 +357,12 @@ static void quickstart_exit(void) acpi_bus_unregister_driver(&quickstart_acpi_driver); - quickstart_btnlst_free(); + quickstart_buttons_free(); } static int __init quickstart_init_input(void) { - struct quickstart_btn **ptr = &btn_list; - int count; + struct quickstart_btn *b; int ret; quickstart_input = input_allocate_device(); @@ -394,11 +373,9 @@ static int __init quickstart_init_input(void) quickstart_input->name = "Quickstart ACPI Buttons"; quickstart_input->id.bustype = BUS_HOST; - while (*ptr) { - count++; + list_for_each_entry(b, &buttons, list) { set_bit(EV_KEY, quickstart_input->evbit); - set_bit((*ptr)->id, quickstart_input->keybit); - ptr = &((*ptr)->next); + set_bit(b->id, quickstart_input->keybit); } ret = input_register_device(quickstart_input); @@ -424,7 +401,7 @@ static int __init quickstart_init(void) return ret; /* If existing bus with no devices */ - if (!btn_list) { + if (list_empty(&buttons)) { ret = -ENODEV; goto fail_pfdrv_reg; } -- cgit v1.2.3-70-g09d2 From 21c1ddf31415f5db34975760e847bf6033b4f9db Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 11 Jan 2012 23:22:48 +0100 Subject: Staging: quickstart: Use %u for printing button id Button id is of unsigned int type. Signed-off-by: Szymon Janc Signed-off-by: Greg Kroah-Hartman --- drivers/staging/quickstart/quickstart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/quickstart/quickstart.c b/drivers/staging/quickstart/quickstart.c index dbed79fefb8..9968a05eb2c 100644 --- a/drivers/staging/quickstart/quickstart.c +++ b/drivers/staging/quickstart/quickstart.c @@ -80,7 +80,7 @@ static ssize_t quickstart_buttons_show(struct device *dev, return snprintf(buf, PAGE_SIZE, "none"); list_for_each_entry(b, &buttons, list) { - count += snprintf(buf + count, PAGE_SIZE - count, "%d\t%s\n", + count += snprintf(buf + count, PAGE_SIZE - count, "%u\t%s\n", b->id, b->name); if (count >= PAGE_SIZE) { -- cgit v1.2.3-70-g09d2 From 3c92e38dc4d803a7f90a08277a9d59f920963e0c Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 11 Jan 2012 23:22:49 +0100 Subject: Staging: quickstart: Rename quickstart_btn to quickstart_button Signed-off-by: Szymon Janc Signed-off-by: Greg Kroah-Hartman --- drivers/staging/quickstart/quickstart.c | 46 ++++++++++++++++----------------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/quickstart/quickstart.c b/drivers/staging/quickstart/quickstart.c index 9968a05eb2c..a67b03a5995 100644 --- a/drivers/staging/quickstart/quickstart.c +++ b/drivers/staging/quickstart/quickstart.c @@ -52,7 +52,7 @@ MODULE_LICENSE("GPL"); #define QUICKSTART_EVENT_WAKE 0x02 #define QUICKSTART_EVENT_RUNTIME 0x80 -struct quickstart_btn { +struct quickstart_button { char *name; unsigned int id; struct list_head list; @@ -60,11 +60,11 @@ struct quickstart_btn { struct quickstart_acpi { struct acpi_device *device; - struct quickstart_btn *btn; + struct quickstart_button *button; }; static LIST_HEAD(buttons); -static struct quickstart_btn *pressed; +static struct quickstart_button *pressed; static struct input_dev *quickstart_input; @@ -74,7 +74,7 @@ static ssize_t quickstart_buttons_show(struct device *dev, char *buf) { int count = 0; - struct quickstart_btn *b; + struct quickstart_button *b; if (list_empty(&buttons)) return snprintf(buf, PAGE_SIZE, "none"); @@ -116,9 +116,9 @@ static ssize_t quickstart_pressed_button_store(struct device *dev, } /* Helper functions */ -static struct quickstart_btn *quickstart_buttons_add(void) +static struct quickstart_button *quickstart_buttons_add(void) { - struct quickstart_btn *b; + struct quickstart_button *b; b = kzalloc(sizeof(*b), GFP_KERNEL); if (!b) @@ -129,7 +129,7 @@ static struct quickstart_btn *quickstart_buttons_add(void) return b; } -static void quickstart_button_del(struct quickstart_btn *data) +static void quickstart_button_del(struct quickstart_button *data) { if (!data) return; @@ -141,7 +141,7 @@ static void quickstart_button_del(struct quickstart_btn *data) static void quickstart_buttons_free(void) { - struct quickstart_btn *b, *n; + struct quickstart_button *b, *n; list_for_each_entry_safe(b, n, &buttons, list) quickstart_button_del(b); @@ -157,12 +157,12 @@ static void quickstart_acpi_notify(acpi_handle handle, u32 event, void *data) switch (event) { case QUICKSTART_EVENT_WAKE: - pressed = quickstart->btn; + pressed = quickstart->button; break; case QUICKSTART_EVENT_RUNTIME: - input_report_key(quickstart_input, quickstart->btn->id, 1); + input_report_key(quickstart_input, quickstart->button->id, 1); input_sync(quickstart_input); - input_report_key(quickstart_input, quickstart->btn->id, 0); + input_report_key(quickstart_input, quickstart->button->id, 0); input_sync(quickstart_input); break; default: @@ -184,7 +184,7 @@ static int quickstart_acpi_ghid(struct quickstart_acpi *quickstart) &buffer); if (ACPI_FAILURE(status)) { printk(KERN_ERR "quickstart: %s GHID method failed.\n", - quickstart->btn->name); + quickstart->button->name); return -EINVAL; } @@ -195,21 +195,21 @@ static int quickstart_acpi_ghid(struct quickstart_acpi *quickstart) */ switch (buffer.length) { case 1: - quickstart->btn->id = *(uint8_t *)buffer.pointer; + quickstart->button->id = *(uint8_t *)buffer.pointer; break; case 2: - quickstart->btn->id = *(uint16_t *)buffer.pointer; + quickstart->button->id = *(uint16_t *)buffer.pointer; break; case 4: - quickstart->btn->id = *(uint32_t *)buffer.pointer; + quickstart->button->id = *(uint32_t *)buffer.pointer; break; case 8: - quickstart->btn->id = *(uint64_t *)buffer.pointer; + quickstart->button->id = *(uint64_t *)buffer.pointer; break; default: printk(KERN_ERR "quickstart: %s GHID method returned buffer " "of unexpected length %u\n", - quickstart->btn->name, buffer.length); + quickstart->button->name, buffer.length); ret = -EINVAL; break; } @@ -229,14 +229,14 @@ static int quickstart_acpi_config(struct quickstart_acpi *quickstart) return -ENOMEM; /* Add new button to list */ - quickstart->btn = quickstart_buttons_add(); - if (!quickstart->btn) { + quickstart->button = quickstart_buttons_add(); + if (!quickstart->button) { kfree(name); return -ENOMEM; } - quickstart->btn->name = name; - strcpy(quickstart->btn->name, bid); + quickstart->button->name = name; + strcpy(quickstart->button->name, bid); return 0; } @@ -285,7 +285,7 @@ fail_ghid: quickstart_acpi_notify); fail_installnotify: - quickstart_button_del(quickstart->btn); + quickstart_button_del(quickstart->button); fail_config: @@ -362,7 +362,7 @@ static void quickstart_exit(void) static int __init quickstart_init_input(void) { - struct quickstart_btn *b; + struct quickstart_button *b; int ret; quickstart_input = input_allocate_device(); -- cgit v1.2.3-70-g09d2 From b71dbbcfaa2a2965e0797db7333396a71062a341 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Tue, 20 Dec 2011 10:41:13 -0500 Subject: Staging: bcm: Fix an integer overflow in IOCTL_BCM_NVM_READ/WRITE Variables stNVMReadWrite.uioffset and stNVMReadWrite.uiNumBytes are chosen from userspace and can be very high. The sum of these two digits would result in a small number. Therefore, this patch verifies a negative number was not entered, and reorganizes the equation to remove the integer overflow. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 179707b5e7c..8bf3f575160 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -1302,8 +1302,10 @@ cntrlEnd: /* * Deny the access if the offset crosses the cal area limit. */ + if (stNVMReadWrite.uiNumBytes > Adapter->uiNVMDSDSize) + return STATUS_FAILURE; - if ((stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) > Adapter->uiNVMDSDSize) { + if (stNVMReadWrite.uiOffset > Adapter->uiNVMDSDSize - stNVMReadWrite.uiNumBytes) { /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Can't allow access beyond NVM Size: 0x%x 0x%x\n", stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes); */ return STATUS_FAILURE; } -- cgit v1.2.3-70-g09d2 From 9937fdb022156f285b761bc544d5b910faa2e585 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Wed, 4 Jan 2012 20:29:00 -0500 Subject: Staging: bcm: Fix coding style issues in CmHost.c This patch cleans up several code style issues found in CmHost.c reported by checkpatch.pl. These include: white space, braces, indents, and comments. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/CmHost.c | 3043 ++++++++++++++++++------------------------ 1 file changed, 1325 insertions(+), 1718 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index c0ee95a7134..fcb1835c68f 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -1,431 +1,359 @@ /************************************************************ -* CMHOST.C -* This file contains the routines for handling Connection -* Management. -************************************************************/ + * CMHOST.C + * This file contains the routines for handling Connection + * Management. + ************************************************************/ -//#define CONN_MSG +/* #define CONN_MSG */ #include "headers.h" -typedef enum _E_CLASSIFIER_ACTION -{ +typedef enum _E_CLASSIFIER_ACTION { eInvalidClassifierAction, eAddClassifier, eReplaceClassifier, eDeleteClassifier -}E_CLASSIFIER_ACTION; +} E_CLASSIFIER_ACTION; -static ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter,B_UINT16 tid); +static ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter, B_UINT16 tid); /************************************************************ -* Function - SearchSfid -* -* Description - This routinue would search QOS queues having -* specified SFID as input parameter. -* -* Parameters - Adapter: Pointer to the Adapter structure -* uiSfid : Given SFID for matching -* -* Returns - Queue index for this SFID(If matched) - Else Invalid Queue Index(If Not matched) -************************************************************/ -INT SearchSfid(PMINI_ADAPTER Adapter,UINT uiSfid) + * Function - SearchSfid + * + * Description - This routinue would search QOS queues having + * specified SFID as input parameter. + * + * Parameters - Adapter: Pointer to the Adapter structure + * uiSfid : Given SFID for matching + * + * Returns - Queue index for this SFID(If matched) + * Else Invalid Queue Index(If Not matched) + ************************************************************/ +INT SearchSfid(PMINI_ADAPTER Adapter, UINT uiSfid) { - INT iIndex=0; - for(iIndex=(NO_OF_QUEUES-1); iIndex>=0; iIndex--) - if(Adapter->PackInfo[iIndex].ulSFID==uiSfid) + INT iIndex = 0; + + for (iIndex = (NO_OF_QUEUES-1); iIndex >= 0; iIndex--) + if (Adapter->PackInfo[iIndex].ulSFID == uiSfid) return iIndex; + return NO_OF_QUEUES+1; } /*************************************************************** -* Function - SearchFreeSfid -* -* Description - This routinue would search Free available SFID. -* -* Parameter - Adapter: Pointer to the Adapter structure -* -* Returns - Queue index for the free SFID -* Else returns Invalid Index. -****************************************************************/ + * Function -SearchFreeSfid + * + * Description - This routinue would search Free available SFID. + * + * Parameter - Adapter: Pointer to the Adapter structure + * + * Returns - Queue index for the free SFID + * Else returns Invalid Index. + ****************************************************************/ static INT SearchFreeSfid(PMINI_ADAPTER Adapter) { - UINT uiIndex=0; + UINT uiIndex = 0; - for(uiIndex=0; uiIndex < (NO_OF_QUEUES-1); uiIndex++) - if(Adapter->PackInfo[uiIndex].ulSFID==0) + for (uiIndex = 0; uiIndex < (NO_OF_QUEUES-1); uiIndex++) + if (Adapter->PackInfo[uiIndex].ulSFID == 0) return uiIndex; + return NO_OF_QUEUES+1; } /* -Function: SearchClsid -Description: This routinue would search Classifier having specified ClassifierID as input parameter -Input parameters: PMINI_ADAPTER Adapter - Adapter Context - unsigned int uiSfid - The SF in which the classifier is to searched - B_UINT16 uiClassifierID - The classifier ID to be searched -Return: int :Classifier table index of matching entry -*/ - -static int SearchClsid(PMINI_ADAPTER Adapter,ULONG ulSFID,B_UINT16 uiClassifierID) + * Function: SearchClsid + * Description: This routinue would search Classifier having specified ClassifierID as input parameter + * Input parameters: PMINI_ADAPTER Adapter - Adapter Context + * unsigned int uiSfid - The SF in which the classifier is to searched + * B_UINT16 uiClassifierID - The classifier ID to be searched + * Return: int :Classifier table index of matching entry + */ +static int SearchClsid(PMINI_ADAPTER Adapter, ULONG ulSFID, B_UINT16 uiClassifierID) { unsigned int uiClassifierIndex = 0; - for(uiClassifierIndex=0;uiClassifierIndexastClassifierTable[uiClassifierIndex].bUsed) && - (Adapter->astClassifierTable[uiClassifierIndex].uiClassifierRuleIndex == uiClassifierID)&& + + for (uiClassifierIndex = 0; uiClassifierIndex < MAX_CLASSIFIERS; uiClassifierIndex++) { + if ((Adapter->astClassifierTable[uiClassifierIndex].bUsed) && + (Adapter->astClassifierTable[uiClassifierIndex].uiClassifierRuleIndex == uiClassifierID) && (Adapter->astClassifierTable[uiClassifierIndex].ulSFID == ulSFID)) return uiClassifierIndex; } + return MAX_CLASSIFIERS+1; } -/** -@ingroup ctrl_pkt_functions -This routinue would search Free available Classifier entry in classifier table. -@return free Classifier Entry index in classifier table for specified SF -*/ -static int SearchFreeClsid(PMINI_ADAPTER Adapter /**Adapter Context*/ - ) +/* + * @ingroup ctrl_pkt_functions + * This routinue would search Free available Classifier entry in classifier table. + * @return free Classifier Entry index in classifier table for specified SF + */ +static int SearchFreeClsid(PMINI_ADAPTER Adapter /**Adapter Context*/) { unsigned int uiClassifierIndex = 0; - for(uiClassifierIndex=0;uiClassifierIndexastClassifierTable[uiClassifierIndex].bUsed) + + for (uiClassifierIndex = 0; uiClassifierIndex < MAX_CLASSIFIERS; uiClassifierIndex++) { + if (!Adapter->astClassifierTable[uiClassifierIndex].bUsed) return uiClassifierIndex; } + return MAX_CLASSIFIERS+1; } static VOID deleteSFBySfid(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex) { - //deleting all the packet held in the SF - flush_queue(Adapter,uiSearchRuleIndex); + /* deleting all the packet held in the SF */ + flush_queue(Adapter, uiSearchRuleIndex); - //Deleting the all classifiers for this SF - DeleteAllClassifiersForSF(Adapter,uiSearchRuleIndex); + /* Deleting the all classifiers for this SF */ + DeleteAllClassifiersForSF(Adapter, uiSearchRuleIndex); - //Resetting only MIBS related entries in the SF + /* Resetting only MIBS related entries in the SF */ memset((PVOID)&Adapter->PackInfo[uiSearchRuleIndex], 0, sizeof(S_MIBS_SERVICEFLOW_TABLE)); } static inline VOID -CopyIpAddrToClassifier(S_CLASSIFIER_RULE *pstClassifierEntry , - B_UINT8 u8IpAddressLen , B_UINT8 *pu8IpAddressMaskSrc , - BOOLEAN bIpVersion6 , E_IPADDR_CONTEXT eIpAddrContext) +CopyIpAddrToClassifier(S_CLASSIFIER_RULE *pstClassifierEntry, + B_UINT8 u8IpAddressLen, B_UINT8 *pu8IpAddressMaskSrc, + BOOLEAN bIpVersion6, E_IPADDR_CONTEXT eIpAddrContext) { - UINT ucLoopIndex=0; - UINT nSizeOfIPAddressInBytes = IP_LENGTH_OF_ADDRESS; - UCHAR *ptrClassifierIpAddress = NULL; - UCHAR *ptrClassifierIpMask = NULL; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + UINT ucLoopIndex = 0; + UINT nSizeOfIPAddressInBytes = IP_LENGTH_OF_ADDRESS; + UCHAR *ptrClassifierIpAddress = NULL; + UCHAR *ptrClassifierIpMask = NULL; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); - if(bIpVersion6) - { + if (bIpVersion6) nSizeOfIPAddressInBytes = IPV6_ADDRESS_SIZEINBYTES; - } - //Destination Ip Address - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Ip Address Range Length:0x%X ", - u8IpAddressLen); - if((bIpVersion6?(IPV6_ADDRESS_SIZEINBYTES * MAX_IP_RANGE_LENGTH * 2): - (TOTAL_MASKED_ADDRESS_IN_BYTES)) >= u8IpAddressLen) - { + + /* Destination Ip Address */ + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Ip Address Range Length:0x%X ", u8IpAddressLen); + if ((bIpVersion6 ? (IPV6_ADDRESS_SIZEINBYTES * MAX_IP_RANGE_LENGTH * 2) : + (TOTAL_MASKED_ADDRESS_IN_BYTES)) >= u8IpAddressLen) { /* - //checking both the mask and address togethor in Classification. - //So length will be : TotalLengthInBytes/nSizeOfIPAddressInBytes * 2 - //(nSizeOfIPAddressInBytes for address and nSizeOfIPAddressInBytes for mask) - */ - if(eIpAddrContext == eDestIpAddress) - { - pstClassifierEntry->ucIPDestinationAddressLength = - u8IpAddressLen/(nSizeOfIPAddressInBytes * 2); - if(bIpVersion6) - { - ptrClassifierIpAddress = - pstClassifierEntry->stDestIpAddress.ucIpv6Address; - ptrClassifierIpMask = - pstClassifierEntry->stDestIpAddress.ucIpv6Mask; + * checking both the mask and address togethor in Classification. + * So length will be : TotalLengthInBytes/nSizeOfIPAddressInBytes * 2 + * (nSizeOfIPAddressInBytes for address and nSizeOfIPAddressInBytes for mask) + */ + if (eIpAddrContext == eDestIpAddress) { + pstClassifierEntry->ucIPDestinationAddressLength = u8IpAddressLen/(nSizeOfIPAddressInBytes * 2); + if (bIpVersion6) { + ptrClassifierIpAddress = pstClassifierEntry->stDestIpAddress.ucIpv6Address; + ptrClassifierIpMask = pstClassifierEntry->stDestIpAddress.ucIpv6Mask; + } else { + ptrClassifierIpAddress = pstClassifierEntry->stDestIpAddress.ucIpv4Address; + ptrClassifierIpMask = pstClassifierEntry->stDestIpAddress.ucIpv4Mask; } - else - { - ptrClassifierIpAddress = - pstClassifierEntry->stDestIpAddress.ucIpv4Address; - ptrClassifierIpMask = - pstClassifierEntry->stDestIpAddress.ucIpv4Mask; + } else if (eIpAddrContext == eSrcIpAddress) { + pstClassifierEntry->ucIPSourceAddressLength = u8IpAddressLen/(nSizeOfIPAddressInBytes * 2); + if (bIpVersion6) { + ptrClassifierIpAddress = pstClassifierEntry->stSrcIpAddress.ucIpv6Address; + ptrClassifierIpMask = pstClassifierEntry->stSrcIpAddress.ucIpv6Mask; + } else { + ptrClassifierIpAddress = pstClassifierEntry->stSrcIpAddress.ucIpv4Address; + ptrClassifierIpMask = pstClassifierEntry->stSrcIpAddress.ucIpv4Mask; } } - else if(eIpAddrContext == eSrcIpAddress) - { - pstClassifierEntry->ucIPSourceAddressLength = - u8IpAddressLen/(nSizeOfIPAddressInBytes * 2); - if(bIpVersion6) - { - ptrClassifierIpAddress = - pstClassifierEntry->stSrcIpAddress.ucIpv6Address; - ptrClassifierIpMask = - pstClassifierEntry->stSrcIpAddress.ucIpv6Mask; - } - else - { - ptrClassifierIpAddress = - pstClassifierEntry->stSrcIpAddress.ucIpv4Address; - ptrClassifierIpMask = - pstClassifierEntry->stSrcIpAddress.ucIpv4Mask; - } - } - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Address Length:0x%X \n", - pstClassifierEntry->ucIPDestinationAddressLength); - while((u8IpAddressLen>= nSizeOfIPAddressInBytes) && - (ucLoopIndex < MAX_IP_RANGE_LENGTH)) - { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Address Length:0x%X\n", pstClassifierEntry->ucIPDestinationAddressLength); + while ((u8IpAddressLen >= nSizeOfIPAddressInBytes) && (ucLoopIndex < MAX_IP_RANGE_LENGTH)) { memcpy(ptrClassifierIpAddress + (ucLoopIndex * nSizeOfIPAddressInBytes), (pu8IpAddressMaskSrc+(ucLoopIndex*nSizeOfIPAddressInBytes*2)), nSizeOfIPAddressInBytes); - if(!bIpVersion6) - { - if(eIpAddrContext == eSrcIpAddress) - { - pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[ucLoopIndex]= - ntohl(pstClassifierEntry->stSrcIpAddress. - ulIpv4Addr[ucLoopIndex]); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Src Ip Address:0x%luX ",pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[ucLoopIndex]); - } - else if(eIpAddrContext == eDestIpAddress) - { - pstClassifierEntry->stDestIpAddress.ulIpv4Addr[ucLoopIndex]= ntohl(pstClassifierEntry->stDestIpAddress. - ulIpv4Addr[ucLoopIndex]); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Dest Ip Address:0x%luX ",pstClassifierEntry->stDestIpAddress.ulIpv4Addr[ucLoopIndex]); + + if (!bIpVersion6) { + if (eIpAddrContext == eSrcIpAddress) { + pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[ucLoopIndex] = ntohl(pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[ucLoopIndex]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Src Ip Address:0x%luX ", + pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[ucLoopIndex]); + } else if (eIpAddrContext == eDestIpAddress) { + pstClassifierEntry->stDestIpAddress.ulIpv4Addr[ucLoopIndex] = ntohl(pstClassifierEntry->stDestIpAddress.ulIpv4Addr[ucLoopIndex]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Dest Ip Address:0x%luX ", + pstClassifierEntry->stDestIpAddress.ulIpv4Addr[ucLoopIndex]); } } - u8IpAddressLen-=nSizeOfIPAddressInBytes; - if(u8IpAddressLen >= nSizeOfIPAddressInBytes) - { + u8IpAddressLen -= nSizeOfIPAddressInBytes; + if (u8IpAddressLen >= nSizeOfIPAddressInBytes) { memcpy(ptrClassifierIpMask + (ucLoopIndex * nSizeOfIPAddressInBytes), (pu8IpAddressMaskSrc+nSizeOfIPAddressInBytes + - (ucLoopIndex*nSizeOfIPAddressInBytes*2)), + (ucLoopIndex*nSizeOfIPAddressInBytes*2)), nSizeOfIPAddressInBytes); - if(!bIpVersion6) - { - if(eIpAddrContext == eSrcIpAddress) - { - pstClassifierEntry->stSrcIpAddress. - ulIpv4Mask[ucLoopIndex]= - ntohl(pstClassifierEntry->stSrcIpAddress. - ulIpv4Mask[ucLoopIndex]); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Src Ip Mask Address:0x%luX ",pstClassifierEntry->stSrcIpAddress.ulIpv4Mask[ucLoopIndex]); - } - else if(eIpAddrContext == eDestIpAddress) - { - pstClassifierEntry->stDestIpAddress. - ulIpv4Mask[ucLoopIndex] = - ntohl(pstClassifierEntry->stDestIpAddress. - ulIpv4Mask[ucLoopIndex]); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Dest Ip Mask Address:0x%luX ",pstClassifierEntry->stDestIpAddress.ulIpv4Mask[ucLoopIndex]); + + if (!bIpVersion6) { + if (eIpAddrContext == eSrcIpAddress) { + pstClassifierEntry->stSrcIpAddress.ulIpv4Mask[ucLoopIndex] = + ntohl(pstClassifierEntry->stSrcIpAddress.ulIpv4Mask[ucLoopIndex]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Src Ip Mask Address:0x%luX ", + pstClassifierEntry->stSrcIpAddress.ulIpv4Mask[ucLoopIndex]); + } else if (eIpAddrContext == eDestIpAddress) { + pstClassifierEntry->stDestIpAddress.ulIpv4Mask[ucLoopIndex] = + ntohl(pstClassifierEntry->stDestIpAddress.ulIpv4Mask[ucLoopIndex]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Dest Ip Mask Address:0x%luX ", + pstClassifierEntry->stDestIpAddress.ulIpv4Mask[ucLoopIndex]); } } - u8IpAddressLen-=nSizeOfIPAddressInBytes; - } - if(0==u8IpAddressLen) - { - pstClassifierEntry->bDestIpValid=TRUE; + u8IpAddressLen -= nSizeOfIPAddressInBytes; } + if (0 == u8IpAddressLen) + pstClassifierEntry->bDestIpValid = TRUE; + ucLoopIndex++; } - if(bIpVersion6) - { - //Restore EndianNess of Struct - for(ucLoopIndex =0 ; ucLoopIndex < MAX_IP_RANGE_LENGTH * 4 ; - ucLoopIndex++) - { - if(eIpAddrContext == eSrcIpAddress) - { - pstClassifierEntry->stSrcIpAddress.ulIpv6Addr[ucLoopIndex]= - ntohl(pstClassifierEntry->stSrcIpAddress. - ulIpv6Addr[ucLoopIndex]); - pstClassifierEntry->stSrcIpAddress.ulIpv6Mask[ucLoopIndex]= ntohl(pstClassifierEntry->stSrcIpAddress. - ulIpv6Mask[ucLoopIndex]); - } - else if(eIpAddrContext == eDestIpAddress) - { - pstClassifierEntry->stDestIpAddress.ulIpv6Addr[ucLoopIndex]= ntohl(pstClassifierEntry->stDestIpAddress. - ulIpv6Addr[ucLoopIndex]); - pstClassifierEntry->stDestIpAddress.ulIpv6Mask[ucLoopIndex]= ntohl(pstClassifierEntry->stDestIpAddress. - ulIpv6Mask[ucLoopIndex]); + if (bIpVersion6) { + /* Restore EndianNess of Struct */ + for (ucLoopIndex = 0; ucLoopIndex < MAX_IP_RANGE_LENGTH * 4; ucLoopIndex++) { + if (eIpAddrContext == eSrcIpAddress) { + pstClassifierEntry->stSrcIpAddress.ulIpv6Addr[ucLoopIndex] = ntohl(pstClassifierEntry->stSrcIpAddress.ulIpv6Addr[ucLoopIndex]); + pstClassifierEntry->stSrcIpAddress.ulIpv6Mask[ucLoopIndex] = ntohl(pstClassifierEntry->stSrcIpAddress.ulIpv6Mask[ucLoopIndex]); + } else if (eIpAddrContext == eDestIpAddress) { + pstClassifierEntry->stDestIpAddress.ulIpv6Addr[ucLoopIndex] = ntohl(pstClassifierEntry->stDestIpAddress.ulIpv6Addr[ucLoopIndex]); + pstClassifierEntry->stDestIpAddress.ulIpv6Mask[ucLoopIndex] = ntohl(pstClassifierEntry->stDestIpAddress.ulIpv6Mask[ucLoopIndex]); } } } } } - -void ClearTargetDSXBuffer(PMINI_ADAPTER Adapter,B_UINT16 TID,BOOLEAN bFreeAll) +void ClearTargetDSXBuffer(PMINI_ADAPTER Adapter, B_UINT16 TID, BOOLEAN bFreeAll) { - ULONG ulIndex; - for(ulIndex=0; ulIndex < Adapter->ulTotalTargetBuffersAvailable; ulIndex++) - { - if(Adapter->astTargetDsxBuffer[ulIndex].valid) + ULONG ulIndex; + + for (ulIndex = 0; ulIndex < Adapter->ulTotalTargetBuffersAvailable; ulIndex++) { + if (Adapter->astTargetDsxBuffer[ulIndex].valid) continue; - if ((bFreeAll) || (Adapter->astTargetDsxBuffer[ulIndex].tid == TID)){ - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "ClearTargetDSXBuffer: found tid %d buffer cleared %lx\n", - TID, Adapter->astTargetDsxBuffer[ulIndex].ulTargetDsxBuffer); - Adapter->astTargetDsxBuffer[ulIndex].valid=1; - Adapter->astTargetDsxBuffer[ulIndex].tid=0; + + if ((bFreeAll) || (Adapter->astTargetDsxBuffer[ulIndex].tid == TID)) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "ClearTargetDSXBuffer: found tid %d buffer cleared %lx\n", + TID, Adapter->astTargetDsxBuffer[ulIndex].ulTargetDsxBuffer); + Adapter->astTargetDsxBuffer[ulIndex].valid = 1; + Adapter->astTargetDsxBuffer[ulIndex].tid = 0; Adapter->ulFreeTargetBufferCnt++; - } + } } } -/** -@ingroup ctrl_pkt_functions -copy classifier rule into the specified SF index -*/ -static inline VOID CopyClassifierRuleToSF(PMINI_ADAPTER Adapter,stConvergenceSLTypes *psfCSType,UINT uiSearchRuleIndex,UINT nClassifierIndex) +/* + * @ingroup ctrl_pkt_functions + * copy classifier rule into the specified SF index + */ +static inline VOID CopyClassifierRuleToSF(PMINI_ADAPTER Adapter, stConvergenceSLTypes *psfCSType, UINT uiSearchRuleIndex, UINT nClassifierIndex) { S_CLASSIFIER_RULE *pstClassifierEntry = NULL; - //VOID *pvPhsContext = NULL; - UINT ucLoopIndex=0; - //UCHAR ucProtocolLength=0; - //ULONG ulPhsStatus; + /* VOID *pvPhsContext = NULL; */ + UINT ucLoopIndex = 0; + /* UCHAR ucProtocolLength=0; */ + /* ULONG ulPhsStatus; */ - - if(Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value == 0 || + if (Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value == 0 || nClassifierIndex > (MAX_CLASSIFIERS-1)) return; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Storing Classifier Rule Index : %X", + ntohs(psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex)); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Storing Classifier Rule Index : %X",ntohs(psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex)); - - if(nClassifierIndex > MAX_CLASSIFIERS-1) + if (nClassifierIndex > MAX_CLASSIFIERS-1) return; pstClassifierEntry = &Adapter->astClassifierTable[nClassifierIndex]; - if(pstClassifierEntry) - { - //Store if Ipv6 - pstClassifierEntry->bIpv6Protocol = - (Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6)?TRUE:FALSE; - - //Destinaiton Port - pstClassifierEntry->ucDestPortRangeLength=psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength/4; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Destination Port Range Length:0x%X ",pstClassifierEntry->ucDestPortRangeLength); - if( MAX_PORT_RANGE >= psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength) - { - for(ucLoopIndex=0;ucLoopIndex<(pstClassifierEntry->ucDestPortRangeLength);ucLoopIndex++) - { - pstClassifierEntry->usDestPortRangeLo[ucLoopIndex] = - *((PUSHORT)(psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange+ucLoopIndex)); + if (pstClassifierEntry) { + /* Store if Ipv6 */ + pstClassifierEntry->bIpv6Protocol = (Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6) ? TRUE : FALSE; + + /* Destinaiton Port */ + pstClassifierEntry->ucDestPortRangeLength = psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength / 4; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Destination Port Range Length:0x%X ", pstClassifierEntry->ucDestPortRangeLength); + + if (MAX_PORT_RANGE >= psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength) { + for (ucLoopIndex = 0; ucLoopIndex < (pstClassifierEntry->ucDestPortRangeLength); ucLoopIndex++) { + pstClassifierEntry->usDestPortRangeLo[ucLoopIndex] = *((PUSHORT)(psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange+ucLoopIndex)); pstClassifierEntry->usDestPortRangeHi[ucLoopIndex] = *((PUSHORT)(psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange+2+ucLoopIndex)); - pstClassifierEntry->usDestPortRangeLo[ucLoopIndex]=ntohs(pstClassifierEntry->usDestPortRangeLo[ucLoopIndex]); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Destination Port Range Lo:0x%X ",pstClassifierEntry->usDestPortRangeLo[ucLoopIndex]); - pstClassifierEntry->usDestPortRangeHi[ucLoopIndex]=ntohs(pstClassifierEntry->usDestPortRangeHi[ucLoopIndex]); + pstClassifierEntry->usDestPortRangeLo[ucLoopIndex] = ntohs(pstClassifierEntry->usDestPortRangeLo[ucLoopIndex]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Destination Port Range Lo:0x%X ", + pstClassifierEntry->usDestPortRangeLo[ucLoopIndex]); + pstClassifierEntry->usDestPortRangeHi[ucLoopIndex] = ntohs(pstClassifierEntry->usDestPortRangeHi[ucLoopIndex]); } + } else { + pstClassifierEntry->ucDestPortRangeLength = 0; } - else - { - pstClassifierEntry->ucDestPortRangeLength=0; - } - //Source Port - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Source Port Range Length:0x%X ",psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength); - if(MAX_PORT_RANGE >= - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength) - { - pstClassifierEntry->ucSrcPortRangeLength = - psfCSType->cCPacketClassificationRule. - u8ProtocolSourcePortRangeLength/4; - for(ucLoopIndex = 0; ucLoopIndex < - (pstClassifierEntry->ucSrcPortRangeLength); ucLoopIndex++) - { + + /* Source Port */ + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Source Port Range Length:0x%X ", + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength); + if (MAX_PORT_RANGE >= psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength) { + pstClassifierEntry->ucSrcPortRangeLength = psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength/4; + for (ucLoopIndex = 0; ucLoopIndex < (pstClassifierEntry->ucSrcPortRangeLength); ucLoopIndex++) { pstClassifierEntry->usSrcPortRangeLo[ucLoopIndex] = - *((PUSHORT)(psfCSType->cCPacketClassificationRule. + *((PUSHORT)(psfCSType->cCPacketClassificationRule. u8ProtocolSourcePortRange+ucLoopIndex)); pstClassifierEntry->usSrcPortRangeHi[ucLoopIndex] = - *((PUSHORT)(psfCSType->cCPacketClassificationRule. + *((PUSHORT)(psfCSType->cCPacketClassificationRule. u8ProtocolSourcePortRange+2+ucLoopIndex)); pstClassifierEntry->usSrcPortRangeLo[ucLoopIndex] = ntohs(pstClassifierEntry->usSrcPortRangeLo[ucLoopIndex]); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Source Port Range Lo:0x%X ",pstClassifierEntry->usSrcPortRangeLo[ucLoopIndex]); - pstClassifierEntry->usSrcPortRangeHi[ucLoopIndex]=ntohs(pstClassifierEntry->usSrcPortRangeHi[ucLoopIndex]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Source Port Range Lo:0x%X ", + pstClassifierEntry->usSrcPortRangeLo[ucLoopIndex]); + pstClassifierEntry->usSrcPortRangeHi[ucLoopIndex] = ntohs(pstClassifierEntry->usSrcPortRangeHi[ucLoopIndex]); } } - //Destination Ip Address and Mask - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Ip Destination Parameters : "); - + /* Destination Ip Address and Mask */ + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Ip Destination Parameters : "); CopyIpAddrToClassifier(pstClassifierEntry, - psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength, - psfCSType->cCPacketClassificationRule.u8IPDestinationAddress, - (Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6)? - TRUE:FALSE, eDestIpAddress); + psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength, + psfCSType->cCPacketClassificationRule.u8IPDestinationAddress, + (Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6) ? + TRUE : FALSE, eDestIpAddress); - //Source Ip Address and Mask - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Ip Source Parameters : "); + /* Source Ip Address and Mask */ + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Ip Source Parameters : "); CopyIpAddrToClassifier(pstClassifierEntry, - psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength, - psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress, - (Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6)?TRUE:FALSE, - eSrcIpAddress); - - //TOS - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"TOS Length:0x%X ",psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength); - if(3 == psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength) - { - pstClassifierEntry->ucIPTypeOfServiceLength = - psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength; - pstClassifierEntry->ucTosLow = - psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0]; - pstClassifierEntry->ucTosHigh = - psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1]; - pstClassifierEntry->ucTosMask = - psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]; + psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength, + psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress, + (Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6) ? TRUE : FALSE, + eSrcIpAddress); + + /* TOS */ + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "TOS Length:0x%X ", psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength); + if (3 == psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength) { + pstClassifierEntry->ucIPTypeOfServiceLength = psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength; + pstClassifierEntry->ucTosLow = psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0]; + pstClassifierEntry->ucTosHigh = psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1]; + pstClassifierEntry->ucTosMask = psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]; pstClassifierEntry->bTOSValid = TRUE; } - if(psfCSType->cCPacketClassificationRule.u8Protocol == 0) - { - //we didn't get protocol field filled in by the BS - pstClassifierEntry->ucProtocolLength=0; - } - else - { - pstClassifierEntry->ucProtocolLength=1;// 1 valid protocol + if (psfCSType->cCPacketClassificationRule.u8Protocol == 0) { + /* we didn't get protocol field filled in by the BS */ + pstClassifierEntry->ucProtocolLength = 0; + } else { + pstClassifierEntry->ucProtocolLength = 1; /* 1 valid protocol */ } - pstClassifierEntry->ucProtocol[0] = - psfCSType->cCPacketClassificationRule.u8Protocol; - - pstClassifierEntry->u8ClassifierRulePriority = - psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority; - - //store the classifier rule ID and set this classifier entry as valid - pstClassifierEntry->ucDirection = - Adapter->PackInfo[uiSearchRuleIndex].ucDirection; - pstClassifierEntry->uiClassifierRuleIndex = ntohs(psfCSType-> - cCPacketClassificationRule.u16PacketClassificationRuleIndex); - pstClassifierEntry->usVCID_Value = - Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value; - pstClassifierEntry->ulSFID = - Adapter->PackInfo[uiSearchRuleIndex].ulSFID; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Search Index %d Dir: %d, Index: %d, Vcid: %d\n", - uiSearchRuleIndex, pstClassifierEntry->ucDirection, - pstClassifierEntry->uiClassifierRuleIndex, - pstClassifierEntry->usVCID_Value); - - if(psfCSType->cCPacketClassificationRule.u8AssociatedPHSI) - { + pstClassifierEntry->ucProtocol[0] = psfCSType->cCPacketClassificationRule.u8Protocol; + pstClassifierEntry->u8ClassifierRulePriority = psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority; + + /* store the classifier rule ID and set this classifier entry as valid */ + pstClassifierEntry->ucDirection = Adapter->PackInfo[uiSearchRuleIndex].ucDirection; + pstClassifierEntry->uiClassifierRuleIndex = ntohs(psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex); + pstClassifierEntry->usVCID_Value = Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value; + pstClassifierEntry->ulSFID = Adapter->PackInfo[uiSearchRuleIndex].ulSFID; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Search Index %d Dir: %d, Index: %d, Vcid: %d\n", + uiSearchRuleIndex, pstClassifierEntry->ucDirection, + pstClassifierEntry->uiClassifierRuleIndex, + pstClassifierEntry->usVCID_Value); + + if (psfCSType->cCPacketClassificationRule.u8AssociatedPHSI) pstClassifierEntry->u8AssociatedPHSI = psfCSType->cCPacketClassificationRule.u8AssociatedPHSI; - } - //Copy ETH CS Parameters + /* Copy ETH CS Parameters */ pstClassifierEntry->ucEthCSSrcMACLen = (psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddressLength); - memcpy(pstClassifierEntry->au8EThCSSrcMAC,psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress,MAC_ADDRESS_SIZE); - memcpy(pstClassifierEntry->au8EThCSSrcMACMask,psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress+MAC_ADDRESS_SIZE,MAC_ADDRESS_SIZE); + memcpy(pstClassifierEntry->au8EThCSSrcMAC, psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress, MAC_ADDRESS_SIZE); + memcpy(pstClassifierEntry->au8EThCSSrcMACMask, psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress + MAC_ADDRESS_SIZE, MAC_ADDRESS_SIZE); pstClassifierEntry->ucEthCSDestMACLen = (psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); - memcpy(pstClassifierEntry->au8EThCSDestMAC,psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress,MAC_ADDRESS_SIZE); - memcpy(pstClassifierEntry->au8EThCSDestMACMask,psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress+MAC_ADDRESS_SIZE,MAC_ADDRESS_SIZE); + memcpy(pstClassifierEntry->au8EThCSDestMAC, psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress, MAC_ADDRESS_SIZE); + memcpy(pstClassifierEntry->au8EThCSDestMACMask, psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress + MAC_ADDRESS_SIZE, MAC_ADDRESS_SIZE); pstClassifierEntry->ucEtherTypeLen = (psfCSType->cCPacketClassificationRule.u8EthertypeLength); - memcpy(pstClassifierEntry->au8EthCSEtherType,psfCSType->cCPacketClassificationRule.u8Ethertype,NUM_ETHERTYPE_BYTES); + memcpy(pstClassifierEntry->au8EthCSEtherType, psfCSType->cCPacketClassificationRule.u8Ethertype, NUM_ETHERTYPE_BYTES); memcpy(pstClassifierEntry->usUserPriority, &psfCSType->cCPacketClassificationRule.u16UserPriority, 2); pstClassifierEntry->usVLANID = ntohs(psfCSType->cCPacketClassificationRule.u16VLANID); pstClassifierEntry->usValidityBitMap = ntohs(psfCSType->cCPacketClassificationRule.u16ValidityBitMap); @@ -434,244 +362,199 @@ static inline VOID CopyClassifierRuleToSF(PMINI_ADAPTER Adapter,stConvergenceSLT } } - -/** -@ingroup ctrl_pkt_functions -*/ -static inline VOID DeleteClassifierRuleFromSF(PMINI_ADAPTER Adapter,UINT uiSearchRuleIndex,UINT nClassifierIndex) +/* + * @ingroup ctrl_pkt_functions + */ +static inline VOID DeleteClassifierRuleFromSF(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex, UINT nClassifierIndex) { S_CLASSIFIER_RULE *pstClassifierEntry = NULL; - B_UINT16 u16PacketClassificationRuleIndex; - USHORT usVCID; - //VOID *pvPhsContext = NULL; - //ULONG ulPhsStatus; + B_UINT16 u16PacketClassificationRuleIndex; + USHORT usVCID; + /* VOID *pvPhsContext = NULL; */ + /*ULONG ulPhsStatus; */ usVCID = Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value; - if(nClassifierIndex > MAX_CLASSIFIERS-1) + if (nClassifierIndex > MAX_CLASSIFIERS-1) return; - if(usVCID == 0) + if (usVCID == 0) return; u16PacketClassificationRuleIndex = Adapter->astClassifierTable[nClassifierIndex].uiClassifierRuleIndex; - - pstClassifierEntry = &Adapter->astClassifierTable[nClassifierIndex]; - if(pstClassifierEntry) - { + if (pstClassifierEntry) { pstClassifierEntry->bUsed = FALSE; pstClassifierEntry->uiClassifierRuleIndex = 0; - memset(pstClassifierEntry,0,sizeof(S_CLASSIFIER_RULE)); + memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_RULE)); - //Delete the PHS Rule for this classifier - PhsDeleteClassifierRule( - &Adapter->stBCMPhsContext, - usVCID, - u16PacketClassificationRuleIndex); + /* Delete the PHS Rule for this classifier */ + PhsDeleteClassifierRule(&Adapter->stBCMPhsContext, usVCID, u16PacketClassificationRuleIndex); } } -/** -@ingroup ctrl_pkt_functions -*/ -VOID DeleteAllClassifiersForSF(PMINI_ADAPTER Adapter,UINT uiSearchRuleIndex) +/* + * @ingroup ctrl_pkt_functions + */ +VOID DeleteAllClassifiersForSF(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex) { S_CLASSIFIER_RULE *pstClassifierEntry = NULL; UINT nClassifierIndex; - //B_UINT16 u16PacketClassificationRuleIndex; - USHORT ulVCID; - //VOID *pvPhsContext = NULL; - //ULONG ulPhsStatus; + /* B_UINT16 u16PacketClassificationRuleIndex; */ + USHORT ulVCID; + /* VOID *pvPhsContext = NULL; */ + /* ULONG ulPhsStatus; */ ulVCID = Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value; - if(ulVCID == 0) + if (ulVCID == 0) return; - - for(nClassifierIndex =0 ; nClassifierIndex < MAX_CLASSIFIERS ; nClassifierIndex++) - { - if(Adapter->astClassifierTable[nClassifierIndex].usVCID_Value == ulVCID) - { + for (nClassifierIndex = 0; nClassifierIndex < MAX_CLASSIFIERS; nClassifierIndex++) { + if (Adapter->astClassifierTable[nClassifierIndex].usVCID_Value == ulVCID) { pstClassifierEntry = &Adapter->astClassifierTable[nClassifierIndex]; - if(pstClassifierEntry->bUsed) - { - DeleteClassifierRuleFromSF(Adapter,uiSearchRuleIndex,nClassifierIndex); - } + + if (pstClassifierEntry->bUsed) + DeleteClassifierRuleFromSF(Adapter, uiSearchRuleIndex, nClassifierIndex); } } - //Delete All Phs Rules Associated with this SF - PhsDeleteSFRules( - &Adapter->stBCMPhsContext, - ulVCID); - + /* Delete All Phs Rules Associated with this SF */ + PhsDeleteSFRules(&Adapter->stBCMPhsContext, ulVCID); } - -/** -This routinue copies the Connection Management -related data into the Adapter structure. -@ingroup ctrl_pkt_functions -*/ - -static VOID CopyToAdapter( register PMINI_ADAPTER Adapter, /**PackInfo[uiSearchRuleIndex].usVCID_Value; UINT UGIValue = 0; - - Adapter->PackInfo[uiSearchRuleIndex].bValid=TRUE; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Search Rule Index = %d\n", uiSearchRuleIndex); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"%s: SFID= %x ",__FUNCTION__, ntohl(psfLocalSet->u32SFID)); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Updating Queue %d",uiSearchRuleIndex); + Adapter->PackInfo[uiSearchRuleIndex].bValid = TRUE; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Search Rule Index = %d\n", uiSearchRuleIndex); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "%s: SFID= %x ", __FUNCTION__, ntohl(psfLocalSet->u32SFID)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Updating Queue %d", uiSearchRuleIndex); ulSFID = ntohl(psfLocalSet->u32SFID); - //Store IP Version used - //Get The Version Of IP used (IPv6 or IPv4) from CSSpecification field of SF + /* Store IP Version used */ + /* Get The Version Of IP used (IPv6 or IPv4) from CSSpecification field of SF */ Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = 0; Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = 0; - /*Enable IP/ETh CS Support As Required*/ - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"CopyToAdapter : u8CSSpecification : %X\n",psfLocalSet->u8CSSpecification); - switch(psfLocalSet->u8CSSpecification) + /* Enable IP/ETh CS Support As Required */ + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "CopyToAdapter : u8CSSpecification : %X\n", psfLocalSet->u8CSSpecification); + switch (psfLocalSet->u8CSSpecification) { + case eCSPacketIPV4: { - case eCSPacketIPV4: - { - Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV4_CS; - break; - } - case eCSPacketIPV6: - { - Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV6_CS; - break; - } - - case eCS802_3PacketEthernet: - case eCS802_1QPacketVLAN: - { - Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = ETH_CS_802_3; - break; - } - - case eCSPacketIPV4Over802_1QVLAN: - case eCSPacketIPV4Over802_3Ethernet: - { - Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV4_CS; - Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = ETH_CS_802_3; - break; - } - - case eCSPacketIPV6Over802_1QVLAN: - case eCSPacketIPV6Over802_3Ethernet: - { - Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV6_CS; - Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = ETH_CS_802_3; - break; - } - - default: - { - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Error in value of CS Classification.. setting default to IP CS\n"); - Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV4_CS; - break; - } + Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV4_CS; + break; + } + case eCSPacketIPV6: + { + Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV6_CS; + break; + } + case eCS802_3PacketEthernet: + case eCS802_1QPacketVLAN: + { + Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = ETH_CS_802_3; + break; + } + case eCSPacketIPV4Over802_1QVLAN: + case eCSPacketIPV4Over802_3Ethernet: + { + Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV4_CS; + Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = ETH_CS_802_3; + break; + } + case eCSPacketIPV6Over802_1QVLAN: + case eCSPacketIPV6Over802_3Ethernet: + { + Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV6_CS; + Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = ETH_CS_802_3; + break; + } + default: + { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Error in value of CS Classification.. setting default to IP CS\n"); + Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV4_CS; + break; + } } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"CopyToAdapter : Queue No : %X ETH CS Support : %X , IP CS Support : %X \n", - uiSearchRuleIndex, - Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport, - Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "CopyToAdapter : Queue No : %X ETH CS Support : %X , IP CS Support : %X\n", + uiSearchRuleIndex, + Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport, + Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport); - //Store IP Version used - //Get The Version Of IP used (IPv6 or IPv4) from CSSpecification field of SF - if(Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport == IPV6_CS) - { + /* Store IP Version used */ + /* Get The Version Of IP used (IPv6 or IPv4) from CSSpecification field of SF */ + if (Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport == IPV6_CS) Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion = IPV6; - } else - { Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion = IPV4; - } /* To ensure that the ETH CS code doesn't gets executed if the BS doesn't supports ETH CS */ - if(!Adapter->bETHCSEnabled) + if (!Adapter->bETHCSEnabled) Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = 0; - if(psfLocalSet->u8ServiceClassNameLength > 0 && - psfLocalSet->u8ServiceClassNameLength < 32) - { - memcpy(Adapter->PackInfo[uiSearchRuleIndex].ucServiceClassName, - psfLocalSet->u8ServiceClassName, - psfLocalSet->u8ServiceClassNameLength); - } - Adapter->PackInfo[uiSearchRuleIndex].u8QueueType = - psfLocalSet->u8ServiceFlowSchedulingType; + if (psfLocalSet->u8ServiceClassNameLength > 0 && psfLocalSet->u8ServiceClassNameLength < 32) + memcpy(Adapter->PackInfo[uiSearchRuleIndex].ucServiceClassName, psfLocalSet->u8ServiceClassName, psfLocalSet->u8ServiceClassNameLength); - if(Adapter->PackInfo[uiSearchRuleIndex].u8QueueType==BE && - Adapter->PackInfo[uiSearchRuleIndex].ucDirection) - { - Adapter->usBestEffortQueueIndex=uiSearchRuleIndex; - } + Adapter->PackInfo[uiSearchRuleIndex].u8QueueType = psfLocalSet->u8ServiceFlowSchedulingType; + + if (Adapter->PackInfo[uiSearchRuleIndex].u8QueueType == BE && Adapter->PackInfo[uiSearchRuleIndex].ucDirection) + Adapter->usBestEffortQueueIndex = uiSearchRuleIndex; Adapter->PackInfo[uiSearchRuleIndex].ulSFID = ntohl(psfLocalSet->u32SFID); Adapter->PackInfo[uiSearchRuleIndex].u8TrafficPriority = psfLocalSet->u8TrafficPriority; - //copy all the classifier in the Service Flow param structure - for(nIndex=0; nIndexu8TotalClassifiers; nIndex++) - { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Classifier index =%d",nIndex); - psfCSType = &psfLocalSet->cConvergenceSLTypes[nIndex]; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Classifier index =%d",nIndex); + /* copy all the classifier in the Service Flow param structure */ + for (nIndex = 0; nIndex < psfLocalSet->u8TotalClassifiers; nIndex++) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Classifier index =%d", nIndex); + psfCSType = &psfLocalSet->cConvergenceSLTypes[nIndex]; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Classifier index =%d", nIndex); - if(psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority) - { - Adapter->PackInfo[uiSearchRuleIndex].bClassifierPriority=TRUE; - } - - if(psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority) - { - Adapter->PackInfo[uiSearchRuleIndex].bClassifierPriority=TRUE; - } + if (psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority) + Adapter->PackInfo[uiSearchRuleIndex].bClassifierPriority = TRUE; + if (psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority) + Adapter->PackInfo[uiSearchRuleIndex].bClassifierPriority = TRUE; - if(ucDsxType== DSA_ACK) - { + if (ucDsxType == DSA_ACK) { eClassifierAction = eAddClassifier; - } - else if(ucDsxType == DSC_ACK) - { - switch(psfCSType->u8ClassfierDSCAction) - { - case 0://DSC Add Classifier + } else if (ucDsxType == DSC_ACK) { + switch (psfCSType->u8ClassfierDSCAction) { + case 0: /* DSC Add Classifier */ { eClassifierAction = eAddClassifier; } break; - case 1://DSC Replace Classifier + case 1: /* DSC Replace Classifier */ { eClassifierAction = eReplaceClassifier; } break; - case 2://DSC Delete Classifier + case 2: /* DSC Delete Classifier */ { eClassifierAction = eDeleteClassifier; - } break; default: @@ -683,163 +566,133 @@ static VOID CopyToAdapter( register PMINI_ADAPTER Adapter, /**cCPacketClassificationRule.u16PacketClassificationRuleIndex); - switch(eClassifierAction) - { + switch (eClassifierAction) { case eAddClassifier: { - //Get a Free Classifier Index From Classifier table for this SF to add the Classifier - //Contained in this message - nClassifierIndex = SearchClsid(Adapter,ulSFID,u16PacketClassificationRuleIndex); + /* Get a Free Classifier Index From Classifier table for this SF to add the Classifier */ + /* Contained in this message */ + nClassifierIndex = SearchClsid(Adapter, ulSFID, u16PacketClassificationRuleIndex); - if(nClassifierIndex > MAX_CLASSIFIERS) - { + if (nClassifierIndex > MAX_CLASSIFIERS) { nClassifierIndex = SearchFreeClsid(Adapter); - if(nClassifierIndex > MAX_CLASSIFIERS) - { - //Failed To get a free Entry - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Error Failed To get a free Classifier Entry"); + if (nClassifierIndex > MAX_CLASSIFIERS) { + /* Failed To get a free Entry */ + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Error Failed To get a free Classifier Entry"); break; } - //Copy the Classifier Rule for this service flow into our Classifier table maintained per SF. - CopyClassifierRuleToSF(Adapter,psfCSType,uiSearchRuleIndex,nClassifierIndex); - } - - else - { - //This Classifier Already Exists and it is invalid to Add Classifier with existing PCRI - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"CopyToAdapter : Error The Specified Classifier Already Exists \ - and attempted To Add Classifier with Same PCRI : 0x%x\n", u16PacketClassificationRuleIndex); + /* Copy the Classifier Rule for this service flow into our Classifier table maintained per SF. */ + CopyClassifierRuleToSF(Adapter, psfCSType, uiSearchRuleIndex, nClassifierIndex); + } else { + /* This Classifier Already Exists and it is invalid to Add Classifier with existing PCRI */ + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, + "CopyToAdapter: Error The Specified Classifier Already Exists and attempted To Add Classifier with Same PCRI : 0x%x\n", + u16PacketClassificationRuleIndex); } } break; - case eReplaceClassifier: { - //Get the Classifier Index From Classifier table for this SF and replace existing Classifier - //with the new classifier Contained in this message - nClassifierIndex = SearchClsid(Adapter,ulSFID,u16PacketClassificationRuleIndex); - if(nClassifierIndex > MAX_CLASSIFIERS) - { - //Failed To search the classifier - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Error Search for Classifier To be replaced failed"); + /* Get the Classifier Index From Classifier table for this SF and replace existing Classifier */ + /* with the new classifier Contained in this message */ + nClassifierIndex = SearchClsid(Adapter, ulSFID, u16PacketClassificationRuleIndex); + if (nClassifierIndex > MAX_CLASSIFIERS) { + /* Failed To search the classifier */ + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Error Search for Classifier To be replaced failed"); break; } - //Copy the Classifier Rule for this service flow into our Classifier table maintained per SF. - CopyClassifierRuleToSF(Adapter,psfCSType,uiSearchRuleIndex,nClassifierIndex); + /* Copy the Classifier Rule for this service flow into our Classifier table maintained per SF. */ + CopyClassifierRuleToSF(Adapter, psfCSType, uiSearchRuleIndex, nClassifierIndex); } break; - case eDeleteClassifier: { - //Get the Classifier Index From Classifier table for this SF and replace existing Classifier - //with the new classifier Contained in this message - nClassifierIndex = SearchClsid(Adapter,ulSFID,u16PacketClassificationRuleIndex); - if(nClassifierIndex > MAX_CLASSIFIERS) - { - //Failed To search the classifier - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Error Search for Classifier To be deleted failed"); + /* Get the Classifier Index From Classifier table for this SF and replace existing Classifier */ + /* with the new classifier Contained in this message */ + nClassifierIndex = SearchClsid(Adapter, ulSFID, u16PacketClassificationRuleIndex); + if (nClassifierIndex > MAX_CLASSIFIERS) { + /* Failed To search the classifier */ + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Error Search for Classifier To be deleted failed"); break; } - //Delete This classifier - DeleteClassifierRuleFromSF(Adapter,uiSearchRuleIndex,nClassifierIndex); + /* Delete This classifier */ + DeleteClassifierRuleFromSF(Adapter, uiSearchRuleIndex, nClassifierIndex); } break; - default: { - //Invalid Action for classifier + /* Invalid Action for classifier */ break; } } } - //Repeat parsing Classification Entries to process PHS Rules - for(nIndex=0; nIndex < psfLocalSet->u8TotalClassifiers; nIndex++) - { - psfCSType = &psfLocalSet->cConvergenceSLTypes[nIndex]; - - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "psfCSType->u8PhsDSCAction : 0x%x\n", - psfCSType->u8PhsDSCAction ); + /* Repeat parsing Classification Entries to process PHS Rules */ + for (nIndex = 0; nIndex < psfLocalSet->u8TotalClassifiers; nIndex++) { + psfCSType = &psfLocalSet->cConvergenceSLTypes[nIndex]; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "psfCSType->u8PhsDSCAction : 0x%x\n", psfCSType->u8PhsDSCAction); - switch (psfCSType->u8PhsDSCAction) - { + switch (psfCSType->u8PhsDSCAction) { case eDeleteAllPHSRules: { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Deleting All PHS Rules For VCID: 0x%X\n",uVCID); - - //Delete All the PHS rules for this Service flow - - PhsDeleteSFRules( - &Adapter->stBCMPhsContext, - uVCID); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Deleting All PHS Rules For VCID: 0x%X\n", uVCID); + /* Delete All the PHS rules for this Service flow */ + PhsDeleteSFRules(&Adapter->stBCMPhsContext, uVCID); break; } case eDeletePHSRule: { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"PHS DSC Action = Delete PHS Rule \n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "PHS DSC Action = Delete PHS Rule\n"); + + if (psfCSType->cPhsRule.u8PHSI) + PhsDeletePHSRule(&Adapter->stBCMPhsContext, uVCID, psfCSType->cCPacketClassificationRule.u8AssociatedPHSI); - if(psfCSType->cPhsRule.u8PHSI) - { - PhsDeletePHSRule( - &Adapter->stBCMPhsContext, - uVCID, - psfCSType->cCPacketClassificationRule.u8AssociatedPHSI); - } - else - { - //BCM_DEBUG_PRINT(CONN_MSG,("Error CPHSRule.PHSI is ZERO \n")); - } break; } - default : + default: { - if(ucDsxType == DSC_ACK) - { - //BCM_DEBUG_PRINT(CONN_MSG,("Invalid PHS DSC Action For DSC \n",psfCSType->cPhsRule.u8PHSI)); - break; //FOr DSC ACK Case PHS DSC Action must be in valid set + if (ucDsxType == DSC_ACK) { + /* BCM_DEBUG_PRINT(CONN_MSG,("Invalid PHS DSC Action For DSC\n",psfCSType->cPhsRule.u8PHSI)); */ + break; /* FOr DSC ACK Case PHS DSC Action must be in valid set */ } } - //Proceed To Add PHS rule for DSA_ACK case even if PHS DSC action is unspecified - //No Break Here . Intentionally! + /* Proceed To Add PHS rule for DSA_ACK case even if PHS DSC action is unspecified */ + /* No Break Here . Intentionally! */ case eAddPHSRule: case eSetPHSRule: { - if(psfCSType->cPhsRule.u8PHSI) - { - //Apply This PHS Rule to all classifiers whose Associated PHSI Match + if (psfCSType->cPhsRule.u8PHSI) { + /* Apply This PHS Rule to all classifiers whose Associated PHSI Match */ unsigned int uiClassifierIndex = 0; - if(pstAddIndication->u8Direction == UPLINK_DIR ) - { - for(uiClassifierIndex=0;uiClassifierIndexastClassifierTable[uiClassifierIndex].bUsed) && + if (pstAddIndication->u8Direction == UPLINK_DIR) { + for (uiClassifierIndex = 0; uiClassifierIndex < MAX_CLASSIFIERS; uiClassifierIndex++) { + if ((Adapter->astClassifierTable[uiClassifierIndex].bUsed) && (Adapter->astClassifierTable[uiClassifierIndex].ulSFID == Adapter->PackInfo[uiSearchRuleIndex].ulSFID) && - (Adapter->astClassifierTable[uiClassifierIndex].u8AssociatedPHSI == psfCSType->cPhsRule.u8PHSI)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Adding PHS Rule For Classifier : 0x%x cPhsRule.u8PHSI : 0x%x\n", - Adapter->astClassifierTable[uiClassifierIndex].uiClassifierRuleIndex, - psfCSType->cPhsRule.u8PHSI); - //Update The PHS Rule for this classifier as Associated PHSI id defined - - //Copy the PHS Rule - sPhsRule.u8PHSI = psfCSType->cPhsRule.u8PHSI; - sPhsRule.u8PHSFLength = psfCSType->cPhsRule.u8PHSFLength; + (Adapter->astClassifierTable[uiClassifierIndex].u8AssociatedPHSI == psfCSType->cPhsRule.u8PHSI)) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, + "Adding PHS Rule For Classifier: 0x%x cPhsRule.u8PHSI: 0x%x\n", + Adapter->astClassifierTable[uiClassifierIndex].uiClassifierRuleIndex, + psfCSType->cPhsRule.u8PHSI); + /* Update The PHS Rule for this classifier as Associated PHSI id defined */ + + /* Copy the PHS Rule */ + sPhsRule.u8PHSI = psfCSType->cPhsRule.u8PHSI; + sPhsRule.u8PHSFLength = psfCSType->cPhsRule.u8PHSFLength; sPhsRule.u8PHSMLength = psfCSType->cPhsRule.u8PHSMLength; sPhsRule.u8PHSS = psfCSType->cPhsRule.u8PHSS; sPhsRule.u8PHSV = psfCSType->cPhsRule.u8PHSV; - memcpy(sPhsRule.u8PHSF,psfCSType->cPhsRule.u8PHSF,MAX_PHS_LENGTHS); - memcpy(sPhsRule.u8PHSM,psfCSType->cPhsRule.u8PHSM,MAX_PHS_LENGTHS); + memcpy(sPhsRule.u8PHSF, psfCSType->cPhsRule.u8PHSF, MAX_PHS_LENGTHS); + memcpy(sPhsRule.u8PHSM, psfCSType->cPhsRule.u8PHSM, MAX_PHS_LENGTHS); sPhsRule.u8RefCnt = 0; sPhsRule.bUnclassifiedPHSRule = FALSE; sPhsRule.PHSModifiedBytes = 0; sPhsRule.PHSModifiedNumPackets = 0; sPhsRule.PHSErrorNumPackets = 0; - //bPHSRuleAssociated = TRUE; - //Store The PHS Rule for this classifier + /* bPHSRuleAssociated = TRUE; */ + /* Store The PHS Rule for this classifier */ PhsUpdateClassifierRule( &Adapter->stBCMPhsContext, @@ -848,184 +701,157 @@ static VOID CopyToAdapter( register PMINI_ADAPTER Adapter, /**astClassifierTable[uiClassifierIndex].u8AssociatedPHSI); - //Update PHS Rule For the Classifier - if(sPhsRule.u8PHSI) - { + /* Update PHS Rule For the Classifier */ + if (sPhsRule.u8PHSI) { Adapter->astClassifierTable[uiClassifierIndex].u32PHSRuleID = sPhsRule.u8PHSI; - memcpy(&Adapter->astClassifierTable[uiClassifierIndex].sPhsRule,&sPhsRule,sizeof(S_PHS_RULE)); + memcpy(&Adapter->astClassifierTable[uiClassifierIndex].sPhsRule, &sPhsRule, sizeof(S_PHS_RULE)); } - } } + } else { + /* Error PHS Rule specified in signaling could not be applied to any classifier */ + + /* Copy the PHS Rule */ + sPhsRule.u8PHSI = psfCSType->cPhsRule.u8PHSI; + sPhsRule.u8PHSFLength = psfCSType->cPhsRule.u8PHSFLength; + sPhsRule.u8PHSMLength = psfCSType->cPhsRule.u8PHSMLength; + sPhsRule.u8PHSS = psfCSType->cPhsRule.u8PHSS; + sPhsRule.u8PHSV = psfCSType->cPhsRule.u8PHSV; + memcpy(sPhsRule.u8PHSF, psfCSType->cPhsRule.u8PHSF, MAX_PHS_LENGTHS); + memcpy(sPhsRule.u8PHSM, psfCSType->cPhsRule.u8PHSM, MAX_PHS_LENGTHS); + sPhsRule.u8RefCnt = 0; + sPhsRule.bUnclassifiedPHSRule = TRUE; + sPhsRule.PHSModifiedBytes = 0; + sPhsRule.PHSModifiedNumPackets = 0; + sPhsRule.PHSErrorNumPackets = 0; + /* Store The PHS Rule for this classifier */ + + /* + * Passing the argument u8PHSI instead of clsid. Because for DL with no classifier rule, + * clsid will be zero hence we can't have multiple PHS rules for the same SF. + * To support multiple PHS rule, passing u8PHSI. + */ + PhsUpdateClassifierRule( + &Adapter->stBCMPhsContext, + uVCID, + sPhsRule.u8PHSI, + &sPhsRule, + sPhsRule.u8PHSI); } - else - { - //Error PHS Rule specified in signaling could not be applied to any classifier - - //Copy the PHS Rule - sPhsRule.u8PHSI = psfCSType->cPhsRule.u8PHSI; - sPhsRule.u8PHSFLength = psfCSType->cPhsRule.u8PHSFLength; - sPhsRule.u8PHSMLength = psfCSType->cPhsRule.u8PHSMLength; - sPhsRule.u8PHSS = psfCSType->cPhsRule.u8PHSS; - sPhsRule.u8PHSV = psfCSType->cPhsRule.u8PHSV; - memcpy(sPhsRule.u8PHSF,psfCSType->cPhsRule.u8PHSF,MAX_PHS_LENGTHS); - memcpy(sPhsRule.u8PHSM,psfCSType->cPhsRule.u8PHSM,MAX_PHS_LENGTHS); - sPhsRule.u8RefCnt = 0; - sPhsRule.bUnclassifiedPHSRule = TRUE; - sPhsRule.PHSModifiedBytes = 0; - sPhsRule.PHSModifiedNumPackets = 0; - sPhsRule.PHSErrorNumPackets = 0; - //Store The PHS Rule for this classifier - - /* - Passing the argument u8PHSI instead of clsid. Because for DL with no classifier rule, - clsid will be zero hence we can't have multiple PHS rules for the same SF. - To support multiple PHS rule, passing u8PHSI. - */ - - PhsUpdateClassifierRule( - &Adapter->stBCMPhsContext, - uVCID, - sPhsRule.u8PHSI, - &sPhsRule, - sPhsRule.u8PHSI); - - } - } } break; } } - if(psfLocalSet->u32MaxSustainedTrafficRate == 0 ) - { - //No Rate Limit . Set Max Sustained Traffic Rate to Maximum - Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate = - WIMAX_MAX_ALLOWED_RATE; - - } - else if (ntohl(psfLocalSet->u32MaxSustainedTrafficRate) > - WIMAX_MAX_ALLOWED_RATE) - { - //Too large Allowed Rate specified. Limiting to Wi Max Allowed rate - Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate = - WIMAX_MAX_ALLOWED_RATE; - } - else - { - Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate = - ntohl(psfLocalSet->u32MaxSustainedTrafficRate); + if (psfLocalSet->u32MaxSustainedTrafficRate == 0) { + /* No Rate Limit . Set Max Sustained Traffic Rate to Maximum */ + Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate = WIMAX_MAX_ALLOWED_RATE; + } else if (ntohl(psfLocalSet->u32MaxSustainedTrafficRate) > WIMAX_MAX_ALLOWED_RATE) { + /* Too large Allowed Rate specified. Limiting to Wi Max Allowed rate */ + Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate = WIMAX_MAX_ALLOWED_RATE; + } else { + Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate = ntohl(psfLocalSet->u32MaxSustainedTrafficRate); } Adapter->PackInfo[uiSearchRuleIndex].uiMaxLatency = ntohl(psfLocalSet->u32MaximumLatency); - - if(Adapter->PackInfo[uiSearchRuleIndex].uiMaxLatency == 0) /* 0 should be treated as infinite */ + if (Adapter->PackInfo[uiSearchRuleIndex].uiMaxLatency == 0) /* 0 should be treated as infinite */ Adapter->PackInfo[uiSearchRuleIndex].uiMaxLatency = MAX_LATENCY_ALLOWED; + if ((Adapter->PackInfo[uiSearchRuleIndex].u8QueueType == ERTPS || + Adapter->PackInfo[uiSearchRuleIndex].u8QueueType == UGS)) + UGIValue = ntohs(psfLocalSet->u16UnsolicitedGrantInterval); - if(( Adapter->PackInfo[uiSearchRuleIndex].u8QueueType == ERTPS || - Adapter->PackInfo[uiSearchRuleIndex].u8QueueType == UGS ) ) - UGIValue = ntohs(psfLocalSet->u16UnsolicitedGrantInterval); - - if(UGIValue == 0) + if (UGIValue == 0) UGIValue = DEFAULT_UG_INTERVAL; /* - For UGI based connections... - DEFAULT_UGI_FACTOR*UGIInterval worth of data is the max token count at host... - The extra amount of token is to ensure that a large amount of jitter won't have loss in throughput... - In case of non-UGI based connection, 200 frames worth of data is the max token count at host... - */ - + * For UGI based connections... + * DEFAULT_UGI_FACTOR*UGIInterval worth of data is the max token count at host... + * The extra amount of token is to ensure that a large amount of jitter won't have loss in throughput... + * In case of non-UGI based connection, 200 frames worth of data is the max token count at host... + */ Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize = - (DEFAULT_UGI_FACTOR*Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate*UGIValue)/1000; + (DEFAULT_UGI_FACTOR*Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate*UGIValue)/1000; - if(Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize < WIMAX_MAX_MTU*8) - { + if (Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize < WIMAX_MAX_MTU*8) { UINT UGIFactor = 0; /* Special Handling to ensure the biggest size of packet can go out from host to FW as follows: - 1. Any packet from Host to FW can go out in different packet size. - 2. So in case the Bucket count is smaller than MTU, the packets of size (Size > TokenCount), will get dropped. - 3. We can allow packets of MaxSize from Host->FW that can go out from FW in multiple SDUs by fragmentation at Wimax Layer - */ + * 1. Any packet from Host to FW can go out in different packet size. + * 2. So in case the Bucket count is smaller than MTU, the packets of size (Size > TokenCount), will get dropped. + * 3. We can allow packets of MaxSize from Host->FW that can go out from FW in multiple SDUs by fragmentation at Wimax Layer + */ UGIFactor = (Adapter->PackInfo[uiSearchRuleIndex].uiMaxLatency/UGIValue + 1); - if(UGIFactor > DEFAULT_UGI_FACTOR) - Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize = - (UGIFactor*Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate*UGIValue)/1000; + if (UGIFactor > DEFAULT_UGI_FACTOR) + Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize = + (UGIFactor*Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate*UGIValue)/1000; - if(Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize > WIMAX_MAX_MTU*8) + if (Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize > WIMAX_MAX_MTU*8) Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize = WIMAX_MAX_MTU*8; } + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "LAT: %d, UGI: %d\n", Adapter->PackInfo[uiSearchRuleIndex].uiMaxLatency, UGIValue); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "uiMaxAllowedRate: 0x%x, u32MaxSustainedTrafficRate: 0x%x ,uiMaxBucketSize: 0x%x", + Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate, + ntohl(psfLocalSet->u32MaxSustainedTrafficRate), + Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"LAT: %d, UGI: %d \n", Adapter->PackInfo[uiSearchRuleIndex].uiMaxLatency, UGIValue); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"uiMaxAllowedRate: 0x%x, u32MaxSustainedTrafficRate: 0x%x ,uiMaxBucketSize: 0x%x", - Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate, - ntohl(psfLocalSet->u32MaxSustainedTrafficRate), - Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize); + /* copy the extended SF Parameters to Support MIBS */ + CopyMIBSExtendedSFParameters(Adapter, psfLocalSet, uiSearchRuleIndex); - //copy the extended SF Parameters to Support MIBS - CopyMIBSExtendedSFParameters(Adapter,psfLocalSet,uiSearchRuleIndex); - - //store header suppression enabled flag per SF + /* store header suppression enabled flag per SF */ Adapter->PackInfo[uiSearchRuleIndex].bHeaderSuppressionEnabled = - !(psfLocalSet->u8RequesttransmissionPolicy & - MASK_DISABLE_HEADER_SUPPRESSION); + !(psfLocalSet->u8RequesttransmissionPolicy & + MASK_DISABLE_HEADER_SUPPRESSION); kfree(Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication); Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication = pstAddIndication; - //Re Sort the SF list in PackInfo according to Traffic Priority + /* Re Sort the SF list in PackInfo according to Traffic Priority */ SortPackInfo(Adapter); /* Re Sort the Classifier Rules table and re - arrange - according to Classifier Rule Priority */ + * according to Classifier Rule Priority + */ SortClassifiers(Adapter); - DumpPhsRules(&Adapter->stBCMPhsContext); - - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"%s <=====", __FUNCTION__); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "%s <=====", __FUNCTION__); } - /*********************************************************************** -* Function - DumpCmControlPacket -* -* Description - This routinue Dumps the Contents of the AddIndication -* Structure in the Connection Management Control Packet -* -* Parameter - pvBuffer: Pointer to the buffer containing the -* AddIndication data. -* -* Returns - None -*************************************************************************/ + * Function - DumpCmControlPacket + * + * Description - This routinue Dumps the Contents of the AddIndication + * Structure in the Connection Management Control Packet + * + * Parameter - pvBuffer: Pointer to the buffer containing the + * AddIndication data. + * + * Returns - None + *************************************************************************/ static VOID DumpCmControlPacket(PVOID pvBuffer) { - UINT uiLoopIndex; - UINT nIndex; - stLocalSFAddIndicationAlt *pstAddIndication; - UINT nCurClassifierCnt; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + UINT uiLoopIndex; + UINT nIndex; + stLocalSFAddIndicationAlt *pstAddIndication; + UINT nCurClassifierCnt; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); pstAddIndication = (stLocalSFAddIndicationAlt *)pvBuffer; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "======>"); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Type : 0x%X",pstAddIndication->u8Type); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Direction : 0x%X",pstAddIndication->u8Direction); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TID: 0x%X", ntohs(pstAddIndication->u16TID)); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID : 0x%X",ntohs(pstAddIndication->u16CID)); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16VCID : 0x%X",ntohs(pstAddIndication->u16VCID)); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " AuthorizedSet--->"); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32SFID : 0x%X",htonl(pstAddIndication->sfAuthorizedSet.u32SFID)); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID : 0x%X",htons(pstAddIndication->sfAuthorizedSet.u16CID)); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassNameLength : 0x%X", - pstAddIndication->sfAuthorizedSet.u8ServiceClassNameLength); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassName : 0x%X ,0x%X , 0x%X, 0x%X, 0x%X, 0x%X", + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "======>"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Type: 0x%X", pstAddIndication->u8Type); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Direction: 0x%X", pstAddIndication->u8Direction); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TID: 0x%X", ntohs(pstAddIndication->u16TID)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID: 0x%X", ntohs(pstAddIndication->u16CID)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16VCID: 0x%X", ntohs(pstAddIndication->u16VCID)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " AuthorizedSet--->"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32SFID: 0x%X", htonl(pstAddIndication->sfAuthorizedSet.u32SFID)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID: 0x%X", htons(pstAddIndication->sfAuthorizedSet.u16CID)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassNameLength: 0x%X", + pstAddIndication->sfAuthorizedSet.u8ServiceClassNameLength); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassName: 0x%X ,0x%X , 0x%X, 0x%X, 0x%X, 0x%X", pstAddIndication->sfAuthorizedSet.u8ServiceClassName[0], pstAddIndication->sfAuthorizedSet.u8ServiceClassName[1], pstAddIndication->sfAuthorizedSet.u8ServiceClassName[2], @@ -1033,207 +859,170 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) pstAddIndication->sfAuthorizedSet.u8ServiceClassName[4], pstAddIndication->sfAuthorizedSet.u8ServiceClassName[5]); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8MBSService : 0x%X", - pstAddIndication->sfAuthorizedSet.u8MBSService); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8QosParamSet : 0x%X", - pstAddIndication->sfAuthorizedSet.u8QosParamSet); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority : 0x%X, %p", - pstAddIndication->sfAuthorizedSet.u8TrafficPriority, &pstAddIndication->sfAuthorizedSet.u8TrafficPriority); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxSustainedTrafficRate : 0x%X 0x%p", - pstAddIndication->sfAuthorizedSet.u32MaxSustainedTrafficRate, + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8MBSService: 0x%X", pstAddIndication->sfAuthorizedSet.u8MBSService); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8QosParamSet: 0x%X", pstAddIndication->sfAuthorizedSet.u8QosParamSet); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority: 0x%X, %p", + pstAddIndication->sfAuthorizedSet.u8TrafficPriority, &pstAddIndication->sfAuthorizedSet.u8TrafficPriority); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxSustainedTrafficRate: 0x%X 0x%p", + pstAddIndication->sfAuthorizedSet.u32MaxSustainedTrafficRate, &pstAddIndication->sfAuthorizedSet.u32MaxSustainedTrafficRate); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst : 0x%X", - pstAddIndication->sfAuthorizedSet.u32MaxTrafficBurst); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate : 0x%X", - pstAddIndication->sfAuthorizedSet.u32MinReservedTrafficRate); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength : 0x%X", - pstAddIndication->sfAuthorizedSet.u8VendorSpecificQoSParamLength); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam : 0x%X", - pstAddIndication->sfAuthorizedSet.u8VendorSpecificQoSParam[0]); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceFlowSchedulingType : 0x%X", - pstAddIndication->sfAuthorizedSet.u8ServiceFlowSchedulingType); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32ToleratedJitter : 0x%X", - pstAddIndication->sfAuthorizedSet.u32ToleratedJitter); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaximumLatency : 0x%X", - pstAddIndication->sfAuthorizedSet.u32MaximumLatency); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8FixedLengthVSVariableLengthSDUIndicator: 0x%X", - pstAddIndication->sfAuthorizedSet.u8FixedLengthVSVariableLengthSDUIndicator); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8SDUSize : 0x%X", - pstAddIndication->sfAuthorizedSet.u8SDUSize); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TargetSAID : 0x%X", - pstAddIndication->sfAuthorizedSet.u16TargetSAID); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQEnable : 0x%X", - pstAddIndication->sfAuthorizedSet.u8ARQEnable); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQWindowSize : 0x%X", - pstAddIndication->sfAuthorizedSet.u16ARQWindowSize); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryTxTimeOut : 0x%X", - pstAddIndication->sfAuthorizedSet.u16ARQRetryTxTimeOut); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryRxTimeOut : 0x%X", - pstAddIndication->sfAuthorizedSet.u16ARQRetryRxTimeOut); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockLifeTime : 0x%X", - pstAddIndication->sfAuthorizedSet.u16ARQBlockLifeTime); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQSyncLossTimeOut : 0x%X", - pstAddIndication->sfAuthorizedSet.u16ARQSyncLossTimeOut); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQDeliverInOrder : 0x%X", - pstAddIndication->sfAuthorizedSet.u8ARQDeliverInOrder); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRxPurgeTimeOut : 0x%X", - pstAddIndication->sfAuthorizedSet.u16ARQRxPurgeTimeOut); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockSize : 0x%X", - pstAddIndication->sfAuthorizedSet.u16ARQBlockSize); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8CSSpecification : 0x%X", - pstAddIndication->sfAuthorizedSet.u8CSSpecification); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TypeOfDataDeliveryService : 0x%X", - pstAddIndication->sfAuthorizedSet.u8TypeOfDataDeliveryService); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16SDUInterArrivalTime : 0x%X", - pstAddIndication->sfAuthorizedSet.u16SDUInterArrivalTime); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TimeBase : 0x%X", - pstAddIndication->sfAuthorizedSet.u16TimeBase); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8PagingPreference : 0x%X", - pstAddIndication->sfAuthorizedSet.u8PagingPreference); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UnsolicitedPollingInterval : 0x%X", - pstAddIndication->sfAuthorizedSet.u16UnsolicitedPollingInterval); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "sfAuthorizedSet.u8HARQChannelMapping %x %x %x ", - *(unsigned int*)pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping, - *(unsigned int*)&pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping[4], - *(USHORT*) &pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping[8]); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficIndicationPreference : 0x%X", - pstAddIndication->sfAuthorizedSet.u8TrafficIndicationPreference); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " Total Classifiers Received : 0x%X",pstAddIndication->sfAuthorizedSet.u8TotalClassifiers); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst: 0x%X", pstAddIndication->sfAuthorizedSet.u32MaxTrafficBurst); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate : 0x%X", + pstAddIndication->sfAuthorizedSet.u32MinReservedTrafficRate); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength: 0x%X", + pstAddIndication->sfAuthorizedSet.u8VendorSpecificQoSParamLength); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam: 0x%X", + pstAddIndication->sfAuthorizedSet.u8VendorSpecificQoSParam[0]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceFlowSchedulingType: 0x%X", + pstAddIndication->sfAuthorizedSet.u8ServiceFlowSchedulingType); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32ToleratedJitter: 0x%X", pstAddIndication->sfAuthorizedSet.u32ToleratedJitter); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaximumLatency: 0x%X", pstAddIndication->sfAuthorizedSet.u32MaximumLatency); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8FixedLengthVSVariableLengthSDUIndicator: 0x%X", + pstAddIndication->sfAuthorizedSet.u8FixedLengthVSVariableLengthSDUIndicator); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8SDUSize: 0x%X", pstAddIndication->sfAuthorizedSet.u8SDUSize); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TargetSAID: 0x%X", pstAddIndication->sfAuthorizedSet.u16TargetSAID); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQEnable: 0x%X", pstAddIndication->sfAuthorizedSet.u8ARQEnable); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQWindowSize: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQWindowSize); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryTxTimeOut: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQRetryTxTimeOut); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryRxTimeOut: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQRetryRxTimeOut); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockLifeTime: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQBlockLifeTime); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQSyncLossTimeOut: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQSyncLossTimeOut); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQDeliverInOrder: 0x%X", pstAddIndication->sfAuthorizedSet.u8ARQDeliverInOrder); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRxPurgeTimeOut: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQRxPurgeTimeOut); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockSize: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQBlockSize); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8CSSpecification: 0x%X", pstAddIndication->sfAuthorizedSet.u8CSSpecification); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TypeOfDataDeliveryService: 0x%X", + pstAddIndication->sfAuthorizedSet.u8TypeOfDataDeliveryService); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16SDUInterArrivalTime: 0x%X", pstAddIndication->sfAuthorizedSet.u16SDUInterArrivalTime); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TimeBase: 0x%X", pstAddIndication->sfAuthorizedSet.u16TimeBase); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8PagingPreference: 0x%X", pstAddIndication->sfAuthorizedSet.u8PagingPreference); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UnsolicitedPollingInterval: 0x%X", + pstAddIndication->sfAuthorizedSet.u16UnsolicitedPollingInterval); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "sfAuthorizedSet.u8HARQChannelMapping %x %x %x ", + *(unsigned int *)pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping, + *(unsigned int *)&pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping[4], + *(USHORT *)&pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping[8]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficIndicationPreference: 0x%X", + pstAddIndication->sfAuthorizedSet.u8TrafficIndicationPreference); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " Total Classifiers Received: 0x%X", pstAddIndication->sfAuthorizedSet.u8TotalClassifiers); nCurClassifierCnt = pstAddIndication->sfAuthorizedSet.u8TotalClassifiers; - - if(nCurClassifierCnt > MAX_CLASSIFIERS_IN_SF) - { + if (nCurClassifierCnt > MAX_CLASSIFIERS_IN_SF) nCurClassifierCnt = MAX_CLASSIFIERS_IN_SF; - } - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "pstAddIndication->sfAuthorizedSet.bValid %d", pstAddIndication->sfAuthorizedSet.bValid); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "pstAddIndication->sfAuthorizedSet.u16MacOverhead %x", pstAddIndication->sfAuthorizedSet.u16MacOverhead); - if(!pstAddIndication->sfAuthorizedSet.bValid) - pstAddIndication->sfAuthorizedSet.bValid=1; - for(nIndex = 0 ; nIndex < nCurClassifierCnt ; nIndex++) - { + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "pstAddIndication->sfAuthorizedSet.bValid %d", pstAddIndication->sfAuthorizedSet.bValid); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "pstAddIndication->sfAuthorizedSet.u16MacOverhead %x", pstAddIndication->sfAuthorizedSet.u16MacOverhead); + if (!pstAddIndication->sfAuthorizedSet.bValid) + pstAddIndication->sfAuthorizedSet.bValid = 1; + for (nIndex = 0; nIndex < nCurClassifierCnt; nIndex++) { stConvergenceSLTypes *psfCSType = NULL; psfCSType = &pstAddIndication->sfAuthorizedSet.cConvergenceSLTypes[nIndex]; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "psfCSType = %p", psfCSType); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "CCPacketClassificationRuleSI====>"); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ClassifierRulePriority :0x%X ", - psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfServiceLength :0x%X ", - psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfService[3] :0x%X ,0x%X ,0x%X ", - psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0], - psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1], - psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]); - - for(uiLoopIndex=0; uiLoopIndex < 1; uiLoopIndex++) - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Protocol : 0x%02X ", - psfCSType->cCPacketClassificationRule.u8Protocol); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddressLength :0x%X ", - psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength); - - for(uiLoopIndex=0; uiLoopIndex < 32; uiLoopIndex++) - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddress[32] : 0x%02X ", - psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress[uiLoopIndex]); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddressLength : 0x%X ", - psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength); - - for(uiLoopIndex=0; uiLoopIndex < 32; uiLoopIndex++) - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddress[32] : 0x%02X ", - psfCSType->cCPacketClassificationRule.u8IPDestinationAddress[uiLoopIndex]); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRangeLength:0x%X ", - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRange[4]: 0x%02X ,0x%02X ,0x%02X ,0x%02X ", - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[0], - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[1], - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[2], - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[3]); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRangeLength : 0x%02X ", - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRange[4]: 0x%02X ,0x%02X ,0x%02X ,0x%02X ", - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[0], - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[1], - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[2], - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[3]); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddressLength : 0x%02X ", - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddress[6] : 0x %02X %02X %02X %02X %02X %02X", - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[0], - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[1], - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[2], - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[3], - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[4], - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[5]); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddressLength : 0x%02X ", - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddress[6] : 0x %02X %02X %02X %02X %02X %02X", - psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[0], - psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[1], - psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[2], - psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[3], - psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[4], - psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[5]); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthertypeLength : 0x%02X ", - psfCSType->cCPacketClassificationRule.u8EthertypeLength); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Ethertype[3] : 0x%02X ,0x%02X ,0x%02X ", - psfCSType->cCPacketClassificationRule.u8Ethertype[0], - psfCSType->cCPacketClassificationRule.u8Ethertype[1], - psfCSType->cCPacketClassificationRule.u8Ethertype[2]); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UserPriority : 0x%X ", - psfCSType->cCPacketClassificationRule.u16UserPriority); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16VLANID : 0x%X ", - psfCSType->cCPacketClassificationRule.u16VLANID); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8AssociatedPHSI : 0x%02X ", - psfCSType->cCPacketClassificationRule.u8AssociatedPHSI); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16PacketClassificationRuleIndex : 0x%X ", - psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParamLength : 0x%X ", - psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParamLength); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParam[1] : 0x%X ", - psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParam[0]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "psfCSType = %p", psfCSType); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "CCPacketClassificationRuleSI====>"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ClassifierRulePriority: 0x%X ", + psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfServiceLength: 0x%X ", + psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfService[3]: 0x%X ,0x%X ,0x%X ", + psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0], + psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1], + psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]); + + for (uiLoopIndex = 0; uiLoopIndex < 1; uiLoopIndex++) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Protocol: 0x%02X ", + psfCSType->cCPacketClassificationRule.u8Protocol); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddressLength: 0x%X ", + psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength); + + for (uiLoopIndex = 0; uiLoopIndex < 32; uiLoopIndex++) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddress[32]: 0x%02X ", + psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress[uiLoopIndex]); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddressLength: 0x%X ", + psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength); + + for (uiLoopIndex = 0; uiLoopIndex < 32; uiLoopIndex++) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddress[32]: 0x%02X ", + psfCSType->cCPacketClassificationRule.u8IPDestinationAddress[uiLoopIndex]); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRangeLength:0x%X ", + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRange[4]: 0x%02X ,0x%02X ,0x%02X ,0x%02X ", + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[0], + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[1], + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[2], + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[3]); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRangeLength: 0x%02X ", + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRange[4]: 0x%02X ,0x%02X ,0x%02X ,0x%02X ", + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[0], + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[1], + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[2], + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[3]); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddressLength: 0x%02X ", + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddress[6]: 0x %02X %02X %02X %02X %02X %02X", + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[0], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[1], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[2], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[3], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[4], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[5]); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddressLength: 0x%02X ", + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddress[6]: 0x %02X %02X %02X %02X %02X %02X", + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[0], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[1], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[2], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[3], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[4], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[5]); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthertypeLength: 0x%02X ", + psfCSType->cCPacketClassificationRule.u8EthertypeLength); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Ethertype[3]: 0x%02X ,0x%02X ,0x%02X ", + psfCSType->cCPacketClassificationRule.u8Ethertype[0], + psfCSType->cCPacketClassificationRule.u8Ethertype[1], + psfCSType->cCPacketClassificationRule.u8Ethertype[2]); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UserPriority: 0x%X ", psfCSType->cCPacketClassificationRule.u16UserPriority); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16VLANID: 0x%X ", psfCSType->cCPacketClassificationRule.u16VLANID); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8AssociatedPHSI: 0x%02X ", psfCSType->cCPacketClassificationRule.u8AssociatedPHSI); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16PacketClassificationRuleIndex: 0x%X ", + psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParamLength: 0x%X ", + psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParamLength); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParam[1]: 0x%X ", + psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParam[0]); #ifdef VERSION_D5 - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLableLength :0x%X ", - psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLable[6] : 0x %02X %02X %02X %02X %02X %02X ", - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[0], - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[1], - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[2], - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[3], - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[4], - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[5]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLableLength: 0x%X ", + psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLable[6]: 0x %02X %02X %02X %02X %02X %02X ", + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[0], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[1], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[2], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[3], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[4], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[5]); #endif } - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "bValid : 0x%02X",pstAddIndication->sfAuthorizedSet.bValid); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "AdmittedSet--->"); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32SFID : 0x%X",pstAddIndication->sfAdmittedSet.u32SFID); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID : 0x%X",pstAddIndication->sfAdmittedSet.u16CID); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassNameLength : 0x%X", - pstAddIndication->sfAdmittedSet.u8ServiceClassNameLength); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassName : 0x %02X %02X %02X %02X %02X %02X", + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "bValid: 0x%02X", pstAddIndication->sfAuthorizedSet.bValid); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "AdmittedSet--->"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32SFID: 0x%X", pstAddIndication->sfAdmittedSet.u32SFID); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID: 0x%X", pstAddIndication->sfAdmittedSet.u16CID); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassNameLength: 0x%X", + pstAddIndication->sfAdmittedSet.u8ServiceClassNameLength); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassName: 0x %02X %02X %02X %02X %02X %02X", pstAddIndication->sfAdmittedSet.u8ServiceClassName[0], pstAddIndication->sfAdmittedSet.u8ServiceClassName[1], pstAddIndication->sfAdmittedSet.u8ServiceClassName[2], @@ -1241,429 +1030,338 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) pstAddIndication->sfAdmittedSet.u8ServiceClassName[4], pstAddIndication->sfAdmittedSet.u8ServiceClassName[5]); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8MBSService : 0x%02X", - pstAddIndication->sfAdmittedSet.u8MBSService); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8QosParamSet : 0x%02X", - pstAddIndication->sfAdmittedSet.u8QosParamSet); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority : 0x%02X", - pstAddIndication->sfAdmittedSet.u8TrafficPriority); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst : 0x%X", - pstAddIndication->sfAdmittedSet.u32MaxTrafficBurst); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate : 0x%X", - pstAddIndication->sfAdmittedSet.u32MinReservedTrafficRate); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength : 0x%02X", - pstAddIndication->sfAdmittedSet.u8VendorSpecificQoSParamLength); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam : 0x%02X", - pstAddIndication->sfAdmittedSet.u8VendorSpecificQoSParam[0]); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceFlowSchedulingType : 0x%02X", - pstAddIndication->sfAdmittedSet.u8ServiceFlowSchedulingType); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32ToleratedJitter : 0x%X", - pstAddIndication->sfAdmittedSet.u32ToleratedJitter); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaximumLatency : 0x%X", - pstAddIndication->sfAdmittedSet.u32MaximumLatency); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8FixedLengthVSVariableLengthSDUIndicator: 0x%02X", - pstAddIndication->sfAdmittedSet.u8FixedLengthVSVariableLengthSDUIndicator); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8SDUSize : 0x%02X", - pstAddIndication->sfAdmittedSet.u8SDUSize); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TargetSAID : 0x%02X", - pstAddIndication->sfAdmittedSet.u16TargetSAID); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQEnable : 0x%02X", - pstAddIndication->sfAdmittedSet.u8ARQEnable); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQWindowSize : 0x%X", - pstAddIndication->sfAdmittedSet.u16ARQWindowSize); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryTxTimeOut : 0x%X", - pstAddIndication->sfAdmittedSet.u16ARQRetryTxTimeOut); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryRxTimeOut : 0x%X", - pstAddIndication->sfAdmittedSet.u16ARQRetryRxTimeOut); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockLifeTime : 0x%X", - pstAddIndication->sfAdmittedSet.u16ARQBlockLifeTime); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQSyncLossTimeOut : 0x%X", - pstAddIndication->sfAdmittedSet.u16ARQSyncLossTimeOut); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQDeliverInOrder : 0x%02X", - pstAddIndication->sfAdmittedSet.u8ARQDeliverInOrder); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRxPurgeTimeOut : 0x%X", - pstAddIndication->sfAdmittedSet.u16ARQRxPurgeTimeOut); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockSize : 0x%X", - pstAddIndication->sfAdmittedSet.u16ARQBlockSize); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8CSSpecification : 0x%02X", - pstAddIndication->sfAdmittedSet.u8CSSpecification); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TypeOfDataDeliveryService : 0x%02X", - pstAddIndication->sfAdmittedSet.u8TypeOfDataDeliveryService); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16SDUInterArrivalTime : 0x%X", - pstAddIndication->sfAdmittedSet.u16SDUInterArrivalTime); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TimeBase : 0x%X", - pstAddIndication->sfAdmittedSet.u16TimeBase); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8PagingPreference : 0x%X", - pstAddIndication->sfAdmittedSet.u8PagingPreference); - - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficIndicationPreference : 0x%02X", - pstAddIndication->sfAdmittedSet.u8TrafficIndicationPreference); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " Total Classifiers Received : 0x%X",pstAddIndication->sfAdmittedSet.u8TotalClassifiers); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8MBSService: 0x%02X", pstAddIndication->sfAdmittedSet.u8MBSService); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8QosParamSet: 0x%02X", pstAddIndication->sfAdmittedSet.u8QosParamSet); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority: 0x%02X", pstAddIndication->sfAdmittedSet.u8TrafficPriority); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst: 0x%X", pstAddIndication->sfAdmittedSet.u32MaxTrafficBurst); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate: 0x%X", + pstAddIndication->sfAdmittedSet.u32MinReservedTrafficRate); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength: 0x%02X", + pstAddIndication->sfAdmittedSet.u8VendorSpecificQoSParamLength); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam: 0x%02X", + pstAddIndication->sfAdmittedSet.u8VendorSpecificQoSParam[0]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceFlowSchedulingType: 0x%02X", + pstAddIndication->sfAdmittedSet.u8ServiceFlowSchedulingType); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32ToleratedJitter: 0x%X", pstAddIndication->sfAdmittedSet.u32ToleratedJitter); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaximumLatency: 0x%X", pstAddIndication->sfAdmittedSet.u32MaximumLatency); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8FixedLengthVSVariableLengthSDUIndicator: 0x%02X", + pstAddIndication->sfAdmittedSet.u8FixedLengthVSVariableLengthSDUIndicator); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8SDUSize: 0x%02X", pstAddIndication->sfAdmittedSet.u8SDUSize); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TargetSAID: 0x%02X", pstAddIndication->sfAdmittedSet.u16TargetSAID); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQEnable: 0x%02X", pstAddIndication->sfAdmittedSet.u8ARQEnable); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQWindowSize: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQWindowSize); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryTxTimeOut: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQRetryTxTimeOut); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryRxTimeOut: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQRetryRxTimeOut); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockLifeTime: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQBlockLifeTime); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQSyncLossTimeOut: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQSyncLossTimeOut); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQDeliverInOrder: 0x%02X", pstAddIndication->sfAdmittedSet.u8ARQDeliverInOrder); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRxPurgeTimeOut: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQRxPurgeTimeOut); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockSize: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQBlockSize); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8CSSpecification: 0x%02X", pstAddIndication->sfAdmittedSet.u8CSSpecification); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TypeOfDataDeliveryService: 0x%02X", + pstAddIndication->sfAdmittedSet.u8TypeOfDataDeliveryService); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16SDUInterArrivalTime: 0x%X", pstAddIndication->sfAdmittedSet.u16SDUInterArrivalTime); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TimeBase: 0x%X", pstAddIndication->sfAdmittedSet.u16TimeBase); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8PagingPreference: 0x%X", pstAddIndication->sfAdmittedSet.u8PagingPreference); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficIndicationPreference: 0x%02X", + pstAddIndication->sfAdmittedSet.u8TrafficIndicationPreference); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " Total Classifiers Received: 0x%X", pstAddIndication->sfAdmittedSet.u8TotalClassifiers); nCurClassifierCnt = pstAddIndication->sfAdmittedSet.u8TotalClassifiers; - - if(nCurClassifierCnt > MAX_CLASSIFIERS_IN_SF) - { + if (nCurClassifierCnt > MAX_CLASSIFIERS_IN_SF) nCurClassifierCnt = MAX_CLASSIFIERS_IN_SF; - } - - - for(nIndex = 0 ; nIndex < nCurClassifierCnt ; nIndex++) - { + for (nIndex = 0; nIndex < nCurClassifierCnt; nIndex++) { stConvergenceSLTypes *psfCSType = NULL; - psfCSType = &pstAddIndication->sfAdmittedSet.cConvergenceSLTypes[nIndex]; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " CCPacketClassificationRuleSI====>"); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ClassifierRulePriority :0x%02X ", - psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfServiceLength :0x%02X", - psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfService[3] :0x%02X %02X %02X", - psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0], - psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1], - psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]); - for(uiLoopIndex=0; uiLoopIndex < 1; uiLoopIndex++) - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Protocol: 0x%02X ", - psfCSType->cCPacketClassificationRule.u8Protocol); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddressLength :0x%02X ", - psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength); - - for(uiLoopIndex=0; uiLoopIndex < 32; uiLoopIndex++) - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddress[32] : 0x%02X ", - psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress[uiLoopIndex]); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddressLength : 0x%02X ", - psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength); - - for(uiLoopIndex=0; uiLoopIndex < 32; uiLoopIndex++) - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddress[32] : 0x%02X ", - psfCSType->cCPacketClassificationRule.u8IPDestinationAddress[uiLoopIndex]); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRangeLength : 0x%02X ", - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRange[4] : 0x %02X %02X %02X %02X ", - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[0], - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[1], - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[2], - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[3]); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRangeLength : 0x%02X ", - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRange[4] : 0x %02X %02X %02X %02X ", - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[0], - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[1], - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[2], - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[3]); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddressLength : 0x%02X ", - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddress[6] : 0x %02X %02X %02X %02X %02X %02X", - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[0], - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[1], - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[2], - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[3], - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[4], - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[5]); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddressLength : 0x%02X ", - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddress[6] : 0x %02X %02X %02X %02X %02X %02X", - psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[0], - psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[1], - psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[2], - psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[3], - psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[4], - psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[5]); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthertypeLength : 0x%02X ", - psfCSType->cCPacketClassificationRule.u8EthertypeLength); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Ethertype[3] : 0x%02X %02X %02X", - psfCSType->cCPacketClassificationRule.u8Ethertype[0], - psfCSType->cCPacketClassificationRule.u8Ethertype[1], - psfCSType->cCPacketClassificationRule.u8Ethertype[2]); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UserPriority : 0x%X ", - psfCSType->cCPacketClassificationRule.u16UserPriority); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16VLANID : 0x%X ", - psfCSType->cCPacketClassificationRule.u16VLANID); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8AssociatedPHSI : 0x%02X ", - psfCSType->cCPacketClassificationRule.u8AssociatedPHSI); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16PacketClassificationRuleIndex : 0x%X ", - psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParamLength : 0x%02X", - psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParamLength); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParam[1] : 0x%02X ", - psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParam[0]); + psfCSType = &pstAddIndication->sfAdmittedSet.cConvergenceSLTypes[nIndex]; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " CCPacketClassificationRuleSI====>"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ClassifierRulePriority: 0x%02X ", + psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfServiceLength: 0x%02X", + psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfService[3]: 0x%02X %02X %02X", + psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0], + psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1], + psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]); + for (uiLoopIndex = 0; uiLoopIndex < 1; uiLoopIndex++) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Protocol: 0x%02X ", psfCSType->cCPacketClassificationRule.u8Protocol); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddressLength: 0x%02X ", + psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength); + + for (uiLoopIndex = 0; uiLoopIndex < 32; uiLoopIndex++) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddress[32]: 0x%02X ", + psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress[uiLoopIndex]); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddressLength: 0x%02X ", + psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength); + + for (uiLoopIndex = 0; uiLoopIndex < 32; uiLoopIndex++) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddress[32]: 0x%02X ", + psfCSType->cCPacketClassificationRule.u8IPDestinationAddress[uiLoopIndex]); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRangeLength: 0x%02X ", + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRange[4]: 0x %02X %02X %02X %02X ", + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[0], + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[1], + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[2], + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[3]); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRangeLength: 0x%02X ", + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRange[4]: 0x %02X %02X %02X %02X ", + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[0], + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[1], + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[2], + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[3]); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddressLength: 0x%02X ", + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddress[6]: 0x %02X %02X %02X %02X %02X %02X", + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[0], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[1], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[2], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[3], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[4], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[5]); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddressLength: 0x%02X ", + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddress[6]: 0x %02X %02X %02X %02X %02X %02X", + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[0], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[1], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[2], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[3], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[4], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[5]); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthertypeLength: 0x%02X ", psfCSType->cCPacketClassificationRule.u8EthertypeLength); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Ethertype[3]: 0x%02X %02X %02X", + psfCSType->cCPacketClassificationRule.u8Ethertype[0], + psfCSType->cCPacketClassificationRule.u8Ethertype[1], + psfCSType->cCPacketClassificationRule.u8Ethertype[2]); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UserPriority: 0x%X ", psfCSType->cCPacketClassificationRule.u16UserPriority); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16VLANID: 0x%X ", psfCSType->cCPacketClassificationRule.u16VLANID); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8AssociatedPHSI: 0x%02X ", psfCSType->cCPacketClassificationRule.u8AssociatedPHSI); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16PacketClassificationRuleIndex: 0x%X ", + psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParamLength: 0x%02X", + psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParamLength); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParam[1]: 0x%02X ", + psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParam[0]); #ifdef VERSION_D5 - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLableLength : 0x%X ", - psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLable[6] : 0x %02X %02X %02X %02X %02X %02X ", - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[0], - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[1], - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[2], - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[3], - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[4], - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[5]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLableLength: 0x%X ", + psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLable[6]: 0x %02X %02X %02X %02X %02X %02X ", + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[0], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[1], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[2], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[3], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[4], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[5]); #endif } - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "bValid : 0x%X",pstAddIndication->sfAdmittedSet.bValid); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " ActiveSet--->"); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32SFID : 0x%X",pstAddIndication->sfActiveSet.u32SFID); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID : 0x%X",pstAddIndication->sfActiveSet.u16CID); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassNameLength : 0x%X", - pstAddIndication->sfActiveSet.u8ServiceClassNameLength); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassName : 0x %02X %02X %02X %02X %02X %02X", - pstAddIndication->sfActiveSet.u8ServiceClassName[0], - pstAddIndication->sfActiveSet.u8ServiceClassName[1], - pstAddIndication->sfActiveSet.u8ServiceClassName[2], - pstAddIndication->sfActiveSet.u8ServiceClassName[3], - pstAddIndication->sfActiveSet.u8ServiceClassName[4], - pstAddIndication->sfActiveSet.u8ServiceClassName[5]); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8MBSService : 0x%02X", - pstAddIndication->sfActiveSet.u8MBSService); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8QosParamSet : 0x%02X", - pstAddIndication->sfActiveSet.u8QosParamSet); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority : 0x%02X", - pstAddIndication->sfActiveSet.u8TrafficPriority); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst : 0x%X", - pstAddIndication->sfActiveSet.u32MaxTrafficBurst); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate : 0x%X", - pstAddIndication->sfActiveSet.u32MinReservedTrafficRate); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength : 0x%02X", - pstAddIndication->sfActiveSet.u8VendorSpecificQoSParamLength); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam : 0x%02X", - pstAddIndication->sfActiveSet.u8VendorSpecificQoSParam[0]); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceFlowSchedulingType : 0x%02X", - pstAddIndication->sfActiveSet.u8ServiceFlowSchedulingType); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32ToleratedJitter : 0x%X", - pstAddIndication->sfActiveSet.u32ToleratedJitter); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaximumLatency : 0x%X", - pstAddIndication->sfActiveSet.u32MaximumLatency); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8FixedLengthVSVariableLengthSDUIndicator: 0x%02X", - pstAddIndication->sfActiveSet.u8FixedLengthVSVariableLengthSDUIndicator); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8SDUSize : 0x%X", - pstAddIndication->sfActiveSet.u8SDUSize); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16TargetSAID : 0x%X", - pstAddIndication->sfActiveSet.u16TargetSAID); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ARQEnable : 0x%X", - pstAddIndication->sfActiveSet.u8ARQEnable); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQWindowSize : 0x%X", - pstAddIndication->sfActiveSet.u16ARQWindowSize); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQRetryTxTimeOut : 0x%X", - pstAddIndication->sfActiveSet.u16ARQRetryTxTimeOut); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQRetryRxTimeOut : 0x%X", - pstAddIndication->sfActiveSet.u16ARQRetryRxTimeOut); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQBlockLifeTime : 0x%X", - pstAddIndication->sfActiveSet.u16ARQBlockLifeTime); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQSyncLossTimeOut : 0x%X", - pstAddIndication->sfActiveSet.u16ARQSyncLossTimeOut); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ARQDeliverInOrder : 0x%X", - pstAddIndication->sfActiveSet.u8ARQDeliverInOrder); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQRxPurgeTimeOut : 0x%X", - pstAddIndication->sfActiveSet.u16ARQRxPurgeTimeOut); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQBlockSize : 0x%X", - pstAddIndication->sfActiveSet.u16ARQBlockSize); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8CSSpecification : 0x%X", - pstAddIndication->sfActiveSet.u8CSSpecification); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8TypeOfDataDeliveryService : 0x%X", - pstAddIndication->sfActiveSet.u8TypeOfDataDeliveryService); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16SDUInterArrivalTime : 0x%X", - pstAddIndication->sfActiveSet.u16SDUInterArrivalTime); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16TimeBase : 0x%X", - pstAddIndication->sfActiveSet.u16TimeBase); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8PagingPreference : 0x%X", - pstAddIndication->sfActiveSet.u8PagingPreference); - - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8TrafficIndicationPreference : 0x%X", - pstAddIndication->sfActiveSet.u8TrafficIndicationPreference); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " Total Classifiers Received : 0x%X",pstAddIndication->sfActiveSet.u8TotalClassifiers); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "bValid: 0x%X", pstAddIndication->sfAdmittedSet.bValid); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " ActiveSet--->"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32SFID: 0x%X", pstAddIndication->sfActiveSet.u32SFID); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID: 0x%X", pstAddIndication->sfActiveSet.u16CID); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassNameLength: 0x%X", pstAddIndication->sfActiveSet.u8ServiceClassNameLength); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassName: 0x %02X %02X %02X %02X %02X %02X", + pstAddIndication->sfActiveSet.u8ServiceClassName[0], + pstAddIndication->sfActiveSet.u8ServiceClassName[1], + pstAddIndication->sfActiveSet.u8ServiceClassName[2], + pstAddIndication->sfActiveSet.u8ServiceClassName[3], + pstAddIndication->sfActiveSet.u8ServiceClassName[4], + pstAddIndication->sfActiveSet.u8ServiceClassName[5]); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8MBSService: 0x%02X", pstAddIndication->sfActiveSet.u8MBSService); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8QosParamSet: 0x%02X", pstAddIndication->sfActiveSet.u8QosParamSet); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority: 0x%02X", pstAddIndication->sfActiveSet.u8TrafficPriority); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst: 0x%X", pstAddIndication->sfActiveSet.u32MaxTrafficBurst); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate: 0x%X", + pstAddIndication->sfActiveSet.u32MinReservedTrafficRate); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength: 0x%02X", + pstAddIndication->sfActiveSet.u8VendorSpecificQoSParamLength); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam: 0x%02X", + pstAddIndication->sfActiveSet.u8VendorSpecificQoSParam[0]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceFlowSchedulingType: 0x%02X", + pstAddIndication->sfActiveSet.u8ServiceFlowSchedulingType); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32ToleratedJitter: 0x%X", pstAddIndication->sfActiveSet.u32ToleratedJitter); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaximumLatency: 0x%X", pstAddIndication->sfActiveSet.u32MaximumLatency); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8FixedLengthVSVariableLengthSDUIndicator: 0x%02X", + pstAddIndication->sfActiveSet.u8FixedLengthVSVariableLengthSDUIndicator); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8SDUSize: 0x%X", pstAddIndication->sfActiveSet.u8SDUSize); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16TargetSAID: 0x%X", pstAddIndication->sfActiveSet.u16TargetSAID); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ARQEnable: 0x%X", pstAddIndication->sfActiveSet.u8ARQEnable); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQWindowSize: 0x%X", pstAddIndication->sfActiveSet.u16ARQWindowSize); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQRetryTxTimeOut: 0x%X", pstAddIndication->sfActiveSet.u16ARQRetryTxTimeOut); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQRetryRxTimeOut: 0x%X", pstAddIndication->sfActiveSet.u16ARQRetryRxTimeOut); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQBlockLifeTime: 0x%X", pstAddIndication->sfActiveSet.u16ARQBlockLifeTime); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQSyncLossTimeOut: 0x%X", pstAddIndication->sfActiveSet.u16ARQSyncLossTimeOut); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ARQDeliverInOrder: 0x%X", pstAddIndication->sfActiveSet.u8ARQDeliverInOrder); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQRxPurgeTimeOut: 0x%X", pstAddIndication->sfActiveSet.u16ARQRxPurgeTimeOut); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQBlockSize: 0x%X", pstAddIndication->sfActiveSet.u16ARQBlockSize); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8CSSpecification: 0x%X", pstAddIndication->sfActiveSet.u8CSSpecification); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8TypeOfDataDeliveryService: 0x%X", + pstAddIndication->sfActiveSet.u8TypeOfDataDeliveryService); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16SDUInterArrivalTime: 0x%X", pstAddIndication->sfActiveSet.u16SDUInterArrivalTime); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16TimeBase: 0x%X", pstAddIndication->sfActiveSet.u16TimeBase); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8PagingPreference: 0x%X", pstAddIndication->sfActiveSet.u8PagingPreference); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8TrafficIndicationPreference: 0x%X", + pstAddIndication->sfActiveSet.u8TrafficIndicationPreference); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " Total Classifiers Received: 0x%X", pstAddIndication->sfActiveSet.u8TotalClassifiers); nCurClassifierCnt = pstAddIndication->sfActiveSet.u8TotalClassifiers; - - if(nCurClassifierCnt > MAX_CLASSIFIERS_IN_SF) - { + if (nCurClassifierCnt > MAX_CLASSIFIERS_IN_SF) nCurClassifierCnt = MAX_CLASSIFIERS_IN_SF; - } - - for(nIndex = 0 ; nIndex < nCurClassifierCnt ; nIndex++) - { + for (nIndex = 0; nIndex < nCurClassifierCnt; nIndex++) { stConvergenceSLTypes *psfCSType = NULL; - psfCSType = &pstAddIndication->sfActiveSet.cConvergenceSLTypes[nIndex]; - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " CCPacketClassificationRuleSI====>"); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ClassifierRulePriority :0x%X ", - psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8IPTypeOfServiceLength :0x%X ", - psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8IPTypeOfService[3] :0x%X ,0x%X ,0x%X ", - psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0], - psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1], - psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]); - for(uiLoopIndex=0; uiLoopIndex < 1; uiLoopIndex++) - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8Protocol : 0x%X ", - psfCSType->cCPacketClassificationRule.u8Protocol); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddressLength :0x%X ", - psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength); - - for(uiLoopIndex=0; uiLoopIndex < 32; uiLoopIndex++) - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddress[32]:0x%X ", - psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress[uiLoopIndex]); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddressLength : 0x%02X ", - psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength); - - for(uiLoopIndex=0;uiLoopIndex<32;uiLoopIndex++) - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8IPDestinationAddress[32]:0x%X ", - psfCSType->cCPacketClassificationRule.u8IPDestinationAddress[uiLoopIndex]); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ProtocolSourcePortRangeLength:0x%X ", - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ProtocolSourcePortRange[4]:0x%X ,0x%X ,0x%X ,0x%X ", - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[0], - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[1], - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[2], - psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[3]); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ProtocolDestPortRangeLength:0x%X ", - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ProtocolDestPortRange[4]:0x%X ,0x%X ,0x%X ,0x%X ", - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[0], - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[1], - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[2], - psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[3]); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8EthernetDestMacAddressLength:0x%X ", - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8EthernetDestMacAddress[6]:0x%X ,0x%X ,0x%X ,0x%X ,0x%X ,0x%X", - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[0], - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[1], - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[2], - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[3], - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[4], - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[5]); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8EthernetSourceMACAddressLength:0x%X ", - psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddress[6]:0x%X ,0x%X ,0x%X ,0x%X ,0x%X ,0x%X", - psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[0], - psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[1], - psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[2], - psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[3], - psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[4], - psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[5]); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8EthertypeLength :0x%X ", - psfCSType->cCPacketClassificationRule.u8EthertypeLength); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8Ethertype[3] :0x%X ,0x%X ,0x%X ", - psfCSType->cCPacketClassificationRule.u8Ethertype[0], - psfCSType->cCPacketClassificationRule.u8Ethertype[1], - psfCSType->cCPacketClassificationRule.u8Ethertype[2]); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16UserPriority :0x%X ", - psfCSType->cCPacketClassificationRule.u16UserPriority); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16VLANID :0x%X ", - psfCSType->cCPacketClassificationRule.u16VLANID); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8AssociatedPHSI :0x%X ", - psfCSType->cCPacketClassificationRule.u8AssociatedPHSI); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16PacketClassificationRuleIndex:0x%X ", - psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8VendorSpecificClassifierParamLength:0x%X ", - psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParamLength); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8VendorSpecificClassifierParam[1]:0x%X ", - psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParam[0]); + psfCSType = &pstAddIndication->sfActiveSet.cConvergenceSLTypes[nIndex]; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " CCPacketClassificationRuleSI====>"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ClassifierRulePriority: 0x%X ", + psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8IPTypeOfServiceLength: 0x%X ", + psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8IPTypeOfService[3]: 0x%X ,0x%X ,0x%X ", + psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0], + psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1], + psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]); + + for (uiLoopIndex = 0; uiLoopIndex < 1; uiLoopIndex++) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8Protocol: 0x%X ", psfCSType->cCPacketClassificationRule.u8Protocol); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddressLength: 0x%X ", + psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength); + + for (uiLoopIndex = 0; uiLoopIndex < 32; uiLoopIndex++) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddress[32]: 0x%X ", + psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress[uiLoopIndex]); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddressLength: 0x%02X ", + psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength); + + for (uiLoopIndex = 0; uiLoopIndex < 32; uiLoopIndex++) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8IPDestinationAddress[32]:0x%X ", + psfCSType->cCPacketClassificationRule.u8IPDestinationAddress[uiLoopIndex]); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ProtocolSourcePortRangeLength: 0x%X ", + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ProtocolSourcePortRange[4]: 0x%X ,0x%X ,0x%X ,0x%X ", + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[0], + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[1], + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[2], + psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[3]); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ProtocolDestPortRangeLength: 0x%X ", + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ProtocolDestPortRange[4]: 0x%X ,0x%X ,0x%X ,0x%X ", + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[0], + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[1], + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[2], + psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[3]); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8EthernetDestMacAddressLength: 0x%X ", + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8EthernetDestMacAddress[6]: 0x%X ,0x%X ,0x%X ,0x%X ,0x%X ,0x%X", + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[0], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[1], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[2], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[3], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[4], + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[5]); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8EthernetSourceMACAddressLength: 0x%X ", + psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddress[6]: 0x%X ,0x%X ,0x%X ,0x%X ,0x%X ,0x%X", + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[0], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[1], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[2], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[3], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[4], + psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[5]); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8EthertypeLength: 0x%X ", + psfCSType->cCPacketClassificationRule.u8EthertypeLength); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8Ethertype[3]: 0x%X ,0x%X ,0x%X ", + psfCSType->cCPacketClassificationRule.u8Ethertype[0], + psfCSType->cCPacketClassificationRule.u8Ethertype[1], + psfCSType->cCPacketClassificationRule.u8Ethertype[2]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16UserPriority: 0x%X ", + psfCSType->cCPacketClassificationRule.u16UserPriority); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16VLANID: 0x%X ", psfCSType->cCPacketClassificationRule.u16VLANID); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8AssociatedPHSI: 0x%X ", psfCSType->cCPacketClassificationRule.u8AssociatedPHSI); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16PacketClassificationRuleIndex:0x%X ", + psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8VendorSpecificClassifierParamLength:0x%X ", + psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParamLength); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8VendorSpecificClassifierParam[1]:0x%X ", + psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParam[0]); #ifdef VERSION_D5 - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8IPv6FlowLableLength :0x%X ", - psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8IPv6FlowLable[6] :0x%X ,0x%X ,0x%X ,0x%X ,0x%X ,0x%X ", - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[0], - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[1], - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[2], - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[3], - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[4], - psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[5]); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8IPv6FlowLableLength: 0x%X ", + psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8IPv6FlowLable[6]: 0x%X ,0x%X ,0x%X ,0x%X ,0x%X ,0x%X ", + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[0], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[1], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[2], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[3], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[4], + psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[5]); #endif } - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " bValid : 0x%X",pstAddIndication->sfActiveSet.bValid); - + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " bValid: 0x%X", pstAddIndication->sfActiveSet.bValid); } -static inline ULONG RestoreSFParam(PMINI_ADAPTER Adapter, ULONG ulAddrSFParamSet,PUCHAR pucDestBuffer) +static inline ULONG RestoreSFParam(PMINI_ADAPTER Adapter, ULONG ulAddrSFParamSet, PUCHAR pucDestBuffer) { UINT nBytesToRead = sizeof(stServiceFlowParamSI); - if(ulAddrSFParamSet == 0 || NULL == pucDestBuffer) - { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Got Param address as 0!!"); + if (ulAddrSFParamSet == 0 || NULL == pucDestBuffer) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Got Param address as 0!!"); return 0; } ulAddrSFParamSet = ntohl(ulAddrSFParamSet); - //Read out the SF Param Set At the indicated Location - if(rdm(Adapter, ulAddrSFParamSet, (PUCHAR)pucDestBuffer, nBytesToRead) < 0) + /* Read out the SF Param Set At the indicated Location */ + if (rdm(Adapter, ulAddrSFParamSet, (PUCHAR)pucDestBuffer, nBytesToRead) < 0) return STATUS_FAILURE; return 1; } - -static ULONG StoreSFParam(PMINI_ADAPTER Adapter,PUCHAR pucSrcBuffer,ULONG ulAddrSFParamSet) +static ULONG StoreSFParam(PMINI_ADAPTER Adapter, PUCHAR pucSrcBuffer, ULONG ulAddrSFParamSet) { - UINT nBytesToWrite = sizeof(stServiceFlowParamSI); + UINT nBytesToWrite = sizeof(stServiceFlowParamSI); int ret = 0; - if(ulAddrSFParamSet == 0 || NULL == pucSrcBuffer) - { + if (ulAddrSFParamSet == 0 || NULL == pucSrcBuffer) return 0; - } ret = wrm(Adapter, ulAddrSFParamSet, (u8 *)pucSrcBuffer, nBytesToWrite); if (ret < 0) { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "%s:%d WRM failed",__FUNCTION__, __LINE__); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "%s:%d WRM failed", __FUNCTION__, __LINE__); return ret; } return 1; } -ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT *puBufferLength) +ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter, PVOID pvBuffer, UINT *puBufferLength) { stLocalSFAddIndicationAlt *pstAddIndicationAlt = NULL; - stLocalSFAddIndication * pstAddIndication = NULL; + stLocalSFAddIndication *pstAddIndication = NULL; stLocalSFDeleteRequest *pstDeletionRequest; UINT uiSearchRuleIndex; ULONG ulSFID; @@ -1671,52 +1369,47 @@ ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT *p pstAddIndicationAlt = (stLocalSFAddIndicationAlt *)(pvBuffer); /* - * In case of DSD Req By MS, we should immediately delete this SF so that - * we can stop the further classifying the pkt for this SF. - */ - if(pstAddIndicationAlt->u8Type == DSD_REQ) - { + * In case of DSD Req By MS, we should immediately delete this SF so that + * we can stop the further classifying the pkt for this SF. + */ + if (pstAddIndicationAlt->u8Type == DSD_REQ) { pstDeletionRequest = (stLocalSFDeleteRequest *)pvBuffer; ulSFID = ntohl(pstDeletionRequest->u32SFID); - uiSearchRuleIndex=SearchSfid(Adapter,ulSFID); + uiSearchRuleIndex = SearchSfid(Adapter, ulSFID); - if(uiSearchRuleIndex < NO_OF_QUEUES) - { - deleteSFBySfid(Adapter,uiSearchRuleIndex); + if (uiSearchRuleIndex < NO_OF_QUEUES) { + deleteSFBySfid(Adapter, uiSearchRuleIndex); Adapter->u32TotalDSD++; } return 1; } - - if( (pstAddIndicationAlt->u8Type == DSD_RSP) || - (pstAddIndicationAlt->u8Type == DSD_ACK)) - { - //No Special handling send the message as it is + if ((pstAddIndicationAlt->u8Type == DSD_RSP) || + (pstAddIndicationAlt->u8Type == DSD_ACK)) { + /* No Special handling send the message as it is */ return 1; } - // For DSA_REQ, only up to "psfAuthorizedSet" parameter should be accessed by driver! + /* For DSA_REQ, only up to "psfAuthorizedSet" parameter should be accessed by driver! */ - pstAddIndication=kmalloc(sizeof(*pstAddIndication), GFP_KERNEL); - if(NULL==pstAddIndication) + pstAddIndication = kmalloc(sizeof(*pstAddIndication), GFP_KERNEL); + if (NULL == pstAddIndication) return 0; /* AUTHORIZED SET */ pstAddIndication->psfAuthorizedSet = (stServiceFlowParamSI *) GetNextTargetBufferLocation(Adapter, pstAddIndicationAlt->u16TID); - if(!pstAddIndication->psfAuthorizedSet) + if (!pstAddIndication->psfAuthorizedSet) return 0; - if(StoreSFParam(Adapter,(PUCHAR)&pstAddIndicationAlt->sfAuthorizedSet, - (ULONG)pstAddIndication->psfAuthorizedSet)!= 1) + if (StoreSFParam(Adapter, (PUCHAR)&pstAddIndicationAlt->sfAuthorizedSet, + (ULONG)pstAddIndication->psfAuthorizedSet) != 1) return 0; /* this can't possibly be right */ pstAddIndication->psfAuthorizedSet = (stServiceFlowParamSI *)ntohl((ULONG)pstAddIndication->psfAuthorizedSet); - if(pstAddIndicationAlt->u8Type == DSA_REQ) - { + if (pstAddIndicationAlt->u8Type == DSA_REQ) { stLocalSFAddRequest AddRequest; AddRequest.u8Type = pstAddIndicationAlt->u8Type; @@ -1724,18 +1417,17 @@ ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT *p AddRequest.u16TID = pstAddIndicationAlt->u16TID; AddRequest.u16CID = pstAddIndicationAlt->u16CID; AddRequest.u16VCID = pstAddIndicationAlt->u16VCID; - AddRequest.psfParameterSet =pstAddIndication->psfAuthorizedSet ; + AddRequest.psfParameterSet = pstAddIndication->psfAuthorizedSet; (*puBufferLength) = sizeof(stLocalSFAddRequest); - memcpy(pvBuffer,&AddRequest,sizeof(stLocalSFAddRequest)); + memcpy(pvBuffer, &AddRequest, sizeof(stLocalSFAddRequest)); return 1; } - // Since it's not DSA_REQ, we can access all field in pstAddIndicationAlt - - //We need to extract the structure from the buffer and pack it differently + /* Since it's not DSA_REQ, we can access all field in pstAddIndicationAlt */ + /* We need to extract the structure from the buffer and pack it differently */ pstAddIndication->u8Type = pstAddIndicationAlt->u8Type; - pstAddIndication->eConnectionDir= pstAddIndicationAlt->u8Direction ; + pstAddIndication->eConnectionDir = pstAddIndicationAlt->u8Direction; pstAddIndication->u16TID = pstAddIndicationAlt->u16TID; pstAddIndication->u16CID = pstAddIndicationAlt->u16CID; pstAddIndication->u16VCID = pstAddIndicationAlt->u16VCID; @@ -1744,20 +1436,19 @@ ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT *p /* ADMITTED SET */ pstAddIndication->psfAdmittedSet = (stServiceFlowParamSI *) GetNextTargetBufferLocation(Adapter, pstAddIndicationAlt->u16TID); - if(!pstAddIndication->psfAdmittedSet) + if (!pstAddIndication->psfAdmittedSet) return 0; - if(StoreSFParam(Adapter,(PUCHAR)&pstAddIndicationAlt->sfAdmittedSet,(ULONG)pstAddIndication->psfAdmittedSet) != 1) + if (StoreSFParam(Adapter, (PUCHAR)&pstAddIndicationAlt->sfAdmittedSet, (ULONG)pstAddIndication->psfAdmittedSet) != 1) return 0; pstAddIndication->psfAdmittedSet = (stServiceFlowParamSI *)ntohl((ULONG)pstAddIndication->psfAdmittedSet); - /* ACTIVE SET */ pstAddIndication->psfActiveSet = (stServiceFlowParamSI *) GetNextTargetBufferLocation(Adapter, pstAddIndicationAlt->u16TID); - if(!pstAddIndication->psfActiveSet) + if (!pstAddIndication->psfActiveSet) return 0; - if(StoreSFParam(Adapter,(PUCHAR)&pstAddIndicationAlt->sfActiveSet,(ULONG)pstAddIndication->psfActiveSet) != 1) + if (StoreSFParam(Adapter, (PUCHAR)&pstAddIndicationAlt->sfActiveSet, (ULONG)pstAddIndication->psfActiveSet) != 1) return 0; pstAddIndication->psfActiveSet = (stServiceFlowParamSI *)ntohl((ULONG)pstAddIndication->psfActiveSet); @@ -1768,47 +1459,41 @@ ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT *p return 1; } - static inline stLocalSFAddIndicationAlt -*RestoreCmControlResponseMessage(register PMINI_ADAPTER Adapter,register PVOID pvBuffer) +*RestoreCmControlResponseMessage(register PMINI_ADAPTER Adapter, register PVOID pvBuffer) { - ULONG ulStatus=0; + ULONG ulStatus = 0; stLocalSFAddIndication *pstAddIndication = NULL; stLocalSFAddIndicationAlt *pstAddIndicationDest = NULL; - pstAddIndication = (stLocalSFAddIndication *)(pvBuffer); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "=====>" ); + pstAddIndication = (stLocalSFAddIndication *)(pvBuffer); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "=====>"); if ((pstAddIndication->u8Type == DSD_REQ) || (pstAddIndication->u8Type == DSD_RSP) || (pstAddIndication->u8Type == DSD_ACK)) - { return (stLocalSFAddIndicationAlt *)pvBuffer; - } - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Inside RestoreCmControlResponseMessage "); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Inside RestoreCmControlResponseMessage "); /* - //Need to Allocate memory to contain the SUPER Large structures - //Our driver can't create these structures on Stack :( - */ - pstAddIndicationDest=kmalloc(sizeof(stLocalSFAddIndicationAlt), GFP_KERNEL); - - if(pstAddIndicationDest) - { - memset(pstAddIndicationDest,0,sizeof(stLocalSFAddIndicationAlt)); - } - else - { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Failed to allocate memory for SF Add Indication Structure "); + * Need to Allocate memory to contain the SUPER Large structures + * Our driver can't create these structures on Stack :( + */ + pstAddIndicationDest = kmalloc(sizeof(stLocalSFAddIndicationAlt), GFP_KERNEL); + + if (pstAddIndicationDest) { + memset(pstAddIndicationDest, 0, sizeof(stLocalSFAddIndicationAlt)); + } else { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Failed to allocate memory for SF Add Indication Structure "); return NULL; } - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-u8Type : 0x%X",pstAddIndication->u8Type); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-u8Direction : 0x%X",pstAddIndication->eConnectionDir); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-u8TID : 0x%X",ntohs(pstAddIndication->u16TID)); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-u8CID : 0x%X",ntohs(pstAddIndication->u16CID)); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-u16VCID : 0x%X",ntohs(pstAddIndication->u16VCID)); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-autorized set loc : %p",pstAddIndication->psfAuthorizedSet); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-admitted set loc : %p",pstAddIndication->psfAdmittedSet); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-Active set loc : %p",pstAddIndication->psfActiveSet); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-u8Type : 0x%X", pstAddIndication->u8Type); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-u8Direction : 0x%X", pstAddIndication->eConnectionDir); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-u8TID : 0x%X", ntohs(pstAddIndication->u16TID)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-u8CID : 0x%X", ntohs(pstAddIndication->u16CID)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-u16VCID : 0x%X", ntohs(pstAddIndication->u16VCID)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-autorized set loc : %p", pstAddIndication->psfAuthorizedSet); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-admitted set loc : %p", pstAddIndication->psfAdmittedSet); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-Active set loc : %p", pstAddIndication->psfActiveSet); pstAddIndicationDest->u8Type = pstAddIndication->u8Type; pstAddIndicationDest->u8Direction = pstAddIndication->eConnectionDir; @@ -1817,42 +1502,39 @@ static inline stLocalSFAddIndicationAlt pstAddIndicationDest->u16VCID = pstAddIndication->u16VCID; pstAddIndicationDest->u8CC = pstAddIndication->u8CC; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Restoring Active Set "); - ulStatus=RestoreSFParam(Adapter,(ULONG)pstAddIndication->psfActiveSet, (PUCHAR)&pstAddIndicationDest->sfActiveSet); - if(ulStatus != 1) - { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Restoring Active Set "); + ulStatus = RestoreSFParam(Adapter, (ULONG)pstAddIndication->psfActiveSet, (PUCHAR)&pstAddIndicationDest->sfActiveSet); + if (ulStatus != 1) goto failed_restore_sf_param; - } - if(pstAddIndicationDest->sfActiveSet.u8TotalClassifiers > MAX_CLASSIFIERS_IN_SF) + + if (pstAddIndicationDest->sfActiveSet.u8TotalClassifiers > MAX_CLASSIFIERS_IN_SF) pstAddIndicationDest->sfActiveSet.u8TotalClassifiers = MAX_CLASSIFIERS_IN_SF; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Restoring Admitted Set "); - ulStatus=RestoreSFParam(Adapter,(ULONG)pstAddIndication->psfAdmittedSet,(PUCHAR)&pstAddIndicationDest->sfAdmittedSet); - if(ulStatus != 1) - { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Restoring Admitted Set "); + ulStatus = RestoreSFParam(Adapter, (ULONG)pstAddIndication->psfAdmittedSet, (PUCHAR)&pstAddIndicationDest->sfAdmittedSet); + if (ulStatus != 1) goto failed_restore_sf_param; - } - if(pstAddIndicationDest->sfAdmittedSet.u8TotalClassifiers > MAX_CLASSIFIERS_IN_SF) + + if (pstAddIndicationDest->sfAdmittedSet.u8TotalClassifiers > MAX_CLASSIFIERS_IN_SF) pstAddIndicationDest->sfAdmittedSet.u8TotalClassifiers = MAX_CLASSIFIERS_IN_SF; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Restoring Authorized Set "); - ulStatus=RestoreSFParam(Adapter,(ULONG)pstAddIndication->psfAuthorizedSet,(PUCHAR)&pstAddIndicationDest->sfAuthorizedSet); - if(ulStatus != 1) - { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Restoring Authorized Set "); + ulStatus = RestoreSFParam(Adapter, (ULONG)pstAddIndication->psfAuthorizedSet, (PUCHAR)&pstAddIndicationDest->sfAuthorizedSet); + if (ulStatus != 1) goto failed_restore_sf_param; - } - if(pstAddIndicationDest->sfAuthorizedSet.u8TotalClassifiers > MAX_CLASSIFIERS_IN_SF) + + if (pstAddIndicationDest->sfAuthorizedSet.u8TotalClassifiers > MAX_CLASSIFIERS_IN_SF) pstAddIndicationDest->sfAuthorizedSet.u8TotalClassifiers = MAX_CLASSIFIERS_IN_SF; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Dumping the whole raw packet"); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "============================================================"); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " pstAddIndicationDest->sfActiveSet size %zx %p", sizeof(*pstAddIndicationDest), pstAddIndicationDest); - //BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, (unsigned char *)pstAddIndicationDest, sizeof(*pstAddIndicationDest)); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "============================================================"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Dumping the whole raw packet"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "============================================================"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " pstAddIndicationDest->sfActiveSet size %zx %p", sizeof(*pstAddIndicationDest), pstAddIndicationDest); + /* BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, (unsigned char *)pstAddIndicationDest, sizeof(*pstAddIndicationDest)); */ + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "============================================================"); return pstAddIndicationDest; failed_restore_sf_param: kfree(pstAddIndicationDest); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "<=====" ); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "<====="); return NULL; } @@ -1860,7 +1542,7 @@ ULONG SetUpTargetDsxBuffers(PMINI_ADAPTER Adapter) { ULONG ulTargetDsxBuffersBase = 0; ULONG ulCntTargetBuffers; - ULONG ulIndex=0; + ULONG ulIndex = 0; int Status; if (!Adapter) { @@ -1868,100 +1550,85 @@ ULONG SetUpTargetDsxBuffers(PMINI_ADAPTER Adapter) return 0; } - if(Adapter->astTargetDsxBuffer[0].ulTargetDsxBuffer) + if (Adapter->astTargetDsxBuffer[0].ulTargetDsxBuffer) return 1; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Size of Each DSX Buffer(Also size of ServiceFlowParamSI): %zx ",sizeof(stServiceFlowParamSI)); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Reading DSX buffer From Target location %x ",DSX_MESSAGE_EXCHANGE_BUFFER); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Size of Each DSX Buffer(Also size of ServiceFlowParamSI): %zx ", sizeof(stServiceFlowParamSI)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Reading DSX buffer From Target location %x ", DSX_MESSAGE_EXCHANGE_BUFFER); - Status = rdmalt(Adapter, DSX_MESSAGE_EXCHANGE_BUFFER, - (PUINT)&ulTargetDsxBuffersBase, sizeof(UINT)); - if(Status < 0) - { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "RDM failed!!"); + Status = rdmalt(Adapter, DSX_MESSAGE_EXCHANGE_BUFFER, (PUINT)&ulTargetDsxBuffersBase, sizeof(UINT)); + if (Status < 0) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "RDM failed!!"); return 0; } - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Base Address Of DSX Target Buffer : 0x%lx",ulTargetDsxBuffersBase); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Tgt Buffer is Now %lx :",ulTargetDsxBuffersBase); - - ulCntTargetBuffers = DSX_MESSAGE_EXCHANGE_BUFFER_SIZE/sizeof(stServiceFlowParamSI); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Base Address Of DSX Target Buffer : 0x%lx", ulTargetDsxBuffersBase); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Tgt Buffer is Now %lx :", ulTargetDsxBuffersBase); + ulCntTargetBuffers = DSX_MESSAGE_EXCHANGE_BUFFER_SIZE / sizeof(stServiceFlowParamSI); Adapter->ulTotalTargetBuffersAvailable = ulCntTargetBuffers > MAX_TARGET_DSX_BUFFERS ? MAX_TARGET_DSX_BUFFERS : ulCntTargetBuffers; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " Total Target DSX Buffer setup %lx ",Adapter->ulTotalTargetBuffersAvailable); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " Total Target DSX Buffer setup %lx ", Adapter->ulTotalTargetBuffersAvailable); - for(ulIndex=0; ulIndex < Adapter->ulTotalTargetBuffersAvailable ; ulIndex++) - { + for (ulIndex = 0; ulIndex < Adapter->ulTotalTargetBuffersAvailable; ulIndex++) { Adapter->astTargetDsxBuffer[ulIndex].ulTargetDsxBuffer = ulTargetDsxBuffersBase; - Adapter->astTargetDsxBuffer[ulIndex].valid=1; - Adapter->astTargetDsxBuffer[ulIndex].tid=0; - ulTargetDsxBuffersBase+=sizeof(stServiceFlowParamSI); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " Target DSX Buffer %lx setup at 0x%lx", - ulIndex, Adapter->astTargetDsxBuffer[ulIndex].ulTargetDsxBuffer); + Adapter->astTargetDsxBuffer[ulIndex].valid = 1; + Adapter->astTargetDsxBuffer[ulIndex].tid = 0; + ulTargetDsxBuffersBase += sizeof(stServiceFlowParamSI); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " Target DSX Buffer %lx setup at 0x%lx", + ulIndex, Adapter->astTargetDsxBuffer[ulIndex].ulTargetDsxBuffer); } Adapter->ulCurrentTargetBuffer = 0; Adapter->ulFreeTargetBufferCnt = Adapter->ulTotalTargetBuffersAvailable; return 1; } -static ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter,B_UINT16 tid) +static ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter, B_UINT16 tid) { - ULONG ulTargetDSXBufferAddress; - ULONG ulTargetDsxBufferIndexToUse,ulMaxTry; + ULONG ulTargetDSXBufferAddress; + ULONG ulTargetDsxBufferIndexToUse, ulMaxTry; - if((Adapter->ulTotalTargetBuffersAvailable == 0)|| - (Adapter->ulFreeTargetBufferCnt == 0)) - { - ClearTargetDSXBuffer(Adapter,tid,FALSE); + if ((Adapter->ulTotalTargetBuffersAvailable == 0) || (Adapter->ulFreeTargetBufferCnt == 0)) { + ClearTargetDSXBuffer(Adapter, tid, FALSE); return 0; } - ulTargetDsxBufferIndexToUse = Adapter->ulCurrentTargetBuffer; - ulMaxTry = Adapter->ulTotalTargetBuffersAvailable; - while((ulMaxTry)&&(Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].valid != 1)) - { - ulTargetDsxBufferIndexToUse = (ulTargetDsxBufferIndexToUse+1)% - Adapter->ulTotalTargetBuffersAvailable; - ulMaxTry--; + ulTargetDsxBufferIndexToUse = Adapter->ulCurrentTargetBuffer; + ulMaxTry = Adapter->ulTotalTargetBuffersAvailable; + while ((ulMaxTry) && (Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].valid != 1)) { + ulTargetDsxBufferIndexToUse = (ulTargetDsxBufferIndexToUse+1) % Adapter->ulTotalTargetBuffersAvailable; + ulMaxTry--; } - if(ulMaxTry==0) - { - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "\n GetNextTargetBufferLocation : Error No Free Target DSX Buffers FreeCnt : %lx ",Adapter->ulFreeTargetBufferCnt); - ClearTargetDSXBuffer(Adapter,tid,FALSE); + if (ulMaxTry == 0) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "\n GetNextTargetBufferLocation : Error No Free Target DSX Buffers FreeCnt : %lx ", Adapter->ulFreeTargetBufferCnt); + ClearTargetDSXBuffer(Adapter, tid, FALSE); return 0; } - - ulTargetDSXBufferAddress = - Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].ulTargetDsxBuffer; - Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].valid=0; - Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].tid=tid; + ulTargetDSXBufferAddress = Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].ulTargetDsxBuffer; + Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].valid = 0; + Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].tid = tid; Adapter->ulFreeTargetBufferCnt--; - - - ulTargetDsxBufferIndexToUse = - (ulTargetDsxBufferIndexToUse+1)%Adapter->ulTotalTargetBuffersAvailable; + ulTargetDsxBufferIndexToUse = (ulTargetDsxBufferIndexToUse+1)%Adapter->ulTotalTargetBuffersAvailable; Adapter->ulCurrentTargetBuffer = ulTargetDsxBufferIndexToUse; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "GetNextTargetBufferLocation :Returning address %lx tid %d\n", - ulTargetDSXBufferAddress,tid); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "GetNextTargetBufferLocation :Returning address %lx tid %d\n", ulTargetDSXBufferAddress, tid); + return ulTargetDSXBufferAddress; } - INT AllocAdapterDsxBuffer(PMINI_ADAPTER Adapter) { /* - //Need to Allocate memory to contain the SUPER Large structures - //Our driver can't create these structures on Stack - */ - Adapter->caDsxReqResp=kmalloc(sizeof(stLocalSFAddIndicationAlt)+LEADER_SIZE, GFP_KERNEL); - if(!Adapter->caDsxReqResp) + * Need to Allocate memory to contain the SUPER Large structures + * Our driver can't create these structures on Stack + */ + Adapter->caDsxReqResp = kmalloc(sizeof(stLocalSFAddIndicationAlt)+LEADER_SIZE, GFP_KERNEL); + if (!Adapter->caDsxReqResp) return -ENOMEM; + return 0; } @@ -1969,310 +1636,261 @@ INT FreeAdapterDsxBuffer(PMINI_ADAPTER Adapter) { kfree(Adapter->caDsxReqResp); return 0; - } -/** -@ingroup ctrl_pkt_functions -This routinue would process the Control responses -for the Connection Management. -@return - Queue index for the free SFID else returns Invalid Index. -*/ -BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**u16TID, FALSE); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0, "Error in restoring Service Flow param structure from DSx message"); + * Otherwise the message contains a target address from where we need to + * read out the rest of the service flow param structure + */ + if ((pstAddIndication = RestoreCmControlResponseMessage(Adapter, pvBuffer)) == NULL) { + ClearTargetDSXBuffer(Adapter, ((stLocalSFAddIndication *)pvBuffer)->u16TID, FALSE); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Error in restoring Service Flow param structure from DSx message"); return FALSE; } DumpCmControlPacket(pstAddIndication); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "====>"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "====>"); pLeader = (PLEADER)Adapter->caDsxReqResp; - pLeader->Status =CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ; + pLeader->Status = CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ; pLeader->Vcid = 0; - ClearTargetDSXBuffer(Adapter,pstAddIndication->u16TID,FALSE); - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "### TID RECEIVED %d\n",pstAddIndication->u16TID); - switch(pstAddIndication->u8Type) + ClearTargetDSXBuffer(Adapter, pstAddIndication->u16TID, FALSE); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "### TID RECEIVED %d\n", pstAddIndication->u16TID); + switch (pstAddIndication->u8Type) { + case DSA_REQ: { - case DSA_REQ: - { - pLeader->PLength = sizeof(stLocalSFAddIndicationAlt); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Sending DSA Response....\n"); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSA RESPONSE TO MAC %d", pLeader->PLength ); - *((stLocalSFAddIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE])) - = *pstAddIndication; - ((stLocalSFAddIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_RSP; - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " VCID = %x", ntohs(pstAddIndication->u16VCID)); - CopyBufferToControlPacket(Adapter,(PVOID)Adapter->caDsxReqResp); - kfree(pstAddIndication); - } - break; - case DSA_RSP: - { - pLeader->PLength = sizeof(stLocalSFAddIndicationAlt); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSA ACK TO MAC %d", + pLeader->PLength = sizeof(stLocalSFAddIndicationAlt); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Sending DSA Response....\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSA RESPONSE TO MAC %d", pLeader->PLength); + *((stLocalSFAddIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE])) + = *pstAddIndication; + ((stLocalSFAddIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_RSP; + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " VCID = %x", ntohs(pstAddIndication->u16VCID)); + CopyBufferToControlPacket(Adapter, (PVOID)Adapter->caDsxReqResp); + kfree(pstAddIndication); + } + break; + case DSA_RSP: + { + pLeader->PLength = sizeof(stLocalSFAddIndicationAlt); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSA ACK TO MAC %d", pLeader->PLength); - *((stLocalSFAddIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE])) - = *pstAddIndication; - ((stLocalSFAddIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_ACK; + *((stLocalSFAddIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE])) + = *pstAddIndication; + ((stLocalSFAddIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_ACK; - }//no break here..we should go down. - case DSA_ACK: - { - UINT uiSearchRuleIndex=0; + } /* no break here..we should go down. */ + case DSA_ACK: + { + UINT uiSearchRuleIndex = 0; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "VCID:0x%X", + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "VCID:0x%X", ntohs(pstAddIndication->u16VCID)); - uiSearchRuleIndex=SearchFreeSfid(Adapter); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"uiSearchRuleIndex:0x%X ", + uiSearchRuleIndex = SearchFreeSfid(Adapter); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "uiSearchRuleIndex:0x%X ", uiSearchRuleIndex); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Direction:0x%X ", + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Direction:0x%X ", pstAddIndication->u8Direction); - if((uiSearchRuleIndex< NO_OF_QUEUES) ) - { - Adapter->PackInfo[uiSearchRuleIndex].ucDirection = - pstAddIndication->u8Direction; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "bValid:0x%X ", + if ((uiSearchRuleIndex < NO_OF_QUEUES)) { + Adapter->PackInfo[uiSearchRuleIndex].ucDirection = + pstAddIndication->u8Direction; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "bValid:0x%X ", pstAddIndication->sfActiveSet.bValid); - if(pstAddIndication->sfActiveSet.bValid==TRUE) - { - Adapter->PackInfo[uiSearchRuleIndex].bActiveSet=TRUE; - } - if(pstAddIndication->sfAuthorizedSet.bValid==TRUE) - { - Adapter->PackInfo[uiSearchRuleIndex].bAuthorizedSet=TRUE; - } - if(pstAddIndication->sfAdmittedSet.bValid==TRUE) - { - Adapter->PackInfo[uiSearchRuleIndex].bAdmittedSet=TRUE; - } - if(FALSE == pstAddIndication->sfActiveSet.bValid) - { - Adapter->PackInfo[uiSearchRuleIndex].bActive = FALSE; - Adapter->PackInfo[uiSearchRuleIndex].bActivateRequestSent = FALSE; - if(pstAddIndication->sfAdmittedSet.bValid) - { - psfLocalSet = &pstAddIndication->sfAdmittedSet; - } - else if(pstAddIndication->sfAuthorizedSet.bValid) - { - psfLocalSet = &pstAddIndication->sfAuthorizedSet; - } - } - else - { - psfLocalSet = &pstAddIndication->sfActiveSet; - Adapter->PackInfo[uiSearchRuleIndex].bActive=TRUE; - } - - if(!psfLocalSet) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "No set is valid\n"); - Adapter->PackInfo[uiSearchRuleIndex].bActive=FALSE; - Adapter->PackInfo[uiSearchRuleIndex].bValid=FALSE; - Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value=0; - kfree(pstAddIndication); - } + if (pstAddIndication->sfActiveSet.bValid == TRUE) + Adapter->PackInfo[uiSearchRuleIndex].bActiveSet = TRUE; + + if (pstAddIndication->sfAuthorizedSet.bValid == TRUE) + Adapter->PackInfo[uiSearchRuleIndex].bAuthorizedSet = TRUE; + + if (pstAddIndication->sfAdmittedSet.bValid == TRUE) + Adapter->PackInfo[uiSearchRuleIndex].bAdmittedSet = TRUE; + + if (FALSE == pstAddIndication->sfActiveSet.bValid) { + Adapter->PackInfo[uiSearchRuleIndex].bActive = FALSE; + Adapter->PackInfo[uiSearchRuleIndex].bActivateRequestSent = FALSE; + if (pstAddIndication->sfAdmittedSet.bValid) + psfLocalSet = &pstAddIndication->sfAdmittedSet; + else if (pstAddIndication->sfAuthorizedSet.bValid) + psfLocalSet = &pstAddIndication->sfAuthorizedSet; + } else { + psfLocalSet = &pstAddIndication->sfActiveSet; + Adapter->PackInfo[uiSearchRuleIndex].bActive = TRUE; + } - else if(psfLocalSet->bValid && (pstAddIndication->u8CC == 0)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSA ACK"); - Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = - ntohs(pstAddIndication->u16VCID); - Adapter->PackInfo[uiSearchRuleIndex].usCID = - ntohs(pstAddIndication->u16CID); - - if(UPLINK_DIR == pstAddIndication->u8Direction) - atomic_set(&Adapter->PackInfo[uiSearchRuleIndex].uiPerSFTxResourceCount, DEFAULT_PERSFCOUNT); - CopyToAdapter(Adapter,psfLocalSet,uiSearchRuleIndex, - DSA_ACK, pstAddIndication); - // don't free pstAddIndication - - /* Inside CopyToAdapter, Sorting of all the SFs take place. - Hence any access to the newly added SF through uiSearchRuleIndex is invalid. - SHOULD BE STRICTLY AVOIDED. - */ -// *(PULONG)(((PUCHAR)pvBuffer)+1)=psfLocalSet->u32SFID; - memcpy((((PUCHAR)pvBuffer)+1), &psfLocalSet->u32SFID, 4); - - if(pstAddIndication->sfActiveSet.bValid == TRUE) - { - if(UPLINK_DIR == pstAddIndication->u8Direction) - { - if(!Adapter->LinkUpStatus) - { - netif_carrier_on(Adapter->dev); - netif_start_queue(Adapter->dev); - Adapter->LinkUpStatus = 1; - if (netif_msg_link(Adapter)) - pr_info(PFX "%s: link up\n", Adapter->dev->name); - atomic_set(&Adapter->TxPktAvail, 1); - wake_up(&Adapter->tx_packet_wait_queue); - Adapter->liTimeSinceLastNetEntry = get_seconds(); - } + if (!psfLocalSet) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "No set is valid\n"); + Adapter->PackInfo[uiSearchRuleIndex].bActive = FALSE; + Adapter->PackInfo[uiSearchRuleIndex].bValid = FALSE; + Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = 0; + kfree(pstAddIndication); + } else if (psfLocalSet->bValid && (pstAddIndication->u8CC == 0)) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSA ACK"); + Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = ntohs(pstAddIndication->u16VCID); + Adapter->PackInfo[uiSearchRuleIndex].usCID = ntohs(pstAddIndication->u16CID); + + if (UPLINK_DIR == pstAddIndication->u8Direction) + atomic_set(&Adapter->PackInfo[uiSearchRuleIndex].uiPerSFTxResourceCount, DEFAULT_PERSFCOUNT); + + CopyToAdapter(Adapter, psfLocalSet, uiSearchRuleIndex, DSA_ACK, pstAddIndication); + /* don't free pstAddIndication */ + + /* Inside CopyToAdapter, Sorting of all the SFs take place. + * Hence any access to the newly added SF through uiSearchRuleIndex is invalid. + * SHOULD BE STRICTLY AVOIDED. + */ + /* *(PULONG)(((PUCHAR)pvBuffer)+1)=psfLocalSet->u32SFID; */ + memcpy((((PUCHAR)pvBuffer)+1), &psfLocalSet->u32SFID, 4); + + if (pstAddIndication->sfActiveSet.bValid == TRUE) { + if (UPLINK_DIR == pstAddIndication->u8Direction) { + if (!Adapter->LinkUpStatus) { + netif_carrier_on(Adapter->dev); + netif_start_queue(Adapter->dev); + Adapter->LinkUpStatus = 1; + if (netif_msg_link(Adapter)) + pr_info(PFX "%s: link up\n", Adapter->dev->name); + atomic_set(&Adapter->TxPktAvail, 1); + wake_up(&Adapter->tx_packet_wait_queue); + Adapter->liTimeSinceLastNetEntry = get_seconds(); } } } - - else - { - Adapter->PackInfo[uiSearchRuleIndex].bActive=FALSE; - Adapter->PackInfo[uiSearchRuleIndex].bValid=FALSE; - Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value=0; - kfree(pstAddIndication); - } - } - else - { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0, "DSA ACK did not get valid SFID"); + } else { + Adapter->PackInfo[uiSearchRuleIndex].bActive = FALSE; + Adapter->PackInfo[uiSearchRuleIndex].bValid = FALSE; + Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = 0; kfree(pstAddIndication); - return FALSE; } - } - break; - case DSC_REQ: - { - pLeader->PLength = sizeof(stLocalSFChangeIndicationAlt); - pstChangeIndication = (stLocalSFChangeIndicationAlt*)pstAddIndication; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSC RESPONSE TO MAC %d", pLeader->PLength); - - *((stLocalSFChangeIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication; - ((stLocalSFChangeIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_RSP; - - CopyBufferToControlPacket(Adapter,(PVOID)Adapter->caDsxReqResp); + } else { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "DSA ACK did not get valid SFID"); kfree(pstAddIndication); + return FALSE; } - break; - case DSC_RSP: - { - pLeader->PLength = sizeof(stLocalSFChangeIndicationAlt); - pstChangeIndication = (stLocalSFChangeIndicationAlt*)pstAddIndication; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSC ACK TO MAC %d", pLeader->PLength); - *((stLocalSFChangeIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication; - ((stLocalSFChangeIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_ACK; - } - case DSC_ACK: - { - UINT uiSearchRuleIndex=0; + } + break; + case DSC_REQ: + { + pLeader->PLength = sizeof(stLocalSFChangeIndicationAlt); + pstChangeIndication = (stLocalSFChangeIndicationAlt *)pstAddIndication; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSC RESPONSE TO MAC %d", pLeader->PLength); - pstChangeIndication = (stLocalSFChangeIndicationAlt *)pstAddIndication; - uiSearchRuleIndex=SearchSfid(Adapter,ntohl(pstChangeIndication->sfActiveSet.u32SFID)); - if(uiSearchRuleIndex > NO_OF_QUEUES-1) - { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0, "SF doesn't exist for which DSC_ACK is received"); - } - if((uiSearchRuleIndex < NO_OF_QUEUES)) - { - Adapter->PackInfo[uiSearchRuleIndex].ucDirection = pstChangeIndication->u8Direction; - if(pstChangeIndication->sfActiveSet.bValid==TRUE) - { - Adapter->PackInfo[uiSearchRuleIndex].bActiveSet=TRUE; - } - if(pstChangeIndication->sfAuthorizedSet.bValid==TRUE) - { - Adapter->PackInfo[uiSearchRuleIndex].bAuthorizedSet=TRUE; - } - if(pstChangeIndication->sfAdmittedSet.bValid==TRUE) - { - Adapter->PackInfo[uiSearchRuleIndex].bAdmittedSet=TRUE; - } + *((stLocalSFChangeIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication; + ((stLocalSFChangeIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_RSP; - if(FALSE==pstChangeIndication->sfActiveSet.bValid) - { - Adapter->PackInfo[uiSearchRuleIndex].bActive = FALSE; - Adapter->PackInfo[uiSearchRuleIndex].bActivateRequestSent = FALSE; - if(pstChangeIndication->sfAdmittedSet.bValid) - { - psfLocalSet = &pstChangeIndication->sfAdmittedSet; - } - else if(pstChangeIndication->sfAuthorizedSet.bValid) - { - psfLocalSet = &pstChangeIndication->sfAuthorizedSet; - } - } - - else - { - psfLocalSet = &pstChangeIndication->sfActiveSet; - Adapter->PackInfo[uiSearchRuleIndex].bActive=TRUE; - } - if(psfLocalSet->bValid && (pstChangeIndication->u8CC == 0)) - { - Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = - ntohs(pstChangeIndication->u16VCID); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "CC field is %d bvalid = %d\n", - pstChangeIndication->u8CC, psfLocalSet->bValid); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "VCID= %d\n", ntohs(pstChangeIndication->u16VCID)); - Adapter->PackInfo[uiSearchRuleIndex].usCID = - ntohs(pstChangeIndication->u16CID); - CopyToAdapter(Adapter,psfLocalSet,uiSearchRuleIndex, - DSC_ACK, pstAddIndication); - - *(PULONG)(((PUCHAR)pvBuffer)+1)=psfLocalSet->u32SFID; - } - else if(pstChangeIndication->u8CC == 6) - { - deleteSFBySfid(Adapter,uiSearchRuleIndex); - kfree(pstAddIndication); - } + CopyBufferToControlPacket(Adapter, (PVOID)Adapter->caDsxReqResp); + kfree(pstAddIndication); + } + break; + case DSC_RSP: + { + pLeader->PLength = sizeof(stLocalSFChangeIndicationAlt); + pstChangeIndication = (stLocalSFChangeIndicationAlt *)pstAddIndication; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSC ACK TO MAC %d", pLeader->PLength); + *((stLocalSFChangeIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication; + ((stLocalSFChangeIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_ACK; + } + case DSC_ACK: + { + UINT uiSearchRuleIndex = 0; + + pstChangeIndication = (stLocalSFChangeIndicationAlt *)pstAddIndication; + uiSearchRuleIndex = SearchSfid(Adapter, ntohl(pstChangeIndication->sfActiveSet.u32SFID)); + if (uiSearchRuleIndex > NO_OF_QUEUES-1) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "SF doesn't exist for which DSC_ACK is received"); + + if ((uiSearchRuleIndex < NO_OF_QUEUES)) { + Adapter->PackInfo[uiSearchRuleIndex].ucDirection = pstChangeIndication->u8Direction; + if (pstChangeIndication->sfActiveSet.bValid == TRUE) + Adapter->PackInfo[uiSearchRuleIndex].bActiveSet = TRUE; + + if (pstChangeIndication->sfAuthorizedSet.bValid == TRUE) + Adapter->PackInfo[uiSearchRuleIndex].bAuthorizedSet = TRUE; + + if (pstChangeIndication->sfAdmittedSet.bValid == TRUE) + Adapter->PackInfo[uiSearchRuleIndex].bAdmittedSet = TRUE; + + if (FALSE == pstChangeIndication->sfActiveSet.bValid) { + Adapter->PackInfo[uiSearchRuleIndex].bActive = FALSE; + Adapter->PackInfo[uiSearchRuleIndex].bActivateRequestSent = FALSE; + + if (pstChangeIndication->sfAdmittedSet.bValid) + psfLocalSet = &pstChangeIndication->sfAdmittedSet; + else if (pstChangeIndication->sfAuthorizedSet.bValid) + psfLocalSet = &pstChangeIndication->sfAuthorizedSet; + } else { + psfLocalSet = &pstChangeIndication->sfActiveSet; + Adapter->PackInfo[uiSearchRuleIndex].bActive = TRUE; } - else - { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0, "DSC ACK did not get valid SFID"); + + if (psfLocalSet->bValid && (pstChangeIndication->u8CC == 0)) { + Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = ntohs(pstChangeIndication->u16VCID); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "CC field is %d bvalid = %d\n", + pstChangeIndication->u8CC, psfLocalSet->bValid); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "VCID= %d\n", ntohs(pstChangeIndication->u16VCID)); + Adapter->PackInfo[uiSearchRuleIndex].usCID = ntohs(pstChangeIndication->u16CID); + CopyToAdapter(Adapter, psfLocalSet, uiSearchRuleIndex, DSC_ACK, pstAddIndication); + + *(PULONG)(((PUCHAR)pvBuffer)+1) = psfLocalSet->u32SFID; + } else if (pstChangeIndication->u8CC == 6) { + deleteSFBySfid(Adapter, uiSearchRuleIndex); kfree(pstAddIndication); - return FALSE; } + } else { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "DSC ACK did not get valid SFID"); + kfree(pstAddIndication); + return FALSE; } - break; - case DSD_REQ: - { - UINT uiSearchRuleIndex; - ULONG ulSFID; - - pLeader->PLength = sizeof(stLocalSFDeleteIndication); - *((stLocalSFDeleteIndication*)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *((stLocalSFDeleteIndication*)pstAddIndication); + } + break; + case DSD_REQ: + { + UINT uiSearchRuleIndex; + ULONG ulSFID; - ulSFID = ntohl(((stLocalSFDeleteIndication*)pstAddIndication)->u32SFID); - uiSearchRuleIndex=SearchSfid(Adapter,ulSFID); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSD - Removing connection %x",uiSearchRuleIndex); + pLeader->PLength = sizeof(stLocalSFDeleteIndication); + *((stLocalSFDeleteIndication *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *((stLocalSFDeleteIndication *)pstAddIndication); - if(uiSearchRuleIndex < NO_OF_QUEUES) - { - //Delete All Classifiers Associated with this SFID - deleteSFBySfid(Adapter,uiSearchRuleIndex); - Adapter->u32TotalDSD++; - } + ulSFID = ntohl(((stLocalSFDeleteIndication *)pstAddIndication)->u32SFID); + uiSearchRuleIndex = SearchSfid(Adapter, ulSFID); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSD - Removing connection %x", uiSearchRuleIndex); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSD RESPONSE TO MAC"); - ((stLocalSFDeleteIndication*)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSD_RSP; - CopyBufferToControlPacket(Adapter,(PVOID)Adapter->caDsxReqResp); - } - case DSD_RSP: - { - //Do nothing as SF has already got Deleted + if (uiSearchRuleIndex < NO_OF_QUEUES) { + /* Delete All Classifiers Associated with this SFID */ + deleteSFBySfid(Adapter, uiSearchRuleIndex); + Adapter->u32TotalDSD++; } - break; + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSD RESPONSE TO MAC"); + ((stLocalSFDeleteIndication *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSD_RSP; + CopyBufferToControlPacket(Adapter, (PVOID)Adapter->caDsxReqResp); + } + case DSD_RSP: + { + /* Do nothing as SF has already got Deleted */ + } + break; case DSD_ACK: - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSD ACK Rcd, let App handle it\n"); - break; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSD ACK Rcd, let App handle it\n"); + break; default: kfree(pstAddIndication); - return FALSE ; + return FALSE; } return TRUE; } @@ -2280,78 +1898,67 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**= NO_OF_QUEUES) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SFID %d not present in queue !!!", uiSFId ); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SFID %d not present in queue !!!", uiSFId); return -EINVAL; } - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "status =%d",status); - psSfInfo=&Adapter->PackInfo[status]; - if(psSfInfo->pstSFIndication && copy_to_user(user_buffer, - psSfInfo->pstSFIndication, sizeof(stLocalSFAddIndicationAlt))) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copy to user failed SFID %d, present in queue !!!", uiSFId ); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "status =%d", status); + psSfInfo = &Adapter->PackInfo[status]; + if (psSfInfo->pstSFIndication && copy_to_user(user_buffer, + psSfInfo->pstSFIndication, sizeof(stLocalSFAddIndicationAlt))) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "copy to user failed SFID %d, present in queue !!!", uiSFId); status = -EFAULT; return status; } return STATUS_SUCCESS; } -VOID OverrideServiceFlowParams(PMINI_ADAPTER Adapter,PUINT puiBuffer) +VOID OverrideServiceFlowParams(PMINI_ADAPTER Adapter, PUINT puiBuffer) { - B_UINT32 u32NumofSFsinMsg = ntohl(*(puiBuffer + 1)); + B_UINT32 u32NumofSFsinMsg = ntohl(*(puiBuffer + 1)); stIM_SFHostNotify *pHostInfo = NULL; - UINT uiSearchRuleIndex = 0; - ULONG ulSFID = 0; + UINT uiSearchRuleIndex = 0; + ULONG ulSFID = 0; - puiBuffer+=2; + puiBuffer += 2; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32NumofSFsinMsg: 0x%x\n", u32NumofSFsinMsg); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32NumofSFsinMsg: 0x%x\n",u32NumofSFsinMsg); - - while(u32NumofSFsinMsg != 0 && u32NumofSFsinMsg < NO_OF_QUEUES) - { + while (u32NumofSFsinMsg != 0 && u32NumofSFsinMsg < NO_OF_QUEUES) { u32NumofSFsinMsg--; pHostInfo = (stIM_SFHostNotify *)puiBuffer; puiBuffer = (PUINT)(pHostInfo + 1); ulSFID = ntohl(pHostInfo->SFID); - uiSearchRuleIndex=SearchSfid(Adapter,ulSFID); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"SFID: 0x%lx\n",ulSFID); + uiSearchRuleIndex = SearchSfid(Adapter, ulSFID); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SFID: 0x%lx\n", ulSFID); - if(uiSearchRuleIndex >= NO_OF_QUEUES || uiSearchRuleIndex == HiPriority) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"The SFID <%lx> doesn't exist in host entry or is Invalid\n", ulSFID); + if (uiSearchRuleIndex >= NO_OF_QUEUES || uiSearchRuleIndex == HiPriority) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "The SFID <%lx> doesn't exist in host entry or is Invalid\n", ulSFID); continue; } - if(pHostInfo->RetainSF == FALSE) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Going to Delete SF"); - deleteSFBySfid(Adapter,uiSearchRuleIndex); - } - else - { - + if (pHostInfo->RetainSF == FALSE) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Going to Delete SF"); + deleteSFBySfid(Adapter, uiSearchRuleIndex); + } else { Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = ntohs(pHostInfo->VCID); Adapter->PackInfo[uiSearchRuleIndex].usCID = ntohs(pHostInfo->newCID); - Adapter->PackInfo[uiSearchRuleIndex].bActive=FALSE; + Adapter->PackInfo[uiSearchRuleIndex].bActive = FALSE; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"pHostInfo->QoSParamSet: 0x%x\n",pHostInfo->QoSParamSet); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "pHostInfo->QoSParamSet: 0x%x\n", pHostInfo->QoSParamSet); - if(pHostInfo->QoSParamSet & 0x1) - Adapter->PackInfo[uiSearchRuleIndex].bAuthorizedSet =TRUE; - if(pHostInfo->QoSParamSet & 0x2) - Adapter->PackInfo[uiSearchRuleIndex].bAdmittedSet =TRUE; - if(pHostInfo->QoSParamSet & 0x4) - { - Adapter->PackInfo[uiSearchRuleIndex].bActiveSet =TRUE; - Adapter->PackInfo[uiSearchRuleIndex].bActive=TRUE; + if (pHostInfo->QoSParamSet & 0x1) + Adapter->PackInfo[uiSearchRuleIndex].bAuthorizedSet = TRUE; + if (pHostInfo->QoSParamSet & 0x2) + Adapter->PackInfo[uiSearchRuleIndex].bAdmittedSet = TRUE; + if (pHostInfo->QoSParamSet & 0x4) { + Adapter->PackInfo[uiSearchRuleIndex].bActiveSet = TRUE; + Adapter->PackInfo[uiSearchRuleIndex].bActive = TRUE; } } } } - - - -- cgit v1.2.3-70-g09d2 From e4868623bfe1c05e1e17d86729907a3850d12882 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Wed, 4 Jan 2012 20:29:01 -0500 Subject: Staging: bcm: Replace dated variable __FUNCTION__. This patch replaces the obsolete variable, __FUNCTION__, that holds the name of the current function with variable, __func__. Reported by checkpatch.pl. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/CmHost.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index fcb1835c68f..63d768d45bf 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -447,7 +447,7 @@ static VOID CopyToAdapter(register PMINI_ADAPTER Adapter, /* PackInfo[uiSearchRuleIndex].bValid = TRUE; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Search Rule Index = %d\n", uiSearchRuleIndex); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "%s: SFID= %x ", __FUNCTION__, ntohl(psfLocalSet->u32SFID)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "%s: SFID= %x ", __func__, ntohl(psfLocalSet->u32SFID)); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Updating Queue %d", uiSearchRuleIndex); ulSFID = ntohl(psfLocalSet->u32SFID); @@ -816,7 +816,7 @@ static VOID CopyToAdapter(register PMINI_ADAPTER Adapter, /* stBCMPhsContext); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "%s <=====", __FUNCTION__); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "%s <=====", __func__); } /*********************************************************************** @@ -1352,7 +1352,7 @@ static ULONG StoreSFParam(PMINI_ADAPTER Adapter, PUCHAR pucSrcBuffer, ULONG ulAd ret = wrm(Adapter, ulAddrSFParamSet, (u8 *)pucSrcBuffer, nBytesToWrite); if (ret < 0) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "%s:%d WRM failed", __FUNCTION__, __LINE__); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "%s:%d WRM failed", __func__, __LINE__); return ret; } return 1; -- cgit v1.2.3-70-g09d2 From 5db125fb5ca2fed67a668c532af576a67a3d3bdc Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Wed, 4 Jan 2012 20:29:02 -0500 Subject: Staging: bcm: Remove typedef from CmHost.c and use enum. This patch removes a typedef from a variable definition in CmHost.c, and uses a enum instead. This Warning was reported by checkpatch.pl. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/CmHost.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index 63d768d45bf..cf4146e5639 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -7,12 +7,12 @@ /* #define CONN_MSG */ #include "headers.h" -typedef enum _E_CLASSIFIER_ACTION { +enum E_CLASSIFIER_ACTION { eInvalidClassifierAction, eAddClassifier, eReplaceClassifier, eDeleteClassifier -} E_CLASSIFIER_ACTION; +}; static ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter, B_UINT16 tid); @@ -437,7 +437,7 @@ static VOID CopyToAdapter(register PMINI_ADAPTER Adapter, /* Date: Wed, 4 Jan 2012 20:29:03 -0500 Subject: Staging: bcm: Remove assignment from if statement and reverse if logic for readability. This patch removes an assignment from an if statement, and it reverses the logic in several if statements to make them more readable and understandable. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/CmHost.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index cf4146e5639..de38bedce33 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -194,7 +194,7 @@ CopyIpAddrToClassifier(S_CLASSIFIER_RULE *pstClassifierEntry, } u8IpAddressLen -= nSizeOfIPAddressInBytes; } - if (0 == u8IpAddressLen) + if (u8IpAddressLen == 0) pstClassifierEntry->bDestIpValid = TRUE; ucLoopIndex++; @@ -263,7 +263,7 @@ static inline VOID CopyClassifierRuleToSF(PMINI_ADAPTER Adapter, stConvergenceSL pstClassifierEntry->ucDestPortRangeLength = psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength / 4; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Destination Port Range Length:0x%X ", pstClassifierEntry->ucDestPortRangeLength); - if (MAX_PORT_RANGE >= psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength) { + if (psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength <= MAX_PORT_RANGE) { for (ucLoopIndex = 0; ucLoopIndex < (pstClassifierEntry->ucDestPortRangeLength); ucLoopIndex++) { pstClassifierEntry->usDestPortRangeLo[ucLoopIndex] = *((PUSHORT)(psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange+ucLoopIndex)); pstClassifierEntry->usDestPortRangeHi[ucLoopIndex] = @@ -280,7 +280,7 @@ static inline VOID CopyClassifierRuleToSF(PMINI_ADAPTER Adapter, stConvergenceSL /* Source Port */ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Source Port Range Length:0x%X ", psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength); - if (MAX_PORT_RANGE >= psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength) { + if (psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength <= MAX_PORT_RANGE) { pstClassifierEntry->ucSrcPortRangeLength = psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength/4; for (ucLoopIndex = 0; ucLoopIndex < (pstClassifierEntry->ucSrcPortRangeLength); ucLoopIndex++) { pstClassifierEntry->usSrcPortRangeLo[ucLoopIndex] = @@ -315,7 +315,7 @@ static inline VOID CopyClassifierRuleToSF(PMINI_ADAPTER Adapter, stConvergenceSL /* TOS */ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "TOS Length:0x%X ", psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength); - if (3 == psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength) { + if (psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength == 3) { pstClassifierEntry->ucIPTypeOfServiceLength = psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength; pstClassifierEntry->ucTosLow = psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0]; pstClassifierEntry->ucTosHigh = psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1]; @@ -1393,7 +1393,7 @@ ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter, PVOID pvBuffer, UINT /* For DSA_REQ, only up to "psfAuthorizedSet" parameter should be accessed by driver! */ pstAddIndication = kmalloc(sizeof(*pstAddIndication), GFP_KERNEL); - if (NULL == pstAddIndication) + if (pstAddIndication == NULL) return 0; /* AUTHORIZED SET */ @@ -1656,7 +1656,8 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /* u16TID, FALSE); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Error in restoring Service Flow param structure from DSx message"); return FALSE; @@ -1721,7 +1722,7 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /* sfAdmittedSet.bValid == TRUE) Adapter->PackInfo[uiSearchRuleIndex].bAdmittedSet = TRUE; - if (FALSE == pstAddIndication->sfActiveSet.bValid) { + if (pstAddIndication->sfActiveSet.bValid == FALSE) { Adapter->PackInfo[uiSearchRuleIndex].bActive = FALSE; Adapter->PackInfo[uiSearchRuleIndex].bActivateRequestSent = FALSE; if (pstAddIndication->sfAdmittedSet.bValid) @@ -1825,7 +1826,7 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /* sfAdmittedSet.bValid == TRUE) Adapter->PackInfo[uiSearchRuleIndex].bAdmittedSet = TRUE; - if (FALSE == pstChangeIndication->sfActiveSet.bValid) { + if (pstChangeIndication->sfActiveSet.bValid == FALSE) { Adapter->PackInfo[uiSearchRuleIndex].bActive = FALSE; Adapter->PackInfo[uiSearchRuleIndex].bActivateRequestSent = FALSE; -- cgit v1.2.3-70-g09d2 From ce4bbc2ae4626f6fdf1af8767d59852978e5f942 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Wed, 4 Jan 2012 20:29:04 -0500 Subject: Staging: bcm: Replace variables and function outputs defined as INT with int. This patch replaces all variables and function output that have a datatype definition of "INT" with "int". Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/CmHost.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index de38bedce33..941d047e78d 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -28,9 +28,9 @@ static ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter, B_UINT16 tid); * Returns - Queue index for this SFID(If matched) * Else Invalid Queue Index(If Not matched) ************************************************************/ -INT SearchSfid(PMINI_ADAPTER Adapter, UINT uiSfid) +int SearchSfid(PMINI_ADAPTER Adapter, UINT uiSfid) { - INT iIndex = 0; + int iIndex = 0; for (iIndex = (NO_OF_QUEUES-1); iIndex >= 0; iIndex--) if (Adapter->PackInfo[iIndex].ulSFID == uiSfid) @@ -49,7 +49,7 @@ INT SearchSfid(PMINI_ADAPTER Adapter, UINT uiSfid) * Returns - Queue index for the free SFID * Else returns Invalid Index. ****************************************************************/ -static INT SearchFreeSfid(PMINI_ADAPTER Adapter) +static int SearchFreeSfid(PMINI_ADAPTER Adapter) { UINT uiIndex = 0; @@ -1619,7 +1619,7 @@ static ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter, B_UINT16 tid) return ulTargetDSXBufferAddress; } -INT AllocAdapterDsxBuffer(PMINI_ADAPTER Adapter) +int AllocAdapterDsxBuffer(PMINI_ADAPTER Adapter) { /* * Need to Allocate memory to contain the SUPER Large structures @@ -1632,7 +1632,7 @@ INT AllocAdapterDsxBuffer(PMINI_ADAPTER Adapter) return 0; } -INT FreeAdapterDsxBuffer(PMINI_ADAPTER Adapter) +int FreeAdapterDsxBuffer(PMINI_ADAPTER Adapter) { kfree(Adapter->caDsxReqResp); return 0; -- cgit v1.2.3-70-g09d2 From 5cf4d6b936ca21f67aa763dd0d3f8fdd9873b22c Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Wed, 4 Jan 2012 20:29:05 -0500 Subject: Staging: bcm: Alter name, datatype, and default value of iterator variables. This patch renames variables used in iteration statements with i, changes the datatype to int, and removes any default value. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/CmHost.c | 168 +++++++++++++++++++++---------------------- 1 file changed, 84 insertions(+), 84 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index 941d047e78d..522d0052e83 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -30,11 +30,11 @@ static ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter, B_UINT16 tid); ************************************************************/ int SearchSfid(PMINI_ADAPTER Adapter, UINT uiSfid) { - int iIndex = 0; + int i; - for (iIndex = (NO_OF_QUEUES-1); iIndex >= 0; iIndex--) - if (Adapter->PackInfo[iIndex].ulSFID == uiSfid) - return iIndex; + for (i = (NO_OF_QUEUES-1); i >= 0; i--) + if (Adapter->PackInfo[i].ulSFID == uiSfid) + return i; return NO_OF_QUEUES+1; } @@ -51,11 +51,11 @@ int SearchSfid(PMINI_ADAPTER Adapter, UINT uiSfid) ****************************************************************/ static int SearchFreeSfid(PMINI_ADAPTER Adapter) { - UINT uiIndex = 0; + int i; - for (uiIndex = 0; uiIndex < (NO_OF_QUEUES-1); uiIndex++) - if (Adapter->PackInfo[uiIndex].ulSFID == 0) - return uiIndex; + for (i = 0; i < (NO_OF_QUEUES-1); i++) + if (Adapter->PackInfo[i].ulSFID == 0) + return i; return NO_OF_QUEUES+1; } @@ -70,13 +70,13 @@ static int SearchFreeSfid(PMINI_ADAPTER Adapter) */ static int SearchClsid(PMINI_ADAPTER Adapter, ULONG ulSFID, B_UINT16 uiClassifierID) { - unsigned int uiClassifierIndex = 0; + int i; - for (uiClassifierIndex = 0; uiClassifierIndex < MAX_CLASSIFIERS; uiClassifierIndex++) { - if ((Adapter->astClassifierTable[uiClassifierIndex].bUsed) && - (Adapter->astClassifierTable[uiClassifierIndex].uiClassifierRuleIndex == uiClassifierID) && - (Adapter->astClassifierTable[uiClassifierIndex].ulSFID == ulSFID)) - return uiClassifierIndex; + for (i = 0; i < MAX_CLASSIFIERS; i++) { + if ((Adapter->astClassifierTable[i].bUsed) && + (Adapter->astClassifierTable[i].uiClassifierRuleIndex == uiClassifierID) && + (Adapter->astClassifierTable[i].ulSFID == ulSFID)) + return i; } return MAX_CLASSIFIERS+1; @@ -89,11 +89,11 @@ static int SearchClsid(PMINI_ADAPTER Adapter, ULONG ulSFID, B_UINT16 uiClassifi */ static int SearchFreeClsid(PMINI_ADAPTER Adapter /**Adapter Context*/) { - unsigned int uiClassifierIndex = 0; + int i; - for (uiClassifierIndex = 0; uiClassifierIndex < MAX_CLASSIFIERS; uiClassifierIndex++) { - if (!Adapter->astClassifierTable[uiClassifierIndex].bUsed) - return uiClassifierIndex; + for (i = 0; i < MAX_CLASSIFIERS; i++) { + if (!Adapter->astClassifierTable[i].bUsed) + return i; } return MAX_CLASSIFIERS+1; @@ -116,7 +116,7 @@ CopyIpAddrToClassifier(S_CLASSIFIER_RULE *pstClassifierEntry, B_UINT8 u8IpAddressLen, B_UINT8 *pu8IpAddressMaskSrc, BOOLEAN bIpVersion6, E_IPADDR_CONTEXT eIpAddrContext) { - UINT ucLoopIndex = 0; + int i = 0; UINT nSizeOfIPAddressInBytes = IP_LENGTH_OF_ADDRESS; UCHAR *ptrClassifierIpAddress = NULL; UCHAR *ptrClassifierIpMask = NULL; @@ -154,42 +154,42 @@ CopyIpAddrToClassifier(S_CLASSIFIER_RULE *pstClassifierEntry, } } BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Address Length:0x%X\n", pstClassifierEntry->ucIPDestinationAddressLength); - while ((u8IpAddressLen >= nSizeOfIPAddressInBytes) && (ucLoopIndex < MAX_IP_RANGE_LENGTH)) { + while ((u8IpAddressLen >= nSizeOfIPAddressInBytes) && (i < MAX_IP_RANGE_LENGTH)) { memcpy(ptrClassifierIpAddress + - (ucLoopIndex * nSizeOfIPAddressInBytes), - (pu8IpAddressMaskSrc+(ucLoopIndex*nSizeOfIPAddressInBytes*2)), + (i * nSizeOfIPAddressInBytes), + (pu8IpAddressMaskSrc+(i*nSizeOfIPAddressInBytes*2)), nSizeOfIPAddressInBytes); if (!bIpVersion6) { if (eIpAddrContext == eSrcIpAddress) { - pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[ucLoopIndex] = ntohl(pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[ucLoopIndex]); + pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[i] = ntohl(pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[i]); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Src Ip Address:0x%luX ", - pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[ucLoopIndex]); + pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[i]); } else if (eIpAddrContext == eDestIpAddress) { - pstClassifierEntry->stDestIpAddress.ulIpv4Addr[ucLoopIndex] = ntohl(pstClassifierEntry->stDestIpAddress.ulIpv4Addr[ucLoopIndex]); + pstClassifierEntry->stDestIpAddress.ulIpv4Addr[i] = ntohl(pstClassifierEntry->stDestIpAddress.ulIpv4Addr[i]); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Dest Ip Address:0x%luX ", - pstClassifierEntry->stDestIpAddress.ulIpv4Addr[ucLoopIndex]); + pstClassifierEntry->stDestIpAddress.ulIpv4Addr[i]); } } u8IpAddressLen -= nSizeOfIPAddressInBytes; if (u8IpAddressLen >= nSizeOfIPAddressInBytes) { memcpy(ptrClassifierIpMask + - (ucLoopIndex * nSizeOfIPAddressInBytes), + (i * nSizeOfIPAddressInBytes), (pu8IpAddressMaskSrc+nSizeOfIPAddressInBytes + - (ucLoopIndex*nSizeOfIPAddressInBytes*2)), + (i*nSizeOfIPAddressInBytes*2)), nSizeOfIPAddressInBytes); if (!bIpVersion6) { if (eIpAddrContext == eSrcIpAddress) { - pstClassifierEntry->stSrcIpAddress.ulIpv4Mask[ucLoopIndex] = - ntohl(pstClassifierEntry->stSrcIpAddress.ulIpv4Mask[ucLoopIndex]); + pstClassifierEntry->stSrcIpAddress.ulIpv4Mask[i] = + ntohl(pstClassifierEntry->stSrcIpAddress.ulIpv4Mask[i]); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Src Ip Mask Address:0x%luX ", - pstClassifierEntry->stSrcIpAddress.ulIpv4Mask[ucLoopIndex]); + pstClassifierEntry->stSrcIpAddress.ulIpv4Mask[i]); } else if (eIpAddrContext == eDestIpAddress) { - pstClassifierEntry->stDestIpAddress.ulIpv4Mask[ucLoopIndex] = - ntohl(pstClassifierEntry->stDestIpAddress.ulIpv4Mask[ucLoopIndex]); + pstClassifierEntry->stDestIpAddress.ulIpv4Mask[i] = + ntohl(pstClassifierEntry->stDestIpAddress.ulIpv4Mask[i]); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Dest Ip Mask Address:0x%luX ", - pstClassifierEntry->stDestIpAddress.ulIpv4Mask[ucLoopIndex]); + pstClassifierEntry->stDestIpAddress.ulIpv4Mask[i]); } } u8IpAddressLen -= nSizeOfIPAddressInBytes; @@ -197,17 +197,17 @@ CopyIpAddrToClassifier(S_CLASSIFIER_RULE *pstClassifierEntry, if (u8IpAddressLen == 0) pstClassifierEntry->bDestIpValid = TRUE; - ucLoopIndex++; + i++; } if (bIpVersion6) { /* Restore EndianNess of Struct */ - for (ucLoopIndex = 0; ucLoopIndex < MAX_IP_RANGE_LENGTH * 4; ucLoopIndex++) { + for (i = 0; i < MAX_IP_RANGE_LENGTH * 4; i++) { if (eIpAddrContext == eSrcIpAddress) { - pstClassifierEntry->stSrcIpAddress.ulIpv6Addr[ucLoopIndex] = ntohl(pstClassifierEntry->stSrcIpAddress.ulIpv6Addr[ucLoopIndex]); - pstClassifierEntry->stSrcIpAddress.ulIpv6Mask[ucLoopIndex] = ntohl(pstClassifierEntry->stSrcIpAddress.ulIpv6Mask[ucLoopIndex]); + pstClassifierEntry->stSrcIpAddress.ulIpv6Addr[i] = ntohl(pstClassifierEntry->stSrcIpAddress.ulIpv6Addr[i]); + pstClassifierEntry->stSrcIpAddress.ulIpv6Mask[i] = ntohl(pstClassifierEntry->stSrcIpAddress.ulIpv6Mask[i]); } else if (eIpAddrContext == eDestIpAddress) { - pstClassifierEntry->stDestIpAddress.ulIpv6Addr[ucLoopIndex] = ntohl(pstClassifierEntry->stDestIpAddress.ulIpv6Addr[ucLoopIndex]); - pstClassifierEntry->stDestIpAddress.ulIpv6Mask[ucLoopIndex] = ntohl(pstClassifierEntry->stDestIpAddress.ulIpv6Mask[ucLoopIndex]); + pstClassifierEntry->stDestIpAddress.ulIpv6Addr[i] = ntohl(pstClassifierEntry->stDestIpAddress.ulIpv6Addr[i]); + pstClassifierEntry->stDestIpAddress.ulIpv6Mask[i] = ntohl(pstClassifierEntry->stDestIpAddress.ulIpv6Mask[i]); } } } @@ -216,17 +216,17 @@ CopyIpAddrToClassifier(S_CLASSIFIER_RULE *pstClassifierEntry, void ClearTargetDSXBuffer(PMINI_ADAPTER Adapter, B_UINT16 TID, BOOLEAN bFreeAll) { - ULONG ulIndex; + int i; - for (ulIndex = 0; ulIndex < Adapter->ulTotalTargetBuffersAvailable; ulIndex++) { - if (Adapter->astTargetDsxBuffer[ulIndex].valid) + for (i = 0; i < Adapter->ulTotalTargetBuffersAvailable; i++) { + if (Adapter->astTargetDsxBuffer[i].valid) continue; - if ((bFreeAll) || (Adapter->astTargetDsxBuffer[ulIndex].tid == TID)) { + if ((bFreeAll) || (Adapter->astTargetDsxBuffer[i].tid == TID)) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "ClearTargetDSXBuffer: found tid %d buffer cleared %lx\n", - TID, Adapter->astTargetDsxBuffer[ulIndex].ulTargetDsxBuffer); - Adapter->astTargetDsxBuffer[ulIndex].valid = 1; - Adapter->astTargetDsxBuffer[ulIndex].tid = 0; + TID, Adapter->astTargetDsxBuffer[i].ulTargetDsxBuffer); + Adapter->astTargetDsxBuffer[i].valid = 1; + Adapter->astTargetDsxBuffer[i].tid = 0; Adapter->ulFreeTargetBufferCnt++; } } @@ -240,7 +240,7 @@ static inline VOID CopyClassifierRuleToSF(PMINI_ADAPTER Adapter, stConvergenceSL { S_CLASSIFIER_RULE *pstClassifierEntry = NULL; /* VOID *pvPhsContext = NULL; */ - UINT ucLoopIndex = 0; + int i; /* UCHAR ucProtocolLength=0; */ /* ULONG ulPhsStatus; */ @@ -264,14 +264,14 @@ static inline VOID CopyClassifierRuleToSF(PMINI_ADAPTER Adapter, stConvergenceSL BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Destination Port Range Length:0x%X ", pstClassifierEntry->ucDestPortRangeLength); if (psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength <= MAX_PORT_RANGE) { - for (ucLoopIndex = 0; ucLoopIndex < (pstClassifierEntry->ucDestPortRangeLength); ucLoopIndex++) { - pstClassifierEntry->usDestPortRangeLo[ucLoopIndex] = *((PUSHORT)(psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange+ucLoopIndex)); - pstClassifierEntry->usDestPortRangeHi[ucLoopIndex] = - *((PUSHORT)(psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange+2+ucLoopIndex)); - pstClassifierEntry->usDestPortRangeLo[ucLoopIndex] = ntohs(pstClassifierEntry->usDestPortRangeLo[ucLoopIndex]); + for (i = 0; i < (pstClassifierEntry->ucDestPortRangeLength); i++) { + pstClassifierEntry->usDestPortRangeLo[i] = *((PUSHORT)(psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange+i)); + pstClassifierEntry->usDestPortRangeHi[i] = + *((PUSHORT)(psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange+2+i)); + pstClassifierEntry->usDestPortRangeLo[i] = ntohs(pstClassifierEntry->usDestPortRangeLo[i]); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Destination Port Range Lo:0x%X ", - pstClassifierEntry->usDestPortRangeLo[ucLoopIndex]); - pstClassifierEntry->usDestPortRangeHi[ucLoopIndex] = ntohs(pstClassifierEntry->usDestPortRangeHi[ucLoopIndex]); + pstClassifierEntry->usDestPortRangeLo[i]); + pstClassifierEntry->usDestPortRangeHi[i] = ntohs(pstClassifierEntry->usDestPortRangeHi[i]); } } else { pstClassifierEntry->ucDestPortRangeLength = 0; @@ -282,18 +282,18 @@ static inline VOID CopyClassifierRuleToSF(PMINI_ADAPTER Adapter, stConvergenceSL psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength); if (psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength <= MAX_PORT_RANGE) { pstClassifierEntry->ucSrcPortRangeLength = psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength/4; - for (ucLoopIndex = 0; ucLoopIndex < (pstClassifierEntry->ucSrcPortRangeLength); ucLoopIndex++) { - pstClassifierEntry->usSrcPortRangeLo[ucLoopIndex] = + for (i = 0; i < (pstClassifierEntry->ucSrcPortRangeLength); i++) { + pstClassifierEntry->usSrcPortRangeLo[i] = *((PUSHORT)(psfCSType->cCPacketClassificationRule. - u8ProtocolSourcePortRange+ucLoopIndex)); - pstClassifierEntry->usSrcPortRangeHi[ucLoopIndex] = + u8ProtocolSourcePortRange+i)); + pstClassifierEntry->usSrcPortRangeHi[i] = *((PUSHORT)(psfCSType->cCPacketClassificationRule. - u8ProtocolSourcePortRange+2+ucLoopIndex)); - pstClassifierEntry->usSrcPortRangeLo[ucLoopIndex] = - ntohs(pstClassifierEntry->usSrcPortRangeLo[ucLoopIndex]); + u8ProtocolSourcePortRange+2+i)); + pstClassifierEntry->usSrcPortRangeLo[i] = + ntohs(pstClassifierEntry->usSrcPortRangeLo[i]); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Source Port Range Lo:0x%X ", - pstClassifierEntry->usSrcPortRangeLo[ucLoopIndex]); - pstClassifierEntry->usSrcPortRangeHi[ucLoopIndex] = ntohs(pstClassifierEntry->usSrcPortRangeHi[ucLoopIndex]); + pstClassifierEntry->usSrcPortRangeLo[i]); + pstClassifierEntry->usSrcPortRangeHi[i] = ntohs(pstClassifierEntry->usSrcPortRangeHi[i]); } } /* Destination Ip Address and Mask */ @@ -399,7 +399,7 @@ static inline VOID DeleteClassifierRuleFromSF(PMINI_ADAPTER Adapter, UINT uiSear VOID DeleteAllClassifiersForSF(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex) { S_CLASSIFIER_RULE *pstClassifierEntry = NULL; - UINT nClassifierIndex; + int i; /* B_UINT16 u16PacketClassificationRuleIndex; */ USHORT ulVCID; /* VOID *pvPhsContext = NULL; */ @@ -410,12 +410,12 @@ VOID DeleteAllClassifiersForSF(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex) if (ulVCID == 0) return; - for (nClassifierIndex = 0; nClassifierIndex < MAX_CLASSIFIERS; nClassifierIndex++) { - if (Adapter->astClassifierTable[nClassifierIndex].usVCID_Value == ulVCID) { - pstClassifierEntry = &Adapter->astClassifierTable[nClassifierIndex]; + for (i = 0; i < MAX_CLASSIFIERS; i++) { + if (Adapter->astClassifierTable[i].usVCID_Value == ulVCID) { + pstClassifierEntry = &Adapter->astClassifierTable[i]; if (pstClassifierEntry->bUsed) - DeleteClassifierRuleFromSF(Adapter, uiSearchRuleIndex, nClassifierIndex); + DeleteClassifierRuleFromSF(Adapter, uiSearchRuleIndex, i); } } @@ -439,7 +439,7 @@ static VOID CopyToAdapter(register PMINI_ADAPTER Adapter, /* PackInfo[uiSearchRuleIndex].usVCID_Value; @@ -527,10 +527,10 @@ static VOID CopyToAdapter(register PMINI_ADAPTER Adapter, /* PackInfo[uiSearchRuleIndex].u8TrafficPriority = psfLocalSet->u8TrafficPriority; /* copy all the classifier in the Service Flow param structure */ - for (nIndex = 0; nIndex < psfLocalSet->u8TotalClassifiers; nIndex++) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Classifier index =%d", nIndex); - psfCSType = &psfLocalSet->cConvergenceSLTypes[nIndex]; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Classifier index =%d", nIndex); + for (i = 0; i < psfLocalSet->u8TotalClassifiers; i++) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Classifier index =%d", i); + psfCSType = &psfLocalSet->cConvergenceSLTypes[i]; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Classifier index =%d", i); if (psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority) Adapter->PackInfo[uiSearchRuleIndex].bClassifierPriority = TRUE; @@ -628,8 +628,8 @@ static VOID CopyToAdapter(register PMINI_ADAPTER Adapter, /* u8TotalClassifiers; nIndex++) { - psfCSType = &psfLocalSet->cConvergenceSLTypes[nIndex]; + for (i = 0; i < psfLocalSet->u8TotalClassifiers; i++) { + psfCSType = &psfLocalSet->cConvergenceSLTypes[i]; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "psfCSType->u8PhsDSCAction : 0x%x\n", psfCSType->u8PhsDSCAction); switch (psfCSType->u8PhsDSCAction) { @@ -832,8 +832,8 @@ static VOID CopyToAdapter(register PMINI_ADAPTER Adapter, /* ulTotalTargetBuffersAvailable); - for (ulIndex = 0; ulIndex < Adapter->ulTotalTargetBuffersAvailable; ulIndex++) { - Adapter->astTargetDsxBuffer[ulIndex].ulTargetDsxBuffer = ulTargetDsxBuffersBase; - Adapter->astTargetDsxBuffer[ulIndex].valid = 1; - Adapter->astTargetDsxBuffer[ulIndex].tid = 0; + for (i = 0; i < Adapter->ulTotalTargetBuffersAvailable; i++) { + Adapter->astTargetDsxBuffer[i].ulTargetDsxBuffer = ulTargetDsxBuffersBase; + Adapter->astTargetDsxBuffer[i].valid = 1; + Adapter->astTargetDsxBuffer[i].tid = 0; ulTargetDsxBuffersBase += sizeof(stServiceFlowParamSI); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " Target DSX Buffer %lx setup at 0x%lx", - ulIndex, Adapter->astTargetDsxBuffer[ulIndex].ulTargetDsxBuffer); + i, Adapter->astTargetDsxBuffer[i].ulTargetDsxBuffer); } Adapter->ulCurrentTargetBuffer = 0; Adapter->ulFreeTargetBufferCnt = Adapter->ulTotalTargetBuffersAvailable; -- cgit v1.2.3-70-g09d2 From 2d9ebe77b7665a431a9816eff3eb588e05176dfa Mon Sep 17 00:00:00 2001 From: Thomas Meyer Date: Sun, 22 Jan 2012 18:29:51 +0100 Subject: Staging: bcm: Use memdup_user rather than duplicating its implementation This is a little bit restricted to reduce false positives The semantic patch that makes this change is available in scripts/coccinelle/api/memdup_user.cocci. More information about semantic patching is available at http://coccinelle.lip6.fr/ Signed-off-by: Thomas Meyer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 8bf3f575160..cf305921695 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -728,14 +728,10 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if (IoBuffer.InputLength > MAX_CNTL_PKT_SIZE) return -EINVAL; - pvBuffer = kmalloc(IoBuffer.InputLength, GFP_KERNEL); - if (!pvBuffer) - return -ENOMEM; - - if (copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) { - kfree(pvBuffer); - return -EFAULT; - } + pvBuffer = memdup_user(IoBuffer.InputBuffer, + IoBuffer.InputLength); + if (IS_ERR(pvBuffer)) + return PTR_ERR(pvBuffer); down(&Adapter->LowPowerModeSync); Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue, @@ -1140,15 +1136,10 @@ cntrlEnd: if (IoBuffer.InputLength < sizeof(ULONG) * 2) return -EINVAL; - pvBuffer = kmalloc(IoBuffer.InputLength, GFP_KERNEL); - if (!pvBuffer) - return -ENOMEM; - - /* Get WrmBuffer structure */ - if (copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) { - kfree(pvBuffer); - return -EFAULT; - } + pvBuffer = memdup_user(IoBuffer.InputBuffer, + IoBuffer.InputLength); + if (IS_ERR(pvBuffer)) + return PTR_ERR(pvBuffer); pBulkBuffer = (PBULKWRM_BUFFER)pvBuffer; @@ -1310,14 +1301,10 @@ cntrlEnd: return STATUS_FAILURE; } - pReadData = kzalloc(stNVMReadWrite.uiNumBytes, GFP_KERNEL); - if (!pReadData) - return -ENOMEM; - - if (copy_from_user(pReadData, stNVMReadWrite.pBuffer, stNVMReadWrite.uiNumBytes)) { - kfree(pReadData); - return -EFAULT; - } + pReadData = memdup_user(stNVMReadWrite.pBuffer, + stNVMReadWrite.uiNumBytes); + if (IS_ERR(pReadData)) + return PTR_ERR(pReadData); do_gettimeofday(&tv0); if (IOCTL_BCM_NVM_READ == cmd) { -- cgit v1.2.3-70-g09d2 From 09b6b51b0b6c1b9bb61815baf205e4d74c89ff04 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 10 Jan 2012 13:43:30 -0500 Subject: SCSI & usb-storage: add flags for VPD pages and REPORT LUNS This patch (as1507) adds a skip_vpd_pages flag to struct scsi_device and a no_report_luns flag to struct scsi_target. The first is used to control whether sd will look at VPD pages for information on block provisioning, limits, and characteristics. The second prevents scsi_report_lun_scan() from issuing a REPORT LUNS command. The patch also modifies usb-storage to set the new flag bits for all USB devices and targets, and to stop adjusting the scsi_level value. Historically we have seen that USB mass-storage devices often don't support VPD pages or REPORT LUNS properly. Until now we have avoided these things by setting the scsi_level to SCSI_2 for all USB devices. But this has the side effect of storing the LUN bits into the second byte of each CDB, and now we have a report of a device which doesn't like that. The best solution is to stop abusing scsi_level and instead have separate flags for VPD pages and REPORT LUNS. Signed-off-by: Alan Stern Reported-by: Perry Wagle CC: Matthew Dharm Cc: James Bottomley Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/scsi_scan.c | 4 ++++ drivers/scsi/sd.c | 2 +- drivers/usb/storage/scsiglue.c | 26 ++++++++++++++++---------- include/scsi/scsi_device.h | 3 +++ 4 files changed, 24 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 89da43f73c0..fd37bfbfbcd 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -1295,6 +1295,7 @@ EXPORT_SYMBOL(int_to_scsilun); * LUNs even if it's older than SCSI-3. * If BLIST_NOREPORTLUN is set, return 1 always. * If BLIST_NOLUN is set, return 0 always. + * If starget->no_report_luns is set, return 1 always. * * Return: * 0: scan completed (or no memory, so further scanning is futile) @@ -1321,6 +1322,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, * Only support SCSI-3 and up devices if BLIST_NOREPORTLUN is not set. * Also allow SCSI-2 if BLIST_REPORTLUN2 is set and host adapter does * support more than 8 LUNs. + * Don't attempt if the target doesn't support REPORT LUNS. */ if (bflags & BLIST_NOREPORTLUN) return 1; @@ -1332,6 +1334,8 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, return 1; if (bflags & BLIST_NOLUN) return 0; + if (starget->no_report_luns) + return 1; if (!(sdev = scsi_device_lookup_by_target(starget, 0))) { sdev = scsi_alloc_sdev(starget, 0, NULL); diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index c691fb50e6c..d173b90b25e 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -2349,7 +2349,7 @@ static int sd_try_extended_inquiry(struct scsi_device *sdp) * some USB ones crash on receiving them, and the pages * we currently ask for are for SPC-3 and beyond */ - if (sdp->scsi_level > SCSI_SPC_2) + if (sdp->scsi_level > SCSI_SPC_2 && !sdp->skip_vpd_pages) return 1; return 0; } diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 13b8bcdf3db..dc68cc9fef5 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -197,6 +197,9 @@ static int slave_configure(struct scsi_device *sdev) * page x08, so we will skip it. */ sdev->skip_ms_page_8 = 1; + /* Some devices don't handle VPD pages correctly */ + sdev->skip_vpd_pages = 1; + /* Some disks return the total number of blocks in response * to READ CAPACITY rather than the highest block number. * If this device makes that mistake, tell the sd driver. */ @@ -217,16 +220,6 @@ static int slave_configure(struct scsi_device *sdev) if (sdev->scsi_level > SCSI_SPC_2) us->fflags |= US_FL_SANE_SENSE; - /* Some devices report a SCSI revision level above 2 but are - * unable to handle the REPORT LUNS command (for which - * support is mandatory at level 3). Since we already have - * a Get-Max-LUN request, we won't lose much by setting the - * revision level down to 2. The only devices that would be - * affected are those with sparse LUNs. */ - if (sdev->scsi_level > SCSI_2) - sdev->sdev_target->scsi_level = - sdev->scsi_level = SCSI_2; - /* USB-IDE bridges tend to report SK = 0x04 (Non-recoverable * Hardware Error) when any low-level error occurs, * recoverable or not. Setting this flag tells the SCSI @@ -283,6 +276,18 @@ static int slave_configure(struct scsi_device *sdev) return 0; } +static int target_alloc(struct scsi_target *starget) +{ + /* + * Some USB drives don't support REPORT LUNS, even though they + * report a SCSI revision level above 2. Tell the SCSI layer + * not to issue that command; it will perform a normal sequential + * scan instead. + */ + starget->no_report_luns = 1; + return 0; +} + /* queue a command */ /* This is always called with scsi_lock(host) held */ static int queuecommand_lck(struct scsi_cmnd *srb, @@ -546,6 +551,7 @@ struct scsi_host_template usb_stor_host_template = { .slave_alloc = slave_alloc, .slave_configure = slave_configure, + .target_alloc = target_alloc, /* lots of sg segments can be handled */ .sg_tablesize = SCSI_MAX_SG_CHAIN_SEGMENTS, diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 01cb3c4cb74..b3a1c2daf6c 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -136,6 +136,7 @@ struct scsi_device { unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */ unsigned skip_ms_page_8:1; /* do not use MODE SENSE page 0x08 */ unsigned skip_ms_page_3f:1; /* do not use MODE SENSE page 0x3f */ + unsigned skip_vpd_pages:1; /* do not read VPD pages */ unsigned use_192_bytes_for_3f:1; /* ask for 192 bytes from page 0x3f */ unsigned no_start_on_add:1; /* do not issue start on add */ unsigned allow_restart:1; /* issue START_UNIT in error handler */ @@ -248,6 +249,8 @@ struct scsi_target { * for the device at a time. */ unsigned int pdt_1f_for_no_lun:1; /* PDT = 0x1f * means no lun present. */ + unsigned int no_report_luns:1; /* Don't use + * REPORT LUNS for scanning. */ /* commands actually active on LLD. protected by host lock. */ unsigned int target_busy; /* -- cgit v1.2.3-70-g09d2 From af74d2dae8f85a0e90a30594beb507f5d954fa3f Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 10 Jan 2012 13:43:40 -0500 Subject: usb-storage: reorganize target-specific code Now that usb-storage has a target_alloc() routine, this patch (as1508) moves some existing target-specific code out of the slave_alloc() routine to where it really belongs. Signed-off-by: Alan Stern CC: Matthew Dharm Cc: James Bottomley Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/scsiglue.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index dc68cc9fef5..a324a5d21e9 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -78,8 +78,6 @@ static const char* host_info(struct Scsi_Host *host) static int slave_alloc (struct scsi_device *sdev) { - struct us_data *us = host_to_us(sdev->host); - /* * Set the INQUIRY transfer length to 36. We don't use any of * the extra data and many devices choke if asked for more or @@ -104,18 +102,6 @@ static int slave_alloc (struct scsi_device *sdev) */ blk_queue_update_dma_alignment(sdev->request_queue, (512 - 1)); - /* - * The UFI spec treates the Peripheral Qualifier bits in an - * INQUIRY result as reserved and requires devices to set them - * to 0. However the SCSI spec requires these bits to be set - * to 3 to indicate when a LUN is not present. - * - * Let the scanning code know if this target merely sets - * Peripheral Device Type to 0x1f to indicate no LUN. - */ - if (us->subclass == USB_SC_UFI) - sdev->sdev_target->pdt_1f_for_no_lun = 1; - return 0; } @@ -278,6 +264,8 @@ static int slave_configure(struct scsi_device *sdev) static int target_alloc(struct scsi_target *starget) { + struct us_data *us = host_to_us(dev_to_shost(starget->dev.parent)); + /* * Some USB drives don't support REPORT LUNS, even though they * report a SCSI revision level above 2. Tell the SCSI layer @@ -285,6 +273,19 @@ static int target_alloc(struct scsi_target *starget) * scan instead. */ starget->no_report_luns = 1; + + /* + * The UFI spec treats the Peripheral Qualifier bits in an + * INQUIRY result as reserved and requires devices to set them + * to 0. However the SCSI spec requires these bits to be set + * to 3 to indicate when a LUN is not present. + * + * Let the scanning code know if this target merely sets + * Peripheral Device Type to 0x1f to indicate no LUN. + */ + if (us->subclass == USB_SC_UFI) + starget->pdt_1f_for_no_lun = 1; + return 0; } -- cgit v1.2.3-70-g09d2 From 3cf0ad02e42a91e85ffe9bd67422dd266531d3ec Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 25 Jan 2012 11:51:19 +0100 Subject: usb: gadget: dummy_hcd: don't assign ->desc on error case If the stream check fails then we leave ep->desc assigend but we return with an error code. The caller assumes the endpoint is not enabled (which is the case) but it can not enable it again due to this assigment. Signed-off-by: Sebastian Andrzej Siewior Acked-by: Alan Stern Signed-off-by: Felipe Balbi --- drivers/usb/gadget/dummy_hcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 67573e5f2a1..9170a4c7ced 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -514,7 +514,6 @@ static int dummy_enable(struct usb_ep *_ep, } _ep->maxpacket = max; - ep->desc = desc; if (usb_ss_max_streams(_ep->comp_desc)) { if (!usb_endpoint_xfer_bulk(desc)) { dev_err(udc_dev(dum), "Can't enable stream support on " @@ -523,6 +522,7 @@ static int dummy_enable(struct usb_ep *_ep, } ep->stream_en = 1; } + ep->desc = desc; dev_dbg(udc_dev(dum), "enabled %s (ep%d%s-%s) maxpacket %d stream %s\n", _ep->name, -- cgit v1.2.3-70-g09d2 From 20edfbb6a17f3007c1905e9849d8d306e318883b Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 25 Jan 2012 15:18:58 +0100 Subject: usb: gadget: dummy_hcd: fix null-deref free req _ep to ep is a pointer substraction so ep won't be zero unless _ep was 8. This was not intendent by the author, it was probably a typo while checking for NULL of the argument. Signed-off-by: Sebastian Andrzej Siewior Acked-by: Alan Stern Signed-off-by: Felipe Balbi --- drivers/usb/gadget/dummy_hcd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 9170a4c7ced..8cc1a88d21e 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -599,8 +599,10 @@ static void dummy_free_request(struct usb_ep *_ep, struct usb_request *_req) struct dummy_ep *ep; struct dummy_request *req; + if (!_ep || !_req) + return; ep = usb_ep_to_dummy_ep(_ep); - if (!ep || !_req || (!ep->desc && _ep->name != ep0name)) + if (!ep->desc && _ep->name != ep0name) return; req = usb_request_to_dummy_request(_req); -- cgit v1.2.3-70-g09d2 From dd63180b758d5972fc90621af0741d5bfae1a684 Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Fri, 3 Feb 2012 16:35:26 +0900 Subject: usb: gadget: pch_udc: Detecting VBUS through GPIO Problem: In USB Suspend, pch_udc handles 'disconnect'. Root cause: The current pch_udc is not monitoring VBUS. When USB cable is disconnected, USB Device Controller generates an interrupt of USB Suspend. pch_udc cannot distinguish it is USB Suspend or disconnect. Therefore, pch_udc handles 'disconnect' after an interrupt of USB Suspend happend. Solution: VBUS is detected through GPIO. After an interrupt produced USB Suspend, if VBUS is Low, pch_udc handles 'disconnect'. If VBUS is High, pch_udc handles 'suspend'. Signed-off-by: Tomoya MORINAGA Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pch_udc.c | 145 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 142 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index 82416aae816..9c5ae2c1014 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c @@ -15,6 +15,13 @@ #include #include #include +#include + +/* GPIO port for VBUS detecting */ +static int vbus_gpio_port = -1; /* GPIO port number (-1:Not used) */ + +#define PCH_VBUS_PERIOD 3000 /* VBUS polling period (msec) */ +#define PCH_VBUS_INTERVAL 10 /* VBUS polling interval (msec) */ /* Address offset of Registers */ #define UDC_EP_REG_SHIFT 0x20 /* Offset to next EP */ @@ -295,6 +302,17 @@ struct pch_udc_ep { unsigned long epsts; }; +/** + * struct pch_vbus_gpio_data - Structure holding GPIO informaton + * for detecting VBUS + * @port: gpio port number + * @irq_work_fall Structure for WorkQueue + */ +struct pch_vbus_gpio_data { + int port; + struct work_struct irq_work_fall; +}; + /** * struct pch_udc_dev - Structure holding complete information * of the PCH USB device @@ -323,6 +341,7 @@ struct pch_udc_ep { * @base_addr: for mapped device memory * @irq: IRQ line for the device * @cfg_data: current cfg, intf, and alt in use + * @vbus_gpio: GPIO informaton for detecting VBUS */ struct pch_udc_dev { struct usb_gadget gadget; @@ -349,7 +368,8 @@ struct pch_udc_dev { unsigned long phys_addr; void __iomem *base_addr; unsigned irq; - struct pch_udc_cfg_data cfg_data; + struct pch_udc_cfg_data cfg_data; + struct pch_vbus_gpio_data vbus_gpio; }; #define PCH_UDC_PCI_BAR 1 @@ -1225,6 +1245,115 @@ static const struct usb_gadget_ops pch_udc_ops = { .stop = pch_udc_stop, }; +/** + * pch_vbus_gpio_get_value() - This API gets value of GPIO port as VBUS status. + * @dev: Reference to the driver structure + * + * Return value: + * 1: VBUS is high + * 0: VBUS is low + * -1: It is not enable to detect VBUS using GPIO + */ +static int pch_vbus_gpio_get_value(struct pch_udc_dev *dev) +{ + int vbus = 0; + + if (dev->vbus_gpio.port) + vbus = gpio_get_value(dev->vbus_gpio.port) ? 1 : 0; + else + vbus = -1; + + return vbus; +} + +/** + * pch_vbus_gpio_work_fall() - This API keeps watch on VBUS becoming Low. + * If VBUS is Low, disconnect is processed + * @irq_work: Structure for WorkQueue + * + */ +static void pch_vbus_gpio_work_fall(struct work_struct *irq_work) +{ + struct pch_vbus_gpio_data *vbus_gpio = container_of(irq_work, + struct pch_vbus_gpio_data, irq_work_fall); + struct pch_udc_dev *dev = + container_of(vbus_gpio, struct pch_udc_dev, vbus_gpio); + int vbus_saved = -1; + int vbus; + int count; + + if (!dev->vbus_gpio.port) + return; + + for (count = 0; count < (PCH_VBUS_PERIOD / PCH_VBUS_INTERVAL); + count++) { + vbus = pch_vbus_gpio_get_value(dev); + + if ((vbus_saved == vbus) && (vbus == 0)) { + dev_dbg(&dev->pdev->dev, "VBUS fell"); + if (dev->driver + && dev->driver->disconnect) { + dev->driver->disconnect( + &dev->gadget); + } + pch_udc_reconnect(dev); + dev_dbg(&dev->pdev->dev, "VBUS fell"); + return; + } + vbus_saved = vbus; + mdelay(PCH_VBUS_INTERVAL); + } +} + +/** + * pch_vbus_gpio_init() - This API initializes GPIO port detecting VBUS. + * @dev: Reference to the driver structure + * @vbus_gpio Number of GPIO port to detect gpio + * + * Return codes: + * 0: Success + * -EINVAL: GPIO port is invalid or can't be initialized. + */ +static int pch_vbus_gpio_init(struct pch_udc_dev *dev, int vbus_gpio_port) +{ + int err; + + dev->vbus_gpio.port = 0; + + if (vbus_gpio_port <= -1) + return -EINVAL; + + err = gpio_is_valid(vbus_gpio_port); + if (!err) { + pr_err("%s: gpio port %d is invalid\n", + __func__, vbus_gpio_port); + return -EINVAL; + } + + err = gpio_request(vbus_gpio_port, "pch_vbus"); + if (err) { + pr_err("%s: can't request gpio port %d, err: %d\n", + __func__, vbus_gpio_port, err); + return -EINVAL; + } + + dev->vbus_gpio.port = vbus_gpio_port; + gpio_direction_input(vbus_gpio_port); + INIT_WORK(&dev->vbus_gpio.irq_work_fall, pch_vbus_gpio_work_fall); + + return 0; +} + +/** + * pch_vbus_gpio_free() - This API frees resources of GPIO port + * @dev: Reference to the driver structure + */ +static void pch_vbus_gpio_free(struct pch_udc_dev *dev) +{ + if (dev->vbus_gpio.port) + gpio_free(dev->vbus_gpio.port); +} + /** * complete_req() - This API is invoked from the driver when processing * of a request is complete @@ -2510,6 +2639,8 @@ static void pch_udc_svc_cfg_interrupt(struct pch_udc_dev *dev) */ static void pch_udc_dev_isr(struct pch_udc_dev *dev, u32 dev_intr) { + int vbus; + /* USB Reset Interrupt */ if (dev_intr & UDC_DEVINT_UR) { pch_udc_svc_ur_interrupt(dev); @@ -2535,14 +2666,19 @@ static void pch_udc_dev_isr(struct pch_udc_dev *dev, u32 dev_intr) spin_lock(&dev->lock); } - if (dev->vbus_session == 0) { + vbus = pch_vbus_gpio_get_value(dev); + if ((dev->vbus_session == 0) + && (vbus != 1)) { if (dev->driver && dev->driver->disconnect) { spin_unlock(&dev->lock); dev->driver->disconnect(&dev->gadget); spin_lock(&dev->lock); } pch_udc_reconnect(dev); - } + } else if ((dev->vbus_session == 0) + && (vbus == 1)) + schedule_work(&dev->vbus_gpio.irq_work_fall); + dev_dbg(&dev->pdev->dev, "USB_SUSPEND\n"); } /* Clear the SOF interrupt, if enabled */ @@ -2704,6 +2840,7 @@ static int pch_udc_pcd_init(struct pch_udc_dev *dev) { pch_udc_init(dev); pch_udc_pcd_reinit(dev); + pch_vbus_gpio_init(dev, vbus_gpio_port); return 0; } @@ -2882,6 +3019,8 @@ static void pch_udc_remove(struct pci_dev *pdev) UDC_EP0OUT_BUFF_SIZE * 4, DMA_FROM_DEVICE); kfree(dev->ep0out_buf); + pch_vbus_gpio_free(dev); + pch_udc_exit(dev); if (dev->irq_registered) -- cgit v1.2.3-70-g09d2 From 637b78eb31e0b167ed913f1750bb645dfeda38f0 Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Fri, 3 Feb 2012 16:14:18 +0900 Subject: usb: gadget: pch_udc: Detecting VBUS through GPIO with interrupt Problem: pch_udc continues operation even if VBUS becomes Low. pch_udc performs D+ pulling up before VBUS becomes High. USB device should be controlled according to VBUS state. Root cause: The current pch_udc is not always monitoring VBUS. Solution: The change of VBUS is detected using an interrupt of GPIO. If VBUS became Low, pch_udc handles 'disconnect'. After VBUS became High, a pull improves D+, and pch_udc handles 'connect'. [ balbi@ti.com : make it actually compile ] Signed-off-by: Tomoya MORINAGA Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pch_udc.c | 87 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index 9c5ae2c1014..a992084d389 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c @@ -306,11 +306,15 @@ struct pch_udc_ep { * struct pch_vbus_gpio_data - Structure holding GPIO informaton * for detecting VBUS * @port: gpio port number + * @intr: gpio interrupt number * @irq_work_fall Structure for WorkQueue + * @irq_work_rise Structure for WorkQueue */ struct pch_vbus_gpio_data { int port; + int intr; struct work_struct irq_work_fall; + struct work_struct irq_work_rise; }; /** @@ -1296,8 +1300,10 @@ static void pch_vbus_gpio_work_fall(struct work_struct *irq_work) dev->driver->disconnect( &dev->gadget); } - pch_udc_reconnect(dev); - dev_dbg(&dev->pdev->dev, "VBUS fell"); + if (dev->vbus_gpio.intr) + pch_udc_init(dev); + else + pch_udc_reconnect(dev); return; } vbus_saved = vbus; @@ -1305,6 +1311,57 @@ static void pch_vbus_gpio_work_fall(struct work_struct *irq_work) } } +/** + * pch_vbus_gpio_work_rise() - This API checks VBUS is High. + * If VBUS is High, connect is processed + * @irq_work: Structure for WorkQueue + * + */ +static void pch_vbus_gpio_work_rise(struct work_struct *irq_work) +{ + struct pch_vbus_gpio_data *vbus_gpio = container_of(irq_work, + struct pch_vbus_gpio_data, irq_work_rise); + struct pch_udc_dev *dev = + container_of(vbus_gpio, struct pch_udc_dev, vbus_gpio); + int vbus; + + if (!dev->vbus_gpio.port) + return; + + mdelay(PCH_VBUS_INTERVAL); + vbus = pch_vbus_gpio_get_value(dev); + + if (vbus == 1) { + dev_dbg(&dev->pdev->dev, "VBUS rose"); + pch_udc_reconnect(dev); + return; + } +} + +/** + * pch_vbus_gpio_irq() - IRQ handler for GPIO intrerrupt for changing VBUS + * @irq: Interrupt request number + * @dev: Reference to the device structure + * + * Return codes: + * 0: Success + * -EINVAL: GPIO port is invalid or can't be initialized. + */ +static irqreturn_t pch_vbus_gpio_irq(int irq, void *data) +{ + struct pch_udc_dev *dev = (struct pch_udc_dev *)data; + + if (!dev->vbus_gpio.port || !dev->vbus_gpio.intr) + return IRQ_NONE; + + if (pch_vbus_gpio_get_value(dev)) + schedule_work(&dev->vbus_gpio.irq_work_rise); + else + schedule_work(&dev->vbus_gpio.irq_work_fall); + + return IRQ_HANDLED; +} + /** * pch_vbus_gpio_init() - This API initializes GPIO port detecting VBUS. * @dev: Reference to the driver structure @@ -1317,8 +1374,10 @@ static void pch_vbus_gpio_work_fall(struct work_struct *irq_work) static int pch_vbus_gpio_init(struct pch_udc_dev *dev, int vbus_gpio_port) { int err; + int irq_num = 0; dev->vbus_gpio.port = 0; + dev->vbus_gpio.intr = 0; if (vbus_gpio_port <= -1) return -EINVAL; @@ -1341,6 +1400,21 @@ static int pch_vbus_gpio_init(struct pch_udc_dev *dev, int vbus_gpio_port) gpio_direction_input(vbus_gpio_port); INIT_WORK(&dev->vbus_gpio.irq_work_fall, pch_vbus_gpio_work_fall); + irq_num = gpio_to_irq(vbus_gpio_port); + if (irq_num > 0) { + irq_set_irq_type(irq_num, IRQ_TYPE_EDGE_BOTH); + err = request_irq(irq_num, pch_vbus_gpio_irq, 0, + "vbus_detect", dev); + if (!err) { + dev->vbus_gpio.intr = irq_num; + INIT_WORK(&dev->vbus_gpio.irq_work_rise, + pch_vbus_gpio_work_rise); + } else { + pr_err("%s: can't request irq %d, err: %d\n", + __func__, irq_num, err); + } + } + return 0; } @@ -1350,6 +1424,9 @@ static int pch_vbus_gpio_init(struct pch_udc_dev *dev, int vbus_gpio_port) */ static void pch_vbus_gpio_free(struct pch_udc_dev *dev) { + if (dev->vbus_gpio.intr) + free_irq(dev->vbus_gpio.intr, dev); + if (dev->vbus_gpio.port) gpio_free(dev->vbus_gpio.port); } @@ -2676,7 +2753,8 @@ static void pch_udc_dev_isr(struct pch_udc_dev *dev, u32 dev_intr) } pch_udc_reconnect(dev); } else if ((dev->vbus_session == 0) - && (vbus == 1)) + && (vbus == 1) + && !dev->vbus_gpio.intr) schedule_work(&dev->vbus_gpio.irq_work_fall); dev_dbg(&dev->pdev->dev, "USB_SUSPEND\n"); @@ -2941,7 +3019,8 @@ static int pch_udc_start(struct usb_gadget_driver *driver, pch_udc_setup_ep0(dev); /* clear SD */ - pch_udc_clear_disconnect(dev); + if ((pch_vbus_gpio_get_value(dev) != 0) || !dev->vbus_gpio.intr) + pch_udc_clear_disconnect(dev); dev->connected = 1; return 0; -- cgit v1.2.3-70-g09d2 From 609ca228073ae06c5513474d2cdf0af7ee5766ec Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 6 Feb 2012 18:46:35 +0100 Subject: usb: gadget: clean the ep in autoconf before returning it. Since commit 72c973dd aka ("usb: gadget: add usb_endpoint_descriptor to struct usb_ep) the descriptor is part of the ep. Most gadgets like g_zero or masstorage call config_ep_by_speed() to grab an available endpoint which may be used for FS/HS/SS bulk/iso/intr and in a second they assign the proper descriptor by calling config_ep_by_speed(). This is good so far. A few of them like ncm call config_ep_by_speed() only if ep->desc not assigned earlier. That means ep->desc is never assigned if the endpoint was used by another gadget before it was removed. Some of those gadgets also assign ep->driver_data to NULL on reset or ep_disable part _but_ keep a reference to this endpoint. At ep_enable time they assign driver_data to their private data. This probably needs a clean up of its own. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/epautoconf.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 753aa0683ac..f59f7e367b5 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c @@ -275,24 +275,24 @@ struct usb_ep *usb_ep_autoconfig_ss( /* 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)) - return ep; + goto found_ep; ep = find_ep (gadget, "ep-f"); if (ep && ep_matches(gadget, ep, desc, ep_comp)) - return ep; + 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)) - return ep; + 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)) - return ep; + goto found_ep; } #ifdef CONFIG_BLACKFIN @@ -311,18 +311,22 @@ struct usb_ep *usb_ep_autoconfig_ss( } else ep = NULL; if (ep && ep_matches(gadget, ep, desc, ep_comp)) - return ep; + 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)) - return ep; + goto found_ep; } /* Fail */ return NULL; +found_ep: + ep->desc = NULL; + ep->comp_desc = NULL; + return ep; } /** -- cgit v1.2.3-70-g09d2 From 6fecfb05c077586ba85aa6f52f10abf30a4bfb40 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 6 Feb 2012 18:46:36 +0100 Subject: usb: gadget: add usb3.0 descriptors to serial gadgets This patch adds SS descriptors to the ACM & generic serial gadget. The ACM part was tested with minicom + dummy + send / receive files over ttyACM <=> ttyGS0. The generic serial part (f_serial) was not tested (haven't found a driver on the host side). The nokia & multi gadget use HS at most. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_acm.c | 50 +++++++++++++++++++++++++++++++++++++++++++ drivers/usb/gadget/f_serial.c | 42 ++++++++++++++++++++++++++++++++++++ drivers/usb/gadget/serial.c | 2 +- 3 files changed, 93 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index e4821219546..d672250a61f 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c @@ -237,6 +237,42 @@ static struct usb_descriptor_header *acm_hs_function[] = { 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 @@ -643,9 +679,21 @@ acm_bind(struct usb_configuration *c, struct usb_function *f) /* 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); @@ -675,6 +723,8 @@ acm_unbind(struct usb_configuration *c, struct usb_function *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); diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c index cf33a8d0fd5..07197d63d9b 100644 --- a/drivers/usb/gadget/f_serial.c +++ b/drivers/usb/gadget/f_serial.c @@ -99,6 +99,34 @@ static struct usb_descriptor_header *gser_hs_function[] __initdata = { NULL, }; +static struct usb_endpoint_descriptor gser_ss_in_desc __initdata = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(1024), +}; + +static struct usb_endpoint_descriptor gser_ss_out_desc __initdata = { + .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 gser_ss_bulk_comp_desc __initdata = { + .bLength = sizeof gser_ss_bulk_comp_desc, + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, +}; + +static struct usb_descriptor_header *gser_ss_function[] __initdata = { + (struct usb_descriptor_header *) &gser_interface_desc, + (struct usb_descriptor_header *) &gser_ss_in_desc, + (struct usb_descriptor_header *) &gser_ss_bulk_comp_desc, + (struct usb_descriptor_header *) &gser_ss_out_desc, + (struct usb_descriptor_header *) &gser_ss_bulk_comp_desc, + NULL, +}; + /* string descriptors: */ static struct usb_string gser_string_defs[] = { @@ -201,9 +229,21 @@ gser_bind(struct usb_configuration *c, struct usb_function *f) /* copy descriptors, and track endpoint copies */ f->hs_descriptors = usb_copy_descriptors(gser_hs_function); } + if (gadget_is_superspeed(c->cdev->gadget)) { + gser_ss_in_desc.bEndpointAddress = + gser_fs_in_desc.bEndpointAddress; + gser_ss_out_desc.bEndpointAddress = + gser_fs_out_desc.bEndpointAddress; + + /* copy descriptors, and track endpoint copies */ + f->ss_descriptors = usb_copy_descriptors(gser_ss_function); + if (!f->ss_descriptors) + goto fail; + } DBG(cdev, "generic ttyGS%d: %s speed IN/%s OUT/%s\n", gser->port_num, + gadget_is_superspeed(c->cdev->gadget) ? "super" : gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", gser->port.in->name, gser->port.out->name); return 0; @@ -225,6 +265,8 @@ gser_unbind(struct usb_configuration *c, struct usb_function *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); kfree(func_to_gser(f)); } diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index ad9e5b2df64..665c07422c2 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c @@ -242,7 +242,7 @@ static struct usb_composite_driver gserial_driver = { .name = "g_serial", .dev = &device_desc, .strings = dev_strings, - .max_speed = USB_SPEED_HIGH, + .max_speed = USB_SPEED_SUPER, }; static int __init init(void) -- cgit v1.2.3-70-g09d2 From 1cf0c6e69e396538615153056605aaafab11935a Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Mon, 6 Feb 2012 08:49:25 +0100 Subject: Input: Add EVIOC mechanism for MT slots This patch adds the ability to extract MT slot data via a new ioctl, EVIOCGMTSLOTS. The function returns an array of slot values for the specified ABS_MT event type. Example of user space usage: struct { unsigned code; int values[64]; } req; req.code = ABS_MT_POSITION_X; if (ioctl(fd, EVIOCGMTSLOTS(sizeof(req)), &req) < 0) return -1; for (i = 0; i < 64; i++) printf("slot %d: %d\n", i, req.values[i]); Reviewed-by: Chase Douglas Signed-off-by: Henrik Rydberg --- drivers/input/evdev.c | 27 ++++++++++++++++++++++++++- include/linux/input.h | 25 +++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 76457d50bc3..e4cad161be9 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include "input-compat.h" @@ -623,6 +623,28 @@ static int evdev_handle_set_keycode_v2(struct input_dev *dev, void __user *p) return input_set_keycode(dev, &ke); } +static int evdev_handle_mt_request(struct input_dev *dev, + unsigned int size, + int __user *ip) +{ + const struct input_mt_slot *mt = dev->mt; + unsigned int code; + int max_slots; + int i; + + if (get_user(code, &ip[0])) + return -EFAULT; + if (!input_is_mt_value(code)) + return -EINVAL; + + max_slots = (size - sizeof(__u32)) / sizeof(__s32); + for (i = 0; i < dev->mtsize && i < max_slots; i++) + if (put_user(input_mt_get_value(&mt[i], code), &ip[1 + i])) + return -EFAULT; + + return 0; +} + static long evdev_do_ioctl(struct file *file, unsigned int cmd, void __user *p, int compat_mode) { @@ -708,6 +730,9 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, return bits_to_user(dev->propbit, INPUT_PROP_MAX, size, p, compat_mode); + case EVIOCGMTSLOTS(0): + return evdev_handle_mt_request(dev, size, ip); + case EVIOCGKEY(0): return bits_to_user(dev->key, KEY_MAX, size, p, compat_mode); diff --git a/include/linux/input.h b/include/linux/input.h index 3862e32c4ee..af264438631 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -114,6 +114,31 @@ struct input_keymap_entry { #define EVIOCGUNIQ(len) _IOC(_IOC_READ, 'E', 0x08, len) /* get unique identifier */ #define EVIOCGPROP(len) _IOC(_IOC_READ, 'E', 0x09, len) /* get device properties */ +/** + * EVIOCGMTSLOTS(len) - get MT slot values + * + * The ioctl buffer argument should be binary equivalent to + * + * struct input_mt_request_layout { + * __u32 code; + * __s32 values[num_slots]; + * }; + * + * where num_slots is the (arbitrary) number of MT slots to extract. + * + * The ioctl size argument (len) is the size of the buffer, which + * should satisfy len = (num_slots + 1) * sizeof(__s32). If len is + * too small to fit all available slots, the first num_slots are + * returned. + * + * Before the call, code is set to the wanted ABS_MT event type. On + * return, values[] is filled with the slot values for the specified + * ABS_MT code. + * + * If the request code is not an ABS_MT value, -EINVAL is returned. + */ +#define EVIOCGMTSLOTS(len) _IOC(_IOC_READ, 'E', 0x0a, len) + #define EVIOCGKEY(len) _IOC(_IOC_READ, 'E', 0x18, len) /* get global key state */ #define EVIOCGLED(len) _IOC(_IOC_READ, 'E', 0x19, len) /* get all LEDs */ #define EVIOCGSND(len) _IOC(_IOC_READ, 'E', 0x1a, len) /* get all sounds status */ -- cgit v1.2.3-70-g09d2 From ff240199b6a3b0bec5ae9b6d26403dad38e8cb19 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 31 Jan 2012 21:08:14 +0100 Subject: drm/i915: s/DRM_ERROR/DRM_DEBUG in i915_gem_execbuffer.c These are all user-trigerable, so tune down their loudness a notch. For some of these we have i-g-t tests (because they prevent newly-discovered bugs), without this patches running the test suite leaves behind a dirty dmesg. Reviewed-by: Chris Wilson Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 50 +++++++++++++++--------------- 1 file changed, 25 insertions(+), 25 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 123c51445a8..b964998b5e2 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -287,14 +287,14 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, * exec_object list, so it should have a GTT space bound by now. */ if (unlikely(target_offset == 0)) { - DRM_ERROR("No GTT space found for object %d\n", + DRM_DEBUG("No GTT space found for object %d\n", reloc->target_handle); return ret; } /* Validate that the target is in a valid r/w GPU domain */ if (unlikely(reloc->write_domain & (reloc->write_domain - 1))) { - DRM_ERROR("reloc with multiple write domains: " + DRM_DEBUG("reloc with multiple write domains: " "obj %p target %d offset %d " "read %08x write %08x", obj, reloc->target_handle, @@ -305,7 +305,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, } if (unlikely((reloc->write_domain | reloc->read_domains) & ~I915_GEM_GPU_DOMAINS)) { - DRM_ERROR("reloc with read/write non-GPU domains: " + DRM_DEBUG("reloc with read/write non-GPU domains: " "obj %p target %d offset %d " "read %08x write %08x", obj, reloc->target_handle, @@ -316,7 +316,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, } if (unlikely(reloc->write_domain && target_obj->pending_write_domain && reloc->write_domain != target_obj->pending_write_domain)) { - DRM_ERROR("Write domain conflict: " + DRM_DEBUG("Write domain conflict: " "obj %p target %d offset %d " "new %08x old %08x\n", obj, reloc->target_handle, @@ -337,7 +337,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, /* Check that the relocation address is valid... */ if (unlikely(reloc->offset > obj->base.size - 4)) { - DRM_ERROR("Relocation beyond object bounds: " + DRM_DEBUG("Relocation beyond object bounds: " "obj %p target %d offset %d size %d.\n", obj, reloc->target_handle, (int) reloc->offset, @@ -345,7 +345,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, return ret; } if (unlikely(reloc->offset & 3)) { - DRM_ERROR("Relocation not 4-byte aligned: " + DRM_DEBUG("Relocation not 4-byte aligned: " "obj %p target %d offset %d.\n", obj, reloc->target_handle, (int) reloc->offset); @@ -724,7 +724,7 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, obj = to_intel_bo(drm_gem_object_lookup(dev, file, exec[i].handle)); if (&obj->base == NULL) { - DRM_ERROR("Invalid object handle %d at index %d\n", + DRM_DEBUG("Invalid object handle %d at index %d\n", exec[i].handle, i); ret = -ENOENT; goto err; @@ -1055,7 +1055,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, int ret, mode, i; if (!i915_gem_check_execbuffer(args)) { - DRM_ERROR("execbuf with invalid offset/length\n"); + DRM_DEBUG("execbuf with invalid offset/length\n"); return -EINVAL; } @@ -1070,20 +1070,20 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, break; case I915_EXEC_BSD: if (!HAS_BSD(dev)) { - DRM_ERROR("execbuf with invalid ring (BSD)\n"); + DRM_DEBUG("execbuf with invalid ring (BSD)\n"); return -EINVAL; } ring = &dev_priv->ring[VCS]; break; case I915_EXEC_BLT: if (!HAS_BLT(dev)) { - DRM_ERROR("execbuf with invalid ring (BLT)\n"); + DRM_DEBUG("execbuf with invalid ring (BLT)\n"); return -EINVAL; } ring = &dev_priv->ring[BCS]; break; default: - DRM_ERROR("execbuf with unknown ring: %d\n", + DRM_DEBUG("execbuf with unknown ring: %d\n", (int)(args->flags & I915_EXEC_RING_MASK)); return -EINVAL; } @@ -1109,18 +1109,18 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, } break; default: - DRM_ERROR("execbuf with unknown constants: %d\n", mode); + DRM_DEBUG("execbuf with unknown constants: %d\n", mode); return -EINVAL; } if (args->buffer_count < 1) { - DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); + DRM_DEBUG("execbuf with %d buffers\n", args->buffer_count); return -EINVAL; } if (args->num_cliprects != 0) { if (ring != &dev_priv->ring[RCS]) { - DRM_ERROR("clip rectangles are only valid with the render ring\n"); + DRM_DEBUG("clip rectangles are only valid with the render ring\n"); return -EINVAL; } @@ -1165,7 +1165,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, obj = to_intel_bo(drm_gem_object_lookup(dev, file, exec[i].handle)); if (&obj->base == NULL) { - DRM_ERROR("Invalid object handle %d at index %d\n", + DRM_DEBUG("Invalid object handle %d at index %d\n", exec[i].handle, i); /* prevent error path from reading uninitialized data */ ret = -ENOENT; @@ -1173,7 +1173,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, } if (!list_empty(&obj->exec_list)) { - DRM_ERROR("Object %p [handle %d, index %d] appears more than once in object list\n", + DRM_DEBUG("Object %p [handle %d, index %d] appears more than once in object list\n", obj, exec[i].handle, i); ret = -EINVAL; goto err; @@ -1211,7 +1211,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, /* Set the pending read domains for the batch buffer to COMMAND */ if (batch_obj->base.pending_write_domain) { - DRM_ERROR("Attempting to use self-modifying batch buffer\n"); + DRM_DEBUG("Attempting to use self-modifying batch buffer\n"); ret = -EINVAL; goto err; } @@ -1316,7 +1316,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, int ret, i; if (args->buffer_count < 1) { - DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); + DRM_DEBUG("execbuf with %d buffers\n", args->buffer_count); return -EINVAL; } @@ -1324,7 +1324,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, exec_list = drm_malloc_ab(sizeof(*exec_list), args->buffer_count); exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count); if (exec_list == NULL || exec2_list == NULL) { - DRM_ERROR("Failed to allocate exec list for %d buffers\n", + DRM_DEBUG("Failed to allocate exec list for %d buffers\n", args->buffer_count); drm_free_large(exec_list); drm_free_large(exec2_list); @@ -1335,7 +1335,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, (uintptr_t) args->buffers_ptr, sizeof(*exec_list) * args->buffer_count); if (ret != 0) { - DRM_ERROR("copy %d exec entries failed %d\n", + DRM_DEBUG("copy %d exec entries failed %d\n", args->buffer_count, ret); drm_free_large(exec_list); drm_free_large(exec2_list); @@ -1376,7 +1376,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, sizeof(*exec_list) * args->buffer_count); if (ret) { ret = -EFAULT; - DRM_ERROR("failed to copy %d exec entries " + DRM_DEBUG("failed to copy %d exec entries " "back to user (%d)\n", args->buffer_count, ret); } @@ -1396,7 +1396,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, int ret; if (args->buffer_count < 1) { - DRM_ERROR("execbuf2 with %d buffers\n", args->buffer_count); + DRM_DEBUG("execbuf2 with %d buffers\n", args->buffer_count); return -EINVAL; } @@ -1406,7 +1406,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count); if (exec2_list == NULL) { - DRM_ERROR("Failed to allocate exec list for %d buffers\n", + DRM_DEBUG("Failed to allocate exec list for %d buffers\n", args->buffer_count); return -ENOMEM; } @@ -1415,7 +1415,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, (uintptr_t) args->buffers_ptr, sizeof(*exec2_list) * args->buffer_count); if (ret != 0) { - DRM_ERROR("copy %d exec entries failed %d\n", + DRM_DEBUG("copy %d exec entries failed %d\n", args->buffer_count, ret); drm_free_large(exec2_list); return -EFAULT; @@ -1430,7 +1430,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, sizeof(*exec2_list) * args->buffer_count); if (ret) { ret = -EFAULT; - DRM_ERROR("failed to copy %d exec entries " + DRM_DEBUG("failed to copy %d exec entries " "back to user (%d)\n", args->buffer_count, ret); } -- cgit v1.2.3-70-g09d2 From 4a67d39190315558631d944b1cea4466ed4c86d8 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 6 Feb 2012 10:58:17 +0100 Subject: drm: add convenience function to create an enum property Creating an enum property is a common pattern, so create a convenience function for this and use it where appropriate. Signed-off-by: Sascha Hauer Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc.c | 100 ++++++++++++++---------------- drivers/gpu/drm/i915/intel_modes.c | 28 ++++----- drivers/gpu/drm/nouveau/nouveau_display.c | 10 +-- drivers/gpu/drm/radeon/radeon_display.c | 43 +++---------- include/drm/drm_crtc.h | 8 +++ 5 files changed, 80 insertions(+), 109 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 322bc7b1300..3fe99c456a1 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -38,11 +38,6 @@ #include "drm_edid.h" #include "drm_fourcc.h" -struct drm_prop_enum_list { - int type; - char *name; -}; - /* Avoid boilerplate. I'm tired of typing. */ #define DRM_ENUM_NAME_FN(fnname, list) \ char *fnname(int val) \ @@ -658,7 +653,6 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev) { struct drm_property *edid; struct drm_property *dpms; - int i; /* * Standard properties (apply to all connectors) @@ -668,11 +662,9 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev) "EDID", 0); dev->mode_config.edid_property = edid; - dpms = drm_property_create(dev, DRM_MODE_PROP_ENUM, - "DPMS", ARRAY_SIZE(drm_dpms_enum_list)); - for (i = 0; i < ARRAY_SIZE(drm_dpms_enum_list); i++) - drm_property_add_enum(dpms, i, drm_dpms_enum_list[i].type, - drm_dpms_enum_list[i].name); + dpms = drm_property_create_enum(dev, 0, + "DPMS", drm_dpms_enum_list, + ARRAY_SIZE(drm_dpms_enum_list)); dev->mode_config.dpms_property = dpms; return 0; @@ -688,30 +680,21 @@ int drm_mode_create_dvi_i_properties(struct drm_device *dev) { struct drm_property *dvi_i_selector; struct drm_property *dvi_i_subconnector; - int i; if (dev->mode_config.dvi_i_select_subconnector_property) return 0; dvi_i_selector = - drm_property_create(dev, DRM_MODE_PROP_ENUM, + drm_property_create_enum(dev, 0, "select subconnector", + drm_dvi_i_select_enum_list, ARRAY_SIZE(drm_dvi_i_select_enum_list)); - for (i = 0; i < ARRAY_SIZE(drm_dvi_i_select_enum_list); i++) - drm_property_add_enum(dvi_i_selector, i, - drm_dvi_i_select_enum_list[i].type, - drm_dvi_i_select_enum_list[i].name); dev->mode_config.dvi_i_select_subconnector_property = dvi_i_selector; - dvi_i_subconnector = - drm_property_create(dev, DRM_MODE_PROP_ENUM | - DRM_MODE_PROP_IMMUTABLE, + dvi_i_subconnector = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, "subconnector", + drm_dvi_i_subconnector_enum_list, ARRAY_SIZE(drm_dvi_i_subconnector_enum_list)); - for (i = 0; i < ARRAY_SIZE(drm_dvi_i_subconnector_enum_list); i++) - drm_property_add_enum(dvi_i_subconnector, i, - drm_dvi_i_subconnector_enum_list[i].type, - drm_dvi_i_subconnector_enum_list[i].name); dev->mode_config.dvi_i_subconnector_property = dvi_i_subconnector; return 0; @@ -742,23 +725,17 @@ int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes, /* * Basic connector properties */ - tv_selector = drm_property_create(dev, DRM_MODE_PROP_ENUM, + tv_selector = drm_property_create_enum(dev, 0, "select subconnector", + drm_tv_select_enum_list, ARRAY_SIZE(drm_tv_select_enum_list)); - for (i = 0; i < ARRAY_SIZE(drm_tv_select_enum_list); i++) - drm_property_add_enum(tv_selector, i, - drm_tv_select_enum_list[i].type, - drm_tv_select_enum_list[i].name); dev->mode_config.tv_select_subconnector_property = tv_selector; tv_subconnector = - drm_property_create(dev, DRM_MODE_PROP_ENUM | - DRM_MODE_PROP_IMMUTABLE, "subconnector", + drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, + "subconnector", + drm_tv_subconnector_enum_list, ARRAY_SIZE(drm_tv_subconnector_enum_list)); - for (i = 0; i < ARRAY_SIZE(drm_tv_subconnector_enum_list); i++) - drm_property_add_enum(tv_subconnector, i, - drm_tv_subconnector_enum_list[i].type, - drm_tv_subconnector_enum_list[i].name); dev->mode_config.tv_subconnector_property = tv_subconnector; /* @@ -845,18 +822,14 @@ EXPORT_SYMBOL(drm_mode_create_tv_properties); int drm_mode_create_scaling_mode_property(struct drm_device *dev) { struct drm_property *scaling_mode; - int i; if (dev->mode_config.scaling_mode_property) return 0; scaling_mode = - drm_property_create(dev, DRM_MODE_PROP_ENUM, "scaling mode", + drm_property_create_enum(dev, 0, "scaling mode", + drm_scaling_mode_enum_list, ARRAY_SIZE(drm_scaling_mode_enum_list)); - for (i = 0; i < ARRAY_SIZE(drm_scaling_mode_enum_list); i++) - drm_property_add_enum(scaling_mode, i, - drm_scaling_mode_enum_list[i].type, - drm_scaling_mode_enum_list[i].name); dev->mode_config.scaling_mode_property = scaling_mode; @@ -874,18 +847,14 @@ EXPORT_SYMBOL(drm_mode_create_scaling_mode_property); int drm_mode_create_dithering_property(struct drm_device *dev) { struct drm_property *dithering_mode; - int i; if (dev->mode_config.dithering_mode_property) return 0; dithering_mode = - drm_property_create(dev, DRM_MODE_PROP_ENUM, "dithering", + drm_property_create_enum(dev, 0, "dithering", + drm_dithering_mode_enum_list, ARRAY_SIZE(drm_dithering_mode_enum_list)); - for (i = 0; i < ARRAY_SIZE(drm_dithering_mode_enum_list); i++) - drm_property_add_enum(dithering_mode, i, - drm_dithering_mode_enum_list[i].type, - drm_dithering_mode_enum_list[i].name); dev->mode_config.dithering_mode_property = dithering_mode; return 0; @@ -902,20 +871,15 @@ EXPORT_SYMBOL(drm_mode_create_dithering_property); int drm_mode_create_dirty_info_property(struct drm_device *dev) { struct drm_property *dirty_info; - int i; if (dev->mode_config.dirty_info_property) return 0; dirty_info = - drm_property_create(dev, DRM_MODE_PROP_ENUM | - DRM_MODE_PROP_IMMUTABLE, + drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, "dirty", + drm_dirty_info_enum_list, ARRAY_SIZE(drm_dirty_info_enum_list)); - for (i = 0; i < ARRAY_SIZE(drm_dirty_info_enum_list); i++) - drm_property_add_enum(dirty_info, i, - drm_dirty_info_enum_list[i].type, - drm_dirty_info_enum_list[i].name); dev->mode_config.dirty_info_property = dirty_info; return 0; @@ -2629,6 +2593,34 @@ fail: } EXPORT_SYMBOL(drm_property_create); +struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags, + const char *name, + const struct drm_prop_enum_list *props, + int num_values) +{ + struct drm_property *property; + int i, ret; + + flags |= DRM_MODE_PROP_ENUM; + + property = drm_property_create(dev, flags, name, num_values); + if (!property) + return NULL; + + for (i = 0; i < num_values; i++) { + ret = drm_property_add_enum(property, i, + props[i].type, + props[i].name); + if (ret) { + drm_property_destroy(dev, property); + return NULL; + } + } + + return property; +} +EXPORT_SYMBOL(drm_property_create_enum); + int drm_property_add_enum(struct drm_property *property, int index, uint64_t value, const char *name) { diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c index be2c6fe07d1..961f75dbeae 100644 --- a/drivers/gpu/drm/i915/intel_modes.c +++ b/drivers/gpu/drm/i915/intel_modes.c @@ -83,10 +83,10 @@ int intel_ddc_get_modes(struct drm_connector *connector, return ret; } -static const char *force_audio_names[] = { - "off", - "auto", - "on", +static const struct drm_prop_enum_list force_audio_names[] = { + { -1, "off" }, + { 0, "auto" }, + { 1, "on" }, }; void @@ -95,27 +95,24 @@ intel_attach_force_audio_property(struct drm_connector *connector) struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct drm_property *prop; - int i; prop = dev_priv->force_audio_property; if (prop == NULL) { - prop = drm_property_create(dev, DRM_MODE_PROP_ENUM, + prop = drm_property_create_enum(dev, 0, "audio", + force_audio_names, ARRAY_SIZE(force_audio_names)); if (prop == NULL) return; - for (i = 0; i < ARRAY_SIZE(force_audio_names); i++) - drm_property_add_enum(prop, i, i-1, force_audio_names[i]); - dev_priv->force_audio_property = prop; } drm_connector_attach_property(connector, prop, 0); } -static const char *broadcast_rgb_names[] = { - "Full", - "Limited 16:235", +static const struct drm_prop_enum_list broadcast_rgb_names[] = { + { 0, "Full" }, + { 1, "Limited 16:235" }, }; void @@ -124,19 +121,16 @@ intel_attach_broadcast_rgb_property(struct drm_connector *connector) struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct drm_property *prop; - int i; prop = dev_priv->broadcast_rgb_property; if (prop == NULL) { - prop = drm_property_create(dev, DRM_MODE_PROP_ENUM, + prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM, "Broadcast RGB", + broadcast_rgb_names, ARRAY_SIZE(broadcast_rgb_names)); if (prop == NULL) return; - for (i = 0; i < ARRAY_SIZE(broadcast_rgb_names); i++) - drm_property_add_enum(prop, i, i, broadcast_rgb_names[i]); - dev_priv->broadcast_rgb_property = prop; } diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 795a9e3c990..cc94f3cbd5a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -155,20 +155,20 @@ static const struct drm_mode_config_funcs nouveau_mode_config_funcs = { }; -struct drm_prop_enum_list { +struct nouveau_drm_prop_enum_list { u8 gen_mask; int type; char *name; }; -static struct drm_prop_enum_list underscan[] = { +static struct nouveau_drm_prop_enum_list underscan[] = { { 6, UNDERSCAN_AUTO, "auto" }, { 6, UNDERSCAN_OFF, "off" }, { 6, UNDERSCAN_ON, "on" }, {} }; -static struct drm_prop_enum_list dither_mode[] = { +static struct nouveau_drm_prop_enum_list dither_mode[] = { { 7, DITHERING_MODE_AUTO, "auto" }, { 7, DITHERING_MODE_OFF, "off" }, { 1, DITHERING_MODE_ON, "on" }, @@ -178,7 +178,7 @@ static struct drm_prop_enum_list dither_mode[] = { {} }; -static struct drm_prop_enum_list dither_depth[] = { +static struct nouveau_drm_prop_enum_list dither_depth[] = { { 6, DITHERING_DEPTH_AUTO, "auto" }, { 6, DITHERING_DEPTH_6BPC, "6 bpc" }, { 6, DITHERING_DEPTH_8BPC, "8 bpc" }, @@ -186,7 +186,7 @@ static struct drm_prop_enum_list dither_depth[] = { }; #define PROP_ENUM(p,gen,n,list) do { \ - struct drm_prop_enum_list *l = (list); \ + struct nouveau_drm_prop_enum_list *l = (list); \ int c = 0; \ while (l->gen_mask) { \ if (l->gen_mask & (1 << (gen))) \ diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 8c49fef1ce7..54629faf284 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -1124,11 +1124,6 @@ static const struct drm_mode_config_funcs radeon_mode_funcs = { .output_poll_changed = radeon_output_poll_changed }; -struct drm_prop_enum_list { - int type; - char *name; -}; - static struct drm_prop_enum_list radeon_tmds_pll_enum_list[] = { { 0, "driver" }, { 1, "bios" }, @@ -1153,7 +1148,7 @@ static struct drm_prop_enum_list radeon_underscan_enum_list[] = static int radeon_modeset_create_props(struct radeon_device *rdev) { - int i, sz; + int sz; if (rdev->is_atom_bios) { rdev->mode_info.coherent_mode_property = @@ -1170,15 +1165,9 @@ static int radeon_modeset_create_props(struct radeon_device *rdev) if (!ASIC_IS_AVIVO(rdev)) { sz = ARRAY_SIZE(radeon_tmds_pll_enum_list); rdev->mode_info.tmds_pll_property = - drm_property_create(rdev->ddev, - DRM_MODE_PROP_ENUM, - "tmds_pll", sz); - for (i = 0; i < sz; i++) { - drm_property_add_enum(rdev->mode_info.tmds_pll_property, - i, - radeon_tmds_pll_enum_list[i].type, - radeon_tmds_pll_enum_list[i].name); - } + drm_property_create_enum(rdev->ddev, 0, + "tmds_pll", + radeon_tmds_pll_enum_list, sz); } rdev->mode_info.load_detect_property = @@ -1194,27 +1183,15 @@ static int radeon_modeset_create_props(struct radeon_device *rdev) sz = ARRAY_SIZE(radeon_tv_std_enum_list); rdev->mode_info.tv_std_property = - drm_property_create(rdev->ddev, - DRM_MODE_PROP_ENUM, - "tv standard", sz); - for (i = 0; i < sz; i++) { - drm_property_add_enum(rdev->mode_info.tv_std_property, - i, - radeon_tv_std_enum_list[i].type, - radeon_tv_std_enum_list[i].name); - } + drm_property_create_enum(rdev->ddev, 0, + "tv standard", + radeon_tv_std_enum_list, sz); sz = ARRAY_SIZE(radeon_underscan_enum_list); rdev->mode_info.underscan_property = - drm_property_create(rdev->ddev, - DRM_MODE_PROP_ENUM, - "underscan", sz); - for (i = 0; i < sz; i++) { - drm_property_add_enum(rdev->mode_info.underscan_property, - i, - radeon_underscan_enum_list[i].type, - radeon_underscan_enum_list[i].name); - } + drm_property_create_enum(rdev->ddev, 0, + "underscan", + radeon_underscan_enum_list, sz); rdev->mode_info.underscan_hborder_property = drm_property_create(rdev->ddev, diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 8d593ad95f1..3b93cdccea4 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -807,6 +807,10 @@ struct drm_mode_config { #define obj_to_blob(x) container_of(x, struct drm_property_blob, base) #define obj_to_plane(x) container_of(x, struct drm_plane, base) +struct drm_prop_enum_list { + int type; + char *name; +}; extern void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, @@ -904,6 +908,10 @@ extern int drm_connector_attach_property(struct drm_connector *connector, struct drm_property *property, uint64_t init_val); extern struct drm_property *drm_property_create(struct drm_device *dev, int flags, const char *name, int num_values); +extern struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags, + const char *name, + const struct drm_prop_enum_list *props, + int num_values); extern void drm_property_destroy(struct drm_device *dev, struct drm_property *property); extern int drm_property_add_enum(struct drm_property *property, int index, uint64_t value, const char *name); -- cgit v1.2.3-70-g09d2 From d9bc3c02e36d844c2d980e65ddda5c7699e073f8 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 6 Feb 2012 10:58:18 +0100 Subject: drm: add convenience function to create an range property Creating a range property is a common pattern, so create a convenience function for this and use it where appropriate. Signed-off-by: Sascha Hauer Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc.c | 69 +++++++++++++------------------ drivers/gpu/drm/gma500/framebuffer.c | 5 +-- drivers/gpu/drm/gma500/psb_intel_sdvo.c | 28 +++---------- drivers/gpu/drm/i2c/ch7006_drv.c | 5 +-- drivers/gpu/drm/i915/intel_sdvo.c | 30 ++++---------- drivers/gpu/drm/nouveau/nouveau_display.c | 10 +---- drivers/gpu/drm/radeon/radeon_display.c | 27 +++--------- include/drm/drm_crtc.h | 3 ++ 8 files changed, 56 insertions(+), 121 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 3fe99c456a1..6fdaf6fe94e 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -742,28 +742,16 @@ int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes, * Other, TV specific properties: margins & TV modes. */ dev->mode_config.tv_left_margin_property = - drm_property_create(dev, DRM_MODE_PROP_RANGE, - "left margin", 2); - dev->mode_config.tv_left_margin_property->values[0] = 0; - dev->mode_config.tv_left_margin_property->values[1] = 100; + drm_property_create_range(dev, 0, "left margin", 0, 100); dev->mode_config.tv_right_margin_property = - drm_property_create(dev, DRM_MODE_PROP_RANGE, - "right margin", 2); - dev->mode_config.tv_right_margin_property->values[0] = 0; - dev->mode_config.tv_right_margin_property->values[1] = 100; + drm_property_create_range(dev, 0, "right margin", 0, 100); dev->mode_config.tv_top_margin_property = - drm_property_create(dev, DRM_MODE_PROP_RANGE, - "top margin", 2); - dev->mode_config.tv_top_margin_property->values[0] = 0; - dev->mode_config.tv_top_margin_property->values[1] = 100; + drm_property_create_range(dev, 0, "top margin", 0, 100); dev->mode_config.tv_bottom_margin_property = - drm_property_create(dev, DRM_MODE_PROP_RANGE, - "bottom margin", 2); - dev->mode_config.tv_bottom_margin_property->values[0] = 0; - dev->mode_config.tv_bottom_margin_property->values[1] = 100; + drm_property_create_range(dev, 0, "bottom margin", 0, 100); dev->mode_config.tv_mode_property = drm_property_create(dev, DRM_MODE_PROP_ENUM, @@ -773,40 +761,22 @@ int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes, i, modes[i]); dev->mode_config.tv_brightness_property = - drm_property_create(dev, DRM_MODE_PROP_RANGE, - "brightness", 2); - dev->mode_config.tv_brightness_property->values[0] = 0; - dev->mode_config.tv_brightness_property->values[1] = 100; + drm_property_create_range(dev, 0, "brightness", 0, 100); dev->mode_config.tv_contrast_property = - drm_property_create(dev, DRM_MODE_PROP_RANGE, - "contrast", 2); - dev->mode_config.tv_contrast_property->values[0] = 0; - dev->mode_config.tv_contrast_property->values[1] = 100; + drm_property_create_range(dev, 0, "contrast", 0, 100); dev->mode_config.tv_flicker_reduction_property = - drm_property_create(dev, DRM_MODE_PROP_RANGE, - "flicker reduction", 2); - dev->mode_config.tv_flicker_reduction_property->values[0] = 0; - dev->mode_config.tv_flicker_reduction_property->values[1] = 100; + drm_property_create_range(dev, 0, "flicker reduction", 0, 100); dev->mode_config.tv_overscan_property = - drm_property_create(dev, DRM_MODE_PROP_RANGE, - "overscan", 2); - dev->mode_config.tv_overscan_property->values[0] = 0; - dev->mode_config.tv_overscan_property->values[1] = 100; + drm_property_create_range(dev, 0, "overscan", 0, 100); dev->mode_config.tv_saturation_property = - drm_property_create(dev, DRM_MODE_PROP_RANGE, - "saturation", 2); - dev->mode_config.tv_saturation_property->values[0] = 0; - dev->mode_config.tv_saturation_property->values[1] = 100; + drm_property_create_range(dev, 0, "saturation", 0, 100); dev->mode_config.tv_hue_property = - drm_property_create(dev, DRM_MODE_PROP_RANGE, - "hue", 2); - dev->mode_config.tv_hue_property->values[0] = 0; - dev->mode_config.tv_hue_property->values[1] = 100; + drm_property_create_range(dev, 0, "hue", 0, 100); return 0; } @@ -2621,6 +2591,25 @@ struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags, } EXPORT_SYMBOL(drm_property_create_enum); +struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, + const char *name, + uint64_t min, uint64_t max) +{ + struct drm_property *property; + + flags |= DRM_MODE_PROP_RANGE; + + property = drm_property_create(dev, flags, name, 2); + if (!property) + return NULL; + + property->values[0] = min; + property->values[1] = max; + + return property; +} +EXPORT_SYMBOL(drm_property_create_range); + int drm_property_add_enum(struct drm_property *property, int index, uint64_t value, const char *name) { diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index 830dfdd6bf1..78733b5fd3f 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c @@ -725,10 +725,7 @@ static int psb_create_backlight_property(struct drm_device *dev) if (dev_priv->backlight_property) return 0; - backlight = drm_property_create(dev, DRM_MODE_PROP_RANGE, - "backlight", 2); - backlight->values[0] = 0; - backlight->values[1] = 100; + backlight = drm_property_create_range(dev, 0, "backlight", 0, 100); dev_priv->backlight_property = backlight; diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c index 88b42971c0f..41b55d7a7bf 100644 --- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c +++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c @@ -2312,10 +2312,8 @@ static bool psb_intel_sdvo_tv_create_property(struct psb_intel_sdvo *psb_intel_s psb_intel_sdvo_connector->max_##name = data_value[0]; \ psb_intel_sdvo_connector->cur_##name = response; \ psb_intel_sdvo_connector->name = \ - drm_property_create(dev, DRM_MODE_PROP_RANGE, #name, 2); \ + drm_property_create_range(dev, 0, #name, 0, data_value[0]); \ if (!psb_intel_sdvo_connector->name) return false; \ - psb_intel_sdvo_connector->name->values[0] = 0; \ - psb_intel_sdvo_connector->name->values[1] = data_value[0]; \ drm_connector_attach_property(connector, \ psb_intel_sdvo_connector->name, \ psb_intel_sdvo_connector->cur_##name); \ @@ -2349,25 +2347,19 @@ psb_intel_sdvo_create_enhance_property_tv(struct psb_intel_sdvo *psb_intel_sdvo, psb_intel_sdvo_connector->left_margin = data_value[0] - response; psb_intel_sdvo_connector->right_margin = psb_intel_sdvo_connector->left_margin; psb_intel_sdvo_connector->left = - drm_property_create(dev, DRM_MODE_PROP_RANGE, - "left_margin", 2); + drm_property_create_range(dev, 0, "left_margin", 0, data_value[0]); if (!psb_intel_sdvo_connector->left) return false; - psb_intel_sdvo_connector->left->values[0] = 0; - psb_intel_sdvo_connector->left->values[1] = data_value[0]; drm_connector_attach_property(connector, psb_intel_sdvo_connector->left, psb_intel_sdvo_connector->left_margin); psb_intel_sdvo_connector->right = - drm_property_create(dev, DRM_MODE_PROP_RANGE, - "right_margin", 2); + drm_property_create_range(dev, 0, "right_margin", 0, data_value[0]); if (!psb_intel_sdvo_connector->right) return false; - psb_intel_sdvo_connector->right->values[0] = 0; - psb_intel_sdvo_connector->right->values[1] = data_value[0]; drm_connector_attach_property(connector, psb_intel_sdvo_connector->right, psb_intel_sdvo_connector->right_margin); @@ -2391,25 +2383,19 @@ psb_intel_sdvo_create_enhance_property_tv(struct psb_intel_sdvo *psb_intel_sdvo, psb_intel_sdvo_connector->top_margin = data_value[0] - response; psb_intel_sdvo_connector->bottom_margin = psb_intel_sdvo_connector->top_margin; psb_intel_sdvo_connector->top = - drm_property_create(dev, DRM_MODE_PROP_RANGE, - "top_margin", 2); + drm_property_create_range(dev, 0, "top_margin", 0, data_value[0]); if (!psb_intel_sdvo_connector->top) return false; - psb_intel_sdvo_connector->top->values[0] = 0; - psb_intel_sdvo_connector->top->values[1] = data_value[0]; drm_connector_attach_property(connector, psb_intel_sdvo_connector->top, psb_intel_sdvo_connector->top_margin); psb_intel_sdvo_connector->bottom = - drm_property_create(dev, DRM_MODE_PROP_RANGE, - "bottom_margin", 2); + drm_property_create_range(dev, 0, "bottom_margin", 0, data_value[0]); if (!psb_intel_sdvo_connector->bottom) return false; - psb_intel_sdvo_connector->bottom->values[0] = 0; - psb_intel_sdvo_connector->bottom->values[1] = data_value[0]; drm_connector_attach_property(connector, psb_intel_sdvo_connector->bottom, psb_intel_sdvo_connector->bottom_margin); @@ -2438,12 +2424,10 @@ psb_intel_sdvo_create_enhance_property_tv(struct psb_intel_sdvo *psb_intel_sdvo, psb_intel_sdvo_connector->max_dot_crawl = 1; psb_intel_sdvo_connector->cur_dot_crawl = response & 0x1; psb_intel_sdvo_connector->dot_crawl = - drm_property_create(dev, DRM_MODE_PROP_RANGE, "dot_crawl", 2); + drm_property_create_range(dev, 0, "dot_crawl", 0, 1); if (!psb_intel_sdvo_connector->dot_crawl) return false; - psb_intel_sdvo_connector->dot_crawl->values[0] = 0; - psb_intel_sdvo_connector->dot_crawl->values[1] = 1; drm_connector_attach_property(connector, psb_intel_sdvo_connector->dot_crawl, psb_intel_sdvo_connector->cur_dot_crawl); diff --git a/drivers/gpu/drm/i2c/ch7006_drv.c b/drivers/gpu/drm/i2c/ch7006_drv.c index 07d55df6623..d3f2e878501 100644 --- a/drivers/gpu/drm/i2c/ch7006_drv.c +++ b/drivers/gpu/drm/i2c/ch7006_drv.c @@ -252,10 +252,7 @@ static int ch7006_encoder_create_resources(struct drm_encoder *encoder, drm_mode_create_tv_properties(dev, NUM_TV_NORMS, ch7006_tv_norm_names); - priv->scale_property = drm_property_create(dev, DRM_MODE_PROP_RANGE, - "scale", 2); - priv->scale_property->values[0] = 0; - priv->scale_property->values[1] = 2; + priv->scale_property = drm_property_create_range(dev, 0, "scale", 0, 2); drm_connector_attach_property(connector, conf->tv_select_subconnector_property, priv->select_subconnector); diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index e334ec33a47..80acc3f241e 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -2277,10 +2277,8 @@ static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, intel_sdvo_connector->max_##name = data_value[0]; \ intel_sdvo_connector->cur_##name = response; \ intel_sdvo_connector->name = \ - drm_property_create(dev, DRM_MODE_PROP_RANGE, #name, 2); \ + drm_property_create_range(dev, 0, #name, 0, data_value[0]); \ if (!intel_sdvo_connector->name) return false; \ - intel_sdvo_connector->name->values[0] = 0; \ - intel_sdvo_connector->name->values[1] = data_value[0]; \ drm_connector_attach_property(connector, \ intel_sdvo_connector->name, \ intel_sdvo_connector->cur_##name); \ @@ -2314,25 +2312,19 @@ intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo, intel_sdvo_connector->left_margin = data_value[0] - response; intel_sdvo_connector->right_margin = intel_sdvo_connector->left_margin; intel_sdvo_connector->left = - drm_property_create(dev, DRM_MODE_PROP_RANGE, - "left_margin", 2); + drm_property_create_range(dev, 0, "left_margin", 0, data_value[0]); if (!intel_sdvo_connector->left) return false; - intel_sdvo_connector->left->values[0] = 0; - intel_sdvo_connector->left->values[1] = data_value[0]; drm_connector_attach_property(connector, intel_sdvo_connector->left, intel_sdvo_connector->left_margin); intel_sdvo_connector->right = - drm_property_create(dev, DRM_MODE_PROP_RANGE, - "right_margin", 2); + drm_property_create_range(dev, 0, "right_margin", 0, data_value[0]); if (!intel_sdvo_connector->right) return false; - intel_sdvo_connector->right->values[0] = 0; - intel_sdvo_connector->right->values[1] = data_value[0]; drm_connector_attach_property(connector, intel_sdvo_connector->right, intel_sdvo_connector->right_margin); @@ -2356,25 +2348,21 @@ intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo, intel_sdvo_connector->top_margin = data_value[0] - response; intel_sdvo_connector->bottom_margin = intel_sdvo_connector->top_margin; intel_sdvo_connector->top = - drm_property_create(dev, DRM_MODE_PROP_RANGE, - "top_margin", 2); + drm_property_create_range(dev, 0, + "top_margin", 0, data_value[0]); if (!intel_sdvo_connector->top) return false; - intel_sdvo_connector->top->values[0] = 0; - intel_sdvo_connector->top->values[1] = data_value[0]; drm_connector_attach_property(connector, intel_sdvo_connector->top, intel_sdvo_connector->top_margin); intel_sdvo_connector->bottom = - drm_property_create(dev, DRM_MODE_PROP_RANGE, - "bottom_margin", 2); + drm_property_create_range(dev, 0, + "bottom_margin", 0, data_value[0]); if (!intel_sdvo_connector->bottom) return false; - intel_sdvo_connector->bottom->values[0] = 0; - intel_sdvo_connector->bottom->values[1] = data_value[0]; drm_connector_attach_property(connector, intel_sdvo_connector->bottom, intel_sdvo_connector->bottom_margin); @@ -2403,12 +2391,10 @@ intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo, intel_sdvo_connector->max_dot_crawl = 1; intel_sdvo_connector->cur_dot_crawl = response & 0x1; intel_sdvo_connector->dot_crawl = - drm_property_create(dev, DRM_MODE_PROP_RANGE, "dot_crawl", 2); + drm_property_create_range(dev, 0, "dot_crawl", 0, 1); if (!intel_sdvo_connector->dot_crawl) return false; - intel_sdvo_connector->dot_crawl->values[0] = 0; - intel_sdvo_connector->dot_crawl->values[1] = 1; drm_connector_attach_property(connector, intel_sdvo_connector->dot_crawl, intel_sdvo_connector->cur_dot_crawl); diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index cc94f3cbd5a..5565e5056ba 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -281,16 +281,10 @@ nouveau_display_create(struct drm_device *dev) PROP_ENUM(disp->underscan_property, gen, "underscan", underscan); disp->underscan_hborder_property = - drm_property_create(dev, DRM_MODE_PROP_RANGE, - "underscan hborder", 2); - disp->underscan_hborder_property->values[0] = 0; - disp->underscan_hborder_property->values[1] = 128; + drm_property_create_range(dev, 0, "underscan hborder", 0, 128); disp->underscan_vborder_property = - drm_property_create(dev, DRM_MODE_PROP_RANGE, - "underscan vborder", 2); - disp->underscan_vborder_property->values[0] = 0; - disp->underscan_vborder_property->values[1] = 128; + drm_property_create_range(dev, 0, "underscan vborder", 0, 128); dev->mode_config.funcs = (void *)&nouveau_mode_config_funcs; dev->mode_config.fb_base = pci_resource_start(dev->pdev, 1); diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 54629faf284..5515f1054b2 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -1152,14 +1152,9 @@ static int radeon_modeset_create_props(struct radeon_device *rdev) if (rdev->is_atom_bios) { rdev->mode_info.coherent_mode_property = - drm_property_create(rdev->ddev, - DRM_MODE_PROP_RANGE, - "coherent", 2); + drm_property_create_range(rdev->ddev, 0 , "coherent", 0, 1); if (!rdev->mode_info.coherent_mode_property) return -ENOMEM; - - rdev->mode_info.coherent_mode_property->values[0] = 0; - rdev->mode_info.coherent_mode_property->values[1] = 1; } if (!ASIC_IS_AVIVO(rdev)) { @@ -1171,13 +1166,9 @@ static int radeon_modeset_create_props(struct radeon_device *rdev) } rdev->mode_info.load_detect_property = - drm_property_create(rdev->ddev, - DRM_MODE_PROP_RANGE, - "load detection", 2); + drm_property_create_range(rdev->ddev, 0, "load detection", 0, 1); if (!rdev->mode_info.load_detect_property) return -ENOMEM; - rdev->mode_info.load_detect_property->values[0] = 0; - rdev->mode_info.load_detect_property->values[1] = 1; drm_mode_create_scaling_mode_property(rdev->ddev); @@ -1194,22 +1185,16 @@ static int radeon_modeset_create_props(struct radeon_device *rdev) radeon_underscan_enum_list, sz); rdev->mode_info.underscan_hborder_property = - drm_property_create(rdev->ddev, - DRM_MODE_PROP_RANGE, - "underscan hborder", 2); + drm_property_create_range(rdev->ddev, 0, + "underscan hborder", 0, 128); if (!rdev->mode_info.underscan_hborder_property) return -ENOMEM; - rdev->mode_info.underscan_hborder_property->values[0] = 0; - rdev->mode_info.underscan_hborder_property->values[1] = 128; rdev->mode_info.underscan_vborder_property = - drm_property_create(rdev->ddev, - DRM_MODE_PROP_RANGE, - "underscan vborder", 2); + drm_property_create_range(rdev->ddev, 0, + "underscan vborder", 0, 128); if (!rdev->mode_info.underscan_vborder_property) return -ENOMEM; - rdev->mode_info.underscan_vborder_property->values[0] = 0; - rdev->mode_info.underscan_vborder_property->values[1] = 128; return 0; } diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 3b93cdccea4..82353145479 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -912,6 +912,9 @@ extern struct drm_property *drm_property_create_enum(struct drm_device *dev, int const char *name, const struct drm_prop_enum_list *props, int num_values); +struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, + const char *name, + uint64_t min, uint64_t max); extern void drm_property_destroy(struct drm_device *dev, struct drm_property *property); extern int drm_property_add_enum(struct drm_property *property, int index, uint64_t value, const char *name); -- cgit v1.2.3-70-g09d2 From fb2a99e15ff0d342de4ba58c84a791224a96a01a Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 6 Feb 2012 10:58:19 +0100 Subject: drm: do not set fb_info->pixmap fields The drm drivers set the fb_info->pixmap fields without setting fb_info->pixmap.addr. If this is not set the fb core will overwrite these all fb_info->pixmap fields anyway, so there is not much point in setting them in the first place. [airlied: dropped nvidiafb piece - not mine] Signed-off-by: Sascha Hauer Signed-off-by: Dave Airlie --- drivers/gpu/drm/gma500/framebuffer.c | 6 +----- drivers/gpu/drm/i915/intel_fb.c | 6 +----- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 6 +----- drivers/gpu/drm/radeon/radeon_fb.c | 6 +----- drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 14 +------------- 5 files changed, 5 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index 78733b5fd3f..c1c4dc174fa 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c @@ -507,11 +507,7 @@ static int psbfb_create(struct psb_fbdev *fbdev, info->fix.mmio_start = pci_resource_start(dev->pdev, 0); info->fix.mmio_len = pci_resource_len(dev->pdev, 0); - info->pixmap.size = 64 * 1024; - info->pixmap.buf_align = 8; - info->pixmap.access_align = 32; - info->pixmap.flags = FB_PIXMAP_SYSTEM; - info->pixmap.scan_align = 1; + /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ dev_info(dev->dev, "allocated %dx%d fb\n", psbfb->base.width, psbfb->base.height); diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 571375a3eef..2d876697838 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c @@ -152,11 +152,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev, drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth); drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height); - info->pixmap.size = 64*1024; - info->pixmap.buf_align = 8; - info->pixmap.access_align = 32; - info->pixmap.flags = FB_PIXMAP_SYSTEM; - info->pixmap.scan_align = 1; + /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x, bo %p\n", fb->width, fb->height, diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 9892218d745..8113e9201ed 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -381,11 +381,7 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev, goto out_unref; } - info->pixmap.size = 64*1024; - info->pixmap.buf_align = 8; - info->pixmap.access_align = 32; - info->pixmap.flags = FB_PIXMAP_SYSTEM; - info->pixmap.scan_align = 1; + /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ mutex_unlock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index cf2bf35b56b..a5692d5f415 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c @@ -254,11 +254,7 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev, info->apertures->ranges[0].base = rdev->ddev->mode_config.fb_base; info->apertures->ranges[0].size = rdev->mc.aper_size; - info->pixmap.size = 64*1024; - info->pixmap.buf_align = 8; - info->pixmap.access_align = 32; - info->pixmap.flags = FB_PIXMAP_SYSTEM; - info->pixmap.scan_align = 1; + /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ if (info->screen_base == NULL) { ret = -ENOSPC; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index 34e51a1695b..67f1d54b79b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c @@ -515,19 +515,7 @@ int vmw_fb_init(struct vmw_private *vmw_priv) info->var.xres = initial_width; info->var.yres = initial_height; -#if 0 - info->pixmap.size = 64*1024; - info->pixmap.buf_align = 8; - info->pixmap.access_align = 32; - info->pixmap.flags = FB_PIXMAP_SYSTEM; - info->pixmap.scan_align = 1; -#else - info->pixmap.size = 0; - info->pixmap.buf_align = 8; - info->pixmap.access_align = 32; - info->pixmap.flags = FB_PIXMAP_SYSTEM; - info->pixmap.scan_align = 1; -#endif + /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ info->apertures = alloc_apertures(1); if (!info->apertures) { -- cgit v1.2.3-70-g09d2 From 7e3b8737e719c4de7dd79b096b80ece444b2f0ba Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 1 Feb 2012 22:26:45 +0100 Subject: drm/i915: dump even more into the error_state Chris Wilson and me have again stared at funny error states and it's been pretty clear from the start that something was seriously amiss. The seqnos last seen by the cpu were a few hundred behind those that the gpu could have possibly emitted last before it died ... Chris now tracked it down (hopefully, definit verdict's still out), but in hindsight we'd have found the bug by simply dumping the cpu side tracking of the ring head and tail registers. Fix this and prevent an identical time-waster in the future. Because the hangs always involved semaphores in one way or another, we've tried to dump the mbox registers, but couldn't find any inconsistencies. Still, dump them too. Reviewed-and-wanted-by: Chris Wilson Reviewed-by: Eugeni Dodonov Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 6 ++++++ drivers/gpu/drm/i915/i915_drv.h | 4 ++++ drivers/gpu/drm/i915/i915_irq.c | 7 +++++++ 3 files changed, 17 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 4ebca6d0494..f3fe2f872d5 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -721,8 +721,14 @@ static void i915_ring_error_state(struct seq_file *m, if (INTEL_INFO(dev)->gen >= 6) { seq_printf(m, " FADDR: 0x%08x\n", error->faddr[ring]); seq_printf(m, " FAULT_REG: 0x%08x\n", error->fault_reg[ring]); + seq_printf(m, " SYNC_0: 0x%08x\n", + error->semaphore_mboxes[ring][0]); + seq_printf(m, " SYNC_1: 0x%08x\n", + error->semaphore_mboxes[ring][1]); } seq_printf(m, " seqno: 0x%08x\n", error->seqno[ring]); + seq_printf(m, " ring->head: 0x%08x\n", error->cpu_ring_head[ring]); + seq_printf(m, " ring->tail: 0x%08x\n", error->cpu_ring_tail[ring]); } static int i915_error_state(struct seq_file *m, void *unused) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 08454192c4c..28740bc0200 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -159,6 +159,10 @@ struct drm_i915_error_state { u32 ipehr[I915_NUM_RINGS]; u32 instdone[I915_NUM_RINGS]; u32 acthd[I915_NUM_RINGS]; + u32 semaphore_mboxes[I915_NUM_RINGS][I915_NUM_RINGS - 1]; + /* our own tracking of ring head and tail */ + u32 cpu_ring_head[I915_NUM_RINGS]; + u32 cpu_ring_tail[I915_NUM_RINGS]; u32 error; /* gen6+ */ u32 instpm[I915_NUM_RINGS]; u32 instps[I915_NUM_RINGS]; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 8ea1ca4158a..cde1ce94563 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -903,6 +903,10 @@ static void i915_record_ring_state(struct drm_device *dev, if (INTEL_INFO(dev)->gen >= 6) { error->faddr[ring->id] = I915_READ(RING_DMA_FADD(ring->mmio_base)); error->fault_reg[ring->id] = I915_READ(RING_FAULT_REG(ring)); + error->semaphore_mboxes[ring->id][0] + = I915_READ(RING_SYNC_0(ring->mmio_base)); + error->semaphore_mboxes[ring->id][1] + = I915_READ(RING_SYNC_1(ring->mmio_base)); } if (INTEL_INFO(dev)->gen >= 4) { @@ -925,6 +929,9 @@ static void i915_record_ring_state(struct drm_device *dev, error->acthd[ring->id] = intel_ring_get_active_head(ring); error->head[ring->id] = I915_READ_HEAD(ring); error->tail[ring->id] = I915_READ_TAIL(ring); + + error->cpu_ring_head[ring->id] = ring->head; + error->cpu_ring_tail[ring->id] = ring->tail; } /** -- cgit v1.2.3-70-g09d2 From 43f674a322aa8a3404df5785f84dc1351a5d84b6 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 9 Feb 2012 13:08:39 +0000 Subject: regulator: Don't add the function name to pr_fmt Liam pointed out via IM that since we now use the pure function name for all regulator logging a lot of the messages such as those logging the constraints are getting a bit noisy due to the implementation detail that is the function name: print_constraints: VDDARM: 1000 <--> 1300 mV at 1300 mV at 0 mA In discussion it seemed like the best thing was to just drop the pr_fmt and clarify individual log messages where there is an issue otherwise we get into silly things like renaming the functions to suit the logging. This is mostly an issue as we have a moderate amount of non-error logging in the boot sequence to aid debug if something goes wrong since regulator misconfiguration can kill the system pretty quickly. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- drivers/regulator/core.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index daba2f60f7d..e3271daa3ab 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -13,8 +13,6 @@ * */ -#define pr_fmt(fmt) "%s: " fmt, __func__ - #include #include #include -- cgit v1.2.3-70-g09d2 From 4a682922817fde4d82fed4303dc902c29d7b2e4e Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 9 Feb 2012 13:26:13 +0000 Subject: regulator: Complain if a voltage range is specified but can't be used It doesn't make much sense to specify a range of voltages consumers can use if they haven't been given permission to change the voltage. Log if this happens, probably the user forgot to specify CHANGE_VOLTAGE. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- drivers/regulator/core.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index e3271daa3ab..9a143aebb84 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -805,6 +805,11 @@ static void print_constraints(struct regulator_dev *rdev) count += sprintf(buf + count, "standby"); rdev_info(rdev, "%s\n", buf); + + if ((constraints->min_uV != constraints->max_uV) && + !(constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) + rdev_warn(rdev, + "Voltage range but no REGULATOR_CHANGE_VOLTAGE\n"); } static int machine_constraints_voltage(struct regulator_dev *rdev, -- cgit v1.2.3-70-g09d2 From 2640335438ca4d7b139e114dae5f0d80e740e106 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 2 Feb 2012 16:56:50 -0800 Subject: drivers: hv: kvp: Cleanup the kernel/user protocol Now, cleanup the user/kernel KVP protocol by using the same structure definition that is used for host/guest KVP protocol. This simplifies the code. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv_kvp.c | 41 +++++++++++++++++++++++++---------------- include/linux/hyperv.h | 30 +++++------------------------- tools/hv/hv_kvp_daemon.c | 30 +++++++++++++++--------------- 3 files changed, 45 insertions(+), 56 deletions(-) (limited to 'drivers') diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c index 4a6971e1353..0ef4c1f6ca5 100644 --- a/drivers/hv/hv_kvp.c +++ b/drivers/hv/hv_kvp.c @@ -71,15 +71,20 @@ kvp_register(void) { struct cn_msg *msg; + struct hv_kvp_msg *kvp_msg; + char *version; - msg = kzalloc(sizeof(*msg) + strlen(HV_DRV_VERSION) + 1 , GFP_ATOMIC); + msg = kzalloc(sizeof(*msg) + sizeof(struct hv_kvp_msg), GFP_ATOMIC); if (msg) { + kvp_msg = (struct hv_kvp_msg *)msg->data; + version = kvp_msg->body.kvp_version; msg->id.idx = CN_KVP_IDX; msg->id.val = CN_KVP_VAL; - msg->seq = KVP_REGISTER; - strcpy(msg->data, HV_DRV_VERSION); - msg->len = strlen(HV_DRV_VERSION) + 1; + + kvp_msg->kvp_hdr.operation = KVP_OP_REGISTER; + strcpy(version, HV_DRV_VERSION); + msg->len = sizeof(struct hv_kvp_msg); cn_netlink_send(msg, 0, GFP_ATOMIC); kfree(msg); } @@ -101,23 +106,24 @@ kvp_work_func(struct work_struct *dummy) static void kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) { - struct hv_ku_msg *message; + struct hv_kvp_msg *message; + struct hv_kvp_msg_enumerate *data; - message = (struct hv_ku_msg *)msg->data; - if (msg->seq == KVP_REGISTER) { + message = (struct hv_kvp_msg *)msg->data; + if (message->kvp_hdr.operation == KVP_OP_REGISTER) { pr_info("KVP: user-mode registering done.\n"); kvp_register(); } - if (msg->seq == KVP_USER_SET) { + if (message->kvp_hdr.operation == KVP_OP_ENUMERATE) { + data = &message->body.kvp_enum_data; /* * Complete the transaction by forwarding the key value * to the host. But first, cancel the timeout. */ if (cancel_delayed_work_sync(&kvp_work)) - kvp_respond_to_host(message->kvp_key, - message->kvp_value, - !strlen(message->kvp_key)); + kvp_respond_to_host(data->data.key, data->data.value, + !strlen(data->data.key)); } } @@ -125,6 +131,7 @@ static void kvp_send_key(struct work_struct *dummy) { struct cn_msg *msg; + struct hv_kvp_msg *message; int index = kvp_transaction.index; msg = kzalloc(sizeof(*msg) + sizeof(struct hv_kvp_msg) , GFP_ATOMIC); @@ -132,9 +139,11 @@ kvp_send_key(struct work_struct *dummy) if (msg) { msg->id.idx = CN_KVP_IDX; msg->id.val = CN_KVP_VAL; - msg->seq = KVP_KERNEL_GET; - ((struct hv_ku_msg *)msg->data)->kvp_index = index; - msg->len = sizeof(struct hv_ku_msg); + + message = (struct hv_kvp_msg *)msg->data; + message->kvp_hdr.operation = KVP_OP_ENUMERATE; + message->body.kvp_enum_data.index = index; + msg->len = sizeof(struct hv_kvp_msg); cn_netlink_send(msg, 0, GFP_ATOMIC); kfree(msg); } @@ -191,7 +200,7 @@ kvp_respond_to_host(char *key, char *value, int error) kvp_msg = (struct hv_kvp_msg *) &recv_buffer[sizeof(struct vmbuspipe_hdr) + sizeof(struct icmsg_hdr)]; - kvp_data = &kvp_msg->kvp_data; + kvp_data = &kvp_msg->body.kvp_enum_data; key_name = key; /* @@ -266,7 +275,7 @@ void hv_kvp_onchannelcallback(void *context) sizeof(struct vmbuspipe_hdr) + sizeof(struct icmsg_hdr)]; - kvp_data = &kvp_msg->kvp_data; + kvp_data = &kvp_msg->body.kvp_enum_data; /* * We only support the "get" operation on diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index b822978ecbc..75aee6720c1 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -113,30 +113,6 @@ * (not supported), a NULL key string is returned. */ -/* - * - * The following definitions are shared with the user-mode component; do not - * change any of this without making the corresponding changes in - * the KVP user-mode component. - */ - -enum hv_ku_op { - KVP_REGISTER = 0, /* Register the user mode component */ - KVP_KERNEL_GET, /* Kernel is requesting the value */ - KVP_KERNEL_SET, /* Kernel is providing the value */ - KVP_USER_GET, /* User is requesting the value */ - KVP_USER_SET /* User is providing the value */ -}; - -struct hv_ku_msg { - __u32 kvp_index; /* Key index */ - __u8 kvp_key[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; /* Key name */ - __u8 kvp_value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; /* Key value */ -}; - - - - /* * Registry value types. @@ -149,6 +125,7 @@ enum hv_kvp_exchg_op { KVP_OP_SET, KVP_OP_DELETE, KVP_OP_ENUMERATE, + KVP_OP_REGISTER, KVP_OP_COUNT /* Number of operations, must be last. */ }; @@ -182,7 +159,10 @@ struct hv_kvp_msg_enumerate { struct hv_kvp_msg { struct hv_kvp_hdr kvp_hdr; - struct hv_kvp_msg_enumerate kvp_data; + union { + struct hv_kvp_msg_enumerate kvp_enum_data; + char kvp_version[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; + } body; } __attribute__((packed)); #ifdef __KERNEL__ diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c index b75523cde2c..4ebf7038058 100644 --- a/tools/hv/hv_kvp_daemon.c +++ b/tools/hv/hv_kvp_daemon.c @@ -302,7 +302,7 @@ int main(void) struct pollfd pfd; struct nlmsghdr *incoming_msg; struct cn_msg *incoming_cn_msg; - struct hv_ku_msg *hv_msg; + struct hv_kvp_msg *hv_msg; char *p; char *key_value; char *key_name; @@ -340,9 +340,11 @@ int main(void) message = (struct cn_msg *)kvp_send_buffer; message->id.idx = CN_KVP_IDX; message->id.val = CN_KVP_VAL; - message->seq = KVP_REGISTER; + + hv_msg = (struct hv_kvp_msg *)message->data; + hv_msg->kvp_hdr.operation = KVP_OP_REGISTER; message->ack = 0; - message->len = 0; + message->len = sizeof(struct hv_kvp_msg); len = netlink_send(fd, message); if (len < 0) { @@ -368,14 +370,15 @@ int main(void) incoming_msg = (struct nlmsghdr *)kvp_recv_buffer; incoming_cn_msg = (struct cn_msg *)NLMSG_DATA(incoming_msg); + hv_msg = (struct hv_kvp_msg *)incoming_cn_msg->data; - switch (incoming_cn_msg->seq) { - case KVP_REGISTER: + switch (hv_msg->kvp_hdr.operation) { + case KVP_OP_REGISTER: /* * Driver is registering with us; stash away the version * information. */ - p = (char *)incoming_cn_msg->data; + p = (char *)hv_msg->body.kvp_version; lic_version = malloc(strlen(p) + 1); if (lic_version) { strcpy(lic_version, p); @@ -386,17 +389,15 @@ int main(void) } continue; - case KVP_KERNEL_GET: - break; default: - continue; + break; } - hv_msg = (struct hv_ku_msg *)incoming_cn_msg->data; - key_name = (char *)hv_msg->kvp_key; - key_value = (char *)hv_msg->kvp_value; + hv_msg = (struct hv_kvp_msg *)incoming_cn_msg->data; + key_name = (char *)hv_msg->body.kvp_enum_data.data.key; + key_value = (char *)hv_msg->body.kvp_enum_data.data.value; - switch (hv_msg->kvp_index) { + switch (hv_msg->body.kvp_enum_data.index) { case FullyQualifiedDomainName: kvp_get_domain_name(key_value, HV_KVP_EXCHANGE_MAX_VALUE_SIZE); @@ -456,9 +457,8 @@ int main(void) incoming_cn_msg->id.idx = CN_KVP_IDX; incoming_cn_msg->id.val = CN_KVP_VAL; - incoming_cn_msg->seq = KVP_USER_SET; incoming_cn_msg->ack = 0; - incoming_cn_msg->len = sizeof(struct hv_ku_msg); + incoming_cn_msg->len = sizeof(struct hv_kvp_msg); len = netlink_send(fd, incoming_cn_msg); if (len < 0) { -- cgit v1.2.3-70-g09d2 From 14c1bf8a8920f36f6e0603a2ff920b48eec14387 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 2 Feb 2012 16:56:51 -0800 Subject: drivers: hv: Increase the number of VCPUs supported in the guest The current code arbirarily limited the number of CPUs the guest could have. Change that so that we can support the maximum number of CPUs the guest can support. While we use NR_CPUS to size the per-cpu state all we are allocating based on NR_CPUS are the pointers to per-cpu state that will be allocatted in the context of the initializing CPU. This patch triggers a checkpatch warning for the usage of NR_CPU and since all we are allocating a couple of pointers per CPU, it should be ok. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv.c | 4 ++-- drivers/hv/hyperv_vmbus.h | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index 12aa97f31f9..15956bd48b4 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c @@ -155,9 +155,9 @@ int hv_init(void) union hv_x64_msr_hypercall_contents hypercall_msr; void *virtaddr = NULL; - memset(hv_context.synic_event_page, 0, sizeof(void *) * MAX_NUM_CPUS); + memset(hv_context.synic_event_page, 0, sizeof(void *) * NR_CPUS); memset(hv_context.synic_message_page, 0, - sizeof(void *) * MAX_NUM_CPUS); + sizeof(void *) * NR_CPUS); if (!query_hypervisor_presence()) goto cleanup; diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h index 6d7d286d544..699f0d8e59e 100644 --- a/drivers/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h @@ -457,7 +457,6 @@ static const uuid_le VMBUS_SERVICE_ID = { }, }; -#define MAX_NUM_CPUS 32 struct hv_input_signal_event_buffer { @@ -483,8 +482,8 @@ struct hv_context { /* 8-bytes aligned of the buffer above */ struct hv_input_signal_event *signal_event_param; - void *synic_message_page[MAX_NUM_CPUS]; - void *synic_event_page[MAX_NUM_CPUS]; + void *synic_message_page[NR_CPUS]; + void *synic_event_page[NR_CPUS]; }; extern struct hv_context hv_context; -- cgit v1.2.3-70-g09d2 From e250b34e57888ebe829a0b89cfa8ad303ad5ae74 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 4 Feb 2012 16:33:55 +0000 Subject: w1: Use linux/gpio.h rather than asm/gpio.h Direct inclusion of the asm header has long been deprecated by the introduction of gpiolib. Signed-off-by: Mark Brown Acked-by: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- drivers/w1/masters/w1-gpio.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c index fcbe742188a..df600d14974 100644 --- a/drivers/w1/masters/w1-gpio.c +++ b/drivers/w1/masters/w1-gpio.c @@ -13,12 +13,11 @@ #include #include #include +#include #include "../w1.h" #include "../w1_int.h" -#include - static void w1_gpio_write_bit_dir(void *data, u8 bit) { struct w1_gpio_platform_data *pdata = data; -- cgit v1.2.3-70-g09d2 From 956563362be8ac7ce084b00825168be1adfb29ee Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 18 Nov 2011 10:14:24 -0800 Subject: DWC3: use module_pci_driver This cuts down on the boilerplate code. Cc: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman Acked-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/dwc3-pci.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 64e1f7c67b0..c68e4270457 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -171,14 +171,4 @@ MODULE_AUTHOR("Felipe Balbi "); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("DesignWare USB3 PCI Glue Layer"); -static int __devinit dwc3_pci_init(void) -{ - return pci_register_driver(&dwc3_pci_driver); -} -module_init(dwc3_pci_init); - -static void __exit dwc3_pci_exit(void) -{ - pci_unregister_driver(&dwc3_pci_driver); -} -module_exit(dwc3_pci_exit); +module_pci_driver(dwc3_pci_driver); -- cgit v1.2.3-70-g09d2 From 0846e7e9856c0928223447d9349a877202a63f24 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Fri, 3 Feb 2012 17:11:54 -0500 Subject: usb: Add support for indicating whether a port is removable Userspace may want to make policy decisions based on whether or not a given USB device is removable. Add a per-device member and support for exposing it in sysfs. Information sources to populate it will be added later. Signed-off-by: Matthew Garrett Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/testing/sysfs-bus-usb | 11 +++++++++++ drivers/usb/core/sysfs.c | 23 +++++++++++++++++++++++ include/linux/usb.h | 8 ++++++++ 3 files changed, 42 insertions(+) (limited to 'drivers') diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb index b4f548792e3..7c22a532fdf 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb +++ b/Documentation/ABI/testing/sysfs-bus-usb @@ -182,3 +182,14 @@ Description: USB2 hardware LPM is enabled for the device. Developer can write y/Y/1 or n/N/0 to the file to enable/disable the feature. + +What: /sys/bus/usb/devices/.../removable +Date: February 2012 +Contact: Matthew Garrett +Description: + Some information about whether a given USB device is + physically fixed to the platform can be inferred from a + combination of hub decriptor bits and platform-specific data + such as ACPI. This file will read either "removable" or + "fixed" if the information is available, and "unknown" + otherwise. \ No newline at end of file diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 9e491ca2e5c..566d9f94f73 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -230,6 +230,28 @@ show_urbnum(struct device *dev, struct device_attribute *attr, char *buf) } static DEVICE_ATTR(urbnum, S_IRUGO, show_urbnum, NULL); +static ssize_t +show_removable(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct usb_device *udev; + char *state; + + udev = to_usb_device(dev); + + switch (udev->removable) { + case USB_DEVICE_REMOVABLE: + state = "removable"; + break; + case USB_DEVICE_FIXED: + state = "fixed"; + break; + default: + state = "unknown"; + } + + return sprintf(buf, "%s\n", state); +} +static DEVICE_ATTR(removable, S_IRUGO, show_removable, NULL); #ifdef CONFIG_PM @@ -626,6 +648,7 @@ static struct attribute *dev_attrs[] = { &dev_attr_avoid_reset_quirk.attr, &dev_attr_authorized.attr, &dev_attr_remove.attr, + &dev_attr_removable.attr, NULL, }; static struct attribute_group dev_attr_grp = { diff --git a/include/linux/usb.h b/include/linux/usb.h index 27a4e16d2bf..b2eb3a47caf 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -376,6 +376,12 @@ struct usb_bus { struct usb_tt; +enum usb_device_removable { + USB_DEVICE_REMOVABLE_UNKNOWN = 0, + USB_DEVICE_REMOVABLE, + USB_DEVICE_FIXED, +}; + /** * struct usb_device - kernel's representation of a USB device * @devnum: device number; address on a USB bus @@ -432,6 +438,7 @@ struct usb_tt; * @wusb_dev: if this is a Wireless USB device, link to the WUSB * specific data for the device. * @slot_id: Slot ID assigned by xHCI + * @removable: Device can be physically removed from this port * * Notes: * Usbcore drivers should not set usbdev->state directly. Instead use @@ -509,6 +516,7 @@ struct usb_device { #endif struct wusb_dev *wusb_dev; int slot_id; + enum usb_device_removable removable; }; #define to_usb_device(d) container_of(d, struct usb_device, dev) -- cgit v1.2.3-70-g09d2 From d35e70d50a0641ebc1502fd343bef9b4011ada27 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Fri, 3 Feb 2012 17:11:55 -0500 Subject: usb: Use hub port data to determine whether a port is removable Hubs have a flag to indicate whether a given port carries removable devices or not. This is not strictly accurate in that some built-in devices will be flagged as removable, but followup patches will make use of platform data to make this more reliable. Signed-off-by: Matthew Garrett Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index a0613d8f9be..2d773cbe191 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1838,6 +1838,37 @@ fail: return err; } +static void set_usb_port_removable(struct usb_device *udev) +{ + struct usb_device *hdev = udev->parent; + struct usb_hub *hub; + u8 port = udev->portnum; + u16 wHubCharacteristics; + bool removable = true; + + if (!hdev) + return; + + hub = hdev_to_hub(udev->parent); + + wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); + + if (!(wHubCharacteristics & HUB_CHAR_COMPOUND)) + return; + + if (hub_is_superspeed(hdev)) { + if (hub->descriptor->u.ss.DeviceRemovable & (1 << port)) + removable = false; + } else { + if (hub->descriptor->u.hs.DeviceRemovable[port / 8] & (1 << (port % 8))) + removable = false; + } + + if (removable) + udev->removable = USB_DEVICE_REMOVABLE; + else + udev->removable = USB_DEVICE_FIXED; +} /** * usb_new_device - perform initial device setup (usbcore-internal) @@ -1896,6 +1927,15 @@ int usb_new_device(struct usb_device *udev) announce_device(udev); device_enable_async_suspend(&udev->dev); + + /* + * check whether the hub marks this port as non-removable. Do it + * now so that platform-specific data can override it in + * device_add() + */ + if (udev->parent) + set_usb_port_removable(udev); + /* Register the device. The device driver is responsible * for configuring the device and invoking the add-device * notifier chain (used by usbfs and possibly others). -- cgit v1.2.3-70-g09d2 From 815b043ddac433eecb2899cb2090495b27f77aac Mon Sep 17 00:00:00 2001 From: Danny Kukawka Date: Wed, 8 Feb 2012 14:16:47 -0800 Subject: cs5535-mfgpt: don't call __init function from __devinit Fix and reset_all_timers() to be __devinit and not __init since the function gets called from cs5535_mfgpt_probe which is __devinit. Signed-off-by: Danny Kukawka Acked-by: Andres Salomon Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/misc/cs5535-mfgpt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/misc/cs5535-mfgpt.c b/drivers/misc/cs5535-mfgpt.c index bc685bfc4c3..f836359226a 100644 --- a/drivers/misc/cs5535-mfgpt.c +++ b/drivers/misc/cs5535-mfgpt.c @@ -246,7 +246,7 @@ EXPORT_SYMBOL_GPL(cs5535_mfgpt_write); * Jordan tells me that he and Mitch once played w/ it, but it's unclear * what the results of that were (and they experienced some instability). */ -static void __init reset_all_timers(void) +static void __devinit reset_all_timers(void) { uint32_t val, dummy; -- cgit v1.2.3-70-g09d2 From 5fb15db4376fed99f6f1cae552766f9d81f062e3 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Tue, 7 Feb 2012 22:33:56 +0900 Subject: char: Fix typo in viotape.c Correct spelling "allocat" to "allocate" in drivers/char/viotape.c Signed-off-by: Masanari Iida Signed-off-by: Greg Kroah-Hartman --- drivers/char/viotape.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index ad6e64a2912..8b34c65511e 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c @@ -976,7 +976,7 @@ int __init viotap_init(void) tape_class = class_create(THIS_MODULE, "tape"); if (IS_ERR(tape_class)) { - printk(VIOTAPE_KERN_WARN "Unable to allocat class\n"); + printk(VIOTAPE_KERN_WARN "Unable to allocate class\n"); ret = PTR_ERR(tape_class); goto unreg_chrdev; } -- cgit v1.2.3-70-g09d2 From 838d51bfa31540d474b9562056379b6325ec07d7 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Tue, 7 Feb 2012 23:55:52 +0900 Subject: char: Fix typo in tlclk.c Correct spelling "telclk_interrup" to "telclk_interrupt" in drivers/char/tlclk.c Signed-off-by: Masanari Iida Signed-off-by: Greg Kroah-Hartman --- drivers/char/tlclk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c index 0c964cdcc22..ce29e7cce52 100644 --- a/drivers/char/tlclk.c +++ b/drivers/char/tlclk.c @@ -797,7 +797,7 @@ static int __init tlclk_init(void) telclk_interrupt = (inb(TLCLK_REG7) & 0x0f); if (0x0F == telclk_interrupt ) { /* not MCPBL0010 ? */ - printk(KERN_ERR "telclk_interrup = 0x%x non-mcpbl0010 hw.\n", + printk(KERN_ERR "telclk_interrupt = 0x%x non-mcpbl0010 hw.\n", telclk_interrupt); ret = -ENXIO; goto out3; -- cgit v1.2.3-70-g09d2 From d011411ddb294e90511211a9edfc79da1c0465dc Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Mon, 6 Feb 2012 17:24:43 +0800 Subject: serial: pch_uart: add debugfs hook for register dump This driver will be use as interfaces for multiple kinds of devices like Bluetooth/GPS etc, this debug hook will make driver debugging much easier. Signed-off-by: Feng Tang Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pch_uart.c | 84 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) (limited to 'drivers') diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 17ae65762d1..6d9ca293336 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -144,6 +145,8 @@ enum { #define PCH_UART_DLL 0x00 #define PCH_UART_DLM 0x01 +#define PCH_UART_BRCSR 0x0E + #define PCH_UART_IID_RLS (PCH_UART_IIR_REI) #define PCH_UART_IID_RDR (PCH_UART_IIR_RRI) #define PCH_UART_IID_RDR_TO (PCH_UART_IIR_RRI | PCH_UART_IIR_TOI) @@ -243,6 +246,8 @@ struct eg20t_port { int tx_dma_use; void *rx_buf_virt; dma_addr_t rx_buf_dma; + + struct dentry *debugfs; }; /** @@ -292,6 +297,73 @@ static const int trigger_level_64[4] = { 1, 16, 32, 56 }; static const int trigger_level_16[4] = { 1, 4, 8, 14 }; static const int trigger_level_1[4] = { 1, 1, 1, 1 }; +#ifdef CONFIG_DEBUG_FS + +#define PCH_REGS_BUFSIZE 1024 +static int pch_show_regs_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +static ssize_t port_show_regs(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct eg20t_port *priv = file->private_data; + char *buf; + u32 len = 0; + ssize_t ret; + unsigned char lcr; + + buf = kzalloc(PCH_REGS_BUFSIZE, GFP_KERNEL); + if (!buf) + return 0; + + len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, + "PCH EG20T port[%d] regs:\n", priv->port.line); + + len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, + "=================================\n"); + len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, + "IER: \t0x%02x\n", ioread8(priv->membase + UART_IER)); + len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, + "IIR: \t0x%02x\n", ioread8(priv->membase + UART_IIR)); + len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, + "LCR: \t0x%02x\n", ioread8(priv->membase + UART_LCR)); + len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, + "MCR: \t0x%02x\n", ioread8(priv->membase + UART_MCR)); + len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, + "LSR: \t0x%02x\n", ioread8(priv->membase + UART_LSR)); + len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, + "MSR: \t0x%02x\n", ioread8(priv->membase + UART_MSR)); + len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, + "BRCSR: \t0x%02x\n", + ioread8(priv->membase + PCH_UART_BRCSR)); + + lcr = ioread8(priv->membase + UART_LCR); + iowrite8(PCH_UART_LCR_DLAB, priv->membase + UART_LCR); + len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, + "DLL: \t0x%02x\n", ioread8(priv->membase + UART_DLL)); + len += snprintf(buf + len, PCH_REGS_BUFSIZE - len, + "DLM: \t0x%02x\n", ioread8(priv->membase + UART_DLM)); + iowrite8(lcr, priv->membase + UART_LCR); + + if (len > PCH_REGS_BUFSIZE) + len = PCH_REGS_BUFSIZE; + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); + kfree(buf); + return ret; +} + +static const struct file_operations port_regs_ops = { + .owner = THIS_MODULE, + .open = pch_show_regs_open, + .read = port_show_regs, + .llseek = default_llseek, +}; +#endif /* CONFIG_DEBUG_FS */ + static void pch_uart_hal_request(struct pci_dev *pdev, int fifosize, int base_baud) { @@ -1554,6 +1626,7 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, int port_type; struct pch_uart_driver_data *board; const char *board_name; + char name[32]; /* for debugfs file name */ board = &drv_dat[id->driver_data]; port_type = board->port_type; @@ -1623,6 +1696,12 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, if (ret < 0) goto init_port_hal_free; +#ifdef CONFIG_DEBUG_FS + snprintf(name, sizeof(name), "uart%d_regs", board->line_no); + priv->debugfs = debugfs_create_file(name, S_IFREG | S_IRUGO, + NULL, priv, &port_regs_ops); +#endif + return priv; init_port_hal_free: @@ -1639,6 +1718,11 @@ init_port_alloc_err: static void pch_uart_exit_port(struct eg20t_port *priv) { + +#ifdef CONFIG_DEBUG_FS + if (priv->debugfs) + debugfs_remove(priv->debugfs); +#endif uart_remove_one_port(&pch_uart_driver, &priv->port); pci_set_drvdata(priv->pdev, NULL); free_page((unsigned long)priv->rxbuf.buf); -- cgit v1.2.3-70-g09d2 From 30c6c6b5bf82d4f4a23235a0aa0657681d1c21f2 Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Mon, 6 Feb 2012 17:24:44 +0800 Subject: serial: pch_uart: trivial cleanup by removing the get_msr() The short get_msr() has some unnecessary code and only used once, so merge it with its caller to make code cleaner. No functional change at all. Signed-off-by: Feng Tang Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pch_uart.c | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 6d9ca293336..811edcbe730 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -373,14 +373,6 @@ static void pch_uart_hal_request(struct pci_dev *pdev, int fifosize, priv->fcr = 0; } -static unsigned int get_msr(struct eg20t_port *priv, void __iomem *base) -{ - unsigned int msr = ioread8(base + UART_MSR); - priv->dmsr |= msr & PCH_UART_MSR_DELTA; - - return msr; -} - static void pch_uart_hal_enable_interrupt(struct eg20t_port *priv, unsigned int flag) { @@ -514,8 +506,9 @@ static int pch_uart_hal_set_fifo(struct eg20t_port *priv, static u8 pch_uart_hal_get_modem(struct eg20t_port *priv) { - priv->dmsr = 0; - return get_msr(priv, priv->membase); + unsigned int msr = ioread8(priv->membase + UART_MSR); + priv->dmsr = msr & PCH_UART_MSR_DELTA; + return (u8)msr; } static void pch_uart_hal_write(struct eg20t_port *priv, @@ -596,7 +589,7 @@ static int push_rx(struct eg20t_port *priv, const unsigned char *buf, static int pop_tx_x(struct eg20t_port *priv, unsigned char *buf) { - int ret; + int ret = 0; struct uart_port *port = &priv->port; if (port->x_char) { @@ -605,8 +598,6 @@ static int pop_tx_x(struct eg20t_port *priv, unsigned char *buf) buf[0] = port->x_char; port->x_char = 0; ret = 1; - } else { - ret = 0; } return ret; @@ -1104,14 +1095,12 @@ static irqreturn_t pch_uart_interrupt(int irq, void *dev_id) static unsigned int pch_uart_tx_empty(struct uart_port *port) { struct eg20t_port *priv; - int ret; + priv = container_of(port, struct eg20t_port, port); if (priv->tx_empty) - ret = TIOCSER_TEMT; + return TIOCSER_TEMT; else - ret = 0; - - return ret; + return 0; } /* Returns the current state of modem control inputs. */ @@ -1345,9 +1334,8 @@ static void pch_uart_set_termios(struct uart_port *port, else parity = PCH_UART_HAL_PARITY_EVEN; - } else { + } else parity = PCH_UART_HAL_PARITY_NONE; - } /* Only UART0 has auto hardware flow function */ if ((termios->c_cflag & CRTSCTS) && (priv->fifo_size == 256)) @@ -1519,7 +1507,6 @@ static void pch_console_write(struct console *co, const char *s, unsigned int count) { struct eg20t_port *priv; - unsigned long flags; u8 ier; int locked = 1; -- cgit v1.2.3-70-g09d2 From 6f56d0f43656deb98c6366a133a75b5a7cf73a26 Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Mon, 6 Feb 2012 17:24:45 +0800 Subject: serial: pch_uart: trivail cleanup by removing the pch_uart_hal_request() pch_uart_hal_request() has parameters which it never uses, also it is very short, so merge it with its caller to make code cleaner. No functional changes at all. Signed-off-by: Feng Tang Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pch_uart.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 811edcbe730..aa4d07b4a9d 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -364,15 +364,6 @@ static const struct file_operations port_regs_ops = { }; #endif /* CONFIG_DEBUG_FS */ -static void pch_uart_hal_request(struct pci_dev *pdev, int fifosize, - int base_baud) -{ - struct eg20t_port *priv = pci_get_drvdata(pdev); - - priv->trigger_level = 1; - priv->fcr = 0; -} - static void pch_uart_hal_enable_interrupt(struct eg20t_port *priv, unsigned int flag) { @@ -1674,7 +1665,8 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, spin_lock_init(&priv->port.lock); pci_set_drvdata(pdev, priv); - pch_uart_hal_request(pdev, fifosize, base_baud); + priv->trigger_level = 1; + priv->fcr = 0; #ifdef CONFIG_SERIAL_PCH_UART_CONSOLE pch_uart_ports[board->line_no] = priv; @@ -1717,9 +1709,7 @@ static void pch_uart_exit_port(struct eg20t_port *priv) static void pch_uart_pci_remove(struct pci_dev *pdev) { - struct eg20t_port *priv; - - priv = (struct eg20t_port *)pci_get_drvdata(pdev); + struct eg20t_port *priv = pci_get_drvdata(pdev); pci_disable_msi(pdev); -- cgit v1.2.3-70-g09d2 From e502babe0a85226f2417b60a8710cf8192879180 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Tue, 7 Feb 2012 10:49:39 +0400 Subject: sysrq: Fix possible race with exiting task sysrq should grab the tasklist lock, otherwise calling force_sig() is not safe, as it might race with exiting task, which ->sighand might be set to NULL already. Signed-off-by: Anton Vorontsov Acked-by: David Rientjes Signed-off-by: Greg Kroah-Hartman --- drivers/tty/sysrq.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 7867b7c4538..a1bcad7ef73 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -322,11 +322,13 @@ static void send_sig_all(int sig) { struct task_struct *p; + read_lock(&tasklist_lock); for_each_process(p) { if (p->mm && !is_global_init(p)) /* Not swapper, init nor kernel thread */ force_sig(sig, p); } + read_unlock(&tasklist_lock); } static void sysrq_handle_term(int key) -- cgit v1.2.3-70-g09d2 From d3a532a9c617106a0169232d40164ee35d0440b5 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Tue, 7 Feb 2012 10:49:51 +0400 Subject: sysrq: Properly check for kernel threads There's a real possibility of killing kernel threads that might have issued use_mm(), so kthread's mm might become non-NULL. This patch fixes the issue by checking for PF_KTHREAD (just as get_task_mm()). Suggested-by: Oleg Nesterov Signed-off-by: Anton Vorontsov Acked-by: David Rientjes Signed-off-by: Greg Kroah-Hartman --- drivers/tty/sysrq.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index a1bcad7ef73..8db9125133b 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -324,9 +324,12 @@ static void send_sig_all(int sig) read_lock(&tasklist_lock); for_each_process(p) { - if (p->mm && !is_global_init(p)) - /* Not swapper, init nor kernel thread */ - force_sig(sig, p); + if (p->flags & PF_KTHREAD) + continue; + if (is_global_init(p)) + continue; + + force_sig(sig, p); } read_unlock(&tasklist_lock); } -- cgit v1.2.3-70-g09d2 From 3f5dc70721af68b76ad544b0c61fea365d67c041 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 8 Feb 2012 14:35:46 +0100 Subject: tty: serial: altera_uart: remove early_altera_uart_setup The function has no users inside the tree and the nios2 (out-of-mainline) port doesn't use it either (anymore). Signed-off-by: Tobias Klauser Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/altera_uart.c | 23 ----------------------- include/linux/altera_uart.h | 4 ---- 2 files changed, 27 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index 1d04c5037f2..217833e94b5 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c @@ -403,29 +403,6 @@ static struct altera_uart altera_uart_ports[CONFIG_SERIAL_ALTERA_UART_MAXPORTS]; #if defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE) -int __init early_altera_uart_setup(struct altera_uart_platform_uart *platp) -{ - struct uart_port *port; - int i; - - for (i = 0; i < CONFIG_SERIAL_ALTERA_UART_MAXPORTS && platp[i].mapbase; i++) { - port = &altera_uart_ports[i].port; - - port->line = i; - port->type = PORT_ALTERA_UART; - port->mapbase = platp[i].mapbase; - port->membase = ioremap(port->mapbase, ALTERA_UART_SIZE); - port->iotype = SERIAL_IO_MEM; - port->irq = platp[i].irq; - port->uartclk = platp[i].uartclk; - port->flags = UPF_BOOT_AUTOCONF; - port->ops = &altera_uart_ops; - port->private_data = platp; - } - - return 0; -} - static void altera_uart_console_putc(struct uart_port *port, const char c) { while (!(altera_uart_readl(port, ALTERA_UART_STATUS_REG) & diff --git a/include/linux/altera_uart.h b/include/linux/altera_uart.h index a10a9079197..c022c82db7c 100644 --- a/include/linux/altera_uart.h +++ b/include/linux/altera_uart.h @@ -5,8 +5,6 @@ #ifndef __ALTUART_H #define __ALTUART_H -#include - struct altera_uart_platform_uart { unsigned long mapbase; /* Physical address base */ unsigned int irq; /* Interrupt vector */ @@ -14,6 +12,4 @@ struct altera_uart_platform_uart { unsigned int bus_shift; /* Bus shift (address stride) */ }; -int __init early_altera_uart_setup(struct altera_uart_platform_uart *platp); - #endif /* __ALTUART_H */ -- cgit v1.2.3-70-g09d2 From 418a936e84e8f346da322c2e839992aa9df108d4 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 8 Feb 2012 14:36:09 +0100 Subject: tty: serial: altera_uart: Add CONSOLE_POLL support This allows altera_uart to be used for KGDB debugging over serial line. Signed-off-by: Tobias Klauser Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Makefile | 2 +- drivers/tty/serial/altera_uart.c | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index 1997ad4a39a..50d279000e7 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -75,12 +75,12 @@ obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o obj-$(CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL) += nwpserial.o obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o +obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o obj-$(CONFIG_SERIAL_QE) += ucc_uart.o obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o obj-$(CONFIG_SERIAL_GRLIB_GAISLER_APBUART) += apbuart.o obj-$(CONFIG_SERIAL_ALTERA_JTAGUART) += altera_jtaguart.o -obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o obj-$(CONFIG_SERIAL_VT8500) += vt8500_serial.o obj-$(CONFIG_SERIAL_MRST_MAX3110) += mrst_max3110.o obj-$(CONFIG_SERIAL_MFD_HSU) += mfd.o diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index 217833e94b5..e7903751e05 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c @@ -377,6 +377,26 @@ static int altera_uart_verify_port(struct uart_port *port, return 0; } +#ifdef CONFIG_CONSOLE_POLL +static int altera_uart_poll_get_char(struct uart_port *port) +{ + while (!(altera_uart_readl(port, ALTERA_UART_STATUS_REG) & + ALTERA_UART_STATUS_RRDY_MSK)) + cpu_relax(); + + return altera_uart_readl(port, ALTERA_UART_RXDATA_REG); +} + +static void altera_uart_poll_put_char(struct uart_port *port, unsigned char c) +{ + while (!(altera_uart_readl(port, ALTERA_UART_STATUS_REG) & + ALTERA_UART_STATUS_TRDY_MSK)) + cpu_relax(); + + altera_uart_writel(port, c, ALTERA_UART_TXDATA_REG); +} +#endif + /* * Define the basic serial functions we support. */ @@ -397,6 +417,10 @@ static struct uart_ops altera_uart_ops = { .release_port = altera_uart_release_port, .config_port = altera_uart_config_port, .verify_port = altera_uart_verify_port, +#ifdef CONFIG_CONSOLE_POLL + .poll_get_char = altera_uart_poll_get_char, + .poll_put_char = altera_uart_poll_put_char, +#endif }; static struct altera_uart altera_uart_ports[CONFIG_SERIAL_ALTERA_UART_MAXPORTS]; -- cgit v1.2.3-70-g09d2 From d8e4cd99d5a13f65fb961e627b63ae70ab0fe951 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 9 Feb 2012 14:56:25 +0200 Subject: staging: fix the build breakage cuased by telephony drivers Fix build error caused by commit: 6222d7a17745f6e48fddda7245e4bb0d58bfeaf0 telephony: Move to staging The telephony driver was moved to staging but the Makefiles weren't updated Cc: Joe Perches Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/Makefile | 1 - drivers/staging/Makefile | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/Makefile b/drivers/Makefile index c07be024b96..932e8bf2035 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -86,7 +86,6 @@ obj-$(CONFIG_POWER_SUPPLY) += power/ obj-$(CONFIG_HWMON) += hwmon/ obj-$(CONFIG_THERMAL) += thermal/ obj-$(CONFIG_WATCHDOG) += watchdog/ -obj-$(CONFIG_PHONE) += telephony/ obj-$(CONFIG_MD) += md/ obj-$(CONFIG_BT) += bluetooth/ obj-$(CONFIG_ACCESSIBILITY) += accessibility/ diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 31c81fabfc3..077a3f3c0b8 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -58,3 +58,4 @@ obj-$(CONFIG_MFD_NVEC) += nvec/ obj-$(CONFIG_DRM_OMAP) += omapdrm/ obj-$(CONFIG_ANDROID) += android/ obj-$(CONFIG_RAMSTER) += ramster/ +obj-$(CONFIG_PHONE) += telephony/ -- cgit v1.2.3-70-g09d2 From 86587b671bf87ed81d2d89cd1199af912402a05f Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Wed, 8 Feb 2012 19:42:03 -0600 Subject: staging: r8712u: Simplify semaphores I am preparing to convert this driver from semaphore to mutex locking, The first step has been to eliminate a number of semaphores that were initialized but never used, and one whose only use was a single "up" after initialization. A total of 9 semaphores were removed in this process. One other change was to remove some inline semaphore routines that were unused. In addition, several cases had the following structure: down() if () { ... } up() The locking overhead was reduced by moving the up/down inside the if block. Signed-off-by: Larry Finger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/drv_types.h | 1 - drivers/staging/rtl8712/os_intfs.c | 1 - drivers/staging/rtl8712/osdep_service.h | 17 ----------------- drivers/staging/rtl8712/rtl8712_recv.c | 2 -- drivers/staging/rtl8712/rtl871x_io.c | 1 - drivers/staging/rtl8712/rtl871x_io.h | 1 - drivers/staging/rtl8712/rtl871x_pwrctrl.c | 11 ++++------- drivers/staging/rtl8712/rtl871x_pwrctrl.h | 1 - drivers/staging/rtl8712/rtl871x_recv.c | 1 - drivers/staging/rtl8712/rtl871x_recv.h | 3 --- drivers/staging/rtl8712/rtl871x_xmit.c | 3 --- drivers/staging/rtl8712/rtl871x_xmit.h | 3 --- drivers/staging/rtl8712/usb_intf.c | 1 - 13 files changed, 4 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/drv_types.h b/drivers/staging/rtl8712/drv_types.h index 9b5d771e650..0735de9aad9 100644 --- a/drivers/staging/rtl8712/drv_types.h +++ b/drivers/staging/rtl8712/drv_types.h @@ -138,7 +138,6 @@ struct dvobj_priv { u8 ishighspeed; uint(*inirp_init)(struct _adapter *adapter); uint(*inirp_deinit)(struct _adapter *adapter); - struct semaphore usb_suspend_sema; struct usb_device *pusbdev; }; diff --git a/drivers/staging/rtl8712/os_intfs.c b/drivers/staging/rtl8712/os_intfs.c index 9a75c6dbe50..250cd116f0c 100644 --- a/drivers/staging/rtl8712/os_intfs.c +++ b/drivers/staging/rtl8712/os_intfs.c @@ -329,7 +329,6 @@ u8 r8712_init_drv_sw(struct _adapter *padapter) padapter->stapriv.padapter = padapter; r8712_init_bcmc_stainfo(padapter); r8712_init_pwrctrl_priv(padapter); - sema_init(&(padapter->pwrctrlpriv.pnp_pwr_mgnt_sema), 0); mp871xinit(padapter); if (init_default_value(padapter) != _SUCCESS) return _FAIL; diff --git a/drivers/staging/rtl8712/osdep_service.h b/drivers/staging/rtl8712/osdep_service.h index 1ee943a58c4..9ba603310fd 100644 --- a/drivers/staging/rtl8712/osdep_service.h +++ b/drivers/staging/rtl8712/osdep_service.h @@ -72,18 +72,6 @@ static inline struct list_head *get_list_head(struct __queue *queue) #define LIST_CONTAINOR(ptr, type, member) \ ((type *)((char *)(ptr)-(SIZE_T)(&((type *)0)->member))) -static inline void _enter_hwio_critical(struct semaphore *prwlock, - unsigned long *pirqL) -{ - down(prwlock); -} - -static inline void _exit_hwio_critical(struct semaphore *prwlock, - unsigned long *pirqL) -{ - up(prwlock); -} - static inline void list_delete(struct list_head *plist) { list_del_init(plist); @@ -152,11 +140,6 @@ static inline u32 _down_sema(struct semaphore *sema) return _SUCCESS; } -static inline void _rtl_rwlock_init(struct semaphore *prwlock) -{ - sema_init(prwlock, 1); -} - static inline void _init_listhead(struct list_head *list) { INIT_LIST_HEAD(list); diff --git a/drivers/staging/rtl8712/rtl8712_recv.c b/drivers/staging/rtl8712/rtl8712_recv.c index 6d692657e78..fa6dc9c09b3 100644 --- a/drivers/staging/rtl8712/rtl8712_recv.c +++ b/drivers/staging/rtl8712/rtl8712_recv.c @@ -55,8 +55,6 @@ int r8712_init_recv_priv(struct recv_priv *precvpriv, struct _adapter *padapter) int alignment = 0; struct sk_buff *pskb = NULL; - sema_init(&precvpriv->recv_sema, 0); - sema_init(&precvpriv->terminate_recvthread_sema, 0); /*init recv_buf*/ _init_queue(&precvpriv->free_recv_buf_queue); precvpriv->pallocated_recv_buf = _malloc(NR_RECVBUFF * diff --git a/drivers/staging/rtl8712/rtl871x_io.c b/drivers/staging/rtl8712/rtl871x_io.c index ca84ee02eac..abc1c97378f 100644 --- a/drivers/staging/rtl8712/rtl871x_io.c +++ b/drivers/staging/rtl8712/rtl871x_io.c @@ -131,7 +131,6 @@ uint r8712_alloc_io_queue(struct _adapter *adapter) pio_req = (struct io_req *)(pio_queue->free_ioreqs_buf); for (i = 0; i < NUM_IOREQ; i++) { _init_listhead(&pio_req->list); - sema_init(&pio_req->sema, 0); list_insert_tail(&pio_req->list, &pio_queue->free_ioreqs); pio_req++; } diff --git a/drivers/staging/rtl8712/rtl871x_io.h b/drivers/staging/rtl8712/rtl871x_io.h index 86308a0093e..d3d8727c2ec 100644 --- a/drivers/staging/rtl8712/rtl871x_io.h +++ b/drivers/staging/rtl8712/rtl871x_io.h @@ -117,7 +117,6 @@ struct io_req { u32 command; u32 status; u8 *pbuf; - struct semaphore sema; void (*_async_io_callback)(struct _adapter *padater, struct io_req *pio_req, u8 *cnxt); u8 *cnxt; diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.c b/drivers/staging/rtl8712/rtl871x_pwrctrl.c index 23e72a0401a..9fd2ec7596c 100644 --- a/drivers/staging/rtl8712/rtl871x_pwrctrl.c +++ b/drivers/staging/rtl8712/rtl871x_pwrctrl.c @@ -100,7 +100,6 @@ void r8712_cpwm_int_hdl(struct _adapter *padapter, { struct pwrctrl_priv *pwrpriv = &(padapter->pwrctrlpriv); struct cmd_priv *pcmdpriv = &(padapter->cmdpriv); - struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); if (pwrpriv->cpwm_tog == ((preportpwrstate->state) & 0x80)) return; @@ -110,8 +109,6 @@ void r8712_cpwm_int_hdl(struct _adapter *padapter, if (pwrpriv->cpwm >= PS_STATE_S2) { if (pwrpriv->alives & CMD_ALIVE) up(&(pcmdpriv->cmd_queue_sema)); - if (pwrpriv->alives & XMIT_ALIVE) - up(&(pxmitpriv->xmit_sema)); } pwrpriv->cpwm_tog = (preportpwrstate->state) & 0x80; up(&pwrpriv->lock); @@ -145,12 +142,12 @@ static void SetPSModeWorkItemCallback(struct work_struct *work) struct pwrctrl_priv, SetPSModeWorkItem); struct _adapter *padapter = container_of(pwrpriv, struct _adapter, pwrctrlpriv); - _enter_pwrlock(&pwrpriv->lock); if (!pwrpriv->bSleep) { + _enter_pwrlock(&pwrpriv->lock); if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) r8712_set_rpwm(padapter, PS_STATE_S4); + up(&pwrpriv->lock); } - up(&pwrpriv->lock); } static void rpwm_workitem_callback(struct work_struct *work) @@ -160,13 +157,13 @@ static void rpwm_workitem_callback(struct work_struct *work) struct _adapter *padapter = container_of(pwrpriv, struct _adapter, pwrctrlpriv); u8 cpwm = pwrpriv->cpwm; - _enter_pwrlock(&pwrpriv->lock); if (pwrpriv->cpwm != pwrpriv->rpwm) { + _enter_pwrlock(&pwrpriv->lock); cpwm = r8712_read8(padapter, SDIO_HCPWM); pwrpriv->rpwm_retry = 1; r8712_set_rpwm(padapter, pwrpriv->rpwm); + up(&pwrpriv->lock); } - up(&pwrpriv->lock); } static void rpwm_check_handler (void *FunctionContext) diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.h b/drivers/staging/rtl8712/rtl871x_pwrctrl.h index b41ca2892be..6024c4f63d5 100644 --- a/drivers/staging/rtl8712/rtl871x_pwrctrl.h +++ b/drivers/staging/rtl8712/rtl871x_pwrctrl.h @@ -133,7 +133,6 @@ struct pwrctrl_priv { u8 rpwm_retry; uint bSetPSModeWorkItemInProgress; - struct semaphore pnp_pwr_mgnt_sema; spinlock_t pnp_pwr_mgnt_lock; s32 pnp_current_pwr_state; u8 pnp_bstop_trx; diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c index 7069f06d9b5..5b03b405883 100644 --- a/drivers/staging/rtl8712/rtl871x_recv.c +++ b/drivers/staging/rtl8712/rtl871x_recv.c @@ -93,7 +93,6 @@ sint _r8712_init_recv_priv(struct recv_priv *precvpriv, precvframe++; } precvpriv->rx_pending_cnt = 1; - sema_init(&precvpriv->allrxreturnevt, 0); return r8712_init_recv_priv(precvpriv, padapter); } diff --git a/drivers/staging/rtl8712/rtl871x_recv.h b/drivers/staging/rtl8712/rtl871x_recv.h index cc7a72fee1c..e42e6f0a15e 100644 --- a/drivers/staging/rtl8712/rtl871x_recv.h +++ b/drivers/staging/rtl8712/rtl871x_recv.h @@ -85,8 +85,6 @@ using enter_critical section to protect */ struct recv_priv { spinlock_t lock; - struct semaphore recv_sema; - struct semaphore terminate_recvthread_sema; struct __queue free_recv_queue; struct __queue recv_pending_queue; u8 *pallocated_frame_buf; @@ -100,7 +98,6 @@ struct recv_priv { uint rx_largepacket_crcerr; uint rx_smallpacket_crcerr; uint rx_middlepacket_crcerr; - struct semaphore allrxreturnevt; u8 rx_pending_cnt; uint ff_hwaddr; struct tasklet_struct recv_tasklet; diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c b/drivers/staging/rtl8712/rtl871x_xmit.c index 8bbdee70f86..aa57e7754f0 100644 --- a/drivers/staging/rtl8712/rtl871x_xmit.c +++ b/drivers/staging/rtl8712/rtl871x_xmit.c @@ -71,8 +71,6 @@ sint _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv, memset((unsigned char *)pxmitpriv, 0, sizeof(struct xmit_priv)); spin_lock_init(&pxmitpriv->lock); - sema_init(&pxmitpriv->xmit_sema, 0); - sema_init(&pxmitpriv->terminate_xmitthread_sema, 0); /* Please insert all the queue initializaiton using _init_queue below */ @@ -121,7 +119,6 @@ sint _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv, _r8712_init_hw_txqueue(&pxmitpriv->bmc_txqueue, BMC_QUEUE_INX); pxmitpriv->frag_len = MAX_FRAG_THRESHOLD; pxmitpriv->txirp_cnt = 1; - sema_init(&(pxmitpriv->tx_retevt), 0); /*per AC pending irp*/ pxmitpriv->beq_cnt = 0; pxmitpriv->bkq_cnt = 0; diff --git a/drivers/staging/rtl8712/rtl871x_xmit.h b/drivers/staging/rtl8712/rtl871x_xmit.h index a034c0fec71..638b79b4c5a 100644 --- a/drivers/staging/rtl8712/rtl871x_xmit.h +++ b/drivers/staging/rtl8712/rtl871x_xmit.h @@ -202,8 +202,6 @@ struct hw_txqueue { struct xmit_priv { spinlock_t lock; - struct semaphore xmit_sema; - struct semaphore terminate_xmitthread_sema; struct __queue be_pending; struct __queue bk_pending; struct __queue vi_pending; @@ -233,7 +231,6 @@ struct xmit_priv { uint tx_drop; struct hw_xmit *hwxmits; u8 hwxmit_entry; - struct semaphore tx_retevt;/*all tx return event;*/ u8 txirp_cnt; struct tasklet_struct xmit_tasklet; _workitem xmit_pipe4_reset_wi; diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c index 5385da2e9cd..01378eaa79b 100644 --- a/drivers/staging/rtl8712/usb_intf.c +++ b/drivers/staging/rtl8712/usb_intf.c @@ -280,7 +280,6 @@ static uint r8712_usb_dvobj_init(struct _adapter *padapter) } if ((r8712_alloc_io_queue(padapter)) == _FAIL) status = _FAIL; - sema_init(&(padapter->dvobjpriv.usb_suspend_sema), 0); return status; } -- cgit v1.2.3-70-g09d2 From a2f9dc55345baff05378c23de6e9e026f6838556 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 12 Jan 2012 22:49:27 +0100 Subject: drivers/staging: adjust double test Rewrite a duplicated test to test the correct value The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression E; @@ ( * E || ... || E | * E && ... && E ) // Signed-off-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib_rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c index 6c5061f12ba..13979b5ea32 100644 --- a/drivers/staging/rtl8192e/rtllib_rx.c +++ b/drivers/staging/rtl8192e/rtllib_rx.c @@ -2453,7 +2453,7 @@ static inline void update_network(struct rtllib_network *dst, if (src->wmm_param[0].ac_aci_acm_aifsn || src->wmm_param[1].ac_aci_acm_aifsn || src->wmm_param[2].ac_aci_acm_aifsn || - src->wmm_param[1].ac_aci_acm_aifsn) + src->wmm_param[3].ac_aci_acm_aifsn) memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN); dst->SignalStrength = src->SignalStrength; -- cgit v1.2.3-70-g09d2 From 2da57c8e4ac0933417f9fdd141bf5bebc87edc1e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sun, 15 Jan 2012 14:29:39 +0300 Subject: staging: precedence bug in crystalhd_stop_tx_dma_engine() The intent here is to see if we have cleared the DMA_START_BIT flag. We clear it a couple lines later. The current code has a precedence bug so it is equivalent to "if (!dma_cntrl) { ...". Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/crystalhd/crystalhd_hw.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/crystalhd/crystalhd_hw.c b/drivers/staging/crystalhd/crystalhd_hw.c index 5acf39e7cde..eeddee9a605 100644 --- a/drivers/staging/crystalhd/crystalhd_hw.c +++ b/drivers/staging/crystalhd/crystalhd_hw.c @@ -868,8 +868,7 @@ static enum BC_STATUS crystalhd_stop_tx_dma_engine(struct crystalhd_hw *hw) BCMLOG(BCMLOG_DBG, "Stopping TX DMA Engine..\n"); - /* FIXME: jarod: invert dma_ctrl and check bit? or are there missing parens? */ - if (!dma_cntrl & DMA_START_BIT) { + if (!(dma_cntrl & DMA_START_BIT)) { BCMLOG(BCMLOG_DBG, "Already Stopped\n"); return BC_STS_SUCCESS; } -- cgit v1.2.3-70-g09d2 From 3784129a9de3fc33ffe6c6ece906a9caa1c65fab Mon Sep 17 00:00:00 2001 From: Markus Grabner Date: Fri, 20 Jan 2012 00:09:07 +0100 Subject: staging: line6: removed obsolete code Signed-off-by: Markus Grabner Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/pcm.h | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/line6/pcm.h b/drivers/staging/line6/pcm.h index 55d8297dd3d..47c6d6942b4 100644 --- a/drivers/staging/line6/pcm.h +++ b/drivers/staging/line6/pcm.h @@ -305,13 +305,4 @@ extern void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm); extern int line6_pcm_start(struct snd_line6_pcm *line6pcm, int channels); extern int line6_pcm_stop(struct snd_line6_pcm *line6pcm, int channels); -#define PRINT_FRAME_DIFF(op) { \ - static int diff_prev = 1000; \ - int diff = line6pcm->last_frame_out - line6pcm->last_frame_in; \ - if ((diff != diff_prev) && (abs(diff) < 100)) { \ - printk(KERN_INFO "%s frame diff = %d\n", op, diff); \ - diff_prev = diff; \ - } \ -} - #endif -- cgit v1.2.3-70-g09d2 From 12177acdecfcb538b86590036a56fc47b443e135 Mon Sep 17 00:00:00 2001 From: Markus Grabner Date: Fri, 20 Jan 2012 00:09:08 +0100 Subject: staging: line6: use source select control for UX2 devices Signed-off-by: Markus Grabner Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/toneport.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/line6/toneport.c b/drivers/staging/line6/toneport.c index f31057830db..b776130058c 100644 --- a/drivers/staging/line6/toneport.c +++ b/drivers/staging/line6/toneport.c @@ -320,7 +320,9 @@ static void toneport_setup(struct usb_line6_toneport *toneport) /* initialize source select: */ switch (usbdev->descriptor.idProduct) { case LINE6_DEVID_TONEPORT_UX1: + case LINE6_DEVID_TONEPORT_UX2: case LINE6_DEVID_PODSTUDIO_UX1: + case LINE6_DEVID_PODSTUDIO_UX2: toneport_send_cmd(usbdev, toneport_source_info[toneport->source].code, 0x0000); @@ -363,7 +365,9 @@ static int toneport_try_init(struct usb_interface *interface, /* register source select control: */ switch (usbdev->descriptor.idProduct) { case LINE6_DEVID_TONEPORT_UX1: + case LINE6_DEVID_TONEPORT_UX2: case LINE6_DEVID_PODSTUDIO_UX1: + case LINE6_DEVID_PODSTUDIO_UX2: err = snd_ctl_add(line6->card, snd_ctl_new1(&toneport_control_source, -- cgit v1.2.3-70-g09d2 From 0ca54888060135806d5567f47a6ad54be5297b34 Mon Sep 17 00:00:00 2001 From: Markus Grabner Date: Fri, 20 Jan 2012 00:09:09 +0100 Subject: staging: line6: separate handling of buffer allocation and stream startup There are several features of the Line6 USB driver which require PCM data to be exchanged with the device: *) PCM playback and capture via ALSA *) software monitoring (for devices without hardware monitoring) *) optional impulse response measurement However, from the device's point of view, there is just a single capture and playback stream, which must be shared between these subsystems. It is therefore necessary to maintain the state of the subsystems with respect to PCM usage. We define several constants of the form LINE6_BIT_PCM___ with the following meanings: *) is one of -) ALSA: PCM playback and capture via ALSA -) MONITOR: software monitoring -) IMPULSE: optional impulse response measurement *) is one of -) PLAYBACK: audio output (from host to device) -) CAPTURE: audio input (from device to host) *) is one of -) BUFFER: buffer required by PCM data stream -) STREAM: actual PCM data stream The subsystems call line6_pcm_acquire() to acquire the (shared) resources needed for a particular operation (e.g., allocate the buffer for ALSA playback or start the capture stream for software monitoring). When a resource is no longer needed, it is released by calling line6_pcm_release(). Buffer allocation and stream startup are handled separately to allow the ALSA kernel driver to perform them at appropriate places (since the callback which starts a PCM stream is not allowed to sleep). Signed-off-by: Markus Grabner Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/capture.c | 54 ++++--------- drivers/staging/line6/capture.h | 2 +- drivers/staging/line6/driver.c | 2 +- drivers/staging/line6/pcm.c | 109 ++++++++++++++++++--------- drivers/staging/line6/pcm.h | 158 ++++++++++++++++++++++++++++----------- drivers/staging/line6/playback.c | 68 ++++++----------- drivers/staging/line6/playback.h | 2 +- drivers/staging/line6/toneport.c | 8 +- drivers/staging/line6/usbdefs.h | 44 ++++++----- 9 files changed, 254 insertions(+), 193 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/line6/capture.c b/drivers/staging/line6/capture.c index 127f9524774..c85c5b6bffb 100644 --- a/drivers/staging/line6/capture.c +++ b/drivers/staging/line6/capture.c @@ -107,7 +107,7 @@ void line6_unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm) Wait until unlinking of all currently active capture URBs has been finished. */ -static void wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm) +void line6_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm) { int timeout = HZ; unsigned int i; @@ -134,7 +134,7 @@ static void wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm) void line6_unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm) { line6_unlink_audio_in_urbs(line6pcm); - wait_clear_audio_in_urbs(line6pcm); + line6_wait_clear_audio_in_urbs(line6pcm); } /* @@ -193,25 +193,6 @@ void line6_capture_check_period(struct snd_line6_pcm *line6pcm, int length) } } -int line6_alloc_capture_buffer(struct snd_line6_pcm *line6pcm) -{ - /* We may be invoked multiple times in a row so allocate once only */ - if (line6pcm->buffer_in) - return 0; - - line6pcm->buffer_in = - kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * - line6pcm->max_packet_size, GFP_KERNEL); - - if (!line6pcm->buffer_in) { - dev_err(line6pcm->line6->ifcdev, - "cannot malloc capture buffer\n"); - return -ENOMEM; - } - - return 0; -} - void line6_free_capture_buffer(struct snd_line6_pcm *line6pcm) { kfree(line6pcm->buffer_in); @@ -273,9 +254,9 @@ static void audio_in_callback(struct urb *urb) line6pcm->prev_fsize = fsize; #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE - if (!(line6pcm->flags & MASK_PCM_IMPULSE)) + if (!(line6pcm->flags & LINE6_BITS_PCM_IMPULSE)) #endif - if (test_bit(BIT_PCM_ALSA_CAPTURE, &line6pcm->flags) + if (test_bit(LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM, &line6pcm->flags) && (fsize > 0)) line6_capture_copy(line6pcm, fbuf, fsize); } @@ -291,9 +272,9 @@ static void audio_in_callback(struct urb *urb) submit_audio_in_urb(line6pcm); #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE - if (!(line6pcm->flags & MASK_PCM_IMPULSE)) + if (!(line6pcm->flags & LINE6_BITS_PCM_IMPULSE)) #endif - if (test_bit(BIT_PCM_ALSA_CAPTURE, &line6pcm->flags)) + if (test_bit(LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM, &line6pcm->flags)) line6_capture_check_period(line6pcm, length); } } @@ -341,17 +322,17 @@ static int snd_line6_capture_hw_params(struct snd_pcm_substream *substream, } /* -- [FD] end */ - if ((line6pcm->flags & MASK_CAPTURE) == 0) { - ret = line6_alloc_capture_buffer(line6pcm); + ret = line6_pcm_acquire(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER); - if (ret < 0) - return ret; - } + if (ret < 0) + return ret; ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); - if (ret < 0) + if (ret < 0) { + line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER); return ret; + } line6pcm->period_in = params_period_bytes(hw_params); return 0; @@ -361,12 +342,7 @@ static int snd_line6_capture_hw_params(struct snd_pcm_substream *substream, static int snd_line6_capture_hw_free(struct snd_pcm_substream *substream) { struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); - - if ((line6pcm->flags & MASK_CAPTURE) == 0) { - line6_unlink_wait_clear_audio_in_urbs(line6pcm); - line6_free_capture_buffer(line6pcm); - } - + line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER); return snd_pcm_lib_free_pages(substream); } @@ -380,7 +356,7 @@ int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd) #ifdef CONFIG_PM case SNDRV_PCM_TRIGGER_RESUME: #endif - err = line6_pcm_start(line6pcm, MASK_PCM_ALSA_CAPTURE); + err = line6_pcm_acquire(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_STREAM); if (err < 0) return err; @@ -391,7 +367,7 @@ int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd) #ifdef CONFIG_PM case SNDRV_PCM_TRIGGER_SUSPEND: #endif - err = line6_pcm_stop(line6pcm, MASK_PCM_ALSA_CAPTURE); + err = line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_STREAM); if (err < 0) return err; diff --git a/drivers/staging/line6/capture.h b/drivers/staging/line6/capture.h index 366cbaa7c88..4157bcb598a 100644 --- a/drivers/staging/line6/capture.h +++ b/drivers/staging/line6/capture.h @@ -19,7 +19,6 @@ extern struct snd_pcm_ops snd_line6_capture_ops; -extern int line6_alloc_capture_buffer(struct snd_line6_pcm *line6pcm); extern void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf, int fsize); extern void line6_capture_check_period(struct snd_line6_pcm *line6pcm, @@ -30,6 +29,7 @@ extern int line6_submit_audio_in_all_urbs(struct snd_line6_pcm *line6pcm); extern void line6_unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm); extern void line6_unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm); +extern void line6_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm); extern int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd); #endif diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index 6a1959e16e0..e8023afd365 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -1346,7 +1346,7 @@ static void __exit line6_exit(void) if (line6pcm == NULL) continue; - line6_pcm_stop(line6pcm, ~0); + line6_pcm_release(line6pcm, ~0); } usb_deregister(&line6_driver); diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c index 37675e66da8..90d2d4475cb 100644 --- a/drivers/staging/line6/pcm.c +++ b/drivers/staging/line6/pcm.c @@ -52,9 +52,9 @@ static ssize_t pcm_set_impulse_volume(struct device *dev, line6pcm->impulse_volume = value; if (value > 0) - line6_pcm_start(line6pcm, MASK_PCM_IMPULSE); + line6_pcm_acquire(line6pcm, LINE6_BITS_PCM_IMPULSE); else - line6_pcm_stop(line6pcm, MASK_PCM_IMPULSE); + line6_pcm_release(line6pcm, LINE6_BITS_PCM_IMPULSE); return count; } @@ -92,29 +92,43 @@ static bool test_flags(unsigned long flags0, unsigned long flags1, return ((flags0 & mask) == 0) && ((flags1 & mask) != 0); } -int line6_pcm_start(struct snd_line6_pcm *line6pcm, int channels) +int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels) { unsigned long flags_old = __sync_fetch_and_or(&line6pcm->flags, channels); unsigned long flags_new = flags_old | channels; + unsigned long flags_final = flags_old; int err = 0; line6pcm->prev_fbuf = NULL; - if (test_flags(flags_old, flags_new, MASK_CAPTURE)) { + if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_BUFFER)) { + /* We may be invoked multiple times in a row so allocate once only */ + if (!line6pcm->buffer_in) { + line6pcm->buffer_in = + kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * + line6pcm->max_packet_size, GFP_KERNEL); + + if (!line6pcm->buffer_in) { + dev_err(line6pcm->line6->ifcdev, + "cannot malloc capture buffer\n"); + err = -ENOMEM; + goto pcm_acquire_error; + } + + flags_final |= channels & LINE6_BITS_CAPTURE_BUFFER; + } + } + + if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_STREAM)) { /* Waiting for completion of active URBs in the stop handler is a bug, we therefore report an error if capturing is restarted too soon. */ - if (line6pcm->active_urb_in | line6pcm->unlink_urb_in) + if (line6pcm->active_urb_in | line6pcm->unlink_urb_in) { + dev_err(line6pcm->line6->ifcdev, "Device not yet ready\n"); return -EBUSY; - - if (!(flags_new & MASK_PCM_ALSA_CAPTURE)) { - err = line6_alloc_capture_buffer(line6pcm); - - if (err < 0) - goto pcm_start_error; } line6pcm->count_in = 0; @@ -122,55 +136,78 @@ int line6_pcm_start(struct snd_line6_pcm *line6pcm, int channels) err = line6_submit_audio_in_all_urbs(line6pcm); if (err < 0) - goto pcm_start_error; + goto pcm_acquire_error; + + flags_final |= channels & LINE6_BITS_CAPTURE_STREAM; } - if (test_flags(flags_old, flags_new, MASK_PLAYBACK)) { - /* - See comment above regarding PCM restart. - */ - if (line6pcm->active_urb_out | line6pcm->unlink_urb_out) - return -EBUSY; + if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_BUFFER)) { + /* We may be invoked multiple times in a row so allocate once only */ + if (!line6pcm->buffer_out) { + line6pcm->buffer_out = + kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * + line6pcm->max_packet_size, GFP_KERNEL); + + if (!line6pcm->buffer_out) { + dev_err(line6pcm->line6->ifcdev, + "cannot malloc playback buffer\n"); + err = -ENOMEM; + goto pcm_acquire_error; + } - if (!(flags_new & MASK_PCM_ALSA_PLAYBACK)) { - err = line6_alloc_playback_buffer(line6pcm); + flags_final |= channels & LINE6_BITS_PLAYBACK_BUFFER; + } + } - if (err < 0) - goto pcm_start_error; + if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_STREAM)) { + /* + See comment above regarding PCM restart. + */ + if (line6pcm->active_urb_out | line6pcm->unlink_urb_out) { + dev_err(line6pcm->line6->ifcdev, "Device not yet ready\n"); + return -EBUSY; } line6pcm->count_out = 0; err = line6_submit_audio_out_all_urbs(line6pcm); if (err < 0) - goto pcm_start_error; + goto pcm_acquire_error; + + flags_final |= channels & LINE6_BITS_PLAYBACK_STREAM; } return 0; -pcm_start_error: - __sync_fetch_and_and(&line6pcm->flags, ~channels); +pcm_acquire_error: + /* + If not all requested resources/streams could be obtained, release + those which were successfully obtained (if any). + */ + line6_pcm_release(line6pcm, flags_final & channels); return err; } -int line6_pcm_stop(struct snd_line6_pcm *line6pcm, int channels) +int line6_pcm_release(struct snd_line6_pcm *line6pcm, int channels) { unsigned long flags_old = __sync_fetch_and_and(&line6pcm->flags, ~channels); unsigned long flags_new = flags_old & ~channels; - if (test_flags(flags_new, flags_old, MASK_CAPTURE)) { + if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_STREAM)) line6_unlink_audio_in_urbs(line6pcm); - if (!(flags_old & MASK_PCM_ALSA_CAPTURE)) - line6_free_capture_buffer(line6pcm); + if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_BUFFER)) { + line6_wait_clear_audio_in_urbs(line6pcm); + line6_free_capture_buffer(line6pcm); } - if (test_flags(flags_new, flags_old, MASK_PLAYBACK)) { + if (test_flags(flags_new, flags_old, LINE6_BITS_PLAYBACK_STREAM)) line6_unlink_audio_out_urbs(line6pcm); - if (!(flags_old & MASK_PCM_ALSA_PLAYBACK)) - line6_free_playback_buffer(line6pcm); + if (test_flags(flags_new, flags_old, LINE6_BITS_PLAYBACK_BUFFER)) { + line6_wait_clear_audio_out_urbs(line6pcm); + line6_free_playback_buffer(line6pcm); } return 0; @@ -185,7 +222,7 @@ int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd) unsigned long flags; spin_lock_irqsave(&line6pcm->lock_trigger, flags); - clear_bit(BIT_PREPARED, &line6pcm->flags); + clear_bit(LINE6_INDEX_PREPARED, &line6pcm->flags); snd_pcm_group_for_each_entry(s, substream) { switch (s->stream) { @@ -498,13 +535,13 @@ int snd_line6_prepare(struct snd_pcm_substream *substream) switch (substream->stream) { case SNDRV_PCM_STREAM_PLAYBACK: - if ((line6pcm->flags & MASK_PLAYBACK) == 0) + if ((line6pcm->flags & LINE6_BITS_PLAYBACK_STREAM) == 0) line6_unlink_wait_clear_audio_out_urbs(line6pcm); break; case SNDRV_PCM_STREAM_CAPTURE: - if ((line6pcm->flags & MASK_CAPTURE) == 0) + if ((line6pcm->flags & LINE6_BITS_CAPTURE_STREAM) == 0) line6_unlink_wait_clear_audio_in_urbs(line6pcm); break; @@ -513,7 +550,7 @@ int snd_line6_prepare(struct snd_pcm_substream *substream) MISSING_CASE; } - if (!test_and_set_bit(BIT_PREPARED, &line6pcm->flags)) { + if (!test_and_set_bit(LINE6_INDEX_PREPARED, &line6pcm->flags)) { line6pcm->count_out = 0; line6pcm->pos_out = 0; line6pcm->pos_out_done = 0; diff --git a/drivers/staging/line6/pcm.h b/drivers/staging/line6/pcm.h index 47c6d6942b4..5210ec8dbe1 100644 --- a/drivers/staging/line6/pcm.h +++ b/drivers/staging/line6/pcm.h @@ -46,57 +46,131 @@ (line6pcm->pcm->streams[stream].substream) /* - PCM mode bits and masks. - "ALSA": operations triggered by applications via ALSA - "MONITOR": software monitoring - "IMPULSE": optional impulse response operation + PCM mode bits. + + There are several features of the Line6 USB driver which require PCM + data to be exchanged with the device: + *) PCM playback and capture via ALSA + *) software monitoring (for devices without hardware monitoring) + *) optional impulse response measurement + However, from the device's point of view, there is just a single + capture and playback stream, which must be shared between these + subsystems. It is therefore necessary to maintain the state of the + subsystems with respect to PCM usage. We define several constants of + the form LINE6_BIT_PCM___ with the + following meanings: + *) is one of + -) ALSA: PCM playback and capture via ALSA + -) MONITOR: software monitoring + -) IMPULSE: optional impulse response measurement + *) is one of + -) PLAYBACK: audio output (from host to device) + -) CAPTURE: audio input (from device to host) + *) is one of + -) BUFFER: buffer required by PCM data stream + -) STREAM: actual PCM data stream + + The subsystems call line6_pcm_acquire() to acquire the (shared) + resources needed for a particular operation (e.g., allocate the buffer + for ALSA playback or start the capture stream for software monitoring). + When a resource is no longer needed, it is released by calling + line6_pcm_release(). Buffer allocation and stream startup are handled + separately to allow the ALSA kernel driver to perform them at + appropriate places (since the callback which starts a PCM stream is not + allowed to sleep). */ enum { - /* individual bits: */ - BIT_PCM_ALSA_PLAYBACK, - BIT_PCM_ALSA_CAPTURE, - BIT_PCM_MONITOR_PLAYBACK, - BIT_PCM_MONITOR_CAPTURE, + /* individual bit indices: */ + LINE6_INDEX_PCM_ALSA_PLAYBACK_BUFFER, + LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, + LINE6_INDEX_PCM_ALSA_CAPTURE_BUFFER, + LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM, + LINE6_INDEX_PCM_MONITOR_PLAYBACK_BUFFER, + LINE6_INDEX_PCM_MONITOR_PLAYBACK_STREAM, + LINE6_INDEX_PCM_MONITOR_CAPTURE_BUFFER, + LINE6_INDEX_PCM_MONITOR_CAPTURE_STREAM, #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE - BIT_PCM_IMPULSE_PLAYBACK, - BIT_PCM_IMPULSE_CAPTURE, + LINE6_INDEX_PCM_IMPULSE_PLAYBACK_BUFFER, + LINE6_INDEX_PCM_IMPULSE_PLAYBACK_STREAM, + LINE6_INDEX_PCM_IMPULSE_CAPTURE_BUFFER, + LINE6_INDEX_PCM_IMPULSE_CAPTURE_STREAM, #endif - BIT_PAUSE_PLAYBACK, - BIT_PREPARED, - - /* individual masks: */ -/* *INDENT-OFF* */ - MASK_PCM_ALSA_PLAYBACK = 1 << BIT_PCM_ALSA_PLAYBACK, - MASK_PCM_ALSA_CAPTURE = 1 << BIT_PCM_ALSA_CAPTURE, - MASK_PCM_MONITOR_PLAYBACK = 1 << BIT_PCM_MONITOR_PLAYBACK, - MASK_PCM_MONITOR_CAPTURE = 1 << BIT_PCM_MONITOR_CAPTURE, + LINE6_INDEX_PAUSE_PLAYBACK, + LINE6_INDEX_PREPARED, + + /* individual bit masks: */ + LINE6_BIT(PCM_ALSA_PLAYBACK_BUFFER), + LINE6_BIT(PCM_ALSA_PLAYBACK_STREAM), + LINE6_BIT(PCM_ALSA_CAPTURE_BUFFER), + LINE6_BIT(PCM_ALSA_CAPTURE_STREAM), + LINE6_BIT(PCM_MONITOR_PLAYBACK_BUFFER), + LINE6_BIT(PCM_MONITOR_PLAYBACK_STREAM), + LINE6_BIT(PCM_MONITOR_CAPTURE_BUFFER), + LINE6_BIT(PCM_MONITOR_CAPTURE_STREAM), #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE - MASK_PCM_IMPULSE_PLAYBACK = 1 << BIT_PCM_IMPULSE_PLAYBACK, - MASK_PCM_IMPULSE_CAPTURE = 1 << BIT_PCM_IMPULSE_CAPTURE, + LINE6_BIT(PCM_IMPULSE_PLAYBACK_BUFFER), + LINE6_BIT(PCM_IMPULSE_PLAYBACK_STREAM), + LINE6_BIT(PCM_IMPULSE_CAPTURE_BUFFER), + LINE6_BIT(PCM_IMPULSE_CAPTURE_STREAM), #endif - MASK_PAUSE_PLAYBACK = 1 << BIT_PAUSE_PLAYBACK, - MASK_PREPARED = 1 << BIT_PREPARED, -/* *INDENT-ON* */ + LINE6_BIT(PAUSE_PLAYBACK), + LINE6_BIT(PREPARED), - /* combined masks (by operation): */ - MASK_PCM_ALSA = MASK_PCM_ALSA_PLAYBACK | MASK_PCM_ALSA_CAPTURE, - MASK_PCM_MONITOR = MASK_PCM_MONITOR_PLAYBACK | MASK_PCM_MONITOR_CAPTURE, + /* combined bit masks (by operation): */ + LINE6_BITS_PCM_ALSA_BUFFER = + LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER | + LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER, + + LINE6_BITS_PCM_ALSA_STREAM = + LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM | + LINE6_BIT_PCM_ALSA_CAPTURE_STREAM, + + LINE6_BITS_PCM_MONITOR = + LINE6_BIT_PCM_MONITOR_PLAYBACK_BUFFER | + LINE6_BIT_PCM_MONITOR_PLAYBACK_STREAM | + LINE6_BIT_PCM_MONITOR_CAPTURE_BUFFER | + LINE6_BIT_PCM_MONITOR_CAPTURE_STREAM, + +#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE + LINE6_BITS_PCM_IMPULSE = + LINE6_BIT_PCM_IMPULSE_PLAYBACK_BUFFER | + LINE6_BIT_PCM_IMPULSE_PLAYBACK_STREAM | + LINE6_BIT_PCM_IMPULSE_CAPTURE_BUFFER | + LINE6_BIT_PCM_IMPULSE_CAPTURE_STREAM, +#endif + + /* combined bit masks (by direction): */ + LINE6_BITS_PLAYBACK_BUFFER = +#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE + LINE6_BIT_PCM_IMPULSE_PLAYBACK_BUFFER | +#endif + LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER | + LINE6_BIT_PCM_MONITOR_PLAYBACK_BUFFER , + + LINE6_BITS_PLAYBACK_STREAM = +#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE + LINE6_BIT_PCM_IMPULSE_PLAYBACK_STREAM | +#endif + LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM | + LINE6_BIT_PCM_MONITOR_PLAYBACK_STREAM , + + LINE6_BITS_CAPTURE_BUFFER = #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE - MASK_PCM_IMPULSE = MASK_PCM_IMPULSE_PLAYBACK | MASK_PCM_IMPULSE_CAPTURE, + LINE6_BIT_PCM_IMPULSE_CAPTURE_BUFFER | #endif + LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER | + LINE6_BIT_PCM_MONITOR_CAPTURE_BUFFER , - /* combined masks (by direction): */ + LINE6_BITS_CAPTURE_STREAM = #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE - MASK_PLAYBACK = - MASK_PCM_ALSA_PLAYBACK | MASK_PCM_MONITOR_PLAYBACK | - MASK_PCM_IMPULSE_PLAYBACK, - MASK_CAPTURE = - MASK_PCM_ALSA_CAPTURE | MASK_PCM_MONITOR_CAPTURE | - MASK_PCM_IMPULSE_CAPTURE -#else - MASK_PLAYBACK = MASK_PCM_ALSA_PLAYBACK | MASK_PCM_MONITOR_PLAYBACK, - MASK_CAPTURE = MASK_PCM_ALSA_CAPTURE | MASK_PCM_MONITOR_CAPTURE + LINE6_BIT_PCM_IMPULSE_CAPTURE_STREAM | #endif + LINE6_BIT_PCM_ALSA_CAPTURE_STREAM | + LINE6_BIT_PCM_MONITOR_CAPTURE_STREAM, + + LINE6_BITS_STREAM = + LINE6_BITS_PLAYBACK_STREAM | + LINE6_BITS_CAPTURE_STREAM }; struct line6_pcm_properties { @@ -290,7 +364,7 @@ struct snd_line6_pcm { #endif /** - Several status bits (see BIT_*). + Several status bits (see LINE6_BIT_*). */ unsigned long flags; @@ -302,7 +376,7 @@ extern int line6_init_pcm(struct usb_line6 *line6, extern int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd); extern int snd_line6_prepare(struct snd_pcm_substream *substream); extern void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm); -extern int line6_pcm_start(struct snd_line6_pcm *line6pcm, int channels); -extern int line6_pcm_stop(struct snd_line6_pcm *line6pcm, int channels); +extern int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels); +extern int line6_pcm_release(struct snd_line6_pcm *line6pcm, int channels); #endif diff --git a/drivers/staging/line6/playback.c b/drivers/staging/line6/playback.c index 4152db2328b..a0ab9d0493f 100644 --- a/drivers/staging/line6/playback.c +++ b/drivers/staging/line6/playback.c @@ -166,7 +166,7 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm) struct usb_iso_packet_descriptor *fout = &urb_out->iso_frame_desc[i]; - if (line6pcm->flags & MASK_CAPTURE) + if (line6pcm->flags & LINE6_BITS_CAPTURE_STREAM) fsize = line6pcm->prev_fsize; if (fsize == 0) { @@ -196,8 +196,8 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm) urb_out->transfer_buffer_length = urb_size; urb_out->context = line6pcm; - if (test_bit(BIT_PCM_ALSA_PLAYBACK, &line6pcm->flags) && - !test_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags)) { + if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, &line6pcm->flags) && + !test_bit(LINE6_INDEX_PAUSE_PLAYBACK, &line6pcm->flags)) { struct snd_pcm_runtime *runtime = get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK)->runtime; @@ -238,10 +238,10 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm) if (line6pcm->prev_fbuf != NULL) { #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE - if (line6pcm->flags & MASK_PCM_IMPULSE) { + if (line6pcm->flags & LINE6_BITS_PCM_IMPULSE) { create_impulse_test_signal(line6pcm, urb_out, bytes_per_frame); - if (line6pcm->flags & MASK_PCM_ALSA_CAPTURE) { + if (line6pcm->flags & LINE6_BIT_PCM_ALSA_CAPTURE_STREAM) { line6_capture_copy(line6pcm, urb_out->transfer_buffer, urb_out-> @@ -254,8 +254,8 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm) if (! (line6pcm->line6-> properties->capabilities & LINE6_BIT_HWMON) -&& (line6pcm->flags & MASK_PLAYBACK) -&& (line6pcm->flags & MASK_CAPTURE)) + && (line6pcm->flags & LINE6_BITS_PLAYBACK_STREAM) + && (line6pcm->flags & LINE6_BITS_CAPTURE_STREAM)) add_monitor_signal(urb_out, line6pcm->prev_fbuf, line6pcm->volume_monitor, bytes_per_frame); @@ -321,7 +321,7 @@ void line6_unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm) /* Wait until unlinking of all currently active playback URBs has been finished. */ -static void wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm) +void line6_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm) { int timeout = HZ; unsigned int i; @@ -348,26 +348,7 @@ static void wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm) void line6_unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm) { line6_unlink_audio_out_urbs(line6pcm); - wait_clear_audio_out_urbs(line6pcm); -} - -int line6_alloc_playback_buffer(struct snd_line6_pcm *line6pcm) -{ - /* We may be invoked multiple times in a row so allocate once only */ - if (line6pcm->buffer_out) - return 0; - - line6pcm->buffer_out = - kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * - line6pcm->max_packet_size, GFP_KERNEL); - - if (!line6pcm->buffer_out) { - dev_err(line6pcm->line6->ifcdev, - "cannot malloc playback buffer\n"); - return -ENOMEM; - } - - return 0; + line6_wait_clear_audio_out_urbs(line6pcm); } void line6_free_playback_buffer(struct snd_line6_pcm *line6pcm) @@ -407,7 +388,7 @@ static void audio_out_callback(struct urb *urb) spin_lock_irqsave(&line6pcm->lock_audio_out, flags); - if (test_bit(BIT_PCM_ALSA_PLAYBACK, &line6pcm->flags)) { + if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, &line6pcm->flags)) { struct snd_pcm_runtime *runtime = substream->runtime; line6pcm->pos_out_done += length / line6pcm->properties->bytes_per_frame; @@ -432,7 +413,7 @@ static void audio_out_callback(struct urb *urb) if (!shutdown) { submit_audio_out_urb(line6pcm); - if (test_bit(BIT_PCM_ALSA_PLAYBACK, &line6pcm->flags)) { + if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, &line6pcm->flags)) { line6pcm->bytes_out += length; if (line6pcm->bytes_out >= line6pcm->period_out) { line6pcm->bytes_out %= line6pcm->period_out; @@ -484,17 +465,17 @@ static int snd_line6_playback_hw_params(struct snd_pcm_substream *substream, } /* -- [FD] end */ - if ((line6pcm->flags & MASK_PLAYBACK) == 0) { - ret = line6_alloc_playback_buffer(line6pcm); + ret = line6_pcm_acquire(line6pcm, LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER); - if (ret < 0) - return ret; - } + if (ret < 0) + return ret; ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); - if (ret < 0) + if (ret < 0) { + line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER); return ret; + } line6pcm->period_out = params_period_bytes(hw_params); return 0; @@ -504,12 +485,7 @@ static int snd_line6_playback_hw_params(struct snd_pcm_substream *substream, static int snd_line6_playback_hw_free(struct snd_pcm_substream *substream) { struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); - - if ((line6pcm->flags & MASK_PLAYBACK) == 0) { - line6_unlink_wait_clear_audio_out_urbs(line6pcm); - line6_free_playback_buffer(line6pcm); - } - + line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER); return snd_pcm_lib_free_pages(substream); } @@ -523,7 +499,7 @@ int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd) #ifdef CONFIG_PM case SNDRV_PCM_TRIGGER_RESUME: #endif - err = line6_pcm_start(line6pcm, MASK_PCM_ALSA_PLAYBACK); + err = line6_pcm_acquire(line6pcm, LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM); if (err < 0) return err; @@ -534,7 +510,7 @@ int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd) #ifdef CONFIG_PM case SNDRV_PCM_TRIGGER_SUSPEND: #endif - err = line6_pcm_stop(line6pcm, MASK_PCM_ALSA_PLAYBACK); + err = line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM); if (err < 0) return err; @@ -542,11 +518,11 @@ int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd) break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - set_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags); + set_bit(LINE6_INDEX_PAUSE_PLAYBACK, &line6pcm->flags); break; case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - clear_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags); + clear_bit(LINE6_INDEX_PAUSE_PLAYBACK, &line6pcm->flags); break; default: diff --git a/drivers/staging/line6/playback.h b/drivers/staging/line6/playback.h index 02487ff2453..743bd6f74c5 100644 --- a/drivers/staging/line6/playback.h +++ b/drivers/staging/line6/playback.h @@ -29,13 +29,13 @@ extern struct snd_pcm_ops snd_line6_playback_ops; -extern int line6_alloc_playback_buffer(struct snd_line6_pcm *line6pcm); extern int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm); extern void line6_free_playback_buffer(struct snd_line6_pcm *line6pcm); extern int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm); extern void line6_unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm); extern void line6_unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm); +extern void line6_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm); extern int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd); #endif diff --git a/drivers/staging/line6/toneport.c b/drivers/staging/line6/toneport.c index b776130058c..b754f69a29c 100644 --- a/drivers/staging/line6/toneport.c +++ b/drivers/staging/line6/toneport.c @@ -207,9 +207,9 @@ static int snd_toneport_monitor_put(struct snd_kcontrol *kcontrol, line6pcm->volume_monitor = ucontrol->value.integer.value[0]; if (line6pcm->volume_monitor > 0) - line6_pcm_start(line6pcm, MASK_PCM_MONITOR); + line6_pcm_acquire(line6pcm, LINE6_BITS_PCM_MONITOR); else - line6_pcm_stop(line6pcm, MASK_PCM_MONITOR); + line6_pcm_release(line6pcm, LINE6_BITS_PCM_MONITOR); return 1; } @@ -264,7 +264,7 @@ static void toneport_start_pcm(unsigned long arg) { struct usb_line6_toneport *toneport = (struct usb_line6_toneport *)arg; struct usb_line6 *line6 = &toneport->line6; - line6_pcm_start(line6->line6pcm, MASK_PCM_MONITOR); + line6_pcm_acquire(line6->line6pcm, LINE6_BITS_PCM_MONITOR); } /* control definition */ @@ -446,7 +446,7 @@ void line6_toneport_disconnect(struct usb_interface *interface) struct snd_line6_pcm *line6pcm = toneport->line6.line6pcm; if (line6pcm != NULL) { - line6_pcm_stop(line6pcm, MASK_PCM_MONITOR); + line6_pcm_release(line6pcm, LINE6_BITS_PCM_MONITOR); line6_pcm_disconnect(line6pcm); } } diff --git a/drivers/staging/line6/usbdefs.h b/drivers/staging/line6/usbdefs.h index aff9e5caea4..353d59d77b0 100644 --- a/drivers/staging/line6/usbdefs.h +++ b/drivers/staging/line6/usbdefs.h @@ -39,31 +39,29 @@ #define LINE6_DEVID_TONEPORT_UX2 0x4142 #define LINE6_DEVID_VARIAX 0x534d -enum { - LINE6_ID_BASSPODXT, - LINE6_ID_BASSPODXTLIVE, - LINE6_ID_BASSPODXTPRO, - LINE6_ID_GUITARPORT, - LINE6_ID_POCKETPOD, - LINE6_ID_PODHD300, - LINE6_ID_PODHD500, - LINE6_ID_PODSTUDIO_GX, - LINE6_ID_PODSTUDIO_UX1, - LINE6_ID_PODSTUDIO_UX2, - LINE6_ID_PODX3, - LINE6_ID_PODX3LIVE, - LINE6_ID_PODXT, - LINE6_ID_PODXTLIVE, - LINE6_ID_PODXTPRO, - LINE6_ID_TONEPORT_GX, - LINE6_ID_TONEPORT_UX1, - LINE6_ID_TONEPORT_UX2, - LINE6_ID_VARIAX -}; - -#define LINE6_BIT(x) LINE6_BIT_ ## x = 1 << LINE6_ID_ ## x +#define LINE6_BIT(x) LINE6_BIT_ ## x = 1 << LINE6_INDEX_ ## x enum { + LINE6_INDEX_BASSPODXT, + LINE6_INDEX_BASSPODXTLIVE, + LINE6_INDEX_BASSPODXTPRO, + LINE6_INDEX_GUITARPORT, + LINE6_INDEX_POCKETPOD, + LINE6_INDEX_PODHD300, + LINE6_INDEX_PODHD500, + LINE6_INDEX_PODSTUDIO_GX, + LINE6_INDEX_PODSTUDIO_UX1, + LINE6_INDEX_PODSTUDIO_UX2, + LINE6_INDEX_PODX3, + LINE6_INDEX_PODX3LIVE, + LINE6_INDEX_PODXT, + LINE6_INDEX_PODXTLIVE, + LINE6_INDEX_PODXTPRO, + LINE6_INDEX_TONEPORT_GX, + LINE6_INDEX_TONEPORT_UX1, + LINE6_INDEX_TONEPORT_UX2, + LINE6_INDEX_VARIAX, + LINE6_BIT(BASSPODXT), LINE6_BIT(BASSPODXTLIVE), LINE6_BIT(BASSPODXTPRO), -- cgit v1.2.3-70-g09d2 From 77974a30b94bf51f2a5d6707ba652b7f51c99260 Mon Sep 17 00:00:00 2001 From: Sam Hansen Date: Fri, 20 Jan 2012 01:11:27 -0800 Subject: staging: vme: code convention fix Fixed a code convention violation in vme.h Signed-off-by: Sam Hansen Acked-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/vme.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/vme/vme.h b/drivers/staging/vme/vme.h index 9d38ceed60e..c9d65bf14ce 100644 --- a/drivers/staging/vme/vme.h +++ b/drivers/staging/vme/vme.h @@ -156,7 +156,7 @@ int vme_irq_request(struct vme_dev *, int, int, void vme_irq_free(struct vme_dev *, int, int); int vme_irq_generate(struct vme_dev *, int, int); -struct vme_resource * vme_lm_request(struct vme_dev *); +struct vme_resource *vme_lm_request(struct vme_dev *); int vme_lm_count(struct vme_resource *); int vme_lm_set(struct vme_resource *, unsigned long long, u32, u32); int vme_lm_get(struct vme_resource *, unsigned long long *, u32 *, u32 *); -- cgit v1.2.3-70-g09d2 From 1a2463f6e22532ad1b036f1cedab33dc998b3088 Mon Sep 17 00:00:00 2001 From: Marcos Paulo de Souza Date: Wed, 28 Dec 2011 21:03:15 +0000 Subject: staging: vt6656: iwctl.c: Remove commented code Signed-off-by: Marcos Paulo de Souza Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/iwctl.c | 172 ----------------------------------------- 1 file changed, 172 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index ecfda5272fa..480e07f6c4b 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -46,9 +46,6 @@ #include - -/*--------------------- Static Definitions -------------------------*/ - #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT #define SUPPORTED_WIRELESS_EXT 18 #else @@ -63,19 +60,8 @@ static const long frequency_list[] = { 5700, 5745, 5765, 5785, 5805, 5825 }; - -/*--------------------- Static Classes ----------------------------*/ - - -//static int msglevel =MSG_LEVEL_DEBUG; static int msglevel =MSG_LEVEL_INFO; - -/*--------------------- Static Variables --------------------------*/ -/*--------------------- Static Functions --------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev) { PSDevice pDevice = netdev_priv(dev); @@ -87,7 +73,6 @@ struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev) pDevice->wstats.qual.qual =(BYTE) pDevice->scStatistic.LinkQuality; RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm); pDevice->wstats.qual.level = ldBm; - //pDevice->wstats.qual.level = 0x100 - pDevice->uCurrRSSI; pDevice->wstats.qual.noise = 0; pDevice->wstats.qual.updated = 1; pDevice->wstats.discard.nwid = 0; @@ -100,11 +85,6 @@ struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev) return &pDevice->wstats; } - - -/*------------------------------------------------------------------*/ - - static int iwctl_commit(struct net_device *dev, struct iw_request_info *info, void *wrq, @@ -197,14 +177,12 @@ if(pDevice->byReAssocCount > 0) { //reject scan when re-associating! } 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; } - /* * Wireless Handler : get scan results */ @@ -708,9 +686,7 @@ int iwctl_giwap(struct net_device *dev, memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6); -//20080123-02, by Einsn Liu if ((pDevice->bLinkPass == FALSE) && (pMgmt->eCurrMode != WMAC_MODE_ESS_AP)) - // if ((pDevice->bLinkPass == FALSE) && (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)) memset(wrq->sa_data, 0, 6); if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { @@ -913,7 +889,6 @@ int iwctl_giwessid(struct net_device *dev, // Get the current SSID pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; - //pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; memcpy(extra, pItemSSID->abySSID , pItemSSID->len); extra[pItemSSID->len] = '\0'; @@ -1327,55 +1302,6 @@ int iwctl_siwencode(struct net_device *dev, return rc; } -/* - * Wireless Handler : get encode mode - */ -//2008-0409-06, by Einsn Liu - /* -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"); - - - 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 (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (BYTE)index , &pKey)){ - wrq->length = pKey->uKeyLength; - memcpy(abyKey, pKey->abyKey, pKey->uKeyLength); - } - else { - rc = -EINVAL; - return rc; - } - wrq->flags |= index; - // Copy the key to the user buffer - memcpy(extra, abyKey, WLAN_WEP232_KEYLEN); - return 0; -} -*/ - int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, @@ -1562,7 +1488,6 @@ int iwctl_siwauth(struct net_device *dev, wpa_version = wrq->value; if(wrq->value == IW_AUTH_WPA_VERSION_DISABLED) { PRINT_K("iwctl_siwauth:set WPADEV to disable at 1??????\n"); - //pDevice->bWPADEVUp = FALSE; } else if(wrq->value == IW_AUTH_WPA_VERSION_WPA) { PRINT_K("iwctl_siwauth:set WPADEV to WPA1******\n"); @@ -1570,7 +1495,6 @@ int iwctl_siwauth(struct net_device *dev, else { PRINT_K("iwctl_siwauth:set WPADEV to WPA2******\n"); } - //pDevice->bWPASuppWextEnabled =TRUE; break; case IW_AUTH_CIPHER_PAIRWISE: pairwise = wrq->value; @@ -1627,11 +1551,6 @@ int iwctl_siwauth(struct net_device *dev, } break; case IW_AUTH_WPA_ENABLED: - //pDevice->bWPADEVUp = !! wrq->value; - //if(pDevice->bWPADEVUp==TRUE) - // printk("iwctl_siwauth:set WPADEV to enable successful*******\n"); - //else - // printk("iwctl_siwauth:set WPADEV to enable fail?????\n"); break; case IW_AUTH_RX_UNENCRYPTED_EAPOL: break; @@ -1646,7 +1565,6 @@ int iwctl_siwauth(struct net_device *dev, pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; pMgmt->bShareKeyAlgorithm = FALSE; pMgmt->eAuthenMode = WMAC_AUTH_OPEN; - //pDevice->bWPADEVUp = FALSE; PRINT_K("iwctl_siwauth:set WPADEV to disaable at 2?????\n"); } @@ -1655,15 +1573,6 @@ int iwctl_siwauth(struct net_device *dev, ret = -EOPNOTSUPP; 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->bWPADEVUp = %s\n",pDevice->bWPADEVUp?"TRUE":"FALSE"); -*/ return ret; } @@ -1752,8 +1661,6 @@ int iwctl_siwencodeext(struct net_device *dev, 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]; @@ -1883,7 +1790,6 @@ int iwctl_siwmlme(struct net_device *dev, PSDevice pDevice = (PSDevice)netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); struct iw_mlme *mlme = (struct iw_mlme *)extra; - //u16 reason = cpu_to_le16(mlme->reason_code); int ret = 0; if(memcmp(pMgmt->abyCurrBSSID, mlme->addr.sa_data, ETH_ALEN)){ @@ -1892,12 +1798,6 @@ int iwctl_siwmlme(struct net_device *dev, } switch(mlme->cmd){ case IW_MLME_DEAUTH: - //this command seems to be not complete,please test it --einsnliu - //printk("iwctl_siwmlme--->send DEAUTH\n"); - /* bScheduleCommand((void *) pDevice, - WLAN_CMD_DEAUTH, - (PBYTE)&reason); */ - //break; case IW_MLME_DISASSOC: if(pDevice->bLinkPass == TRUE){ PRINT_K("iwctl_siwmlme--->send DISASSOCIATE\n"); @@ -1916,74 +1816,6 @@ int iwctl_siwmlme(struct net_device *dev, #endif -/*------------------------------------------------------------------*/ -/* - * Structures to export the Wireless Handlers - */ - - -/* -static const iw_handler iwctl_handler[] = -{ - (iw_handler) iwctl_commit, // SIOCSIWCOMMIT - (iw_handler) iwctl_giwname, // SIOCGIWNAME - (iw_handler) NULL, // SIOCSIWNWID - (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 @@ -2063,13 +1895,9 @@ const struct iw_handler_def iwctl_handler_def = { .get_wireless_stats = &iwctl_get_wireless_stats, .num_standard = sizeof(iwctl_handler)/sizeof(iw_handler), -// .num_private = sizeof(iwctl_private_handler)/sizeof(iw_handler), -// .num_private_args = sizeof(iwctl_private_args)/sizeof(struct iw_priv_args), .num_private = 0, .num_private_args = 0, .standard = (iw_handler *) iwctl_handler, -// .private = (iw_handler *) iwctl_private_handler, -// .private_args = (struct iw_priv_args *)iwctl_private_args, .private = NULL, .private_args = NULL, }; -- cgit v1.2.3-70-g09d2 From 506215ba22fea4a9190b7e33413405bd4d4ab1e1 Mon Sep 17 00:00:00 2001 From: Marcos Paulo de Souza Date: Wed, 28 Dec 2011 21:07:40 +0000 Subject: staging: vt6656: iwctl.c: Remove useless function The funciton iwctl_commit does nothing, and can be removed. Signed-off-by: Marcos Paulo de Souza Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/iwctl.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index 480e07f6c4b..d6fd0105bf9 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -85,16 +85,6 @@ struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev) return &pDevice->wstats; } -static int iwctl_commit(struct net_device *dev, - struct iw_request_info *info, - void *wrq, - char *extra) -{ - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWCOMMIT\n"); - - return 0; -} - /* * Wireless Handler : get protocol name */ @@ -1818,7 +1808,7 @@ int iwctl_siwmlme(struct net_device *dev, static const iw_handler iwctl_handler[] = { - (iw_handler) iwctl_commit, // SIOCSIWCOMMIT + (iw_handler) NULL, /* SIOCSIWCOMMIT */ (iw_handler) NULL, // SIOCGIWNAME (iw_handler) NULL, // SIOCSIWNWID (iw_handler) NULL, // SIOCGIWNWID -- cgit v1.2.3-70-g09d2 From 5d11b1737d52b6f9428c2daea72457cd477e0122 Mon Sep 17 00:00:00 2001 From: Marcos Paulo de Souza Date: Wed, 28 Dec 2011 21:09:13 +0000 Subject: staging: vt6656: Remove return statement of iwctl_giwmode This function will always return 0, and this data is not used by who calls this function. Signed-off-by: Marcos Paulo de Souza Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/iwctl.c | 4 +--- drivers/staging/vt6656/iwctl.h | 2 +- drivers/staging/vt6656/main_usb.c | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index d6fd0105bf9..75b36d3bf1a 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -471,7 +471,7 @@ int iwctl_siwmode(struct net_device *dev, * Wireless Handler : get operation mode */ -int iwctl_giwmode(struct net_device *dev, +void iwctl_giwmode(struct net_device *dev, struct iw_request_info *info, __u32 *wmode, char *extra) @@ -498,8 +498,6 @@ int iwctl_giwmode(struct net_device *dev, default: *wmode = IW_MODE_ADHOC; } - - return 0; } diff --git a/drivers/staging/vt6656/iwctl.h b/drivers/staging/vt6656/iwctl.h index 10a240e6501..60180a75f30 100644 --- a/drivers/staging/vt6656/iwctl.h +++ b/drivers/staging/vt6656/iwctl.h @@ -52,7 +52,7 @@ int iwctl_giwrange(struct net_device *dev, char *extra); -int iwctl_giwmode(struct net_device *dev, +void iwctl_giwmode(struct net_device *dev, struct iw_request_info *info, __u32 *wmode, char *extra); diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index 6a708f44765..fdd35c6af1c 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -1733,7 +1733,7 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { // Get mode of operation case SIOCGIWMODE: - rc = iwctl_giwmode(dev, NULL, &(wrq->u.mode), NULL); + iwctl_giwmode(dev, NULL, &(wrq->u.mode), NULL); break; // Set WEP keys and mode -- cgit v1.2.3-70-g09d2 From f9b9f93426139e7525306b94df8f82989c3f6138 Mon Sep 17 00:00:00 2001 From: Marcos Paulo de Souza Date: Wed, 28 Dec 2011 21:10:50 +0000 Subject: staging: vt6656: Remove return statement of iwctl_giwrange The function iwctl_giwrange will always return 0, and this data is not used by who calls this function. Signed-off-by: Marcos Paulo de Souza Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/iwctl.c | 5 +---- drivers/staging/vt6656/iwctl.h | 2 +- drivers/staging/vt6656/main_usb.c | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index 75b36d3bf1a..0e27fb1d964 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -505,7 +505,7 @@ void iwctl_giwmode(struct net_device *dev, * Wireless Handler : get capability range */ -int iwctl_giwrange(struct net_device *dev, +void iwctl_giwrange(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) @@ -600,9 +600,6 @@ int iwctl_giwrange(struct net_device *dev, range->avg_qual.level = 176; // -80 dBm range->avg_qual.noise = 0; } - - - return 0; } diff --git a/drivers/staging/vt6656/iwctl.h b/drivers/staging/vt6656/iwctl.h index 60180a75f30..22acf8be8e7 100644 --- a/drivers/staging/vt6656/iwctl.h +++ b/drivers/staging/vt6656/iwctl.h @@ -46,7 +46,7 @@ int iwctl_siwap(struct net_device *dev, struct sockaddr *wrq, char *extra); -int iwctl_giwrange(struct net_device *dev, +void iwctl_giwrange(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra); diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index fdd35c6af1c..6213075030d 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -1811,7 +1811,7 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { { struct iw_range range; - rc = iwctl_giwrange(dev, NULL, &(wrq->u.data), (char *) &range); + iwctl_giwrange(dev, NULL, &(wrq->u.data), (char *) &range); if (copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range))) rc = -EFAULT; } -- cgit v1.2.3-70-g09d2 From caa20de81635b567ee0114a81ffbbffb3085d727 Mon Sep 17 00:00:00 2001 From: Marcos Paulo de Souza Date: Wed, 28 Dec 2011 21:12:12 +0000 Subject: staging: vt6656: iwctl.c: Remove return statement of iwctl_giwessid This function will always return 0, and this data is not used by who calls this function. Signed-off-by: Marcos Paulo de Souza Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/iwctl.c | 5 +---- drivers/staging/vt6656/iwctl.h | 2 +- drivers/staging/vt6656/main_usb.c | 4 ++-- 3 files changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index 0e27fb1d964..d6c969a65cf 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -856,8 +856,7 @@ int iwctl_siwessid(struct net_device *dev, /* * Wireless Handler : get essid */ - -int iwctl_giwessid(struct net_device *dev, +void iwctl_giwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra) @@ -879,8 +878,6 @@ int iwctl_giwessid(struct net_device *dev, wrq->length = pItemSSID->len; wrq->flags = 1; // active - - return 0; } /* diff --git a/drivers/staging/vt6656/iwctl.h b/drivers/staging/vt6656/iwctl.h index 22acf8be8e7..0bab0d755c5 100644 --- a/drivers/staging/vt6656/iwctl.h +++ b/drivers/staging/vt6656/iwctl.h @@ -97,7 +97,7 @@ int iwctl_siwessid(struct net_device *dev, struct iw_point *wrq, char *extra); -int iwctl_giwessid(struct net_device *dev, +void iwctl_giwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra); diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index 6213075030d..91b953cb6d3 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -1657,8 +1657,8 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { { char essid[IW_ESSID_MAX_SIZE+1]; if (wrq->u.essid.pointer) { - rc = iwctl_giwessid(dev, NULL, - &(wrq->u.essid), essid); + iwctl_giwessid(dev, NULL, + &(wrq->u.essid), essid); if (copy_to_user(wrq->u.essid.pointer, essid, wrq->u.essid.length) ) -- cgit v1.2.3-70-g09d2 From 739ea07640f4dd3cc440b836ad6a88388c2dcf28 Mon Sep 17 00:00:00 2001 From: Marcos Paulo de Souza Date: Wed, 28 Dec 2011 21:13:39 +0000 Subject: staging: vt6656: iwctl.c: Remove return statement of iwctl_giwrate This function will always return 0, and this data is not used by who calls this function. Signed-off-by: Marcos Paulo de Souza Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/iwctl.c | 6 +----- drivers/staging/vt6656/iwctl.h | 2 +- drivers/staging/vt6656/main_usb.c | 3 +-- 3 files changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index d6c969a65cf..4f33b0c0812 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -965,8 +965,7 @@ int iwctl_siwrate(struct net_device *dev, /* * Wireless Handler : get data rate */ - -int iwctl_giwrate(struct net_device *dev, +void iwctl_giwrate(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) @@ -1004,9 +1003,6 @@ int iwctl_giwrate(struct net_device *dev, if (pDevice->bFixRate == TRUE) wrq->fixed = TRUE; } - - - return 0; } diff --git a/drivers/staging/vt6656/iwctl.h b/drivers/staging/vt6656/iwctl.h index 0bab0d755c5..bd38e9dc6f3 100644 --- a/drivers/staging/vt6656/iwctl.h +++ b/drivers/staging/vt6656/iwctl.h @@ -107,7 +107,7 @@ int iwctl_siwrate(struct net_device *dev, struct iw_param *wrq, char *extra); -int iwctl_giwrate(struct net_device *dev, +void iwctl_giwrate(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra); diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index 91b953cb6d3..33a451c6ac1 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -1698,8 +1698,7 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { // Get the current bit-rate case SIOCGIWRATE: - - rc = iwctl_giwrate(dev, NULL, &(wrq->u.bitrate), NULL); + iwctl_giwrate(dev, NULL, &(wrq->u.bitrate), NULL); break; // Set the desired RTS threshold -- cgit v1.2.3-70-g09d2 From 2fdde902ca4b19d051c5fa15f81dd6d900551db8 Mon Sep 17 00:00:00 2001 From: Marcos Paulo de Souza Date: Wed, 28 Dec 2011 21:18:31 +0000 Subject: staging: vt6656: iwctl.c: Rewrite siwrts funciton This function has the following issues: Parameter info and extra are not used Wrong error handling(the function not return -EINVAL when it happens) This patch simplifies this funtion, remove the not used parameters and fix the error handilng. Signed-off-by: Marcos Paulo de Souza Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/iwctl.c | 26 +++++++++----------------- drivers/staging/vt6656/iwctl.h | 5 +---- drivers/staging/vt6656/main_usb.c | 2 +- 3 files changed, 11 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index 4f33b0c0812..b24e5314a6a 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -1010,27 +1010,19 @@ void iwctl_giwrate(struct net_device *dev, /* * Wireless Handler : set rts threshold */ - int iwctl_siwrts(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) + struct iw_param *wrq) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - int rc = 0; + PSDevice pDevice = (PSDevice)netdev_priv(dev); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRTS \n"); + if ((wrq->value < 0 || wrq->value > 2312) && !wrq->disabled) + return -EINVAL; - { - int rthr = wrq->value; - if(wrq->disabled) - rthr = 2312; - if((rthr < 0) || (rthr > 2312)) { - rc = -EINVAL; - }else { - pDevice->wRTSThreshold = rthr; - } - } + else if (wrq->disabled) + pDevice->wRTSThreshold = 2312; + + else + pDevice->wRTSThreshold = wrq->value; return 0; } diff --git a/drivers/staging/vt6656/iwctl.h b/drivers/staging/vt6656/iwctl.h index bd38e9dc6f3..0c6e0496779 100644 --- a/drivers/staging/vt6656/iwctl.h +++ b/drivers/staging/vt6656/iwctl.h @@ -113,10 +113,7 @@ void iwctl_giwrate(struct net_device *dev, char *extra); int iwctl_siwrts(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra); - + struct iw_param *wrq); int iwctl_giwrts(struct net_device *dev, struct iw_request_info *info, diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index 33a451c6ac1..763e028a5cc 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -1704,7 +1704,7 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { // Set the desired RTS threshold case SIOCSIWRTS: - rc = iwctl_siwrts(dev, NULL, &(wrq->u.rts), NULL); + rc = iwctl_siwrts(dev, &(wrq->u.rts)); break; // Get the current RTS threshold -- cgit v1.2.3-70-g09d2 From 08afcf9c9f5b9372e26f3f29313f45528fafc15c Mon Sep 17 00:00:00 2001 From: mahendra singh meena Date: Mon, 16 Jan 2012 23:50:38 +0530 Subject: Staging: vt6655: Fix brace coding style issues in ioctl.c This patch fixes up unnecessary brace warnings found in ioctl.c by checkpatch.pl . Signed-off-by: Mahendra Singh Meena Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/ioctl.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/ioctl.c b/drivers/staging/vt6655/ioctl.c index 7fd5cc5a55f..ef197efab04 100644 --- a/drivers/staging/vt6655/ioctl.c +++ b/drivers/staging/vt6655/ioctl.c @@ -324,16 +324,16 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID; memset(pList->sBSSIDList[ii].abySSID, 0, WLAN_SSID_MAXLEN + 1); memcpy(pList->sBSSIDList[ii].abySSID, pItemSSID->abySSID, pItemSSID->len); - if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) { + if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) pList->sBSSIDList[ii].byNetType = INFRA; - } else { + else pList->sBSSIDList[ii].byNetType = ADHOC; - } - if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) { + + if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) pList->sBSSIDList[ii].bWEPOn = true; - } else { + else pList->sBSSIDList[ii].bWEPOn = false; - } + ii++; if (ii >= pList->uItem) break; @@ -367,9 +367,9 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) netif_stop_queue(pDevice->dev); spin_lock_irq(&pDevice->lock); - if (pDevice->bRadioOff == false) { + if (pDevice->bRadioOff == false) CARDbRadioPowerOff(pDevice); - } + pDevice->bLinkPass = false; memset(pMgmt->abyCurrBSSID, 0, 6); pMgmt->eCurrState = WMAC_STATE_IDLE; @@ -489,13 +489,12 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) break; } - if (sStartAPCmd.wBBPType == PHY80211g) { + if (sStartAPCmd.wBBPType == PHY80211g) pMgmt->byAPBBType = PHY_TYPE_11G; - } else if (sStartAPCmd.wBBPType == PHY80211a) { + else if (sStartAPCmd.wBBPType == PHY80211a) pMgmt->byAPBBType = PHY_TYPE_11A; - } else { + else pMgmt->byAPBBType = PHY_TYPE_11B; - } pItemSSID = (PWLAN_IE_SSID)sStartAPCmd.ssid; if (pItemSSID->len > WLAN_SSID_MAXLEN + 1) -- cgit v1.2.3-70-g09d2 From 4e1efd6e853977a134ff262230ccb4b69319d926 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 16 Jan 2012 21:28:23 +0100 Subject: staging, vt6656/wpactl.c: A basic style cleanup This patch cleans up the coding style in drivers/staging/vt6656/wpactl.c to closer match the generally accepted kernel CodingStyle. It is by no means a "make it perfect" patch, but it does get the file a fair bit closer to matching the accepted style (whomever was involved in the evolution of this file seriously need to configure their editors to maintain a consistent style - it was a mess). Besides pure style cleanups I also took the liberty of removing some pointless parens, some unneeded casts and removing some commented out code (it was obviously not used and git has it if it's ever needed in the future). Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/wpactl.c | 936 ++++++++++++++++++---------------------- 1 file changed, 418 insertions(+), 518 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/wpactl.c b/drivers/staging/vt6656/wpactl.c index 2fa4f845a75..9d148686635 100644 --- a/drivers/staging/vt6656/wpactl.c +++ b/drivers/staging/vt6656/wpactl.c @@ -46,23 +46,18 @@ #define VIAWGET_WPA_MAX_BUF_SIZE 1024 - - static const int frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484 }; + /*--------------------- Static Classes ----------------------------*/ /*--------------------- Static Variables --------------------------*/ -//static int msglevel =MSG_LEVEL_DEBUG; -static int msglevel =MSG_LEVEL_INFO; +static int msglevel = MSG_LEVEL_INFO; /*--------------------- Static Functions --------------------------*/ - - - /*--------------------- Export Variables --------------------------*/ static void wpadev_setup(struct net_device *dev) { @@ -72,9 +67,9 @@ 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; + dev->flags = IFF_BROADCAST | IFF_MULTICAST; } /* @@ -90,45 +85,43 @@ static void wpadev_setup(struct net_device *dev) * Return Value: * */ - 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; } - /* * Description: * unregister net_device (wpadev) @@ -141,29 +134,24 @@ static int wpa_init_wpadev(PSDevice pDevice) * Return Value: * */ - static int wpa_release_wpadev(PSDevice pDevice) { - if (pDevice->skb) { - dev_kfree_skb(pDevice->skb); - pDevice->skb = 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; - } + 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; } - - - - /* * Description: * Set enable/disable dev for wpa supplicant deamon @@ -177,13 +165,11 @@ static int wpa_release_wpadev(PSDevice pDevice) * Return Value: * */ - int wpa_set_wpadev(PSDevice pDevice, int val) { if (val) return wpa_init_wpadev(pDevice); - else - return wpa_release_wpadev(pDevice); + return wpa_release_wpadev(pDevice); } /* @@ -199,245 +185,217 @@ int wpa_set_wpadev(PSDevice pDevice, int val) * Return Value: * */ - int wpa_set_keys(PSDevice pDevice, void *ctx, BOOL fcpfkernel) { - struct viawget_wpa_param *param=ctx; - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - DWORD dwKeyIndex = 0; - BYTE abyKey[MAX_KEY_LEN]; - BYTE abySeq[MAX_KEY_LEN]; - QWORD KeyRSC; -// NDIS_802_11_KEY_RSC KeyRSC; - BYTE byKeyDecMode = KEY_CTL_WEP; + struct viawget_wpa_param *param = ctx; + PSMgmtObject pMgmt = &pDevice->sMgmtObj; + DWORD dwKeyIndex = 0; + BYTE abyKey[MAX_KEY_LEN]; + BYTE abySeq[MAX_KEY_LEN]; + QWORD KeyRSC; + BYTE byKeyDecMode = KEY_CTL_WEP; int ret = 0; - int uu, ii; - + int uu; + int ii; if (param->u.wpa_key.alg_name > WPA_ALG_CCMP) 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; - for (uu=0; uueEncryptionStatus = Ndis802_11EncryptionDisabled; + pDevice->bEncryptionEnable = FALSE; + pDevice->byKeyIndex = 0; + pDevice->bTransmitKey = FALSE; + for (uu=0; uuu.wpa_key.key && param->u.wpa_key.key_len > sizeof(abyKey)) return -EINVAL; - 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 { - 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_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 { + 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); + spin_lock_irq(&pDevice->lock); - dwKeyIndex = (DWORD)(param->u.wpa_key.key_index); + dwKeyIndex = (DWORD)(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 = (BYTE)dwKeyIndex; - pDevice->bTransmitKey = TRUE; - dwKeyIndex |= (1 << 31); - } - KeybSetDefaultKey( pDevice, - &(pDevice->sKey), - dwKeyIndex & ~(BIT30 | USE_KEYRSC), - param->u.wpa_key.key_len, - NULL, - abyKey, - KEY_CTL_WEP - ); - - } - pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - pDevice->bEncryptionEnable = TRUE; - return ret; + if (dwKeyIndex > 3) { + return -EINVAL; + } else { + if (param->u.wpa_key.set_tx) { + pDevice->byKeyIndex = (BYTE)dwKeyIndex; + pDevice->bTransmitKey = TRUE; + dwKeyIndex |= (1 << 31); + } + KeybSetDefaultKey( pDevice, + &(pDevice->sKey), + dwKeyIndex & ~(BIT30 | USE_KEYRSC), + param->u.wpa_key.key_len, + NULL, + abyKey, + KEY_CTL_WEP + ); + + } + pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; + pDevice->bEncryptionEnable = TRUE; + return ret; } if (param->u.wpa_key.seq && param->u.wpa_key.seq_len > sizeof(abySeq)) return -EINVAL; - 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 { - 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_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 { + 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)); + if (ii < 4) + LODWORD(KeyRSC) |= (abySeq[ii] << (ii * 8)); + else + HIDWORD(KeyRSC) |= (abySeq[ii] << ((ii-4) * 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_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return - AES Key must be 128 bits\n"); - return -EINVAL; - } + 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; + } - if (is_broadcast_ether_addr(¶m->addr[0]) || (param->addr == NULL)) { - /* if broadcast, set the key as every key entry's group key */ - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Groupe Key Assign.\n"); - - if ((KeybSetAllGroupKey(pDevice, - &(pDevice->sKey), - dwKeyIndex, - param->u.wpa_key.key_len, - (PQWORD) &(KeyRSC), - (PBYTE)abyKey, - byKeyDecMode - ) == TRUE) && - (KeybSetDefaultKey(pDevice, - &(pDevice->sKey), - dwKeyIndex, - param->u.wpa_key.key_len, - (PQWORD) &(KeyRSC), - (PBYTE)abyKey, - byKeyDecMode - ) == 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")); - 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"); - 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")); - return -EINVAL; - } - if (KeybSetKey(pDevice, - &(pDevice->sKey), - ¶m->addr[0], - dwKeyIndex, - param->u.wpa_key.key_len, - (PQWORD) &(KeyRSC), - (PBYTE)abyKey, - byKeyDecMode - ) == 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")); - return -EINVAL; - - } else { - // Save Key and configure just before associate/reassociate to BSSID - // we do not implement now - return -EINVAL; - } - } - } // BSSID not 0xffffffffffff - if ((ret == 0) && ((param->u.wpa_key.set_tx) != 0)) { - pDevice->byKeyIndex = (BYTE)param->u.wpa_key.key_index; - pDevice->bTransmitKey = TRUE; + // 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_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return- TKIP Key must be 256 bits!\n"); + return -EINVAL; } - pDevice->bEncryptionEnable = TRUE; + // 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_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return - AES Key must be 128 bits\n"); + return -EINVAL; + } -/* - 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] - ); -*/ + if (is_broadcast_ether_addr(¶m->addr[0]) || (param->addr == NULL)) { + /* if broadcast, set the key as every key entry's group key */ + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Groupe Key Assign.\n"); + + if ((KeybSetAllGroupKey(pDevice, &(pDevice->sKey), dwKeyIndex, + param->u.wpa_key.key_len, + (PQWORD) &(KeyRSC), + (PBYTE)abyKey, + byKeyDecMode + ) == TRUE) && + (KeybSetDefaultKey(pDevice, + &(pDevice->sKey), + dwKeyIndex, + param->u.wpa_key.key_len, + (PQWORD) &(KeyRSC), + (PBYTE)abyKey, + byKeyDecMode + ) == TRUE) ) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GROUP Key Assign.\n"); + } else { + 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"); + 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")); + return -EINVAL; + } + if (KeybSetKey(pDevice, &(pDevice->sKey), ¶m->addr[0], + dwKeyIndex, param->u.wpa_key.key_len, + (PQWORD) &(KeyRSC), (PBYTE)abyKey, byKeyDecMode + ) == 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")); + return -EINVAL; + } else { + // Save Key and configure just before associate/reassociate to BSSID + // we do not implement now + return -EINVAL; + } + } + } // BSSID not 0xffffffffffff + if ((ret == 0) && ((param->u.wpa_key.set_tx) != 0)) { + pDevice->byKeyIndex = (BYTE)param->u.wpa_key.key_index; + pDevice->bTransmitKey = TRUE; + } + pDevice->bEncryptionEnable = TRUE; return ret; - } @@ -454,23 +412,17 @@ int wpa_set_wpadev(PSDevice pDevice, int val) * Return Value: * */ - -static int wpa_set_wpa(PSDevice pDevice, - struct viawget_wpa_param *param) +static int wpa_set_wpa(PSDevice pDevice, struct viawget_wpa_param *param) { - - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSMgmtObject pMgmt = &pDevice->sMgmtObj; 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 @@ -484,25 +436,21 @@ static int wpa_set_wpa(PSDevice pDevice, * Return Value: * */ - -static int wpa_set_disassociate(PSDevice pDevice, - struct viawget_wpa_param *param) +static int wpa_set_disassociate(PSDevice pDevice, struct viawget_wpa_param *param) { - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSMgmtObject pMgmt = &pDevice->sMgmtObj; 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; } - - /* * Description: * enable scan process @@ -516,36 +464,30 @@ static int wpa_set_disassociate(PSDevice pDevice, * Return Value: * */ - -static int wpa_set_scan(PSDevice pDevice, - struct viawget_wpa_param *param) +static int wpa_set_scan(PSDevice pDevice, struct viawget_wpa_param *param) { int ret = 0; /**set ap_scan=1&&scan_ssid=1 under hidden ssid mode**/ - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - PWLAN_IE_SSID pItemSSID; -printk("wpa_set_scan-->desired [ssid=%s,ssid_len=%d]\n", - param->u.scan_req.ssid,param->u.scan_req.ssid_len); + PSMgmtObject pMgmt = &pDevice->sMgmtObj; + PWLAN_IE_SSID pItemSSID; + printk("wpa_set_scan-->desired [ssid=%s,ssid_len=%d]\n", + param->u.scan_req.ssid,param->u.scan_req.ssid_len); // 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; -memcpy(pItemSSID->abySSID, param->u.scan_req.ssid, param->u.scan_req.ssid_len); -pItemSSID->len = param->u.scan_req.ssid_len; - - spin_lock_irq(&pDevice->lock); - BSSvClearBSSList((void *) pDevice, pDevice->bLinkPass); - /* bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL); */ - bScheduleCommand((void *) pDevice, - WLAN_CMD_BSSID_SCAN, - pMgmt->abyDesireSSID); - spin_unlock_irq(&pDevice->lock); - - return ret; -} + memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); + pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; + pItemSSID->byElementID = WLAN_EID_SSID; + memcpy(pItemSSID->abySSID, param->u.scan_req.ssid, param->u.scan_req.ssid_len); + pItemSSID->len = param->u.scan_req.ssid_len; + spin_lock_irq(&pDevice->lock); + BSSvClearBSSList((void *) pDevice, pDevice->bLinkPass); + bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, + pMgmt->abyDesireSSID); + spin_unlock_irq(&pDevice->lock); + return ret; +} /* * Description: @@ -560,19 +502,15 @@ pItemSSID->len = param->u.scan_req.ssid_len; * Return Value: * */ - -static int wpa_get_bssid(PSDevice pDevice, - struct viawget_wpa_param *param) +static int wpa_get_bssid(PSDevice pDevice, struct viawget_wpa_param *param) { - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - int ret = 0; - memcpy(param->u.wpa_associate.bssid, pMgmt->abyCurrBSSID , 6); + PSMgmtObject pMgmt = &pDevice->sMgmtObj; + int ret = 0; + memcpy(param->u.wpa_associate.bssid, pMgmt->abyCurrBSSID, 6); return ret; - } - /* * Description: * get bssid @@ -586,24 +524,20 @@ static int wpa_get_bssid(PSDevice pDevice, * Return Value: * */ - -static int wpa_get_ssid(PSDevice pDevice, - struct viawget_wpa_param *param) +static int wpa_get_ssid(PSDevice pDevice, struct viawget_wpa_param *param) { - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - PWLAN_IE_SSID pItemSSID; + PSMgmtObject pMgmt = &pDevice->sMgmtObj; + 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); + memcpy(param->u.wpa_associate.ssid, pItemSSID->abySSID, pItemSSID->len); param->u.wpa_associate.ssid_len = pItemSSID->len; - return ret; + return ret; } - - /* * Description: * get scan results @@ -617,135 +551,114 @@ static int wpa_get_ssid(PSDevice pDevice, * Return Value: * */ - -static int wpa_get_scan(PSDevice pDevice, - struct viawget_wpa_param *param) +static int wpa_get_scan(PSDevice pDevice, struct viawget_wpa_param *param) { struct viawget_scan_result *scan_buf; - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - PWLAN_IE_SSID pItemSSID; - PKnownBSS pBSS; - PBYTE pBuf; + PSMgmtObject pMgmt = &pDevice->sMgmtObj; + PWLAN_IE_SSID pItemSSID; + PKnownBSS pBSS; + PBYTE pBuf; int ret = 0; u16 count = 0; - u16 ii, jj; - long ldBm;//James //add + u16 ii; + u16 jj; + long ldBm; //James //add //******mike:bubble sort by stronger RSSI*****// + PBYTE ptempBSS; - PBYTE ptempBSS; - + ptempBSS = kmalloc(sizeof(KnownBSS), GFP_ATOMIC); + if (ptempBSS == NULL) { + printk("bubble sort kmalloc memory fail@@@\n"); + ret = -ENOMEM; + return ret; + } - ptempBSS = kmalloc(sizeof(KnownBSS), (int)GFP_ATOMIC); - - if (ptempBSS == NULL) { - - printk("bubble sort kmalloc memory fail@@@\n"); - - ret = -ENOMEM; - - return ret; - - } - - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - - for (jj = 0; jj < MAX_BSS_NUM - ii - 1; jj++) { - - if ((pMgmt->sBSSList[jj].bActive != TRUE) || - - ((pMgmt->sBSSList[jj].uRSSI>pMgmt->sBSSList[jj+1].uRSSI) &&(pMgmt->sBSSList[jj+1].bActive!=FALSE))) { - - memcpy(ptempBSS,&pMgmt->sBSSList[jj],sizeof(KnownBSS)); - - memcpy(&pMgmt->sBSSList[jj],&pMgmt->sBSSList[jj+1],sizeof(KnownBSS)); - - memcpy(&pMgmt->sBSSList[jj+1],ptempBSS,sizeof(KnownBSS)); - - } - - } - - } - - kfree(ptempBSS); - - // printk("bubble sort result:\n"); + for (ii = 0; ii < MAX_BSS_NUM; ii++) { + for (jj = 0; jj < MAX_BSS_NUM - ii - 1; jj++) { + if ((pMgmt->sBSSList[jj].bActive != TRUE) + || ((pMgmt->sBSSList[jj].uRSSI > pMgmt->sBSSList[jj + 1].uRSSI) + && (pMgmt->sBSSList[jj + 1].bActive != FALSE))) { + memcpy(ptempBSS,&pMgmt->sBSSList[jj], sizeof(KnownBSS)); + memcpy(&pMgmt->sBSSList[jj], &pMgmt->sBSSList[jj + 1], + sizeof(KnownBSS)); + memcpy(&pMgmt->sBSSList[jj + 1], ptempBSS, sizeof(KnownBSS)); + } + } + } + kfree(ptempBSS); count = 0; pBSS = &(pMgmt->sBSSList[0]); - for (ii = 0; ii < MAX_BSS_NUM; ii++) { - pBSS = &(pMgmt->sBSSList[ii]); - if (!pBSS->bActive) - continue; - count++; - } + 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); + pBuf = kcalloc(count, sizeof(struct viawget_scan_result), GFP_ATOMIC); - if (pBuf == NULL) { - ret = -ENOMEM; - return ret; - } - scan_buf = (struct viawget_scan_result *)pBuf; + 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; //DavidWang for sharemode - - RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm); - if(-ldBm<50){ + 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; // DavidWang for sharemode + + RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm); + if (-ldBm < 50) scan_buf->qual = 100; - }else if(-ldBm > 90) { - scan_buf->qual = 0; - }else { + else if (-ldBm > 90) + scan_buf->qual = 0; + else scan_buf->qual=(40-(-ldBm-50))*100/40; - } //James - //scan_buf->caps = pBSS->wCapInfo; - //scan_buf->qual = - scan_buf->noise = 0; - scan_buf->level = ldBm; - - //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 *)((PBYTE)scan_buf + sizeof(struct viawget_scan_result)); - jj ++; - } - } + //scan_buf->caps = pBSS->wCapInfo; + //scan_buf->qual = + scan_buf->noise = 0; + scan_buf->level = ldBm; + + //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 *)((PBYTE)scan_buf + sizeof(struct viawget_scan_result)); + jj ++; + } + } - if (jj < count) - count = jj; + if (jj < count) + count = jj; - if (copy_to_user(param->u.scan_results.buf, pBuf, sizeof(struct viawget_scan_result) * count)) { + 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; } - - /* * Description: * set associate with AP @@ -759,25 +672,23 @@ static int wpa_get_scan(PSDevice pDevice, * Return Value: * */ - -static int wpa_set_associate(PSDevice pDevice, - struct viawget_wpa_param *param) +static int wpa_set_associate(PSDevice pDevice, struct viawget_wpa_param *param) { - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - PWLAN_IE_SSID pItemSSID; - BYTE abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - BYTE abyWPAIE[64]; - int ret = 0; - BOOL bwepEnabled=FALSE; + PSMgmtObject pMgmt = &pDevice->sMgmtObj; + PWLAN_IE_SSID pItemSSID; + BYTE abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + BYTE 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 "Roaming dBm = %d\n", param->u.wpa_associate.roam_dbm); //Davidwang + 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 "Roaming dBm = %d\n", param->u.wpa_associate.roam_dbm); // Davidwang if (param->u.wpa_associate.wpa_ie) { if (param->u.wpa_associate.wpa_ie_len > sizeof(abyWPAIE)) @@ -789,25 +700,25 @@ 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; + pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; // set bssid - if (memcmp(param->u.wpa_associate.bssid, &abyNullAddr[0], 6) != 0) - memcpy(pMgmt->abyDesireBSSID, param->u.wpa_associate.bssid, 6); - // set ssid + if (memcmp(param->u.wpa_associate.bssid, &abyNullAddr[0], 6) != 0) + memcpy(pMgmt->abyDesireBSSID, param->u.wpa_associate.bssid, 6); + // 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); - 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; @@ -817,9 +728,9 @@ static int wpa_set_associate(PSDevice pDevice, 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) { @@ -833,7 +744,6 @@ static int wpa_set_associate(PSDevice pDevice, case CIPHER_WEP104: pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; bwepEnabled = TRUE; - // printk("****************wpa_set_associate:set CIPHER_WEP40_104\n"); break; case CIPHER_NONE: if (param->u.wpa_associate.group_suite == CIPHER_CCMP) @@ -845,70 +755,64 @@ static int wpa_set_associate(PSDevice pDevice, pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; } - pMgmt->Roam_dbm = param->u.wpa_associate.roam_dbm; - // if ((pMgmt->Roam_dbm > 40)&&(pMgmt->Roam_dbm<80)) - // pDevice->bEnableRoaming = TRUE; - - if (pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) { //@wep-sharekey - pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - pMgmt->bShareKeyAlgorithm = TRUE; - } - else if (pMgmt->eAuthenMode == WMAC_AUTH_OPEN) { - if(bwepEnabled==TRUE) { //@open-wep - pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; - } - else { //@only open - pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; + pMgmt->Roam_dbm = param->u.wpa_associate.roam_dbm; + if (pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) { // @wep-sharekey + pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; + pMgmt->bShareKeyAlgorithm = TRUE; + } else if (pMgmt->eAuthenMode == WMAC_AUTH_OPEN) { + if(bwepEnabled==TRUE) { //@open-wep + pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; + } else { + // @only open + pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; } - } -//mike save old encryption status + } + // 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))) { - //mike re-comment:open-wep && sharekey-wep needn't do initial key!! - - } - else - KeyvInitTable(pDevice,&pDevice->sKey); + if (pDevice->eEncryptionStatus != Ndis802_11EncryptionDisabled) + pDevice->bEncryptionEnable = TRUE; + else + pDevice->bEncryptionEnable = FALSE; - spin_lock_irq(&pDevice->lock); - pDevice->bLinkPass = FALSE; - ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW); - memset(pMgmt->abyCurrBSSID, 0, 6); - pMgmt->eCurrState = WMAC_STATE_IDLE; - netif_stop_queue(pDevice->dev); + if ((pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) || + ((pMgmt->eAuthenMode == WMAC_AUTH_OPEN) && (bwepEnabled==TRUE))) { + // mike re-comment:open-wep && sharekey-wep needn't do initial key!! + } else { + KeyvInitTable(pDevice,&pDevice->sKey); + } -/*******search if ap_scan=2 ,which is associating request in hidden ssid mode ****/ -{ - PKnownBSS pCurr = NULL; - pCurr = BSSpSearchBSSList(pDevice, - pMgmt->abyDesireBSSID, - pMgmt->abyDesireSSID, - pDevice->eConfigPHYMode - ); - - if (pCurr == NULL){ - printk("wpa_set_associate---->hidden mode site survey before associate.......\n"); - bScheduleCommand((void *) pDevice, - WLAN_CMD_BSSID_SCAN, - pMgmt->abyDesireSSID); - } -} + spin_lock_irq(&pDevice->lock); + pDevice->bLinkPass = FALSE; + ControlvMaskByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PAPEDELAY, LEDSTS_STS, LEDSTS_SLOW); + memset(pMgmt->abyCurrBSSID, 0, 6); + pMgmt->eCurrState = WMAC_STATE_IDLE; + netif_stop_queue(pDevice->dev); + +/******* search if ap_scan=2, which is associating request in hidden ssid mode ****/ + { + PKnownBSS pCurr = NULL; + pCurr = BSSpSearchBSSList(pDevice, + pMgmt->abyDesireBSSID, + pMgmt->abyDesireSSID, + pDevice->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; } - /* * Description: * wpa_ioctl main function supported for wpa supplicant @@ -922,7 +826,6 @@ static int wpa_set_associate(PSDevice pDevice, * Return Value: * */ - int wpa_ioctl(PSDevice pDevice, struct iw_point *p) { struct viawget_wpa_param *param; @@ -930,10 +833,10 @@ int wpa_ioctl(PSDevice pDevice, struct iw_point *p) int wpa_ioctl = 0; if (p->length < sizeof(struct viawget_wpa_param) || - p->length > VIAWGET_WPA_MAX_BUF_SIZE || !p->pointer) + p->length > VIAWGET_WPA_MAX_BUF_SIZE || !p->pointer) return -EINVAL; - param = kmalloc((int)p->length, (int)GFP_KERNEL); + param = kmalloc((int)p->length, GFP_KERNEL); if (param == NULL) return -ENOMEM; @@ -944,63 +847,62 @@ 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; } if ((ret == 0) && wpa_ioctl) { @@ -1012,7 +914,5 @@ int wpa_ioctl(PSDevice pDevice, struct iw_point *p) out: kfree(param); - return ret; } - -- cgit v1.2.3-70-g09d2 From e3b09e4bf6455caccc7ef215256e4f0065fbca7d Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 16 Jan 2012 21:28:37 +0100 Subject: staging, vt6656/wpactl.c: Fix mem leak in wpa_ioctl() If we hit the default case in the switch statement in wpa_ioctl() we'll leak the memory allocated to 'param' when the variable goes out of scope without having been assigned to anything. This patch fixes the leak by kfree()'ing the memory before we return from the function. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/wpactl.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/vt6656/wpactl.c b/drivers/staging/vt6656/wpactl.c index 9d148686635..5435e8205b2 100644 --- a/drivers/staging/vt6656/wpactl.c +++ b/drivers/staging/vt6656/wpactl.c @@ -902,6 +902,7 @@ int wpa_ioctl(PSDevice pDevice, struct iw_point *p) default: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ioctl: unknown cmd=%d\n", param->cmd); + kfree(param); return -EOPNOTSUPP; } -- cgit v1.2.3-70-g09d2 From e24b0a3f0c9ab95a7910458f3b4d90fdf19954e2 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Sun, 15 Jan 2012 20:34:52 +0100 Subject: staging/xgifb: Remove unsupported mode LCD_320x480 This patch removes the probed mode LCD_320x480 which isn't supported anyway since this mode falls through to the default (=invalid) mode in the XGIfb_validate_mode function (see line 529 ff. for details. the commented out code for this mode is also removed). By removing this assignment, we can use the LCD_TYPEs from the sis driver without modifications. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 2502c49c9c5..e618aa6d63b 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -526,12 +526,6 @@ static int XGIfb_validate_mode(struct xgifb_video_info *xgifb_info, int myindex) xres = 1600; yres = 1200; break; - /* case LCD_320x480: */ /* TW: FSTN */ - /* - xres = 320; - yres = 480; - break; - */ default: xres = 0; yres = 0; @@ -2117,10 +2111,6 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, reg = xgifb_reg_get(XGICR, IND_XGI_LCD_PANEL); reg &= 0x0f; hw_info->ulCRT2LCDType = XGI310paneltype[reg]; - - } else { - /* TW: FSTN/DSTN */ - hw_info->ulCRT2LCDType = LCD_320x480; } } -- cgit v1.2.3-70-g09d2 From b33704dffa36f3ed972602ea9ef8b46d3d5e3b06 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Sun, 15 Jan 2012 19:22:11 +0100 Subject: staging/xgifb: Include sis headers This patch includes the headers of the sis driver and reorders some includes. Since the xgi driver used to redefine a lot of stuff from the sis driver, we can simply include the headers of the sis driver itself, so we can remove duplicated stuff later on. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main.h | 1 + drivers/staging/xgifb/XGIfb.h | 2 +- drivers/staging/xgifb/vb_init.c | 2 +- drivers/staging/xgifb/vb_struct.h | 1 + drivers/staging/xgifb/vgatypes.h | 9 +++++++++ 5 files changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index 35f7b2a485e..fdee421cd49 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -7,6 +7,7 @@ #include "XGIfb.h" #include "vb_struct.h" +#include "../../video/sis/sis.h" #include "vb_def.h" #define XGIFAIL(x) do { printk(x "\n"); return -EINVAL; } while (0) diff --git a/drivers/staging/xgifb/XGIfb.h b/drivers/staging/xgifb/XGIfb.h index 2c866bb65a0..37bb730de04 100644 --- a/drivers/staging/xgifb/XGIfb.h +++ b/drivers/staging/xgifb/XGIfb.h @@ -3,8 +3,8 @@ #include #include -#include "vb_struct.h" #include "vgatypes.h" +#include "vb_struct.h" enum xgifb_display_type { XGIFB_DISP_NONE = 0, diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 4ccd988ffd7..a53a097131b 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -3,8 +3,8 @@ #include #include -#include "vgatypes.h" #include "XGIfb.h" +#include "vgatypes.h" #include "vb_def.h" #include "vb_struct.h" diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 6556a0d6ff8..d70df04e7dc 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -10,6 +10,7 @@ struct XGI_LCDDataStruct { unsigned short LCDVT; }; +#include "../../video/sis/vstruct.h" struct XGI_LVDSCRT1HDataStruct { unsigned char Reg[8]; diff --git a/drivers/staging/xgifb/vgatypes.h b/drivers/staging/xgifb/vgatypes.h index 9e166bbb00c..a7208e31581 100644 --- a/drivers/staging/xgifb/vgatypes.h +++ b/drivers/staging/xgifb/vgatypes.h @@ -2,6 +2,9 @@ #define _VGATYPES_ #include +#include /* for struct fb_var_screeninfo for sis.h */ +#include "../../video/sis/vgatypes.h" +#include "../../video/sis/sis.h" /* for LCD_TYPE */ #ifndef XGI_VB_CHIP_TYPE enum XGI_VB_CHIP_TYPE { @@ -19,6 +22,12 @@ enum XGI_VB_CHIP_TYPE { }; #endif + +#define XGI_LCD_TYPE +/* Since the merge with video/sis the LCD_TYPEs are used from + drivers/video/sis/sis.h . Nevertheless we keep this (for the moment) for + future reference until the code is merged completely and we are sure + nothing of this should be added to the sis.h header */ #ifndef XGI_LCD_TYPE enum XGI_LCD_TYPE { LCD_INVALID = 0, -- cgit v1.2.3-70-g09d2 From fc39dcb7fa8bb917484a5b229cf3751dd3aa7313 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Sun, 15 Jan 2012 19:22:12 +0100 Subject: staging/xgifb: Use structs and defines from the sis headers This patch removes the usage of some xgi structs and defines and replaces them with the _identical_ structs from the sis headers. Thus the old structs and defines can be removed. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 88 ++++++++++++++++++------------------- drivers/staging/xgifb/vb_setmode.c | 22 +++++----- drivers/staging/xgifb/vb_struct.h | 12 ++--- drivers/staging/xgifb/vb_table.h | 10 ++--- 4 files changed, 66 insertions(+), 66 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index e618aa6d63b..ff7a144044c 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -805,27 +805,27 @@ static void XGIfb_pre_setmode(struct xgifb_video_info *xgifb_info) switch (xgifb_info->display2) { case XGIFB_DISP_CRT: - cr30 = (XGI_VB_OUTPUT_CRT2 | XGI_SIMULTANEOUS_VIEW_ENABLE); - cr31 |= XGI_DRIVER_MODE; + cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE); + cr31 |= SIS_DRIVER_MODE; break; case XGIFB_DISP_LCD: - cr30 = (XGI_VB_OUTPUT_LCD | XGI_SIMULTANEOUS_VIEW_ENABLE); - cr31 |= XGI_DRIVER_MODE; + cr30 = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE); + cr31 |= SIS_DRIVER_MODE; break; case XGIFB_DISP_TV: if (xgifb_info->TV_type == TVMODE_HIVISION) - cr30 = (XGI_VB_OUTPUT_HIVISION - | XGI_SIMULTANEOUS_VIEW_ENABLE); + cr30 = (SIS_VB_OUTPUT_HIVISION + | SIS_SIMULTANEOUS_VIEW_ENABLE); else if (xgifb_info->TV_plug == TVPLUG_SVIDEO) - cr30 = (XGI_VB_OUTPUT_SVIDEO - | XGI_SIMULTANEOUS_VIEW_ENABLE); + cr30 = (SIS_VB_OUTPUT_SVIDEO + | SIS_SIMULTANEOUS_VIEW_ENABLE); else if (xgifb_info->TV_plug == TVPLUG_COMPOSITE) - cr30 = (XGI_VB_OUTPUT_COMPOSITE - | XGI_SIMULTANEOUS_VIEW_ENABLE); + cr30 = (SIS_VB_OUTPUT_COMPOSITE + | SIS_SIMULTANEOUS_VIEW_ENABLE); else if (xgifb_info->TV_plug == TVPLUG_SCART) - cr30 = (XGI_VB_OUTPUT_SCART - | XGI_SIMULTANEOUS_VIEW_ENABLE); - cr31 |= XGI_DRIVER_MODE; + cr30 = (SIS_VB_OUTPUT_SCART + | SIS_SIMULTANEOUS_VIEW_ENABLE); + cr31 |= SIS_DRIVER_MODE; if (XGIfb_tvmode == 1 || xgifb_info->TV_type == TVMODE_PAL) cr31 |= 0x01; @@ -834,7 +834,7 @@ static void XGIfb_pre_setmode(struct xgifb_video_info *xgifb_info) break; default: /* disable CRT2 */ cr30 = 0x00; - cr31 |= (XGI_DRIVER_MODE | XGI_VB_OUTPUT_DISABLE); + cr31 |= (SIS_DRIVER_MODE | SIS_VB_OUTPUT_DISABLE); } xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30); @@ -848,7 +848,7 @@ static void XGIfb_post_setmode(struct xgifb_video_info *xgifb_info) u8 reg; unsigned char doit = 1; /* - xgifb_reg_set(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD); + xgifb_reg_set(XGISR,IND_SIS_PASSWORD,SIS_PASSWORD); xgifb_reg_set(XGICR, 0x13, 0x00); xgifb_reg_and_or(XGISR,0x0E, 0xF0, 0x01); *test* @@ -884,7 +884,7 @@ static void XGIfb_post_setmode(struct xgifb_video_info *xgifb_info) reg |= 0x80; xgifb_reg_set(XGICR, 0x17, reg); - xgifb_reg_and(XGISR, IND_XGI_RAMDAC_CONTROL, ~0x04); + xgifb_reg_and(XGISR, IND_SIS_RAMDAC_CONTROL, ~0x04); if (xgifb_info->display2 == XGIFB_DISP_TV && xgifb_info->hasVB == HASVB_301) { @@ -917,7 +917,7 @@ static void XGIfb_post_setmode(struct xgifb_video_info *xgifb_info) break; } xgifb_reg_or(XGIPART1, - IND_XGI_CRT2_WRITE_ENABLE_315, + SIS_CRT2_WENABLE_315, 0x01); if (xgifb_info->TV_type == TVMODE_NTSC) { @@ -1178,7 +1178,7 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, info->fix.line_length = ((info->var.xres_virtual * info->var.bits_per_pixel) >> 6); - xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD); + xgifb_reg_set(XGISR, IND_SIS_PASSWORD, SIS_PASSWORD); xgifb_reg_set(XGICR, 0x13, (info->fix.line_length & 0x00ff)); xgifb_reg_set(XGISR, @@ -1267,7 +1267,7 @@ static int XGIfb_pan_var(struct fb_var_screeninfo *var, struct fb_info *info) break; } - xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD); + xgifb_reg_set(XGISR, IND_SIS_PASSWORD, SIS_PASSWORD); xgifb_reg_set(XGICR, 0x0D, base & 0xFF); xgifb_reg_set(XGICR, 0x0C, (base >> 8) & 0xFF); @@ -1276,7 +1276,7 @@ static int XGIfb_pan_var(struct fb_var_screeninfo *var, struct fb_info *info) xgifb_reg_and_or(XGISR, 0x37, 0xDF, (base >> 21) & 0x04); if (xgifb_info->display2 != XGIFB_DISP_NONE) { - xgifb_reg_or(XGIPART1, IND_XGI_CRT2_WRITE_ENABLE_315, 0x01); + xgifb_reg_or(XGIPART1, SIS_CRT2_WENABLE_315, 0x01); xgifb_reg_set(XGIPART1, 0x06, (base & 0xFF)); xgifb_reg_set(XGIPART1, 0x05, ((base >> 8) & 0xFF)); xgifb_reg_set(XGIPART1, 0x04, ((base >> 16) & 0xFF)); @@ -1381,7 +1381,7 @@ static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con, fix->line_length = xgifb_info->video_linelength; fix->mmio_start = xgifb_info->mmio_base; fix->mmio_len = xgifb_info->mmio_size; - fix->accel = FB_ACCEL_XGI_XABRE; + fix->accel = FB_ACCEL_SIS_XABRE; DEBUGPRN("end of get_fix"); return 0; @@ -1628,9 +1628,9 @@ static int XGIfb_get_dram_size(struct xgifb_video_info *xgifb_info) /* xorg driver sets 32MB * 1 channel */ if (xgifb_info->chip == XG27) - xgifb_reg_set(XGISR, IND_XGI_DRAM_SIZE, 0x51); + xgifb_reg_set(XGISR, IND_SIS_DRAM_SIZE, 0x51); - reg = xgifb_reg_get(XGISR, IND_XGI_DRAM_SIZE); + reg = xgifb_reg_get(XGISR, IND_SIS_DRAM_SIZE); switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) { case XGI_DRAM_SIZE_1MB: xgifb_info->video_size = 0x100000; @@ -1730,7 +1730,7 @@ static void XGIfb_detect_VB(struct xgifb_video_info *xgifb_info) cr32 = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR32); - if ((cr32 & XGI_CRT1) && !XGIfb_crt1off) + if ((cr32 & SIS_CRT1) && !XGIfb_crt1off) XGIfb_crt1off = 0; else { if (cr32 & 0x5F) @@ -1740,11 +1740,11 @@ static void XGIfb_detect_VB(struct xgifb_video_info *xgifb_info) } if (!xgifb_info->display2_force) { - if (cr32 & XGI_VB_TV) + if (cr32 & SIS_VB_TV) xgifb_info->display2 = XGIFB_DISP_TV; - else if (cr32 & XGI_VB_LCD) + else if (cr32 & SIS_VB_LCD) xgifb_info->display2 = XGIFB_DISP_LCD; - else if (cr32 & XGI_VB_CRT2) + else if (cr32 & SIS_VB_CRT2) xgifb_info->display2 = XGIFB_DISP_CRT; else xgifb_info->display2 = XGIFB_DISP_NONE; @@ -1753,14 +1753,14 @@ static void XGIfb_detect_VB(struct xgifb_video_info *xgifb_info) if (XGIfb_tvplug != -1) /* PR/TW: Override with option */ xgifb_info->TV_plug = XGIfb_tvplug; - else if (cr32 & XGI_VB_HIVISION) { + else if (cr32 & SIS_VB_HIVISION) { xgifb_info->TV_type = TVMODE_HIVISION; xgifb_info->TV_plug = TVPLUG_SVIDEO; - } else if (cr32 & XGI_VB_SVIDEO) + } else if (cr32 & SIS_VB_SVIDEO) xgifb_info->TV_plug = TVPLUG_SVIDEO; - else if (cr32 & XGI_VB_COMPOSITE) + else if (cr32 & SIS_VB_COMPOSITE) xgifb_info->TV_plug = TVPLUG_COMPOSITE; - else if (cr32 & XGI_VB_SCART) + else if (cr32 & SIS_VB_SCART) xgifb_info->TV_plug = TVPLUG_SCART; if (xgifb_info->TV_type == 0) { @@ -1805,11 +1805,11 @@ static void XGIfb_get_VB_type(struct xgifb_video_info *xgifb_info) if (!XGIfb_has_VB(xgifb_info)) { reg = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR37); - switch ((reg & XGI_EXTERNAL_CHIP_MASK) >> 1) { - case XGI310_EXTERNAL_CHIP_LVDS: + switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) { + case SIS_EXTERNAL_CHIP_LVDS: xgifb_info->hasVB = HASVB_LVDS; break; - case XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL: + case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL: xgifb_info->hasVB = HASVB_LVDS_CHRONTEL; break; default: @@ -1927,8 +1927,8 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, XGIRegInit(&xgifb_info->dev_info, (unsigned long)hw_info->pjIOAddress); - xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD); - reg1 = xgifb_reg_get(XGISR, IND_XGI_PASSWORD); + xgifb_reg_set(XGISR, IND_SIS_PASSWORD, SIS_PASSWORD); + reg1 = xgifb_reg_get(XGISR, IND_SIS_PASSWORD); if (reg1 != 0xa1) { /*I/O error */ printk("\nXGIfb: I/O error!!!"); @@ -1937,7 +1937,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, } switch (xgifb_info->chip_id) { - case PCI_DEVICE_ID_XG_20: + case PCI_DEVICE_ID_XGI_20: xgifb_reg_or(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN); CR48 = xgifb_reg_get(XGICR, Index_CR_GPIO_Reg1); if (CR48&GPIOG_READ) @@ -1945,16 +1945,16 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, else xgifb_info->chip = XG20; break; - case PCI_DEVICE_ID_XG_40: + case PCI_DEVICE_ID_XGI_40: xgifb_info->chip = XG40; break; - case PCI_DEVICE_ID_XG_41: + case PCI_DEVICE_ID_XGI_41: xgifb_info->chip = XG41; break; - case PCI_DEVICE_ID_XG_42: + case PCI_DEVICE_ID_XGI_42: xgifb_info->chip = XG42; break; - case PCI_DEVICE_ID_XG_27: + case PCI_DEVICE_ID_XGI_27: xgifb_info->chip = XG27; break; default: @@ -1973,10 +1973,10 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */ xgifb_reg_or(XGISR, - IND_XGI_PCI_ADDRESS_SET, - (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE)); + IND_SIS_PCI_ADDRESS_SET, + (SIS_PCI_ADDR_ENABLE | SIS_MEM_MAP_IO_ENABLE)); /* Enable 2D accelerator engine */ - xgifb_reg_or(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D); + xgifb_reg_or(XGISR, IND_SIS_MODULE_ENABLE, SIS_ENABLE_2D); hw_info->ulVideoMemorySize = xgifb_info->video_size; diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 67a316c3c10..fad144c565c 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -61,20 +61,20 @@ static const unsigned short XGINew_VGA_DAC[] = { void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) { pVBInfo->SModeIDTable = (struct XGI_StStruct *) XGI330_SModeIDTable; - pVBInfo->StandTable = (struct XGI_StandTableStruct *) XGI330_StandTable; + pVBInfo->StandTable = (struct SiS_StandTable_S *) XGI330_StandTable; pVBInfo->EModeIDTable = (struct XGI_ExtStruct *) XGI330_EModeIDTable; pVBInfo->RefIndex = (struct XGI_Ext2Struct *) XGI330_RefIndex; pVBInfo->XGINEWUB_CRT1Table = (struct XGI_CRT1TableStruct *) XGI_CRT1Table; - pVBInfo->MCLKData = (struct XGI_MCLKDataStruct *) XGI340New_MCLKData; + pVBInfo->MCLKData = (struct SiS_MCLKData *) XGI340New_MCLKData; pVBInfo->ECLKData = (struct XGI_ECLKDataStruct *) XGI340_ECLKData; - pVBInfo->VCLKData = (struct XGI_VCLKDataStruct *) XGI_VCLKData; - pVBInfo->VBVCLKData = (struct XGI_VBVCLKDataStruct *) XGI_VBVCLKData; + pVBInfo->VCLKData = (struct SiS_VCLKData *) XGI_VCLKData; + pVBInfo->VBVCLKData = (struct SiS_VBVCLKData *) XGI_VBVCLKData; pVBInfo->ScreenOffset = XGI330_ScreenOffset; - pVBInfo->StResInfo = (struct XGI_StResInfoStruct *) XGI330_StResInfo; + pVBInfo->StResInfo = (struct SiS_StResInfo_S *) XGI330_StResInfo; pVBInfo->ModeResInfo - = (struct XGI_ModeResInfoStruct *) XGI330_ModeResInfo; + = (struct SiS_ModeResInfo_S *) XGI330_ModeResInfo; pVBInfo->pOutputSelect = &XGI330_OutputSelect; pVBInfo->pSoftSetting = &XGI330_SoftSetting; @@ -153,7 +153,7 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) if (ChipType == XG27) { pVBInfo->MCLKData - = (struct XGI_MCLKDataStruct *) XGI27New_MCLKData; + = (struct SiS_MCLKData *) XGI27New_MCLKData; pVBInfo->CR40 = XGI27_cr41; pVBInfo->pXGINew_CR97 = &XG27_CR97; pVBInfo->pSR36 = &XG27_SR36; @@ -3918,8 +3918,8 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, { unsigned short tempax = 0, tempbx, modeflag, resinfo; - struct XGI_LCDDataStruct *LCDPtr = NULL; - struct XGI_TVDataStruct *TVPtr = NULL; + struct SiS_LCDData *LCDPtr = NULL; + struct SiS_TVData *TVPtr = NULL; if (ModeNo <= 0x13) { /* si+St_ResInfo */ @@ -3943,7 +3943,7 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, tempbx = 4; if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { - LCDPtr = (struct XGI_LCDDataStruct *) XGI_GetLcdPtr(tempbx, + LCDPtr = (struct SiS_LCDData *) XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); @@ -4028,7 +4028,7 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->VBInfo & (SetCRT2ToTV)) { tempbx = 4; - TVPtr = (struct XGI_TVDataStruct *) XGI_GetTVPtr(tempbx, + TVPtr = (struct SiS_TVData *) XGI_GetTVPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index d70df04e7dc..76a17c29245 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -351,7 +351,7 @@ struct vb_device_info { unsigned char *pCRT2Data_4_D; unsigned char *pCRT2Data_4_E; unsigned char *pCRT2Data_4_10; - struct XGI_MCLKDataStruct *MCLKData; + struct SiS_MCLKData *MCLKData; struct XGI_ECLKDataStruct *ECLKData; unsigned char *XGI_TVDelayList; @@ -381,15 +381,15 @@ struct vb_device_info { struct XGI_TimingVStruct *TimingV; struct XGI_StStruct *SModeIDTable; - struct XGI_StandTableStruct *StandTable; + struct SiS_StandTable_S *StandTable; struct XGI_ExtStruct *EModeIDTable; struct XGI_Ext2Struct *RefIndex; /* XGINew_CRT1TableStruct *CRT1Table; */ struct XGI_CRT1TableStruct *XGINEWUB_CRT1Table; - struct XGI_VCLKDataStruct *VCLKData; - struct XGI_VBVCLKDataStruct *VBVCLKData; - struct XGI_StResInfoStruct *StResInfo; - struct XGI_ModeResInfoStruct *ModeResInfo; + struct SiS_VCLKData *VCLKData; + struct SiS_VBVCLKData *VBVCLKData; + struct SiS_StResInfo_S *StResInfo; + struct SiS_ModeResInfo_S *ModeResInfo; struct XGI_XG21CRT1Struct *UpdateCRT1; int ram_type; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index e7946f1c114..217fb879434 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -1,5 +1,5 @@ /* yilin modify for xgi20 */ -static struct XGI_MCLKDataStruct XGI340New_MCLKData[] = { +static struct SiS_MCLKData XGI340New_MCLKData[] = { {0x16, 0x01, 0x01, 166}, {0x19, 0x02, 0x01, 124}, {0x7C, 0x08, 0x01, 200}, @@ -10,7 +10,7 @@ static struct XGI_MCLKDataStruct XGI340New_MCLKData[] = { {0x5c, 0x23, 0x01, 166} }; -static struct XGI_MCLKDataStruct XGI27New_MCLKData[] = { +static struct SiS_MCLKData XGI27New_MCLKData[] = { {0x5c, 0x23, 0x01, 166}, {0x19, 0x02, 0x01, 124}, {0x7C, 0x08, 0x80, 200}, @@ -296,7 +296,7 @@ static struct XGI_ExtStruct XGI330_EModeIDTable[] = { 0x00, 0x00, 0x00, 0x00, 0x00} }; -static struct XGI_StandTableStruct XGI330_StandTable[] = { +static struct SiS_StandTable_S XGI330_StandTable[] = { /* MD_0_200 */ { 0x28, 0x18, 0x08, 0x0800, @@ -2729,7 +2729,7 @@ static unsigned char XGI330_ScreenOffset[] = { 0x57, 0x48 }; -static struct XGI_StResInfoStruct XGI330_StResInfo[] = { +static struct SiS_StResInfo_S XGI330_StResInfo[] = { {640, 400}, {640, 350}, {720, 400}, @@ -2737,7 +2737,7 @@ static struct XGI_StResInfoStruct XGI330_StResInfo[] = { {640, 480} }; -static struct XGI_ModeResInfoStruct XGI330_ModeResInfo[] = { +static struct SiS_ModeResInfo_S XGI330_ModeResInfo[] = { { 320, 200, 8, 8}, { 320, 240, 8, 8}, { 320, 400, 8, 8}, -- cgit v1.2.3-70-g09d2 From 7ad6651d78dbf269c76f6ca141c2a9629943bb49 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Sun, 15 Jan 2012 19:22:13 +0100 Subject: staging/xgifb: Remove remaining duplicate structs and defines This patch removes the now unused structs and defines which were mere duplicates of the ones in the sgi headers Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main.h | 77 +++++---------------------------------- drivers/staging/xgifb/vb_struct.h | 66 --------------------------------- 2 files changed, 10 insertions(+), 133 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index fdee421cd49..e828fd403c3 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -12,43 +12,27 @@ #define XGIFAIL(x) do { printk(x "\n"); return -EINVAL; } while (0) -#ifndef PCI_VENDOR_ID_XG -#define PCI_VENDOR_ID_XG 0x18CA +#ifndef PCI_DEVICE_ID_XGI_41 +#define PCI_DEVICE_ID_XGI_41 0x041 #endif - -#ifndef PCI_DEVICE_ID_XG_40 -#define PCI_DEVICE_ID_XG_40 0x040 -#endif -#ifndef PCI_DEVICE_ID_XG_41 -#define PCI_DEVICE_ID_XG_41 0x041 -#endif -#ifndef PCI_DEVICE_ID_XG_42 -#define PCI_DEVICE_ID_XG_42 0x042 +#ifndef PCI_DEVICE_ID_XGI_42 +#define PCI_DEVICE_ID_XGI_42 0x042 #endif -#ifndef PCI_DEVICE_ID_XG_20 -#define PCI_DEVICE_ID_XG_20 0x020 -#endif -#ifndef PCI_DEVICE_ID_XG_27 -#define PCI_DEVICE_ID_XG_27 0x027 +#ifndef PCI_DEVICE_ID_XGI_27 +#define PCI_DEVICE_ID_XGI_27 0x027 #endif static DEFINE_PCI_DEVICE_TABLE(xgifb_pci_table) = { - {PCI_DEVICE(PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_20)}, - {PCI_DEVICE(PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_27)}, - {PCI_DEVICE(PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_40)}, - {PCI_DEVICE(PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_42)}, + {PCI_DEVICE(PCI_VENDOR_ID_XGI, PCI_DEVICE_ID_XGI_20)}, + {PCI_DEVICE(PCI_VENDOR_ID_XGI, PCI_DEVICE_ID_XGI_27)}, + {PCI_DEVICE(PCI_VENDOR_ID_XGI, PCI_DEVICE_ID_XGI_40)}, + {PCI_DEVICE(PCI_VENDOR_ID_XGI, PCI_DEVICE_ID_XGI_42)}, {0} }; MODULE_DEVICE_TABLE(pci, xgifb_pci_table); /* To be included in fb.h */ -#ifndef FB_ACCEL_XGI_XABRE -#define FB_ACCEL_XGI_XABRE 41 /* XGI 330 ("Xabre") */ -#endif - -#define SEQ_DATA 0x15 - #define XGISR (xgifb_info->dev_info.P3c4) #define XGICR (xgifb_info->dev_info.P3d4) #define XGIDACA (xgifb_info->dev_info.P3c8) @@ -61,12 +45,6 @@ MODULE_DEVICE_TABLE(pci, xgifb_pci_table); #define XGIDAC2A XGIPART5 #define XGIDAC2D (XGIPART5 + 1) -#define IND_XGI_PASSWORD 0x05 /* SRs */ -#define IND_XGI_RAMDAC_CONTROL 0x07 -#define IND_XGI_DRAM_SIZE 0x14 -#define IND_XGI_MODULE_ENABLE 0x1E -#define IND_XGI_PCI_ADDRESS_SET 0x20 - #define IND_XGI_SCRATCH_REG_CR30 0x30 /* CRs */ #define IND_XGI_SCRATCH_REG_CR31 0x31 #define IND_XGI_SCRATCH_REG_CR32 0x32 @@ -74,10 +52,6 @@ MODULE_DEVICE_TABLE(pci, xgifb_pci_table); #define IND_XGI_LCD_PANEL 0x36 #define IND_XGI_SCRATCH_REG_CR37 0x37 -#define IND_XGI_CRT2_WRITE_ENABLE_315 0x2F - -#define XGI_PASSWORD 0x86 /* SR05 */ - #define XGI_DRAM_SIZE_MASK 0xF0 /*SR14 */ #define XGI_DRAM_SIZE_1MB 0x00 #define XGI_DRAM_SIZE_2MB 0x01 @@ -89,37 +63,6 @@ MODULE_DEVICE_TABLE(pci, xgifb_pci_table); #define XGI_DRAM_SIZE_128MB 0x07 #define XGI_DRAM_SIZE_256MB 0x08 -#define XGI_ENABLE_2D 0x40 /* SR1E */ - -#define XGI_MEM_MAP_IO_ENABLE 0x01 /* SR20 */ -#define XGI_PCI_ADDR_ENABLE 0x80 - -#define XGI_SIMULTANEOUS_VIEW_ENABLE 0x01 /* CR30 */ -#define XGI_VB_OUTPUT_COMPOSITE 0x04 -#define XGI_VB_OUTPUT_SVIDEO 0x08 -#define XGI_VB_OUTPUT_SCART 0x10 -#define XGI_VB_OUTPUT_LCD 0x20 -#define XGI_VB_OUTPUT_CRT2 0x40 -#define XGI_VB_OUTPUT_HIVISION 0x80 - -#define XGI_VB_OUTPUT_DISABLE 0x20 /* CR31 */ -#define XGI_DRIVER_MODE 0x40 - -#define XGI_VB_COMPOSITE 0x01 /* CR32 */ -#define XGI_VB_SVIDEO 0x02 -#define XGI_VB_SCART 0x04 -#define XGI_VB_LCD 0x08 -#define XGI_VB_CRT2 0x10 -#define XGI_CRT1 0x20 -#define XGI_VB_HIVISION 0x40 -#define XGI_VB_YPBPR 0x80 -#define XGI_VB_TV (XGI_VB_COMPOSITE | XGI_VB_SVIDEO | \ - XGI_VB_SCART | XGI_VB_HIVISION|XGI_VB_YPBPR) - -#define XGI_EXTERNAL_CHIP_MASK 0x0E /* CR37 */ -#define XGI310_EXTERNAL_CHIP_LVDS 0x02 /* in CR37 << 1 ! */ -#define XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL 0x03 /* in CR37 << 1 ! */ - /* ------------------- Global Variables ----------------------------- */ /* display status */ diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 76a17c29245..a5bd56af92b 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -1,15 +1,5 @@ #ifndef _VB_STRUCT_ #define _VB_STRUCT_ - -struct XGI_LCDDataStruct { - unsigned short RVBHCMAX; - unsigned short RVBHCFACT; - unsigned short VGAHT; - unsigned short VGAVT; - unsigned short LCDHT; - unsigned short LCDVT; -}; - #include "../../video/sis/vstruct.h" struct XGI_LVDSCRT1HDataStruct { @@ -20,22 +10,6 @@ struct XGI_LVDSCRT1VDataStruct { unsigned char Reg[7]; }; -struct XGI_TVDataStruct { - unsigned short RVBHCMAX; - unsigned short RVBHCFACT; - unsigned short VGAHT; - unsigned short VGAVT; - unsigned short TVHDE; - unsigned short TVVDE; - unsigned short RVBHRS; - unsigned char FlickerMode; - unsigned short HALFRVBHRS; - unsigned char RY1COE; - unsigned char RY2COE; - unsigned char RY3COE; - unsigned char RY4COE; -}; - struct XGI_StStruct { unsigned char St_ModeID; unsigned short St_ModeFlag; @@ -48,18 +22,6 @@ struct XGI_StStruct { unsigned char VB_StTVYFilterIndex; }; -struct XGI_StandTableStruct { - unsigned char CRT_COLS; - unsigned char ROWS; - unsigned char CHAR_HEIGHT; - unsigned short CRT_LEN; - unsigned char SR[4]; - unsigned char MISC; - unsigned char CRTC[0x19]; - unsigned char ATTR[0x14]; - unsigned char GRC[9]; -}; - struct XGI_ExtStruct { unsigned char Ext_ModeID; unsigned short Ext_ModeFlag; @@ -86,39 +48,11 @@ struct XGI_Ext2Struct { /* unsigned short ROM_OFFSET; */ }; - -struct XGI_MCLKDataStruct { - unsigned char SR28, SR29, SR2A; - unsigned short CLOCK; -}; - struct XGI_ECLKDataStruct { unsigned char SR2E, SR2F, SR30; unsigned short CLOCK; }; -struct XGI_VCLKDataStruct { - unsigned char SR2B, SR2C; - unsigned short CLOCK; -}; - -struct XGI_VBVCLKDataStruct { - unsigned char Part4_A, Part4_B; - unsigned short CLOCK; -}; - -struct XGI_StResInfoStruct { - unsigned short HTotal; - unsigned short VTotal; -}; - -struct XGI_ModeResInfoStruct { - unsigned short HTotal; - unsigned short VTotal; - unsigned char XChar; - unsigned char YChar; -}; - /*add for new UNIVGABIOS*/ struct XGI_LCDDesStruct { unsigned short LCDHDES; -- cgit v1.2.3-70-g09d2 From 96c66042be64c08c6f0e23a107de0f04bc6c7fd1 Mon Sep 17 00:00:00 2001 From: Sam Hansen Date: Sun, 22 Jan 2012 00:48:25 -0800 Subject: staging: xgifb: pr_fmt kbuild macro Added the kbuild macro pr_fmt() to XGI_main_26.c Signed-off-by: Sam Hansen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index ff7a144044c..bbbbfd14695 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -4,6 +4,8 @@ * Base on TW's sis fbdev code. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + /* #include */ #include #include -- cgit v1.2.3-70-g09d2 From cae9a7bef2c497d40328f7f3fe6384efcf5c13b3 Mon Sep 17 00:00:00 2001 From: Sam Hansen Date: Sun, 22 Jan 2012 16:48:51 -0800 Subject: staging: xgifb: checkpatch cleanup braces Cleaned up XGI_main_26.c and removed some unneeded braces to keep with code conventions. Signed-off-by: Sam Hansen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index bbbbfd14695..8fe6edab4b7 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -2029,13 +2029,12 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, xgifb_info->hasVB = HASVB_NONE; } else if (xgifb_info->chip == XG21) { CR38 = xgifb_reg_get(XGICR, 0x38); - if ((CR38&0xE0) == 0xC0) { + if ((CR38&0xE0) == 0xC0) xgifb_info->display2 = XGIFB_DISP_LCD; - } else if ((CR38&0xE0) == 0x60) { + else if ((CR38&0xE0) == 0x60) xgifb_info->hasVB = HASVB_CHRONTEL; - } else { + else xgifb_info->hasVB = HASVB_NONE; - } } else { XGIfb_get_VB_type(xgifb_info); } @@ -2139,9 +2138,6 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, if (tmp & 0x20) { tmp = xgifb_reg_get( XGIPART1, 0x13); - if (tmp & 0x04) { - /* XGI_Pr.XGI_UseLCDA = 1; */ - } } } } -- cgit v1.2.3-70-g09d2 From b4fdf7be0a0e776e4e500e767600e654d8f4f6c2 Mon Sep 17 00:00:00 2001 From: Sam Hansen Date: Sun, 22 Jan 2012 16:48:52 -0800 Subject: staging: xgifb: checkpatch cleanup __func__ Replaced an instance of __FUNCTION__ with __func__ in XGI_main_26.c. Signed-off-by: Sam Hansen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 8fe6edab4b7..a67f65d6209 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -57,7 +57,7 @@ static unsigned int refresh_rate; #undef XGIFBDEBUG #ifdef XGIFBDEBUG -#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args) +#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args) #else #define DPRINTK(fmt, args...) #endif -- cgit v1.2.3-70-g09d2 From 4a6b1518d702d4bf4bb9262993c47263a8573518 Mon Sep 17 00:00:00 2001 From: Sam Hansen Date: Sun, 22 Jan 2012 16:48:53 -0800 Subject: staging: xgifb: checkpatch cleanup printk() -> pr_lvl() Rewrote code to use pr_lvl() instead of printk(). There are still a few instances of printk(), mainly in the debug code which looks like it's going to be dropped/rewrote (most of it is blocked out). Signed-off-by: Sam Hansen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 88 ++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index a67f65d6209..fb9b5b3cc55 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -57,7 +57,7 @@ static unsigned int refresh_rate; #undef XGIFBDEBUG #ifdef XGIFBDEBUG -#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args) +#define DPRINTK(fmt, args...) pr_debug("%s: " fmt, __func__ , ## args) #else #define DPRINTK(fmt, args...) #endif @@ -144,7 +144,7 @@ static inline void dumpVGAReg(void) #if 1 #define DEBUGPRN(x) #else -#define DEBUGPRN(x) printk(KERN_INFO x "\n"); +#define DEBUGPRN(x) pr_info(x "\n"); #endif /* --------------- Hardware Access Routines -------------------------- */ @@ -426,7 +426,7 @@ static void XGIfb_search_mode(struct xgifb_video_info *xgifb_info, i++; } if (!j) - printk(KERN_INFO "XGIfb: Invalid mode '%s'\n", name); + pr_info("Invalid mode '%s'\n", name); } static void XGIfb_search_vesamode(struct xgifb_video_info *xgifb_info, @@ -451,7 +451,7 @@ static void XGIfb_search_vesamode(struct xgifb_video_info *xgifb_info, invalid: if (!j) - printk(KERN_INFO "XGIfb: Invalid VESA mode 0x%x'\n", vesamode); + pr_info("Invalid VESA mode 0x%x'\n", vesamode); } static int XGIfb_validate_mode(struct xgifb_video_info *xgifb_info, int myindex) @@ -688,7 +688,7 @@ static void XGIfb_search_crt2type(const char *name) i++; } if (XGIfb_crt2type < 0) - printk(KERN_INFO "XGIfb: Invalid CRT2 type: %s\n", name); + pr_info("Invalid CRT2 type: %s\n", name); } static u8 XGIfb_search_refresh_rate(struct xgifb_video_info *xgifb_info, @@ -738,7 +738,7 @@ static u8 XGIfb_search_refresh_rate(struct xgifb_video_info *xgifb_info, if (xgifb_info->rate_idx > 0) { return xgifb_info->rate_idx; } else { - printk(KERN_INFO "XGIfb: Unsupported rate %d for %dx%d\n", + pr_info("Unsupported rate %d for %dx%d\n", rate, xres, yres); return 0; } @@ -1114,7 +1114,7 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, if (!htotal || !vtotal) { DPRINTK("XGIfb: Invalid 'var' information\n"); return -EINVAL; - } printk(KERN_DEBUG "XGIfb: var->pixclock=%d, htotal=%d, vtotal=%d\n", + } pr_debug("var->pixclock=%d, htotal=%d, vtotal=%d\n", var->pixclock, htotal, vtotal); if (var->pixclock && htotal && vtotal) { @@ -1126,7 +1126,7 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, xgifb_info->refresh_rate = 60; } - printk(KERN_DEBUG "XGIfb: Change mode to %dx%dx%d-%dHz\n", + pr_debug("Change mode to %dx%dx%d-%dHz\n", var->xres, var->yres, var->bits_per_pixel, @@ -1154,7 +1154,7 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, xgifb_info->mode_idx = -1; if (xgifb_info->mode_idx < 0) { - printk(KERN_ERR "XGIfb: Mode %dx%dx%d not supported\n", + pr_err("Mode %dx%dx%d not supported\n", var->xres, var->yres, var->bits_per_pixel); xgifb_info->mode_idx = old_mode; return -EINVAL; @@ -1173,7 +1173,7 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, if (XGISetModeNew(xgifb_info, hw_info, XGIbios_mode[xgifb_info->mode_idx].mode_no) == 0) { - printk(KERN_ERR "XGIfb: Setting mode[0x%x] failed\n", + pr_err("Setting mode[0x%x] failed\n", XGIbios_mode[xgifb_info->mode_idx].mode_no); return -EINVAL; } @@ -1235,7 +1235,7 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, break; default: xgifb_info->video_cmap_len = 16; - printk(KERN_ERR "XGIfb: Unsupported depth %d", + pr_err("Unsupported depth %d", xgifb_info->video_bpp); break; } @@ -1437,7 +1437,7 @@ static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) hrate = (drate * 1000) / htotal; xgifb_info->refresh_rate = (unsigned int) (hrate * 2 / vtotal); - printk(KERN_DEBUG + pr_debug( "%s: pixclock = %d ,htotal=%d, vtotal=%d\n" "%s: drate=%d, hrate=%d, refresh_rate=%d\n", __func__, var->pixclock, htotal, vtotal, @@ -1475,7 +1475,7 @@ static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) if (!found_mode) { - printk(KERN_ERR "XGIfb: %dx%dx%d is no valid mode\n", + pr_err("%dx%dx%d is no valid mode\n", var->xres, var->yres, var->bits_per_pixel); search_idx = 0; while (XGIbios_mode[search_idx].mode_no != 0) { @@ -1494,11 +1494,11 @@ static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) if (found_mode) { var->xres = XGIbios_mode[search_idx].xres; var->yres = XGIbios_mode[search_idx].yres; - printk(KERN_DEBUG "XGIfb: Adapted to mode %dx%dx%d\n", + pr_debug("Adapted to mode %dx%dx%d\n", var->xres, var->yres, var->bits_per_pixel); } else { - printk(KERN_ERR "XGIfb: Failed to find similar mode to %dx%dx%d\n", + pr_err("Failed to find similar mode to %dx%dx%d\n", var->xres, var->yres, var->bits_per_pixel); return -EINVAL; } @@ -1707,7 +1707,7 @@ static int XGIfb_get_dram_size(struct xgifb_video_info *xgifb_info) /* xgifb_info->video_size = 0x200000; */ /* 1024x768x16 */ /* xgifb_info->video_size = 0x1000000; */ /* benchmark */ - printk("XGIfb: SR14=%x DramSzie %x ChannelNum %x\n", + pr_info("SR14=%x DramSzie %x ChannelNum %x\n", reg, xgifb_info->video_size, ChannelNum); return 0; @@ -1913,7 +1913,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, xgifb_info->vga_base = pci_resource_start(pdev, 2) + 0x30; hw_info->pjIOAddress = (unsigned char *)xgifb_info->vga_base; /* XGI_Pr.RelIO = ioremap(pci_resource_start(pdev, 2), 128) + 0x30; */ - printk("XGIfb: Relocate IO address: %lx [%08lx]\n", + pr_info("Relocate IO address: %lx [%08lx]\n", (unsigned long)pci_resource_start(pdev, 2), xgifb_info->dev_info.RelIO); @@ -1933,7 +1933,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, reg1 = xgifb_reg_get(XGISR, IND_SIS_PASSWORD); if (reg1 != 0xa1) { /*I/O error */ - printk("\nXGIfb: I/O error!!!"); + pr_err("I/O error!!!"); ret = -EIO; goto error; } @@ -1964,11 +1964,11 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, goto error; } - printk("XGIfb:chipid = %x\n", xgifb_info->chip); + pr_info("chipid = %x\n", xgifb_info->chip); hw_info->jChipType = xgifb_info->chip; if (XGIfb_get_dram_size(xgifb_info)) { - printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n"); + pr_err("Fatal error: Unable to determine RAM size.\n"); ret = -ENODEV; goto error; } @@ -1985,10 +1985,10 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, if (!request_mem_region(xgifb_info->video_base, xgifb_info->video_size, "XGIfb FB")) { - printk("unable request memory size %x", + pr_err("unable request memory size %x\n", xgifb_info->video_size); - printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve frame buffer memory\n"); - printk(KERN_ERR "XGIfb: Is there another framebuffer driver active?\n"); + pr_err("Fatal error: Unable to reserve frame buffer memory\n"); + pr_err("Is there another framebuffer driver active?\n"); ret = -ENODEV; goto error; } @@ -1996,7 +1996,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, if (!request_mem_region(xgifb_info->mmio_base, xgifb_info->mmio_size, "XGIfb MMIO")) { - printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve MMIO region\n"); + pr_err("Fatal error: Unable to reserve MMIO region\n"); ret = -ENODEV; goto error_0; } @@ -2006,20 +2006,18 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, xgifb_info->mmio_vbase = ioremap(xgifb_info->mmio_base, xgifb_info->mmio_size); - printk(KERN_INFO "XGIfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n", + pr_info("Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n", xgifb_info->video_base, xgifb_info->video_vbase, xgifb_info->video_size / 1024); - printk(KERN_INFO "XGIfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n", + pr_info("MMIO at 0x%lx, mapped to 0x%p, size %ldk\n", xgifb_info->mmio_base, xgifb_info->mmio_vbase, xgifb_info->mmio_size / 1024); - printk("XGIfb: XGIInitNew() ..."); + pci_set_drvdata(pdev, xgifb_info); - if (XGIInitNew(pdev)) - printk("OK\n"); - else - printk("Fail\n"); + if (!XGIInitNew(pdev)) + pr_err("XGIInitNew() failed!\n"); xgifb_info->mtrr = (unsigned int) 0; @@ -2048,10 +2046,10 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, reg = xgifb_reg_get(XGIPART4, 0x01); if (reg >= 0xE0) { hw_info->ujVBChipID = VB_CHIP_302LV; - printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg); + pr_info("XGI302LV bridge detected (revision 0x%02x)\n", reg); } else if (reg >= 0xD0) { hw_info->ujVBChipID = VB_CHIP_301LV; - printk(KERN_INFO "XGIfb: XGI301LV bridge detected (revision 0x%02x)\n", reg); + pr_info("XGI301LV bridge detected (revision 0x%02x)\n", reg); } /* else if (reg >= 0xB0) { hw_info->ujVBChipID = VB_CHIP_301B; @@ -2060,17 +2058,17 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, } */ else { hw_info->ujVBChipID = VB_CHIP_301; - printk("XGIfb: XGI301 bridge detected\n"); + pr_info("XGI301 bridge detected\n"); } break; case HASVB_302: reg = xgifb_reg_get(XGIPART4, 0x01); if (reg >= 0xE0) { hw_info->ujVBChipID = VB_CHIP_302LV; - printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg); + pr_info("XGI302LV bridge detected (revision 0x%02x)\n", reg); } else if (reg >= 0xD0) { hw_info->ujVBChipID = VB_CHIP_301LV; - printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg); + pr_info("XGI302LV bridge detected (revision 0x%02x)\n", reg); } else if (reg >= 0xB0) { reg1 = xgifb_reg_get(XGIPART4, 0x23); @@ -2078,27 +2076,27 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, } else { hw_info->ujVBChipID = VB_CHIP_302; - printk(KERN_INFO "XGIfb: XGI302 bridge detected\n"); + pr_info("XGI302 bridge detected\n"); } break; case HASVB_LVDS: hw_info->ulExternalChip = 0x1; - printk(KERN_INFO "XGIfb: LVDS transmitter detected\n"); + pr_info("LVDS transmitter detected\n"); break; case HASVB_TRUMPION: hw_info->ulExternalChip = 0x2; - printk(KERN_INFO "XGIfb: Trumpion Zurac LVDS scaler detected\n"); + pr_info("Trumpion Zurac LVDS scaler detected\n"); break; case HASVB_CHRONTEL: hw_info->ulExternalChip = 0x4; - printk(KERN_INFO "XGIfb: Chrontel TV encoder detected\n"); + pr_info("Chrontel TV encoder detected\n"); break; case HASVB_LVDS_CHRONTEL: hw_info->ulExternalChip = 0x5; - printk(KERN_INFO "XGIfb: LVDS transmitter and Chrontel TV encoder detected\n"); + pr_info("LVDS transmitter and Chrontel TV encoder detected\n"); break; default: - printk(KERN_INFO "XGIfb: No or unknown bridge type detected\n"); + pr_info("No or unknown bridge type detected\n"); break; } @@ -2210,12 +2208,12 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, break; default: xgifb_info->video_cmap_len = 16; - printk(KERN_INFO "XGIfb: Unsupported depth %d", + pr_info("Unsupported depth %d\n", xgifb_info->video_bpp); break; } - printk(KERN_INFO "XGIfb: Default mode is %dx%dx%d (%dHz)\n", + pr_info("Default mode is %dx%dx%d (%dHz)\n", xgifb_info->video_width, xgifb_info->video_height, xgifb_info->video_bpp, @@ -2392,7 +2390,7 @@ MODULE_PARM_DESC(filter, static void __exit xgifb_remove_module(void) { pci_unregister_driver(&xgifb_driver); - printk(KERN_DEBUG "xgifb: Module unloaded\n"); + pr_debug("Module unloaded\n"); } module_exit(xgifb_remove_module); -- cgit v1.2.3-70-g09d2 From 4f1ef76165306577ad0cb708ea90fc19d311e7be Mon Sep 17 00:00:00 2001 From: Víctor Manuel Jáquez Leal Date: Tue, 31 Jan 2012 00:12:17 +0100 Subject: staging: tidspbridge: more readable code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Uppercase function names are not pretty. Also the code flow readability is enhanced. Signed-off-by: Víctor Manuel Jáquez Leal Signed-off-by: Greg Kroah-Hartman --- drivers/staging/tidspbridge/rmgr/drv_interface.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c index 76cfc6edecd..85f6e8e404e 100644 --- a/drivers/staging/tidspbridge/rmgr/drv_interface.c +++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c @@ -428,7 +428,7 @@ func_cont: } #ifdef CONFIG_PM -static int BRIDGE_SUSPEND(struct platform_device *pdev, pm_message_t state) +static int bridge_suspend(struct platform_device *pdev, pm_message_t state) { u32 status; u32 command = PWR_EMERGENCYDEEPSLEEP; @@ -441,7 +441,7 @@ static int BRIDGE_SUSPEND(struct platform_device *pdev, pm_message_t state) return 0; } -static int BRIDGE_RESUME(struct platform_device *pdev) +static int bridge_resume(struct platform_device *pdev) { u32 status; @@ -453,9 +453,6 @@ static int BRIDGE_RESUME(struct platform_device *pdev) wake_up(&bridge_suspend_data.suspend_wq); return 0; } -#else -#define BRIDGE_SUSPEND NULL -#define BRIDGE_RESUME NULL #endif static struct platform_driver bridge_driver = { @@ -464,8 +461,10 @@ static struct platform_driver bridge_driver = { }, .probe = omap34_xx_bridge_probe, .remove = __devexit_p(omap34_xx_bridge_remove), - .suspend = BRIDGE_SUSPEND, - .resume = BRIDGE_RESUME, +#ifdef CONFIG_PM + .suspend = bridge_suspend, + .resume = bridge_resume, +#endif }; static int __init bridge_init(void) -- cgit v1.2.3-70-g09d2 From 518761dba1270ebb6f735d152f1fd808382705e8 Mon Sep 17 00:00:00 2001 From: Víctor Manuel Jáquez Leal Date: Tue, 31 Jan 2012 00:12:18 +0100 Subject: staging: tidspbridge: remove unused header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No functional changes. The header file drv_interface.h was only used locally, hence there's no need to have it. Also the only prototyped functions were the file_operations callbacks, then this commit moves them up to avoid prototyping too. Signed-off-by: Víctor Manuel Jáquez Leal Signed-off-by: Greg Kroah-Hartman --- drivers/staging/tidspbridge/rmgr/drv_interface.c | 313 +++++++++++------------ drivers/staging/tidspbridge/rmgr/drv_interface.h | 28 -- 2 files changed, 155 insertions(+), 186 deletions(-) delete mode 100644 drivers/staging/tidspbridge/rmgr/drv_interface.h (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c index 85f6e8e404e..5ea753cb7fc 100644 --- a/drivers/staging/tidspbridge/rmgr/drv_interface.c +++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c @@ -48,9 +48,6 @@ /* ----------------------------------- Resource Manager */ #include -/* ----------------------------------- This */ -#include - #include #include #include @@ -133,6 +130,161 @@ MODULE_VERSION(DSPBRIDGE_VERSION); static char *driver_name = DRIVER_NAME; +/* + * This function is called when an application opens handle to the + * bridge driver. + */ +static int bridge_open(struct inode *ip, struct file *filp) +{ + int status = 0; + struct process_context *pr_ctxt = NULL; + + /* + * Allocate a new process context and insert it into global + * process context list. + */ + +#ifdef CONFIG_TIDSPBRIDGE_RECOVERY + if (recover) { + if (filp->f_flags & O_NONBLOCK || + wait_for_completion_interruptible(&bridge_open_comp)) + return -EBUSY; + } +#endif + pr_ctxt = kzalloc(sizeof(struct process_context), GFP_KERNEL); + if (pr_ctxt) { + pr_ctxt->res_state = PROC_RES_ALLOCATED; + spin_lock_init(&pr_ctxt->dmm_map_lock); + INIT_LIST_HEAD(&pr_ctxt->dmm_map_list); + spin_lock_init(&pr_ctxt->dmm_rsv_lock); + INIT_LIST_HEAD(&pr_ctxt->dmm_rsv_list); + + pr_ctxt->node_id = kzalloc(sizeof(struct idr), GFP_KERNEL); + if (pr_ctxt->node_id) { + idr_init(pr_ctxt->node_id); + } else { + status = -ENOMEM; + goto err; + } + + pr_ctxt->stream_id = kzalloc(sizeof(struct idr), GFP_KERNEL); + if (pr_ctxt->stream_id) + idr_init(pr_ctxt->stream_id); + else + status = -ENOMEM; + } else { + status = -ENOMEM; + } +err: + filp->private_data = pr_ctxt; +#ifdef CONFIG_TIDSPBRIDGE_RECOVERY + if (!status) + atomic_inc(&bridge_cref); +#endif + return status; +} + +/* + * This function is called when an application closes handle to the bridge + * driver. + */ +static int bridge_release(struct inode *ip, struct file *filp) +{ + int status = 0; + struct process_context *pr_ctxt; + + if (!filp->private_data) { + status = -EIO; + goto err; + } + + pr_ctxt = filp->private_data; + flush_signals(current); + drv_remove_all_resources(pr_ctxt); + proc_detach(pr_ctxt); + kfree(pr_ctxt); + + filp->private_data = NULL; + +err: +#ifdef CONFIG_TIDSPBRIDGE_RECOVERY + if (!atomic_dec_return(&bridge_cref)) + complete(&bridge_comp); +#endif + return status; +} + +/* This function provides IO interface to the bridge driver. */ +static long bridge_ioctl(struct file *filp, unsigned int code, + unsigned long args) +{ + int status; + u32 retval = 0; + union trapped_args buf_in; + + DBC_REQUIRE(filp != NULL); +#ifdef CONFIG_TIDSPBRIDGE_RECOVERY + if (recover) { + status = -EIO; + goto err; + } +#endif +#ifdef CONFIG_PM + status = omap34_xxbridge_suspend_lockout(&bridge_suspend_data, filp); + if (status != 0) + return status; +#endif + + if (!filp->private_data) { + status = -EIO; + goto err; + } + + status = copy_from_user(&buf_in, (union trapped_args *)args, + sizeof(union trapped_args)); + + if (!status) { + status = api_call_dev_ioctl(code, &buf_in, &retval, + filp->private_data); + + if (!status) { + status = retval; + } else { + dev_dbg(bridge, "%s: IOCTL Failed, code: 0x%x " + "status 0x%x\n", __func__, code, status); + status = -1; + } + + } + +err: + return status; +} + +/* This function maps kernel space memory to user space memory. */ +static int bridge_mmap(struct file *filp, struct vm_area_struct *vma) +{ + u32 offset = vma->vm_pgoff << PAGE_SHIFT; + u32 status; + + DBC_ASSERT(vma->vm_start < vma->vm_end); + + vma->vm_flags |= VM_RESERVED | VM_IO; + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + dev_dbg(bridge, "%s: vm filp %p offset %x start %lx end %lx page_prot " + "%lx flags %lx\n", __func__, filp, offset, + vma->vm_start, vma->vm_end, vma->vm_page_prot, vma->vm_flags); + + status = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, + vma->vm_end - vma->vm_start, + vma->vm_page_prot); + if (status != 0) + status = -EAGAIN; + + return status; +} + static const struct file_operations bridge_fops = { .open = bridge_open, .release = bridge_release, @@ -477,161 +629,6 @@ static void __exit bridge_exit(void) platform_driver_unregister(&bridge_driver); } -/* - * This function is called when an application opens handle to the - * bridge driver. - */ -static int bridge_open(struct inode *ip, struct file *filp) -{ - int status = 0; - struct process_context *pr_ctxt = NULL; - - /* - * Allocate a new process context and insert it into global - * process context list. - */ - -#ifdef CONFIG_TIDSPBRIDGE_RECOVERY - if (recover) { - if (filp->f_flags & O_NONBLOCK || - wait_for_completion_interruptible(&bridge_open_comp)) - return -EBUSY; - } -#endif - pr_ctxt = kzalloc(sizeof(struct process_context), GFP_KERNEL); - if (pr_ctxt) { - pr_ctxt->res_state = PROC_RES_ALLOCATED; - spin_lock_init(&pr_ctxt->dmm_map_lock); - INIT_LIST_HEAD(&pr_ctxt->dmm_map_list); - spin_lock_init(&pr_ctxt->dmm_rsv_lock); - INIT_LIST_HEAD(&pr_ctxt->dmm_rsv_list); - - pr_ctxt->node_id = kzalloc(sizeof(struct idr), GFP_KERNEL); - if (pr_ctxt->node_id) { - idr_init(pr_ctxt->node_id); - } else { - status = -ENOMEM; - goto err; - } - - pr_ctxt->stream_id = kzalloc(sizeof(struct idr), GFP_KERNEL); - if (pr_ctxt->stream_id) - idr_init(pr_ctxt->stream_id); - else - status = -ENOMEM; - } else { - status = -ENOMEM; - } -err: - filp->private_data = pr_ctxt; -#ifdef CONFIG_TIDSPBRIDGE_RECOVERY - if (!status) - atomic_inc(&bridge_cref); -#endif - return status; -} - -/* - * This function is called when an application closes handle to the bridge - * driver. - */ -static int bridge_release(struct inode *ip, struct file *filp) -{ - int status = 0; - struct process_context *pr_ctxt; - - if (!filp->private_data) { - status = -EIO; - goto err; - } - - pr_ctxt = filp->private_data; - flush_signals(current); - drv_remove_all_resources(pr_ctxt); - proc_detach(pr_ctxt); - kfree(pr_ctxt); - - filp->private_data = NULL; - -err: -#ifdef CONFIG_TIDSPBRIDGE_RECOVERY - if (!atomic_dec_return(&bridge_cref)) - complete(&bridge_comp); -#endif - return status; -} - -/* This function provides IO interface to the bridge driver. */ -static long bridge_ioctl(struct file *filp, unsigned int code, - unsigned long args) -{ - int status; - u32 retval = 0; - union trapped_args buf_in; - - DBC_REQUIRE(filp != NULL); -#ifdef CONFIG_TIDSPBRIDGE_RECOVERY - if (recover) { - status = -EIO; - goto err; - } -#endif -#ifdef CONFIG_PM - status = omap34_xxbridge_suspend_lockout(&bridge_suspend_data, filp); - if (status != 0) - return status; -#endif - - if (!filp->private_data) { - status = -EIO; - goto err; - } - - status = copy_from_user(&buf_in, (union trapped_args *)args, - sizeof(union trapped_args)); - - if (!status) { - status = api_call_dev_ioctl(code, &buf_in, &retval, - filp->private_data); - - if (!status) { - status = retval; - } else { - dev_dbg(bridge, "%s: IOCTL Failed, code: 0x%x " - "status 0x%x\n", __func__, code, status); - status = -1; - } - - } - -err: - return status; -} - -/* This function maps kernel space memory to user space memory. */ -static int bridge_mmap(struct file *filp, struct vm_area_struct *vma) -{ - u32 offset = vma->vm_pgoff << PAGE_SHIFT; - u32 status; - - DBC_ASSERT(vma->vm_start < vma->vm_end); - - vma->vm_flags |= VM_RESERVED | VM_IO; - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - - dev_dbg(bridge, "%s: vm filp %p offset %x start %lx end %lx page_prot " - "%lx flags %lx\n", __func__, filp, offset, - vma->vm_start, vma->vm_end, vma->vm_page_prot, vma->vm_flags); - - status = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, - vma->vm_end - vma->vm_start, - vma->vm_page_prot); - if (status != 0) - status = -EAGAIN; - - return status; -} - /* To remove all process resources before removing the process from the * process context list */ int drv_remove_all_resources(void *process_ctxt) diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.h b/drivers/staging/tidspbridge/rmgr/drv_interface.h deleted file mode 100644 index ab070602adc..00000000000 --- a/drivers/staging/tidspbridge/rmgr/drv_interface.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * drv_interface.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef _DRV_INTERFACE_H_ -#define _DRV_INTERFACE_H_ - -/* Prototypes for all functions in this bridge */ -static int __init bridge_init(void); /* Initialize bridge */ -static void __exit bridge_exit(void); /* Opposite of initialize */ -static int bridge_open(struct inode *ip, struct file *filp); /* Open */ -static int bridge_release(struct inode *ip, struct file *filp); /* Release */ -static long bridge_ioctl(struct file *filp, unsigned int code, - unsigned long args); -static int bridge_mmap(struct file *filp, struct vm_area_struct *vma); -#endif /* ifndef _DRV_INTERFACE_H_ */ -- cgit v1.2.3-70-g09d2 From 7724e8bfda8a5e7fd0a1f9819fd9b750c43e0495 Mon Sep 17 00:00:00 2001 From: Víctor Manuel Jáquez Leal Date: Tue, 31 Jan 2012 00:12:19 +0100 Subject: staging: tidspbridge: Lindent to drv_interface.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No functional changes. According to Lindent, the file drv_internface.c had some lines with bad indentation. This commit is the output of Lindent. Signed-off-by: Víctor Manuel Jáquez Leal Signed-off-by: Greg Kroah-Hartman --- drivers/staging/tidspbridge/rmgr/drv_interface.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c index 5ea753cb7fc..4316f4e6801 100644 --- a/drivers/staging/tidspbridge/rmgr/drv_interface.c +++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c @@ -147,7 +147,7 @@ static int bridge_open(struct inode *ip, struct file *filp) #ifdef CONFIG_TIDSPBRIDGE_RECOVERY if (recover) { if (filp->f_flags & O_NONBLOCK || - wait_for_completion_interruptible(&bridge_open_comp)) + wait_for_completion_interruptible(&bridge_open_comp)) return -EBUSY; } #endif @@ -245,7 +245,7 @@ static long bridge_ioctl(struct file *filp, unsigned int code, if (!status) { status = api_call_dev_ioctl(code, &buf_in, &retval, - filp->private_data); + filp->private_data); if (!status) { status = retval; @@ -363,10 +363,10 @@ void bridge_recover_schedule(void) #endif #ifdef CONFIG_TIDSPBRIDGE_DVFS static int dspbridge_scale_notification(struct notifier_block *op, - unsigned long val, void *ptr) + unsigned long val, void *ptr) { struct omap_dsp_platform_data *pdata = - omap_dspbridge_dev->dev.platform_data; + omap_dspbridge_dev->dev.platform_data; if (CPUFREQ_POSTCHANGE == val && pdata->dsp_get_opp) pwr_pm_post_scale(PRCM_VDD1, pdata->dsp_get_opp()); @@ -471,7 +471,7 @@ err2: err1: #ifdef CONFIG_TIDSPBRIDGE_DVFS cpufreq_unregister_notifier(&iva_clk_notifier, - CPUFREQ_TRANSITION_NOTIFIER); + CPUFREQ_TRANSITION_NOTIFIER); #endif dsp_clk_exit(); @@ -550,7 +550,7 @@ static int __devexit omap34_xx_bridge_remove(struct platform_device *pdev) #ifdef CONFIG_TIDSPBRIDGE_DVFS if (cpufreq_unregister_notifier(&iva_clk_notifier, - CPUFREQ_TRANSITION_NOTIFIER)) + CPUFREQ_TRANSITION_NOTIFIER)) pr_err("%s: cpufreq_unregister_notifier failed for iva2_ck\n", __func__); #endif /* #ifdef CONFIG_TIDSPBRIDGE_DVFS */ -- cgit v1.2.3-70-g09d2 From 9fdf6550613d1b7ac251a1e254829a4b9636c380 Mon Sep 17 00:00:00 2001 From: Víctor Manuel Jáquez Leal Date: Thu, 2 Feb 2012 23:51:08 +0100 Subject: staging: tidspbridge: silence the compiler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When compiling this report is raised by the compiler: CC [M] drivers/staging/tidspbridge/rmgr/drv_interface.o drivers/staging/tidspbridge/rmgr/drv_interface.c: In function 'bridge_mmap': drivers/staging/tidspbridge/rmgr/drv_interface.c:275:2: warning: format '%lx' expects type 'long unsigned int', but argument 9 has type 'pgprot_t' This patch fixes that warning message. Signed-off-by: Víctor Manuel Jáquez Leal Signed-off-by: Greg Kroah-Hartman --- drivers/staging/tidspbridge/rmgr/drv_interface.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c index 4316f4e6801..7a6401a022d 100644 --- a/drivers/staging/tidspbridge/rmgr/drv_interface.c +++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c @@ -273,8 +273,9 @@ static int bridge_mmap(struct file *filp, struct vm_area_struct *vma) vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); dev_dbg(bridge, "%s: vm filp %p offset %x start %lx end %lx page_prot " - "%lx flags %lx\n", __func__, filp, offset, - vma->vm_start, vma->vm_end, vma->vm_page_prot, vma->vm_flags); + "%ulx flags %lx\n", __func__, filp, offset, + vma->vm_start, vma->vm_end, vma->vm_page_prot, + vma->vm_flags); status = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, vma->vm_end - vma->vm_start, -- cgit v1.2.3-70-g09d2 From 0b86809a909b61c908281e5b85bfe5abcbf69d1f Mon Sep 17 00:00:00 2001 From: Víctor Manuel Jáquez Leal Date: Tue, 31 Jan 2012 00:12:21 +0100 Subject: staging: tidspbridge: remove header inclusions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drv_interface.c include several header files that are not really used. Signed-off-by: Víctor Manuel Jáquez Leal Signed-off-by: Greg Kroah-Hartman --- drivers/staging/tidspbridge/rmgr/drv_interface.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c index 7a6401a022d..4531920d88b 100644 --- a/drivers/staging/tidspbridge/rmgr/drv_interface.c +++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c @@ -16,11 +16,8 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -/* ----------------------------------- Host OS */ - #include -#include #include #include #include @@ -38,10 +35,8 @@ /* ----------------------------------- OS Adaptation Layer */ #include -#include /* ----------------------------------- Platform Manager */ -#include #include #include @@ -49,10 +44,8 @@ #include #include -#include #include #include -#include #ifdef CONFIG_TIDSPBRIDGE_DVFS #include -- cgit v1.2.3-70-g09d2 From b8bfa4c57c003e85aefbc5aef14f1704ef37b403 Mon Sep 17 00:00:00 2001 From: Víctor Manuel Jáquez Leal Date: Tue, 31 Jan 2012 00:12:22 +0100 Subject: staging: tidspbridge: remove trivial assert MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function dsp_deinit() always return true, so assert its output is pointless. As consequence the variable were the returned value is stored, is no longer needed. Signed-off-by: Víctor Manuel Jáquez Leal Signed-off-by: Greg Kroah-Hartman --- drivers/staging/tidspbridge/rmgr/drv_interface.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c index 4531920d88b..97c40ffd844 100644 --- a/drivers/staging/tidspbridge/rmgr/drv_interface.c +++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c @@ -531,7 +531,6 @@ err1: static int __devexit omap34_xx_bridge_remove(struct platform_device *pdev) { dev_t devno; - bool ret; int status = 0; struct drv_data *drv_datap = dev_get_drvdata(bridge); @@ -551,9 +550,8 @@ static int __devexit omap34_xx_bridge_remove(struct platform_device *pdev) if (driver_context) { /* Put the DSP in reset state */ - ret = dsp_deinit(driver_context); + dsp_deinit(driver_context); driver_context = 0; - DBC_ASSERT(ret == true); } func_cont: -- cgit v1.2.3-70-g09d2 From 4f8aae5375e429b003a72a37d8ece6e1b99e486e Mon Sep 17 00:00:00 2001 From: Víctor Manuel Jáquez Leal Date: Tue, 31 Jan 2012 00:12:23 +0100 Subject: staging: tidspbridge: clean up bridge_mmap() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The variable offset is not used but in the debug log, so I don't see reason to calculate it here. Signed-off-by: Víctor Manuel Jáquez Leal Signed-off-by: Greg Kroah-Hartman --- drivers/staging/tidspbridge/rmgr/drv_interface.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c index 97c40ffd844..5f810b64f9a 100644 --- a/drivers/staging/tidspbridge/rmgr/drv_interface.c +++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c @@ -257,7 +257,6 @@ err: /* This function maps kernel space memory to user space memory. */ static int bridge_mmap(struct file *filp, struct vm_area_struct *vma) { - u32 offset = vma->vm_pgoff << PAGE_SHIFT; u32 status; DBC_ASSERT(vma->vm_start < vma->vm_end); @@ -265,8 +264,8 @@ static int bridge_mmap(struct file *filp, struct vm_area_struct *vma) vma->vm_flags |= VM_RESERVED | VM_IO; vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - dev_dbg(bridge, "%s: vm filp %p offset %x start %lx end %lx page_prot " - "%ulx flags %lx\n", __func__, filp, offset, + dev_dbg(bridge, "%s: vm filp %p start %lx end %lx page_prot %ulx " + "flags %lx\n", __func__, filp, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma->vm_flags); -- cgit v1.2.3-70-g09d2 From 3bdb54fc548316196f752010a44dd221a220f53b Mon Sep 17 00:00:00 2001 From: Víctor Manuel Jáquez Leal Date: Tue, 31 Jan 2012 00:12:24 +0100 Subject: staging: tidspbridge: use the driver name string Instead of assign it to a global variable which is not used anymore. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/tidspbridge/rmgr/drv_interface.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c index 5f810b64f9a..93fc862c79d 100644 --- a/drivers/staging/tidspbridge/rmgr/drv_interface.c +++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c @@ -52,7 +52,6 @@ #endif /* ----------------------------------- Globals */ -#define DRIVER_NAME "DspBridge" #define DSPBRIDGE_VERSION "0.3" s32 dsp_debug; @@ -121,8 +120,6 @@ MODULE_AUTHOR("Texas Instruments"); MODULE_LICENSE("GPL"); MODULE_VERSION(DSPBRIDGE_VERSION); -static char *driver_name = DRIVER_NAME; - /* * This function is called when an application opens handle to the * bridge driver. @@ -490,7 +487,7 @@ static int __devinit omap34_xx_bridge_probe(struct platform_device *pdev) goto err1; /* use 2.6 device model */ - err = alloc_chrdev_region(&dev, 0, 1, driver_name); + err = alloc_chrdev_region(&dev, 0, 1, "DspBridge"); if (err) { pr_err("%s: Can't get major %d\n", __func__, driver_major); goto err1; -- cgit v1.2.3-70-g09d2 From 8900f00b1546a32be6b9dd7cf1633560e4381a76 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 24 Jan 2012 13:25:05 -0800 Subject: staging: tidspbridge: Rename module from bridgedriver to tidspbridge tidspbridge when built as a module is named bridgedriver. bridgedriver is not a particularly good module name. tidspbridge is what the source is named. That seems a more appropriate module name too as it describes the hardware function better. Signed-off-by: Joe Perches Acked-by: Omar Ramirez Luna Acked-by: Felipe Contreras Signed-off-by: Greg Kroah-Hartman --- drivers/staging/tidspbridge/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/Makefile b/drivers/staging/tidspbridge/Makefile index fd6a2761cc3..8c8c92a9083 100644 --- a/drivers/staging/tidspbridge/Makefile +++ b/drivers/staging/tidspbridge/Makefile @@ -1,4 +1,4 @@ -obj-$(CONFIG_TIDSPBRIDGE) += bridgedriver.o +obj-$(CONFIG_TIDSPBRIDGE) += tidspbridge.o libgen = gen/gh.o gen/uuidutil.o libcore = core/chnl_sm.o core/msg_sm.o core/io_sm.o core/tiomap3430.o \ @@ -13,7 +13,7 @@ libdload = dynload/cload.o dynload/getsection.o dynload/reloc.o \ dynload/tramp.o libhw = hw/hw_mmu.o -bridgedriver-y := $(libgen) $(libservices) $(libcore) $(libpmgr) $(librmgr) \ +tidspbridge-y := $(libgen) $(libservices) $(libcore) $(libpmgr) $(librmgr) \ $(libdload) $(libhw) #Machine dependent -- cgit v1.2.3-70-g09d2 From 276cc746d58b73aa4e046745441b8cf56858f9ef Mon Sep 17 00:00:00 2001 From: Víctor Manuel Jáquez Leal Date: Tue, 7 Feb 2012 00:39:34 +0100 Subject: staging: tidspbridge: remove DBC_ENSURE and DBC_REQUIRED MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The kernel does not use a "Design by Contract" approach, and it is only activated in the module if CONFIG_TIDSPBRDIGE_DEBUG is enabled, so they are executed rarely. It is better to remove them: less code to maintain. Signed-off-by: Víctor Manuel Jáquez Leal Signed-off-by: Greg Kroah-Hartman --- drivers/staging/tidspbridge/core/chnl_sm.c | 19 +--- drivers/staging/tidspbridge/core/tiomap3430.c | 3 - drivers/staging/tidspbridge/gen/uuidutil.c | 4 - .../staging/tidspbridge/include/dspbridge/dbc.h | 7 -- drivers/staging/tidspbridge/pmgr/chnl.c | 16 --- drivers/staging/tidspbridge/pmgr/cmm.c | 59 ---------- drivers/staging/tidspbridge/pmgr/cod.c | 71 ------------ drivers/staging/tidspbridge/pmgr/dbll.c | 108 +----------------- drivers/staging/tidspbridge/pmgr/dev.c | 123 --------------------- drivers/staging/tidspbridge/pmgr/dmm.c | 11 -- drivers/staging/tidspbridge/pmgr/dspapi.c | 4 - drivers/staging/tidspbridge/pmgr/io.c | 14 --- drivers/staging/tidspbridge/pmgr/msg.c | 14 --- drivers/staging/tidspbridge/rmgr/dbdcd.c | 80 -------------- drivers/staging/tidspbridge/rmgr/disp.c | 38 ------- drivers/staging/tidspbridge/rmgr/drv.c | 38 ------- drivers/staging/tidspbridge/rmgr/drv_interface.c | 1 - drivers/staging/tidspbridge/rmgr/dspdrv.c | 2 - drivers/staging/tidspbridge/rmgr/mgr.c | 31 ------ drivers/staging/tidspbridge/rmgr/nldr.c | 47 -------- drivers/staging/tidspbridge/rmgr/node.c | 84 -------------- drivers/staging/tidspbridge/rmgr/proc.c | 73 ------------ drivers/staging/tidspbridge/rmgr/rmm.c | 30 ----- drivers/staging/tidspbridge/rmgr/strm.c | 72 +----------- 24 files changed, 3 insertions(+), 946 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/core/chnl_sm.c b/drivers/staging/tidspbridge/core/chnl_sm.c index 6d66e7d0fba..91daf25d29a 100644 --- a/drivers/staging/tidspbridge/core/chnl_sm.c +++ b/drivers/staging/tidspbridge/core/chnl_sm.c @@ -358,13 +358,6 @@ int bridge_chnl_create(struct chnl_mgr **channel_mgr, struct chnl_mgr *chnl_mgr_obj = NULL; u8 max_channels; - /* Check DBC requirements: */ - DBC_REQUIRE(channel_mgr != NULL); - DBC_REQUIRE(mgr_attrts != NULL); - DBC_REQUIRE(mgr_attrts->max_channels > 0); - DBC_REQUIRE(mgr_attrts->max_channels <= CHNL_MAXCHANNELS); - DBC_REQUIRE(mgr_attrts->word_size != 0); - /* Allocate channel manager object */ chnl_mgr_obj = kzalloc(sizeof(struct chnl_mgr), GFP_KERNEL); if (chnl_mgr_obj) { @@ -491,7 +484,6 @@ int bridge_chnl_flush_io(struct chnl_object *chnl_obj, u32 timeout) pchnl->state &= ~CHNL_STATECANCEL; } } - DBC_ENSURE(status || list_empty(&pchnl->io_requests)); return status; } @@ -705,8 +697,6 @@ int bridge_chnl_idle(struct chnl_object *chnl_obj, u32 timeout, struct chnl_mgr *chnl_mgr_obj; int status = 0; - DBC_REQUIRE(chnl_obj); - chnl_mode = chnl_obj->chnl_mode; chnl_mgr_obj = chnl_obj->chnl_mgr_obj; @@ -736,10 +726,7 @@ int bridge_chnl_open(struct chnl_object **chnl, struct chnl_mgr *chnl_mgr_obj = hchnl_mgr; struct chnl_object *pchnl = NULL; struct sync_object *sync_event = NULL; - /* Ensure DBC requirements: */ - DBC_REQUIRE(chnl != NULL); - DBC_REQUIRE(pattrs != NULL); - DBC_REQUIRE(hchnl_mgr != NULL); + *chnl = NULL; /* Validate Args: */ @@ -906,8 +893,6 @@ static void free_chirp_list(struct list_head *chirp_list) { struct chnl_irp *chirp, *tmp; - DBC_REQUIRE(chirp_list != NULL); - list_for_each_entry_safe(chirp, tmp, chirp_list, link) { list_del(&chirp->link); kfree(chirp); @@ -924,8 +909,6 @@ static int search_free_channel(struct chnl_mgr *chnl_mgr_obj, int status = -ENOSR; u32 i; - DBC_REQUIRE(chnl_mgr_obj); - for (i = 0; i < chnl_mgr_obj->max_channels; i++) { if (chnl_mgr_obj->channels[i] == NULL) { status = 0; diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index e1c4492a710..212cbc9414d 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -256,9 +256,6 @@ static void bad_page_dump(u32 pa, struct page *pg) void bridge_drv_entry(struct bridge_drv_interface **drv_intf, const char *driver_file_name) { - - DBC_REQUIRE(driver_file_name != NULL); - if (strcmp(driver_file_name, "UMA") == 0) *drv_intf = &drv_interface_fxns; else diff --git a/drivers/staging/tidspbridge/gen/uuidutil.c b/drivers/staging/tidspbridge/gen/uuidutil.c index ff6ebadf98f..5797fb5c306 100644 --- a/drivers/staging/tidspbridge/gen/uuidutil.c +++ b/drivers/staging/tidspbridge/gen/uuidutil.c @@ -41,8 +41,6 @@ void uuid_uuid_to_string(struct dsp_uuid *uuid_obj, char *sz_uuid, { s32 i; /* return result from snprintf. */ - DBC_REQUIRE(uuid_obj && sz_uuid); - i = snprintf(sz_uuid, size, "%.8X_%.4X_%.4X_%.2X%.2X_%.2X%.2X%.2X%.2X%.2X%.2X", uuid_obj->data1, uuid_obj->data2, uuid_obj->data3, @@ -50,8 +48,6 @@ void uuid_uuid_to_string(struct dsp_uuid *uuid_obj, char *sz_uuid, uuid_obj->data6[0], uuid_obj->data6[1], uuid_obj->data6[2], uuid_obj->data6[3], uuid_obj->data6[4], uuid_obj->data6[5]); - - DBC_ENSURE(i != -1); } static s32 uuid_hex_to_bin(char *buf, s32 len) diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbc.h b/drivers/staging/tidspbridge/include/dspbridge/dbc.h index 463760f499a..dc88f34f166 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dbc.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dbc.h @@ -32,15 +32,8 @@ if (!(exp)) \ pr_err("%s, line %d: Assertion (" #exp ") failed.\n", \ __FILE__, __LINE__) -#define DBC_REQUIRE DBC_ASSERT /* Function Precondition. */ -#define DBC_ENSURE DBC_ASSERT /* Function Postcondition. */ - #else - #define DBC_ASSERT(exp) {} -#define DBC_REQUIRE(exp) {} -#define DBC_ENSURE(exp) {} - #endif /* DEBUG */ #endif /* DBC_ */ diff --git a/drivers/staging/tidspbridge/pmgr/chnl.c b/drivers/staging/tidspbridge/pmgr/chnl.c index 245de82e2d6..61ee0f0e511 100644 --- a/drivers/staging/tidspbridge/pmgr/chnl.c +++ b/drivers/staging/tidspbridge/pmgr/chnl.c @@ -58,10 +58,6 @@ int chnl_create(struct chnl_mgr **channel_mgr, struct chnl_mgr *hchnl_mgr; struct chnl_mgr_ *chnl_mgr_obj = NULL; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(channel_mgr != NULL); - DBC_REQUIRE(mgr_attrts != NULL); - *channel_mgr = NULL; /* Validate args: */ @@ -99,8 +95,6 @@ int chnl_create(struct chnl_mgr **channel_mgr, } } - DBC_ENSURE(status || chnl_mgr_obj); - return status; } @@ -115,8 +109,6 @@ int chnl_destroy(struct chnl_mgr *hchnl_mgr) struct bridge_drv_interface *intf_fxns; int status; - DBC_REQUIRE(refs > 0); - if (chnl_mgr_obj) { intf_fxns = chnl_mgr_obj->intf_fxns; /* Let Bridge channel module destroy the chnl_mgr: */ @@ -135,11 +127,7 @@ int chnl_destroy(struct chnl_mgr *hchnl_mgr) */ void chnl_exit(void) { - DBC_REQUIRE(refs > 0); - refs--; - - DBC_ENSURE(refs >= 0); } /* @@ -151,12 +139,8 @@ bool chnl_init(void) { bool ret = true; - DBC_REQUIRE(refs >= 0); - if (ret) refs++; - DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0))); - return ret; } diff --git a/drivers/staging/tidspbridge/pmgr/cmm.c b/drivers/staging/tidspbridge/pmgr/cmm.c index e6b2c8962f8..2eeb5370927 100644 --- a/drivers/staging/tidspbridge/pmgr/cmm.c +++ b/drivers/staging/tidspbridge/pmgr/cmm.c @@ -244,9 +244,6 @@ int cmm_create(struct cmm_object **ph_cmm_mgr, struct cmm_object *cmm_obj = NULL; int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(ph_cmm_mgr != NULL); - *ph_cmm_mgr = NULL; /* create, zero, and tag a cmm mgr object */ cmm_obj = kzalloc(sizeof(struct cmm_object), GFP_KERNEL); @@ -283,7 +280,6 @@ int cmm_destroy(struct cmm_object *hcmm_mgr, bool force) s32 slot_seg; struct cmm_mnode *node, *tmp; - DBC_REQUIRE(refs > 0); if (!hcmm_mgr) { status = -EFAULT; return status; @@ -333,8 +329,6 @@ int cmm_destroy(struct cmm_object *hcmm_mgr, bool force) */ void cmm_exit(void) { - DBC_REQUIRE(refs > 0); - refs--; } @@ -351,9 +345,6 @@ int cmm_free_buf(struct cmm_object *hcmm_mgr, void *buf_pa, u32 ul_seg_id) struct cmm_allocator *allocator; struct cmm_attrs *pattrs; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(buf_pa != NULL); - if (ul_seg_id == 0) { pattrs = &cmm_dfltalctattrs; ul_seg_id = pattrs->seg_id; @@ -392,8 +383,6 @@ int cmm_get_handle(void *hprocessor, struct cmm_object ** ph_cmm_mgr) int status = 0; struct dev_object *hdev_obj; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(ph_cmm_mgr != NULL); if (hprocessor != NULL) status = proc_get_dev_object(hprocessor, &hdev_obj); else @@ -419,8 +408,6 @@ int cmm_get_info(struct cmm_object *hcmm_mgr, struct cmm_allocator *altr; struct cmm_mnode *curr; - DBC_REQUIRE(cmm_info_obj != NULL); - if (!hcmm_mgr) { status = -EFAULT; return status; @@ -472,12 +459,9 @@ bool cmm_init(void) { bool ret = true; - DBC_REQUIRE(refs >= 0); if (ret) refs++; - DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0))); - return ret; } @@ -499,13 +483,6 @@ int cmm_register_gppsm_seg(struct cmm_object *hcmm_mgr, struct cmm_mnode *new_node; s32 slot_seg; - DBC_REQUIRE(ul_size > 0); - DBC_REQUIRE(sgmt_id != NULL); - DBC_REQUIRE(dw_gpp_base_pa != 0); - DBC_REQUIRE(gpp_base_va != 0); - DBC_REQUIRE((c_factor <= CMM_ADDTODSPPA) && - (c_factor >= CMM_SUBFROMDSPPA)); - dev_dbg(bridge, "%s: dw_gpp_base_pa %x ul_size %x dsp_addr_offset %x " "dw_dsp_base %x ul_dsp_size %x gpp_base_va %x\n", __func__, dw_gpp_base_pa, ul_size, dsp_addr_offset, @@ -589,7 +566,6 @@ int cmm_un_register_gppsm_seg(struct cmm_object *hcmm_mgr, struct cmm_allocator *psma; u32 ul_id = ul_seg_id; - DBC_REQUIRE(ul_seg_id > 0); if (!hcmm_mgr) return -EFAULT; @@ -635,8 +611,6 @@ static void un_register_gppsm_seg(struct cmm_allocator *psma) { struct cmm_mnode *curr, *tmp; - DBC_REQUIRE(psma != NULL); - /* free nodes on free list */ list_for_each_entry_safe(curr, tmp, &psma->free_list, link) { list_del(&curr->link); @@ -664,7 +638,6 @@ static void un_register_gppsm_seg(struct cmm_allocator *psma) static s32 get_slot(struct cmm_object *cmm_mgr_obj) { s32 slot_seg = -1; /* neg on failure */ - DBC_REQUIRE(cmm_mgr_obj != NULL); /* get first available slot in cmm mgr SMSegTab[] */ for (slot_seg = 0; slot_seg < CMM_MAXGPPSEGS; slot_seg++) { if (cmm_mgr_obj->pa_gppsm_seg_tab[slot_seg] == NULL) @@ -687,11 +660,6 @@ static struct cmm_mnode *get_node(struct cmm_object *cmm_mgr_obj, u32 dw_pa, { struct cmm_mnode *pnode; - DBC_REQUIRE(cmm_mgr_obj != NULL); - DBC_REQUIRE(dw_pa != 0); - DBC_REQUIRE(dw_va != 0); - DBC_REQUIRE(ul_size != 0); - /* Check cmm mgr's node freelist */ if (list_empty(&cmm_mgr_obj->node_free_list)) { pnode = kzalloc(sizeof(struct cmm_mnode), GFP_KERNEL); @@ -719,7 +687,6 @@ static struct cmm_mnode *get_node(struct cmm_object *cmm_mgr_obj, u32 dw_pa, */ static void delete_node(struct cmm_object *cmm_mgr_obj, struct cmm_mnode *pnode) { - DBC_REQUIRE(pnode != NULL); list_add_tail(&pnode->link, &cmm_mgr_obj->node_free_list); } @@ -794,9 +761,6 @@ static void add_to_free_list(struct cmm_allocator *allocator, static struct cmm_allocator *get_allocator(struct cmm_object *cmm_mgr_obj, u32 ul_seg_id) { - DBC_REQUIRE(cmm_mgr_obj != NULL); - DBC_REQUIRE((ul_seg_id > 0) && (ul_seg_id <= CMM_MAXGPPSEGS)); - return cmm_mgr_obj->pa_gppsm_seg_tab[ul_seg_id - 1]; } @@ -818,10 +782,6 @@ int cmm_xlator_create(struct cmm_xlatorobject **xlator, struct cmm_xlator *xlator_object = NULL; int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(xlator != NULL); - DBC_REQUIRE(hcmm_mgr != NULL); - *xlator = NULL; if (xlator_attrs == NULL) xlator_attrs = &cmm_dfltxlatorattrs; /* set defaults */ @@ -851,13 +811,6 @@ void *cmm_xlator_alloc_buf(struct cmm_xlatorobject *xlator, void *va_buf, void *tmp_va_buff; struct cmm_attrs attrs; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(xlator != NULL); - DBC_REQUIRE(xlator_obj->cmm_mgr != NULL); - DBC_REQUIRE(va_buf != NULL); - DBC_REQUIRE(pa_size > 0); - DBC_REQUIRE(xlator_obj->seg_id > 0); - if (xlator_obj) { attrs.seg_id = xlator_obj->seg_id; __raw_writel(0, va_buf); @@ -887,10 +840,6 @@ int cmm_xlator_free_buf(struct cmm_xlatorobject *xlator, void *buf_va) int status = -EPERM; void *buf_pa = NULL; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(buf_va != NULL); - DBC_REQUIRE(xlator_obj->seg_id > 0); - if (xlator_obj) { /* convert Va to Pa so we can free it. */ buf_pa = cmm_xlator_translate(xlator, buf_va, CMM_VA2PA); @@ -918,10 +867,6 @@ int cmm_xlator_info(struct cmm_xlatorobject *xlator, u8 ** paddr, struct cmm_xlator *xlator_obj = (struct cmm_xlator *)xlator; int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(paddr != NULL); - DBC_REQUIRE((segm_id > 0) && (segm_id <= CMM_MAXGPPSEGS)); - if (xlator_obj) { if (set_info) { /* set translators virtual address range */ @@ -948,10 +893,6 @@ void *cmm_xlator_translate(struct cmm_xlatorobject *xlator, void *paddr, struct cmm_allocator *allocator = NULL; u32 dw_offset = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(paddr != NULL); - DBC_REQUIRE((xtype >= CMM_VA2PA) && (xtype <= CMM_DSPPA2PA)); - if (!xlator_obj) goto loop_cont; diff --git a/drivers/staging/tidspbridge/pmgr/cod.c b/drivers/staging/tidspbridge/pmgr/cod.c index 1a29264b585..be7c7772521 100644 --- a/drivers/staging/tidspbridge/pmgr/cod.c +++ b/drivers/staging/tidspbridge/pmgr/cod.c @@ -183,10 +183,6 @@ void cod_close(struct cod_libraryobj *lib) { struct cod_manager *hmgr; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(lib != NULL); - DBC_REQUIRE(lib->cod_mgr); - hmgr = lib->cod_mgr; hmgr->fxns.close_fxn(lib->dbll_lib); @@ -208,9 +204,6 @@ int cod_create(struct cod_manager **mgr, char *str_zl_file) struct dbll_attrs zl_attrs; int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(mgr != NULL); - /* assume failure */ *mgr = NULL; @@ -263,9 +256,6 @@ int cod_create(struct cod_manager **mgr, char *str_zl_file) */ void cod_delete(struct cod_manager *cod_mgr_obj) { - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(cod_mgr_obj); - if (cod_mgr_obj->base_lib) { if (cod_mgr_obj->loaded) cod_mgr_obj->fxns.unload_fxn(cod_mgr_obj->base_lib, @@ -288,11 +278,7 @@ void cod_delete(struct cod_manager *cod_mgr_obj) */ void cod_exit(void) { - DBC_REQUIRE(refs > 0); - refs--; - - DBC_ENSURE(refs >= 0); } /* @@ -305,10 +291,6 @@ int cod_get_base_lib(struct cod_manager *cod_mgr_obj, { int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(cod_mgr_obj); - DBC_REQUIRE(plib != NULL); - *plib = (struct dbll_library_obj *)cod_mgr_obj->base_lib; return status; @@ -322,10 +304,6 @@ int cod_get_base_name(struct cod_manager *cod_mgr_obj, char *sz_name, { int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(cod_mgr_obj); - DBC_REQUIRE(sz_name != NULL); - if (usize <= COD_MAXPATHLENGTH) strncpy(sz_name, cod_mgr_obj->sz_zl_file, usize); else @@ -342,10 +320,6 @@ int cod_get_base_name(struct cod_manager *cod_mgr_obj, char *sz_name, */ int cod_get_entry(struct cod_manager *cod_mgr_obj, u32 *entry_pt) { - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(cod_mgr_obj); - DBC_REQUIRE(entry_pt != NULL); - *entry_pt = cod_mgr_obj->entry; return 0; @@ -361,10 +335,6 @@ int cod_get_loader(struct cod_manager *cod_mgr_obj, { int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(cod_mgr_obj); - DBC_REQUIRE(loader != NULL); - *loader = (struct dbll_tar_obj *)cod_mgr_obj->target; return status; @@ -382,13 +352,6 @@ int cod_get_section(struct cod_libraryobj *lib, char *str_sect, struct cod_manager *cod_mgr_obj; int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(lib != NULL); - DBC_REQUIRE(lib->cod_mgr); - DBC_REQUIRE(str_sect != NULL); - DBC_REQUIRE(addr != NULL); - DBC_REQUIRE(len != NULL); - *addr = 0; *len = 0; if (lib != NULL) { @@ -399,8 +362,6 @@ int cod_get_section(struct cod_libraryobj *lib, char *str_sect, status = -ESPIPE; } - DBC_ENSURE(!status || ((*addr == 0) && (*len == 0))); - return status; } @@ -417,11 +378,6 @@ int cod_get_sym_value(struct cod_manager *cod_mgr_obj, char *str_sym, { struct dbll_sym_val *dbll_sym; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(cod_mgr_obj); - DBC_REQUIRE(str_sym != NULL); - DBC_REQUIRE(pul_value != NULL); - dev_dbg(bridge, "%s: cod_mgr_obj: %p str_sym: %s pul_value: %p\n", __func__, cod_mgr_obj, str_sym, pul_value); if (cod_mgr_obj->base_lib) { @@ -451,12 +407,9 @@ bool cod_init(void) { bool ret = true; - DBC_REQUIRE(refs >= 0); - if (ret) refs++; - DBC_ENSURE((ret && refs > 0) || (!ret && refs >= 0)); return ret; } @@ -482,14 +435,6 @@ int cod_load_base(struct cod_manager *cod_mgr_obj, u32 num_argc, char *args[], int status; u32 i; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(cod_mgr_obj); - DBC_REQUIRE(num_argc > 0); - DBC_REQUIRE(args != NULL); - DBC_REQUIRE(args[0] != NULL); - DBC_REQUIRE(pfn_write != NULL); - DBC_REQUIRE(cod_mgr_obj->base_lib != NULL); - /* * Make sure every argv[] stated in argc has a value, or change argc to * reflect true number in NULL terminated argv array. @@ -538,12 +483,6 @@ int cod_open(struct cod_manager *hmgr, char *sz_coff_path, int status = 0; struct cod_libraryobj *lib = NULL; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(hmgr); - DBC_REQUIRE(sz_coff_path != NULL); - DBC_REQUIRE(flags == COD_NOLOAD || flags == COD_SYMB); - DBC_REQUIRE(lib_obj != NULL); - *lib_obj = NULL; lib = kzalloc(sizeof(struct cod_libraryobj), GFP_KERNEL); @@ -575,10 +514,6 @@ int cod_open_base(struct cod_manager *hmgr, char *sz_coff_path, int status = 0; struct dbll_library_obj *lib; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(hmgr); - DBC_REQUIRE(sz_coff_path != NULL); - /* if we previously opened a base image, close it now */ if (hmgr->base_lib) { if (hmgr->loaded) { @@ -612,12 +547,6 @@ int cod_read_section(struct cod_libraryobj *lib, char *str_sect, { int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(lib != NULL); - DBC_REQUIRE(lib->cod_mgr); - DBC_REQUIRE(str_sect != NULL); - DBC_REQUIRE(str_content != NULL); - if (lib != NULL) status = lib->cod_mgr->fxns.read_sect_fxn(lib->dbll_lib, str_sect, diff --git a/drivers/staging/tidspbridge/pmgr/dbll.c b/drivers/staging/tidspbridge/pmgr/dbll.c index 31da62b14bc..db1af795544 100644 --- a/drivers/staging/tidspbridge/pmgr/dbll.c +++ b/drivers/staging/tidspbridge/pmgr/dbll.c @@ -202,9 +202,6 @@ void dbll_close(struct dbll_library_obj *zl_lib) { struct dbll_tar_obj *zl_target; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(zl_lib); - DBC_REQUIRE(zl_lib->open_ref > 0); zl_target = zl_lib->target_obj; zl_lib->open_ref--; if (zl_lib->open_ref == 0) { @@ -241,10 +238,6 @@ int dbll_create(struct dbll_tar_obj **target_obj, struct dbll_tar_obj *pzl_target; int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(pattrs != NULL); - DBC_REQUIRE(target_obj != NULL); - /* Allocate DBL target object */ pzl_target = kzalloc(sizeof(struct dbll_tar_obj), GFP_KERNEL); if (target_obj != NULL) { @@ -255,8 +248,6 @@ int dbll_create(struct dbll_tar_obj **target_obj, pzl_target->attrs = *pattrs; *target_obj = (struct dbll_tar_obj *)pzl_target; } - DBC_ENSURE((!status && *target_obj) || - (status && *target_obj == NULL)); } return status; @@ -269,9 +260,6 @@ void dbll_delete(struct dbll_tar_obj *target) { struct dbll_tar_obj *zl_target = (struct dbll_tar_obj *)target; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(zl_target); - kfree(zl_target); } @@ -282,14 +270,10 @@ void dbll_delete(struct dbll_tar_obj *target) */ void dbll_exit(void) { - DBC_REQUIRE(refs > 0); - refs--; if (refs == 0) gh_exit(); - - DBC_ENSURE(refs >= 0); } /* @@ -302,12 +286,6 @@ bool dbll_get_addr(struct dbll_library_obj *zl_lib, char *name, struct dbll_symbol *sym; bool status = false; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(zl_lib); - DBC_REQUIRE(name != NULL); - DBC_REQUIRE(sym_val != NULL); - DBC_REQUIRE(zl_lib->sym_tab != NULL); - sym = (struct dbll_symbol *)gh_find(zl_lib->sym_tab, name); if (sym != NULL) { *sym_val = &sym->value; @@ -327,10 +305,6 @@ void dbll_get_attrs(struct dbll_tar_obj *target, struct dbll_attrs *pattrs) { struct dbll_tar_obj *zl_target = (struct dbll_tar_obj *)target; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(zl_target); - DBC_REQUIRE(pattrs != NULL); - if ((pattrs != NULL) && (zl_target != NULL)) *pattrs = zl_target->attrs; @@ -347,12 +321,6 @@ bool dbll_get_c_addr(struct dbll_library_obj *zl_lib, char *name, char cname[MAXEXPR + 1]; bool status = false; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(zl_lib); - DBC_REQUIRE(sym_val != NULL); - DBC_REQUIRE(zl_lib->sym_tab != NULL); - DBC_REQUIRE(name != NULL); - cname[0] = '_'; strncpy(cname + 1, name, sizeof(cname) - 2); @@ -382,12 +350,6 @@ int dbll_get_sect(struct dbll_library_obj *lib, char *name, u32 *paddr, struct dbll_library_obj *zl_lib = (struct dbll_library_obj *)lib; int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(name != NULL); - DBC_REQUIRE(paddr != NULL); - DBC_REQUIRE(psize != NULL); - DBC_REQUIRE(zl_lib); - /* If DOFF file is not open, we open it. */ if (zl_lib != NULL) { if (zl_lib->fp == NULL) { @@ -434,8 +396,6 @@ int dbll_get_sect(struct dbll_library_obj *lib, char *name, u32 *paddr, */ bool dbll_init(void) { - DBC_REQUIRE(refs >= 0); - if (refs == 0) gh_init(); @@ -456,10 +416,6 @@ int dbll_load(struct dbll_library_obj *lib, dbll_flags flags, s32 err; int status = 0; bool opened_doff = false; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(zl_lib); - DBC_REQUIRE(entry != NULL); - DBC_REQUIRE(attrs != NULL); /* * Load if not already loaded. @@ -558,8 +514,6 @@ int dbll_load(struct dbll_library_obj *lib, dbll_flags flags, if (opened_doff) dof_close(zl_lib); - DBC_ENSURE(status || zl_lib->load_ref > 0); - dev_dbg(bridge, "%s: lib: %p flags: 0x%x entry: %p, status 0x%x\n", __func__, lib, flags, entry, status); @@ -577,12 +531,6 @@ int dbll_open(struct dbll_tar_obj *target, char *file, dbll_flags flags, s32 err; int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(zl_target); - DBC_REQUIRE(zl_target->attrs.fopen != NULL); - DBC_REQUIRE(file != NULL); - DBC_REQUIRE(lib_obj != NULL); - zl_lib = zl_target->head; while (zl_lib != NULL) { if (strcmp(zl_lib->file_name, file) == 0) { @@ -699,8 +647,6 @@ func_cont: dbll_close((struct dbll_library_obj *)zl_lib); } - DBC_ENSURE((!status && (zl_lib->open_ref > 0) && *lib_obj) - || (status && *lib_obj == NULL)); dev_dbg(bridge, "%s: target: %p file: %s lib_obj: %p, status 0x%x\n", __func__, target, file, lib_obj, status); @@ -722,12 +668,6 @@ int dbll_read_sect(struct dbll_library_obj *lib, char *name, const struct ldr_section_info *sect = NULL; int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(zl_lib); - DBC_REQUIRE(name != NULL); - DBC_REQUIRE(buf != NULL); - DBC_REQUIRE(size != 0); - /* If DOFF file is not open, we open it. */ if (zl_lib != NULL) { if (zl_lib->fp == NULL) { @@ -788,14 +728,11 @@ void dbll_unload(struct dbll_library_obj *lib, struct dbll_attrs *attrs) struct dbll_library_obj *zl_lib = (struct dbll_library_obj *)lib; s32 err = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(zl_lib); - DBC_REQUIRE(zl_lib->load_ref > 0); dev_dbg(bridge, "%s: lib: %p\n", __func__, lib); zl_lib->load_ref--; /* Unload only if reference count is 0 */ if (zl_lib->load_ref != 0) - goto func_end; + return; zl_lib->target_obj->attrs = *attrs; if (zl_lib->dload_mod_obj) { @@ -814,8 +751,6 @@ void dbll_unload(struct dbll_library_obj *lib, struct dbll_attrs *attrs) /* delete DOFF desc since it holds *lots* of host OS * resources */ dof_close(zl_lib); -func_end: - DBC_ENSURE(zl_lib->load_ref >= 0); } /* @@ -874,8 +809,6 @@ static u16 name_hash(void *key, u16 max_bucket) u16 hash; char *name = (char *)key; - DBC_REQUIRE(name != NULL); - hash = 0; while (*name) { @@ -893,9 +826,6 @@ static u16 name_hash(void *key, u16 max_bucket) */ static bool name_match(void *key, void *sp) { - DBC_REQUIRE(key != NULL); - DBC_REQUIRE(sp != NULL); - if ((key != NULL) && (sp != NULL)) { if (strcmp((char *)key, ((struct dbll_symbol *)sp)->name) == 0) @@ -938,10 +868,7 @@ static int dbll_read_buffer(struct dynamic_loader_stream *this, void *buffer, struct dbll_library_obj *lib; int bytes_read = 0; - DBC_REQUIRE(this != NULL); lib = pstream->lib; - DBC_REQUIRE(lib); - if (lib != NULL) { bytes_read = (*(lib->target_obj->attrs.fread)) (buffer, 1, bufsize, @@ -960,10 +887,7 @@ static int dbll_set_file_posn(struct dynamic_loader_stream *this, struct dbll_library_obj *lib; int status = 0; /* Success */ - DBC_REQUIRE(this != NULL); lib = pstream->lib; - DBC_REQUIRE(lib); - if (lib != NULL) { status = (*(lib->target_obj->attrs.fseek)) (lib->fp, (long)pos, SEEK_SET); @@ -986,10 +910,7 @@ static struct dynload_symbol *dbll_find_symbol(struct dynamic_loader_sym *this, struct dbll_sym_val *dbll_sym = NULL; bool status = false; /* Symbol not found yet */ - DBC_REQUIRE(this != NULL); lib = ldr_sym->lib; - DBC_REQUIRE(lib); - if (lib != NULL) { if (lib->target_obj->attrs.sym_lookup) { /* Check current lib + base lib + dep lib + @@ -1034,11 +955,7 @@ static struct dynload_symbol *find_in_symbol_table(struct dynamic_loader_sym struct dbll_library_obj *lib; struct dbll_symbol *sym; - DBC_REQUIRE(this != NULL); lib = ldr_sym->lib; - DBC_REQUIRE(lib); - DBC_REQUIRE(lib->sym_tab != NULL); - sym = (struct dbll_symbol *)gh_find(lib->sym_tab, (char *)name); ret_sym = (struct dynload_symbol *)&sym->value; @@ -1059,10 +976,7 @@ static struct dynload_symbol *dbll_add_to_symbol_table(struct dynamic_loader_sym struct dbll_library_obj *lib; struct dynload_symbol *ret; - DBC_REQUIRE(this != NULL); - DBC_REQUIRE(name); lib = ldr_sym->lib; - DBC_REQUIRE(lib); /* Check to see if symbol is already defined in symbol table */ if (!(lib->target_obj->attrs.base_image)) { @@ -1111,10 +1025,7 @@ static void dbll_purge_symbol_table(struct dynamic_loader_sym *this, struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this; struct dbll_library_obj *lib; - DBC_REQUIRE(this != NULL); lib = ldr_sym->lib; - DBC_REQUIRE(lib); - /* May not need to do anything */ } @@ -1127,9 +1038,7 @@ static void *allocate(struct dynamic_loader_sym *this, unsigned memsize) struct dbll_library_obj *lib; void *buf; - DBC_REQUIRE(this != NULL); lib = ldr_sym->lib; - DBC_REQUIRE(lib); buf = kzalloc(memsize, GFP_KERNEL); @@ -1144,9 +1053,7 @@ static void deallocate(struct dynamic_loader_sym *this, void *mem_ptr) struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this; struct dbll_library_obj *lib; - DBC_REQUIRE(this != NULL); lib = ldr_sym->lib; - DBC_REQUIRE(lib); kfree(mem_ptr); } @@ -1161,9 +1068,7 @@ static void dbll_err_report(struct dynamic_loader_sym *this, const char *errstr, struct dbll_library_obj *lib; char temp_buf[MAXEXPR]; - DBC_REQUIRE(this != NULL); lib = ldr_sym->lib; - DBC_REQUIRE(lib); vsnprintf((char *)temp_buf, MAXEXPR, (char *)errstr, args); dev_dbg(bridge, "%s\n", temp_buf); } @@ -1195,9 +1100,7 @@ static int dbll_rmm_alloc(struct dynamic_loader_allocate *this, u32 alloc_size = 0; u32 run_addr_flag = 0; - DBC_REQUIRE(this != NULL); lib = dbll_alloc_obj->lib; - DBC_REQUIRE(lib); mem_sect_type = (stype == DLOAD_TEXT) ? DBLL_CODE : (stype == @@ -1206,7 +1109,6 @@ static int dbll_rmm_alloc(struct dynamic_loader_allocate *this, /* Attempt to extract the segment ID and requirement information from the name of the section */ - DBC_REQUIRE(info->name); token_len = strlen((char *)(info->name)) + 1; sz_sect_name = kzalloc(token_len, GFP_KERNEL); @@ -1307,9 +1209,7 @@ static void rmm_dealloc(struct dynamic_loader_allocate *this, (stype == DLOAD_TEXT) ? DBLL_CODE : (stype == DLOAD_BSS) ? DBLL_BSS : DBLL_DATA; - DBC_REQUIRE(this != NULL); lib = dbll_alloc_obj->lib; - DBC_REQUIRE(lib); /* segid was set by alloc function */ segid = (u32) info->context; if (mem_sect_type == DBLL_CODE) @@ -1347,9 +1247,7 @@ static int read_mem(struct dynamic_loader_initialize *this, void *buf, struct dbll_library_obj *lib; int bytes_read = 0; - DBC_REQUIRE(this != NULL); lib = init_obj->lib; - DBC_REQUIRE(lib); /* Need bridge_brd_read function */ return bytes_read; } @@ -1368,7 +1266,6 @@ static int write_mem(struct dynamic_loader_initialize *this, void *buf, u32 mem_sect_type; bool ret = true; - DBC_REQUIRE(this != NULL); lib = init_obj->lib; if (!lib) return false; @@ -1415,7 +1312,6 @@ static int fill_mem(struct dynamic_loader_initialize *this, ldr_addr addr, struct dbll_library_obj *lib; struct dbll_init_obj *init_obj = (struct dbll_init_obj *)this; - DBC_REQUIRE(this != NULL); lib = init_obj->lib; pbuf = NULL; /* Pass the NULL pointer to write_mem to get the start address of Shared @@ -1439,9 +1335,7 @@ static int execute(struct dynamic_loader_initialize *this, ldr_addr start) struct dbll_library_obj *lib; bool ret = true; - DBC_REQUIRE(this != NULL); lib = init_obj->lib; - DBC_REQUIRE(lib); /* Save entry point */ if (lib != NULL) lib->entry = (u32) start; diff --git a/drivers/staging/tidspbridge/pmgr/dev.c b/drivers/staging/tidspbridge/pmgr/dev.c index 522810bc742..e4257fd7ff0 100644 --- a/drivers/staging/tidspbridge/pmgr/dev.c +++ b/drivers/staging/tidspbridge/pmgr/dev.c @@ -106,8 +106,6 @@ u32 dev_brd_write_fxn(void *arb, u32 dsp_add, void *host_buf, u32 ul_written = 0; int status; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(host_buf != NULL); /* Required of BrdWrite(). */ if (dev_obj) { /* Require of BrdWrite() */ DBC_ASSERT(dev_obj->bridge_context != NULL); @@ -143,9 +141,6 @@ int dev_create_device(struct dev_object **device_obj, struct drv_object *hdrv_obj = NULL; struct drv_data *drv_datap = dev_get_drvdata(bridge); int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(device_obj != NULL); - DBC_REQUIRE(driver_file_name != NULL); status = drv_request_bridge_res_dsp((void *)&host_res); @@ -271,7 +266,6 @@ leave: *device_obj = NULL; } - DBC_ENSURE((!status && *device_obj) || (status && !*device_obj)); return status; } @@ -287,17 +281,12 @@ int dev_create2(struct dev_object *hdev_obj) int status = 0; struct dev_object *dev_obj = hdev_obj; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(hdev_obj); - /* There can be only one Node Manager per DEV object */ DBC_ASSERT(!dev_obj->node_mgr); status = node_create_mgr(&dev_obj->node_mgr, hdev_obj); if (status) dev_obj->node_mgr = NULL; - DBC_ENSURE((!status && dev_obj->node_mgr != NULL) - || (status && dev_obj->node_mgr == NULL)); return status; } @@ -311,9 +300,6 @@ int dev_destroy2(struct dev_object *hdev_obj) int status = 0; struct dev_object *dev_obj = hdev_obj; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(hdev_obj); - if (dev_obj->node_mgr) { if (node_delete_mgr(dev_obj->node_mgr)) status = -EPERM; @@ -322,7 +308,6 @@ int dev_destroy2(struct dev_object *hdev_obj) } - DBC_ENSURE((!status && dev_obj->node_mgr == NULL) || status); return status; } @@ -337,8 +322,6 @@ int dev_destroy_device(struct dev_object *hdev_obj) int status = 0; struct dev_object *dev_obj = hdev_obj; - DBC_REQUIRE(refs > 0); - if (hdev_obj) { if (dev_obj->cod_mgr) { cod_delete(dev_obj->cod_mgr); @@ -415,9 +398,6 @@ int dev_get_chnl_mgr(struct dev_object *hdev_obj, int status = 0; struct dev_object *dev_obj = hdev_obj; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(mgr != NULL); - if (hdev_obj) { *mgr = dev_obj->chnl_mgr; } else { @@ -425,7 +405,6 @@ int dev_get_chnl_mgr(struct dev_object *hdev_obj, status = -EFAULT; } - DBC_ENSURE(!status || (mgr != NULL && *mgr == NULL)); return status; } @@ -441,9 +420,6 @@ int dev_get_cmm_mgr(struct dev_object *hdev_obj, int status = 0; struct dev_object *dev_obj = hdev_obj; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(mgr != NULL); - if (hdev_obj) { *mgr = dev_obj->cmm_mgr; } else { @@ -451,7 +427,6 @@ int dev_get_cmm_mgr(struct dev_object *hdev_obj, status = -EFAULT; } - DBC_ENSURE(!status || (mgr != NULL && *mgr == NULL)); return status; } @@ -467,9 +442,6 @@ int dev_get_dmm_mgr(struct dev_object *hdev_obj, int status = 0; struct dev_object *dev_obj = hdev_obj; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(mgr != NULL); - if (hdev_obj) { *mgr = dev_obj->dmm_mgr; } else { @@ -477,7 +449,6 @@ int dev_get_dmm_mgr(struct dev_object *hdev_obj, status = -EFAULT; } - DBC_ENSURE(!status || (mgr != NULL && *mgr == NULL)); return status; } @@ -492,9 +463,6 @@ int dev_get_cod_mgr(struct dev_object *hdev_obj, int status = 0; struct dev_object *dev_obj = hdev_obj; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(cod_mgr != NULL); - if (hdev_obj) { *cod_mgr = dev_obj->cod_mgr; } else { @@ -502,7 +470,6 @@ int dev_get_cod_mgr(struct dev_object *hdev_obj, status = -EFAULT; } - DBC_ENSURE(!status || (cod_mgr != NULL && *cod_mgr == NULL)); return status; } @@ -514,9 +481,6 @@ int dev_get_deh_mgr(struct dev_object *hdev_obj, { int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(deh_manager != NULL); - DBC_REQUIRE(hdev_obj); if (hdev_obj) { *deh_manager = hdev_obj->deh_mgr; } else { @@ -537,9 +501,6 @@ int dev_get_dev_node(struct dev_object *hdev_obj, int status = 0; struct dev_object *dev_obj = hdev_obj; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(dev_nde != NULL); - if (hdev_obj) { *dev_nde = dev_obj->dev_node_obj; } else { @@ -547,7 +508,6 @@ int dev_get_dev_node(struct dev_object *hdev_obj, status = -EFAULT; } - DBC_ENSURE(!status || (dev_nde != NULL && *dev_nde == NULL)); return status; } @@ -578,9 +538,6 @@ int dev_get_intf_fxns(struct dev_object *hdev_obj, int status = 0; struct dev_object *dev_obj = hdev_obj; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(if_fxns != NULL); - if (hdev_obj) { *if_fxns = &dev_obj->bridge_interface; } else { @@ -588,7 +545,6 @@ int dev_get_intf_fxns(struct dev_object *hdev_obj, status = -EFAULT; } - DBC_ENSURE(!status || ((if_fxns != NULL) && (*if_fxns == NULL))); return status; } @@ -600,10 +556,6 @@ int dev_get_io_mgr(struct dev_object *hdev_obj, { int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(io_man != NULL); - DBC_REQUIRE(hdev_obj); - if (hdev_obj) { *io_man = hdev_obj->iomgr; } else { @@ -638,10 +590,6 @@ struct dev_object *dev_get_next(struct dev_object *hdev_obj) */ void dev_get_msg_mgr(struct dev_object *hdev_obj, struct msg_mgr **msg_man) { - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(msg_man != NULL); - DBC_REQUIRE(hdev_obj); - *msg_man = hdev_obj->msg_mgr; } @@ -656,9 +604,6 @@ int dev_get_node_manager(struct dev_object *hdev_obj, int status = 0; struct dev_object *dev_obj = hdev_obj; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(node_man != NULL); - if (hdev_obj) { *node_man = dev_obj->node_mgr; } else { @@ -666,7 +611,6 @@ int dev_get_node_manager(struct dev_object *hdev_obj, status = -EFAULT; } - DBC_ENSURE(!status || (node_man != NULL && *node_man == NULL)); return status; } @@ -679,9 +623,6 @@ int dev_get_symbol(struct dev_object *hdev_obj, int status = 0; struct cod_manager *cod_mgr; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(str_sym != NULL && pul_value != NULL); - if (hdev_obj) { status = dev_get_cod_mgr(hdev_obj, &cod_mgr); if (cod_mgr) @@ -706,9 +647,6 @@ int dev_get_bridge_context(struct dev_object *hdev_obj, int status = 0; struct dev_object *dev_obj = hdev_obj; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(phbridge_context != NULL); - if (hdev_obj) { *phbridge_context = dev_obj->bridge_context; } else { @@ -716,8 +654,6 @@ int dev_get_bridge_context(struct dev_object *hdev_obj, status = -EFAULT; } - DBC_ENSURE(!status || ((phbridge_context != NULL) && - (*phbridge_context == NULL))); return status; } @@ -729,16 +665,12 @@ int dev_get_bridge_context(struct dev_object *hdev_obj, */ void dev_exit(void) { - DBC_REQUIRE(refs > 0); - refs--; if (refs == 0) { cmm_exit(); dmm_exit(); } - - DBC_ENSURE(refs >= 0); } /* @@ -750,8 +682,6 @@ bool dev_init(void) { bool cmm_ret, dmm_ret, ret = true; - DBC_REQUIRE(refs >= 0); - if (refs == 0) { cmm_ret = cmm_init(); dmm_ret = dmm_init(); @@ -771,8 +701,6 @@ bool dev_init(void) if (ret) refs++; - DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0))); - return ret; } @@ -841,14 +769,11 @@ int dev_set_chnl_mgr(struct dev_object *hdev_obj, int status = 0; struct dev_object *dev_obj = hdev_obj; - DBC_REQUIRE(refs > 0); - if (hdev_obj) dev_obj->chnl_mgr = hmgr; else status = -EFAULT; - DBC_ENSURE(status || (dev_obj->chnl_mgr == hmgr)); return status; } @@ -859,9 +784,6 @@ int dev_set_chnl_mgr(struct dev_object *hdev_obj, */ void dev_set_msg_mgr(struct dev_object *hdev_obj, struct msg_mgr *hmgr) { - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(hdev_obj); - hdev_obj->msg_mgr = hmgr; } @@ -879,8 +801,6 @@ int dev_start_device(struct cfg_devnode *dev_node_obj) struct mgr_object *hmgr_obj = NULL; struct drv_data *drv_datap = dev_get_drvdata(bridge); - DBC_REQUIRE(refs > 0); - /* Given all resources, create a device object. */ status = dev_create_device(&hdev_obj, bridge_file_name, dev_node_obj); @@ -944,9 +864,6 @@ static int init_cod_mgr(struct dev_object *dev_obj) int status = 0; char *sz_dummy_file = "dummy"; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(!dev_obj || (dev_obj->cod_mgr == NULL)); - status = cod_create(&dev_obj->cod_mgr, sz_dummy_file); return status; @@ -976,10 +893,6 @@ int dev_insert_proc_object(struct dev_object *hdev_obj, { struct dev_object *dev_obj = (struct dev_object *)hdev_obj; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(dev_obj); - DBC_REQUIRE(proc_obj != 0); - DBC_REQUIRE(already_attached != NULL); if (!list_empty(&dev_obj->proc_list)) *already_attached = true; @@ -1017,10 +930,6 @@ int dev_remove_proc_object(struct dev_object *hdev_obj, u32 proc_obj) struct list_head *cur_elem; struct dev_object *dev_obj = (struct dev_object *)hdev_obj; - DBC_REQUIRE(dev_obj); - DBC_REQUIRE(proc_obj != 0); - DBC_REQUIRE(!list_empty(&dev_obj->proc_list)); - /* Search list for dev_obj: */ list_for_each(cur_elem, &dev_obj->proc_list) { if ((u32) cur_elem == proc_obj) { @@ -1069,10 +978,6 @@ static void store_interface_fxns(struct bridge_drv_interface *drv_fxns, (intf_fxns->pfn = ((drv_fxns->pfn != NULL) ? drv_fxns->pfn : \ (cast)fxn_not_implemented)) - DBC_REQUIRE(intf_fxns != NULL); - DBC_REQUIRE(drv_fxns != NULL); - DBC_REQUIRE(MAKEVERSION(drv_fxns->brd_api_major_version, - drv_fxns->brd_api_minor_version) <= BRD_API_VERSION); bridge_version = MAKEVERSION(drv_fxns->brd_api_major_version, drv_fxns->brd_api_minor_version); intf_fxns->brd_api_major_version = drv_fxns->brd_api_major_version; @@ -1119,33 +1024,5 @@ static void store_interface_fxns(struct bridge_drv_interface *drv_fxns, STORE_FXN(fxn_msg_setqueueid, msg_set_queue_id); } /* Add code for any additional functions in newerBridge versions here */ - /* Ensure postcondition: */ - DBC_ENSURE(intf_fxns->dev_create != NULL); - DBC_ENSURE(intf_fxns->dev_destroy != NULL); - DBC_ENSURE(intf_fxns->dev_cntrl != NULL); - DBC_ENSURE(intf_fxns->brd_monitor != NULL); - DBC_ENSURE(intf_fxns->brd_start != NULL); - DBC_ENSURE(intf_fxns->brd_stop != NULL); - DBC_ENSURE(intf_fxns->brd_status != NULL); - DBC_ENSURE(intf_fxns->brd_read != NULL); - DBC_ENSURE(intf_fxns->brd_write != NULL); - DBC_ENSURE(intf_fxns->chnl_create != NULL); - DBC_ENSURE(intf_fxns->chnl_destroy != NULL); - DBC_ENSURE(intf_fxns->chnl_open != NULL); - DBC_ENSURE(intf_fxns->chnl_close != NULL); - DBC_ENSURE(intf_fxns->chnl_add_io_req != NULL); - DBC_ENSURE(intf_fxns->chnl_get_ioc != NULL); - DBC_ENSURE(intf_fxns->chnl_cancel_io != NULL); - DBC_ENSURE(intf_fxns->chnl_flush_io != NULL); - DBC_ENSURE(intf_fxns->chnl_get_info != NULL); - DBC_ENSURE(intf_fxns->chnl_get_mgr_info != NULL); - DBC_ENSURE(intf_fxns->chnl_idle != NULL); - DBC_ENSURE(intf_fxns->chnl_register_notify != NULL); - DBC_ENSURE(intf_fxns->io_create != NULL); - DBC_ENSURE(intf_fxns->io_destroy != NULL); - DBC_ENSURE(intf_fxns->io_on_loaded != NULL); - DBC_ENSURE(intf_fxns->io_get_proc_load != NULL); - DBC_ENSURE(intf_fxns->msg_set_queue_id != NULL); - #undef STORE_FXN } diff --git a/drivers/staging/tidspbridge/pmgr/dmm.c b/drivers/staging/tidspbridge/pmgr/dmm.c index 8685233d762..cece7801d6c 100644 --- a/drivers/staging/tidspbridge/pmgr/dmm.c +++ b/drivers/staging/tidspbridge/pmgr/dmm.c @@ -123,8 +123,6 @@ int dmm_create(struct dmm_object **dmm_manager, { struct dmm_object *dmm_obj = NULL; int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(dmm_manager != NULL); *dmm_manager = NULL; /* create, zero, and tag a cmm mgr object */ @@ -149,7 +147,6 @@ int dmm_destroy(struct dmm_object *dmm_mgr) struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr; int status = 0; - DBC_REQUIRE(refs > 0); if (dmm_mgr) { status = dmm_delete_tables(dmm_obj); if (!status) @@ -169,7 +166,6 @@ int dmm_delete_tables(struct dmm_object *dmm_mgr) { int status = 0; - DBC_REQUIRE(refs > 0); /* Delete all DMM tables */ if (dmm_mgr) vfree(virtual_mapping_table); @@ -186,7 +182,6 @@ int dmm_delete_tables(struct dmm_object *dmm_mgr) */ void dmm_exit(void) { - DBC_REQUIRE(refs > 0); refs--; } @@ -202,8 +197,6 @@ int dmm_get_handle(void *hprocessor, struct dmm_object **dmm_manager) int status = 0; struct dev_object *hdev_obj; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(dmm_manager != NULL); if (hprocessor != NULL) status = proc_get_dev_object(hprocessor, &hdev_obj); else @@ -224,13 +217,9 @@ bool dmm_init(void) { bool ret = true; - DBC_REQUIRE(refs >= 0); - if (ret) refs++; - DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0))); - virtual_mapping_table = NULL; table_size = 0; diff --git a/drivers/staging/tidspbridge/pmgr/dspapi.c b/drivers/staging/tidspbridge/pmgr/dspapi.c index 767ffe270ed..27c14a577dc 100644 --- a/drivers/staging/tidspbridge/pmgr/dspapi.c +++ b/drivers/staging/tidspbridge/pmgr/dspapi.c @@ -266,7 +266,6 @@ err: */ void api_exit(void) { - DBC_REQUIRE(api_c_refs > 0); api_c_refs--; if (api_c_refs == 0) { @@ -284,7 +283,6 @@ void api_exit(void) rmm_exit(); drv_exit(); } - DBC_ENSURE(api_c_refs >= 0); } /* @@ -382,8 +380,6 @@ int api_init_complete2(void) struct drv_data *drv_datap; u8 dev_type; - DBC_REQUIRE(api_c_refs > 0); - /* Walk the list of DevObjects, get each devnode, and attempting to * autostart the board. Note that this requires COF loading, which * requires KFILE. */ diff --git a/drivers/staging/tidspbridge/pmgr/io.c b/drivers/staging/tidspbridge/pmgr/io.c index 65245f310f8..bbfe94cb36b 100644 --- a/drivers/staging/tidspbridge/pmgr/io.c +++ b/drivers/staging/tidspbridge/pmgr/io.c @@ -50,10 +50,6 @@ int io_create(struct io_mgr **io_man, struct dev_object *hdev_obj, struct io_mgr_ *pio_mgr = NULL; int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(io_man != NULL); - DBC_REQUIRE(mgr_attrts != NULL); - *io_man = NULL; /* A memory base of 0 implies no memory base: */ @@ -94,8 +90,6 @@ int io_destroy(struct io_mgr *hio_mgr) struct io_mgr_ *pio_mgr = (struct io_mgr_ *)hio_mgr; int status; - DBC_REQUIRE(refs > 0); - intf_fxns = pio_mgr->intf_fxns; /* Let Bridge channel module destroy the io_mgr: */ @@ -111,11 +105,7 @@ int io_destroy(struct io_mgr *hio_mgr) */ void io_exit(void) { - DBC_REQUIRE(refs > 0); - refs--; - - DBC_ENSURE(refs >= 0); } /* @@ -127,12 +117,8 @@ bool io_init(void) { bool ret = true; - DBC_REQUIRE(refs >= 0); - if (ret) refs++; - DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0))); - return ret; } diff --git a/drivers/staging/tidspbridge/pmgr/msg.c b/drivers/staging/tidspbridge/pmgr/msg.c index a6916039eed..150026dfc74 100644 --- a/drivers/staging/tidspbridge/pmgr/msg.c +++ b/drivers/staging/tidspbridge/pmgr/msg.c @@ -53,11 +53,6 @@ int msg_create(struct msg_mgr **msg_man, struct msg_mgr *hmsg_mgr; int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(msg_man != NULL); - DBC_REQUIRE(msg_callback != NULL); - DBC_REQUIRE(hdev_obj != NULL); - *msg_man = NULL; dev_get_intf_fxns(hdev_obj, &intf_fxns); @@ -90,8 +85,6 @@ void msg_delete(struct msg_mgr *hmsg_mgr) struct msg_mgr_ *msg_mgr_obj = (struct msg_mgr_ *)hmsg_mgr; struct bridge_drv_interface *intf_fxns; - DBC_REQUIRE(refs > 0); - if (msg_mgr_obj) { intf_fxns = msg_mgr_obj->intf_fxns; @@ -108,10 +101,7 @@ void msg_delete(struct msg_mgr *hmsg_mgr) */ void msg_exit(void) { - DBC_REQUIRE(refs > 0); refs--; - - DBC_ENSURE(refs >= 0); } /* @@ -119,11 +109,7 @@ void msg_exit(void) */ bool msg_mod_init(void) { - DBC_REQUIRE(refs >= 0); - refs++; - DBC_ENSURE(refs >= 0); - return true; } diff --git a/drivers/staging/tidspbridge/rmgr/dbdcd.c b/drivers/staging/tidspbridge/rmgr/dbdcd.c index fda240214cd..792b44363fd 100644 --- a/drivers/staging/tidspbridge/rmgr/dbdcd.c +++ b/drivers/staging/tidspbridge/rmgr/dbdcd.c @@ -85,8 +85,6 @@ int dcd_auto_register(struct dcd_manager *hdcd_mgr, { int status = 0; - DBC_REQUIRE(refs > 0); - if (hdcd_mgr) status = dcd_get_objects(hdcd_mgr, sz_coff_path, (dcd_registerfxn) dcd_register_object, @@ -107,8 +105,6 @@ int dcd_auto_unregister(struct dcd_manager *hdcd_mgr, { int status = 0; - DBC_REQUIRE(refs > 0); - if (hdcd_mgr) status = dcd_get_objects(hdcd_mgr, sz_coff_path, (dcd_registerfxn) dcd_register_object, @@ -131,9 +127,6 @@ int dcd_create_manager(char *sz_zl_dll_name, struct dcd_manager *dcd_mgr_obj = NULL; /* DCD Manager pointer */ int status = 0; - DBC_REQUIRE(refs >= 0); - DBC_REQUIRE(dcd_mgr); - status = cod_create(&cod_mgr, sz_zl_dll_name); if (status) goto func_end; @@ -156,9 +149,6 @@ int dcd_create_manager(char *sz_zl_dll_name, cod_delete(cod_mgr); } - DBC_ENSURE((!status) || - ((dcd_mgr_obj == NULL) && (status == -ENOMEM))); - func_end: return status; } @@ -173,8 +163,6 @@ int dcd_destroy_manager(struct dcd_manager *hdcd_mgr) struct dcd_manager *dcd_mgr_obj = hdcd_mgr; int status = -EFAULT; - DBC_REQUIRE(refs >= 0); - if (hdcd_mgr) { /* Delete the COD manager. */ cod_delete(dcd_mgr_obj->cod_mgr); @@ -205,10 +193,6 @@ int dcd_enumerate_object(s32 index, enum dsp_dcdobjtype obj_type, struct dcd_key_elem *dcd_key; int len; - DBC_REQUIRE(refs >= 0); - DBC_REQUIRE(index >= 0); - DBC_REQUIRE(uuid_obj != NULL); - if ((index != 0) && (enum_refs == 0)) { /* * If an enumeration is being performed on an index greater @@ -294,8 +278,6 @@ int dcd_enumerate_object(s32 index, enum dsp_dcdobjtype obj_type, } } - DBC_ENSURE(uuid_obj || (status == -EPERM)); - return status; } @@ -307,7 +289,6 @@ int dcd_enumerate_object(s32 index, enum dsp_dcdobjtype obj_type, void dcd_exit(void) { struct dcd_key_elem *rv, *rv_tmp; - DBC_REQUIRE(refs > 0); refs--; if (refs == 0) { @@ -319,7 +300,6 @@ void dcd_exit(void) } } - DBC_ENSURE(refs >= 0); } /* @@ -333,12 +313,6 @@ int dcd_get_dep_libs(struct dcd_manager *hdcd_mgr, { int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(hdcd_mgr); - DBC_REQUIRE(uuid_obj != NULL); - DBC_REQUIRE(dep_lib_uuids != NULL); - DBC_REQUIRE(prstnt_dep_libs != NULL); - status = get_dep_lib_info(hdcd_mgr, uuid_obj, &num_libs, NULL, dep_lib_uuids, prstnt_dep_libs, phase); @@ -356,12 +330,6 @@ int dcd_get_num_dep_libs(struct dcd_manager *hdcd_mgr, { int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(hdcd_mgr); - DBC_REQUIRE(num_libs != NULL); - DBC_REQUIRE(num_pers_libs != NULL); - DBC_REQUIRE(uuid_obj != NULL); - status = get_dep_lib_info(hdcd_mgr, uuid_obj, num_libs, num_pers_libs, NULL, NULL, phase); @@ -393,10 +361,6 @@ int dcd_get_object_def(struct dcd_manager *hdcd_mgr, u32 dw_key_len; /* Len of REG key. */ char sz_obj_type[MAX_INT2CHAR_LENGTH]; /* str. rep. of obj_type. */ - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(obj_def != NULL); - DBC_REQUIRE(obj_uuid != NULL); - sz_uuid = kzalloc(MAXUUIDLEN, GFP_KERNEL); if (!sz_uuid) { status = -ENOMEM; @@ -553,7 +517,6 @@ int dcd_get_objects(struct dcd_manager *hdcd_mgr, struct dsp_uuid dsp_uuid_obj; s32 object_type; - DBC_REQUIRE(refs > 0); if (!hdcd_mgr) { status = -EFAULT; goto func_end; @@ -663,11 +626,6 @@ int dcd_get_library_name(struct dcd_manager *hdcd_mgr, int status = 0; struct dcd_key_elem *dcd_key = NULL; - DBC_REQUIRE(uuid_obj != NULL); - DBC_REQUIRE(str_lib_name != NULL); - DBC_REQUIRE(buff_size != NULL); - DBC_REQUIRE(hdcd_mgr); - dev_dbg(bridge, "%s: hdcd_mgr %p, uuid_obj %p, str_lib_name %p," " buff_size %p\n", __func__, hdcd_mgr, uuid_obj, str_lib_name, buff_size); @@ -790,8 +748,6 @@ bool dcd_init(void) bool init_cod; bool ret = true; - DBC_REQUIRE(refs >= 0); - if (refs == 0) { /* Initialize required modules. */ init_cod = cod_init(); @@ -809,8 +765,6 @@ bool dcd_init(void) if (ret) refs++; - DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs == 0))); - return ret; } @@ -832,15 +786,6 @@ int dcd_register_object(struct dsp_uuid *uuid_obj, char sz_obj_type[MAX_INT2CHAR_LENGTH]; /* str. rep. of obj_type. */ struct dcd_key_elem *dcd_key = NULL; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(uuid_obj != NULL); - DBC_REQUIRE((obj_type == DSP_DCDNODETYPE) || - (obj_type == DSP_DCDPROCESSORTYPE) || - (obj_type == DSP_DCDLIBRARYTYPE) || - (obj_type == DSP_DCDCREATELIBTYPE) || - (obj_type == DSP_DCDEXECUTELIBTYPE) || - (obj_type == DSP_DCDDELETELIBTYPE)); - dev_dbg(bridge, "%s: object UUID %p, obj_type %d, szPathName %s\n", __func__, uuid_obj, obj_type, psz_path_name); @@ -987,15 +932,6 @@ int dcd_unregister_object(struct dsp_uuid *uuid_obj, { int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(uuid_obj != NULL); - DBC_REQUIRE((obj_type == DSP_DCDNODETYPE) || - (obj_type == DSP_DCDPROCESSORTYPE) || - (obj_type == DSP_DCDLIBRARYTYPE) || - (obj_type == DSP_DCDCREATELIBTYPE) || - (obj_type == DSP_DCDEXECUTELIBTYPE) || - (obj_type == DSP_DCDDELETELIBTYPE)); - /* * When dcd_register_object is called with NULL as pathname, * it indicates an unregister object operation. @@ -1055,12 +991,6 @@ static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size, s32 entry_id; #endif - DBC_REQUIRE(psz_buf != NULL); - DBC_REQUIRE(ul_buf_size != 0); - DBC_REQUIRE((obj_type == DSP_DCDNODETYPE) - || (obj_type == DSP_DCDPROCESSORTYPE)); - DBC_REQUIRE(gen_obj != NULL); - switch (obj_type) { case DSP_DCDNODETYPE: /* @@ -1082,7 +1012,6 @@ static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size, token = strsep(&psz_cur, seps); /* ac_name */ - DBC_REQUIRE(token); token_len = strlen(token); if (token_len > DSP_MAXNAMELEN - 1) token_len = DSP_MAXNAMELEN - 1; @@ -1167,7 +1096,6 @@ static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size, token = strsep(&psz_cur, seps); /* char *str_create_phase_fxn */ - DBC_REQUIRE(token); token_len = strlen(token); gen_obj->obj_data.node_obj.str_create_phase_fxn = kzalloc(token_len + 1, GFP_KERNEL); @@ -1178,7 +1106,6 @@ static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size, token = strsep(&psz_cur, seps); /* char *str_execute_phase_fxn */ - DBC_REQUIRE(token); token_len = strlen(token); gen_obj->obj_data.node_obj.str_execute_phase_fxn = kzalloc(token_len + 1, GFP_KERNEL); @@ -1189,7 +1116,6 @@ static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size, token = strsep(&psz_cur, seps); /* char *str_delete_phase_fxn */ - DBC_REQUIRE(token); token_len = strlen(token); gen_obj->obj_data.node_obj.str_delete_phase_fxn = kzalloc(token_len + 1, GFP_KERNEL); @@ -1421,12 +1347,6 @@ static int get_dep_lib_info(struct dcd_manager *hdcd_mgr, u16 dep_libs = 0; int status = 0; - DBC_REQUIRE(refs > 0); - - DBC_REQUIRE(hdcd_mgr); - DBC_REQUIRE(num_libs != NULL); - DBC_REQUIRE(uuid_obj != NULL); - /* Initialize to 0 dependent libraries, if only counting number of * dependent libraries */ if (!get_uuids) { diff --git a/drivers/staging/tidspbridge/rmgr/disp.c b/drivers/staging/tidspbridge/rmgr/disp.c index a9aa22f3b4f..04c88a7d019 100644 --- a/drivers/staging/tidspbridge/rmgr/disp.c +++ b/drivers/staging/tidspbridge/rmgr/disp.c @@ -96,11 +96,6 @@ int disp_create(struct disp_object **dispatch_obj, int status = 0; u8 dev_type; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(dispatch_obj != NULL); - DBC_REQUIRE(disp_attrs != NULL); - DBC_REQUIRE(hdev_obj != NULL); - *dispatch_obj = NULL; /* Allocate Node Dispatcher object */ @@ -168,8 +163,6 @@ func_cont: else delete_disp(disp_obj); - DBC_ENSURE((status && *dispatch_obj == NULL) || - (!status && *dispatch_obj)); return status; } @@ -179,9 +172,6 @@ func_cont: */ void disp_delete(struct disp_object *disp_obj) { - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(disp_obj); - delete_disp(disp_obj); } @@ -191,11 +181,7 @@ void disp_delete(struct disp_object *disp_obj) */ void disp_exit(void) { - DBC_REQUIRE(refs > 0); - refs--; - - DBC_ENSURE(refs >= 0); } /* @@ -206,12 +192,9 @@ bool disp_init(void) { bool ret = true; - DBC_REQUIRE(refs >= 0); - if (ret) refs++; - DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0))); return ret; } @@ -227,10 +210,6 @@ int disp_node_change_priority(struct disp_object *disp_obj, struct rms_command *rms_cmd; int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(disp_obj); - DBC_REQUIRE(hnode != NULL); - /* Send message to RMS to change priority */ rms_cmd = (struct rms_command *)(disp_obj->buf); rms_cmd->fxn = (rms_word) (rms_fxn); @@ -276,12 +255,6 @@ int disp_node_create(struct disp_object *disp_obj, struct dsp_nodeinfo node_info; u8 dev_type; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(disp_obj); - DBC_REQUIRE(hnode != NULL); - DBC_REQUIRE(node_get_type(hnode) != NODE_DEVICE); - DBC_REQUIRE(node_env != NULL); - status = dev_get_dev_type(disp_obj->dev_obj, &dev_type); if (status) @@ -292,7 +265,6 @@ int disp_node_create(struct disp_object *disp_obj, __func__, dev_type); goto func_end; } - DBC_REQUIRE(pargs != NULL); node_type = node_get_type(hnode); node_msg_args = pargs->asa.node_msg_args; max = disp_obj->bufsize_rms; /*Max # of RMS words that can be sent */ @@ -480,10 +452,6 @@ int disp_node_delete(struct disp_object *disp_obj, int status = 0; u8 dev_type; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(disp_obj); - DBC_REQUIRE(hnode != NULL); - status = dev_get_dev_type(disp_obj->dev_obj, &dev_type); if (!status) { @@ -521,9 +489,6 @@ int disp_node_run(struct disp_object *disp_obj, struct rms_command *rms_cmd; int status = 0; u8 dev_type; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(disp_obj); - DBC_REQUIRE(hnode != NULL); status = dev_get_dev_type(disp_obj->dev_obj, &dev_type); @@ -620,7 +585,6 @@ static int fill_stream_def(rms_word *pdw_buf, u32 *ptotal, u32 offset, * 1 from total. */ total += sizeof(struct rms_strm_def) / sizeof(rms_word) - 1; - DBC_REQUIRE(strm_def.sz_device); dw_length = strlen(strm_def.sz_device) + 1; /* Number of RMS_WORDS needed to hold device name */ @@ -659,8 +623,6 @@ static int send_message(struct disp_object *disp_obj, u32 timeout, struct chnl_ioc chnl_ioc_obj; int status = 0; - DBC_REQUIRE(pdw_arg != NULL); - *pdw_arg = (u32) NULL; intf_fxns = disp_obj->intf_fxns; chnl_obj = disp_obj->chnl_to_dsp; diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c index db8215f540d..f3bff1bfcc6 100644 --- a/drivers/staging/tidspbridge/rmgr/drv.c +++ b/drivers/staging/tidspbridge/rmgr/drv.c @@ -308,9 +308,6 @@ int drv_create(struct drv_object **drv_obj) struct drv_object *pdrv_object = NULL; struct drv_data *drv_datap = dev_get_drvdata(bridge); - DBC_REQUIRE(drv_obj != NULL); - DBC_REQUIRE(refs > 0); - pdrv_object = kzalloc(sizeof(struct drv_object), GFP_KERNEL); if (pdrv_object) { /* Create and Initialize List of device objects */ @@ -336,7 +333,6 @@ int drv_create(struct drv_object **drv_obj) kfree(pdrv_object); } - DBC_ENSURE(status || pdrv_object); return status; } @@ -347,11 +343,7 @@ int drv_create(struct drv_object **drv_obj) */ void drv_exit(void) { - DBC_REQUIRE(refs > 0); - refs--; - - DBC_ENSURE(refs >= 0); } /* @@ -365,9 +357,6 @@ int drv_destroy(struct drv_object *driver_obj) struct drv_object *pdrv_object = (struct drv_object *)driver_obj; struct drv_data *drv_datap = dev_get_drvdata(bridge); - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(pdrv_object); - kfree(pdrv_object); /* Update the DRV Object in the driver data */ if (drv_datap) { @@ -395,10 +384,6 @@ int drv_get_dev_object(u32 index, struct drv_object *hdrv_obj, #endif struct dev_object *dev_obj; u32 i; - DBC_REQUIRE(pdrv_obj); - DBC_REQUIRE(device_obj != NULL); - DBC_REQUIRE(index >= 0); - DBC_REQUIRE(refs > 0); DBC_ASSERT(!(list_empty(&pdrv_obj->dev_list))); dev_obj = (struct dev_object *)drv_get_first_dev_object(); @@ -532,13 +517,9 @@ int drv_init(void) { s32 ret = 1; /* function return value */ - DBC_REQUIRE(refs >= 0); - if (ret) refs++; - DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0))); - return ret; } @@ -552,10 +533,6 @@ int drv_insert_dev_object(struct drv_object *driver_obj, { struct drv_object *pdrv_object = (struct drv_object *)driver_obj; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(hdev_obj != NULL); - DBC_REQUIRE(pdrv_object); - list_add_tail((struct list_head *)hdev_obj, &pdrv_object->dev_list); return 0; @@ -574,12 +551,6 @@ int drv_remove_dev_object(struct drv_object *driver_obj, struct drv_object *pdrv_object = (struct drv_object *)driver_obj; struct list_head *cur_elem; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(pdrv_object); - DBC_REQUIRE(hdev_obj != NULL); - - DBC_REQUIRE(!list_empty(&pdrv_object->dev_list)); - /* Search list for p_proc_object: */ list_for_each(cur_elem, &pdrv_object->dev_list) { /* If found, remove it. */ @@ -605,9 +576,6 @@ int drv_request_resources(u32 dw_context, u32 *dev_node_strg) struct drv_ext *pszdev_node; struct drv_data *drv_datap = dev_get_drvdata(bridge); - DBC_REQUIRE(dw_context != 0); - DBC_REQUIRE(dev_node_strg != NULL); - /* * Allocate memory to hold the string. This will live until * it is freed in the Release resources. Update the driver object @@ -639,10 +607,6 @@ int drv_request_resources(u32 dw_context, u32 *dev_node_strg) *dev_node_strg = 0; } - DBC_ENSURE((!status && dev_node_strg != NULL && - !list_empty(&pdrv_object->dev_node_string)) || - (status && *dev_node_strg == 0)); - return status; } @@ -900,8 +864,6 @@ void *mem_alloc_phys_mem(u32 byte_size, u32 align_mask, void mem_free_phys_mem(void *virtual_address, u32 physical_address, u32 byte_size) { - DBC_REQUIRE(virtual_address != NULL); - if (!ext_phys_mem_pool_enabled) dma_free_coherent(NULL, byte_size, virtual_address, physical_address); diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c index 93fc862c79d..34730de45aa 100644 --- a/drivers/staging/tidspbridge/rmgr/drv_interface.c +++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c @@ -212,7 +212,6 @@ static long bridge_ioctl(struct file *filp, unsigned int code, u32 retval = 0; union trapped_args buf_in; - DBC_REQUIRE(filp != NULL); #ifdef CONFIG_TIDSPBRIDGE_RECOVERY if (recover) { status = -EIO; diff --git a/drivers/staging/tidspbridge/rmgr/dspdrv.c b/drivers/staging/tidspbridge/rmgr/dspdrv.c index 7a6fc737872..5d2576301f7 100644 --- a/drivers/staging/tidspbridge/rmgr/dspdrv.c +++ b/drivers/staging/tidspbridge/rmgr/dspdrv.c @@ -102,8 +102,6 @@ func_cont: } else { dev_dbg(bridge, "%s: Failed\n", __func__); } /* End api_init_complete2 */ - DBC_ENSURE((!status && drv_obj != NULL) || - (status && drv_obj == NULL)); *init_status = status; /* Return the Driver Object */ return (u32) drv_obj; diff --git a/drivers/staging/tidspbridge/rmgr/mgr.c b/drivers/staging/tidspbridge/rmgr/mgr.c index d635c01c015..1dca953e4d6 100644 --- a/drivers/staging/tidspbridge/rmgr/mgr.c +++ b/drivers/staging/tidspbridge/rmgr/mgr.c @@ -62,9 +62,6 @@ int mgr_create(struct mgr_object **mgr_obj, struct mgr_object *pmgr_obj = NULL; struct drv_data *drv_datap = dev_get_drvdata(bridge); - DBC_REQUIRE(mgr_obj != NULL); - DBC_REQUIRE(refs > 0); - pmgr_obj = kzalloc(sizeof(struct mgr_object), GFP_KERNEL); if (pmgr_obj) { status = dcd_create_manager(ZLDLLNAME, &pmgr_obj->dcd_mgr); @@ -92,7 +89,6 @@ int mgr_create(struct mgr_object **mgr_obj, status = -ENOMEM; } - DBC_ENSURE(status || pmgr_obj); return status; } @@ -106,9 +102,6 @@ int mgr_destroy(struct mgr_object *hmgr_obj) struct mgr_object *pmgr_obj = (struct mgr_object *)hmgr_obj; struct drv_data *drv_datap = dev_get_drvdata(bridge); - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(hmgr_obj); - /* Free resources */ if (hmgr_obj->dcd_mgr) dcd_destroy_manager(hmgr_obj->dcd_mgr); @@ -140,11 +133,6 @@ int mgr_enum_node_info(u32 node_id, struct dsp_ndbprops *pndb_props, struct mgr_object *pmgr_obj = NULL; struct drv_data *drv_datap = dev_get_drvdata(bridge); - DBC_REQUIRE(pndb_props != NULL); - DBC_REQUIRE(pu_num_nodes != NULL); - DBC_REQUIRE(undb_props_size >= sizeof(struct dsp_ndbprops)); - DBC_REQUIRE(refs > 0); - *pu_num_nodes = 0; /* Get the Manager Object from the driver data */ if (!drv_datap || !drv_datap->mgr_object) { @@ -205,11 +193,6 @@ int mgr_enum_processor_info(u32 processor_id, struct drv_data *drv_datap = dev_get_drvdata(bridge); bool proc_detect = false; - DBC_REQUIRE(processor_info != NULL); - DBC_REQUIRE(pu_num_procs != NULL); - DBC_REQUIRE(processor_info_size >= sizeof(struct dsp_processorinfo)); - DBC_REQUIRE(refs > 0); - *pu_num_procs = 0; /* Retrieve the Object handle from the driver data */ @@ -310,12 +293,9 @@ func_end: */ void mgr_exit(void) { - DBC_REQUIRE(refs > 0); refs--; if (refs == 0) dcd_exit(); - - DBC_ENSURE(refs >= 0); } /* @@ -328,16 +308,11 @@ int mgr_get_dcd_handle(struct mgr_object *mgr_handle, int status = -EPERM; struct mgr_object *pmgr_obj = (struct mgr_object *)mgr_handle; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(dcd_handle != NULL); - *dcd_handle = (u32) NULL; if (pmgr_obj) { *dcd_handle = (u32) pmgr_obj->dcd_mgr; status = 0; } - DBC_ENSURE((!status && *dcd_handle != (u32) NULL) || - (status && *dcd_handle == (u32) NULL)); return status; } @@ -351,8 +326,6 @@ bool mgr_init(void) bool ret = true; bool init_dcd = false; - DBC_REQUIRE(refs >= 0); - if (refs == 0) { init_dcd = dcd_init(); /* DCD Module */ @@ -363,8 +336,6 @@ bool mgr_init(void) if (ret) refs++; - DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0))); - return ret; } @@ -380,8 +351,6 @@ int mgr_wait_for_bridge_events(struct dsp_notification **anotifications, struct sync_object *sync_events[MAX_EVENTS]; u32 i; - DBC_REQUIRE(count < MAX_EVENTS); - for (i = 0; i < count; i++) sync_events[i] = anotifications[i]->handle; diff --git a/drivers/staging/tidspbridge/rmgr/nldr.c b/drivers/staging/tidspbridge/rmgr/nldr.c index 0e70cba15eb..6fb19ef68a8 100644 --- a/drivers/staging/tidspbridge/rmgr/nldr.c +++ b/drivers/staging/tidspbridge/rmgr/nldr.c @@ -313,11 +313,6 @@ int nldr_allocate(struct nldr_object *nldr_obj, void *priv_ref, struct nldr_nodeobject *nldr_node_obj = NULL; int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(node_props != NULL); - DBC_REQUIRE(nldr_nodeobj != NULL); - DBC_REQUIRE(nldr_obj); - /* Initialize handle in case of failure */ *nldr_nodeobj = NULL; /* Allocate node object */ @@ -398,8 +393,6 @@ int nldr_allocate(struct nldr_object *nldr_obj, void *priv_ref, if (status && nldr_node_obj) kfree(nldr_node_obj); - DBC_ENSURE((!status && *nldr_nodeobj) - || (status && *nldr_nodeobj == NULL)); return status; } @@ -425,12 +418,6 @@ int nldr_create(struct nldr_object **nldr, struct rmm_segment *rmm_segs = NULL; u16 i; int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(nldr != NULL); - DBC_REQUIRE(hdev_obj != NULL); - DBC_REQUIRE(pattrs != NULL); - DBC_REQUIRE(pattrs->ovly != NULL); - DBC_REQUIRE(pattrs->write != NULL); /* Allocate dynamic loader object */ nldr_obj = kzalloc(sizeof(struct nldr_object), GFP_KERNEL); @@ -583,7 +570,6 @@ int nldr_create(struct nldr_object **nldr, *nldr = NULL; } /* FIXME:Temp. Fix. Must be removed */ - DBC_ENSURE((!status && *nldr) || (status && *nldr == NULL)); return status; } @@ -595,8 +581,6 @@ void nldr_delete(struct nldr_object *nldr_obj) struct ovly_sect *ovly_section; struct ovly_sect *next; u16 i; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(nldr_obj); nldr_obj->ldr_fxns.exit_fxn(); if (nldr_obj->rmm) @@ -649,14 +633,10 @@ void nldr_delete(struct nldr_object *nldr_obj) */ void nldr_exit(void) { - DBC_REQUIRE(refs > 0); - refs--; if (refs == 0) rmm_exit(); - - DBC_ENSURE(refs >= 0); } /* @@ -671,10 +651,6 @@ int nldr_get_fxn_addr(struct nldr_nodeobject *nldr_node_obj, bool status1 = false; s32 i = 0; struct lib_node root = { NULL, 0, NULL }; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(nldr_node_obj); - DBC_REQUIRE(addr != NULL); - DBC_REQUIRE(str_fxn != NULL); nldr_obj = nldr_node_obj->nldr_obj; /* Called from node_create(), node_delete(), or node_run(). */ @@ -760,7 +736,6 @@ int nldr_get_rmm_manager(struct nldr_object *nldr, { int status = 0; struct nldr_object *nldr_obj = nldr; - DBC_REQUIRE(rmm_mgr != NULL); if (nldr) { *rmm_mgr = nldr_obj->rmm; @@ -769,8 +744,6 @@ int nldr_get_rmm_manager(struct nldr_object *nldr, status = -EFAULT; } - DBC_ENSURE(!status || (rmm_mgr != NULL && *rmm_mgr == NULL)); - return status; } @@ -780,14 +753,11 @@ int nldr_get_rmm_manager(struct nldr_object *nldr, */ bool nldr_init(void) { - DBC_REQUIRE(refs >= 0); - if (refs == 0) rmm_init(); refs++; - DBC_ENSURE(refs > 0); return true; } @@ -801,9 +771,6 @@ int nldr_load(struct nldr_nodeobject *nldr_node_obj, struct dsp_uuid lib_uuid; int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(nldr_node_obj); - nldr_obj = nldr_node_obj->nldr_obj; if (nldr_node_obj->dynamic) { @@ -863,9 +830,6 @@ int nldr_unload(struct nldr_nodeobject *nldr_node_obj, struct lib_node *root_lib = NULL; s32 i = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(nldr_node_obj); - if (nldr_node_obj != NULL) { if (nldr_node_obj->dynamic) { if (*nldr_node_obj->phase_split) { @@ -929,7 +893,6 @@ static int add_ovly_info(void *handle, struct dbll_sect_info *sect_info, /* Find the node it belongs to */ for (i = 0; i < nldr_obj->ovly_nodes; i++) { node_name = nldr_obj->ovly_table[i].node_name; - DBC_REQUIRE(node_name); if (strncmp(node_name, sect_name + 1, strlen(node_name)) == 0) { /* Found the node */ break; @@ -1018,8 +981,6 @@ static int add_ovly_node(struct dsp_uuid *uuid_obj, /* Add node to table */ nldr_obj->ovly_table[nldr_obj->ovly_nid].uuid = *uuid_obj; - DBC_REQUIRE(obj_def.obj_data.node_obj.ndb_props. - ac_name); len = strlen(obj_def.obj_data.node_obj.ndb_props.ac_name); node_name = obj_def.obj_data.node_obj.ndb_props.ac_name; @@ -1623,9 +1584,6 @@ static int remote_alloc(void **ref, u16 mem_sect, u32 size, struct rmm_addr *rmm_addr_obj = (struct rmm_addr *)dsp_address; bool mem_load_req = false; int status = -ENOMEM; /* Set to fail */ - DBC_REQUIRE(hnode); - DBC_REQUIRE(mem_sect == DBLL_CODE || mem_sect == DBLL_DATA || - mem_sect == DBLL_BSS); nldr_obj = hnode->nldr_obj; rmm = nldr_obj->rmm; /* Convert size to DSP words */ @@ -1736,8 +1694,6 @@ static int remote_free(void **ref, u16 space, u32 dsp_address, u32 word_size; int status = -ENOMEM; /* Set to fail */ - DBC_REQUIRE(nldr_obj); - rmm = nldr_obj->rmm; /* Convert size to DSP words */ @@ -1897,9 +1853,6 @@ int nldr_find_addr(struct nldr_nodeobject *nldr_node, u32 sym_addr, bool status1 = false; s32 i = 0; struct lib_node root = { NULL, 0, NULL }; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(offset_output != NULL); - DBC_REQUIRE(sym_name != NULL); pr_debug("%s(0x%x, 0x%x, 0x%x, 0x%x, %s)\n", __func__, (u32) nldr_node, sym_addr, offset_range, (u32) offset_output, sym_name); diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c index 5dadaa445ad..d23d1d07d67 100644 --- a/drivers/staging/tidspbridge/rmgr/node.c +++ b/drivers/staging/tidspbridge/rmgr/node.c @@ -326,11 +326,6 @@ int node_allocate(struct proc_object *hprocessor, void *node_res; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(hprocessor != NULL); - DBC_REQUIRE(noderes != NULL); - DBC_REQUIRE(node_uuid != NULL); - *noderes = NULL; status = proc_get_processor_id(hprocessor, &proc_id); @@ -673,7 +668,6 @@ func_cont: drv_proc_node_update_heap_status(node_res, true); drv_proc_node_update_status(node_res, true); } - DBC_ENSURE((status && *noderes == NULL) || (!status && *noderes)); func_end: dev_dbg(bridge, "%s: hprocessor: %p pNodeId: %p pargs: %p attr_in: %p " "node_res: %p status: 0x%x\n", __func__, hprocessor, @@ -696,11 +690,6 @@ DBAPI node_alloc_msg_buf(struct node_object *hnode, u32 usize, bool set_info; u32 proc_id; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(pbuffer != NULL); - - DBC_REQUIRE(usize > 0); - if (!pnode) status = -EFAULT; else if (node_get_type(pnode) == NODE_DEVICE) @@ -782,8 +771,6 @@ int node_change_priority(struct node_object *hnode, s32 prio) int status = 0; u32 proc_id; - DBC_REQUIRE(refs > 0); - if (!hnode || !hnode->node_mgr) { status = -EFAULT; } else { @@ -854,7 +841,6 @@ int node_connect(struct node_object *node1, u32 stream1, s8 chnl_mode; u32 dw_length; int status = 0; - DBC_REQUIRE(refs > 0); if (!node1 || !node2) return -EFAULT; @@ -1139,7 +1125,6 @@ int node_create(struct node_object *hnode) omap_dspbridge_dev->dev.platform_data; #endif - DBC_REQUIRE(refs > 0); if (!pnode) { status = -EFAULT; goto func_end; @@ -1291,10 +1276,6 @@ int node_create_mgr(struct node_mgr **node_man, int status = 0; u8 dev_type; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(node_man != NULL); - DBC_REQUIRE(hdev_obj != NULL); - *node_man = NULL; /* Allocate Node manager object */ node_mgr_obj = kzalloc(sizeof(struct node_mgr), GFP_KERNEL); @@ -1375,8 +1356,6 @@ int node_create_mgr(struct node_mgr **node_man, *node_man = node_mgr_obj; - DBC_ENSURE((status && *node_man == NULL) || (!status && *node_man)); - return status; out_err: delete_node_mgr(node_mgr_obj); @@ -1409,7 +1388,6 @@ int node_delete(struct node_res_object *noderes, void *node_res = noderes; struct dsp_processorstate proc_state; - DBC_REQUIRE(refs > 0); if (!pnode) { status = -EFAULT; @@ -1554,8 +1532,6 @@ func_end: */ int node_delete_mgr(struct node_mgr *hnode_mgr) { - DBC_REQUIRE(refs > 0); - if (!hnode_mgr) return -EFAULT; @@ -1576,10 +1552,6 @@ int node_enum_nodes(struct node_mgr *hnode_mgr, void **node_tab, struct node_object *hnode; u32 i = 0; int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(node_tab != NULL || node_tab_size == 0); - DBC_REQUIRE(pu_num_nodes != NULL); - DBC_REQUIRE(pu_allocated != NULL); if (!hnode_mgr) { status = -EFAULT; @@ -1611,11 +1583,7 @@ func_end: */ void node_exit(void) { - DBC_REQUIRE(refs > 0); - refs--; - - DBC_ENSURE(refs >= 0); } /* @@ -1629,10 +1597,6 @@ int node_free_msg_buf(struct node_object *hnode, u8 * pbuffer, struct node_object *pnode = (struct node_object *)hnode; int status = 0; u32 proc_id; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(pbuffer != NULL); - DBC_REQUIRE(pnode != NULL); - DBC_REQUIRE(pnode->xlator != NULL); if (!hnode) { status = -EFAULT; @@ -1669,9 +1633,6 @@ int node_get_attr(struct node_object *hnode, struct dsp_nodeattr *pattr, u32 attr_size) { struct node_mgr *hnode_mgr; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(pattr != NULL); - DBC_REQUIRE(attr_size >= sizeof(struct dsp_nodeattr)); if (!hnode) return -EFAULT; @@ -1713,9 +1674,6 @@ int node_get_channel_id(struct node_object *hnode, u32 dir, u32 index, { enum node_type node_type; int status = -EINVAL; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(dir == DSP_TONODE || dir == DSP_FROMNODE); - DBC_REQUIRE(chan_id != NULL); if (!hnode) { status = -EFAULT; @@ -1761,9 +1719,6 @@ int node_get_message(struct node_object *hnode, struct dsp_processorstate proc_state; struct proc_object *hprocessor; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(message != NULL); - if (!hnode) { status = -EFAULT; goto func_end; @@ -1831,14 +1786,12 @@ int node_get_nldr_obj(struct node_mgr *hnode_mgr, { int status = 0; struct node_mgr *node_mgr_obj = hnode_mgr; - DBC_REQUIRE(nldr_ovlyobj != NULL); if (!hnode_mgr) status = -EFAULT; else *nldr_ovlyobj = node_mgr_obj->nldr_obj; - DBC_ENSURE(!status || (nldr_ovlyobj != NULL && *nldr_ovlyobj == NULL)); return status; } @@ -1852,8 +1805,6 @@ int node_get_strm_mgr(struct node_object *hnode, { int status = 0; - DBC_REQUIRE(refs > 0); - if (!hnode) status = -EFAULT; else @@ -1867,8 +1818,6 @@ int node_get_strm_mgr(struct node_object *hnode, */ enum nldr_loadtype node_get_load_type(struct node_object *hnode) { - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(hnode); if (!hnode) { dev_dbg(bridge, "%s: Failed. hnode: %p\n", __func__, hnode); return -1; @@ -1884,8 +1833,6 @@ enum nldr_loadtype node_get_load_type(struct node_object *hnode) */ u32 node_get_timeout(struct node_object *hnode) { - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(hnode); if (!hnode) { dev_dbg(bridge, "%s: failed. hnode: %p\n", __func__, hnode); return 0; @@ -1921,8 +1868,6 @@ enum node_type node_get_type(struct node_object *hnode) */ bool node_init(void) { - DBC_REQUIRE(refs >= 0); - refs++; return true; @@ -1970,8 +1915,6 @@ int node_pause(struct node_object *hnode) struct dsp_processorstate proc_state; struct proc_object *hprocessor; - DBC_REQUIRE(refs > 0); - if (!hnode) { status = -EFAULT; } else { @@ -2054,9 +1997,6 @@ int node_put_message(struct node_object *hnode, struct dsp_processorstate proc_state; struct proc_object *hprocessor; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(pmsg != NULL); - if (!hnode) { status = -EFAULT; goto func_end; @@ -2146,9 +2086,6 @@ int node_register_notify(struct node_object *hnode, u32 event_mask, struct bridge_drv_interface *intf_fxns; int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(hnotification != NULL); - if (!hnode) { status = -EFAULT; } else { @@ -2207,8 +2144,6 @@ int node_run(struct node_object *hnode) struct dsp_processorstate proc_state; struct proc_object *hprocessor; - DBC_REQUIRE(refs > 0); - if (!hnode) { status = -EFAULT; goto func_end; @@ -2326,9 +2261,6 @@ int node_terminate(struct node_object *hnode, int *pstatus) struct deh_mgr *hdeh_mgr; struct dsp_processorstate proc_state; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(pstatus != NULL); - if (!hnode || !hnode->node_mgr) { status = -EFAULT; goto func_end; @@ -2748,9 +2680,6 @@ static int get_fxn_address(struct node_object *hnode, u32 * fxn_addr, char *pstr_fxn_name = NULL; struct node_mgr *hnode_mgr = hnode->node_mgr; int status = 0; - DBC_REQUIRE(node_get_type(hnode) == NODE_TASK || - node_get_type(hnode) == NODE_DAISSOCKET || - node_get_type(hnode) == NODE_MESSAGE); switch (phase) { case CREATEPHASE: @@ -2787,9 +2716,6 @@ void get_node_info(struct node_object *hnode, struct dsp_nodeinfo *node_info) { u32 i; - DBC_REQUIRE(hnode); - DBC_REQUIRE(node_info != NULL); - node_info->cb_struct = sizeof(struct dsp_nodeinfo); node_info->nb_node_database_props = hnode->dcd_props.obj_data.node_obj.ndb_props; @@ -2848,7 +2774,6 @@ static int get_node_props(struct dcd_manager *hdcd_mgr, pmsg_args->max_msgs); } else { /* Copy device name */ - DBC_REQUIRE(pndb_props->ac_name); len = strlen(pndb_props->ac_name); DBC_ASSERT(len < MAXDEVNAMELEN); hnode->str_dev_name = kzalloc(len + 1, GFP_KERNEL); @@ -2938,10 +2863,6 @@ int node_get_uuid_props(void *hprocessor, struct dcd_nodeprops dcd_node_props; struct dsp_processorstate proc_state; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(hprocessor != NULL); - DBC_REQUIRE(node_uuid != NULL); - if (hprocessor == NULL || node_uuid == NULL) { status = -EFAULT; goto func_end; @@ -3063,8 +2984,6 @@ static u32 ovly(void *priv_ref, u32 dsp_run_addr, u32 dsp_load_addr, /* Function interface to Bridge driver*/ struct bridge_drv_interface *intf_fxns; - DBC_REQUIRE(hnode); - hnode_mgr = hnode->node_mgr; ul_size = ul_num_bytes / hnode_mgr->dsp_word_size; @@ -3106,9 +3025,6 @@ static u32 mem_write(void *priv_ref, u32 dsp_add, void *pbuf, /* Function interface to Bridge driver */ struct bridge_drv_interface *intf_fxns; - DBC_REQUIRE(hnode); - DBC_REQUIRE(mem_space & DBLL_CODE || mem_space & DBLL_DATA); - hnode_mgr = hnode->node_mgr; ul_timeout = hnode->timeout; diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c index 242dd139999..4e2f2e450b2 100644 --- a/drivers/staging/tidspbridge/rmgr/proc.c +++ b/drivers/staging/tidspbridge/rmgr/proc.c @@ -281,9 +281,6 @@ proc_attach(u32 processor_id, struct drv_data *drv_datap = dev_get_drvdata(bridge); u8 dev_type; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(ph_processor != NULL); - if (pr_ctxt->processor) { *ph_processor = pr_ctxt->processor; return status; @@ -382,10 +379,6 @@ proc_attach(u32 processor_id, kfree(p_proc_object); } func_end: - DBC_ENSURE((status == -EPERM && *ph_processor == NULL) || - (!status && p_proc_object) || - (status == 0 && p_proc_object)); - return status; } @@ -445,10 +438,6 @@ int proc_auto_start(struct cfg_devnode *dev_node_obj, struct drv_data *drv_datap = dev_get_drvdata(bridge); u8 dev_type; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(dev_node_obj != NULL); - DBC_REQUIRE(hdev_obj != NULL); - /* Create a Dummy PROC Object */ if (!drv_datap || !drv_datap->mgr_object) { status = -ENODATA; @@ -516,8 +505,6 @@ int proc_ctrl(void *hprocessor, u32 dw_cmd, struct dsp_cbdata * arg) struct proc_object *p_proc_object = hprocessor; u32 timeout = 0; - DBC_REQUIRE(refs > 0); - if (p_proc_object) { /* intercept PWR deep sleep command */ if (dw_cmd == BRDIOCTL_DEEPSLEEP) { @@ -565,8 +552,6 @@ int proc_detach(struct process_context *pr_ctxt) int status = 0; struct proc_object *p_proc_object = NULL; - DBC_REQUIRE(refs > 0); - p_proc_object = (struct proc_object *)pr_ctxt->processor; if (p_proc_object) { @@ -607,11 +592,6 @@ int proc_enum_nodes(void *hprocessor, void **node_tab, struct proc_object *p_proc_object = (struct proc_object *)hprocessor; struct node_mgr *hnode_mgr = NULL; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(node_tab != NULL || node_tab_size == 0); - DBC_REQUIRE(pu_num_nodes != NULL); - DBC_REQUIRE(pu_allocated != NULL); - if (p_proc_object) { if (!(dev_get_node_manager(p_proc_object->dev_obj, &hnode_mgr))) { @@ -768,8 +748,6 @@ int proc_begin_dma(void *hprocessor, void *pmpu_addr, u32 ul_size, struct process_context *pr_ctxt = (struct process_context *) hprocessor; struct dmm_map_object *map_obj; - DBC_REQUIRE(refs > 0); - if (!pr_ctxt) { status = -EFAULT; goto err_out; @@ -810,8 +788,6 @@ int proc_end_dma(void *hprocessor, void *pmpu_addr, u32 ul_size, struct process_context *pr_ctxt = (struct process_context *) hprocessor; struct dmm_map_object *map_obj; - DBC_REQUIRE(refs > 0); - if (!pr_ctxt) { status = -EFAULT; goto err_out; @@ -884,10 +860,6 @@ int proc_get_resource_info(void *hprocessor, u32 resource_type, struct rmm_target_obj *rmm = NULL; struct io_mgr *hio_mgr = NULL; /* IO manager handle */ - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(resource_info != NULL); - DBC_REQUIRE(resource_info_size >= sizeof(struct dsp_resourceinfo)); - if (!p_proc_object) { status = -EFAULT; goto func_end; @@ -947,11 +919,7 @@ func_end: */ void proc_exit(void) { - DBC_REQUIRE(refs > 0); - refs--; - - DBC_ENSURE(refs >= 0); } /* @@ -966,9 +934,6 @@ int proc_get_dev_object(void *hprocessor, int status = -EPERM; struct proc_object *p_proc_object = (struct proc_object *)hprocessor; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(device_obj != NULL); - if (p_proc_object) { *device_obj = p_proc_object->dev_obj; status = 0; @@ -977,9 +942,6 @@ int proc_get_dev_object(void *hprocessor, status = -EFAULT; } - DBC_ENSURE((!status && *device_obj != NULL) || - (status && *device_obj == NULL)); - return status; } @@ -996,10 +958,6 @@ int proc_get_state(void *hprocessor, struct proc_object *p_proc_object = (struct proc_object *)hprocessor; int brd_status; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(proc_state_obj != NULL); - DBC_REQUIRE(state_info_size >= sizeof(struct dsp_processorstate)); - if (p_proc_object) { /* First, retrieve BRD state information */ status = (*p_proc_object->intf_fxns->brd_status) @@ -1063,13 +1021,9 @@ bool proc_init(void) { bool ret = true; - DBC_REQUIRE(refs >= 0); - if (ret) refs++; - DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0))); - return ret; } @@ -1111,10 +1065,6 @@ int proc_load(void *hprocessor, const s32 argc_index, omap_dspbridge_dev->dev.platform_data; #endif - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(argc_index > 0); - DBC_REQUIRE(user_args != NULL); - #ifdef OPT_LOAD_TIME_INSTRUMENTATION do_gettimeofday(&tv1); #endif @@ -1331,9 +1281,6 @@ func_end: pr_err("%s: Processor failed to load\n", __func__); proc_stop(p_proc_object); } - DBC_ENSURE((!status - && p_proc_object->proc_state == PROC_LOADED) - || status); #ifdef OPT_LOAD_TIME_INSTRUMENTATION do_gettimeofday(&tv2); if (tv2.tv_usec < tv1.tv_usec) { @@ -1443,9 +1390,6 @@ int proc_register_notify(void *hprocessor, u32 event_mask, struct proc_object *p_proc_object = (struct proc_object *)hprocessor; struct deh_mgr *hdeh_mgr; - DBC_REQUIRE(hnotification != NULL); - DBC_REQUIRE(refs > 0); - /* Check processor handle */ if (!p_proc_object) { status = -EFAULT; @@ -1567,7 +1511,6 @@ int proc_start(void *hprocessor) u32 dw_dsp_addr; /* Loaded code's entry point. */ int brd_state; - DBC_REQUIRE(refs > 0); if (!p_proc_object) { status = -EFAULT; goto func_end; @@ -1624,8 +1567,6 @@ func_cont: } func_end: - DBC_ENSURE((!status && p_proc_object->proc_state == - PROC_RUNNING) || status); return status; } @@ -1646,7 +1587,6 @@ int proc_stop(void *hprocessor) u32 nodes_allocated = 0; int brd_state; - DBC_REQUIRE(refs > 0); if (!p_proc_object) { status = -EFAULT; goto func_end; @@ -1822,9 +1762,6 @@ static int proc_monitor(struct proc_object *proc_obj) struct msg_mgr *hmsg_mgr; int brd_state; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(proc_obj); - /* This is needed only when Device is loaded when it is * already 'ACTIVE' */ /* Destroy the Node Manager, msg_ctrl Manager */ @@ -1845,8 +1782,6 @@ static int proc_monitor(struct proc_object *proc_obj) DBC_ASSERT(brd_state == BRD_IDLE); } - DBC_ENSURE((!status && brd_state == BRD_IDLE) || - status); return status; } @@ -1880,8 +1815,6 @@ static char **prepend_envp(char **new_envp, char **envp, s32 envp_elems, { char **pp_envp = new_envp; - DBC_REQUIRE(new_envp); - /* Prepend new environ var=value string */ *new_envp++ = sz_var; @@ -1906,9 +1839,6 @@ int proc_notify_clients(void *proc, u32 events) int status = 0; struct proc_object *p_proc_object = (struct proc_object *)proc; - DBC_REQUIRE(p_proc_object); - DBC_REQUIRE(is_valid_proc_event(events)); - DBC_REQUIRE(refs > 0); if (!p_proc_object) { status = -EFAULT; goto func_end; @@ -1930,9 +1860,6 @@ int proc_notify_all_clients(void *proc, u32 events) int status = 0; struct proc_object *p_proc_object = (struct proc_object *)proc; - DBC_REQUIRE(is_valid_proc_event(events)); - DBC_REQUIRE(refs > 0); - if (!p_proc_object) { status = -EFAULT; goto func_end; diff --git a/drivers/staging/tidspbridge/rmgr/rmm.c b/drivers/staging/tidspbridge/rmgr/rmm.c index f3dc0ddbfac..6b410499c3b 100644 --- a/drivers/staging/tidspbridge/rmgr/rmm.c +++ b/drivers/staging/tidspbridge/rmgr/rmm.c @@ -101,12 +101,6 @@ int rmm_alloc(struct rmm_target_obj *target, u32 segid, u32 size, u32 addr; int status = 0; - DBC_REQUIRE(target); - DBC_REQUIRE(dsp_address != NULL); - DBC_REQUIRE(size > 0); - DBC_REQUIRE(reserve || (target->num_segs > 0)); - DBC_REQUIRE(refs > 0); - if (!reserve) { if (!alloc_block(target, segid, size, align, dsp_address)) { status = -ENOMEM; @@ -170,9 +164,6 @@ int rmm_create(struct rmm_target_obj **target_obj, s32 i; int status = 0; - DBC_REQUIRE(target_obj != NULL); - DBC_REQUIRE(num_segs == 0 || seg_tab != NULL); - /* Allocate DBL target object */ target = kzalloc(sizeof(struct rmm_target_obj), GFP_KERNEL); @@ -235,9 +226,6 @@ func_cont: } - DBC_ENSURE((!status && *target_obj) - || (status && *target_obj == NULL)); - return status; } @@ -251,8 +239,6 @@ void rmm_delete(struct rmm_target_obj *target) struct rmm_header *next; u32 i; - DBC_REQUIRE(target); - kfree(target->seg_tab); list_for_each_entry_safe(sect, tmp, &target->ovly_list, list_elem) { @@ -281,11 +267,7 @@ void rmm_delete(struct rmm_target_obj *target) */ void rmm_exit(void) { - DBC_REQUIRE(refs > 0); - refs--; - - DBC_ENSURE(refs >= 0); } /* @@ -297,15 +279,6 @@ bool rmm_free(struct rmm_target_obj *target, u32 segid, u32 dsp_addr, u32 size, struct rmm_ovly_sect *sect, *tmp; bool ret = false; - DBC_REQUIRE(target); - - DBC_REQUIRE(reserved || segid < target->num_segs); - DBC_REQUIRE(reserved || (dsp_addr >= target->seg_tab[segid].base && - (dsp_addr + size) <= (target->seg_tab[segid]. - base + - target->seg_tab[segid]. - length))); - /* * Free or unreserve memory. */ @@ -335,8 +308,6 @@ bool rmm_free(struct rmm_target_obj *target, u32 segid, u32 dsp_addr, u32 size, */ bool rmm_init(void) { - DBC_REQUIRE(refs >= 0); - refs++; return true; @@ -354,7 +325,6 @@ bool rmm_stat(struct rmm_target_obj *target, enum dsp_memtype segid, u32 total_free_size = 0; u32 free_blocks = 0; - DBC_REQUIRE(mem_stat_buf != NULL); DBC_ASSERT(target != NULL); if ((u32) segid < target->num_segs) { diff --git a/drivers/staging/tidspbridge/rmgr/strm.c b/drivers/staging/tidspbridge/rmgr/strm.c index 3fae0e9f511..8e2d6493344 100644 --- a/drivers/staging/tidspbridge/rmgr/strm.c +++ b/drivers/staging/tidspbridge/rmgr/strm.c @@ -104,9 +104,6 @@ int strm_allocate_buffer(struct strm_res_object *strmres, u32 usize, u32 i; struct strm_object *stream_obj = strmres->stream; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(ap_buffer != NULL); - if (stream_obj) { /* * Allocate from segment specified at time of stream open. @@ -156,8 +153,6 @@ int strm_close(struct strm_res_object *strmres, int status = 0; struct strm_object *stream_obj = strmres->stream; - DBC_REQUIRE(refs > 0); - if (!stream_obj) { status = -EFAULT; } else { @@ -180,9 +175,6 @@ int strm_close(struct strm_res_object *strmres, idr_remove(pr_ctxt->stream_id, strmres->id); func_end: - DBC_ENSURE(status == 0 || status == -EFAULT || - status == -EPIPE || status == -EPERM); - dev_dbg(bridge, "%s: stream_obj: %p, status 0x%x\n", __func__, stream_obj, status); return status; @@ -199,10 +191,6 @@ int strm_create(struct strm_mgr **strm_man, struct strm_mgr *strm_mgr_obj; int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(strm_man != NULL); - DBC_REQUIRE(dev_obj != NULL); - *strm_man = NULL; /* Allocate STRM manager object */ strm_mgr_obj = kzalloc(sizeof(struct strm_mgr), GFP_KERNEL); @@ -226,8 +214,6 @@ int strm_create(struct strm_mgr **strm_man, else kfree(strm_mgr_obj); - DBC_ENSURE((!status && *strm_man) || (status && *strm_man == NULL)); - return status; } @@ -238,9 +224,6 @@ int strm_create(struct strm_mgr **strm_man, */ void strm_delete(struct strm_mgr *strm_mgr_obj) { - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(strm_mgr_obj); - kfree(strm_mgr_obj); } @@ -251,11 +234,7 @@ void strm_delete(struct strm_mgr *strm_mgr_obj) */ void strm_exit(void) { - DBC_REQUIRE(refs > 0); - refs--; - - DBC_ENSURE(refs >= 0); } /* @@ -270,9 +249,6 @@ int strm_free_buffer(struct strm_res_object *strmres, u8 ** ap_buffer, u32 i = 0; struct strm_object *stream_obj = strmres->stream; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(ap_buffer != NULL); - if (!stream_obj) status = -EFAULT; @@ -306,10 +282,6 @@ int strm_get_info(struct strm_object *stream_obj, int status = 0; void *virt_base = NULL; /* NULL if no SM used */ - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(stream_info != NULL); - DBC_REQUIRE(stream_info_size >= sizeof(struct stream_info)); - if (!stream_obj) { status = -EFAULT; } else { @@ -370,8 +342,6 @@ int strm_idle(struct strm_object *stream_obj, bool flush_data) struct bridge_drv_interface *intf_fxns; int status = 0; - DBC_REQUIRE(refs > 0); - if (!stream_obj) { status = -EFAULT; } else { @@ -396,13 +366,9 @@ bool strm_init(void) { bool ret = true; - DBC_REQUIRE(refs >= 0); - if (ret) refs++; - DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0))); - return ret; } @@ -418,9 +384,6 @@ int strm_issue(struct strm_object *stream_obj, u8 *pbuf, u32 ul_bytes, int status = 0; void *tmp_buf = NULL; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(pbuf != NULL); - if (!stream_obj) { status = -EFAULT; } else { @@ -471,9 +434,6 @@ int strm_open(struct node_object *hnode, u32 dir, u32 index, void *stream_res; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(strmres != NULL); - DBC_REQUIRE(pattr != NULL); *strmres = NULL; if (dir != DSP_TONODE && dir != DSP_FROMNODE) { status = -EPERM; @@ -594,12 +554,6 @@ func_cont: (void)delete_strm(strm_obj); } - /* ensure we return a documented error code */ - DBC_ENSURE((!status && strm_obj) || - (*strmres == NULL && (status == -EFAULT || - status == -EPERM - || status == -EINVAL))); - dev_dbg(bridge, "%s: hnode: %p dir: 0x%x index: 0x%x pattr: %p " "strmres: %p status: 0x%x\n", __func__, hnode, dir, index, pattr, strmres, status); @@ -619,11 +573,6 @@ int strm_reclaim(struct strm_object *stream_obj, u8 ** buf_ptr, int status = 0; void *tmp_buf = NULL; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(buf_ptr != NULL); - DBC_REQUIRE(nbytes != NULL); - DBC_REQUIRE(pdw_arg != NULL); - if (!stream_obj) { status = -EFAULT; goto func_end; @@ -679,11 +628,6 @@ int strm_reclaim(struct strm_object *stream_obj, u8 ** buf_ptr, *buf_ptr = chnl_ioc_obj.buf; } func_end: - /* ensure we return a documented return code */ - DBC_ENSURE(!status || status == -EFAULT || - status == -ETIME || status == -ESRCH || - status == -EPERM); - dev_dbg(bridge, "%s: stream_obj: %p buf_ptr: %p nbytes: %p " "pdw_arg: %p status 0x%x\n", __func__, stream_obj, buf_ptr, nbytes, pdw_arg, status); @@ -702,9 +646,6 @@ int strm_register_notify(struct strm_object *stream_obj, u32 event_mask, struct bridge_drv_interface *intf_fxns; int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(hnotification != NULL); - if (!stream_obj) { status = -EFAULT; } else if ((event_mask & ~((DSP_STREAMIOCOMPLETION) | @@ -725,10 +666,7 @@ int strm_register_notify(struct strm_object *stream_obj, u32 event_mask, notify_type, hnotification); } - /* ensure we return a documented return code */ - DBC_ENSURE(!status || status == -EFAULT || - status == -ETIME || status == -ESRCH || - status == -ENOSYS || status == -EPERM); + return status; } @@ -747,11 +685,6 @@ int strm_select(struct strm_object **strm_tab, u32 strms, u32 i; int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(strm_tab != NULL); - DBC_REQUIRE(pmask != NULL); - DBC_REQUIRE(strms > 0); - *pmask = 0; for (i = 0; i < strms; i++) { if (!strm_tab[i]) { @@ -811,9 +744,6 @@ int strm_select(struct strm_object **strm_tab, u32 strms, func_end: kfree(sync_events); - DBC_ENSURE((!status && (*pmask != 0 || utimeout == 0)) || - (status && *pmask == 0)); - return status; } -- cgit v1.2.3-70-g09d2 From 40e6336d1bdc10f072b6563dfb1255b5c4b039a2 Mon Sep 17 00:00:00 2001 From: Víctor Manuel Jáquez Leal Date: Tue, 7 Feb 2012 00:39:35 +0100 Subject: staging: tidspbridge: remove DBC_ASSERT macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This macro is only valid when CONFIG_TIDSPBRDIGE_DEBUG is enabled and it only prints a log message, it is not a real assertion mechanism like BUG_ON() or WARN_ON(). It is better to remove them: less code to maintain. Signed-off-by: Víctor Manuel Jáquez Leal Signed-off-by: Greg Kroah-Hartman --- drivers/staging/tidspbridge/core/chnl_sm.c | 12 ------------ drivers/staging/tidspbridge/core/io_sm.c | 14 -------------- drivers/staging/tidspbridge/core/tiomap3430.c | 3 --- drivers/staging/tidspbridge/core/tiomap3430_pwr.c | 1 - drivers/staging/tidspbridge/core/tiomap_io.c | 15 --------------- .../staging/tidspbridge/include/dspbridge/dbc.h | 11 ----------- drivers/staging/tidspbridge/pmgr/cmm.c | 6 ++---- drivers/staging/tidspbridge/pmgr/dbll.c | 3 --- drivers/staging/tidspbridge/pmgr/dev.c | 6 ------ drivers/staging/tidspbridge/rmgr/dbdcd.c | 6 ------ drivers/staging/tidspbridge/rmgr/disp.c | 3 --- drivers/staging/tidspbridge/rmgr/drv.c | 7 ------- drivers/staging/tidspbridge/rmgr/drv_interface.c | 2 -- drivers/staging/tidspbridge/rmgr/mgr.c | 2 -- drivers/staging/tidspbridge/rmgr/nldr.c | 22 ---------------------- drivers/staging/tidspbridge/rmgr/node.c | 11 ----------- drivers/staging/tidspbridge/rmgr/proc.c | 15 --------------- drivers/staging/tidspbridge/rmgr/rmm.c | 3 --- drivers/staging/tidspbridge/rmgr/strm.c | 11 ----------- 19 files changed, 2 insertions(+), 151 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/core/chnl_sm.c b/drivers/staging/tidspbridge/core/chnl_sm.c index 91daf25d29a..3136e8ddad4 100644 --- a/drivers/staging/tidspbridge/core/chnl_sm.c +++ b/drivers/staging/tidspbridge/core/chnl_sm.c @@ -123,7 +123,6 @@ int bridge_chnl_add_io_req(struct chnl_object *chnl_obj, void *host_buf, CHNL_IS_OUTPUT(pchnl->chnl_mode)) return -EPIPE; /* No other possible states left */ - DBC_ASSERT(0); } dev_obj = dev_get_first(); @@ -190,7 +189,6 @@ func_cont: * Note: for dma chans dw_dsp_addr contains dsp address * of SM buffer. */ - DBC_ASSERT(chnl_mgr_obj->word_size != 0); /* DSP address */ chnl_packet_obj->dsp_tx_addr = dw_dsp_addr / chnl_mgr_obj->word_size; chnl_packet_obj->byte_size = byte_size; @@ -201,7 +199,6 @@ func_cont: CHNL_IOCSTATCOMPLETE); list_add_tail(&chnl_packet_obj->link, &pchnl->io_requests); pchnl->cio_reqs++; - DBC_ASSERT(pchnl->cio_reqs <= pchnl->chnl_packets); /* * If end of stream, update the channel state to prevent * more IOR's. @@ -209,8 +206,6 @@ func_cont: if (is_eos) pchnl->state |= CHNL_STATEEOS; - /* Legacy DSM Processor-Copy */ - DBC_ASSERT(pchnl->chnl_type == CHNL_PCPY); /* Request IO from the DSP */ io_request_chnl(chnl_mgr_obj->iomgr, pchnl, (CHNL_IS_INPUT(pchnl->chnl_mode) ? IO_INPUT : @@ -283,7 +278,6 @@ int bridge_chnl_cancel_io(struct chnl_object *chnl_obj) list_add_tail(&chirp->link, &pchnl->io_completions); pchnl->cio_cs++; pchnl->cio_reqs--; - DBC_ASSERT(pchnl->cio_reqs >= 0); } spin_unlock_bh(&chnl_mgr_obj->chnl_mgr_lock); @@ -311,8 +305,6 @@ int bridge_chnl_close(struct chnl_object *chnl_obj) status = bridge_chnl_cancel_io(chnl_obj); if (status) return status; - /* Assert I/O on this channel is now cancelled: Protects from io_dpc */ - DBC_ASSERT((pchnl->state & CHNL_STATECANCEL)); /* Invalidate channel object: Protects from CHNL_GetIOCompletion() */ /* Free the slot in the channel manager: */ pchnl->chnl_mgr_obj->channels[pchnl->chnl_id] = NULL; @@ -367,7 +359,6 @@ int bridge_chnl_create(struct chnl_mgr **channel_mgr, * mgr_attrts->max_channels = CHNL_MAXCHANNELS = * DDMA_MAXDDMACHNLS = DDMA_MAXZCPYCHNLS. */ - DBC_ASSERT(mgr_attrts->max_channels == CHNL_MAXCHANNELS); max_channels = CHNL_MAXCHANNELS + CHNL_MAXCHANNELS * CHNL_PCPY; /* Create array of channels */ chnl_mgr_obj->channels = kzalloc(sizeof(struct chnl_object *) @@ -584,7 +575,6 @@ int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout, omap_mbox_disable_irq(dev_ctxt->mbox, IRQ_RX); if (dequeue_ioc) { /* Dequeue IOC and set chan_ioc; */ - DBC_ASSERT(!list_empty(&pchnl->io_completions)); chnl_packet_obj = list_first_entry(&pchnl->io_completions, struct chnl_irp, link); list_del(&chnl_packet_obj->link); @@ -748,7 +738,6 @@ int bridge_chnl_open(struct chnl_object **chnl, return status; } - DBC_ASSERT(ch_id < chnl_mgr_obj->max_channels); /* Create channel object: */ pchnl = kzalloc(sizeof(struct chnl_object), GFP_KERNEL); @@ -837,7 +826,6 @@ int bridge_chnl_register_notify(struct chnl_object *chnl_obj, { int status = 0; - DBC_ASSERT(!(event_mask & ~(DSP_STREAMDONE | DSP_STREAMIOCOMPLETION))); if (event_mask) status = ntfy_register(chnl_obj->ntfy_obj, hnotification, diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c index 694c0e5e55c..0930a9851f3 100644 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ b/drivers/staging/tidspbridge/core/io_sm.c @@ -973,29 +973,16 @@ void io_request_chnl(struct io_mgr *io_manager, struct chnl_object *pchnl, chnl_mgr_obj = io_manager->chnl_mgr; sm = io_manager->shared_mem; if (io_mode == IO_INPUT) { - /* - * Assertion fires if CHNL_AddIOReq() called on a stream - * which was cancelled, or attached to a dead board. - */ - DBC_ASSERT((pchnl->state == CHNL_STATEREADY) || - (pchnl->state == CHNL_STATEEOS)); /* Indicate to the DSP we have a buffer available for input */ set_chnl_busy(sm, pchnl->chnl_id); *mbx_val = MBX_PCPY_CLASS; } else if (io_mode == IO_OUTPUT) { - /* - * This assertion fails if CHNL_AddIOReq() was called on a - * stream which was cancelled, or attached to a dead board. - */ - DBC_ASSERT((pchnl->state & ~CHNL_STATEEOS) == - CHNL_STATEREADY); /* * Record the fact that we have a buffer available for * output. */ chnl_mgr_obj->output_mask |= (1 << pchnl->chnl_id); } else { - DBC_ASSERT(io_mode); /* Shouldn't get here. */ } func_end: return; @@ -1087,7 +1074,6 @@ static void input_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl, dw_arg = sm->arg; if (chnl_id >= CHNL_MAXCHANNELS) { /* Shouldn't be here: would indicate corrupted shm. */ - DBC_ASSERT(chnl_id); goto func_end; } pchnl = chnl_mgr_obj->channels[chnl_id]; diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index 212cbc9414d..c3efc2ec455 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -396,16 +396,13 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, (void)dev_get_symbol(dev_context->dev_obj, SHMBASENAME, &ul_shm_base_virt); ul_shm_base_virt *= DSPWORDSIZE; - DBC_ASSERT(ul_shm_base_virt != 0); /* DSP Virtual address */ ul_tlb_base_virt = dev_context->atlb_entry[0].dsp_va; - DBC_ASSERT(ul_tlb_base_virt <= ul_shm_base_virt); ul_shm_offset_virt = ul_shm_base_virt - (ul_tlb_base_virt * DSPWORDSIZE); /* Kernel logical address */ ul_shm_base = dev_context->atlb_entry[0].gpp_va + ul_shm_offset_virt; - DBC_ASSERT(ul_shm_base != 0); /* 2nd wd is used as sync field */ dw_sync_addr = ul_shm_base + SHMSYNCOFFSET; /* Write a signature into the shm base + offset; this will diff --git a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c index 02dd4391309..16a4aafa86a 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c +++ b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c @@ -303,7 +303,6 @@ int dsp_peripheral_clk_ctrl(struct bridge_dev_context *dev_context, } /* TODO -- Assert may be a too hard restriction here.. May be we should * just return with failure when the CLK ID does not match */ - /* DBC_ASSERT(clk_id_index < MBX_PM_MAX_RESOURCES); */ if (clk_id_index == MBX_PM_MAX_RESOURCES) { /* return with a more meaningfull error code */ return -EPERM; diff --git a/drivers/staging/tidspbridge/core/tiomap_io.c b/drivers/staging/tidspbridge/core/tiomap_io.c index dfb356eb672..9c1887390ae 100644 --- a/drivers/staging/tidspbridge/core/tiomap_io.c +++ b/drivers/staging/tidspbridge/core/tiomap_io.c @@ -68,20 +68,17 @@ int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt, status = dev_get_symbol(dev_context->dev_obj, SHMBASENAME, &ul_shm_base_virt); } - DBC_ASSERT(ul_shm_base_virt != 0); /* Check if it is a read of Trace section */ if (!status && !ul_trace_sec_beg) { status = dev_get_symbol(dev_context->dev_obj, DSP_TRACESEC_BEG, &ul_trace_sec_beg); } - DBC_ASSERT(ul_trace_sec_beg != 0); if (!status && !ul_trace_sec_end) { status = dev_get_symbol(dev_context->dev_obj, DSP_TRACESEC_END, &ul_trace_sec_end); } - DBC_ASSERT(ul_trace_sec_end != 0); if (!status) { if ((dsp_addr <= ul_trace_sec_end) && @@ -105,19 +102,16 @@ int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt, status = dev_get_symbol(dev_context->dev_obj, DYNEXTBASE, &ul_dyn_ext_base); } - DBC_ASSERT(ul_dyn_ext_base != 0); if (!status) { status = dev_get_symbol(dev_context->dev_obj, EXTBASE, &ul_ext_base); } - DBC_ASSERT(ul_ext_base != 0); if (!status) { status = dev_get_symbol(dev_context->dev_obj, EXTEND, &ul_ext_end); } - DBC_ASSERT(ul_ext_end != 0); /* Trace buffer is right after the shm SEG0, * so set the base address to SHMBASE */ @@ -126,8 +120,6 @@ int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt, ul_ext_end = ul_trace_sec_end; } - DBC_ASSERT(ul_ext_end != 0); - DBC_ASSERT(ul_ext_end > ul_ext_base); if (ul_ext_end < ul_ext_base) status = -EPERM; @@ -135,7 +127,6 @@ int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt, if (!status) { ul_tlb_base_virt = dev_context->atlb_entry[0].dsp_va * DSPWORDSIZE; - DBC_ASSERT(ul_tlb_base_virt <= ul_shm_base_virt); dw_ext_prog_virt_mem = dev_context->atlb_entry[0].gpp_va; @@ -271,7 +262,6 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context, /* Get SHM_BEG EXT_BEG and EXT_END. */ ret = dev_get_symbol(dev_context->dev_obj, SHMBASENAME, &ul_shm_base_virt); - DBC_ASSERT(ul_shm_base_virt != 0); if (dynamic_load) { if (!ret) { if (symbols_reloaded) @@ -280,7 +270,6 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context, (dev_context->dev_obj, DYNEXTBASE, &ul_ext_base); } - DBC_ASSERT(ul_ext_base != 0); if (!ret) { /* DR OMAPS00013235 : DLModules array may be * in EXTMEM. It is expected that DYNEXTMEM and @@ -299,7 +288,6 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context, dev_get_symbol (dev_context->dev_obj, EXTBASE, &ul_ext_base); - DBC_ASSERT(ul_ext_base != 0); if (!ret) ret = dev_get_symbol @@ -312,15 +300,12 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context, if (trace_load) ul_ext_base = ul_shm_base_virt; - DBC_ASSERT(ul_ext_end != 0); - DBC_ASSERT(ul_ext_end > ul_ext_base); if (ul_ext_end < ul_ext_base) ret = -EPERM; if (!ret) { ul_tlb_base_virt = dev_context->atlb_entry[0].dsp_va * DSPWORDSIZE; - DBC_ASSERT(ul_tlb_base_virt <= ul_shm_base_virt); if (symbols_reloaded) { ret = dev_get_symbol diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbc.h b/drivers/staging/tidspbridge/include/dspbridge/dbc.h index dc88f34f166..90c45f69526 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dbc.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dbc.h @@ -25,15 +25,4 @@ #ifndef DBC_ #define DBC_ -/* Assertion Macros: */ -#ifdef CONFIG_TIDSPBRIDGE_DEBUG - -#define DBC_ASSERT(exp) \ - if (!(exp)) \ - pr_err("%s, line %d: Assertion (" #exp ") failed.\n", \ - __FILE__, __LINE__) -#else -#define DBC_ASSERT(exp) {} -#endif /* DEBUG */ - #endif /* DBC_ */ diff --git a/drivers/staging/tidspbridge/pmgr/cmm.c b/drivers/staging/tidspbridge/pmgr/cmm.c index 2eeb5370927..0d19bcd4ce2 100644 --- a/drivers/staging/tidspbridge/pmgr/cmm.c +++ b/drivers/staging/tidspbridge/pmgr/cmm.c @@ -253,8 +253,6 @@ int cmm_create(struct cmm_object **ph_cmm_mgr, if (mgr_attrts == NULL) mgr_attrts = &cmm_dfltmgrattrs; /* set defaults */ - /* 4 bytes minimum */ - DBC_ASSERT(mgr_attrts->min_block_size >= 4); /* save away smallest block allocation for this cmm mgr */ cmm_obj->min_block_size = mgr_attrts->min_block_size; cmm_obj->page_size = PAGE_SIZE; @@ -849,7 +847,8 @@ int cmm_xlator_free_buf(struct cmm_xlatorobject *xlator, void *buf_va) if (status) { /* Uh oh, this shouldn't happen. Descriptor * gone! */ - DBC_ASSERT(false); /* CMM is leaking mem */ + pr_err("%s, line %d: Assertion failed\n", + __FILE__, __LINE__); } } } @@ -898,7 +897,6 @@ void *cmm_xlator_translate(struct cmm_xlatorobject *xlator, void *paddr, cmm_mgr_obj = (struct cmm_object *)xlator_obj->cmm_mgr; /* get this translator's default SM allocator */ - DBC_ASSERT(xlator_obj->seg_id > 0); allocator = cmm_mgr_obj->pa_gppsm_seg_tab[xlator_obj->seg_id - 1]; if (!allocator) goto loop_cont; diff --git a/drivers/staging/tidspbridge/pmgr/dbll.c b/drivers/staging/tidspbridge/pmgr/dbll.c index db1af795544..997feebbf74 100644 --- a/drivers/staging/tidspbridge/pmgr/dbll.c +++ b/drivers/staging/tidspbridge/pmgr/dbll.c @@ -936,9 +936,6 @@ static struct dynload_symbol *dbll_find_symbol(struct dynamic_loader_sym *this, if (!status && gbl_search) dev_dbg(bridge, "%s: Symbol not found: %s\n", __func__, name); - DBC_ASSERT((status && (dbll_sym != NULL)) - || (!status && (dbll_sym == NULL))); - ret_sym = (struct dynload_symbol *)dbll_sym; return ret_sym; } diff --git a/drivers/staging/tidspbridge/pmgr/dev.c b/drivers/staging/tidspbridge/pmgr/dev.c index e4257fd7ff0..980bd532fb8 100644 --- a/drivers/staging/tidspbridge/pmgr/dev.c +++ b/drivers/staging/tidspbridge/pmgr/dev.c @@ -108,7 +108,6 @@ u32 dev_brd_write_fxn(void *arb, u32 dsp_add, void *host_buf, if (dev_obj) { /* Require of BrdWrite() */ - DBC_ASSERT(dev_obj->bridge_context != NULL); status = (*dev_obj->bridge_interface.brd_write) ( dev_obj->bridge_context, host_buf, dsp_add, ul_num_bytes, mem_space); @@ -164,7 +163,6 @@ int dev_create_device(struct dev_object **device_obj, /* Create the device object, and pass a handle to the Bridge driver for * storage. */ if (!status) { - DBC_ASSERT(drv_fxns); dev_obj = kzalloc(sizeof(struct dev_object), GFP_KERNEL); if (dev_obj) { /* Fill out the rest of the Dev Object structure: */ @@ -186,9 +184,6 @@ int dev_create_device(struct dev_object **device_obj, status = (dev_obj->bridge_interface.dev_create) (&dev_obj->bridge_context, dev_obj, host_res); - /* Assert bridge_dev_create()'s ensure clause: */ - DBC_ASSERT(status - || (dev_obj->bridge_context != NULL)); } else { status = -ENOMEM; } @@ -282,7 +277,6 @@ int dev_create2(struct dev_object *hdev_obj) struct dev_object *dev_obj = hdev_obj; /* There can be only one Node Manager per DEV object */ - DBC_ASSERT(!dev_obj->node_mgr); status = node_create_mgr(&dev_obj->node_mgr, hdev_obj); if (status) dev_obj->node_mgr = NULL; diff --git a/drivers/staging/tidspbridge/rmgr/dbdcd.c b/drivers/staging/tidspbridge/rmgr/dbdcd.c index 792b44363fd..18109fc346a 100644 --- a/drivers/staging/tidspbridge/rmgr/dbdcd.c +++ b/drivers/staging/tidspbridge/rmgr/dbdcd.c @@ -206,7 +206,6 @@ int dcd_enumerate_object(s32 index, enum dsp_dcdobjtype obj_type, * "_\0" + length of sz_obj_type string + terminating NULL. */ dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1; - DBC_ASSERT(dw_key_len < DCD_MAXPATHLENGTH); /* Create proper REG key; concatenate DCD_REGKEY with * obj_type. */ @@ -375,7 +374,6 @@ int dcd_get_object_def(struct dcd_manager *hdcd_mgr, /* Pre-determine final key length. It's length of DCD_REGKEY + * "_\0" + length of sz_obj_type string + terminating NULL */ dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1; - DBC_ASSERT(dw_key_len < DCD_MAXPATHLENGTH); /* Create proper REG key; concatenate DCD_REGKEY with obj_type. */ strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1); @@ -434,7 +432,6 @@ int dcd_get_object_def(struct dcd_manager *hdcd_mgr, } /* Ensure sz_uuid + 1 is not greater than sizeof sz_sect_name. */ - DBC_ASSERT((strlen(sz_uuid) + 1) < sizeof(sz_sect_name)); /* Create section name based on node UUID. A period is * pre-pended to the UUID string to form the section name. @@ -635,7 +632,6 @@ int dcd_get_library_name(struct dcd_manager *hdcd_mgr, * "_\0" + length of sz_obj_type string + terminating NULL. */ dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1; - DBC_ASSERT(dw_key_len < DCD_MAXPATHLENGTH); /* Create proper REG key; concatenate DCD_REGKEY with obj_type. */ strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1); @@ -663,7 +659,6 @@ int dcd_get_library_name(struct dcd_manager *hdcd_mgr, break; default: status = -EINVAL; - DBC_ASSERT(false); } if (!status) { if ((strlen(sz_reg_key) + strlen(sz_obj_type)) < @@ -794,7 +789,6 @@ int dcd_register_object(struct dsp_uuid *uuid_obj, * "_\0" + length of sz_obj_type string + terminating NULL. */ dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1; - DBC_ASSERT(dw_key_len < DCD_MAXPATHLENGTH); /* Create proper REG key; concatenate DCD_REGKEY with obj_type. */ strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1); diff --git a/drivers/staging/tidspbridge/rmgr/disp.c b/drivers/staging/tidspbridge/rmgr/disp.c index 04c88a7d019..63fdf1ee910 100644 --- a/drivers/staging/tidspbridge/rmgr/disp.c +++ b/drivers/staging/tidspbridge/rmgr/disp.c @@ -268,7 +268,6 @@ int disp_node_create(struct disp_object *disp_obj, node_type = node_get_type(hnode); node_msg_args = pargs->asa.node_msg_args; max = disp_obj->bufsize_rms; /*Max # of RMS words that can be sent */ - DBC_ASSERT(max == RMS_COMMANDBUFSIZE); chars_in_rms_word = sizeof(rms_word) / disp_obj->char_size; /* Number of RMS words needed to hold arg data */ dw_length = @@ -429,7 +428,6 @@ int disp_node_create(struct disp_object *disp_obj, } if (!status) { ul_bytes = total * sizeof(rms_word); - DBC_ASSERT(ul_bytes < (RMS_COMMANDBUFSIZE * sizeof(rms_word))); status = send_message(disp_obj, node_get_timeout(hnode), ul_bytes, node_env); } @@ -665,7 +663,6 @@ static int send_message(struct disp_object *disp_obj, u32 timeout, status = -EPERM; } else { if (CHNL_IS_IO_COMPLETE(chnl_ioc_obj)) { - DBC_ASSERT(chnl_ioc_obj.buf == pbuf); if (*((int *)chnl_ioc_obj.buf) < 0) { /* Translate DSP's to kernel error */ status = -EREMOTEIO; diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c index f3bff1bfcc6..cd93c128570 100644 --- a/drivers/staging/tidspbridge/rmgr/drv.c +++ b/drivers/staging/tidspbridge/rmgr/drv.c @@ -172,7 +172,6 @@ void drv_proc_node_update_status(void *node_resource, s32 status) { struct node_res_object *node_res_obj = (struct node_res_object *)node_resource; - DBC_ASSERT(node_resource != NULL); node_res_obj->node_allocated = status; } @@ -181,7 +180,6 @@ void drv_proc_node_update_heap_status(void *node_resource, s32 status) { struct node_res_object *node_res_obj = (struct node_res_object *)node_resource; - DBC_ASSERT(node_resource != NULL); node_res_obj->heap_allocated = status; } @@ -378,13 +376,8 @@ int drv_get_dev_object(u32 index, struct drv_object *hdrv_obj, struct dev_object **device_obj) { int status = 0; -#ifdef CONFIG_TIDSPBRIDGE_DEBUG - /* used only for Assertions and debug messages */ - struct drv_object *pdrv_obj = (struct drv_object *)hdrv_obj; -#endif struct dev_object *dev_obj; u32 i; - DBC_ASSERT(!(list_empty(&pdrv_obj->dev_list))); dev_obj = (struct dev_object *)drv_get_first_dev_object(); for (i = 0; i < index; i++) { diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c index 34730de45aa..f0f07efe4f8 100644 --- a/drivers/staging/tidspbridge/rmgr/drv_interface.c +++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c @@ -255,8 +255,6 @@ static int bridge_mmap(struct file *filp, struct vm_area_struct *vma) { u32 status; - DBC_ASSERT(vma->vm_start < vma->vm_end); - vma->vm_flags |= VM_RESERVED | VM_IO; vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); diff --git a/drivers/staging/tidspbridge/rmgr/mgr.c b/drivers/staging/tidspbridge/rmgr/mgr.c index 1dca953e4d6..b0ce0bc9c81 100644 --- a/drivers/staging/tidspbridge/rmgr/mgr.c +++ b/drivers/staging/tidspbridge/rmgr/mgr.c @@ -141,7 +141,6 @@ int mgr_enum_node_info(u32 node_id, struct dsp_ndbprops *pndb_props, } pmgr_obj = drv_datap->mgr_object; - DBC_ASSERT(pmgr_obj); /* Forever loop till we hit failed or no more items in the * Enumeration. We will exit the loop other than 0; */ while (!status) { @@ -225,7 +224,6 @@ int mgr_enum_processor_info(u32 processor_id, dev_dbg(bridge, "%s: Failed to get MGR Object\n", __func__); goto func_end; } - DBC_ASSERT(pmgr_obj); /* Forever loop till we hit no more items in the * Enumeration. We will exit the loop other than 0; */ while (status1 == 0) { diff --git a/drivers/staging/tidspbridge/rmgr/nldr.c b/drivers/staging/tidspbridge/rmgr/nldr.c index 6fb19ef68a8..cc20dd9bcbe 100644 --- a/drivers/staging/tidspbridge/rmgr/nldr.c +++ b/drivers/staging/tidspbridge/rmgr/nldr.c @@ -427,13 +427,10 @@ int nldr_create(struct nldr_object **nldr, dev_get_cod_mgr(hdev_obj, &cod_mgr); if (cod_mgr) { status = cod_get_loader(cod_mgr, &nldr_obj->dbll); - DBC_ASSERT(!status); status = cod_get_base_lib(cod_mgr, &nldr_obj->base_lib); - DBC_ASSERT(!status); status = cod_get_base_name(cod_mgr, sz_zl_file, COD_MAXPATHLENGTH); - DBC_ASSERT(!status); } status = 0; /* end lazy status checking */ @@ -534,7 +531,6 @@ int nldr_create(struct nldr_object **nldr, status = cod_get_base_name(cod_mgr, sz_zl_file, COD_MAXPATHLENGTH); /* lazy check */ - DBC_ASSERT(!status); /* First count number of overlay nodes */ status = dcd_get_objects(nldr_obj->dcd_mgr, sz_zl_file, @@ -666,7 +662,6 @@ int nldr_get_fxn_addr(struct nldr_nodeobject *nldr_node_obj, root = nldr_node_obj->delete_lib; break; default: - DBC_ASSERT(false); break; } } else { @@ -806,7 +801,6 @@ int nldr_load(struct nldr_nodeobject *nldr_node_obj, break; default: - DBC_ASSERT(false); break; } } @@ -853,7 +847,6 @@ int nldr_unload(struct nldr_nodeobject *nldr_node_obj, nldr_node_obj->pers_libs = 0; break; default: - DBC_ASSERT(false); break; } } else { @@ -1090,7 +1083,6 @@ static void free_sects(struct nldr_object *nldr_obj, ret = rmm_free(nldr_obj->rmm, 0, ovly_section->sect_run_addr, ovly_section->size, true); - DBC_ASSERT(ret); ovly_section = ovly_section->next_sect; i++; } @@ -1210,7 +1202,6 @@ static int load_lib(struct nldr_nodeobject *nldr_node_obj, if (depth > MAXDEPTH) { /* Error */ - DBC_ASSERT(false); } root->lib = NULL; /* Allocate a buffer for library file name of size DBL_MAXPATHLENGTH */ @@ -1273,7 +1264,6 @@ static int load_lib(struct nldr_nodeobject *nldr_node_obj, dcd_get_num_dep_libs(nldr_node_obj->nldr_obj->dcd_mgr, &uuid, &nd_libs, &np_libs, phase); } - DBC_ASSERT(nd_libs >= np_libs); if (!status) { if (!(*nldr_node_obj->phase_split)) np_libs = 0; @@ -1435,7 +1425,6 @@ static int load_ovly(struct nldr_nodeobject *nldr_node_obj, } } - DBC_ASSERT(i < nldr_obj->ovly_nodes); if (!po_node) { status = -ENOENT; @@ -1461,7 +1450,6 @@ static int load_ovly(struct nldr_nodeobject *nldr_node_obj, break; default: - DBC_ASSERT(false); break; } @@ -1609,7 +1597,6 @@ static int remote_alloc(void **ref, u16 mem_sect, u32 size, mem_phase_bit = EXECUTEDATAFLAGBIT; break; default: - DBC_ASSERT(false); break; } if (mem_sect == DBLL_CODE) @@ -1628,11 +1615,9 @@ static int remote_alloc(void **ref, u16 mem_sect, u32 size, /* Find an appropriate segment based on mem_sect */ if (segid == NULLID) { /* No memory requirements of preferences */ - DBC_ASSERT(!mem_load_req); goto func_cont; } if (segid <= MAXSEGID) { - DBC_ASSERT(segid < nldr_obj->dload_segs); /* Attempt to allocate from segid first. */ rmm_addr_obj->segid = segid; status = @@ -1643,7 +1628,6 @@ static int remote_alloc(void **ref, u16 mem_sect, u32 size, } } else { /* segid > MAXSEGID ==> Internal or external memory */ - DBC_ASSERT(segid == MEMINTERNALID || segid == MEMEXTERNALID); /* Check for any internal or external memory segment, * depending on segid. */ mem_sect_type |= segid == MEMINTERNALID ? @@ -1717,7 +1701,6 @@ static void unload_lib(struct nldr_nodeobject *nldr_node_obj, struct nldr_object *nldr_obj = nldr_node_obj->nldr_obj; u16 i; - DBC_ASSERT(root != NULL); /* Unload dependent libraries */ for (i = 0; i < root->dep_libs; i++) @@ -1768,7 +1751,6 @@ static void unload_ovly(struct nldr_nodeobject *nldr_node_obj, } } - DBC_ASSERT(i < nldr_obj->ovly_nodes); if (!po_node) /* TODO: Should we print warning here? */ @@ -1795,14 +1777,11 @@ static void unload_ovly(struct nldr_nodeobject *nldr_node_obj, other_alloc = po_node->other_sects; break; default: - DBC_ASSERT(false); break; } - DBC_ASSERT(ref_count && (*ref_count > 0)); if (ref_count && (*ref_count > 0)) { *ref_count -= 1; if (other_ref) { - DBC_ASSERT(*other_ref > 0); *other_ref -= 1; } } @@ -1868,7 +1847,6 @@ int nldr_find_addr(struct nldr_nodeobject *nldr_node, u32 sym_addr, root = nldr_node->delete_lib; break; default: - DBC_ASSERT(false); break; } } else { diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c index d23d1d07d67..83b053f6be8 100644 --- a/drivers/staging/tidspbridge/rmgr/node.c +++ b/drivers/staging/tidspbridge/rmgr/node.c @@ -703,7 +703,6 @@ DBAPI node_alloc_msg_buf(struct node_object *hnode, u32 usize, status = proc_get_processor_id(pnode->processor, &proc_id); if (proc_id != DSP_UNIT) { - DBC_ASSERT(NULL); goto func_end; } /* If segment ID includes MEM_SETVIRTUALSEGID then pbuffer is a @@ -889,7 +888,6 @@ int node_connect(struct node_object *node1, u32 stream1, if (node1_type != NODE_GPP) { hnode_mgr = node1->node_mgr; } else { - DBC_ASSERT(node2 != (struct node_object *)DSP_HGPPNODE); hnode_mgr = node2->node_mgr; } @@ -968,9 +966,6 @@ int node_connect(struct node_object *node1, u32 stream1, goto out_unlock; } - DBC_ASSERT((node1_type == NODE_GPP) || - (node2_type == NODE_GPP)); - chnl_mode = (node1_type == NODE_GPP) ? CHNL_MODETODSP : CHNL_MODEFROMDSP; @@ -1617,7 +1612,6 @@ int node_free_msg_buf(struct node_object *hnode, u8 * pbuffer, status = cmm_xlator_free_buf(pnode->xlator, pbuffer); } } else { - DBC_ASSERT(NULL); /* BUG */ } func_end: return status; @@ -1692,7 +1686,6 @@ int node_get_channel_id(struct node_object *hnode, u32 dir, u32 index, } } } else { - DBC_ASSERT(dir == DSP_FROMNODE); if (index < MAX_OUTPUTS(hnode)) { if (hnode->outputs[index].type == HOSTCONNECT) { *chan_id = hnode->outputs[index].dev_id; @@ -2222,7 +2215,6 @@ int node_run(struct node_object *hnode) NODE_GET_PRIORITY(hnode)); } else { /* We should never get here */ - DBC_ASSERT(false); } func_cont1: /* Update node state. */ @@ -2600,7 +2592,6 @@ static void fill_stream_connect(struct node_object *node1, strm1->connect_type = CONNECTTYPE_GPPOUTPUT; } else { /* GPP == > NODE */ - DBC_ASSERT(node2 != (struct node_object *)DSP_HGPPNODE); strm_index = node2->num_inputs + node2->num_outputs - 1; strm2 = &(node2->stream_connect[strm_index]); strm2->cb_struct = sizeof(struct dsp_streamconnect); @@ -2696,7 +2687,6 @@ static int get_fxn_address(struct node_object *hnode, u32 * fxn_addr, break; default: /* Should never get here */ - DBC_ASSERT(false); break; } @@ -2775,7 +2765,6 @@ static int get_node_props(struct dcd_manager *hdcd_mgr, } else { /* Copy device name */ len = strlen(pndb_props->ac_name); - DBC_ASSERT(len < MAXDEVNAMELEN); hnode->str_dev_name = kzalloc(len + 1, GFP_KERNEL); if (hnode->str_dev_name == NULL) { status = -ENOMEM; diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c index 4e2f2e450b2..8da5db6fe07 100644 --- a/drivers/staging/tidspbridge/rmgr/proc.c +++ b/drivers/staging/tidspbridge/rmgr/proc.c @@ -1152,8 +1152,6 @@ int proc_load(void *hprocessor, const s32 argc_index, if (status) { status = -EPERM; } else { - DBC_ASSERT(p_proc_object->last_coff == - NULL); /* Allocate memory for pszLastCoff */ p_proc_object->last_coff = kzalloc((strlen(user_args[0]) + @@ -1176,7 +1174,6 @@ int proc_load(void *hprocessor, const s32 argc_index, if (!hmsg_mgr) { status = msg_create(&hmsg_mgr, p_proc_object->dev_obj, (msg_onexit) node_on_exit); - DBC_ASSERT(!status); dev_set_msg_mgr(p_proc_object->dev_obj, hmsg_mgr); } } @@ -1272,7 +1269,6 @@ int proc_load(void *hprocessor, const s32 argc_index, strlen(pargv0) + 1); else status = -ENOMEM; - DBC_ASSERT(brd_state == BRD_LOADED); } } @@ -1559,7 +1555,6 @@ func_cont: if (!((*p_proc_object->intf_fxns->brd_status) (p_proc_object->bridge_context, &brd_state))) { pr_info("%s: dsp in running state\n", __func__); - DBC_ASSERT(brd_state != BRD_HIBERNATION); } } else { pr_err("%s: Failed to start the dsp\n", __func__); @@ -1585,7 +1580,6 @@ int proc_stop(void *hprocessor) u32 node_tab_size = 1; u32 num_nodes = 0; u32 nodes_allocated = 0; - int brd_state; if (!p_proc_object) { status = -EFAULT; @@ -1618,11 +1612,6 @@ int proc_stop(void *hprocessor) msg_delete(hmsg_mgr); dev_set_msg_mgr(p_proc_object->dev_obj, NULL); } - if (!((*p_proc_object-> - intf_fxns->brd_status) (p_proc_object-> - bridge_context, - &brd_state))) - DBC_ASSERT(brd_state == BRD_STOPPED); } } else { pr_err("%s: Failed to stop the processor\n", __func__); @@ -1760,7 +1749,6 @@ static int proc_monitor(struct proc_object *proc_obj) { int status = -EPERM; struct msg_mgr *hmsg_mgr; - int brd_state; /* This is needed only when Device is loaded when it is * already 'ACTIVE' */ @@ -1777,9 +1765,6 @@ static int proc_monitor(struct proc_object *proc_obj) if (!((*proc_obj->intf_fxns->brd_monitor) (proc_obj->bridge_context))) { status = 0; - if (!((*proc_obj->intf_fxns->brd_status) - (proc_obj->bridge_context, &brd_state))) - DBC_ASSERT(brd_state == BRD_IDLE); } return status; diff --git a/drivers/staging/tidspbridge/rmgr/rmm.c b/drivers/staging/tidspbridge/rmgr/rmm.c index 6b410499c3b..fe13a7444ae 100644 --- a/drivers/staging/tidspbridge/rmgr/rmm.c +++ b/drivers/staging/tidspbridge/rmgr/rmm.c @@ -292,7 +292,6 @@ bool rmm_free(struct rmm_target_obj *target, u32 segid, u32 dsp_addr, u32 size, list_for_each_entry_safe(sect, tmp, &target->ovly_list, list_elem) { if (dsp_addr == sect->addr) { - DBC_ASSERT(size == sect->size); /* Remove from list */ list_del(§->list_elem); kfree(sect); @@ -325,8 +324,6 @@ bool rmm_stat(struct rmm_target_obj *target, enum dsp_memtype segid, u32 total_free_size = 0; u32 free_blocks = 0; - DBC_ASSERT(target != NULL); - if ((u32) segid < target->num_segs) { head = target->free_list[segid]; diff --git a/drivers/staging/tidspbridge/rmgr/strm.c b/drivers/staging/tidspbridge/rmgr/strm.c index 8e2d6493344..80d01e5b053 100644 --- a/drivers/staging/tidspbridge/rmgr/strm.c +++ b/drivers/staging/tidspbridge/rmgr/strm.c @@ -119,7 +119,6 @@ int strm_allocate_buffer(struct strm_res_object *strmres, u32 usize, goto func_end; for (i = 0; i < num_bufs; i++) { - DBC_ASSERT(stream_obj->xlator != NULL); (void)cmm_xlator_alloc_buf(stream_obj->xlator, &ap_buffer[i], usize); if (ap_buffer[i] == NULL) { @@ -162,7 +161,6 @@ int strm_close(struct strm_res_object *strmres, status = (*intf_fxns->chnl_get_info) (stream_obj->chnl_obj, &chnl_info_obj); - DBC_ASSERT(!status); if (chnl_info_obj.cio_cs > 0 || chnl_info_obj.cio_reqs > 0) status = -EPIPE; @@ -205,7 +203,6 @@ int strm_create(struct strm_mgr **strm_man, if (!status) { (void)dev_get_intf_fxns(dev_obj, &(strm_mgr_obj->intf_fxns)); - DBC_ASSERT(strm_mgr_obj->intf_fxns != NULL); } } @@ -254,7 +251,6 @@ int strm_free_buffer(struct strm_res_object *strmres, u8 ** ap_buffer, if (!status) { for (i = 0; i < num_bufs; i++) { - DBC_ASSERT(stream_obj->xlator != NULL); status = cmm_xlator_free_buf(stream_obj->xlator, ap_buffer[i]); @@ -302,7 +298,6 @@ int strm_get_info(struct strm_object *stream_obj, if (stream_obj->xlator) { /* We have a translator */ - DBC_ASSERT(stream_obj->segment_id > 0); cmm_xlator_info(stream_obj->xlator, (u8 **) &virt_base, 0, stream_obj->segment_id, false); } @@ -496,14 +491,12 @@ int strm_open(struct node_object *hnode, u32 dir, u32 index, goto func_cont; /* No System DMA */ - DBC_ASSERT(strm_obj->strm_mode != STRMMODE_LDMA); /* Get the shared mem mgr for this streams dev object */ status = dev_get_cmm_mgr(strm_mgr_obj->dev_obj, &hcmm_mgr); if (!status) { /*Allocate a SM addr translator for this strm. */ status = cmm_xlator_create(&strm_obj->xlator, hcmm_mgr, NULL); if (!status) { - DBC_ASSERT(strm_obj->segment_id > 0); /* Set translators Virt Addr attributes */ status = cmm_xlator_info(strm_obj->xlator, (u8 **) &pattr->virt_base, @@ -535,10 +528,6 @@ func_cont: * strm_mgr_obj->chnl_mgr better be valid or we * assert here), and then return -EPERM. */ - DBC_ASSERT(status == -ENOSR || - status == -ECHRNG || - status == -EALREADY || - status == -EIO); status = -EPERM; } } -- cgit v1.2.3-70-g09d2 From f7c908ef871fcb319096caa7e839091b1feabd24 Mon Sep 17 00:00:00 2001 From: Víctor Manuel Jáquez Leal Date: Tue, 7 Feb 2012 00:39:36 +0100 Subject: staging: tidspbridge: remove dbc.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All the macros in dbc.h are removed now so this patch removes it completely. Signed-off-by: Víctor Manuel Jáquez Leal Signed-off-by: Greg Kroah-Hartman --- drivers/staging/tidspbridge/core/chnl_sm.c | 3 --- drivers/staging/tidspbridge/core/dsp-clock.c | 3 --- drivers/staging/tidspbridge/core/io_sm.c | 3 --- drivers/staging/tidspbridge/core/msg_sm.c | 3 --- drivers/staging/tidspbridge/core/tiomap3430.c | 3 --- drivers/staging/tidspbridge/core/tiomap_io.c | 3 --- drivers/staging/tidspbridge/gen/uuidutil.c | 3 --- .../staging/tidspbridge/include/dspbridge/dbc.h | 28 ---------------------- drivers/staging/tidspbridge/pmgr/chnl.c | 3 --- drivers/staging/tidspbridge/pmgr/cmm.c | 3 --- drivers/staging/tidspbridge/pmgr/cod.c | 3 --- drivers/staging/tidspbridge/pmgr/dbll.c | 2 -- drivers/staging/tidspbridge/pmgr/dev.c | 3 --- drivers/staging/tidspbridge/pmgr/dmm.c | 3 --- drivers/staging/tidspbridge/pmgr/dspapi.c | 3 --- drivers/staging/tidspbridge/pmgr/io.c | 3 --- drivers/staging/tidspbridge/pmgr/msg.c | 3 --- drivers/staging/tidspbridge/rmgr/dbdcd.c | 2 -- drivers/staging/tidspbridge/rmgr/disp.c | 3 --- drivers/staging/tidspbridge/rmgr/drv.c | 3 --- drivers/staging/tidspbridge/rmgr/drv_interface.c | 3 --- drivers/staging/tidspbridge/rmgr/dspdrv.c | 3 --- drivers/staging/tidspbridge/rmgr/mgr.c | 3 --- drivers/staging/tidspbridge/rmgr/nldr.c | 2 -- drivers/staging/tidspbridge/rmgr/node.c | 3 --- drivers/staging/tidspbridge/rmgr/proc.c | 3 --- drivers/staging/tidspbridge/rmgr/rmm.c | 3 --- drivers/staging/tidspbridge/rmgr/strm.c | 3 --- 28 files changed, 106 deletions(-) delete mode 100644 drivers/staging/tidspbridge/include/dspbridge/dbc.h (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/core/chnl_sm.c b/drivers/staging/tidspbridge/core/chnl_sm.c index 3136e8ddad4..e0c7e4c470c 100644 --- a/drivers/staging/tidspbridge/core/chnl_sm.c +++ b/drivers/staging/tidspbridge/core/chnl_sm.c @@ -50,9 +50,6 @@ /* ----------------------------------- DSP/BIOS Bridge */ #include -/* ----------------------------------- Trace & Debug */ -#include - /* ----------------------------------- OS Adaptation Layer */ #include diff --git a/drivers/staging/tidspbridge/core/dsp-clock.c b/drivers/staging/tidspbridge/core/dsp-clock.c index 7eb56178fb6..c7df34e6b60 100644 --- a/drivers/staging/tidspbridge/core/dsp-clock.c +++ b/drivers/staging/tidspbridge/core/dsp-clock.c @@ -29,9 +29,6 @@ #include #include "_tiomap.h" -/* ----------------------------------- Trace & Debug */ -#include - /* ----------------------------------- This */ #include diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c index 0930a9851f3..d47b861d61a 100644 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ b/drivers/staging/tidspbridge/core/io_sm.c @@ -33,9 +33,6 @@ /* ----------------------------------- DSP/BIOS Bridge */ #include -/* Trace & Debug */ -#include - /* Services Layer */ #include #include diff --git a/drivers/staging/tidspbridge/core/msg_sm.c b/drivers/staging/tidspbridge/core/msg_sm.c index 94d9e04a22f..ce9557e16eb 100644 --- a/drivers/staging/tidspbridge/core/msg_sm.c +++ b/drivers/staging/tidspbridge/core/msg_sm.c @@ -20,9 +20,6 @@ /* ----------------------------------- DSP/BIOS Bridge */ #include -/* ----------------------------------- Trace & Debug */ -#include - /* ----------------------------------- OS Adaptation Layer */ #include diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index c3efc2ec455..fd846327509 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -27,9 +27,6 @@ /* ----------------------------------- DSP/BIOS Bridge */ #include -/* ----------------------------------- Trace & Debug */ -#include - /* ----------------------------------- OS Adaptation Layer */ #include #include diff --git a/drivers/staging/tidspbridge/core/tiomap_io.c b/drivers/staging/tidspbridge/core/tiomap_io.c index 9c1887390ae..7fda10c3686 100644 --- a/drivers/staging/tidspbridge/core/tiomap_io.c +++ b/drivers/staging/tidspbridge/core/tiomap_io.c @@ -21,9 +21,6 @@ /* ----------------------------------- DSP/BIOS Bridge */ #include -/* ----------------------------------- Trace & Debug */ -#include - /* ----------------------------------- Platform Manager */ #include #include diff --git a/drivers/staging/tidspbridge/gen/uuidutil.c b/drivers/staging/tidspbridge/gen/uuidutil.c index 5797fb5c306..b44656cf785 100644 --- a/drivers/staging/tidspbridge/gen/uuidutil.c +++ b/drivers/staging/tidspbridge/gen/uuidutil.c @@ -23,9 +23,6 @@ /* ----------------------------------- DSP/BIOS Bridge */ #include -/* ----------------------------------- Trace & Debug */ -#include - /* ----------------------------------- This */ #include diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbc.h b/drivers/staging/tidspbridge/include/dspbridge/dbc.h deleted file mode 100644 index 90c45f69526..00000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/dbc.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * dbc.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * "Design by Contract" programming macros. - * - * Notes: - * Requires that the GT->ERROR function has been defaulted to a valid - * error handler for the given execution environment. - * - * Does not require that GT_init() be called. - * - * Copyright (C) 2008 Texas Instruments, Inc. - * - * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef DBC_ -#define DBC_ - -#endif /* DBC_ */ diff --git a/drivers/staging/tidspbridge/pmgr/chnl.c b/drivers/staging/tidspbridge/pmgr/chnl.c index 61ee0f0e511..825be200e27 100644 --- a/drivers/staging/tidspbridge/pmgr/chnl.c +++ b/drivers/staging/tidspbridge/pmgr/chnl.c @@ -24,9 +24,6 @@ /* ----------------------------------- DSP/BIOS Bridge */ #include -/* ----------------------------------- Trace & Debug */ -#include - /* ----------------------------------- OS Adaptation Layer */ #include diff --git a/drivers/staging/tidspbridge/pmgr/cmm.c b/drivers/staging/tidspbridge/pmgr/cmm.c index 0d19bcd4ce2..3366e601009 100644 --- a/drivers/staging/tidspbridge/pmgr/cmm.c +++ b/drivers/staging/tidspbridge/pmgr/cmm.c @@ -35,9 +35,6 @@ /* ----------------------------------- DSP/BIOS Bridge */ #include -/* ----------------------------------- Trace & Debug */ -#include - /* ----------------------------------- OS Adaptation Layer */ #include diff --git a/drivers/staging/tidspbridge/pmgr/cod.c b/drivers/staging/tidspbridge/pmgr/cod.c index be7c7772521..d01fb8e364b 100644 --- a/drivers/staging/tidspbridge/pmgr/cod.c +++ b/drivers/staging/tidspbridge/pmgr/cod.c @@ -30,9 +30,6 @@ /* ----------------------------------- DSP/BIOS Bridge */ #include -/* ----------------------------------- Trace & Debug */ -#include - /* ----------------------------------- Platform Manager */ /* Include appropriate loader header file */ #include diff --git a/drivers/staging/tidspbridge/pmgr/dbll.c b/drivers/staging/tidspbridge/pmgr/dbll.c index 997feebbf74..071ee86dd02 100644 --- a/drivers/staging/tidspbridge/pmgr/dbll.c +++ b/drivers/staging/tidspbridge/pmgr/dbll.c @@ -21,8 +21,6 @@ /* ----------------------------------- DSP/BIOS Bridge */ #include -/* ----------------------------------- Trace & Debug */ -#include #include /* ----------------------------------- OS Adaptation Layer */ diff --git a/drivers/staging/tidspbridge/pmgr/dev.c b/drivers/staging/tidspbridge/pmgr/dev.c index 980bd532fb8..883765e3c85 100644 --- a/drivers/staging/tidspbridge/pmgr/dev.c +++ b/drivers/staging/tidspbridge/pmgr/dev.c @@ -24,9 +24,6 @@ /* ----------------------------------- DSP/BIOS Bridge */ #include -/* ----------------------------------- Trace & Debug */ -#include - /* ----------------------------------- Platform Manager */ #include #include diff --git a/drivers/staging/tidspbridge/pmgr/dmm.c b/drivers/staging/tidspbridge/pmgr/dmm.c index cece7801d6c..83faff885f1 100644 --- a/drivers/staging/tidspbridge/pmgr/dmm.c +++ b/drivers/staging/tidspbridge/pmgr/dmm.c @@ -28,9 +28,6 @@ /* ----------------------------------- DSP/BIOS Bridge */ #include -/* ----------------------------------- Trace & Debug */ -#include - /* ----------------------------------- OS Adaptation Layer */ #include diff --git a/drivers/staging/tidspbridge/pmgr/dspapi.c b/drivers/staging/tidspbridge/pmgr/dspapi.c index 27c14a577dc..27889466a6d 100644 --- a/drivers/staging/tidspbridge/pmgr/dspapi.c +++ b/drivers/staging/tidspbridge/pmgr/dspapi.c @@ -24,9 +24,6 @@ /* ----------------------------------- DSP/BIOS Bridge */ #include -/* ----------------------------------- Trace & Debug */ -#include - /* ----------------------------------- OS Adaptation Layer */ #include diff --git a/drivers/staging/tidspbridge/pmgr/io.c b/drivers/staging/tidspbridge/pmgr/io.c index bbfe94cb36b..a56b085deb4 100644 --- a/drivers/staging/tidspbridge/pmgr/io.c +++ b/drivers/staging/tidspbridge/pmgr/io.c @@ -23,9 +23,6 @@ /* ----------------------------------- DSP/BIOS Bridge */ #include -/* ----------------------------------- Trace & Debug */ -#include - /* ----------------------------------- Platform Manager */ #include diff --git a/drivers/staging/tidspbridge/pmgr/msg.c b/drivers/staging/tidspbridge/pmgr/msg.c index 150026dfc74..077c11850c0 100644 --- a/drivers/staging/tidspbridge/pmgr/msg.c +++ b/drivers/staging/tidspbridge/pmgr/msg.c @@ -23,9 +23,6 @@ /* ----------------------------------- DSP/BIOS Bridge */ #include -/* ----------------------------------- Trace & Debug */ -#include - /* ----------------------------------- Bridge Driver */ #include diff --git a/drivers/staging/tidspbridge/rmgr/dbdcd.c b/drivers/staging/tidspbridge/rmgr/dbdcd.c index 18109fc346a..8378b7b2b66 100644 --- a/drivers/staging/tidspbridge/rmgr/dbdcd.c +++ b/drivers/staging/tidspbridge/rmgr/dbdcd.c @@ -29,8 +29,6 @@ /* ----------------------------------- DSP/BIOS Bridge */ #include -/* ----------------------------------- Trace & Debug */ -#include /* ----------------------------------- Platform Manager */ #include diff --git a/drivers/staging/tidspbridge/rmgr/disp.c b/drivers/staging/tidspbridge/rmgr/disp.c index 63fdf1ee910..e510bb25110 100644 --- a/drivers/staging/tidspbridge/rmgr/disp.c +++ b/drivers/staging/tidspbridge/rmgr/disp.c @@ -24,9 +24,6 @@ /* ----------------------------------- DSP/BIOS Bridge */ #include -/* ----------------------------------- Trace & Debug */ -#include - /* ----------------------------------- OS Adaptation Layer */ #include diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c index cd93c128570..b34dba73938 100644 --- a/drivers/staging/tidspbridge/rmgr/drv.c +++ b/drivers/staging/tidspbridge/rmgr/drv.c @@ -24,9 +24,6 @@ /* ----------------------------------- DSP/BIOS Bridge */ #include -/* ----------------------------------- Trace & Debug */ -#include - /* ----------------------------------- This */ #include #include diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c index f0f07efe4f8..31b5140a00c 100644 --- a/drivers/staging/tidspbridge/rmgr/drv_interface.c +++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c @@ -30,9 +30,6 @@ /* ----------------------------------- DSP/BIOS Bridge */ #include -/* ----------------------------------- Trace & Debug */ -#include - /* ----------------------------------- OS Adaptation Layer */ #include diff --git a/drivers/staging/tidspbridge/rmgr/dspdrv.c b/drivers/staging/tidspbridge/rmgr/dspdrv.c index 5d2576301f7..dc767b183cd 100644 --- a/drivers/staging/tidspbridge/rmgr/dspdrv.c +++ b/drivers/staging/tidspbridge/rmgr/dspdrv.c @@ -23,9 +23,6 @@ /* ----------------------------------- DSP/BIOS Bridge */ #include -/* ----------------------------------- Trace & Debug */ -#include - /* ----------------------------------- Platform Manager */ #include #include diff --git a/drivers/staging/tidspbridge/rmgr/mgr.c b/drivers/staging/tidspbridge/rmgr/mgr.c index b0ce0bc9c81..938eea5aaaf 100644 --- a/drivers/staging/tidspbridge/rmgr/mgr.c +++ b/drivers/staging/tidspbridge/rmgr/mgr.c @@ -26,9 +26,6 @@ /* ----------------------------------- DSP/BIOS Bridge */ #include -/* ----------------------------------- Trace & Debug */ -#include - /* ----------------------------------- OS Adaptation Layer */ #include diff --git a/drivers/staging/tidspbridge/rmgr/nldr.c b/drivers/staging/tidspbridge/rmgr/nldr.c index cc20dd9bcbe..5cff46f767b 100644 --- a/drivers/staging/tidspbridge/rmgr/nldr.c +++ b/drivers/staging/tidspbridge/rmgr/nldr.c @@ -22,8 +22,6 @@ #include -#include - /* Platform manager */ #include #include diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c index 83b053f6be8..1b24589847f 100644 --- a/drivers/staging/tidspbridge/rmgr/node.c +++ b/drivers/staging/tidspbridge/rmgr/node.c @@ -26,9 +26,6 @@ /* ----------------------------------- DSP/BIOS Bridge */ #include -/* ----------------------------------- Trace & Debug */ -#include - /* ----------------------------------- OS Adaptation Layer */ #include #include diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c index 8da5db6fe07..b865d64234a 100644 --- a/drivers/staging/tidspbridge/rmgr/proc.c +++ b/drivers/staging/tidspbridge/rmgr/proc.c @@ -25,9 +25,6 @@ /* ----------------------------------- DSP/BIOS Bridge */ #include -/* ----------------------------------- Trace & Debug */ -#include - /* ----------------------------------- OS Adaptation Layer */ #include #include diff --git a/drivers/staging/tidspbridge/rmgr/rmm.c b/drivers/staging/tidspbridge/rmgr/rmm.c index fe13a7444ae..55acfcd80a8 100644 --- a/drivers/staging/tidspbridge/rmgr/rmm.c +++ b/drivers/staging/tidspbridge/rmgr/rmm.c @@ -46,9 +46,6 @@ /* ----------------------------------- DSP/BIOS Bridge */ #include -/* ----------------------------------- Trace & Debug */ -#include - /* ----------------------------------- This */ #include diff --git a/drivers/staging/tidspbridge/rmgr/strm.c b/drivers/staging/tidspbridge/rmgr/strm.c index 80d01e5b053..bd684f16bae 100644 --- a/drivers/staging/tidspbridge/rmgr/strm.c +++ b/drivers/staging/tidspbridge/rmgr/strm.c @@ -24,9 +24,6 @@ /* ----------------------------------- DSP/BIOS Bridge */ #include -/* ----------------------------------- Trace & Debug */ -#include - /* ----------------------------------- OS Adaptation Layer */ #include -- cgit v1.2.3-70-g09d2 From 451196a338c681a95a79469cd58a54e657904e06 Mon Sep 17 00:00:00 2001 From: Víctor Manuel Jáquez Leal Date: Tue, 7 Feb 2012 00:39:37 +0100 Subject: staging: tidspbridge: remove CONFIG_TIDSPBRIDGE_DEBUG MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since all the asserts and DBC macros are gone, the kconfig macro CONFIG_TIDSPBRIDGE_DEBUG is not almost used, but for printing trace messages. Since it is almost not used, I don't see any case for keep it churning the configuration menu. This patch removes completely the kconfig macro CONFIG_TIDSPBRIDGE_DEBUG, using only TIDSPBRIDGE_BACKTRACE for enabling the debug trace messages. Signed-off-by: Víctor Manuel Jáquez Leal Signed-off-by: Greg Kroah-Hartman --- drivers/staging/tidspbridge/Kconfig | 6 ------ drivers/staging/tidspbridge/core/io_sm.c | 12 ++++++------ drivers/staging/tidspbridge/include/dspbridge/io_sm.h | 2 -- 3 files changed, 6 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/Kconfig b/drivers/staging/tidspbridge/Kconfig index 21a559ecbbb..d660891303b 100644 --- a/drivers/staging/tidspbridge/Kconfig +++ b/drivers/staging/tidspbridge/Kconfig @@ -31,12 +31,6 @@ config TIDSPBRIDGE_MEMPOOL_SIZE Allocate specified size of memory at booting time to avoid allocation failure under heavy memory fragmentation after some use time. -config TIDSPBRIDGE_DEBUG - bool "Debug Support" - depends on TIDSPBRIDGE - help - Say Y to enable Bridge debugging capabilities - config TIDSPBRIDGE_RECOVERY bool "Recovery Support" depends on TIDSPBRIDGE diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c index d47b861d61a..9b50b5bd4ed 100644 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ b/drivers/staging/tidspbridge/core/io_sm.c @@ -111,7 +111,7 @@ struct io_mgr { struct mgr_processorextinfo ext_proc_info; struct cmm_object *cmm_mgr; /* Shared Mem Mngr */ struct work_struct io_workq; /* workqueue */ -#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) || defined(CONFIG_TIDSPBRIDGE_DEBUG) +#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) u32 trace_buffer_begin; /* Trace message start address */ u32 trace_buffer_end; /* Trace message end address */ u32 trace_buffer_current; /* Trace message current address */ @@ -243,7 +243,7 @@ int bridge_io_destroy(struct io_mgr *hio_mgr) /* Free IO DPC object */ tasklet_kill(&hio_mgr->dpc_tasklet); -#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) || defined(CONFIG_TIDSPBRIDGE_DEBUG) +#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) kfree(hio_mgr->msg); #endif dsp_wdt_exit(); @@ -383,7 +383,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) status = -EFAULT; } if (!status) { -#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) || defined(CONFIG_TIDSPBRIDGE_DEBUG) +#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) status = cod_get_sym_value(cod_man, DSP_TRACESEC_END, &shm0_end); #else @@ -728,7 +728,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) hmsg_mgr->max_msgs); memset((void *)hio_mgr->shared_mem, 0, sizeof(struct shm)); -#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) || defined(CONFIG_TIDSPBRIDGE_DEBUG) +#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) /* Get the start address of trace buffer */ status = cod_get_sym_value(cod_man, SYS_PUTCBEG, &hio_mgr->trace_buffer_begin); @@ -907,7 +907,7 @@ void io_dpc(unsigned long ref_data) } #endif -#ifdef CONFIG_TIDSPBRIDGE_DEBUG +#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE if (pio_mgr->intr_val & MBX_DBG_SYSPRINTF) { /* Notify DSP Trace message */ print_dsp_debug_trace(pio_mgr); @@ -1666,7 +1666,7 @@ int bridge_io_get_proc_load(struct io_mgr *hio_mgr, } -#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) || defined(CONFIG_TIDSPBRIDGE_DEBUG) +#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) void print_dsp_debug_trace(struct io_mgr *hio_mgr) { u32 ul_new_message_length = 0, ul_gpp_cur_pointer; diff --git a/drivers/staging/tidspbridge/include/dspbridge/io_sm.h b/drivers/staging/tidspbridge/include/dspbridge/io_sm.h index a054dad2133..903ff12b14d 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/io_sm.h +++ b/drivers/staging/tidspbridge/include/dspbridge/io_sm.h @@ -154,8 +154,6 @@ int dump_dsp_stack(struct bridge_dev_context *bridge_context); void dump_dl_modules(struct bridge_dev_context *bridge_context); -#endif -#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) || defined(CONFIG_TIDSPBRIDGE_DEBUG) void print_dsp_debug_trace(struct io_mgr *hio_mgr); #endif -- cgit v1.2.3-70-g09d2 From 74eabe4ca2f6cf0e7e60e73017206e963f6b170a Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sun, 22 Jan 2012 19:50:13 +0100 Subject: Staging: quickstart: Use pr_err and pr_info for logs Signed-off-by: Szymon Janc Signed-off-by: Greg Kroah-Hartman --- drivers/staging/quickstart/quickstart.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/quickstart/quickstart.c b/drivers/staging/quickstart/quickstart.c index a67b03a5995..88f8ff38662 100644 --- a/drivers/staging/quickstart/quickstart.c +++ b/drivers/staging/quickstart/quickstart.c @@ -25,6 +25,8 @@ #define QUICKSTART_VERSION "1.03" +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -166,6 +168,7 @@ static void quickstart_acpi_notify(acpi_handle handle, u32 event, void *data) input_sync(quickstart_input); break; default: + pr_err("Unexpected ACPI event notify (%u)\n", event); break; } } @@ -183,8 +186,7 @@ static int quickstart_acpi_ghid(struct quickstart_acpi *quickstart) status = acpi_evaluate_object(quickstart->device->handle, "GHID", NULL, &buffer); if (ACPI_FAILURE(status)) { - printk(KERN_ERR "quickstart: %s GHID method failed.\n", - quickstart->button->name); + pr_err("%s GHID method failed\n", quickstart->button->name); return -EINVAL; } @@ -207,8 +209,7 @@ static int quickstart_acpi_ghid(struct quickstart_acpi *quickstart) quickstart->button->id = *(uint64_t *)buffer.pointer; break; default: - printk(KERN_ERR "quickstart: %s GHID method returned buffer " - "of unexpected length %u\n", + pr_err("%s GHID method returned buffer of unexpected length %u\n", quickstart->button->name, buffer.length); ret = -EINVAL; break; @@ -269,7 +270,7 @@ static int quickstart_acpi_add(struct acpi_device *device) quickstart_acpi_notify, quickstart); if (ACPI_FAILURE(status)) { - printk(KERN_ERR "quickstart: Notify handler install error\n"); + pr_err("Notify handler install error\n"); ret = -ENODEV; goto fail_installnotify; } @@ -309,7 +310,7 @@ static int quickstart_acpi_remove(struct acpi_device *device, int type) status = acpi_remove_notify_handler(device->handle, ACPI_ALL_NOTIFY, quickstart_acpi_notify); if (ACPI_FAILURE(status)) - printk(KERN_ERR "quickstart: Error removing notify handler\n"); + pr_err("Error removing notify handler\n"); kfree(quickstart); @@ -435,8 +436,7 @@ static int __init quickstart_init(void) if (ret) goto fail_input; - printk(KERN_INFO "quickstart: ACPI Direct App Launch ver %s\n", - QUICKSTART_VERSION); + pr_info("ACPI Direct App Launch ver %s\n", QUICKSTART_VERSION); return 0; fail_input: -- cgit v1.2.3-70-g09d2 From aa2f92ae6b986934ff220eda6b5c91f4ee294b35 Mon Sep 17 00:00:00 2001 From: Márton Németh Date: Sun, 22 Jan 2012 22:47:15 +0100 Subject: staging: rts5139: fix pointer coding style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will remove the following checkpatch.pl error: ERROR: "foo * bar" should be "foo *bar" Signed-off-by: Márton Németh Acked-by: edwin_rong Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5139/ms.h | 4 ++-- drivers/staging/rts5139/rts51x_chip.c | 14 +++++++------- drivers/staging/rts5139/rts51x_chip.h | 6 +++--- drivers/staging/rts5139/rts51x_fop.h | 2 +- drivers/staging/rts5139/rts51x_transport.c | 2 +- drivers/staging/rts5139/rts51x_transport.h | 2 +- drivers/staging/rts5139/sd_cprm.c | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rts5139/ms.h b/drivers/staging/rts5139/ms.h index f9d46d210f2..3ce1dc90f19 100644 --- a/drivers/staging/rts5139/ms.h +++ b/drivers/staging/rts5139/ms.h @@ -249,9 +249,9 @@ int ms_delay_write(struct rts51x_chip *chip); #ifdef SUPPORT_MAGIC_GATE int ms_switch_clock(struct rts51x_chip *chip); -int ms_write_bytes(struct rts51x_chip *chip, u8 tpc, u8 cnt, u8 cfg, u8 * data, +int ms_write_bytes(struct rts51x_chip *chip, u8 tpc, u8 cnt, u8 cfg, u8 *data, int data_len); -int ms_read_bytes(struct rts51x_chip *chip, u8 tpc, u8 cnt, u8 cfg, u8 * data, +int ms_read_bytes(struct rts51x_chip *chip, u8 tpc, u8 cnt, u8 cfg, u8 *data, int data_len); int ms_set_rw_reg_addr(struct rts51x_chip *chip, u8 read_start, u8 read_cnt, u8 write_start, u8 write_cnt); diff --git a/drivers/staging/rts5139/rts51x_chip.c b/drivers/staging/rts5139/rts51x_chip.c index adc0d000573..b3e0bb22b0f 100644 --- a/drivers/staging/rts5139/rts51x_chip.c +++ b/drivers/staging/rts5139/rts51x_chip.c @@ -541,7 +541,7 @@ int rts51x_get_rsp(struct rts51x_chip *chip, int rsp_len, int timeout) return STATUS_SUCCESS; } -int rts51x_get_card_status(struct rts51x_chip *chip, u16 * status) +int rts51x_get_card_status(struct rts51x_chip *chip, u16 *status) { int retval; u16 val; @@ -577,7 +577,7 @@ int rts51x_write_register(struct rts51x_chip *chip, u16 addr, u8 mask, u8 data) return STATUS_SUCCESS; } -int rts51x_read_register(struct rts51x_chip *chip, u16 addr, u8 * data) +int rts51x_read_register(struct rts51x_chip *chip, u16 addr, u8 *data) { int retval; @@ -620,7 +620,7 @@ int rts51x_ep0_write_register(struct rts51x_chip *chip, u16 addr, u8 mask, return STATUS_SUCCESS; } -int rts51x_ep0_read_register(struct rts51x_chip *chip, u16 addr, u8 * data) +int rts51x_ep0_read_register(struct rts51x_chip *chip, u16 addr, u8 *data) { int retval; u16 value = 0; @@ -720,7 +720,7 @@ int rts51x_seq_read_register(struct rts51x_chip *chip, u16 addr, u16 len, return STATUS_SUCCESS; } -int rts51x_read_ppbuf(struct rts51x_chip *chip, u8 * buf, int buf_len) +int rts51x_read_ppbuf(struct rts51x_chip *chip, u8 *buf, int buf_len) { int retval; @@ -735,7 +735,7 @@ int rts51x_read_ppbuf(struct rts51x_chip *chip, u8 * buf, int buf_len) return STATUS_SUCCESS; } -int rts51x_write_ppbuf(struct rts51x_chip *chip, u8 * buf, int buf_len) +int rts51x_write_ppbuf(struct rts51x_chip *chip, u8 *buf, int buf_len) { int retval; @@ -776,7 +776,7 @@ int rts51x_write_phy_register(struct rts51x_chip *chip, u8 addr, u8 val) return STATUS_SUCCESS; } -int rts51x_read_phy_register(struct rts51x_chip *chip, u8 addr, u8 * val) +int rts51x_read_phy_register(struct rts51x_chip *chip, u8 addr, u8 *val) { int retval; @@ -921,7 +921,7 @@ void rts51x_trace_msg(struct rts51x_chip *chip, unsigned char *buf, int clear) } #endif -void rts51x_pp_status(struct rts51x_chip *chip, unsigned int lun, u8 * status, +void rts51x_pp_status(struct rts51x_chip *chip, unsigned int lun, u8 *status, u8 status_len) { struct sd_info *sd_card = &(chip->sd_card); diff --git a/drivers/staging/rts5139/rts51x_chip.h b/drivers/staging/rts5139/rts51x_chip.h index 321ece750ed..13fc2a410d9 100644 --- a/drivers/staging/rts5139/rts51x_chip.h +++ b/drivers/staging/rts5139/rts51x_chip.h @@ -857,12 +857,12 @@ static inline u8 *rts51x_get_rsp_data(struct rts51x_chip *chip) return chip->rsp_buf; } -int rts51x_get_card_status(struct rts51x_chip *chip, u16 * status); +int rts51x_get_card_status(struct rts51x_chip *chip, u16 *status); int rts51x_write_register(struct rts51x_chip *chip, u16 addr, u8 mask, u8 data); -int rts51x_read_register(struct rts51x_chip *chip, u16 addr, u8 * data); +int rts51x_read_register(struct rts51x_chip *chip, u16 addr, u8 *data); int rts51x_ep0_write_register(struct rts51x_chip *chip, u16 addr, u8 mask, u8 data); -int rts51x_ep0_read_register(struct rts51x_chip *chip, u16 addr, u8 * data); +int rts51x_ep0_read_register(struct rts51x_chip *chip, u16 addr, u8 *data); int rts51x_seq_write_register(struct rts51x_chip *chip, u16 addr, u16 len, u8 *data); int rts51x_seq_read_register(struct rts51x_chip *chip, u16 addr, u16 len, diff --git a/drivers/staging/rts5139/rts51x_fop.h b/drivers/staging/rts5139/rts51x_fop.h index 0453f57d1a8..94d75f08d25 100644 --- a/drivers/staging/rts5139/rts51x_fop.h +++ b/drivers/staging/rts5139/rts51x_fop.h @@ -48,7 +48,7 @@ int rts51x_open(struct inode *inode, struct file *filp); int rts51x_release(struct inode *inode, struct file *filp); ssize_t rts51x_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos); -ssize_t rts51x_write(struct file *filp, const char __user * buf, size_t count, +ssize_t rts51x_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos); #if 0 /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) */ int rts51x_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, diff --git a/drivers/staging/rts5139/rts51x_transport.c b/drivers/staging/rts5139/rts51x_transport.c index e11467acc57..da9c83b4942 100644 --- a/drivers/staging/rts5139/rts51x_transport.c +++ b/drivers/staging/rts5139/rts51x_transport.c @@ -883,7 +883,7 @@ int rts51x_transfer_data_partial(struct rts51x_chip *chip, unsigned int pipe, return result; } -int rts51x_get_epc_status(struct rts51x_chip *chip, u16 * status) +int rts51x_get_epc_status(struct rts51x_chip *chip, u16 *status) { unsigned int pipe = RCV_INTR_PIPE(chip); struct usb_host_endpoint *ep; diff --git a/drivers/staging/rts5139/rts51x_transport.h b/drivers/staging/rts5139/rts51x_transport.h index 8464c4836d5..9dd556ea9c0 100644 --- a/drivers/staging/rts5139/rts51x_transport.h +++ b/drivers/staging/rts5139/rts51x_transport.h @@ -73,7 +73,7 @@ int rts51x_start_epc_transfer(struct rts51x_chip *chip); void rts51x_cancel_epc_transfer(struct rts51x_chip *chip); #endif -int rts51x_get_epc_status(struct rts51x_chip *chip, u16 * status); +int rts51x_get_epc_status(struct rts51x_chip *chip, u16 *status); void rts51x_invoke_transport(struct scsi_cmnd *srb, struct rts51x_chip *chip); #endif /* __RTS51X_TRANSPORT_H */ diff --git a/drivers/staging/rts5139/sd_cprm.c b/drivers/staging/rts5139/sd_cprm.c index 407cd43ad3b..d5969d992d8 100644 --- a/drivers/staging/rts5139/sd_cprm.c +++ b/drivers/staging/rts5139/sd_cprm.c @@ -233,7 +233,7 @@ RTY_SEND_CMD: return STATUS_SUCCESS; } -int ext_sd_get_rsp(struct rts51x_chip *chip, int len, u8 * rsp, u8 rsp_type) +int ext_sd_get_rsp(struct rts51x_chip *chip, int len, u8 *rsp, u8 rsp_type) { int retval, rsp_len; u16 reg_addr; -- cgit v1.2.3-70-g09d2 From 37fe58ba6832de1df88f3734d8e18f6da6a06971 Mon Sep 17 00:00:00 2001 From: Thomas Meyer Date: Sun, 22 Jan 2012 18:27:21 +0100 Subject: staging: drm/omap: Use ERR_CAST inlined function instead of ERR_PTR(PTR_ERR(.. The semantic patch that makes this change is available in scripts/coccinelle/api/err_cast.cocci. More information about semantic patching is available at http://coccinelle.lip6.fr/ Signed-off-by: Thomas Meyer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_gem_helpers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/omapdrm/omap_gem_helpers.c b/drivers/staging/omapdrm/omap_gem_helpers.c index 29275c7209e..f895363a5e5 100644 --- a/drivers/staging/omapdrm/omap_gem_helpers.c +++ b/drivers/staging/omapdrm/omap_gem_helpers.c @@ -84,7 +84,7 @@ fail: page_cache_release(pages[i]); } drm_free_large(pages); - return ERR_PTR(PTR_ERR(p)); + return ERR_CAST(p); } /** -- cgit v1.2.3-70-g09d2 From 98b9de2189180a1c62ea1ea912e66230908305f0 Mon Sep 17 00:00:00 2001 From: Bart Westgeest Date: Mon, 23 Jan 2012 10:55:45 -0500 Subject: staging: usbip: removed unused structure field Signed-off-by: Bart Westgeest Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/stub.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/usbip/stub.h b/drivers/staging/usbip/stub.h index d4073684eac..a73e437ec21 100644 --- a/drivers/staging/usbip/stub.h +++ b/drivers/staging/usbip/stub.h @@ -35,7 +35,6 @@ struct stub_device { struct usb_interface *interface; struct usb_device *udev; - struct list_head list; struct usbip_device ud; __u32 devid; -- cgit v1.2.3-70-g09d2 From ac2b41acfa3efe4650102067a99251587a806d70 Mon Sep 17 00:00:00 2001 From: Bart Westgeest Date: Mon, 23 Jan 2012 10:55:46 -0500 Subject: staging: usbip: changed function return type to void The function usbip_pad_iso never returns anything but 0 (success). Signed-off-by: Bart Westgeest Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/usbip_common.c | 11 ++++------- drivers/staging/usbip/usbip_common.h | 2 +- drivers/staging/usbip/vhci_rx.c | 3 +-- 3 files changed, 6 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c index d93e7f1f797..70f23026932 100644 --- a/drivers/staging/usbip/usbip_common.c +++ b/drivers/staging/usbip/usbip_common.c @@ -735,26 +735,25 @@ EXPORT_SYMBOL_GPL(usbip_recv_iso); * buffer and iso packets need to be stored and be in propeper endian in urb * before calling this function */ -int usbip_pad_iso(struct usbip_device *ud, struct urb *urb) +void usbip_pad_iso(struct usbip_device *ud, struct urb *urb) { int np = urb->number_of_packets; int i; - int ret; int actualoffset = urb->actual_length; if (!usb_pipeisoc(urb->pipe)) - return 0; + return; /* if no packets or length of data is 0, then nothing to unpack */ if (np == 0 || urb->actual_length == 0) - return 0; + return; /* * if actual_length is transfer_buffer_length then no padding is * present. */ if (urb->actual_length == urb->transfer_buffer_length) - return 0; + return; /* * loop over all packets from last to first (to prevent overwritting @@ -766,8 +765,6 @@ int usbip_pad_iso(struct usbip_device *ud, struct urb *urb) urb->transfer_buffer + actualoffset, urb->iso_frame_desc[i].actual_length); } - - return ret; } EXPORT_SYMBOL_GPL(usbip_pad_iso); diff --git a/drivers/staging/usbip/usbip_common.h b/drivers/staging/usbip/usbip_common.h index b8f8c48b8a7..c7b888ca54f 100644 --- a/drivers/staging/usbip/usbip_common.h +++ b/drivers/staging/usbip/usbip_common.h @@ -306,7 +306,7 @@ void usbip_header_correct_endian(struct usbip_header *pdu, int send); void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen); /* some members of urb must be substituted before. */ int usbip_recv_iso(struct usbip_device *ud, struct urb *urb); -int usbip_pad_iso(struct usbip_device *ud, struct urb *urb); +void usbip_pad_iso(struct usbip_device *ud, struct urb *urb); int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb); /* usbip_event.c */ diff --git a/drivers/staging/usbip/vhci_rx.c b/drivers/staging/usbip/vhci_rx.c index 3f511b47563..f5fba7320c5 100644 --- a/drivers/staging/usbip/vhci_rx.c +++ b/drivers/staging/usbip/vhci_rx.c @@ -94,8 +94,7 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev, return; /* restore the padding in iso packets */ - if (usbip_pad_iso(ud, urb) < 0) - return; + usbip_pad_iso(ud, urb); if (usbip_dbg_flag_vhci_rx) usbip_dump_urb(urb); -- cgit v1.2.3-70-g09d2 From 34c09578179f5838e5958c45e8aed4edc9c6c3b8 Mon Sep 17 00:00:00 2001 From: Bart Westgeest Date: Mon, 23 Jan 2012 10:55:47 -0500 Subject: staging: usbip: removed #if 0'd out code Signed-off-by: Bart Westgeest Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/stub_rx.c | 9 --------- drivers/staging/usbip/vhci_hcd.c | 39 --------------------------------------- 2 files changed, 48 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c index 27ac363d1cf..1d5b3fc6216 100644 --- a/drivers/staging/usbip/stub_rx.c +++ b/drivers/staging/usbip/stub_rx.c @@ -367,15 +367,6 @@ static int get_pipe(struct stub_device *sdev, int epnum, int dir) } epd = &ep->desc; -#if 0 - /* epnum 0 is always control */ - if (epnum == 0) { - if (dir == USBIP_DIR_OUT) - return usb_sndctrlpipe(udev, 0); - else - return usb_rcvctrlpipe(udev, 0); - } -#endif if (usb_endpoint_xfer_control(epd)) { if (dir == USBIP_DIR_OUT) return usb_sndctrlpipe(udev, epnum); diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index 2ee97e2095b..8d96ab065cb 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -386,29 +386,6 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, dum->port_status[rhport] |= USB_PORT_STAT_ENABLE; } -#if 0 - if (dum->driver) { - dum->port_status[rhport] |= - USB_PORT_STAT_ENABLE; - /* give it the best speed we agree on */ - dum->gadget.speed = dum->driver->speed; - dum->gadget.ep0->maxpacket = 64; - switch (dum->gadget.speed) { - case USB_SPEED_HIGH: - dum->port_status[rhport] |= - USB_PORT_STAT_HIGH_SPEED; - break; - case USB_SPEED_LOW: - dum->gadget.ep0->maxpacket = 8; - dum->port_status[rhport] |= - USB_PORT_STAT_LOW_SPEED; - break; - default: - dum->gadget.speed = USB_SPEED_FULL; - break; - } - } -#endif } ((u16 *) buf)[0] = cpu_to_le16(dum->port_status[rhport]); ((u16 *) buf)[1] = cpu_to_le16(dum->port_status[rhport] >> 16); @@ -425,15 +402,6 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, case USB_PORT_FEAT_SUSPEND: usbip_dbg_vhci_rh(" SetPortFeature: " "USB_PORT_FEAT_SUSPEND\n"); -#if 0 - dum->port_status[rhport] |= - (1 << USB_PORT_FEAT_SUSPEND); - if (dum->driver->suspend) { - spin_unlock(&dum->lock); - dum->driver->suspend(&dum->gadget); - spin_lock(&dum->lock); - } -#endif break; case USB_PORT_FEAT_RESET: usbip_dbg_vhci_rh(" SetPortFeature: " @@ -444,13 +412,6 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, ~(USB_PORT_STAT_ENABLE | USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED); -#if 0 - if (dum->driver) { - dev_dbg(hardware, "disconnect\n"); - stop_activity(dum, dum->driver); - } -#endif - /* FIXME test that code path! */ } /* 50msec reset signaling */ -- cgit v1.2.3-70-g09d2 From 8ebc0b65d77e424ad184357e59ca9c6093eee8f2 Mon Sep 17 00:00:00 2001 From: Kashyap Gada Date: Mon, 6 Feb 2012 02:01:16 +0000 Subject: Staging: ft1000: ft1000-pcmia: fix space required after that ', ' in ft1000_proc.c This is a patch to the ft1000_proc.c that fixes up space required after ',' errors found by the checkpatch.pl tool Signed-off-by: Kashyap Gada Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c index 7faeadad1ff..71aaad31270 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c @@ -29,10 +29,10 @@ #define FT1000_PROC "ft1000" #define MAX_FILE_LEN 255 -#define PUTM_TO_PAGE(len,page,args...) \ +#define PUTM_TO_PAGE(len, page, args...) \ len += snprintf(page+len, PAGE_SIZE - len, args) -#define PUTX_TO_PAGE(len,page,message,size,var) \ +#define PUTX_TO_PAGE(len, page, message, size, var) \ len += snprintf(page+len, PAGE_SIZE - len, message); \ for(i = 0; i < (size - 1); i++) \ { \ @@ -40,7 +40,7 @@ } \ len += snprintf(page+len, PAGE_SIZE - len, "%02x\n", var[i]) -#define PUTD_TO_PAGE(len,page,message,size,var) \ +#define PUTD_TO_PAGE(len, page, message, size, var) \ len += snprintf(page+len, PAGE_SIZE - len, message); \ for(i = 0; i < (size - 1); i++) \ { \ -- cgit v1.2.3-70-g09d2 From 733ba91cc0d5b0a3cc012431b8c5b354697b57c1 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 9 Feb 2012 19:25:53 +0200 Subject: staging/mei: update copyright year to 2012 1. Update Copyright to 2012 2. Also fix mei.h copyright format checkpaatch complained: WARNING: please, no spaces at the start of a line Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/mei/hw.h | 2 +- drivers/staging/mei/init.c | 2 +- drivers/staging/mei/interface.c | 2 +- drivers/staging/mei/interface.h | 2 +- drivers/staging/mei/interrupt.c | 2 +- drivers/staging/mei/iorw.c | 2 +- drivers/staging/mei/main.c | 2 +- drivers/staging/mei/mei.h | 125 ++++++++++++++++++++------------------ drivers/staging/mei/mei_dev.h | 2 +- drivers/staging/mei/mei_version.h | 2 +- drivers/staging/mei/wd.c | 2 +- 11 files changed, 75 insertions(+), 70 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/mei/hw.h b/drivers/staging/mei/hw.h index 9b9008cb693..b08c90193f7 100644 --- a/drivers/staging/mei/hw.h +++ b/drivers/staging/mei/hw.h @@ -1,7 +1,7 @@ /* * * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2011, Intel Corporation. + * Copyright (c) 2003-2012, Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, diff --git a/drivers/staging/mei/init.c b/drivers/staging/mei/init.c index 4ac3696883c..393da4bb202 100644 --- a/drivers/staging/mei/init.c +++ b/drivers/staging/mei/init.c @@ -1,7 +1,7 @@ /* * * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2011, Intel Corporation. + * Copyright (c) 2003-2012, Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, diff --git a/drivers/staging/mei/interface.c b/drivers/staging/mei/interface.c index eb5df7fc226..951e61f427b 100644 --- a/drivers/staging/mei/interface.c +++ b/drivers/staging/mei/interface.c @@ -1,7 +1,7 @@ /* * * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2011, Intel Corporation. + * Copyright (c) 2003-2012, Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, diff --git a/drivers/staging/mei/interface.h b/drivers/staging/mei/interface.h index aeae511419c..392987469e3 100644 --- a/drivers/staging/mei/interface.h +++ b/drivers/staging/mei/interface.h @@ -1,7 +1,7 @@ /* * * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2011, Intel Corporation. + * Copyright (c) 2003-2012, Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, diff --git a/drivers/staging/mei/interrupt.c b/drivers/staging/mei/interrupt.c index e85a85a9603..8e16e948560 100644 --- a/drivers/staging/mei/interrupt.c +++ b/drivers/staging/mei/interrupt.c @@ -1,7 +1,7 @@ /* * * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2011, Intel Corporation. + * Copyright (c) 2003-2012, Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, diff --git a/drivers/staging/mei/iorw.c b/drivers/staging/mei/iorw.c index 0752ead4269..a3fbac9546f 100644 --- a/drivers/staging/mei/iorw.c +++ b/drivers/staging/mei/iorw.c @@ -1,7 +1,7 @@ /* * * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2011, Intel Corporation. + * Copyright (c) 2003-2012, Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, diff --git a/drivers/staging/mei/main.c b/drivers/staging/mei/main.c index 1e1a9f996e7..22afc92319b 100644 --- a/drivers/staging/mei/main.c +++ b/drivers/staging/mei/main.c @@ -1,7 +1,7 @@ /* * * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2011, Intel Corporation. + * Copyright (c) 2003-2012, Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, diff --git a/drivers/staging/mei/mei.h b/drivers/staging/mei/mei.h index 6da7c4f33f9..b09b11cbe30 100644 --- a/drivers/staging/mei/mei.h +++ b/drivers/staging/mei/mei.h @@ -1,63 +1,68 @@ -/* - - Intel Management Engine Interface (Intel MEI) Linux driver - Intel MEI Interface Header - - This file is provided under a dual BSD/GPLv2 license. When using or - redistributing this file, you may do so under either license. - - GPL LICENSE SUMMARY - - Copyright(c) 2003-2011 Intel Corporation. All rights reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - Contact Information: - Intel Corporation. - linux-mei@linux.intel.com - http://www.intel.com - - - BSD LICENSE - - Copyright(c) 2003-2011 Intel Corporation. All rights reserved. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - +/****************************************************************************** + * Intel Management Engine Interface (Intel MEI) Linux driver + * Intel MEI Interface Header + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Corporation. + * linux-mei@linux.intel.com + * http://www.intel.com + * + * BSD LICENSE + * + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ #ifndef _LINUX_MEI_H #define _LINUX_MEI_H diff --git a/drivers/staging/mei/mei_dev.h b/drivers/staging/mei/mei_dev.h index 82bacfc624c..b9957e00f52 100644 --- a/drivers/staging/mei/mei_dev.h +++ b/drivers/staging/mei/mei_dev.h @@ -1,7 +1,7 @@ /* * * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2011, Intel Corporation. + * Copyright (c) 2003-2012, Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, diff --git a/drivers/staging/mei/mei_version.h b/drivers/staging/mei/mei_version.h index 075bad8f0bf..21955e7921c 100644 --- a/drivers/staging/mei/mei_version.h +++ b/drivers/staging/mei/mei_version.h @@ -1,7 +1,7 @@ /* * * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2011, Intel Corporation. + * Copyright (c) 2003-2012, Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, diff --git a/drivers/staging/mei/wd.c b/drivers/staging/mei/wd.c index 8094941a98f..f397835d7be 100644 --- a/drivers/staging/mei/wd.c +++ b/drivers/staging/mei/wd.c @@ -1,7 +1,7 @@ /* * * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2011, Intel Corporation. + * Copyright (c) 2003-2012, Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, -- cgit v1.2.3-70-g09d2 From edf1eed46636d0d34473657f24c32dc779afc85f Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 9 Feb 2012 19:25:54 +0200 Subject: staging/mei: normalize prototypes of all read buffers 1. convert all read buffers to unsigned char and drop useless castings 2. simplify mei_read_slots implementation Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/mei/interface.c | 23 +++++++---------------- drivers/staging/mei/interface.h | 3 ++- drivers/staging/mei/interrupt.c | 16 +++++----------- drivers/staging/mei/mei_dev.h | 6 ++++-- 4 files changed, 18 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/mei/interface.c b/drivers/staging/mei/interface.c index 951e61f427b..484be56a659 100644 --- a/drivers/staging/mei/interface.c +++ b/drivers/staging/mei/interface.c @@ -215,26 +215,17 @@ int mei_count_full_read_slots(struct mei_device *dev) * @buffer: message buffer will be written * @buffer_length: message size will be read */ -void mei_read_slots(struct mei_device *dev, - unsigned char *buffer, unsigned long buffer_length) +void mei_read_slots(struct mei_device *dev, unsigned char *buffer, + unsigned long buffer_length) { - u32 i = 0; - unsigned char temp_buf[sizeof(u32)]; + u32 *reg_buf = (u32 *)buffer; - while (buffer_length >= sizeof(u32)) { - ((u32 *) buffer)[i] = mei_mecbrw_read(dev); - - dev_dbg(&dev->pdev->dev, - "buffer[%d]= %d\n", - i, ((u32 *) buffer)[i]); - - i++; - buffer_length -= sizeof(u32); - } + for (; buffer_length >= sizeof(u32); buffer_length -= sizeof(u32)) + *reg_buf++ = mei_mecbrw_read(dev); if (buffer_length > 0) { - *((u32 *) &temp_buf) = mei_mecbrw_read(dev); - memcpy(&buffer[i * 4], temp_buf, buffer_length); + u32 reg = mei_mecbrw_read(dev); + memcpy(reg_buf, ®, buffer_length); } dev->host_hw_state |= H_IG; diff --git a/drivers/staging/mei/interface.h b/drivers/staging/mei/interface.h index 392987469e3..e5bfb18865f 100644 --- a/drivers/staging/mei/interface.h +++ b/drivers/staging/mei/interface.h @@ -33,7 +33,8 @@ void mei_read_slots(struct mei_device *dev, - unsigned char *buffer, unsigned long buffer_length); + unsigned char *buffer, + unsigned long buffer_length); int mei_write_message(struct mei_device *dev, struct mei_msg_hdr *header, diff --git a/drivers/staging/mei/interrupt.c b/drivers/staging/mei/interrupt.c index 8e16e948560..3c21c93af8e 100644 --- a/drivers/staging/mei/interrupt.c +++ b/drivers/staging/mei/interrupt.c @@ -123,8 +123,7 @@ static int mei_irq_thread_read_amthi_message(struct mei_io_list *complete_list, BUG_ON(mei_hdr->me_addr != dev->iamthif_cl.me_client_id); BUG_ON(dev->iamthif_state != MEI_IAMTHIF_READING); - buffer = (unsigned char *) (dev->iamthif_msg_buf + - dev->iamthif_msg_buf_index); + buffer = dev->iamthif_msg_buf + dev->iamthif_msg_buf_index; BUG_ON(dev->iamthif_mtu < dev->iamthif_msg_buf_index + mei_hdr->length); mei_read_slots(dev, buffer, mei_hdr->length); @@ -206,9 +205,7 @@ static int mei_irq_thread_read_client_message(struct mei_io_list *complete_list, cl = (struct mei_cl *)cb_pos->file_private; if (cl && _mei_irq_thread_state_ok(cl, mei_hdr)) { cl->reading_state = MEI_READING; - buffer = (unsigned char *) - (cb_pos->response_buffer.data + - cb_pos->information); + buffer = cb_pos->response_buffer.data + cb_pos->information; if (cb_pos->response_buffer.size < mei_hdr->length + cb_pos->information) { @@ -247,8 +244,7 @@ static int mei_irq_thread_read_client_message(struct mei_io_list *complete_list, quit: dev_dbg(&dev->pdev->dev, "message read\n"); if (!buffer) { - mei_read_slots(dev, (unsigned char *) dev->rd_msg_buf, - mei_hdr->length); + mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length); dev_dbg(&dev->pdev->dev, "discarding message, header =%08x.\n", *(u32 *) dev->rd_msg_buf); } @@ -632,13 +628,11 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev, struct hbm_host_stop_request *host_stop_req; int res; - unsigned char *buffer; /* read the message to our buffer */ - buffer = (unsigned char *) dev->rd_msg_buf; BUG_ON(mei_hdr->length >= sizeof(dev->rd_msg_buf)); - mei_read_slots(dev, buffer, mei_hdr->length); - mei_msg = (struct mei_bus_message *) buffer; + mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length); + mei_msg = (struct mei_bus_message *)dev->rd_msg_buf; switch (*(u8 *) mei_msg) { case HOST_START_RES_CMD: diff --git a/drivers/staging/mei/mei_dev.h b/drivers/staging/mei/mei_dev.h index b9957e00f52..0d937b07532 100644 --- a/drivers/staging/mei/mei_dev.h +++ b/drivers/staging/mei/mei_dev.h @@ -30,6 +30,8 @@ #define MEI_WD_PARAMS_SIZE 4 #define MEI_WD_STATE_INDEPENDENCE_MSG_SENT (1 << 0) +#define MEI_RD_MSG_BUF_SIZE (128 * sizeof(u32)) + /* * MEI PCI Device object */ @@ -125,7 +127,7 @@ enum mei_cb_major_types { */ struct mei_message_data { u32 size; - char *data; + unsigned char *data; } __packed; @@ -219,7 +221,7 @@ struct mei_device { bool need_reset; u32 extra_write_index; - u32 rd_msg_buf[128]; /* used for control messages */ + unsigned char rd_msg_buf[MEI_RD_MSG_BUF_SIZE]; /* control messages */ u32 wr_msg_buf[128]; /* used for control messages */ u32 ext_msg_buf[8]; /* for control responses */ u32 rd_msg_hdr; -- cgit v1.2.3-70-g09d2 From c52827cc4ddf387c59b605c9d83dcaffbbf465bf Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 9 Feb 2012 19:25:55 +0200 Subject: staging/mei: add mei user space example this example tries to connect to amt host interface client and retrieve versions of its sub components When AMT is enabled an output might look like that: Intel AMT: ENABLED Flash: 6.1.0 Netstack: 6.1.0 AMTApps: 6.1.0 AMT: 6.1.0 Sku: 258 VendorID: 8086 Build Number: 1042 Recovery Version: 6.1.0 Recovery Build Num: 1042 Legacy Mode: False otherwise: Intel AMT: DISABLED Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/mei/mei-amt-version.c | 479 ++++++++++++++++++++++++++++++++++ 1 file changed, 479 insertions(+) create mode 100644 drivers/staging/mei/mei-amt-version.c (limited to 'drivers') diff --git a/drivers/staging/mei/mei-amt-version.c b/drivers/staging/mei/mei-amt-version.c new file mode 100644 index 00000000000..be04934cd32 --- /dev/null +++ b/drivers/staging/mei/mei-amt-version.c @@ -0,0 +1,479 @@ +/****************************************************************************** + * Intel Management Engine Interface (Intel MEI) Linux driver + * Intel MEI Interface Header + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Corporation. + * linux-mei@linux.intel.com + * http://www.intel.com + * + * BSD LICENSE + * + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mei.h" + +/***************************************************************************** + * Intel Management Enginin Interface + *****************************************************************************/ + +#define mei_msg(_me, fmt, ARGS...) do { \ + if (_me->verbose) \ + fprintf(stderr, fmt, ##ARGS); \ +} while (0) + +#define mei_err(_me, fmt, ARGS...) do { \ + fprintf(stderr, "Error: " fmt, ##ARGS); \ +} while (0) + +struct mei { + uuid_le guid; + bool initialized; + bool verbose; + unsigned int buf_size; + unsigned char prot_ver; + int fd; +}; + +static void mei_deinit(struct mei *cl) +{ + if (cl->fd != -1) + close(cl->fd); + cl->fd = -1; + cl->buf_size = 0; + cl->prot_ver = 0; + cl->initialized = false; +} + +static bool mei_init(struct mei *me, const uuid_le *guid, + unsigned char req_protocol_version, bool verbose) +{ + int result; + struct mei_client *cl; + struct mei_connect_client_data data; + + mei_deinit(me); + + me->verbose = verbose; + + me->fd = open("/dev/mei", O_RDWR); + if (me->fd == -1) { + mei_err(me, "Cannot establish a handle to the Intel MEI driver\n"); + goto err; + } + memcpy(&me->guid, guid, sizeof(*guid)); + memset(&data, 0, sizeof(data)); + me->initialized = true; + + memcpy(&data.in_client_uuid, &me->guid, sizeof(me->guid)); + result = ioctl(me->fd, IOCTL_MEI_CONNECT_CLIENT, &data); + if (result) { + mei_err(me, "IOCTL_MEI_CONNECT_CLIENT receive message. err=%d\n", result); + goto err; + } + cl = &data.out_client_properties; + mei_msg(me, "max_message_length %d\n", cl->max_msg_length); + mei_msg(me, "protocol_version %d\n", cl->protocol_version); + + if ((req_protocol_version > 0) && + (cl->protocol_version != req_protocol_version)) { + mei_err(me, "Intel MEI protocol version not supported\n"); + goto err; + } + + me->buf_size = cl->max_msg_length; + me->prot_ver = cl->protocol_version; + + return true; +err: + mei_deinit(me); + return false; +} + +static ssize_t mei_recv_msg(struct mei *me, unsigned char *buffer, + ssize_t len, unsigned long timeout) +{ + ssize_t rc; + + mei_msg(me, "call read length = %zd\n", len); + + rc = read(me->fd, buffer, len); + if (rc < 0) { + mei_err(me, "read failed with status %zd %s\n", + rc, strerror(errno)); + mei_deinit(me); + } else { + mei_msg(me, "read succeeded with result %zd\n", rc); + } + return rc; +} + +static ssize_t mei_send_msg(struct mei *me, const unsigned char *buffer, + ssize_t len, unsigned long timeout) +{ + struct timeval tv; + ssize_t written; + ssize_t rc; + fd_set set; + + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000000; + + mei_msg(me, "call write length = %zd\n", len); + + written = write(me->fd, buffer, len); + if (written < 0) { + rc = -errno; + mei_err(me, "write failed with status %zd %s\n", + written, strerror(errno)); + goto out; + } + + FD_ZERO(&set); + FD_SET(me->fd, &set); + rc = select(me->fd + 1 , &set, NULL, NULL, &tv); + if (rc > 0 && FD_ISSET(me->fd, &set)) { + mei_msg(me, "write success\n"); + } else if (rc == 0) { + mei_err(me, "write failed on timeout with status\n"); + goto out; + } else { /* rc < 0 */ + mei_err(me, "write failed on select with status %zd\n", rc); + goto out; + } + + rc = written; +out: + if (rc < 0) + mei_deinit(me); + + return rc; +} + +/*************************************************************************** + * Intel Advanced Management Technolgy ME Client + ***************************************************************************/ + +#define AMT_MAJOR_VERSION 1 +#define AMT_MINOR_VERSION 1 + +#define AMT_STATUS_SUCCESS 0x0 +#define AMT_STATUS_INTERNAL_ERROR 0x1 +#define AMT_STATUS_NOT_READY 0x2 +#define AMT_STATUS_INVALID_AMT_MODE 0x3 +#define AMT_STATUS_INVALID_MESSAGE_LENGTH 0x4 + +#define AMT_STATUS_HOST_IF_EMPTY_RESPONSE 0x4000 +#define AMT_STATUS_SDK_RESOURCES 0x1004 + + +#define AMT_BIOS_VERSION_LEN 65 +#define AMT_VERSIONS_NUMBER 50 +#define AMT_UNICODE_STRING_LEN 20 + +struct amt_unicode_string { + uint16_t length; + char string[AMT_UNICODE_STRING_LEN]; +} __attribute__((packed)); + +struct amt_version_type { + struct amt_unicode_string description; + struct amt_unicode_string version; +} __attribute__((packed)); + +struct amt_version { + uint8_t major; + uint8_t minor; +} __attribute__((packed)); + +struct amt_code_versions { + uint8_t bios[AMT_BIOS_VERSION_LEN]; + uint32_t count; + struct amt_version_type versions[AMT_VERSIONS_NUMBER]; +} __attribute__((packed)); + +/*************************************************************************** + * Intel Advanced Management Technolgy Host Interface + ***************************************************************************/ + +struct amt_host_if_msg_header { + struct amt_version version; + uint16_t _reserved; + uint32_t command; + uint32_t length; +} __attribute__((packed)); + +struct amt_host_if_resp_header { + struct amt_host_if_msg_header header; + uint32_t status; + unsigned char data[0]; +} __attribute__((packed)); + +const uuid_le MEI_IAMTHIF = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, \ + 0xac, 0xa8, 0x46, 0xe0, 0xff, 0x65, 0x81, 0x4c); + +#define AMT_HOST_IF_CODE_VERSIONS_REQUEST 0x0400001A +#define AMT_HOST_IF_CODE_VERSIONS_RESPONSE 0x0480001A + +const struct amt_host_if_msg_header CODE_VERSION_REQ = { + .version = {AMT_MAJOR_VERSION, AMT_MINOR_VERSION}, + ._reserved = 0, + .command = AMT_HOST_IF_CODE_VERSIONS_REQUEST, + .length = 0 +}; + + +struct amt_host_if { + struct mei mei_cl; + unsigned long send_timeout; + bool initialized; +}; + + +bool amt_host_if_init(struct amt_host_if *acmd, + unsigned long send_timeout, bool verbose) +{ + acmd->send_timeout = (send_timeout) ? send_timeout : 20000; + acmd->initialized = mei_init(&acmd->mei_cl, &MEI_IAMTHIF, 0, verbose); + return acmd->initialized; +} + +void amt_host_if_deinit(struct amt_host_if *acmd) +{ + mei_deinit(&acmd->mei_cl); + acmd->initialized = false; +} + +uint32_t amt_verify_code_versions(const struct amt_host_if_resp_header *resp) +{ + uint32_t status = AMT_STATUS_SUCCESS; + struct amt_code_versions *code_ver; + size_t code_ver_len; + uint32_t ver_type_cnt; + uint32_t len; + uint32_t i; + + code_ver = (struct amt_code_versions *)resp->data; + /* length - sizeof(status) */ + code_ver_len = resp->header.length - sizeof(uint32_t); + ver_type_cnt = code_ver_len - + sizeof(code_ver->bios) - + sizeof(code_ver->count); + if (code_ver->count != ver_type_cnt / sizeof(struct amt_version_type)) { + status = AMT_STATUS_INTERNAL_ERROR; + goto out; + } + + for (i = 0; i < code_ver->count; i++) { + len = code_ver->versions[i].description.length; + + if (len > AMT_UNICODE_STRING_LEN) { + status = AMT_STATUS_INTERNAL_ERROR; + goto out; + } + + len = code_ver->versions[i].version.length; + if (code_ver->versions[i].version.string[len] != '\0' || + len != strlen(code_ver->versions[i].version.string)) { + status = AMT_STATUS_INTERNAL_ERROR; + goto out; + } + } +out: + return status; +} + +uint32_t amt_verify_response_header(uint32_t command, + const struct amt_host_if_msg_header *resp_hdr, + uint32_t response_size) +{ + if (response_size < sizeof(struct amt_host_if_resp_header)) { + return AMT_STATUS_INTERNAL_ERROR; + } else if (response_size != (resp_hdr->length + + sizeof(struct amt_host_if_msg_header))) { + return AMT_STATUS_INTERNAL_ERROR; + } else if (resp_hdr->command != command) { + return AMT_STATUS_INTERNAL_ERROR; + } else if (resp_hdr->_reserved != 0) { + return AMT_STATUS_INTERNAL_ERROR; + } else if (resp_hdr->version.major != AMT_MAJOR_VERSION || + resp_hdr->version.minor < AMT_MINOR_VERSION) { + return AMT_STATUS_INTERNAL_ERROR; + } + return AMT_STATUS_SUCCESS; +} + +static uint32_t amt_host_if_call(struct amt_host_if *acmd, + const unsigned char *command, ssize_t command_sz, + uint8_t **read_buf, uint32_t rcmd, + unsigned int expected_sz) +{ + uint32_t in_buf_sz; + uint32_t out_buf_sz; + ssize_t written; + uint32_t status; + struct amt_host_if_resp_header *msg_hdr; + + in_buf_sz = acmd->mei_cl.buf_size; + *read_buf = (uint8_t *)malloc(sizeof(uint8_t) * in_buf_sz); + if (*read_buf == NULL) + return AMT_STATUS_SDK_RESOURCES; + memset(*read_buf, 0, in_buf_sz); + msg_hdr = (struct amt_host_if_resp_header *)*read_buf; + + written = mei_send_msg(&acmd->mei_cl, + command, command_sz, acmd->send_timeout); + if (written != command_sz) + return AMT_STATUS_INTERNAL_ERROR; + + out_buf_sz = mei_recv_msg(&acmd->mei_cl, *read_buf, in_buf_sz, 2000); + if (out_buf_sz <= 0) + return AMT_STATUS_HOST_IF_EMPTY_RESPONSE; + + status = msg_hdr->status; + if (status != AMT_STATUS_SUCCESS) + return status; + + status = amt_verify_response_header(rcmd, + &msg_hdr->header, out_buf_sz); + if (status != AMT_STATUS_SUCCESS) + return status; + + if (expected_sz && expected_sz != out_buf_sz) + return AMT_STATUS_INTERNAL_ERROR; + + return AMT_STATUS_SUCCESS; +} + + +uint32_t amt_get_code_versions(struct amt_host_if *cmd, + struct amt_code_versions *versions) +{ + struct amt_host_if_resp_header *response = NULL; + uint32_t status; + + status = amt_host_if_call(cmd, + (const unsigned char *)&CODE_VERSION_REQ, + sizeof(CODE_VERSION_REQ), + (uint8_t **)&response, + AMT_HOST_IF_CODE_VERSIONS_RESPONSE, 0); + + if (status != AMT_STATUS_SUCCESS) + goto out; + + status = amt_verify_code_versions(response); + if (status != AMT_STATUS_SUCCESS) + goto out; + + memcpy(versions, response->data, sizeof(struct amt_code_versions)); +out: + if (response != NULL) + free(response); + + return status; +} + +/************************** end of amt_host_if_command ***********************/ +int main(int argc, char **argv) +{ + struct amt_code_versions ver; + struct amt_host_if acmd; + unsigned int i; + uint32_t status; + int ret; + bool verbose; + + verbose = (argc > 1 && strcmp(argv[1], "-v") == 0); + + if (!amt_host_if_init(&acmd, 5000, verbose)) { + ret = 1; + goto out; + } + + status = amt_get_code_versions(&acmd, &ver); + + switch (status) { + case AMT_STATUS_HOST_IF_EMPTY_RESPONSE: + printf("Intel AMT: DISABLED\n"); + ret = 0; + break; + case AMT_STATUS_SUCCESS: + printf("Intel AMT: ENABLED\n"); + for (i = 0; i < ver.count; i++) { + printf("%s:\t%s\n", ver.versions[i].description.string, + ver.versions[i].version.string); + } + ret = 0; + break; + default: + printf("An error has occurred\n"); + ret = 1; + break; + } + +out: + return ret; +} -- cgit v1.2.3-70-g09d2 From 190f998b7951bcb8aff7e1fd023f25d0adcc5045 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 9 Feb 2012 19:25:56 +0200 Subject: staging/mei: TODO : how to handle example code after unstaging Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/mei/TODO | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/mei/TODO b/drivers/staging/mei/TODO index 7d9a13b0f2d..fc266018355 100644 --- a/drivers/staging/mei/TODO +++ b/drivers/staging/mei/TODO @@ -3,5 +3,8 @@ TODO: Upon Unstaging: - move mei.h to include/linux/mei.h - Documentation/ioctl/ioctl-number.txt + - move mei.txt under Documentation/mei/ + - move mei-amt-version.c under Documentation/mei + - add hostprogs-y for mei-amt-version.c - drop mei_version.h - Updated MAINTAINERS -- cgit v1.2.3-70-g09d2 From 3e150cf51d9242ae4ef9c872cdf6766ee5115c44 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 17 Jan 2012 10:31:52 +0300 Subject: Staging: sbe-2t3e3: logical || vs bitwise | Bitwise OR was clearly intended here. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sbe-2t3e3/intr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/sbe-2t3e3/intr.c b/drivers/staging/sbe-2t3e3/intr.c index 7ad1a838203..1336aab11bd 100644 --- a/drivers/staging/sbe-2t3e3/intr.c +++ b/drivers/staging/sbe-2t3e3/intr.c @@ -188,7 +188,7 @@ void dc_intr_rx(struct channel *sc) } if (sc->s.LOS) { - error_mask &= ~(SBE_2T3E3_RX_DESC_DRIBBLING_BIT || + error_mask &= ~(SBE_2T3E3_RX_DESC_DRIBBLING_BIT | SBE_2T3E3_RX_DESC_MII_ERROR); } -- cgit v1.2.3-70-g09d2 From d0bc218b0a75bbddc9ef54aac6d9cc65a7a58661 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Wed, 25 Jan 2012 00:35:41 +0900 Subject: staging: Fix typo in ieee80211_rx.c Correct spelling "suppported" to "supported" in drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c Signed-off-by: Masanari iida Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c index c9bdc7f6bdc..be2a28cf8ed 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c @@ -237,7 +237,7 @@ ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb, #ifdef NOT_YET if (ieee->iw_mode == IW_MODE_MASTER) { - printk(KERN_DEBUG "%s: Master mode not yet suppported.\n", + printk(KERN_DEBUG "%s: Master mode not yet supported.\n", ieee->dev->name); return 0; /* -- cgit v1.2.3-70-g09d2 From 881763361e8283a6d33d5a30ac6edc36e7dc6d44 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sun, 29 Jan 2012 21:55:28 +0100 Subject: staging, media, easycap: Fix mem leak in easycap_usb_probe() If allocating 'pdata_urb' fails, the function will return -ENOMEM without freeing the memory allocated, just a few lines above, for 'purb' and will leak that memory when 'purb' goes out of scope. This patch resolves the leak by freeing the allocated storage with usb_free_urb() before the return. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/easycap/easycap_main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/media/easycap/easycap_main.c b/drivers/staging/media/easycap/easycap_main.c index 8ff5f38ea19..3d439b790cc 100644 --- a/drivers/staging/media/easycap/easycap_main.c +++ b/drivers/staging/media/easycap/easycap_main.c @@ -3825,6 +3825,7 @@ static int easycap_usb_probe(struct usb_interface *intf, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL); if (!pdata_urb) { + usb_free_urb(purb); SAM("ERROR: Could not allocate struct data_urb.\n"); return -ENOMEM; } -- cgit v1.2.3-70-g09d2 From 2e254212942e483eba4753830268045ac87ea224 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 31 Jan 2012 11:45:15 +0300 Subject: Staging: wlan-ng: cap the ssid length We're getting the ssid length from the scan here. Let's cap it before doing the memcpy(). Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/prism2mgmt.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/wlan-ng/prism2mgmt.c b/drivers/staging/wlan-ng/prism2mgmt.c index 6675c8226ce..c3bb05dd744 100644 --- a/drivers/staging/wlan-ng/prism2mgmt.c +++ b/drivers/staging/wlan-ng/prism2mgmt.c @@ -406,6 +406,7 @@ int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp) /* SSID */ req->ssid.status = P80211ENUM_msgitem_status_data_ok; req->ssid.data.len = le16_to_cpu(item->ssid.len); + req->ssid.data.len = min_t(u16, req->ssid.data.len, WLAN_BSSID_LEN); memcpy(req->ssid.data.data, item->ssid.data, req->ssid.data.len); /* supported rates */ -- cgit v1.2.3-70-g09d2 From 586b9839273b3b58b28a26e4518be13366cecaeb Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 9 Jan 2012 15:48:19 +0000 Subject: staging: comedi: ni_pcimio: Add support for NI PXIe-6251 Paul Fulmek reports that PXIe-6251 works the same as the existing PCIe-6251 and just needs the new PCI device ID adding to ni_pci_table[] and a new entry adding to ni_boards[] based on the existing entry for PCIe-6251. The new entry has PCI device ID 0x72e8 and board name "pxie-6251". Thanks Paul! Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_pcimio.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index 0f0d995f137..27baefa32b1 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -29,14 +29,15 @@ Devices: [National Instruments] PCI-MIO-16XE-50 (ni_pcimio), PCI-MIO-16XE-10, PXI-6030E, PCI-MIO-16E-1, PCI-MIO-16E-4, PCI-6014, PCI-6040E, PXI-6040E, PCI-6030E, PCI-6031E, PCI-6032E, PCI-6033E, PCI-6071E, PCI-6023E, PCI-6024E, PCI-6025E, PXI-6025E, PCI-6034E, PCI-6035E, PCI-6052E, - PCI-6110, PCI-6111, PCI-6220, PCI-6221, PCI-6224, PXI-6224, PCI-6225, PXI-6225, - PCI-6229, PCI-6250, PCI-6251, PCIe-6251, PCI-6254, PCI-6259, PCIe-6259, + PCI-6110, PCI-6111, PCI-6220, PCI-6221, PCI-6224, PXI-6224, + PCI-6225, PXI-6225, PCI-6229, PCI-6250, PCI-6251, PCIe-6251, PXIe-6251, + PCI-6254, PCI-6259, PCIe-6259, PCI-6280, PCI-6281, PXI-6281, PCI-6284, PCI-6289, PCI-6711, PXI-6711, PCI-6713, PXI-6713, PXI-6071E, PCI-6070E, PXI-6070E, PXI-6052E, PCI-6036E, PCI-6731, PCI-6733, PXI-6733, PCI-6143, PXI-6143 -Updated: Wed, 03 Dec 2008 10:51:47 +0000 +Updated: Mon, 09 Jan 2012 14:52:48 +0000 These boards are almost identical to the AT-MIO E series, except that they use the PCI bus instead of ISA (i.e., AT). See the notes for @@ -182,6 +183,7 @@ static DEFINE_PCI_DEVICE_TABLE(ni_pci_table) = { {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)}, {0} }; @@ -1045,6 +1047,25 @@ static const struct ni_board_struct ni_boards[] = { .caldac = {caldac_none}, .has_8255 = 0, }, + { + .device_id = 0x72e8, + .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 = 357, + .num_p0_dio_channels = 8, + .caldac = {caldac_none}, + .has_8255 = 0, + }, { .device_id = 0x70b7, .name = "pci-6254", -- cgit v1.2.3-70-g09d2 From 8383def69b8629df052f917acb844381bdd6e000 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 9 Jan 2012 15:48:35 +0000 Subject: staging: comedi: dt2801: do INSN_CONFIG properly for DIO subdevice. Handle INSN_CONFIG_DIO_INPUT, INSN_CONFIG_DIO_OUTPUT and INSN_CONFIG_DIO_QUERY in data[0]. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt2801.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c index 5cce1b5f448..b85c8366a39 100644 --- a/drivers/staging/comedi/drivers/dt2801.c +++ b/drivers/staging/comedi/drivers/dt2801.c @@ -720,12 +720,20 @@ static int dt2801_dio_insn_config(struct comedi_device *dev, which = 1; /* configure */ - if (data[0]) { + switch (data[0]) { + case INSN_CONFIG_DIO_OUTPUT: s->io_bits = 0xff; dt2801_writecmd(dev, DT_C_SET_DIGOUT); - } else { + break; + case INSN_CONFIG_DIO_INPUT: s->io_bits = 0; dt2801_writecmd(dev, DT_C_SET_DIGIN); + break; + case INSN_CONFIG_DIO_QUERY: + data[1] = s->io_bits ? COMEDI_OUTPUT : COMEDI_INPUT; + return insn->n; + default: + return -EINVAL; } dt2801_writedata(dev, which); -- cgit v1.2.3-70-g09d2 From f3445c1e5915bc554da1ee524b17c5d59e921ebc Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 9 Jan 2012 15:48:56 +0000 Subject: staging: comedi: me4000: Check for unsupported INSN_CONFIG. The INSN_CONFIG handler for the DIO subdevice should error out for unsupported configuration instruction codes. Also fix incorrect use of constant COMEDI_OUTPUT where INSN_CONFIG_DIO_OUTPUT was meant. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me4000.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index b692fea0d2b..b0bc6bb877a 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -2098,23 +2098,29 @@ static int me4000_dio_insn_config(struct comedi_device *dev, CALL_PDEBUG("In me4000_dio_insn_config()\n"); - if (data[0] == INSN_CONFIG_DIO_QUERY) { + switch (data[0]) { + default: + return -EINVAL; + case INSN_CONFIG_DIO_QUERY: data[1] = (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT; return insn->n; + case INSN_CONFIG_DIO_INPUT: + case INSN_CONFIG_DIO_OUTPUT: + break; } /* * The input or output configuration of each digital line is * configured by a special insn_config instruction. chanspec * contains the channel to be changed, and data[0] contains the - * value COMEDI_INPUT or COMEDI_OUTPUT. + * value INSN_CONFIG_DIO_INPUT or INSN_CONFIG_DIO_OUTPUT. * On the ME-4000 it is only possible to switch port wise (8 bit) */ tmp = me4000_inl(dev, info->dio_context.ctrl_reg); - if (data[0] == COMEDI_OUTPUT) { + if (data[0] == INSN_CONFIG_DIO_OUTPUT) { if (chan < 8) { s->io_bits |= 0xFF; tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 | -- cgit v1.2.3-70-g09d2 From 9e77e6b62e699fe23a4648ac438115c5fc952e42 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 9 Jan 2012 15:45:45 +0000 Subject: staging: comedi: adv_pci_dio: Advantech PCI-1739U support This patch is ported over by me (Ian Abbott) from the out-of-tree Comedi git repository at "git://comedi.org/git/comedi/comedi.git". The original patch is by Nicholas Nell. ----- Advantech PCI-1739U support Hello, I've added a bit of simple configuration to adv_pci_dio.c in order to make the PCI-1739U work with the adv_pci_dio driver. I have tested inputs only so far but they seem to work. A git style patch is attached. Thanks, -- Nicholas Nell Professional Research Assistant University of Colorado ----- Signed-off-by: Ian Abbott Cc: Nico Nell Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 5 +++-- drivers/staging/comedi/drivers/adv_pci_dio.c | 29 ++++++++++++++++++++++++---- 2 files changed, 28 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 4c77e508066..12c691d9090 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -765,8 +765,9 @@ config COMEDI_ADV_PCI_DIO default N ---help--- Enable support for Advantech PCI DIO cards - PCI-1730, PCI-1733, PCI-1734, PCI-1736UP, PCI-1750, PCI-1751, - PCI-1752, PCI-1753/E, PCI-1754, PCI-1756 and PCI-1762 + PCI-1730, PCI-1733, PCI-1734, PCI-1735U, PCI-1736UP, PCI-1739U, + PCI-1750, PCI-1751, PCI-1752, PCI-1753/E, PCI-1754, PCI-1756, + PCI-1760 and PCI-1762 To compile this driver as a module, choose M here: the module will be called adv_pci_dio. diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 537e5853427..7af068f4a74 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -8,16 +8,16 @@ /* Driver: adv_pci_dio Description: Advantech PCI-1730, PCI-1733, PCI-1734, PCI-1735U, - PCI-1736UP, PCI-1750, PCI-1751, PCI-1752, PCI-1753/E, - PCI-1754, PCI-1756, PCI-1762 + PCI-1736UP, PCI-1739U, PCI-1750, PCI-1751, PCI-1752, + PCI-1753/E, PCI-1754, PCI-1756, PCI-1760, PCI-1762 Author: Michal Dobes Devices: [Advantech] PCI-1730 (adv_pci_dio), PCI-1733, - PCI-1734, PCI-1735U, PCI-1736UP, PCI-1750, + PCI-1734, PCI-1735U, PCI-1736UP, PCI-1739U, PCI-1750, PCI-1751, PCI-1752, PCI-1753, PCI-1753+PCI-1753E, PCI-1754, PCI-1756, PCI-1760, PCI-1762 Status: untested -Updated: Tue, 04 May 2010 13:00:00 +0000 +Updated: Mon, 09 Jan 2012 12:40:46 +0000 This driver supports now only insn interface for DI/DO/DIO. @@ -51,6 +51,7 @@ Configuration options: /* hardware types of the cards */ enum hw_cards_id { TYPE_PCI1730, TYPE_PCI1733, TYPE_PCI1734, TYPE_PCI1735, TYPE_PCI1736, + TYPE_PCI1739, TYPE_PCI1750, TYPE_PCI1751, TYPE_PCI1752, @@ -109,6 +110,12 @@ enum hw_io_access { #define PCI1736_BOARDID 4 /* R: Board I/D switch for 1736UP */ #define PCI1736_MAINREG 0 /* Normal register (2) doesn't work */ +/* Advantech PCI-1739U */ +#define PCI1739_DIO 0 /* R/W: begin of 8255 registers block */ +#define PCI1739_ICR 32 /* W: Interrupt control register */ +#define PCI1739_ISR 32 /* R: Interrupt status register */ +#define PCI1739_BOARDID 8 /* R: Board I/D switch for 1739U */ + /* Advantech PCI-1750 */ #define PCI1750_IDI 0 /* R: Isolated digital input 0-15 */ #define PCI1750_IDO 0 /* W: Isolated digital output 0-15 */ @@ -262,6 +269,7 @@ static DEFINE_PCI_DEVICE_TABLE(pci_dio_pci_table) = { { 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) }, @@ -316,6 +324,14 @@ static const struct dio_boardtype boardtypes[] = { {4, PCI1736_BOARDID, 1, SDF_INTERNAL}, { {0, 0, 0, 0} }, IO_8b}, + {"pci1739", PCI_VENDOR_ID_ADVANTECH, 0x1739, PCIDIO_MAINREG, + TYPE_PCI1739, + { {0, 0, 0, 0}, {0, 0, 0, 0} }, + { {0, 0, 0, 0}, {0, 0, 0, 0} }, + { {48, PCI1739_DIO, 2, 0}, {0, 0, 0, 0} }, + {0, 0, 0, 0}, + { {0, 0, 0, 0} }, + IO_8b}, {"pci1750", PCI_VENDOR_ID_ADVANTECH, 0x1750, PCIDIO_MAINREG, TYPE_PCI1750, { {0, 0, 0, 0}, {16, PCI1750_IDI, 2, 0} }, @@ -883,6 +899,11 @@ static int pci_dio_reset(struct comedi_device *dev) outb(0, dev->iobase + PCI1736_3_INT_RF); break; + case TYPE_PCI1739: + /* disable & clear interrupts */ + outb(0x88, dev->iobase + PCI1739_ICR); + break; + case TYPE_PCI1750: case TYPE_PCI1751: /* disable & clear interrupts */ -- cgit v1.2.3-70-g09d2 From 41add2e84bff0c887949698e01dab28105f11a6b Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 9 Jan 2012 15:47:30 +0000 Subject: staging: comedi: ni_pcidio: Mark buffer for writing when setting up DMA. When setting up the DMA for 'read' streaming acquisition on the DIO subdevice, mark the whole buffer as writable before starting the DMA. This prevents a spurious detection of a DMA overwrite of good data during the first interrupt. Problem reported by Nicholas Nell. Fix suggested by Frank Mori Hess. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_pcidio.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 045a4c00f34..c9e5f2b2dfb 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -1012,6 +1012,9 @@ static int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->di_mite_chan->dir = COMEDI_INPUT; + /* write alloc the entire buffer */ + comedi_buf_write_alloc(s->async, s->async->prealloc_bufsz); + mite_prep_dma(devpriv->di_mite_chan, 32, 32); mite_dma_arm(devpriv->di_mite_chan); -- cgit v1.2.3-70-g09d2 From e3794b52f56ac20947a2dbdd505e9ad29013c555 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 9 Jan 2012 15:47:31 +0000 Subject: staging: comedi: ni_pcidio: Grab MITE spinlock while preparing DMA. When setting up the DMA for 'read' streaming acquisition command, grab the MITE channel spinlock before preparing and arming the DMA. Change inspired by ni_ai_setup_MITE_dma() in ni_mio_common.c. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_pcidio.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index c9e5f2b2dfb..5145bf129c8 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -436,6 +436,7 @@ static int ni_pcidio_request_di_mite_channel(struct comedi_device *dev) comedi_error(dev, "failed to reserve mite dma channel."); return -EBUSY; } + devpriv->di_mite_chan->dir = COMEDI_INPUT; writeb(primary_DMAChannel_bits(devpriv->di_mite_chan->channel) | secondary_DMAChannel_bits(devpriv->di_mite_chan->channel), devpriv->mite->daq_io_addr + DMA_Line_Control_Group1); @@ -1005,20 +1006,24 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s) { int retval; + unsigned long flags; retval = ni_pcidio_request_di_mite_channel(dev); if (retval) return retval; - devpriv->di_mite_chan->dir = COMEDI_INPUT; - /* write alloc the entire buffer */ comedi_buf_write_alloc(s->async, s->async->prealloc_bufsz); - mite_prep_dma(devpriv->di_mite_chan, 32, 32); + spin_lock_irqsave(&devpriv->mite_channel_lock, flags); + if (devpriv->di_mite_chan) { + mite_prep_dma(devpriv->di_mite_chan, 32, 32); + mite_dma_arm(devpriv->di_mite_chan); + } else + retval = -EIO; + spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); - mite_dma_arm(devpriv->di_mite_chan); - return 0; + return retval; } static int ni_pcidio_inttrig(struct comedi_device *dev, -- cgit v1.2.3-70-g09d2 From 02f69d67684b77f7f04e281a026a790f0e08b3a3 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 9 Jan 2012 18:35:53 +0000 Subject: staging: comedi: ni_pcidio: Add comedi_poll support This patch is ported over by me (Ian Abbott) from the out-of-tree Comedi git repository at "git://comedi.org/git/comedi/comedi.git". The original patch is by Nicholas Nell. The patch adds support for the COMEDI_POLL ioctl to the ni_pcidio driver. Signed-off-by: Ian Abbott Cc: Nicholas Nell Cc: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_pcidio.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 5145bf129c8..88728bdf2c6 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -483,6 +483,21 @@ void ni_pcidio_event(struct comedi_device *dev, struct comedi_subdevice *s) comedi_event(dev, s); } +static int ni_pcidio_poll(struct comedi_device *dev, struct comedi_subdevice *s) +{ + unsigned long irq_flags; + int count; + + spin_lock_irqsave(&dev->spinlock, irq_flags); + spin_lock(&devpriv->mite_channel_lock); + if (devpriv->di_mite_chan) + mite_sync_input_dma(devpriv->di_mite_chan, s->async); + spin_unlock(&devpriv->mite_channel_lock); + count = s->async->buf_write_count - s->async->buf_read_count; + spin_unlock_irqrestore(&dev->spinlock, irq_flags); + return count; +} + static irqreturn_t nidio_interrupt(int irq, void *d) { struct comedi_device *dev = d; @@ -498,7 +513,6 @@ static irqreturn_t nidio_interrupt(int irq, void *d) int status; int work = 0; unsigned int m_status = 0; - unsigned long irq_flags; /* interrupcions parasites */ if (dev->attached == 0) { @@ -506,6 +520,9 @@ static irqreturn_t nidio_interrupt(int irq, void *d) return IRQ_NONE; } + /* Lock to avoid race with comedi_poll */ + spin_lock(&dev->spinlock); + status = readb(devpriv->mite->daq_io_addr + Interrupt_And_Window_Status); flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags); @@ -519,7 +536,7 @@ static irqreturn_t nidio_interrupt(int irq, void *d) /* printk("buf[4096]=%08x\n", *(unsigned int *)(async->prealloc_buf+4096)); */ - spin_lock_irqsave(&devpriv->mite_channel_lock, irq_flags); + spin_lock(&devpriv->mite_channel_lock); if (devpriv->di_mite_chan) m_status = mite_get_status(devpriv->di_mite_chan); #ifdef MITE_DEBUG @@ -544,7 +561,7 @@ static irqreturn_t nidio_interrupt(int irq, void *d) disable_irq(dev->irq); } } - spin_unlock_irqrestore(&devpriv->mite_channel_lock, irq_flags); + spin_unlock(&devpriv->mite_channel_lock); while (status & DataLeft) { work++; @@ -646,6 +663,8 @@ out: Master_DMA_And_Interrupt_Control); } #endif + + spin_unlock(&dev->spinlock); return IRQ_HANDLED; } @@ -1252,6 +1271,7 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->len_chanlist = 32; /* XXX */ s->buf_change = &ni_pcidio_change; s->async_dma_dir = DMA_BIDIRECTIONAL; + s->poll = &ni_pcidio_poll; writel(0, devpriv->mite->daq_io_addr + Port_IO(0)); writel(0, devpriv->mite->daq_io_addr + Port_Pin_Directions(0)); -- cgit v1.2.3-70-g09d2 From 22494ed9b8e9404d6646f85c835bcd7b37d3f562 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 9 Jan 2012 15:47:33 +0000 Subject: staging: comedi: ni_pcidio: Support trailing edge external trigger This patch is ported over by me (Ian Abbott) from the out-of-tree Comedi git repository at "git://comedi.org/git/comedi/comedi.git". The original patch is by Nicholas Nell. The patch adds support for trailing (falling) edge external triggers for scans in asynchronous command support in the ni_pcidio driver. This is supported at least on the PCI-DIO_32HS and PCI-6533 boards; not sure about the other boards. Signed-off-by: Ian Abbott Cc: Nicholas Nell Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_pcidio.c | 19 +++++++++++++++---- 1 file changed, 15 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 88728bdf2c6..1df8fcbcd10 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -30,7 +30,7 @@ Status: works Devices: [National Instruments] PCI-DIO-32HS (ni_pcidio), PXI-6533, PCI-DIO-96, PCI-DIO-96B, PXI-6508, PCI-6503, PCI-6503B, PCI-6503X, PXI-6503, PCI-6533, PCI-6534 -Updated: Sun, 21 Apr 2002 21:03:38 -0700 +Updated: Mon, 09 Jan 2012 14:27:23 +0000 The DIO-96 appears as four 8255 subdevices. See the 8255 driver notes for details. @@ -42,6 +42,11 @@ supports simple digital I/O; no handshaking is supported. DMA mostly works for the PCI-DIO32HS, but only in timed input mode. +The PCI-DIO-32HS/PCI-6533 has a configurable external trigger. Setting +scan_begin_arg to 0 or CR_EDGE triggers on the leading edge. Setting +scan_begin_arg to CR_INVERT or (CR_EDGE | CR_INVERT) triggers on the +trailing edge. + This driver could be easily modified to support AT-MIO32HS and AT-MIO96. @@ -845,8 +850,8 @@ static int ni_pcidio_cmdtest(struct comedi_device *dev, } else { /* TRIG_EXT */ /* should be level/edge, hi/lo specification here */ - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; + if ((cmd->scan_begin_arg & ~(CR_EDGE | CR_INVERT)) != 0) { + cmd->scan_begin_arg &= (CR_EDGE | CR_INVERT); err++; } } @@ -961,7 +966,13 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) writeb(0, devpriv->mite->daq_io_addr + Sequence); writeb(0x00, devpriv->mite->daq_io_addr + ReqReg); writeb(4, devpriv->mite->daq_io_addr + BlockMode); - writeb(0, devpriv->mite->daq_io_addr + LinePolarities); + if (!(cmd->scan_begin_arg & CR_INVERT)) { + /* Leading Edge pulse mode */ + writeb(0, devpriv->mite->daq_io_addr + LinePolarities); + } else { + /* Trailing Edge pulse mode */ + writeb(2, devpriv->mite->daq_io_addr + LinePolarities); + } writeb(0x00, devpriv->mite->daq_io_addr + AckSer); writel(1, devpriv->mite->daq_io_addr + StartDelay); writeb(1, devpriv->mite->daq_io_addr + ReqDelay); -- cgit v1.2.3-70-g09d2 From cba2c99363beb532c29f9aebf5b22878d88bcb93 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 17 Jan 2012 10:31:13 +0300 Subject: Staging: comedi: logical || vs bitwise | These are bitfields and the intend was to OR them together. A logical OR here is simply 1. Signed-off-by: Dan Carpenter Acked-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt9812.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c index 32d9c42e965..e86ab586289 100644 --- a/drivers/staging/comedi/drivers/dt9812.c +++ b/drivers/staging/comedi/drivers/dt9812.c @@ -527,7 +527,7 @@ static void dt9812_configure_gain(struct usb_dt9812 *dev, * 11x -> Gain = 0.5 */ case DT9812_GAIN_0PT5: - rmw->or_value = F020_MASK_ADC0CF_AMP0GN2 || + rmw->or_value = F020_MASK_ADC0CF_AMP0GN2 | F020_MASK_ADC0CF_AMP0GN1; break; case DT9812_GAIN_1: @@ -540,7 +540,7 @@ static void dt9812_configure_gain(struct usb_dt9812 *dev, rmw->or_value = F020_MASK_ADC0CF_AMP0GN1; break; case DT9812_GAIN_8: - rmw->or_value = F020_MASK_ADC0CF_AMP0GN1 || + rmw->or_value = F020_MASK_ADC0CF_AMP0GN1 | F020_MASK_ADC0CF_AMP0GN0; break; case DT9812_GAIN_16: -- cgit v1.2.3-70-g09d2 From 4ee195241a3d9384ad222da7c593f7565a7cf518 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Thu, 22 Dec 2011 18:44:43 -0800 Subject: staging:iio: isl29018: add of_match table for device-tree probing As simple as can be right now; just one ID and no custom properties to parse. Signed-off-by: Olof Johansson Acked-by: Grant Likely Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/light/isl29018.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c index 849d6a564af..38ec52b65df 100644 --- a/drivers/staging/iio/light/isl29018.c +++ b/drivers/staging/iio/light/isl29018.c @@ -592,11 +592,18 @@ static const struct i2c_device_id isl29018_id[] = { MODULE_DEVICE_TABLE(i2c, isl29018_id); +static const struct of_device_id isl29018_of_match[] = { + { .compatible = "invn,isl29018", }, + { }, +}; +MODULE_DEVICE_TABLE(of, isl29018_of_match); + static struct i2c_driver isl29018_driver = { .class = I2C_CLASS_HWMON, .driver = { .name = "isl29018", .owner = THIS_MODULE, + .of_match_table = isl29018_of_match, }, .probe = isl29018_probe, .remove = __devexit_p(isl29018_remove), -- cgit v1.2.3-70-g09d2 From 54461c3067b2dce5947c9e4f88a8d905dca2c0c9 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Thu, 22 Dec 2011 18:46:42 -0800 Subject: staging:iio: ak8975: add of_match table for device-tree probing Just like isl29018; trivial addition. Using both asahi-kasei,ak8975 and the non-prefixed version (I couldn't figure out if Asahi Kasei had a stock symbol to use, I only found numerical indexes for their stock info). Signed-off-by: Olof Johansson Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/magnetometer/ak8975.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/iio/magnetometer/ak8975.c b/drivers/staging/iio/magnetometer/ak8975.c index 3158f12cb05..d5ddac3d883 100644 --- a/drivers/staging/iio/magnetometer/ak8975.c +++ b/drivers/staging/iio/magnetometer/ak8975.c @@ -564,9 +564,17 @@ static const struct i2c_device_id ak8975_id[] = { MODULE_DEVICE_TABLE(i2c, ak8975_id); +static const struct of_device_id ak8975_of_match[] = { + { .compatible = "asahi-kasei,ak8975", }, + { .compatible = "ak8975", }, + { } +}; +MODULE_DEVICE_TABLE(of, ak8975_of_match); + static struct i2c_driver ak8975_driver = { .driver = { .name = "ak8975", + .of_match_table = ak8975_of_match, }, .probe = ak8975_probe, .remove = __devexit_p(ak8975_remove), -- cgit v1.2.3-70-g09d2 From 7e632344adfe749749aa525f6fbe0ffc05ae3190 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 3 Jan 2012 11:02:51 +0100 Subject: staging:iio: Setup buffer access functions when allocating the buffer Setup the buffer access functions in the buffer allocate function. There is no need to let each driver handle this on its own. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/adis16201_ring.c | 2 -- drivers/staging/iio/accel/adis16203_ring.c | 2 -- drivers/staging/iio/accel/adis16204_ring.c | 2 -- drivers/staging/iio/accel/adis16209_ring.c | 2 -- drivers/staging/iio/accel/adis16240_ring.c | 2 -- drivers/staging/iio/accel/lis3l02dq.h | 2 -- drivers/staging/iio/accel/lis3l02dq_ring.c | 2 -- drivers/staging/iio/adc/ad7192.c | 2 -- drivers/staging/iio/adc/ad7298_ring.c | 3 -- drivers/staging/iio/adc/ad7476_ring.c | 2 -- drivers/staging/iio/adc/ad7606_ring.c | 2 -- drivers/staging/iio/adc/ad7793.c | 2 -- drivers/staging/iio/adc/ad7887_ring.c | 2 -- drivers/staging/iio/adc/ad799x_ring.c | 2 -- drivers/staging/iio/adc/max1363_ring.c | 2 -- drivers/staging/iio/gyro/adis16260_ring.c | 2 -- drivers/staging/iio/iio_simple_dummy_buffer.c | 2 -- drivers/staging/iio/impedance-analyzer/ad5933.c | 3 -- drivers/staging/iio/imu/adis16400_ring.c | 2 -- drivers/staging/iio/kfifo_buf.c | 46 ++++++++++++------------- drivers/staging/iio/kfifo_buf.h | 2 -- drivers/staging/iio/meter/ade7758_ring.c | 2 -- drivers/staging/iio/ring_sw.c | 22 ++++++------ drivers/staging/iio/ring_sw.h | 5 --- 24 files changed, 34 insertions(+), 83 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/accel/adis16201_ring.c b/drivers/staging/iio/accel/adis16201_ring.c index 26c610faee3..97f9e6b159d 100644 --- a/drivers/staging/iio/accel/adis16201_ring.c +++ b/drivers/staging/iio/accel/adis16201_ring.c @@ -115,9 +115,7 @@ int adis16201_configure_ring(struct iio_dev *indio_dev) return ret; } indio_dev->buffer = ring; - /* Effectively select the ring buffer implementation */ ring->scan_timestamp = true; - ring->access = &ring_sw_access_funcs; indio_dev->setup_ops = &adis16201_ring_setup_ops; indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, diff --git a/drivers/staging/iio/accel/adis16203_ring.c b/drivers/staging/iio/accel/adis16203_ring.c index 064640d15e4..6a8963db4f6 100644 --- a/drivers/staging/iio/accel/adis16203_ring.c +++ b/drivers/staging/iio/accel/adis16203_ring.c @@ -117,9 +117,7 @@ int adis16203_configure_ring(struct iio_dev *indio_dev) return ret; } indio_dev->buffer = ring; - /* Effectively select the ring buffer implementation */ ring->scan_timestamp = true; - ring->access = &ring_sw_access_funcs; indio_dev->setup_ops = &adis16203_ring_setup_ops; indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, diff --git a/drivers/staging/iio/accel/adis16204_ring.c b/drivers/staging/iio/accel/adis16204_ring.c index 4081179dfa5..5c8ab733886 100644 --- a/drivers/staging/iio/accel/adis16204_ring.c +++ b/drivers/staging/iio/accel/adis16204_ring.c @@ -112,8 +112,6 @@ int adis16204_configure_ring(struct iio_dev *indio_dev) return ret; } indio_dev->buffer = ring; - /* Effectively select the ring buffer implementation */ - ring->access = &ring_sw_access_funcs; ring->scan_timestamp = true; indio_dev->setup_ops = &adis16204_ring_setup_ops; diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c index 2a6fd334f5f..57254b6b38b 100644 --- a/drivers/staging/iio/accel/adis16209_ring.c +++ b/drivers/staging/iio/accel/adis16209_ring.c @@ -113,8 +113,6 @@ int adis16209_configure_ring(struct iio_dev *indio_dev) return ret; } indio_dev->buffer = ring; - /* Effectively select the ring buffer implementation */ - ring->access = &ring_sw_access_funcs; ring->scan_timestamp = true; indio_dev->setup_ops = &adis16209_ring_setup_ops; diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c index e23622d96f9..43ba84e993a 100644 --- a/drivers/staging/iio/accel/adis16240_ring.c +++ b/drivers/staging/iio/accel/adis16240_ring.c @@ -110,8 +110,6 @@ int adis16240_configure_ring(struct iio_dev *indio_dev) return ret; } indio_dev->buffer = ring; - /* Effectively select the ring buffer implementation */ - ring->access = &ring_sw_access_funcs; ring->scan_timestamp = true; indio_dev->setup_ops = &adis16240_ring_setup_ops; diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h index 2db383fc274..ae5f225b4bb 100644 --- a/drivers/staging/iio/accel/lis3l02dq.h +++ b/drivers/staging/iio/accel/lis3l02dq.h @@ -187,12 +187,10 @@ void lis3l02dq_unconfigure_buffer(struct iio_dev *indio_dev); #ifdef CONFIG_LIS3L02DQ_BUF_RING_SW #define lis3l02dq_free_buf iio_sw_rb_free #define lis3l02dq_alloc_buf iio_sw_rb_allocate -#define lis3l02dq_access_funcs ring_sw_access_funcs #endif #ifdef CONFIG_LIS3L02DQ_BUF_KFIFO #define lis3l02dq_free_buf iio_kfifo_free #define lis3l02dq_alloc_buf iio_kfifo_allocate -#define lis3l02dq_access_funcs kfifo_access_funcs #endif irqreturn_t lis3l02dq_data_rdy_trig_poll(int irq, void *private); #define lis3l02dq_th lis3l02dq_data_rdy_trig_poll diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index 98c5c92d345..ca0a1fe6ff3 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -406,8 +406,6 @@ int lis3l02dq_configure_buffer(struct iio_dev *indio_dev) return -ENOMEM; indio_dev->buffer = buffer; - /* Effectively select the buffer implementation */ - indio_dev->buffer->access = &lis3l02dq_access_funcs; buffer->scan_timestamp = true; indio_dev->setup_ops = &lis3l02dq_buffer_setup_ops; diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index 45f4504ed92..9d251653307 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -561,8 +561,6 @@ static int ad7192_register_ring_funcs_and_init(struct iio_dev *indio_dev) ret = -ENOMEM; goto error_ret; } - /* Effectively select the ring buffer implementation */ - indio_dev->buffer->access = &ring_sw_access_funcs; indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, &ad7192_trigger_handler, IRQF_ONESHOT, diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c index d1a12dd015e..feeb0eeba59 100644 --- a/drivers/staging/iio/adc/ad7298_ring.c +++ b/drivers/staging/iio/adc/ad7298_ring.c @@ -131,9 +131,6 @@ int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev) ret = -ENOMEM; goto error_ret; } - /* Effectively select the ring buffer implementation */ - indio_dev->buffer->access = &ring_sw_access_funcs; - indio_dev->pollfunc = iio_alloc_pollfunc(NULL, &ad7298_trigger_handler, IRQF_ONESHOT, diff --git a/drivers/staging/iio/adc/ad7476_ring.c b/drivers/staging/iio/adc/ad7476_ring.c index 4e298b2a05b..35a8576a227 100644 --- a/drivers/staging/iio/adc/ad7476_ring.c +++ b/drivers/staging/iio/adc/ad7476_ring.c @@ -98,8 +98,6 @@ int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev) ret = -ENOMEM; goto error_ret; } - /* Effectively select the ring buffer implementation */ - indio_dev->buffer->access = &ring_sw_access_funcs; indio_dev->pollfunc = iio_alloc_pollfunc(NULL, &ad7476_trigger_handler, diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c index e8f94a18a94..1ef9fbcaf2d 100644 --- a/drivers/staging/iio/adc/ad7606_ring.c +++ b/drivers/staging/iio/adc/ad7606_ring.c @@ -110,8 +110,6 @@ int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev) goto error_ret; } - /* Effectively select the ring buffer implementation */ - indio_dev->buffer->access = &ring_sw_access_funcs; indio_dev->pollfunc = iio_alloc_pollfunc(&ad7606_trigger_handler_th_bh, &ad7606_trigger_handler_th_bh, 0, diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c index 6a058b19c49..84ecde1ad04 100644 --- a/drivers/staging/iio/adc/ad7793.c +++ b/drivers/staging/iio/adc/ad7793.c @@ -427,8 +427,6 @@ static int ad7793_register_ring_funcs_and_init(struct iio_dev *indio_dev) ret = -ENOMEM; goto error_ret; } - /* Effectively select the ring buffer implementation */ - indio_dev->buffer->access = &ring_sw_access_funcs; indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, &ad7793_trigger_handler, IRQF_ONESHOT, diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c index 85076cd962e..d1809079b63 100644 --- a/drivers/staging/iio/adc/ad7887_ring.c +++ b/drivers/staging/iio/adc/ad7887_ring.c @@ -131,8 +131,6 @@ int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev) ret = -ENOMEM; goto error_ret; } - /* Effectively select the ring buffer implementation */ - indio_dev->buffer->access = &ring_sw_access_funcs; indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, &ad7887_trigger_handler, IRQF_ONESHOT, diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c index 5dded9e7820..28e9a419291 100644 --- a/drivers/staging/iio/adc/ad799x_ring.c +++ b/drivers/staging/iio/adc/ad799x_ring.c @@ -141,8 +141,6 @@ int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev) ret = -ENOMEM; goto error_ret; } - /* Effectively select the ring buffer implementation */ - indio_dev->buffer->access = &ring_sw_access_funcs; indio_dev->pollfunc = iio_alloc_pollfunc(NULL, &ad799x_trigger_handler, IRQF_ONESHOT, diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c index f730b3fb971..d0a60a38293 100644 --- a/drivers/staging/iio/adc/max1363_ring.c +++ b/drivers/staging/iio/adc/max1363_ring.c @@ -116,8 +116,6 @@ int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev) ret = -ENOMEM; goto error_deallocate_sw_rb; } - /* Effectively select the ring buffer implementation */ - indio_dev->buffer->access = &ring_sw_access_funcs; /* Ring buffer functions - here trigger setup related */ indio_dev->setup_ops = &max1363_ring_setup_ops; diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c index 699a6152c40..711f15122a0 100644 --- a/drivers/staging/iio/gyro/adis16260_ring.c +++ b/drivers/staging/iio/gyro/adis16260_ring.c @@ -115,8 +115,6 @@ int adis16260_configure_ring(struct iio_dev *indio_dev) return ret; } indio_dev->buffer = ring; - /* Effectively select the ring buffer implementation */ - ring->access = &ring_sw_access_funcs; ring->scan_timestamp = true; indio_dev->setup_ops = &adis16260_ring_setup_ops; diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c index d6a1c0e82a5..bb4daf74436 100644 --- a/drivers/staging/iio/iio_simple_dummy_buffer.c +++ b/drivers/staging/iio/iio_simple_dummy_buffer.c @@ -142,8 +142,6 @@ int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev) } indio_dev->buffer = buffer; - /* Tell the core how to access the buffer */ - buffer->access = &kfifo_access_funcs; /* Enable timestamps by default */ buffer->scan_timestamp = true; diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index 9a2ca55625f..cd82b56d58a 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -607,9 +607,6 @@ static int ad5933_register_ring_funcs_and_init(struct iio_dev *indio_dev) if (!indio_dev->buffer) return -ENOMEM; - /* Effectively select the ring buffer implementation */ - indio_dev->buffer->access = &ring_sw_access_funcs; - /* Ring buffer functions - here trigger setup related */ indio_dev->setup_ops = &ad5933_ring_setup_ops; diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c index ac22de573f3..8daa038b23e 100644 --- a/drivers/staging/iio/imu/adis16400_ring.c +++ b/drivers/staging/iio/imu/adis16400_ring.c @@ -187,8 +187,6 @@ int adis16400_configure_ring(struct iio_dev *indio_dev) return ret; } indio_dev->buffer = ring; - /* Effectively select the ring buffer implementation */ - ring->access = &ring_sw_access_funcs; ring->scan_timestamp = true; indio_dev->setup_ops = &adis16400_ring_setup_ops; diff --git a/drivers/staging/iio/kfifo_buf.c b/drivers/staging/iio/kfifo_buf.c index e1e9c06cde4..9f3bd59c0e7 100644 --- a/drivers/staging/iio/kfifo_buf.c +++ b/drivers/staging/iio/kfifo_buf.c @@ -59,21 +59,6 @@ static struct attribute_group iio_kfifo_attribute_group = { .name = "buffer", }; -struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev) -{ - struct iio_kfifo *kf; - - kf = kzalloc(sizeof *kf, GFP_KERNEL); - if (!kf) - return NULL; - kf->update_needed = true; - iio_buffer_init(&kf->buffer); - kf->buffer.attrs = &iio_kfifo_attribute_group; - - return &kf->buffer; -} -EXPORT_SYMBOL(iio_kfifo_allocate); - static int iio_get_bytes_per_datum_kfifo(struct iio_buffer *r) { return r->bytes_per_datum; @@ -104,12 +89,6 @@ static int iio_set_length_kfifo(struct iio_buffer *r, int length) return 0; } -void iio_kfifo_free(struct iio_buffer *r) -{ - kfree(iio_to_kfifo(r)); -} -EXPORT_SYMBOL(iio_kfifo_free); - static int iio_store_to_kfifo(struct iio_buffer *r, u8 *data, s64 timestamp) @@ -137,7 +116,7 @@ static int iio_read_first_n_kfifo(struct iio_buffer *r, return copied; } -const struct iio_buffer_access_funcs kfifo_access_funcs = { +static const struct iio_buffer_access_funcs kfifo_access_funcs = { .store_to = &iio_store_to_kfifo, .read_first_n = &iio_read_first_n_kfifo, .request_update = &iio_request_update_kfifo, @@ -146,6 +125,27 @@ const struct iio_buffer_access_funcs kfifo_access_funcs = { .get_length = &iio_get_length_kfifo, .set_length = &iio_set_length_kfifo, }; -EXPORT_SYMBOL(kfifo_access_funcs); + +struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev) +{ + struct iio_kfifo *kf; + + kf = kzalloc(sizeof *kf, GFP_KERNEL); + if (!kf) + return NULL; + kf->update_needed = true; + iio_buffer_init(&kf->buffer); + kf->buffer.attrs = &iio_kfifo_attribute_group; + kf->buffer.access = &kfifo_access_funcs; + + return &kf->buffer; +} +EXPORT_SYMBOL(iio_kfifo_allocate); + +void iio_kfifo_free(struct iio_buffer *r) +{ + kfree(iio_to_kfifo(r)); +} +EXPORT_SYMBOL(iio_kfifo_free); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/iio/kfifo_buf.h b/drivers/staging/iio/kfifo_buf.h index cc2bd9a1ccf..9f7da016af0 100644 --- a/drivers/staging/iio/kfifo_buf.h +++ b/drivers/staging/iio/kfifo_buf.h @@ -3,8 +3,6 @@ #include "iio.h" #include "buffer.h" -extern const struct iio_buffer_access_funcs kfifo_access_funcs; - struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev); void iio_kfifo_free(struct iio_buffer *r); diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c index f29f2b278fe..c5c522bb69a 100644 --- a/drivers/staging/iio/meter/ade7758_ring.c +++ b/drivers/staging/iio/meter/ade7758_ring.c @@ -144,8 +144,6 @@ int ade7758_configure_ring(struct iio_dev *indio_dev) return ret; } - /* Effectively select the ring buffer implementation */ - indio_dev->buffer->access = &ring_sw_access_funcs; indio_dev->setup_ops = &ade7758_ring_setup_ops; indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c index 3e24ec45585..eeac0daf47b 100644 --- a/drivers/staging/iio/ring_sw.c +++ b/drivers/staging/iio/ring_sw.c @@ -329,6 +329,16 @@ static struct attribute_group iio_ring_attribute_group = { .name = "buffer", }; +static const struct iio_buffer_access_funcs ring_sw_access_funcs = { + .store_to = &iio_store_to_sw_rb, + .read_first_n = &iio_read_first_n_sw_rb, + .request_update = &iio_request_update_sw_rb, + .get_bytes_per_datum = &iio_get_bytes_per_datum_sw_rb, + .set_bytes_per_datum = &iio_set_bytes_per_datum_sw_rb, + .get_length = &iio_get_length_sw_rb, + .set_length = &iio_set_length_sw_rb, +}; + struct iio_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev) { struct iio_buffer *buf; @@ -341,6 +351,7 @@ struct iio_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev) buf = &ring->buf; iio_buffer_init(buf); buf->attrs = &iio_ring_attribute_group; + buf->access = &ring_sw_access_funcs; return buf; } @@ -352,16 +363,5 @@ void iio_sw_rb_free(struct iio_buffer *r) } EXPORT_SYMBOL(iio_sw_rb_free); -const struct iio_buffer_access_funcs ring_sw_access_funcs = { - .store_to = &iio_store_to_sw_rb, - .read_first_n = &iio_read_first_n_sw_rb, - .request_update = &iio_request_update_sw_rb, - .get_bytes_per_datum = &iio_get_bytes_per_datum_sw_rb, - .set_bytes_per_datum = &iio_set_bytes_per_datum_sw_rb, - .get_length = &iio_get_length_sw_rb, - .set_length = &iio_set_length_sw_rb, -}; -EXPORT_SYMBOL(ring_sw_access_funcs); - MODULE_DESCRIPTION("Industrialio I/O software ring buffer"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/iio/ring_sw.h b/drivers/staging/iio/ring_sw.h index e6a6e2c4096..7556e212236 100644 --- a/drivers/staging/iio/ring_sw.h +++ b/drivers/staging/iio/ring_sw.h @@ -25,11 +25,6 @@ #define _IIO_RING_SW_H_ #include "buffer.h" -/** - * ring_sw_access_funcs - access functions for a software ring buffer - **/ -extern const struct iio_buffer_access_funcs ring_sw_access_funcs; - struct iio_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev); void iio_sw_rb_free(struct iio_buffer *ring); #endif /* _IIO_RING_SW_H_ */ -- cgit v1.2.3-70-g09d2 From 16a39b7a9ccd81458e7e1799c1b213d1d590630c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 3 Jan 2012 14:59:37 +0100 Subject: staging:iio: Update iio_event_interface documentation The documentation for the iio_event_interface does not match the actual struct anymore. This patch removes the documentation for non-existing fields and adds documentation for missing fields. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/industrialio-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c index 19f897f3c85..580f3738d59 100644 --- a/drivers/staging/iio/industrialio-core.c +++ b/drivers/staging/iio/industrialio-core.c @@ -112,13 +112,14 @@ struct iio_detected_event_list { /** * struct iio_event_interface - chrdev interface for an event line - * @dev: device assocated with event interface * @wait: wait queue to allow blocking reads of events * @event_list_lock: mutex to protect the list of detected events * @det_events: list of detected events * @max_events: maximum number of events before new ones are dropped * @current_events: number of events in detected list + * @dev_attr_list: list of event interface sysfs attribute * @flags: file operations related flags including busy flag. + * @group: event interface sysfs attribute group */ struct iio_event_interface { wait_queue_head_t wait; -- cgit v1.2.3-70-g09d2 From 0a769a95334a8819da046f13c2ef8d8b344fc199 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 3 Jan 2012 14:59:38 +0100 Subject: staging:iio: Factor out event handling into its own file The core iio file has gotten quite cluttered over time. This patch moves the event handling code into its own file. Since the event handling code is largely independent from the core code the only code changes necessary for this are to make the moved iio_device_register_eventset, iio_device_unregister_eventset and iio_event_getfd functions non static. This has also the advantage that industrialio-core.c is now closer again to its counterpart in the outofstaging branch. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Makefile | 2 +- drivers/staging/iio/iio_core.h | 4 + drivers/staging/iio/industrialio-core.c | 459 ----------------------------- drivers/staging/iio/industrialio-event.c | 483 +++++++++++++++++++++++++++++++ 4 files changed, 488 insertions(+), 460 deletions(-) create mode 100644 drivers/staging/iio/industrialio-event.c (limited to 'drivers') diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile index 1340aead18b..657710b266b 100644 --- a/drivers/staging/iio/Makefile +++ b/drivers/staging/iio/Makefile @@ -3,7 +3,7 @@ # obj-$(CONFIG_IIO) += industrialio.o -industrialio-y := industrialio-core.o +industrialio-y := industrialio-core.o industrialio-event.o industrialio-$(CONFIG_IIO_BUFFER) += industrialio-buffer.o industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o diff --git a/drivers/staging/iio/iio_core.h b/drivers/staging/iio/iio_core.h index 107cfb1cbb0..c9dfcba0bac 100644 --- a/drivers/staging/iio/iio_core.h +++ b/drivers/staging/iio/iio_core.h @@ -49,4 +49,8 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf, #endif +int iio_device_register_eventset(struct iio_dev *indio_dev); +void iio_device_unregister_eventset(struct iio_dev *indio_dev); +int iio_event_getfd(struct iio_dev *indio_dev); + #endif diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c index 580f3738d59..e4824fe8b40 100644 --- a/drivers/staging/iio/industrialio-core.c +++ b/drivers/staging/iio/industrialio-core.c @@ -100,72 +100,6 @@ const struct iio_chan_spec return NULL; } -/** - * struct iio_detected_event_list - list element for events that have occurred - * @list: linked list header - * @ev: the event itself - */ -struct iio_detected_event_list { - struct list_head list; - struct iio_event_data ev; -}; - -/** - * struct iio_event_interface - chrdev interface for an event line - * @wait: wait queue to allow blocking reads of events - * @event_list_lock: mutex to protect the list of detected events - * @det_events: list of detected events - * @max_events: maximum number of events before new ones are dropped - * @current_events: number of events in detected list - * @dev_attr_list: list of event interface sysfs attribute - * @flags: file operations related flags including busy flag. - * @group: event interface sysfs attribute group - */ -struct iio_event_interface { - wait_queue_head_t wait; - struct mutex event_list_lock; - struct list_head det_events; - int max_events; - int current_events; - struct list_head dev_attr_list; - unsigned long flags; - struct attribute_group group; -}; - -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_detected_event_list *ev; - int ret = 0; - - /* Does anyone care? */ - mutex_lock(&ev_int->event_list_lock); - if (test_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) { - if (ev_int->current_events == ev_int->max_events) { - mutex_unlock(&ev_int->event_list_lock); - return 0; - } - ev = kmalloc(sizeof(*ev), GFP_KERNEL); - if (ev == NULL) { - ret = -ENOMEM; - mutex_unlock(&ev_int->event_list_lock); - goto error_ret; - } - ev->ev.id = ev_code; - ev->ev.timestamp = timestamp; - - list_add_tail(&ev->list, &ev_int->det_events); - ev_int->current_events++; - mutex_unlock(&ev_int->event_list_lock); - wake_up_interruptible(&ev_int->wait); - } else - mutex_unlock(&ev_int->event_list_lock); - -error_ret: - return ret; -} -EXPORT_SYMBOL(iio_push_event); - /* This turns up an awful lot */ ssize_t iio_read_const_attr(struct device *dev, struct device_attribute *attr, @@ -175,110 +109,6 @@ ssize_t iio_read_const_attr(struct device *dev, } EXPORT_SYMBOL(iio_read_const_attr); -static ssize_t iio_event_chrdev_read(struct file *filep, - char __user *buf, - size_t count, - loff_t *f_ps) -{ - struct iio_event_interface *ev_int = filep->private_data; - struct iio_detected_event_list *el; - size_t len = sizeof(el->ev); - int ret; - - if (count < len) - return -EINVAL; - - mutex_lock(&ev_int->event_list_lock); - if (list_empty(&ev_int->det_events)) { - if (filep->f_flags & O_NONBLOCK) { - ret = -EAGAIN; - goto error_mutex_unlock; - } - mutex_unlock(&ev_int->event_list_lock); - /* Blocking on device; waiting for something to be there */ - ret = wait_event_interruptible(ev_int->wait, - !list_empty(&ev_int - ->det_events)); - if (ret) - goto error_ret; - /* Single access device so no one else can get the data */ - mutex_lock(&ev_int->event_list_lock); - } - - el = list_first_entry(&ev_int->det_events, - struct iio_detected_event_list, - list); - if (copy_to_user(buf, &(el->ev), len)) { - ret = -EFAULT; - goto error_mutex_unlock; - } - list_del(&el->list); - ev_int->current_events--; - mutex_unlock(&ev_int->event_list_lock); - kfree(el); - - return len; - -error_mutex_unlock: - mutex_unlock(&ev_int->event_list_lock); -error_ret: - - return ret; -} - -static int iio_event_chrdev_release(struct inode *inode, struct file *filep) -{ - struct iio_event_interface *ev_int = filep->private_data; - struct iio_detected_event_list *el, *t; - - mutex_lock(&ev_int->event_list_lock); - clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); - /* - * In order to maintain a clean state for reopening, - * clear out any awaiting events. The mask will prevent - * any new __iio_push_event calls running. - */ - list_for_each_entry_safe(el, t, &ev_int->det_events, list) { - list_del(&el->list); - kfree(el); - } - ev_int->current_events = 0; - mutex_unlock(&ev_int->event_list_lock); - - return 0; -} - -static const struct file_operations iio_event_chrdev_fileops = { - .read = iio_event_chrdev_read, - .release = iio_event_chrdev_release, - .owner = THIS_MODULE, - .llseek = noop_llseek, -}; - -static int iio_event_getfd(struct iio_dev *indio_dev) -{ - struct iio_event_interface *ev_int = indio_dev->event_interface; - int fd; - - if (ev_int == NULL) - return -ENODEV; - - mutex_lock(&ev_int->event_list_lock); - if (test_and_set_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) { - mutex_unlock(&ev_int->event_list_lock); - return -EBUSY; - } - mutex_unlock(&ev_int->event_list_lock); - fd = anon_inode_getfd("iio:event", - &iio_event_chrdev_fileops, ev_int, O_RDONLY); - if (fd < 0) { - mutex_lock(&ev_int->event_list_lock); - clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); - mutex_unlock(&ev_int->event_list_lock); - } - return fd; -} - static int __init iio_init(void) { int ret; @@ -727,295 +557,6 @@ static void iio_device_unregister_sysfs(struct iio_dev *indio_dev) kfree(indio_dev->chan_attr_group.attrs); } -static const char * const iio_ev_type_text[] = { - [IIO_EV_TYPE_THRESH] = "thresh", - [IIO_EV_TYPE_MAG] = "mag", - [IIO_EV_TYPE_ROC] = "roc", - [IIO_EV_TYPE_THRESH_ADAPTIVE] = "thresh_adaptive", - [IIO_EV_TYPE_MAG_ADAPTIVE] = "mag_adaptive", -}; - -static const char * const iio_ev_dir_text[] = { - [IIO_EV_DIR_EITHER] = "either", - [IIO_EV_DIR_RISING] = "rising", - [IIO_EV_DIR_FALLING] = "falling" -}; - -static ssize_t iio_ev_state_store(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int ret; - bool val; - - ret = strtobool(buf, &val); - if (ret < 0) - return ret; - - ret = indio_dev->info->write_event_config(indio_dev, - this_attr->address, - val); - return (ret < 0) ? ret : len; -} - -static ssize_t iio_ev_state_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int val = indio_dev->info->read_event_config(indio_dev, - this_attr->address); - - if (val < 0) - return val; - else - return sprintf(buf, "%d\n", val); -} - -static ssize_t iio_ev_value_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int val, ret; - - ret = indio_dev->info->read_event_value(indio_dev, - this_attr->address, &val); - if (ret < 0) - return ret; - - return sprintf(buf, "%d\n", val); -} - -static ssize_t iio_ev_value_store(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - unsigned long val; - int ret; - - if (!indio_dev->info->write_event_value) - return -EINVAL; - - ret = strict_strtoul(buf, 10, &val); - if (ret) - return ret; - - ret = indio_dev->info->write_event_value(indio_dev, this_attr->address, - val); - if (ret < 0) - return ret; - - return len; -} - -static int iio_device_add_event_sysfs(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan) -{ - int ret = 0, i, attrcount = 0; - u64 mask = 0; - char *postfix; - if (!chan->event_mask) - return 0; - - for_each_set_bit(i, &chan->event_mask, sizeof(chan->event_mask)*8) { - postfix = kasprintf(GFP_KERNEL, "%s_%s_en", - iio_ev_type_text[i/IIO_EV_DIR_MAX], - iio_ev_dir_text[i%IIO_EV_DIR_MAX]); - if (postfix == NULL) { - ret = -ENOMEM; - goto error_ret; - } - if (chan->modified) - mask = IIO_MOD_EVENT_CODE(chan->type, 0, chan->channel, - i/IIO_EV_DIR_MAX, - i%IIO_EV_DIR_MAX); - else if (chan->differential) - mask = IIO_EVENT_CODE(chan->type, - 0, 0, - i%IIO_EV_DIR_MAX, - i/IIO_EV_DIR_MAX, - 0, - chan->channel, - chan->channel2); - else - mask = IIO_UNMOD_EVENT_CODE(chan->type, - chan->channel, - i/IIO_EV_DIR_MAX, - i%IIO_EV_DIR_MAX); - - ret = __iio_add_chan_devattr(postfix, - chan, - &iio_ev_state_show, - iio_ev_state_store, - mask, - 0, - &indio_dev->dev, - &indio_dev->event_interface-> - dev_attr_list); - kfree(postfix); - if (ret) - goto error_ret; - attrcount++; - postfix = kasprintf(GFP_KERNEL, "%s_%s_value", - iio_ev_type_text[i/IIO_EV_DIR_MAX], - iio_ev_dir_text[i%IIO_EV_DIR_MAX]); - if (postfix == NULL) { - ret = -ENOMEM; - goto error_ret; - } - ret = __iio_add_chan_devattr(postfix, chan, - iio_ev_value_show, - iio_ev_value_store, - mask, - 0, - &indio_dev->dev, - &indio_dev->event_interface-> - dev_attr_list); - kfree(postfix); - if (ret) - goto error_ret; - attrcount++; - } - ret = attrcount; -error_ret: - return ret; -} - -static inline void __iio_remove_event_config_attrs(struct iio_dev *indio_dev) -{ - struct iio_dev_attr *p, *n; - list_for_each_entry_safe(p, n, - &indio_dev->event_interface-> - dev_attr_list, l) { - kfree(p->dev_attr.attr.name); - kfree(p); - } -} - -static inline int __iio_add_event_config_attrs(struct iio_dev *indio_dev) -{ - int j, ret, attrcount = 0; - - INIT_LIST_HEAD(&indio_dev->event_interface->dev_attr_list); - /* Dynically created from the channels array */ - for (j = 0; j < indio_dev->num_channels; j++) { - ret = iio_device_add_event_sysfs(indio_dev, - &indio_dev->channels[j]); - if (ret < 0) - goto error_clear_attrs; - attrcount += ret; - } - return attrcount; - -error_clear_attrs: - __iio_remove_event_config_attrs(indio_dev); - - return ret; -} - -static bool iio_check_for_dynamic_events(struct iio_dev *indio_dev) -{ - int j; - - for (j = 0; j < indio_dev->num_channels; j++) - if (indio_dev->channels[j].event_mask != 0) - return true; - return false; -} - -static void iio_setup_ev_int(struct iio_event_interface *ev_int) -{ - mutex_init(&ev_int->event_list_lock); - /* discussion point - make this variable? */ - ev_int->max_events = 10; - ev_int->current_events = 0; - INIT_LIST_HEAD(&ev_int->det_events); - init_waitqueue_head(&ev_int->wait); -} - -static const char *iio_event_group_name = "events"; -static int iio_device_register_eventset(struct iio_dev *indio_dev) -{ - struct iio_dev_attr *p; - int ret = 0, attrcount_orig = 0, attrcount, attrn; - struct attribute **attr; - - if (!(indio_dev->info->event_attrs || - iio_check_for_dynamic_events(indio_dev))) - return 0; - - indio_dev->event_interface = - kzalloc(sizeof(struct iio_event_interface), GFP_KERNEL); - if (indio_dev->event_interface == NULL) { - ret = -ENOMEM; - goto error_ret; - } - - iio_setup_ev_int(indio_dev->event_interface); - if (indio_dev->info->event_attrs != NULL) { - attr = indio_dev->info->event_attrs->attrs; - while (*attr++ != NULL) - attrcount_orig++; - } - attrcount = attrcount_orig; - if (indio_dev->channels) { - ret = __iio_add_event_config_attrs(indio_dev); - if (ret < 0) - goto error_free_setup_event_lines; - attrcount += ret; - } - - indio_dev->event_interface->group.name = iio_event_group_name; - indio_dev->event_interface->group.attrs = kcalloc(attrcount + 1, - sizeof(indio_dev->event_interface->group.attrs[0]), - GFP_KERNEL); - if (indio_dev->event_interface->group.attrs == NULL) { - ret = -ENOMEM; - goto error_free_setup_event_lines; - } - if (indio_dev->info->event_attrs) - memcpy(indio_dev->event_interface->group.attrs, - indio_dev->info->event_attrs->attrs, - sizeof(indio_dev->event_interface->group.attrs[0]) - *attrcount_orig); - attrn = attrcount_orig; - /* Add all elements from the list. */ - list_for_each_entry(p, - &indio_dev->event_interface->dev_attr_list, - l) - indio_dev->event_interface->group.attrs[attrn++] = - &p->dev_attr.attr; - indio_dev->groups[indio_dev->groupcounter++] = - &indio_dev->event_interface->group; - - return 0; - -error_free_setup_event_lines: - __iio_remove_event_config_attrs(indio_dev); - kfree(indio_dev->event_interface); -error_ret: - - return ret; -} - -static void iio_device_unregister_eventset(struct iio_dev *indio_dev) -{ - if (indio_dev->event_interface == NULL) - return; - __iio_remove_event_config_attrs(indio_dev); - kfree(indio_dev->event_interface->group.attrs); - kfree(indio_dev->event_interface); -} - static void iio_dev_release(struct device *device) { struct iio_dev *indio_dev = container_of(device, struct iio_dev, dev); diff --git a/drivers/staging/iio/industrialio-event.c b/drivers/staging/iio/industrialio-event.c new file mode 100644 index 00000000000..a7b345ddc25 --- /dev/null +++ b/drivers/staging/iio/industrialio-event.c @@ -0,0 +1,483 @@ +/* Industrial I/O event handling + * + * Copyright (c) 2008 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * Based on elements of hwmon and input subsystems. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "iio.h" +#include "iio_core.h" +#include "sysfs.h" +#include "events.h" + +/** + * struct iio_detected_event_list - list element for events that have occurred + * @list: linked list header + * @ev: the event itself + */ +struct iio_detected_event_list { + struct list_head list; + struct iio_event_data ev; +}; + +/** + * struct iio_event_interface - chrdev interface for an event line + * @wait: wait queue to allow blocking reads of events + * @event_list_lock: mutex to protect the list of detected events + * @det_events: list of detected events + * @max_events: maximum number of events before new ones are dropped + * @current_events: number of events in detected list + * @dev_attr_list: list of event interface sysfs attribute + * @flags: file operations related flags including busy flag. + * @group: event interface sysfs attribute group + */ +struct iio_event_interface { + wait_queue_head_t wait; + struct mutex event_list_lock; + struct list_head det_events; + int max_events; + int current_events; + struct list_head dev_attr_list; + unsigned long flags; + struct attribute_group group; +}; + +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_detected_event_list *ev; + int ret = 0; + + /* Does anyone care? */ + mutex_lock(&ev_int->event_list_lock); + if (test_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) { + if (ev_int->current_events == ev_int->max_events) { + mutex_unlock(&ev_int->event_list_lock); + return 0; + } + ev = kmalloc(sizeof(*ev), GFP_KERNEL); + if (ev == NULL) { + ret = -ENOMEM; + mutex_unlock(&ev_int->event_list_lock); + goto error_ret; + } + ev->ev.id = ev_code; + ev->ev.timestamp = timestamp; + + list_add_tail(&ev->list, &ev_int->det_events); + ev_int->current_events++; + mutex_unlock(&ev_int->event_list_lock); + wake_up_interruptible(&ev_int->wait); + } else + mutex_unlock(&ev_int->event_list_lock); + +error_ret: + return ret; +} +EXPORT_SYMBOL(iio_push_event); + +static ssize_t iio_event_chrdev_read(struct file *filep, + char __user *buf, + size_t count, + loff_t *f_ps) +{ + struct iio_event_interface *ev_int = filep->private_data; + struct iio_detected_event_list *el; + size_t len = sizeof(el->ev); + int ret; + + if (count < len) + return -EINVAL; + + mutex_lock(&ev_int->event_list_lock); + if (list_empty(&ev_int->det_events)) { + if (filep->f_flags & O_NONBLOCK) { + ret = -EAGAIN; + goto error_mutex_unlock; + } + mutex_unlock(&ev_int->event_list_lock); + /* Blocking on device; waiting for something to be there */ + ret = wait_event_interruptible(ev_int->wait, + !list_empty(&ev_int + ->det_events)); + if (ret) + goto error_ret; + /* Single access device so no one else can get the data */ + mutex_lock(&ev_int->event_list_lock); + } + + el = list_first_entry(&ev_int->det_events, + struct iio_detected_event_list, + list); + if (copy_to_user(buf, &(el->ev), len)) { + ret = -EFAULT; + goto error_mutex_unlock; + } + list_del(&el->list); + ev_int->current_events--; + mutex_unlock(&ev_int->event_list_lock); + kfree(el); + + return len; + +error_mutex_unlock: + mutex_unlock(&ev_int->event_list_lock); +error_ret: + + return ret; +} + +static int iio_event_chrdev_release(struct inode *inode, struct file *filep) +{ + struct iio_event_interface *ev_int = filep->private_data; + struct iio_detected_event_list *el, *t; + + mutex_lock(&ev_int->event_list_lock); + clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); + /* + * In order to maintain a clean state for reopening, + * clear out any awaiting events. The mask will prevent + * any new __iio_push_event calls running. + */ + list_for_each_entry_safe(el, t, &ev_int->det_events, list) { + list_del(&el->list); + kfree(el); + } + ev_int->current_events = 0; + mutex_unlock(&ev_int->event_list_lock); + + return 0; +} + +static const struct file_operations iio_event_chrdev_fileops = { + .read = iio_event_chrdev_read, + .release = iio_event_chrdev_release, + .owner = THIS_MODULE, + .llseek = noop_llseek, +}; + +int iio_event_getfd(struct iio_dev *indio_dev) +{ + struct iio_event_interface *ev_int = indio_dev->event_interface; + int fd; + + if (ev_int == NULL) + return -ENODEV; + + mutex_lock(&ev_int->event_list_lock); + if (test_and_set_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) { + mutex_unlock(&ev_int->event_list_lock); + return -EBUSY; + } + mutex_unlock(&ev_int->event_list_lock); + fd = anon_inode_getfd("iio:event", + &iio_event_chrdev_fileops, ev_int, O_RDONLY); + if (fd < 0) { + mutex_lock(&ev_int->event_list_lock); + clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); + mutex_unlock(&ev_int->event_list_lock); + } + return fd; +} + +static const char * const iio_ev_type_text[] = { + [IIO_EV_TYPE_THRESH] = "thresh", + [IIO_EV_TYPE_MAG] = "mag", + [IIO_EV_TYPE_ROC] = "roc", + [IIO_EV_TYPE_THRESH_ADAPTIVE] = "thresh_adaptive", + [IIO_EV_TYPE_MAG_ADAPTIVE] = "mag_adaptive", +}; + +static const char * const iio_ev_dir_text[] = { + [IIO_EV_DIR_EITHER] = "either", + [IIO_EV_DIR_RISING] = "rising", + [IIO_EV_DIR_FALLING] = "falling" +}; + +static ssize_t iio_ev_state_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + bool val; + + ret = strtobool(buf, &val); + if (ret < 0) + return ret; + + ret = indio_dev->info->write_event_config(indio_dev, + this_attr->address, + val); + return (ret < 0) ? ret : len; +} + +static ssize_t iio_ev_state_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int val = indio_dev->info->read_event_config(indio_dev, + this_attr->address); + + if (val < 0) + return val; + else + return sprintf(buf, "%d\n", val); +} + +static ssize_t iio_ev_value_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int val, ret; + + ret = indio_dev->info->read_event_value(indio_dev, + this_attr->address, &val); + if (ret < 0) + return ret; + + return sprintf(buf, "%d\n", val); +} + +static ssize_t iio_ev_value_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + unsigned long val; + int ret; + + if (!indio_dev->info->write_event_value) + return -EINVAL; + + ret = strict_strtoul(buf, 10, &val); + if (ret) + return ret; + + ret = indio_dev->info->write_event_value(indio_dev, this_attr->address, + val); + if (ret < 0) + return ret; + + return len; +} + +static int iio_device_add_event_sysfs(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan) +{ + int ret = 0, i, attrcount = 0; + u64 mask = 0; + char *postfix; + if (!chan->event_mask) + return 0; + + for_each_set_bit(i, &chan->event_mask, sizeof(chan->event_mask)*8) { + postfix = kasprintf(GFP_KERNEL, "%s_%s_en", + iio_ev_type_text[i/IIO_EV_DIR_MAX], + iio_ev_dir_text[i%IIO_EV_DIR_MAX]); + if (postfix == NULL) { + ret = -ENOMEM; + goto error_ret; + } + if (chan->modified) + mask = IIO_MOD_EVENT_CODE(chan->type, 0, chan->channel, + i/IIO_EV_DIR_MAX, + i%IIO_EV_DIR_MAX); + else if (chan->differential) + mask = IIO_EVENT_CODE(chan->type, + 0, 0, + i%IIO_EV_DIR_MAX, + i/IIO_EV_DIR_MAX, + 0, + chan->channel, + chan->channel2); + else + mask = IIO_UNMOD_EVENT_CODE(chan->type, + chan->channel, + i/IIO_EV_DIR_MAX, + i%IIO_EV_DIR_MAX); + + ret = __iio_add_chan_devattr(postfix, + chan, + &iio_ev_state_show, + iio_ev_state_store, + mask, + 0, + &indio_dev->dev, + &indio_dev->event_interface-> + dev_attr_list); + kfree(postfix); + if (ret) + goto error_ret; + attrcount++; + postfix = kasprintf(GFP_KERNEL, "%s_%s_value", + iio_ev_type_text[i/IIO_EV_DIR_MAX], + iio_ev_dir_text[i%IIO_EV_DIR_MAX]); + if (postfix == NULL) { + ret = -ENOMEM; + goto error_ret; + } + ret = __iio_add_chan_devattr(postfix, chan, + iio_ev_value_show, + iio_ev_value_store, + mask, + 0, + &indio_dev->dev, + &indio_dev->event_interface-> + dev_attr_list); + kfree(postfix); + if (ret) + goto error_ret; + attrcount++; + } + ret = attrcount; +error_ret: + return ret; +} + +static inline void __iio_remove_event_config_attrs(struct iio_dev *indio_dev) +{ + struct iio_dev_attr *p, *n; + list_for_each_entry_safe(p, n, + &indio_dev->event_interface-> + dev_attr_list, l) { + kfree(p->dev_attr.attr.name); + kfree(p); + } +} + +static inline int __iio_add_event_config_attrs(struct iio_dev *indio_dev) +{ + int j, ret, attrcount = 0; + + INIT_LIST_HEAD(&indio_dev->event_interface->dev_attr_list); + /* Dynically created from the channels array */ + for (j = 0; j < indio_dev->num_channels; j++) { + ret = iio_device_add_event_sysfs(indio_dev, + &indio_dev->channels[j]); + if (ret < 0) + goto error_clear_attrs; + attrcount += ret; + } + return attrcount; + +error_clear_attrs: + __iio_remove_event_config_attrs(indio_dev); + + return ret; +} + +static bool iio_check_for_dynamic_events(struct iio_dev *indio_dev) +{ + int j; + + for (j = 0; j < indio_dev->num_channels; j++) + if (indio_dev->channels[j].event_mask != 0) + return true; + return false; +} + +static void iio_setup_ev_int(struct iio_event_interface *ev_int) +{ + mutex_init(&ev_int->event_list_lock); + /* discussion point - make this variable? */ + ev_int->max_events = 10; + ev_int->current_events = 0; + INIT_LIST_HEAD(&ev_int->det_events); + init_waitqueue_head(&ev_int->wait); +} + +static const char *iio_event_group_name = "events"; +int iio_device_register_eventset(struct iio_dev *indio_dev) +{ + struct iio_dev_attr *p; + int ret = 0, attrcount_orig = 0, attrcount, attrn; + struct attribute **attr; + + if (!(indio_dev->info->event_attrs || + iio_check_for_dynamic_events(indio_dev))) + return 0; + + indio_dev->event_interface = + kzalloc(sizeof(struct iio_event_interface), GFP_KERNEL); + if (indio_dev->event_interface == NULL) { + ret = -ENOMEM; + goto error_ret; + } + + iio_setup_ev_int(indio_dev->event_interface); + if (indio_dev->info->event_attrs != NULL) { + attr = indio_dev->info->event_attrs->attrs; + while (*attr++ != NULL) + attrcount_orig++; + } + attrcount = attrcount_orig; + if (indio_dev->channels) { + ret = __iio_add_event_config_attrs(indio_dev); + if (ret < 0) + goto error_free_setup_event_lines; + attrcount += ret; + } + + indio_dev->event_interface->group.name = iio_event_group_name; + indio_dev->event_interface->group.attrs = kcalloc(attrcount + 1, + sizeof(indio_dev->event_interface->group.attrs[0]), + GFP_KERNEL); + if (indio_dev->event_interface->group.attrs == NULL) { + ret = -ENOMEM; + goto error_free_setup_event_lines; + } + if (indio_dev->info->event_attrs) + memcpy(indio_dev->event_interface->group.attrs, + indio_dev->info->event_attrs->attrs, + sizeof(indio_dev->event_interface->group.attrs[0]) + *attrcount_orig); + attrn = attrcount_orig; + /* Add all elements from the list. */ + list_for_each_entry(p, + &indio_dev->event_interface->dev_attr_list, + l) + indio_dev->event_interface->group.attrs[attrn++] = + &p->dev_attr.attr; + indio_dev->groups[indio_dev->groupcounter++] = + &indio_dev->event_interface->group; + + return 0; + +error_free_setup_event_lines: + __iio_remove_event_config_attrs(indio_dev); + kfree(indio_dev->event_interface); +error_ret: + + return ret; +} + +void iio_device_unregister_eventset(struct iio_dev *indio_dev) +{ + if (indio_dev->event_interface == NULL) + return; + __iio_remove_event_config_attrs(indio_dev); + kfree(indio_dev->event_interface->group.attrs); + kfree(indio_dev->event_interface); +} -- cgit v1.2.3-70-g09d2 From 2c00193fa15dc51566dc7931fe32184c99c6b317 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 3 Jan 2012 14:59:39 +0100 Subject: staging:iio:events: Use kfifo for event queue The current IIO event code uses a list to emulate FIFO like behavior. Just use a kfifo directly instead to implement the event queue. As part of this patch the maximum of events in the queue is increased from 10 to 16 since kfifo requires a power of two for the number of FIFO elements. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/industrialio-event.c | 85 ++++++++------------------------ 1 file changed, 21 insertions(+), 64 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/industrialio-event.c b/drivers/staging/iio/industrialio-event.c index a7b345ddc25..335b615bd16 100644 --- a/drivers/staging/iio/industrialio-event.c +++ b/drivers/staging/iio/industrialio-event.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -23,23 +24,11 @@ #include "sysfs.h" #include "events.h" -/** - * struct iio_detected_event_list - list element for events that have occurred - * @list: linked list header - * @ev: the event itself - */ -struct iio_detected_event_list { - struct list_head list; - struct iio_event_data ev; -}; - /** * struct iio_event_interface - chrdev interface for an event line * @wait: wait queue to allow blocking reads of events * @event_list_lock: mutex to protect the list of detected events * @det_events: list of detected events - * @max_events: maximum number of events before new ones are dropped - * @current_events: number of events in detected list * @dev_attr_list: list of event interface sysfs attribute * @flags: file operations related flags including busy flag. * @group: event interface sysfs attribute group @@ -47,9 +36,8 @@ struct iio_detected_event_list { struct iio_event_interface { wait_queue_head_t wait; struct mutex event_list_lock; - struct list_head det_events; - int max_events; - int current_events; + DECLARE_KFIFO(det_events, struct iio_event_data, 16); + struct list_head dev_attr_list; unsigned long flags; struct attribute_group group; @@ -58,34 +46,25 @@ struct iio_event_interface { 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_detected_event_list *ev; - int ret = 0; + struct iio_event_data ev; + int copied; /* Does anyone care? */ mutex_lock(&ev_int->event_list_lock); if (test_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) { - if (ev_int->current_events == ev_int->max_events) { - mutex_unlock(&ev_int->event_list_lock); - return 0; - } - ev = kmalloc(sizeof(*ev), GFP_KERNEL); - if (ev == NULL) { - ret = -ENOMEM; - mutex_unlock(&ev_int->event_list_lock); - goto error_ret; - } - ev->ev.id = ev_code; - ev->ev.timestamp = timestamp; - list_add_tail(&ev->list, &ev_int->det_events); - ev_int->current_events++; + ev.id = ev_code; + ev.timestamp = timestamp; + + copied = kfifo_put(&ev_int->det_events, &ev); + mutex_unlock(&ev_int->event_list_lock); - wake_up_interruptible(&ev_int->wait); + if (copied != 0) + wake_up_interruptible(&ev_int->wait); } else mutex_unlock(&ev_int->event_list_lock); -error_ret: - return ret; + return 0; } EXPORT_SYMBOL(iio_push_event); @@ -95,15 +74,14 @@ static ssize_t iio_event_chrdev_read(struct file *filep, loff_t *f_ps) { struct iio_event_interface *ev_int = filep->private_data; - struct iio_detected_event_list *el; - size_t len = sizeof(el->ev); + unsigned int copied; int ret; - if (count < len) + if (count < sizeof(struct iio_event_data)) return -EINVAL; mutex_lock(&ev_int->event_list_lock); - if (list_empty(&ev_int->det_events)) { + if (kfifo_is_empty(&ev_int->det_events)) { if (filep->f_flags & O_NONBLOCK) { ret = -EAGAIN; goto error_mutex_unlock; @@ -111,39 +89,25 @@ static ssize_t iio_event_chrdev_read(struct file *filep, mutex_unlock(&ev_int->event_list_lock); /* Blocking on device; waiting for something to be there */ ret = wait_event_interruptible(ev_int->wait, - !list_empty(&ev_int - ->det_events)); + !kfifo_is_empty(&ev_int->det_events)); if (ret) goto error_ret; /* Single access device so no one else can get the data */ mutex_lock(&ev_int->event_list_lock); } - el = list_first_entry(&ev_int->det_events, - struct iio_detected_event_list, - list); - if (copy_to_user(buf, &(el->ev), len)) { - ret = -EFAULT; - goto error_mutex_unlock; - } - list_del(&el->list); - ev_int->current_events--; mutex_unlock(&ev_int->event_list_lock); - kfree(el); - - return len; + ret = kfifo_to_user(&ev_int->det_events, buf, count, &copied); error_mutex_unlock: mutex_unlock(&ev_int->event_list_lock); error_ret: - - return ret; + return ret ? ret : copied; } static int iio_event_chrdev_release(struct inode *inode, struct file *filep) { struct iio_event_interface *ev_int = filep->private_data; - struct iio_detected_event_list *el, *t; mutex_lock(&ev_int->event_list_lock); clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); @@ -152,11 +116,7 @@ static int iio_event_chrdev_release(struct inode *inode, struct file *filep) * clear out any awaiting events. The mask will prevent * any new __iio_push_event calls running. */ - list_for_each_entry_safe(el, t, &ev_int->det_events, list) { - list_del(&el->list); - kfree(el); - } - ev_int->current_events = 0; + kfifo_reset_out(&ev_int->det_events); mutex_unlock(&ev_int->event_list_lock); return 0; @@ -401,10 +361,7 @@ static bool iio_check_for_dynamic_events(struct iio_dev *indio_dev) static void iio_setup_ev_int(struct iio_event_interface *ev_int) { mutex_init(&ev_int->event_list_lock); - /* discussion point - make this variable? */ - ev_int->max_events = 10; - ev_int->current_events = 0; - INIT_LIST_HEAD(&ev_int->det_events); + INIT_KFIFO(ev_int->det_events); init_waitqueue_head(&ev_int->wait); } -- cgit v1.2.3-70-g09d2 From 43ba1100af11f34cc67bdf6b359667cfa851e6a8 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 3 Jan 2012 14:59:40 +0100 Subject: staging:iio:events: Use waitqueue lock to protect event queue Use the waitqueue lock to protect the event queue instead of a custom mutex. This has the advantage that we can call the waitqueue operations with the lock held, which simplifies the code flow a bit. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/industrialio-event.c | 43 +++++++++++++------------------- 1 file changed, 18 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/industrialio-event.c b/drivers/staging/iio/industrialio-event.c index 335b615bd16..f0c41f1f505 100644 --- a/drivers/staging/iio/industrialio-event.c +++ b/drivers/staging/iio/industrialio-event.c @@ -35,7 +35,6 @@ */ struct iio_event_interface { wait_queue_head_t wait; - struct mutex event_list_lock; DECLARE_KFIFO(det_events, struct iio_event_data, 16); struct list_head dev_attr_list; @@ -50,19 +49,17 @@ int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp) int copied; /* Does anyone care? */ - mutex_lock(&ev_int->event_list_lock); + spin_lock(&ev_int->wait.lock); if (test_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) { ev.id = ev_code; ev.timestamp = timestamp; copied = kfifo_put(&ev_int->det_events, &ev); - - mutex_unlock(&ev_int->event_list_lock); if (copied != 0) - wake_up_interruptible(&ev_int->wait); - } else - mutex_unlock(&ev_int->event_list_lock); + wake_up_locked(&ev_int->wait); + } + spin_unlock(&ev_int->wait.lock); return 0; } @@ -80,28 +77,25 @@ static ssize_t iio_event_chrdev_read(struct file *filep, if (count < sizeof(struct iio_event_data)) return -EINVAL; - mutex_lock(&ev_int->event_list_lock); + spin_lock(&ev_int->wait.lock); if (kfifo_is_empty(&ev_int->det_events)) { if (filep->f_flags & O_NONBLOCK) { ret = -EAGAIN; - goto error_mutex_unlock; + goto error_unlock; } - mutex_unlock(&ev_int->event_list_lock); /* Blocking on device; waiting for something to be there */ - ret = wait_event_interruptible(ev_int->wait, + ret = wait_event_interruptible_locked(ev_int->wait, !kfifo_is_empty(&ev_int->det_events)); if (ret) - goto error_ret; + goto error_unlock; /* Single access device so no one else can get the data */ - mutex_lock(&ev_int->event_list_lock); } - mutex_unlock(&ev_int->event_list_lock); ret = kfifo_to_user(&ev_int->det_events, buf, count, &copied); -error_mutex_unlock: - mutex_unlock(&ev_int->event_list_lock); -error_ret: +error_unlock: + spin_unlock(&ev_int->wait.lock); + return ret ? ret : copied; } @@ -109,7 +103,7 @@ static int iio_event_chrdev_release(struct inode *inode, struct file *filep) { struct iio_event_interface *ev_int = filep->private_data; - mutex_lock(&ev_int->event_list_lock); + spin_lock(&ev_int->wait.lock); clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); /* * In order to maintain a clean state for reopening, @@ -117,7 +111,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); - mutex_unlock(&ev_int->event_list_lock); + spin_unlock(&ev_int->wait.lock); return 0; } @@ -137,18 +131,18 @@ int iio_event_getfd(struct iio_dev *indio_dev) if (ev_int == NULL) return -ENODEV; - mutex_lock(&ev_int->event_list_lock); + spin_lock(&ev_int->wait.lock); if (test_and_set_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) { - mutex_unlock(&ev_int->event_list_lock); + spin_unlock(&ev_int->wait.lock); return -EBUSY; } - mutex_unlock(&ev_int->event_list_lock); + spin_unlock(&ev_int->wait.lock); fd = anon_inode_getfd("iio:event", &iio_event_chrdev_fileops, ev_int, O_RDONLY); if (fd < 0) { - mutex_lock(&ev_int->event_list_lock); + spin_lock(&ev_int->wait.lock); clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); - mutex_unlock(&ev_int->event_list_lock); + spin_unlock(&ev_int->wait.lock); } return fd; } @@ -360,7 +354,6 @@ static bool iio_check_for_dynamic_events(struct iio_dev *indio_dev) static void iio_setup_ev_int(struct iio_event_interface *ev_int) { - mutex_init(&ev_int->event_list_lock); INIT_KFIFO(ev_int->det_events); init_waitqueue_head(&ev_int->wait); } -- cgit v1.2.3-70-g09d2 From e18045ed75ec682a26a385b0072dcc030fd12a7e Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 3 Jan 2012 14:59:41 +0100 Subject: staging:iio:events: Add poll support Add poll support to the event queue. This will allow us to check for pending events in a application's event loop using poll() or similar. Since we already have support for blocking reads adding poll support as well is trivial. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/industrialio-event.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/industrialio-event.c b/drivers/staging/iio/industrialio-event.c index f0c41f1f505..800f67d4cce 100644 --- a/drivers/staging/iio/industrialio-event.c +++ b/drivers/staging/iio/industrialio-event.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -57,7 +58,7 @@ int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp) copied = kfifo_put(&ev_int->det_events, &ev); if (copied != 0) - wake_up_locked(&ev_int->wait); + wake_up_locked_poll(&ev_int->wait, POLLIN); } spin_unlock(&ev_int->wait.lock); @@ -65,6 +66,25 @@ int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp) } EXPORT_SYMBOL(iio_push_event); +/** + * iio_event_poll() - poll the event queue to find out if it has data + */ +static unsigned int iio_event_poll(struct file *filep, + struct poll_table_struct *wait) +{ + struct iio_event_interface *ev_int = filep->private_data; + unsigned int events = 0; + + poll_wait(filep, &ev_int->wait, wait); + + spin_lock(&ev_int->wait.lock); + if (!kfifo_is_empty(&ev_int->det_events)) + events = POLLIN | POLLRDNORM; + spin_unlock(&ev_int->wait.lock); + + return events; +} + static ssize_t iio_event_chrdev_read(struct file *filep, char __user *buf, size_t count, @@ -118,6 +138,7 @@ static int iio_event_chrdev_release(struct inode *inode, struct file *filep) static const struct file_operations iio_event_chrdev_fileops = { .read = iio_event_chrdev_read, + .poll = iio_event_poll, .release = iio_event_chrdev_release, .owner = THIS_MODULE, .llseek = noop_llseek, -- cgit v1.2.3-70-g09d2 From a046c1e866673dd334c31d06312283e2bc5b483b Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 3 Jan 2012 14:59:42 +0100 Subject: staging:iio:events: Use non-atmoic bitops We always hold the waitqueue lock when modifying the flags field. So it is safe to use the non-atomic bitops here instead of the atomic versions. The lock has to be held, because we need to clear the busy flag and flush the event FIFO in one atomic operation when closing the event file descriptor. Signed-off-by: Lars-Peter Clausen Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/industrialio-event.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/industrialio-event.c b/drivers/staging/iio/industrialio-event.c index 800f67d4cce..66d320bf302 100644 --- a/drivers/staging/iio/industrialio-event.c +++ b/drivers/staging/iio/industrialio-event.c @@ -124,7 +124,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); - clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); + __clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); /* * In order to maintain a clean state for reopening, * clear out any awaiting events. The mask will prevent @@ -153,7 +153,7 @@ int iio_event_getfd(struct iio_dev *indio_dev) return -ENODEV; spin_lock(&ev_int->wait.lock); - if (test_and_set_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) { + if (__test_and_set_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) { spin_unlock(&ev_int->wait.lock); return -EBUSY; } @@ -162,7 +162,7 @@ int iio_event_getfd(struct iio_dev *indio_dev) &iio_event_chrdev_fileops, ev_int, O_RDONLY); if (fd < 0) { spin_lock(&ev_int->wait.lock); - clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); + __clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); spin_unlock(&ev_int->wait.lock); } return fd; -- cgit v1.2.3-70-g09d2 From 15bbb7793ad7f6f106ce09fdfa3956c5aff37cf1 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 29 Jan 2012 11:07:00 +0000 Subject: staging:iio:adc:ad7192 unwind use of is_visible for attribute group. It saves a couple of lines of code but reduces simplicity of code. I generally wish to discourage use of is_visible throughout IIO. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/ad7192.c | 43 +++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index 9d251653307..9fd6d63d299 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -822,25 +822,20 @@ static struct attribute *ad7192_attributes[] = { NULL }; -static umode_t ad7192_attr_is_visible(struct kobject *kobj, - struct attribute *attr, int n) -{ - struct device *dev = container_of(kobj, struct device, kobj); - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad7192_state *st = iio_priv(indio_dev); - - umode_t mode = attr->mode; - - if ((st->devid != ID_AD7195) && - (attr == &iio_dev_attr_ac_excitation_en.dev_attr.attr)) - mode = 0; - - return mode; -} - static const struct attribute_group ad7192_attribute_group = { .attrs = ad7192_attributes, - .is_visible = ad7192_attr_is_visible, +}; + +static struct attribute *ad7195_attributes[] = { + &iio_dev_attr_sampling_frequency.dev_attr.attr, + &iio_dev_attr_in_v_m_v_scale_available.dev_attr.attr, + &iio_dev_attr_in_voltage_scale_available.dev_attr.attr, + &iio_dev_attr_bridge_switch_en.dev_attr.attr, + NULL +}; + +static const struct attribute_group ad7195_attribute_group = { + .attrs = ad7195_attributes, }; static int ad7192_read_raw(struct iio_dev *indio_dev, @@ -970,6 +965,15 @@ static const struct iio_info ad7192_info = { .driver_module = THIS_MODULE, }; +static const struct iio_info ad7195_info = { + .read_raw = &ad7192_read_raw, + .write_raw = &ad7192_write_raw, + .write_raw_get_fmt = &ad7192_write_raw_get_fmt, + .attrs = &ad7195_attribute_group, + .validate_trigger = ad7192_validate_trigger, + .driver_module = THIS_MODULE, +}; + #define AD7192_CHAN_DIFF(_chan, _chan2, _name, _address, _si) \ { .type = IIO_VOLTAGE, \ .differential = 1, \ @@ -1062,7 +1066,10 @@ static int __devinit ad7192_probe(struct spi_device *spi) indio_dev->channels = ad7192_channels; indio_dev->num_channels = ARRAY_SIZE(ad7192_channels); indio_dev->available_scan_masks = st->available_scan_masks; - indio_dev->info = &ad7192_info; + if (st->devid == ID_AD7195) + indio_dev->info = &ad7195_info; + else + indio_dev->info = &ad7192_info; for (i = 0; i < indio_dev->num_channels; i++) st->available_scan_masks[i] = (1 << i) | (1 << -- cgit v1.2.3-70-g09d2 From b2c04a34aa9a1b82af590b7e7cc965e7125ce9fa Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 29 Jan 2012 11:07:01 +0000 Subject: staging:iio:dds:ad9834 unwind use of is_visible for attrs. Trivial usecase in which just having two different attr groups covers all options. Slightly more code, but a simpler to follow result. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dds/ad9834.c | 53 ++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/dds/ad9834.c b/drivers/staging/iio/dds/ad9834.c index 5e67104fea1..38a2de08626 100644 --- a/drivers/staging/iio/dds/ad9834.c +++ b/drivers/staging/iio/dds/ad9834.c @@ -281,29 +281,27 @@ static struct attribute *ad9834_attributes[] = { NULL, }; -static umode_t ad9834_attr_is_visible(struct kobject *kobj, - struct attribute *attr, int n) -{ - struct device *dev = container_of(kobj, struct device, kobj); - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad9834_state *st = iio_priv(indio_dev); - - umode_t mode = attr->mode; - - if (((st->devid == ID_AD9833) || (st->devid == ID_AD9837)) && - ((attr == &iio_dev_attr_dds0_out1_enable.dev_attr.attr) || - (attr == &iio_dev_attr_dds0_out1_wavetype.dev_attr.attr) || - (attr == - &iio_dev_attr_dds0_out1_wavetype_available.dev_attr.attr) || - (attr == &iio_dev_attr_dds0_pincontrol_en.dev_attr.attr))) - mode = 0; - - return mode; -} +static struct attribute *ad9833_attributes[] = { + &iio_dev_attr_dds0_freq0.dev_attr.attr, + &iio_dev_attr_dds0_freq1.dev_attr.attr, + &iio_const_attr_dds0_freq_scale.dev_attr.attr, + &iio_dev_attr_dds0_phase0.dev_attr.attr, + &iio_dev_attr_dds0_phase1.dev_attr.attr, + &iio_const_attr_dds0_phase_scale.dev_attr.attr, + &iio_dev_attr_dds0_freqsymbol.dev_attr.attr, + &iio_dev_attr_dds0_phasesymbol.dev_attr.attr, + &iio_dev_attr_dds0_out_enable.dev_attr.attr, + &iio_dev_attr_dds0_out0_wavetype.dev_attr.attr, + &iio_dev_attr_dds0_out0_wavetype_available.dev_attr.attr, + NULL, +}; static const struct attribute_group ad9834_attribute_group = { .attrs = ad9834_attributes, - .is_visible = ad9834_attr_is_visible, +}; + +static const struct attribute_group ad9833_attribute_group = { + .attrs = ad9833_attributes, }; static const struct iio_info ad9834_info = { @@ -311,6 +309,11 @@ static const struct iio_info ad9834_info = { .driver_module = THIS_MODULE, }; +static const struct iio_info ad9833_info = { + .attrs = &ad9833_attribute_group, + .driver_module = THIS_MODULE, +}; + static int __devinit ad9834_probe(struct spi_device *spi) { struct ad9834_platform_data *pdata = spi->dev.platform_data; @@ -344,7 +347,15 @@ static int __devinit ad9834_probe(struct spi_device *spi) st->reg = reg; indio_dev->dev.parent = &spi->dev; indio_dev->name = spi_get_device_id(spi)->name; - indio_dev->info = &ad9834_info; + switch (st->devid) { + case ID_AD9833: + case ID_AD9837: + indio_dev->info = &ad9833_info; + break; + default: + indio_dev->info = &ad9834_info; + break; + } indio_dev->modes = INDIO_DIRECT_MODE; /* Setup default messages */ -- cgit v1.2.3-70-g09d2 From 7389266cc9fa4b9b2761785bcc6fba7bbeb8d070 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 29 Jan 2012 11:07:02 +0000 Subject: staging:iio:dac:ad5446 unwind use of is_visible for attrs. Trivial case where no attributes are valid for some parts. Better handled using two iio_info structures and selecting the right one at probe time. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/ad5446.c | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c index 693e7482524..e439baea333 100644 --- a/drivers/staging/iio/dac/ad5446.c +++ b/drivers/staging/iio/dac/ad5446.c @@ -149,30 +149,8 @@ static struct attribute *ad5446_attributes[] = { NULL, }; -static umode_t ad5446_attr_is_visible(struct kobject *kobj, - struct attribute *attr, int n) -{ - struct device *dev = container_of(kobj, struct device, kobj); - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5446_state *st = iio_priv(indio_dev); - - umode_t mode = attr->mode; - - if (!st->chip_info->store_pwr_down && - (attr == &iio_dev_attr_out_voltage0_powerdown.dev_attr.attr || - attr == &iio_dev_attr_out_voltage_powerdown_mode. - dev_attr.attr || - attr == - &iio_const_attr_out_voltage_powerdown_mode_available. - dev_attr.attr)) - mode = 0; - - return mode; -} - static const struct attribute_group ad5446_attribute_group = { .attrs = ad5446_attributes, - .is_visible = ad5446_attr_is_visible, }; #define AD5446_CHANNEL(bits, storage, shift) { \ @@ -321,6 +299,12 @@ static const struct iio_info ad5446_info = { .driver_module = THIS_MODULE, }; +static const struct iio_info ad5446_info_no_pwr_down = { + .read_raw = ad5446_read_raw, + .write_raw = ad5446_write_raw, + .driver_module = THIS_MODULE, +}; + static int __devinit ad5446_probe(struct spi_device *spi) { struct ad5446_state *st; @@ -353,7 +337,10 @@ static int __devinit ad5446_probe(struct spi_device *spi) /* Estabilish that the iio_dev is a child of the spi device */ indio_dev->dev.parent = &spi->dev; indio_dev->name = spi_get_device_id(spi)->name; - indio_dev->info = &ad5446_info; + if (st->chip_info->store_pwr_down) + indio_dev->info = &ad5446_info; + else + indio_dev->info = &ad5446_info_no_pwr_down; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = &st->chip_info->channel; indio_dev->num_channels = 1; -- cgit v1.2.3-70-g09d2 From 9214cc6e1302f5af5ee76db38d345907806dca67 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 29 Jan 2012 11:07:03 +0000 Subject: staging:iio:adc:ad7606 unwind use of is_visible for attrs. This is the most controversial of this set of is_visible removals. There are two conditions controlling availability of attrs resulting in 4 different attribute groups. Still for a few more lines things are clearer to read to my mind. Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/ad7606_core.c | 83 ++++++++++++++++++++++------------- 1 file changed, 53 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c index ddb7ef92f5c..97e8d3d4471 100644 --- a/drivers/staging/iio/adc/ad7606_core.c +++ b/drivers/staging/iio/adc/ad7606_core.c @@ -197,7 +197,7 @@ static IIO_DEVICE_ATTR(oversampling_ratio, S_IRUGO | S_IWUSR, ad7606_store_oversampling_ratio, 0); static IIO_CONST_ATTR(oversampling_ratio_available, "0 2 4 8 16 32 64"); -static struct attribute *ad7606_attributes[] = { +static struct attribute *ad7606_attributes_os_and_range[] = { &iio_dev_attr_in_voltage_range.dev_attr.attr, &iio_const_attr_in_voltage_range_available.dev_attr.attr, &iio_dev_attr_oversampling_ratio.dev_attr.attr, @@ -205,34 +205,28 @@ static struct attribute *ad7606_attributes[] = { NULL, }; -static umode_t ad7606_attr_is_visible(struct kobject *kobj, - struct attribute *attr, int n) -{ - struct device *dev = container_of(kobj, struct device, kobj); - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad7606_state *st = iio_priv(indio_dev); +static const struct attribute_group ad7606_attribute_group_os_and_range = { + .attrs = ad7606_attributes_os_and_range, +}; - umode_t mode = attr->mode; - - if (!(gpio_is_valid(st->pdata->gpio_os0) && - gpio_is_valid(st->pdata->gpio_os1) && - gpio_is_valid(st->pdata->gpio_os2)) && - (attr == &iio_dev_attr_oversampling_ratio.dev_attr.attr || - attr == - &iio_const_attr_oversampling_ratio_available.dev_attr.attr)) - mode = 0; - else if (!gpio_is_valid(st->pdata->gpio_range) && - (attr == &iio_dev_attr_in_voltage_range.dev_attr.attr || - attr == - &iio_const_attr_in_voltage_range_available.dev_attr.attr)) - mode = 0; - - return mode; -} +static struct attribute *ad7606_attributes_os[] = { + &iio_dev_attr_oversampling_ratio.dev_attr.attr, + &iio_const_attr_oversampling_ratio_available.dev_attr.attr, + NULL, +}; -static const struct attribute_group ad7606_attribute_group = { - .attrs = ad7606_attributes, - .is_visible = ad7606_attr_is_visible, +static const struct attribute_group ad7606_attribute_group_os = { + .attrs = ad7606_attributes_os, +}; + +static struct attribute *ad7606_attributes_range[] = { + &iio_dev_attr_in_voltage_range.dev_attr.attr, + &iio_const_attr_in_voltage_range_available.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad7606_attribute_group_range = { + .attrs = ad7606_attributes_range, }; #define AD7606_CHANNEL(num) \ @@ -435,10 +429,27 @@ static irqreturn_t ad7606_interrupt(int irq, void *dev_id) return IRQ_HANDLED; }; -static const struct iio_info ad7606_info = { +static const struct iio_info ad7606_info_no_os_or_range = { .driver_module = THIS_MODULE, .read_raw = &ad7606_read_raw, - .attrs = &ad7606_attribute_group, +}; + +static const struct iio_info ad7606_info_os_and_range = { + .driver_module = THIS_MODULE, + .read_raw = &ad7606_read_raw, + .attrs = &ad7606_attribute_group_os_and_range, +}; + +static const struct iio_info ad7606_info_os = { + .driver_module = THIS_MODULE, + .read_raw = &ad7606_read_raw, + .attrs = &ad7606_attribute_group_os, +}; + +static const struct iio_info ad7606_info_range = { + .driver_module = THIS_MODULE, + .read_raw = &ad7606_read_raw, + .attrs = &ad7606_attribute_group_range, }; struct iio_dev *ad7606_probe(struct device *dev, int irq, @@ -483,7 +494,19 @@ struct iio_dev *ad7606_probe(struct device *dev, int irq, st->chip_info = &ad7606_chip_info_tbl[id]; indio_dev->dev.parent = dev; - indio_dev->info = &ad7606_info; + if (gpio_is_valid(st->pdata->gpio_os0) && + gpio_is_valid(st->pdata->gpio_os1) && + gpio_is_valid(st->pdata->gpio_os2)) { + if (gpio_is_valid(st->pdata->gpio_range)) + indio_dev->info = &ad7606_info_os_and_range; + else + indio_dev->info = &ad7606_info_os; + } else { + if (gpio_is_valid(st->pdata->gpio_range)) + indio_dev->info = &ad7606_info_range; + else + indio_dev->info = &ad7606_info_no_os_or_range; + } indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->name = st->chip_info->name; indio_dev->channels = st->chip_info->channels; -- cgit v1.2.3-70-g09d2 From 8f9cde23c3f7b74dfad617d2ffbbb5c2ba55e1ee Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 29 Jan 2012 11:07:04 +0000 Subject: staging:iio:adc:adt7310/7410 sticking plaster fix for broken event attrs. Neither of these drivers has ever been anywhere near the iio abi. Probably as a result of this the fact they had two event groups each was not picked up when we restricted IIO to having only 1 event line per device (as part of the chrdev merge set). As such these definitely didn't work before. This patch squishes the only element from the 'comparator' event line that isn't in the 'interrupt' one into it and kills off the 'comparator' one. Ultimately both of these drivers belong in hwmon not IIO and are just waiting here because I don't want to kill off a driver that may prove useful to someone. (Ultimately I will ask Greg to scrap these two if no one steps up to deal with them.) Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/adt7310.c | 21 ++++----------------- drivers/staging/iio/adc/adt7410.c | 21 ++++----------------- 2 files changed, 8 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/adt7310.c b/drivers/staging/iio/adc/adt7310.c index eec2f325d54..caf57c1169b 100644 --- a/drivers/staging/iio/adc/adt7310.c +++ b/drivers/staging/iio/adc/adt7310.c @@ -725,32 +725,19 @@ static struct attribute *adt7310_event_int_attributes[] = { &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_hyst.dev_attr.attr, - NULL, -}; - -static struct attribute *adt7310_event_ct_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_crit.dev_attr.attr, &iio_dev_attr_t_hyst.dev_attr.attr, NULL, }; -static struct attribute_group adt7310_event_attribute_group[ADT7310_IRQS] = { - { - .attrs = adt7310_event_int_attributes, - .name = "events", - }, { - .attrs = adt7310_event_ct_attributes, - .name = "events", - } +static struct attribute_group adt7310_event_attribute_group = { + .attrs = adt7310_event_int_attributes, + .name = "events", }; static const struct iio_info adt7310_info = { .attrs = &adt7310_attribute_group, - .event_attrs = adt7310_event_attribute_group, + .event_attrs = &adt7310_event_attribute_group, .driver_module = THIS_MODULE, }; diff --git a/drivers/staging/iio/adc/adt7410.c b/drivers/staging/iio/adc/adt7410.c index c62248ceb37..dff3e8ca2d7 100644 --- a/drivers/staging/iio/adc/adt7410.c +++ b/drivers/staging/iio/adc/adt7410.c @@ -693,32 +693,19 @@ static struct attribute *adt7410_event_int_attributes[] = { &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_hyst.dev_attr.attr, - NULL, -}; - -static struct attribute *adt7410_event_ct_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_crit.dev_attr.attr, &iio_dev_attr_t_hyst.dev_attr.attr, NULL, }; -static struct attribute_group adt7410_event_attribute_group[ADT7410_IRQS] = { - { - .attrs = adt7410_event_int_attributes, - .name = "events", - }, { - .attrs = adt7410_event_ct_attributes, - .name = "events", - } +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, + .event_attrs = &adt7410_event_attribute_group, .driver_module = THIS_MODULE, }; -- cgit v1.2.3-70-g09d2 From 72a9826b45c0d126f47c1acc8444c5d9ee478fcd Mon Sep 17 00:00:00 2001 From: Seth Jennings Date: Thu, 9 Feb 2012 12:25:02 -0600 Subject: staging: zcache: fix serialization bug in zv stats In a multithreaded workload, the zv_curr_dist_counts and zv_cumul_dist_counts statistics are being corrupted because the increments and decrements in zv_create and zv_free are not atomic. This patch converts these statistics and their corresponding increments/decrements/reads to atomic operations. Signed-off-by: Seth Jennings Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zcache/zcache-main.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index da222c28a12..8887fd4a3fc 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c @@ -690,8 +690,8 @@ static unsigned int zv_max_zsize = (PAGE_SIZE / 8) * 7; */ static unsigned int zv_max_mean_zsize = (PAGE_SIZE / 8) * 5; -static unsigned long zv_curr_dist_counts[NCHUNKS]; -static unsigned long zv_cumul_dist_counts[NCHUNKS]; +static atomic_t zv_curr_dist_counts[NCHUNKS]; +static atomic_t zv_cumul_dist_counts[NCHUNKS]; static struct zv_hdr *zv_create(struct xv_pool *xvpool, uint32_t pool_id, struct tmem_oid *oid, uint32_t index, @@ -710,8 +710,8 @@ static struct zv_hdr *zv_create(struct xv_pool *xvpool, uint32_t pool_id, &page, &offset, ZCACHE_GFP_MASK); if (unlikely(ret)) goto out; - zv_curr_dist_counts[chunks]++; - zv_cumul_dist_counts[chunks]++; + atomic_inc(&zv_curr_dist_counts[chunks]); + atomic_inc(&zv_cumul_dist_counts[chunks]); zv = kmap_atomic(page, KM_USER0) + offset; zv->index = index; zv->oid = *oid; @@ -733,7 +733,7 @@ static void zv_free(struct xv_pool *xvpool, struct zv_hdr *zv) ASSERT_SENTINEL(zv, ZVH); BUG_ON(chunks >= NCHUNKS); - zv_curr_dist_counts[chunks]--; + atomic_dec(&zv_curr_dist_counts[chunks]); size -= sizeof(*zv); BUG_ON(size == 0); INVERT_SENTINEL(zv, ZVH); @@ -773,7 +773,7 @@ static int zv_curr_dist_counts_show(char *buf) char *p = buf; for (i = 0; i < NCHUNKS; i++) { - n = zv_curr_dist_counts[i]; + n = atomic_read(&zv_curr_dist_counts[i]); p += sprintf(p, "%lu ", n); chunks += n; sum_total_chunks += i * n; @@ -789,7 +789,7 @@ static int zv_cumul_dist_counts_show(char *buf) char *p = buf; for (i = 0; i < NCHUNKS; i++) { - n = zv_cumul_dist_counts[i]; + n = atomic_read(&zv_cumul_dist_counts[i]); p += sprintf(p, "%lu ", n); chunks += n; sum_total_chunks += i * n; -- cgit v1.2.3-70-g09d2 From a49aeb1de58557ea6f0293bdd04ddda4c5a3020b Mon Sep 17 00:00:00 2001 From: Seth Jennings Date: Thu, 9 Feb 2012 12:25:03 -0600 Subject: staging: zcache: replace xvmalloc with zsmalloc Replaces xvmalloc with zsmalloc as the persistent memory allocator for zcache Signed-off-by: Seth Jennings Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zcache/Kconfig | 2 +- drivers/staging/zcache/zcache-main.c | 83 +++++++++++++++++++----------------- 2 files changed, 44 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zcache/Kconfig b/drivers/staging/zcache/Kconfig index 1b7bba7b1a3..94e48aa9f36 100644 --- a/drivers/staging/zcache/Kconfig +++ b/drivers/staging/zcache/Kconfig @@ -1,7 +1,7 @@ config ZCACHE tristate "Dynamic compression of swap pages and clean pagecache pages" depends on (CLEANCACHE || FRONTSWAP) && CRYPTO - select XVMALLOC + select ZSMALLOC select CRYPTO_LZO default n help diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index 8887fd4a3fc..04a4a3f59d8 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c @@ -9,7 +9,7 @@ * page-accessible memory [1] interfaces, both utilizing the crypto compression * API: * 1) "compression buddies" ("zbud") is used for ephemeral pages - * 2) xvmalloc is used for persistent pages. + * 2) zsmalloc is used for persistent pages. * Xvmalloc (based on the TLSF allocator) has very low fragmentation * so maximizes space efficiency, while zbud allows pairs (and potentially, * in the future, more than a pair of) compressed pages to be closely linked @@ -33,7 +33,7 @@ #include #include "tmem.h" -#include "../zram/xvmalloc.h" /* if built in drivers/staging */ +#include "../zsmalloc/zsmalloc.h" #if (!defined(CONFIG_CLEANCACHE) && !defined(CONFIG_FRONTSWAP)) #error "zcache is useless without CONFIG_CLEANCACHE or CONFIG_FRONTSWAP" @@ -62,7 +62,7 @@ MODULE_LICENSE("GPL"); struct zcache_client { struct tmem_pool *tmem_pools[MAX_POOLS_PER_CLIENT]; - struct xv_pool *xvpool; + struct zs_pool *zspool; bool allocated; atomic_t refcount; }; @@ -658,7 +658,7 @@ static int zbud_show_cumul_chunk_counts(char *buf) #endif /********** - * This "zv" PAM implementation combines the TLSF-based xvMalloc + * This "zv" PAM implementation combines the slab-based zsmalloc * with the crypto compression API to maximize the amount of data that can * be packed into a physical page. * @@ -672,6 +672,7 @@ struct zv_hdr { uint32_t pool_id; struct tmem_oid oid; uint32_t index; + size_t size; DECL_SENTINEL }; @@ -693,71 +694,73 @@ static unsigned int zv_max_mean_zsize = (PAGE_SIZE / 8) * 5; static atomic_t zv_curr_dist_counts[NCHUNKS]; static atomic_t zv_cumul_dist_counts[NCHUNKS]; -static struct zv_hdr *zv_create(struct xv_pool *xvpool, uint32_t pool_id, +static struct zv_hdr *zv_create(struct zs_pool *pool, uint32_t pool_id, struct tmem_oid *oid, uint32_t index, void *cdata, unsigned clen) { - struct page *page; - struct zv_hdr *zv = NULL; - uint32_t offset; - int alloc_size = clen + sizeof(struct zv_hdr); - int chunks = (alloc_size + (CHUNK_SIZE - 1)) >> CHUNK_SHIFT; - int ret; + struct zv_hdr *zv; + u32 size = clen + sizeof(struct zv_hdr); + int chunks = (size + (CHUNK_SIZE - 1)) >> CHUNK_SHIFT; + void *handle = NULL; + char *buf; BUG_ON(!irqs_disabled()); BUG_ON(chunks >= NCHUNKS); - ret = xv_malloc(xvpool, alloc_size, - &page, &offset, ZCACHE_GFP_MASK); - if (unlikely(ret)) + handle = zs_malloc(pool, size); + if (!handle) goto out; atomic_inc(&zv_curr_dist_counts[chunks]); atomic_inc(&zv_cumul_dist_counts[chunks]); - zv = kmap_atomic(page, KM_USER0) + offset; + zv = (struct zv_hdr *)((char *)cdata - sizeof(*zv)); zv->index = index; zv->oid = *oid; zv->pool_id = pool_id; + zv->size = clen; SET_SENTINEL(zv, ZVH); - memcpy((char *)zv + sizeof(struct zv_hdr), cdata, clen); - kunmap_atomic(zv, KM_USER0); + buf = zs_map_object(pool, handle); + memcpy(buf, zv, clen + sizeof(*zv)); + zs_unmap_object(pool, handle); out: - return zv; + return handle; } -static void zv_free(struct xv_pool *xvpool, struct zv_hdr *zv) +static void zv_free(struct zs_pool *pool, void *handle) { unsigned long flags; - struct page *page; - uint32_t offset; - uint16_t size = xv_get_object_size(zv); - int chunks = (size + (CHUNK_SIZE - 1)) >> CHUNK_SHIFT; + struct zv_hdr *zv; + uint16_t size; + int chunks; + zv = zs_map_object(pool, handle); ASSERT_SENTINEL(zv, ZVH); + size = zv->size + sizeof(struct zv_hdr); + INVERT_SENTINEL(zv, ZVH); + zs_unmap_object(pool, handle); + + chunks = (size + (CHUNK_SIZE - 1)) >> CHUNK_SHIFT; BUG_ON(chunks >= NCHUNKS); atomic_dec(&zv_curr_dist_counts[chunks]); - size -= sizeof(*zv); - BUG_ON(size == 0); - INVERT_SENTINEL(zv, ZVH); - page = virt_to_page(zv); - offset = (unsigned long)zv & ~PAGE_MASK; + local_irq_save(flags); - xv_free(xvpool, page, offset); + zs_free(pool, handle); local_irq_restore(flags); } -static void zv_decompress(struct page *page, struct zv_hdr *zv) +static void zv_decompress(struct page *page, void *handle) { unsigned int clen = PAGE_SIZE; char *to_va; - unsigned size; int ret; + struct zv_hdr *zv; + zv = zs_map_object(zcache_host.zspool, handle); + BUG_ON(zv->size == 0); ASSERT_SENTINEL(zv, ZVH); - size = xv_get_object_size(zv) - sizeof(*zv); - BUG_ON(size == 0); to_va = kmap_atomic(page, KM_USER0); ret = zcache_comp_op(ZCACHE_COMPOP_DECOMPRESS, (char *)zv + sizeof(*zv), - size, to_va, &clen); + zv->size, to_va, &clen); kunmap_atomic(to_va, KM_USER0); + zs_unmap_object(zcache_host.zspool, handle); BUG_ON(ret); BUG_ON(clen != PAGE_SIZE); } @@ -984,8 +987,8 @@ int zcache_new_client(uint16_t cli_id) goto out; cli->allocated = 1; #ifdef CONFIG_FRONTSWAP - cli->xvpool = xv_create_pool(); - if (cli->xvpool == NULL) + cli->zspool = zs_create_pool("zcache", ZCACHE_GFP_MASK); + if (cli->zspool == NULL) goto out; #endif ret = 0; @@ -1216,7 +1219,7 @@ static void *zcache_pampd_create(char *data, size_t size, bool raw, int eph, } /* reject if mean compression is too poor */ if ((clen > zv_max_mean_zsize) && (curr_pers_pampd_count > 0)) { - total_zsize = xv_get_total_size_bytes(cli->xvpool); + total_zsize = zs_get_total_size_bytes(cli->zspool); zv_mean_zsize = div_u64(total_zsize, curr_pers_pampd_count); if (zv_mean_zsize > zv_max_mean_zsize) { @@ -1224,7 +1227,7 @@ static void *zcache_pampd_create(char *data, size_t size, bool raw, int eph, goto out; } } - pampd = (void *)zv_create(cli->xvpool, pool->pool_id, + pampd = (void *)zv_create(cli->zspool, pool->pool_id, oid, index, cdata, clen); if (pampd == NULL) goto out; @@ -1282,7 +1285,7 @@ static void zcache_pampd_free(void *pampd, struct tmem_pool *pool, atomic_dec(&zcache_curr_eph_pampd_count); BUG_ON(atomic_read(&zcache_curr_eph_pampd_count) < 0); } else { - zv_free(cli->xvpool, (struct zv_hdr *)pampd); + zv_free(cli->zspool, pampd); atomic_dec(&zcache_curr_pers_pampd_count); BUG_ON(atomic_read(&zcache_curr_pers_pampd_count) < 0); } @@ -2072,7 +2075,7 @@ static int __init zcache_init(void) old_ops = zcache_frontswap_register_ops(); pr_info("zcache: frontswap enabled using kernel " - "transcendent memory and xvmalloc\n"); + "transcendent memory and zsmalloc\n"); if (old_ops.init != NULL) pr_warning("zcache: frontswap_ops overridden"); } -- cgit v1.2.3-70-g09d2 From 0cb1f4b96092b9d91d4e50d5c77b424745cd1102 Mon Sep 17 00:00:00 2001 From: Jeffrey Huang Date: Wed, 8 Feb 2012 17:33:56 +0000 Subject: cnic: set error flag when iSCSI connection fails to speed up error recovery due to SPQ failures. The error flag will expedite the recovery process by skipping the timeouts. Signed-off-by: Jeffrey Huang Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/cnic.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index 7381460142e..e2365609a0b 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c @@ -3927,6 +3927,8 @@ static void cnic_cm_process_kcqe(struct cnic_dev *dev, struct kcqe *kcqe) case L4_KCQE_OPCODE_VALUE_CONNECT_COMPLETE: if (l4kcqe->status == 0) set_bit(SK_F_OFFLD_COMPLETE, &csk->flags); + else if (l4kcqe->status == L4_KCQE_COMPLETION_STATUS_NIC_ERROR) + set_bit(SK_F_HW_ERR, &csk->flags); smp_mb__before_clear_bit(); clear_bit(SK_F_OFFLD_SCHED, &csk->flags); -- cgit v1.2.3-70-g09d2 From 4cbbb04dc115423682349aa7466c8aeead825140 Mon Sep 17 00:00:00 2001 From: Eddie Wai Date: Wed, 8 Feb 2012 17:33:57 +0000 Subject: cnic: Update VLAN ID during ISCSI_UEVENT_PATH_UPDATE This will support the new VLAN attribute in the iSCSI iface file. Signed-off-by: Eddie Wai Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/cnic.c | 2 ++ drivers/net/ethernet/broadcom/cnic_if.h | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index e2365609a0b..df429959abd 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c @@ -380,6 +380,8 @@ static int cnic_iscsi_nl_msg_recv(struct cnic_dev *dev, u32 msg_type, if (cnic_in_use(csk) && test_bit(SK_F_CONNECT_START, &csk->flags)) { + csk->vlan_id = path_resp->vlan_id; + memcpy(csk->ha, path_resp->mac_addr, 6); if (test_bit(SK_F_IPV6, &csk->flags)) memcpy(&csk->src_ip[0], &path_resp->src.v6_addr, diff --git a/drivers/net/ethernet/broadcom/cnic_if.h b/drivers/net/ethernet/broadcom/cnic_if.h index 1517763d4e5..60deb84d36b 100644 --- a/drivers/net/ethernet/broadcom/cnic_if.h +++ b/drivers/net/ethernet/broadcom/cnic_if.h @@ -12,8 +12,8 @@ #ifndef CNIC_IF_H #define CNIC_IF_H -#define CNIC_MODULE_VERSION "2.5.8" -#define CNIC_MODULE_RELDATE "Jan 3, 2012" +#define CNIC_MODULE_VERSION "2.5.9" +#define CNIC_MODULE_RELDATE "Feb 8, 2012" #define CNIC_ULP_RDMA 0 #define CNIC_ULP_ISCSI 1 -- cgit v1.2.3-70-g09d2 From 12325280dfeba18164f9c47e226a40ab34e23ee7 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 9 Feb 2012 14:48:25 -0500 Subject: rtlwifi: Modify rtl_pci_init to return 0 on success Fixes problem where caller would think routine succeeded when it failed leading to divide by zero panic. (This also reverts an earlier attempt, commit 42bc0c97 "rtlwifi: Return correct failure code on error". -- JWL) Signed-off-by: Simon Graham Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/pci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 8a941b588a4..07dd38efe62 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -1492,10 +1492,10 @@ static int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev) if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "tx ring initialization failed\n"); - return 0; + return err; } - return 1; + return 0; } static int rtl_pci_start(struct ieee80211_hw *hw) @@ -1866,7 +1866,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, } /* Init PCI sw */ - err = !rtl_pci_init(hw, pdev); + err = rtl_pci_init(hw, pdev); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Failed to init PCI\n"); goto fail3; -- cgit v1.2.3-70-g09d2 From 50a4c4a94d24fe13167e3ab1dc1486623369c31a Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 9 Feb 2012 17:15:44 +0100 Subject: agp/intel-gtt: export the scratch page dma address To implement a PPGTT for drm/i915 that fully aliases the GTT, we also need to properly alias the scratch page. Reviewed-by: Ben Widawsky Tested-by: Chris Wilson Tested-by: Eugeni Dodonov Reviewed-by: Eugeni Dodonov Signed-Off-by: Daniel Vetter --- drivers/char/agp/intel-gtt.c | 9 ++++----- include/drm/intel-gtt.h | 2 ++ 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index c92424ca1a5..0a305acb037 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -76,7 +76,6 @@ static struct _intel_private { struct resource ifp_resource; int resource_valid; struct page *scratch_page; - dma_addr_t scratch_page_dma; } intel_private; #define INTEL_GTT_GEN intel_private.driver->gen @@ -306,9 +305,9 @@ static int intel_gtt_setup_scratch_page(void) if (pci_dma_mapping_error(intel_private.pcidev, dma_addr)) return -EINVAL; - intel_private.scratch_page_dma = dma_addr; + intel_private.base.scratch_page_dma = dma_addr; } else - intel_private.scratch_page_dma = page_to_phys(page); + intel_private.base.scratch_page_dma = page_to_phys(page); intel_private.scratch_page = page; @@ -631,7 +630,7 @@ static unsigned int intel_gtt_mappable_entries(void) static void intel_gtt_teardown_scratch_page(void) { set_pages_wb(intel_private.scratch_page, 1); - pci_unmap_page(intel_private.pcidev, intel_private.scratch_page_dma, + pci_unmap_page(intel_private.pcidev, intel_private.base.scratch_page_dma, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); put_page(intel_private.scratch_page); __free_page(intel_private.scratch_page); @@ -975,7 +974,7 @@ void intel_gtt_clear_range(unsigned int first_entry, unsigned int num_entries) unsigned int i; for (i = first_entry; i < (first_entry + num_entries); i++) { - intel_private.driver->write_entry(intel_private.scratch_page_dma, + intel_private.driver->write_entry(intel_private.base.scratch_page_dma, i, 0); } readl(intel_private.gtt+i-1); diff --git a/include/drm/intel-gtt.h b/include/drm/intel-gtt.h index b174620cc9b..6d4c77ac7d7 100644 --- a/include/drm/intel-gtt.h +++ b/include/drm/intel-gtt.h @@ -15,6 +15,8 @@ const struct intel_gtt { unsigned int needs_dmar : 1; /* Whether we idle the gpu before mapping/unmapping */ unsigned int do_idle_maps : 1; + /* Share the scratch page dma with ppgtts. */ + dma_addr_t scratch_page_dma; } *intel_gtt_get(void); void intel_gtt_chipset_flush(void); -- cgit v1.2.3-70-g09d2 From 428ccb21b740f603a6a1f08cbe6d935fb3177620 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 9 Feb 2012 17:15:45 +0100 Subject: agp/intel-gtt: export the gtt pagetable iomapping We need this because ppgtt page directory entries need to be in the global gtt pagetable. Reviewed-by: Ben Widawsky Tested-by: Chris Wilson Tested-by: Eugeni Dodonov Reviewed-by: Eugeni Dodonov Signed-Off-by: Daniel Vetter --- drivers/char/agp/intel-gtt.c | 1 + include/drm/intel-gtt.h | 2 ++ 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 0a305acb037..5cf47ac2d40 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -680,6 +680,7 @@ static int intel_gtt_init(void) iounmap(intel_private.registers); return -ENOMEM; } + intel_private.base.gtt = intel_private.gtt; global_cache_flush(); /* FIXME: ? */ diff --git a/include/drm/intel-gtt.h b/include/drm/intel-gtt.h index 6d4c77ac7d7..0a0001b9dc7 100644 --- a/include/drm/intel-gtt.h +++ b/include/drm/intel-gtt.h @@ -17,6 +17,8 @@ const struct intel_gtt { unsigned int do_idle_maps : 1; /* Share the scratch page dma with ppgtts. */ dma_addr_t scratch_page_dma; + /* for ppgtt PDE access */ + u32 __iomem *gtt; } *intel_gtt_get(void); void intel_gtt_chipset_flush(void); -- cgit v1.2.3-70-g09d2 From 1d2a314c97ceaf383de8e23cdde46729927d433c Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 9 Feb 2012 17:15:46 +0100 Subject: drm/i915: initialization/teardown for the aliasing ppgtt This just adds the setup and teardown code for the ppgtt PDE and the last-level pagetables, which are fixed for the entire lifetime, at least for the moment. v2: Kill the stray debug printk noted by and improve the pte definitions as suggested by Chris Wilson. v3: Clean up the aperture stealing code as noted by Ben Widawsky. v4: Paint the init code in a more pleasing colour as suggest by Chris Wilson. v5: Explain the magic numbers noticed by Ben Widawsky. Reviewed-by: Ben Widawsky Tested-by: Chris Wilson Tested-by: Eugeni Dodonov Reviewed-by: Eugeni Dodonov Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 41 ++++++++--- drivers/gpu/drm/i915/i915_drv.h | 18 +++++ drivers/gpu/drm/i915/i915_gem_gtt.c | 139 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_reg.h | 16 +++++ 4 files changed, 203 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index dfef9569f2a..039fbf4fae1 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1196,22 +1196,39 @@ static int i915_load_gem_init(struct drm_device *dev) /* Basic memrange allocator for stolen space */ drm_mm_init(&dev_priv->mm.stolen, 0, prealloc_size); - /* Let GEM Manage all of the aperture. - * - * However, leave one page at the end still bound to the scratch page. - * There are a number of places where the hardware apparently - * prefetches past the end of the object, and we've seen multiple - * hangs with the GPU head pointer stuck in a batchbuffer bound - * at the last page of the aperture. One page should be enough to - * keep any prefetching inside of the aperture. - */ - i915_gem_do_init(dev, 0, mappable_size, gtt_size - PAGE_SIZE); + if (HAS_ALIASING_PPGTT(dev)) { + /* PPGTT pdes are stolen from global gtt ptes, so shrink the + * aperture accordingly when using aliasing ppgtt. */ + gtt_size -= I915_PPGTT_PD_ENTRIES*PAGE_SIZE; + /* For paranoia keep the guard page in between. */ + gtt_size -= PAGE_SIZE; + + i915_gem_do_init(dev, 0, mappable_size, gtt_size); + + ret = i915_gem_init_aliasing_ppgtt(dev); + if (ret) + return ret; + } else { + /* Let GEM Manage all of the aperture. + * + * However, leave one page at the end still bound to the scratch + * page. There are a number of places where the hardware + * apparently prefetches past the end of the object, and we've + * seen multiple hangs with the GPU head pointer stuck in a + * batchbuffer bound at the last page of the aperture. One page + * should be enough to keep any prefetching inside of the + * aperture. + */ + i915_gem_do_init(dev, 0, mappable_size, gtt_size - PAGE_SIZE); + } mutex_lock(&dev->struct_mutex); ret = i915_gem_init_hw(dev); mutex_unlock(&dev->struct_mutex); - if (ret) + if (ret) { + i915_gem_cleanup_aliasing_ppgtt(dev); return ret; + } /* Try to set up FBC with a reasonable compressed buffer size */ if (I915_HAS_FBC(dev) && i915_powersave) { @@ -1298,6 +1315,7 @@ cleanup_gem: mutex_lock(&dev->struct_mutex); i915_gem_cleanup_ringbuffer(dev); mutex_unlock(&dev->struct_mutex); + i915_gem_cleanup_aliasing_ppgtt(dev); cleanup_vga_switcheroo: vga_switcheroo_unregister_client(dev->pdev); cleanup_vga_client: @@ -2184,6 +2202,7 @@ int i915_driver_unload(struct drm_device *dev) i915_gem_free_all_phys_object(dev); i915_gem_cleanup_ringbuffer(dev); mutex_unlock(&dev->struct_mutex); + i915_gem_cleanup_aliasing_ppgtt(dev); if (I915_HAS_FBC(dev) && i915_powersave) i915_cleanup_compression(dev); drm_mm_takedown(&dev_priv->mm.stolen); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 28740bc0200..03a9e49fe93 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -258,6 +258,16 @@ struct intel_device_info { u8 has_llc:1; }; +#define I915_PPGTT_PD_ENTRIES 512 +#define I915_PPGTT_PT_ENTRIES 1024 +struct i915_hw_ppgtt { + unsigned num_pd_entries; + struct page **pt_pages; + uint32_t pd_offset; + dma_addr_t *pt_dma_addr; + dma_addr_t scratch_page_dma_addr; +}; + enum no_fbc_reason { FBC_NO_OUTPUT, /* no outputs enabled to compress */ FBC_STOLEN_TOO_SMALL, /* not enough space to hold compressed buffers */ @@ -578,6 +588,9 @@ typedef struct drm_i915_private { struct io_mapping *gtt_mapping; int gtt_mtrr; + /** PPGTT used for aliasing the PPGTT with the GTT */ + struct i915_hw_ppgtt *aliasing_ppgtt; + struct shrinker inactive_shrinker; /** @@ -973,6 +986,8 @@ struct drm_i915_file_private { #define HAS_LLC(dev) (INTEL_INFO(dev)->has_llc) #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) +#define HAS_ALIASING_PPGTT(dev) (INTEL_INFO(dev)->gen >=6) + #define HAS_OVERLAY(dev) (INTEL_INFO(dev)->has_overlay) #define OVERLAY_NEEDS_PHYSICAL(dev) (INTEL_INFO(dev)->overlay_needs_physical) @@ -1232,6 +1247,9 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, enum i915_cache_level cache_level); /* i915_gem_gtt.c */ +int __must_check i915_gem_init_aliasing_ppgtt(struct drm_device *dev); +void i915_gem_cleanup_aliasing_ppgtt(struct drm_device *dev); + void i915_gem_restore_gtt_mappings(struct drm_device *dev); int __must_check i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj); void i915_gem_gtt_rebind_object(struct drm_i915_gem_object *obj, diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 11bddd5a5a6..f408f8c710d 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -29,6 +29,145 @@ #include "i915_trace.h" #include "intel_drv.h" +/* PPGTT support for Sandybdrige/Gen6 and later */ +static void i915_ppgtt_clear_range(struct i915_hw_ppgtt *ppgtt, + unsigned first_entry, + unsigned num_entries) +{ + int i, j; + uint32_t *pt_vaddr; + uint32_t scratch_pte; + + scratch_pte = GEN6_PTE_ADDR_ENCODE(ppgtt->scratch_page_dma_addr); + scratch_pte |= GEN6_PTE_VALID | GEN6_PTE_CACHE_LLC; + + for (i = 0; i < ppgtt->num_pd_entries; i++) { + pt_vaddr = kmap_atomic(ppgtt->pt_pages[i]); + + for (j = 0; j < I915_PPGTT_PT_ENTRIES; j++) + pt_vaddr[j] = scratch_pte; + + kunmap_atomic(pt_vaddr); + } + +} + +int i915_gem_init_aliasing_ppgtt(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct i915_hw_ppgtt *ppgtt; + uint32_t pd_entry; + unsigned first_pd_entry_in_global_pt; + uint32_t __iomem *pd_addr; + int i; + int ret = -ENOMEM; + + /* ppgtt PDEs reside in the global gtt pagetable, which has 512*1024 + * entries. For aliasing ppgtt support we just steal them at the end for + * now. */ + first_pd_entry_in_global_pt = 512*1024 - I915_PPGTT_PD_ENTRIES; + + ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL); + if (!ppgtt) + return ret; + + ppgtt->num_pd_entries = I915_PPGTT_PD_ENTRIES; + ppgtt->pt_pages = kzalloc(sizeof(struct page *)*ppgtt->num_pd_entries, + GFP_KERNEL); + if (!ppgtt->pt_pages) + goto err_ppgtt; + + for (i = 0; i < ppgtt->num_pd_entries; i++) { + ppgtt->pt_pages[i] = alloc_page(GFP_KERNEL); + if (!ppgtt->pt_pages[i]) + goto err_pt_alloc; + } + + if (dev_priv->mm.gtt->needs_dmar) { + ppgtt->pt_dma_addr = kzalloc(sizeof(dma_addr_t) + *ppgtt->num_pd_entries, + GFP_KERNEL); + if (!ppgtt->pt_dma_addr) + goto err_pt_alloc; + } + + pd_addr = dev_priv->mm.gtt->gtt + first_pd_entry_in_global_pt; + for (i = 0; i < ppgtt->num_pd_entries; i++) { + dma_addr_t pt_addr; + if (dev_priv->mm.gtt->needs_dmar) { + pt_addr = pci_map_page(dev->pdev, ppgtt->pt_pages[i], + 0, 4096, + PCI_DMA_BIDIRECTIONAL); + + if (pci_dma_mapping_error(dev->pdev, + pt_addr)) { + ret = -EIO; + goto err_pd_pin; + + } + ppgtt->pt_dma_addr[i] = pt_addr; + } else + pt_addr = page_to_phys(ppgtt->pt_pages[i]); + + pd_entry = GEN6_PDE_ADDR_ENCODE(pt_addr); + pd_entry |= GEN6_PDE_VALID; + + writel(pd_entry, pd_addr + i); + } + readl(pd_addr); + + ppgtt->scratch_page_dma_addr = dev_priv->mm.gtt->scratch_page_dma; + + i915_ppgtt_clear_range(ppgtt, 0, + ppgtt->num_pd_entries*I915_PPGTT_PT_ENTRIES); + + ppgtt->pd_offset = (first_pd_entry_in_global_pt)*sizeof(uint32_t); + + dev_priv->mm.aliasing_ppgtt = ppgtt; + + return 0; + +err_pd_pin: + if (ppgtt->pt_dma_addr) { + for (i--; i >= 0; i--) + pci_unmap_page(dev->pdev, ppgtt->pt_dma_addr[i], + 4096, PCI_DMA_BIDIRECTIONAL); + } +err_pt_alloc: + kfree(ppgtt->pt_dma_addr); + for (i = 0; i < ppgtt->num_pd_entries; i++) { + if (ppgtt->pt_pages[i]) + __free_page(ppgtt->pt_pages[i]); + } + kfree(ppgtt->pt_pages); +err_ppgtt: + kfree(ppgtt); + + return ret; +} + +void i915_gem_cleanup_aliasing_ppgtt(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; + int i; + + if (!ppgtt) + return; + + if (ppgtt->pt_dma_addr) { + for (i = 0; i < ppgtt->num_pd_entries; i++) + pci_unmap_page(dev->pdev, ppgtt->pt_dma_addr[i], + 4096, PCI_DMA_BIDIRECTIONAL); + } + + kfree(ppgtt->pt_dma_addr); + for (i = 0; i < ppgtt->num_pd_entries; i++) + __free_page(ppgtt->pt_pages[i]); + kfree(ppgtt->pt_pages); + kfree(ppgtt); +} + /* XXX kill agp_type! */ static unsigned int cache_level_to_agp_type(struct drm_device *dev, enum i915_cache_level cache_level) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 89816fe3f9d..92eb404d063 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -92,6 +92,22 @@ #define GEN6_GRDOM_MEDIA (1 << 2) #define GEN6_GRDOM_BLT (1 << 3) +/* PPGTT stuff */ +#define GEN6_GTT_ADDR_ENCODE(addr) ((addr) | (((addr) >> 28) & 0xff0)) + +#define GEN6_PDE_VALID (1 << 0) +#define GEN6_PDE_LARGE_PAGE (2 << 0) /* use 32kb pages */ +/* gen6+ has bit 11-4 for physical addr bit 39-32 */ +#define GEN6_PDE_ADDR_ENCODE(addr) GEN6_GTT_ADDR_ENCODE(addr) + +#define GEN6_PTE_VALID (1 << 0) +#define GEN6_PTE_UNCACHED (1 << 1) +#define GEN6_PTE_CACHE_LLC (2 << 1) +#define GEN6_PTE_CACHE_LLC_MLC (3 << 1) +#define GEN6_PTE_CACHE_BITS (3 << 1) +#define GEN6_PTE_GFDT (1 << 3) +#define GEN6_PTE_ADDR_ENCODE(addr) GEN6_GTT_ADDR_ENCODE(addr) + /* VGA stuff */ #define VGA_ST01_MDA 0x3ba -- cgit v1.2.3-70-g09d2 From 7bddb01fb9697afd5d39bb69dd9f782a28063101 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 9 Feb 2012 17:15:47 +0100 Subject: drm/i915: ppgtt binding/unbinding support This adds support to bind/unbind objects and wires it up. Objects are only put into the ppgtt when necessary, i.e. at execbuf time. Objects are still unconditionally put into the global gtt. v2: Kill the quick hack and explicitly pass cache_level to ppgtt_bind like for the global gtt function. Noticed by Chris Wilson. Reviewed-by: Ben Widawsky Tested-by: Chris Wilson Tested-by: Eugeni Dodonov Reviewed-by: Eugeni Dodonov Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 7 ++ drivers/gpu/drm/i915/i915_gem.c | 11 +++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 9 ++ drivers/gpu/drm/i915/i915_gem_gtt.c | 146 +++++++++++++++++++++++++++-- 4 files changed, 167 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 03a9e49fe93..35c8b531639 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -850,6 +850,8 @@ struct drm_i915_gem_object { unsigned int cache_level:2; + unsigned int has_aliasing_ppgtt_mapping:1; + struct page **pages; /** @@ -1249,6 +1251,11 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, /* i915_gem_gtt.c */ int __must_check i915_gem_init_aliasing_ppgtt(struct drm_device *dev); void i915_gem_cleanup_aliasing_ppgtt(struct drm_device *dev); +void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt, + struct drm_i915_gem_object *obj, + enum i915_cache_level cache_level); +void i915_ppgtt_unbind_object(struct i915_hw_ppgtt *ppgtt, + struct drm_i915_gem_object *obj); void i915_gem_restore_gtt_mappings(struct drm_device *dev); int __must_check i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 27fe07a2fd3..59092997bcf 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2020,6 +2020,7 @@ static void i915_gem_object_finish_gtt(struct drm_i915_gem_object *obj) int i915_gem_object_unbind(struct drm_i915_gem_object *obj) { + drm_i915_private_t *dev_priv = obj->base.dev->dev_private; int ret = 0; if (obj->gtt_space == NULL) @@ -2064,6 +2065,11 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj) trace_i915_gem_object_unbind(obj); i915_gem_gtt_unbind_object(obj); + if (obj->has_aliasing_ppgtt_mapping) { + i915_ppgtt_unbind_object(dev_priv->mm.aliasing_ppgtt, obj); + obj->has_aliasing_ppgtt_mapping = 0; + } + i915_gem_object_put_pages_gtt(obj); list_del_init(&obj->gtt_list); @@ -2882,6 +2888,8 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, enum i915_cache_level cache_level) { + struct drm_device *dev = obj->base.dev; + drm_i915_private_t *dev_priv = dev->dev_private; int ret; if (obj->cache_level == cache_level) @@ -2910,6 +2918,9 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, } i915_gem_gtt_rebind_object(obj, cache_level); + if (obj->has_aliasing_ppgtt_mapping) + i915_ppgtt_bind_object(dev_priv->mm.aliasing_ppgtt, + obj, cache_level); } if (cache_level == I915_CACHE_NONE) { diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index b964998b5e2..9835b2efd93 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -515,6 +515,7 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, struct drm_file *file, struct list_head *objects) { + drm_i915_private_t *dev_priv = ring->dev->dev_private; struct drm_i915_gem_object *obj; int ret, retry; bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4; @@ -623,6 +624,14 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, } i915_gem_object_unpin(obj); + + /* ... and ensure ppgtt mapping exist if needed. */ + if (dev_priv->mm.aliasing_ppgtt && !obj->has_aliasing_ppgtt_mapping) { + i915_ppgtt_bind_object(dev_priv->mm.aliasing_ppgtt, + obj, obj->cache_level); + + obj->has_aliasing_ppgtt_mapping = 1; + } } if (ret != -ENOSPC || retry > 1) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index f408f8c710d..2eacd78bb93 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -34,22 +34,31 @@ static void i915_ppgtt_clear_range(struct i915_hw_ppgtt *ppgtt, unsigned first_entry, unsigned num_entries) { - int i, j; uint32_t *pt_vaddr; uint32_t scratch_pte; + unsigned act_pd = first_entry / I915_PPGTT_PT_ENTRIES; + unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES; + unsigned last_pte, i; scratch_pte = GEN6_PTE_ADDR_ENCODE(ppgtt->scratch_page_dma_addr); scratch_pte |= GEN6_PTE_VALID | GEN6_PTE_CACHE_LLC; - for (i = 0; i < ppgtt->num_pd_entries; i++) { - pt_vaddr = kmap_atomic(ppgtt->pt_pages[i]); + while (num_entries) { + last_pte = first_pte + num_entries; + if (last_pte > I915_PPGTT_PT_ENTRIES) + last_pte = I915_PPGTT_PT_ENTRIES; + + pt_vaddr = kmap_atomic(ppgtt->pt_pages[act_pd]); - for (j = 0; j < I915_PPGTT_PT_ENTRIES; j++) - pt_vaddr[j] = scratch_pte; + for (i = first_pte; i < last_pte; i++) + pt_vaddr[i] = scratch_pte; kunmap_atomic(pt_vaddr); - } + num_entries -= last_pte - first_pte; + first_pte = 0; + act_pd++; + } } int i915_gem_init_aliasing_ppgtt(struct drm_device *dev) @@ -168,6 +177,131 @@ void i915_gem_cleanup_aliasing_ppgtt(struct drm_device *dev) kfree(ppgtt); } +static void i915_ppgtt_insert_sg_entries(struct i915_hw_ppgtt *ppgtt, + struct scatterlist *sg_list, + unsigned sg_len, + unsigned first_entry, + uint32_t pte_flags) +{ + uint32_t *pt_vaddr, pte; + unsigned act_pd = first_entry / I915_PPGTT_PT_ENTRIES; + unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES; + unsigned i, j, m, segment_len; + dma_addr_t page_addr; + struct scatterlist *sg; + + /* init sg walking */ + sg = sg_list; + i = 0; + segment_len = sg_dma_len(sg) >> PAGE_SHIFT; + m = 0; + + while (i < sg_len) { + pt_vaddr = kmap_atomic(ppgtt->pt_pages[act_pd]); + + for (j = first_pte; j < I915_PPGTT_PT_ENTRIES; j++) { + page_addr = sg_dma_address(sg) + (m << PAGE_SHIFT); + pte = GEN6_PTE_ADDR_ENCODE(page_addr); + pt_vaddr[j] = pte | pte_flags; + + /* grab the next page */ + m++; + if (m == segment_len) { + sg = sg_next(sg); + i++; + if (i == sg_len) + break; + + segment_len = sg_dma_len(sg) >> PAGE_SHIFT; + m = 0; + } + } + + kunmap_atomic(pt_vaddr); + + first_pte = 0; + act_pd++; + } +} + +static void i915_ppgtt_insert_pages(struct i915_hw_ppgtt *ppgtt, + unsigned first_entry, unsigned num_entries, + struct page **pages, uint32_t pte_flags) +{ + uint32_t *pt_vaddr, pte; + unsigned act_pd = first_entry / I915_PPGTT_PT_ENTRIES; + unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES; + unsigned last_pte, i; + dma_addr_t page_addr; + + while (num_entries) { + last_pte = first_pte + num_entries; + last_pte = min_t(unsigned, last_pte, I915_PPGTT_PT_ENTRIES); + + pt_vaddr = kmap_atomic(ppgtt->pt_pages[act_pd]); + + for (i = first_pte; i < last_pte; i++) { + page_addr = page_to_phys(*pages); + pte = GEN6_PTE_ADDR_ENCODE(page_addr); + pt_vaddr[i] = pte | pte_flags; + + pages++; + } + + kunmap_atomic(pt_vaddr); + + num_entries -= last_pte - first_pte; + first_pte = 0; + act_pd++; + } +} + +void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt, + struct drm_i915_gem_object *obj, + enum i915_cache_level cache_level) +{ + struct drm_device *dev = obj->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t pte_flags = GEN6_PTE_VALID; + + switch (cache_level) { + case I915_CACHE_LLC_MLC: + pte_flags |= GEN6_PTE_CACHE_LLC_MLC; + break; + case I915_CACHE_LLC: + pte_flags |= GEN6_PTE_CACHE_LLC; + break; + case I915_CACHE_NONE: + pte_flags |= GEN6_PTE_UNCACHED; + break; + default: + BUG(); + } + + if (dev_priv->mm.gtt->needs_dmar) { + BUG_ON(!obj->sg_list); + + i915_ppgtt_insert_sg_entries(ppgtt, + obj->sg_list, + obj->num_sg, + obj->gtt_space->start >> PAGE_SHIFT, + pte_flags); + } else + i915_ppgtt_insert_pages(ppgtt, + obj->gtt_space->start >> PAGE_SHIFT, + obj->base.size >> PAGE_SHIFT, + obj->pages, + pte_flags); +} + +void i915_ppgtt_unbind_object(struct i915_hw_ppgtt *ppgtt, + struct drm_i915_gem_object *obj) +{ + i915_ppgtt_clear_range(ppgtt, + obj->gtt_space->start >> PAGE_SHIFT, + obj->base.size >> PAGE_SHIFT); +} + /* XXX kill agp_type! */ static unsigned int cache_level_to_agp_type(struct drm_device *dev, enum i915_cache_level cache_level) -- cgit v1.2.3-70-g09d2 From 5eb719cdbe4723729ff28d6aa1ebd3bf2392d7e3 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 9 Feb 2012 17:15:48 +0100 Subject: drm/i915: ppgtt register definitions Split out for easier cross-checking of the boring pieces with bspec. Reviewed-by: Ben Widawsky Tested-by: Chris Wilson Tested-by: Eugeni Dodonov Reviewed-by: Eugeni Dodonov Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 92eb404d063..341ce44e732 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -86,6 +86,13 @@ #define GEN6_MBC_SNPCR_LOW (2<<21) #define GEN6_MBC_SNPCR_MIN (3<<21) /* only 1/16th of the cache is shared */ +#define GEN6_MBCTL 0x0907c +#define GEN6_MBCTL_ENABLE_BOOT_FETCH (1 << 4) +#define GEN6_MBCTL_CTX_FETCH_NEEDED (1 << 3) +#define GEN6_MBCTL_BME_UPDATE_ENABLE (1 << 2) +#define GEN6_MBCTL_MAE_UPDATE_ENABLE (1 << 1) +#define GEN6_MBCTL_BOOT_FETCH_MECH (1 << 0) + #define GEN6_GDRST 0x941c #define GEN6_GRDOM_FULL (1 << 0) #define GEN6_GRDOM_RENDER (1 << 1) @@ -108,6 +115,16 @@ #define GEN6_PTE_GFDT (1 << 3) #define GEN6_PTE_ADDR_ENCODE(addr) GEN6_GTT_ADDR_ENCODE(addr) +#define RING_PP_DIR_BASE(ring) ((ring)->mmio_base+0x228) +#define RING_PP_DIR_BASE_READ(ring) ((ring)->mmio_base+0x518) +#define RING_PP_DIR_DCLV(ring) ((ring)->mmio_base+0x220) +#define PP_DIR_DCLV_2G 0xffffffff + +#define GAM_ECOCHK 0x4090 +#define ECOCHK_SNB_BIT (1<<10) +#define ECOCHK_PPGTT_CACHE64B (0x3<<3) +#define ECOCHK_PPGTT_CACHE4B (0x0<<3) + /* VGA stuff */ #define VGA_ST01_MDA 0x3ba @@ -422,6 +439,7 @@ #define GFX_MODE 0x02520 #define GFX_MODE_GEN7 0x0229c +#define RING_MODE_GEN7(ring) ((ring)->mmio_base+0x29c) #define GFX_RUN_LIST_ENABLE (1<<15) #define GFX_TLB_INVALIDATE_ALWAYS (1<<13) #define GFX_SURFACE_FAULT_ENABLE (1<<12) -- cgit v1.2.3-70-g09d2 From 3cf17fc522ee081f7cb2ab325e6c697ca12005e4 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 9 Feb 2012 17:15:49 +0100 Subject: drm/i915: ppgtt debugfs info This was pretty usefull for debugging, might be useful for diagnosing issues. Reviewed-by: Ben Widawsky Tested-by: Chris Wilson Tested-by: Eugeni Dodonov Reviewed-by: Eugeni Dodonov Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 38 +++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index f3fe2f872d5..5d24581452e 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1447,6 +1447,43 @@ static int i915_swizzle_info(struct seq_file *m, void *data) return 0; } +static int i915_ppgtt_info(struct seq_file *m, void *data) +{ + struct drm_info_node *node = (struct drm_info_node *) m->private; + struct drm_device *dev = node->minor->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_ring_buffer *ring; + int i, ret; + + + ret = mutex_lock_interruptible(&dev->struct_mutex); + if (ret) + return ret; + if (INTEL_INFO(dev)->gen == 6) + seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(GFX_MODE)); + + for (i = 0; i < I915_NUM_RINGS; i++) { + ring = &dev_priv->ring[i]; + + seq_printf(m, "%s\n", ring->name); + if (INTEL_INFO(dev)->gen == 7) + seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(RING_MODE_GEN7(ring))); + seq_printf(m, "PP_DIR_BASE: 0x%08x\n", I915_READ(RING_PP_DIR_BASE(ring))); + seq_printf(m, "PP_DIR_BASE_READ: 0x%08x\n", I915_READ(RING_PP_DIR_BASE_READ(ring))); + seq_printf(m, "PP_DIR_DCLV: 0x%08x\n", I915_READ(RING_PP_DIR_DCLV(ring))); + } + if (dev_priv->mm.aliasing_ppgtt) { + struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; + + seq_printf(m, "aliasing PPGTT:\n"); + seq_printf(m, "pd gtt offset: 0x%08x\n", ppgtt->pd_offset); + } + seq_printf(m, "ECOCHK: 0x%08x\n", I915_READ(GAM_ECOCHK)); + mutex_unlock(&dev->struct_mutex); + + return 0; +} + static int i915_debugfs_common_open(struct inode *inode, struct file *filp) @@ -1788,6 +1825,7 @@ static struct drm_info_list i915_debugfs_list[] = { {"i915_context_status", i915_context_status, 0}, {"i915_gen6_forcewake_count", i915_gen6_forcewake_count_info, 0}, {"i915_swizzle_info", i915_swizzle_info, 0}, + {"i915_ppgtt_info", i915_ppgtt_info, 0}, }; #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) -- cgit v1.2.3-70-g09d2 From e21af88d39796c907c38648c824be3d646ffbe35 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 9 Feb 2012 20:53:27 +0100 Subject: drm/i915: enable ppgtt We want to unconditionally enable ppgtt for two reasons: - Windows uses this on snb and later. - We need the basic hw support to work before we can think about real per-process address spaces and other cool features we want. But Chris Wilson was complaining all over irc and intel-gfx that this will blow up if we don't have a module option to disable it. Hence add one, to prevent this. ppgtt support seems to slightly change the timings and make crashy things slightly more or less crashy. Now in my testing and the testing this got on troublesome snb machines, it seems to have improved things only. But on ivb it makes quite a few crashes happen much more often, see https://bugs.freedesktop.org/show_bug.cgi?id=41353 Luckily Eugeni Dodonov seems to have a set of workarounds that fix this issue. v2: Don't try to enable ppgtt on pre-snb. v3: Pimp commit message and make Chris Wilson less grumpy by adding a module option. v4: New try at making Chris Wilson happy. Reviewed-by: Ben Widawsky Acked-by: Chris Wilson Tested-by: Chris Wilson Tested-by: Eugeni Dodonov Reviewed-by: Eugeni Dodonov Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 2 +- drivers/gpu/drm/i915/i915_drv.c | 7 +++++++ drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_gem.c | 39 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 49 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 039fbf4fae1..40bfafa13b7 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1196,7 +1196,7 @@ static int i915_load_gem_init(struct drm_device *dev) /* Basic memrange allocator for stolen space */ drm_mm_init(&dev_priv->mm.stolen, 0, prealloc_size); - if (HAS_ALIASING_PPGTT(dev)) { + if (i915_enable_ppgtt && HAS_ALIASING_PPGTT(dev)) { /* PPGTT pdes are stolen from global gtt ptes, so shrink the * aperture accordingly when using aliasing ppgtt. */ gtt_size -= I915_PPGTT_PD_ENTRIES*PAGE_SIZE; diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 12ddf47b818..d92c92dea4e 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -103,6 +103,11 @@ MODULE_PARM_DESC(enable_hangcheck, "WARNING: Disabling this can cause system wide hangs. " "(default: true)"); +bool i915_enable_ppgtt __read_mostly = 1; +module_param_named(i915_enable_ppgtt, i915_enable_ppgtt, bool, 0600); +MODULE_PARM_DESC(i915_enable_ppgtt, + "Enable PPGTT (default: true)"); + static struct drm_driver driver; extern int intel_agp_enabled; @@ -694,6 +699,8 @@ int i915_reset(struct drm_device *dev, u8 flags) if (HAS_BLT(dev)) dev_priv->ring[BCS].init(&dev_priv->ring[BCS]); + i915_gem_init_ppgtt(dev); + mutex_unlock(&dev->struct_mutex); drm_irq_uninstall(dev); drm_mode_config_reset(dev); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 35c8b531639..45b609e6b13 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1032,6 +1032,7 @@ extern int i915_vbt_sdvo_panel_type __read_mostly; extern int i915_enable_rc6 __read_mostly; extern int i915_enable_fbc __read_mostly; extern bool i915_enable_hangcheck __read_mostly; +extern bool i915_enable_ppgtt __read_mostly; extern int i915_suspend(struct drm_device *dev, pm_message_t state); extern int i915_resume(struct drm_device *dev); @@ -1210,6 +1211,7 @@ int __must_check i915_gem_object_set_domain(struct drm_i915_gem_object *obj, int __must_check i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj); int __must_check i915_gem_init_hw(struct drm_device *dev); void i915_gem_init_swizzling(struct drm_device *dev); +void i915_gem_init_ppgtt(struct drm_device *dev); void i915_gem_cleanup_ringbuffer(struct drm_device *dev); void i915_gem_do_init(struct drm_device *dev, unsigned long start, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 59092997bcf..f1193b19433 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3712,6 +3712,43 @@ void i915_gem_init_swizzling(struct drm_device *dev) else I915_WRITE(ARB_MODE, ARB_MODE_ENABLE(ARB_MODE_SWIZZLE_IVB)); } + +void i915_gem_init_ppgtt(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + uint32_t pd_offset; + struct intel_ring_buffer *ring; + int i; + + if (!dev_priv->mm.aliasing_ppgtt) + return; + + pd_offset = dev_priv->mm.aliasing_ppgtt->pd_offset; + pd_offset /= 64; /* in cachelines, */ + pd_offset <<= 16; + + if (INTEL_INFO(dev)->gen == 6) { + uint32_t ecochk = I915_READ(GAM_ECOCHK); + I915_WRITE(GAM_ECOCHK, ecochk | ECOCHK_SNB_BIT | + ECOCHK_PPGTT_CACHE64B); + I915_WRITE(GFX_MODE, GFX_MODE_ENABLE(GFX_PPGTT_ENABLE)); + } else if (INTEL_INFO(dev)->gen >= 7) { + I915_WRITE(GAM_ECOCHK, ECOCHK_PPGTT_CACHE64B); + /* GFX_MODE is per-ring on gen7+ */ + } + + for (i = 0; i < I915_NUM_RINGS; i++) { + ring = &dev_priv->ring[i]; + + if (INTEL_INFO(dev)->gen >= 7) + I915_WRITE(RING_MODE_GEN7(ring), + GFX_MODE_ENABLE(GFX_PPGTT_ENABLE)); + + I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G); + I915_WRITE(RING_PP_DIR_BASE(ring), pd_offset); + } +} + int i915_gem_init_hw(struct drm_device *dev) { @@ -3738,6 +3775,8 @@ i915_gem_init_hw(struct drm_device *dev) dev_priv->next_seqno = 1; + i915_gem_init_ppgtt(dev); + return 0; cleanup_bsd_ring: -- cgit v1.2.3-70-g09d2 From a7ccf3775219bfcb2e0df73619abbe13abc6408f Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Tue, 7 Feb 2012 22:33:56 +0900 Subject: char: Fix typo in viotape.c Correct spelling "allocat" to "allocate" in drivers/char/viotape.c Signed-off-by: Masanari Iida Signed-off-by: Jiri Kosina --- drivers/char/viotape.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index ad6e64a2912..8b34c65511e 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c @@ -976,7 +976,7 @@ int __init viotap_init(void) tape_class = class_create(THIS_MODULE, "tape"); if (IS_ERR(tape_class)) { - printk(VIOTAPE_KERN_WARN "Unable to allocat class\n"); + printk(VIOTAPE_KERN_WARN "Unable to allocate class\n"); ret = PTR_ERR(tape_class); goto unreg_chrdev; } -- cgit v1.2.3-70-g09d2 From 31cf913da3664f4804a346792937a3bad15cdede Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Tue, 7 Feb 2012 23:55:52 +0900 Subject: char: Fix typo in tlclk.c Correct spelling "telclk_interrup" to "telclk_interrupt" in drivers/char/tlclk.c Signed-off-by: Masanari Iida Signed-off-by: Jiri Kosina --- drivers/char/tlclk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c index 0c964cdcc22..ce29e7cce52 100644 --- a/drivers/char/tlclk.c +++ b/drivers/char/tlclk.c @@ -797,7 +797,7 @@ static int __init tlclk_init(void) telclk_interrupt = (inb(TLCLK_REG7) & 0x0f); if (0x0F == telclk_interrupt ) { /* not MCPBL0010 ? */ - printk(KERN_ERR "telclk_interrup = 0x%x non-mcpbl0010 hw.\n", + printk(KERN_ERR "telclk_interrupt = 0x%x non-mcpbl0010 hw.\n", telclk_interrupt); ret = -ENXIO; goto out3; -- cgit v1.2.3-70-g09d2 From d4b48ba395a6289fbd72c1b883cc52ee680d967a Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Wed, 8 Feb 2012 20:28:23 +0900 Subject: mantis: Fix typo in mantis_hif.c Correct typo "Adater" to "Adapter" in drivers/media/dvb/mantis/mantis_hif.c Signed-off-by: Masanari Iida Signed-off-by: Jiri Kosina --- drivers/media/dvb/mantis/mantis_hif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/mantis/mantis_hif.c b/drivers/media/dvb/mantis/mantis_hif.c index 672cf4d2462..10c68df7e16 100644 --- a/drivers/media/dvb/mantis/mantis_hif.c +++ b/drivers/media/dvb/mantis/mantis_hif.c @@ -76,7 +76,7 @@ static int mantis_hif_write_wait(struct mantis_ca *ca) udelay(500); timeout++; if (timeout > 100) { - dprintk(MANTIS_ERROR, 1, "Adater(%d) Slot(0): Write operation timed out!", mantis->num); + dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Write operation timed out!", mantis->num); rc = -ETIMEDOUT; break; } -- cgit v1.2.3-70-g09d2 From 58642a24987195f6c572bfa0849824815cc0e68c Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Thu, 9 Feb 2012 23:23:33 +0900 Subject: aeroflex: Fix typo in greth.c Correct spelling "reseting" to "resetting" in drivers/net/ethernet/aeroflex/greth.c Signed-off-by: Masanari Iida Signed-off-by: Jiri Kosina --- drivers/net/ethernet/aeroflex/greth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c index c885aa905de..15d303acf58 100644 --- a/drivers/net/ethernet/aeroflex/greth.c +++ b/drivers/net/ethernet/aeroflex/greth.c @@ -1422,7 +1422,7 @@ static int __devinit greth_of_probe(struct platform_device *ofdev) SET_NETDEV_DEV(dev, greth->dev); if (netif_msg_probe(greth)) - dev_dbg(greth->dev, "reseting controller.\n"); + dev_dbg(greth->dev, "resetting controller.\n"); /* Reset the controller. */ GRETH_REGSAVE(regs->control, GRETH_RESET); -- cgit v1.2.3-70-g09d2 From 7367d99b30a2eb385cea33aa8846d2f0502da2da Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Thu, 9 Feb 2012 23:37:43 +0900 Subject: SRP: Fix typo in ib_srpt.c Correct spelling "alocate" to "allocate" in drivers/infiniband/ulp/srpt/ib_srpt.c Signed-off-by: Masanari Iida Signed-off-by: Jiri Kosina --- drivers/infiniband/ulp/srpt/ib_srpt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index cd5d05e22a7..368f956891b 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -3450,7 +3450,7 @@ static struct se_node_acl *srpt_alloc_fabric_acl(struct se_portal_group *se_tpg) nacl = kzalloc(sizeof(struct srpt_node_acl), GFP_KERNEL); if (!nacl) { - printk(KERN_ERR "Unable to alocate struct srpt_node_acl\n"); + printk(KERN_ERR "Unable to allocate struct srpt_node_acl\n"); return NULL; } -- cgit v1.2.3-70-g09d2 From 4bcf053baf6b255e8c82c7ecd0d15954adb0379b Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Tue, 31 Jan 2012 06:37:59 +0000 Subject: e1000e: remove test that is always false warning: comparison of unsigned expression < 0 is always false Remove an unnecessary test that is reported when compiling driver with W=1. The test is unnecessary because Intel wired GbE hardware older (i.e. less) than 82571 is not supported by this driver. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/mac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/mac.c b/drivers/net/ethernet/intel/e1000e/mac.c index e1cf1072f31..33d1b9e3c8d 100644 --- a/drivers/net/ethernet/intel/e1000e/mac.c +++ b/drivers/net/ethernet/intel/e1000e/mac.c @@ -174,8 +174,8 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) if (ret_val) goto out; - /* not supported on older hardware or 82573 */ - if ((hw->mac.type < e1000_82571) || (hw->mac.type == e1000_82573)) + /* not supported on 82573 */ + if (hw->mac.type == e1000_82573) goto out; ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1, -- cgit v1.2.3-70-g09d2 From fe1e980f24697edb7d4e17cd74bbeae4a0388525 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Tue, 31 Jan 2012 06:37:54 +0000 Subject: e1000e: remove unnecessary returns from void functions ...and convert some goto's which simply return to just return. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/ich8lan.c | 3 --- drivers/net/ethernet/intel/e1000e/mac.c | 8 ++------ drivers/net/ethernet/intel/e1000e/netdev.c | 7 ++----- 3 files changed, 4 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 5061d4ded6e..942f4da86fb 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -1762,7 +1762,6 @@ static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate) extcnf_ctrl &= ~E1000_EXTCNF_CTRL_GATE_PHY_CFG; ew32(EXTCNF_CTRL, extcnf_ctrl); - return; } /** @@ -3768,8 +3767,6 @@ void e1000_resume_workarounds_pchlan(struct e1000_hw *hw) release: hw->phy.ops.release(hw); - - return; } /** diff --git a/drivers/net/ethernet/intel/e1000e/mac.c b/drivers/net/ethernet/intel/e1000e/mac.c index 33d1b9e3c8d..be8335aead5 100644 --- a/drivers/net/ethernet/intel/e1000e/mac.c +++ b/drivers/net/ethernet/intel/e1000e/mac.c @@ -1661,7 +1661,7 @@ void e1000e_reset_adaptive(struct e1000_hw *hw) if (!mac->adaptive_ifs) { e_dbg("Not in Adaptive IFS mode!\n"); - goto out; + return; } mac->current_ifs_val = 0; @@ -1672,8 +1672,6 @@ void e1000e_reset_adaptive(struct e1000_hw *hw) mac->in_ifs_mode = false; ew32(AIT, 0); -out: - return; } /** @@ -1689,7 +1687,7 @@ void e1000e_update_adaptive(struct e1000_hw *hw) if (!mac->adaptive_ifs) { e_dbg("Not in Adaptive IFS mode!\n"); - goto out; + return; } if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) { @@ -1712,6 +1710,4 @@ void e1000e_update_adaptive(struct e1000_hw *hw) ew32(AIT, 0); } } -out: - return; } diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 293a7606e0f..7ccd5f3cef6 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -221,7 +221,7 @@ static void e1000e_dump(struct e1000_adapter *adapter) /* Print Tx Ring Summary */ if (!netdev || !netif_running(netdev)) - goto exit; + return; dev_info(&adapter->pdev->dev, "Tx Ring Summary\n"); pr_info("Queue [NTU] [NTC] [bi(ntc)->dma ] leng ntw timestamp\n"); @@ -308,7 +308,7 @@ rx_ring_summary: /* Print Rx Ring */ if (!netif_msg_rx_status(adapter)) - goto exit; + return; dev_info(&adapter->pdev->dev, "Rx Ring Dump\n"); switch (adapter->rx_ps_pages) { @@ -449,9 +449,6 @@ rx_ring_summary: } } } - -exit: - return; } /** -- cgit v1.2.3-70-g09d2 From 668018d74762741c3fe5a54f0eea1bd65dcabd7e Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Tue, 31 Jan 2012 07:02:56 +0000 Subject: e1000e: remove unnecessary parentheses Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/82571.c | 2 +- drivers/net/ethernet/intel/e1000e/ethtool.c | 4 ++-- drivers/net/ethernet/intel/e1000e/mac.c | 6 +++--- drivers/net/ethernet/intel/e1000e/manage.c | 2 +- drivers/net/ethernet/intel/e1000e/phy.c | 10 +++++----- 5 files changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/82571.c b/drivers/net/ethernet/intel/e1000e/82571.c index 4cadcc76ad5..7ef4711a32b 100644 --- a/drivers/net/ethernet/intel/e1000e/82571.c +++ b/drivers/net/ethernet/intel/e1000e/82571.c @@ -1865,7 +1865,7 @@ static void e1000_power_down_phy_copper_82571(struct e1000_hw *hw) struct e1000_phy_info *phy = &hw->phy; struct e1000_mac_info *mac = &hw->mac; - if (!(phy->ops.check_reset_block)) + if (!phy->ops.check_reset_block) return; /* If the management interface is not enabled, then power down */ diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index f4dc0fa9d9b..b1f5d7491b5 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -1088,7 +1088,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) tx_ring->buffer_info = kcalloc(tx_ring->count, sizeof(struct e1000_buffer), GFP_KERNEL); - if (!(tx_ring->buffer_info)) { + if (!tx_ring->buffer_info) { ret_val = 1; goto err_nomem; } @@ -1150,7 +1150,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) rx_ring->buffer_info = kcalloc(rx_ring->count, sizeof(struct e1000_buffer), GFP_KERNEL); - if (!(rx_ring->buffer_info)) { + if (!rx_ring->buffer_info) { ret_val = 5; goto err_nomem; } diff --git a/drivers/net/ethernet/intel/e1000e/mac.c b/drivers/net/ethernet/intel/e1000e/mac.c index be8335aead5..0d63c3e1971 100644 --- a/drivers/net/ethernet/intel/e1000e/mac.c +++ b/drivers/net/ethernet/intel/e1000e/mac.c @@ -511,8 +511,8 @@ s32 e1000e_check_for_fiber_link(struct e1000_hw *hw) * was just plugged in. The autoneg_failed flag does this. */ /* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */ - if ((ctrl & E1000_CTRL_SWDPIN1) && (!(status & E1000_STATUS_LU)) && - (!(rxcw & E1000_RXCW_C))) { + if ((ctrl & E1000_CTRL_SWDPIN1) && !(status & E1000_STATUS_LU) && + !(rxcw & E1000_RXCW_C)) { if (mac->autoneg_failed == 0) { mac->autoneg_failed = 1; return 0; @@ -577,7 +577,7 @@ s32 e1000e_check_for_serdes_link(struct e1000_hw *hw) * time to complete. */ /* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */ - if ((!(status & E1000_STATUS_LU)) && (!(rxcw & E1000_RXCW_C))) { + if (!(status & E1000_STATUS_LU) && !(rxcw & E1000_RXCW_C)) { if (mac->autoneg_failed == 0) { mac->autoneg_failed = 1; return 0; diff --git a/drivers/net/ethernet/intel/e1000e/manage.c b/drivers/net/ethernet/intel/e1000e/manage.c index 6594dbf248b..c54caf6e580 100644 --- a/drivers/net/ethernet/intel/e1000e/manage.c +++ b/drivers/net/ethernet/intel/e1000e/manage.c @@ -78,7 +78,7 @@ static s32 e1000_mng_enable_host_if(struct e1000_hw *hw) u32 hicr; u8 i; - if (!(hw->mac.arc_subsystem_valid)) { + if (!hw->mac.arc_subsystem_valid) { e_dbg("ARC subsystem not valid.\n"); return -E1000_ERR_HOST_INTERFACE_COMMAND; } diff --git a/drivers/net/ethernet/intel/e1000e/phy.c b/drivers/net/ethernet/intel/e1000e/phy.c index 8dd2ff03f1f..e8ad0804702 100644 --- a/drivers/net/ethernet/intel/e1000e/phy.c +++ b/drivers/net/ethernet/intel/e1000e/phy.c @@ -132,7 +132,7 @@ s32 e1000e_get_phy_id(struct e1000_hw *hw) u16 phy_id; u16 retry_count = 0; - if (!(phy->ops.read_reg)) + if (!phy->ops.read_reg) goto out; while (retry_count < 2) { @@ -382,7 +382,7 @@ static s32 __e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data, s32 ret_val = 0; if (!locked) { - if (!(hw->phy.ops.acquire)) + if (!hw->phy.ops.acquire) goto out; ret_val = hw->phy.ops.acquire(hw); @@ -453,7 +453,7 @@ static s32 __e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data, s32 ret_val = 0; if (!locked) { - if (!(hw->phy.ops.acquire)) + if (!hw->phy.ops.acquire) goto out; ret_val = hw->phy.ops.acquire(hw); @@ -526,7 +526,7 @@ static s32 __e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data, s32 ret_val = 0; if (!locked) { - if (!(hw->phy.ops.acquire)) + if (!hw->phy.ops.acquire) goto out; ret_val = hw->phy.ops.acquire(hw); @@ -599,7 +599,7 @@ static s32 __e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data, s32 ret_val = 0; if (!locked) { - if (!(hw->phy.ops.acquire)) + if (!hw->phy.ops.acquire) goto out; ret_val = hw->phy.ops.acquire(hw); -- cgit v1.2.3-70-g09d2 From 07914ee3ccbf93ce688f1aaba15d8b01f19c5d77 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Tue, 31 Jan 2012 07:03:02 +0000 Subject: e1000e: use true/false for bool autoneg_false v2 - replaced mac->autoneg_failed == false with !mac->autoneg_failed Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/mac.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/mac.c b/drivers/net/ethernet/intel/e1000e/mac.c index 0d63c3e1971..83f93684dc2 100644 --- a/drivers/net/ethernet/intel/e1000e/mac.c +++ b/drivers/net/ethernet/intel/e1000e/mac.c @@ -513,8 +513,8 @@ s32 e1000e_check_for_fiber_link(struct e1000_hw *hw) /* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */ if ((ctrl & E1000_CTRL_SWDPIN1) && !(status & E1000_STATUS_LU) && !(rxcw & E1000_RXCW_C)) { - if (mac->autoneg_failed == 0) { - mac->autoneg_failed = 1; + if (!mac->autoneg_failed) { + mac->autoneg_failed = true; return 0; } e_dbg("NOT Rx'ing /C/, disable AutoNeg and force link.\n"); @@ -578,8 +578,8 @@ s32 e1000e_check_for_serdes_link(struct e1000_hw *hw) */ /* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */ if (!(status & E1000_STATUS_LU) && !(rxcw & E1000_RXCW_C)) { - if (mac->autoneg_failed == 0) { - mac->autoneg_failed = 1; + if (!mac->autoneg_failed) { + mac->autoneg_failed = true; return 0; } e_dbg("NOT Rx'ing /C/, disable AutoNeg and force link.\n"); @@ -855,7 +855,7 @@ static s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw) } if (i == FIBER_LINK_UP_LIMIT) { e_dbg("Never got a valid link from auto-neg!!!\n"); - mac->autoneg_failed = 1; + mac->autoneg_failed = true; /* * AutoNeg failed to achieve a link, so we'll call * mac->check_for_link. This routine will force the @@ -867,9 +867,9 @@ static s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw) e_dbg("Error while checking for link\n"); return ret_val; } - mac->autoneg_failed = 0; + mac->autoneg_failed = false; } else { - mac->autoneg_failed = 0; + mac->autoneg_failed = false; e_dbg("Valid Link Found\n"); } -- cgit v1.2.3-70-g09d2 From ec34c170da8798f521f0d40cad54580ff93cea3a Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 1 Feb 2012 10:53:05 +0000 Subject: e1000e: pass pointer to hw struct for e1000_init_mac_params_XXX() The e1000_init_mac_params_XXX() functions (where XXX is one of the three MAC-family types 80003es2lan, 82571 and ich8lan) was not meant to require a pointer to the adapter struct but does require a pointer to the hw struct. Pass that pointer in to the functions instead. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/80003es2lan.c | 7 +++---- drivers/net/ethernet/intel/e1000e/82571.c | 7 +++---- drivers/net/ethernet/intel/e1000e/ich8lan.c | 5 ++--- 3 files changed, 8 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/80003es2lan.c b/drivers/net/ethernet/intel/e1000e/80003es2lan.c index 9b969615b72..cfb361e5f49 100644 --- a/drivers/net/ethernet/intel/e1000e/80003es2lan.c +++ b/drivers/net/ethernet/intel/e1000e/80003es2lan.c @@ -201,13 +201,12 @@ static s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw) * e1000_init_mac_params_80003es2lan - Init ESB2 MAC func ptrs. * @hw: pointer to the HW structure **/ -static s32 e1000_init_mac_params_80003es2lan(struct e1000_adapter *adapter) +static s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw) { - struct e1000_hw *hw = &adapter->hw; struct e1000_mac_info *mac = &hw->mac; /* Set media type and media-dependent function pointers */ - switch (adapter->pdev->device) { + switch (hw->adapter->pdev->device) { case E1000_DEV_ID_80003ES2LAN_SERDES_DPT: hw->phy.media_type = e1000_media_type_internal_serdes; mac->ops.check_for_link = e1000e_check_for_serdes_link; @@ -246,7 +245,7 @@ static s32 e1000_get_variants_80003es2lan(struct e1000_adapter *adapter) struct e1000_hw *hw = &adapter->hw; s32 rc; - rc = e1000_init_mac_params_80003es2lan(adapter); + rc = e1000_init_mac_params_80003es2lan(hw); if (rc) return rc; diff --git a/drivers/net/ethernet/intel/e1000e/82571.c b/drivers/net/ethernet/intel/e1000e/82571.c index 7ef4711a32b..795c3d64061 100644 --- a/drivers/net/ethernet/intel/e1000e/82571.c +++ b/drivers/net/ethernet/intel/e1000e/82571.c @@ -235,16 +235,15 @@ static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw) * e1000_init_mac_params_82571 - Init MAC func ptrs. * @hw: pointer to the HW structure **/ -static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter) +static s32 e1000_init_mac_params_82571(struct e1000_hw *hw) { - struct e1000_hw *hw = &adapter->hw; struct e1000_mac_info *mac = &hw->mac; u32 swsm = 0; u32 swsm2 = 0; bool force_clear_smbi = false; /* Set media type and media-dependent function pointers */ - switch (adapter->pdev->device) { + switch (hw->adapter->pdev->device) { case E1000_DEV_ID_82571EB_FIBER: case E1000_DEV_ID_82572EI_FIBER: case E1000_DEV_ID_82571EB_QUAD_FIBER: @@ -371,7 +370,7 @@ static s32 e1000_get_variants_82571(struct e1000_adapter *adapter) int is_port_b = er32(STATUS) & E1000_STATUS_FUNC_1; s32 rc; - rc = e1000_init_mac_params_82571(adapter); + rc = e1000_init_mac_params_82571(hw); if (rc) return rc; diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 942f4da86fb..112d55f76b7 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -553,9 +553,8 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw) * Initialize family-specific MAC parameters and function * pointers. **/ -static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter) +static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw) { - struct e1000_hw *hw = &adapter->hw; struct e1000_mac_info *mac = &hw->mac; /* Set media type function pointer */ @@ -775,7 +774,7 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter) struct e1000_hw *hw = &adapter->hw; s32 rc; - rc = e1000_init_mac_params_ich8lan(adapter); + rc = e1000_init_mac_params_ich8lan(hw); if (rc) return rc; -- cgit v1.2.3-70-g09d2 From f92518ddec7ce0ef2f7e91ae5f07e0a9e19055bf Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 1 Feb 2012 11:16:42 +0000 Subject: e1000e: replace '1' with 'true' for boolean get_link_status Signed-off-by: Bruce Allan Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/netdev.c | 6 +++--- drivers/net/ethernet/intel/e1000e/phy.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 7ccd5f3cef6..f868fb822a3 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -1652,7 +1652,7 @@ static irqreturn_t e1000_intr_msi(int irq, void *data) */ if (icr & E1000_ICR_LSC) { - hw->mac.get_link_status = 1; + hw->mac.get_link_status = true; /* * ICH8 workaround-- Call gig speed drop workaround on cable * disconnect (LSC) before accessing any PHY registers @@ -1718,7 +1718,7 @@ static irqreturn_t e1000_intr(int irq, void *data) */ if (icr & E1000_ICR_LSC) { - hw->mac.get_link_status = 1; + hw->mac.get_link_status = true; /* * ICH8 workaround-- Call gig speed drop workaround on cable * disconnect (LSC) before accessing any PHY registers @@ -1775,7 +1775,7 @@ static irqreturn_t e1000_msix_other(int irq, void *data) if (icr & E1000_ICR_OTHER) { if (!(icr & E1000_ICR_LSC)) goto no_link_interrupt; - hw->mac.get_link_status = 1; + hw->mac.get_link_status = true; /* guard against interrupt when we're going down */ if (!test_bit(__E1000_DOWN, &adapter->state)) mod_timer(&adapter->watchdog_timer, jiffies + 1); diff --git a/drivers/net/ethernet/intel/e1000e/phy.c b/drivers/net/ethernet/intel/e1000e/phy.c index e8ad0804702..6f44c3fb80b 100644 --- a/drivers/net/ethernet/intel/e1000e/phy.c +++ b/drivers/net/ethernet/intel/e1000e/phy.c @@ -1141,7 +1141,7 @@ static s32 e1000_copper_link_autoneg(struct e1000_hw *hw) } } - hw->mac.get_link_status = 1; + hw->mac.get_link_status = true; return ret_val; } -- cgit v1.2.3-70-g09d2 From d9dd966d7fc088a6bed991c2b1e2fba4485e0a31 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Sat, 28 Jan 2012 08:10:35 +0000 Subject: igb: fix warning about unused function This patch fixes a warning about unused function when CONFIG_PM_SLEEP is not selected in the kernel config: igb_main.c: warning: `igb_suspend` defined but not used [W-unused-function] Signed-off-by: Emil Tantilov Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/igb/igb_main.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index e91d73c8aa4..fd911cac1ac 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -173,7 +173,9 @@ static int igb_check_vf_assignment(struct igb_adapter *adapter); #endif #ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int igb_suspend(struct device *); +#endif static int igb_resume(struct device *); #ifdef CONFIG_PM_RUNTIME static int igb_runtime_suspend(struct device *dev); @@ -6709,6 +6711,7 @@ static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake, } #ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int igb_suspend(struct device *dev) { int retval; @@ -6728,6 +6731,7 @@ static int igb_suspend(struct device *dev) return 0; } +#endif /* CONFIG_PM_SLEEP */ static int igb_resume(struct device *dev) { -- cgit v1.2.3-70-g09d2 From 50db7fa3eae48fb7dc8e82651b2cd3f4d0c1c805 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Fri, 10 Feb 2012 00:29:32 +0900 Subject: zd1211rw: Fix typo in zd_usb.c and zd_mac.c Correct spelling "reseting" to "resetting" in drivers/net/wireless/zd1211rw/zd_usb.c drivers/net/wireless/zd1211rw/zd_mac.c Signed-off-by: Masanari Iida Signed-off-by: Jiri Kosina --- drivers/net/wireless/zd1211rw/zd_mac.c | 2 +- drivers/net/wireless/zd1211rw/zd_usb.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 0a70149df3f..a8370eb0778 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -846,7 +846,7 @@ reset_device: /* semaphore stuck, reset device to avoid fw freeze later */ dev_warn(zd_mac_dev(mac), "CR_BCN_FIFO_SEMAPHORE stuck, " - "reseting device..."); + "resetting device..."); usb_queue_reset_device(mac->chip.usb.intf); return r; diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 785bdbe38f2..f766b3e67c6 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -1104,7 +1104,7 @@ static void zd_tx_watchdog_handler(struct work_struct *work) goto out; /* TX halted, try reset */ - dev_warn(zd_usb_dev(usb), "TX-stall detected, reseting device..."); + dev_warn(zd_usb_dev(usb), "TX-stall detected, resetting device..."); usb_queue_reset_device(usb->intf); -- cgit v1.2.3-70-g09d2 From ce64b8d85de96a1a9538f6dbc960ef592ca05fe8 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sun, 5 Feb 2012 01:32:02 +0100 Subject: power, max8998: Include linux/module.h just once in drivers/power/max8998_charger.c Remove the duplicate. Signed-off-by: Jesper Juhl Signed-off-by: Jiri Kosina --- drivers/power/max8998_charger.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/power/max8998_charger.c b/drivers/power/max8998_charger.c index 9b3f2bf56e7..5c5f281ced1 100644 --- a/drivers/power/max8998_charger.c +++ b/drivers/power/max8998_charger.c @@ -21,7 +21,6 @@ #include #include -#include #include #include #include -- cgit v1.2.3-70-g09d2 From a2888ec985f36f8584609fedc916e5b1fd37aaac Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sun, 5 Feb 2012 01:37:56 +0100 Subject: SCSI, ISCSI: Just #include "host.h" once in host.c There's no need to include the header twice. Signed-off-by: Jesper Juhl Signed-off-by: Jiri Kosina --- drivers/scsi/isci/host.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c index 1a65d651423..0061cfd93bb 100644 --- a/drivers/scsi/isci/host.c +++ b/drivers/scsi/isci/host.c @@ -58,7 +58,6 @@ #include "host.h" #include "isci.h" #include "port.h" -#include "host.h" #include "probe_roms.h" #include "remote_device.h" #include "request.h" -- cgit v1.2.3-70-g09d2 From 8cd7c62e13812875ce89e2abad0a9cf77fbe0c37 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sun, 5 Feb 2012 01:40:09 +0100 Subject: Staging: The header linux/module.h is included twice in drivers/staging/iio/dac/ad5686.c Remove the unneeded duplicate. Signed-off-by: Jesper Juhl Signed-off-by: Jiri Kosina --- drivers/staging/iio/dac/ad5686.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/dac/ad5686.c b/drivers/staging/iio/dac/ad5686.c index ce2d6193dd8..2415a6e60c7 100644 --- a/drivers/staging/iio/dac/ad5686.c +++ b/drivers/staging/iio/dac/ad5686.c @@ -15,7 +15,6 @@ #include #include #include -#include #include "../iio.h" #include "../sysfs.h" -- cgit v1.2.3-70-g09d2 From 596f17f901dbc645883cf663c26ef2c80b5db5a4 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 6 Feb 2012 00:18:57 +0100 Subject: bonding: Fix misspelling of "since" Signed-off-by: Jesper Juhl Signed-off-by: Jiri Kosina --- drivers/net/bonding/bond_3ad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 0ae0d7c54cc..793b0013827 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -660,7 +660,7 @@ static void __attach_bond_to_agg(struct port *port) static void __detach_bond_from_agg(struct port *port) { port = NULL; /* just to satisfy the compiler */ - // This function does nothing sience the parser/multiplexer of the receive + // This function does nothing since the parser/multiplexer of the receive // and the parser/multiplexer of the aggregator are already combined } -- cgit v1.2.3-70-g09d2 From 090725431b9636a0a59516ff0fe94933cf09a82b Mon Sep 17 00:00:00 2001 From: Gerard Cauvy Date: Fri, 10 Feb 2012 12:14:53 +0200 Subject: usb: dwc3: debugfs: fix off by one when entering testmode When implementing the USB2 testmode support via debugfs, Felipe has committed a mistake when counting the number of letters of some of the strings, resulting on an off by one error which prevented some of the Test modes to be entered properly. This patch, fixes that mistake. Signed-off-by: Gerard Cauvy Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/debugfs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index 78ec092db5e..d4a30f11872 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c @@ -525,11 +525,11 @@ static ssize_t dwc3_testmode_write(struct file *file, testmode = TEST_J; else if (!strncmp(buf, "test_k", 6)) testmode = TEST_K; - else if (!strncmp(buf, "test_se0_nak", 13)) + else if (!strncmp(buf, "test_se0_nak", 12)) testmode = TEST_SE0_NAK; - else if (!strncmp(buf, "test_packet", 12)) + else if (!strncmp(buf, "test_packet", 11)) testmode = TEST_PACKET; - else if (!strncmp(buf, "test_force_enable", 18)) + else if (!strncmp(buf, "test_force_enable", 17)) testmode = TEST_FORCE_EN; else testmode = 0; -- cgit v1.2.3-70-g09d2 From 3b637367ae40b6d3c20e30cb0cdd059e67bbf848 Mon Sep 17 00:00:00 2001 From: Gerard Cauvy Date: Fri, 10 Feb 2012 12:21:18 +0200 Subject: usb: dwc3: ep0: fix SetFeature(TEST) When host requests us to enter a test mode, we cannot directly enter the test mode before Status Phase is completed, otherwise the core will never be able to deliver the Status ZLP to host, because it has already entered the requested Test Mode. In order to fix the error, we move the actual start of Test Mode right after we receive Transfer Complete event of the status phase. Signed-off-by: Gerard Cauvy Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.h | 3 +++ drivers/usb/dwc3/ep0.c | 21 +++++++++++++-------- drivers/usb/dwc3/gadget.c | 1 + 3 files changed, 17 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 71d958af239..4dac9828577 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -684,6 +684,9 @@ struct dwc3 { struct dwc3_hwparams hwparams; struct dentry *root; + + u8 test_mode; + u8 test_mode_nr; }; /* -------------------------------------------------------------------------- */ diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 5104dbf4668..c20e30c8b69 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -316,7 +316,6 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc, u32 wValue; u32 wIndex; int ret; - u32 mode; wValue = le16_to_cpu(ctrl->wValue); wIndex = le16_to_cpu(ctrl->wIndex); @@ -355,13 +354,8 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc, if (!set) return -EINVAL; - mode = wIndex >> 8; - ret = dwc3_gadget_set_test_mode(dwc, mode); - if (ret < 0) { - dev_dbg(dwc->dev, "Invalid Test #%d\n", - mode); - return ret; - } + dwc->test_mode_nr = wIndex >> 8; + dwc->test_mode = true; } break; @@ -604,6 +598,17 @@ static void dwc3_ep0_complete_req(struct dwc3 *dwc, dwc3_gadget_giveback(dep, r, 0); } + if (dwc->test_mode) { + int ret; + + ret = dwc3_gadget_set_test_mode(dwc, dwc->test_mode_nr); + if (ret < 0) { + dev_dbg(dwc->dev, "Invalid Test #%d\n", + dwc->test_mode_nr); + dwc3_ep0_stall_and_restart(dwc); + } + } + dwc->ep0state = EP0_SETUP_PHASE; dwc3_ep0_out_start(dwc); } diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index c30ab6da3d0..76327005d54 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1962,6 +1962,7 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) reg = dwc3_readl(dwc->regs, DWC3_DCTL); reg &= ~DWC3_DCTL_TSTCTRL_MASK; dwc3_writel(dwc->regs, DWC3_DCTL, reg); + dwc->test_mode = false; dwc3_stop_active_transfers(dwc); dwc3_clear_stall_all_ep(dwc); -- cgit v1.2.3-70-g09d2 From 2a14d7d9b7439fe62082a60a7f8983ccb463d134 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 10 Feb 2012 19:29:55 +0800 Subject: regmap: Fix kcalloc parameters swapped The first parameter should be "number of elements" and the second parameter should be "element size". Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 28e89fd7c28..46b2bd742ee 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -709,7 +709,7 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs, } } - map->patch = kcalloc(sizeof(struct reg_default), num_regs, GFP_KERNEL); + map->patch = kcalloc(num_regs, sizeof(struct reg_default), GFP_KERNEL); if (map->patch != NULL) { memcpy(map->patch, regs, num_regs * sizeof(struct reg_default)); -- cgit v1.2.3-70-g09d2 From d442ae181ba86085c3add085d5cb4482a8ccca68 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sat, 28 Jan 2012 14:49:19 +0100 Subject: drm/i915: clean up interlaced pipeconf bit definitions - Clarify which bits are for which chips. - Note that gen2 can't do interlaced directly (only via dvo tv chips). - Move the mask to the top to make it clearer how wide this field is. - Add defintions for all possible values. This patch doesn't change any code. v2: Paulo Zanoni pointed out that the pixel doubling modes do no longer exist on ivb. Cc: Peter Ross Reviewed-by: Eugeni Dodonov Reviewed-by: Paulo Zanoni Tested-by: Paulo Zanoni Tested-by: Christopher Egert Tested-by: Alfonso Fiore Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 341ce44e732..3369f829f46 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2387,10 +2387,21 @@ #define PIPECONF_PALETTE 0 #define PIPECONF_GAMMA (1<<24) #define PIPECONF_FORCE_BORDER (1<<25) -#define PIPECONF_PROGRESSIVE (0 << 21) -#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) -#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) #define PIPECONF_INTERLACE_MASK (7 << 21) +/* Note that pre-gen3 does not support interlaced display directly. Panel + * fitting must be disabled on pre-ilk for interlaced. */ +#define PIPECONF_PROGRESSIVE (0 << 21) +#define PIPECONF_INTERLACE_W_SYNC_SHIFT_PANEL (4 << 21) /* gen4 only */ +#define PIPECONF_INTERLACE_W_SYNC_SHIFT (5 << 21) /* gen4 only */ +#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) +#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) /* gen3 only */ +/* Ironlake and later have a complete new set of values for interlaced. PFIT + * means panel fitter required, PF means progressive fetch, DBL means power + * saving pixel doubling. */ +#define PIPECONF_PFIT_PF_INTERLACED_ILK (1 << 21) +#define PIPECONF_INTERLACED_ILK (3 << 21) +#define PIPECONF_INTERLACED_DBL_ILK (4 << 21) /* ilk/snb only */ +#define PIPECONF_PFIT_PF_INTERLACED_DBL_ILK (5 << 21) /* ilk/snb only */ #define PIPECONF_CXSR_DOWNCLOCK (1<<16) #define PIPECONF_BPP_MASK (0x000000e0) #define PIPECONF_BPP_8 (0<<5) -- cgit v1.2.3-70-g09d2 From ca9bfa7eed20ea34e862804e62aae10eb159edbb Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sat, 28 Jan 2012 14:49:20 +0100 Subject: drm/i915: fixup interlaced vertical timings confusion, part 1 We have a pretty decent confusion about vertical timings of interlaced modes. Peter Ross has written a patch that makes interlace modes work on a lot more platforms/output combinations by doubling the vertical timings. The issue with that patch is that core drm _does_ support specifying whether we want these vertical timings in fields or frames, we just haven't managed to consistently use this facility. The relavant function is drm_mode_set_crtcinfo, which fills in the crtc timing information. The first thing to note is that the drm core keeps interlaced modes in frames, but displays modelines in fields. So when the crtc modeset helper copies over the mode into adjusted_mode it will already contain vertical timings in half-frames. The result is that the fixup code in intel_crtc_mode_fixup doesn't actually do anything (in most cases at least). Now gen3+ natively supports interlaced modes and wants the vertical timings in frames. Which is what sdvo already fixes up, at least under some conditions. There are a few other place that demand vertical timings in fields but never actually deal with interlaced modes, so use frame timings for consistency, too. These are: - lvds panel, - dvo encoders - dvo is the only way gen2 could support interlaced mode, but currently we don't support any encoders that do. - tv out - despite that the tv dac sends out an interlaced signal it expects a progressive mode pipe configuration. All these encoders enforce progressive modes by resetting interlace_allowed. Hence we always want crtc vertical timings in frames. Enforce this in our crtc mode_fixup function and rip out any redudant timing computations from the encoders' mode_fixup function. v2-4: Adjust the vertical timings a bit. v5: Split out the 'subtract-one for interlaced' fixes. v6: Clarify issues around tv-out and gen2. Reviewed-by: Eugeni Dodonov Reviewed-by: Paulo Zanoni Tested-by: Paulo Zanoni Tested-by: Christopher Egert Tested-by: Alfonso Fiore Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 7 ++----- drivers/gpu/drm/i915/intel_dvo.c | 1 - drivers/gpu/drm/i915/intel_overlay.c | 2 +- drivers/gpu/drm/i915/intel_panel.c | 2 +- drivers/gpu/drm/i915/intel_sdvo.c | 1 - drivers/gpu/drm/i915/intel_tv.c | 2 +- 6 files changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index efe56a2c4f4..41d4e82f412 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3437,11 +3437,8 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, return false; } - /* XXX some encoders set the crtcinfo, others don't. - * Obviously we need some form of conflict resolution here... - */ - if (adjusted_mode->crtc_htotal == 0) - drm_mode_set_crtcinfo(adjusted_mode, 0); + /* All interlaced capable intel hw wants timings in frames. */ + drm_mode_set_crtcinfo(adjusted_mode, 0); return true; } diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 6eda1b51c63..020a7d7f744 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -157,7 +157,6 @@ static bool intel_dvo_mode_fixup(struct drm_encoder *encoder, C(vsync_end); C(vtotal); C(clock); - drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); #undef C } diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 23a543cdfa9..5542e9006f9 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -264,7 +264,7 @@ i830_activate_pipe_a(struct drm_device *dev) DRM_DEBUG_DRIVER("Enabling pipe A in order to enable overlay\n"); mode = drm_mode_duplicate(dev, &vesa_640x480); - drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); + drm_mode_set_crtcinfo(mode, 0); if (!drm_crtc_helper_set_mode(&crtc->base, mode, crtc->base.x, crtc->base.y, crtc->base.fb)) diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index c935cdaa215..230a141dbea 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -48,7 +48,7 @@ intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, adjusted_mode->clock = fixed_mode->clock; - drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); + drm_mode_set_crtcinfo(adjusted_mode, 0); } /* adjusted_mode has been preset to be the panel's fixed mode */ diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index e334ec33a47..5b480bbad68 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -944,7 +944,6 @@ intel_sdvo_set_input_timings_for_mode(struct intel_sdvo *intel_sdvo, intel_sdvo_get_mode_from_dtd(adjusted_mode, &intel_sdvo->input_dtd); - drm_mode_set_crtcinfo(adjusted_mode, 0); return true; } diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 1571be37ce3..05f765ef546 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -1240,7 +1240,7 @@ intel_tv_detect(struct drm_connector *connector, bool force) int type; mode = reported_modes[0]; - drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); + drm_mode_set_crtcinfo(&mode, 0); if (intel_tv->base.base.crtc && intel_tv->base.base.crtc->enabled) { type = intel_tv_detect_type(intel_tv, connector); -- cgit v1.2.3-70-g09d2 From 99fca60c76ffbdbf64aa00abf671014f711aea0e Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sat, 28 Jan 2012 14:49:21 +0100 Subject: drm/i915: fixup interlaced vertical timings confusion, part 2 According to bspec, we need to subtract an additional line from vtotal for interlaced modes and vblank_end needs to equal vtotal. All other timing fields do not need this special treatment, so kill it. Bspec says that this is irrespective of whether the interlaced mode has an odd or even vtotal, both modes are supported. Reviewed-by: Eugeni Dodonov Reviewed-by: Paulo Zanoni Tested-by: Paulo Zanoni Tested-by: Christopher Egert Tested-by: Alfonso Fiore Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 41d4e82f412..dc765a60a7e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5388,12 +5388,8 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; /* the chip adds 2 halflines automatically */ - adjusted_mode->crtc_vdisplay -= 1; adjusted_mode->crtc_vtotal -= 1; - adjusted_mode->crtc_vblank_start -= 1; adjusted_mode->crtc_vblank_end -= 1; - adjusted_mode->crtc_vsync_end -= 1; - adjusted_mode->crtc_vsync_start -= 1; } else pipeconf |= PIPECONF_PROGRESSIVE; @@ -5981,12 +5977,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; /* the chip adds 2 halflines automatically */ - adjusted_mode->crtc_vdisplay -= 1; adjusted_mode->crtc_vtotal -= 1; - adjusted_mode->crtc_vblank_start -= 1; adjusted_mode->crtc_vblank_end -= 1; - adjusted_mode->crtc_vsync_end -= 1; - adjusted_mode->crtc_vsync_start -= 1; } else pipeconf |= PIPECONF_PROGRESSIVE; -- cgit v1.2.3-70-g09d2 From 5def474ec6e37fe8dbac5070da4899931d46bf1f Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sat, 28 Jan 2012 14:49:22 +0100 Subject: drm/i915: fixup interlaced support on ilk+ According to Paulo Zanoni, this is what windows does. Reviewed-by: Paulo Zanoni Tested-by: Paulo Zanoni Tested-by: Alfonso Fiore Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index dc765a60a7e..d588aec4790 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5975,7 +5975,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, pipeconf &= ~PIPECONF_INTERLACE_MASK; if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { - pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; + pipeconf |= PIPECONF_INTERLACED_ILK; /* the chip adds 2 halflines automatically */ adjusted_mode->crtc_vtotal -= 1; adjusted_mode->crtc_vblank_end -= 1; -- cgit v1.2.3-70-g09d2 From dbb025757a30cd225c5587685ae0971ecf301718 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sat, 28 Jan 2012 14:49:23 +0100 Subject: drm/i915: don't allow interlaced pipeconf on gen2 gen2 doesn't support it, so be a bit more paranoid and add a check to ensure that we never ever set an unsupported interlaced bit. Ensure that userspace can't set an interlaced mode by resetting interlace_allowed for the crt on gen2. dvo and lvds are the only other encoders that gen2 supports and these already disallow interlaced modes. Reviewed-by: Eugeni Dodonov Reviewed-by: Paulo Zanoni Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_crt.c | 5 ++++- drivers/gpu/drm/i915/intel_display.c | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index dd729d46a61..4d3d736a4f5 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -594,7 +594,10 @@ void intel_crt_init(struct drm_device *dev) 1 << INTEL_ANALOG_CLONE_BIT | 1 << INTEL_SDVO_LVDS_CLONE_BIT); crt->base.crtc_mask = (1 << 0) | (1 << 1); - connector->interlace_allowed = 1; + if (IS_GEN2(dev)) + connector->interlace_allowed = 0; + else + connector->interlace_allowed = 1; connector->doublescan_allowed = 0; drm_encoder_helper_add(&crt->base.base, &intel_crt_helper_funcs); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d588aec4790..1fde35d5360 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5385,7 +5385,8 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, } pipeconf &= ~PIPECONF_INTERLACE_MASK; - if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { + if (!IS_GEN2(dev) && + adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; /* the chip adds 2 halflines automatically */ adjusted_mode->crtc_vtotal -= 1; -- cgit v1.2.3-70-g09d2 From 0529a0d9f0e702fd5215a493b7440be73f5941af Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sat, 28 Jan 2012 14:49:24 +0100 Subject: drm/i915: correctly program the VSYNCSHIFT register The hw seems to use this to correctly insert the required delay before/after an even/odd interlaced field. This might also explain why we need to substract 1 half-line from vtotal - if the hw just adds the delay programmend in VSYNCSHIFT the total frame time would be about that too long. These registers seems to only exist on gen4 and later. For paranoia also program it to 0 for progressive modes, but according to documentation the hw should just ignore it in this case. Reviewed-by: Paulo Zanoni Tested-by: Paulo Zanoni Tested-by: Alfonso Fiore Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 8 ++++++++ drivers/gpu/drm/i915/intel_display.c | 19 ++++++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 3369f829f46..7eabdf056af 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1384,6 +1384,7 @@ #define _VSYNC_A 0x60014 #define _PIPEASRC 0x6001c #define _BCLRPAT_A 0x60020 +#define _VSYNCSHIFT_A 0x60028 /* Pipe B timing regs */ #define _HTOTAL_B 0x61000 @@ -1394,6 +1395,8 @@ #define _VSYNC_B 0x61014 #define _PIPEBSRC 0x6101c #define _BCLRPAT_B 0x61020 +#define _VSYNCSHIFT_B 0x61028 + #define HTOTAL(pipe) _PIPE(pipe, _HTOTAL_A, _HTOTAL_B) #define HBLANK(pipe) _PIPE(pipe, _HBLANK_A, _HBLANK_B) @@ -1402,6 +1405,7 @@ #define VBLANK(pipe) _PIPE(pipe, _VBLANK_A, _VBLANK_B) #define VSYNC(pipe) _PIPE(pipe, _VSYNC_A, _VSYNC_B) #define BCLRPAT(pipe) _PIPE(pipe, _BCLRPAT_A, _BCLRPAT_B) +#define VSYNCSHIFT(pipe) _PIPE(pipe, _VSYNCSHIFT_A, _VSYNCSHIFT_B) /* VGA port control */ #define ADPA 0x61100 @@ -3284,6 +3288,7 @@ #define _TRANS_VSYNC_A 0xe0014 #define TRANS_VSYNC_END_SHIFT 16 #define TRANS_VSYNC_START_SHIFT 0 +#define _TRANS_VSYNCSHIFT_A 0xe0028 #define _TRANSA_DATA_M1 0xe0030 #define _TRANSA_DATA_N1 0xe0034 @@ -3314,6 +3319,7 @@ #define _TRANS_VTOTAL_B 0xe100c #define _TRANS_VBLANK_B 0xe1010 #define _TRANS_VSYNC_B 0xe1014 +#define _TRANS_VSYNCSHIFT_B 0xe1028 #define TRANS_HTOTAL(pipe) _PIPE(pipe, _TRANS_HTOTAL_A, _TRANS_HTOTAL_B) #define TRANS_HBLANK(pipe) _PIPE(pipe, _TRANS_HBLANK_A, _TRANS_HBLANK_B) @@ -3321,6 +3327,8 @@ #define TRANS_VTOTAL(pipe) _PIPE(pipe, _TRANS_VTOTAL_A, _TRANS_VTOTAL_B) #define TRANS_VBLANK(pipe) _PIPE(pipe, _TRANS_VBLANK_A, _TRANS_VBLANK_B) #define TRANS_VSYNC(pipe) _PIPE(pipe, _TRANS_VSYNC_A, _TRANS_VSYNC_B) +#define TRANS_VSYNCSHIFT(pipe) _PIPE(pipe, _TRANS_VSYNCSHIFT_A, \ + _TRANS_VSYNCSHIFT_B) #define _TRANSB_DATA_M1 0xe1030 #define _TRANSB_DATA_N1 0xe1034 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 1fde35d5360..34c63459c48 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2973,6 +2973,7 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) I915_WRITE(TRANS_VTOTAL(pipe), I915_READ(VTOTAL(pipe))); I915_WRITE(TRANS_VBLANK(pipe), I915_READ(VBLANK(pipe))); I915_WRITE(TRANS_VSYNC(pipe), I915_READ(VSYNC(pipe))); + I915_WRITE(TRANS_VSYNCSHIFT(pipe), I915_READ(VSYNCSHIFT(pipe))); intel_fdi_normal_train(crtc); @@ -5103,7 +5104,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, int plane = intel_crtc->plane; int refclk, num_connectors = 0; intel_clock_t clock, reduced_clock; - u32 dpll, dspcntr, pipeconf; + u32 dpll, dspcntr, pipeconf, vsyncshift; bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false; bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; struct drm_mode_config *mode_config = &dev->mode_config; @@ -5391,8 +5392,15 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, /* the chip adds 2 halflines automatically */ adjusted_mode->crtc_vtotal -= 1; adjusted_mode->crtc_vblank_end -= 1; - } else + vsyncshift = adjusted_mode->crtc_hsync_start + - adjusted_mode->crtc_htotal/2; + } else { pipeconf |= PIPECONF_PROGRESSIVE; + vsyncshift = 0; + } + + if (!IS_GEN3(dev)) + I915_WRITE(VSYNCSHIFT(pipe), vsyncshift); I915_WRITE(HTOTAL(pipe), (adjusted_mode->crtc_hdisplay - 1) | @@ -5980,8 +5988,13 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, /* the chip adds 2 halflines automatically */ adjusted_mode->crtc_vtotal -= 1; adjusted_mode->crtc_vblank_end -= 1; - } else + I915_WRITE(VSYNCSHIFT(pipe), + adjusted_mode->crtc_hsync_start + - adjusted_mode->crtc_htotal/2); + } else { pipeconf |= PIPECONF_PROGRESSIVE; + I915_WRITE(VSYNCSHIFT(pipe), 0); + } I915_WRITE(HTOTAL(pipe), (adjusted_mode->crtc_hdisplay - 1) | -- cgit v1.2.3-70-g09d2 From 8f4839e21ea9a8f7300daac1fa30bfec514c9a25 Mon Sep 17 00:00:00 2001 From: Peter Ross Date: Sat, 28 Jan 2012 14:49:25 +0100 Subject: drm/i915: allow interlaced mode output on the SDVO connector Signed-off-by: Peter Ross Reviewed-by: Eugeni Dodonov Reviewed-by: Paulo Zanoni Tested-by: Paulo Zanoni Tested-by: Christopher Egert Tested-by: Alfonso Fiore Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_sdvo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 5b480bbad68..80fb5da421f 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1984,7 +1984,7 @@ intel_sdvo_connector_init(struct intel_sdvo_connector *connector, drm_connector_helper_add(&connector->base.base, &intel_sdvo_connector_helper_funcs); - connector->base.base.interlace_allowed = 0; + connector->base.base.interlace_allowed = 1; connector->base.base.doublescan_allowed = 0; connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB; -- cgit v1.2.3-70-g09d2 From c3febcc438ba0878b164c74310bd77c50dbb0ba8 Mon Sep 17 00:00:00 2001 From: Peter Ross Date: Sat, 28 Jan 2012 14:49:26 +0100 Subject: drm/i915: allow interlaced mode output on the HDMI connector Signed-off-by: Peter Ross Reviewed-by: Eugeni Dodonov Reviewed-by: Paulo Zanoni Tested-by: Paulo Zanoni Tested-by: Christopher Egert Tested-by: Alfonso Fiore Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_hdmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 64541f7ef90..086288e85fa 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -514,7 +514,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) intel_encoder->type = INTEL_OUTPUT_HDMI; connector->polled = DRM_CONNECTOR_POLL_HPD; - connector->interlace_allowed = 0; + connector->interlace_allowed = 1; connector->doublescan_allowed = 0; intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); -- cgit v1.2.3-70-g09d2 From 75c13993db592343bda1fd62f2555fea037d56bd Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sat, 28 Jan 2012 23:48:46 +0100 Subject: drm/i915: fixup overlay checks for interlaced modes The drm core _really_ likes to frob around with the crtc timings and put halfed vertical timings (in fields) in there. Which confuses the overlay code, resulting in it's refusal to display anything at the lower half of an interlaced pipe. Tested-by: Christopher Egert Reviewed-by: Eugeni Dodonov Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_overlay.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 5542e9006f9..91d294e74ac 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -937,10 +937,10 @@ static int check_overlay_dst(struct intel_overlay *overlay, { struct drm_display_mode *mode = &overlay->crtc->base.mode; - if (rec->dst_x < mode->crtc_hdisplay && - rec->dst_x + rec->dst_width <= mode->crtc_hdisplay && - rec->dst_y < mode->crtc_vdisplay && - rec->dst_y + rec->dst_height <= mode->crtc_vdisplay) + if (rec->dst_x < mode->hdisplay && + rec->dst_x + rec->dst_width <= mode->hdisplay && + rec->dst_y < mode->vdisplay && + rec->dst_y + rec->dst_height <= mode->vdisplay) return 0; else return -EINVAL; -- cgit v1.2.3-70-g09d2 From 5f7f726d2caf1e51a39872e5a30b6984235d388e Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Fri, 3 Feb 2012 17:47:15 -0200 Subject: drm/i915: set interlaced bits for TRANSCONF I'm not sure why they are needed (I didn't notice any difference in my tests), but these bits are in our documentation and they are also set by the Windows driver. Signed-off-by: Paulo Zanoni Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 2 ++ drivers/gpu/drm/i915/intel_display.c | 12 ++++++++++-- 2 files changed, 12 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 7eabdf056af..7b4477cb165 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3362,7 +3362,9 @@ #define TRANS_FSYNC_DELAY_HB4 (3<<27) #define TRANS_DP_AUDIO_ONLY (1<<26) #define TRANS_DP_VIDEO_AUDIO (0<<26) +#define TRANS_INTERLACE_MASK (7<<21) #define TRANS_PROGRESSIVE (0<<21) +#define TRANS_INTERLACED (3<<21) #define TRANS_8BPC (0<<5) #define TRANS_10BPC (1<<5) #define TRANS_6BPC (2<<5) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 34c63459c48..7fae6917bea 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1266,7 +1266,7 @@ static void intel_enable_transcoder(struct drm_i915_private *dev_priv, enum pipe pipe) { int reg; - u32 val; + u32 val, pipeconf_val; /* PCH only available on ILK+ */ BUG_ON(dev_priv->info->gen < 5); @@ -1280,6 +1280,7 @@ static void intel_enable_transcoder(struct drm_i915_private *dev_priv, reg = TRANSCONF(pipe); val = I915_READ(reg); + pipeconf_val = I915_READ(PIPECONF(pipe)); if (HAS_PCH_IBX(dev_priv->dev)) { /* @@ -1287,8 +1288,15 @@ static void intel_enable_transcoder(struct drm_i915_private *dev_priv, * that in pipeconf reg. */ val &= ~PIPE_BPC_MASK; - val |= I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK; + val |= pipeconf_val & PIPE_BPC_MASK; } + + val &= ~TRANS_INTERLACE_MASK; + if ((pipeconf_val & PIPECONF_INTERLACE_MASK) == PIPECONF_INTERLACED_ILK) + val |= TRANS_INTERLACED; + else + val |= TRANS_PROGRESSIVE; + I915_WRITE(reg, val | TRANS_ENABLE); if (wait_for(I915_READ(reg) & TRANS_STATE_ENABLE, 100)) DRM_ERROR("failed to enable transcoder %d\n", pipe); -- cgit v1.2.3-70-g09d2 From c123daaad835681d4acffd7631e448fd2c77677f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 10 Feb 2012 09:45:22 -0800 Subject: staging: ramster: delete the driver Turns out it's not quite ready to be included, thanks to some other work done in the zcache and zram code, which breaks this driver. So, delete it for now, per the recommendation of Dan. Acked-by: Dan Magenheimer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/ramster/Kconfig | 14 - drivers/staging/ramster/Makefile | 2 - drivers/staging/ramster/TODO | 9 - drivers/staging/ramster/cluster/Makefile | 5 - drivers/staging/ramster/cluster/heartbeat.c | 2687 ---------------- drivers/staging/ramster/cluster/heartbeat.h | 92 - drivers/staging/ramster/cluster/masklog.c | 155 - drivers/staging/ramster/cluster/masklog.h | 219 -- drivers/staging/ramster/cluster/netdebug.c | 579 ---- drivers/staging/ramster/cluster/nodemanager.c | 989 ------ drivers/staging/ramster/cluster/nodemanager.h | 88 - drivers/staging/ramster/cluster/ocfs2_heartbeat.h | 38 - .../staging/ramster/cluster/ocfs2_nodemanager.h | 45 - drivers/staging/ramster/cluster/quorum.c | 331 -- drivers/staging/ramster/cluster/quorum.h | 36 - drivers/staging/ramster/cluster/sys.c | 82 - drivers/staging/ramster/cluster/sys.h | 33 - drivers/staging/ramster/cluster/tcp.c | 2262 -------------- drivers/staging/ramster/cluster/tcp.h | 160 - drivers/staging/ramster/cluster/tcp_internal.h | 249 -- drivers/staging/ramster/cluster/ver.c | 42 - drivers/staging/ramster/cluster/ver.h | 31 - drivers/staging/ramster/ramster.h | 117 - drivers/staging/ramster/ramster_o2net.c | 402 --- drivers/staging/ramster/tmem.c | 851 ----- drivers/staging/ramster/tmem.h | 244 -- drivers/staging/ramster/zcache-main.c | 3264 -------------------- drivers/staging/ramster/zcache.h | 22 - 30 files changed, 13051 deletions(-) delete mode 100644 drivers/staging/ramster/Kconfig delete mode 100644 drivers/staging/ramster/Makefile delete mode 100644 drivers/staging/ramster/TODO delete mode 100644 drivers/staging/ramster/cluster/Makefile delete mode 100644 drivers/staging/ramster/cluster/heartbeat.c delete mode 100644 drivers/staging/ramster/cluster/heartbeat.h delete mode 100644 drivers/staging/ramster/cluster/masklog.c delete mode 100644 drivers/staging/ramster/cluster/masklog.h delete mode 100644 drivers/staging/ramster/cluster/netdebug.c delete mode 100644 drivers/staging/ramster/cluster/nodemanager.c delete mode 100644 drivers/staging/ramster/cluster/nodemanager.h delete mode 100644 drivers/staging/ramster/cluster/ocfs2_heartbeat.h delete mode 100644 drivers/staging/ramster/cluster/ocfs2_nodemanager.h delete mode 100644 drivers/staging/ramster/cluster/quorum.c delete mode 100644 drivers/staging/ramster/cluster/quorum.h delete mode 100644 drivers/staging/ramster/cluster/sys.c delete mode 100644 drivers/staging/ramster/cluster/sys.h delete mode 100644 drivers/staging/ramster/cluster/tcp.c delete mode 100644 drivers/staging/ramster/cluster/tcp.h delete mode 100644 drivers/staging/ramster/cluster/tcp_internal.h delete mode 100644 drivers/staging/ramster/cluster/ver.c delete mode 100644 drivers/staging/ramster/cluster/ver.h delete mode 100644 drivers/staging/ramster/ramster.h delete mode 100644 drivers/staging/ramster/ramster_o2net.c delete mode 100644 drivers/staging/ramster/tmem.c delete mode 100644 drivers/staging/ramster/tmem.h delete mode 100644 drivers/staging/ramster/zcache-main.c delete mode 100644 drivers/staging/ramster/zcache.h (limited to 'drivers') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 783bc0a9121..f916a3f7444 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -136,6 +136,4 @@ source "drivers/staging/android/Kconfig" source "drivers/staging/telephony/Kconfig" -source "drivers/staging/ramster/Kconfig" - endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 077a3f3c0b8..f6d4a433d84 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -57,5 +57,4 @@ obj-$(CONFIG_INTEL_MEI) += mei/ obj-$(CONFIG_MFD_NVEC) += nvec/ obj-$(CONFIG_DRM_OMAP) += omapdrm/ obj-$(CONFIG_ANDROID) += android/ -obj-$(CONFIG_RAMSTER) += ramster/ obj-$(CONFIG_PHONE) += telephony/ diff --git a/drivers/staging/ramster/Kconfig b/drivers/staging/ramster/Kconfig deleted file mode 100644 index 3957b875afc..00000000000 --- a/drivers/staging/ramster/Kconfig +++ /dev/null @@ -1,14 +0,0 @@ -config RAMSTER - tristate "Cross-machine RAM capacity sharing, aka peer-to-peer tmem" - depends on (CLEANCACHE || FRONTSWAP) && CONFIGFS_FS && !OCFS2_FS && !ZCACHE && !HIGHMEM - select XVMALLOC - select LZO_COMPRESS - select LZO_DECOMPRESS - default n - help - RAMster allows RAM on other machines in a cluster to be utilized - dynamically and symmetrically instead of swapping to a local swap - disk, thus improving performance on memory-constrained workloads - while minimizing total RAM across the cluster. RAMster, like - zcache, compresses swap pages into local RAM, but then remotifies - the compressed pages to another node in the RAMster cluster. diff --git a/drivers/staging/ramster/Makefile b/drivers/staging/ramster/Makefile deleted file mode 100644 index e6c4a2eb14d..00000000000 --- a/drivers/staging/ramster/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -obj-$(CONFIG_RAMSTER) += zcache-main.o tmem.o -obj-$(CONFIG_RAMSTER) += ramster_o2net.o cluster/ diff --git a/drivers/staging/ramster/TODO b/drivers/staging/ramster/TODO deleted file mode 100644 index d4268f06514..00000000000 --- a/drivers/staging/ramster/TODO +++ /dev/null @@ -1,9 +0,0 @@ -For this staging driver, RAMster duplicates code from fs/ocfs2/cluster -and from drivers/staging/zcache, then incorporates changes to the local -copy of the code. Before RAMster can be promoted from staging, this code -duplication must be resolved. Specifically, we will first need to work with -the ocfs2 maintainers to split out the ocfs2 core cluster code so that -it can be easily included by another subsystem, even if ocfs2 is not -configured, and also to merge the handful of functional changes required. -Second, the zcache and RAMster drivers should be either merged or reorganized -to separate out common code. diff --git a/drivers/staging/ramster/cluster/Makefile b/drivers/staging/ramster/cluster/Makefile deleted file mode 100644 index 3fc85508cf8..00000000000 --- a/drivers/staging/ramster/cluster/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -#obj-$(CONFIG_OCFS2_FS) += ocfs2_nodemanager.o -obj-$(CONFIG_RAMSTER) += ocfs2_nodemanager.o - -ocfs2_nodemanager-objs := heartbeat.o masklog.o sys.o nodemanager.o \ - quorum.o tcp.o netdebug.o ver.o diff --git a/drivers/staging/ramster/cluster/heartbeat.c b/drivers/staging/ramster/cluster/heartbeat.c deleted file mode 100644 index 1f72143e2d3..00000000000 --- a/drivers/staging/ramster/cluster/heartbeat.c +++ /dev/null @@ -1,2687 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * Copyright (C) 2004, 2005 Oracle. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "heartbeat.h" -#include "tcp.h" -#include "nodemanager.h" -#include "quorum.h" - -#include "masklog.h" - - -/* - * The first heartbeat pass had one global thread that would serialize all hb - * callback calls. This global serializing sem should only be removed once - * we've made sure that all callees can deal with being called concurrently - * from multiple hb region threads. - */ -static DECLARE_RWSEM(o2hb_callback_sem); - -/* - * multiple hb threads are watching multiple regions. A node is live - * whenever any of the threads sees activity from the node in its region. - */ -static DEFINE_SPINLOCK(o2hb_live_lock); -static struct list_head o2hb_live_slots[O2NM_MAX_NODES]; -static unsigned long o2hb_live_node_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)]; -static LIST_HEAD(o2hb_node_events); -static DECLARE_WAIT_QUEUE_HEAD(o2hb_steady_queue); - -/* - * In global heartbeat, we maintain a series of region bitmaps. - * - o2hb_region_bitmap allows us to limit the region number to max region. - * - o2hb_live_region_bitmap tracks live regions (seen steady iterations). - * - o2hb_quorum_region_bitmap tracks live regions that have seen all nodes - * heartbeat on it. - * - o2hb_failed_region_bitmap tracks the regions that have seen io timeouts. - */ -static unsigned long o2hb_region_bitmap[BITS_TO_LONGS(O2NM_MAX_REGIONS)]; -static unsigned long o2hb_live_region_bitmap[BITS_TO_LONGS(O2NM_MAX_REGIONS)]; -static unsigned long o2hb_quorum_region_bitmap[BITS_TO_LONGS(O2NM_MAX_REGIONS)]; -static unsigned long o2hb_failed_region_bitmap[BITS_TO_LONGS(O2NM_MAX_REGIONS)]; - -#define O2HB_DB_TYPE_LIVENODES 0 -#define O2HB_DB_TYPE_LIVEREGIONS 1 -#define O2HB_DB_TYPE_QUORUMREGIONS 2 -#define O2HB_DB_TYPE_FAILEDREGIONS 3 -#define O2HB_DB_TYPE_REGION_LIVENODES 4 -#define O2HB_DB_TYPE_REGION_NUMBER 5 -#define O2HB_DB_TYPE_REGION_ELAPSED_TIME 6 -#define O2HB_DB_TYPE_REGION_PINNED 7 -struct o2hb_debug_buf { - int db_type; - int db_size; - int db_len; - void *db_data; -}; - -static struct o2hb_debug_buf *o2hb_db_livenodes; -static struct o2hb_debug_buf *o2hb_db_liveregions; -static struct o2hb_debug_buf *o2hb_db_quorumregions; -static struct o2hb_debug_buf *o2hb_db_failedregions; - -#define O2HB_DEBUG_DIR "o2hb" -#define O2HB_DEBUG_LIVENODES "livenodes" -#define O2HB_DEBUG_LIVEREGIONS "live_regions" -#define O2HB_DEBUG_QUORUMREGIONS "quorum_regions" -#define O2HB_DEBUG_FAILEDREGIONS "failed_regions" -#define O2HB_DEBUG_REGION_NUMBER "num" -#define O2HB_DEBUG_REGION_ELAPSED_TIME "elapsed_time_in_ms" -#define O2HB_DEBUG_REGION_PINNED "pinned" - -static struct dentry *o2hb_debug_dir; -static struct dentry *o2hb_debug_livenodes; -static struct dentry *o2hb_debug_liveregions; -static struct dentry *o2hb_debug_quorumregions; -static struct dentry *o2hb_debug_failedregions; - -static LIST_HEAD(o2hb_all_regions); - -static struct o2hb_callback { - struct list_head list; -} o2hb_callbacks[O2HB_NUM_CB]; - -static struct o2hb_callback *hbcall_from_type(enum o2hb_callback_type type); - -#define O2HB_DEFAULT_BLOCK_BITS 9 - -enum o2hb_heartbeat_modes { - O2HB_HEARTBEAT_LOCAL = 0, - O2HB_HEARTBEAT_GLOBAL, - O2HB_HEARTBEAT_NUM_MODES, -}; - -char *o2hb_heartbeat_mode_desc[O2HB_HEARTBEAT_NUM_MODES] = { - "local", /* O2HB_HEARTBEAT_LOCAL */ - "global", /* O2HB_HEARTBEAT_GLOBAL */ -}; - -unsigned int o2hb_dead_threshold = O2HB_DEFAULT_DEAD_THRESHOLD; -unsigned int o2hb_heartbeat_mode = O2HB_HEARTBEAT_LOCAL; - -/* - * o2hb_dependent_users tracks the number of registered callbacks that depend - * on heartbeat. o2net and o2dlm are two entities that register this callback. - * However only o2dlm depends on the heartbeat. It does not want the heartbeat - * to stop while a dlm domain is still active. - */ -unsigned int o2hb_dependent_users; - -/* - * In global heartbeat mode, all regions are pinned if there are one or more - * dependent users and the quorum region count is <= O2HB_PIN_CUT_OFF. All - * regions are unpinned if the region count exceeds the cut off or the number - * of dependent users falls to zero. - */ -#define O2HB_PIN_CUT_OFF 3 - -/* - * In local heartbeat mode, we assume the dlm domain name to be the same as - * region uuid. This is true for domains created for the file system but not - * necessarily true for userdlm domains. This is a known limitation. - * - * In global heartbeat mode, we pin/unpin all o2hb regions. This solution - * works for both file system and userdlm domains. - */ -static int o2hb_region_pin(const char *region_uuid); -static void o2hb_region_unpin(const char *region_uuid); - -/* Only sets a new threshold if there are no active regions. - * - * No locking or otherwise interesting code is required for reading - * o2hb_dead_threshold as it can't change once regions are active and - * it's not interesting to anyone until then anyway. */ -static void o2hb_dead_threshold_set(unsigned int threshold) -{ - if (threshold > O2HB_MIN_DEAD_THRESHOLD) { - spin_lock(&o2hb_live_lock); - if (list_empty(&o2hb_all_regions)) - o2hb_dead_threshold = threshold; - spin_unlock(&o2hb_live_lock); - } -} - -static int o2hb_global_hearbeat_mode_set(unsigned int hb_mode) -{ - int ret = -1; - - if (hb_mode < O2HB_HEARTBEAT_NUM_MODES) { - spin_lock(&o2hb_live_lock); - if (list_empty(&o2hb_all_regions)) { - o2hb_heartbeat_mode = hb_mode; - ret = 0; - } - spin_unlock(&o2hb_live_lock); - } - - return ret; -} - -struct o2hb_node_event { - struct list_head hn_item; - enum o2hb_callback_type hn_event_type; - struct o2nm_node *hn_node; - int hn_node_num; -}; - -struct o2hb_disk_slot { - struct o2hb_disk_heartbeat_block *ds_raw_block; - u8 ds_node_num; - u64 ds_last_time; - u64 ds_last_generation; - u16 ds_equal_samples; - u16 ds_changed_samples; - struct list_head ds_live_item; -}; - -/* each thread owns a region.. when we're asked to tear down the region - * we ask the thread to stop, who cleans up the region */ -struct o2hb_region { - struct config_item hr_item; - - struct list_head hr_all_item; - unsigned hr_unclean_stop:1, - hr_aborted_start:1, - hr_item_pinned:1, - hr_item_dropped:1; - - /* protected by the hr_callback_sem */ - struct task_struct *hr_task; - - unsigned int hr_blocks; - unsigned long long hr_start_block; - - unsigned int hr_block_bits; - unsigned int hr_block_bytes; - - unsigned int hr_slots_per_page; - unsigned int hr_num_pages; - - struct page **hr_slot_data; - struct block_device *hr_bdev; - struct o2hb_disk_slot *hr_slots; - - /* live node map of this region */ - unsigned long hr_live_node_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)]; - unsigned int hr_region_num; - - struct dentry *hr_debug_dir; - struct dentry *hr_debug_livenodes; - struct dentry *hr_debug_regnum; - struct dentry *hr_debug_elapsed_time; - struct dentry *hr_debug_pinned; - struct o2hb_debug_buf *hr_db_livenodes; - struct o2hb_debug_buf *hr_db_regnum; - struct o2hb_debug_buf *hr_db_elapsed_time; - struct o2hb_debug_buf *hr_db_pinned; - - /* let the person setting up hb wait for it to return until it - * has reached a 'steady' state. This will be fixed when we have - * a more complete api that doesn't lead to this sort of fragility. */ - atomic_t hr_steady_iterations; - - /* terminate o2hb thread if it does not reach steady state - * (hr_steady_iterations == 0) within hr_unsteady_iterations */ - atomic_t hr_unsteady_iterations; - - char hr_dev_name[BDEVNAME_SIZE]; - - unsigned int hr_timeout_ms; - - /* randomized as the region goes up and down so that a node - * recognizes a node going up and down in one iteration */ - u64 hr_generation; - - struct delayed_work hr_write_timeout_work; - unsigned long hr_last_timeout_start; - - /* Used during o2hb_check_slot to hold a copy of the block - * being checked because we temporarily have to zero out the - * crc field. */ - struct o2hb_disk_heartbeat_block *hr_tmp_block; -}; - -struct o2hb_bio_wait_ctxt { - atomic_t wc_num_reqs; - struct completion wc_io_complete; - int wc_error; -}; - -static int o2hb_pop_count(void *map, int count) -{ - int i = -1, pop = 0; - - while ((i = find_next_bit(map, count, i + 1)) < count) - pop++; - return pop; -} - -static void o2hb_write_timeout(struct work_struct *work) -{ - int failed, quorum; - unsigned long flags; - struct o2hb_region *reg = - container_of(work, struct o2hb_region, - hr_write_timeout_work.work); - - mlog(ML_ERROR, "Heartbeat write timeout to device %s after %u " - "milliseconds\n", reg->hr_dev_name, - jiffies_to_msecs(jiffies - reg->hr_last_timeout_start)); - - if (o2hb_global_heartbeat_active()) { - spin_lock_irqsave(&o2hb_live_lock, flags); - if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap)) - set_bit(reg->hr_region_num, o2hb_failed_region_bitmap); - failed = o2hb_pop_count(&o2hb_failed_region_bitmap, - O2NM_MAX_REGIONS); - quorum = o2hb_pop_count(&o2hb_quorum_region_bitmap, - O2NM_MAX_REGIONS); - spin_unlock_irqrestore(&o2hb_live_lock, flags); - - mlog(ML_HEARTBEAT, "Number of regions %d, failed regions %d\n", - quorum, failed); - - /* - * Fence if the number of failed regions >= half the number - * of quorum regions - */ - if ((failed << 1) < quorum) - return; - } - - o2quo_disk_timeout(); -} - -static void o2hb_arm_write_timeout(struct o2hb_region *reg) -{ - /* Arm writeout only after thread reaches steady state */ - if (atomic_read(®->hr_steady_iterations) != 0) - return; - - mlog(ML_HEARTBEAT, "Queue write timeout for %u ms\n", - O2HB_MAX_WRITE_TIMEOUT_MS); - - if (o2hb_global_heartbeat_active()) { - spin_lock(&o2hb_live_lock); - clear_bit(reg->hr_region_num, o2hb_failed_region_bitmap); - spin_unlock(&o2hb_live_lock); - } - cancel_delayed_work(®->hr_write_timeout_work); - reg->hr_last_timeout_start = jiffies; - schedule_delayed_work(®->hr_write_timeout_work, - msecs_to_jiffies(O2HB_MAX_WRITE_TIMEOUT_MS)); -} - -static void o2hb_disarm_write_timeout(struct o2hb_region *reg) -{ - cancel_delayed_work_sync(®->hr_write_timeout_work); -} - -static inline void o2hb_bio_wait_init(struct o2hb_bio_wait_ctxt *wc) -{ - atomic_set(&wc->wc_num_reqs, 1); - init_completion(&wc->wc_io_complete); - wc->wc_error = 0; -} - -/* Used in error paths too */ -static inline void o2hb_bio_wait_dec(struct o2hb_bio_wait_ctxt *wc, - unsigned int num) -{ - /* sadly atomic_sub_and_test() isn't available on all platforms. The - * good news is that the fast path only completes one at a time */ - while(num--) { - if (atomic_dec_and_test(&wc->wc_num_reqs)) { - BUG_ON(num > 0); - complete(&wc->wc_io_complete); - } - } -} - -static void o2hb_wait_on_io(struct o2hb_region *reg, - struct o2hb_bio_wait_ctxt *wc) -{ - o2hb_bio_wait_dec(wc, 1); - wait_for_completion(&wc->wc_io_complete); -} - -static void o2hb_bio_end_io(struct bio *bio, - int error) -{ - struct o2hb_bio_wait_ctxt *wc = bio->bi_private; - - if (error) { - mlog(ML_ERROR, "IO Error %d\n", error); - wc->wc_error = error; - } - - o2hb_bio_wait_dec(wc, 1); - bio_put(bio); -} - -/* Setup a Bio to cover I/O against num_slots slots starting at - * start_slot. */ -static struct bio *o2hb_setup_one_bio(struct o2hb_region *reg, - struct o2hb_bio_wait_ctxt *wc, - unsigned int *current_slot, - unsigned int max_slots) -{ - int len, current_page; - unsigned int vec_len, vec_start; - unsigned int bits = reg->hr_block_bits; - unsigned int spp = reg->hr_slots_per_page; - unsigned int cs = *current_slot; - struct bio *bio; - struct page *page; - - /* Testing has shown this allocation to take long enough under - * GFP_KERNEL that the local node can get fenced. It would be - * nicest if we could pre-allocate these bios and avoid this - * all together. */ - bio = bio_alloc(GFP_ATOMIC, 16); - if (!bio) { - mlog(ML_ERROR, "Could not alloc slots BIO!\n"); - bio = ERR_PTR(-ENOMEM); - goto bail; - } - - /* Must put everything in 512 byte sectors for the bio... */ - bio->bi_sector = (reg->hr_start_block + cs) << (bits - 9); - bio->bi_bdev = reg->hr_bdev; - bio->bi_private = wc; - bio->bi_end_io = o2hb_bio_end_io; - - vec_start = (cs << bits) % PAGE_CACHE_SIZE; - while(cs < max_slots) { - current_page = cs / spp; - page = reg->hr_slot_data[current_page]; - - vec_len = min(PAGE_CACHE_SIZE - vec_start, - (max_slots-cs) * (PAGE_CACHE_SIZE/spp) ); - - mlog(ML_HB_BIO, "page %d, vec_len = %u, vec_start = %u\n", - current_page, vec_len, vec_start); - - len = bio_add_page(bio, page, vec_len, vec_start); - if (len != vec_len) break; - - cs += vec_len / (PAGE_CACHE_SIZE/spp); - vec_start = 0; - } - -bail: - *current_slot = cs; - return bio; -} - -static int o2hb_read_slots(struct o2hb_region *reg, - unsigned int max_slots) -{ - unsigned int current_slot=0; - int status; - struct o2hb_bio_wait_ctxt wc; - struct bio *bio; - - o2hb_bio_wait_init(&wc); - - while(current_slot < max_slots) { - bio = o2hb_setup_one_bio(reg, &wc, ¤t_slot, max_slots); - if (IS_ERR(bio)) { - status = PTR_ERR(bio); - mlog_errno(status); - goto bail_and_wait; - } - - atomic_inc(&wc.wc_num_reqs); - submit_bio(READ, bio); - } - - status = 0; - -bail_and_wait: - o2hb_wait_on_io(reg, &wc); - if (wc.wc_error && !status) - status = wc.wc_error; - - return status; -} - -static int o2hb_issue_node_write(struct o2hb_region *reg, - struct o2hb_bio_wait_ctxt *write_wc) -{ - int status; - unsigned int slot; - struct bio *bio; - - o2hb_bio_wait_init(write_wc); - - slot = o2nm_this_node(); - - bio = o2hb_setup_one_bio(reg, write_wc, &slot, slot+1); - if (IS_ERR(bio)) { - status = PTR_ERR(bio); - mlog_errno(status); - goto bail; - } - - atomic_inc(&write_wc->wc_num_reqs); - submit_bio(WRITE, bio); - - status = 0; -bail: - return status; -} - -static u32 o2hb_compute_block_crc_le(struct o2hb_region *reg, - struct o2hb_disk_heartbeat_block *hb_block) -{ - __le32 old_cksum; - u32 ret; - - /* We want to compute the block crc with a 0 value in the - * hb_cksum field. Save it off here and replace after the - * crc. */ - old_cksum = hb_block->hb_cksum; - hb_block->hb_cksum = 0; - - ret = crc32_le(0, (unsigned char *) hb_block, reg->hr_block_bytes); - - hb_block->hb_cksum = old_cksum; - - return ret; -} - -static void o2hb_dump_slot(struct o2hb_disk_heartbeat_block *hb_block) -{ - mlog(ML_ERROR, "Dump slot information: seq = 0x%llx, node = %u, " - "cksum = 0x%x, generation 0x%llx\n", - (long long)le64_to_cpu(hb_block->hb_seq), - hb_block->hb_node, le32_to_cpu(hb_block->hb_cksum), - (long long)le64_to_cpu(hb_block->hb_generation)); -} - -static int o2hb_verify_crc(struct o2hb_region *reg, - struct o2hb_disk_heartbeat_block *hb_block) -{ - u32 read, computed; - - read = le32_to_cpu(hb_block->hb_cksum); - computed = o2hb_compute_block_crc_le(reg, hb_block); - - return read == computed; -} - -/* - * Compare the slot data with what we wrote in the last iteration. - * If the match fails, print an appropriate error message. This is to - * detect errors like... another node hearting on the same slot, - * flaky device that is losing writes, etc. - * Returns 1 if check succeeds, 0 otherwise. - */ -static int o2hb_check_own_slot(struct o2hb_region *reg) -{ - struct o2hb_disk_slot *slot; - struct o2hb_disk_heartbeat_block *hb_block; - char *errstr; - - slot = ®->hr_slots[o2nm_this_node()]; - /* Don't check on our 1st timestamp */ - if (!slot->ds_last_time) - return 0; - - hb_block = slot->ds_raw_block; - if (le64_to_cpu(hb_block->hb_seq) == slot->ds_last_time && - le64_to_cpu(hb_block->hb_generation) == slot->ds_last_generation && - hb_block->hb_node == slot->ds_node_num) - return 1; - -#define ERRSTR1 "Another node is heartbeating on device" -#define ERRSTR2 "Heartbeat generation mismatch on device" -#define ERRSTR3 "Heartbeat sequence mismatch on device" - - if (hb_block->hb_node != slot->ds_node_num) - errstr = ERRSTR1; - else if (le64_to_cpu(hb_block->hb_generation) != - slot->ds_last_generation) - errstr = ERRSTR2; - else - errstr = ERRSTR3; - - mlog(ML_ERROR, "%s (%s): expected(%u:0x%llx, 0x%llx), " - "ondisk(%u:0x%llx, 0x%llx)\n", errstr, reg->hr_dev_name, - slot->ds_node_num, (unsigned long long)slot->ds_last_generation, - (unsigned long long)slot->ds_last_time, hb_block->hb_node, - (unsigned long long)le64_to_cpu(hb_block->hb_generation), - (unsigned long long)le64_to_cpu(hb_block->hb_seq)); - - return 0; -} - -static inline void o2hb_prepare_block(struct o2hb_region *reg, - u64 generation) -{ - int node_num; - u64 cputime; - struct o2hb_disk_slot *slot; - struct o2hb_disk_heartbeat_block *hb_block; - - node_num = o2nm_this_node(); - slot = ®->hr_slots[node_num]; - - hb_block = (struct o2hb_disk_heartbeat_block *)slot->ds_raw_block; - memset(hb_block, 0, reg->hr_block_bytes); - /* TODO: time stuff */ - cputime = CURRENT_TIME.tv_sec; - if (!cputime) - cputime = 1; - - hb_block->hb_seq = cpu_to_le64(cputime); - hb_block->hb_node = node_num; - hb_block->hb_generation = cpu_to_le64(generation); - hb_block->hb_dead_ms = cpu_to_le32(o2hb_dead_threshold * O2HB_REGION_TIMEOUT_MS); - - /* This step must always happen last! */ - hb_block->hb_cksum = cpu_to_le32(o2hb_compute_block_crc_le(reg, - hb_block)); - - mlog(ML_HB_BIO, "our node generation = 0x%llx, cksum = 0x%x\n", - (long long)generation, - le32_to_cpu(hb_block->hb_cksum)); -} - -static void o2hb_fire_callbacks(struct o2hb_callback *hbcall, - struct o2nm_node *node, - int idx) -{ - struct list_head *iter; - struct o2hb_callback_func *f; - - list_for_each(iter, &hbcall->list) { - f = list_entry(iter, struct o2hb_callback_func, hc_item); - mlog(ML_HEARTBEAT, "calling funcs %p\n", f); - (f->hc_func)(node, idx, f->hc_data); - } -} - -/* Will run the list in order until we process the passed event */ -static void o2hb_run_event_list(struct o2hb_node_event *queued_event) -{ - int empty; - struct o2hb_callback *hbcall; - struct o2hb_node_event *event; - - spin_lock(&o2hb_live_lock); - empty = list_empty(&queued_event->hn_item); - spin_unlock(&o2hb_live_lock); - if (empty) - return; - - /* Holding callback sem assures we don't alter the callback - * lists when doing this, and serializes ourselves with other - * processes wanting callbacks. */ - down_write(&o2hb_callback_sem); - - spin_lock(&o2hb_live_lock); - while (!list_empty(&o2hb_node_events) - && !list_empty(&queued_event->hn_item)) { - event = list_entry(o2hb_node_events.next, - struct o2hb_node_event, - hn_item); - list_del_init(&event->hn_item); - spin_unlock(&o2hb_live_lock); - - mlog(ML_HEARTBEAT, "Node %s event for %d\n", - event->hn_event_type == O2HB_NODE_UP_CB ? "UP" : "DOWN", - event->hn_node_num); - - hbcall = hbcall_from_type(event->hn_event_type); - - /* We should *never* have gotten on to the list with a - * bad type... This isn't something that we should try - * to recover from. */ - BUG_ON(IS_ERR(hbcall)); - - o2hb_fire_callbacks(hbcall, event->hn_node, event->hn_node_num); - - spin_lock(&o2hb_live_lock); - } - spin_unlock(&o2hb_live_lock); - - up_write(&o2hb_callback_sem); -} - -static void o2hb_queue_node_event(struct o2hb_node_event *event, - enum o2hb_callback_type type, - struct o2nm_node *node, - int node_num) -{ - assert_spin_locked(&o2hb_live_lock); - - BUG_ON((!node) && (type != O2HB_NODE_DOWN_CB)); - - event->hn_event_type = type; - event->hn_node = node; - event->hn_node_num = node_num; - - mlog(ML_HEARTBEAT, "Queue node %s event for node %d\n", - type == O2HB_NODE_UP_CB ? "UP" : "DOWN", node_num); - - list_add_tail(&event->hn_item, &o2hb_node_events); -} - -static void o2hb_shutdown_slot(struct o2hb_disk_slot *slot) -{ - struct o2hb_node_event event = - { .hn_item = LIST_HEAD_INIT(event.hn_item), }; - struct o2nm_node *node; - - node = o2nm_get_node_by_num(slot->ds_node_num); - if (!node) - return; - - spin_lock(&o2hb_live_lock); - if (!list_empty(&slot->ds_live_item)) { - mlog(ML_HEARTBEAT, "Shutdown, node %d leaves region\n", - slot->ds_node_num); - - list_del_init(&slot->ds_live_item); - - if (list_empty(&o2hb_live_slots[slot->ds_node_num])) { - clear_bit(slot->ds_node_num, o2hb_live_node_bitmap); - - o2hb_queue_node_event(&event, O2HB_NODE_DOWN_CB, node, - slot->ds_node_num); - } - } - spin_unlock(&o2hb_live_lock); - - o2hb_run_event_list(&event); - - o2nm_node_put(node); -} - -static void o2hb_set_quorum_device(struct o2hb_region *reg) -{ - if (!o2hb_global_heartbeat_active()) - return; - - /* Prevent race with o2hb_heartbeat_group_drop_item() */ - if (kthread_should_stop()) - return; - - /* Tag region as quorum only after thread reaches steady state */ - if (atomic_read(®->hr_steady_iterations) != 0) - return; - - spin_lock(&o2hb_live_lock); - - if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap)) - goto unlock; - - /* - * A region can be added to the quorum only when it sees all - * live nodes heartbeat on it. In other words, the region has been - * added to all nodes. - */ - if (memcmp(reg->hr_live_node_bitmap, o2hb_live_node_bitmap, - sizeof(o2hb_live_node_bitmap))) - goto unlock; - - printk(KERN_NOTICE "o2hb: Region %s (%s) is now a quorum device\n", - config_item_name(®->hr_item), reg->hr_dev_name); - - set_bit(reg->hr_region_num, o2hb_quorum_region_bitmap); - - /* - * If global heartbeat active, unpin all regions if the - * region count > CUT_OFF - */ - if (o2hb_pop_count(&o2hb_quorum_region_bitmap, - O2NM_MAX_REGIONS) > O2HB_PIN_CUT_OFF) - o2hb_region_unpin(NULL); -unlock: - spin_unlock(&o2hb_live_lock); -} - -static int o2hb_check_slot(struct o2hb_region *reg, - struct o2hb_disk_slot *slot) -{ - int changed = 0, gen_changed = 0; - struct o2hb_node_event event = - { .hn_item = LIST_HEAD_INIT(event.hn_item), }; - struct o2nm_node *node; - struct o2hb_disk_heartbeat_block *hb_block = reg->hr_tmp_block; - u64 cputime; - unsigned int dead_ms = o2hb_dead_threshold * O2HB_REGION_TIMEOUT_MS; - unsigned int slot_dead_ms; - int tmp; - - memcpy(hb_block, slot->ds_raw_block, reg->hr_block_bytes); - - /* - * If a node is no longer configured but is still in the livemap, we - * may need to clear that bit from the livemap. - */ - node = o2nm_get_node_by_num(slot->ds_node_num); - if (!node) { - spin_lock(&o2hb_live_lock); - tmp = test_bit(slot->ds_node_num, o2hb_live_node_bitmap); - spin_unlock(&o2hb_live_lock); - if (!tmp) - return 0; - } - - if (!o2hb_verify_crc(reg, hb_block)) { - /* all paths from here will drop o2hb_live_lock for - * us. */ - spin_lock(&o2hb_live_lock); - - /* Don't print an error on the console in this case - - * a freshly formatted heartbeat area will not have a - * crc set on it. */ - if (list_empty(&slot->ds_live_item)) - goto out; - - /* The node is live but pushed out a bad crc. We - * consider it a transient miss but don't populate any - * other values as they may be junk. */ - mlog(ML_ERROR, "Node %d has written a bad crc to %s\n", - slot->ds_node_num, reg->hr_dev_name); - o2hb_dump_slot(hb_block); - - slot->ds_equal_samples++; - goto fire_callbacks; - } - - /* we don't care if these wrap.. the state transitions below - * clear at the right places */ - cputime = le64_to_cpu(hb_block->hb_seq); - if (slot->ds_last_time != cputime) - slot->ds_changed_samples++; - else - slot->ds_equal_samples++; - slot->ds_last_time = cputime; - - /* The node changed heartbeat generations. We assume this to - * mean it dropped off but came back before we timed out. We - * want to consider it down for the time being but don't want - * to lose any changed_samples state we might build up to - * considering it live again. */ - if (slot->ds_last_generation != le64_to_cpu(hb_block->hb_generation)) { - gen_changed = 1; - slot->ds_equal_samples = 0; - mlog(ML_HEARTBEAT, "Node %d changed generation (0x%llx " - "to 0x%llx)\n", slot->ds_node_num, - (long long)slot->ds_last_generation, - (long long)le64_to_cpu(hb_block->hb_generation)); - } - - slot->ds_last_generation = le64_to_cpu(hb_block->hb_generation); - - mlog(ML_HEARTBEAT, "Slot %d gen 0x%llx cksum 0x%x " - "seq %llu last %llu changed %u equal %u\n", - slot->ds_node_num, (long long)slot->ds_last_generation, - le32_to_cpu(hb_block->hb_cksum), - (unsigned long long)le64_to_cpu(hb_block->hb_seq), - (unsigned long long)slot->ds_last_time, slot->ds_changed_samples, - slot->ds_equal_samples); - - spin_lock(&o2hb_live_lock); - -fire_callbacks: - /* dead nodes only come to life after some number of - * changes at any time during their dead time */ - if (list_empty(&slot->ds_live_item) && - slot->ds_changed_samples >= O2HB_LIVE_THRESHOLD) { - mlog(ML_HEARTBEAT, "Node %d (id 0x%llx) joined my region\n", - slot->ds_node_num, (long long)slot->ds_last_generation); - - set_bit(slot->ds_node_num, reg->hr_live_node_bitmap); - - /* first on the list generates a callback */ - if (list_empty(&o2hb_live_slots[slot->ds_node_num])) { - mlog(ML_HEARTBEAT, "o2hb: Add node %d to live nodes " - "bitmap\n", slot->ds_node_num); - set_bit(slot->ds_node_num, o2hb_live_node_bitmap); - - o2hb_queue_node_event(&event, O2HB_NODE_UP_CB, node, - slot->ds_node_num); - - changed = 1; - } - - list_add_tail(&slot->ds_live_item, - &o2hb_live_slots[slot->ds_node_num]); - - slot->ds_equal_samples = 0; - - /* We want to be sure that all nodes agree on the - * number of milliseconds before a node will be - * considered dead. The self-fencing timeout is - * computed from this value, and a discrepancy might - * result in heartbeat calling a node dead when it - * hasn't self-fenced yet. */ - slot_dead_ms = le32_to_cpu(hb_block->hb_dead_ms); - if (slot_dead_ms && slot_dead_ms != dead_ms) { - /* TODO: Perhaps we can fail the region here. */ - mlog(ML_ERROR, "Node %d on device %s has a dead count " - "of %u ms, but our count is %u ms.\n" - "Please double check your configuration values " - "for 'O2CB_HEARTBEAT_THRESHOLD'\n", - slot->ds_node_num, reg->hr_dev_name, slot_dead_ms, - dead_ms); - } - goto out; - } - - /* if the list is dead, we're done.. */ - if (list_empty(&slot->ds_live_item)) - goto out; - - /* live nodes only go dead after enough consequtive missed - * samples.. reset the missed counter whenever we see - * activity */ - if (slot->ds_equal_samples >= o2hb_dead_threshold || gen_changed) { - mlog(ML_HEARTBEAT, "Node %d left my region\n", - slot->ds_node_num); - - clear_bit(slot->ds_node_num, reg->hr_live_node_bitmap); - - /* last off the live_slot generates a callback */ - list_del_init(&slot->ds_live_item); - if (list_empty(&o2hb_live_slots[slot->ds_node_num])) { - mlog(ML_HEARTBEAT, "o2hb: Remove node %d from live " - "nodes bitmap\n", slot->ds_node_num); - clear_bit(slot->ds_node_num, o2hb_live_node_bitmap); - - /* node can be null */ - o2hb_queue_node_event(&event, O2HB_NODE_DOWN_CB, - node, slot->ds_node_num); - - changed = 1; - } - - /* We don't clear this because the node is still - * actually writing new blocks. */ - if (!gen_changed) - slot->ds_changed_samples = 0; - goto out; - } - if (slot->ds_changed_samples) { - slot->ds_changed_samples = 0; - slot->ds_equal_samples = 0; - } -out: - spin_unlock(&o2hb_live_lock); - - o2hb_run_event_list(&event); - - if (node) - o2nm_node_put(node); - return changed; -} - -/* This could be faster if we just implmented a find_last_bit, but I - * don't think the circumstances warrant it. */ -static int o2hb_highest_node(unsigned long *nodes, - int numbits) -{ - int highest, node; - - highest = numbits; - node = -1; - while ((node = find_next_bit(nodes, numbits, node + 1)) != -1) { - if (node >= numbits) - break; - - highest = node; - } - - return highest; -} - -static int o2hb_do_disk_heartbeat(struct o2hb_region *reg) -{ - int i, ret, highest_node; - int membership_change = 0, own_slot_ok = 0; - unsigned long configured_nodes[BITS_TO_LONGS(O2NM_MAX_NODES)]; - unsigned long live_node_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)]; - struct o2hb_bio_wait_ctxt write_wc; - - ret = o2nm_configured_node_map(configured_nodes, - sizeof(configured_nodes)); - if (ret) { - mlog_errno(ret); - goto bail; - } - - /* - * If a node is not configured but is in the livemap, we still need - * to read the slot so as to be able to remove it from the livemap. - */ - o2hb_fill_node_map(live_node_bitmap, sizeof(live_node_bitmap)); - i = -1; - while ((i = find_next_bit(live_node_bitmap, - O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES) { - set_bit(i, configured_nodes); - } - - highest_node = o2hb_highest_node(configured_nodes, O2NM_MAX_NODES); - if (highest_node >= O2NM_MAX_NODES) { - mlog(ML_NOTICE, "o2hb: No configured nodes found!\n"); - ret = -EINVAL; - goto bail; - } - - /* No sense in reading the slots of nodes that don't exist - * yet. Of course, if the node definitions have holes in them - * then we're reading an empty slot anyway... Consider this - * best-effort. */ - ret = o2hb_read_slots(reg, highest_node + 1); - if (ret < 0) { - mlog_errno(ret); - goto bail; - } - - /* With an up to date view of the slots, we can check that no - * other node has been improperly configured to heartbeat in - * our slot. */ - own_slot_ok = o2hb_check_own_slot(reg); - - /* fill in the proper info for our next heartbeat */ - o2hb_prepare_block(reg, reg->hr_generation); - - ret = o2hb_issue_node_write(reg, &write_wc); - if (ret < 0) { - mlog_errno(ret); - goto bail; - } - - i = -1; - while((i = find_next_bit(configured_nodes, - O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES) { - membership_change |= o2hb_check_slot(reg, ®->hr_slots[i]); - } - - /* - * We have to be sure we've advertised ourselves on disk - * before we can go to steady state. This ensures that - * people we find in our steady state have seen us. - */ - o2hb_wait_on_io(reg, &write_wc); - if (write_wc.wc_error) { - /* Do not re-arm the write timeout on I/O error - we - * can't be sure that the new block ever made it to - * disk */ - mlog(ML_ERROR, "Write error %d on device \"%s\"\n", - write_wc.wc_error, reg->hr_dev_name); - ret = write_wc.wc_error; - goto bail; - } - - /* Skip disarming the timeout if own slot has stale/bad data */ - if (own_slot_ok) { - o2hb_set_quorum_device(reg); - o2hb_arm_write_timeout(reg); - } - -bail: - /* let the person who launched us know when things are steady */ - if (atomic_read(®->hr_steady_iterations) != 0) { - if (!ret && own_slot_ok && !membership_change) { - if (atomic_dec_and_test(®->hr_steady_iterations)) - wake_up(&o2hb_steady_queue); - } - } - - if (atomic_read(®->hr_steady_iterations) != 0) { - if (atomic_dec_and_test(®->hr_unsteady_iterations)) { - printk(KERN_NOTICE "o2hb: Unable to stabilize " - "heartbeart on region %s (%s)\n", - config_item_name(®->hr_item), - reg->hr_dev_name); - atomic_set(®->hr_steady_iterations, 0); - reg->hr_aborted_start = 1; - wake_up(&o2hb_steady_queue); - ret = -EIO; - } - } - - return ret; -} - -/* Subtract b from a, storing the result in a. a *must* have a larger - * value than b. */ -static void o2hb_tv_subtract(struct timeval *a, - struct timeval *b) -{ - /* just return 0 when a is after b */ - if (a->tv_sec < b->tv_sec || - (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec)) { - a->tv_sec = 0; - a->tv_usec = 0; - return; - } - - a->tv_sec -= b->tv_sec; - a->tv_usec -= b->tv_usec; - while ( a->tv_usec < 0 ) { - a->tv_sec--; - a->tv_usec += 1000000; - } -} - -static unsigned int o2hb_elapsed_msecs(struct timeval *start, - struct timeval *end) -{ - struct timeval res = *end; - - o2hb_tv_subtract(&res, start); - - return res.tv_sec * 1000 + res.tv_usec / 1000; -} - -/* - * we ride the region ref that the region dir holds. before the region - * dir is removed and drops it ref it will wait to tear down this - * thread. - */ -static int o2hb_thread(void *data) -{ - int i, ret; - struct o2hb_region *reg = data; - struct o2hb_bio_wait_ctxt write_wc; - struct timeval before_hb, after_hb; - unsigned int elapsed_msec; - - mlog(ML_HEARTBEAT|ML_KTHREAD, "hb thread running\n"); - - set_user_nice(current, -20); - - /* Pin node */ - o2nm_depend_this_node(); - - while (!kthread_should_stop() && - !reg->hr_unclean_stop && !reg->hr_aborted_start) { - /* We track the time spent inside - * o2hb_do_disk_heartbeat so that we avoid more than - * hr_timeout_ms between disk writes. On busy systems - * this should result in a heartbeat which is less - * likely to time itself out. */ - do_gettimeofday(&before_hb); - - ret = o2hb_do_disk_heartbeat(reg); - - do_gettimeofday(&after_hb); - elapsed_msec = o2hb_elapsed_msecs(&before_hb, &after_hb); - - mlog(ML_HEARTBEAT, - "start = %lu.%lu, end = %lu.%lu, msec = %u\n", - before_hb.tv_sec, (unsigned long) before_hb.tv_usec, - after_hb.tv_sec, (unsigned long) after_hb.tv_usec, - elapsed_msec); - - if (!kthread_should_stop() && - elapsed_msec < reg->hr_timeout_ms) { - /* the kthread api has blocked signals for us so no - * need to record the return value. */ - msleep_interruptible(reg->hr_timeout_ms - elapsed_msec); - } - } - - o2hb_disarm_write_timeout(reg); - - /* unclean stop is only used in very bad situation */ - for(i = 0; !reg->hr_unclean_stop && i < reg->hr_blocks; i++) - o2hb_shutdown_slot(®->hr_slots[i]); - - /* Explicit down notification - avoid forcing the other nodes - * to timeout on this region when we could just as easily - * write a clear generation - thus indicating to them that - * this node has left this region. - */ - if (!reg->hr_unclean_stop && !reg->hr_aborted_start) { - o2hb_prepare_block(reg, 0); - ret = o2hb_issue_node_write(reg, &write_wc); - if (ret == 0) - o2hb_wait_on_io(reg, &write_wc); - else - mlog_errno(ret); - } - - /* Unpin node */ - o2nm_undepend_this_node(); - - mlog(ML_HEARTBEAT|ML_KTHREAD, "o2hb thread exiting\n"); - - return 0; -} - -#ifdef CONFIG_DEBUG_FS -static int o2hb_debug_open(struct inode *inode, struct file *file) -{ - struct o2hb_debug_buf *db = inode->i_private; - struct o2hb_region *reg; - unsigned long map[BITS_TO_LONGS(O2NM_MAX_NODES)]; - unsigned long lts; - char *buf = NULL; - int i = -1; - int out = 0; - - /* max_nodes should be the largest bitmap we pass here */ - BUG_ON(sizeof(map) < db->db_size); - - buf = kmalloc(PAGE_SIZE, GFP_KERNEL); - if (!buf) - goto bail; - - switch (db->db_type) { - case O2HB_DB_TYPE_LIVENODES: - case O2HB_DB_TYPE_LIVEREGIONS: - case O2HB_DB_TYPE_QUORUMREGIONS: - case O2HB_DB_TYPE_FAILEDREGIONS: - spin_lock(&o2hb_live_lock); - memcpy(map, db->db_data, db->db_size); - spin_unlock(&o2hb_live_lock); - break; - - case O2HB_DB_TYPE_REGION_LIVENODES: - spin_lock(&o2hb_live_lock); - reg = (struct o2hb_region *)db->db_data; - memcpy(map, reg->hr_live_node_bitmap, db->db_size); - spin_unlock(&o2hb_live_lock); - break; - - case O2HB_DB_TYPE_REGION_NUMBER: - reg = (struct o2hb_region *)db->db_data; - out += snprintf(buf + out, PAGE_SIZE - out, "%d\n", - reg->hr_region_num); - goto done; - - case O2HB_DB_TYPE_REGION_ELAPSED_TIME: - reg = (struct o2hb_region *)db->db_data; - lts = reg->hr_last_timeout_start; - /* If 0, it has never been set before */ - if (lts) - lts = jiffies_to_msecs(jiffies - lts); - out += snprintf(buf + out, PAGE_SIZE - out, "%lu\n", lts); - goto done; - - case O2HB_DB_TYPE_REGION_PINNED: - reg = (struct o2hb_region *)db->db_data; - out += snprintf(buf + out, PAGE_SIZE - out, "%u\n", - !!reg->hr_item_pinned); - goto done; - - default: - goto done; - } - - while ((i = find_next_bit(map, db->db_len, i + 1)) < db->db_len) - out += snprintf(buf + out, PAGE_SIZE - out, "%d ", i); - out += snprintf(buf + out, PAGE_SIZE - out, "\n"); - -done: - i_size_write(inode, out); - - file->private_data = buf; - - return 0; -bail: - return -ENOMEM; -} - -static int o2hb_debug_release(struct inode *inode, struct file *file) -{ - kfree(file->private_data); - return 0; -} - -static ssize_t o2hb_debug_read(struct file *file, char __user *buf, - size_t nbytes, loff_t *ppos) -{ - return simple_read_from_buffer(buf, nbytes, ppos, file->private_data, - i_size_read(file->f_mapping->host)); -} -#else -static int o2hb_debug_open(struct inode *inode, struct file *file) -{ - return 0; -} -static int o2hb_debug_release(struct inode *inode, struct file *file) -{ - return 0; -} -static ssize_t o2hb_debug_read(struct file *file, char __user *buf, - size_t nbytes, loff_t *ppos) -{ - return 0; -} -#endif /* CONFIG_DEBUG_FS */ - -static const struct file_operations o2hb_debug_fops = { - .open = o2hb_debug_open, - .release = o2hb_debug_release, - .read = o2hb_debug_read, - .llseek = generic_file_llseek, -}; - -void o2hb_exit(void) -{ - kfree(o2hb_db_livenodes); - kfree(o2hb_db_liveregions); - kfree(o2hb_db_quorumregions); - kfree(o2hb_db_failedregions); - debugfs_remove(o2hb_debug_failedregions); - debugfs_remove(o2hb_debug_quorumregions); - debugfs_remove(o2hb_debug_liveregions); - debugfs_remove(o2hb_debug_livenodes); - debugfs_remove(o2hb_debug_dir); -} - -static struct dentry *o2hb_debug_create(const char *name, struct dentry *dir, - struct o2hb_debug_buf **db, int db_len, - int type, int size, int len, void *data) -{ - *db = kmalloc(db_len, GFP_KERNEL); - if (!*db) - return NULL; - - (*db)->db_type = type; - (*db)->db_size = size; - (*db)->db_len = len; - (*db)->db_data = data; - - return debugfs_create_file(name, S_IFREG|S_IRUSR, dir, *db, - &o2hb_debug_fops); -} - -static int o2hb_debug_init(void) -{ - int ret = -ENOMEM; - - o2hb_debug_dir = debugfs_create_dir(O2HB_DEBUG_DIR, NULL); - if (!o2hb_debug_dir) { - mlog_errno(ret); - goto bail; - } - - o2hb_debug_livenodes = o2hb_debug_create(O2HB_DEBUG_LIVENODES, - o2hb_debug_dir, - &o2hb_db_livenodes, - sizeof(*o2hb_db_livenodes), - O2HB_DB_TYPE_LIVENODES, - sizeof(o2hb_live_node_bitmap), - O2NM_MAX_NODES, - o2hb_live_node_bitmap); - if (!o2hb_debug_livenodes) { - mlog_errno(ret); - goto bail; - } - - o2hb_debug_liveregions = o2hb_debug_create(O2HB_DEBUG_LIVEREGIONS, - o2hb_debug_dir, - &o2hb_db_liveregions, - sizeof(*o2hb_db_liveregions), - O2HB_DB_TYPE_LIVEREGIONS, - sizeof(o2hb_live_region_bitmap), - O2NM_MAX_REGIONS, - o2hb_live_region_bitmap); - if (!o2hb_debug_liveregions) { - mlog_errno(ret); - goto bail; - } - - o2hb_debug_quorumregions = - o2hb_debug_create(O2HB_DEBUG_QUORUMREGIONS, - o2hb_debug_dir, - &o2hb_db_quorumregions, - sizeof(*o2hb_db_quorumregions), - O2HB_DB_TYPE_QUORUMREGIONS, - sizeof(o2hb_quorum_region_bitmap), - O2NM_MAX_REGIONS, - o2hb_quorum_region_bitmap); - if (!o2hb_debug_quorumregions) { - mlog_errno(ret); - goto bail; - } - - o2hb_debug_failedregions = - o2hb_debug_create(O2HB_DEBUG_FAILEDREGIONS, - o2hb_debug_dir, - &o2hb_db_failedregions, - sizeof(*o2hb_db_failedregions), - O2HB_DB_TYPE_FAILEDREGIONS, - sizeof(o2hb_failed_region_bitmap), - O2NM_MAX_REGIONS, - o2hb_failed_region_bitmap); - if (!o2hb_debug_failedregions) { - mlog_errno(ret); - goto bail; - } - - ret = 0; -bail: - if (ret) - o2hb_exit(); - - return ret; -} - -int o2hb_init(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(o2hb_callbacks); i++) - INIT_LIST_HEAD(&o2hb_callbacks[i].list); - - for (i = 0; i < ARRAY_SIZE(o2hb_live_slots); i++) - INIT_LIST_HEAD(&o2hb_live_slots[i]); - - INIT_LIST_HEAD(&o2hb_node_events); - - memset(o2hb_live_node_bitmap, 0, sizeof(o2hb_live_node_bitmap)); - memset(o2hb_region_bitmap, 0, sizeof(o2hb_region_bitmap)); - memset(o2hb_live_region_bitmap, 0, sizeof(o2hb_live_region_bitmap)); - memset(o2hb_quorum_region_bitmap, 0, sizeof(o2hb_quorum_region_bitmap)); - memset(o2hb_failed_region_bitmap, 0, sizeof(o2hb_failed_region_bitmap)); - - o2hb_dependent_users = 0; - - return o2hb_debug_init(); -} - -/* if we're already in a callback then we're already serialized by the sem */ -static void o2hb_fill_node_map_from_callback(unsigned long *map, - unsigned bytes) -{ - BUG_ON(bytes < (BITS_TO_LONGS(O2NM_MAX_NODES) * sizeof(unsigned long))); - - memcpy(map, &o2hb_live_node_bitmap, bytes); -} - -/* - * get a map of all nodes that are heartbeating in any regions - */ -void o2hb_fill_node_map(unsigned long *map, unsigned bytes) -{ - /* callers want to serialize this map and callbacks so that they - * can trust that they don't miss nodes coming to the party */ - down_read(&o2hb_callback_sem); - spin_lock(&o2hb_live_lock); - o2hb_fill_node_map_from_callback(map, bytes); - spin_unlock(&o2hb_live_lock); - up_read(&o2hb_callback_sem); -} -EXPORT_SYMBOL_GPL(o2hb_fill_node_map); - -/* - * heartbeat configfs bits. The heartbeat set is a default set under - * the cluster set in nodemanager.c. - */ - -static struct o2hb_region *to_o2hb_region(struct config_item *item) -{ - return item ? container_of(item, struct o2hb_region, hr_item) : NULL; -} - -/* drop_item only drops its ref after killing the thread, nothing should - * be using the region anymore. this has to clean up any state that - * attributes might have built up. */ -static void o2hb_region_release(struct config_item *item) -{ - int i; - struct page *page; - struct o2hb_region *reg = to_o2hb_region(item); - - mlog(ML_HEARTBEAT, "hb region release (%s)\n", reg->hr_dev_name); - - if (reg->hr_tmp_block) - kfree(reg->hr_tmp_block); - - if (reg->hr_slot_data) { - for (i = 0; i < reg->hr_num_pages; i++) { - page = reg->hr_slot_data[i]; - if (page) - __free_page(page); - } - kfree(reg->hr_slot_data); - } - - if (reg->hr_bdev) - blkdev_put(reg->hr_bdev, FMODE_READ|FMODE_WRITE); - - if (reg->hr_slots) - kfree(reg->hr_slots); - - kfree(reg->hr_db_regnum); - kfree(reg->hr_db_livenodes); - debugfs_remove(reg->hr_debug_livenodes); - debugfs_remove(reg->hr_debug_regnum); - debugfs_remove(reg->hr_debug_elapsed_time); - debugfs_remove(reg->hr_debug_pinned); - debugfs_remove(reg->hr_debug_dir); - - spin_lock(&o2hb_live_lock); - list_del(®->hr_all_item); - spin_unlock(&o2hb_live_lock); - - kfree(reg); -} - -static int o2hb_read_block_input(struct o2hb_region *reg, - const char *page, - size_t count, - unsigned long *ret_bytes, - unsigned int *ret_bits) -{ - unsigned long bytes; - char *p = (char *)page; - - bytes = simple_strtoul(p, &p, 0); - if (!p || (*p && (*p != '\n'))) - return -EINVAL; - - /* Heartbeat and fs min / max block sizes are the same. */ - if (bytes > 4096 || bytes < 512) - return -ERANGE; - if (hweight16(bytes) != 1) - return -EINVAL; - - if (ret_bytes) - *ret_bytes = bytes; - if (ret_bits) - *ret_bits = ffs(bytes) - 1; - - return 0; -} - -static ssize_t o2hb_region_block_bytes_read(struct o2hb_region *reg, - char *page) -{ - return sprintf(page, "%u\n", reg->hr_block_bytes); -} - -static ssize_t o2hb_region_block_bytes_write(struct o2hb_region *reg, - const char *page, - size_t count) -{ - int status; - unsigned long block_bytes; - unsigned int block_bits; - - if (reg->hr_bdev) - return -EINVAL; - - status = o2hb_read_block_input(reg, page, count, - &block_bytes, &block_bits); - if (status) - return status; - - reg->hr_block_bytes = (unsigned int)block_bytes; - reg->hr_block_bits = block_bits; - - return count; -} - -static ssize_t o2hb_region_start_block_read(struct o2hb_region *reg, - char *page) -{ - return sprintf(page, "%llu\n", reg->hr_start_block); -} - -static ssize_t o2hb_region_start_block_write(struct o2hb_region *reg, - const char *page, - size_t count) -{ - unsigned long long tmp; - char *p = (char *)page; - - if (reg->hr_bdev) - return -EINVAL; - - tmp = simple_strtoull(p, &p, 0); - if (!p || (*p && (*p != '\n'))) - return -EINVAL; - - reg->hr_start_block = tmp; - - return count; -} - -static ssize_t o2hb_region_blocks_read(struct o2hb_region *reg, - char *page) -{ - return sprintf(page, "%d\n", reg->hr_blocks); -} - -static ssize_t o2hb_region_blocks_write(struct o2hb_region *reg, - const char *page, - size_t count) -{ - unsigned long tmp; - char *p = (char *)page; - - if (reg->hr_bdev) - return -EINVAL; - - tmp = simple_strtoul(p, &p, 0); - if (!p || (*p && (*p != '\n'))) - return -EINVAL; - - if (tmp > O2NM_MAX_NODES || tmp == 0) - return -ERANGE; - - reg->hr_blocks = (unsigned int)tmp; - - return count; -} - -static ssize_t o2hb_region_dev_read(struct o2hb_region *reg, - char *page) -{ - unsigned int ret = 0; - - if (reg->hr_bdev) - ret = sprintf(page, "%s\n", reg->hr_dev_name); - - return ret; -} - -static void o2hb_init_region_params(struct o2hb_region *reg) -{ - reg->hr_slots_per_page = PAGE_CACHE_SIZE >> reg->hr_block_bits; - reg->hr_timeout_ms = O2HB_REGION_TIMEOUT_MS; - - mlog(ML_HEARTBEAT, "hr_start_block = %llu, hr_blocks = %u\n", - reg->hr_start_block, reg->hr_blocks); - mlog(ML_HEARTBEAT, "hr_block_bytes = %u, hr_block_bits = %u\n", - reg->hr_block_bytes, reg->hr_block_bits); - mlog(ML_HEARTBEAT, "hr_timeout_ms = %u\n", reg->hr_timeout_ms); - mlog(ML_HEARTBEAT, "dead threshold = %u\n", o2hb_dead_threshold); -} - -static int o2hb_map_slot_data(struct o2hb_region *reg) -{ - int i, j; - unsigned int last_slot; - unsigned int spp = reg->hr_slots_per_page; - struct page *page; - char *raw; - struct o2hb_disk_slot *slot; - - reg->hr_tmp_block = kmalloc(reg->hr_block_bytes, GFP_KERNEL); - if (reg->hr_tmp_block == NULL) { - mlog_errno(-ENOMEM); - return -ENOMEM; - } - - reg->hr_slots = kcalloc(reg->hr_blocks, - sizeof(struct o2hb_disk_slot), GFP_KERNEL); - if (reg->hr_slots == NULL) { - mlog_errno(-ENOMEM); - return -ENOMEM; - } - - for(i = 0; i < reg->hr_blocks; i++) { - slot = ®->hr_slots[i]; - slot->ds_node_num = i; - INIT_LIST_HEAD(&slot->ds_live_item); - slot->ds_raw_block = NULL; - } - - reg->hr_num_pages = (reg->hr_blocks + spp - 1) / spp; - mlog(ML_HEARTBEAT, "Going to require %u pages to cover %u blocks " - "at %u blocks per page\n", - reg->hr_num_pages, reg->hr_blocks, spp); - - reg->hr_slot_data = kcalloc(reg->hr_num_pages, sizeof(struct page *), - GFP_KERNEL); - if (!reg->hr_slot_data) { - mlog_errno(-ENOMEM); - return -ENOMEM; - } - - for(i = 0; i < reg->hr_num_pages; i++) { - page = alloc_page(GFP_KERNEL); - if (!page) { - mlog_errno(-ENOMEM); - return -ENOMEM; - } - - reg->hr_slot_data[i] = page; - - last_slot = i * spp; - raw = page_address(page); - for (j = 0; - (j < spp) && ((j + last_slot) < reg->hr_blocks); - j++) { - BUG_ON((j + last_slot) >= reg->hr_blocks); - - slot = ®->hr_slots[j + last_slot]; - slot->ds_raw_block = - (struct o2hb_disk_heartbeat_block *) raw; - - raw += reg->hr_block_bytes; - } - } - - return 0; -} - -/* Read in all the slots available and populate the tracking - * structures so that we can start with a baseline idea of what's - * there. */ -static int o2hb_populate_slot_data(struct o2hb_region *reg) -{ - int ret, i; - struct o2hb_disk_slot *slot; - struct o2hb_disk_heartbeat_block *hb_block; - - ret = o2hb_read_slots(reg, reg->hr_blocks); - if (ret) { - mlog_errno(ret); - goto out; - } - - /* We only want to get an idea of the values initially in each - * slot, so we do no verification - o2hb_check_slot will - * actually determine if each configured slot is valid and - * whether any values have changed. */ - for(i = 0; i < reg->hr_blocks; i++) { - slot = ®->hr_slots[i]; - hb_block = (struct o2hb_disk_heartbeat_block *) slot->ds_raw_block; - - /* Only fill the values that o2hb_check_slot uses to - * determine changing slots */ - slot->ds_last_time = le64_to_cpu(hb_block->hb_seq); - slot->ds_last_generation = le64_to_cpu(hb_block->hb_generation); - } - -out: - return ret; -} - -/* this is acting as commit; we set up all of hr_bdev and hr_task or nothing */ -static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, - const char *page, - size_t count) -{ - struct task_struct *hb_task; - long fd; - int sectsize; - char *p = (char *)page; - struct file *filp = NULL; - struct inode *inode = NULL; - ssize_t ret = -EINVAL; - int live_threshold; - - if (reg->hr_bdev) - goto out; - - /* We can't heartbeat without having had our node number - * configured yet. */ - if (o2nm_this_node() == O2NM_MAX_NODES) - goto out; - - fd = simple_strtol(p, &p, 0); - if (!p || (*p && (*p != '\n'))) - goto out; - - if (fd < 0 || fd >= INT_MAX) - goto out; - - filp = fget(fd); - if (filp == NULL) - goto out; - - if (reg->hr_blocks == 0 || reg->hr_start_block == 0 || - reg->hr_block_bytes == 0) - goto out; - - inode = igrab(filp->f_mapping->host); - if (inode == NULL) - goto out; - - if (!S_ISBLK(inode->i_mode)) - goto out; - - reg->hr_bdev = I_BDEV(filp->f_mapping->host); - ret = blkdev_get(reg->hr_bdev, FMODE_WRITE | FMODE_READ, NULL); - if (ret) { - reg->hr_bdev = NULL; - goto out; - } - inode = NULL; - - bdevname(reg->hr_bdev, reg->hr_dev_name); - - sectsize = bdev_logical_block_size(reg->hr_bdev); - if (sectsize != reg->hr_block_bytes) { - mlog(ML_ERROR, - "blocksize %u incorrect for device, expected %d", - reg->hr_block_bytes, sectsize); - ret = -EINVAL; - goto out; - } - - o2hb_init_region_params(reg); - - /* Generation of zero is invalid */ - do { - get_random_bytes(®->hr_generation, - sizeof(reg->hr_generation)); - } while (reg->hr_generation == 0); - - ret = o2hb_map_slot_data(reg); - if (ret) { - mlog_errno(ret); - goto out; - } - - ret = o2hb_populate_slot_data(reg); - if (ret) { - mlog_errno(ret); - goto out; - } - - INIT_DELAYED_WORK(®->hr_write_timeout_work, o2hb_write_timeout); - - /* - * A node is considered live after it has beat LIVE_THRESHOLD - * times. We're not steady until we've given them a chance - * _after_ our first read. - * The default threshold is bare minimum so as to limit the delay - * during mounts. For global heartbeat, the threshold doubled for the - * first region. - */ - live_threshold = O2HB_LIVE_THRESHOLD; - if (o2hb_global_heartbeat_active()) { - spin_lock(&o2hb_live_lock); - if (o2hb_pop_count(&o2hb_region_bitmap, O2NM_MAX_REGIONS) == 1) - live_threshold <<= 1; - spin_unlock(&o2hb_live_lock); - } - ++live_threshold; - atomic_set(®->hr_steady_iterations, live_threshold); - /* unsteady_iterations is double the steady_iterations */ - atomic_set(®->hr_unsteady_iterations, (live_threshold << 1)); - - hb_task = kthread_run(o2hb_thread, reg, "o2hb-%s", - reg->hr_item.ci_name); - if (IS_ERR(hb_task)) { - ret = PTR_ERR(hb_task); - mlog_errno(ret); - goto out; - } - - spin_lock(&o2hb_live_lock); - reg->hr_task = hb_task; - spin_unlock(&o2hb_live_lock); - - ret = wait_event_interruptible(o2hb_steady_queue, - atomic_read(®->hr_steady_iterations) == 0); - if (ret) { - atomic_set(®->hr_steady_iterations, 0); - reg->hr_aborted_start = 1; - } - - if (reg->hr_aborted_start) { - ret = -EIO; - goto out; - } - - /* Ok, we were woken. Make sure it wasn't by drop_item() */ - spin_lock(&o2hb_live_lock); - hb_task = reg->hr_task; - if (o2hb_global_heartbeat_active()) - set_bit(reg->hr_region_num, o2hb_live_region_bitmap); - spin_unlock(&o2hb_live_lock); - - if (hb_task) - ret = count; - else - ret = -EIO; - - if (hb_task && o2hb_global_heartbeat_active()) - printk(KERN_NOTICE "o2hb: Heartbeat started on region %s (%s)\n", - config_item_name(®->hr_item), reg->hr_dev_name); - -out: - if (filp) - fput(filp); - if (inode) - iput(inode); - if (ret < 0) { - if (reg->hr_bdev) { - blkdev_put(reg->hr_bdev, FMODE_READ|FMODE_WRITE); - reg->hr_bdev = NULL; - } - } - return ret; -} - -static ssize_t o2hb_region_pid_read(struct o2hb_region *reg, - char *page) -{ - pid_t pid = 0; - - spin_lock(&o2hb_live_lock); - if (reg->hr_task) - pid = task_pid_nr(reg->hr_task); - spin_unlock(&o2hb_live_lock); - - if (!pid) - return 0; - - return sprintf(page, "%u\n", pid); -} - -struct o2hb_region_attribute { - struct configfs_attribute attr; - ssize_t (*show)(struct o2hb_region *, char *); - ssize_t (*store)(struct o2hb_region *, const char *, size_t); -}; - -static struct o2hb_region_attribute o2hb_region_attr_block_bytes = { - .attr = { .ca_owner = THIS_MODULE, - .ca_name = "block_bytes", - .ca_mode = S_IRUGO | S_IWUSR }, - .show = o2hb_region_block_bytes_read, - .store = o2hb_region_block_bytes_write, -}; - -static struct o2hb_region_attribute o2hb_region_attr_start_block = { - .attr = { .ca_owner = THIS_MODULE, - .ca_name = "start_block", - .ca_mode = S_IRUGO | S_IWUSR }, - .show = o2hb_region_start_block_read, - .store = o2hb_region_start_block_write, -}; - -static struct o2hb_region_attribute o2hb_region_attr_blocks = { - .attr = { .ca_owner = THIS_MODULE, - .ca_name = "blocks", - .ca_mode = S_IRUGO | S_IWUSR }, - .show = o2hb_region_blocks_read, - .store = o2hb_region_blocks_write, -}; - -static struct o2hb_region_attribute o2hb_region_attr_dev = { - .attr = { .ca_owner = THIS_MODULE, - .ca_name = "dev", - .ca_mode = S_IRUGO | S_IWUSR }, - .show = o2hb_region_dev_read, - .store = o2hb_region_dev_write, -}; - -static struct o2hb_region_attribute o2hb_region_attr_pid = { - .attr = { .ca_owner = THIS_MODULE, - .ca_name = "pid", - .ca_mode = S_IRUGO | S_IRUSR }, - .show = o2hb_region_pid_read, -}; - -static struct configfs_attribute *o2hb_region_attrs[] = { - &o2hb_region_attr_block_bytes.attr, - &o2hb_region_attr_start_block.attr, - &o2hb_region_attr_blocks.attr, - &o2hb_region_attr_dev.attr, - &o2hb_region_attr_pid.attr, - NULL, -}; - -static ssize_t o2hb_region_show(struct config_item *item, - struct configfs_attribute *attr, - char *page) -{ - struct o2hb_region *reg = to_o2hb_region(item); - struct o2hb_region_attribute *o2hb_region_attr = - container_of(attr, struct o2hb_region_attribute, attr); - ssize_t ret = 0; - - if (o2hb_region_attr->show) - ret = o2hb_region_attr->show(reg, page); - return ret; -} - -static ssize_t o2hb_region_store(struct config_item *item, - struct configfs_attribute *attr, - const char *page, size_t count) -{ - struct o2hb_region *reg = to_o2hb_region(item); - struct o2hb_region_attribute *o2hb_region_attr = - container_of(attr, struct o2hb_region_attribute, attr); - ssize_t ret = -EINVAL; - - if (o2hb_region_attr->store) - ret = o2hb_region_attr->store(reg, page, count); - return ret; -} - -static struct configfs_item_operations o2hb_region_item_ops = { - .release = o2hb_region_release, - .show_attribute = o2hb_region_show, - .store_attribute = o2hb_region_store, -}; - -static struct config_item_type o2hb_region_type = { - .ct_item_ops = &o2hb_region_item_ops, - .ct_attrs = o2hb_region_attrs, - .ct_owner = THIS_MODULE, -}; - -/* heartbeat set */ - -struct o2hb_heartbeat_group { - struct config_group hs_group; - /* some stuff? */ -}; - -static struct o2hb_heartbeat_group *to_o2hb_heartbeat_group(struct config_group *group) -{ - return group ? - container_of(group, struct o2hb_heartbeat_group, hs_group) - : NULL; -} - -static int o2hb_debug_region_init(struct o2hb_region *reg, struct dentry *dir) -{ - int ret = -ENOMEM; - - reg->hr_debug_dir = - debugfs_create_dir(config_item_name(®->hr_item), dir); - if (!reg->hr_debug_dir) { - mlog_errno(ret); - goto bail; - } - - reg->hr_debug_livenodes = - o2hb_debug_create(O2HB_DEBUG_LIVENODES, - reg->hr_debug_dir, - &(reg->hr_db_livenodes), - sizeof(*(reg->hr_db_livenodes)), - O2HB_DB_TYPE_REGION_LIVENODES, - sizeof(reg->hr_live_node_bitmap), - O2NM_MAX_NODES, reg); - if (!reg->hr_debug_livenodes) { - mlog_errno(ret); - goto bail; - } - - reg->hr_debug_regnum = - o2hb_debug_create(O2HB_DEBUG_REGION_NUMBER, - reg->hr_debug_dir, - &(reg->hr_db_regnum), - sizeof(*(reg->hr_db_regnum)), - O2HB_DB_TYPE_REGION_NUMBER, - 0, O2NM_MAX_NODES, reg); - if (!reg->hr_debug_regnum) { - mlog_errno(ret); - goto bail; - } - - reg->hr_debug_elapsed_time = - o2hb_debug_create(O2HB_DEBUG_REGION_ELAPSED_TIME, - reg->hr_debug_dir, - &(reg->hr_db_elapsed_time), - sizeof(*(reg->hr_db_elapsed_time)), - O2HB_DB_TYPE_REGION_ELAPSED_TIME, - 0, 0, reg); - if (!reg->hr_debug_elapsed_time) { - mlog_errno(ret); - goto bail; - } - - reg->hr_debug_pinned = - o2hb_debug_create(O2HB_DEBUG_REGION_PINNED, - reg->hr_debug_dir, - &(reg->hr_db_pinned), - sizeof(*(reg->hr_db_pinned)), - O2HB_DB_TYPE_REGION_PINNED, - 0, 0, reg); - if (!reg->hr_debug_pinned) { - mlog_errno(ret); - goto bail; - } - - ret = 0; -bail: - return ret; -} - -static struct config_item *o2hb_heartbeat_group_make_item(struct config_group *group, - const char *name) -{ - struct o2hb_region *reg = NULL; - int ret; - - reg = kzalloc(sizeof(struct o2hb_region), GFP_KERNEL); - if (reg == NULL) - return ERR_PTR(-ENOMEM); - - if (strlen(name) > O2HB_MAX_REGION_NAME_LEN) { - ret = -ENAMETOOLONG; - goto free; - } - - spin_lock(&o2hb_live_lock); - reg->hr_region_num = 0; - if (o2hb_global_heartbeat_active()) { - reg->hr_region_num = find_first_zero_bit(o2hb_region_bitmap, - O2NM_MAX_REGIONS); - if (reg->hr_region_num >= O2NM_MAX_REGIONS) { - spin_unlock(&o2hb_live_lock); - ret = -EFBIG; - goto free; - } - set_bit(reg->hr_region_num, o2hb_region_bitmap); - } - list_add_tail(®->hr_all_item, &o2hb_all_regions); - spin_unlock(&o2hb_live_lock); - - config_item_init_type_name(®->hr_item, name, &o2hb_region_type); - - ret = o2hb_debug_region_init(reg, o2hb_debug_dir); - if (ret) { - config_item_put(®->hr_item); - goto free; - } - - return ®->hr_item; -free: - kfree(reg); - return ERR_PTR(ret); -} - -static void o2hb_heartbeat_group_drop_item(struct config_group *group, - struct config_item *item) -{ - struct task_struct *hb_task; - struct o2hb_region *reg = to_o2hb_region(item); - int quorum_region = 0; - - /* stop the thread when the user removes the region dir */ - spin_lock(&o2hb_live_lock); - hb_task = reg->hr_task; - reg->hr_task = NULL; - reg->hr_item_dropped = 1; - spin_unlock(&o2hb_live_lock); - - if (hb_task) - kthread_stop(hb_task); - - if (o2hb_global_heartbeat_active()) { - spin_lock(&o2hb_live_lock); - clear_bit(reg->hr_region_num, o2hb_region_bitmap); - clear_bit(reg->hr_region_num, o2hb_live_region_bitmap); - if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap)) - quorum_region = 1; - clear_bit(reg->hr_region_num, o2hb_quorum_region_bitmap); - spin_unlock(&o2hb_live_lock); - printk(KERN_NOTICE "o2hb: Heartbeat %s on region %s (%s)\n", - ((atomic_read(®->hr_steady_iterations) == 0) ? - "stopped" : "start aborted"), config_item_name(item), - reg->hr_dev_name); - } - - /* - * If we're racing a dev_write(), we need to wake them. They will - * check reg->hr_task - */ - if (atomic_read(®->hr_steady_iterations) != 0) { - reg->hr_aborted_start = 1; - atomic_set(®->hr_steady_iterations, 0); - wake_up(&o2hb_steady_queue); - } - - config_item_put(item); - - if (!o2hb_global_heartbeat_active() || !quorum_region) - return; - - /* - * If global heartbeat active and there are dependent users, - * pin all regions if quorum region count <= CUT_OFF - */ - spin_lock(&o2hb_live_lock); - - if (!o2hb_dependent_users) - goto unlock; - - if (o2hb_pop_count(&o2hb_quorum_region_bitmap, - O2NM_MAX_REGIONS) <= O2HB_PIN_CUT_OFF) - o2hb_region_pin(NULL); - -unlock: - spin_unlock(&o2hb_live_lock); -} - -struct o2hb_heartbeat_group_attribute { - struct configfs_attribute attr; - ssize_t (*show)(struct o2hb_heartbeat_group *, char *); - ssize_t (*store)(struct o2hb_heartbeat_group *, const char *, size_t); -}; - -static ssize_t o2hb_heartbeat_group_show(struct config_item *item, - struct configfs_attribute *attr, - char *page) -{ - struct o2hb_heartbeat_group *reg = to_o2hb_heartbeat_group(to_config_group(item)); - struct o2hb_heartbeat_group_attribute *o2hb_heartbeat_group_attr = - container_of(attr, struct o2hb_heartbeat_group_attribute, attr); - ssize_t ret = 0; - - if (o2hb_heartbeat_group_attr->show) - ret = o2hb_heartbeat_group_attr->show(reg, page); - return ret; -} - -static ssize_t o2hb_heartbeat_group_store(struct config_item *item, - struct configfs_attribute *attr, - const char *page, size_t count) -{ - struct o2hb_heartbeat_group *reg = to_o2hb_heartbeat_group(to_config_group(item)); - struct o2hb_heartbeat_group_attribute *o2hb_heartbeat_group_attr = - container_of(attr, struct o2hb_heartbeat_group_attribute, attr); - ssize_t ret = -EINVAL; - - if (o2hb_heartbeat_group_attr->store) - ret = o2hb_heartbeat_group_attr->store(reg, page, count); - return ret; -} - -static ssize_t o2hb_heartbeat_group_threshold_show(struct o2hb_heartbeat_group *group, - char *page) -{ - return sprintf(page, "%u\n", o2hb_dead_threshold); -} - -static ssize_t o2hb_heartbeat_group_threshold_store(struct o2hb_heartbeat_group *group, - const char *page, - size_t count) -{ - unsigned long tmp; - char *p = (char *)page; - - tmp = simple_strtoul(p, &p, 10); - if (!p || (*p && (*p != '\n'))) - return -EINVAL; - - /* this will validate ranges for us. */ - o2hb_dead_threshold_set((unsigned int) tmp); - - return count; -} - -static -ssize_t o2hb_heartbeat_group_mode_show(struct o2hb_heartbeat_group *group, - char *page) -{ - return sprintf(page, "%s\n", - o2hb_heartbeat_mode_desc[o2hb_heartbeat_mode]); -} - -static -ssize_t o2hb_heartbeat_group_mode_store(struct o2hb_heartbeat_group *group, - const char *page, size_t count) -{ - unsigned int i; - int ret; - size_t len; - - len = (page[count - 1] == '\n') ? count - 1 : count; - if (!len) - return -EINVAL; - - for (i = 0; i < O2HB_HEARTBEAT_NUM_MODES; ++i) { - if (strnicmp(page, o2hb_heartbeat_mode_desc[i], len)) - continue; - - ret = o2hb_global_hearbeat_mode_set(i); - if (!ret) - printk(KERN_NOTICE "o2hb: Heartbeat mode set to %s\n", - o2hb_heartbeat_mode_desc[i]); - return count; - } - - return -EINVAL; - -} - -static struct o2hb_heartbeat_group_attribute o2hb_heartbeat_group_attr_threshold = { - .attr = { .ca_owner = THIS_MODULE, - .ca_name = "dead_threshold", - .ca_mode = S_IRUGO | S_IWUSR }, - .show = o2hb_heartbeat_group_threshold_show, - .store = o2hb_heartbeat_group_threshold_store, -}; - -static struct o2hb_heartbeat_group_attribute o2hb_heartbeat_group_attr_mode = { - .attr = { .ca_owner = THIS_MODULE, - .ca_name = "mode", - .ca_mode = S_IRUGO | S_IWUSR }, - .show = o2hb_heartbeat_group_mode_show, - .store = o2hb_heartbeat_group_mode_store, -}; - -static struct configfs_attribute *o2hb_heartbeat_group_attrs[] = { - &o2hb_heartbeat_group_attr_threshold.attr, - &o2hb_heartbeat_group_attr_mode.attr, - NULL, -}; - -static struct configfs_item_operations o2hb_hearbeat_group_item_ops = { - .show_attribute = o2hb_heartbeat_group_show, - .store_attribute = o2hb_heartbeat_group_store, -}; - -static struct configfs_group_operations o2hb_heartbeat_group_group_ops = { - .make_item = o2hb_heartbeat_group_make_item, - .drop_item = o2hb_heartbeat_group_drop_item, -}; - -static struct config_item_type o2hb_heartbeat_group_type = { - .ct_group_ops = &o2hb_heartbeat_group_group_ops, - .ct_item_ops = &o2hb_hearbeat_group_item_ops, - .ct_attrs = o2hb_heartbeat_group_attrs, - .ct_owner = THIS_MODULE, -}; - -/* this is just here to avoid touching group in heartbeat.h which the - * entire damn world #includes */ -struct config_group *o2hb_alloc_hb_set(void) -{ - struct o2hb_heartbeat_group *hs = NULL; - struct config_group *ret = NULL; - - hs = kzalloc(sizeof(struct o2hb_heartbeat_group), GFP_KERNEL); - if (hs == NULL) - goto out; - - config_group_init_type_name(&hs->hs_group, "heartbeat", - &o2hb_heartbeat_group_type); - - ret = &hs->hs_group; -out: - if (ret == NULL) - kfree(hs); - return ret; -} - -void o2hb_free_hb_set(struct config_group *group) -{ - struct o2hb_heartbeat_group *hs = to_o2hb_heartbeat_group(group); - kfree(hs); -} - -/* hb callback registration and issuing */ - -static struct o2hb_callback *hbcall_from_type(enum o2hb_callback_type type) -{ - if (type == O2HB_NUM_CB) - return ERR_PTR(-EINVAL); - - return &o2hb_callbacks[type]; -} - -void o2hb_setup_callback(struct o2hb_callback_func *hc, - enum o2hb_callback_type type, - o2hb_cb_func *func, - void *data, - int priority) -{ - INIT_LIST_HEAD(&hc->hc_item); - hc->hc_func = func; - hc->hc_data = data; - hc->hc_priority = priority; - hc->hc_type = type; - hc->hc_magic = O2HB_CB_MAGIC; -} -EXPORT_SYMBOL_GPL(o2hb_setup_callback); - -/* - * In local heartbeat mode, region_uuid passed matches the dlm domain name. - * In global heartbeat mode, region_uuid passed is NULL. - * - * In local, we only pin the matching region. In global we pin all the active - * regions. - */ -static int o2hb_region_pin(const char *region_uuid) -{ - int ret = 0, found = 0; - struct o2hb_region *reg; - char *uuid; - - assert_spin_locked(&o2hb_live_lock); - - list_for_each_entry(reg, &o2hb_all_regions, hr_all_item) { - uuid = config_item_name(®->hr_item); - - /* local heartbeat */ - if (region_uuid) { - if (strcmp(region_uuid, uuid)) - continue; - found = 1; - } - - if (reg->hr_item_pinned || reg->hr_item_dropped) - goto skip_pin; - - /* Ignore ENOENT only for local hb (userdlm domain) */ - ret = o2nm_depend_item(®->hr_item); - if (!ret) { - mlog(ML_CLUSTER, "Pin region %s\n", uuid); - reg->hr_item_pinned = 1; - } else { - if (ret == -ENOENT && found) - ret = 0; - else { - mlog(ML_ERROR, "Pin region %s fails with %d\n", - uuid, ret); - break; - } - } -skip_pin: - if (found) - break; - } - - return ret; -} - -/* - * In local heartbeat mode, region_uuid passed matches the dlm domain name. - * In global heartbeat mode, region_uuid passed is NULL. - * - * In local, we only unpin the matching region. In global we unpin all the - * active regions. - */ -static void o2hb_region_unpin(const char *region_uuid) -{ - struct o2hb_region *reg; - char *uuid; - int found = 0; - - assert_spin_locked(&o2hb_live_lock); - - list_for_each_entry(reg, &o2hb_all_regions, hr_all_item) { - uuid = config_item_name(®->hr_item); - if (region_uuid) { - if (strcmp(region_uuid, uuid)) - continue; - found = 1; - } - - if (reg->hr_item_pinned) { - mlog(ML_CLUSTER, "Unpin region %s\n", uuid); - o2nm_undepend_item(®->hr_item); - reg->hr_item_pinned = 0; - } - if (found) - break; - } -} - -static int o2hb_region_inc_user(const char *region_uuid) -{ - int ret = 0; - - spin_lock(&o2hb_live_lock); - - /* local heartbeat */ - if (!o2hb_global_heartbeat_active()) { - ret = o2hb_region_pin(region_uuid); - goto unlock; - } - - /* - * if global heartbeat active and this is the first dependent user, - * pin all regions if quorum region count <= CUT_OFF - */ - o2hb_dependent_users++; - if (o2hb_dependent_users > 1) - goto unlock; - - if (o2hb_pop_count(&o2hb_quorum_region_bitmap, - O2NM_MAX_REGIONS) <= O2HB_PIN_CUT_OFF) - ret = o2hb_region_pin(NULL); - -unlock: - spin_unlock(&o2hb_live_lock); - return ret; -} - -void o2hb_region_dec_user(const char *region_uuid) -{ - spin_lock(&o2hb_live_lock); - - /* local heartbeat */ - if (!o2hb_global_heartbeat_active()) { - o2hb_region_unpin(region_uuid); - goto unlock; - } - - /* - * if global heartbeat active and there are no dependent users, - * unpin all quorum regions - */ - o2hb_dependent_users--; - if (!o2hb_dependent_users) - o2hb_region_unpin(NULL); - -unlock: - spin_unlock(&o2hb_live_lock); -} - -int o2hb_register_callback(const char *region_uuid, - struct o2hb_callback_func *hc) -{ - struct o2hb_callback_func *tmp; - struct list_head *iter; - struct o2hb_callback *hbcall; - int ret; - - BUG_ON(hc->hc_magic != O2HB_CB_MAGIC); - BUG_ON(!list_empty(&hc->hc_item)); - - hbcall = hbcall_from_type(hc->hc_type); - if (IS_ERR(hbcall)) { - ret = PTR_ERR(hbcall); - goto out; - } - - if (region_uuid) { - ret = o2hb_region_inc_user(region_uuid); - if (ret) { - mlog_errno(ret); - goto out; - } - } - - down_write(&o2hb_callback_sem); - - list_for_each(iter, &hbcall->list) { - tmp = list_entry(iter, struct o2hb_callback_func, hc_item); - if (hc->hc_priority < tmp->hc_priority) { - list_add_tail(&hc->hc_item, iter); - break; - } - } - if (list_empty(&hc->hc_item)) - list_add_tail(&hc->hc_item, &hbcall->list); - - up_write(&o2hb_callback_sem); - ret = 0; -out: - mlog(ML_CLUSTER, "returning %d on behalf of %p for funcs %p\n", - ret, __builtin_return_address(0), hc); - return ret; -} -EXPORT_SYMBOL_GPL(o2hb_register_callback); - -void o2hb_unregister_callback(const char *region_uuid, - struct o2hb_callback_func *hc) -{ - BUG_ON(hc->hc_magic != O2HB_CB_MAGIC); - - mlog(ML_CLUSTER, "on behalf of %p for funcs %p\n", - __builtin_return_address(0), hc); - - /* XXX Can this happen _with_ a region reference? */ - if (list_empty(&hc->hc_item)) - return; - - if (region_uuid) - o2hb_region_dec_user(region_uuid); - - down_write(&o2hb_callback_sem); - - list_del_init(&hc->hc_item); - - up_write(&o2hb_callback_sem); -} -EXPORT_SYMBOL_GPL(o2hb_unregister_callback); - -int o2hb_check_node_heartbeating(u8 node_num) -{ - unsigned long testing_map[BITS_TO_LONGS(O2NM_MAX_NODES)]; - - o2hb_fill_node_map(testing_map, sizeof(testing_map)); - if (!test_bit(node_num, testing_map)) { - mlog(ML_HEARTBEAT, - "node (%u) does not have heartbeating enabled.\n", - node_num); - return 0; - } - - return 1; -} -EXPORT_SYMBOL_GPL(o2hb_check_node_heartbeating); - -int o2hb_check_node_heartbeating_from_callback(u8 node_num) -{ - unsigned long testing_map[BITS_TO_LONGS(O2NM_MAX_NODES)]; - - o2hb_fill_node_map_from_callback(testing_map, sizeof(testing_map)); - if (!test_bit(node_num, testing_map)) { - mlog(ML_HEARTBEAT, - "node (%u) does not have heartbeating enabled.\n", - node_num); - return 0; - } - - return 1; -} -EXPORT_SYMBOL_GPL(o2hb_check_node_heartbeating_from_callback); - -/* Makes sure our local node is configured with a node number, and is - * heartbeating. */ -int o2hb_check_local_node_heartbeating(void) -{ - u8 node_num; - - /* if this node was set then we have networking */ - node_num = o2nm_this_node(); - if (node_num == O2NM_MAX_NODES) { - mlog(ML_HEARTBEAT, "this node has not been configured.\n"); - return 0; - } - - return o2hb_check_node_heartbeating(node_num); -} -EXPORT_SYMBOL_GPL(o2hb_check_local_node_heartbeating); - -/* - * this is just a hack until we get the plumbing which flips file systems - * read only and drops the hb ref instead of killing the node dead. - */ -void o2hb_stop_all_regions(void) -{ - struct o2hb_region *reg; - - mlog(ML_ERROR, "stopping heartbeat on all active regions.\n"); - - spin_lock(&o2hb_live_lock); - - list_for_each_entry(reg, &o2hb_all_regions, hr_all_item) - reg->hr_unclean_stop = 1; - - spin_unlock(&o2hb_live_lock); -} -EXPORT_SYMBOL_GPL(o2hb_stop_all_regions); - -int o2hb_get_all_regions(char *region_uuids, u8 max_regions) -{ - struct o2hb_region *reg; - int numregs = 0; - char *p; - - spin_lock(&o2hb_live_lock); - - p = region_uuids; - list_for_each_entry(reg, &o2hb_all_regions, hr_all_item) { - mlog(0, "Region: %s\n", config_item_name(®->hr_item)); - if (numregs < max_regions) { - memcpy(p, config_item_name(®->hr_item), - O2HB_MAX_REGION_NAME_LEN); - p += O2HB_MAX_REGION_NAME_LEN; - } - numregs++; - } - - spin_unlock(&o2hb_live_lock); - - return numregs; -} -EXPORT_SYMBOL_GPL(o2hb_get_all_regions); - -int o2hb_global_heartbeat_active(void) -{ - return (o2hb_heartbeat_mode == O2HB_HEARTBEAT_GLOBAL); -} -EXPORT_SYMBOL(o2hb_global_heartbeat_active); - -#ifdef CONFIG_RAMSTER -void o2hb_manual_set_node_heartbeating(int node_num) -{ - if (node_num < O2NM_MAX_NODES) - set_bit(node_num, o2hb_live_node_bitmap); -} -EXPORT_SYMBOL(o2hb_manual_set_node_heartbeating); -#endif diff --git a/drivers/staging/ramster/cluster/heartbeat.h b/drivers/staging/ramster/cluster/heartbeat.h deleted file mode 100644 index cf1a16426d9..00000000000 --- a/drivers/staging/ramster/cluster/heartbeat.h +++ /dev/null @@ -1,92 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * heartbeat.h - * - * Function prototypes - * - * Copyright (C) 2004 Oracle. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - * - */ - -#ifndef O2CLUSTER_HEARTBEAT_H -#define O2CLUSTER_HEARTBEAT_H - -#include "ocfs2_heartbeat.h" - -#define O2HB_REGION_TIMEOUT_MS 2000 - -#define O2HB_MAX_REGION_NAME_LEN 32 - -/* number of changes to be seen as live */ -#define O2HB_LIVE_THRESHOLD 2 -/* number of equal samples to be seen as dead */ -extern unsigned int o2hb_dead_threshold; -#define O2HB_DEFAULT_DEAD_THRESHOLD 31 -/* Otherwise MAX_WRITE_TIMEOUT will be zero... */ -#define O2HB_MIN_DEAD_THRESHOLD 2 -#define O2HB_MAX_WRITE_TIMEOUT_MS (O2HB_REGION_TIMEOUT_MS * (o2hb_dead_threshold - 1)) - -#define O2HB_CB_MAGIC 0x51d1e4ec - -/* callback stuff */ -enum o2hb_callback_type { - O2HB_NODE_DOWN_CB = 0, - O2HB_NODE_UP_CB, - O2HB_NUM_CB -}; - -struct o2nm_node; -typedef void (o2hb_cb_func)(struct o2nm_node *, int, void *); - -struct o2hb_callback_func { - u32 hc_magic; - struct list_head hc_item; - o2hb_cb_func *hc_func; - void *hc_data; - int hc_priority; - enum o2hb_callback_type hc_type; -}; - -struct config_group *o2hb_alloc_hb_set(void); -void o2hb_free_hb_set(struct config_group *group); - -void o2hb_setup_callback(struct o2hb_callback_func *hc, - enum o2hb_callback_type type, - o2hb_cb_func *func, - void *data, - int priority); -int o2hb_register_callback(const char *region_uuid, - struct o2hb_callback_func *hc); -void o2hb_unregister_callback(const char *region_uuid, - struct o2hb_callback_func *hc); -void o2hb_fill_node_map(unsigned long *map, - unsigned bytes); -void o2hb_exit(void); -int o2hb_init(void); -int o2hb_check_node_heartbeating(u8 node_num); -int o2hb_check_node_heartbeating_from_callback(u8 node_num); -int o2hb_check_local_node_heartbeating(void); -void o2hb_stop_all_regions(void); -int o2hb_get_all_regions(char *region_uuids, u8 numregions); -int o2hb_global_heartbeat_active(void); -#ifdef CONFIG_RAMSTER -void o2hb_manual_set_node_heartbeating(int); -#endif - -#endif /* O2CLUSTER_HEARTBEAT_H */ diff --git a/drivers/staging/ramster/cluster/masklog.c b/drivers/staging/ramster/cluster/masklog.c deleted file mode 100644 index 07ac24fd925..00000000000 --- a/drivers/staging/ramster/cluster/masklog.c +++ /dev/null @@ -1,155 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * Copyright (C) 2004, 2005 Oracle. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - */ - -#include -#include -#include -#include -#include -#include - -#include "masklog.h" - -struct mlog_bits mlog_and_bits = MLOG_BITS_RHS(MLOG_INITIAL_AND_MASK); -EXPORT_SYMBOL_GPL(mlog_and_bits); -struct mlog_bits mlog_not_bits = MLOG_BITS_RHS(0); -EXPORT_SYMBOL_GPL(mlog_not_bits); - -static ssize_t mlog_mask_show(u64 mask, char *buf) -{ - char *state; - - if (__mlog_test_u64(mask, mlog_and_bits)) - state = "allow"; - else if (__mlog_test_u64(mask, mlog_not_bits)) - state = "deny"; - else - state = "off"; - - return snprintf(buf, PAGE_SIZE, "%s\n", state); -} - -static ssize_t mlog_mask_store(u64 mask, const char *buf, size_t count) -{ - if (!strnicmp(buf, "allow", 5)) { - __mlog_set_u64(mask, mlog_and_bits); - __mlog_clear_u64(mask, mlog_not_bits); - } else if (!strnicmp(buf, "deny", 4)) { - __mlog_set_u64(mask, mlog_not_bits); - __mlog_clear_u64(mask, mlog_and_bits); - } else if (!strnicmp(buf, "off", 3)) { - __mlog_clear_u64(mask, mlog_not_bits); - __mlog_clear_u64(mask, mlog_and_bits); - } else - return -EINVAL; - - return count; -} - -struct mlog_attribute { - struct attribute attr; - u64 mask; -}; - -#define to_mlog_attr(_attr) container_of(_attr, struct mlog_attribute, attr) - -#define define_mask(_name) { \ - .attr = { \ - .name = #_name, \ - .mode = S_IRUGO | S_IWUSR, \ - }, \ - .mask = ML_##_name, \ -} - -static struct mlog_attribute mlog_attrs[MLOG_MAX_BITS] = { - define_mask(TCP), - define_mask(MSG), - define_mask(SOCKET), - define_mask(HEARTBEAT), - define_mask(HB_BIO), - define_mask(DLMFS), - define_mask(DLM), - define_mask(DLM_DOMAIN), - define_mask(DLM_THREAD), - define_mask(DLM_MASTER), - define_mask(DLM_RECOVERY), - define_mask(DLM_GLUE), - define_mask(VOTE), - define_mask(CONN), - define_mask(QUORUM), - define_mask(BASTS), - define_mask(CLUSTER), - define_mask(ERROR), - define_mask(NOTICE), - define_mask(KTHREAD), -}; - -static struct attribute *mlog_attr_ptrs[MLOG_MAX_BITS] = {NULL, }; - -static ssize_t mlog_show(struct kobject *obj, struct attribute *attr, - char *buf) -{ - struct mlog_attribute *mlog_attr = to_mlog_attr(attr); - - return mlog_mask_show(mlog_attr->mask, buf); -} - -static ssize_t mlog_store(struct kobject *obj, struct attribute *attr, - const char *buf, size_t count) -{ - struct mlog_attribute *mlog_attr = to_mlog_attr(attr); - - return mlog_mask_store(mlog_attr->mask, buf, count); -} - -static const struct sysfs_ops mlog_attr_ops = { - .show = mlog_show, - .store = mlog_store, -}; - -static struct kobj_type mlog_ktype = { - .default_attrs = mlog_attr_ptrs, - .sysfs_ops = &mlog_attr_ops, -}; - -static struct kset mlog_kset = { - .kobj = {.ktype = &mlog_ktype}, -}; - -int mlog_sys_init(struct kset *o2cb_kset) -{ - int i = 0; - - while (mlog_attrs[i].attr.mode) { - mlog_attr_ptrs[i] = &mlog_attrs[i].attr; - i++; - } - mlog_attr_ptrs[i] = NULL; - - kobject_set_name(&mlog_kset.kobj, "logmask"); - mlog_kset.kobj.kset = o2cb_kset; - return kset_register(&mlog_kset); -} - -void mlog_sys_shutdown(void) -{ - kset_unregister(&mlog_kset); -} diff --git a/drivers/staging/ramster/cluster/masklog.h b/drivers/staging/ramster/cluster/masklog.h deleted file mode 100644 index baa2b9ef7ee..00000000000 --- a/drivers/staging/ramster/cluster/masklog.h +++ /dev/null @@ -1,219 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * Copyright (C) 2005 Oracle. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - */ - -#ifndef O2CLUSTER_MASKLOG_H -#define O2CLUSTER_MASKLOG_H - -/* - * For now this is a trivial wrapper around printk() that gives the critical - * ability to enable sets of debugging output at run-time. In the future this - * will almost certainly be redirected to relayfs so that it can pay a - * substantially lower heisenberg tax. - * - * Callers associate the message with a bitmask and a global bitmask is - * maintained with help from /proc. If any of the bits match the message is - * output. - * - * We must have efficient bit tests on i386 and it seems gcc still emits crazy - * code for the 64bit compare. It emits very good code for the dual unsigned - * long tests, though, completely avoiding tests that can never pass if the - * caller gives a constant bitmask that fills one of the longs with all 0s. So - * the desire is to have almost all of the calls decided on by comparing just - * one of the longs. This leads to having infrequently given bits that are - * frequently matched in the high bits. - * - * _ERROR and _NOTICE are used for messages that always go to the console and - * have appropriate KERN_ prefixes. We wrap these in our function instead of - * just calling printk() so that this can eventually make its way through - * relayfs along with the debugging messages. Everything else gets KERN_DEBUG. - * The inline tests and macro dance give GCC the opportunity to quite cleverly - * only emit the appropriage printk() when the caller passes in a constant - * mask, as is almost always the case. - * - * All this bitmask nonsense is managed from the files under - * /sys/fs/o2cb/logmask/. Reading the files gives a straightforward - * indication of which bits are allowed (allow) or denied (off/deny). - * ENTRY deny - * EXIT deny - * TCP off - * MSG off - * SOCKET off - * ERROR allow - * NOTICE allow - * - * Writing changes the state of a given bit and requires a strictly formatted - * single write() call: - * - * write(fd, "allow", 5); - * - * Echoing allow/deny/off string into the logmask files can flip the bits - * on or off as expected; here is the bash script for example: - * - * log_mask="/sys/fs/o2cb/log_mask" - * for node in ENTRY EXIT TCP MSG SOCKET ERROR NOTICE; do - * echo allow >"$log_mask"/"$node" - * done - * - * The debugfs.ocfs2 tool can also flip the bits with the -l option: - * - * debugfs.ocfs2 -l TCP allow - */ - -/* for task_struct */ -#include - -/* bits that are frequently given and infrequently matched in the low word */ -/* NOTE: If you add a flag, you need to also update masklog.c! */ -#define ML_TCP 0x0000000000000001ULL /* net cluster/tcp.c */ -#define ML_MSG 0x0000000000000002ULL /* net network messages */ -#define ML_SOCKET 0x0000000000000004ULL /* net socket lifetime */ -#define ML_HEARTBEAT 0x0000000000000008ULL /* hb all heartbeat tracking */ -#define ML_HB_BIO 0x0000000000000010ULL /* hb io tracing */ -#define ML_DLMFS 0x0000000000000020ULL /* dlm user dlmfs */ -#define ML_DLM 0x0000000000000040ULL /* dlm general debugging */ -#define ML_DLM_DOMAIN 0x0000000000000080ULL /* dlm domain debugging */ -#define ML_DLM_THREAD 0x0000000000000100ULL /* dlm domain thread */ -#define ML_DLM_MASTER 0x0000000000000200ULL /* dlm master functions */ -#define ML_DLM_RECOVERY 0x0000000000000400ULL /* dlm master functions */ -#define ML_DLM_GLUE 0x0000000000000800ULL /* ocfs2 dlm glue layer */ -#define ML_VOTE 0x0000000000001000ULL /* ocfs2 node messaging */ -#define ML_CONN 0x0000000000002000ULL /* net connection management */ -#define ML_QUORUM 0x0000000000004000ULL /* net connection quorum */ -#define ML_BASTS 0x0000000000008000ULL /* dlmglue asts and basts */ -#define ML_CLUSTER 0x0000000000010000ULL /* cluster stack */ - -/* bits that are infrequently given and frequently matched in the high word */ -#define ML_ERROR 0x1000000000000000ULL /* sent to KERN_ERR */ -#define ML_NOTICE 0x2000000000000000ULL /* setn to KERN_NOTICE */ -#define ML_KTHREAD 0x4000000000000000ULL /* kernel thread activity */ - -#define MLOG_INITIAL_AND_MASK (ML_ERROR|ML_NOTICE) -#ifndef MLOG_MASK_PREFIX -#define MLOG_MASK_PREFIX 0 -#endif - -/* - * When logging is disabled, force the bit test to 0 for anything other - * than errors and notices, allowing gcc to remove the code completely. - * When enabled, allow all masks. - */ -#if defined(CONFIG_OCFS2_DEBUG_MASKLOG) -#define ML_ALLOWED_BITS ~0 -#else -#define ML_ALLOWED_BITS (ML_ERROR|ML_NOTICE) -#endif - -#define MLOG_MAX_BITS 64 - -struct mlog_bits { - unsigned long words[MLOG_MAX_BITS / BITS_PER_LONG]; -}; - -extern struct mlog_bits mlog_and_bits, mlog_not_bits; - -#if BITS_PER_LONG == 32 - -#define __mlog_test_u64(mask, bits) \ - ( (u32)(mask & 0xffffffff) & bits.words[0] || \ - ((u64)(mask) >> 32) & bits.words[1] ) -#define __mlog_set_u64(mask, bits) do { \ - bits.words[0] |= (u32)(mask & 0xffffffff); \ - bits.words[1] |= (u64)(mask) >> 32; \ -} while (0) -#define __mlog_clear_u64(mask, bits) do { \ - bits.words[0] &= ~((u32)(mask & 0xffffffff)); \ - bits.words[1] &= ~((u64)(mask) >> 32); \ -} while (0) -#define MLOG_BITS_RHS(mask) { \ - { \ - [0] = (u32)(mask & 0xffffffff), \ - [1] = (u64)(mask) >> 32, \ - } \ -} - -#else /* 32bit long above, 64bit long below */ - -#define __mlog_test_u64(mask, bits) ((mask) & bits.words[0]) -#define __mlog_set_u64(mask, bits) do { \ - bits.words[0] |= (mask); \ -} while (0) -#define __mlog_clear_u64(mask, bits) do { \ - bits.words[0] &= ~(mask); \ -} while (0) -#define MLOG_BITS_RHS(mask) { { (mask) } } - -#endif - -/* - * smp_processor_id() "helpfully" screams when called outside preemptible - * regions in current kernels. sles doesn't have the variants that don't - * scream. just do this instead of trying to guess which we're building - * against.. *sigh*. - */ -#define __mlog_cpu_guess ({ \ - unsigned long _cpu = get_cpu(); \ - put_cpu(); \ - _cpu; \ -}) - -/* In the following two macros, the whitespace after the ',' just - * before ##args is intentional. Otherwise, gcc 2.95 will eat the - * previous token if args expands to nothing. - */ -#define __mlog_printk(level, fmt, args...) \ - printk(level "(%s,%u,%lu):%s:%d " fmt, current->comm, \ - task_pid_nr(current), __mlog_cpu_guess, \ - __PRETTY_FUNCTION__, __LINE__ , ##args) - -#define mlog(mask, fmt, args...) do { \ - u64 __m = MLOG_MASK_PREFIX | (mask); \ - if ((__m & ML_ALLOWED_BITS) && \ - __mlog_test_u64(__m, mlog_and_bits) && \ - !__mlog_test_u64(__m, mlog_not_bits)) { \ - if (__m & ML_ERROR) \ - __mlog_printk(KERN_ERR, "ERROR: "fmt , ##args); \ - else if (__m & ML_NOTICE) \ - __mlog_printk(KERN_NOTICE, fmt , ##args); \ - else __mlog_printk(KERN_INFO, fmt , ##args); \ - } \ -} while (0) - -#define mlog_errno(st) do { \ - int _st = (st); \ - if (_st != -ERESTARTSYS && _st != -EINTR && \ - _st != AOP_TRUNCATED_PAGE && _st != -ENOSPC) \ - mlog(ML_ERROR, "status = %lld\n", (long long)_st); \ -} while (0) - -#define mlog_bug_on_msg(cond, fmt, args...) do { \ - if (cond) { \ - mlog(ML_ERROR, "bug expression: " #cond "\n"); \ - mlog(ML_ERROR, fmt, ##args); \ - BUG(); \ - } \ -} while (0) - -#include -#include -int mlog_sys_init(struct kset *o2cb_subsys); -void mlog_sys_shutdown(void); - -#endif /* O2CLUSTER_MASKLOG_H */ diff --git a/drivers/staging/ramster/cluster/netdebug.c b/drivers/staging/ramster/cluster/netdebug.c deleted file mode 100644 index dc45deb19e6..00000000000 --- a/drivers/staging/ramster/cluster/netdebug.c +++ /dev/null @@ -1,579 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * netdebug.c - * - * debug functionality for o2net - * - * Copyright (C) 2005, 2008 Oracle. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - * - */ - -#ifdef CONFIG_DEBUG_FS - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "tcp.h" -#include "nodemanager.h" -#define MLOG_MASK_PREFIX ML_TCP -#include "masklog.h" - -#include "tcp_internal.h" - -#define O2NET_DEBUG_DIR "o2net" -#define SC_DEBUG_NAME "sock_containers" -#define NST_DEBUG_NAME "send_tracking" -#define STATS_DEBUG_NAME "stats" -#define NODES_DEBUG_NAME "connected_nodes" - -#define SHOW_SOCK_CONTAINERS 0 -#define SHOW_SOCK_STATS 1 - -static struct dentry *o2net_dentry; -static struct dentry *sc_dentry; -static struct dentry *nst_dentry; -static struct dentry *stats_dentry; -static struct dentry *nodes_dentry; - -static DEFINE_SPINLOCK(o2net_debug_lock); - -static LIST_HEAD(sock_containers); -static LIST_HEAD(send_tracking); - -void o2net_debug_add_nst(struct o2net_send_tracking *nst) -{ - spin_lock(&o2net_debug_lock); - list_add(&nst->st_net_debug_item, &send_tracking); - spin_unlock(&o2net_debug_lock); -} - -void o2net_debug_del_nst(struct o2net_send_tracking *nst) -{ - spin_lock(&o2net_debug_lock); - if (!list_empty(&nst->st_net_debug_item)) - list_del_init(&nst->st_net_debug_item); - spin_unlock(&o2net_debug_lock); -} - -static struct o2net_send_tracking - *next_nst(struct o2net_send_tracking *nst_start) -{ - struct o2net_send_tracking *nst, *ret = NULL; - - assert_spin_locked(&o2net_debug_lock); - - list_for_each_entry(nst, &nst_start->st_net_debug_item, - st_net_debug_item) { - /* discover the head of the list */ - if (&nst->st_net_debug_item == &send_tracking) - break; - - /* use st_task to detect real nsts in the list */ - if (nst->st_task != NULL) { - ret = nst; - break; - } - } - - return ret; -} - -static void *nst_seq_start(struct seq_file *seq, loff_t *pos) -{ - struct o2net_send_tracking *nst, *dummy_nst = seq->private; - - spin_lock(&o2net_debug_lock); - nst = next_nst(dummy_nst); - spin_unlock(&o2net_debug_lock); - - return nst; -} - -static void *nst_seq_next(struct seq_file *seq, void *v, loff_t *pos) -{ - struct o2net_send_tracking *nst, *dummy_nst = seq->private; - - spin_lock(&o2net_debug_lock); - nst = next_nst(dummy_nst); - list_del_init(&dummy_nst->st_net_debug_item); - if (nst) - list_add(&dummy_nst->st_net_debug_item, - &nst->st_net_debug_item); - spin_unlock(&o2net_debug_lock); - - return nst; /* unused, just needs to be null when done */ -} - -static int nst_seq_show(struct seq_file *seq, void *v) -{ - struct o2net_send_tracking *nst, *dummy_nst = seq->private; - ktime_t now; - s64 sock, send, status; - - spin_lock(&o2net_debug_lock); - nst = next_nst(dummy_nst); - if (!nst) - goto out; - - now = ktime_get(); - sock = ktime_to_us(ktime_sub(now, nst->st_sock_time)); - send = ktime_to_us(ktime_sub(now, nst->st_send_time)); - status = ktime_to_us(ktime_sub(now, nst->st_status_time)); - - /* get_task_comm isn't exported. oh well. */ - seq_printf(seq, "%p:\n" - " pid: %lu\n" - " tgid: %lu\n" - " process name: %s\n" - " node: %u\n" - " sc: %p\n" - " message id: %d\n" - " message type: %u\n" - " message key: 0x%08x\n" - " sock acquiry: %lld usecs ago\n" - " send start: %lld usecs ago\n" - " wait start: %lld usecs ago\n", - nst, (unsigned long)task_pid_nr(nst->st_task), - (unsigned long)nst->st_task->tgid, - nst->st_task->comm, nst->st_node, - nst->st_sc, nst->st_id, nst->st_msg_type, - nst->st_msg_key, - (long long)sock, - (long long)send, - (long long)status); - -out: - spin_unlock(&o2net_debug_lock); - - return 0; -} - -static void nst_seq_stop(struct seq_file *seq, void *v) -{ -} - -static const struct seq_operations nst_seq_ops = { - .start = nst_seq_start, - .next = nst_seq_next, - .stop = nst_seq_stop, - .show = nst_seq_show, -}; - -static int nst_fop_open(struct inode *inode, struct file *file) -{ - struct o2net_send_tracking *dummy_nst; - struct seq_file *seq; - int ret; - - dummy_nst = kmalloc(sizeof(struct o2net_send_tracking), GFP_KERNEL); - if (dummy_nst == NULL) { - ret = -ENOMEM; - goto out; - } - dummy_nst->st_task = NULL; - - ret = seq_open(file, &nst_seq_ops); - if (ret) - goto out; - - seq = file->private_data; - seq->private = dummy_nst; - o2net_debug_add_nst(dummy_nst); - - dummy_nst = NULL; - -out: - kfree(dummy_nst); - return ret; -} - -static int nst_fop_release(struct inode *inode, struct file *file) -{ - struct seq_file *seq = file->private_data; - struct o2net_send_tracking *dummy_nst = seq->private; - - o2net_debug_del_nst(dummy_nst); - return seq_release_private(inode, file); -} - -static const struct file_operations nst_seq_fops = { - .open = nst_fop_open, - .read = seq_read, - .llseek = seq_lseek, - .release = nst_fop_release, -}; - -void o2net_debug_add_sc(struct o2net_sock_container *sc) -{ - spin_lock(&o2net_debug_lock); - list_add(&sc->sc_net_debug_item, &sock_containers); - spin_unlock(&o2net_debug_lock); -} - -void o2net_debug_del_sc(struct o2net_sock_container *sc) -{ - spin_lock(&o2net_debug_lock); - list_del_init(&sc->sc_net_debug_item); - spin_unlock(&o2net_debug_lock); -} - -struct o2net_sock_debug { - int dbg_ctxt; - struct o2net_sock_container *dbg_sock; -}; - -static struct o2net_sock_container - *next_sc(struct o2net_sock_container *sc_start) -{ - struct o2net_sock_container *sc, *ret = NULL; - - assert_spin_locked(&o2net_debug_lock); - - list_for_each_entry(sc, &sc_start->sc_net_debug_item, - sc_net_debug_item) { - /* discover the head of the list miscast as a sc */ - if (&sc->sc_net_debug_item == &sock_containers) - break; - - /* use sc_page to detect real scs in the list */ - if (sc->sc_page != NULL) { - ret = sc; - break; - } - } - - return ret; -} - -static void *sc_seq_start(struct seq_file *seq, loff_t *pos) -{ - struct o2net_sock_debug *sd = seq->private; - struct o2net_sock_container *sc, *dummy_sc = sd->dbg_sock; - - spin_lock(&o2net_debug_lock); - sc = next_sc(dummy_sc); - spin_unlock(&o2net_debug_lock); - - return sc; -} - -static void *sc_seq_next(struct seq_file *seq, void *v, loff_t *pos) -{ - struct o2net_sock_debug *sd = seq->private; - struct o2net_sock_container *sc, *dummy_sc = sd->dbg_sock; - - spin_lock(&o2net_debug_lock); - sc = next_sc(dummy_sc); - list_del_init(&dummy_sc->sc_net_debug_item); - if (sc) - list_add(&dummy_sc->sc_net_debug_item, &sc->sc_net_debug_item); - spin_unlock(&o2net_debug_lock); - - return sc; /* unused, just needs to be null when done */ -} - -#ifdef CONFIG_OCFS2_FS_STATS -# define sc_send_count(_s) ((_s)->sc_send_count) -# define sc_recv_count(_s) ((_s)->sc_recv_count) -# define sc_tv_acquiry_total_ns(_s) (ktime_to_ns((_s)->sc_tv_acquiry_total)) -# define sc_tv_send_total_ns(_s) (ktime_to_ns((_s)->sc_tv_send_total)) -# define sc_tv_status_total_ns(_s) (ktime_to_ns((_s)->sc_tv_status_total)) -# define sc_tv_process_total_ns(_s) (ktime_to_ns((_s)->sc_tv_process_total)) -#else -# define sc_send_count(_s) (0U) -# define sc_recv_count(_s) (0U) -# define sc_tv_acquiry_total_ns(_s) (0LL) -# define sc_tv_send_total_ns(_s) (0LL) -# define sc_tv_status_total_ns(_s) (0LL) -# define sc_tv_process_total_ns(_s) (0LL) -#endif - -/* So that debugfs.ocfs2 can determine which format is being used */ -#define O2NET_STATS_STR_VERSION 1 -static void sc_show_sock_stats(struct seq_file *seq, - struct o2net_sock_container *sc) -{ - if (!sc) - return; - - seq_printf(seq, "%d,%u,%lu,%lld,%lld,%lld,%lu,%lld\n", O2NET_STATS_STR_VERSION, - sc->sc_node->nd_num, (unsigned long)sc_send_count(sc), - (long long)sc_tv_acquiry_total_ns(sc), - (long long)sc_tv_send_total_ns(sc), - (long long)sc_tv_status_total_ns(sc), - (unsigned long)sc_recv_count(sc), - (long long)sc_tv_process_total_ns(sc)); -} - -static void sc_show_sock_container(struct seq_file *seq, - struct o2net_sock_container *sc) -{ - struct inet_sock *inet = NULL; - __be32 saddr = 0, daddr = 0; - __be16 sport = 0, dport = 0; - - if (!sc) - return; - - if (sc->sc_sock) { - inet = inet_sk(sc->sc_sock->sk); - /* the stack's structs aren't sparse endian clean */ - saddr = (__force __be32)inet->inet_saddr; - daddr = (__force __be32)inet->inet_daddr; - sport = (__force __be16)inet->inet_sport; - dport = (__force __be16)inet->inet_dport; - } - - /* XXX sigh, inet-> doesn't have sparse annotation so any - * use of it here generates a warning with -Wbitwise */ - seq_printf(seq, "%p:\n" - " krefs: %d\n" - " sock: %pI4:%u -> " - "%pI4:%u\n" - " remote node: %s\n" - " page off: %zu\n" - " handshake ok: %u\n" - " timer: %lld usecs\n" - " data ready: %lld usecs\n" - " advance start: %lld usecs\n" - " advance stop: %lld usecs\n" - " func start: %lld usecs\n" - " func stop: %lld usecs\n" - " func key: 0x%08x\n" - " func type: %u\n", - sc, - atomic_read(&sc->sc_kref.refcount), - &saddr, inet ? ntohs(sport) : 0, - &daddr, inet ? ntohs(dport) : 0, - sc->sc_node->nd_name, - sc->sc_page_off, - sc->sc_handshake_ok, - (long long)ktime_to_us(sc->sc_tv_timer), - (long long)ktime_to_us(sc->sc_tv_data_ready), - (long long)ktime_to_us(sc->sc_tv_advance_start), - (long long)ktime_to_us(sc->sc_tv_advance_stop), - (long long)ktime_to_us(sc->sc_tv_func_start), - (long long)ktime_to_us(sc->sc_tv_func_stop), - sc->sc_msg_key, - sc->sc_msg_type); -} - -static int sc_seq_show(struct seq_file *seq, void *v) -{ - struct o2net_sock_debug *sd = seq->private; - struct o2net_sock_container *sc, *dummy_sc = sd->dbg_sock; - - spin_lock(&o2net_debug_lock); - sc = next_sc(dummy_sc); - - if (sc) { - if (sd->dbg_ctxt == SHOW_SOCK_CONTAINERS) - sc_show_sock_container(seq, sc); - else - sc_show_sock_stats(seq, sc); - } - - spin_unlock(&o2net_debug_lock); - - return 0; -} - -static void sc_seq_stop(struct seq_file *seq, void *v) -{ -} - -static const struct seq_operations sc_seq_ops = { - .start = sc_seq_start, - .next = sc_seq_next, - .stop = sc_seq_stop, - .show = sc_seq_show, -}; - -static int sc_common_open(struct file *file, struct o2net_sock_debug *sd) -{ - struct o2net_sock_container *dummy_sc; - struct seq_file *seq; - int ret; - - dummy_sc = kmalloc(sizeof(struct o2net_sock_container), GFP_KERNEL); - if (dummy_sc == NULL) { - ret = -ENOMEM; - goto out; - } - dummy_sc->sc_page = NULL; - - ret = seq_open(file, &sc_seq_ops); - if (ret) - goto out; - - seq = file->private_data; - seq->private = sd; - sd->dbg_sock = dummy_sc; - o2net_debug_add_sc(dummy_sc); - - dummy_sc = NULL; - -out: - kfree(dummy_sc); - return ret; -} - -static int sc_fop_release(struct inode *inode, struct file *file) -{ - struct seq_file *seq = file->private_data; - struct o2net_sock_debug *sd = seq->private; - struct o2net_sock_container *dummy_sc = sd->dbg_sock; - - o2net_debug_del_sc(dummy_sc); - return seq_release_private(inode, file); -} - -static int stats_fop_open(struct inode *inode, struct file *file) -{ - struct o2net_sock_debug *sd; - - sd = kmalloc(sizeof(struct o2net_sock_debug), GFP_KERNEL); - if (sd == NULL) - return -ENOMEM; - - sd->dbg_ctxt = SHOW_SOCK_STATS; - sd->dbg_sock = NULL; - - return sc_common_open(file, sd); -} - -static const struct file_operations stats_seq_fops = { - .open = stats_fop_open, - .read = seq_read, - .llseek = seq_lseek, - .release = sc_fop_release, -}; - -static int sc_fop_open(struct inode *inode, struct file *file) -{ - struct o2net_sock_debug *sd; - - sd = kmalloc(sizeof(struct o2net_sock_debug), GFP_KERNEL); - if (sd == NULL) - return -ENOMEM; - - sd->dbg_ctxt = SHOW_SOCK_CONTAINERS; - sd->dbg_sock = NULL; - - return sc_common_open(file, sd); -} - -static const struct file_operations sc_seq_fops = { - .open = sc_fop_open, - .read = seq_read, - .llseek = seq_lseek, - .release = sc_fop_release, -}; - -static int o2net_fill_bitmap(char *buf, int len) -{ - unsigned long map[BITS_TO_LONGS(O2NM_MAX_NODES)]; - int i = -1, out = 0; - - o2net_fill_node_map(map, sizeof(map)); - - while ((i = find_next_bit(map, O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES) - out += snprintf(buf + out, PAGE_SIZE - out, "%d ", i); - out += snprintf(buf + out, PAGE_SIZE - out, "\n"); - - return out; -} - -static int nodes_fop_open(struct inode *inode, struct file *file) -{ - char *buf; - - buf = kmalloc(PAGE_SIZE, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - i_size_write(inode, o2net_fill_bitmap(buf, PAGE_SIZE)); - - file->private_data = buf; - - return 0; -} - -static int o2net_debug_release(struct inode *inode, struct file *file) -{ - kfree(file->private_data); - return 0; -} - -static ssize_t o2net_debug_read(struct file *file, char __user *buf, - size_t nbytes, loff_t *ppos) -{ - return simple_read_from_buffer(buf, nbytes, ppos, file->private_data, - i_size_read(file->f_mapping->host)); -} - -static const struct file_operations nodes_fops = { - .open = nodes_fop_open, - .release = o2net_debug_release, - .read = o2net_debug_read, - .llseek = generic_file_llseek, -}; - -void o2net_debugfs_exit(void) -{ - debugfs_remove(nodes_dentry); - debugfs_remove(stats_dentry); - debugfs_remove(sc_dentry); - debugfs_remove(nst_dentry); - debugfs_remove(o2net_dentry); -} - -int o2net_debugfs_init(void) -{ - mode_t mode = S_IFREG|S_IRUSR; - - o2net_dentry = debugfs_create_dir(O2NET_DEBUG_DIR, NULL); - if (o2net_dentry) - nst_dentry = debugfs_create_file(NST_DEBUG_NAME, mode, - o2net_dentry, NULL, &nst_seq_fops); - if (nst_dentry) - sc_dentry = debugfs_create_file(SC_DEBUG_NAME, mode, - o2net_dentry, NULL, &sc_seq_fops); - if (sc_dentry) - stats_dentry = debugfs_create_file(STATS_DEBUG_NAME, mode, - o2net_dentry, NULL, &stats_seq_fops); - if (stats_dentry) - nodes_dentry = debugfs_create_file(NODES_DEBUG_NAME, mode, - o2net_dentry, NULL, &nodes_fops); - if (nodes_dentry) - return 0; - - o2net_debugfs_exit(); - mlog_errno(-ENOMEM); - return -ENOMEM; -} - -#endif /* CONFIG_DEBUG_FS */ diff --git a/drivers/staging/ramster/cluster/nodemanager.c b/drivers/staging/ramster/cluster/nodemanager.c deleted file mode 100644 index bb240647ca5..00000000000 --- a/drivers/staging/ramster/cluster/nodemanager.c +++ /dev/null @@ -1,989 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * Copyright (C) 2004, 2005 Oracle. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - */ - -#include -#include -#include -#include - -#include "tcp.h" -#include "nodemanager.h" -#include "heartbeat.h" -#include "masklog.h" -#include "sys.h" -#include "ver.h" - -/* for now we operate under the assertion that there can be only one - * cluster active at a time. Changing this will require trickling - * cluster references throughout where nodes are looked up */ -struct o2nm_cluster *o2nm_single_cluster = NULL; - -char *o2nm_fence_method_desc[O2NM_FENCE_METHODS] = { - "reset", /* O2NM_FENCE_RESET */ - "panic", /* O2NM_FENCE_PANIC */ -}; - -struct o2nm_node *o2nm_get_node_by_num(u8 node_num) -{ - struct o2nm_node *node = NULL; - - if (node_num >= O2NM_MAX_NODES || o2nm_single_cluster == NULL) - goto out; - - read_lock(&o2nm_single_cluster->cl_nodes_lock); - node = o2nm_single_cluster->cl_nodes[node_num]; - if (node) - config_item_get(&node->nd_item); - read_unlock(&o2nm_single_cluster->cl_nodes_lock); -out: - return node; -} -EXPORT_SYMBOL_GPL(o2nm_get_node_by_num); - -int o2nm_configured_node_map(unsigned long *map, unsigned bytes) -{ - struct o2nm_cluster *cluster = o2nm_single_cluster; - - BUG_ON(bytes < (sizeof(cluster->cl_nodes_bitmap))); - - if (cluster == NULL) - return -EINVAL; - - read_lock(&cluster->cl_nodes_lock); - memcpy(map, cluster->cl_nodes_bitmap, sizeof(cluster->cl_nodes_bitmap)); - read_unlock(&cluster->cl_nodes_lock); - - return 0; -} -EXPORT_SYMBOL_GPL(o2nm_configured_node_map); - -static struct o2nm_node *o2nm_node_ip_tree_lookup(struct o2nm_cluster *cluster, - __be32 ip_needle, - struct rb_node ***ret_p, - struct rb_node **ret_parent) -{ - struct rb_node **p = &cluster->cl_node_ip_tree.rb_node; - struct rb_node *parent = NULL; - struct o2nm_node *node, *ret = NULL; - - while (*p) { - int cmp; - - parent = *p; - node = rb_entry(parent, struct o2nm_node, nd_ip_node); - - cmp = memcmp(&ip_needle, &node->nd_ipv4_address, - sizeof(ip_needle)); - if (cmp < 0) - p = &(*p)->rb_left; - else if (cmp > 0) - p = &(*p)->rb_right; - else { - ret = node; - break; - } - } - - if (ret_p != NULL) - *ret_p = p; - if (ret_parent != NULL) - *ret_parent = parent; - - return ret; -} - -struct o2nm_node *o2nm_get_node_by_ip(__be32 addr) -{ - struct o2nm_node *node = NULL; - struct o2nm_cluster *cluster = o2nm_single_cluster; - - if (cluster == NULL) - goto out; - - read_lock(&cluster->cl_nodes_lock); - node = o2nm_node_ip_tree_lookup(cluster, addr, NULL, NULL); - if (node) - config_item_get(&node->nd_item); - read_unlock(&cluster->cl_nodes_lock); - -out: - return node; -} -EXPORT_SYMBOL_GPL(o2nm_get_node_by_ip); - -void o2nm_node_put(struct o2nm_node *node) -{ - config_item_put(&node->nd_item); -} -EXPORT_SYMBOL_GPL(o2nm_node_put); - -void o2nm_node_get(struct o2nm_node *node) -{ - config_item_get(&node->nd_item); -} -EXPORT_SYMBOL_GPL(o2nm_node_get); - -u8 o2nm_this_node(void) -{ - u8 node_num = O2NM_MAX_NODES; - - if (o2nm_single_cluster && o2nm_single_cluster->cl_has_local) - node_num = o2nm_single_cluster->cl_local_node; - - return node_num; -} -EXPORT_SYMBOL_GPL(o2nm_this_node); - -/* node configfs bits */ - -static struct o2nm_cluster *to_o2nm_cluster(struct config_item *item) -{ - return item ? - container_of(to_config_group(item), struct o2nm_cluster, - cl_group) - : NULL; -} - -static struct o2nm_node *to_o2nm_node(struct config_item *item) -{ - return item ? container_of(item, struct o2nm_node, nd_item) : NULL; -} - -static void o2nm_node_release(struct config_item *item) -{ - struct o2nm_node *node = to_o2nm_node(item); - kfree(node); -} - -static ssize_t o2nm_node_num_read(struct o2nm_node *node, char *page) -{ - return sprintf(page, "%d\n", node->nd_num); -} - -static struct o2nm_cluster *to_o2nm_cluster_from_node(struct o2nm_node *node) -{ - /* through the first node_set .parent - * mycluster/nodes/mynode == o2nm_cluster->o2nm_node_group->o2nm_node */ - return to_o2nm_cluster(node->nd_item.ci_parent->ci_parent); -} - -enum { - O2NM_NODE_ATTR_NUM = 0, - O2NM_NODE_ATTR_PORT, - O2NM_NODE_ATTR_ADDRESS, - O2NM_NODE_ATTR_LOCAL, -}; - -static ssize_t o2nm_node_num_write(struct o2nm_node *node, const char *page, - size_t count) -{ - struct o2nm_cluster *cluster = to_o2nm_cluster_from_node(node); - unsigned long tmp; - char *p = (char *)page; - - tmp = simple_strtoul(p, &p, 0); - if (!p || (*p && (*p != '\n'))) - return -EINVAL; - - if (tmp >= O2NM_MAX_NODES) - return -ERANGE; - - /* once we're in the cl_nodes tree networking can look us up by - * node number and try to use our address and port attributes - * to connect to this node.. make sure that they've been set - * before writing the node attribute? */ - if (!test_bit(O2NM_NODE_ATTR_ADDRESS, &node->nd_set_attributes) || - !test_bit(O2NM_NODE_ATTR_PORT, &node->nd_set_attributes)) - return -EINVAL; /* XXX */ - - write_lock(&cluster->cl_nodes_lock); - if (cluster->cl_nodes[tmp]) - p = NULL; - else { - cluster->cl_nodes[tmp] = node; - node->nd_num = tmp; - set_bit(tmp, cluster->cl_nodes_bitmap); - } - write_unlock(&cluster->cl_nodes_lock); - if (p == NULL) - return -EEXIST; - - return count; -} -static ssize_t o2nm_node_ipv4_port_read(struct o2nm_node *node, char *page) -{ - return sprintf(page, "%u\n", ntohs(node->nd_ipv4_port)); -} - -static ssize_t o2nm_node_ipv4_port_write(struct o2nm_node *node, - const char *page, size_t count) -{ - unsigned long tmp; - char *p = (char *)page; - - tmp = simple_strtoul(p, &p, 0); - if (!p || (*p && (*p != '\n'))) - return -EINVAL; - - if (tmp == 0) - return -EINVAL; - if (tmp >= (u16)-1) - return -ERANGE; - - node->nd_ipv4_port = htons(tmp); - - return count; -} - -static ssize_t o2nm_node_ipv4_address_read(struct o2nm_node *node, char *page) -{ - return sprintf(page, "%pI4\n", &node->nd_ipv4_address); -} - -static ssize_t o2nm_node_ipv4_address_write(struct o2nm_node *node, - const char *page, - size_t count) -{ - struct o2nm_cluster *cluster = to_o2nm_cluster_from_node(node); - int ret, i; - struct rb_node **p, *parent; - unsigned int octets[4]; - __be32 ipv4_addr = 0; - - ret = sscanf(page, "%3u.%3u.%3u.%3u", &octets[3], &octets[2], - &octets[1], &octets[0]); - if (ret != 4) - return -EINVAL; - - for (i = 0; i < ARRAY_SIZE(octets); i++) { - if (octets[i] > 255) - return -ERANGE; - be32_add_cpu(&ipv4_addr, octets[i] << (i * 8)); - } - - ret = 0; - write_lock(&cluster->cl_nodes_lock); - if (o2nm_node_ip_tree_lookup(cluster, ipv4_addr, &p, &parent)) - ret = -EEXIST; - else { - rb_link_node(&node->nd_ip_node, parent, p); - rb_insert_color(&node->nd_ip_node, &cluster->cl_node_ip_tree); - } - write_unlock(&cluster->cl_nodes_lock); - if (ret) - return ret; - - memcpy(&node->nd_ipv4_address, &ipv4_addr, sizeof(ipv4_addr)); - - return count; -} - -static ssize_t o2nm_node_local_read(struct o2nm_node *node, char *page) -{ - return sprintf(page, "%d\n", node->nd_local); -} - -static ssize_t o2nm_node_local_write(struct o2nm_node *node, const char *page, - size_t count) -{ - struct o2nm_cluster *cluster = to_o2nm_cluster_from_node(node); - unsigned long tmp; - char *p = (char *)page; - ssize_t ret; - - tmp = simple_strtoul(p, &p, 0); - if (!p || (*p && (*p != '\n'))) - return -EINVAL; - - tmp = !!tmp; /* boolean of whether this node wants to be local */ - - /* setting local turns on networking rx for now so we require having - * set everything else first */ - if (!test_bit(O2NM_NODE_ATTR_ADDRESS, &node->nd_set_attributes) || - !test_bit(O2NM_NODE_ATTR_NUM, &node->nd_set_attributes) || - !test_bit(O2NM_NODE_ATTR_PORT, &node->nd_set_attributes)) - return -EINVAL; /* XXX */ - - /* the only failure case is trying to set a new local node - * when a different one is already set */ - if (tmp && tmp == cluster->cl_has_local && - cluster->cl_local_node != node->nd_num) - return -EBUSY; - - /* bring up the rx thread if we're setting the new local node. */ - if (tmp && !cluster->cl_has_local) { - ret = o2net_start_listening(node); - if (ret) - return ret; - } - - if (!tmp && cluster->cl_has_local && - cluster->cl_local_node == node->nd_num) { - o2net_stop_listening(node); - cluster->cl_local_node = O2NM_INVALID_NODE_NUM; - } - - node->nd_local = tmp; - if (node->nd_local) { - cluster->cl_has_local = tmp; - cluster->cl_local_node = node->nd_num; - } - - return count; -} - -struct o2nm_node_attribute { - struct configfs_attribute attr; - ssize_t (*show)(struct o2nm_node *, char *); - ssize_t (*store)(struct o2nm_node *, const char *, size_t); -}; - -static struct o2nm_node_attribute o2nm_node_attr_num = { - .attr = { .ca_owner = THIS_MODULE, - .ca_name = "num", - .ca_mode = S_IRUGO | S_IWUSR }, - .show = o2nm_node_num_read, - .store = o2nm_node_num_write, -}; - -static struct o2nm_node_attribute o2nm_node_attr_ipv4_port = { - .attr = { .ca_owner = THIS_MODULE, - .ca_name = "ipv4_port", - .ca_mode = S_IRUGO | S_IWUSR }, - .show = o2nm_node_ipv4_port_read, - .store = o2nm_node_ipv4_port_write, -}; - -static struct o2nm_node_attribute o2nm_node_attr_ipv4_address = { - .attr = { .ca_owner = THIS_MODULE, - .ca_name = "ipv4_address", - .ca_mode = S_IRUGO | S_IWUSR }, - .show = o2nm_node_ipv4_address_read, - .store = o2nm_node_ipv4_address_write, -}; - -static struct o2nm_node_attribute o2nm_node_attr_local = { - .attr = { .ca_owner = THIS_MODULE, - .ca_name = "local", - .ca_mode = S_IRUGO | S_IWUSR }, - .show = o2nm_node_local_read, - .store = o2nm_node_local_write, -}; - -static struct configfs_attribute *o2nm_node_attrs[] = { - [O2NM_NODE_ATTR_NUM] = &o2nm_node_attr_num.attr, - [O2NM_NODE_ATTR_PORT] = &o2nm_node_attr_ipv4_port.attr, - [O2NM_NODE_ATTR_ADDRESS] = &o2nm_node_attr_ipv4_address.attr, - [O2NM_NODE_ATTR_LOCAL] = &o2nm_node_attr_local.attr, - NULL, -}; - -static int o2nm_attr_index(struct configfs_attribute *attr) -{ - int i; - for (i = 0; i < ARRAY_SIZE(o2nm_node_attrs); i++) { - if (attr == o2nm_node_attrs[i]) - return i; - } - BUG(); - return 0; -} - -static ssize_t o2nm_node_show(struct config_item *item, - struct configfs_attribute *attr, - char *page) -{ - struct o2nm_node *node = to_o2nm_node(item); - struct o2nm_node_attribute *o2nm_node_attr = - container_of(attr, struct o2nm_node_attribute, attr); - ssize_t ret = 0; - - if (o2nm_node_attr->show) - ret = o2nm_node_attr->show(node, page); - return ret; -} - -static ssize_t o2nm_node_store(struct config_item *item, - struct configfs_attribute *attr, - const char *page, size_t count) -{ - struct o2nm_node *node = to_o2nm_node(item); - struct o2nm_node_attribute *o2nm_node_attr = - container_of(attr, struct o2nm_node_attribute, attr); - ssize_t ret; - int attr_index = o2nm_attr_index(attr); - - if (o2nm_node_attr->store == NULL) { - ret = -EINVAL; - goto out; - } - - if (test_bit(attr_index, &node->nd_set_attributes)) - return -EBUSY; - - ret = o2nm_node_attr->store(node, page, count); - if (ret < count) - goto out; - - set_bit(attr_index, &node->nd_set_attributes); -out: - return ret; -} - -static struct configfs_item_operations o2nm_node_item_ops = { - .release = o2nm_node_release, - .show_attribute = o2nm_node_show, - .store_attribute = o2nm_node_store, -}; - -static struct config_item_type o2nm_node_type = { - .ct_item_ops = &o2nm_node_item_ops, - .ct_attrs = o2nm_node_attrs, - .ct_owner = THIS_MODULE, -}; - -/* node set */ - -struct o2nm_node_group { - struct config_group ns_group; - /* some stuff? */ -}; - -#if 0 -static struct o2nm_node_group *to_o2nm_node_group(struct config_group *group) -{ - return group ? - container_of(group, struct o2nm_node_group, ns_group) - : NULL; -} -#endif - -struct o2nm_cluster_attribute { - struct configfs_attribute attr; - ssize_t (*show)(struct o2nm_cluster *, char *); - ssize_t (*store)(struct o2nm_cluster *, const char *, size_t); -}; - -static ssize_t o2nm_cluster_attr_write(const char *page, ssize_t count, - unsigned int *val) -{ - unsigned long tmp; - char *p = (char *)page; - - tmp = simple_strtoul(p, &p, 0); - if (!p || (*p && (*p != '\n'))) - return -EINVAL; - - if (tmp == 0) - return -EINVAL; - if (tmp >= (u32)-1) - return -ERANGE; - - *val = tmp; - - return count; -} - -static ssize_t o2nm_cluster_attr_idle_timeout_ms_read( - struct o2nm_cluster *cluster, char *page) -{ - return sprintf(page, "%u\n", cluster->cl_idle_timeout_ms); -} - -static ssize_t o2nm_cluster_attr_idle_timeout_ms_write( - struct o2nm_cluster *cluster, const char *page, size_t count) -{ - ssize_t ret; - unsigned int val; - - ret = o2nm_cluster_attr_write(page, count, &val); - - if (ret > 0) { - if (cluster->cl_idle_timeout_ms != val - && o2net_num_connected_peers()) { - mlog(ML_NOTICE, - "o2net: cannot change idle timeout after " - "the first peer has agreed to it." - " %d connected peers\n", - o2net_num_connected_peers()); - ret = -EINVAL; - } else if (val <= cluster->cl_keepalive_delay_ms) { - mlog(ML_NOTICE, "o2net: idle timeout must be larger " - "than keepalive delay\n"); - ret = -EINVAL; - } else { - cluster->cl_idle_timeout_ms = val; - } - } - - return ret; -} - -static ssize_t o2nm_cluster_attr_keepalive_delay_ms_read( - struct o2nm_cluster *cluster, char *page) -{ - return sprintf(page, "%u\n", cluster->cl_keepalive_delay_ms); -} - -static ssize_t o2nm_cluster_attr_keepalive_delay_ms_write( - struct o2nm_cluster *cluster, const char *page, size_t count) -{ - ssize_t ret; - unsigned int val; - - ret = o2nm_cluster_attr_write(page, count, &val); - - if (ret > 0) { - if (cluster->cl_keepalive_delay_ms != val - && o2net_num_connected_peers()) { - mlog(ML_NOTICE, - "o2net: cannot change keepalive delay after" - " the first peer has agreed to it." - " %d connected peers\n", - o2net_num_connected_peers()); - ret = -EINVAL; - } else if (val >= cluster->cl_idle_timeout_ms) { - mlog(ML_NOTICE, "o2net: keepalive delay must be " - "smaller than idle timeout\n"); - ret = -EINVAL; - } else { - cluster->cl_keepalive_delay_ms = val; - } - } - - return ret; -} - -static ssize_t o2nm_cluster_attr_reconnect_delay_ms_read( - struct o2nm_cluster *cluster, char *page) -{ - return sprintf(page, "%u\n", cluster->cl_reconnect_delay_ms); -} - -static ssize_t o2nm_cluster_attr_reconnect_delay_ms_write( - struct o2nm_cluster *cluster, const char *page, size_t count) -{ - return o2nm_cluster_attr_write(page, count, - &cluster->cl_reconnect_delay_ms); -} - -static ssize_t o2nm_cluster_attr_fence_method_read( - struct o2nm_cluster *cluster, char *page) -{ - ssize_t ret = 0; - - if (cluster) - ret = sprintf(page, "%s\n", - o2nm_fence_method_desc[cluster->cl_fence_method]); - return ret; -} - -static ssize_t o2nm_cluster_attr_fence_method_write( - struct o2nm_cluster *cluster, const char *page, size_t count) -{ - unsigned int i; - - if (page[count - 1] != '\n') - goto bail; - - for (i = 0; i < O2NM_FENCE_METHODS; ++i) { - if (count != strlen(o2nm_fence_method_desc[i]) + 1) - continue; - if (strncasecmp(page, o2nm_fence_method_desc[i], count - 1)) - continue; - if (cluster->cl_fence_method != i) { - printk(KERN_INFO "ocfs2: Changing fence method to %s\n", - o2nm_fence_method_desc[i]); - cluster->cl_fence_method = i; - } - return count; - } - -bail: - return -EINVAL; -} - -static struct o2nm_cluster_attribute o2nm_cluster_attr_idle_timeout_ms = { - .attr = { .ca_owner = THIS_MODULE, - .ca_name = "idle_timeout_ms", - .ca_mode = S_IRUGO | S_IWUSR }, - .show = o2nm_cluster_attr_idle_timeout_ms_read, - .store = o2nm_cluster_attr_idle_timeout_ms_write, -}; - -static struct o2nm_cluster_attribute o2nm_cluster_attr_keepalive_delay_ms = { - .attr = { .ca_owner = THIS_MODULE, - .ca_name = "keepalive_delay_ms", - .ca_mode = S_IRUGO | S_IWUSR }, - .show = o2nm_cluster_attr_keepalive_delay_ms_read, - .store = o2nm_cluster_attr_keepalive_delay_ms_write, -}; - -static struct o2nm_cluster_attribute o2nm_cluster_attr_reconnect_delay_ms = { - .attr = { .ca_owner = THIS_MODULE, - .ca_name = "reconnect_delay_ms", - .ca_mode = S_IRUGO | S_IWUSR }, - .show = o2nm_cluster_attr_reconnect_delay_ms_read, - .store = o2nm_cluster_attr_reconnect_delay_ms_write, -}; - -static struct o2nm_cluster_attribute o2nm_cluster_attr_fence_method = { - .attr = { .ca_owner = THIS_MODULE, - .ca_name = "fence_method", - .ca_mode = S_IRUGO | S_IWUSR }, - .show = o2nm_cluster_attr_fence_method_read, - .store = o2nm_cluster_attr_fence_method_write, -}; - -static struct configfs_attribute *o2nm_cluster_attrs[] = { - &o2nm_cluster_attr_idle_timeout_ms.attr, - &o2nm_cluster_attr_keepalive_delay_ms.attr, - &o2nm_cluster_attr_reconnect_delay_ms.attr, - &o2nm_cluster_attr_fence_method.attr, - NULL, -}; -static ssize_t o2nm_cluster_show(struct config_item *item, - struct configfs_attribute *attr, - char *page) -{ - struct o2nm_cluster *cluster = to_o2nm_cluster(item); - struct o2nm_cluster_attribute *o2nm_cluster_attr = - container_of(attr, struct o2nm_cluster_attribute, attr); - ssize_t ret = 0; - - if (o2nm_cluster_attr->show) - ret = o2nm_cluster_attr->show(cluster, page); - return ret; -} - -static ssize_t o2nm_cluster_store(struct config_item *item, - struct configfs_attribute *attr, - const char *page, size_t count) -{ - struct o2nm_cluster *cluster = to_o2nm_cluster(item); - struct o2nm_cluster_attribute *o2nm_cluster_attr = - container_of(attr, struct o2nm_cluster_attribute, attr); - ssize_t ret; - - if (o2nm_cluster_attr->store == NULL) { - ret = -EINVAL; - goto out; - } - - ret = o2nm_cluster_attr->store(cluster, page, count); - if (ret < count) - goto out; -out: - return ret; -} - -static struct config_item *o2nm_node_group_make_item(struct config_group *group, - const char *name) -{ - struct o2nm_node *node = NULL; - - if (strlen(name) > O2NM_MAX_NAME_LEN) - return ERR_PTR(-ENAMETOOLONG); - - node = kzalloc(sizeof(struct o2nm_node), GFP_KERNEL); - if (node == NULL) - return ERR_PTR(-ENOMEM); - - strcpy(node->nd_name, name); /* use item.ci_namebuf instead? */ - config_item_init_type_name(&node->nd_item, name, &o2nm_node_type); - spin_lock_init(&node->nd_lock); - - mlog(ML_CLUSTER, "o2nm: Registering node %s\n", name); - - return &node->nd_item; -} - -static void o2nm_node_group_drop_item(struct config_group *group, - struct config_item *item) -{ - struct o2nm_node *node = to_o2nm_node(item); - struct o2nm_cluster *cluster = to_o2nm_cluster(group->cg_item.ci_parent); - - o2net_disconnect_node(node); - - if (cluster->cl_has_local && - (cluster->cl_local_node == node->nd_num)) { - cluster->cl_has_local = 0; - cluster->cl_local_node = O2NM_INVALID_NODE_NUM; - o2net_stop_listening(node); - } - - /* XXX call into net to stop this node from trading messages */ - - write_lock(&cluster->cl_nodes_lock); - - /* XXX sloppy */ - if (node->nd_ipv4_address) - rb_erase(&node->nd_ip_node, &cluster->cl_node_ip_tree); - - /* nd_num might be 0 if the node number hasn't been set.. */ - if (cluster->cl_nodes[node->nd_num] == node) { - cluster->cl_nodes[node->nd_num] = NULL; - clear_bit(node->nd_num, cluster->cl_nodes_bitmap); - } - write_unlock(&cluster->cl_nodes_lock); - - mlog(ML_CLUSTER, "o2nm: Unregistered node %s\n", - config_item_name(&node->nd_item)); - - config_item_put(item); -} - -static struct configfs_group_operations o2nm_node_group_group_ops = { - .make_item = o2nm_node_group_make_item, - .drop_item = o2nm_node_group_drop_item, -}; - -static struct config_item_type o2nm_node_group_type = { - .ct_group_ops = &o2nm_node_group_group_ops, - .ct_owner = THIS_MODULE, -}; - -/* cluster */ - -static void o2nm_cluster_release(struct config_item *item) -{ - struct o2nm_cluster *cluster = to_o2nm_cluster(item); - - kfree(cluster->cl_group.default_groups); - kfree(cluster); -} - -static struct configfs_item_operations o2nm_cluster_item_ops = { - .release = o2nm_cluster_release, - .show_attribute = o2nm_cluster_show, - .store_attribute = o2nm_cluster_store, -}; - -static struct config_item_type o2nm_cluster_type = { - .ct_item_ops = &o2nm_cluster_item_ops, - .ct_attrs = o2nm_cluster_attrs, - .ct_owner = THIS_MODULE, -}; - -/* cluster set */ - -struct o2nm_cluster_group { - struct configfs_subsystem cs_subsys; - /* some stuff? */ -}; - -#if 0 -static struct o2nm_cluster_group *to_o2nm_cluster_group(struct config_group *group) -{ - return group ? - container_of(to_configfs_subsystem(group), struct o2nm_cluster_group, cs_subsys) - : NULL; -} -#endif - -static struct config_group *o2nm_cluster_group_make_group(struct config_group *group, - const char *name) -{ - struct o2nm_cluster *cluster = NULL; - struct o2nm_node_group *ns = NULL; - struct config_group *o2hb_group = NULL, *ret = NULL; - void *defs = NULL; - - /* this runs under the parent dir's i_mutex; there can be only - * one caller in here at a time */ - if (o2nm_single_cluster) - return ERR_PTR(-ENOSPC); - - cluster = kzalloc(sizeof(struct o2nm_cluster), GFP_KERNEL); - ns = kzalloc(sizeof(struct o2nm_node_group), GFP_KERNEL); - defs = kcalloc(3, sizeof(struct config_group *), GFP_KERNEL); - o2hb_group = o2hb_alloc_hb_set(); - if (cluster == NULL || ns == NULL || o2hb_group == NULL || defs == NULL) - goto out; - - config_group_init_type_name(&cluster->cl_group, name, - &o2nm_cluster_type); - config_group_init_type_name(&ns->ns_group, "node", - &o2nm_node_group_type); - - cluster->cl_group.default_groups = defs; - cluster->cl_group.default_groups[0] = &ns->ns_group; - cluster->cl_group.default_groups[1] = o2hb_group; - cluster->cl_group.default_groups[2] = NULL; - rwlock_init(&cluster->cl_nodes_lock); - cluster->cl_node_ip_tree = RB_ROOT; - cluster->cl_reconnect_delay_ms = O2NET_RECONNECT_DELAY_MS_DEFAULT; - cluster->cl_idle_timeout_ms = O2NET_IDLE_TIMEOUT_MS_DEFAULT; - cluster->cl_keepalive_delay_ms = O2NET_KEEPALIVE_DELAY_MS_DEFAULT; - cluster->cl_fence_method = O2NM_FENCE_RESET; - - ret = &cluster->cl_group; - o2nm_single_cluster = cluster; - -out: - if (ret == NULL) { - kfree(cluster); - kfree(ns); - o2hb_free_hb_set(o2hb_group); - kfree(defs); - ret = ERR_PTR(-ENOMEM); - } - - return ret; -} - -static void o2nm_cluster_group_drop_item(struct config_group *group, struct config_item *item) -{ - struct o2nm_cluster *cluster = to_o2nm_cluster(item); - int i; - struct config_item *killme; - - BUG_ON(o2nm_single_cluster != cluster); - o2nm_single_cluster = NULL; - - for (i = 0; cluster->cl_group.default_groups[i]; i++) { - killme = &cluster->cl_group.default_groups[i]->cg_item; - cluster->cl_group.default_groups[i] = NULL; - config_item_put(killme); - } - - config_item_put(item); -} - -static struct configfs_group_operations o2nm_cluster_group_group_ops = { - .make_group = o2nm_cluster_group_make_group, - .drop_item = o2nm_cluster_group_drop_item, -}; - -static struct config_item_type o2nm_cluster_group_type = { - .ct_group_ops = &o2nm_cluster_group_group_ops, - .ct_owner = THIS_MODULE, -}; - -static struct o2nm_cluster_group o2nm_cluster_group = { - .cs_subsys = { - .su_group = { - .cg_item = { - .ci_namebuf = "cluster", - .ci_type = &o2nm_cluster_group_type, - }, - }, - }, -}; - -int o2nm_depend_item(struct config_item *item) -{ - return configfs_depend_item(&o2nm_cluster_group.cs_subsys, item); -} - -void o2nm_undepend_item(struct config_item *item) -{ - configfs_undepend_item(&o2nm_cluster_group.cs_subsys, item); -} - -int o2nm_depend_this_node(void) -{ - int ret = 0; - struct o2nm_node *local_node; - - local_node = o2nm_get_node_by_num(o2nm_this_node()); - if (!local_node) { - ret = -EINVAL; - goto out; - } - - ret = o2nm_depend_item(&local_node->nd_item); - o2nm_node_put(local_node); - -out: - return ret; -} - -void o2nm_undepend_this_node(void) -{ - struct o2nm_node *local_node; - - local_node = o2nm_get_node_by_num(o2nm_this_node()); - BUG_ON(!local_node); - - o2nm_undepend_item(&local_node->nd_item); - o2nm_node_put(local_node); -} - - -static void __exit exit_o2nm(void) -{ - /* XXX sync with hb callbacks and shut down hb? */ - o2net_unregister_hb_callbacks(); - configfs_unregister_subsystem(&o2nm_cluster_group.cs_subsys); - o2cb_sys_shutdown(); - - o2net_exit(); - o2hb_exit(); -} - -static int __init init_o2nm(void) -{ - int ret = -1; - - cluster_print_version(); - - ret = o2hb_init(); - if (ret) - goto out; - - ret = o2net_init(); - if (ret) - goto out_o2hb; - - ret = o2net_register_hb_callbacks(); - if (ret) - goto out_o2net; - - config_group_init(&o2nm_cluster_group.cs_subsys.su_group); - mutex_init(&o2nm_cluster_group.cs_subsys.su_mutex); - ret = configfs_register_subsystem(&o2nm_cluster_group.cs_subsys); - if (ret) { - printk(KERN_ERR "nodemanager: Registration returned %d\n", ret); - goto out_callbacks; - } - - ret = o2cb_sys_init(); - if (!ret) - goto out; - - configfs_unregister_subsystem(&o2nm_cluster_group.cs_subsys); -out_callbacks: - o2net_unregister_hb_callbacks(); -out_o2net: - o2net_exit(); -out_o2hb: - o2hb_exit(); -out: - return ret; -} - -MODULE_AUTHOR("Oracle"); -MODULE_LICENSE("GPL"); - -module_init(init_o2nm) -module_exit(exit_o2nm) diff --git a/drivers/staging/ramster/cluster/nodemanager.h b/drivers/staging/ramster/cluster/nodemanager.h deleted file mode 100644 index 09ea2d388bb..00000000000 --- a/drivers/staging/ramster/cluster/nodemanager.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * nodemanager.h - * - * Function prototypes - * - * Copyright (C) 2004 Oracle. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - * - */ - -#ifndef O2CLUSTER_NODEMANAGER_H -#define O2CLUSTER_NODEMANAGER_H - -#include "ocfs2_nodemanager.h" - -/* This totally doesn't belong here. */ -#include -#include - -enum o2nm_fence_method { - O2NM_FENCE_RESET = 0, - O2NM_FENCE_PANIC, - O2NM_FENCE_METHODS, /* Number of fence methods */ -}; - -struct o2nm_node { - spinlock_t nd_lock; - struct config_item nd_item; - char nd_name[O2NM_MAX_NAME_LEN+1]; /* replace? */ - __u8 nd_num; - /* only one address per node, as attributes, for now. */ - __be32 nd_ipv4_address; - __be16 nd_ipv4_port; - struct rb_node nd_ip_node; - /* there can be only one local node for now */ - int nd_local; - - unsigned long nd_set_attributes; -}; - -struct o2nm_cluster { - struct config_group cl_group; - unsigned cl_has_local:1; - u8 cl_local_node; - rwlock_t cl_nodes_lock; - struct o2nm_node *cl_nodes[O2NM_MAX_NODES]; - struct rb_root cl_node_ip_tree; - unsigned int cl_idle_timeout_ms; - unsigned int cl_keepalive_delay_ms; - unsigned int cl_reconnect_delay_ms; - enum o2nm_fence_method cl_fence_method; - - /* this bitmap is part of a hack for disk bitmap.. will go eventually. - zab */ - unsigned long cl_nodes_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)]; -}; - -extern struct o2nm_cluster *o2nm_single_cluster; - -u8 o2nm_this_node(void); - -int o2nm_configured_node_map(unsigned long *map, unsigned bytes); -struct o2nm_node *o2nm_get_node_by_num(u8 node_num); -struct o2nm_node *o2nm_get_node_by_ip(__be32 addr); -void o2nm_node_get(struct o2nm_node *node); -void o2nm_node_put(struct o2nm_node *node); - -int o2nm_depend_item(struct config_item *item); -void o2nm_undepend_item(struct config_item *item); -int o2nm_depend_this_node(void); -void o2nm_undepend_this_node(void); - -#endif /* O2CLUSTER_NODEMANAGER_H */ diff --git a/drivers/staging/ramster/cluster/ocfs2_heartbeat.h b/drivers/staging/ramster/cluster/ocfs2_heartbeat.h deleted file mode 100644 index 3f4151da970..00000000000 --- a/drivers/staging/ramster/cluster/ocfs2_heartbeat.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * ocfs2_heartbeat.h - * - * On-disk structures for ocfs2_heartbeat - * - * Copyright (C) 2002, 2004 Oracle. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - */ - -#ifndef _OCFS2_HEARTBEAT_H -#define _OCFS2_HEARTBEAT_H - -struct o2hb_disk_heartbeat_block { - __le64 hb_seq; - __u8 hb_node; - __u8 hb_pad1[3]; - __le32 hb_cksum; - __le64 hb_generation; - __le32 hb_dead_ms; -}; - -#endif /* _OCFS2_HEARTBEAT_H */ diff --git a/drivers/staging/ramster/cluster/ocfs2_nodemanager.h b/drivers/staging/ramster/cluster/ocfs2_nodemanager.h deleted file mode 100644 index 49b594325be..00000000000 --- a/drivers/staging/ramster/cluster/ocfs2_nodemanager.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * ocfs2_nodemanager.h - * - * Header describing the interface between userspace and the kernel - * for the ocfs2_nodemanager module. - * - * Copyright (C) 2002, 2004 Oracle. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - * - */ - -#ifndef _OCFS2_NODEMANAGER_H -#define _OCFS2_NODEMANAGER_H - -#define O2NM_API_VERSION 5 - -#define O2NM_MAX_NODES 255 -#define O2NM_INVALID_NODE_NUM 255 - -/* host name, group name, cluster name all 64 bytes */ -#define O2NM_MAX_NAME_LEN 64 // __NEW_UTS_LEN - -/* - * Maximum number of global heartbeat regions allowed. - * **CAUTION** Changing this number will break dlm compatibility. - */ -#define O2NM_MAX_REGIONS 32 - -#endif /* _OCFS2_NODEMANAGER_H */ diff --git a/drivers/staging/ramster/cluster/quorum.c b/drivers/staging/ramster/cluster/quorum.c deleted file mode 100644 index 8f9cea1597a..00000000000 --- a/drivers/staging/ramster/cluster/quorum.c +++ /dev/null @@ -1,331 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * Copyright (C) 2005 Oracle. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - */ - -/* This quorum hack is only here until we transition to some more rational - * approach that is driven from userspace. Honest. No foolin'. - * - * Imagine two nodes lose network connectivity to each other but they're still - * up and operating in every other way. Presumably a network timeout indicates - * that a node is broken and should be recovered. They can't both recover each - * other and both carry on without serialising their access to the file system. - * They need to decide who is authoritative. Now extend that problem to - * arbitrary groups of nodes losing connectivity between each other. - * - * So we declare that a node which has given up on connecting to a majority - * of nodes who are still heartbeating will fence itself. - * - * There are huge opportunities for races here. After we give up on a node's - * connection we need to wait long enough to give heartbeat an opportunity - * to declare the node as truly dead. We also need to be careful with the - * race between when we see a node start heartbeating and when we connect - * to it. - * - * So nodes that are in this transtion put a hold on the quorum decision - * with a counter. As they fall out of this transition they drop the count - * and if they're the last, they fire off the decision. - */ -#include -#include -#include - -#include "heartbeat.h" -#include "nodemanager.h" -#define MLOG_MASK_PREFIX ML_QUORUM -#include "masklog.h" -#include "quorum.h" - -static struct o2quo_state { - spinlock_t qs_lock; - struct work_struct qs_work; - int qs_pending; - int qs_heartbeating; - unsigned long qs_hb_bm[BITS_TO_LONGS(O2NM_MAX_NODES)]; - int qs_connected; - unsigned long qs_conn_bm[BITS_TO_LONGS(O2NM_MAX_NODES)]; - int qs_holds; - unsigned long qs_hold_bm[BITS_TO_LONGS(O2NM_MAX_NODES)]; -} o2quo_state; - -/* this is horribly heavy-handed. It should instead flip the file - * system RO and call some userspace script. */ -static void o2quo_fence_self(void) -{ - /* panic spins with interrupts enabled. with preempt - * threads can still schedule, etc, etc */ - o2hb_stop_all_regions(); - - switch (o2nm_single_cluster->cl_fence_method) { - case O2NM_FENCE_PANIC: - panic("*** ocfs2 is very sorry to be fencing this system by " - "panicing ***\n"); - break; - default: - WARN_ON(o2nm_single_cluster->cl_fence_method >= - O2NM_FENCE_METHODS); - case O2NM_FENCE_RESET: - printk(KERN_ERR "*** ocfs2 is very sorry to be fencing this " - "system by restarting ***\n"); - emergency_restart(); - break; - }; -} - -/* Indicate that a timeout occurred on a hearbeat region write. The - * other nodes in the cluster may consider us dead at that time so we - * want to "fence" ourselves so that we don't scribble on the disk - * after they think they've recovered us. This can't solve all - * problems related to writeout after recovery but this hack can at - * least close some of those gaps. When we have real fencing, this can - * go away as our node would be fenced externally before other nodes - * begin recovery. */ -void o2quo_disk_timeout(void) -{ - o2quo_fence_self(); -} - -static void o2quo_make_decision(struct work_struct *work) -{ - int quorum; - int lowest_hb, lowest_reachable = 0, fence = 0; - struct o2quo_state *qs = &o2quo_state; - - spin_lock(&qs->qs_lock); - - lowest_hb = find_first_bit(qs->qs_hb_bm, O2NM_MAX_NODES); - if (lowest_hb != O2NM_MAX_NODES) - lowest_reachable = test_bit(lowest_hb, qs->qs_conn_bm); - - mlog(0, "heartbeating: %d, connected: %d, " - "lowest: %d (%sreachable)\n", qs->qs_heartbeating, - qs->qs_connected, lowest_hb, lowest_reachable ? "" : "un"); - - if (!test_bit(o2nm_this_node(), qs->qs_hb_bm) || - qs->qs_heartbeating == 1) - goto out; - - if (qs->qs_heartbeating & 1) { - /* the odd numbered cluster case is straight forward -- - * if we can't talk to the majority we're hosed */ - quorum = (qs->qs_heartbeating + 1)/2; - if (qs->qs_connected < quorum) { - mlog(ML_ERROR, "fencing this node because it is " - "only connected to %u nodes and %u is needed " - "to make a quorum out of %u heartbeating nodes\n", - qs->qs_connected, quorum, - qs->qs_heartbeating); - fence = 1; - } - } else { - /* the even numbered cluster adds the possibility of each half - * of the cluster being able to talk amongst themselves.. in - * that case we're hosed if we can't talk to the group that has - * the lowest numbered node */ - quorum = qs->qs_heartbeating / 2; - if (qs->qs_connected < quorum) { - mlog(ML_ERROR, "fencing this node because it is " - "only connected to %u nodes and %u is needed " - "to make a quorum out of %u heartbeating nodes\n", - qs->qs_connected, quorum, - qs->qs_heartbeating); - fence = 1; - } - else if ((qs->qs_connected == quorum) && - !lowest_reachable) { - mlog(ML_ERROR, "fencing this node because it is " - "connected to a half-quorum of %u out of %u " - "nodes which doesn't include the lowest active " - "node %u\n", quorum, qs->qs_heartbeating, - lowest_hb); - fence = 1; - } - } - -out: - spin_unlock(&qs->qs_lock); - if (fence) - o2quo_fence_self(); -} - -static void o2quo_set_hold(struct o2quo_state *qs, u8 node) -{ - assert_spin_locked(&qs->qs_lock); - - if (!test_and_set_bit(node, qs->qs_hold_bm)) { - qs->qs_holds++; - mlog_bug_on_msg(qs->qs_holds == O2NM_MAX_NODES, - "node %u\n", node); - mlog(0, "node %u, %d total\n", node, qs->qs_holds); - } -} - -static void o2quo_clear_hold(struct o2quo_state *qs, u8 node) -{ - assert_spin_locked(&qs->qs_lock); - - if (test_and_clear_bit(node, qs->qs_hold_bm)) { - mlog(0, "node %u, %d total\n", node, qs->qs_holds - 1); - if (--qs->qs_holds == 0) { - if (qs->qs_pending) { - qs->qs_pending = 0; - schedule_work(&qs->qs_work); - } - } - mlog_bug_on_msg(qs->qs_holds < 0, "node %u, holds %d\n", - node, qs->qs_holds); - } -} - -/* as a node comes up we delay the quorum decision until we know the fate of - * the connection. the hold will be droped in conn_up or hb_down. it might be - * perpetuated by con_err until hb_down. if we already have a conn, we might - * be dropping a hold that conn_up got. */ -void o2quo_hb_up(u8 node) -{ - struct o2quo_state *qs = &o2quo_state; - - spin_lock(&qs->qs_lock); - - qs->qs_heartbeating++; - mlog_bug_on_msg(qs->qs_heartbeating == O2NM_MAX_NODES, - "node %u\n", node); - mlog_bug_on_msg(test_bit(node, qs->qs_hb_bm), "node %u\n", node); - set_bit(node, qs->qs_hb_bm); - - mlog(0, "node %u, %d total\n", node, qs->qs_heartbeating); - - if (!test_bit(node, qs->qs_conn_bm)) - o2quo_set_hold(qs, node); - else - o2quo_clear_hold(qs, node); - - spin_unlock(&qs->qs_lock); -} - -/* hb going down releases any holds we might have had due to this node from - * conn_up, conn_err, or hb_up */ -void o2quo_hb_down(u8 node) -{ - struct o2quo_state *qs = &o2quo_state; - - spin_lock(&qs->qs_lock); - - qs->qs_heartbeating--; - mlog_bug_on_msg(qs->qs_heartbeating < 0, - "node %u, %d heartbeating\n", - node, qs->qs_heartbeating); - mlog_bug_on_msg(!test_bit(node, qs->qs_hb_bm), "node %u\n", node); - clear_bit(node, qs->qs_hb_bm); - - mlog(0, "node %u, %d total\n", node, qs->qs_heartbeating); - - o2quo_clear_hold(qs, node); - - spin_unlock(&qs->qs_lock); -} - -/* this tells us that we've decided that the node is still heartbeating - * even though we've lost it's conn. it must only be called after conn_err - * and indicates that we must now make a quorum decision in the future, - * though we might be doing so after waiting for holds to drain. Here - * we'll be dropping the hold from conn_err. */ -void o2quo_hb_still_up(u8 node) -{ - struct o2quo_state *qs = &o2quo_state; - - spin_lock(&qs->qs_lock); - - mlog(0, "node %u\n", node); - - qs->qs_pending = 1; - o2quo_clear_hold(qs, node); - - spin_unlock(&qs->qs_lock); -} - -/* This is analogous to hb_up. as a node's connection comes up we delay the - * quorum decision until we see it heartbeating. the hold will be droped in - * hb_up or hb_down. it might be perpetuated by con_err until hb_down. if - * it's already heartbeating we we might be dropping a hold that conn_up got. - * */ -void o2quo_conn_up(u8 node) -{ - struct o2quo_state *qs = &o2quo_state; - - spin_lock(&qs->qs_lock); - - qs->qs_connected++; - mlog_bug_on_msg(qs->qs_connected == O2NM_MAX_NODES, - "node %u\n", node); - mlog_bug_on_msg(test_bit(node, qs->qs_conn_bm), "node %u\n", node); - set_bit(node, qs->qs_conn_bm); - - mlog(0, "node %u, %d total\n", node, qs->qs_connected); - - if (!test_bit(node, qs->qs_hb_bm)) - o2quo_set_hold(qs, node); - else - o2quo_clear_hold(qs, node); - - spin_unlock(&qs->qs_lock); -} - -/* we've decided that we won't ever be connecting to the node again. if it's - * still heartbeating we grab a hold that will delay decisions until either the - * node stops heartbeating from hb_down or the caller decides that the node is - * still up and calls still_up */ -void o2quo_conn_err(u8 node) -{ - struct o2quo_state *qs = &o2quo_state; - - spin_lock(&qs->qs_lock); - - if (test_bit(node, qs->qs_conn_bm)) { - qs->qs_connected--; - mlog_bug_on_msg(qs->qs_connected < 0, - "node %u, connected %d\n", - node, qs->qs_connected); - - clear_bit(node, qs->qs_conn_bm); - } - - mlog(0, "node %u, %d total\n", node, qs->qs_connected); - - if (test_bit(node, qs->qs_hb_bm)) - o2quo_set_hold(qs, node); - - spin_unlock(&qs->qs_lock); -} - -void o2quo_init(void) -{ - struct o2quo_state *qs = &o2quo_state; - - spin_lock_init(&qs->qs_lock); - INIT_WORK(&qs->qs_work, o2quo_make_decision); -} - -void o2quo_exit(void) -{ - struct o2quo_state *qs = &o2quo_state; - - flush_work_sync(&qs->qs_work); -} diff --git a/drivers/staging/ramster/cluster/quorum.h b/drivers/staging/ramster/cluster/quorum.h deleted file mode 100644 index 6649cc6f67c..00000000000 --- a/drivers/staging/ramster/cluster/quorum.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * Copyright (C) 2005 Oracle. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - * - */ - -#ifndef O2CLUSTER_QUORUM_H -#define O2CLUSTER_QUORUM_H - -void o2quo_init(void); -void o2quo_exit(void); - -void o2quo_hb_up(u8 node); -void o2quo_hb_down(u8 node); -void o2quo_hb_still_up(u8 node); -void o2quo_conn_up(u8 node); -void o2quo_conn_err(u8 node); -void o2quo_disk_timeout(void); - -#endif /* O2CLUSTER_QUORUM_H */ diff --git a/drivers/staging/ramster/cluster/sys.c b/drivers/staging/ramster/cluster/sys.c deleted file mode 100644 index a4b07730b2e..00000000000 --- a/drivers/staging/ramster/cluster/sys.c +++ /dev/null @@ -1,82 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * sys.c - * - * OCFS2 cluster sysfs interface - * - * Copyright (C) 2005 Oracle. 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, - * version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - * - */ - -#include -#include -#include -#include -#include - -#include "ocfs2_nodemanager.h" -#include "masklog.h" -#include "sys.h" - - -static ssize_t version_show(struct kobject *kobj, struct kobj_attribute *attr, - char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%u\n", O2NM_API_VERSION); -} -static struct kobj_attribute attr_version = - __ATTR(interface_revision, S_IFREG | S_IRUGO, version_show, NULL); - -static struct attribute *o2cb_attrs[] = { - &attr_version.attr, - NULL, -}; - -static struct attribute_group o2cb_attr_group = { - .attrs = o2cb_attrs, -}; - -static struct kset *o2cb_kset; - -void o2cb_sys_shutdown(void) -{ - mlog_sys_shutdown(); - kset_unregister(o2cb_kset); -} - -int o2cb_sys_init(void) -{ - int ret; - - o2cb_kset = kset_create_and_add("o2cb", NULL, fs_kobj); - if (!o2cb_kset) - return -ENOMEM; - - ret = sysfs_create_group(&o2cb_kset->kobj, &o2cb_attr_group); - if (ret) - goto error; - - ret = mlog_sys_init(o2cb_kset); - if (ret) - goto error; - return 0; -error: - kset_unregister(o2cb_kset); - return ret; -} diff --git a/drivers/staging/ramster/cluster/sys.h b/drivers/staging/ramster/cluster/sys.h deleted file mode 100644 index d66b8ab0045..00000000000 --- a/drivers/staging/ramster/cluster/sys.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * sys.h - * - * Function prototypes for o2cb sysfs interface - * - * Copyright (C) 2005 Oracle. 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, - * version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - * - */ - -#ifndef O2CLUSTER_SYS_H -#define O2CLUSTER_SYS_H - -void o2cb_sys_shutdown(void); -int o2cb_sys_init(void); - -#endif /* O2CLUSTER_SYS_H */ diff --git a/drivers/staging/ramster/cluster/tcp.c b/drivers/staging/ramster/cluster/tcp.c deleted file mode 100644 index e9bd00eb405..00000000000 --- a/drivers/staging/ramster/cluster/tcp.c +++ /dev/null @@ -1,2262 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * Copyright (C) 2004 Oracle. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - * - * ---- - * - * Callers for this were originally written against a very simple synchronus - * API. This implementation reflects those simple callers. Some day I'm sure - * we'll need to move to a more robust posting/callback mechanism. - * - * Transmit calls pass in kernel virtual addresses and block copying this into - * the socket's tx buffers via a usual blocking sendmsg. They'll block waiting - * for a failed socket to timeout. TX callers can also pass in a poniter to an - * 'int' which gets filled with an errno off the wire in response to the - * message they send. - * - * Handlers for unsolicited messages are registered. Each socket has a page - * that incoming data is copied into. First the header, then the data. - * Handlers are called from only one thread with a reference to this per-socket - * page. This page is destroyed after the handler call, so it can't be - * referenced beyond the call. Handlers may block but are discouraged from - * doing so. - * - * Any framing errors (bad magic, large payload lengths) close a connection. - * - * Our sock_container holds the state we associate with a socket. It's current - * framing state is held there as well as the refcounting we do around when it - * is safe to tear down the socket. The socket is only finally torn down from - * the container when the container loses all of its references -- so as long - * as you hold a ref on the container you can trust that the socket is valid - * for use with kernel socket APIs. - * - * Connections are initiated between a pair of nodes when the node with the - * higher node number gets a heartbeat callback which indicates that the lower - * numbered node has started heartbeating. The lower numbered node is passive - * and only accepts the connection if the higher numbered node is heartbeating. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "heartbeat.h" -#include "tcp.h" -#include "nodemanager.h" -#define MLOG_MASK_PREFIX ML_TCP -#include "masklog.h" -#include "quorum.h" - -#include "tcp_internal.h" - -#define SC_NODEF_FMT "node %s (num %u) at %pI4:%u" -#define SC_NODEF_ARGS(sc) sc->sc_node->nd_name, sc->sc_node->nd_num, \ - &sc->sc_node->nd_ipv4_address, \ - ntohs(sc->sc_node->nd_ipv4_port) - -/* - * In the following two log macros, the whitespace after the ',' just - * before ##args is intentional. Otherwise, gcc 2.95 will eat the - * previous token if args expands to nothing. - */ -#define msglog(hdr, fmt, args...) do { \ - typeof(hdr) __hdr = (hdr); \ - mlog(ML_MSG, "[mag %u len %u typ %u stat %d sys_stat %d " \ - "key %08x num %u] " fmt, \ - be16_to_cpu(__hdr->magic), be16_to_cpu(__hdr->data_len), \ - be16_to_cpu(__hdr->msg_type), be32_to_cpu(__hdr->status), \ - be32_to_cpu(__hdr->sys_status), be32_to_cpu(__hdr->key), \ - be32_to_cpu(__hdr->msg_num) , ##args); \ -} while (0) - -#define sclog(sc, fmt, args...) do { \ - typeof(sc) __sc = (sc); \ - mlog(ML_SOCKET, "[sc %p refs %d sock %p node %u page %p " \ - "pg_off %zu] " fmt, __sc, \ - atomic_read(&__sc->sc_kref.refcount), __sc->sc_sock, \ - __sc->sc_node->nd_num, __sc->sc_page, __sc->sc_page_off , \ - ##args); \ -} while (0) - -static DEFINE_RWLOCK(o2net_handler_lock); -static struct rb_root o2net_handler_tree = RB_ROOT; - -static struct o2net_node o2net_nodes[O2NM_MAX_NODES]; - -/* XXX someday we'll need better accounting */ -static struct socket *o2net_listen_sock = NULL; - -/* - * listen work is only queued by the listening socket callbacks on the - * o2net_wq. teardown detaches the callbacks before destroying the workqueue. - * quorum work is queued as sock containers are shutdown.. stop_listening - * tears down all the node's sock containers, preventing future shutdowns - * and queued quroum work, before canceling delayed quorum work and - * destroying the work queue. - */ -static struct workqueue_struct *o2net_wq; -static struct work_struct o2net_listen_work; - -static struct o2hb_callback_func o2net_hb_up, o2net_hb_down; -#define O2NET_HB_PRI 0x1 - -static struct o2net_handshake *o2net_hand; -static struct o2net_msg *o2net_keep_req, *o2net_keep_resp; - -static int o2net_sys_err_translations[O2NET_ERR_MAX] = - {[O2NET_ERR_NONE] = 0, - [O2NET_ERR_NO_HNDLR] = -ENOPROTOOPT, - [O2NET_ERR_OVERFLOW] = -EOVERFLOW, - [O2NET_ERR_DIED] = -EHOSTDOWN,}; - -/* can't quite avoid *all* internal declarations :/ */ -static void o2net_sc_connect_completed(struct work_struct *work); -static void o2net_rx_until_empty(struct work_struct *work); -static void o2net_shutdown_sc(struct work_struct *work); -static void o2net_listen_data_ready(struct sock *sk, int bytes); -static void o2net_sc_send_keep_req(struct work_struct *work); -static void o2net_idle_timer(unsigned long data); -static void o2net_sc_postpone_idle(struct o2net_sock_container *sc); -static void o2net_sc_reset_idle_timer(struct o2net_sock_container *sc); - -#ifdef CONFIG_DEBUG_FS -static void o2net_init_nst(struct o2net_send_tracking *nst, u32 msgtype, - u32 msgkey, struct task_struct *task, u8 node) -{ - INIT_LIST_HEAD(&nst->st_net_debug_item); - nst->st_task = task; - nst->st_msg_type = msgtype; - nst->st_msg_key = msgkey; - nst->st_node = node; -} - -static inline void o2net_set_nst_sock_time(struct o2net_send_tracking *nst) -{ - nst->st_sock_time = ktime_get(); -} - -static inline void o2net_set_nst_send_time(struct o2net_send_tracking *nst) -{ - nst->st_send_time = ktime_get(); -} - -static inline void o2net_set_nst_status_time(struct o2net_send_tracking *nst) -{ - nst->st_status_time = ktime_get(); -} - -static inline void o2net_set_nst_sock_container(struct o2net_send_tracking *nst, - struct o2net_sock_container *sc) -{ - nst->st_sc = sc; -} - -static inline void o2net_set_nst_msg_id(struct o2net_send_tracking *nst, - u32 msg_id) -{ - nst->st_id = msg_id; -} - -static inline void o2net_set_sock_timer(struct o2net_sock_container *sc) -{ - sc->sc_tv_timer = ktime_get(); -} - -static inline void o2net_set_data_ready_time(struct o2net_sock_container *sc) -{ - sc->sc_tv_data_ready = ktime_get(); -} - -static inline void o2net_set_advance_start_time(struct o2net_sock_container *sc) -{ - sc->sc_tv_advance_start = ktime_get(); -} - -static inline void o2net_set_advance_stop_time(struct o2net_sock_container *sc) -{ - sc->sc_tv_advance_stop = ktime_get(); -} - -static inline void o2net_set_func_start_time(struct o2net_sock_container *sc) -{ - sc->sc_tv_func_start = ktime_get(); -} - -static inline void o2net_set_func_stop_time(struct o2net_sock_container *sc) -{ - sc->sc_tv_func_stop = ktime_get(); -} - -#else /* CONFIG_DEBUG_FS */ -# define o2net_init_nst(a, b, c, d, e) -# define o2net_set_nst_sock_time(a) -# define o2net_set_nst_send_time(a) -# define o2net_set_nst_status_time(a) -# define o2net_set_nst_sock_container(a, b) -# define o2net_set_nst_msg_id(a, b) -# define o2net_set_sock_timer(a) -# define o2net_set_data_ready_time(a) -# define o2net_set_advance_start_time(a) -# define o2net_set_advance_stop_time(a) -# define o2net_set_func_start_time(a) -# define o2net_set_func_stop_time(a) -#endif /* CONFIG_DEBUG_FS */ - -#ifdef CONFIG_OCFS2_FS_STATS -static ktime_t o2net_get_func_run_time(struct o2net_sock_container *sc) -{ - return ktime_sub(sc->sc_tv_func_stop, sc->sc_tv_func_start); -} - -static void o2net_update_send_stats(struct o2net_send_tracking *nst, - struct o2net_sock_container *sc) -{ - sc->sc_tv_status_total = ktime_add(sc->sc_tv_status_total, - ktime_sub(ktime_get(), - nst->st_status_time)); - sc->sc_tv_send_total = ktime_add(sc->sc_tv_send_total, - ktime_sub(nst->st_status_time, - nst->st_send_time)); - sc->sc_tv_acquiry_total = ktime_add(sc->sc_tv_acquiry_total, - ktime_sub(nst->st_send_time, - nst->st_sock_time)); - sc->sc_send_count++; -} - -static void o2net_update_recv_stats(struct o2net_sock_container *sc) -{ - sc->sc_tv_process_total = ktime_add(sc->sc_tv_process_total, - o2net_get_func_run_time(sc)); - sc->sc_recv_count++; -} - -#else - -# define o2net_update_send_stats(a, b) - -# define o2net_update_recv_stats(sc) - -#endif /* CONFIG_OCFS2_FS_STATS */ - -static inline int o2net_reconnect_delay(void) -{ - return o2nm_single_cluster->cl_reconnect_delay_ms; -} - -static inline int o2net_keepalive_delay(void) -{ - return o2nm_single_cluster->cl_keepalive_delay_ms; -} - -static inline int o2net_idle_timeout(void) -{ - return o2nm_single_cluster->cl_idle_timeout_ms; -} - -static inline int o2net_sys_err_to_errno(enum o2net_system_error err) -{ - int trans; - BUG_ON(err >= O2NET_ERR_MAX); - trans = o2net_sys_err_translations[err]; - - /* Just in case we mess up the translation table above */ - BUG_ON(err != O2NET_ERR_NONE && trans == 0); - return trans; -} - -#ifdef CONFIG_RAMSTER -struct o2net_node *o2net_nn_from_num(u8 node_num) -#else -static struct o2net_node * o2net_nn_from_num(u8 node_num) -#endif -{ - BUG_ON(node_num >= ARRAY_SIZE(o2net_nodes)); - return &o2net_nodes[node_num]; -} - -static u8 o2net_num_from_nn(struct o2net_node *nn) -{ - BUG_ON(nn == NULL); - return nn - o2net_nodes; -} - -/* ------------------------------------------------------------ */ - -static int o2net_prep_nsw(struct o2net_node *nn, struct o2net_status_wait *nsw) -{ - int ret = 0; - - 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); - - if (ret == 0) { - init_waitqueue_head(&nsw->ns_wq); - nsw->ns_sys_status = O2NET_ERR_NONE; - nsw->ns_status = 0; - } - - return ret; -} - -static void o2net_complete_nsw_locked(struct o2net_node *nn, - struct o2net_status_wait *nsw, - enum o2net_system_error sys_status, - s32 status) -{ - assert_spin_locked(&nn->nn_lock); - - if (!list_empty(&nsw->ns_node_item)) { - list_del_init(&nsw->ns_node_item); - nsw->ns_sys_status = sys_status; - nsw->ns_status = status; - idr_remove(&nn->nn_status_idr, nsw->ns_id); - wake_up(&nsw->ns_wq); - } -} - -static void o2net_complete_nsw(struct o2net_node *nn, - struct o2net_status_wait *nsw, - u64 id, enum o2net_system_error sys_status, - s32 status) -{ - spin_lock(&nn->nn_lock); - if (nsw == NULL) { - if (id > INT_MAX) - goto out; - - nsw = idr_find(&nn->nn_status_idr, id); - if (nsw == NULL) - goto out; - } - - o2net_complete_nsw_locked(nn, nsw, sys_status, status); - -out: - spin_unlock(&nn->nn_lock); - return; -} - -static void o2net_complete_nodes_nsw(struct o2net_node *nn) -{ - struct o2net_status_wait *nsw, *tmp; - unsigned int num_kills = 0; - - assert_spin_locked(&nn->nn_lock); - - list_for_each_entry_safe(nsw, tmp, &nn->nn_status_list, ns_node_item) { - o2net_complete_nsw_locked(nn, nsw, O2NET_ERR_DIED, 0); - num_kills++; - } - - mlog(0, "completed %d messages for node %u\n", num_kills, - o2net_num_from_nn(nn)); -} - -static int o2net_nsw_completed(struct o2net_node *nn, - struct o2net_status_wait *nsw) -{ - int completed; - spin_lock(&nn->nn_lock); - completed = list_empty(&nsw->ns_node_item); - spin_unlock(&nn->nn_lock); - return completed; -} - -/* ------------------------------------------------------------ */ - -static void sc_kref_release(struct kref *kref) -{ - struct o2net_sock_container *sc = container_of(kref, - struct o2net_sock_container, sc_kref); - BUG_ON(timer_pending(&sc->sc_idle_timeout)); - - sclog(sc, "releasing\n"); - - if (sc->sc_sock) { - sock_release(sc->sc_sock); - sc->sc_sock = NULL; - } - - o2nm_undepend_item(&sc->sc_node->nd_item); - o2nm_node_put(sc->sc_node); - sc->sc_node = NULL; - - o2net_debug_del_sc(sc); - kfree(sc); -} - -static void sc_put(struct o2net_sock_container *sc) -{ - sclog(sc, "put\n"); - kref_put(&sc->sc_kref, sc_kref_release); -} -static void sc_get(struct o2net_sock_container *sc) -{ - sclog(sc, "get\n"); - kref_get(&sc->sc_kref); -} -static struct o2net_sock_container *sc_alloc(struct o2nm_node *node) -{ - struct o2net_sock_container *sc, *ret = NULL; - struct page *page = NULL; - int status = 0; - - page = alloc_page(GFP_NOFS); - sc = kzalloc(sizeof(*sc), GFP_NOFS); - if (sc == NULL || page == NULL) - goto out; - - kref_init(&sc->sc_kref); - o2nm_node_get(node); - sc->sc_node = node; - - /* pin the node item of the remote node */ - status = o2nm_depend_item(&node->nd_item); - if (status) { - mlog_errno(status); - o2nm_node_put(node); - goto out; - } - INIT_WORK(&sc->sc_connect_work, o2net_sc_connect_completed); - INIT_WORK(&sc->sc_rx_work, o2net_rx_until_empty); - INIT_WORK(&sc->sc_shutdown_work, o2net_shutdown_sc); - INIT_DELAYED_WORK(&sc->sc_keepalive_work, o2net_sc_send_keep_req); - - init_timer(&sc->sc_idle_timeout); - sc->sc_idle_timeout.function = o2net_idle_timer; - sc->sc_idle_timeout.data = (unsigned long)sc; - - sclog(sc, "alloced\n"); - - ret = sc; - sc->sc_page = page; - o2net_debug_add_sc(sc); - sc = NULL; - page = NULL; - -out: - if (page) - __free_page(page); - kfree(sc); - - return ret; -} - -/* ------------------------------------------------------------ */ - -static void o2net_sc_queue_work(struct o2net_sock_container *sc, - struct work_struct *work) -{ - sc_get(sc); - if (!queue_work(o2net_wq, work)) - sc_put(sc); -} -static void o2net_sc_queue_delayed_work(struct o2net_sock_container *sc, - struct delayed_work *work, - int delay) -{ - sc_get(sc); - if (!queue_delayed_work(o2net_wq, work, delay)) - sc_put(sc); -} -static void o2net_sc_cancel_delayed_work(struct o2net_sock_container *sc, - struct delayed_work *work) -{ - if (cancel_delayed_work(work)) - sc_put(sc); -} - -static atomic_t o2net_connected_peers = ATOMIC_INIT(0); - -int o2net_num_connected_peers(void) -{ - return atomic_read(&o2net_connected_peers); -} - -static void o2net_set_nn_state(struct o2net_node *nn, - struct o2net_sock_container *sc, - unsigned valid, int err) -{ - int was_valid = nn->nn_sc_valid; - int was_err = nn->nn_persistent_error; - struct o2net_sock_container *old_sc = nn->nn_sc; - - assert_spin_locked(&nn->nn_lock); - - if (old_sc && !sc) - atomic_dec(&o2net_connected_peers); - else if (!old_sc && sc) - atomic_inc(&o2net_connected_peers); - - /* the node num comparison and single connect/accept path should stop - * an non-null sc from being overwritten with another */ - BUG_ON(sc && nn->nn_sc && nn->nn_sc != sc); - mlog_bug_on_msg(err && valid, "err %d valid %u\n", err, valid); - mlog_bug_on_msg(valid && !sc, "valid %u sc %p\n", valid, sc); - - if (was_valid && !valid && err == 0) - err = -ENOTCONN; - - mlog(ML_CONN, "node %u sc: %p -> %p, valid %u -> %u, err %d -> %d\n", - o2net_num_from_nn(nn), nn->nn_sc, sc, nn->nn_sc_valid, valid, - nn->nn_persistent_error, err); - - nn->nn_sc = sc; - nn->nn_sc_valid = valid ? 1 : 0; - nn->nn_persistent_error = err; - - /* mirrors o2net_tx_can_proceed() */ - if (nn->nn_persistent_error || nn->nn_sc_valid) - wake_up(&nn->nn_sc_wq); - - if (!was_err && nn->nn_persistent_error) { - o2quo_conn_err(o2net_num_from_nn(nn)); - queue_delayed_work(o2net_wq, &nn->nn_still_up, - msecs_to_jiffies(O2NET_QUORUM_DELAY_MS)); - } - - if (was_valid && !valid) { - printk(KERN_NOTICE "o2net: No longer connected to " - SC_NODEF_FMT "\n", SC_NODEF_ARGS(old_sc)); - o2net_complete_nodes_nsw(nn); - } - - if (!was_valid && valid) { - o2quo_conn_up(o2net_num_from_nn(nn)); - cancel_delayed_work(&nn->nn_connect_expired); - printk(KERN_NOTICE "o2net: %s " SC_NODEF_FMT "\n", - o2nm_this_node() > sc->sc_node->nd_num ? - "Connected to" : "Accepted connection from", - SC_NODEF_ARGS(sc)); - } - - /* trigger the connecting worker func as long as we're not valid, - * it will back off if it shouldn't connect. This can be called - * from node config teardown and so needs to be careful about - * the work queue actually being up. */ - if (!valid && o2net_wq) { - unsigned long delay; - /* delay if we're within a RECONNECT_DELAY of the - * last attempt */ - delay = (nn->nn_last_connect_attempt + - msecs_to_jiffies(o2net_reconnect_delay())) - - jiffies; - if (delay > msecs_to_jiffies(o2net_reconnect_delay())) - delay = 0; - mlog(ML_CONN, "queueing conn attempt in %lu jiffies\n", delay); - queue_delayed_work(o2net_wq, &nn->nn_connect_work, delay); - - /* - * Delay the expired work after idle timeout. - * - * We might have lots of failed connection attempts that run - * through here but we only cancel the connect_expired work when - * a connection attempt succeeds. So only the first enqueue of - * the connect_expired work will do anything. The rest will see - * that it's already queued and do nothing. - */ - delay += msecs_to_jiffies(o2net_idle_timeout()); - queue_delayed_work(o2net_wq, &nn->nn_connect_expired, delay); - } - - /* keep track of the nn's sc ref for the caller */ - if ((old_sc == NULL) && sc) - sc_get(sc); - if (old_sc && (old_sc != sc)) { - o2net_sc_queue_work(old_sc, &old_sc->sc_shutdown_work); - sc_put(old_sc); - } -} - -/* see o2net_register_callbacks() */ -static void o2net_data_ready(struct sock *sk, int bytes) -{ - void (*ready)(struct sock *sk, int bytes); - - read_lock(&sk->sk_callback_lock); - if (sk->sk_user_data) { - struct o2net_sock_container *sc = sk->sk_user_data; - sclog(sc, "data_ready hit\n"); - o2net_set_data_ready_time(sc); - o2net_sc_queue_work(sc, &sc->sc_rx_work); - ready = sc->sc_data_ready; - } else { - ready = sk->sk_data_ready; - } - read_unlock(&sk->sk_callback_lock); - - ready(sk, bytes); -} - -/* see o2net_register_callbacks() */ -static void o2net_state_change(struct sock *sk) -{ - void (*state_change)(struct sock *sk); - struct o2net_sock_container *sc; - - read_lock(&sk->sk_callback_lock); - sc = sk->sk_user_data; - if (sc == NULL) { - state_change = sk->sk_state_change; - goto out; - } - - sclog(sc, "state_change to %d\n", sk->sk_state); - - state_change = sc->sc_state_change; - - switch(sk->sk_state) { - /* ignore connecting sockets as they make progress */ - case TCP_SYN_SENT: - case TCP_SYN_RECV: - break; - case TCP_ESTABLISHED: - o2net_sc_queue_work(sc, &sc->sc_connect_work); - break; - default: - printk(KERN_INFO "o2net: Connection to " SC_NODEF_FMT - " shutdown, state %d\n", - SC_NODEF_ARGS(sc), sk->sk_state); - o2net_sc_queue_work(sc, &sc->sc_shutdown_work); - break; - } -out: - read_unlock(&sk->sk_callback_lock); - state_change(sk); -} - -/* - * we register callbacks so we can queue work on events before calling - * the original callbacks. our callbacks our careful to test user_data - * to discover when they've reaced with o2net_unregister_callbacks(). - */ -static void o2net_register_callbacks(struct sock *sk, - struct o2net_sock_container *sc) -{ - write_lock_bh(&sk->sk_callback_lock); - - /* accepted sockets inherit the old listen socket data ready */ - if (sk->sk_data_ready == o2net_listen_data_ready) { - sk->sk_data_ready = sk->sk_user_data; - sk->sk_user_data = NULL; - } - - BUG_ON(sk->sk_user_data != NULL); - sk->sk_user_data = sc; - sc_get(sc); - - sc->sc_data_ready = sk->sk_data_ready; - sc->sc_state_change = sk->sk_state_change; - sk->sk_data_ready = o2net_data_ready; - sk->sk_state_change = o2net_state_change; - - mutex_init(&sc->sc_send_lock); - - write_unlock_bh(&sk->sk_callback_lock); -} - -static int o2net_unregister_callbacks(struct sock *sk, - struct o2net_sock_container *sc) -{ - int ret = 0; - - write_lock_bh(&sk->sk_callback_lock); - if (sk->sk_user_data == sc) { - ret = 1; - sk->sk_user_data = NULL; - sk->sk_data_ready = sc->sc_data_ready; - sk->sk_state_change = sc->sc_state_change; - } - write_unlock_bh(&sk->sk_callback_lock); - - return ret; -} - -/* - * this is a little helper that is called by callers who have seen a problem - * with an sc and want to detach it from the nn if someone already hasn't beat - * them to it. if an error is given then the shutdown will be persistent - * and pending transmits will be canceled. - */ -static void o2net_ensure_shutdown(struct o2net_node *nn, - struct o2net_sock_container *sc, - int err) -{ - spin_lock(&nn->nn_lock); - if (nn->nn_sc == sc) - o2net_set_nn_state(nn, NULL, 0, err); - spin_unlock(&nn->nn_lock); -} - -/* - * This work queue function performs the blocking parts of socket shutdown. A - * few paths lead here. set_nn_state will trigger this callback if it sees an - * sc detached from the nn. state_change will also trigger this callback - * directly when it sees errors. In that case we need to call set_nn_state - * ourselves as state_change couldn't get the nn_lock and call set_nn_state - * itself. - */ -static void o2net_shutdown_sc(struct work_struct *work) -{ - struct o2net_sock_container *sc = - container_of(work, struct o2net_sock_container, - sc_shutdown_work); - struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num); - - sclog(sc, "shutting down\n"); - - /* drop the callbacks ref and call shutdown only once */ - if (o2net_unregister_callbacks(sc->sc_sock->sk, sc)) { - /* we shouldn't flush as we're in the thread, the - * races with pending sc work structs are harmless */ - del_timer_sync(&sc->sc_idle_timeout); - o2net_sc_cancel_delayed_work(sc, &sc->sc_keepalive_work); - sc_put(sc); - kernel_sock_shutdown(sc->sc_sock, SHUT_RDWR); - } - - /* not fatal so failed connects before the other guy has our - * heartbeat can be retried */ - o2net_ensure_shutdown(nn, sc, 0); - sc_put(sc); -} - -/* ------------------------------------------------------------ */ - -static int o2net_handler_cmp(struct o2net_msg_handler *nmh, u32 msg_type, - u32 key) -{ - int ret = memcmp(&nmh->nh_key, &key, sizeof(key)); - - if (ret == 0) - ret = memcmp(&nmh->nh_msg_type, &msg_type, sizeof(msg_type)); - - return ret; -} - -static struct o2net_msg_handler * -o2net_handler_tree_lookup(u32 msg_type, u32 key, struct rb_node ***ret_p, - struct rb_node **ret_parent) -{ - struct rb_node **p = &o2net_handler_tree.rb_node; - struct rb_node *parent = NULL; - struct o2net_msg_handler *nmh, *ret = NULL; - int cmp; - - while (*p) { - parent = *p; - nmh = rb_entry(parent, struct o2net_msg_handler, nh_node); - cmp = o2net_handler_cmp(nmh, msg_type, key); - - if (cmp < 0) - p = &(*p)->rb_left; - else if (cmp > 0) - p = &(*p)->rb_right; - else { - ret = nmh; - break; - } - } - - if (ret_p != NULL) - *ret_p = p; - if (ret_parent != NULL) - *ret_parent = parent; - - return ret; -} - -static void o2net_handler_kref_release(struct kref *kref) -{ - struct o2net_msg_handler *nmh; - nmh = container_of(kref, struct o2net_msg_handler, nh_kref); - - kfree(nmh); -} - -static void o2net_handler_put(struct o2net_msg_handler *nmh) -{ - kref_put(&nmh->nh_kref, o2net_handler_kref_release); -} - -/* max_len is protection for the handler func. incoming messages won't - * be given to the handler if their payload is longer than the max. */ -int o2net_register_handler(u32 msg_type, u32 key, u32 max_len, - o2net_msg_handler_func *func, void *data, - o2net_post_msg_handler_func *post_func, - struct list_head *unreg_list) -{ - struct o2net_msg_handler *nmh = NULL; - struct rb_node **p, *parent; - int ret = 0; - - if (max_len > O2NET_MAX_PAYLOAD_BYTES) { - mlog(0, "max_len for message handler out of range: %u\n", - max_len); - ret = -EINVAL; - goto out; - } - - if (!msg_type) { - mlog(0, "no message type provided: %u, %p\n", msg_type, func); - ret = -EINVAL; - goto out; - - } - if (!func) { - mlog(0, "no message handler provided: %u, %p\n", - msg_type, func); - ret = -EINVAL; - goto out; - } - - nmh = kzalloc(sizeof(struct o2net_msg_handler), GFP_NOFS); - if (nmh == NULL) { - ret = -ENOMEM; - goto out; - } - - nmh->nh_func = func; - nmh->nh_func_data = data; - nmh->nh_post_func = post_func; - nmh->nh_msg_type = msg_type; - nmh->nh_max_len = max_len; - nmh->nh_key = key; - /* the tree and list get this ref.. they're both removed in - * unregister when this ref is dropped */ - kref_init(&nmh->nh_kref); - INIT_LIST_HEAD(&nmh->nh_unregister_item); - - write_lock(&o2net_handler_lock); - if (o2net_handler_tree_lookup(msg_type, key, &p, &parent)) - ret = -EEXIST; - else { - rb_link_node(&nmh->nh_node, parent, p); - rb_insert_color(&nmh->nh_node, &o2net_handler_tree); - list_add_tail(&nmh->nh_unregister_item, unreg_list); - - mlog(ML_TCP, "registered handler func %p type %u key %08x\n", - func, msg_type, key); - /* we've had some trouble with handlers seemingly vanishing. */ - mlog_bug_on_msg(o2net_handler_tree_lookup(msg_type, key, &p, - &parent) == NULL, - "couldn't find handler we *just* registerd " - "for type %u key %08x\n", msg_type, key); - } - write_unlock(&o2net_handler_lock); - if (ret) - goto out; - -out: - if (ret) - kfree(nmh); - - return ret; -} -EXPORT_SYMBOL_GPL(o2net_register_handler); - -void o2net_unregister_handler_list(struct list_head *list) -{ - struct o2net_msg_handler *nmh, *n; - - write_lock(&o2net_handler_lock); - list_for_each_entry_safe(nmh, n, list, nh_unregister_item) { - mlog(ML_TCP, "unregistering handler func %p type %u key %08x\n", - nmh->nh_func, nmh->nh_msg_type, nmh->nh_key); - rb_erase(&nmh->nh_node, &o2net_handler_tree); - list_del_init(&nmh->nh_unregister_item); - kref_put(&nmh->nh_kref, o2net_handler_kref_release); - } - write_unlock(&o2net_handler_lock); -} -EXPORT_SYMBOL_GPL(o2net_unregister_handler_list); - -static struct o2net_msg_handler *o2net_handler_get(u32 msg_type, u32 key) -{ - struct o2net_msg_handler *nmh; - - read_lock(&o2net_handler_lock); - nmh = o2net_handler_tree_lookup(msg_type, key, NULL, NULL); - if (nmh) - kref_get(&nmh->nh_kref); - read_unlock(&o2net_handler_lock); - - return nmh; -} - -/* ------------------------------------------------------------ */ - -static int o2net_recv_tcp_msg(struct socket *sock, void *data, size_t len) -{ - int ret; - mm_segment_t oldfs; - struct kvec vec = { - .iov_len = len, - .iov_base = data, - }; - struct msghdr msg = { - .msg_iovlen = 1, - .msg_iov = (struct iovec *)&vec, - .msg_flags = MSG_DONTWAIT, - }; - - oldfs = get_fs(); - set_fs(get_ds()); - ret = sock_recvmsg(sock, &msg, len, msg.msg_flags); - set_fs(oldfs); - - return ret; -} - -static int o2net_send_tcp_msg(struct socket *sock, struct kvec *vec, - size_t veclen, size_t total) -{ - int ret; - mm_segment_t oldfs; - struct msghdr msg = { - .msg_iov = (struct iovec *)vec, - .msg_iovlen = veclen, - }; - - if (sock == NULL) { - ret = -EINVAL; - goto out; - } - - oldfs = get_fs(); - set_fs(get_ds()); - ret = sock_sendmsg(sock, &msg, total); - set_fs(oldfs); - if (ret != total) { - mlog(ML_ERROR, "sendmsg returned %d instead of %zu\n", ret, - total); - if (ret >= 0) - ret = -EPIPE; /* should be smarter, I bet */ - goto out; - } - - ret = 0; -out: - if (ret < 0) - mlog(0, "returning error: %d\n", ret); - return ret; -} - -static void o2net_sendpage(struct o2net_sock_container *sc, - void *kmalloced_virt, - size_t size) -{ - struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num); - ssize_t ret; - - while (1) { - mutex_lock(&sc->sc_send_lock); - ret = sc->sc_sock->ops->sendpage(sc->sc_sock, - virt_to_page(kmalloced_virt), - (long)kmalloced_virt & ~PAGE_MASK, - size, MSG_DONTWAIT); - mutex_unlock(&sc->sc_send_lock); - if (ret == size) - break; - if (ret == (ssize_t)-EAGAIN) { - mlog(0, "sendpage of size %zu to " SC_NODEF_FMT - " returned EAGAIN\n", size, SC_NODEF_ARGS(sc)); - cond_resched(); - continue; - } - mlog(ML_ERROR, "sendpage of size %zu to " SC_NODEF_FMT - " failed with %zd\n", size, SC_NODEF_ARGS(sc), ret); - o2net_ensure_shutdown(nn, sc, 0); - break; - } -} - -static void o2net_init_msg(struct o2net_msg *msg, u16 data_len, u16 msg_type, u32 key) -{ - memset(msg, 0, sizeof(struct o2net_msg)); - msg->magic = cpu_to_be16(O2NET_MSG_MAGIC); - msg->data_len = cpu_to_be16(data_len); - msg->msg_type = cpu_to_be16(msg_type); - msg->sys_status = cpu_to_be32(O2NET_ERR_NONE); - msg->status = 0; - msg->key = cpu_to_be32(key); -} - -static int o2net_tx_can_proceed(struct o2net_node *nn, - struct o2net_sock_container **sc_ret, - int *error) -{ - int ret = 0; - - spin_lock(&nn->nn_lock); - if (nn->nn_persistent_error) { - ret = 1; - *sc_ret = NULL; - *error = nn->nn_persistent_error; - } else if (nn->nn_sc_valid) { - kref_get(&nn->nn_sc->sc_kref); - - ret = 1; - *sc_ret = nn->nn_sc; - *error = 0; - } - spin_unlock(&nn->nn_lock); - - return ret; -} - -/* Get a map of all nodes to which this node is currently connected to */ -void o2net_fill_node_map(unsigned long *map, unsigned bytes) -{ - struct o2net_sock_container *sc; - int node, ret; - - BUG_ON(bytes < (BITS_TO_LONGS(O2NM_MAX_NODES) * sizeof(unsigned long))); - - memset(map, 0, bytes); - for (node = 0; node < O2NM_MAX_NODES; ++node) { - o2net_tx_can_proceed(o2net_nn_from_num(node), &sc, &ret); - if (!ret) { - set_bit(node, map); - sc_put(sc); - } - } -} -EXPORT_SYMBOL_GPL(o2net_fill_node_map); - -int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec, - size_t caller_veclen, u8 target_node, int *status) -{ - int ret = 0; - struct o2net_msg *msg = NULL; - size_t veclen, caller_bytes = 0; - struct kvec *vec = NULL; - struct o2net_sock_container *sc = NULL; - struct o2net_node *nn = o2net_nn_from_num(target_node); - struct o2net_status_wait nsw = { - .ns_node_item = LIST_HEAD_INIT(nsw.ns_node_item), - }; - struct o2net_send_tracking nst; - -#ifdef CONFIG_RAMSTER - /* this may be a general bug fix */ - init_waitqueue_head(&nsw.ns_wq); -#endif - - o2net_init_nst(&nst, msg_type, key, current, target_node); - - if (o2net_wq == NULL) { - mlog(0, "attempt to tx without o2netd running\n"); - ret = -ESRCH; - goto out; - } - - if (caller_veclen == 0) { - mlog(0, "bad kvec array length\n"); - ret = -EINVAL; - goto out; - } - - caller_bytes = iov_length((struct iovec *)caller_vec, caller_veclen); - if (caller_bytes > O2NET_MAX_PAYLOAD_BYTES) { - mlog(0, "total payload len %zu too large\n", caller_bytes); - ret = -EINVAL; - goto out; - } - - if (target_node == o2nm_this_node()) { - ret = -ELOOP; - goto out; - } - - o2net_debug_add_nst(&nst); - - o2net_set_nst_sock_time(&nst); - - wait_event(nn->nn_sc_wq, o2net_tx_can_proceed(nn, &sc, &ret)); - if (ret) - goto out; - - o2net_set_nst_sock_container(&nst, sc); - - veclen = caller_veclen + 1; - vec = kmalloc(sizeof(struct kvec) * veclen, GFP_ATOMIC); - if (vec == NULL) { - mlog(0, "failed to %zu element kvec!\n", veclen); - ret = -ENOMEM; - goto out; - } - - msg = kmalloc(sizeof(struct o2net_msg), GFP_ATOMIC); - if (!msg) { - mlog(0, "failed to allocate a o2net_msg!\n"); - ret = -ENOMEM; - goto out; - } - - o2net_init_msg(msg, caller_bytes, msg_type, key); - - vec[0].iov_len = sizeof(struct o2net_msg); - vec[0].iov_base = msg; - memcpy(&vec[1], caller_vec, caller_veclen * sizeof(struct kvec)); - - ret = o2net_prep_nsw(nn, &nsw); - if (ret) - goto out; - - msg->msg_num = cpu_to_be32(nsw.ns_id); - o2net_set_nst_msg_id(&nst, nsw.ns_id); - - o2net_set_nst_send_time(&nst); - - /* finally, convert the message header to network byte-order - * and send */ - mutex_lock(&sc->sc_send_lock); - ret = o2net_send_tcp_msg(sc->sc_sock, vec, veclen, - sizeof(struct o2net_msg) + caller_bytes); - mutex_unlock(&sc->sc_send_lock); - msglog(msg, "sending returned %d\n", ret); - if (ret < 0) { - mlog(0, "error returned from o2net_send_tcp_msg=%d\n", ret); - goto out; - } - - /* wait on other node's handler */ - o2net_set_nst_status_time(&nst); - wait_event(nsw.ns_wq, o2net_nsw_completed(nn, &nsw)); - - o2net_update_send_stats(&nst, sc); - - /* Note that we avoid overwriting the callers status return - * variable if a system error was reported on the other - * side. Callers beware. */ - ret = o2net_sys_err_to_errno(nsw.ns_sys_status); - if (status && !ret) - *status = nsw.ns_status; - - mlog(0, "woken, returning system status %d, user status %d\n", - ret, nsw.ns_status); -out: - o2net_debug_del_nst(&nst); /* must be before dropping sc and node */ - if (sc) - sc_put(sc); - if (vec) - kfree(vec); - if (msg) - kfree(msg); - o2net_complete_nsw(nn, &nsw, 0, 0, 0); - return ret; -} -EXPORT_SYMBOL_GPL(o2net_send_message_vec); - -int o2net_send_message(u32 msg_type, u32 key, void *data, u32 len, - u8 target_node, int *status) -{ - struct kvec vec = { - .iov_base = data, - .iov_len = len, - }; - return o2net_send_message_vec(msg_type, key, &vec, 1, - target_node, status); -} -EXPORT_SYMBOL_GPL(o2net_send_message); - -static int o2net_send_status_magic(struct socket *sock, struct o2net_msg *hdr, - enum o2net_system_error syserr, int err) -{ - struct kvec vec = { - .iov_base = hdr, - .iov_len = sizeof(struct o2net_msg), - }; - - BUG_ON(syserr >= O2NET_ERR_MAX); - - /* leave other fields intact from the incoming message, msg_num - * in particular */ - hdr->sys_status = cpu_to_be32(syserr); - hdr->status = cpu_to_be32(err); - hdr->magic = cpu_to_be16(O2NET_MSG_STATUS_MAGIC); // twiddle the magic - hdr->data_len = 0; - - msglog(hdr, "about to send status magic %d\n", err); - /* hdr has been in host byteorder this whole time */ - return o2net_send_tcp_msg(sock, &vec, 1, sizeof(struct o2net_msg)); -} - -#ifdef CONFIG_RAMSTER -/* - * "data magic" is a long version of "status magic" where the message - * payload actually contains data to be passed in reply to certain messages - */ -static int o2net_send_data_magic(struct o2net_sock_container *sc, - struct o2net_msg *hdr, - void *data, size_t data_len, - enum o2net_system_error syserr, int err) -{ - struct kvec vec[2]; - int ret; - - vec[0].iov_base = hdr; - vec[0].iov_len = sizeof(struct o2net_msg); - vec[1].iov_base = data; - vec[1].iov_len = data_len; - - BUG_ON(syserr >= O2NET_ERR_MAX); - - /* leave other fields intact from the incoming message, msg_num - * in particular */ - hdr->sys_status = cpu_to_be32(syserr); - hdr->status = cpu_to_be32(err); - hdr->magic = cpu_to_be16(O2NET_MSG_DATA_MAGIC); /* twiddle magic */ - hdr->data_len = cpu_to_be16(data_len); - - msglog(hdr, "about to send data magic %d\n", err); - /* hdr has been in host byteorder this whole time */ - ret = o2net_send_tcp_msg(sc->sc_sock, vec, 2, - sizeof(struct o2net_msg) + data_len); - return ret; -} - -/* - * called by a message handler to convert an otherwise normal reply - * message into a "data magic" message - */ -void o2net_force_data_magic(struct o2net_msg *hdr, u16 msgtype, u32 msgkey) -{ - hdr->magic = cpu_to_be16(O2NET_MSG_DATA_MAGIC); - hdr->msg_type = cpu_to_be16(msgtype); - hdr->key = cpu_to_be32(msgkey); -} -#endif - -/* this returns -errno if the header was unknown or too large, etc. - * after this is called the buffer us reused for the next message */ -static int o2net_process_message(struct o2net_sock_container *sc, - struct o2net_msg *hdr) -{ - struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num); - int ret = 0, handler_status; - enum o2net_system_error syserr; - struct o2net_msg_handler *nmh = NULL; - void *ret_data = NULL; -#ifdef CONFIG_RAMSTER - int data_magic = 0; -#endif - - msglog(hdr, "processing message\n"); - - o2net_sc_postpone_idle(sc); - - switch(be16_to_cpu(hdr->magic)) { - case O2NET_MSG_STATUS_MAGIC: - /* special type for returning message status */ - o2net_complete_nsw(nn, NULL, - be32_to_cpu(hdr->msg_num), - be32_to_cpu(hdr->sys_status), - be32_to_cpu(hdr->status)); - goto out; - case O2NET_MSG_KEEP_REQ_MAGIC: - o2net_sendpage(sc, o2net_keep_resp, - sizeof(*o2net_keep_resp)); - goto out; - case O2NET_MSG_KEEP_RESP_MAGIC: - goto out; - case O2NET_MSG_MAGIC: - break; -#ifdef CONFIG_RAMSTER - case O2NET_MSG_DATA_MAGIC: - /* - * unlike a normal status magic, a data magic DOES - * (MUST) have a handler, so the control flow is - * a little funky here as a result - */ - data_magic = 1; - break; -#endif - default: - msglog(hdr, "bad magic\n"); - ret = -EINVAL; - goto out; - break; - } - - /* find a handler for it */ - handler_status = 0; - nmh = o2net_handler_get(be16_to_cpu(hdr->msg_type), - be32_to_cpu(hdr->key)); - if (!nmh) { - mlog(ML_TCP, "couldn't find handler for type %u key %08x\n", - be16_to_cpu(hdr->msg_type), be32_to_cpu(hdr->key)); - syserr = O2NET_ERR_NO_HNDLR; - goto out_respond; - } - - syserr = O2NET_ERR_NONE; - - if (be16_to_cpu(hdr->data_len) > nmh->nh_max_len) - syserr = O2NET_ERR_OVERFLOW; - - if (syserr != O2NET_ERR_NONE) - goto out_respond; - - o2net_set_func_start_time(sc); - sc->sc_msg_key = be32_to_cpu(hdr->key); - sc->sc_msg_type = be16_to_cpu(hdr->msg_type); - handler_status = (nmh->nh_func)(hdr, sizeof(struct o2net_msg) + - be16_to_cpu(hdr->data_len), - nmh->nh_func_data, &ret_data); -#ifdef CONFIG_RAMSTER - if (data_magic) { - /* - * handler handled data sent in reply to request - * so complete the transaction - */ - o2net_complete_nsw(nn, NULL, be32_to_cpu(hdr->msg_num), - be32_to_cpu(hdr->sys_status), handler_status); - goto out; - } - /* - * handler changed magic to DATA_MAGIC to reply to request for data, - * implies ret_data points to data to return and handler_status - * is the number of bytes of data - */ - if (be16_to_cpu(hdr->magic) == O2NET_MSG_DATA_MAGIC) { - ret = o2net_send_data_magic(sc, hdr, - ret_data, handler_status, - syserr, 0); - hdr = NULL; - mlog(0, "sending data reply %d, syserr %d returned %d\n", - handler_status, syserr, ret); - o2net_set_func_stop_time(sc); - - o2net_update_recv_stats(sc); - goto out; - } -#endif - o2net_set_func_stop_time(sc); - - o2net_update_recv_stats(sc); - -out_respond: - /* this destroys the hdr, so don't use it after this */ - mutex_lock(&sc->sc_send_lock); - ret = o2net_send_status_magic(sc->sc_sock, hdr, syserr, - handler_status); - mutex_unlock(&sc->sc_send_lock); - hdr = NULL; - mlog(0, "sending handler status %d, syserr %d returned %d\n", - handler_status, syserr, ret); - - if (nmh) { - BUG_ON(ret_data != NULL && nmh->nh_post_func == NULL); - if (nmh->nh_post_func) - (nmh->nh_post_func)(handler_status, nmh->nh_func_data, - ret_data); - } - -out: - if (nmh) - o2net_handler_put(nmh); - return ret; -} - -static int o2net_check_handshake(struct o2net_sock_container *sc) -{ - struct o2net_handshake *hand = page_address(sc->sc_page); - struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num); - - if (hand->protocol_version != cpu_to_be64(O2NET_PROTOCOL_VERSION)) { - printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " Advertised net " - "protocol version %llu but %llu is required. " - "Disconnecting.\n", SC_NODEF_ARGS(sc), - (unsigned long long)be64_to_cpu(hand->protocol_version), - O2NET_PROTOCOL_VERSION); - - /* don't bother reconnecting if its the wrong version. */ - o2net_ensure_shutdown(nn, sc, -ENOTCONN); - return -1; - } - - /* - * Ensure timeouts are consistent with other nodes, otherwise - * we can end up with one node thinking that the other must be down, - * but isn't. This can ultimately cause corruption. - */ - if (be32_to_cpu(hand->o2net_idle_timeout_ms) != - o2net_idle_timeout()) { - printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " uses a network " - "idle timeout of %u ms, but we use %u ms locally. " - "Disconnecting.\n", SC_NODEF_ARGS(sc), - be32_to_cpu(hand->o2net_idle_timeout_ms), - o2net_idle_timeout()); - o2net_ensure_shutdown(nn, sc, -ENOTCONN); - return -1; - } - - if (be32_to_cpu(hand->o2net_keepalive_delay_ms) != - o2net_keepalive_delay()) { - printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " uses a keepalive " - "delay of %u ms, but we use %u ms locally. " - "Disconnecting.\n", SC_NODEF_ARGS(sc), - be32_to_cpu(hand->o2net_keepalive_delay_ms), - o2net_keepalive_delay()); - o2net_ensure_shutdown(nn, sc, -ENOTCONN); - return -1; - } - - if (be32_to_cpu(hand->o2hb_heartbeat_timeout_ms) != - O2HB_MAX_WRITE_TIMEOUT_MS) { - printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " uses a heartbeat " - "timeout of %u ms, but we use %u ms locally. " - "Disconnecting.\n", SC_NODEF_ARGS(sc), - be32_to_cpu(hand->o2hb_heartbeat_timeout_ms), - O2HB_MAX_WRITE_TIMEOUT_MS); - o2net_ensure_shutdown(nn, sc, -ENOTCONN); - return -1; - } - - sc->sc_handshake_ok = 1; - - spin_lock(&nn->nn_lock); - /* set valid and queue the idle timers only if it hasn't been - * shut down already */ - if (nn->nn_sc == sc) { - o2net_sc_reset_idle_timer(sc); - atomic_set(&nn->nn_timeout, 0); - o2net_set_nn_state(nn, sc, 1, 0); - } - spin_unlock(&nn->nn_lock); - - /* shift everything up as though it wasn't there */ - sc->sc_page_off -= sizeof(struct o2net_handshake); - if (sc->sc_page_off) - memmove(hand, hand + 1, sc->sc_page_off); - - return 0; -} - -/* this demuxes the queued rx bytes into header or payload bits and calls - * handlers as each full message is read off the socket. it returns -error, - * == 0 eof, or > 0 for progress made.*/ -static int o2net_advance_rx(struct o2net_sock_container *sc) -{ - struct o2net_msg *hdr; - int ret = 0; - void *data; - size_t datalen; - - sclog(sc, "receiving\n"); - o2net_set_advance_start_time(sc); - - if (unlikely(sc->sc_handshake_ok == 0)) { - if(sc->sc_page_off < sizeof(struct o2net_handshake)) { - data = page_address(sc->sc_page) + sc->sc_page_off; - datalen = sizeof(struct o2net_handshake) - sc->sc_page_off; - ret = o2net_recv_tcp_msg(sc->sc_sock, data, datalen); - if (ret > 0) - sc->sc_page_off += ret; - } - - if (sc->sc_page_off == sizeof(struct o2net_handshake)) { - o2net_check_handshake(sc); - if (unlikely(sc->sc_handshake_ok == 0)) - ret = -EPROTO; - } - goto out; - } - - /* do we need more header? */ - if (sc->sc_page_off < sizeof(struct o2net_msg)) { - data = page_address(sc->sc_page) + sc->sc_page_off; - datalen = sizeof(struct o2net_msg) - sc->sc_page_off; - ret = o2net_recv_tcp_msg(sc->sc_sock, data, datalen); - if (ret > 0) { - sc->sc_page_off += ret; - /* only swab incoming here.. we can - * only get here once as we cross from - * being under to over */ - if (sc->sc_page_off == sizeof(struct o2net_msg)) { - hdr = page_address(sc->sc_page); - if (be16_to_cpu(hdr->data_len) > - O2NET_MAX_PAYLOAD_BYTES) - ret = -EOVERFLOW; - } - } - if (ret <= 0) - goto out; - } - - if (sc->sc_page_off < sizeof(struct o2net_msg)) { - /* oof, still don't have a header */ - goto out; - } - - /* this was swabbed above when we first read it */ - hdr = page_address(sc->sc_page); - - msglog(hdr, "at page_off %zu\n", sc->sc_page_off); - - /* do we need more payload? */ - if (sc->sc_page_off - sizeof(struct o2net_msg) < be16_to_cpu(hdr->data_len)) { - /* need more payload */ - data = page_address(sc->sc_page) + sc->sc_page_off; - datalen = (sizeof(struct o2net_msg) + be16_to_cpu(hdr->data_len)) - - sc->sc_page_off; - ret = o2net_recv_tcp_msg(sc->sc_sock, data, datalen); - if (ret > 0) - sc->sc_page_off += ret; - if (ret <= 0) - goto out; - } - - if (sc->sc_page_off - sizeof(struct o2net_msg) == be16_to_cpu(hdr->data_len)) { - /* we can only get here once, the first time we read - * the payload.. so set ret to progress if the handler - * works out. after calling this the message is toast */ - ret = o2net_process_message(sc, hdr); - if (ret == 0) - ret = 1; - sc->sc_page_off = 0; - } - -out: - sclog(sc, "ret = %d\n", ret); - o2net_set_advance_stop_time(sc); - return ret; -} - -/* this work func is triggerd by data ready. it reads until it can read no - * more. it interprets 0, eof, as fatal. if data_ready hits while we're doing - * our work the work struct will be marked and we'll be called again. */ -static void o2net_rx_until_empty(struct work_struct *work) -{ - struct o2net_sock_container *sc = - container_of(work, struct o2net_sock_container, sc_rx_work); - int ret; - - do { - ret = o2net_advance_rx(sc); - } while (ret > 0); - - if (ret <= 0 && ret != -EAGAIN) { - struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num); - sclog(sc, "saw error %d, closing\n", ret); - /* not permanent so read failed handshake can retry */ - o2net_ensure_shutdown(nn, sc, 0); - } - - sc_put(sc); -} - -static int o2net_set_nodelay(struct socket *sock) -{ - int ret, val = 1; - mm_segment_t oldfs; - - oldfs = get_fs(); - set_fs(KERNEL_DS); - - /* - * Dear unsuspecting programmer, - * - * Don't use sock_setsockopt() for SOL_TCP. It doesn't check its level - * argument and assumes SOL_SOCKET so, say, your TCP_NODELAY will - * silently turn into SO_DEBUG. - * - * Yours, - * Keeper of hilariously fragile interfaces. - */ - ret = sock->ops->setsockopt(sock, SOL_TCP, TCP_NODELAY, - (char __user *)&val, sizeof(val)); - - set_fs(oldfs); - return ret; -} - -static void o2net_initialize_handshake(void) -{ - o2net_hand->o2hb_heartbeat_timeout_ms = cpu_to_be32( - O2HB_MAX_WRITE_TIMEOUT_MS); - o2net_hand->o2net_idle_timeout_ms = cpu_to_be32(o2net_idle_timeout()); - o2net_hand->o2net_keepalive_delay_ms = cpu_to_be32( - o2net_keepalive_delay()); - o2net_hand->o2net_reconnect_delay_ms = cpu_to_be32( - o2net_reconnect_delay()); -} - -/* ------------------------------------------------------------ */ - -/* called when a connect completes and after a sock is accepted. the - * rx path will see the response and mark the sc valid */ -static void o2net_sc_connect_completed(struct work_struct *work) -{ - struct o2net_sock_container *sc = - container_of(work, struct o2net_sock_container, - sc_connect_work); - - mlog(ML_MSG, "sc sending handshake with ver %llu id %llx\n", - (unsigned long long)O2NET_PROTOCOL_VERSION, - (unsigned long long)be64_to_cpu(o2net_hand->connector_id)); - - o2net_initialize_handshake(); - o2net_sendpage(sc, o2net_hand, sizeof(*o2net_hand)); - sc_put(sc); -} - -/* this is called as a work_struct func. */ -static void o2net_sc_send_keep_req(struct work_struct *work) -{ - struct o2net_sock_container *sc = - container_of(work, struct o2net_sock_container, - sc_keepalive_work.work); - - o2net_sendpage(sc, o2net_keep_req, sizeof(*o2net_keep_req)); - sc_put(sc); -} - -/* socket shutdown does a del_timer_sync against this as it tears down. - * we can't start this timer until we've got to the point in sc buildup - * where shutdown is going to be involved */ -static void o2net_idle_timer(unsigned long data) -{ - struct o2net_sock_container *sc = (struct o2net_sock_container *)data; -#ifndef CONFIG_RAMSTER - struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num); -#endif -#ifdef CONFIG_DEBUG_FS - unsigned long msecs = ktime_to_ms(ktime_get()) - - ktime_to_ms(sc->sc_tv_timer); -#else - unsigned long msecs = o2net_idle_timeout(); -#endif - - printk(KERN_NOTICE "o2net: Connection to " SC_NODEF_FMT " has been " - "idle for %lu.%lu secs, shutting it down.\n", SC_NODEF_ARGS(sc), - msecs / 1000, msecs % 1000); - - /* - * Initialize the nn_timeout so that the next connection attempt - * will continue in o2net_start_connect. - */ -#ifdef CONFIG_RAMSTER - /* Avoid spurious shutdowns... not sure if this is still necessary */ - pr_err("o2net_idle_timer, skipping shutdown work\n"); -#else - atomic_set(&nn->nn_timeout, 1); - - o2net_sc_queue_work(sc, &sc->sc_shutdown_work); -#endif -} - -static void o2net_sc_reset_idle_timer(struct o2net_sock_container *sc) -{ - o2net_sc_cancel_delayed_work(sc, &sc->sc_keepalive_work); - o2net_sc_queue_delayed_work(sc, &sc->sc_keepalive_work, - msecs_to_jiffies(o2net_keepalive_delay())); - o2net_set_sock_timer(sc); - mod_timer(&sc->sc_idle_timeout, - jiffies + msecs_to_jiffies(o2net_idle_timeout())); -} - -static void o2net_sc_postpone_idle(struct o2net_sock_container *sc) -{ - /* Only push out an existing timer */ - if (timer_pending(&sc->sc_idle_timeout)) - o2net_sc_reset_idle_timer(sc); -} - -/* this work func is kicked whenever a path sets the nn state which doesn't - * have valid set. This includes seeing hb come up, losing a connection, - * having a connect attempt fail, etc. This centralizes the logic which decides - * if a connect attempt should be made or if we should give up and all future - * transmit attempts should fail */ -static void o2net_start_connect(struct work_struct *work) -{ - struct o2net_node *nn = - container_of(work, struct o2net_node, nn_connect_work.work); - struct o2net_sock_container *sc = NULL; - struct o2nm_node *node = NULL, *mynode = NULL; - struct socket *sock = NULL; - struct sockaddr_in myaddr = {0, }, remoteaddr = {0, }; - int ret = 0, stop; - unsigned int timeout; - - /* if we're greater we initiate tx, otherwise we accept */ - if (o2nm_this_node() <= o2net_num_from_nn(nn)) - goto out; - - /* watch for racing with tearing a node down */ - node = o2nm_get_node_by_num(o2net_num_from_nn(nn)); - if (node == NULL) { - ret = 0; - goto out; - } - - mynode = o2nm_get_node_by_num(o2nm_this_node()); - if (mynode == NULL) { - ret = 0; - goto out; - } - - spin_lock(&nn->nn_lock); - /* - * see if we already have one pending or have given up. - * For nn_timeout, it is set when we close the connection - * because of the idle time out. So it means that we have - * at least connected to that node successfully once, - * now try to connect to it again. - */ - timeout = atomic_read(&nn->nn_timeout); - stop = (nn->nn_sc || - (nn->nn_persistent_error && - (nn->nn_persistent_error != -ENOTCONN || timeout == 0))); - spin_unlock(&nn->nn_lock); - if (stop) - goto out; - - nn->nn_last_connect_attempt = jiffies; - - sc = sc_alloc(node); - if (sc == NULL) { - mlog(0, "couldn't allocate sc\n"); - ret = -ENOMEM; - goto out; - } - - ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock); - if (ret < 0) { - mlog(0, "can't create socket: %d\n", ret); - goto out; - } - sc->sc_sock = sock; /* freed by sc_kref_release */ - - sock->sk->sk_allocation = GFP_ATOMIC; - - myaddr.sin_family = AF_INET; - myaddr.sin_addr.s_addr = mynode->nd_ipv4_address; - myaddr.sin_port = htons(0); /* any port */ - - ret = sock->ops->bind(sock, (struct sockaddr *)&myaddr, - sizeof(myaddr)); - if (ret) { - mlog(ML_ERROR, "bind failed with %d at address %pI4\n", - ret, &mynode->nd_ipv4_address); - goto out; - } - - ret = o2net_set_nodelay(sc->sc_sock); - if (ret) { - mlog(ML_ERROR, "setting TCP_NODELAY failed with %d\n", ret); - goto out; - } - - o2net_register_callbacks(sc->sc_sock->sk, sc); - - spin_lock(&nn->nn_lock); - /* handshake completion will set nn->nn_sc_valid */ - o2net_set_nn_state(nn, sc, 0, 0); - spin_unlock(&nn->nn_lock); - - remoteaddr.sin_family = AF_INET; - remoteaddr.sin_addr.s_addr = node->nd_ipv4_address; - remoteaddr.sin_port = node->nd_ipv4_port; - - ret = sc->sc_sock->ops->connect(sc->sc_sock, - (struct sockaddr *)&remoteaddr, - sizeof(remoteaddr), - O_NONBLOCK); - if (ret == -EINPROGRESS) - ret = 0; - -out: - if (ret) { - printk(KERN_NOTICE "o2net: Connect attempt to " SC_NODEF_FMT - " failed with errno %d\n", SC_NODEF_ARGS(sc), ret); - /* 0 err so that another will be queued and attempted - * from set_nn_state */ - if (sc) - o2net_ensure_shutdown(nn, sc, 0); - } - if (sc) - sc_put(sc); - if (node) - o2nm_node_put(node); - if (mynode) - o2nm_node_put(mynode); - - return; -} - -static void o2net_connect_expired(struct work_struct *work) -{ - struct o2net_node *nn = - container_of(work, struct o2net_node, nn_connect_expired.work); - - spin_lock(&nn->nn_lock); - if (!nn->nn_sc_valid) { - printk(KERN_NOTICE "o2net: No connection established with " - "node %u after %u.%u seconds, giving up.\n", - o2net_num_from_nn(nn), - o2net_idle_timeout() / 1000, - o2net_idle_timeout() % 1000); - - o2net_set_nn_state(nn, NULL, 0, -ENOTCONN); - } - spin_unlock(&nn->nn_lock); -} - -static void o2net_still_up(struct work_struct *work) -{ - struct o2net_node *nn = - container_of(work, struct o2net_node, nn_still_up.work); - - o2quo_hb_still_up(o2net_num_from_nn(nn)); -} - -/* ------------------------------------------------------------ */ - -void o2net_disconnect_node(struct o2nm_node *node) -{ - struct o2net_node *nn = o2net_nn_from_num(node->nd_num); - - /* don't reconnect until it's heartbeating again */ - spin_lock(&nn->nn_lock); - atomic_set(&nn->nn_timeout, 0); - o2net_set_nn_state(nn, NULL, 0, -ENOTCONN); - spin_unlock(&nn->nn_lock); - - if (o2net_wq) { - cancel_delayed_work(&nn->nn_connect_expired); - cancel_delayed_work(&nn->nn_connect_work); - cancel_delayed_work(&nn->nn_still_up); - flush_workqueue(o2net_wq); - } -} - -static void o2net_hb_node_down_cb(struct o2nm_node *node, int node_num, - void *data) -{ - o2quo_hb_down(node_num); - - if (!node) - return; - - if (node_num != o2nm_this_node()) - o2net_disconnect_node(node); - - BUG_ON(atomic_read(&o2net_connected_peers) < 0); -} - -static void o2net_hb_node_up_cb(struct o2nm_node *node, int node_num, - void *data) -{ - struct o2net_node *nn = o2net_nn_from_num(node_num); - - o2quo_hb_up(node_num); - - BUG_ON(!node); - - /* ensure an immediate connect attempt */ - nn->nn_last_connect_attempt = jiffies - - (msecs_to_jiffies(o2net_reconnect_delay()) + 1); - - if (node_num != o2nm_this_node()) { - /* believe it or not, accept and node hearbeating testing - * can succeed for this node before we got here.. so - * only use set_nn_state to clear the persistent error - * if that hasn't already happened */ - spin_lock(&nn->nn_lock); - atomic_set(&nn->nn_timeout, 0); - if (nn->nn_persistent_error) - o2net_set_nn_state(nn, NULL, 0, 0); - spin_unlock(&nn->nn_lock); - } -} - -void o2net_unregister_hb_callbacks(void) -{ - o2hb_unregister_callback(NULL, &o2net_hb_up); - o2hb_unregister_callback(NULL, &o2net_hb_down); -} - -int o2net_register_hb_callbacks(void) -{ - int ret; - - o2hb_setup_callback(&o2net_hb_down, O2HB_NODE_DOWN_CB, - o2net_hb_node_down_cb, NULL, O2NET_HB_PRI); - o2hb_setup_callback(&o2net_hb_up, O2HB_NODE_UP_CB, - o2net_hb_node_up_cb, NULL, O2NET_HB_PRI); - - ret = o2hb_register_callback(NULL, &o2net_hb_up); - if (ret == 0) - ret = o2hb_register_callback(NULL, &o2net_hb_down); - - if (ret) - o2net_unregister_hb_callbacks(); - - return ret; -} - -/* ------------------------------------------------------------ */ - -static int o2net_accept_one(struct socket *sock) -{ - int ret, slen; - struct sockaddr_in sin; - struct socket *new_sock = NULL; - struct o2nm_node *node = NULL; - struct o2nm_node *local_node = NULL; - struct o2net_sock_container *sc = NULL; - struct o2net_node *nn; - - BUG_ON(sock == NULL); - ret = sock_create_lite(sock->sk->sk_family, sock->sk->sk_type, - sock->sk->sk_protocol, &new_sock); - if (ret) - goto out; - - new_sock->type = sock->type; - new_sock->ops = sock->ops; - ret = sock->ops->accept(sock, new_sock, O_NONBLOCK); - if (ret < 0) - goto out; - - new_sock->sk->sk_allocation = GFP_ATOMIC; - - ret = o2net_set_nodelay(new_sock); - if (ret) { - mlog(ML_ERROR, "setting TCP_NODELAY failed with %d\n", ret); - goto out; - } - - slen = sizeof(sin); - ret = new_sock->ops->getname(new_sock, (struct sockaddr *) &sin, - &slen, 1); - if (ret < 0) - goto out; - - node = o2nm_get_node_by_ip(sin.sin_addr.s_addr); - if (node == NULL) { - printk(KERN_NOTICE "o2net: Attempt to connect from unknown " - "node at %pI4:%d\n", &sin.sin_addr.s_addr, - ntohs(sin.sin_port)); - ret = -EINVAL; - goto out; - } - - if (o2nm_this_node() >= node->nd_num) { - local_node = o2nm_get_node_by_num(o2nm_this_node()); - printk(KERN_NOTICE "o2net: Unexpected connect attempt seen " - "at node '%s' (%u, %pI4:%d) from node '%s' (%u, " - "%pI4:%d)\n", local_node->nd_name, local_node->nd_num, - &(local_node->nd_ipv4_address), - ntohs(local_node->nd_ipv4_port), node->nd_name, - node->nd_num, &sin.sin_addr.s_addr, ntohs(sin.sin_port)); - ret = -EINVAL; - goto out; - } - - /* this happens all the time when the other node sees our heartbeat - * and tries to connect before we see their heartbeat */ - if (!o2hb_check_node_heartbeating_from_callback(node->nd_num)) { - mlog(ML_CONN, "attempt to connect from node '%s' at " - "%pI4:%d but it isn't heartbeating\n", - node->nd_name, &sin.sin_addr.s_addr, - ntohs(sin.sin_port)); - ret = -EINVAL; - goto out; - } - - nn = o2net_nn_from_num(node->nd_num); - - spin_lock(&nn->nn_lock); - if (nn->nn_sc) - ret = -EBUSY; - else - ret = 0; - spin_unlock(&nn->nn_lock); - if (ret) { - printk(KERN_NOTICE "o2net: Attempt to connect from node '%s' " - "at %pI4:%d but it already has an open connection\n", - node->nd_name, &sin.sin_addr.s_addr, - ntohs(sin.sin_port)); - goto out; - } - - sc = sc_alloc(node); - if (sc == NULL) { - ret = -ENOMEM; - goto out; - } - - sc->sc_sock = new_sock; - new_sock = NULL; - - spin_lock(&nn->nn_lock); - atomic_set(&nn->nn_timeout, 0); - o2net_set_nn_state(nn, sc, 0, 0); - spin_unlock(&nn->nn_lock); - - o2net_register_callbacks(sc->sc_sock->sk, sc); - o2net_sc_queue_work(sc, &sc->sc_rx_work); - - o2net_initialize_handshake(); - o2net_sendpage(sc, o2net_hand, sizeof(*o2net_hand)); - -out: - if (new_sock) - sock_release(new_sock); - if (node) - o2nm_node_put(node); - if (local_node) - o2nm_node_put(local_node); - if (sc) - sc_put(sc); - return ret; -} - -static void o2net_accept_many(struct work_struct *work) -{ - struct socket *sock = o2net_listen_sock; - while (o2net_accept_one(sock) == 0) - cond_resched(); -} - -static void o2net_listen_data_ready(struct sock *sk, int bytes) -{ - void (*ready)(struct sock *sk, int bytes); - - read_lock(&sk->sk_callback_lock); - ready = sk->sk_user_data; - if (ready == NULL) { /* check for teardown race */ - ready = sk->sk_data_ready; - goto out; - } - - /* ->sk_data_ready is also called for a newly established child socket - * before it has been accepted and the acceptor has set up their - * data_ready.. we only want to queue listen work for our listening - * socket */ - if (sk->sk_state == TCP_LISTEN) { - mlog(ML_TCP, "bytes: %d\n", bytes); - queue_work(o2net_wq, &o2net_listen_work); - } - -out: - read_unlock(&sk->sk_callback_lock); - ready(sk, bytes); -} - -static int o2net_open_listening_sock(__be32 addr, __be16 port) -{ - struct socket *sock = NULL; - int ret; - struct sockaddr_in sin = { - .sin_family = PF_INET, - .sin_addr = { .s_addr = addr }, - .sin_port = port, - }; - - ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock); - if (ret < 0) { - printk(KERN_ERR "o2net: Error %d while creating socket\n", ret); - goto out; - } - - sock->sk->sk_allocation = GFP_ATOMIC; - - write_lock_bh(&sock->sk->sk_callback_lock); - sock->sk->sk_user_data = sock->sk->sk_data_ready; - sock->sk->sk_data_ready = o2net_listen_data_ready; - write_unlock_bh(&sock->sk->sk_callback_lock); - - o2net_listen_sock = sock; - INIT_WORK(&o2net_listen_work, o2net_accept_many); - - sock->sk->sk_reuse = 1; - ret = sock->ops->bind(sock, (struct sockaddr *)&sin, sizeof(sin)); - if (ret < 0) { - printk(KERN_ERR "o2net: Error %d while binding socket at " - "%pI4:%u\n", ret, &addr, ntohs(port)); - goto out; - } - - ret = sock->ops->listen(sock, 64); - if (ret < 0) - printk(KERN_ERR "o2net: Error %d while listening on %pI4:%u\n", - ret, &addr, ntohs(port)); - -out: - if (ret) { - o2net_listen_sock = NULL; - if (sock) - sock_release(sock); - } - return ret; -} - -/* - * called from node manager when we should bring up our network listening - * socket. node manager handles all the serialization to only call this - * once and to match it with o2net_stop_listening(). note, - * o2nm_this_node() doesn't work yet as we're being called while it - * is being set up. - */ -int o2net_start_listening(struct o2nm_node *node) -{ - int ret = 0; - - BUG_ON(o2net_wq != NULL); - BUG_ON(o2net_listen_sock != NULL); - - mlog(ML_KTHREAD, "starting o2net thread...\n"); - o2net_wq = create_singlethread_workqueue("o2net"); - if (o2net_wq == NULL) { - mlog(ML_ERROR, "unable to launch o2net thread\n"); - return -ENOMEM; /* ? */ - } - - ret = o2net_open_listening_sock(node->nd_ipv4_address, - node->nd_ipv4_port); - if (ret) { - destroy_workqueue(o2net_wq); - o2net_wq = NULL; - } else - o2quo_conn_up(node->nd_num); - - return ret; -} - -/* again, o2nm_this_node() doesn't work here as we're involved in - * tearing it down */ -void o2net_stop_listening(struct o2nm_node *node) -{ - struct socket *sock = o2net_listen_sock; - size_t i; - - BUG_ON(o2net_wq == NULL); - BUG_ON(o2net_listen_sock == NULL); - - /* stop the listening socket from generating work */ - write_lock_bh(&sock->sk->sk_callback_lock); - sock->sk->sk_data_ready = sock->sk->sk_user_data; - sock->sk->sk_user_data = NULL; - write_unlock_bh(&sock->sk->sk_callback_lock); - - for (i = 0; i < ARRAY_SIZE(o2net_nodes); i++) { - struct o2nm_node *node = o2nm_get_node_by_num(i); - if (node) { - o2net_disconnect_node(node); - o2nm_node_put(node); - } - } - - /* finish all work and tear down the work queue */ - mlog(ML_KTHREAD, "waiting for o2net thread to exit....\n"); - destroy_workqueue(o2net_wq); - o2net_wq = NULL; - - sock_release(o2net_listen_sock); - o2net_listen_sock = NULL; - - o2quo_conn_err(node->nd_num); -} - -#ifdef CONFIG_RAMSTER -void o2net_hb_node_up_manual(int node_num) -{ - struct o2nm_node dummy; - o2hb_manual_set_node_heartbeating(node_num); - o2net_hb_node_up_cb(&dummy, node_num, NULL); -} -#endif - -/* ------------------------------------------------------------ */ - -int o2net_init(void) -{ - unsigned long i; - - o2quo_init(); - - if (o2net_debugfs_init()) - return -ENOMEM; - - o2net_hand = kzalloc(sizeof(struct o2net_handshake), GFP_KERNEL); - o2net_keep_req = kzalloc(sizeof(struct o2net_msg), GFP_KERNEL); - o2net_keep_resp = kzalloc(sizeof(struct o2net_msg), GFP_KERNEL); - if (!o2net_hand || !o2net_keep_req || !o2net_keep_resp) { - kfree(o2net_hand); - kfree(o2net_keep_req); - kfree(o2net_keep_resp); - return -ENOMEM; - } - - o2net_hand->protocol_version = cpu_to_be64(O2NET_PROTOCOL_VERSION); - o2net_hand->connector_id = cpu_to_be64(1); - - o2net_keep_req->magic = cpu_to_be16(O2NET_MSG_KEEP_REQ_MAGIC); - o2net_keep_resp->magic = cpu_to_be16(O2NET_MSG_KEEP_RESP_MAGIC); - - for (i = 0; i < ARRAY_SIZE(o2net_nodes); i++) { - struct o2net_node *nn = o2net_nn_from_num(i); - - atomic_set(&nn->nn_timeout, 0); - spin_lock_init(&nn->nn_lock); - INIT_DELAYED_WORK(&nn->nn_connect_work, o2net_start_connect); - INIT_DELAYED_WORK(&nn->nn_connect_expired, - o2net_connect_expired); - INIT_DELAYED_WORK(&nn->nn_still_up, o2net_still_up); - /* until we see hb from a node we'll return einval */ - nn->nn_persistent_error = -ENOTCONN; - init_waitqueue_head(&nn->nn_sc_wq); - idr_init(&nn->nn_status_idr); - INIT_LIST_HEAD(&nn->nn_status_list); - } - - return 0; -} - -void o2net_exit(void) -{ - o2quo_exit(); - kfree(o2net_hand); - kfree(o2net_keep_req); - kfree(o2net_keep_resp); - o2net_debugfs_exit(); -} diff --git a/drivers/staging/ramster/cluster/tcp.h b/drivers/staging/ramster/cluster/tcp.h deleted file mode 100644 index 95a991f2f63..00000000000 --- a/drivers/staging/ramster/cluster/tcp.h +++ /dev/null @@ -1,160 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * tcp.h - * - * Function prototypes - * - * Copyright (C) 2004 Oracle. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - * - */ - -#ifndef O2CLUSTER_TCP_H -#define O2CLUSTER_TCP_H - -#include -#ifdef __KERNEL__ -#include -#include -#else -#include -#endif -#include -#include - -struct o2net_msg -{ - __be16 magic; - __be16 data_len; - __be16 msg_type; - __be16 pad1; - __be32 sys_status; - __be32 status; - __be32 key; - __be32 msg_num; - __u8 buf[0]; -}; - -typedef int (o2net_msg_handler_func)(struct o2net_msg *msg, u32 len, void *data, - void **ret_data); -typedef void (o2net_post_msg_handler_func)(int status, void *data, - void *ret_data); - -#define O2NET_MAX_PAYLOAD_BYTES (4096 - sizeof(struct o2net_msg)) - -/* same as hb delay, we're waiting for another node to recognize our hb */ -#define O2NET_RECONNECT_DELAY_MS_DEFAULT 2000 - -#define O2NET_KEEPALIVE_DELAY_MS_DEFAULT 2000 -#define O2NET_IDLE_TIMEOUT_MS_DEFAULT 30000 - - -/* TODO: figure this out.... */ -static inline int o2net_link_down(int err, struct socket *sock) -{ - if (sock) { - if (sock->sk->sk_state != TCP_ESTABLISHED && - sock->sk->sk_state != TCP_CLOSE_WAIT) - return 1; - } - - if (err >= 0) - return 0; - switch (err) { - /* ????????????????????????? */ - case -ERESTARTSYS: - case -EBADF: - /* When the server has died, an ICMP port unreachable - * message prompts ECONNREFUSED. */ - case -ECONNREFUSED: - case -ENOTCONN: - case -ECONNRESET: - case -EPIPE: - return 1; - } - return 0; -} - -enum { - O2NET_DRIVER_UNINITED, - O2NET_DRIVER_READY, -}; - -int o2net_send_message(u32 msg_type, u32 key, void *data, u32 len, - u8 target_node, int *status); -int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *vec, - size_t veclen, u8 target_node, int *status); - -int o2net_register_handler(u32 msg_type, u32 key, u32 max_len, - o2net_msg_handler_func *func, void *data, - o2net_post_msg_handler_func *post_func, - struct list_head *unreg_list); -void o2net_unregister_handler_list(struct list_head *list); - -void o2net_fill_node_map(unsigned long *map, unsigned bytes); - -#ifdef CONFIG_RAMSTER -void o2net_force_data_magic(struct o2net_msg *, u16, u32); -void o2net_hb_node_up_manual(int); -struct o2net_node *o2net_nn_from_num(u8); -#endif - -struct o2nm_node; -int o2net_register_hb_callbacks(void); -void o2net_unregister_hb_callbacks(void); -int o2net_start_listening(struct o2nm_node *node); -void o2net_stop_listening(struct o2nm_node *node); -void o2net_disconnect_node(struct o2nm_node *node); -int o2net_num_connected_peers(void); - -int o2net_init(void); -void o2net_exit(void); - -struct o2net_send_tracking; -struct o2net_sock_container; - -#ifdef CONFIG_DEBUG_FS -int o2net_debugfs_init(void); -void o2net_debugfs_exit(void); -void o2net_debug_add_nst(struct o2net_send_tracking *nst); -void o2net_debug_del_nst(struct o2net_send_tracking *nst); -void o2net_debug_add_sc(struct o2net_sock_container *sc); -void o2net_debug_del_sc(struct o2net_sock_container *sc); -#else -static inline int o2net_debugfs_init(void) -{ - return 0; -} -static inline void o2net_debugfs_exit(void) -{ -} -static inline void o2net_debug_add_nst(struct o2net_send_tracking *nst) -{ -} -static inline void o2net_debug_del_nst(struct o2net_send_tracking *nst) -{ -} -static inline void o2net_debug_add_sc(struct o2net_sock_container *sc) -{ -} -static inline void o2net_debug_del_sc(struct o2net_sock_container *sc) -{ -} -#endif /* CONFIG_DEBUG_FS */ - -#endif /* O2CLUSTER_TCP_H */ diff --git a/drivers/staging/ramster/cluster/tcp_internal.h b/drivers/staging/ramster/cluster/tcp_internal.h deleted file mode 100644 index ce171350c31..00000000000 --- a/drivers/staging/ramster/cluster/tcp_internal.h +++ /dev/null @@ -1,249 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * Copyright (C) 2005 Oracle. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - */ - -#ifndef O2CLUSTER_TCP_INTERNAL_H -#define O2CLUSTER_TCP_INTERNAL_H - -#define O2NET_MSG_MAGIC ((u16)0xfa55) -#define O2NET_MSG_STATUS_MAGIC ((u16)0xfa56) -#define O2NET_MSG_KEEP_REQ_MAGIC ((u16)0xfa57) -#define O2NET_MSG_KEEP_RESP_MAGIC ((u16)0xfa58) -#ifdef CONFIG_RAMSTER -/* - * "data magic" is a long version of "status magic" where the message - * payload actually contains data to be passed in reply to certain messages - */ -#define O2NET_MSG_DATA_MAGIC ((u16)0xfa59) -#endif - -/* we're delaying our quorum decision so that heartbeat will have timed - * out truly dead nodes by the time we come around to making decisions - * on their number */ -#define O2NET_QUORUM_DELAY_MS ((o2hb_dead_threshold + 2) * O2HB_REGION_TIMEOUT_MS) - -/* - * This version number represents quite a lot, unfortunately. It not - * only represents the raw network message protocol on the wire but also - * locking semantics of the file system using the protocol. It should - * be somewhere else, I'm sure, but right now it isn't. - * - * With version 11, we separate out the filesystem locking portion. The - * filesystem now has a major.minor version it negotiates. Version 11 - * introduces this negotiation to the o2dlm protocol, and as such the - * version here in tcp_internal.h should not need to be bumped for - * filesystem locking changes. - * - * New in version 11 - * - Negotiation of filesystem locking in the dlm join. - * - * New in version 10: - * - Meta/data locks combined - * - * New in version 9: - * - All votes removed - * - * New in version 8: - * - Replace delete inode votes with a cluster lock - * - * New in version 7: - * - DLM join domain includes the live nodemap - * - * New in version 6: - * - DLM lockres remote refcount fixes. - * - * New in version 5: - * - Network timeout checking protocol - * - * New in version 4: - * - Remove i_generation from lock names for better stat performance. - * - * New in version 3: - * - Replace dentry votes with a cluster lock - * - * New in version 2: - * - full 64 bit i_size in the metadata lock lvbs - * - introduction of "rw" lock and pushing meta/data locking down - */ -#define O2NET_PROTOCOL_VERSION 11ULL -struct o2net_handshake { - __be64 protocol_version; - __be64 connector_id; - __be32 o2hb_heartbeat_timeout_ms; - __be32 o2net_idle_timeout_ms; - __be32 o2net_keepalive_delay_ms; - __be32 o2net_reconnect_delay_ms; -}; - -struct o2net_node { - /* this is never called from int/bh */ - spinlock_t nn_lock; - - /* set the moment an sc is allocated and a connect is started */ - struct o2net_sock_container *nn_sc; - /* _valid is only set after the handshake passes and tx can happen */ - unsigned nn_sc_valid:1; - /* if this is set tx just returns it */ - int nn_persistent_error; - /* It is only set to 1 after the idle time out. */ - atomic_t nn_timeout; - - /* threads waiting for an sc to arrive wait on the wq for generation - * to increase. it is increased when a connecting socket succeeds - * or fails or when an accepted socket is attached. */ - wait_queue_head_t nn_sc_wq; - - struct idr nn_status_idr; - struct list_head nn_status_list; - - /* connects are attempted from when heartbeat comes up until either hb - * goes down, the node is unconfigured, no connect attempts succeed - * before O2NET_CONN_IDLE_DELAY, or a connect succeeds. connect_work - * is queued from set_nn_state both from hb up and from itself if a - * connect attempt fails and so can be self-arming. shutdown is - * careful to first mark the nn such that no connects will be attempted - * before canceling delayed connect work and flushing the queue. */ - struct delayed_work nn_connect_work; - unsigned long nn_last_connect_attempt; - - /* this is queued as nodes come up and is canceled when a connection is - * established. this expiring gives up on the node and errors out - * transmits */ - struct delayed_work nn_connect_expired; - - /* after we give up on a socket we wait a while before deciding - * that it is still heartbeating and that we should do some - * quorum work */ - struct delayed_work nn_still_up; -}; - -struct o2net_sock_container { - struct kref sc_kref; - /* the next two are valid for the life time of the sc */ - struct socket *sc_sock; - struct o2nm_node *sc_node; - - /* all of these sc work structs hold refs on the sc while they are - * queued. they should not be able to ref a freed sc. the teardown - * race is with o2net_wq destruction in o2net_stop_listening() */ - - /* rx and connect work are generated from socket callbacks. sc - * shutdown removes the callbacks and then flushes the work queue */ - struct work_struct sc_rx_work; - struct work_struct sc_connect_work; - /* shutdown work is triggered in two ways. the simple way is - * for a code path calls ensure_shutdown which gets a lock, removes - * the sc from the nn, and queues the work. in this case the - * work is single-shot. the work is also queued from a sock - * callback, though, and in this case the work will find the sc - * still on the nn and will call ensure_shutdown itself.. this - * ends up triggering the shutdown work again, though nothing - * will be done in that second iteration. so work queue teardown - * has to be careful to remove the sc from the nn before waiting - * on the work queue so that the shutdown work doesn't remove the - * sc and rearm itself. - */ - struct work_struct sc_shutdown_work; - - struct timer_list sc_idle_timeout; - struct delayed_work sc_keepalive_work; - - unsigned sc_handshake_ok:1; - - struct page *sc_page; - size_t sc_page_off; - - /* original handlers for the sockets */ - void (*sc_state_change)(struct sock *sk); - void (*sc_data_ready)(struct sock *sk, int bytes); - - u32 sc_msg_key; - u16 sc_msg_type; - -#ifdef CONFIG_DEBUG_FS - struct list_head sc_net_debug_item; - ktime_t sc_tv_timer; - ktime_t sc_tv_data_ready; - ktime_t sc_tv_advance_start; - ktime_t sc_tv_advance_stop; - ktime_t sc_tv_func_start; - ktime_t sc_tv_func_stop; -#endif -#ifdef CONFIG_OCFS2_FS_STATS - ktime_t sc_tv_acquiry_total; - ktime_t sc_tv_send_total; - ktime_t sc_tv_status_total; - u32 sc_send_count; - u32 sc_recv_count; - ktime_t sc_tv_process_total; -#endif - struct mutex sc_send_lock; -}; - -struct o2net_msg_handler { - struct rb_node nh_node; - u32 nh_max_len; - u32 nh_msg_type; - u32 nh_key; - o2net_msg_handler_func *nh_func; - o2net_msg_handler_func *nh_func_data; - o2net_post_msg_handler_func - *nh_post_func; - struct kref nh_kref; - struct list_head nh_unregister_item; -}; - -enum o2net_system_error { - O2NET_ERR_NONE = 0, - O2NET_ERR_NO_HNDLR, - O2NET_ERR_OVERFLOW, - O2NET_ERR_DIED, - O2NET_ERR_MAX -}; - -struct o2net_status_wait { - enum o2net_system_error ns_sys_status; - s32 ns_status; - int ns_id; - wait_queue_head_t ns_wq; - struct list_head ns_node_item; -}; - -#ifdef CONFIG_DEBUG_FS -/* just for state dumps */ -struct o2net_send_tracking { - struct list_head st_net_debug_item; - struct task_struct *st_task; - struct o2net_sock_container *st_sc; - u32 st_id; - u32 st_msg_type; - u32 st_msg_key; - u8 st_node; - ktime_t st_sock_time; - ktime_t st_send_time; - ktime_t st_status_time; -}; -#else -struct o2net_send_tracking { - u32 dummy; -}; -#endif /* CONFIG_DEBUG_FS */ - -#endif /* O2CLUSTER_TCP_INTERNAL_H */ diff --git a/drivers/staging/ramster/cluster/ver.c b/drivers/staging/ramster/cluster/ver.c deleted file mode 100644 index a56eee6abad..00000000000 --- a/drivers/staging/ramster/cluster/ver.c +++ /dev/null @@ -1,42 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * ver.c - * - * version string - * - * Copyright (C) 2002, 2005 Oracle. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - */ - -#include -#include - -#include "ver.h" - -#define CLUSTER_BUILD_VERSION "1.5.0" - -#define VERSION_STR "OCFS2 Node Manager " CLUSTER_BUILD_VERSION - -void cluster_print_version(void) -{ - printk(KERN_INFO "%s\n", VERSION_STR); -} - -MODULE_DESCRIPTION(VERSION_STR); - -MODULE_VERSION(CLUSTER_BUILD_VERSION); diff --git a/drivers/staging/ramster/cluster/ver.h b/drivers/staging/ramster/cluster/ver.h deleted file mode 100644 index 32554c3382c..00000000000 --- a/drivers/staging/ramster/cluster/ver.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; -*- - * vim: noexpandtab sw=8 ts=8 sts=0: - * - * ver.h - * - * Function prototypes - * - * Copyright (C) 2005 Oracle. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - */ - -#ifndef O2CLUSTER_VER_H -#define O2CLUSTER_VER_H - -void cluster_print_version(void); - -#endif /* O2CLUSTER_VER_H */ diff --git a/drivers/staging/ramster/ramster.h b/drivers/staging/ramster/ramster.h deleted file mode 100644 index 329351253b3..00000000000 --- a/drivers/staging/ramster/ramster.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * ramster.h - * - * Peer-to-peer transcendent memory - * - * Copyright (c) 2009-2012, Dan Magenheimer, Oracle Corp. - */ - -#ifndef _RAMSTER_H_ -#define _RAMSTER_H_ - -/* - * format of remote pampd: - * bit 0 == intransit - * bit 1 == is_remote... if this bit is set, then - * bit 2-9 == remotenode - * bit 10-22 == size - * bit 23-30 == cksum - */ -#define FAKE_PAMPD_INTRANSIT_BITS 1 -#define FAKE_PAMPD_ISREMOTE_BITS 1 -#define FAKE_PAMPD_REMOTENODE_BITS 8 -#define FAKE_PAMPD_REMOTESIZE_BITS 13 -#define FAKE_PAMPD_CHECKSUM_BITS 8 - -#define FAKE_PAMPD_INTRANSIT_SHIFT 0 -#define FAKE_PAMPD_ISREMOTE_SHIFT (FAKE_PAMPD_INTRANSIT_SHIFT + \ - FAKE_PAMPD_INTRANSIT_BITS) -#define FAKE_PAMPD_REMOTENODE_SHIFT (FAKE_PAMPD_ISREMOTE_SHIFT + \ - FAKE_PAMPD_ISREMOTE_BITS) -#define FAKE_PAMPD_REMOTESIZE_SHIFT (FAKE_PAMPD_REMOTENODE_SHIFT + \ - FAKE_PAMPD_REMOTENODE_BITS) -#define FAKE_PAMPD_CHECKSUM_SHIFT (FAKE_PAMPD_REMOTESIZE_SHIFT + \ - FAKE_PAMPD_REMOTESIZE_BITS) - -#define FAKE_PAMPD_MASK(x) ((1UL << (x)) - 1) - -static inline void *pampd_make_remote(int remotenode, size_t size, - unsigned char cksum) -{ - unsigned long fake_pampd = 0; - fake_pampd |= 1UL << FAKE_PAMPD_ISREMOTE_SHIFT; - fake_pampd |= ((unsigned long)remotenode & - FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTENODE_BITS)) << - FAKE_PAMPD_REMOTENODE_SHIFT; - fake_pampd |= ((unsigned long)size & - FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTESIZE_BITS)) << - FAKE_PAMPD_REMOTESIZE_SHIFT; - fake_pampd |= ((unsigned long)cksum & - FAKE_PAMPD_MASK(FAKE_PAMPD_CHECKSUM_BITS)) << - FAKE_PAMPD_CHECKSUM_SHIFT; - return (void *)fake_pampd; -} - -static inline unsigned int pampd_remote_node(void *pampd) -{ - unsigned long fake_pampd = (unsigned long)pampd; - return (fake_pampd >> FAKE_PAMPD_REMOTENODE_SHIFT) & - FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTENODE_BITS); -} - -static inline unsigned int pampd_remote_size(void *pampd) -{ - unsigned long fake_pampd = (unsigned long)pampd; - return (fake_pampd >> FAKE_PAMPD_REMOTESIZE_SHIFT) & - FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTESIZE_BITS); -} - -static inline unsigned char pampd_remote_cksum(void *pampd) -{ - unsigned long fake_pampd = (unsigned long)pampd; - return (fake_pampd >> FAKE_PAMPD_CHECKSUM_SHIFT) & - FAKE_PAMPD_MASK(FAKE_PAMPD_CHECKSUM_BITS); -} - -static inline bool pampd_is_remote(void *pampd) -{ - unsigned long fake_pampd = (unsigned long)pampd; - return (fake_pampd >> FAKE_PAMPD_ISREMOTE_SHIFT) & - FAKE_PAMPD_MASK(FAKE_PAMPD_ISREMOTE_BITS); -} - -static inline bool pampd_is_intransit(void *pampd) -{ - unsigned long fake_pampd = (unsigned long)pampd; - return (fake_pampd >> FAKE_PAMPD_INTRANSIT_SHIFT) & - FAKE_PAMPD_MASK(FAKE_PAMPD_INTRANSIT_BITS); -} - -/* note that it is a BUG for intransit to be set without isremote also set */ -static inline void *pampd_mark_intransit(void *pampd) -{ - unsigned long fake_pampd = (unsigned long)pampd; - - fake_pampd |= 1UL << FAKE_PAMPD_ISREMOTE_SHIFT; - fake_pampd |= 1UL << FAKE_PAMPD_INTRANSIT_SHIFT; - return (void *)fake_pampd; -} - -static inline void *pampd_mask_intransit_and_remote(void *marked_pampd) -{ - unsigned long pampd = (unsigned long)marked_pampd; - - pampd &= ~(1UL << FAKE_PAMPD_INTRANSIT_SHIFT); - pampd &= ~(1UL << FAKE_PAMPD_ISREMOTE_SHIFT); - return (void *)pampd; -} - -extern int ramster_remote_async_get(struct tmem_xhandle *, - bool, int, size_t, uint8_t, void *extra); -extern int ramster_remote_put(struct tmem_xhandle *, char *, size_t, - bool, int *); -extern int ramster_remote_flush(struct tmem_xhandle *, int); -extern int ramster_remote_flush_object(struct tmem_xhandle *, int); -extern int ramster_o2net_register_handlers(void); - -#endif /* _TMEM_H */ diff --git a/drivers/staging/ramster/ramster_o2net.c b/drivers/staging/ramster/ramster_o2net.c deleted file mode 100644 index c5a47cc4540..00000000000 --- a/drivers/staging/ramster/ramster_o2net.c +++ /dev/null @@ -1,402 +0,0 @@ -/* - * ramster_o2net.c - * - * Copyright (c) 2011, Dan Magenheimer, Oracle Corp. - * - * Ramster_o2net provides an interface between zcache and o2net. - * - * FIXME: support more than two nodes - */ - -#include -#include "cluster/tcp.h" -#include "cluster/nodemanager.h" -#include "tmem.h" -#include "zcache.h" -#include "ramster.h" - -#define RAMSTER_TESTING - -#define RMSTR_KEY 0x77347734 - -enum { - RMSTR_TMEM_PUT_EPH = 100, - RMSTR_TMEM_PUT_PERS, - RMSTR_TMEM_ASYNC_GET_REQUEST, - RMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST, - RMSTR_TMEM_ASYNC_GET_REPLY, - RMSTR_TMEM_FLUSH, - RMSTR_TMEM_FLOBJ, - RMSTR_TMEM_DESTROY_POOL, -}; - -#define RMSTR_O2NET_MAX_LEN \ - (O2NET_MAX_PAYLOAD_BYTES - sizeof(struct tmem_xhandle)) - -#include "cluster/tcp_internal.h" - -static struct o2nm_node *ramster_choose_node(int *nodenum, - struct tmem_xhandle *xh) -{ - struct o2nm_node *node = NULL; - int i; - -/* FIXME reproducibly pick a node based on xh that is NOT this node */ - i = o2nm_this_node(); - i = !i; /* FIXME ONLY FOR TWO NODES */ - node = o2nm_get_node_by_num(i); - /* WARNING: THIS DOES NOT CHECK TO ENSURE CONNECTED */ - if (node != NULL) - *nodenum = i; - return node; -} - -static void ramster_put_node(struct o2nm_node *node) -{ - o2nm_node_put(node); -} - -/* FIXME following buffer should be per-cpu, protected by preempt_disable */ -static char ramster_async_get_buf[O2NET_MAX_PAYLOAD_BYTES]; - -static int ramster_remote_async_get_request_handler(struct o2net_msg *msg, - u32 len, void *data, void **ret_data) -{ - char *pdata; - struct tmem_xhandle xh; - int found; - size_t size = RMSTR_O2NET_MAX_LEN; - u16 msgtype = be16_to_cpu(msg->msg_type); - bool get_and_free = (msgtype == RMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST); - unsigned long flags; - - xh = *(struct tmem_xhandle *)msg->buf; - if (xh.xh_data_size > RMSTR_O2NET_MAX_LEN) - BUG(); - pdata = ramster_async_get_buf; - *(struct tmem_xhandle *)pdata = xh; - pdata += sizeof(struct tmem_xhandle); - local_irq_save(flags); - found = zcache_get(xh.client_id, xh.pool_id, &xh.oid, xh.index, - pdata, &size, 1, get_and_free ? 1 : -1); - local_irq_restore(flags); - if (found < 0) { - /* a zero size indicates the get failed */ - size = 0; - } - if (size > RMSTR_O2NET_MAX_LEN) - BUG(); - *ret_data = pdata - sizeof(struct tmem_xhandle); - /* now make caller (o2net_process_message) handle specially */ - o2net_force_data_magic(msg, RMSTR_TMEM_ASYNC_GET_REPLY, RMSTR_KEY); - return size + sizeof(struct tmem_xhandle); -} - -static int ramster_remote_async_get_reply_handler(struct o2net_msg *msg, - u32 len, void *data, void **ret_data) -{ - char *in = (char *)msg->buf; - int datalen = len - sizeof(struct o2net_msg); - int ret = -1; - struct tmem_xhandle *xh = (struct tmem_xhandle *)in; - - in += sizeof(struct tmem_xhandle); - datalen -= sizeof(struct tmem_xhandle); - BUG_ON(datalen < 0 || datalen > PAGE_SIZE); - ret = zcache_localify(xh->pool_id, &xh->oid, xh->index, - in, datalen, xh->extra); -#ifdef RAMSTER_TESTING - if (ret == -EEXIST) - pr_err("TESTING ArrgREP, aborted overwrite on racy put\n"); -#endif - return ret; -} - -int ramster_remote_put_handler(struct o2net_msg *msg, - u32 len, void *data, void **ret_data) -{ - struct tmem_xhandle *xh; - char *p = (char *)msg->buf; - int datalen = len - sizeof(struct o2net_msg) - - sizeof(struct tmem_xhandle); - u16 msgtype = be16_to_cpu(msg->msg_type); - bool ephemeral = (msgtype == RMSTR_TMEM_PUT_EPH); - unsigned long flags; - int ret; - - xh = (struct tmem_xhandle *)p; - p += sizeof(struct tmem_xhandle); - zcache_autocreate_pool(xh->client_id, xh->pool_id, ephemeral); - local_irq_save(flags); - ret = zcache_put(xh->client_id, xh->pool_id, &xh->oid, xh->index, - p, datalen, 1, ephemeral ? 1 : -1); - local_irq_restore(flags); - return ret; -} - -int ramster_remote_flush_handler(struct o2net_msg *msg, - u32 len, void *data, void **ret_data) -{ - struct tmem_xhandle *xh; - char *p = (char *)msg->buf; - - xh = (struct tmem_xhandle *)p; - p += sizeof(struct tmem_xhandle); - (void)zcache_flush(xh->client_id, xh->pool_id, &xh->oid, xh->index); - return 0; -} - -int ramster_remote_flobj_handler(struct o2net_msg *msg, - u32 len, void *data, void **ret_data) -{ - struct tmem_xhandle *xh; - char *p = (char *)msg->buf; - - xh = (struct tmem_xhandle *)p; - p += sizeof(struct tmem_xhandle); - (void)zcache_flush_object(xh->client_id, xh->pool_id, &xh->oid); - return 0; -} - -int ramster_remote_async_get(struct tmem_xhandle *xh, bool free, int remotenode, - size_t expect_size, uint8_t expect_cksum, - void *extra) -{ - int ret = -1, status; - struct o2nm_node *node = NULL; - struct kvec vec[1]; - size_t veclen = 1; - u32 msg_type; - - node = o2nm_get_node_by_num(remotenode); - if (node == NULL) - goto out; - xh->client_id = o2nm_this_node(); /* which node is getting */ - xh->xh_data_cksum = expect_cksum; - xh->xh_data_size = expect_size; - xh->extra = extra; - vec[0].iov_len = sizeof(*xh); - vec[0].iov_base = xh; - if (free) - msg_type = RMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST; - else - msg_type = RMSTR_TMEM_ASYNC_GET_REQUEST; - ret = o2net_send_message_vec(msg_type, RMSTR_KEY, - vec, veclen, remotenode, &status); - ramster_put_node(node); - if (ret < 0) { - /* FIXME handle bad message possibilities here? */ - pr_err("UNTESTED ret<0 in ramster_remote_async_get\n"); - } - ret = status; -out: - return ret; -} - -#ifdef RAMSTER_TESTING -/* leave me here to see if it catches a weird crash */ -static void ramster_check_irq_counts(void) -{ - static int last_hardirq_cnt, last_softirq_cnt, last_preempt_cnt; - int cur_hardirq_cnt, cur_softirq_cnt, cur_preempt_cnt; - - cur_hardirq_cnt = hardirq_count() >> HARDIRQ_SHIFT; - if (cur_hardirq_cnt > last_hardirq_cnt) { - last_hardirq_cnt = cur_hardirq_cnt; - if (!(last_hardirq_cnt&(last_hardirq_cnt-1))) - pr_err("RAMSTER TESTING RRP hardirq_count=%d\n", - last_hardirq_cnt); - } - cur_softirq_cnt = softirq_count() >> SOFTIRQ_SHIFT; - if (cur_softirq_cnt > last_softirq_cnt) { - last_softirq_cnt = cur_softirq_cnt; - if (!(last_softirq_cnt&(last_softirq_cnt-1))) - pr_err("RAMSTER TESTING RRP softirq_count=%d\n", - last_softirq_cnt); - } - cur_preempt_cnt = preempt_count() & PREEMPT_MASK; - if (cur_preempt_cnt > last_preempt_cnt) { - last_preempt_cnt = cur_preempt_cnt; - if (!(last_preempt_cnt&(last_preempt_cnt-1))) - pr_err("RAMSTER TESTING RRP preempt_count=%d\n", - last_preempt_cnt); - } -} -#endif - -int ramster_remote_put(struct tmem_xhandle *xh, char *data, size_t size, - bool ephemeral, int *remotenode) -{ - int nodenum, ret = -1, status; - struct o2nm_node *node = NULL; - struct kvec vec[2]; - size_t veclen = 2; - u32 msg_type; -#ifdef RAMSTER_TESTING - struct o2net_node *nn; -#endif - - BUG_ON(size > RMSTR_O2NET_MAX_LEN); - xh->client_id = o2nm_this_node(); /* which node is putting */ - vec[0].iov_len = sizeof(*xh); - vec[0].iov_base = xh; - vec[1].iov_len = size; - vec[1].iov_base = data; - node = ramster_choose_node(&nodenum, xh); - if (!node) - goto out; - -#ifdef RAMSTER_TESTING - nn = o2net_nn_from_num(nodenum); - WARN_ON_ONCE(nn->nn_persistent_error || !nn->nn_sc_valid); -#endif - - if (ephemeral) - msg_type = RMSTR_TMEM_PUT_EPH; - else - msg_type = RMSTR_TMEM_PUT_PERS; -#ifdef RAMSTER_TESTING - /* leave me here to see if it catches a weird crash */ - ramster_check_irq_counts(); -#endif - - ret = o2net_send_message_vec(msg_type, RMSTR_KEY, - vec, veclen, nodenum, &status); -#ifdef RAMSTER_TESTING - if (ret != 0) { - static unsigned long cnt; - cnt++; - if (!(cnt&(cnt-1))) - pr_err("ramster_remote_put: message failed, " - "ret=%d, cnt=%lu\n", ret, cnt); - ret = -1; - } -#endif - if (ret < 0) - ret = -1; - else { - ret = status; - *remotenode = nodenum; - } - - ramster_put_node(node); -out: - return ret; -} - -int ramster_remote_flush(struct tmem_xhandle *xh, int remotenode) -{ - int ret = -1, status; - struct o2nm_node *node = NULL; - struct kvec vec[1]; - size_t veclen = 1; - - node = o2nm_get_node_by_num(remotenode); - BUG_ON(node == NULL); - xh->client_id = o2nm_this_node(); /* which node is flushing */ - vec[0].iov_len = sizeof(*xh); - vec[0].iov_base = xh; - BUG_ON(irqs_disabled()); - BUG_ON(in_softirq()); - ret = o2net_send_message_vec(RMSTR_TMEM_FLUSH, RMSTR_KEY, - vec, veclen, remotenode, &status); - ramster_put_node(node); - return ret; -} - -int ramster_remote_flush_object(struct tmem_xhandle *xh, int remotenode) -{ - int ret = -1, status; - struct o2nm_node *node = NULL; - struct kvec vec[1]; - size_t veclen = 1; - - node = o2nm_get_node_by_num(remotenode); - BUG_ON(node == NULL); - xh->client_id = o2nm_this_node(); /* which node is flobjing */ - vec[0].iov_len = sizeof(*xh); - vec[0].iov_base = xh; - ret = o2net_send_message_vec(RMSTR_TMEM_FLOBJ, RMSTR_KEY, - vec, veclen, remotenode, &status); - ramster_put_node(node); - return ret; -} - -/* - * Handler registration - */ - -static LIST_HEAD(ramster_o2net_unreg_list); - -static void ramster_o2net_unregister_handlers(void) -{ - o2net_unregister_handler_list(&ramster_o2net_unreg_list); -} - -int ramster_o2net_register_handlers(void) -{ - int status; - - status = o2net_register_handler(RMSTR_TMEM_PUT_EPH, RMSTR_KEY, - RMSTR_O2NET_MAX_LEN, - ramster_remote_put_handler, - NULL, NULL, &ramster_o2net_unreg_list); - if (status) - goto bail; - - status = o2net_register_handler(RMSTR_TMEM_PUT_PERS, RMSTR_KEY, - RMSTR_O2NET_MAX_LEN, - ramster_remote_put_handler, - NULL, NULL, &ramster_o2net_unreg_list); - if (status) - goto bail; - - status = o2net_register_handler(RMSTR_TMEM_ASYNC_GET_REQUEST, RMSTR_KEY, - RMSTR_O2NET_MAX_LEN, - ramster_remote_async_get_request_handler, - NULL, NULL, - &ramster_o2net_unreg_list); - if (status) - goto bail; - - status = o2net_register_handler(RMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST, - RMSTR_KEY, RMSTR_O2NET_MAX_LEN, - ramster_remote_async_get_request_handler, - NULL, NULL, - &ramster_o2net_unreg_list); - if (status) - goto bail; - - status = o2net_register_handler(RMSTR_TMEM_ASYNC_GET_REPLY, RMSTR_KEY, - RMSTR_O2NET_MAX_LEN, - ramster_remote_async_get_reply_handler, - NULL, NULL, - &ramster_o2net_unreg_list); - if (status) - goto bail; - - status = o2net_register_handler(RMSTR_TMEM_FLUSH, RMSTR_KEY, - RMSTR_O2NET_MAX_LEN, - ramster_remote_flush_handler, - NULL, NULL, - &ramster_o2net_unreg_list); - if (status) - goto bail; - - status = o2net_register_handler(RMSTR_TMEM_FLOBJ, RMSTR_KEY, - RMSTR_O2NET_MAX_LEN, - ramster_remote_flobj_handler, - NULL, NULL, - &ramster_o2net_unreg_list); - if (status) - goto bail; - - pr_info("ramster_o2net: handlers registered\n"); - -bail: - if (status) { - ramster_o2net_unregister_handlers(); - pr_err("ramster_o2net: couldn't register handlers\n"); - } - return status; -} diff --git a/drivers/staging/ramster/tmem.c b/drivers/staging/ramster/tmem.c deleted file mode 100644 index 8f2f6892d8d..00000000000 --- a/drivers/staging/ramster/tmem.c +++ /dev/null @@ -1,851 +0,0 @@ -/* - * In-kernel transcendent memory (generic implementation) - * - * Copyright (c) 2009-2011, Dan Magenheimer, Oracle Corp. - * - * The primary purpose of Transcedent Memory ("tmem") is to map object-oriented - * "handles" (triples containing a pool id, and object id, and an index), to - * pages in a page-accessible memory (PAM). Tmem references the PAM pages via - * an abstract "pampd" (PAM page-descriptor), which can be operated on by a - * set of functions (pamops). Each pampd contains some representation of - * PAGE_SIZE bytes worth of data. Tmem must support potentially millions of - * pages and must be able to insert, find, and delete these pages at a - * potential frequency of thousands per second concurrently across many CPUs, - * (and, if used with KVM, across many vcpus across many guests). - * Tmem is tracked with a hierarchy of data structures, organized by - * the elements in a handle-tuple: pool_id, object_id, and page index. - * One or more "clients" (e.g. guests) each provide one or more tmem_pools. - * Each pool, contains a hash table of rb_trees of tmem_objs. Each - * tmem_obj contains a radix-tree-like tree of pointers, with intermediate - * nodes called tmem_objnodes. Each leaf pointer in this tree points to - * a pampd, which is accessible only through a small set of callbacks - * registered by the PAM implementation (see tmem_register_pamops). Tmem - * does all memory allocation via a set of callbacks registered by the tmem - * host implementation (e.g. see tmem_register_hostops). - */ - -#include -#include -#include -#include - -#include "tmem.h" - -/* data structure sentinels used for debugging... see tmem.h */ -#define POOL_SENTINEL 0x87658765 -#define OBJ_SENTINEL 0x12345678 -#define OBJNODE_SENTINEL 0xfedcba09 - -/* - * A tmem host implementation must use this function to register callbacks - * for memory allocation. - */ -static struct tmem_hostops tmem_hostops; - -static void tmem_objnode_tree_init(void); - -void tmem_register_hostops(struct tmem_hostops *m) -{ - tmem_objnode_tree_init(); - tmem_hostops = *m; -} - -/* - * A tmem host implementation must use this function to register - * callbacks for a page-accessible memory (PAM) implementation - */ -static struct tmem_pamops tmem_pamops; - -void tmem_register_pamops(struct tmem_pamops *m) -{ - tmem_pamops = *m; -} - -/* - * Oid's are potentially very sparse and tmem_objs may have an indeterminately - * short life, being added and deleted at a relatively high frequency. - * So an rb_tree is an ideal data structure to manage tmem_objs. But because - * of the potentially huge number of tmem_objs, each pool manages a hashtable - * of rb_trees to reduce search, insert, delete, and rebalancing time. - * Each hashbucket also has a lock to manage concurrent access. - * - * The following routines manage tmem_objs. When any tmem_obj is accessed, - * the hashbucket lock must be held. - */ - -/* searches for object==oid in pool, returns locked object if found */ -static struct tmem_obj *tmem_obj_find(struct tmem_hashbucket *hb, - struct tmem_oid *oidp) -{ - struct rb_node *rbnode; - struct tmem_obj *obj; - - rbnode = hb->obj_rb_root.rb_node; - while (rbnode) { - BUG_ON(RB_EMPTY_NODE(rbnode)); - obj = rb_entry(rbnode, struct tmem_obj, rb_tree_node); - switch (tmem_oid_compare(oidp, &obj->oid)) { - case 0: /* equal */ - goto out; - case -1: - rbnode = rbnode->rb_left; - break; - case 1: - rbnode = rbnode->rb_right; - break; - } - } - obj = NULL; -out: - return obj; -} - -static void tmem_pampd_destroy_all_in_obj(struct tmem_obj *); - -/* free an object that has no more pampds in it */ -static void tmem_obj_free(struct tmem_obj *obj, struct tmem_hashbucket *hb) -{ - struct tmem_pool *pool; - - BUG_ON(obj == NULL); - ASSERT_SENTINEL(obj, OBJ); - BUG_ON(obj->pampd_count > 0); - pool = obj->pool; - BUG_ON(pool == NULL); - if (obj->objnode_tree_root != NULL) /* may be "stump" with no leaves */ - tmem_pampd_destroy_all_in_obj(obj); - BUG_ON(obj->objnode_tree_root != NULL); - BUG_ON((long)obj->objnode_count != 0); - atomic_dec(&pool->obj_count); - BUG_ON(atomic_read(&pool->obj_count) < 0); - INVERT_SENTINEL(obj, OBJ); - obj->pool = NULL; - tmem_oid_set_invalid(&obj->oid); - rb_erase(&obj->rb_tree_node, &hb->obj_rb_root); -} - -/* - * initialize, and insert an tmem_object_root (called only if find failed) - */ -static void tmem_obj_init(struct tmem_obj *obj, struct tmem_hashbucket *hb, - struct tmem_pool *pool, - struct tmem_oid *oidp) -{ - struct rb_root *root = &hb->obj_rb_root; - struct rb_node **new = &(root->rb_node), *parent = NULL; - struct tmem_obj *this; - - BUG_ON(pool == NULL); - atomic_inc(&pool->obj_count); - obj->objnode_tree_height = 0; - obj->objnode_tree_root = NULL; - obj->pool = pool; - obj->oid = *oidp; - obj->objnode_count = 0; - obj->pampd_count = 0; - (*tmem_pamops.new_obj)(obj); - SET_SENTINEL(obj, OBJ); - while (*new) { - BUG_ON(RB_EMPTY_NODE(*new)); - this = rb_entry(*new, struct tmem_obj, rb_tree_node); - parent = *new; - switch (tmem_oid_compare(oidp, &this->oid)) { - case 0: - BUG(); /* already present; should never happen! */ - break; - case -1: - new = &(*new)->rb_left; - break; - case 1: - new = &(*new)->rb_right; - break; - } - } - rb_link_node(&obj->rb_tree_node, parent, new); - rb_insert_color(&obj->rb_tree_node, root); -} - -/* - * Tmem is managed as a set of tmem_pools with certain attributes, such as - * "ephemeral" vs "persistent". These attributes apply to all tmem_objs - * and all pampds that belong to a tmem_pool. A tmem_pool is created - * or deleted relatively rarely (for example, when a filesystem is - * mounted or unmounted. - */ - -/* flush all data from a pool and, optionally, free it */ -static void tmem_pool_flush(struct tmem_pool *pool, bool destroy) -{ - struct rb_node *rbnode; - struct tmem_obj *obj; - struct tmem_hashbucket *hb = &pool->hashbucket[0]; - int i; - - BUG_ON(pool == NULL); - for (i = 0; i < TMEM_HASH_BUCKETS; i++, hb++) { - spin_lock(&hb->lock); - rbnode = rb_first(&hb->obj_rb_root); - while (rbnode != NULL) { - obj = rb_entry(rbnode, struct tmem_obj, rb_tree_node); - rbnode = rb_next(rbnode); - tmem_pampd_destroy_all_in_obj(obj); - tmem_obj_free(obj, hb); - (*tmem_hostops.obj_free)(obj, pool); - } - spin_unlock(&hb->lock); - } - if (destroy) - list_del(&pool->pool_list); -} - -/* - * A tmem_obj contains a radix-tree-like tree in which the intermediate - * nodes are called tmem_objnodes. (The kernel lib/radix-tree.c implementation - * is very specialized and tuned for specific uses and is not particularly - * suited for use from this code, though some code from the core algorithms has - * been reused, thus the copyright notices below). Each tmem_objnode contains - * a set of pointers which point to either a set of intermediate tmem_objnodes - * or a set of of pampds. - * - * Portions Copyright (C) 2001 Momchil Velikov - * Portions Copyright (C) 2001 Christoph Hellwig - * Portions Copyright (C) 2005 SGI, Christoph Lameter - */ - -struct tmem_objnode_tree_path { - struct tmem_objnode *objnode; - int offset; -}; - -/* objnode height_to_maxindex translation */ -static unsigned long tmem_objnode_tree_h2max[OBJNODE_TREE_MAX_PATH + 1]; - -static void tmem_objnode_tree_init(void) -{ - unsigned int ht, tmp; - - for (ht = 0; ht < ARRAY_SIZE(tmem_objnode_tree_h2max); ht++) { - tmp = ht * OBJNODE_TREE_MAP_SHIFT; - if (tmp >= OBJNODE_TREE_INDEX_BITS) - tmem_objnode_tree_h2max[ht] = ~0UL; - else - tmem_objnode_tree_h2max[ht] = - (~0UL >> (OBJNODE_TREE_INDEX_BITS - tmp - 1)) >> 1; - } -} - -static struct tmem_objnode *tmem_objnode_alloc(struct tmem_obj *obj) -{ - struct tmem_objnode *objnode; - - ASSERT_SENTINEL(obj, OBJ); - BUG_ON(obj->pool == NULL); - ASSERT_SENTINEL(obj->pool, POOL); - objnode = (*tmem_hostops.objnode_alloc)(obj->pool); - if (unlikely(objnode == NULL)) - goto out; - objnode->obj = obj; - SET_SENTINEL(objnode, OBJNODE); - memset(&objnode->slots, 0, sizeof(objnode->slots)); - objnode->slots_in_use = 0; - obj->objnode_count++; -out: - return objnode; -} - -static void tmem_objnode_free(struct tmem_objnode *objnode) -{ - struct tmem_pool *pool; - int i; - - BUG_ON(objnode == NULL); - for (i = 0; i < OBJNODE_TREE_MAP_SIZE; i++) - BUG_ON(objnode->slots[i] != NULL); - ASSERT_SENTINEL(objnode, OBJNODE); - INVERT_SENTINEL(objnode, OBJNODE); - BUG_ON(objnode->obj == NULL); - ASSERT_SENTINEL(objnode->obj, OBJ); - pool = objnode->obj->pool; - BUG_ON(pool == NULL); - ASSERT_SENTINEL(pool, POOL); - objnode->obj->objnode_count--; - objnode->obj = NULL; - (*tmem_hostops.objnode_free)(objnode, pool); -} - -/* - * lookup index in object and return associated pampd (or NULL if not found) - */ -static void **__tmem_pampd_lookup_in_obj(struct tmem_obj *obj, uint32_t index) -{ - unsigned int height, shift; - struct tmem_objnode **slot = NULL; - - BUG_ON(obj == NULL); - ASSERT_SENTINEL(obj, OBJ); - BUG_ON(obj->pool == NULL); - ASSERT_SENTINEL(obj->pool, POOL); - - height = obj->objnode_tree_height; - if (index > tmem_objnode_tree_h2max[obj->objnode_tree_height]) - goto out; - if (height == 0 && obj->objnode_tree_root) { - slot = &obj->objnode_tree_root; - goto out; - } - shift = (height-1) * OBJNODE_TREE_MAP_SHIFT; - slot = &obj->objnode_tree_root; - while (height > 0) { - if (*slot == NULL) - goto out; - slot = (struct tmem_objnode **) - ((*slot)->slots + - ((index >> shift) & OBJNODE_TREE_MAP_MASK)); - shift -= OBJNODE_TREE_MAP_SHIFT; - height--; - } -out: - return slot != NULL ? (void **)slot : NULL; -} - -static void *tmem_pampd_lookup_in_obj(struct tmem_obj *obj, uint32_t index) -{ - struct tmem_objnode **slot; - - slot = (struct tmem_objnode **)__tmem_pampd_lookup_in_obj(obj, index); - return slot != NULL ? *slot : NULL; -} - -static void *tmem_pampd_replace_in_obj(struct tmem_obj *obj, uint32_t index, - void *new_pampd, bool no_free) -{ - struct tmem_objnode **slot; - void *ret = NULL; - - slot = (struct tmem_objnode **)__tmem_pampd_lookup_in_obj(obj, index); - if ((slot != NULL) && (*slot != NULL)) { - void *old_pampd = *(void **)slot; - *(void **)slot = new_pampd; - if (!no_free) - (*tmem_pamops.free)(old_pampd, obj->pool, - NULL, 0, false); - ret = new_pampd; - } - return ret; -} - -static int tmem_pampd_add_to_obj(struct tmem_obj *obj, uint32_t index, - void *pampd) -{ - int ret = 0; - struct tmem_objnode *objnode = NULL, *newnode, *slot; - unsigned int height, shift; - int offset = 0; - - /* if necessary, extend the tree to be higher */ - if (index > tmem_objnode_tree_h2max[obj->objnode_tree_height]) { - height = obj->objnode_tree_height + 1; - if (index > tmem_objnode_tree_h2max[height]) - while (index > tmem_objnode_tree_h2max[height]) - height++; - if (obj->objnode_tree_root == NULL) { - obj->objnode_tree_height = height; - goto insert; - } - do { - newnode = tmem_objnode_alloc(obj); - if (!newnode) { - ret = -ENOMEM; - goto out; - } - newnode->slots[0] = obj->objnode_tree_root; - newnode->slots_in_use = 1; - obj->objnode_tree_root = newnode; - obj->objnode_tree_height++; - } while (height > obj->objnode_tree_height); - } -insert: - slot = obj->objnode_tree_root; - height = obj->objnode_tree_height; - shift = (height-1) * OBJNODE_TREE_MAP_SHIFT; - while (height > 0) { - if (slot == NULL) { - /* add a child objnode. */ - slot = tmem_objnode_alloc(obj); - if (!slot) { - ret = -ENOMEM; - goto out; - } - if (objnode) { - - objnode->slots[offset] = slot; - objnode->slots_in_use++; - } else - obj->objnode_tree_root = slot; - } - /* go down a level */ - offset = (index >> shift) & OBJNODE_TREE_MAP_MASK; - objnode = slot; - slot = objnode->slots[offset]; - shift -= OBJNODE_TREE_MAP_SHIFT; - height--; - } - BUG_ON(slot != NULL); - if (objnode) { - objnode->slots_in_use++; - objnode->slots[offset] = pampd; - } else - obj->objnode_tree_root = pampd; - obj->pampd_count++; -out: - return ret; -} - -static void *tmem_pampd_delete_from_obj(struct tmem_obj *obj, uint32_t index) -{ - struct tmem_objnode_tree_path path[OBJNODE_TREE_MAX_PATH + 1]; - struct tmem_objnode_tree_path *pathp = path; - struct tmem_objnode *slot = NULL; - unsigned int height, shift; - int offset; - - BUG_ON(obj == NULL); - ASSERT_SENTINEL(obj, OBJ); - BUG_ON(obj->pool == NULL); - ASSERT_SENTINEL(obj->pool, POOL); - height = obj->objnode_tree_height; - if (index > tmem_objnode_tree_h2max[height]) - goto out; - slot = obj->objnode_tree_root; - if (height == 0 && obj->objnode_tree_root) { - obj->objnode_tree_root = NULL; - goto out; - } - shift = (height - 1) * OBJNODE_TREE_MAP_SHIFT; - pathp->objnode = NULL; - do { - if (slot == NULL) - goto out; - pathp++; - offset = (index >> shift) & OBJNODE_TREE_MAP_MASK; - pathp->offset = offset; - pathp->objnode = slot; - slot = slot->slots[offset]; - shift -= OBJNODE_TREE_MAP_SHIFT; - height--; - } while (height > 0); - if (slot == NULL) - goto out; - while (pathp->objnode) { - pathp->objnode->slots[pathp->offset] = NULL; - pathp->objnode->slots_in_use--; - if (pathp->objnode->slots_in_use) { - if (pathp->objnode == obj->objnode_tree_root) { - while (obj->objnode_tree_height > 0 && - obj->objnode_tree_root->slots_in_use == 1 && - obj->objnode_tree_root->slots[0]) { - struct tmem_objnode *to_free = - obj->objnode_tree_root; - - obj->objnode_tree_root = - to_free->slots[0]; - obj->objnode_tree_height--; - to_free->slots[0] = NULL; - to_free->slots_in_use = 0; - tmem_objnode_free(to_free); - } - } - goto out; - } - tmem_objnode_free(pathp->objnode); /* 0 slots used, free it */ - pathp--; - } - obj->objnode_tree_height = 0; - obj->objnode_tree_root = NULL; - -out: - if (slot != NULL) - obj->pampd_count--; - BUG_ON(obj->pampd_count < 0); - return slot; -} - -/* recursively walk the objnode_tree destroying pampds and objnodes */ -static void tmem_objnode_node_destroy(struct tmem_obj *obj, - struct tmem_objnode *objnode, - unsigned int ht) -{ - int i; - - if (ht == 0) - return; - for (i = 0; i < OBJNODE_TREE_MAP_SIZE; i++) { - if (objnode->slots[i]) { - if (ht == 1) { - obj->pampd_count--; - (*tmem_pamops.free)(objnode->slots[i], - obj->pool, NULL, 0, true); - objnode->slots[i] = NULL; - continue; - } - tmem_objnode_node_destroy(obj, objnode->slots[i], ht-1); - tmem_objnode_free(objnode->slots[i]); - objnode->slots[i] = NULL; - } - } -} - -static void tmem_pampd_destroy_all_in_obj(struct tmem_obj *obj) -{ - if (obj->objnode_tree_root == NULL) - return; - if (obj->objnode_tree_height == 0) { - obj->pampd_count--; - (*tmem_pamops.free)(obj->objnode_tree_root, - obj->pool, NULL, 0, true); - } else { - tmem_objnode_node_destroy(obj, obj->objnode_tree_root, - obj->objnode_tree_height); - tmem_objnode_free(obj->objnode_tree_root); - obj->objnode_tree_height = 0; - } - obj->objnode_tree_root = NULL; - (*tmem_pamops.free_obj)(obj->pool, obj); -} - -/* - * Tmem is operated on by a set of well-defined actions: - * "put", "get", "flush", "flush_object", "new pool" and "destroy pool". - * (The tmem ABI allows for subpages and exchanges but these operations - * are not included in this implementation.) - * - * These "tmem core" operations are implemented in the following functions. - */ - -/* - * "Put" a page, e.g. copy a page from the kernel into newly allocated - * PAM space (if such space is available). Tmem_put is complicated by - * a corner case: What if a page with matching handle already exists in - * tmem? To guarantee coherency, one of two actions is necessary: Either - * the data for the page must be overwritten, or the page must be - * "flushed" so that the data is not accessible to a subsequent "get". - * Since these "duplicate puts" are relatively rare, this implementation - * always flushes for simplicity. - */ -int tmem_put(struct tmem_pool *pool, struct tmem_oid *oidp, uint32_t index, - char *data, size_t size, bool raw, int ephemeral) -{ - struct tmem_obj *obj = NULL, *objfound = NULL, *objnew = NULL; - void *pampd = NULL, *pampd_del = NULL; - int ret = -ENOMEM; - struct tmem_hashbucket *hb; - - hb = &pool->hashbucket[tmem_oid_hash(oidp)]; - spin_lock(&hb->lock); - obj = objfound = tmem_obj_find(hb, oidp); - if (obj != NULL) { - pampd = tmem_pampd_lookup_in_obj(objfound, index); - if (pampd != NULL) { - /* if found, is a dup put, flush the old one */ - pampd_del = tmem_pampd_delete_from_obj(obj, index); - BUG_ON(pampd_del != pampd); - (*tmem_pamops.free)(pampd, pool, oidp, index, true); - if (obj->pampd_count == 0) { - objnew = obj; - objfound = NULL; - } - pampd = NULL; - } - } else { - obj = objnew = (*tmem_hostops.obj_alloc)(pool); - if (unlikely(obj == NULL)) { - ret = -ENOMEM; - goto out; - } - tmem_obj_init(obj, hb, pool, oidp); - } - BUG_ON(obj == NULL); - BUG_ON(((objnew != obj) && (objfound != obj)) || (objnew == objfound)); - pampd = (*tmem_pamops.create)(data, size, raw, ephemeral, - obj->pool, &obj->oid, index); - if (unlikely(pampd == NULL)) - goto free; - ret = tmem_pampd_add_to_obj(obj, index, pampd); - if (unlikely(ret == -ENOMEM)) - /* may have partially built objnode tree ("stump") */ - goto delete_and_free; - goto out; - -delete_and_free: - (void)tmem_pampd_delete_from_obj(obj, index); -free: - if (pampd) - (*tmem_pamops.free)(pampd, pool, NULL, 0, true); - if (objnew) { - tmem_obj_free(objnew, hb); - (*tmem_hostops.obj_free)(objnew, pool); - } -out: - spin_unlock(&hb->lock); - return ret; -} - -void *tmem_localify_get_pampd(struct tmem_pool *pool, struct tmem_oid *oidp, - uint32_t index, struct tmem_obj **ret_obj, - void **saved_hb) -{ - struct tmem_hashbucket *hb; - struct tmem_obj *obj = NULL; - void *pampd = NULL; - - hb = &pool->hashbucket[tmem_oid_hash(oidp)]; - spin_lock(&hb->lock); - obj = tmem_obj_find(hb, oidp); - if (likely(obj != NULL)) - pampd = tmem_pampd_lookup_in_obj(obj, index); - *ret_obj = obj; - *saved_hb = (void *)hb; - /* note, hashbucket remains locked */ - return pampd; -} - -void tmem_localify_finish(struct tmem_obj *obj, uint32_t index, - void *pampd, void *saved_hb, bool delete) -{ - struct tmem_hashbucket *hb = (struct tmem_hashbucket *)saved_hb; - - BUG_ON(!spin_is_locked(&hb->lock)); - if (pampd != NULL) { - BUG_ON(obj == NULL); - (void)tmem_pampd_replace_in_obj(obj, index, pampd, 1); - } else if (delete) { - BUG_ON(obj == NULL); - (void)tmem_pampd_delete_from_obj(obj, index); - } - spin_unlock(&hb->lock); -} - -static int tmem_repatriate(void **ppampd, struct tmem_hashbucket *hb, - struct tmem_pool *pool, struct tmem_oid *oidp, - uint32_t index, bool free, char *data) -{ - void *old_pampd = *ppampd, *new_pampd = NULL; - bool intransit = false; - int ret = 0; - - - if (!is_ephemeral(pool)) - new_pampd = (*tmem_pamops.repatriate_preload)( - old_pampd, pool, oidp, index, &intransit); - if (intransit) - ret = -EAGAIN; - else if (new_pampd != NULL) - *ppampd = new_pampd; - /* must release the hb->lock else repatriate can't sleep */ - spin_unlock(&hb->lock); - if (!intransit) - ret = (*tmem_pamops.repatriate)(old_pampd, new_pampd, pool, - oidp, index, free, data); - return ret; -} - -/* - * "Get" a page, e.g. if one can be found, copy the tmem page with the - * matching handle from PAM space to the kernel. By tmem definition, - * when a "get" is successful on an ephemeral page, the page is "flushed", - * and when a "get" is successful on a persistent page, the page is retained - * in tmem. Note that to preserve - * coherency, "get" can never be skipped if tmem contains the data. - * That is, if a get is done with a certain handle and fails, any - * subsequent "get" must also fail (unless of course there is a - * "put" done with the same handle). - - */ -int tmem_get(struct tmem_pool *pool, struct tmem_oid *oidp, uint32_t index, - char *data, size_t *size, bool raw, int get_and_free) -{ - struct tmem_obj *obj; - void *pampd; - bool ephemeral = is_ephemeral(pool); - int ret = -1; - struct tmem_hashbucket *hb; - bool free = (get_and_free == 1) || ((get_and_free == 0) && ephemeral); - bool lock_held = 0; - void **ppampd; - -again: - hb = &pool->hashbucket[tmem_oid_hash(oidp)]; - spin_lock(&hb->lock); - lock_held = 1; - obj = tmem_obj_find(hb, oidp); - if (obj == NULL) - goto out; - ppampd = __tmem_pampd_lookup_in_obj(obj, index); - if (ppampd == NULL) - goto out; - if (tmem_pamops.is_remote(*ppampd)) { - ret = tmem_repatriate(ppampd, hb, pool, oidp, - index, free, data); - lock_held = 0; /* note hb->lock has been unlocked */ - if (ret == -EAGAIN) { - /* rare I think, but should cond_resched()??? */ - usleep_range(10, 1000); - goto again; - } else if (ret != 0) { - if (ret != -ENOENT) - pr_err("UNTESTED case in tmem_get, ret=%d\n", - ret); - ret = -1; - goto out; - } - goto out; - } - if (free) - pampd = tmem_pampd_delete_from_obj(obj, index); - else - pampd = tmem_pampd_lookup_in_obj(obj, index); - if (pampd == NULL) - goto out; - if (free) { - if (obj->pampd_count == 0) { - tmem_obj_free(obj, hb); - (*tmem_hostops.obj_free)(obj, pool); - obj = NULL; - } - } - if (free) - ret = (*tmem_pamops.get_data_and_free)( - data, size, raw, pampd, pool, oidp, index); - else - ret = (*tmem_pamops.get_data)( - data, size, raw, pampd, pool, oidp, index); - if (ret < 0) - goto out; - ret = 0; -out: - if (lock_held) - spin_unlock(&hb->lock); - return ret; -} - -/* - * If a page in tmem matches the handle, "flush" this page from tmem such - * that any subsequent "get" does not succeed (unless, of course, there - * was another "put" with the same handle). - */ -int tmem_flush_page(struct tmem_pool *pool, - struct tmem_oid *oidp, uint32_t index) -{ - struct tmem_obj *obj; - void *pampd; - int ret = -1; - struct tmem_hashbucket *hb; - - hb = &pool->hashbucket[tmem_oid_hash(oidp)]; - spin_lock(&hb->lock); - obj = tmem_obj_find(hb, oidp); - if (obj == NULL) - goto out; - pampd = tmem_pampd_delete_from_obj(obj, index); - if (pampd == NULL) - goto out; - (*tmem_pamops.free)(pampd, pool, oidp, index, true); - if (obj->pampd_count == 0) { - tmem_obj_free(obj, hb); - (*tmem_hostops.obj_free)(obj, pool); - } - ret = 0; - -out: - spin_unlock(&hb->lock); - return ret; -} - -/* - * If a page in tmem matches the handle, replace the page so that any - * subsequent "get" gets the new page. Returns the new page if - * there was a page to replace, else returns NULL. - */ -int tmem_replace(struct tmem_pool *pool, struct tmem_oid *oidp, - uint32_t index, void *new_pampd) -{ - struct tmem_obj *obj; - int ret = -1; - struct tmem_hashbucket *hb; - - hb = &pool->hashbucket[tmem_oid_hash(oidp)]; - spin_lock(&hb->lock); - obj = tmem_obj_find(hb, oidp); - if (obj == NULL) - goto out; - new_pampd = tmem_pampd_replace_in_obj(obj, index, new_pampd, 0); - ret = (*tmem_pamops.replace_in_obj)(new_pampd, obj); -out: - spin_unlock(&hb->lock); - return ret; -} - -/* - * "Flush" all pages in tmem matching this oid. - */ -int tmem_flush_object(struct tmem_pool *pool, struct tmem_oid *oidp) -{ - struct tmem_obj *obj; - struct tmem_hashbucket *hb; - int ret = -1; - - hb = &pool->hashbucket[tmem_oid_hash(oidp)]; - spin_lock(&hb->lock); - obj = tmem_obj_find(hb, oidp); - if (obj == NULL) - goto out; - tmem_pampd_destroy_all_in_obj(obj); - tmem_obj_free(obj, hb); - (*tmem_hostops.obj_free)(obj, pool); - ret = 0; - -out: - spin_unlock(&hb->lock); - return ret; -} - -/* - * "Flush" all pages (and tmem_objs) from this tmem_pool and disable - * all subsequent access to this tmem_pool. - */ -int tmem_destroy_pool(struct tmem_pool *pool) -{ - int ret = -1; - - if (pool == NULL) - goto out; - tmem_pool_flush(pool, 1); - ret = 0; -out: - return ret; -} - -static LIST_HEAD(tmem_global_pool_list); - -/* - * Create a new tmem_pool with the provided flag and return - * a pool id provided by the tmem host implementation. - */ -void tmem_new_pool(struct tmem_pool *pool, uint32_t flags) -{ - int persistent = flags & TMEM_POOL_PERSIST; - int shared = flags & TMEM_POOL_SHARED; - struct tmem_hashbucket *hb = &pool->hashbucket[0]; - int i; - - for (i = 0; i < TMEM_HASH_BUCKETS; i++, hb++) { - hb->obj_rb_root = RB_ROOT; - spin_lock_init(&hb->lock); - } - INIT_LIST_HEAD(&pool->pool_list); - atomic_set(&pool->obj_count, 0); - SET_SENTINEL(pool, POOL); - list_add_tail(&pool->pool_list, &tmem_global_pool_list); - pool->persistent = persistent; - pool->shared = shared; -} diff --git a/drivers/staging/ramster/tmem.h b/drivers/staging/ramster/tmem.h deleted file mode 100644 index 47f1918c831..00000000000 --- a/drivers/staging/ramster/tmem.h +++ /dev/null @@ -1,244 +0,0 @@ -/* - * tmem.h - * - * Transcendent memory - * - * Copyright (c) 2009-2011, Dan Magenheimer, Oracle Corp. - */ - -#ifndef _TMEM_H_ -#define _TMEM_H_ - -#include -#include -#include - -/* - * These are pre-defined by the Xen<->Linux ABI - */ -#define TMEM_PUT_PAGE 4 -#define TMEM_GET_PAGE 5 -#define TMEM_FLUSH_PAGE 6 -#define TMEM_FLUSH_OBJECT 7 -#define TMEM_POOL_PERSIST 1 -#define TMEM_POOL_SHARED 2 -#define TMEM_POOL_PRECOMPRESSED 4 -#define TMEM_POOL_PAGESIZE_SHIFT 4 -#define TMEM_POOL_PAGESIZE_MASK 0xf -#define TMEM_POOL_RESERVED_BITS 0x00ffff00 - -/* - * sentinels have proven very useful for debugging but can be removed - * or disabled before final merge. - */ -#define SENTINELS -#ifdef SENTINELS -#define DECL_SENTINEL uint32_t sentinel; -#define SET_SENTINEL(_x, _y) (_x->sentinel = _y##_SENTINEL) -#define INVERT_SENTINEL(_x, _y) (_x->sentinel = ~_y##_SENTINEL) -#define ASSERT_SENTINEL(_x, _y) WARN_ON(_x->sentinel != _y##_SENTINEL) -#define ASSERT_INVERTED_SENTINEL(_x, _y) WARN_ON(_x->sentinel != ~_y##_SENTINEL) -#else -#define DECL_SENTINEL -#define SET_SENTINEL(_x, _y) do { } while (0) -#define INVERT_SENTINEL(_x, _y) do { } while (0) -#define ASSERT_SENTINEL(_x, _y) do { } while (0) -#define ASSERT_INVERTED_SENTINEL(_x, _y) do { } while (0) -#endif - -#define ASSERT_SPINLOCK(_l) WARN_ON(!spin_is_locked(_l)) - -/* - * A pool is the highest-level data structure managed by tmem and - * usually corresponds to a large independent set of pages such as - * a filesystem. Each pool has an id, and certain attributes and counters. - * It also contains a set of hash buckets, each of which contains an rbtree - * of objects and a lock to manage concurrency within the pool. - */ - -#define TMEM_HASH_BUCKET_BITS 8 -#define TMEM_HASH_BUCKETS (1<persistent) -#define is_ephemeral(_p) (!(_p->persistent)) - -/* - * An object id ("oid") is large: 192-bits (to ensure, for example, files - * in a modern filesystem can be uniquely identified). - */ - -struct tmem_oid { - uint64_t oid[3]; -}; - -struct tmem_xhandle { - uint8_t client_id; - uint8_t xh_data_cksum; - uint16_t xh_data_size; - uint16_t pool_id; - struct tmem_oid oid; - uint32_t index; - void *extra; -}; - -static inline struct tmem_xhandle tmem_xhandle_fill(uint16_t client_id, - struct tmem_pool *pool, - struct tmem_oid *oidp, - uint32_t index) -{ - struct tmem_xhandle xh; - xh.client_id = client_id; - xh.xh_data_cksum = (uint8_t)-1; - xh.xh_data_size = (uint16_t)-1; - xh.pool_id = pool->pool_id; - xh.oid = *oidp; - xh.index = index; - return xh; -} - -static inline void tmem_oid_set_invalid(struct tmem_oid *oidp) -{ - oidp->oid[0] = oidp->oid[1] = oidp->oid[2] = -1UL; -} - -static inline bool tmem_oid_valid(struct tmem_oid *oidp) -{ - return oidp->oid[0] != -1UL || oidp->oid[1] != -1UL || - oidp->oid[2] != -1UL; -} - -static inline int tmem_oid_compare(struct tmem_oid *left, - struct tmem_oid *right) -{ - int ret; - - if (left->oid[2] == right->oid[2]) { - if (left->oid[1] == right->oid[1]) { - if (left->oid[0] == right->oid[0]) - ret = 0; - else if (left->oid[0] < right->oid[0]) - ret = -1; - else - return 1; - } else if (left->oid[1] < right->oid[1]) - ret = -1; - else - ret = 1; - } else if (left->oid[2] < right->oid[2]) - ret = -1; - else - ret = 1; - return ret; -} - -static inline unsigned tmem_oid_hash(struct tmem_oid *oidp) -{ - return hash_long(oidp->oid[0] ^ oidp->oid[1] ^ oidp->oid[2], - TMEM_HASH_BUCKET_BITS); -} - -/* - * A tmem_obj contains an identifier (oid), pointers to the parent - * pool and the rb_tree to which it belongs, counters, and an ordered - * set of pampds, structured in a radix-tree-like tree. The intermediate - * nodes of the tree are called tmem_objnodes. - */ - -struct tmem_objnode; - -struct tmem_obj { - struct tmem_oid oid; - struct tmem_pool *pool; - struct rb_node rb_tree_node; - struct tmem_objnode *objnode_tree_root; - unsigned int objnode_tree_height; - unsigned long objnode_count; - long pampd_count; - /* for current design of ramster, all pages belonging to - * an object reside on the same remotenode and extra is - * used to record the number of the remotenode so a - * flush-object operation can specify it */ - void *extra; /* for use by pampd implementation */ - DECL_SENTINEL -}; - -#define OBJNODE_TREE_MAP_SHIFT 6 -#define OBJNODE_TREE_MAP_SIZE (1UL << OBJNODE_TREE_MAP_SHIFT) -#define OBJNODE_TREE_MAP_MASK (OBJNODE_TREE_MAP_SIZE-1) -#define OBJNODE_TREE_INDEX_BITS (8 /* CHAR_BIT */ * sizeof(unsigned long)) -#define OBJNODE_TREE_MAX_PATH \ - (OBJNODE_TREE_INDEX_BITS/OBJNODE_TREE_MAP_SHIFT + 2) - -struct tmem_objnode { - struct tmem_obj *obj; - DECL_SENTINEL - void *slots[OBJNODE_TREE_MAP_SIZE]; - unsigned int slots_in_use; -}; - -/* pampd abstract datatype methods provided by the PAM implementation */ -struct tmem_pamops { - void *(*create)(char *, size_t, bool, int, - struct tmem_pool *, struct tmem_oid *, uint32_t); - int (*get_data)(char *, size_t *, bool, void *, struct tmem_pool *, - struct tmem_oid *, uint32_t); - int (*get_data_and_free)(char *, size_t *, bool, void *, - struct tmem_pool *, struct tmem_oid *, - uint32_t); - void (*free)(void *, struct tmem_pool *, - struct tmem_oid *, uint32_t, bool); - void (*free_obj)(struct tmem_pool *, struct tmem_obj *); - bool (*is_remote)(void *); - void *(*repatriate_preload)(void *, struct tmem_pool *, - struct tmem_oid *, uint32_t, bool *); - int (*repatriate)(void *, void *, struct tmem_pool *, - struct tmem_oid *, uint32_t, bool, void *); - void (*new_obj)(struct tmem_obj *); - int (*replace_in_obj)(void *, struct tmem_obj *); -}; -extern void tmem_register_pamops(struct tmem_pamops *m); - -/* memory allocation methods provided by the host implementation */ -struct tmem_hostops { - struct tmem_obj *(*obj_alloc)(struct tmem_pool *); - void (*obj_free)(struct tmem_obj *, struct tmem_pool *); - struct tmem_objnode *(*objnode_alloc)(struct tmem_pool *); - void (*objnode_free)(struct tmem_objnode *, struct tmem_pool *); -}; -extern void tmem_register_hostops(struct tmem_hostops *m); - -/* core tmem accessor functions */ -extern int tmem_put(struct tmem_pool *, struct tmem_oid *, uint32_t index, - char *, size_t, bool, int); -extern int tmem_get(struct tmem_pool *, struct tmem_oid *, uint32_t index, - char *, size_t *, bool, int); -extern int tmem_replace(struct tmem_pool *, struct tmem_oid *, uint32_t index, - void *); -extern void *tmem_localify_get_pampd(struct tmem_pool *, struct tmem_oid *, - uint32_t index, struct tmem_obj **, - void **); -extern void tmem_localify_finish(struct tmem_obj *, uint32_t index, - void *, void *, bool); -extern int tmem_flush_page(struct tmem_pool *, struct tmem_oid *, - uint32_t index); -extern int tmem_flush_object(struct tmem_pool *, struct tmem_oid *); -extern int tmem_destroy_pool(struct tmem_pool *); -extern void tmem_new_pool(struct tmem_pool *, uint32_t); -#endif /* _TMEM_H */ diff --git a/drivers/staging/ramster/zcache-main.c b/drivers/staging/ramster/zcache-main.c deleted file mode 100644 index 851e94af8ec..00000000000 --- a/drivers/staging/ramster/zcache-main.c +++ /dev/null @@ -1,3264 +0,0 @@ -/* - * zcache.c - * - * Copyright (c) 2010-2012, Dan Magenheimer, Oracle Corp. - * Copyright (c) 2010,2011, Nitin Gupta - * - * Zcache provides an in-kernel "host implementation" for transcendent memory - * and, thus indirectly, for cleancache and frontswap. Zcache includes two - * page-accessible memory [1] interfaces, both utilizing lzo1x compression: - * 1) "compression buddies" ("zbud") is used for ephemeral pages - * 2) xvmalloc is used for persistent pages. - * Xvmalloc (based on the TLSF allocator) has very low fragmentation - * so maximizes space efficiency, while zbud allows pairs (and potentially, - * in the future, more than a pair of) compressed pages to be closely linked - * so that reclaiming can be done via the kernel's physical-page-oriented - * "shrinker" interface. - * - * [1] For a definition of page-accessible memory (aka PAM), see: - * http://marc.info/?l=linux-mm&m=127811271605009 - * RAMSTER TODO: - * - handle remotifying of buddied pages (see zbud_remotify_zbpg) - * - kernel boot params: nocleancache/nofrontswap don't always work?!? - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "tmem.h" -#include "zcache.h" -#include "ramster.h" -#include "cluster/tcp.h" - -#include "../zram/xvmalloc.h" /* if built in drivers/staging */ - -#define RAMSTER_TESTING - -#if (!defined(CONFIG_CLEANCACHE) && !defined(CONFIG_FRONTSWAP)) -#error "ramster is useless without CONFIG_CLEANCACHE or CONFIG_FRONTSWAP" -#endif -#ifdef CONFIG_CLEANCACHE -#include -#endif -#ifdef CONFIG_FRONTSWAP -#include -#endif - -enum ramster_remotify_op { - RAMSTER_REMOTIFY_EPH_PUT, - RAMSTER_REMOTIFY_PERS_PUT, - RAMSTER_REMOTIFY_FLUSH_PAGE, - RAMSTER_REMOTIFY_FLUSH_OBJ, - RAMSTER_INTRANSIT_PERS -}; - -struct ramster_remotify_hdr { - enum ramster_remotify_op op; - struct list_head list; -}; - -#define ZBH_SENTINEL 0x43214321 -#define ZBPG_SENTINEL 0xdeadbeef - -#define ZBUD_MAX_BUDS 2 - -struct zbud_hdr { - struct ramster_remotify_hdr rem_op; - uint16_t client_id; - uint16_t pool_id; - struct tmem_oid oid; - uint32_t index; - uint16_t size; /* compressed size in bytes, zero means unused */ - DECL_SENTINEL -}; - -#define ZVH_SENTINEL 0x43214321 -static const int zv_max_page_size = (PAGE_SIZE / 8) * 7; - -struct zv_hdr { - struct ramster_remotify_hdr rem_op; - uint16_t client_id; - uint16_t pool_id; - struct tmem_oid oid; - uint32_t index; - DECL_SENTINEL -}; - -struct flushlist_node { - struct ramster_remotify_hdr rem_op; - struct tmem_xhandle xh; -}; - -union { - struct ramster_remotify_hdr rem_op; - struct zv_hdr zv; - struct zbud_hdr zbud; - struct flushlist_node flist; -} remotify_list_node; - -static LIST_HEAD(zcache_rem_op_list); -static DEFINE_SPINLOCK(zcache_rem_op_list_lock); - -#if 0 -/* this is more aggressive but may cause other problems? */ -#define ZCACHE_GFP_MASK (GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN) -#else -#define ZCACHE_GFP_MASK \ - (__GFP_FS | __GFP_NORETRY | __GFP_NOWARN | __GFP_NOMEMALLOC) -#endif - -#define MAX_POOLS_PER_CLIENT 16 - -#define MAX_CLIENTS 16 -#define LOCAL_CLIENT ((uint16_t)-1) - -MODULE_LICENSE("GPL"); - -struct zcache_client { - struct tmem_pool *tmem_pools[MAX_POOLS_PER_CLIENT]; - struct xv_pool *xvpool; - bool allocated; - atomic_t refcount; -}; - -static struct zcache_client zcache_host; -static struct zcache_client zcache_clients[MAX_CLIENTS]; - -static inline uint16_t get_client_id_from_client(struct zcache_client *cli) -{ - BUG_ON(cli == NULL); - if (cli == &zcache_host) - return LOCAL_CLIENT; - return cli - &zcache_clients[0]; -} - -static inline bool is_local_client(struct zcache_client *cli) -{ - return cli == &zcache_host; -} - -/********** - * Compression buddies ("zbud") provides for packing two (or, possibly - * in the future, more) compressed ephemeral pages into a single "raw" - * (physical) page and tracking them with data structures so that - * the raw pages can be easily reclaimed. - * - * A zbud page ("zbpg") is an aligned page containing a list_head, - * a lock, and two "zbud headers". The remainder of the physical - * page is divided up into aligned 64-byte "chunks" which contain - * the compressed data for zero, one, or two zbuds. Each zbpg - * resides on: (1) an "unused list" if it has no zbuds; (2) a - * "buddied" list if it is fully populated with two zbuds; or - * (3) one of PAGE_SIZE/64 "unbuddied" lists indexed by how many chunks - * the one unbuddied zbud uses. The data inside a zbpg cannot be - * read or written unless the zbpg's lock is held. - */ - -struct zbud_page { - struct list_head bud_list; - spinlock_t lock; - struct zbud_hdr buddy[ZBUD_MAX_BUDS]; - DECL_SENTINEL - /* followed by NUM_CHUNK aligned CHUNK_SIZE-byte chunks */ -}; - -#define CHUNK_SHIFT 6 -#define CHUNK_SIZE (1 << CHUNK_SHIFT) -#define CHUNK_MASK (~(CHUNK_SIZE-1)) -#define NCHUNKS (((PAGE_SIZE - sizeof(struct zbud_page)) & \ - CHUNK_MASK) >> CHUNK_SHIFT) -#define MAX_CHUNK (NCHUNKS-1) - -static struct { - struct list_head list; - unsigned count; -} zbud_unbuddied[NCHUNKS]; -/* list N contains pages with N chunks USED and NCHUNKS-N unused */ -/* element 0 is never used but optimizing that isn't worth it */ -static unsigned long zbud_cumul_chunk_counts[NCHUNKS]; - -struct list_head zbud_buddied_list; -static unsigned long zcache_zbud_buddied_count; - -/* protects the buddied list and all unbuddied lists */ -static DEFINE_SPINLOCK(zbud_budlists_spinlock); - -static atomic_t zcache_zbud_curr_raw_pages; -static atomic_t zcache_zbud_curr_zpages; -static unsigned long zcache_zbud_curr_zbytes; -static unsigned long zcache_zbud_cumul_zpages; -static unsigned long zcache_zbud_cumul_zbytes; -static unsigned long zcache_compress_poor; -static unsigned long zcache_policy_percent_exceeded; -static unsigned long zcache_mean_compress_poor; - -/* - * RAMster counters - * - Remote pages are pages with a local pampd but the data is remote - * - Foreign pages are pages stored locally but belonging to another node - */ -static atomic_t ramster_remote_pers_pages = ATOMIC_INIT(0); -static unsigned long ramster_pers_remotify_enable; -static unsigned long ramster_eph_remotify_enable; -static unsigned long ramster_eph_pages_remoted; -static unsigned long ramster_eph_pages_remote_failed; -static unsigned long ramster_pers_pages_remoted; -static unsigned long ramster_pers_pages_remote_failed; -static unsigned long ramster_pers_pages_remote_nomem; -static unsigned long ramster_remote_objects_flushed; -static unsigned long ramster_remote_object_flushes_failed; -static unsigned long ramster_remote_pages_flushed; -static unsigned long ramster_remote_page_flushes_failed; -static unsigned long ramster_remote_eph_pages_succ_get; -static unsigned long ramster_remote_pers_pages_succ_get; -static unsigned long ramster_remote_eph_pages_unsucc_get; -static unsigned long ramster_remote_pers_pages_unsucc_get; -static atomic_t ramster_curr_flnode_count = ATOMIC_INIT(0); -static unsigned long ramster_curr_flnode_count_max; -static atomic_t ramster_foreign_eph_pampd_count = ATOMIC_INIT(0); -static unsigned long ramster_foreign_eph_pampd_count_max; -static atomic_t ramster_foreign_pers_pampd_count = ATOMIC_INIT(0); -static unsigned long ramster_foreign_pers_pampd_count_max; - -/* forward references */ -static void *zcache_get_free_page(void); -static void zcache_free_page(void *p); - -/* - * zbud helper functions - */ - -static inline unsigned zbud_max_buddy_size(void) -{ - return MAX_CHUNK << CHUNK_SHIFT; -} - -static inline unsigned zbud_size_to_chunks(unsigned size) -{ - BUG_ON(size == 0 || size > zbud_max_buddy_size()); - return (size + CHUNK_SIZE - 1) >> CHUNK_SHIFT; -} - -static inline int zbud_budnum(struct zbud_hdr *zh) -{ - unsigned offset = (unsigned long)zh & (PAGE_SIZE - 1); - struct zbud_page *zbpg = NULL; - unsigned budnum = -1U; - int i; - - for (i = 0; i < ZBUD_MAX_BUDS; i++) - if (offset == offsetof(typeof(*zbpg), buddy[i])) { - budnum = i; - break; - } - BUG_ON(budnum == -1U); - return budnum; -} - -static char *zbud_data(struct zbud_hdr *zh, unsigned size) -{ - struct zbud_page *zbpg; - char *p; - unsigned budnum; - - ASSERT_SENTINEL(zh, ZBH); - budnum = zbud_budnum(zh); - BUG_ON(size == 0 || size > zbud_max_buddy_size()); - zbpg = container_of(zh, struct zbud_page, buddy[budnum]); - ASSERT_SPINLOCK(&zbpg->lock); - p = (char *)zbpg; - if (budnum == 0) - p += ((sizeof(struct zbud_page) + CHUNK_SIZE - 1) & - CHUNK_MASK); - else if (budnum == 1) - p += PAGE_SIZE - ((size + CHUNK_SIZE - 1) & CHUNK_MASK); - return p; -} - -static void zbud_copy_from_pampd(char *data, size_t *size, struct zbud_hdr *zh) -{ - struct zbud_page *zbpg; - char *p; - unsigned budnum; - - ASSERT_SENTINEL(zh, ZBH); - budnum = zbud_budnum(zh); - zbpg = container_of(zh, struct zbud_page, buddy[budnum]); - spin_lock(&zbpg->lock); - BUG_ON(zh->size > *size); - p = (char *)zbpg; - if (budnum == 0) - p += ((sizeof(struct zbud_page) + CHUNK_SIZE - 1) & - CHUNK_MASK); - else if (budnum == 1) - p += PAGE_SIZE - ((zh->size + CHUNK_SIZE - 1) & CHUNK_MASK); - /* client should be filled in by caller */ - memcpy(data, p, zh->size); - *size = zh->size; - spin_unlock(&zbpg->lock); -} - -/* - * zbud raw page management - */ - -static struct zbud_page *zbud_alloc_raw_page(void) -{ - struct zbud_page *zbpg = NULL; - struct zbud_hdr *zh0, *zh1; - zbpg = zcache_get_free_page(); - if (likely(zbpg != NULL)) { - INIT_LIST_HEAD(&zbpg->bud_list); - zh0 = &zbpg->buddy[0]; zh1 = &zbpg->buddy[1]; - spin_lock_init(&zbpg->lock); - atomic_inc(&zcache_zbud_curr_raw_pages); - INIT_LIST_HEAD(&zbpg->bud_list); - SET_SENTINEL(zbpg, ZBPG); - zh0->size = 0; zh1->size = 0; - tmem_oid_set_invalid(&zh0->oid); - tmem_oid_set_invalid(&zh1->oid); - } - return zbpg; -} - -static void zbud_free_raw_page(struct zbud_page *zbpg) -{ - struct zbud_hdr *zh0 = &zbpg->buddy[0], *zh1 = &zbpg->buddy[1]; - - ASSERT_SENTINEL(zbpg, ZBPG); - BUG_ON(!list_empty(&zbpg->bud_list)); - ASSERT_SPINLOCK(&zbpg->lock); - BUG_ON(zh0->size != 0 || tmem_oid_valid(&zh0->oid)); - BUG_ON(zh1->size != 0 || tmem_oid_valid(&zh1->oid)); - INVERT_SENTINEL(zbpg, ZBPG); - spin_unlock(&zbpg->lock); - atomic_dec(&zcache_zbud_curr_raw_pages); - zcache_free_page(zbpg); -} - -/* - * core zbud handling routines - */ - -static unsigned zbud_free(struct zbud_hdr *zh) -{ - unsigned size; - - ASSERT_SENTINEL(zh, ZBH); - BUG_ON(!tmem_oid_valid(&zh->oid)); - size = zh->size; - BUG_ON(zh->size == 0 || zh->size > zbud_max_buddy_size()); - zh->size = 0; - tmem_oid_set_invalid(&zh->oid); - INVERT_SENTINEL(zh, ZBH); - zcache_zbud_curr_zbytes -= size; - atomic_dec(&zcache_zbud_curr_zpages); - return size; -} - -static void zbud_free_and_delist(struct zbud_hdr *zh) -{ - unsigned chunks; - struct zbud_hdr *zh_other; - unsigned budnum = zbud_budnum(zh), size; - struct zbud_page *zbpg = - container_of(zh, struct zbud_page, buddy[budnum]); - - /* FIXME, should be BUG_ON, pool destruction path doesn't disable - * interrupts tmem_destroy_pool()->tmem_pampd_destroy_all_in_obj()-> - * tmem_objnode_node_destroy()-> zcache_pampd_free() */ - WARN_ON(!irqs_disabled()); - spin_lock(&zbpg->lock); - if (list_empty(&zbpg->bud_list)) { - /* ignore zombie page... see zbud_evict_pages() */ - spin_unlock(&zbpg->lock); - return; - } - size = zbud_free(zh); - ASSERT_SPINLOCK(&zbpg->lock); - zh_other = &zbpg->buddy[(budnum == 0) ? 1 : 0]; - if (zh_other->size == 0) { /* was unbuddied: unlist and free */ - chunks = zbud_size_to_chunks(size) ; - spin_lock(&zbud_budlists_spinlock); - BUG_ON(list_empty(&zbud_unbuddied[chunks].list)); - list_del_init(&zbpg->bud_list); - zbud_unbuddied[chunks].count--; - spin_unlock(&zbud_budlists_spinlock); - zbud_free_raw_page(zbpg); - } else { /* was buddied: move remaining buddy to unbuddied list */ - chunks = zbud_size_to_chunks(zh_other->size) ; - spin_lock(&zbud_budlists_spinlock); - list_del_init(&zbpg->bud_list); - zcache_zbud_buddied_count--; - list_add_tail(&zbpg->bud_list, &zbud_unbuddied[chunks].list); - zbud_unbuddied[chunks].count++; - spin_unlock(&zbud_budlists_spinlock); - spin_unlock(&zbpg->lock); - } -} - -static struct zbud_hdr *zbud_create(uint16_t client_id, uint16_t pool_id, - struct tmem_oid *oid, - uint32_t index, struct page *page, - void *cdata, unsigned size) -{ - struct zbud_hdr *zh0, *zh1, *zh = NULL; - struct zbud_page *zbpg = NULL, *ztmp; - unsigned nchunks; - char *to; - int i, found_good_buddy = 0; - - nchunks = zbud_size_to_chunks(size) ; - for (i = MAX_CHUNK - nchunks + 1; i > 0; i--) { - spin_lock(&zbud_budlists_spinlock); - if (!list_empty(&zbud_unbuddied[i].list)) { - list_for_each_entry_safe(zbpg, ztmp, - &zbud_unbuddied[i].list, bud_list) { - if (spin_trylock(&zbpg->lock)) { - found_good_buddy = i; - goto found_unbuddied; - } - } - } - spin_unlock(&zbud_budlists_spinlock); - } - /* didn't find a good buddy, try allocating a new page */ - zbpg = zbud_alloc_raw_page(); - if (unlikely(zbpg == NULL)) - goto out; - /* ok, have a page, now compress the data before taking locks */ - spin_lock(&zbud_budlists_spinlock); - spin_lock(&zbpg->lock); - list_add_tail(&zbpg->bud_list, &zbud_unbuddied[nchunks].list); - zbud_unbuddied[nchunks].count++; - zh = &zbpg->buddy[0]; - goto init_zh; - -found_unbuddied: - ASSERT_SPINLOCK(&zbpg->lock); - zh0 = &zbpg->buddy[0]; zh1 = &zbpg->buddy[1]; - BUG_ON(!((zh0->size == 0) ^ (zh1->size == 0))); - if (zh0->size != 0) { /* buddy0 in use, buddy1 is vacant */ - ASSERT_SENTINEL(zh0, ZBH); - zh = zh1; - } else if (zh1->size != 0) { /* buddy1 in use, buddy0 is vacant */ - ASSERT_SENTINEL(zh1, ZBH); - zh = zh0; - } else - BUG(); - list_del_init(&zbpg->bud_list); - zbud_unbuddied[found_good_buddy].count--; - list_add_tail(&zbpg->bud_list, &zbud_buddied_list); - zcache_zbud_buddied_count++; - -init_zh: - SET_SENTINEL(zh, ZBH); - zh->size = size; - zh->index = index; - zh->oid = *oid; - zh->pool_id = pool_id; - zh->client_id = client_id; - to = zbud_data(zh, size); - memcpy(to, cdata, size); - spin_unlock(&zbpg->lock); - spin_unlock(&zbud_budlists_spinlock); - zbud_cumul_chunk_counts[nchunks]++; - atomic_inc(&zcache_zbud_curr_zpages); - zcache_zbud_cumul_zpages++; - zcache_zbud_curr_zbytes += size; - zcache_zbud_cumul_zbytes += size; -out: - return zh; -} - -static int zbud_decompress(struct page *page, struct zbud_hdr *zh) -{ - struct zbud_page *zbpg; - unsigned budnum = zbud_budnum(zh); - size_t out_len = PAGE_SIZE; - char *to_va, *from_va; - unsigned size; - int ret = 0; - - zbpg = container_of(zh, struct zbud_page, buddy[budnum]); - spin_lock(&zbpg->lock); - if (list_empty(&zbpg->bud_list)) { - /* ignore zombie page... see zbud_evict_pages() */ - ret = -EINVAL; - goto out; - } - ASSERT_SENTINEL(zh, ZBH); - BUG_ON(zh->size == 0 || zh->size > zbud_max_buddy_size()); - to_va = kmap_atomic(page, KM_USER0); - size = zh->size; - from_va = zbud_data(zh, size); - ret = lzo1x_decompress_safe(from_va, size, to_va, &out_len); - BUG_ON(ret != LZO_E_OK); - BUG_ON(out_len != PAGE_SIZE); - kunmap_atomic(to_va, KM_USER0); -out: - spin_unlock(&zbpg->lock); - return ret; -} - -/* - * The following routines handle shrinking of ephemeral pages by evicting - * pages "least valuable" first. - */ - -static unsigned long zcache_evicted_raw_pages; -static unsigned long zcache_evicted_buddied_pages; -static unsigned long zcache_evicted_unbuddied_pages; - -static struct tmem_pool *zcache_get_pool_by_id(uint16_t cli_id, - uint16_t poolid); -static void zcache_put_pool(struct tmem_pool *pool); - -/* - * Flush and free all zbuds in a zbpg, then free the pageframe - */ -static void zbud_evict_zbpg(struct zbud_page *zbpg) -{ - struct zbud_hdr *zh; - int i, j; - uint32_t pool_id[ZBUD_MAX_BUDS], client_id[ZBUD_MAX_BUDS]; - uint32_t index[ZBUD_MAX_BUDS]; - struct tmem_oid oid[ZBUD_MAX_BUDS]; - struct tmem_pool *pool; - unsigned long flags; - - ASSERT_SPINLOCK(&zbpg->lock); - for (i = 0, j = 0; i < ZBUD_MAX_BUDS; i++) { - zh = &zbpg->buddy[i]; - if (zh->size) { - client_id[j] = zh->client_id; - pool_id[j] = zh->pool_id; - oid[j] = zh->oid; - index[j] = zh->index; - j++; - } - } - spin_unlock(&zbpg->lock); - for (i = 0; i < j; i++) { - pool = zcache_get_pool_by_id(client_id[i], pool_id[i]); - BUG_ON(pool == NULL); - local_irq_save(flags); - /* these flushes should dispose of any local storage */ - tmem_flush_page(pool, &oid[i], index[i]); - local_irq_restore(flags); - zcache_put_pool(pool); - } -} - -/* - * Free nr pages. This code is funky because we want to hold the locks - * protecting various lists for as short a time as possible, and in some - * circumstances the list may change asynchronously when the list lock is - * not held. In some cases we also trylock not only to avoid waiting on a - * page in use by another cpu, but also to avoid potential deadlock due to - * lock inversion. - */ -static void zbud_evict_pages(int nr) -{ - struct zbud_page *zbpg; - int i, newly_unused_pages = 0; - - - /* now try freeing unbuddied pages, starting with least space avail */ - for (i = 0; i < MAX_CHUNK; i++) { -retry_unbud_list_i: - spin_lock_bh(&zbud_budlists_spinlock); - if (list_empty(&zbud_unbuddied[i].list)) { - spin_unlock_bh(&zbud_budlists_spinlock); - continue; - } - list_for_each_entry(zbpg, &zbud_unbuddied[i].list, bud_list) { - if (unlikely(!spin_trylock(&zbpg->lock))) - continue; - zbud_unbuddied[i].count--; - spin_unlock(&zbud_budlists_spinlock); - zcache_evicted_unbuddied_pages++; - /* want budlists unlocked when doing zbpg eviction */ - zbud_evict_zbpg(zbpg); - newly_unused_pages++; - local_bh_enable(); - if (--nr <= 0) - goto evict_unused; - goto retry_unbud_list_i; - } - spin_unlock_bh(&zbud_budlists_spinlock); - } - - /* as a last resort, free buddied pages */ -retry_bud_list: - spin_lock_bh(&zbud_budlists_spinlock); - if (list_empty(&zbud_buddied_list)) { - spin_unlock_bh(&zbud_budlists_spinlock); - goto evict_unused; - } - list_for_each_entry(zbpg, &zbud_buddied_list, bud_list) { - if (unlikely(!spin_trylock(&zbpg->lock))) - continue; - zcache_zbud_buddied_count--; - spin_unlock(&zbud_budlists_spinlock); - zcache_evicted_buddied_pages++; - /* want budlists unlocked when doing zbpg eviction */ - zbud_evict_zbpg(zbpg); - newly_unused_pages++; - local_bh_enable(); - if (--nr <= 0) - goto evict_unused; - goto retry_bud_list; - } - spin_unlock_bh(&zbud_budlists_spinlock); - -evict_unused: - return; -} - -static DEFINE_PER_CPU(unsigned char *, zcache_remoteputmem); - -static int zbud_remotify_zbud(struct tmem_xhandle *xh, char *data, - size_t size) -{ - struct tmem_pool *pool; - int i, remotenode, ret = -1; - unsigned char cksum, *p; - unsigned long flags; - - for (p = data, cksum = 0, i = 0; i < size; i++) - cksum += *p; - ret = ramster_remote_put(xh, data, size, true, &remotenode); - if (ret == 0) { - /* data was successfully remoted so change the local version - * to point to the remote node where it landed */ - pool = zcache_get_pool_by_id(LOCAL_CLIENT, xh->pool_id); - BUG_ON(pool == NULL); - local_irq_save(flags); - /* tmem_replace will also free up any local space */ - (void)tmem_replace(pool, &xh->oid, xh->index, - pampd_make_remote(remotenode, size, cksum)); - local_irq_restore(flags); - zcache_put_pool(pool); - ramster_eph_pages_remoted++; - ret = 0; - } else - ramster_eph_pages_remote_failed++; - return ret; -} - -static int zbud_remotify_zbpg(struct zbud_page *zbpg) -{ - struct zbud_hdr *zh1, *zh2 = NULL; - struct tmem_xhandle xh1, xh2 = { 0 }; - char *data1 = NULL, *data2 = NULL; - size_t size1 = 0, size2 = 0; - int ret = 0; - unsigned char *tmpmem = __get_cpu_var(zcache_remoteputmem); - - ASSERT_SPINLOCK(&zbpg->lock); - if (zbpg->buddy[0].size == 0) - zh1 = &zbpg->buddy[1]; - else if (zbpg->buddy[1].size == 0) - zh1 = &zbpg->buddy[0]; - else { - zh1 = &zbpg->buddy[0]; - zh2 = &zbpg->buddy[1]; - } - /* don't remotify pages that are already remotified */ - if (zh1->client_id != LOCAL_CLIENT) - zh1 = NULL; - if ((zh2 != NULL) && (zh2->client_id != LOCAL_CLIENT)) - zh2 = NULL; - - /* copy the data and metadata so can release lock */ - if (zh1 != NULL) { - xh1.client_id = zh1->client_id; - xh1.pool_id = zh1->pool_id; - xh1.oid = zh1->oid; - xh1.index = zh1->index; - size1 = zh1->size; - data1 = zbud_data(zh1, size1); - memcpy(tmpmem, zbud_data(zh1, size1), size1); - data1 = tmpmem; - tmpmem += size1; - } - if (zh2 != NULL) { - xh2.client_id = zh2->client_id; - xh2.pool_id = zh2->pool_id; - xh2.oid = zh2->oid; - xh2.index = zh2->index; - size2 = zh2->size; - memcpy(tmpmem, zbud_data(zh2, size2), size2); - data2 = tmpmem; - } - spin_unlock(&zbpg->lock); - preempt_enable(); - - /* OK, no locks held anymore, remotify one or both zbuds */ - if (zh1 != NULL) - ret = zbud_remotify_zbud(&xh1, data1, size1); - if (zh2 != NULL) - ret |= zbud_remotify_zbud(&xh2, data2, size2); - return ret; -} - -void zbud_remotify_pages(int nr) -{ - struct zbud_page *zbpg; - int i, ret; - - /* - * for now just try remotifying unbuddied pages, starting with - * least space avail - */ - for (i = 0; i < MAX_CHUNK; i++) { -retry_unbud_list_i: - preempt_disable(); /* enable in zbud_remotify_zbpg */ - spin_lock_bh(&zbud_budlists_spinlock); - if (list_empty(&zbud_unbuddied[i].list)) { - spin_unlock_bh(&zbud_budlists_spinlock); - preempt_enable(); - continue; /* next i in for loop */ - } - list_for_each_entry(zbpg, &zbud_unbuddied[i].list, bud_list) { - if (unlikely(!spin_trylock(&zbpg->lock))) - continue; /* next list_for_each_entry */ - zbud_unbuddied[i].count--; - /* want budlists unlocked when doing zbpg remotify */ - spin_unlock_bh(&zbud_budlists_spinlock); - ret = zbud_remotify_zbpg(zbpg); - /* preemption is re-enabled in zbud_remotify_zbpg */ - if (ret == 0) { - if (--nr <= 0) - goto out; - goto retry_unbud_list_i; - } - /* if fail to remotify any page, quit */ - pr_err("TESTING zbud_remotify_pages failed on page," - " trying to re-add\n"); - spin_lock_bh(&zbud_budlists_spinlock); - spin_lock(&zbpg->lock); - list_add_tail(&zbpg->bud_list, &zbud_unbuddied[i].list); - zbud_unbuddied[i].count++; - spin_unlock(&zbpg->lock); - spin_unlock_bh(&zbud_budlists_spinlock); - pr_err("TESTING zbud_remotify_pages failed on page," - " finished re-add\n"); - goto out; - } - spin_unlock_bh(&zbud_budlists_spinlock); - preempt_enable(); - } - -next_buddied_zbpg: - preempt_disable(); /* enable in zbud_remotify_zbpg */ - spin_lock_bh(&zbud_budlists_spinlock); - if (list_empty(&zbud_buddied_list)) - goto unlock_out; - list_for_each_entry(zbpg, &zbud_buddied_list, bud_list) { - if (unlikely(!spin_trylock(&zbpg->lock))) - continue; /* next list_for_each_entry */ - zcache_zbud_buddied_count--; - /* want budlists unlocked when doing zbpg remotify */ - spin_unlock_bh(&zbud_budlists_spinlock); - ret = zbud_remotify_zbpg(zbpg); - /* preemption is re-enabled in zbud_remotify_zbpg */ - if (ret == 0) { - if (--nr <= 0) - goto out; - goto next_buddied_zbpg; - } - /* if fail to remotify any page, quit */ - pr_err("TESTING zbud_remotify_pages failed on BUDDIED page," - " trying to re-add\n"); - spin_lock_bh(&zbud_budlists_spinlock); - spin_lock(&zbpg->lock); - list_add_tail(&zbpg->bud_list, &zbud_buddied_list); - zcache_zbud_buddied_count++; - spin_unlock(&zbpg->lock); - spin_unlock_bh(&zbud_budlists_spinlock); - pr_err("TESTING zbud_remotify_pages failed on BUDDIED page," - " finished re-add\n"); - goto out; - } -unlock_out: - spin_unlock_bh(&zbud_budlists_spinlock); - preempt_enable(); -out: - return; -} - -/* the "flush list" asynchronously collects pages to remotely flush */ -#define FLUSH_ENTIRE_OBJECT ((uint32_t)-1) -static void ramster_flnode_free(struct flushlist_node *, - struct tmem_pool *); - -static void zcache_remote_flush_page(struct flushlist_node *flnode) -{ - struct tmem_xhandle *xh; - int remotenode, ret; - - preempt_disable(); - xh = &flnode->xh; - remotenode = flnode->xh.client_id; - ret = ramster_remote_flush(xh, remotenode); - if (ret >= 0) - ramster_remote_pages_flushed++; - else - ramster_remote_page_flushes_failed++; - preempt_enable_no_resched(); - ramster_flnode_free(flnode, NULL); -} - -static void zcache_remote_flush_object(struct flushlist_node *flnode) -{ - struct tmem_xhandle *xh; - int remotenode, ret; - - preempt_disable(); - xh = &flnode->xh; - remotenode = flnode->xh.client_id; - ret = ramster_remote_flush_object(xh, remotenode); - if (ret >= 0) - ramster_remote_objects_flushed++; - else - ramster_remote_object_flushes_failed++; - preempt_enable_no_resched(); - ramster_flnode_free(flnode, NULL); -} - -static void zcache_remote_eph_put(struct zbud_hdr *zbud) -{ - /* FIXME */ -} - -static void zcache_remote_pers_put(struct zv_hdr *zv) -{ - struct tmem_xhandle xh; - uint16_t size; - bool ephemeral; - int remotenode, ret = -1; - char *data; - struct tmem_pool *pool; - unsigned long flags; - unsigned char cksum; - char *p; - int i; - unsigned char *tmpmem = __get_cpu_var(zcache_remoteputmem); - - ASSERT_SENTINEL(zv, ZVH); - BUG_ON(zv->client_id != LOCAL_CLIENT); - local_bh_disable(); - xh.client_id = zv->client_id; - xh.pool_id = zv->pool_id; - xh.oid = zv->oid; - xh.index = zv->index; - size = xv_get_object_size(zv) - sizeof(*zv); - BUG_ON(size == 0 || size > zv_max_page_size); - data = (char *)zv + sizeof(*zv); - for (p = data, cksum = 0, i = 0; i < size; i++) - cksum += *p; - memcpy(tmpmem, data, size); - data = tmpmem; - pool = zcache_get_pool_by_id(zv->client_id, zv->pool_id); - ephemeral = is_ephemeral(pool); - zcache_put_pool(pool); - /* now OK to release lock set in caller */ - spin_unlock(&zcache_rem_op_list_lock); - local_bh_enable(); - preempt_disable(); - ret = ramster_remote_put(&xh, data, size, ephemeral, &remotenode); - preempt_enable_no_resched(); - if (ret != 0) { - /* - * This is some form of a memory leak... if the remote put - * fails, there will never be another attempt to remotify - * this page. But since we've dropped the zv pointer, - * the page may have been freed or the data replaced - * so we can't just "put it back" in the remote op list. - * Even if we could, not sure where to put it in the list - * because there may be flushes that must be strictly - * ordered vs the put. So leave this as a FIXME for now. - * But count them so we know if it becomes a problem. - */ - ramster_pers_pages_remote_failed++; - goto out; - } else - atomic_inc(&ramster_remote_pers_pages); - ramster_pers_pages_remoted++; - /* - * data was successfully remoted so change the local version to - * point to the remote node where it landed - */ - local_bh_disable(); - pool = zcache_get_pool_by_id(LOCAL_CLIENT, xh.pool_id); - local_irq_save(flags); - (void)tmem_replace(pool, &xh.oid, xh.index, - pampd_make_remote(remotenode, size, cksum)); - local_irq_restore(flags); - zcache_put_pool(pool); - local_bh_enable(); -out: - return; -} - -static void zcache_do_remotify_ops(int nr) -{ - struct ramster_remotify_hdr *rem_op; - union remotify_list_node *u; - - while (1) { - if (!nr) - goto out; - spin_lock(&zcache_rem_op_list_lock); - if (list_empty(&zcache_rem_op_list)) { - spin_unlock(&zcache_rem_op_list_lock); - goto out; - } - rem_op = list_first_entry(&zcache_rem_op_list, - struct ramster_remotify_hdr, list); - list_del_init(&rem_op->list); - if (rem_op->op != RAMSTER_REMOTIFY_PERS_PUT) - spin_unlock(&zcache_rem_op_list_lock); - u = (union remotify_list_node *)rem_op; - switch (rem_op->op) { - case RAMSTER_REMOTIFY_EPH_PUT: -BUG(); - zcache_remote_eph_put((struct zbud_hdr *)rem_op); - break; - case RAMSTER_REMOTIFY_PERS_PUT: - zcache_remote_pers_put((struct zv_hdr *)rem_op); - break; - case RAMSTER_REMOTIFY_FLUSH_PAGE: - zcache_remote_flush_page((struct flushlist_node *)u); - break; - case RAMSTER_REMOTIFY_FLUSH_OBJ: - zcache_remote_flush_object((struct flushlist_node *)u); - break; - default: - BUG(); - } - } -out: - return; -} - -/* - * For now, just push over a few pages every few seconds to - * ensure that it basically works - */ -static struct workqueue_struct *ramster_remotify_workqueue; -static void ramster_remotify_process(struct work_struct *work); -static DECLARE_DELAYED_WORK(ramster_remotify_worker, - ramster_remotify_process); - -static void ramster_remotify_queue_delayed_work(unsigned long delay) -{ - if (!queue_delayed_work(ramster_remotify_workqueue, - &ramster_remotify_worker, delay)) - pr_err("ramster_remotify: bad workqueue\n"); -} - - -static int use_frontswap; -static int use_cleancache; -static void ramster_remotify_process(struct work_struct *work) -{ - static bool remotify_in_progress; - - BUG_ON(irqs_disabled()); - if (remotify_in_progress) - ramster_remotify_queue_delayed_work(HZ); - else { - remotify_in_progress = true; -#ifdef CONFIG_CLEANCACHE - if (use_cleancache && ramster_eph_remotify_enable) - zbud_remotify_pages(5000); /* FIXME is this a good number? */ -#endif -#ifdef CONFIG_FRONTSWAP - if (use_frontswap && ramster_pers_remotify_enable) - zcache_do_remotify_ops(500); /* FIXME is this a good number? */ -#endif - remotify_in_progress = false; - ramster_remotify_queue_delayed_work(HZ); - } -} - -static void ramster_remotify_init(void) -{ - unsigned long n = 60UL; - ramster_remotify_workqueue = - create_singlethread_workqueue("ramster_remotify"); - ramster_remotify_queue_delayed_work(n * HZ); -} - - -static void zbud_init(void) -{ - int i; - - INIT_LIST_HEAD(&zbud_buddied_list); - zcache_zbud_buddied_count = 0; - for (i = 0; i < NCHUNKS; i++) { - INIT_LIST_HEAD(&zbud_unbuddied[i].list); - zbud_unbuddied[i].count = 0; - } -} - -#ifdef CONFIG_SYSFS -/* - * These sysfs routines show a nice distribution of how many zbpg's are - * currently (and have ever been placed) in each unbuddied list. It's fun - * to watch but can probably go away before final merge. - */ -static int zbud_show_unbuddied_list_counts(char *buf) -{ - int i; - char *p = buf; - - for (i = 0; i < NCHUNKS; i++) - p += sprintf(p, "%u ", zbud_unbuddied[i].count); - return p - buf; -} - -static int zbud_show_cumul_chunk_counts(char *buf) -{ - unsigned long i, chunks = 0, total_chunks = 0, sum_total_chunks = 0; - unsigned long total_chunks_lte_21 = 0, total_chunks_lte_32 = 0; - unsigned long total_chunks_lte_42 = 0; - char *p = buf; - - for (i = 0; i < NCHUNKS; i++) { - p += sprintf(p, "%lu ", zbud_cumul_chunk_counts[i]); - chunks += zbud_cumul_chunk_counts[i]; - total_chunks += zbud_cumul_chunk_counts[i]; - sum_total_chunks += i * zbud_cumul_chunk_counts[i]; - if (i == 21) - total_chunks_lte_21 = total_chunks; - if (i == 32) - total_chunks_lte_32 = total_chunks; - if (i == 42) - total_chunks_lte_42 = total_chunks; - } - p += sprintf(p, "<=21:%lu <=32:%lu <=42:%lu, mean:%lu\n", - total_chunks_lte_21, total_chunks_lte_32, total_chunks_lte_42, - chunks == 0 ? 0 : sum_total_chunks / chunks); - return p - buf; -} -#endif - -/********** - * This "zv" PAM implementation combines the TLSF-based xvMalloc - * with lzo1x compression to maximize the amount of data that can - * be packed into a physical page. - * - * Zv represents a PAM page with the index and object (plus a "size" value - * necessary for decompression) immediately preceding the compressed data. - */ - -/* rudimentary policy limits */ -/* total number of persistent pages may not exceed this percentage */ -static unsigned int zv_page_count_policy_percent = 75; -/* - * byte count defining poor compression; pages with greater zsize will be - * rejected - */ -static unsigned int zv_max_zsize = (PAGE_SIZE / 8) * 7; -/* - * byte count defining poor *mean* compression; pages with greater zsize - * will be rejected until sufficient better-compressed pages are accepted - * driving the mean below this threshold - */ -static unsigned int zv_max_mean_zsize = (PAGE_SIZE / 8) * 5; - -static atomic_t zv_curr_dist_counts[NCHUNKS]; -static atomic_t zv_cumul_dist_counts[NCHUNKS]; - - -static struct zv_hdr *zv_create(struct zcache_client *cli, uint32_t pool_id, - struct tmem_oid *oid, uint32_t index, - void *cdata, unsigned clen) -{ - struct page *page; - struct zv_hdr *zv = NULL; - uint32_t offset; - int alloc_size = clen + sizeof(struct zv_hdr); - int chunks = (alloc_size + (CHUNK_SIZE - 1)) >> CHUNK_SHIFT; - int ret; - - BUG_ON(!irqs_disabled()); - BUG_ON(chunks >= NCHUNKS); - ret = xv_malloc(cli->xvpool, clen + sizeof(struct zv_hdr), - &page, &offset, ZCACHE_GFP_MASK); - if (unlikely(ret)) - goto out; - atomic_inc(&zv_curr_dist_counts[chunks]); - atomic_inc(&zv_cumul_dist_counts[chunks]); - zv = kmap_atomic(page, KM_USER0) + offset; - zv->index = index; - zv->oid = *oid; - zv->pool_id = pool_id; - SET_SENTINEL(zv, ZVH); - INIT_LIST_HEAD(&zv->rem_op.list); - zv->client_id = get_client_id_from_client(cli); - zv->rem_op.op = RAMSTER_REMOTIFY_PERS_PUT; - if (zv->client_id == LOCAL_CLIENT) { - spin_lock(&zcache_rem_op_list_lock); - list_add_tail(&zv->rem_op.list, &zcache_rem_op_list); - spin_unlock(&zcache_rem_op_list_lock); - } - memcpy((char *)zv + sizeof(struct zv_hdr), cdata, clen); - kunmap_atomic(zv, KM_USER0); -out: - return zv; -} - -/* similar to zv_create, but just reserve space, no data yet */ -static struct zv_hdr *zv_alloc(struct tmem_pool *pool, - struct tmem_oid *oid, uint32_t index, - unsigned clen) -{ - struct zcache_client *cli = pool->client; - struct page *page; - struct zv_hdr *zv = NULL; - uint32_t offset; - int ret; - - BUG_ON(!irqs_disabled()); - BUG_ON(!is_local_client(pool->client)); - ret = xv_malloc(cli->xvpool, clen + sizeof(struct zv_hdr), - &page, &offset, ZCACHE_GFP_MASK); - if (unlikely(ret)) - goto out; - zv = kmap_atomic(page, KM_USER0) + offset; - SET_SENTINEL(zv, ZVH); - INIT_LIST_HEAD(&zv->rem_op.list); - zv->client_id = LOCAL_CLIENT; - zv->rem_op.op = RAMSTER_INTRANSIT_PERS; - zv->index = index; - zv->oid = *oid; - zv->pool_id = pool->pool_id; - kunmap_atomic(zv, KM_USER0); -out: - return zv; -} - -static void zv_free(struct xv_pool *xvpool, struct zv_hdr *zv) -{ - unsigned long flags; - struct page *page; - uint32_t offset; - uint16_t size = xv_get_object_size(zv); - int chunks = (size + (CHUNK_SIZE - 1)) >> CHUNK_SHIFT; - - ASSERT_SENTINEL(zv, ZVH); - BUG_ON(chunks >= NCHUNKS); - atomic_dec(&zv_curr_dist_counts[chunks]); - size -= sizeof(*zv); - spin_lock(&zcache_rem_op_list_lock); - size = xv_get_object_size(zv) - sizeof(*zv); - BUG_ON(size == 0); - INVERT_SENTINEL(zv, ZVH); - if (!list_empty(&zv->rem_op.list)) - list_del_init(&zv->rem_op.list); - spin_unlock(&zcache_rem_op_list_lock); - page = virt_to_page(zv); - offset = (unsigned long)zv & ~PAGE_MASK; - local_irq_save(flags); - xv_free(xvpool, page, offset); - local_irq_restore(flags); -} - -static void zv_decompress(struct page *page, struct zv_hdr *zv) -{ - size_t clen = PAGE_SIZE; - char *to_va; - unsigned size; - int ret; - - ASSERT_SENTINEL(zv, ZVH); - size = xv_get_object_size(zv) - sizeof(*zv); - BUG_ON(size == 0); - to_va = kmap_atomic(page, KM_USER0); - ret = lzo1x_decompress_safe((char *)zv + sizeof(*zv), - size, to_va, &clen); - kunmap_atomic(to_va, KM_USER0); - BUG_ON(ret != LZO_E_OK); - BUG_ON(clen != PAGE_SIZE); -} - -static void zv_copy_from_pampd(char *data, size_t *bufsize, struct zv_hdr *zv) -{ - unsigned size; - - ASSERT_SENTINEL(zv, ZVH); - size = xv_get_object_size(zv) - sizeof(*zv); - BUG_ON(size == 0 || size > zv_max_page_size); - BUG_ON(size > *bufsize); - memcpy(data, (char *)zv + sizeof(*zv), size); - *bufsize = size; -} - -static void zv_copy_to_pampd(struct zv_hdr *zv, char *data, size_t size) -{ - unsigned zv_size; - - ASSERT_SENTINEL(zv, ZVH); - zv_size = xv_get_object_size(zv) - sizeof(*zv); - BUG_ON(zv_size != size); - BUG_ON(zv_size == 0 || zv_size > zv_max_page_size); - memcpy((char *)zv + sizeof(*zv), data, size); -} - -#ifdef CONFIG_SYSFS -/* - * show a distribution of compression stats for zv pages. - */ - -static int zv_curr_dist_counts_show(char *buf) -{ - unsigned long i, n, chunks = 0, sum_total_chunks = 0; - char *p = buf; - - for (i = 0; i < NCHUNKS; i++) { - n = atomic_read(&zv_curr_dist_counts[i]); - p += sprintf(p, "%lu ", n); - chunks += n; - sum_total_chunks += i * n; - } - p += sprintf(p, "mean:%lu\n", - chunks == 0 ? 0 : sum_total_chunks / chunks); - return p - buf; -} - -static int zv_cumul_dist_counts_show(char *buf) -{ - unsigned long i, n, chunks = 0, sum_total_chunks = 0; - char *p = buf; - - for (i = 0; i < NCHUNKS; i++) { - n = atomic_read(&zv_cumul_dist_counts[i]); - p += sprintf(p, "%lu ", n); - chunks += n; - sum_total_chunks += i * n; - } - p += sprintf(p, "mean:%lu\n", - chunks == 0 ? 0 : sum_total_chunks / chunks); - return p - buf; -} - -/* - * setting zv_max_zsize via sysfs causes all persistent (e.g. swap) - * pages that don't compress to less than this value (including metadata - * overhead) to be rejected. We don't allow the value to get too close - * to PAGE_SIZE. - */ -static ssize_t zv_max_zsize_show(struct kobject *kobj, - struct kobj_attribute *attr, - char *buf) -{ - return sprintf(buf, "%u\n", zv_max_zsize); -} - -static ssize_t zv_max_zsize_store(struct kobject *kobj, - struct kobj_attribute *attr, - const char *buf, size_t count) -{ - unsigned long val; - int err; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - err = strict_strtoul(buf, 10, &val); - if (err || (val == 0) || (val > (PAGE_SIZE / 8) * 7)) - return -EINVAL; - zv_max_zsize = val; - return count; -} - -/* - * setting zv_max_mean_zsize via sysfs causes all persistent (e.g. swap) - * pages that don't compress to less than this value (including metadata - * overhead) to be rejected UNLESS the mean compression is also smaller - * than this value. In other words, we are load-balancing-by-zsize the - * accepted pages. Again, we don't allow the value to get too close - * to PAGE_SIZE. - */ -static ssize_t zv_max_mean_zsize_show(struct kobject *kobj, - struct kobj_attribute *attr, - char *buf) -{ - return sprintf(buf, "%u\n", zv_max_mean_zsize); -} - -static ssize_t zv_max_mean_zsize_store(struct kobject *kobj, - struct kobj_attribute *attr, - const char *buf, size_t count) -{ - unsigned long val; - int err; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - err = strict_strtoul(buf, 10, &val); - if (err || (val == 0) || (val > (PAGE_SIZE / 8) * 7)) - return -EINVAL; - zv_max_mean_zsize = val; - return count; -} - -/* - * setting zv_page_count_policy_percent via sysfs sets an upper bound of - * persistent (e.g. swap) pages that will be retained according to: - * (zv_page_count_policy_percent * totalram_pages) / 100) - * when that limit is reached, further puts will be rejected (until - * some pages have been flushed). Note that, due to compression, - * this number may exceed 100; it defaults to 75 and we set an - * arbitary limit of 150. A poor choice will almost certainly result - * in OOM's, so this value should only be changed prudently. - */ -static ssize_t zv_page_count_policy_percent_show(struct kobject *kobj, - struct kobj_attribute *attr, - char *buf) -{ - return sprintf(buf, "%u\n", zv_page_count_policy_percent); -} - -static ssize_t zv_page_count_policy_percent_store(struct kobject *kobj, - struct kobj_attribute *attr, - const char *buf, size_t count) -{ - unsigned long val; - int err; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - err = strict_strtoul(buf, 10, &val); - if (err || (val == 0) || (val > 150)) - return -EINVAL; - zv_page_count_policy_percent = val; - return count; -} - -static struct kobj_attribute zcache_zv_max_zsize_attr = { - .attr = { .name = "zv_max_zsize", .mode = 0644 }, - .show = zv_max_zsize_show, - .store = zv_max_zsize_store, -}; - -static struct kobj_attribute zcache_zv_max_mean_zsize_attr = { - .attr = { .name = "zv_max_mean_zsize", .mode = 0644 }, - .show = zv_max_mean_zsize_show, - .store = zv_max_mean_zsize_store, -}; - -static struct kobj_attribute zcache_zv_page_count_policy_percent_attr = { - .attr = { .name = "zv_page_count_policy_percent", - .mode = 0644 }, - .show = zv_page_count_policy_percent_show, - .store = zv_page_count_policy_percent_store, -}; -#endif - -/* - * zcache core code starts here - */ - -/* useful stats not collected by cleancache or frontswap */ -static unsigned long zcache_flush_total; -static unsigned long zcache_flush_found; -static unsigned long zcache_flobj_total; -static unsigned long zcache_flobj_found; -static unsigned long zcache_failed_eph_puts; -static unsigned long zcache_nonactive_puts; -static unsigned long zcache_failed_pers_puts; - -/* - * Tmem operations assume the poolid implies the invoking client. - * Zcache only has one client (the kernel itself): LOCAL_CLIENT. - * RAMster has each client numbered by cluster node, and a KVM version - * of zcache would have one client per guest and each client might - * have a poolid==N. - */ -static struct tmem_pool *zcache_get_pool_by_id(uint16_t cli_id, uint16_t poolid) -{ - struct tmem_pool *pool = NULL; - struct zcache_client *cli = NULL; - - if (cli_id == LOCAL_CLIENT) - cli = &zcache_host; - else { - if (cli_id >= MAX_CLIENTS) - goto out; - cli = &zcache_clients[cli_id]; - if (cli == NULL) - goto out; - atomic_inc(&cli->refcount); - } - if (poolid < MAX_POOLS_PER_CLIENT) { - pool = cli->tmem_pools[poolid]; - if (pool != NULL) - atomic_inc(&pool->refcount); - } -out: - return pool; -} - -static void zcache_put_pool(struct tmem_pool *pool) -{ - struct zcache_client *cli = NULL; - - if (pool == NULL) - BUG(); - cli = pool->client; - atomic_dec(&pool->refcount); - atomic_dec(&cli->refcount); -} - -int zcache_new_client(uint16_t cli_id) -{ - struct zcache_client *cli = NULL; - int ret = -1; - - if (cli_id == LOCAL_CLIENT) - cli = &zcache_host; - else if ((unsigned int)cli_id < MAX_CLIENTS) - cli = &zcache_clients[cli_id]; - if (cli == NULL) - goto out; - if (cli->allocated) - goto out; - cli->allocated = 1; -#ifdef CONFIG_FRONTSWAP - cli->xvpool = xv_create_pool(); - if (cli->xvpool == NULL) - goto out; -#endif - ret = 0; -out: - return ret; -} - -/* counters for debugging */ -static unsigned long zcache_failed_get_free_pages; -static unsigned long zcache_failed_alloc; -static unsigned long zcache_put_to_flush; - -/* - * for now, used named slabs so can easily track usage; later can - * either just use kmalloc, or perhaps add a slab-like allocator - * to more carefully manage total memory utilization - */ -static struct kmem_cache *zcache_objnode_cache; -static struct kmem_cache *zcache_obj_cache; -static struct kmem_cache *ramster_flnode_cache; -static atomic_t zcache_curr_obj_count = ATOMIC_INIT(0); -static unsigned long zcache_curr_obj_count_max; -static atomic_t zcache_curr_objnode_count = ATOMIC_INIT(0); -static unsigned long zcache_curr_objnode_count_max; - -/* - * to avoid memory allocation recursion (e.g. due to direct reclaim), we - * preload all necessary data structures so the hostops callbacks never - * actually do a malloc - */ -struct zcache_preload { - void *page; - struct tmem_obj *obj; - int nr; - struct tmem_objnode *objnodes[OBJNODE_TREE_MAX_PATH]; - struct flushlist_node *flnode; -}; -static DEFINE_PER_CPU(struct zcache_preload, zcache_preloads) = { 0, }; - -static int zcache_do_preload(struct tmem_pool *pool) -{ - struct zcache_preload *kp; - struct tmem_objnode *objnode; - struct tmem_obj *obj; - struct flushlist_node *flnode; - void *page; - int ret = -ENOMEM; - - if (unlikely(zcache_objnode_cache == NULL)) - goto out; - if (unlikely(zcache_obj_cache == NULL)) - goto out; - preempt_disable(); - kp = &__get_cpu_var(zcache_preloads); - while (kp->nr < ARRAY_SIZE(kp->objnodes)) { - preempt_enable_no_resched(); - objnode = kmem_cache_alloc(zcache_objnode_cache, - ZCACHE_GFP_MASK); - if (unlikely(objnode == NULL)) { - zcache_failed_alloc++; - goto out; - } - preempt_disable(); - kp = &__get_cpu_var(zcache_preloads); - if (kp->nr < ARRAY_SIZE(kp->objnodes)) - kp->objnodes[kp->nr++] = objnode; - else - kmem_cache_free(zcache_objnode_cache, objnode); - } - preempt_enable_no_resched(); - obj = kmem_cache_alloc(zcache_obj_cache, ZCACHE_GFP_MASK); - if (unlikely(obj == NULL)) { - zcache_failed_alloc++; - goto out; - } - flnode = kmem_cache_alloc(ramster_flnode_cache, ZCACHE_GFP_MASK); - if (unlikely(flnode == NULL)) { - zcache_failed_alloc++; - goto out; - } - if (is_ephemeral(pool)) { - page = (void *)__get_free_page(ZCACHE_GFP_MASK); - if (unlikely(page == NULL)) { - zcache_failed_get_free_pages++; - kmem_cache_free(zcache_obj_cache, obj); - kmem_cache_free(ramster_flnode_cache, flnode); - goto out; - } - } - preempt_disable(); - kp = &__get_cpu_var(zcache_preloads); - if (kp->obj == NULL) - kp->obj = obj; - else - kmem_cache_free(zcache_obj_cache, obj); - if (kp->flnode == NULL) - kp->flnode = flnode; - else - kmem_cache_free(ramster_flnode_cache, flnode); - if (is_ephemeral(pool)) { - if (kp->page == NULL) - kp->page = page; - else - free_page((unsigned long)page); - } - ret = 0; -out: - return ret; -} - -static int ramster_do_preload_flnode_only(struct tmem_pool *pool) -{ - struct zcache_preload *kp; - struct flushlist_node *flnode; - int ret = -ENOMEM; - - BUG_ON(!irqs_disabled()); - if (unlikely(ramster_flnode_cache == NULL)) - BUG(); - kp = &__get_cpu_var(zcache_preloads); - flnode = kmem_cache_alloc(ramster_flnode_cache, GFP_ATOMIC); - if (unlikely(flnode == NULL) && kp->flnode == NULL) - BUG(); /* FIXME handle more gracefully, but how??? */ - else if (kp->flnode == NULL) - kp->flnode = flnode; - else - kmem_cache_free(ramster_flnode_cache, flnode); - return ret; -} - -static void *zcache_get_free_page(void) -{ - struct zcache_preload *kp; - void *page; - - kp = &__get_cpu_var(zcache_preloads); - page = kp->page; - BUG_ON(page == NULL); - kp->page = NULL; - return page; -} - -static void zcache_free_page(void *p) -{ - free_page((unsigned long)p); -} - -/* - * zcache implementation for tmem host ops - */ - -static struct tmem_objnode *zcache_objnode_alloc(struct tmem_pool *pool) -{ - struct tmem_objnode *objnode = NULL; - unsigned long count; - struct zcache_preload *kp; - - kp = &__get_cpu_var(zcache_preloads); - if (kp->nr <= 0) - goto out; - objnode = kp->objnodes[kp->nr - 1]; - BUG_ON(objnode == NULL); - kp->objnodes[kp->nr - 1] = NULL; - kp->nr--; - count = atomic_inc_return(&zcache_curr_objnode_count); - if (count > zcache_curr_objnode_count_max) - zcache_curr_objnode_count_max = count; -out: - return objnode; -} - -static void zcache_objnode_free(struct tmem_objnode *objnode, - struct tmem_pool *pool) -{ - atomic_dec(&zcache_curr_objnode_count); - BUG_ON(atomic_read(&zcache_curr_objnode_count) < 0); - kmem_cache_free(zcache_objnode_cache, objnode); -} - -static struct tmem_obj *zcache_obj_alloc(struct tmem_pool *pool) -{ - struct tmem_obj *obj = NULL; - unsigned long count; - struct zcache_preload *kp; - - kp = &__get_cpu_var(zcache_preloads); - obj = kp->obj; - BUG_ON(obj == NULL); - kp->obj = NULL; - count = atomic_inc_return(&zcache_curr_obj_count); - if (count > zcache_curr_obj_count_max) - zcache_curr_obj_count_max = count; - return obj; -} - -static void zcache_obj_free(struct tmem_obj *obj, struct tmem_pool *pool) -{ - atomic_dec(&zcache_curr_obj_count); - BUG_ON(atomic_read(&zcache_curr_obj_count) < 0); - kmem_cache_free(zcache_obj_cache, obj); -} - -static struct flushlist_node *ramster_flnode_alloc(struct tmem_pool *pool) -{ - struct flushlist_node *flnode = NULL; - struct zcache_preload *kp; - int count; - - kp = &__get_cpu_var(zcache_preloads); - flnode = kp->flnode; - BUG_ON(flnode == NULL); - kp->flnode = NULL; - count = atomic_inc_return(&ramster_curr_flnode_count); - if (count > ramster_curr_flnode_count_max) - ramster_curr_flnode_count_max = count; - return flnode; -} - -static void ramster_flnode_free(struct flushlist_node *flnode, - struct tmem_pool *pool) -{ - atomic_dec(&ramster_curr_flnode_count); - BUG_ON(atomic_read(&ramster_curr_flnode_count) < 0); - kmem_cache_free(ramster_flnode_cache, flnode); -} - -static struct tmem_hostops zcache_hostops = { - .obj_alloc = zcache_obj_alloc, - .obj_free = zcache_obj_free, - .objnode_alloc = zcache_objnode_alloc, - .objnode_free = zcache_objnode_free, -}; - -/* - * zcache implementations for PAM page descriptor ops - */ - -static atomic_t zcache_curr_eph_pampd_count = ATOMIC_INIT(0); -static unsigned long zcache_curr_eph_pampd_count_max; -static atomic_t zcache_curr_pers_pampd_count = ATOMIC_INIT(0); -static unsigned long zcache_curr_pers_pampd_count_max; - -/* forward reference */ -static int zcache_compress(struct page *from, void **out_va, size_t *out_len); - -static int zcache_pampd_eph_create(char *data, size_t size, bool raw, - struct tmem_pool *pool, struct tmem_oid *oid, - uint32_t index, void **pampd) -{ - int ret = -1; - void *cdata = data; - size_t clen = size; - struct zcache_client *cli = pool->client; - uint16_t client_id = get_client_id_from_client(cli); - struct page *page = NULL; - unsigned long count; - - if (!raw) { - page = virt_to_page(data); - ret = zcache_compress(page, &cdata, &clen); - if (ret == 0) - goto out; - if (clen == 0 || clen > zbud_max_buddy_size()) { - zcache_compress_poor++; - goto out; - } - } - *pampd = (void *)zbud_create(client_id, pool->pool_id, oid, - index, page, cdata, clen); - if (*pampd == NULL) { - ret = -ENOMEM; - goto out; - } - ret = 0; - count = atomic_inc_return(&zcache_curr_eph_pampd_count); - if (count > zcache_curr_eph_pampd_count_max) - zcache_curr_eph_pampd_count_max = count; - if (client_id != LOCAL_CLIENT) { - count = atomic_inc_return(&ramster_foreign_eph_pampd_count); - if (count > ramster_foreign_eph_pampd_count_max) - ramster_foreign_eph_pampd_count_max = count; - } -out: - return ret; -} - -static int zcache_pampd_pers_create(char *data, size_t size, bool raw, - struct tmem_pool *pool, struct tmem_oid *oid, - uint32_t index, void **pampd) -{ - int ret = -1; - void *cdata = data; - size_t clen = size; - struct zcache_client *cli = pool->client; - struct page *page; - unsigned long count; - unsigned long zv_mean_zsize; - struct zv_hdr *zv; - long curr_pers_pampd_count; - u64 total_zsize; -#ifdef RAMSTER_TESTING - static bool pampd_neg_warned; -#endif - - curr_pers_pampd_count = atomic_read(&zcache_curr_pers_pampd_count) - - atomic_read(&ramster_remote_pers_pages); -#ifdef RAMSTER_TESTING - /* should always be positive, but warn if accounting is off */ - if (!pampd_neg_warned) { - pr_warn("ramster: bad accounting for curr_pers_pampd_count\n"); - pampd_neg_warned = true; - } -#endif - if (curr_pers_pampd_count > - (zv_page_count_policy_percent * totalram_pages) / 100) { - zcache_policy_percent_exceeded++; - goto out; - } - if (raw) - goto ok_to_create; - page = virt_to_page(data); - if (zcache_compress(page, &cdata, &clen) == 0) - goto out; - /* reject if compression is too poor */ - if (clen > zv_max_zsize) { - zcache_compress_poor++; - goto out; - } - /* reject if mean compression is too poor */ - if ((clen > zv_max_mean_zsize) && (curr_pers_pampd_count > 0)) { - total_zsize = xv_get_total_size_bytes(cli->xvpool); - zv_mean_zsize = div_u64(total_zsize, curr_pers_pampd_count); - if (zv_mean_zsize > zv_max_mean_zsize) { - zcache_mean_compress_poor++; - goto out; - } - } -ok_to_create: - *pampd = (void *)zv_create(cli, pool->pool_id, oid, index, cdata, clen); - if (*pampd == NULL) { - ret = -ENOMEM; - goto out; - } - ret = 0; - count = atomic_inc_return(&zcache_curr_pers_pampd_count); - if (count > zcache_curr_pers_pampd_count_max) - zcache_curr_pers_pampd_count_max = count; - if (is_local_client(cli)) - goto out; - zv = *(struct zv_hdr **)pampd; - count = atomic_inc_return(&ramster_foreign_pers_pampd_count); - if (count > ramster_foreign_pers_pampd_count_max) - ramster_foreign_pers_pampd_count_max = count; -out: - return ret; -} - -static void *zcache_pampd_create(char *data, size_t size, bool raw, int eph, - struct tmem_pool *pool, struct tmem_oid *oid, - uint32_t index) -{ - void *pampd = NULL; - int ret; - bool ephemeral; - - BUG_ON(preemptible()); - ephemeral = (eph == 1) || ((eph == 0) && is_ephemeral(pool)); - if (ephemeral) - ret = zcache_pampd_eph_create(data, size, raw, pool, - oid, index, &pampd); - else - ret = zcache_pampd_pers_create(data, size, raw, pool, - oid, index, &pampd); - /* FIXME add some counters here for failed creates? */ - return pampd; -} - -/* - * fill the pageframe corresponding to the struct page with the data - * from the passed pampd - */ -static int zcache_pampd_get_data(char *data, size_t *bufsize, bool raw, - void *pampd, struct tmem_pool *pool, - struct tmem_oid *oid, uint32_t index) -{ - int ret = 0; - - BUG_ON(preemptible()); - BUG_ON(is_ephemeral(pool)); /* Fix later for shared pools? */ - BUG_ON(pampd_is_remote(pampd)); - if (raw) - zv_copy_from_pampd(data, bufsize, pampd); - else - zv_decompress(virt_to_page(data), pampd); - return ret; -} - -static int zcache_pampd_get_data_and_free(char *data, size_t *bufsize, bool raw, - void *pampd, struct tmem_pool *pool, - struct tmem_oid *oid, uint32_t index) -{ - int ret = 0; - unsigned long flags; - struct zcache_client *cli = pool->client; - - BUG_ON(preemptible()); - BUG_ON(pampd_is_remote(pampd)); - if (is_ephemeral(pool)) { - local_irq_save(flags); - if (raw) - zbud_copy_from_pampd(data, bufsize, pampd); - else - ret = zbud_decompress(virt_to_page(data), pampd); - zbud_free_and_delist((struct zbud_hdr *)pampd); - local_irq_restore(flags); - if (!is_local_client(cli)) { - atomic_dec(&ramster_foreign_eph_pampd_count); - WARN_ON_ONCE(atomic_read(&ramster_foreign_eph_pampd_count) < 0); - } - atomic_dec(&zcache_curr_eph_pampd_count); - WARN_ON_ONCE(atomic_read(&zcache_curr_eph_pampd_count) < 0); - } else { - if (is_local_client(cli)) - BUG(); - if (raw) - zv_copy_from_pampd(data, bufsize, pampd); - else - zv_decompress(virt_to_page(data), pampd); - zv_free(cli->xvpool, pampd); - if (!is_local_client(cli)) { - atomic_dec(&ramster_foreign_pers_pampd_count); - WARN_ON_ONCE(atomic_read(&ramster_foreign_pers_pampd_count) < 0); - } - atomic_dec(&zcache_curr_pers_pampd_count); - WARN_ON_ONCE(atomic_read(&zcache_curr_pers_pampd_count) < 0); - ret = 0; - } - return ret; -} - -static bool zcache_pampd_is_remote(void *pampd) -{ - return pampd_is_remote(pampd); -} - -/* - * free the pampd and remove it from any zcache lists - * pampd must no longer be pointed to from any tmem data structures! - */ -static void zcache_pampd_free(void *pampd, struct tmem_pool *pool, - struct tmem_oid *oid, uint32_t index, bool acct) -{ - struct zcache_client *cli = pool->client; - bool eph = is_ephemeral(pool); - struct zv_hdr *zv; - - BUG_ON(preemptible()); - if (pampd_is_remote(pampd)) { - WARN_ON(acct == false); - if (oid == NULL) { - /* - * a NULL oid means to ignore this pampd free - * as the remote freeing will be handled elsewhere - */ - } else if (eph) { - /* FIXME remote flush optional but probably good idea */ - /* FIXME get these working properly again */ - atomic_dec(&zcache_curr_eph_pampd_count); - WARN_ON_ONCE(atomic_read(&zcache_curr_eph_pampd_count) < 0); - } else if (pampd_is_intransit(pampd)) { - /* did a pers remote get_and_free, so just free local */ - pampd = pampd_mask_intransit_and_remote(pampd); - goto local_pers; - } else { - struct flushlist_node *flnode = - ramster_flnode_alloc(pool); - - flnode->xh.client_id = pampd_remote_node(pampd); - flnode->xh.pool_id = pool->pool_id; - flnode->xh.oid = *oid; - flnode->xh.index = index; - flnode->rem_op.op = RAMSTER_REMOTIFY_FLUSH_PAGE; - spin_lock(&zcache_rem_op_list_lock); - list_add(&flnode->rem_op.list, &zcache_rem_op_list); - spin_unlock(&zcache_rem_op_list_lock); - atomic_dec(&zcache_curr_pers_pampd_count); - WARN_ON_ONCE(atomic_read(&zcache_curr_pers_pampd_count) < 0); - atomic_dec(&ramster_remote_pers_pages); - WARN_ON_ONCE(atomic_read(&ramster_remote_pers_pages) < 0); - } - } else if (eph) { - zbud_free_and_delist((struct zbud_hdr *)pampd); - if (!is_local_client(pool->client)) { - atomic_dec(&ramster_foreign_eph_pampd_count); - WARN_ON_ONCE(atomic_read(&ramster_foreign_eph_pampd_count) < 0); - } - if (acct) - atomic_dec(&zcache_curr_eph_pampd_count); - /* FIXME get these working properly again */ - WARN_ON_ONCE(atomic_read(&zcache_curr_eph_pampd_count) < 0); - } else { -local_pers: - zv = (struct zv_hdr *)pampd; - if (!is_local_client(pool->client)) { - atomic_dec(&ramster_foreign_pers_pampd_count); - WARN_ON_ONCE(atomic_read(&ramster_foreign_pers_pampd_count) < 0); - } - zv_free(cli->xvpool, zv); - if (acct) - atomic_dec(&zcache_curr_pers_pampd_count); - /* FIXME get these working properly again */ - WARN_ON_ONCE(atomic_read(&zcache_curr_pers_pampd_count) < 0); - } -} - -static void zcache_pampd_free_obj(struct tmem_pool *pool, - struct tmem_obj *obj) -{ - struct flushlist_node *flnode; - - BUG_ON(preemptible()); - if (obj->extra == NULL) - return; - BUG_ON(!pampd_is_remote(obj->extra)); - flnode = ramster_flnode_alloc(pool); - flnode->xh.client_id = pampd_remote_node(obj->extra); - flnode->xh.pool_id = pool->pool_id; - flnode->xh.oid = obj->oid; - flnode->xh.index = FLUSH_ENTIRE_OBJECT; - flnode->rem_op.op = RAMSTER_REMOTIFY_FLUSH_OBJ; - spin_lock(&zcache_rem_op_list_lock); - list_add(&flnode->rem_op.list, &zcache_rem_op_list); - spin_unlock(&zcache_rem_op_list_lock); -} - -void zcache_pampd_new_obj(struct tmem_obj *obj) -{ - obj->extra = NULL; -} - -int zcache_pampd_replace_in_obj(void *new_pampd, struct tmem_obj *obj) -{ - int ret = -1; - - if (new_pampd != NULL) { - if (obj->extra == NULL) - obj->extra = new_pampd; - /* enforce that all remote pages in an object reside - * in the same node! */ - else if (pampd_remote_node(new_pampd) != - pampd_remote_node((void *)(obj->extra))) - BUG(); - ret = 0; - } - return ret; -} - -/* - * Called by the message handler after a (still compressed) page has been - * fetched from the remote machine in response to an "is_remote" tmem_get - * or persistent tmem_localify. For a tmem_get, "extra" is the address of - * the page that is to be filled to succesfully resolve the tmem_get; for - * a (persistent) tmem_localify, "extra" is NULL (as the data is placed only - * in the local zcache). "data" points to "size" bytes of (compressed) data - * passed in the message. In the case of a persistent remote get, if - * pre-allocation was successful (see zcache_repatriate_preload), the page - * is placed into both local zcache and at "extra". - */ -int zcache_localify(int pool_id, struct tmem_oid *oidp, - uint32_t index, char *data, size_t size, - void *extra) -{ - int ret = -ENOENT; - unsigned long flags; - struct tmem_pool *pool; - bool ephemeral, delete = false; - size_t clen = PAGE_SIZE; - void *pampd, *saved_hb; - struct tmem_obj *obj; - - pool = zcache_get_pool_by_id(LOCAL_CLIENT, pool_id); - if (unlikely(pool == NULL)) - /* pool doesn't exist anymore */ - goto out; - ephemeral = is_ephemeral(pool); - local_irq_save(flags); /* FIXME: maybe only disable softirqs? */ - pampd = tmem_localify_get_pampd(pool, oidp, index, &obj, &saved_hb); - if (pampd == NULL) { - /* hmmm... must have been a flush while waiting */ -#ifdef RAMSTER_TESTING - pr_err("UNTESTED pampd==NULL in zcache_localify\n"); -#endif - if (ephemeral) - ramster_remote_eph_pages_unsucc_get++; - else - ramster_remote_pers_pages_unsucc_get++; - obj = NULL; - goto finish; - } else if (unlikely(!pampd_is_remote(pampd))) { - /* hmmm... must have been a dup put while waiting */ -#ifdef RAMSTER_TESTING - pr_err("UNTESTED dup while waiting in zcache_localify\n"); -#endif - if (ephemeral) - ramster_remote_eph_pages_unsucc_get++; - else - ramster_remote_pers_pages_unsucc_get++; - obj = NULL; - pampd = NULL; - ret = -EEXIST; - goto finish; - } else if (size == 0) { - /* no remote data, delete the local is_remote pampd */ - pampd = NULL; - if (ephemeral) - ramster_remote_eph_pages_unsucc_get++; - else - BUG(); - delete = true; - goto finish; - } - if (!ephemeral && pampd_is_intransit(pampd)) { - /* localify to zcache */ - pampd = pampd_mask_intransit_and_remote(pampd); - zv_copy_to_pampd(pampd, data, size); - } else { - pampd = NULL; - obj = NULL; - } - if (extra != NULL) { - /* decompress direct-to-memory to complete remotify */ - ret = lzo1x_decompress_safe((char *)data, size, - (char *)extra, &clen); - BUG_ON(ret != LZO_E_OK); - BUG_ON(clen != PAGE_SIZE); - } - if (ephemeral) - ramster_remote_eph_pages_succ_get++; - else - ramster_remote_pers_pages_succ_get++; - ret = 0; -finish: - tmem_localify_finish(obj, index, pampd, saved_hb, delete); - zcache_put_pool(pool); - local_irq_restore(flags); -out: - return ret; -} - -/* - * Called on a remote persistent tmem_get to attempt to preallocate - * local storage for the data contained in the remote persistent page. - * If succesfully preallocated, returns the pampd, marked as remote and - * in_transit. Else returns NULL. Note that the appropriate tmem data - * structure must be locked. - */ -static void *zcache_pampd_repatriate_preload(void *pampd, - struct tmem_pool *pool, - struct tmem_oid *oid, - uint32_t index, - bool *intransit) -{ - int clen = pampd_remote_size(pampd); - void *ret_pampd = NULL; - unsigned long flags; - - if (!pampd_is_remote(pampd)) - BUG(); - if (is_ephemeral(pool)) - BUG(); - if (pampd_is_intransit(pampd)) { - /* - * to avoid multiple allocations (and maybe a memory leak) - * don't preallocate if already in the process of being - * repatriated - */ - *intransit = true; - goto out; - } - *intransit = false; - local_irq_save(flags); - ret_pampd = (void *)zv_alloc(pool, oid, index, clen); - if (ret_pampd != NULL) { - /* - * a pampd is marked intransit if it is remote and space has - * been allocated for it locally (note, only happens for - * persistent pages, in which case the remote copy is freed) - */ - ret_pampd = pampd_mark_intransit(ret_pampd); - atomic_dec(&ramster_remote_pers_pages); - WARN_ON_ONCE(atomic_read(&ramster_remote_pers_pages) < 0); - } else - ramster_pers_pages_remote_nomem++; - local_irq_restore(flags); -out: - return ret_pampd; -} - -/* - * Called on a remote tmem_get to invoke a message to fetch the page. - * Might sleep so no tmem locks can be held. "extra" is passed - * all the way through the round-trip messaging to zcache_localify. - */ -static int zcache_pampd_repatriate(void *fake_pampd, void *real_pampd, - struct tmem_pool *pool, - struct tmem_oid *oid, uint32_t index, - bool free, void *extra) -{ - struct tmem_xhandle xh; - int ret; - - if (pampd_is_intransit(real_pampd)) - /* have local space pre-reserved, so free remote copy */ - free = true; - xh = tmem_xhandle_fill(LOCAL_CLIENT, pool, oid, index); - /* unreliable request/response for now */ - ret = ramster_remote_async_get(&xh, free, - pampd_remote_node(fake_pampd), - pampd_remote_size(fake_pampd), - pampd_remote_cksum(fake_pampd), - extra); -#ifdef RAMSTER_TESTING - if (ret != 0 && ret != -ENOENT) - pr_err("TESTING zcache_pampd_repatriate returns, ret=%d\n", - ret); -#endif - return ret; -} - -static struct tmem_pamops zcache_pamops = { - .create = zcache_pampd_create, - .get_data = zcache_pampd_get_data, - .free = zcache_pampd_free, - .get_data_and_free = zcache_pampd_get_data_and_free, - .free_obj = zcache_pampd_free_obj, - .is_remote = zcache_pampd_is_remote, - .repatriate_preload = zcache_pampd_repatriate_preload, - .repatriate = zcache_pampd_repatriate, - .new_obj = zcache_pampd_new_obj, - .replace_in_obj = zcache_pampd_replace_in_obj, -}; - -/* - * zcache compression/decompression and related per-cpu stuff - */ - -#define LZO_WORKMEM_BYTES LZO1X_1_MEM_COMPRESS -#define LZO_DSTMEM_PAGE_ORDER 1 -static DEFINE_PER_CPU(unsigned char *, zcache_workmem); -static DEFINE_PER_CPU(unsigned char *, zcache_dstmem); - -static int zcache_compress(struct page *from, void **out_va, size_t *out_len) -{ - int ret = 0; - unsigned char *dmem = __get_cpu_var(zcache_dstmem); - unsigned char *wmem = __get_cpu_var(zcache_workmem); - char *from_va; - - BUG_ON(!irqs_disabled()); - if (unlikely(dmem == NULL || wmem == NULL)) - goto out; /* no buffer, so can't compress */ - from_va = kmap_atomic(from, KM_USER0); - mb(); - ret = lzo1x_1_compress(from_va, PAGE_SIZE, dmem, out_len, wmem); - BUG_ON(ret != LZO_E_OK); - *out_va = dmem; - kunmap_atomic(from_va, KM_USER0); - ret = 1; -out: - return ret; -} - - -static int zcache_cpu_notifier(struct notifier_block *nb, - unsigned long action, void *pcpu) -{ - int cpu = (long)pcpu; - struct zcache_preload *kp; - - switch (action) { - case CPU_UP_PREPARE: - per_cpu(zcache_dstmem, cpu) = (void *)__get_free_pages( - GFP_KERNEL | __GFP_REPEAT, - LZO_DSTMEM_PAGE_ORDER), - per_cpu(zcache_workmem, cpu) = - kzalloc(LZO1X_MEM_COMPRESS, - GFP_KERNEL | __GFP_REPEAT); - per_cpu(zcache_remoteputmem, cpu) = - kzalloc(PAGE_SIZE, GFP_KERNEL | __GFP_REPEAT); - break; - case CPU_DEAD: - case CPU_UP_CANCELED: - kfree(per_cpu(zcache_remoteputmem, cpu)); - per_cpu(zcache_remoteputmem, cpu) = NULL; - free_pages((unsigned long)per_cpu(zcache_dstmem, cpu), - LZO_DSTMEM_PAGE_ORDER); - per_cpu(zcache_dstmem, cpu) = NULL; - kfree(per_cpu(zcache_workmem, cpu)); - per_cpu(zcache_workmem, cpu) = NULL; - kp = &per_cpu(zcache_preloads, cpu); - while (kp->nr) { - kmem_cache_free(zcache_objnode_cache, - kp->objnodes[kp->nr - 1]); - kp->objnodes[kp->nr - 1] = NULL; - kp->nr--; - } - if (kp->obj) { - kmem_cache_free(zcache_obj_cache, kp->obj); - kp->obj = NULL; - } - if (kp->flnode) { - kmem_cache_free(ramster_flnode_cache, kp->flnode); - kp->flnode = NULL; - } - if (kp->page) { - free_page((unsigned long)kp->page); - kp->page = NULL; - } - break; - default: - break; - } - return NOTIFY_OK; -} - -static struct notifier_block zcache_cpu_notifier_block = { - .notifier_call = zcache_cpu_notifier -}; - -#ifdef CONFIG_SYSFS -#define ZCACHE_SYSFS_RO(_name) \ - static ssize_t zcache_##_name##_show(struct kobject *kobj, \ - struct kobj_attribute *attr, char *buf) \ - { \ - return sprintf(buf, "%lu\n", zcache_##_name); \ - } \ - static struct kobj_attribute zcache_##_name##_attr = { \ - .attr = { .name = __stringify(_name), .mode = 0444 }, \ - .show = zcache_##_name##_show, \ - } - -#define ZCACHE_SYSFS_RO_ATOMIC(_name) \ - static ssize_t zcache_##_name##_show(struct kobject *kobj, \ - struct kobj_attribute *attr, char *buf) \ - { \ - return sprintf(buf, "%d\n", atomic_read(&zcache_##_name)); \ - } \ - static struct kobj_attribute zcache_##_name##_attr = { \ - .attr = { .name = __stringify(_name), .mode = 0444 }, \ - .show = zcache_##_name##_show, \ - } - -#define ZCACHE_SYSFS_RO_CUSTOM(_name, _func) \ - static ssize_t zcache_##_name##_show(struct kobject *kobj, \ - struct kobj_attribute *attr, char *buf) \ - { \ - return _func(buf); \ - } \ - static struct kobj_attribute zcache_##_name##_attr = { \ - .attr = { .name = __stringify(_name), .mode = 0444 }, \ - .show = zcache_##_name##_show, \ - } - -ZCACHE_SYSFS_RO(curr_obj_count_max); -ZCACHE_SYSFS_RO(curr_objnode_count_max); -ZCACHE_SYSFS_RO(flush_total); -ZCACHE_SYSFS_RO(flush_found); -ZCACHE_SYSFS_RO(flobj_total); -ZCACHE_SYSFS_RO(flobj_found); -ZCACHE_SYSFS_RO(failed_eph_puts); -ZCACHE_SYSFS_RO(nonactive_puts); -ZCACHE_SYSFS_RO(failed_pers_puts); -ZCACHE_SYSFS_RO(zbud_curr_zbytes); -ZCACHE_SYSFS_RO(zbud_cumul_zpages); -ZCACHE_SYSFS_RO(zbud_cumul_zbytes); -ZCACHE_SYSFS_RO(zbud_buddied_count); -ZCACHE_SYSFS_RO(evicted_raw_pages); -ZCACHE_SYSFS_RO(evicted_unbuddied_pages); -ZCACHE_SYSFS_RO(evicted_buddied_pages); -ZCACHE_SYSFS_RO(failed_get_free_pages); -ZCACHE_SYSFS_RO(failed_alloc); -ZCACHE_SYSFS_RO(put_to_flush); -ZCACHE_SYSFS_RO(compress_poor); -ZCACHE_SYSFS_RO(mean_compress_poor); -ZCACHE_SYSFS_RO(policy_percent_exceeded); -ZCACHE_SYSFS_RO_ATOMIC(zbud_curr_raw_pages); -ZCACHE_SYSFS_RO_ATOMIC(zbud_curr_zpages); -ZCACHE_SYSFS_RO_ATOMIC(curr_obj_count); -ZCACHE_SYSFS_RO_ATOMIC(curr_objnode_count); -ZCACHE_SYSFS_RO_CUSTOM(zbud_unbuddied_list_counts, - zbud_show_unbuddied_list_counts); -ZCACHE_SYSFS_RO_CUSTOM(zbud_cumul_chunk_counts, - zbud_show_cumul_chunk_counts); -ZCACHE_SYSFS_RO_CUSTOM(zv_curr_dist_counts, - zv_curr_dist_counts_show); -ZCACHE_SYSFS_RO_CUSTOM(zv_cumul_dist_counts, - zv_cumul_dist_counts_show); - -static struct attribute *zcache_attrs[] = { - &zcache_curr_obj_count_attr.attr, - &zcache_curr_obj_count_max_attr.attr, - &zcache_curr_objnode_count_attr.attr, - &zcache_curr_objnode_count_max_attr.attr, - &zcache_flush_total_attr.attr, - &zcache_flobj_total_attr.attr, - &zcache_flush_found_attr.attr, - &zcache_flobj_found_attr.attr, - &zcache_failed_eph_puts_attr.attr, - &zcache_nonactive_puts_attr.attr, - &zcache_failed_pers_puts_attr.attr, - &zcache_policy_percent_exceeded_attr.attr, - &zcache_compress_poor_attr.attr, - &zcache_mean_compress_poor_attr.attr, - &zcache_zbud_curr_raw_pages_attr.attr, - &zcache_zbud_curr_zpages_attr.attr, - &zcache_zbud_curr_zbytes_attr.attr, - &zcache_zbud_cumul_zpages_attr.attr, - &zcache_zbud_cumul_zbytes_attr.attr, - &zcache_zbud_buddied_count_attr.attr, - &zcache_evicted_raw_pages_attr.attr, - &zcache_evicted_unbuddied_pages_attr.attr, - &zcache_evicted_buddied_pages_attr.attr, - &zcache_failed_get_free_pages_attr.attr, - &zcache_failed_alloc_attr.attr, - &zcache_put_to_flush_attr.attr, - &zcache_zbud_unbuddied_list_counts_attr.attr, - &zcache_zbud_cumul_chunk_counts_attr.attr, - &zcache_zv_curr_dist_counts_attr.attr, - &zcache_zv_cumul_dist_counts_attr.attr, - &zcache_zv_max_zsize_attr.attr, - &zcache_zv_max_mean_zsize_attr.attr, - &zcache_zv_page_count_policy_percent_attr.attr, - NULL, -}; - -static struct attribute_group zcache_attr_group = { - .attrs = zcache_attrs, - .name = "zcache", -}; - -#define RAMSTER_SYSFS_RO(_name) \ - static ssize_t ramster_##_name##_show(struct kobject *kobj, \ - struct kobj_attribute *attr, char *buf) \ - { \ - return sprintf(buf, "%lu\n", ramster_##_name); \ - } \ - static struct kobj_attribute ramster_##_name##_attr = { \ - .attr = { .name = __stringify(_name), .mode = 0444 }, \ - .show = ramster_##_name##_show, \ - } - -#define RAMSTER_SYSFS_RW(_name) \ - static ssize_t ramster_##_name##_show(struct kobject *kobj, \ - struct kobj_attribute *attr, char *buf) \ - { \ - return sprintf(buf, "%lu\n", ramster_##_name); \ - } \ - static ssize_t ramster_##_name##_store(struct kobject *kobj, \ - struct kobj_attribute *attr, const char *buf, size_t count) \ - { \ - int err; \ - unsigned long enable; \ - err = strict_strtoul(buf, 10, &enable); \ - if (err) \ - return -EINVAL; \ - ramster_##_name = enable; \ - return count; \ - } \ - static struct kobj_attribute ramster_##_name##_attr = { \ - .attr = { .name = __stringify(_name), .mode = 0644 }, \ - .show = ramster_##_name##_show, \ - .store = ramster_##_name##_store, \ - } - -#define RAMSTER_SYSFS_RO_ATOMIC(_name) \ - static ssize_t ramster_##_name##_show(struct kobject *kobj, \ - struct kobj_attribute *attr, char *buf) \ - { \ - return sprintf(buf, "%d\n", atomic_read(&ramster_##_name)); \ - } \ - static struct kobj_attribute ramster_##_name##_attr = { \ - .attr = { .name = __stringify(_name), .mode = 0444 }, \ - .show = ramster_##_name##_show, \ - } - -RAMSTER_SYSFS_RO_ATOMIC(remote_pers_pages); -RAMSTER_SYSFS_RW(pers_remotify_enable); -RAMSTER_SYSFS_RW(eph_remotify_enable); -RAMSTER_SYSFS_RO(eph_pages_remoted); -RAMSTER_SYSFS_RO(eph_pages_remote_failed); -RAMSTER_SYSFS_RO(pers_pages_remoted); -RAMSTER_SYSFS_RO(pers_pages_remote_failed); -RAMSTER_SYSFS_RO(pers_pages_remote_nomem); -RAMSTER_SYSFS_RO(remote_pages_flushed); -RAMSTER_SYSFS_RO(remote_page_flushes_failed); -RAMSTER_SYSFS_RO(remote_objects_flushed); -RAMSTER_SYSFS_RO(remote_object_flushes_failed); -RAMSTER_SYSFS_RO(remote_eph_pages_succ_get); -RAMSTER_SYSFS_RO(remote_eph_pages_unsucc_get); -RAMSTER_SYSFS_RO(remote_pers_pages_succ_get); -RAMSTER_SYSFS_RO(remote_pers_pages_unsucc_get); -RAMSTER_SYSFS_RO_ATOMIC(foreign_eph_pampd_count); -RAMSTER_SYSFS_RO(foreign_eph_pampd_count_max); -RAMSTER_SYSFS_RO_ATOMIC(foreign_pers_pampd_count); -RAMSTER_SYSFS_RO(foreign_pers_pampd_count_max); -RAMSTER_SYSFS_RO_ATOMIC(curr_flnode_count); -RAMSTER_SYSFS_RO(curr_flnode_count_max); - -#define MANUAL_NODES 8 -static bool ramster_nodes_manual_up[MANUAL_NODES]; -static ssize_t ramster_manual_node_up_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - int i; - char *p = buf; - for (i = 0; i < MANUAL_NODES; i++) - if (ramster_nodes_manual_up[i]) - p += sprintf(p, "%d ", i); - p += sprintf(p, "\n"); - return p - buf; -} - -static ssize_t ramster_manual_node_up_store(struct kobject *kobj, - struct kobj_attribute *attr, const char *buf, size_t count) -{ - int err; - unsigned long node_num; - - err = strict_strtoul(buf, 10, &node_num); - if (err) { - pr_err("bad strtoul?\n"); - return -EINVAL; - } - if (node_num >= MANUAL_NODES) { - pr_err("bad node_num=%lu?\n", node_num); - return -EINVAL; - } - if (ramster_nodes_manual_up[node_num]) { - pr_err("node %d already up, ignoring\n", (int)node_num); - } else { - ramster_nodes_manual_up[node_num] = true; - o2net_hb_node_up_manual((int)node_num); - } - return count; -} - -static struct kobj_attribute ramster_manual_node_up_attr = { - .attr = { .name = "manual_node_up", .mode = 0644 }, - .show = ramster_manual_node_up_show, - .store = ramster_manual_node_up_store, -}; - -static struct attribute *ramster_attrs[] = { - &ramster_pers_remotify_enable_attr.attr, - &ramster_eph_remotify_enable_attr.attr, - &ramster_remote_pers_pages_attr.attr, - &ramster_eph_pages_remoted_attr.attr, - &ramster_eph_pages_remote_failed_attr.attr, - &ramster_pers_pages_remoted_attr.attr, - &ramster_pers_pages_remote_failed_attr.attr, - &ramster_pers_pages_remote_nomem_attr.attr, - &ramster_remote_pages_flushed_attr.attr, - &ramster_remote_page_flushes_failed_attr.attr, - &ramster_remote_objects_flushed_attr.attr, - &ramster_remote_object_flushes_failed_attr.attr, - &ramster_remote_eph_pages_succ_get_attr.attr, - &ramster_remote_eph_pages_unsucc_get_attr.attr, - &ramster_remote_pers_pages_succ_get_attr.attr, - &ramster_remote_pers_pages_unsucc_get_attr.attr, - &ramster_foreign_eph_pampd_count_attr.attr, - &ramster_foreign_eph_pampd_count_max_attr.attr, - &ramster_foreign_pers_pampd_count_attr.attr, - &ramster_foreign_pers_pampd_count_max_attr.attr, - &ramster_curr_flnode_count_attr.attr, - &ramster_curr_flnode_count_max_attr.attr, - &ramster_manual_node_up_attr.attr, - NULL, -}; - -static struct attribute_group ramster_attr_group = { - .attrs = ramster_attrs, - .name = "ramster", -}; - -#endif /* CONFIG_SYSFS */ -/* - * When zcache is disabled ("frozen"), pools can be created and destroyed, - * but all puts (and thus all other operations that require memory allocation) - * must fail. If zcache is unfrozen, accepts puts, then frozen again, - * data consistency requires all puts while frozen to be converted into - * flushes. - */ -static bool zcache_freeze; - -/* - * zcache shrinker interface (only useful for ephemeral pages, so zbud only) - */ -static int shrink_zcache_memory(struct shrinker *shrink, - struct shrink_control *sc) -{ - int ret = -1; - int nr = sc->nr_to_scan; - gfp_t gfp_mask = sc->gfp_mask; - - if (nr >= 0) { - if (!(gfp_mask & __GFP_FS)) - /* does this case really need to be skipped? */ - goto out; - zbud_evict_pages(nr); - } - ret = (int)atomic_read(&zcache_zbud_curr_raw_pages); -out: - return ret; -} - -static struct shrinker zcache_shrinker = { - .shrink = shrink_zcache_memory, - .seeks = DEFAULT_SEEKS, -}; - -/* - * zcache shims between cleancache/frontswap ops and tmem - */ - -int zcache_put(int cli_id, int pool_id, struct tmem_oid *oidp, - uint32_t index, char *data, size_t size, - bool raw, int ephemeral) -{ - struct tmem_pool *pool; - int ret = -1; - - BUG_ON(!irqs_disabled()); - pool = zcache_get_pool_by_id(cli_id, pool_id); - if (unlikely(pool == NULL)) - goto out; - if (!zcache_freeze && zcache_do_preload(pool) == 0) { - /* preload does preempt_disable on success */ - ret = tmem_put(pool, oidp, index, data, size, raw, ephemeral); - if (ret < 0) { - if (is_ephemeral(pool)) - zcache_failed_eph_puts++; - else - zcache_failed_pers_puts++; - } - zcache_put_pool(pool); - preempt_enable_no_resched(); - } else { - zcache_put_to_flush++; - if (atomic_read(&pool->obj_count) > 0) - /* the put fails whether the flush succeeds or not */ - (void)tmem_flush_page(pool, oidp, index); - zcache_put_pool(pool); - } -out: - return ret; -} - -int zcache_get(int cli_id, int pool_id, struct tmem_oid *oidp, - uint32_t index, char *data, size_t *sizep, - bool raw, int get_and_free) -{ - struct tmem_pool *pool; - int ret = -1; - bool eph; - - if (!raw) { - BUG_ON(irqs_disabled()); - BUG_ON(in_softirq()); - } - pool = zcache_get_pool_by_id(cli_id, pool_id); - eph = is_ephemeral(pool); - if (likely(pool != NULL)) { - if (atomic_read(&pool->obj_count) > 0) - ret = tmem_get(pool, oidp, index, data, sizep, - raw, get_and_free); - zcache_put_pool(pool); - } - WARN_ONCE((!eph && (ret != 0)), "zcache_get fails on persistent pool, " - "bad things are very likely to happen soon\n"); -#ifdef RAMSTER_TESTING - if (ret != 0 && ret != -1 && !(ret == -EINVAL && is_ephemeral(pool))) - pr_err("TESTING zcache_get tmem_get returns ret=%d\n", ret); -#endif - if (ret == -EAGAIN) - BUG(); /* FIXME... don't need this anymore??? let's ensure */ - return ret; -} - -int zcache_flush(int cli_id, int pool_id, - struct tmem_oid *oidp, uint32_t index) -{ - struct tmem_pool *pool; - int ret = -1; - unsigned long flags; - - local_irq_save(flags); - zcache_flush_total++; - pool = zcache_get_pool_by_id(cli_id, pool_id); - ramster_do_preload_flnode_only(pool); - if (likely(pool != NULL)) { - if (atomic_read(&pool->obj_count) > 0) - ret = tmem_flush_page(pool, oidp, index); - zcache_put_pool(pool); - } - if (ret >= 0) - zcache_flush_found++; - local_irq_restore(flags); - return ret; -} - -int zcache_flush_object(int cli_id, int pool_id, struct tmem_oid *oidp) -{ - struct tmem_pool *pool; - int ret = -1; - unsigned long flags; - - local_irq_save(flags); - zcache_flobj_total++; - pool = zcache_get_pool_by_id(cli_id, pool_id); - ramster_do_preload_flnode_only(pool); - if (likely(pool != NULL)) { - if (atomic_read(&pool->obj_count) > 0) - ret = tmem_flush_object(pool, oidp); - zcache_put_pool(pool); - } - if (ret >= 0) - zcache_flobj_found++; - local_irq_restore(flags); - return ret; -} - -int zcache_client_destroy_pool(int cli_id, int pool_id) -{ - struct tmem_pool *pool = NULL; - struct zcache_client *cli = NULL; - int ret = -1; - - if (pool_id < 0) - goto out; - if (cli_id == LOCAL_CLIENT) - cli = &zcache_host; - else if ((unsigned int)cli_id < MAX_CLIENTS) - cli = &zcache_clients[cli_id]; - if (cli == NULL) - goto out; - atomic_inc(&cli->refcount); - pool = cli->tmem_pools[pool_id]; - if (pool == NULL) - goto out; - cli->tmem_pools[pool_id] = NULL; - /* wait for pool activity on other cpus to quiesce */ - while (atomic_read(&pool->refcount) != 0) - ; - atomic_dec(&cli->refcount); - local_bh_disable(); - ret = tmem_destroy_pool(pool); - local_bh_enable(); - kfree(pool); - pr_info("ramster: destroyed pool id=%d cli_id=%d\n", pool_id, cli_id); -out: - return ret; -} - -static int zcache_destroy_pool(int pool_id) -{ - return zcache_client_destroy_pool(LOCAL_CLIENT, pool_id); -} - -int zcache_new_pool(uint16_t cli_id, uint32_t flags) -{ - int poolid = -1; - struct tmem_pool *pool; - struct zcache_client *cli = NULL; - - if (cli_id == LOCAL_CLIENT) - cli = &zcache_host; - else if ((unsigned int)cli_id < MAX_CLIENTS) - cli = &zcache_clients[cli_id]; - if (cli == NULL) - goto out; - atomic_inc(&cli->refcount); - pool = kmalloc(sizeof(struct tmem_pool), GFP_ATOMIC); - if (pool == NULL) { - pr_info("ramster: pool creation failed: out of memory\n"); - goto out; - } - - for (poolid = 0; poolid < MAX_POOLS_PER_CLIENT; poolid++) - if (cli->tmem_pools[poolid] == NULL) - break; - if (poolid >= MAX_POOLS_PER_CLIENT) { - pr_info("ramster: pool creation failed: max exceeded\n"); - kfree(pool); - poolid = -1; - goto out; - } - atomic_set(&pool->refcount, 0); - pool->client = cli; - pool->pool_id = poolid; - tmem_new_pool(pool, flags); - cli->tmem_pools[poolid] = pool; - pr_info("ramster: created %s tmem pool, id=%d, client=%d\n", - flags & TMEM_POOL_PERSIST ? "persistent" : "ephemeral", - poolid, cli_id); -out: - if (cli != NULL) - atomic_dec(&cli->refcount); - return poolid; -} - -static int zcache_local_new_pool(uint32_t flags) -{ - return zcache_new_pool(LOCAL_CLIENT, flags); -} - -int zcache_autocreate_pool(int cli_id, int pool_id, bool ephemeral) -{ - struct tmem_pool *pool; - struct zcache_client *cli = NULL; - uint32_t flags = ephemeral ? 0 : TMEM_POOL_PERSIST; - int ret = -1; - - if (cli_id == LOCAL_CLIENT) - goto out; - if (pool_id >= MAX_POOLS_PER_CLIENT) - goto out; - else if ((unsigned int)cli_id < MAX_CLIENTS) - cli = &zcache_clients[cli_id]; - if ((ephemeral && !use_cleancache) || (!ephemeral && !use_frontswap)) - BUG(); /* FIXME, handle more gracefully later */ - if (!cli->allocated) { - if (zcache_new_client(cli_id)) - BUG(); /* FIXME, handle more gracefully later */ - cli = &zcache_clients[cli_id]; - } - atomic_inc(&cli->refcount); - pool = cli->tmem_pools[pool_id]; - if (pool != NULL) { - if (pool->persistent && ephemeral) { - pr_err("zcache_autocreate_pool: type mismatch\n"); - goto out; - } - ret = 0; - goto out; - } - pool = kmalloc(sizeof(struct tmem_pool), GFP_KERNEL); - if (pool == NULL) { - pr_info("ramster: pool creation failed: out of memory\n"); - goto out; - } - atomic_set(&pool->refcount, 0); - pool->client = cli; - pool->pool_id = pool_id; - tmem_new_pool(pool, flags); - cli->tmem_pools[pool_id] = pool; - pr_info("ramster: AUTOcreated %s tmem poolid=%d, for remote client=%d\n", - flags & TMEM_POOL_PERSIST ? "persistent" : "ephemeral", - pool_id, cli_id); - ret = 0; -out: - if (cli == NULL) - BUG(); /* FIXME, handle more gracefully later */ - /* pr_err("zcache_autocreate_pool: failed\n"); */ - if (cli != NULL) - atomic_dec(&cli->refcount); - return ret; -} - -/********** - * Two kernel functionalities currently can be layered on top of tmem. - * These are "cleancache" which is used as a second-chance cache for clean - * page cache pages; and "frontswap" which is used for swap pages - * to avoid writes to disk. A generic "shim" is provided here for each - * to translate in-kernel semantics to zcache semantics. - */ - -#ifdef CONFIG_CLEANCACHE -static void zcache_cleancache_put_page(int pool_id, - struct cleancache_filekey key, - pgoff_t index, struct page *page) -{ - u32 ind = (u32) index; - struct tmem_oid oid = *(struct tmem_oid *)&key; - -#ifdef __PG_WAS_ACTIVE - if (!PageWasActive(page)) { - zcache_nonactive_puts++; - return; - } -#endif - if (likely(ind == index)) { - char *kva = page_address(page); - - (void)zcache_put(LOCAL_CLIENT, pool_id, &oid, index, - kva, PAGE_SIZE, 0, 1); - } -} - -static int zcache_cleancache_get_page(int pool_id, - struct cleancache_filekey key, - pgoff_t index, struct page *page) -{ - u32 ind = (u32) index; - struct tmem_oid oid = *(struct tmem_oid *)&key; - int ret = -1; - - preempt_disable(); - if (likely(ind == index)) { - char *kva = page_address(page); - size_t size = PAGE_SIZE; - - ret = zcache_get(LOCAL_CLIENT, pool_id, &oid, index, - kva, &size, 0, 0); -#ifdef __PG_WAS_ACTIVE - if (ret == 0) - SetPageWasActive(page); -#endif - } - preempt_enable(); - return ret; -} - -static void zcache_cleancache_flush_page(int pool_id, - struct cleancache_filekey key, - pgoff_t index) -{ - u32 ind = (u32) index; - struct tmem_oid oid = *(struct tmem_oid *)&key; - - if (likely(ind == index)) - (void)zcache_flush(LOCAL_CLIENT, pool_id, &oid, ind); -} - -static void zcache_cleancache_flush_inode(int pool_id, - struct cleancache_filekey key) -{ - struct tmem_oid oid = *(struct tmem_oid *)&key; - - (void)zcache_flush_object(LOCAL_CLIENT, pool_id, &oid); -} - -static void zcache_cleancache_flush_fs(int pool_id) -{ - if (pool_id >= 0) - (void)zcache_destroy_pool(pool_id); -} - -static int zcache_cleancache_init_fs(size_t pagesize) -{ - BUG_ON(sizeof(struct cleancache_filekey) != - sizeof(struct tmem_oid)); - BUG_ON(pagesize != PAGE_SIZE); - return zcache_local_new_pool(0); -} - -static int zcache_cleancache_init_shared_fs(char *uuid, size_t pagesize) -{ - /* shared pools are unsupported and map to private */ - BUG_ON(sizeof(struct cleancache_filekey) != - sizeof(struct tmem_oid)); - BUG_ON(pagesize != PAGE_SIZE); - return zcache_local_new_pool(0); -} - -static struct cleancache_ops zcache_cleancache_ops = { - .put_page = zcache_cleancache_put_page, - .get_page = zcache_cleancache_get_page, - .invalidate_page = zcache_cleancache_flush_page, - .invalidate_inode = zcache_cleancache_flush_inode, - .invalidate_fs = zcache_cleancache_flush_fs, - .init_shared_fs = zcache_cleancache_init_shared_fs, - .init_fs = zcache_cleancache_init_fs -}; - -struct cleancache_ops zcache_cleancache_register_ops(void) -{ - struct cleancache_ops old_ops = - cleancache_register_ops(&zcache_cleancache_ops); - - return old_ops; -} -#endif - -#ifdef CONFIG_FRONTSWAP -/* a single tmem poolid is used for all frontswap "types" (swapfiles) */ -static int zcache_frontswap_poolid = -1; - -/* - * Swizzling increases objects per swaptype, increasing tmem concurrency - * for heavy swaploads. Later, larger nr_cpus -> larger SWIZ_BITS - */ -#define SWIZ_BITS 8 -#define SWIZ_MASK ((1 << SWIZ_BITS) - 1) -#define _oswiz(_type, _ind) ((_type << SWIZ_BITS) | (_ind & SWIZ_MASK)) -#define iswiz(_ind) (_ind >> SWIZ_BITS) - -static inline struct tmem_oid oswiz(unsigned type, u32 ind) -{ - struct tmem_oid oid = { .oid = { 0 } }; - oid.oid[0] = _oswiz(type, ind); - return oid; -} - -static int zcache_frontswap_put_page(unsigned type, pgoff_t offset, - struct page *page) -{ - u64 ind64 = (u64)offset; - u32 ind = (u32)offset; - struct tmem_oid oid = oswiz(type, ind); - int ret = -1; - unsigned long flags; - char *kva; - - BUG_ON(!PageLocked(page)); - if (likely(ind64 == ind)) { - local_irq_save(flags); - kva = page_address(page); - ret = zcache_put(LOCAL_CLIENT, zcache_frontswap_poolid, - &oid, iswiz(ind), kva, PAGE_SIZE, 0, 0); - local_irq_restore(flags); - } - return ret; -} - -/* returns 0 if the page was successfully gotten from frontswap, -1 if - * was not present (should never happen!) */ -static int zcache_frontswap_get_page(unsigned type, pgoff_t offset, - struct page *page) -{ - u64 ind64 = (u64)offset; - u32 ind = (u32)offset; - struct tmem_oid oid = oswiz(type, ind); - int ret = -1; - - preempt_disable(); /* FIXME, remove this? */ - BUG_ON(!PageLocked(page)); - if (likely(ind64 == ind)) { - char *kva = page_address(page); - size_t size = PAGE_SIZE; - - ret = zcache_get(LOCAL_CLIENT, zcache_frontswap_poolid, - &oid, iswiz(ind), kva, &size, 0, -1); - } - preempt_enable(); /* FIXME, remove this? */ - return ret; -} - -/* flush a single page from frontswap */ -static void zcache_frontswap_flush_page(unsigned type, pgoff_t offset) -{ - u64 ind64 = (u64)offset; - u32 ind = (u32)offset; - struct tmem_oid oid = oswiz(type, ind); - - if (likely(ind64 == ind)) - (void)zcache_flush(LOCAL_CLIENT, zcache_frontswap_poolid, - &oid, iswiz(ind)); -} - -/* flush all pages from the passed swaptype */ -static void zcache_frontswap_flush_area(unsigned type) -{ - struct tmem_oid oid; - int ind; - - for (ind = SWIZ_MASK; ind >= 0; ind--) { - oid = oswiz(type, ind); - (void)zcache_flush_object(LOCAL_CLIENT, - zcache_frontswap_poolid, &oid); - } -} - -static void zcache_frontswap_init(unsigned ignored) -{ - /* a single tmem poolid is used for all frontswap "types" (swapfiles) */ - if (zcache_frontswap_poolid < 0) - zcache_frontswap_poolid = - zcache_local_new_pool(TMEM_POOL_PERSIST); -} - -static struct frontswap_ops zcache_frontswap_ops = { - .put_page = zcache_frontswap_put_page, - .get_page = zcache_frontswap_get_page, - .invalidate_page = zcache_frontswap_flush_page, - .invalidate_area = zcache_frontswap_flush_area, - .init = zcache_frontswap_init -}; - -struct frontswap_ops zcache_frontswap_register_ops(void) -{ - struct frontswap_ops old_ops = - frontswap_register_ops(&zcache_frontswap_ops); - - return old_ops; -} -#endif - -/* - * frontswap selfshrinking - */ - -#ifdef CONFIG_FRONTSWAP -/* In HZ, controls frequency of worker invocation. */ -static unsigned int selfshrink_interval __read_mostly = 5; - -static void selfshrink_process(struct work_struct *work); -static DECLARE_DELAYED_WORK(selfshrink_worker, selfshrink_process); - -/* Enable/disable with sysfs. */ -static bool frontswap_selfshrinking __read_mostly; - -/* Enable/disable with kernel boot option. */ -static bool use_frontswap_selfshrink __initdata = true; - -/* - * The default values for the following parameters were deemed reasonable - * by experimentation, may be workload-dependent, and can all be - * adjusted via sysfs. - */ - -/* Control rate for frontswap shrinking. Higher hysteresis is slower. */ -static unsigned int frontswap_hysteresis __read_mostly = 20; - -/* - * Number of selfshrink worker invocations to wait before observing that - * frontswap selfshrinking should commence. Note that selfshrinking does - * not use a separate worker thread. - */ -static unsigned int frontswap_inertia __read_mostly = 3; - -/* Countdown to next invocation of frontswap_shrink() */ -static unsigned long frontswap_inertia_counter; - -/* - * Invoked by the selfshrink worker thread, uses current number of pages - * in frontswap (frontswap_curr_pages()), previous status, and control - * values (hysteresis and inertia) to determine if frontswap should be - * shrunk and what the new frontswap size should be. Note that - * frontswap_shrink is essentially a partial swapoff that immediately - * transfers pages from the "swap device" (frontswap) back into kernel - * RAM; despite the name, frontswap "shrinking" is very different from - * the "shrinker" interface used by the kernel MM subsystem to reclaim - * memory. - */ -static void frontswap_selfshrink(void) -{ - static unsigned long cur_frontswap_pages; - static unsigned long last_frontswap_pages; - static unsigned long tgt_frontswap_pages; - - last_frontswap_pages = cur_frontswap_pages; - cur_frontswap_pages = frontswap_curr_pages(); - if (!cur_frontswap_pages || - (cur_frontswap_pages > last_frontswap_pages)) { - frontswap_inertia_counter = frontswap_inertia; - return; - } - if (frontswap_inertia_counter && --frontswap_inertia_counter) - return; - if (cur_frontswap_pages <= frontswap_hysteresis) - tgt_frontswap_pages = 0; - else - tgt_frontswap_pages = cur_frontswap_pages - - (cur_frontswap_pages / frontswap_hysteresis); - frontswap_shrink(tgt_frontswap_pages); -} - -static int __init ramster_nofrontswap_selfshrink_setup(char *s) -{ - use_frontswap_selfshrink = false; - return 1; -} - -__setup("noselfshrink", ramster_nofrontswap_selfshrink_setup); - -static void selfshrink_process(struct work_struct *work) -{ - if (frontswap_selfshrinking && frontswap_enabled) { - frontswap_selfshrink(); - schedule_delayed_work(&selfshrink_worker, - selfshrink_interval * HZ); - } -} - -static int ramster_enabled; - -static int __init ramster_selfshrink_init(void) -{ - frontswap_selfshrinking = ramster_enabled && use_frontswap_selfshrink; - if (frontswap_selfshrinking) - pr_info("ramster: Initializing frontswap " - "selfshrinking driver.\n"); - else - return -ENODEV; - - schedule_delayed_work(&selfshrink_worker, selfshrink_interval * HZ); - - return 0; -} - -subsys_initcall(ramster_selfshrink_init); -#endif - -/* - * zcache initialization - * NOTE FOR NOW ramster MUST BE PROVIDED AS A KERNEL BOOT PARAMETER OR - * NOTHING HAPPENS! - */ - -static int ramster_enabled; - -static int __init enable_ramster(char *s) -{ - ramster_enabled = 1; - return 1; -} -__setup("ramster", enable_ramster); - -/* allow independent dynamic disabling of cleancache and frontswap */ - -static int use_cleancache = 1; - -static int __init no_cleancache(char *s) -{ - pr_info("INIT no_cleancache called\n"); - use_cleancache = 0; - return 1; -} - -/* - * FIXME: need to guarantee this gets checked before zcache_init is called - * What is the correct way to achieve this? - */ -early_param("nocleancache", no_cleancache); - -static int use_frontswap = 1; - -static int __init no_frontswap(char *s) -{ - pr_info("INIT no_frontswap called\n"); - use_frontswap = 0; - return 1; -} - -__setup("nofrontswap", no_frontswap); - -static int __init zcache_init(void) -{ - int ret = 0; - -#ifdef CONFIG_SYSFS - ret = sysfs_create_group(mm_kobj, &zcache_attr_group); - ret = sysfs_create_group(mm_kobj, &ramster_attr_group); - if (ret) { - pr_err("ramster: can't create sysfs\n"); - goto out; - } -#endif /* CONFIG_SYSFS */ -#if defined(CONFIG_CLEANCACHE) || defined(CONFIG_FRONTSWAP) - if (ramster_enabled) { - unsigned int cpu; - - (void)ramster_o2net_register_handlers(); - tmem_register_hostops(&zcache_hostops); - tmem_register_pamops(&zcache_pamops); - ret = register_cpu_notifier(&zcache_cpu_notifier_block); - if (ret) { - pr_err("ramster: can't register cpu notifier\n"); - goto out; - } - for_each_online_cpu(cpu) { - void *pcpu = (void *)(long)cpu; - zcache_cpu_notifier(&zcache_cpu_notifier_block, - CPU_UP_PREPARE, pcpu); - } - } - zcache_objnode_cache = kmem_cache_create("zcache_objnode", - sizeof(struct tmem_objnode), 0, 0, NULL); - zcache_obj_cache = kmem_cache_create("zcache_obj", - sizeof(struct tmem_obj), 0, 0, NULL); - ramster_flnode_cache = kmem_cache_create("ramster_flnode", - sizeof(struct flushlist_node), 0, 0, NULL); -#endif -#ifdef CONFIG_CLEANCACHE - pr_info("INIT ramster_enabled=%d use_cleancache=%d\n", - ramster_enabled, use_cleancache); - if (ramster_enabled && use_cleancache) { - struct cleancache_ops old_ops; - - zbud_init(); - register_shrinker(&zcache_shrinker); - old_ops = zcache_cleancache_register_ops(); - pr_info("ramster: cleancache enabled using kernel " - "transcendent memory and compression buddies\n"); - if (old_ops.init_fs != NULL) - pr_warning("ramster: cleancache_ops overridden"); - } -#endif -#ifdef CONFIG_FRONTSWAP - pr_info("INIT ramster_enabled=%d use_frontswap=%d\n", - ramster_enabled, use_frontswap); - if (ramster_enabled && use_frontswap) { - struct frontswap_ops old_ops; - - zcache_new_client(LOCAL_CLIENT); - old_ops = zcache_frontswap_register_ops(); - pr_info("ramster: frontswap enabled using kernel " - "transcendent memory and xvmalloc\n"); - if (old_ops.init != NULL) - pr_warning("ramster: frontswap_ops overridden"); - } - if (ramster_enabled && (use_frontswap || use_cleancache)) - ramster_remotify_init(); -#endif -out: - return ret; -} - -module_init(zcache_init) diff --git a/drivers/staging/ramster/zcache.h b/drivers/staging/ramster/zcache.h deleted file mode 100644 index 250b121c22e..00000000000 --- a/drivers/staging/ramster/zcache.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * zcache.h - * - * External zcache functions - * - * Copyright (c) 2009-2012, Dan Magenheimer, Oracle Corp. - */ - -#ifndef _ZCACHE_H_ -#define _ZCACHE_H_ - -extern int zcache_put(int, int, struct tmem_oid *, uint32_t, - char *, size_t, bool, int); -extern int zcache_autocreate_pool(int, int, bool); -extern int zcache_get(int, int, struct tmem_oid *, uint32_t, - char *, size_t *, bool, int); -extern int zcache_flush(int, int, struct tmem_oid *, uint32_t); -extern int zcache_flush_object(int, int, struct tmem_oid *); -extern int zcache_localify(int, struct tmem_oid *, uint32_t, - char *, size_t, void *); - -#endif /* _ZCACHE_H */ -- cgit v1.2.3-70-g09d2 From 84359ef62aa36dc92508547852587b284c2664d2 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Thu, 9 Feb 2012 21:11:43 +0100 Subject: staging/xgifb: Include sis initdef.h header This patch includes the initdef.h header from the sis driver. Since the xgi driver used to redefine a lot of stuff from the sis driver, we can simply include the headers of the sis driver itself, so we can remove duplicated stuff later on. In order to include the initdef.h we have to rename the header guards. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_def.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h index 5beeef99bb1..0472c86b292 100644 --- a/drivers/staging/xgifb/vb_def.h +++ b/drivers/staging/xgifb/vb_def.h @@ -1,7 +1,8 @@ /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/xgi/initdef.h * ,v 1.4 2000/12/02 01:16:17 dawes Exp $*/ -#ifndef _INITDEF_ -#define _INITDEF_ +#ifndef _VB_DEF_ +#define _VB_DEF_ +#include "../../video/sis/initdef.h" #define VB_XGI301C 0x0020 /* for 301C */ /*end 301b*/ -- cgit v1.2.3-70-g09d2 From 255aabd2b8ad98a49d224b243c7b1f82adcdfb4a Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Thu, 9 Feb 2012 21:11:44 +0100 Subject: staging/xgifb: Rename panel defines and remove duplicated defines This patch renames the Panel* defines and their usage to the naming convention of the sis initdef.h and removes the now duplicated defines. Renames: Panel320x480 -> Panel_320x480 Panel800x600 -> Panel_800x600 Panel1024x768 -> Panel_1024x768 Panel1024x768x75 -> Panel_1024x768x75 Panel1280x1024 -> Panel_1280x1024 Panel1280x1024x75 -> Panel_1280x1024x75 Panel1280x960 -> Panel_1280x960 Panel1400x1050 -> Panel_1400x1050 Panel1600x1200 -> Panel_1600x1200 Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_def.h | 13 +-- drivers/staging/xgifb/vb_setmode.c | 94 ++++++++++----------- drivers/staging/xgifb/vb_table.h | 168 ++++++++++++++++++------------------- 3 files changed, 134 insertions(+), 141 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h index 0472c86b292..9b2937c4b9f 100644 --- a/drivers/staging/xgifb/vb_def.h +++ b/drivers/staging/xgifb/vb_def.h @@ -19,18 +19,11 @@ #define PanelRGB18Bit 0x0100 #define PanelRGB24Bit 0x0000 -#define Panel320x480 0x07 /*fstn*/ +#define Panel_320x480 0x07 /*fstn*/ /* [ycchen] 02/12/03 Modify for Multi-Sync. LCD Support */ #define PanelResInfo 0x1F /* CR36 Panel Type/LCDResInfo */ -#define Panel800x600 0x01 -#define Panel1024x768 0x02 -#define Panel1024x768x75 0x22 -#define Panel1280x1024 0x03 -#define Panel1280x1024x75 0x23 -#define Panel640x480 0x04 -#define Panel1280x960 0x07 -#define Panel1400x1050 0x09 -#define Panel1600x1200 0x0B +#define Panel_1024x768x75 0x22 +#define Panel_1280x1024x75 0x23 #define PanelRef60Hz 0x00 #define PanelRef75Hz 0x20 diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index fad144c565c..25c647b348b 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -359,8 +359,8 @@ static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { tempax |= SupportLCD; - if (pVBInfo->LCDResInfo != Panel1280x1024) { - if (pVBInfo->LCDResInfo != Panel1280x960) { + if (pVBInfo->LCDResInfo != Panel_1280x1024) { + if (pVBInfo->LCDResInfo != Panel_1280x960) { if (pVBInfo->LCDInfo & LCDNonExpanding) { if (resinfo >= 9) { @@ -436,7 +436,7 @@ static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, if (resinfo > 0x08) return 0; /* 1024x768 */ - if (pVBInfo->LCDResInfo < Panel1024x768) { + if (pVBInfo->LCDResInfo < Panel_1024x768) { if (resinfo > 0x07) return 0; /* 800x600 */ @@ -1267,7 +1267,7 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, if (pVBInfo->IF_DEF_LVDS == 0) { CRT2Index = CRT2Index >> 6; /* for LCD */ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /*301b*/ - if (pVBInfo->LCDResInfo != Panel1024x768) + if (pVBInfo->LCDResInfo != Panel_1024x768) VCLKIndex = LCDXlat2VCLK[CRT2Index]; else VCLKIndex = LCDXlat1VCLK[CRT2Index]; @@ -1329,11 +1329,11 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, VCLKIndex = CRT2Index; VCLKIndex = VCLKIndex >> 6; - if ((pVBInfo->LCDResInfo == Panel800x600) || - (pVBInfo->LCDResInfo == Panel320x480)) + if ((pVBInfo->LCDResInfo == Panel_800x600) || + (pVBInfo->LCDResInfo == Panel_320x480)) VCLKIndex = LVDSXlat1VCLK[VCLKIndex]; - else if ((pVBInfo->LCDResInfo == Panel1024x768) || - (pVBInfo->LCDResInfo == Panel1024x768x75)) + else if ((pVBInfo->LCDResInfo == Panel_1024x768) || + (pVBInfo->LCDResInfo == Panel_1024x768x75)) VCLKIndex = LVDSXlat2VCLK[VCLKIndex]; else VCLKIndex = LVDSXlat3VCLK[VCLKIndex]; @@ -2377,15 +2377,15 @@ static void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { if (!(pVBInfo->LCDInfo & (SetLCDtoNonExpanding | EnableScalingLCD))) { - if ((pVBInfo->LCDResInfo == Panel1024x768) || - (pVBInfo->LCDResInfo == Panel1024x768x75)) { + if ((pVBInfo->LCDResInfo == Panel_1024x768) || + (pVBInfo->LCDResInfo == Panel_1024x768x75)) { pVBInfo->HDE = 1024; pVBInfo->VDE = 768; - } else if ((pVBInfo->LCDResInfo == Panel1280x1024) || - (pVBInfo->LCDResInfo == Panel1280x1024x75)) { + } else if ((pVBInfo->LCDResInfo == Panel_1280x1024) || + (pVBInfo->LCDResInfo == Panel_1280x1024x75)) { pVBInfo->HDE = 1280; pVBInfo->VDE = 1024; - } else if (pVBInfo->LCDResInfo == Panel1400x1050) { + } else if (pVBInfo->LCDResInfo == Panel_1400x1050) { pVBInfo->HDE = 1400; pVBInfo->VDE = 1050; } else { @@ -2496,7 +2496,7 @@ static unsigned short XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo) } if (tempbl == 0xFF) { - pVBInfo->LCDResInfo = Panel1024x768; + pVBInfo->LCDResInfo = Panel_1024x768; pVBInfo->LCDTypeInfo = 0; i = 0; } @@ -2556,15 +2556,15 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, push2 = tempax; /* GetLCDResInfo */ - if ((pVBInfo->LCDResInfo == Panel1024x768) || - (pVBInfo->LCDResInfo == Panel1024x768x75)) { + if ((pVBInfo->LCDResInfo == Panel_1024x768) || + (pVBInfo->LCDResInfo == Panel_1024x768x75)) { tempax = 1024; tempbx = 768; - } else if ((pVBInfo->LCDResInfo == Panel1280x1024) || - (pVBInfo->LCDResInfo == Panel1280x1024x75)) { + } else if ((pVBInfo->LCDResInfo == Panel_1280x1024) || + (pVBInfo->LCDResInfo == Panel_1280x1024x75)) { tempax = 1280; tempbx = 1024; - } else if (pVBInfo->LCDResInfo == Panel1400x1050) { + } else if (pVBInfo->LCDResInfo == Panel_1400x1050) { tempax = 1400; tempbx = 1050; } else { @@ -2768,7 +2768,7 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, temp1 = temp1 / push3; tempbx = (unsigned short) (temp1 & 0xffff); - if (pVBInfo->LCDResInfo == Panel1024x768) + if (pVBInfo->LCDResInfo == Panel_1024x768) tempbx -= 1; tempax = ((tempbx >> 8) & 0xff) << 3; @@ -3386,10 +3386,10 @@ static unsigned char XGI_GetLCDInfo(unsigned short ModeNo, tempbx = temp & 0x0F; if (tempbx == 0) - tempbx = Panel1024x768; /* default */ + tempbx = Panel_1024x768; /* default */ /* LCD75 [2003/8/22] Vicent */ - if ((tempbx == Panel1024x768) || (tempbx == Panel1280x1024)) { + if ((tempbx == Panel_1024x768) || (tempbx == Panel_1280x1024)) { if (pVBInfo->VBInfo & DriverMode) { tempax = xgifb_reg_get(pVBInfo->P3d4, 0x33); if (pVBInfo->VBInfo & SetCRT2ToLCDA) @@ -3434,10 +3434,10 @@ static unsigned char XGI_GetLCDInfo(unsigned short ModeNo, } if (pVBInfo->IF_DEF_LVDS == 0) { - if ((pVBInfo->LCDResInfo == Panel1400x1050) && (pVBInfo->VBInfo + if ((pVBInfo->LCDResInfo == Panel_1400x1050) && (pVBInfo->VBInfo & SetCRT2ToLCD) && (ModeNo > 0x13) && (resinfo == 9) && (!(tempbx & EnableScalingLCD))) - /* set to center in 1280x1024 LCDB for Panel1400x1050 */ + /* set to center in 1280x1024 LCDB for Panel_1400x1050 */ tempbx |= SetLCDtoNonExpanding; } @@ -3448,7 +3448,7 @@ static unsigned char XGI_GetLCDInfo(unsigned short ModeNo, } else { if (ModeNo > 0x13) { if (pVBInfo->LCDResInfo - == Panel1024x768) { + == Panel_1024x768) { if (resinfo == 4) {/* 512x384 */ tempbx |= EnableLVDSDDA; } @@ -3801,14 +3801,14 @@ static void XGI_GetCRT2ResInfo(unsigned short ModeNo, if (pVBInfo->VBInfo & SetCRT2ToLCD) { if (pVBInfo->IF_DEF_LVDS == 0) { - if (pVBInfo->LCDResInfo == Panel1600x1200) { + if (pVBInfo->LCDResInfo == Panel_1600x1200) { if (!(pVBInfo->LCDInfo & LCDVESATiming)) { if (yres == 1024) yres = 1056; } } - if (pVBInfo->LCDResInfo == Panel1280x1024) { + if (pVBInfo->LCDResInfo == Panel_1280x1024) { if (yres == 400) yres = 405; else if (yres == 350) @@ -3820,7 +3820,7 @@ static void XGI_GetCRT2ResInfo(unsigned short ModeNo, } } - if (pVBInfo->LCDResInfo == Panel1024x768) { + if (pVBInfo->LCDResInfo == Panel_1024x768) { if (!(pVBInfo->LCDInfo & LCDVESATiming)) { if (!(pVBInfo->LCDInfo & LCDNonExpanding)) { @@ -3954,7 +3954,7 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, pVBInfo->HT = LCDPtr->LCDHT; pVBInfo->VT = LCDPtr->LCDVT; - if (pVBInfo->LCDResInfo == Panel1024x768) { + if (pVBInfo->LCDResInfo == Panel_1024x768) { tempax = 1024; tempbx = 768; @@ -3971,10 +3971,10 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, tempbx = 768; } else tempbx = 768; - } else if (pVBInfo->LCDResInfo == Panel1024x768x75) { + } else if (pVBInfo->LCDResInfo == Panel_1024x768x75) { tempax = 1024; tempbx = 768; - } else if (pVBInfo->LCDResInfo == Panel1280x1024) { + } else if (pVBInfo->LCDResInfo == Panel_1280x1024) { tempax = 1280; if (pVBInfo->VGAVDE == 360) tempbx = 768; @@ -3984,10 +3984,10 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, tempbx = 864; else tempbx = 1024; - } else if (pVBInfo->LCDResInfo == Panel1280x1024x75) { + } else if (pVBInfo->LCDResInfo == Panel_1280x1024x75) { tempax = 1280; tempbx = 1024; - } else if (pVBInfo->LCDResInfo == Panel1280x960) { + } else if (pVBInfo->LCDResInfo == Panel_1280x960) { tempax = 1280; if (pVBInfo->VGAVDE == 350) tempbx = 700; @@ -3997,7 +3997,7 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, tempbx = 960; else tempbx = 960; - } else if (pVBInfo->LCDResInfo == Panel1400x1050) { + } else if (pVBInfo->LCDResInfo == Panel_1400x1050) { tempax = 1400; tempbx = 1050; @@ -4005,7 +4005,7 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, tempax = 1280; tempbx = 1024; } - } else if (pVBInfo->LCDResInfo == Panel1600x1200) { + } else if (pVBInfo->LCDResInfo == Panel_1600x1200) { tempax = 1600; tempbx = 1200; /* alan 10/14/2003 */ if (!(pVBInfo->LCDInfo & LCDVESATiming)) { @@ -4513,19 +4513,19 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, } } else if (!(modeflag & HalfDCLK)) { temp -= 4; - if (pVBInfo->LCDResInfo != Panel1280x960 && + if (pVBInfo->LCDResInfo != Panel_1280x960 && pVBInfo->VGAHDE >= 800) { temp -= 7; if (pVBInfo->ModeType == ModeEGA && pVBInfo->VGAVDE == 1024) { temp += 15; if (pVBInfo->LCDResInfo != - Panel1280x1024) + Panel_1280x1024) temp += 7; } if (pVBInfo->VGAHDE >= 1280 && - pVBInfo->LCDResInfo != Panel1280x960 && + pVBInfo->LCDResInfo != Panel_1280x960 && (pVBInfo->LCDInfo & LCDNonExpanding)) temp += 28; } @@ -4619,7 +4619,7 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, push2 = tempbx; if (pVBInfo->VBInfo & SetCRT2ToLCD) { - if (pVBInfo->LCDResInfo == Panel1024x768) { + if (pVBInfo->LCDResInfo == Panel_1024x768) { if (!(pVBInfo->LCDInfo & LCDVESATiming)) { if (tempbx == 350) tempbx += 5; @@ -5267,7 +5267,7 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, xgifb_reg_and_or(pVBInfo->Part2Port, 0x2B, 0x0F, temp); temp = 0x01; - if (pVBInfo->LCDResInfo == Panel1280x1024) { + if (pVBInfo->LCDResInfo == Panel_1280x1024) { if (pVBInfo->ModeType == ModeEGA) { if (pVBInfo->VGAHDE >= 1024) { temp = 0x02; @@ -5305,14 +5305,14 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, tempah = pVBInfo->LCDResInfo; tempah &= PanelResInfo; - if ((tempah == Panel1024x768) || (tempah == Panel1024x768x75)) { + if ((tempah == Panel_1024x768) || (tempah == Panel_1024x768x75)) { tempbx = 1024; tempcx = 768; - } else if ((tempah == Panel1280x1024) || - (tempah == Panel1280x1024x75)) { + } else if ((tempah == Panel_1280x1024) || + (tempah == Panel_1280x1024x75)) { tempbx = 1280; tempcx = 1024; - } else if (tempah == Panel1400x1050) { + } else if (tempah == Panel_1400x1050) { tempbx = 1400; tempcx = 1050; } else { @@ -6807,11 +6807,11 @@ static void XGI_SetCRT2ModeRegs(unsigned short ModeNo, tempah |= 0x40; } - if ((pVBInfo->LCDResInfo == Panel1280x1024) - || (pVBInfo->LCDResInfo == Panel1280x1024x75)) + if ((pVBInfo->LCDResInfo == Panel_1280x1024) + || (pVBInfo->LCDResInfo == Panel_1280x1024x75)) tempah |= 0x80; - if (pVBInfo->LCDResInfo == Panel1280x960) + if (pVBInfo->LCDResInfo == Panel_1280x960) tempah |= 0x80; xgifb_reg_set(pVBInfo->Part4Port, 0x0C, tempah); diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 217fb879434..c587d411835 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -2353,109 +2353,109 @@ static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_Vx75[] = { /*add for new UNIVGABIOS*/ static struct XGI330_LCDDataTablStruct XGI_LCDDataTable[] = { - {Panel1024x768, 0x0019, 0x0001, 0}, /* XGI_ExtLCD1024x768Data */ - {Panel1024x768, 0x0019, 0x0000, 1}, /* XGI_StLCD1024x768Data */ - {Panel1024x768, 0x0018, 0x0010, 2}, /* XGI_CetLCD1024x768Data */ - {Panel1280x1024, 0x0019, 0x0001, 3}, /* XGI_ExtLCD1280x1024Data */ - {Panel1280x1024, 0x0019, 0x0000, 4}, /* XGI_StLCD1280x1024Data */ - {Panel1280x1024, 0x0018, 0x0010, 5}, /* XGI_CetLCD1280x1024Data */ - {Panel1400x1050, 0x0019, 0x0001, 6}, /* XGI_ExtLCD1400x1050Data */ - {Panel1400x1050, 0x0019, 0x0000, 7}, /* XGI_StLCD1400x1050Data */ - {Panel1400x1050, 0x0018, 0x0010, 8}, /* XGI_CetLCD1400x1050Data */ - {Panel1600x1200, 0x0019, 0x0001, 9}, /* XGI_ExtLCD1600x1200Data */ - {Panel1600x1200, 0x0019, 0x0000, 10}, /* XGI_StLCD1600x1200Data */ + {Panel_1024x768, 0x0019, 0x0001, 0}, /* XGI_ExtLCD1024x768Data */ + {Panel_1024x768, 0x0019, 0x0000, 1}, /* XGI_StLCD1024x768Data */ + {Panel_1024x768, 0x0018, 0x0010, 2}, /* XGI_CetLCD1024x768Data */ + {Panel_1280x1024, 0x0019, 0x0001, 3}, /* XGI_ExtLCD1280x1024Data */ + {Panel_1280x1024, 0x0019, 0x0000, 4}, /* XGI_StLCD1280x1024Data */ + {Panel_1280x1024, 0x0018, 0x0010, 5}, /* XGI_CetLCD1280x1024Data */ + {Panel_1400x1050, 0x0019, 0x0001, 6}, /* XGI_ExtLCD1400x1050Data */ + {Panel_1400x1050, 0x0019, 0x0000, 7}, /* XGI_StLCD1400x1050Data */ + {Panel_1400x1050, 0x0018, 0x0010, 8}, /* XGI_CetLCD1400x1050Data */ + {Panel_1600x1200, 0x0019, 0x0001, 9}, /* XGI_ExtLCD1600x1200Data */ + {Panel_1600x1200, 0x0019, 0x0000, 10}, /* XGI_StLCD1600x1200Data */ {PanelRef60Hz, 0x0008, 0x0008, 11}, /* XGI_NoScalingData */ - {Panel1024x768x75, 0x0019, 0x0001, 12}, /* XGI_ExtLCD1024x768x75Data */ - {Panel1024x768x75, 0x0019, 0x0000, 13}, /* XGI_StLCD1024x768x75Data */ - {Panel1024x768x75, 0x0018, 0x0010, 14}, /* XGI_CetLCD1024x768x75Data */ - {Panel1280x1024x75, 0x0019, 0x0001, 15}, /* XGI_ExtLCD1280x1024x75Data*/ - {Panel1280x1024x75, 0x0019, 0x0000, 16}, /* XGI_StLCD1280x1024x75Data */ - {Panel1280x1024x75, 0x0018, 0x0010, 17}, /* XGI_CetLCD1280x1024x75Data*/ + {Panel_1024x768x75, 0x0019, 0x0001, 12}, /* XGI_ExtLCD1024x768x75Data */ + {Panel_1024x768x75, 0x0019, 0x0000, 13}, /* XGI_StLCD1024x768x75Data */ + {Panel_1024x768x75, 0x0018, 0x0010, 14}, /* XGI_CetLCD1024x768x75Data */ + {Panel_1280x1024x75, 0x0019, 0x0001, 15}, /* XGI_ExtLCD1280x1024x75Data*/ + {Panel_1280x1024x75, 0x0019, 0x0000, 16}, /* XGI_StLCD1280x1024x75Data */ + {Panel_1280x1024x75, 0x0018, 0x0010, 17}, /* XGI_CetLCD1280x1024x75Data*/ {PanelRef75Hz, 0x0008, 0x0008, 18}, /* XGI_NoScalingDatax75 */ {0xFF, 0x0000, 0x0000, 0} /* End of table */ }; static struct XGI330_LCDDataTablStruct XGI_LCDDesDataTable[] = { - {Panel1024x768, 0x0019, 0x0001, 0}, /* XGI_ExtLCDDes1024x768Data */ - {Panel1024x768, 0x0019, 0x0000, 1}, /* XGI_StLCDDes1024x768Data */ - {Panel1024x768, 0x0018, 0x0010, 2}, /* XGI_CetLCDDes1024x768Data */ - {Panel1280x1024, 0x0019, 0x0001, 3}, /* XGI_ExtLCDDes1280x1024Data */ - {Panel1280x1024, 0x0019, 0x0000, 4}, /* XGI_StLCDDes1280x1024Data */ - {Panel1280x1024, 0x0018, 0x0010, 5}, /* XGI_CetLCDDes1280x1024Data */ - {Panel1400x1050, 0x0019, 0x0001, 6}, /* XGI_ExtLCDDes1400x1050Data */ - {Panel1400x1050, 0x0019, 0x0000, 7}, /* XGI_StLCDDes1400x1050Data */ - {Panel1400x1050, 0x0418, 0x0010, 8}, /* XGI_CetLCDDes1400x1050Data */ - {Panel1400x1050, 0x0418, 0x0410, 9}, /* XGI_CetLCDDes1400x1050Data2 */ - {Panel1600x1200, 0x0019, 0x0001, 10}, /* XGI_ExtLCDDes1600x1200Data */ - {Panel1600x1200, 0x0019, 0x0000, 11}, /* XGI_StLCDDes1600x1200Data */ + {Panel_1024x768, 0x0019, 0x0001, 0}, /* XGI_ExtLCDDes1024x768Data */ + {Panel_1024x768, 0x0019, 0x0000, 1}, /* XGI_StLCDDes1024x768Data */ + {Panel_1024x768, 0x0018, 0x0010, 2}, /* XGI_CetLCDDes1024x768Data */ + {Panel_1280x1024, 0x0019, 0x0001, 3}, /* XGI_ExtLCDDes1280x1024Data */ + {Panel_1280x1024, 0x0019, 0x0000, 4}, /* XGI_StLCDDes1280x1024Data */ + {Panel_1280x1024, 0x0018, 0x0010, 5}, /* XGI_CetLCDDes1280x1024Data */ + {Panel_1400x1050, 0x0019, 0x0001, 6}, /* XGI_ExtLCDDes1400x1050Data */ + {Panel_1400x1050, 0x0019, 0x0000, 7}, /* XGI_StLCDDes1400x1050Data */ + {Panel_1400x1050, 0x0418, 0x0010, 8}, /* XGI_CetLCDDes1400x1050Data */ + {Panel_1400x1050, 0x0418, 0x0410, 9}, /* XGI_CetLCDDes1400x1050Data2 */ + {Panel_1600x1200, 0x0019, 0x0001, 10}, /* XGI_ExtLCDDes1600x1200Data */ + {Panel_1600x1200, 0x0019, 0x0000, 11}, /* XGI_StLCDDes1600x1200Data */ {PanelRef60Hz, 0x0008, 0x0008, 12}, /* XGI_NoScalingDesData */ - {Panel1024x768x75, 0x0019, 0x0001, 13}, /*XGI_ExtLCDDes1024x768x75Data*/ - {Panel1024x768x75, 0x0019, 0x0000, 14}, /* XGI_StLCDDes1024x768x75Data*/ - {Panel1024x768x75, 0x0018, 0x0010, 15}, /*XGI_CetLCDDes1024x768x75Data*/ + {Panel_1024x768x75, 0x0019, 0x0001, 13}, /*XGI_ExtLCDDes1024x768x75Data*/ + {Panel_1024x768x75, 0x0019, 0x0000, 14}, /* XGI_StLCDDes1024x768x75Data*/ + {Panel_1024x768x75, 0x0018, 0x0010, 15}, /*XGI_CetLCDDes1024x768x75Data*/ /* XGI_ExtLCDDes1280x1024x75Data */ - {Panel1280x1024x75, 0x0019, 0x0001, 16}, + {Panel_1280x1024x75, 0x0019, 0x0001, 16}, /* XGI_StLCDDes1280x1024x75Data */ - {Panel1280x1024x75, 0x0019, 0x0000, 17}, + {Panel_1280x1024x75, 0x0019, 0x0000, 17}, /* XGI_CetLCDDes1280x1024x75Data */ - {Panel1280x1024x75, 0x0018, 0x0010, 18}, + {Panel_1280x1024x75, 0x0018, 0x0010, 18}, {PanelRef75Hz, 0x0008, 0x0008, 19}, /* XGI_NoScalingDesDatax75 */ {0xFF, 0x0000, 0x0000, 0} }; static struct XGI330_LCDDataTablStruct xgifb_epllcd_crt1[] = { - {Panel1024x768, 0x0018, 0x0000, 0}, /* XGI_LVDSCRT11024x768_1 */ - {Panel1024x768, 0x0018, 0x0010, 1}, /* XGI_LVDSCRT11024x768_2 */ - {Panel1280x1024, 0x0018, 0x0000, 2}, /* XGI_LVDSCRT11280x1024_1 */ - {Panel1280x1024, 0x0018, 0x0010, 3}, /* XGI_LVDSCRT11280x1024_2 */ - {Panel1400x1050, 0x0018, 0x0000, 4}, /* XGI_LVDSCRT11400x1050_1 */ - {Panel1400x1050, 0x0018, 0x0010, 5}, /* XGI_LVDSCRT11400x1050_2 */ - {Panel1600x1200, 0x0018, 0x0000, 6}, /* XGI_LVDSCRT11600x1200_1 */ - {Panel1024x768x75, 0x0018, 0x0000, 7}, /* XGI_LVDSCRT11024x768_1x75 */ - {Panel1024x768x75, 0x0018, 0x0010, 8}, /* XGI_LVDSCRT11024x768_2x75 */ - {Panel1280x1024x75, 0x0018, 0x0000, 9}, /*XGI_LVDSCRT11280x1024_1x75*/ - {Panel1280x1024x75, 0x0018, 0x0010, 10},/*XGI_LVDSCRT11280x1024_2x75*/ + {Panel_1024x768, 0x0018, 0x0000, 0}, /* XGI_LVDSCRT11024x768_1 */ + {Panel_1024x768, 0x0018, 0x0010, 1}, /* XGI_LVDSCRT11024x768_2 */ + {Panel_1280x1024, 0x0018, 0x0000, 2}, /* XGI_LVDSCRT11280x1024_1 */ + {Panel_1280x1024, 0x0018, 0x0010, 3}, /* XGI_LVDSCRT11280x1024_2 */ + {Panel_1400x1050, 0x0018, 0x0000, 4}, /* XGI_LVDSCRT11400x1050_1 */ + {Panel_1400x1050, 0x0018, 0x0010, 5}, /* XGI_LVDSCRT11400x1050_2 */ + {Panel_1600x1200, 0x0018, 0x0000, 6}, /* XGI_LVDSCRT11600x1200_1 */ + {Panel_1024x768x75, 0x0018, 0x0000, 7}, /* XGI_LVDSCRT11024x768_1x75 */ + {Panel_1024x768x75, 0x0018, 0x0010, 8}, /* XGI_LVDSCRT11024x768_2x75 */ + {Panel_1280x1024x75, 0x0018, 0x0000, 9}, /*XGI_LVDSCRT11280x1024_1x75*/ + {Panel_1280x1024x75, 0x0018, 0x0010, 10},/*XGI_LVDSCRT11280x1024_2x75*/ {0xFF, 0x0000, 0x0000, 0} }; static struct XGI330_LCDDataTablStruct XGI_EPLLCDDataPtr[] = { - {Panel1024x768, 0x0018, 0x0000, 0}, /* XGI_LVDS1024x768Data_1 */ - {Panel1024x768, 0x0018, 0x0010, 1}, /* XGI_LVDS1024x768Data_2 */ - {Panel1280x1024, 0x0018, 0x0000, 2}, /* XGI_LVDS1280x1024Data_1 */ - {Panel1280x1024, 0x0018, 0x0010, 3}, /* XGI_LVDS1280x1024Data_2 */ - {Panel1400x1050, 0x0018, 0x0000, 4}, /* XGI_LVDS1400x1050Data_1 */ - {Panel1400x1050, 0x0018, 0x0010, 5}, /* XGI_LVDS1400x1050Data_2 */ - {Panel1600x1200, 0x0018, 0x0000, 6}, /* XGI_LVDS1600x1200Data_1 */ + {Panel_1024x768, 0x0018, 0x0000, 0}, /* XGI_LVDS1024x768Data_1 */ + {Panel_1024x768, 0x0018, 0x0010, 1}, /* XGI_LVDS1024x768Data_2 */ + {Panel_1280x1024, 0x0018, 0x0000, 2}, /* XGI_LVDS1280x1024Data_1 */ + {Panel_1280x1024, 0x0018, 0x0010, 3}, /* XGI_LVDS1280x1024Data_2 */ + {Panel_1400x1050, 0x0018, 0x0000, 4}, /* XGI_LVDS1400x1050Data_1 */ + {Panel_1400x1050, 0x0018, 0x0010, 5}, /* XGI_LVDS1400x1050Data_2 */ + {Panel_1600x1200, 0x0018, 0x0000, 6}, /* XGI_LVDS1600x1200Data_1 */ {PanelRef60Hz, 0x0008, 0x0008, 7}, /* XGI_LVDSNoScalingData */ - {Panel1024x768x75, 0x0018, 0x0000, 8}, /* XGI_LVDS1024x768Data_1x75 */ - {Panel1024x768x75, 0x0018, 0x0010, 9}, /* XGI_LVDS1024x768Data_2x75 */ - {Panel1280x1024x75, 0x0018, 0x0000, 10}, /* XGI_LVDS1280x1024Data_1x75*/ - {Panel1280x1024x75, 0x0018, 0x0010, 11}, /*XGI_LVDS1280x1024Data_2x75*/ + {Panel_1024x768x75, 0x0018, 0x0000, 8}, /* XGI_LVDS1024x768Data_1x75 */ + {Panel_1024x768x75, 0x0018, 0x0010, 9}, /* XGI_LVDS1024x768Data_2x75 */ + {Panel_1280x1024x75, 0x0018, 0x0000, 10}, /* XGI_LVDS1280x1024Data_1x75*/ + {Panel_1280x1024x75, 0x0018, 0x0010, 11}, /*XGI_LVDS1280x1024Data_2x75*/ {PanelRef75Hz, 0x0008, 0x0008, 12}, /* XGI_LVDSNoScalingDatax75 */ {0xFF, 0x0000, 0x0000, 0} }; static struct XGI330_LCDDataTablStruct XGI_EPLLCDDesDataPtr[] = { - {Panel1024x768, 0x0018, 0x0000, 0}, /* XGI_LVDS1024x768Des_1 */ - {Panel1024x768, 0x0618, 0x0410, 1}, /* XGI_LVDS1024x768Des_3 */ - {Panel1024x768, 0x0018, 0x0010, 2}, /* XGI_LVDS1024x768Des_2 */ - {Panel1280x1024, 0x0018, 0x0000, 3}, /* XGI_LVDS1280x1024Des_1 */ - {Panel1280x1024, 0x0018, 0x0010, 4}, /* XGI_LVDS1280x1024Des_2 */ - {Panel1400x1050, 0x0018, 0x0000, 5}, /* XGI_LVDS1400x1050Des_1 */ - {Panel1400x1050, 0x0018, 0x0010, 6}, /* XGI_LVDS1400x1050Des_2 */ - {Panel1600x1200, 0x0018, 0x0000, 7}, /* XGI_LVDS1600x1200Des_1 */ + {Panel_1024x768, 0x0018, 0x0000, 0}, /* XGI_LVDS1024x768Des_1 */ + {Panel_1024x768, 0x0618, 0x0410, 1}, /* XGI_LVDS1024x768Des_3 */ + {Panel_1024x768, 0x0018, 0x0010, 2}, /* XGI_LVDS1024x768Des_2 */ + {Panel_1280x1024, 0x0018, 0x0000, 3}, /* XGI_LVDS1280x1024Des_1 */ + {Panel_1280x1024, 0x0018, 0x0010, 4}, /* XGI_LVDS1280x1024Des_2 */ + {Panel_1400x1050, 0x0018, 0x0000, 5}, /* XGI_LVDS1400x1050Des_1 */ + {Panel_1400x1050, 0x0018, 0x0010, 6}, /* XGI_LVDS1400x1050Des_2 */ + {Panel_1600x1200, 0x0018, 0x0000, 7}, /* XGI_LVDS1600x1200Des_1 */ {PanelRef60Hz, 0x0008, 0x0008, 8}, /* XGI_LVDSNoScalingDesData */ - {Panel1024x768x75, 0x0018, 0x0000, 9}, /* XGI_LVDS1024x768Des_1x75 */ - {Panel1024x768x75, 0x0618, 0x0410, 10}, /* XGI_LVDS1024x768Des_3x75 */ - {Panel1024x768x75, 0x0018, 0x0010, 11}, /* XGI_LVDS1024x768Des_2x75 */ - {Panel1280x1024x75, 0x0018, 0x0000, 12}, /* XGI_LVDS1280x1024Des_1x75 */ - {Panel1280x1024x75, 0x0018, 0x0010, 13}, /* XGI_LVDS1280x1024Des_2x75 */ + {Panel_1024x768x75, 0x0018, 0x0000, 9}, /* XGI_LVDS1024x768Des_1x75 */ + {Panel_1024x768x75, 0x0618, 0x0410, 10}, /* XGI_LVDS1024x768Des_3x75 */ + {Panel_1024x768x75, 0x0018, 0x0010, 11}, /* XGI_LVDS1024x768Des_2x75 */ + {Panel_1280x1024x75, 0x0018, 0x0000, 12}, /* XGI_LVDS1280x1024Des_1x75 */ + {Panel_1280x1024x75, 0x0018, 0x0010, 13}, /* XGI_LVDS1280x1024Des_2x75 */ {PanelRef75Hz, 0x0008, 0x0008, 14}, /* XGI_LVDSNoScalingDesDatax75 */ {0xFF, 0x0000, 0x0000, 0} }; static struct XGI330_LCDDataTablStruct XGI_EPLCHLCDRegPtr[] = { - {Panel1024x768, 0x0000, 0x0000, 0}, /* XGI_CH7017LV1024x768 */ - {Panel1400x1050, 0x0000, 0x0000, 1}, /* XGI_CH7017LV1400x1050 */ + {Panel_1024x768, 0x0000, 0x0000, 0}, /* XGI_CH7017LV1024x768 */ + {Panel_1400x1050, 0x0000, 0x0000, 1}, /* XGI_CH7017LV1400x1050 */ {0xFF, 0x0000, 0x0000, 0} }; @@ -2501,30 +2501,30 @@ static unsigned short LCDLenList[] = { /* Dual link only */ static struct XGI330_LCDCapStruct XGI_LCDDLCapList[] = { /* LCDCap1024x768 */ - {Panel1024x768, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65, + {Panel_1024x768, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65, 0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}, /* LCDCap1280x1024 */ - {Panel1280x1024, LCDDualLink+DefaultLCDCap, StLCDBToA, + {Panel_1280x1024, LCDDualLink+DefaultLCDCap, StLCDBToA, 0x012, 0x70, 0x03, VCLK108_2, 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, /* LCDCap1400x1050 */ - {Panel1400x1050, LCDDualLink+DefaultLCDCap, StLCDBToA, + {Panel_1400x1050, LCDDualLink+DefaultLCDCap, StLCDBToA, 0x012, 0x70, 0x03, VCLK108_2, 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, /* LCDCap1600x1200 */ - {Panel1600x1200, LCDDualLink+DefaultLCDCap, LCDToFull, + {Panel_1600x1200, LCDDualLink+DefaultLCDCap, LCDToFull, 0x012, 0xC0, 0x03, VCLK162, 0x43, 0x22, 0x70, 0x24, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, /* LCDCap1024x768x75 */ - {Panel1024x768x75, DefaultLCDCap, 0, 0x012, 0x60, 0, VCLK78_75, + {Panel_1024x768x75, DefaultLCDCap, 0, 0x012, 0x60, 0, VCLK78_75, 0x2B, 0x61, 0x2B, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}, /* LCDCap1280x1024x75 */ - {Panel1280x1024x75, LCDDualLink+DefaultLCDCap, StLCDBToA, + {Panel_1280x1024x75, LCDDualLink+DefaultLCDCap, StLCDBToA, 0x012, 0x90, 0x03, VCLK135_5, 0x54, 0x42, 0x4A, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, @@ -2536,30 +2536,30 @@ static struct XGI330_LCDCapStruct XGI_LCDDLCapList[] = { static struct XGI330_LCDCapStruct XGI_LCDCapList[] = { /* LCDCap1024x768 */ - {Panel1024x768, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65, + {Panel_1024x768, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65, 0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}, /* LCDCap1280x1024 */ - {Panel1280x1024, DefaultLCDCap, StLCDBToA, + {Panel_1280x1024, DefaultLCDCap, StLCDBToA, 0x012, 0x70, 0x03, VCLK108_2, 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, /* LCDCap1400x1050 */ - {Panel1400x1050, DefaultLCDCap, StLCDBToA, + {Panel_1400x1050, DefaultLCDCap, StLCDBToA, 0x012, 0x70, 0x03, VCLK108_2, 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, /* LCDCap1600x1200 */ - {Panel1600x1200, DefaultLCDCap, LCDToFull, + {Panel_1600x1200, DefaultLCDCap, LCDToFull, 0x012, 0xC0, 0x03, VCLK162, 0x5A, 0x23, 0x5A, 0x23, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, /* LCDCap1024x768x75 */ - {Panel1024x768x75, DefaultLCDCap, 0, 0x012, 0x60, 0, VCLK78_75, + {Panel_1024x768x75, DefaultLCDCap, 0, 0x012, 0x60, 0, VCLK78_75, 0x2B, 0x61, 0x2B, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}, /* LCDCap1280x1024x75 */ - {Panel1280x1024x75, DefaultLCDCap, StLCDBToA, + {Panel_1280x1024x75, DefaultLCDCap, StLCDBToA, 0x012, 0x90, 0x03, VCLK135_5, 0x54, 0x42, 0x4A, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, -- cgit v1.2.3-70-g09d2 From 599801f9266178ebca7f22996b9e6e00f0e69056 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Thu, 9 Feb 2012 21:11:45 +0100 Subject: staging/xgifb: Rename Set* defines and remove duplicated defines This patch renames the Set* defines and their usage to the naming convention of the sis initdef.h and removes the now duplicated defines. Renames: SetCRT2ToHiVisionTV -> SetCRT2ToHiVision SetCRT2ToYPbPr -> SetCRT2ToYPbPr525750 SetNTSCJ -> TVSetNTSCJ SetPALMTV -> TVSetPALM SetPALNTV -> TVSetPALN SetPALTV -> TVSetPAL SetYPbPrMode1080i -> TVSetHiVision SetYPbPrMode525i -> TVSetYPbPr525i SetYPbPrMode525p -> TVSetYPbPr525p SetYPbPrMode750p -> TVSetYPbPr750p Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_def.h | 10 -- drivers/staging/xgifb/vb_init.c | 4 +- drivers/staging/xgifb/vb_setmode.c | 244 ++++++++++++++++++------------------- 3 files changed, 124 insertions(+), 134 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h index 9b2937c4b9f..c368322a233 100644 --- a/drivers/staging/xgifb/vb_def.h +++ b/drivers/staging/xgifb/vb_def.h @@ -131,11 +131,9 @@ #define SetCRT2ToSCART 0x0010 #define SetCRT2ToLCD 0x0020 #define SetCRT2ToRAMDAC 0x0040 -#define SetCRT2ToHiVisionTV 0x0080 #define SetCRT2ToLCDA 0x0100 #define SetInSlaveMode 0x0200 #define SetNotSimuMode 0x0400 -#define SetCRT2ToYPbPr 0x0800 #define LoadDACFlag 0x1000 #define DisableCRT2Display 0x2000 #define DriverMode 0x4000 @@ -150,14 +148,6 @@ #define EnableChA 0x8000 #define SetNTSCTV 0x0000 /* TV Info */ -#define SetPALTV 0x0001 -#define SetNTSCJ 0x0002 -#define SetPALMTV 0x0004 -#define SetPALNTV 0x0008 -#define SetYPbPrMode525i 0x0020 -#define SetYPbPrMode525p 0x0040 -#define SetYPbPrMode750p 0x0080 -#define SetYPbPrMode1080i 0x0100 #define SetTVLowResolution 0x0400 #define TVSimuMode 0x0800 #define RPLLDIV2XO 0x1000 diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index a53a097131b..4c545682a30 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -1268,7 +1268,7 @@ static void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension, if (pVBInfo->IF_DEF_HiVision == 1) { if ((temp >> 8) & ActiveHiTV) - tempcl |= SetCRT2ToHiVisionTV; + tempcl |= SetCRT2ToHiVision; } if (pVBInfo->IF_DEF_YPbPr == 1) { @@ -1287,7 +1287,7 @@ static void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension, if (pVBInfo->IF_DEF_HiVision == 1) { if ((temp >> 8) & ActiveHiTV) - tempcl |= SetCRT2ToHiVisionTV; + tempcl |= SetCRT2ToHiVision; } if (pVBInfo->IF_DEF_YPbPr == 1) { diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 25c647b348b..ea142e9b94c 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -372,7 +372,7 @@ static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, } } - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { /* for HiTV */ + if (pVBInfo->VBInfo & SetCRT2ToHiVision) { /* for HiTV */ if ((pVBInfo->VBType & VB_XGI301LV) && (pVBInfo->VBExtInfo == VB_YPbPr1080i)) { tempax |= SupportYPbPr; @@ -406,8 +406,8 @@ static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | SetCRT2ToSCART | - SetCRT2ToYPbPr | - SetCRT2ToHiVisionTV)) { + SetCRT2ToYPbPr525750 | + SetCRT2ToHiVision)) { tempax |= SupportTV; if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B @@ -416,7 +416,7 @@ static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, tempax |= SupportTV1024; } - if (!(pVBInfo->VBInfo & SetPALTV)) { + if (!(pVBInfo->VBInfo & TVSetPAL)) { if (modeflag & NoSupportSimuTV) { if (pVBInfo->VBInfo & SetInSlaveMode) { @@ -1271,7 +1271,7 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, VCLKIndex = LCDXlat2VCLK[CRT2Index]; else VCLKIndex = LCDXlat1VCLK[CRT2Index]; - } else if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { + } else if (pVBInfo->VBInfo & SetCRT2ToHiVision) { if (pVBInfo->SetFlag & RPLLDIV2XO) { VCLKIndex = HiTVVCLKDIV2; VCLKIndex += 25; @@ -2844,7 +2844,7 @@ static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex, VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { + if (pVBInfo->VBInfo & SetCRT2ToHiVision) { tempal = HiTVVCLKDIV2; if (!(pVBInfo->TVInfo & RPLLDIV2XO)) tempal = HiTVVCLK; @@ -2857,12 +2857,12 @@ static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex, return tempal; } - if (pVBInfo->TVInfo & SetYPbPrMode750p) { + if (pVBInfo->TVInfo & TVSetYPbPr750p) { tempal = YPbPr750pVCLK; return tempal; } - if (pVBInfo->TVInfo & SetYPbPrMode525p) { + if (pVBInfo->TVInfo & TVSetYPbPr525p) { tempal = YPbPr525pVCLK; return tempal; } @@ -2987,12 +2987,12 @@ static void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension, if (temp & 0x02) tempch |= ActiveSCART; - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { + if (pVBInfo->VBInfo & SetCRT2ToHiVision) { if (temp & 0x01) tempch |= ActiveHiTV; } - if (pVBInfo->VBInfo & SetCRT2ToYPbPr) { + if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) { temp = xgifb_reg_get( pVBInfo->Part2Port, 0x4d); @@ -3090,7 +3090,7 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, push = push << 8; tempax = temp << 8; tempbx = tempbx | tempax; - temp = (SetCRT2ToDualEdge | SetCRT2ToYPbPr | SetCRT2ToLCDA + temp = (SetCRT2ToDualEdge | SetCRT2ToYPbPr525750 | SetCRT2ToLCDA | SetInSlaveMode | DisableCRT2Display); temp = 0xFFFF ^ temp; tempbx &= temp; @@ -3134,13 +3134,13 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, pVBInfo->P3d4, 0x35); temp &= YPbPrMode; - tempbx |= SetCRT2ToHiVisionTV; + tempbx |= SetCRT2ToHiVision; if (temp != YPbPrMode1080i) { tempbx &= - (~SetCRT2ToHiVisionTV); + (~SetCRT2ToHiVision); tempbx |= - SetCRT2ToYPbPr; + SetCRT2ToYPbPr525750; } } } @@ -3195,7 +3195,7 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, SetCRT2ToRAMDAC | SwitchToCRT2 | SetSimuScanMode); - tempbx &= (0x00FF | (~SetCRT2ToYPbPr)); + tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750)); } } else { tempbx &= (~(SetCRT2ToRAMDAC | @@ -3210,7 +3210,7 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, SetCRT2ToLCD | SwitchToCRT2 | SetSimuScanMode); - tempbx &= (0x00FF | (~SetCRT2ToYPbPr)); + tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750)); } } @@ -3219,20 +3219,20 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, SetCRT2ToSCART | SwitchToCRT2 | SetSimuScanMode); - tempbx &= (0x00FF | (~SetCRT2ToYPbPr)); + tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750)); } if (pVBInfo->IF_DEF_YPbPr == 1) { - if (tempbx & SetCRT2ToYPbPr) + if (tempbx & SetCRT2ToYPbPr525750) tempbx &= (0xFF00 | SwitchToCRT2 | SetSimuScanMode); } if (pVBInfo->IF_DEF_HiVision == 1) { - if (tempbx & SetCRT2ToHiVisionTV) + if (tempbx & SetCRT2ToHiVision) tempbx &= (0xFF00 | - SetCRT2ToHiVisionTV | + SetCRT2ToHiVision | SwitchToCRT2 | SetSimuScanMode); } @@ -3291,43 +3291,43 @@ static void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->VBInfo & SetCRT2ToTV) { temp = xgifb_reg_get(pVBInfo->P3d4, 0x35); tempbx = temp; - if (tempbx & SetPALTV) { + if (tempbx & TVSetPAL) { tempbx &= (SetCHTVOverScan | - SetPALMTV | - SetPALNTV | - SetPALTV); - if (tempbx & SetPALMTV) + TVSetPALM | + TVSetPALN | + TVSetPAL); + if (tempbx & TVSetPALM) /* set to NTSC if PAL-M */ - tempbx &= ~SetPALTV; + tempbx &= ~TVSetPAL; } else tempbx &= (SetCHTVOverScan | - SetNTSCJ | - SetPALTV); + TVSetNTSCJ | + TVSetPAL); } if (pVBInfo->IF_DEF_LVDS == 0) { if (pVBInfo->VBInfo & SetCRT2ToSCART) - tempbx |= SetPALTV; + tempbx |= TVSetPAL; } if (pVBInfo->IF_DEF_YPbPr == 1) { - if (pVBInfo->VBInfo & SetCRT2ToYPbPr) { + if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) { index1 = xgifb_reg_get(pVBInfo->P3d4, 0x35); index1 &= YPbPrMode; if (index1 == YPbPrMode525i) - tempbx |= SetYPbPrMode525i; + tempbx |= TVSetYPbPr525i; if (index1 == YPbPrMode525p) - tempbx = tempbx | SetYPbPrMode525p; + tempbx = tempbx | TVSetYPbPr525p; if (index1 == YPbPrMode750p) - tempbx = tempbx | SetYPbPrMode750p; + tempbx = tempbx | TVSetYPbPr750p; } } if (pVBInfo->IF_DEF_HiVision == 1) { - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) - tempbx = tempbx | SetYPbPrMode1080i | SetPALTV; + if (pVBInfo->VBInfo & SetCRT2ToHiVision) + tempbx = tempbx | TVSetHiVision | TVSetPAL; } if (pVBInfo->IF_DEF_LVDS == 0) { /* shampoo */ @@ -3335,19 +3335,19 @@ static void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex, (!(pVBInfo->VBInfo & SetNotSimuMode))) tempbx |= TVSimuMode; - if (!(tempbx & SetPALTV) && + if (!(tempbx & TVSetPAL) && (modeflag > 13) && (resinfo == 8)) /* NTSC 1024x768, */ tempbx |= NTSC1024x768; tempbx |= RPLLDIV2XO; - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { + if (pVBInfo->VBInfo & SetCRT2ToHiVision) { if (pVBInfo->VBInfo & SetInSlaveMode) tempbx &= (~RPLLDIV2XO); } else { if (tempbx & - (SetYPbPrMode525p | SetYPbPrMode750p)) + (TVSetYPbPr525p | TVSetYPbPr750p)) tempbx &= (~RPLLDIV2XO); else if (!(pVBInfo->VBType & (VB_XGI301B | @@ -4041,7 +4041,7 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, pVBInfo->RVBHRS = TVPtr->RVBHRS; pVBInfo->NewFlickerMode = TVPtr->FlickerMode; - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { + if (pVBInfo->VBInfo & SetCRT2ToHiVision) { if (resinfo == 0x08) pVBInfo->NewFlickerMode = 0x40; else if (resinfo == 0x09) @@ -4066,16 +4066,16 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, } } } - } else if (pVBInfo->VBInfo & SetCRT2ToYPbPr) { - if (pVBInfo->TVInfo & SetYPbPrMode750p) { + } else if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) { + if (pVBInfo->TVInfo & TVSetYPbPr750p) { tempax = YPbPrTV750pHT; /* Ext750pTVHT */ tempbx = YPbPrTV750pVT; /* Ext750pTVVT */ } - if (pVBInfo->TVInfo & SetYPbPrMode525p) { + if (pVBInfo->TVInfo & TVSetYPbPr525p) { tempax = YPbPrTV525pHT; /* Ext525pTVHT */ tempbx = YPbPrTV525pVT; /* Ext525pTVVT */ - } else if (pVBInfo->TVInfo & SetYPbPrMode525i) { + } else if (pVBInfo->TVInfo & TVSetYPbPr525i) { tempax = YPbPrTV525iHT; /* Ext525iTVHT */ tempbx = YPbPrTV525iVT; /* Ext525iTVVT */ if (pVBInfo->TVInfo & NTSC1024x768) @@ -4084,7 +4084,7 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, } else { tempax = PALHT; tempbx = PALVT; - if (!(pVBInfo->TVInfo & SetPALTV)) { + if (!(pVBInfo->TVInfo & TVSetPAL)) { tempax = NTSCHT; tempbx = NTSCVT; if (pVBInfo->TVInfo & NTSC1024x768) @@ -4455,7 +4455,7 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, | VB_XGI302LV | VB_XGI301C))) temp += 2; - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { + if (pVBInfo->VBInfo & SetCRT2ToHiVision) { if (pVBInfo->VBType & VB_XGI301LV) { if (pVBInfo->VBExtInfo == VB_YPbPr1080i) { if (resinfo == 7) @@ -4487,7 +4487,7 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, tempax = (tempax / tempcx) - 5; tempcx = tempax; /* 20030401 0x07 horizontal Retrace Start */ - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { + if (pVBInfo->VBInfo & SetCRT2ToHiVision) { temp = (tempbx & 0x00FF) - 1; if (!(modeflag & HalfDCLK)) { temp -= 6; @@ -4669,19 +4669,19 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, tempbx += tempax; } - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { + if (pVBInfo->VBInfo & SetCRT2ToHiVision) { if (pVBInfo->VBType & VB_XGI301LV) { - if (pVBInfo->TVInfo & SetYPbPrMode1080i) { + if (pVBInfo->TVInfo & TVSetHiVision) { tempbx -= 10; } else { if (pVBInfo->TVInfo & TVSimuMode) { - if (pVBInfo->TVInfo & SetPALTV) { + if (pVBInfo->TVInfo & TVSetPAL) { if (pVBInfo->VBType & VB_XGI301LV) { if (!(pVBInfo->TVInfo & - (SetYPbPrMode525p | - SetYPbPrMode750p | - SetYPbPrMode1080i))) + (TVSetYPbPr525p | + TVSetYPbPr750p | + TVSetHiVision))) tempbx += 40; } else { tempbx += 40; @@ -4694,12 +4694,12 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, } } else { if (pVBInfo->TVInfo & TVSimuMode) { - if (pVBInfo->TVInfo & SetPALTV) { + if (pVBInfo->TVInfo & TVSetPAL) { if (pVBInfo->VBType & VB_XGI301LV) { if (!(pVBInfo->TVInfo & - (SetYPbPrMode525p | - SetYPbPrMode750p | - SetYPbPrMode1080i))) + (TVSetYPbPr525p | + TVSetYPbPr750p | + TVSetHiVision))) tempbx += 40; } else { tempbx += 40; @@ -4713,7 +4713,7 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, tempax += tempbx; push1 = tempax; /* push ax */ - if ((pVBInfo->TVInfo & SetPALTV)) { + if ((pVBInfo->TVInfo & TVSetPAL)) { if (tempbx <= 513) { if (tempax >= 513) tempbx = 513; @@ -4813,13 +4813,13 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->VBInfo & SetCRT2ToSCART) tempax |= 0x0200; - if (!(pVBInfo->TVInfo & SetPALTV)) + if (!(pVBInfo->TVInfo & TVSetPAL)) tempax |= 0x1000; - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) + if (pVBInfo->VBInfo & SetCRT2ToHiVision) tempax |= 0x0100; - if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)) + if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p)) tempax &= 0xfe00; tempax = (tempax & 0xff00) >> 8; @@ -4827,10 +4827,10 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, xgifb_reg_set(pVBInfo->Part2Port, 0x0, tempax); TimingPoint = pVBInfo->NTSCTiming; - if (pVBInfo->TVInfo & SetPALTV) + if (pVBInfo->TVInfo & TVSetPAL) TimingPoint = pVBInfo->PALTiming; - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { + if (pVBInfo->VBInfo & SetCRT2ToHiVision) { TimingPoint = pVBInfo->HiTVExtTiming; if (pVBInfo->VBInfo & SetInSlaveMode) @@ -4843,14 +4843,14 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, TimingPoint = pVBInfo->HiTVTextTiming; } - if (pVBInfo->VBInfo & SetCRT2ToYPbPr) { - if (pVBInfo->TVInfo & SetYPbPrMode525i) + if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) { + if (pVBInfo->TVInfo & TVSetYPbPr525i) TimingPoint = pVBInfo->YPbPr525iTiming; - if (pVBInfo->TVInfo & SetYPbPrMode525p) + if (pVBInfo->TVInfo & TVSetYPbPr525p) TimingPoint = pVBInfo->YPbPr525pTiming; - if (pVBInfo->TVInfo & SetYPbPrMode750p) + if (pVBInfo->TVInfo & TVSetYPbPr750p) TimingPoint = pVBInfo->YPbPr750pTiming; } @@ -4868,10 +4868,10 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, temp &= 0x80; xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0xFF, temp); - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) + if (pVBInfo->VBInfo & SetCRT2ToHiVision) tempax = 950; - if (pVBInfo->TVInfo & SetPALTV) + if (pVBInfo->TVInfo & TVSetPAL) tempax = 520; else tempax = 440; @@ -4888,11 +4888,11 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, | VB_XGI302LV | VB_XGI301C)) { if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | SetCRT2ToSCART - | SetCRT2ToYPbPr)) { + | SetCRT2ToYPbPr525750)) { tempcx = pVBInfo->VGAHDE; if (tempcx >= 1024) { temp = 0x17; /* NTSC */ - if (pVBInfo->TVInfo & SetPALTV) + if (pVBInfo->TVInfo & TVSetPAL) temp = 0x19; /* PAL */ } } @@ -4907,11 +4907,11 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, | VB_XGI302LV | VB_XGI301C)) { if ((pVBInfo->VBInfo & (SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | SetCRT2ToSCART - | SetCRT2ToYPbPr))) { + | SetCRT2ToYPbPr525750))) { tempcx = pVBInfo->VGAHDE; if (tempcx >= 1024) { temp = 0x1D; /* NTSC */ - if (pVBInfo->TVInfo & SetPALTV) + if (pVBInfo->TVInfo & TVSetPAL) temp = 0x52; /* PAL */ } } @@ -4936,7 +4936,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, push1 = tempcx; /* push cx */ tempcx += 7; - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) + if (pVBInfo->VBInfo & SetCRT2ToHiVision) tempcx -= 4; temp = tempcx & 0x00FF; @@ -4954,7 +4954,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, tempbx = push2; tempbx = tempbx + 8; - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { + if (pVBInfo->VBInfo & SetCRT2ToHiVision) { tempbx = tempbx - 4; tempcx = tempbx; } @@ -4970,7 +4970,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, xgifb_reg_and_or(pVBInfo->Part2Port, 0x28, 0x0F, temp); tempcx += 8; - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) + if (pVBInfo->VBInfo & SetCRT2ToHiVision) tempcx -= 4; temp = tempcx & 0xFF; @@ -5007,7 +5007,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { if (!(pVBInfo->TVInfo & - (SetYPbPrMode525p | SetYPbPrMode750p))) + (TVSetYPbPr525p | TVSetYPbPr750p))) tempbx = tempbx >> 1; } else tempbx = tempbx >> 1; @@ -5016,9 +5016,9 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, tempbx -= 2; temp = tempbx & 0x00FF; - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { + if (pVBInfo->VBInfo & SetCRT2ToHiVision) { if (pVBInfo->VBType & VB_XGI301LV) { - if (pVBInfo->TVInfo & SetYPbPrMode1080i) { + if (pVBInfo->TVInfo & TVSetHiVision) { if (pVBInfo->VBInfo & SetInSlaveMode) { if (ModeNo == 0x2f) temp += 1; @@ -5037,9 +5037,9 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, temp = (tempcx & 0xFF00) >> 8; temp |= ((tempbx & 0xFF00) >> 8) << 6; - if (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)) { + if (!(pVBInfo->VBInfo & SetCRT2ToHiVision)) { if (pVBInfo->VBType & VB_XGI301LV) { - if (pVBInfo->TVInfo & SetYPbPrMode1080i) { + if (pVBInfo->TVInfo & TVSetHiVision) { temp |= 0x10; if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO)) @@ -5060,8 +5060,8 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, tempcx = tempbx - 2; if (pVBInfo->VBInfo & SetCRT2ToTV) { - if (!(pVBInfo->TVInfo & (SetYPbPrMode525p - | SetYPbPrMode750p))) + if (!(pVBInfo->TVInfo & (TVSetYPbPr525p + | TVSetYPbPr750p))) tempbx = tempbx >> 1; } @@ -5161,7 +5161,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, temp |= 0x18; xgifb_reg_and_or(pVBInfo->Part2Port, 0x46, ~0x1F, temp); - if (pVBInfo->TVInfo & SetPALTV) { + if (pVBInfo->TVInfo & TVSetPAL) { tempbx = 0x0382; tempcx = 0x007e; } else { @@ -5178,13 +5178,13 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, temp = temp << 2; temp |= ((tempbx & 0xFF00) >> 8) & 0x03; - if (pVBInfo->VBInfo & SetCRT2ToYPbPr) { + if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) { temp |= 0x10; - if (pVBInfo->TVInfo & SetYPbPrMode525p) + if (pVBInfo->TVInfo & TVSetYPbPr525p) temp |= 0x20; - if (pVBInfo->TVInfo & SetYPbPrMode750p) + if (pVBInfo->TVInfo & TVSetYPbPr750p) temp |= 0x60; } @@ -5192,7 +5192,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, temp = xgifb_reg_get(pVBInfo->Part2Port, 0x43); /* 301b change */ xgifb_reg_set(pVBInfo->Part2Port, 0x43, (unsigned short) (temp - 3)); - if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))) { + if (!(pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p))) { if (pVBInfo->TVInfo & NTSC1024x768) { TimingPoint = XGI_NTSC1024AdjTime; for (i = 0x1c, j = 0; i <= 0x30; i++, j++) { @@ -5205,12 +5205,12 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, /* [ycchen] 01/14/03 Modify for 301C PALM Support */ if (pVBInfo->VBType & VB_XGI301C) { - if (pVBInfo->TVInfo & SetPALMTV) + if (pVBInfo->TVInfo & TVSetPALM) xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x08, 0x08); /* PALM Mode */ } - if (pVBInfo->TVInfo & SetPALMTV) { + if (pVBInfo->TVInfo & TVSetPALM) { tempax = (unsigned char) xgifb_reg_get(pVBInfo->Part2Port, 0x01); tempax--; @@ -5219,7 +5219,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, xgifb_reg_and(pVBInfo->Part2Port, 0x00, 0xEF); } - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { + if (pVBInfo->VBInfo & SetCRT2ToHiVision) { if (!(pVBInfo->VBInfo & SetInSlaveMode)) xgifb_reg_set(pVBInfo->Part2Port, 0x0B, 0x00); } @@ -5473,18 +5473,18 @@ static struct XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(unsigned short tempcx, else Tap4TimingPtr = xgifb_ntsc_525_tap4_timing; /* NTSC */ - if (pVBInfo->TVInfo & SetPALTV) + if (pVBInfo->TVInfo & TVSetPAL) Tap4TimingPtr = PALTap4Timing; - if (pVBInfo->VBInfo & SetCRT2ToYPbPr) { - if ((pVBInfo->TVInfo & SetYPbPrMode525i) || - (pVBInfo->TVInfo & SetYPbPrMode525p)) + if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) { + if ((pVBInfo->TVInfo & TVSetYPbPr525i) || + (pVBInfo->TVInfo & TVSetYPbPr525p)) Tap4TimingPtr = xgifb_ntsc_525_tap4_timing; - if (pVBInfo->TVInfo & SetYPbPrMode750p) + if (pVBInfo->TVInfo & TVSetYPbPr750p) Tap4TimingPtr = YPbPr750pTap4Timing; } - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) + if (pVBInfo->VBInfo & SetCRT2ToHiVision) Tap4TimingPtr = xgifb_tap4_timing; i = 0; @@ -5510,7 +5510,7 @@ static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo) xgifb_reg_set(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]); if ((pVBInfo->VBInfo & SetCRT2ToTV) && - (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV))) { + (!(pVBInfo->VBInfo & SetCRT2ToHiVision))) { /* Set Vertical Scaling */ Tap4TimingPtr = XGI_GetTap4Ptr(1, pVBInfo); for (i = 0xC0, j = 0; i < 0xFF; i++, j++) @@ -5520,7 +5520,7 @@ static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo) } if ((pVBInfo->VBInfo & SetCRT2ToTV) && - (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV))) + (!(pVBInfo->VBInfo & SetCRT2ToHiVision))) /* Enable V.Scaling */ xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x14, 0x04); else @@ -5543,7 +5543,7 @@ static void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex, modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; xgifb_reg_set(pVBInfo->Part3Port, 0x00, 0x00); - if (pVBInfo->TVInfo & SetPALTV) { + if (pVBInfo->TVInfo & TVSetPAL) { xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xFA); xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xC8); } else { @@ -5554,15 +5554,15 @@ static void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex, if (!(pVBInfo->VBInfo & SetCRT2ToTV)) return; - if (pVBInfo->TVInfo & SetPALMTV) { + if (pVBInfo->TVInfo & TVSetPALM) { xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xFA); xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xC8); xgifb_reg_set(pVBInfo->Part3Port, 0x3D, 0xA8); } - if ((pVBInfo->VBInfo & SetCRT2ToHiVisionTV) || (pVBInfo->VBInfo - & SetCRT2ToYPbPr)) { - if (pVBInfo->TVInfo & SetYPbPrMode525i) + if ((pVBInfo->VBInfo & SetCRT2ToHiVision) || (pVBInfo->VBInfo + & SetCRT2ToYPbPr525750)) { + if (pVBInfo->TVInfo & TVSetYPbPr525i) return; tempdi = pVBInfo->HiTVGroup3Data; @@ -5572,17 +5572,17 @@ static void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex, tempdi = pVBInfo->HiTVGroup3Text; } - if (pVBInfo->TVInfo & SetYPbPrMode525p) + if (pVBInfo->TVInfo & TVSetYPbPr525p) tempdi = pVBInfo->Ren525pGroup3; - if (pVBInfo->TVInfo & SetYPbPrMode750p) + if (pVBInfo->TVInfo & TVSetYPbPr750p) tempdi = pVBInfo->Ren750pGroup3; for (i = 0; i <= 0x3E; i++) xgifb_reg_set(pVBInfo->Part3Port, i, tempdi[i]); if (pVBInfo->VBType & VB_XGI301C) { /* Marcovision */ - if (pVBInfo->TVInfo & SetYPbPrMode525p) + if (pVBInfo->TVInfo & TVSetYPbPr525p) xgifb_reg_set(pVBInfo->Part3Port, 0x28, 0x3f); } } @@ -5637,7 +5637,7 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, if (XGI_IsLCDDualLink(pVBInfo)) tempbx = tempbx >> 1; - if (tempcx & SetCRT2ToHiVisionTV) { + if (tempcx & SetCRT2ToHiVision) { temp = 0; if (tempbx <= 1024) temp = 0xA0; @@ -5656,7 +5656,7 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, } } - if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)) { + if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p)) { temp = 0x00; if (pVBInfo->VGAHDE == 1280) temp = 0x40; @@ -5667,7 +5667,7 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, tempebx = pVBInfo->VDE; - if (tempcx & SetCRT2ToHiVisionTV) { + if (tempcx & SetCRT2ToHiVision) { if (!(temp & 0xE000)) tempbx = tempbx >> 1; } @@ -5735,7 +5735,7 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, temp = (tempax & 0x00FF); xgifb_reg_set(pVBInfo->Part4Port, 0x1D, temp); - if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) { + if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVision)) { if (pVBInfo->VGAHDE > 800) xgifb_reg_or(pVBInfo->Part4Port, 0x1E, 0x08); @@ -5744,8 +5744,8 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->VBInfo & SetCRT2ToTV) { if (!(pVBInfo->TVInfo & (NTSC1024x768 - | SetYPbPrMode525p | SetYPbPrMode750p - | SetYPbPrMode1080i))) { + | TVSetYPbPr525p | TVSetYPbPr750p + | TVSetHiVision))) { temp |= 0x0001; if ((pVBInfo->VBInfo & SetInSlaveMode) && (!(pVBInfo->TVInfo @@ -6254,15 +6254,15 @@ static unsigned short XGI_GetTVPtrIndex(struct vb_device_info *pVBInfo) { unsigned short tempbx = 0; - if (pVBInfo->TVInfo & SetPALTV) + if (pVBInfo->TVInfo & TVSetPAL) tempbx = 2; - if (pVBInfo->TVInfo & SetYPbPrMode1080i) + if (pVBInfo->TVInfo & TVSetHiVision) tempbx = 4; - if (pVBInfo->TVInfo & SetYPbPrMode525i) + if (pVBInfo->TVInfo & TVSetYPbPr525i) tempbx = 6; - if (pVBInfo->TVInfo & SetYPbPrMode525p) + if (pVBInfo->TVInfo & TVSetYPbPr525p) tempbx = 8; - if (pVBInfo->TVInfo & SetYPbPrMode750p) + if (pVBInfo->TVInfo & TVSetYPbPr750p) tempbx = 10; if (pVBInfo->TVInfo & TVSimuMode) tempbx++; @@ -6293,18 +6293,18 @@ static void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char *tempcl, *tempcl = 0; *tempch = 0; - if (pVBInfo->TVInfo & SetPALTV) + if (pVBInfo->TVInfo & TVSetPAL) *tempbx = 1; - if (pVBInfo->TVInfo & SetPALMTV) + if (pVBInfo->TVInfo & TVSetPALM) *tempbx = 2; - if (pVBInfo->TVInfo & SetPALNTV) + if (pVBInfo->TVInfo & TVSetPALN) *tempbx = 3; if (pVBInfo->TVInfo & NTSC1024x768) { *tempbx = 4; - if (pVBInfo->TVInfo & SetPALMTV) + if (pVBInfo->TVInfo & TVSetPALM) *tempbx = 5; } @@ -6524,7 +6524,7 @@ static void XGI_SetAntiFlicker(unsigned short ModeNo, unsigned char tempah; - if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)) + if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p)) return; tempbx = XGI_GetTVPtrIndex(pVBInfo); -- cgit v1.2.3-70-g09d2 From 6896b94e2475948e78948df5a9b2a8c3a27fc6d9 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Thu, 9 Feb 2012 21:11:46 +0100 Subject: staging/xgifb: Rename remaining sis initdef.h defines and remove duplicates This patch renames the remaining duplicate defines and their usage to the naming convention of the sis initdef.h and removes the now duplicated defines. Renames: CRT2DisplayFlag -> DisableCRT2Display ModeInfoFlag -> ModeTypeMask Support16Bpp -> Mode16Bpp Support32Bpp -> Mode32Bpp SupportHiVisionTV -> SupportHiVision SupportYPbPr -> SupportYPbPr750p SwitchToCRT2 -> SwitchCRT2 VB_XGI301 -> VB_SIS301 VB_XGI301B -> VB_SIS301B VB_XGI301LV -> VB_SIS301LV VB_XGI302B -> VB_SIS302B VB_XGI302LV -> VB_SIS302LV VB_YPbPr525p -> YPbPr525p VB_YPbPr750p -> YPbPr750p VCLK108_2 -> VCLK108_2_315 VCLK65 -> VCLK65_315 XGI_CRT2_PORT_04 -> SIS_CRT2_PORT_04 XGI_CRT2_PORT_10 -> SIS_CRT2_PORT_10 XGI_CRT2_PORT_12 -> SIS_CRT2_PORT_12 XGI_CRT2_PORT_14 -> SIS_CRT2_PORT_14 Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 10 +- drivers/staging/xgifb/vb_def.h | 25 --- drivers/staging/xgifb/vb_init.c | 14 +- drivers/staging/xgifb/vb_setmode.c | 306 ++++++++++++++++++------------------ drivers/staging/xgifb/vb_table.h | 172 ++++++++++---------- 5 files changed, 251 insertions(+), 276 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index fb9b5b3cc55..21c037827de 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -371,15 +371,15 @@ static void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr) XGI_Pr->P3c9 = BaseAddr + 0x19; XGI_Pr->P3da = BaseAddr + 0x2A; /* Digital video interface registers (LCD) */ - XGI_Pr->Part1Port = BaseAddr + XGI_CRT2_PORT_04; + XGI_Pr->Part1Port = BaseAddr + SIS_CRT2_PORT_04; /* 301 TV Encoder registers */ - XGI_Pr->Part2Port = BaseAddr + XGI_CRT2_PORT_10; + XGI_Pr->Part2Port = BaseAddr + SIS_CRT2_PORT_10; /* 301 Macrovision registers */ - XGI_Pr->Part3Port = BaseAddr + XGI_CRT2_PORT_12; + XGI_Pr->Part3Port = BaseAddr + SIS_CRT2_PORT_12; /* 301 VGA2 (and LCD) registers */ - XGI_Pr->Part4Port = BaseAddr + XGI_CRT2_PORT_14; + XGI_Pr->Part4Port = BaseAddr + SIS_CRT2_PORT_14; /* 301 palette address port registers */ - XGI_Pr->Part5Port = BaseAddr + XGI_CRT2_PORT_14 + 2; + XGI_Pr->Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2; } diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h index c368322a233..12454c58a46 100644 --- a/drivers/staging/xgifb/vb_def.h +++ b/drivers/staging/xgifb/vb_def.h @@ -5,10 +5,6 @@ #include "../../video/sis/initdef.h" #define VB_XGI301C 0x0020 /* for 301C */ -/*end 301b*/ - -#define VB_YPbPr525p 0x01 -#define VB_YPbPr750p 0x02 #define VB_YPbPr1080i 0x03 #define LVDSCRT1Len 15 @@ -28,16 +24,10 @@ #define PanelRef60Hz 0x00 #define PanelRef75Hz 0x20 -#define CRT2DisplayFlag 0x2000 - #define YPbPr525iVCLK 0x03B #define YPbPr525iVCLK_2 0x03A #define XGI_CRT2_PORT_00 (0x00 - 0x030) -#define XGI_CRT2_PORT_04 (0x04 - 0x030) -#define XGI_CRT2_PORT_10 (0x10 - 0x30) -#define XGI_CRT2_PORT_12 (0x12 - 0x30) -#define XGI_CRT2_PORT_14 (0x14 - 0x30) #define _PanelType00 0x00 #define _PanelType01 0x08 @@ -77,15 +67,9 @@ #define VCLKLen 4 #define VGA_XGI340 0x0001 /* 340 series */ -#define VB_XGI301 0x0001 /* VB Type Info */ -#define VB_XGI301B 0x0002 /* 301 series */ -#define VB_XGI302B 0x0004 #define VB_NoLCD 0x8000 -#define VB_XGI301LV 0x0008 -#define VB_XGI302LV 0x0010 #define VB_LVDS_NS 0x0001 /* 3rd party chip */ -#define ModeInfoFlag 0x0007 #define ModeText 0x0000 #define ModeEGA 0x0002 /* 16 colors mode */ #define ModeVGA 0x0003 /* 256 colors mode */ @@ -103,19 +87,14 @@ #define DoubleScanMode 0x8000 /* -------------- Ext_InfoFlag */ -#define Support16Bpp 0x0005 -#define Support32Bpp 0x0007 - #define SupportAllCRT2 0x0078 #define SupportTV 0x0008 -#define SupportHiVisionTV 0x0010 #define SupportLCD 0x0020 #define SupportRAMDAC2 0x0040 #define NoSupportTV 0x0070 #define NoSupportHiVisionTV 0x0060 #define NoSupportLCD 0x0058 #define SupportTV1024 0x0800 /* 301btest */ -#define SupportYPbPr 0x1000 /* 301lv */ #define InterlaceMode 0x0080 #define SyncPP 0x0000 #define SyncPN 0x4000 @@ -124,7 +103,6 @@ /* -------------- SetMode Stack/Scratch */ #define SetSimuScanMode 0x0001 /* VBInfo/CR30 & CR31 */ -#define SwitchToCRT2 0x0002 #define SetCRT2ToTV 0x089C #define SetCRT2ToAVIDEO 0x0004 #define SetCRT2ToSVIDEO 0x0008 @@ -135,7 +113,6 @@ #define SetInSlaveMode 0x0200 #define SetNotSimuMode 0x0400 #define LoadDACFlag 0x1000 -#define DisableCRT2Display 0x2000 #define DriverMode 0x4000 #define SetCRT2ToDualEdge 0x8000 @@ -275,7 +252,6 @@ #define VCLK50 0x08 #define VCLK52_406 0x09 #define VCLK56_25 0x0A -#define VCLK65 0x0B #define VCLK68_179 0x0D #define VCLK72_852 0x0E #define VCLK75 0x0F @@ -284,7 +260,6 @@ #define VCLK83_95 0x13 #define VCLK86_6 0x15 #define VCLK94_5 0x16 -#define VCLK108_2 0x19 #define VCLK113_309 0x1B #define VCLK116_406 0x1C #define VCLK135_5 0x1E diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 4c545682a30..94d5c35e22f 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -1299,9 +1299,9 @@ static void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension, tempcl |= SetSimuScanMode; if ((!(temp & ActiveCRT1)) && ((temp & ActiveLCD) || (temp & ActiveTV) || (temp & ActiveCRT2))) - tempcl ^= (SetSimuScanMode | SwitchToCRT2); + tempcl ^= (SetSimuScanMode | SwitchCRT2); if ((temp & ActiveLCD) && (temp & ActiveTV)) - tempcl ^= (SetSimuScanMode | SwitchToCRT2); + tempcl ^= (SetSimuScanMode | SwitchCRT2); xgifb_reg_set(pVBInfo->P3d4, 0x30, tempcl); CR31Data = xgifb_reg_get(pVBInfo->P3d4, 0x31); @@ -1516,11 +1516,11 @@ unsigned char XGIInitNew(struct pci_dev *pdev) pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19; pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A; pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00; - pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04; - pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10; - pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12; - pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14; - pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2; + pVBInfo->Part1Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_04; + pVBInfo->Part2Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_10; + pVBInfo->Part3Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_12; + pVBInfo->Part4Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_14; + pVBInfo->Part5Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_14 + 2; printk("5"); if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 */ diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index ea142e9b94c..ab2157c5f97 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -138,7 +138,7 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) pVBInfo->UpdateCRT1 = (struct XGI_XG21CRT1Struct *) XGI_UpdateCRT1Table; /* 310 customization related */ - if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType & VB_XGI302LV)) + if ((pVBInfo->VBType & VB_SIS301LV) || (pVBInfo->VBType & VB_SIS302LV)) pVBInfo->LCDCapList = XGI_LCDDLCapList; else pVBInfo->LCDCapList = XGI_LCDCapList; @@ -373,9 +373,9 @@ static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, } if (pVBInfo->VBInfo & SetCRT2ToHiVision) { /* for HiTV */ - if ((pVBInfo->VBType & VB_XGI301LV) && + if ((pVBInfo->VBType & VB_SIS301LV) && (pVBInfo->VBExtInfo == VB_YPbPr1080i)) { - tempax |= SupportYPbPr; + tempax |= SupportYPbPr750p; if (pVBInfo->VBInfo & SetInSlaveMode) { if (resinfo == 4) return 0; @@ -387,7 +387,7 @@ static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, return 0; } } else { - tempax |= SupportHiVisionTV; + tempax |= SupportHiVision; if (pVBInfo->VBInfo & SetInSlaveMode) { if (resinfo == 4) return 0; @@ -410,8 +410,8 @@ static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, SetCRT2ToHiVision)) { tempax |= SupportTV; - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B - | VB_XGI301LV | VB_XGI302LV + if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B + | VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) { tempax |= SupportTV1024; } @@ -1230,23 +1230,23 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { - unsigned short LCDXlat1VCLK[4] = { VCLK65 + 2, - VCLK65 + 2, - VCLK65 + 2, - VCLK65 + 2 }; - unsigned short LCDXlat2VCLK[4] = { VCLK108_2 + 5, - VCLK108_2 + 5, - VCLK108_2 + 5, - VCLK108_2 + 5 }; + unsigned short LCDXlat1VCLK[4] = { VCLK65_315 + 2, + VCLK65_315 + 2, + VCLK65_315 + 2, + VCLK65_315 + 2 }; + unsigned short LCDXlat2VCLK[4] = { VCLK108_2_315 + 5, + VCLK108_2_315 + 5, + VCLK108_2_315 + 5, + VCLK108_2_315 + 5 }; unsigned short LVDSXlat1VCLK[4] = { VCLK40, VCLK40, VCLK40, VCLK40 }; - unsigned short LVDSXlat2VCLK[4] = { VCLK65 + 2, - VCLK65 + 2, - VCLK65 + 2, - VCLK65 + 2 }; - unsigned short LVDSXlat3VCLK[4] = { VCLK65 + 2, - VCLK65 + 2, - VCLK65 + 2, - VCLK65 + 2 }; + unsigned short LVDSXlat2VCLK[4] = { VCLK65_315 + 2, + VCLK65_315 + 2, + VCLK65_315 + 2, + VCLK65_315 + 2 }; + unsigned short LVDSXlat3VCLK[4] = { VCLK65_315 + 2, + VCLK65_315 + 2, + VCLK65_315 + 2, + VCLK65_315 + 2 }; unsigned short CRT2Index, VCLKIndex; unsigned short modeflag, resinfo; @@ -1291,11 +1291,11 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, } /* 301lv */ - if ((pVBInfo->VBType & VB_XGI301LV) && + if ((pVBInfo->VBType & VB_SIS301LV) && !(pVBInfo->VBExtInfo == VB_YPbPr1080i)) { - if (pVBInfo->VBExtInfo == VB_YPbPr750p) + if (pVBInfo->VBExtInfo == YPbPr750p) VCLKIndex = YPbPr750pVCLK; - else if (pVBInfo->VBExtInfo == VB_YPbPr525p) + else if (pVBInfo->VBExtInfo == YPbPr525p) VCLKIndex = YPbPr525pVCLK; else if (pVBInfo->SetFlag & RPLLDIV2XO) VCLKIndex = YPbPr525iVCLK_2; @@ -1360,8 +1360,8 @@ static void XGI_SetCRT1VCLK(unsigned short ModeNo, xgifb_reg_set(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[index].SR2C); xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01); - } else if ((pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) && (pVBInfo->VBInfo + } else if ((pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV + | VB_SIS302LV | VB_XGI301C)) && (pVBInfo->VBInfo & SetCRT2ToLCDA)) { vclkindex = XGI_GetVCLK2Ptr(ModeNo, ModeIdIndex, RefreshRateTableIndex, HwDeviceExtension, @@ -2128,30 +2128,30 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, return &XGI_CetLCDDes1024x768Data[tempal]; break; case 3: - if ((pVBInfo->VBType & VB_XGI301LV) || - (pVBInfo->VBType & VB_XGI302LV)) + if ((pVBInfo->VBType & VB_SIS301LV) || + (pVBInfo->VBType & VB_SIS302LV)) return &XGI_ExtLCDDLDes1280x1024Data[tempal]; else return &XGI_ExtLCDDes1280x1024Data[tempal]; break; case 4: - if ((pVBInfo->VBType & VB_XGI301LV) || - (pVBInfo->VBType & VB_XGI302LV)) + if ((pVBInfo->VBType & VB_SIS301LV) || + (pVBInfo->VBType & VB_SIS302LV)) return &XGI_StLCDDLDes1280x1024Data[tempal]; else return &XGI_StLCDDes1280x1024Data[tempal]; break; case 5: - if ((pVBInfo->VBType & VB_XGI301LV) || - (pVBInfo->VBType & VB_XGI302LV)) + if ((pVBInfo->VBType & VB_SIS301LV) || + (pVBInfo->VBType & VB_SIS302LV)) return &XGI_CetLCDDLDes1280x1024Data[tempal]; else return &XGI_CetLCDDes1280x1024Data[tempal]; break; case 6: case 7: - if ((pVBInfo->VBType & VB_XGI301LV) || - (pVBInfo->VBType & VB_XGI302LV)) + if ((pVBInfo->VBType & VB_SIS301LV) || + (pVBInfo->VBType & VB_SIS302LV)) return &xgifb_lcddldes_1400x1050[tempal]; else return &xgifb_lcddes_1400x1050[tempal]; @@ -2163,15 +2163,15 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, return &XGI_CetLCDDes1400x1050Data2[tempal]; break; case 10: - if ((pVBInfo->VBType & VB_XGI301LV) || - (pVBInfo->VBType & VB_XGI302LV)) + if ((pVBInfo->VBType & VB_SIS301LV) || + (pVBInfo->VBType & VB_SIS302LV)) return &XGI_ExtLCDDLDes1600x1200Data[tempal]; else return &XGI_ExtLCDDes1600x1200Data[tempal]; break; case 11: - if ((pVBInfo->VBType & VB_XGI301LV) || - (pVBInfo->VBType & VB_XGI302LV)) + if ((pVBInfo->VBType & VB_SIS301LV) || + (pVBInfo->VBType & VB_SIS302LV)) return &XGI_StLCDDLDes1600x1200Data[tempal]; else return &XGI_StLCDDes1600x1200Data[tempal]; @@ -2188,15 +2188,15 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, break; case 16: case 17: - if ((pVBInfo->VBType & VB_XGI301LV) || - (pVBInfo->VBType & VB_XGI302LV)) + if ((pVBInfo->VBType & VB_SIS301LV) || + (pVBInfo->VBType & VB_SIS302LV)) return &xgifb_lcddldes_1280x1024x75[tempal]; else return &xgifb_lcddes_1280x1024x75[tempal]; break; case 18: - if ((pVBInfo->VBType & VB_XGI301LV) || - (pVBInfo->VBType & VB_XGI302LV)) + if ((pVBInfo->VBType & VB_SIS301LV) || + (pVBInfo->VBType & VB_SIS302LV)) return &XGI_CetLCDDLDes1280x1024x75Data[tempal]; else return &XGI_CetLCDDes1280x1024x75Data[tempal]; @@ -2839,10 +2839,10 @@ static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex, /* {TV} */ if (pVBInfo->VBType & - (VB_XGI301B | - VB_XGI302B | - VB_XGI301LV | - VB_XGI302LV | + (VB_SIS301B | + VB_SIS302B | + VB_SIS301LV | + VB_SIS302LV | VB_XGI301C)) { if (pVBInfo->VBInfo & SetCRT2ToHiVision) { tempal = HiTVVCLKDIV2; @@ -2898,8 +2898,8 @@ static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex, static void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0, unsigned char *di_1, struct vb_device_info *pVBInfo) { - if (pVBInfo->VBType & (VB_XGI301 | VB_XGI301B | VB_XGI302B - | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { + if (pVBInfo->VBType & (VB_SIS301 | VB_SIS301B | VB_SIS302B + | VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) { if ((!(pVBInfo->VBInfo & SetCRT2ToLCDA)) && (pVBInfo->SetFlag & ProgrammingCRT2)) { *di_0 = (unsigned char) XGI_VBVCLKData[tempal].SR2B; @@ -2942,8 +2942,8 @@ static void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension, { unsigned short tempcl, tempch, temp, tempbl, tempax; - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { + if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV + | VB_SIS302LV | VB_XGI301C)) { tempcl = 0; tempch = 0; temp = xgifb_reg_get(pVBInfo->P3c4, 0x01); @@ -3029,19 +3029,19 @@ void XGI_GetVBType(struct vb_device_info *pVBInfo) unsigned short flag, tempbx, tempah; if (pVBInfo->IF_DEF_LVDS == 0) { - tempbx = VB_XGI302B; + tempbx = VB_SIS302B; flag = xgifb_reg_get(pVBInfo->Part4Port, 0x00); if (flag != 0x02) { - tempbx = VB_XGI301; + tempbx = VB_SIS301; flag = xgifb_reg_get(pVBInfo->Part4Port, 0x01); if (flag >= 0xB0) { - tempbx = VB_XGI301B; + tempbx = VB_SIS301B; if (flag >= 0xC0) { tempbx = VB_XGI301C; if (flag >= 0xD0) { - tempbx = VB_XGI301LV; + tempbx = VB_SIS301LV; if (flag >= 0xE0) { - tempbx = VB_XGI302LV; + tempbx = VB_SIS302LV; tempah = xgifb_reg_get( pVBInfo->Part4Port, 0x39); @@ -3052,7 +3052,7 @@ void XGI_GetVBType(struct vb_device_info *pVBInfo) } } - if (tempbx & (VB_XGI301B | VB_XGI302B)) { + if (tempbx & (VB_SIS301B | VB_SIS302B)) { flag = xgifb_reg_get( pVBInfo->Part4Port, 0x23); @@ -3078,7 +3078,7 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; pVBInfo->SetFlag = 0; - pVBInfo->ModeType = modeflag & ModeInfoFlag; + pVBInfo->ModeType = modeflag & ModeTypeMask; tempbx = 0; if (pVBInfo->VBType & 0xFFFF) { @@ -3103,9 +3103,9 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, (HwDeviceExtension->jChipType >= XG40)) { if (pVBInfo->IF_DEF_LVDS == 0) { if (pVBInfo->VBType & - (VB_XGI302B | - VB_XGI301LV | - VB_XGI302LV | + (VB_SIS302B | + VB_SIS301LV | + VB_SIS302LV | VB_XGI301C)) { if (temp & EnableDualEdge) { tempbx |= @@ -3123,8 +3123,8 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->IF_DEF_YPbPr == 1) { /* [Billy] 07/05/04 */ if (((pVBInfo->IF_DEF_LVDS == 0) && - ((pVBInfo->VBType & VB_XGI301LV) || - (pVBInfo->VBType & VB_XGI302LV) || + ((pVBInfo->VBType & VB_SIS301LV) || + (pVBInfo->VBType & VB_SIS302LV) || (pVBInfo->VBType & VB_XGI301C)))) { if (temp & SetYPbPr) { if (pVBInfo->IF_DEF_HiVision == 1) { @@ -3176,24 +3176,24 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, if (tempbx & SetSimuScanMode) tempbx &= (~(SetCRT2ToLCD | SetCRT2ToRAMDAC | - SwitchToCRT2)); + SwitchCRT2)); else tempbx &= (~(SetCRT2ToLCD | SetCRT2ToRAMDAC | SetCRT2ToTV | - SwitchToCRT2)); + SwitchCRT2)); } } } /* shampoo add */ /* for driver abnormal */ - if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode))) { + if (!(tempbx & (SwitchCRT2 | SetSimuScanMode))) { if (pVBInfo->IF_DEF_CRT2Monitor == 1) { if (tempbx & SetCRT2ToRAMDAC) { tempbx &= (0xFF00 | SetCRT2ToRAMDAC | - SwitchToCRT2 | + SwitchCRT2 | SetSimuScanMode); tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750)); } @@ -3208,7 +3208,7 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, if (tempbx & SetCRT2ToLCD) { tempbx &= (0xFF00 | SetCRT2ToLCD | - SwitchToCRT2 | + SwitchCRT2 | SetSimuScanMode); tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750)); } @@ -3217,7 +3217,7 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, if (tempbx & SetCRT2ToSCART) { tempbx &= (0xFF00 | SetCRT2ToSCART | - SwitchToCRT2 | + SwitchCRT2 | SetSimuScanMode); tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750)); } @@ -3225,7 +3225,7 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->IF_DEF_YPbPr == 1) { if (tempbx & SetCRT2ToYPbPr525750) tempbx &= (0xFF00 | - SwitchToCRT2 | + SwitchCRT2 | SetSimuScanMode); } @@ -3233,12 +3233,12 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, if (tempbx & SetCRT2ToHiVision) tempbx &= (0xFF00 | SetCRT2ToHiVision | - SwitchToCRT2 | + SwitchCRT2 | SetSimuScanMode); } if (tempax & DisableCRT2Display) { /* Set Display Device Info */ - if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode))) + if (!(tempbx & (SwitchCRT2 | SetSimuScanMode))) tempbx = DisableCRT2Display; } @@ -3350,10 +3350,10 @@ static void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex, (TVSetYPbPr525p | TVSetYPbPr750p)) tempbx &= (~RPLLDIV2XO); else if (!(pVBInfo->VBType & - (VB_XGI301B | - VB_XGI302B | - VB_XGI301LV | - VB_XGI302LV | + (VB_SIS301B | + VB_SIS302B | + VB_SIS301LV | + VB_SIS302LV | VB_XGI301C))) { if (tempbx & TVSimuMode) tempbx &= (~RPLLDIV2XO); @@ -3427,7 +3427,7 @@ static unsigned char XGI_GetLCDInfo(unsigned short ModeNo, tempax = pVBInfo->LCDCapList[LCDIdIndex].LCD_Capability; if (pVBInfo->IF_DEF_LVDS == 0) { /* shampoo */ - if (((pVBInfo->VBType & VB_XGI302LV) || (pVBInfo->VBType + if (((pVBInfo->VBType & VB_SIS302LV) || (pVBInfo->VBType & VB_XGI301C)) && (tempax & LCDDualLink)) { tempbx |= SetLCDDualLink; } @@ -4109,7 +4109,7 @@ static void XGI_SetCRT2VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo); XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo); - if (pVBInfo->VBType & VB_XGI301) { /* shampoo 0129 */ + if (pVBInfo->VBType & VB_SIS301) { /* shampoo 0129 */ /* 301 */ xgifb_reg_set(pVBInfo->Part4Port, 0x0A, 0x10); xgifb_reg_set(pVBInfo->Part4Port, 0x0B, di_1); @@ -4139,7 +4139,7 @@ static unsigned short XGI_GetColorDepth(unsigned short ModeNo, else modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - index = (modeflag & ModeInfoFlag) - ModeEGA; + index = (modeflag & ModeTypeMask) - ModeEGA; if (index < 0) index = 0; @@ -4435,7 +4435,7 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, xgifb_reg_set(pVBInfo->Part1Port, 0x03, temp); tempcx = 0x08; - if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) + if (pVBInfo->VBType & (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) modeflag |= Charx8Dot; tempax = pVBInfo->VGAHDE; /* 0x04 Horizontal Display End */ @@ -4451,12 +4451,12 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, temp = (tempbx & 0xFF00) >> 8; if (pVBInfo->VBInfo & SetCRT2ToTV) { - if (!(pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C))) + if (!(pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV + | VB_SIS302LV | VB_XGI301C))) temp += 2; if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - if (pVBInfo->VBType & VB_XGI301LV) { + if (pVBInfo->VBType & VB_SIS301LV) { if (pVBInfo->VBExtInfo == VB_YPbPr1080i) { if (resinfo == 7) temp -= 2; @@ -4670,14 +4670,14 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, } if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - if (pVBInfo->VBType & VB_XGI301LV) { + if (pVBInfo->VBType & VB_SIS301LV) { if (pVBInfo->TVInfo & TVSetHiVision) { tempbx -= 10; } else { if (pVBInfo->TVInfo & TVSimuMode) { if (pVBInfo->TVInfo & TVSetPAL) { if (pVBInfo->VBType & - VB_XGI301LV) { + VB_SIS301LV) { if (!(pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p | @@ -4695,7 +4695,7 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, } else { if (pVBInfo->TVInfo & TVSimuMode) { if (pVBInfo->TVInfo & TVSetPAL) { - if (pVBInfo->VBType & VB_XGI301LV) { + if (pVBInfo->VBType & VB_SIS301LV) { if (!(pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p | @@ -4761,7 +4761,7 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, temp = (temp >> 1) & 0x09; - if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) + if (pVBInfo->VBType & (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) temp |= 0x01; xgifb_reg_set(pVBInfo->Part1Port, 0x16, temp); /* 0x16 SR01 */ @@ -4884,8 +4884,8 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, temp = (tempax & 0xFF00) >> 8; temp += (unsigned short) TimingPoint[0]; - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { + if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV + | VB_SIS302LV | VB_XGI301C)) { if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | SetCRT2ToSCART | SetCRT2ToYPbPr525750)) { @@ -4903,8 +4903,8 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, temp = (tempax & 0xFF00) >> 8; temp += TimingPoint[1]; - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { + if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV + | VB_SIS302LV | VB_XGI301C)) { if ((pVBInfo->VBInfo & (SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | SetCRT2ToSCART | SetCRT2ToYPbPr525750))) { @@ -5005,7 +5005,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->VBInfo & SetCRT2ToTV) { if (pVBInfo->VBType & - (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { + (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) { if (!(pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p))) tempbx = tempbx >> 1; @@ -5017,7 +5017,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, temp = tempbx & 0x00FF; if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - if (pVBInfo->VBType & VB_XGI301LV) { + if (pVBInfo->VBType & VB_SIS301LV) { if (pVBInfo->TVInfo & TVSetHiVision) { if (pVBInfo->VBInfo & SetInSlaveMode) { if (ModeNo == 0x2f) @@ -5038,7 +5038,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, temp |= ((tempbx & 0xFF00) >> 8) << 6; if (!(pVBInfo->VBInfo & SetCRT2ToHiVision)) { - if (pVBInfo->VBType & VB_XGI301LV) { + if (pVBInfo->VBType & VB_SIS301LV) { if (pVBInfo->TVInfo & TVSetHiVision) { temp |= 0x10; @@ -5054,8 +5054,8 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, xgifb_reg_set(pVBInfo->Part2Port, 0x30, temp); - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { /* TV gatingno */ + if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV + | VB_SIS302LV | VB_XGI301C)) { /* TV gatingno */ tempbx = pVBInfo->VDE; tempcx = tempbx - 2; @@ -5065,7 +5065,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, tempbx = tempbx >> 1; } - if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) { + if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) { temp = 0; if (tempcx & 0x0400) temp |= 0x20; @@ -5118,8 +5118,8 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, /* 301b */ tempecx = 8 * 1024; - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { + if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV + | VB_SIS302LV | VB_XGI301C)) { tempecx = tempecx * 8; } @@ -5133,8 +5133,8 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, tempax = (unsigned short) tempeax; /* 301b */ - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { + if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV + | VB_SIS302LV | VB_XGI301C)) { tempcx = ((tempax & 0xFF00) >> 5) >> 8; } /* end 301b */ @@ -5375,7 +5375,7 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, tempcx = tempcx >> 1; } - if (pVBInfo->VBType & VB_XGI302LV) + if (pVBInfo->VBType & VB_SIS302LV) tempbx += 1; if (pVBInfo->VBType & VB_XGI301C) /* tap4 */ @@ -5405,7 +5405,7 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, tempcx = tempcx >> 1; } - if (pVBInfo->VBType & VB_XGI302LV) + if (pVBInfo->VBType & VB_SIS302LV) tempbx += 1; tempcx += tempbx; @@ -5424,8 +5424,8 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, if (!(pVBInfo->LCDInfo & LCDVESATiming)) { if (pVBInfo->VGAVDE == 525) { - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B - | VB_XGI301LV | VB_XGI302LV + if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B + | VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) { temp = 0xC6; } else @@ -5436,8 +5436,8 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, } if (pVBInfo->VGAVDE == 420) { - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B - | VB_XGI301LV | VB_XGI302LV + if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B + | VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) { temp = 0x4F; } else @@ -5705,8 +5705,8 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, xgifb_reg_set(pVBInfo->Part4Port, 0x19, temp); /* 301b */ - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { + if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV + | VB_SIS302LV | VB_XGI301C)) { temp = 0x0028; xgifb_reg_set(pVBInfo->Part4Port, 0x1C, temp); tempax = pVBInfo->VGAHDE; @@ -5785,7 +5785,7 @@ static void XGI_SetGroup5(unsigned short ModeNo, unsigned short ModeIdIndex, Pdata = pVBInfo->Part5Port + 1; if (pVBInfo->ModeType == ModeVGA) { if (!(pVBInfo->VBInfo & (SetInSlaveMode | LoadDACFlag - | CRT2DisplayFlag))) { + | DisableCRT2Display))) { XGINew_EnableCRT2(pVBInfo); } } @@ -6074,7 +6074,7 @@ static unsigned char XGI_IsLCDON(struct vb_device_info *pVBInfo) tempax = pVBInfo->VBInfo; if (tempax & SetCRT2ToDualEdge) return 0; - else if (tempax & (DisableCRT2Display | SwitchToCRT2 | SetSimuScanMode)) + else if (tempax & (DisableCRT2Display | SwitchCRT2 | SetSimuScanMode)) return 1; return 0; @@ -6140,8 +6140,8 @@ static void XGI_DisableBridge(struct xgifb_video_info *xgifb_info, { unsigned short tempah = 0; - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { + if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV + | VB_SIS302LV | VB_XGI301C)) { tempah = 0x3F; if (!(pVBInfo->VBInfo & (DisableCRT2Display | SetSimuScanMode))) { @@ -6166,7 +6166,7 @@ static void XGI_DisableBridge(struct xgifb_video_info *xgifb_info, /* disable part4_1f */ xgifb_reg_and(pVBInfo->Part4Port, 0x1F, tempah); - if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) { + if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) { if (((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) || (XGI_DisableChISLCD(pVBInfo)) || (XGI_IsLCDON(pVBInfo))) @@ -6308,8 +6308,8 @@ static void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char *tempcl, *tempbx = 5; } - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { + if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV + | VB_SIS302LV | VB_XGI301C)) { if ((!(pVBInfo->VBInfo & SetInSlaveMode)) || (pVBInfo->TVInfo & TVSimuMode)) { *tempbx += 8; @@ -6317,8 +6317,8 @@ static void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char *tempcl, } } - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) + if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV + | VB_SIS302LV | VB_XGI301C)) (*tempch)++; } @@ -6328,8 +6328,8 @@ static void XGI_SetDelayComp(struct vb_device_info *pVBInfo) unsigned char tempah, tempbl, tempbh; - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { + if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV + | VB_SIS302LV | VB_XGI301C)) { if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToTV | SetCRT2ToRAMDAC)) { tempbl = 0; @@ -6338,8 +6338,8 @@ static void XGI_SetDelayComp(struct vb_device_info *pVBInfo) index = XGI_GetTVPtrIndex(pVBInfo); /* Get TV Delay */ tempbl = pVBInfo->XGI_TVDelayList[index]; - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B - | VB_XGI301LV | VB_XGI302LV + if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B + | VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) tempbl = pVBInfo->XGI_TVDelayList2[index]; @@ -6475,13 +6475,13 @@ static void XGI_SetLCDCap(struct vb_device_info *pVBInfo) tempcx = pVBInfo->LCDCapList[XGI_GetLCDCapPtr(pVBInfo)].LCD_Capability; if (pVBInfo->VBType & - (VB_XGI301B | - VB_XGI302B | - VB_XGI301LV | - VB_XGI302LV | + (VB_SIS301B | + VB_SIS302B | + VB_SIS301LV | + VB_SIS302LV | VB_XGI301C)) { /* 301LV/302LV only */ if (pVBInfo->VBType & - (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { + (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) { /* Set 301LV Capability */ xgifb_reg_set(pVBInfo->Part4Port, 0x24, (unsigned char) (tempcx & 0x1F)); @@ -6493,14 +6493,14 @@ static void XGI_SetLCDCap(struct vb_device_info *pVBInfo) | EnablePLLSPLOW)) >> 8)); } - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { + if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV + | VB_SIS302LV | VB_XGI301C)) { if (pVBInfo->VBInfo & SetCRT2ToLCD) XGI_SetLCDCap_B(tempcx, pVBInfo); else if (pVBInfo->VBInfo & SetCRT2ToLCDA) XGI_SetLCDCap_A(tempcx, pVBInfo); - if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) { + if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) { if (tempcx & EnableSpectrum) SetSpectrum(pVBInfo); } @@ -6648,8 +6648,8 @@ static void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex, xgifb_reg_set(pVBInfo->Part2Port, 0x38, filterPtr[index++]); } - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { + if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV + | VB_SIS302LV | VB_XGI301C)) { xgifb_reg_set(pVBInfo->Part2Port, 0x48, filterPtr[index++]); xgifb_reg_set(pVBInfo->Part2Port, 0x49, filterPtr[index++]); xgifb_reg_set(pVBInfo->Part2Port, 0x4A, filterPtr[index++]); @@ -6676,7 +6676,7 @@ static void XGI_OEM310Setting(unsigned short ModeNo, XGI_SetYFilter(ModeNo, ModeIdIndex, pVBInfo); XGI_SetAntiFlicker(ModeNo, ModeIdIndex, pVBInfo); - if (pVBInfo->VBType & VB_XGI301) + if (pVBInfo->VBType & VB_SIS301) XGI_SetEdgeEnhance(ModeNo, ModeIdIndex, pVBInfo); } } @@ -6817,8 +6817,8 @@ static void XGI_SetCRT2ModeRegs(unsigned short ModeNo, xgifb_reg_set(pVBInfo->Part4Port, 0x0C, tempah); } - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { + if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV + | VB_SIS302LV | VB_XGI301C)) { tempah = 0; tempbl = 0xfb; @@ -6857,7 +6857,7 @@ static void XGI_SetCRT2ModeRegs(unsigned short ModeNo, xgifb_reg_and_or(pVBInfo->Part4Port, 0x23, tempbl, tempah); - if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) { + if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) { if (pVBInfo->LCDInfo & SetLCDDualLink) { xgifb_reg_or(pVBInfo->Part4Port, 0x27, 0x20); xgifb_reg_or(pVBInfo->Part4Port, 0x34, 0x10); @@ -6939,8 +6939,8 @@ unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE, if (pVBInfo->SetFlag & ProgrammingCRT2) { if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { if (pVBInfo->IF_DEF_LVDS == 0) { - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B - | VB_XGI301LV | VB_XGI302LV + if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B + | VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) /* 301b */ temp = LCDARefreshIndex[ @@ -6983,7 +6983,7 @@ unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE, break; temp = pVBInfo->RefIndex[RefreshRateTableIndex + i]. Ext_InfoFlag; - temp &= ModeInfoFlag; + temp &= ModeTypeMask; if (temp < pVBInfo->ModeType) break; i++; @@ -7163,8 +7163,8 @@ static void XGI_EnableBridge(struct xgifb_video_info *xgifb_info, { unsigned short tempah; - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { + if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV + | VB_SIS302LV | VB_XGI301C)) { if (!(pVBInfo->SetFlag & DisableChA)) { if (pVBInfo->SetFlag & EnableChA) { /* Power on */ @@ -7207,7 +7207,7 @@ static void XGI_EnableBridge(struct xgifb_video_info *xgifb_info, || (!(pVBInfo->VBInfo & DisableCRT2Display))) { xgifb_reg_and_or(pVBInfo->Part2Port, 0x00, ~0xE0, 0x20); /* shampoo 0129 */ - if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) { + if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) { if (!XGI_DisableChISLCD(pVBInfo)) { if (XGI_EnableChISLCD(pVBInfo) || (pVBInfo->VBInfo & @@ -7311,8 +7311,8 @@ static void XGI_SetCRT1Group(struct xgifb_video_info *xgifb_info, pVBInfo->SetFlag &= temp; pVBInfo->SelectCRT2Rate = 0; - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { + if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV + | VB_SIS302LV | VB_XGI301C)) { if (pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToLCDA | SetInSlaveMode)) { pVBInfo->SetFlag |= ProgrammingCRT2; @@ -7415,11 +7415,11 @@ unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info, pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19; pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A; pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00; - pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04; - pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10; - pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12; - pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14; - pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2; + pVBInfo->Part1Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_04; + pVBInfo->Part2Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_10; + pVBInfo->Part3Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_12; + pVBInfo->Part4Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_14; + pVBInfo->Part5Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_14 + 2; /* for x86 Linux, XG21 LVDS */ if (HwDeviceExtension->jChipType == XG21) { @@ -7461,7 +7461,7 @@ unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info, HwDeviceExtension, pVBInfo); } } else { - if (!(pVBInfo->VBInfo & SwitchToCRT2)) { + if (!(pVBInfo->VBInfo & SwitchCRT2)) { XGI_SetCRT1Group(xgifb_info, HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo); @@ -7473,7 +7473,7 @@ unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info, } } - if (pVBInfo->VBInfo & (SetSimuScanMode | SwitchToCRT2)) { + if (pVBInfo->VBInfo & (SetSimuScanMode | SwitchCRT2)) { switch (HwDeviceExtension->ujVBChipID) { case VB_CHIP_301: XGI_SetCRT2Group301(ModeNo, HwDeviceExtension, @@ -7504,10 +7504,10 @@ unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info, if (ModeNo <= 0x13) { pVBInfo->ModeType = pVBInfo->SModeIDTable[ModeIdIndex]. - St_ModeFlag & ModeInfoFlag; + St_ModeFlag & ModeTypeMask; } else { pVBInfo->ModeType = pVBInfo->EModeIDTable[ModeIdIndex]. - Ext_ModeFlag & ModeInfoFlag; + Ext_ModeFlag & ModeTypeMask; } pVBInfo->SetFlag = 0; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index c587d411835..4f803b615a1 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -2501,17 +2501,17 @@ static unsigned short LCDLenList[] = { /* Dual link only */ static struct XGI330_LCDCapStruct XGI_LCDDLCapList[] = { /* LCDCap1024x768 */ - {Panel_1024x768, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65, + {Panel_1024x768, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65_315, 0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}, /* LCDCap1280x1024 */ {Panel_1280x1024, LCDDualLink+DefaultLCDCap, StLCDBToA, - 0x012, 0x70, 0x03, VCLK108_2, + 0x012, 0x70, 0x03, VCLK108_2_315, 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, /* LCDCap1400x1050 */ {Panel_1400x1050, LCDDualLink+DefaultLCDCap, StLCDBToA, - 0x012, 0x70, 0x03, VCLK108_2, + 0x012, 0x70, 0x03, VCLK108_2_315, 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, /* LCDCap1600x1200 */ @@ -2529,24 +2529,24 @@ static struct XGI330_LCDCapStruct XGI_LCDDLCapList[] = { 0x54, 0x42, 0x4A, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, /* LCDCapDefault */ - {0xFF, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65, + {0xFF, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65_315, 0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10} }; static struct XGI330_LCDCapStruct XGI_LCDCapList[] = { /* LCDCap1024x768 */ - {Panel_1024x768, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65, + {Panel_1024x768, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65_315, 0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}, /* LCDCap1280x1024 */ {Panel_1280x1024, DefaultLCDCap, StLCDBToA, - 0x012, 0x70, 0x03, VCLK108_2, + 0x012, 0x70, 0x03, VCLK108_2_315, 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, /* LCDCap1400x1050 */ {Panel_1400x1050, DefaultLCDCap, StLCDBToA, - 0x012, 0x70, 0x03, VCLK108_2, + 0x012, 0x70, 0x03, VCLK108_2_315, 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, /* LCDCap1600x1200 */ @@ -2564,162 +2564,162 @@ static struct XGI330_LCDCapStruct XGI_LCDCapList[] = { 0x54, 0x42, 0x4A, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, /* LCDCapDefault */ - {0xFF, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65, + {0xFF, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65_315, 0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10} }; static struct XGI_Ext2Struct XGI330_RefIndex[] = { - {Support32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175, + {Mode32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175, 0x00, 0x10, 0x59, 320, 200},/* 00 */ - {Support32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175, + {Mode32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175, 0x00, 0x10, 0x00, 320, 400},/* 01 */ - {Support32Bpp + SupportAllCRT2 + SyncNN, RES320x240, VCLK25_175, + {Mode32Bpp + SupportAllCRT2 + SyncNN, RES320x240, VCLK25_175, 0x04, 0x20, 0x50, 320, 240},/* 02 */ - {Support32Bpp + SupportAllCRT2 + SyncPP, RES400x300, VCLK40, + {Mode32Bpp + SupportAllCRT2 + SyncPP, RES400x300, VCLK40, 0x05, 0x32, 0x51, 400, 300},/* 03 */ - {Support32Bpp + NoSupportTV + SyncNN + SupportTV1024, RES512x384, - VCLK65, 0x06, 0x43, 0x52, 512, 384},/* 04 */ - {Support32Bpp + SupportAllCRT2 + SyncPN, RES640x400, VCLK25_175, + {Mode32Bpp + NoSupportTV + SyncNN + SupportTV1024, RES512x384, + VCLK65_315, 0x06, 0x43, 0x52, 512, 384},/* 04 */ + {Mode32Bpp + SupportAllCRT2 + SyncPN, RES640x400, VCLK25_175, 0x00, 0x14, 0x2f, 640, 400},/* 05 */ - {Support32Bpp + SupportAllCRT2 + SyncNN, RES640x480x60, VCLK25_175, + {Mode32Bpp + SupportAllCRT2 + SyncNN, RES640x480x60, VCLK25_175, 0x04, 0x24, 0x2e, 640, 480},/* 06 640x480x60Hz (LCD 640x480x60z) */ - {Support32Bpp + NoSupportHiVisionTV + SyncNN, RES640x480x72, VCLK31_5, + {Mode32Bpp + NoSupportHiVisionTV + SyncNN, RES640x480x72, VCLK31_5, 0x04, 0x24, 0x2e, 640, 480},/* 07 640x480x72Hz (LCD 640x480x70Hz) */ - {Support32Bpp + NoSupportHiVisionTV + SyncNN, RES640x480x75, VCLK31_5, + {Mode32Bpp + NoSupportHiVisionTV + SyncNN, RES640x480x75, VCLK31_5, 0x47, 0x24, 0x2e, 640, 480},/* 08 640x480x75Hz (LCD 640x480x75Hz) */ - {Support32Bpp + SupportRAMDAC2 + SyncNN, RES640x480x85, VCLK36, + {Mode32Bpp + SupportRAMDAC2 + SyncNN, RES640x480x85, VCLK36, 0x8A, 0x24, 0x2e, 640, 480},/* 09 640x480x85Hz */ - {Support32Bpp + SupportRAMDAC2 + SyncPN, RES640x480x100, VCLK43_163, + {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES640x480x100, VCLK43_163, 0x00, 0x24, 0x2e, 640, 480},/* 0a 640x480x100Hz */ - {Support32Bpp + SupportRAMDAC2 + SyncPN, RES640x480x120, VCLK52_406, + {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES640x480x120, VCLK52_406, 0x00, 0x24, 0x2e, 640, 480},/* 0b 640x480x120Hz */ - {Support32Bpp + SupportRAMDAC2 + SyncPN, RES640x480x160, VCLK72_852, + {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES640x480x160, VCLK72_852, 0x00, 0x24, 0x2e, 640, 480},/* 0c 640x480x160Hz */ - {Support32Bpp + SupportRAMDAC2 + SyncNN, RES640x480x200, VCLK86_6, + {Mode32Bpp + SupportRAMDAC2 + SyncNN, RES640x480x200, VCLK86_6, 0x00, 0x24, 0x2e, 640, 480},/* 0d 640x480x200Hz */ - {Support32Bpp + NoSupportLCD + SyncPP, RES800x600x56, VCLK36, + {Mode32Bpp + NoSupportLCD + SyncPP, RES800x600x56, VCLK36, 0x05, 0x36, 0x6a, 800, 600},/* 0e 800x600x56Hz */ - {Support32Bpp + NoSupportTV + SyncPP, RES800x600x60, VCLK40, + {Mode32Bpp + NoSupportTV + SyncPP, RES800x600x60, VCLK40, 0x05, 0x36, 0x6a, 800, 600},/* 0f 800x600x60Hz (LCD 800x600x60Hz) */ - {Support32Bpp + NoSupportHiVisionTV + SyncPP, RES800x600x72, VCLK50, + {Mode32Bpp + NoSupportHiVisionTV + SyncPP, RES800x600x72, VCLK50, 0x48, 0x36, 0x6a, 800, 600},/* 10 800x600x72Hz (LCD 800x600x70Hz) */ - {Support32Bpp + NoSupportHiVisionTV + SyncPP, RES800x600x75, VCLK49_5, + {Mode32Bpp + NoSupportHiVisionTV + SyncPP, RES800x600x75, VCLK49_5, 0x8B, 0x36, 0x6a, 800, 600},/* 11 800x600x75Hz (LCD 800x600x75Hz) */ - {Support32Bpp + SupportRAMDAC2 + SyncPP, RES800x600x85, VCLK56_25, + {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES800x600x85, VCLK56_25, 0x00, 0x36, 0x6a, 800, 600},/* 12 800x600x85Hz */ - {Support32Bpp + SupportRAMDAC2 + SyncPN, RES800x600x100, VCLK68_179, + {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES800x600x100, VCLK68_179, 0x00, 0x36, 0x6a, 800, 600},/* 13 800x600x100Hz */ - {Support32Bpp + SupportRAMDAC2 + SyncPN, RES800x600x120, VCLK83_95, + {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES800x600x120, VCLK83_95, 0x00, 0x36, 0x6a, 800, 600},/* 14 800x600x120Hz */ - {Support32Bpp + SupportRAMDAC2 + SyncPN, RES800x600x160, VCLK116_406, + {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES800x600x160, VCLK116_406, 0x00, 0x36, 0x6a, 800, 600},/* 15 800x600x160Hz */ - {Support32Bpp + InterlaceMode + SyncPP, RES1024x768x43, VCLK44_9, + {Mode32Bpp + InterlaceMode + SyncPP, RES1024x768x43, VCLK44_9, 0x00, 0x47, 0x37, 1024, 768},/* 16 1024x768x43Hz */ /* 17 1024x768x60Hz (LCD 1024x768x60Hz) */ - {Support32Bpp + NoSupportTV + SyncNN + SupportTV1024, RES1024x768x60, - VCLK65, 0x06, 0x47, 0x37, 1024, 768}, - {Support32Bpp + NoSupportHiVisionTV + SyncNN, RES1024x768x70, VCLK75, + {Mode32Bpp + NoSupportTV + SyncNN + SupportTV1024, RES1024x768x60, + VCLK65_315, 0x06, 0x47, 0x37, 1024, 768}, + {Mode32Bpp + NoSupportHiVisionTV + SyncNN, RES1024x768x70, VCLK75, 0x49, 0x47, 0x37, 1024, 768},/* 18 1024x768x70Hz (LCD 1024x768x70Hz) */ - {Support32Bpp + NoSupportHiVisionTV + SyncPP, RES1024x768x75, VCLK78_75, + {Mode32Bpp + NoSupportHiVisionTV + SyncPP, RES1024x768x75, VCLK78_75, 0x00, 0x47, 0x37, 1024, 768},/* 19 1024x768x75Hz (LCD 1024x768x75Hz) */ - {Support32Bpp + SupportRAMDAC2 + SyncPP, RES1024x768x85, VCLK94_5, + {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1024x768x85, VCLK94_5, 0x8C, 0x47, 0x37, 1024, 768},/* 1a 1024x768x85Hz */ - {Support32Bpp + SupportRAMDAC2 + SyncPN, RES1024x768x100, VCLK113_309, + {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES1024x768x100, VCLK113_309, 0x00, 0x47, 0x37, 1024, 768},/* 1b 1024x768x100Hz */ - {Support32Bpp + SupportRAMDAC2 + SyncPN, RES1024x768x120, VCLK139_054, + {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES1024x768x120, VCLK139_054, 0x00, 0x47, 0x37, 1024, 768},/* 1c 1024x768x120Hz */ - {Support32Bpp + SupportLCD + SyncPP, RES1280x960x60, VCLK108_2, + {Mode32Bpp + SupportLCD + SyncPP, RES1280x960x60, VCLK108_2_315, 0x08, 0x58, 0x7b, 1280, 960},/* 1d 1280x960x60Hz */ - {Support32Bpp + InterlaceMode + SyncPP, RES1280x1024x43, VCLK78_75, + {Mode32Bpp + InterlaceMode + SyncPP, RES1280x1024x43, VCLK78_75, 0x00, 0x58, 0x3a, 1280, 1024},/* 1e 1280x1024x43Hz */ - {Support32Bpp + NoSupportTV + SyncPP, RES1280x1024x60, VCLK108_2, + {Mode32Bpp + NoSupportTV + SyncPP, RES1280x1024x60, VCLK108_2_315, 0x07, 0x58, 0x3a, 1280, 1024},/*1f 1280x1024x60Hz (LCD 1280x1024x60Hz)*/ - {Support32Bpp + NoSupportTV + SyncPP, RES1280x1024x75, VCLK135_5, + {Mode32Bpp + NoSupportTV + SyncPP, RES1280x1024x75, VCLK135_5, 0x00, 0x58, 0x3a, 1280, 1024},/*20 1280x1024x75Hz (LCD 1280x1024x75Hz)*/ - {Support32Bpp + SyncPP, RES1280x1024x85, VCLK157_5, + {Mode32Bpp + SyncPP, RES1280x1024x85, VCLK157_5, 0x00, 0x58, 0x3a, 1280, 1024},/* 21 1280x1024x85Hz */ /* 22 1600x1200x60Hz */ - {Support32Bpp + SupportLCD + SyncPP + SupportCRT2in301C, + {Mode32Bpp + SupportLCD + SyncPP + SupportCRT2in301C, RES1600x1200x60, VCLK162, 0x09, 0x7A, 0x3c, 1600, 1200}, - {Support32Bpp + SyncPP + SupportCRT2in301C, RES1600x1200x65, VCLK175, + {Mode32Bpp + SyncPP + SupportCRT2in301C, RES1600x1200x65, VCLK175, 0x00, 0x69, 0x3c, 1600, 1200},/* 23 1600x1200x65Hz */ - {Support32Bpp + SyncPP + SupportCRT2in301C, RES1600x1200x70, VCLK189, + {Mode32Bpp + SyncPP + SupportCRT2in301C, RES1600x1200x70, VCLK189, 0x00, 0x69, 0x3c, 1600, 1200},/* 24 1600x1200x70Hz */ - {Support32Bpp + SyncPP + SupportCRT2in301C, RES1600x1200x75, VCLK202_5, + {Mode32Bpp + SyncPP + SupportCRT2in301C, RES1600x1200x75, VCLK202_5, 0x00, 0x69, 0x3c, 1600, 1200},/* 25 1600x1200x75Hz */ - {Support32Bpp + SyncPP, RES1600x1200x85, VCLK229_5, + {Mode32Bpp + SyncPP, RES1600x1200x85, VCLK229_5, 0x00, 0x69, 0x3c, 1600, 1200},/* 26 1600x1200x85Hz */ - {Support32Bpp + SyncPP, RES1600x1200x100, VCLK269_655, + {Mode32Bpp + SyncPP, RES1600x1200x100, VCLK269_655, 0x00, 0x69, 0x3c, 1600, 1200},/* 27 1600x1200x100Hz */ - {Support32Bpp + SyncPP, RES1600x1200x120, VCLK323_586, + {Mode32Bpp + SyncPP, RES1600x1200x120, VCLK323_586, 0x00, 0x69, 0x3c, 1600, 1200},/* 28 1600x1200x120Hz */ - {Support32Bpp + SupportLCD + SyncNP, RES1920x1440x60, VCLK234, + {Mode32Bpp + SupportLCD + SyncNP, RES1920x1440x60, VCLK234, 0x00, 0x00, 0x68, 1920, 1440},/* 29 1920x1440x60Hz */ - {Support32Bpp + SyncPN, RES1920x1440x65, VCLK254_817, + {Mode32Bpp + SyncPN, RES1920x1440x65, VCLK254_817, 0x00, 0x00, 0x68, 1920, 1440},/* 2a 1920x1440x65Hz */ - {Support32Bpp + SyncPN, RES1920x1440x70, VCLK277_015, + {Mode32Bpp + SyncPN, RES1920x1440x70, VCLK277_015, 0x00, 0x00, 0x68, 1920, 1440},/* 2b 1920x1440x70Hz */ - {Support32Bpp + SyncPN, RES1920x1440x75, VCLK291_132, + {Mode32Bpp + SyncPN, RES1920x1440x75, VCLK291_132, 0x00, 0x00, 0x68, 1920, 1440},/* 2c 1920x1440x75Hz */ - {Support32Bpp + SyncPN, RES1920x1440x85, VCLK330_615, + {Mode32Bpp + SyncPN, RES1920x1440x85, VCLK330_615, 0x00, 0x00, 0x68, 1920, 1440},/* 2d 1920x1440x85Hz */ - {Support16Bpp + SyncPN, RES1920x1440x100, VCLK388_631, + {Mode16Bpp + SyncPN, RES1920x1440x100, VCLK388_631, 0x00, 0x00, 0x68, 1920, 1440},/* 2e 1920x1440x100Hz */ - {Support32Bpp + SupportLCD + SyncPN, RES2048x1536x60, VCLK266_952, + {Mode32Bpp + SupportLCD + SyncPN, RES2048x1536x60, VCLK266_952, 0x00, 0x00, 0x6c, 2048, 1536},/* 2f 2048x1536x60Hz */ - {Support32Bpp + SyncPN, RES2048x1536x65, VCLK291_766, + {Mode32Bpp + SyncPN, RES2048x1536x65, VCLK291_766, 0x00, 0x00, 0x6c, 2048, 1536},/* 30 2048x1536x65Hz */ - {Support32Bpp + SyncPN, RES2048x1536x70, VCLK315_195, + {Mode32Bpp + SyncPN, RES2048x1536x70, VCLK315_195, 0x00, 0x00, 0x6c, 2048, 1536},/* 31 2048x1536x70Hz */ - {Support32Bpp + SyncPN, RES2048x1536x75, VCLK340_477, + {Mode32Bpp + SyncPN, RES2048x1536x75, VCLK340_477, 0x00, 0x00, 0x6c, 2048, 1536},/* 32 2048x1536x75Hz */ - {Support16Bpp + SyncPN, RES2048x1536x85, VCLK375_847, + {Mode16Bpp + SyncPN, RES2048x1536x85, VCLK375_847, 0x00, 0x00, 0x6c, 2048, 1536},/* 33 2048x1536x85Hz */ - {Support32Bpp + SupportHiVisionTV + SupportRAMDAC2 + - SyncPP + SupportYPbPr, RES800x480x60, VCLK39_77, + {Mode32Bpp + SupportHiVision + SupportRAMDAC2 + + SyncPP + SupportYPbPr750p, RES800x480x60, VCLK39_77, 0x08, 0x00, 0x70, 800, 480},/* 34 800x480x60Hz */ - {Support32Bpp + SupportRAMDAC2 + SyncPP, RES800x480x75, VCLK49_5, + {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES800x480x75, VCLK49_5, 0x08, 0x00, 0x70, 800, 480},/* 35 800x480x75Hz */ - {Support32Bpp + SupportRAMDAC2 + SyncPP, RES800x480x85, VCLK56_25, + {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES800x480x85, VCLK56_25, 0x08, 0x00, 0x70, 800, 480},/* 36 800x480x85Hz */ - {Support32Bpp + SupportHiVisionTV + SupportRAMDAC2 + - SyncPP + SupportYPbPr, RES1024x576x60, VCLK65, + {Mode32Bpp + SupportHiVision + SupportRAMDAC2 + + SyncPP + SupportYPbPr750p, RES1024x576x60, VCLK65_315, 0x09, 0x00, 0x71, 1024, 576},/* 37 1024x576x60Hz */ - {Support32Bpp + SupportRAMDAC2 + SyncPP, RES1024x576x75, VCLK78_75, + {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1024x576x75, VCLK78_75, 0x09, 0x00, 0x71, 1024, 576},/* 38 1024x576x75Hz */ - {Support32Bpp + SupportRAMDAC2 + SyncPP, RES1024x576x85, VCLK94_5, + {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1024x576x85, VCLK94_5, 0x09, 0x00, 0x71, 1024, 576},/* 39 1024x576x85Hz */ - {Support32Bpp + SupportHiVisionTV + SupportRAMDAC2 + - SyncPP + SupportYPbPr, RES1280x720x60, VCLK108_2, + {Mode32Bpp + SupportHiVision + SupportRAMDAC2 + + SyncPP + SupportYPbPr750p, RES1280x720x60, VCLK108_2_315, 0x0A, 0x00, 0x75, 1280, 720},/* 3a 1280x720x60Hz*/ - {Support32Bpp + SupportRAMDAC2 + SyncPP, RES1280x720x75, VCLK135_5, + {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1280x720x75, VCLK135_5, 0x0A, 0x00, 0x75, 1280, 720},/* 3b 1280x720x75Hz */ - {Support32Bpp + SupportRAMDAC2 + SyncPP, RES1280x720x85, VCLK157_5, + {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1280x720x85, VCLK157_5, 0x0A, 0x00, 0x75, 1280, 720},/* 3c 1280x720x85Hz */ - {Support32Bpp + SupportTV + SyncNN, RES720x480x60, VCLK28_322, + {Mode32Bpp + SupportTV + SyncNN, RES720x480x60, VCLK28_322, 0x06, 0x00, 0x31, 720, 480},/* 3d 720x480x60Hz */ - {Support32Bpp + SupportTV + SyncPP, RES720x576x56, VCLK36, + {Mode32Bpp + SupportTV + SyncPP, RES720x576x56, VCLK36, 0x06, 0x00, 0x32, 720, 576},/* 3e 720x576x56Hz */ - {Support32Bpp + InterlaceMode + NoSupportLCD + SyncPP, RES856x480x79I, + {Mode32Bpp + InterlaceMode + NoSupportLCD + SyncPP, RES856x480x79I, VCLK35_2, 0x00, 0x00, 0x00, 856, 480},/* 3f 856x480x79I */ - {Support32Bpp + NoSupportLCD + SyncNN, RES856x480x60, VCLK35_2, + {Mode32Bpp + NoSupportLCD + SyncNN, RES856x480x60, VCLK35_2, 0x00, 0x00, 0x00, 856, 480},/* 40 856x480x60Hz */ - {Support32Bpp + NoSupportHiVisionTV + SyncPP, RES1280x768x60, + {Mode32Bpp + NoSupportHiVisionTV + SyncPP, RES1280x768x60, VCLK79_411, 0x08, 0x48, 0x23, 1280, 768},/* 41 1280x768x60Hz */ - {Support32Bpp + NoSupportHiVisionTV + SyncPP, RES1400x1050x60, + {Mode32Bpp + NoSupportHiVisionTV + SyncPP, RES1400x1050x60, VCLK122_61, 0x08, 0x69, 0x26, 1400, 1050},/* 42 1400x1050x60Hz */ - {Support32Bpp + SupportRAMDAC2 + SyncPP, RES1152x864x60, VCLK80_350, + {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1152x864x60, VCLK80_350, 0x37, 0x00, 0x20, 1152, 864},/* 43 1152x864x60Hz */ - {Support32Bpp + SupportRAMDAC2 + SyncPP, RES1152x864x75, VCLK107_385, + {Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1152x864x75, VCLK107_385, 0x37, 0x00, 0x20, 1152, 864},/* 44 1152x864x75Hz */ - {Support32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP, RES1280x960x75, + {Mode32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP, RES1280x960x75, VCLK125_999, 0x3A, 0x88, 0x7b, 1280, 960},/* 45 1280x960x75Hz */ - {Support32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP, RES1280x960x85, + {Mode32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP, RES1280x960x85, VCLK148_5, 0x0A, 0x88, 0x7b, 1280, 960},/* 46 1280x960x85Hz */ - {Support32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP, RES1280x960x120, + {Mode32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP, RES1280x960x120, VCLK217_325, 0x3A, 0x88, 0x7b, 1280, 960},/* 47 1280x960x120Hz */ - {Support32Bpp + SupportRAMDAC2 + SyncPN, RES1024x768x160, VCLK139_054, + {Mode32Bpp + SupportRAMDAC2 + SyncPN, RES1024x768x160, VCLK139_054, 0x30, 0x47, 0x37, 1024, 768},/* 48 1024x768x160Hz */ }; -- cgit v1.2.3-70-g09d2 From a3d675c88fe1ede40386e944e1f3ab5988aeb13c Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Thu, 9 Feb 2012 21:11:47 +0100 Subject: staging/xgifb: Rename XGI specific initdef.h defines This patch renames some of the defines that exist in the sis initdef.h but seem to have a different value. In order to preserve the functionality of the driver, we simply prepend these defines with XGI_ (for now) to resolve conflicts and review them later on. Renames: SetCRT2ToLCDA -> XGI_SetCRT2ToLCDA LCDVESATiming -> XGI_LCDVESATiming EnableLVDSDDA -> XGI_EnableLVDSDDA LCDDualLink -> XGI_LCDDualLink ModeSwitchStatus -> XGI_ModeSwitchStatus YPbPr750pVCLK -> XGI_YPbPr750pVCLK Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_def.h | 12 +-- drivers/staging/xgifb/vb_setmode.c | 148 ++++++++++++++++++------------------- drivers/staging/xgifb/vb_table.h | 8 +- 3 files changed, 84 insertions(+), 84 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h index 12454c58a46..a4fedbd3691 100644 --- a/drivers/staging/xgifb/vb_def.h +++ b/drivers/staging/xgifb/vb_def.h @@ -109,7 +109,7 @@ #define SetCRT2ToSCART 0x0010 #define SetCRT2ToLCD 0x0020 #define SetCRT2ToRAMDAC 0x0040 -#define SetCRT2ToLCDA 0x0100 +#define XGI_SetCRT2ToLCDA 0x0100 #define SetInSlaveMode 0x0200 #define SetNotSimuMode 0x0400 #define LoadDACFlag 0x1000 @@ -131,8 +131,8 @@ #define NTSC1024x768 0x2000 #define SetTVLockMode 0x4000 -#define LCDVESATiming 0x0001 /* LCD Info/CR37 */ -#define EnableLVDSDDA 0x0002 +#define XGI_LCDVESATiming 0x0001 /* LCD Info/CR37 */ +#define XGI_EnableLVDSDDA 0x0002 #define EnableScalingLCD 0x0008 #define SetPWDEnable 0x0004 #define SetLCDtoNonExpanding 0x0010 @@ -145,7 +145,7 @@ #define EnableLCD24bpp 0x0004 /* default */ #define DisableLCD24bpp 0x0000 #define LCDPolarity 0x00c0 /* default: SyncNN */ -#define LCDDualLink 0x0100 +#define XGI_LCDDualLink 0x0100 #define EnableSpectrum 0x0200 #define PWDEnable 0x0400 #define EnableVBCLKDRVLOW 0x4000 @@ -191,7 +191,7 @@ #define DisplayDeviceFromCMOS 0x10 /* ---------------------- HK Evnet Definition */ -#define ModeSwitchStatus 0xf0 +#define XGI_ModeSwitchStatus 0xf0 #define ActiveCRT1 0x10 #define ActiveLCD 0x0020 #define ActiveTV 0x40 @@ -286,7 +286,7 @@ #define VCLK125_999 0x51 #define VCLK148_5 0x52 #define VCLK217_325 0x55 -#define YPbPr750pVCLK 0x57 +#define XGI_YPbPr750pVCLK 0x57 #define TVVCLKDIV2 0x3A #define TVVCLK 0x3B diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index ab2157c5f97..42eaec7c8b2 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -208,8 +208,8 @@ static void XGI_SetSeqRegs(unsigned short ModeNo, xgifb_reg_set(pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */ tempah = pVBInfo->StandTable[StandTableIndex].SR[0]; - i = SetCRT2ToLCDA; - if (pVBInfo->VBInfo & SetCRT2ToLCDA) { + i = XGI_SetCRT2ToLCDA; + if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { tempah |= 0x01; } else { if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) { @@ -263,7 +263,7 @@ static void XGI_SetATTRegs(unsigned short ModeNo, ARdata = pVBInfo->StandTable[StandTableIndex].ATTR[i]; if (modeflag & Charx8Dot) { /* ifndef Dot9 */ if (i == 0x13) { - if (pVBInfo->VBInfo & SetCRT2ToLCDA) { + if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { ARdata = 0; } else { if (pVBInfo->VBInfo & (SetCRT2ToTV @@ -356,7 +356,7 @@ static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, } /* 301b */ - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { + if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { tempax |= SupportLCD; if (pVBInfo->LCDResInfo != Panel_1280x1024) { @@ -1266,7 +1266,7 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, if (pVBInfo->IF_DEF_LVDS == 0) { CRT2Index = CRT2Index >> 6; /* for LCD */ - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /*301b*/ + if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { /*301b*/ if (pVBInfo->LCDResInfo != Panel_1024x768) VCLKIndex = LCDXlat2VCLK[CRT2Index]; else @@ -1294,7 +1294,7 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, if ((pVBInfo->VBType & VB_SIS301LV) && !(pVBInfo->VBExtInfo == VB_YPbPr1080i)) { if (pVBInfo->VBExtInfo == YPbPr750p) - VCLKIndex = YPbPr750pVCLK; + VCLKIndex = XGI_YPbPr750pVCLK; else if (pVBInfo->VBExtInfo == YPbPr525p) VCLKIndex = YPbPr525pVCLK; else if (pVBInfo->SetFlag & RPLLDIV2XO) @@ -1362,7 +1362,7 @@ static void XGI_SetCRT1VCLK(unsigned short ModeNo, xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01); } else if ((pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) && (pVBInfo->VBInfo - & SetCRT2ToLCDA)) { + & XGI_SetCRT2ToLCDA)) { vclkindex = XGI_GetVCLK2Ptr(ModeNo, ModeIdIndex, RefreshRateTableIndex, HwDeviceExtension, pVBInfo); @@ -1801,7 +1801,7 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, Ext_CRT2CRTC; } - if (pVBInfo->VBInfo & SetCRT2ToLCDA) { + if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { if (ModeNo <= 0x13) tempal = pVBInfo->SModeIDTable[ModeIdIndex]. St_CRT2CRTC2; @@ -2364,7 +2364,7 @@ static void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex, tempbx = 2; - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { + if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { LCDPtr = (struct XGI330_LVDSDataStruct *) XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); @@ -2374,7 +2374,7 @@ static void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex, pVBInfo->VT = LCDPtr->LCDVT; } - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { + if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { if (!(pVBInfo->LCDInfo & (SetLCDtoNonExpanding | EnableScalingLCD))) { if ((pVBInfo->LCDResInfo == Panel_1024x768) || @@ -2415,7 +2415,7 @@ static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex, tempbx = 0; - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { + if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { LCDPtr = (struct XGI_LVDSCRT1HDataStruct *) XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, @@ -2430,7 +2430,7 @@ static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex, tempbx = 1; - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { + if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { LCDPtr1 = (struct XGI_LVDSCRT1VDataStruct *) XGI_GetLcdPtr( tempbx, @@ -2682,7 +2682,7 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, if (tempbx != pVBInfo->VDE) tempax |= 0x40; - if (pVBInfo->LCDInfo & EnableLVDSDDA) + if (pVBInfo->LCDInfo & XGI_EnableLVDSDDA) tempax |= 0x40; xgifb_reg_and_or(pVBInfo->Part1Port, 0x1a, 0x07, @@ -2800,7 +2800,7 @@ static void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1, { unsigned short index; - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { + if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { index = XGI_GetLCDCapPtr1(pVBInfo); if (pVBInfo->VBInfo & SetCRT2ToLCD) { /* LCDB */ @@ -2834,7 +2834,7 @@ static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex, index = XGI_GetLCDCapPtr(pVBInfo); tempal = pVBInfo->LCDCapList[index].LCD_VCLK; - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) + if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) return tempal; /* {TV} */ @@ -2858,7 +2858,7 @@ static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex, } if (pVBInfo->TVInfo & TVSetYPbPr750p) { - tempal = YPbPr750pVCLK; + tempal = XGI_YPbPr750pVCLK; return tempal; } @@ -2900,7 +2900,7 @@ static void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0, { if (pVBInfo->VBType & (VB_SIS301 | VB_SIS301B | VB_SIS302B | VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) { - if ((!(pVBInfo->VBInfo & SetCRT2ToLCDA)) && (pVBInfo->SetFlag + if ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) && (pVBInfo->SetFlag & ProgrammingCRT2)) { *di_0 = (unsigned char) XGI_VBVCLKData[tempal].SR2B; *di_1 = XGI_VBVCLKData[tempal].SR2C; @@ -2926,7 +2926,7 @@ static void XGI_SetCRT2ECLK(unsigned short ModeNo, unsigned short ModeIdIndex, for (i = 0; i < 4; i++) { xgifb_reg_and_or(pVBInfo->P3d4, 0x31, ~0x30, (unsigned short) (0x10 * i)); - if ((!(pVBInfo->VBInfo & SetCRT2ToLCDA)) + if ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) && (!(pVBInfo->VBInfo & SetInSlaveMode))) { xgifb_reg_set(pVBInfo->P3c4, 0x2e, di_0); xgifb_reg_set(pVBInfo->P3c4, 0x2f, di_1); @@ -3014,7 +3014,7 @@ static void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension, } } temp = tempcl; - tempbl = ~ModeSwitchStatus; + tempbl = ~XGI_ModeSwitchStatus; xgifb_reg_and_or(pVBInfo->P3d4, 0x3d, tempbl, temp); if (!(pVBInfo->SetFlag & ReserveTVOption)) @@ -3090,7 +3090,7 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, push = push << 8; tempax = temp << 8; tempbx = tempbx | tempax; - temp = (SetCRT2ToDualEdge | SetCRT2ToYPbPr525750 | SetCRT2ToLCDA + temp = (SetCRT2ToDualEdge | SetCRT2ToYPbPr525750 | XGI_SetCRT2ToLCDA | SetInSlaveMode | DisableCRT2Display); temp = 0xFFFF ^ temp; tempbx &= temp; @@ -3113,7 +3113,7 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, if (temp & SetToLCDA) tempbx |= - SetCRT2ToLCDA; + XGI_SetCRT2ToLCDA; } } } @@ -3172,7 +3172,7 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->IF_DEF_LCDA == 1) { /* Select Display Device */ if (!(pVBInfo->VBType & VB_NoLCD)) { - if (tempbx & SetCRT2ToLCDA) { + if (tempbx & XGI_SetCRT2ToLCDA) { if (tempbx & SetSimuScanMode) tempbx &= (~(SetCRT2ToLCD | SetCRT2ToRAMDAC | @@ -3246,7 +3246,7 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, if ((!(tempbx & DriverMode)) || (!(modeflag & CRT2Mode))) { if (pVBInfo->IF_DEF_LCDA == 1) { - if (!(tempbx & SetCRT2ToLCDA)) + if (!(tempbx & XGI_SetCRT2ToLCDA)) tempbx |= (SetInSlaveMode | SetSimuScanMode); } @@ -3255,9 +3255,9 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, /* LCD+TV can't support in slave mode * (Force LCDA+TV->LCDB) */ if ((tempbx & SetInSlaveMode) && - (tempbx & SetCRT2ToLCDA)) { + (tempbx & XGI_SetCRT2ToLCDA)) { tempbx ^= (SetCRT2ToLCD | - SetCRT2ToLCDA | + XGI_SetCRT2ToLCDA | SetCRT2ToDualEdge); pVBInfo->SetFlag |= ReserveTVOption; } @@ -3392,7 +3392,7 @@ static unsigned char XGI_GetLCDInfo(unsigned short ModeNo, if ((tempbx == Panel_1024x768) || (tempbx == Panel_1280x1024)) { if (pVBInfo->VBInfo & DriverMode) { tempax = xgifb_reg_get(pVBInfo->P3d4, 0x33); - if (pVBInfo->VBInfo & SetCRT2ToLCDA) + if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) tempax &= 0x0F; else tempax = tempax >> 4; @@ -3411,7 +3411,7 @@ static unsigned char XGI_GetLCDInfo(unsigned short ModeNo, /* End of LCD75 */ - if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) + if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))) return 0; tempbx = 0; @@ -3428,7 +3428,7 @@ static unsigned char XGI_GetLCDInfo(unsigned short ModeNo, if (pVBInfo->IF_DEF_LVDS == 0) { /* shampoo */ if (((pVBInfo->VBType & VB_SIS302LV) || (pVBInfo->VBType - & VB_XGI301C)) && (tempax & LCDDualLink)) { + & VB_XGI301C)) && (tempax & XGI_LCDDualLink)) { tempbx |= SetLCDDualLink; } } @@ -3444,13 +3444,13 @@ static unsigned char XGI_GetLCDInfo(unsigned short ModeNo, if (pVBInfo->IF_DEF_ExpLink == 1) { if (modeflag & HalfDCLK) { if (!(tempbx & SetLCDtoNonExpanding)) { - tempbx |= EnableLVDSDDA; + tempbx |= XGI_EnableLVDSDDA; } else { if (ModeNo > 0x13) { if (pVBInfo->LCDResInfo == Panel_1024x768) { if (resinfo == 4) {/* 512x384 */ - tempbx |= EnableLVDSDDA; + tempbx |= XGI_EnableLVDSDDA; } } } @@ -3460,9 +3460,9 @@ static unsigned char XGI_GetLCDInfo(unsigned short ModeNo, if (pVBInfo->VBInfo & SetInSlaveMode) { if (pVBInfo->VBInfo & SetNotSimuMode) - tempbx |= LCDVESATiming; + tempbx |= XGI_LCDVESATiming; } else { - tempbx |= LCDVESATiming; + tempbx |= XGI_LCDVESATiming; } pVBInfo->LCDInfo = tempbx; @@ -3477,7 +3477,7 @@ static unsigned char XGI_GetLCDInfo(unsigned short ModeNo, SetInSlaveMode | SetCRT2ToLCD); pVBInfo->VBInfo |= - SetCRT2ToLCDA | + XGI_SetCRT2ToLCDA | SetCRT2ToDualEdge; } } @@ -3802,7 +3802,7 @@ static void XGI_GetCRT2ResInfo(unsigned short ModeNo, if (pVBInfo->VBInfo & SetCRT2ToLCD) { if (pVBInfo->IF_DEF_LVDS == 0) { if (pVBInfo->LCDResInfo == Panel_1600x1200) { - if (!(pVBInfo->LCDInfo & LCDVESATiming)) { + if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) { if (yres == 1024) yres = 1056; } @@ -3814,14 +3814,14 @@ static void XGI_GetCRT2ResInfo(unsigned short ModeNo, else if (yres == 350) yres = 360; - if (pVBInfo->LCDInfo & LCDVESATiming) { + if (pVBInfo->LCDInfo & XGI_LCDVESATiming) { if (yres == 360) yres = 375; } } if (pVBInfo->LCDResInfo == Panel_1024x768) { - if (!(pVBInfo->LCDInfo & LCDVESATiming)) { + if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) { if (!(pVBInfo->LCDInfo & LCDNonExpanding)) { if (yres == 350) @@ -3848,7 +3848,7 @@ static void XGI_GetCRT2ResInfo(unsigned short ModeNo, static unsigned char XGI_IsLCDDualLink(struct vb_device_info *pVBInfo) { - if ((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) && + if ((pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) && (pVBInfo->LCDInfo & SetLCDDualLink)) /* shampoo0129 */ return 1; @@ -3942,7 +3942,7 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, tempbx = 4; - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { + if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { LCDPtr = (struct SiS_LCDData *) XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); @@ -3958,7 +3958,7 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, tempax = 1024; tempbx = 768; - if (!(pVBInfo->LCDInfo & LCDVESATiming)) { + if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) { if (pVBInfo->VGAVDE == 357) tempbx = 527; else if (pVBInfo->VGAVDE == 420) @@ -4008,7 +4008,7 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, } else if (pVBInfo->LCDResInfo == Panel_1600x1200) { tempax = 1600; tempbx = 1200; /* alan 10/14/2003 */ - if (!(pVBInfo->LCDInfo & LCDVESATiming)) { + if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) { if (pVBInfo->VGAVDE == 350) tempbx = 875; else if (pVBInfo->VGAVDE == 400) @@ -4620,7 +4620,7 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->VBInfo & SetCRT2ToLCD) { if (pVBInfo->LCDResInfo == Panel_1024x768) { - if (!(pVBInfo->LCDInfo & LCDVESATiming)) { + if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) { if (tempbx == 350) tempbx += 5; if (tempbx == 480) @@ -5271,7 +5271,7 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->ModeType == ModeEGA) { if (pVBInfo->VGAHDE >= 1024) { temp = 0x02; - if (pVBInfo->LCDInfo & LCDVESATiming) + if (pVBInfo->LCDInfo & XGI_LCDVESATiming) temp = 0x01; } } @@ -5422,7 +5422,7 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, temp = tempcx & 0x00FF; /* RHSYEXP2S=lcdhre */ xgifb_reg_set(pVBInfo->Part2Port, 0x21, temp); - if (!(pVBInfo->LCDInfo & LCDVESATiming)) { + if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) { if (pVBInfo->VGAVDE == 525) { if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV | VB_SIS302LV @@ -6145,10 +6145,10 @@ static void XGI_DisableBridge(struct xgifb_video_info *xgifb_info, tempah = 0x3F; if (!(pVBInfo->VBInfo & (DisableCRT2Display | SetSimuScanMode))) { - if (pVBInfo->VBInfo & SetCRT2ToLCDA) { + if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { if (pVBInfo->VBInfo & SetCRT2ToDualEdge) { tempah = 0x7F; /* Disable Channel A */ - if (!(pVBInfo->VBInfo & SetCRT2ToLCDA)) + if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) /* Disable Channel B */ tempah = 0xBF; @@ -6167,7 +6167,7 @@ static void XGI_DisableBridge(struct xgifb_video_info *xgifb_info, xgifb_reg_and(pVBInfo->Part4Port, 0x1F, tempah); if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) { - if (((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) + if (((pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))) || (XGI_DisableChISLCD(pVBInfo)) || (XGI_IsLCDON(pVBInfo))) /* LVDS Driver power down */ @@ -6175,16 +6175,16 @@ static void XGI_DisableBridge(struct xgifb_video_info *xgifb_info, } if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo - & (DisableCRT2Display | SetCRT2ToLCDA + & (DisableCRT2Display | XGI_SetCRT2ToLCDA | SetSimuScanMode))) { if (pVBInfo->SetFlag & GatingCRT) XGI_EnableGatingCRT(HwDeviceExtension, pVBInfo); XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo); } - if (pVBInfo->VBInfo & SetCRT2ToLCDA) { + if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo - & SetCRT2ToLCDA)) + & XGI_SetCRT2ToLCDA)) /* Power down */ xgifb_reg_and(pVBInfo->Part1Port, 0x1e, 0xdf); } @@ -6198,7 +6198,7 @@ static void XGI_DisableBridge(struct xgifb_video_info *xgifb_info, if ((pVBInfo->SetFlag & DisableChB) || (pVBInfo->VBInfo & (DisableCRT2Display | SetSimuScanMode)) || - ((!(pVBInfo->VBInfo & SetCRT2ToLCDA)) && + ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) && (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV)))) xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80); @@ -6206,7 +6206,7 @@ static void XGI_DisableBridge(struct xgifb_video_info *xgifb_info, if ((pVBInfo->SetFlag & DisableChB) || (pVBInfo->VBInfo & (DisableCRT2Display | SetSimuScanMode)) || - (!(pVBInfo->VBInfo & SetCRT2ToLCDA)) || + (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) || (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))) { /* save Part1 index 0 */ @@ -6227,7 +6227,7 @@ static void XGI_DisableBridge(struct xgifb_video_info *xgifb_info, xgifb_reg_and(pVBInfo->P3c4, 0x32, 0xDF); } - if (pVBInfo->VBInfo & (DisableCRT2Display | SetCRT2ToLCDA + if (pVBInfo->VBInfo & (DisableCRT2Display | XGI_SetCRT2ToLCDA | SetSimuScanMode)) XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo); } @@ -6330,7 +6330,7 @@ static void XGI_SetDelayComp(struct vb_device_info *pVBInfo) if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) { - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA + if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA | SetCRT2ToTV | SetCRT2ToRAMDAC)) { tempbl = 0; tempbh = 0; @@ -6345,13 +6345,13 @@ static void XGI_SetDelayComp(struct vb_device_info *pVBInfo) if (pVBInfo->VBInfo & SetCRT2ToDualEdge) tempbl = tempbl >> 4; - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { + if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { /* Get LCD Delay */ index = XGI_GetLCDCapPtr(pVBInfo); tempbh = pVBInfo->LCDCapList[index]. LCD_DelayCompensation; - if (!(pVBInfo->VBInfo & SetCRT2ToLCDA)) + if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) tempbl = tempbh; } @@ -6365,7 +6365,7 @@ static void XGI_SetDelayComp(struct vb_device_info *pVBInfo) tempah |= tempbl; } - if (pVBInfo->VBInfo & SetCRT2ToLCDA) { /* Channel A */ + if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { /* Channel A */ tempah &= 0x0F; tempah |= tempbh; } @@ -6497,7 +6497,7 @@ static void XGI_SetLCDCap(struct vb_device_info *pVBInfo) | VB_SIS302LV | VB_XGI301C)) { if (pVBInfo->VBInfo & SetCRT2ToLCD) XGI_SetLCDCap_B(tempcx, pVBInfo); - else if (pVBInfo->VBInfo & SetCRT2ToLCDA) + else if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) XGI_SetLCDCap_A(tempcx, pVBInfo); if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) { @@ -6668,7 +6668,7 @@ static void XGI_OEM310Setting(unsigned short ModeNo, { XGI_SetDelayComp(pVBInfo); - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) + if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) XGI_SetLCDCap(pVBInfo); if (pVBInfo->VBInfo & SetCRT2ToTV) { @@ -6732,15 +6732,15 @@ static void XGI_SetCRT2ModeRegs(unsigned short ModeNo, tempbl = 0xff; if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV - | SetCRT2ToLCD | SetCRT2ToLCDA)) { - if ((pVBInfo->VBInfo & SetCRT2ToLCDA) && + | SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { + if ((pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) && (!(pVBInfo->VBInfo & SetSimuScanMode))) { tempbl &= 0xf7; tempah |= 0x01; xgifb_reg_and_or(pVBInfo->Part1Port, 0x2e, tempbl, tempah); } else { - if (pVBInfo->VBInfo & SetCRT2ToLCDA) { + if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { tempbl &= 0xf7; tempah |= 0x01; } @@ -6780,7 +6780,7 @@ static void XGI_SetCRT2ModeRegs(unsigned short ModeNo, } if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD - | SetCRT2ToLCDA)) { + | XGI_SetCRT2ToLCDA)) { tempah &= (~0x08); if ((pVBInfo->ModeType == ModeVGA) && (!(pVBInfo->VBInfo & SetInSlaveMode))) { @@ -6824,7 +6824,7 @@ static void XGI_SetCRT2ModeRegs(unsigned short ModeNo, if (pVBInfo->VBInfo & SetCRT2ToDualEdge) { tempbl = 0xff; - if (pVBInfo->VBInfo & SetCRT2ToLCDA) + if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) tempah |= 0x04; /* shampoo 0129 */ } @@ -6849,7 +6849,7 @@ static void XGI_SetCRT2ModeRegs(unsigned short ModeNo, tempah = 0; tempbl = 0x7f; - if (!(pVBInfo->VBInfo & SetCRT2ToLCDA)) { + if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) { tempbl = 0xff; if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge)) tempah |= 0x80; @@ -6872,7 +6872,7 @@ static void XGI_CloseCRTC(struct xgi_hw_device_info *HwDeviceExtension, tempbx = 0; - if (pVBInfo->VBInfo & SetCRT2ToLCDA) + if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) tempbx = 0x08A0; } @@ -6937,7 +6937,7 @@ unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE, index--; if (pVBInfo->SetFlag & ProgrammingCRT2) { - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { + if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { if (pVBInfo->IF_DEF_LVDS == 0) { if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV | VB_SIS302LV @@ -7211,7 +7211,7 @@ static void XGI_EnableBridge(struct xgifb_video_info *xgifb_info, if (!XGI_DisableChISLCD(pVBInfo)) { if (XGI_EnableChISLCD(pVBInfo) || (pVBInfo->VBInfo & - (SetCRT2ToLCD | SetCRT2ToLCDA))) + (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))) /* LVDS PLL power on */ xgifb_reg_and( pVBInfo->Part4Port, @@ -7229,12 +7229,12 @@ static void XGI_EnableBridge(struct xgifb_video_info *xgifb_info, tempah = 0xc0; if (!(pVBInfo->VBInfo & SetSimuScanMode)) { - if (pVBInfo->VBInfo & SetCRT2ToLCDA) { + if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { if (pVBInfo->VBInfo & SetCRT2ToDualEdge) { tempah = tempah & 0x40; if (pVBInfo->VBInfo & - SetCRT2ToLCDA) + XGI_SetCRT2ToLCDA) tempah = tempah ^ 0xC0; if (pVBInfo->SetFlag & @@ -7271,7 +7271,7 @@ static void XGI_EnableBridge(struct xgifb_video_info *xgifb_info, } /* 301 */ else { /* LVDS */ if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD - | SetCRT2ToLCDA)) + | XGI_SetCRT2ToLCDA)) /* enable CRT2 */ xgifb_reg_or(pVBInfo->Part1Port, 0x1E, 0x20); @@ -7313,7 +7313,7 @@ static void XGI_SetCRT1Group(struct xgifb_video_info *xgifb_info, if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) { - if (pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToLCDA + if (pVBInfo->VBInfo & (SetSimuScanMode | XGI_SetCRT2ToLCDA | SetInSlaveMode)) { pVBInfo->SetFlag |= ProgrammingCRT2; } @@ -7452,11 +7452,11 @@ unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info, XGI_GetLCDInfo(ModeNo, ModeIdIndex, pVBInfo); XGI_DisableBridge(xgifb_info, HwDeviceExtension, pVBInfo); - if (pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) { + if (pVBInfo->VBInfo & (SetSimuScanMode | XGI_SetCRT2ToLCDA)) { XGI_SetCRT1Group(xgifb_info, HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo); - if (pVBInfo->VBInfo & SetCRT2ToLCDA) { + if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { XGI_SetLCDAGroup(ModeNo, ModeIdIndex, HwDeviceExtension, pVBInfo); } @@ -7465,7 +7465,7 @@ unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info, XGI_SetCRT1Group(xgifb_info, HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo); - if (pVBInfo->VBInfo & SetCRT2ToLCDA) { + if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { XGI_SetLCDAGroup(ModeNo, ModeIdIndex, HwDeviceExtension, pVBInfo); diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 4f803b615a1..dddf261ed53 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -2505,17 +2505,17 @@ static struct XGI330_LCDCapStruct XGI_LCDDLCapList[] = { 0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}, /* LCDCap1280x1024 */ - {Panel_1280x1024, LCDDualLink+DefaultLCDCap, StLCDBToA, + {Panel_1280x1024, XGI_LCDDualLink+DefaultLCDCap, StLCDBToA, 0x012, 0x70, 0x03, VCLK108_2_315, 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, /* LCDCap1400x1050 */ - {Panel_1400x1050, LCDDualLink+DefaultLCDCap, StLCDBToA, + {Panel_1400x1050, XGI_LCDDualLink+DefaultLCDCap, StLCDBToA, 0x012, 0x70, 0x03, VCLK108_2_315, 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, /* LCDCap1600x1200 */ - {Panel_1600x1200, LCDDualLink+DefaultLCDCap, LCDToFull, + {Panel_1600x1200, XGI_LCDDualLink+DefaultLCDCap, LCDToFull, 0x012, 0xC0, 0x03, VCLK162, 0x43, 0x22, 0x70, 0x24, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, @@ -2524,7 +2524,7 @@ static struct XGI330_LCDCapStruct XGI_LCDDLCapList[] = { 0x2B, 0x61, 0x2B, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}, /* LCDCap1280x1024x75 */ - {Panel_1280x1024x75, LCDDualLink+DefaultLCDCap, StLCDBToA, + {Panel_1280x1024x75, XGI_LCDDualLink+DefaultLCDCap, StLCDBToA, 0x012, 0x90, 0x03, VCLK135_5, 0x54, 0x42, 0x4A, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00, 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, -- cgit v1.2.3-70-g09d2 From ccc8cb25ae7c9213c641efb34a0cb58110315188 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Thu, 9 Feb 2012 21:11:48 +0100 Subject: staging/xgifb: Use TVCLKBASE_315 as a base address Since the defines TVVCLKDIV2, TVVCLK, HiTVVCLKDIV2, HiTVVCLK, HiTVSimuVCLK and HiTVTextVCLK are now defined as relative values, we have to use TVCLKBASE_315 (0x31) as a base address to get the same values as before the merge. The old and now duplicated defines were removed Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_def.h | 6 ------ drivers/staging/xgifb/vb_setmode.c | 24 ++++++++++++------------ 2 files changed, 12 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h index a4fedbd3691..d2e0bcd6b4b 100644 --- a/drivers/staging/xgifb/vb_def.h +++ b/drivers/staging/xgifb/vb_def.h @@ -288,12 +288,6 @@ #define VCLK217_325 0x55 #define XGI_YPbPr750pVCLK 0x57 -#define TVVCLKDIV2 0x3A -#define TVVCLK 0x3B -#define HiTVVCLKDIV2 0x3C -#define HiTVVCLK 0x3D -#define HiTVSimuVCLK 0x3E -#define HiTVTextVCLK 0x3F #define VCLK39_77 0x40 #define YPbPr525pVCLK 0x3A #define NTSC1024VCLK 0x41 diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 42eaec7c8b2..2919924213c 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -1273,19 +1273,19 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, VCLKIndex = LCDXlat1VCLK[CRT2Index]; } else if (pVBInfo->VBInfo & SetCRT2ToHiVision) { if (pVBInfo->SetFlag & RPLLDIV2XO) { - VCLKIndex = HiTVVCLKDIV2; + VCLKIndex = TVCLKBASE_315 + HiTVVCLKDIV2; VCLKIndex += 25; } else { - VCLKIndex = HiTVVCLK; + VCLKIndex = TVCLKBASE_315 + HiTVVCLK; VCLKIndex += 25; } if (pVBInfo->SetFlag & TVSimuMode) { if (modeflag & Charx8Dot) { - VCLKIndex = HiTVSimuVCLK; + VCLKIndex = TVCLKBASE_315 + HiTVSimuVCLK; VCLKIndex += 25; } else { - VCLKIndex = HiTVTextVCLK; + VCLKIndex = TVCLKBASE_315 + HiTVTextVCLK; VCLKIndex += 25; } } @@ -1304,10 +1304,10 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, } } else if (pVBInfo->VBInfo & SetCRT2ToTV) { if (pVBInfo->SetFlag & RPLLDIV2XO) { - VCLKIndex = TVVCLKDIV2; + VCLKIndex = TVCLKBASE_315 + TVVCLKDIV2; VCLKIndex += 25; } else { - VCLKIndex = TVVCLK; + VCLKIndex = TVCLKBASE_315 + TVVCLK; VCLKIndex += 25; } } else { /* for CRT2 */ @@ -2845,13 +2845,13 @@ static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex, VB_SIS302LV | VB_XGI301C)) { if (pVBInfo->VBInfo & SetCRT2ToHiVision) { - tempal = HiTVVCLKDIV2; + tempal = TVCLKBASE_315 + HiTVVCLKDIV2; if (!(pVBInfo->TVInfo & RPLLDIV2XO)) - tempal = HiTVVCLK; + tempal = TVCLKBASE_315 + HiTVVCLK; if (pVBInfo->TVInfo & TVSimuMode) { - tempal = HiTVSimuVCLK; + tempal = TVCLKBASE_315 + HiTVSimuVCLK; if (!(modeflag & Charx8Dot)) - tempal = HiTVTextVCLK; + tempal = TVCLKBASE_315 + HiTVTextVCLK; } return tempal; @@ -2870,9 +2870,9 @@ static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex, tempal = NTSC1024VCLK; if (!(pVBInfo->TVInfo & NTSC1024x768)) { - tempal = TVVCLKDIV2; + tempal = TVCLKBASE_315 + TVVCLKDIV2; if (!(pVBInfo->TVInfo & RPLLDIV2XO)) - tempal = TVVCLK; + tempal = TVCLKBASE_315 + TVVCLK; } if (pVBInfo->VBInfo & SetCRT2ToTV) -- cgit v1.2.3-70-g09d2 From c3b3b3f9b0efa20a123244def80698669996b8ec Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Thu, 9 Feb 2012 21:11:49 +0100 Subject: staging/xgifb: remove remaining duplicate initdef.h defines This patch removes the remaining defines that are already defined identically in the sis initdef.h header. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_def.h | 107 +---------------------------------------- 1 file changed, 1 insertion(+), 106 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h index d2e0bcd6b4b..c7317931f67 100644 --- a/drivers/staging/xgifb/vb_def.h +++ b/drivers/staging/xgifb/vb_def.h @@ -8,12 +8,8 @@ #define VB_YPbPr1080i 0x03 #define LVDSCRT1Len 15 - -#define SupportCHTV 0x0800 #define SupportCRT2in301C 0x0100 /* for 301C */ #define SetCHTVOverScan 0x8000 -#define PanelRGB18Bit 0x0100 -#define PanelRGB24Bit 0x0000 #define Panel_320x480 0x07 /*fstn*/ /* [ycchen] 02/12/03 Modify for Multi-Sync. LCD Support */ @@ -29,94 +25,24 @@ #define XGI_CRT2_PORT_00 (0x00 - 0x030) -#define _PanelType00 0x00 -#define _PanelType01 0x08 -#define _PanelType02 0x10 -#define _PanelType03 0x18 -#define _PanelType04 0x20 -#define _PanelType05 0x28 -#define _PanelType06 0x30 -#define _PanelType07 0x38 -#define _PanelType08 0x40 -#define _PanelType09 0x48 -#define _PanelType0A 0x50 -#define _PanelType0B 0x58 -#define _PanelType0C 0x60 -#define _PanelType0D 0x68 -#define _PanelType0E 0x70 -#define _PanelType0F 0x78 - /* ============================================================= for 310 ============================================================== */ -/* add LCDDataList for GetLCDPtr */ -#define LCDDataList (VBIOSTablePointerStart+0x22) -/* */ -/* Modify from 310.inc */ -/* */ -/* */ - #define ModeSoftSetting 0x04 -#define BoardTVType 0x02 - -#define SoftDRAMType 0x80 /* DRAMSetting */ - /* ---------------- SetMode Stack */ #define CRT1Len 15 #define VCLKLen 4 -#define VGA_XGI340 0x0001 /* 340 series */ - -#define VB_NoLCD 0x8000 -#define VB_LVDS_NS 0x0001 /* 3rd party chip */ -#define ModeText 0x0000 -#define ModeEGA 0x0002 /* 16 colors mode */ -#define ModeVGA 0x0003 /* 256 colors mode */ - -#define DACInfoFlag 0x0018 - -#define MemoryInfoFlag 0x01e0 -#define MemorySizeShift 5 - -#define Charx8Dot 0x0200 -#define LineCompareOff 0x0400 -#define CRT2Mode 0x0800 -#define HalfDCLK 0x1000 -#define NoSupportSimuTV 0x2000 -#define DoubleScanMode 0x8000 - -/* -------------- Ext_InfoFlag */ #define SupportAllCRT2 0x0078 -#define SupportTV 0x0008 -#define SupportLCD 0x0020 -#define SupportRAMDAC2 0x0040 #define NoSupportTV 0x0070 #define NoSupportHiVisionTV 0x0060 #define NoSupportLCD 0x0058 -#define SupportTV1024 0x0800 /* 301btest */ -#define InterlaceMode 0x0080 -#define SyncPP 0x0000 -#define SyncPN 0x4000 -#define SyncNP 0x8000 -#define SyncNN 0xC000 /* -------------- SetMode Stack/Scratch */ -#define SetSimuScanMode 0x0001 /* VBInfo/CR30 & CR31 */ -#define SetCRT2ToTV 0x089C -#define SetCRT2ToAVIDEO 0x0004 -#define SetCRT2ToSVIDEO 0x0008 -#define SetCRT2ToSCART 0x0010 -#define SetCRT2ToLCD 0x0020 -#define SetCRT2ToRAMDAC 0x0040 #define XGI_SetCRT2ToLCDA 0x0100 -#define SetInSlaveMode 0x0200 -#define SetNotSimuMode 0x0400 -#define LoadDACFlag 0x1000 -#define DriverMode 0x4000 #define SetCRT2ToDualEdge 0x8000 -#define ProgrammingCRT2 0x0001 /* Set Flag */ #define ReserveTVOption 0x0008 #define GatingCRT 0x0800 #define DisableChB 0x1000 @@ -124,7 +50,6 @@ #define DisableChA 0x4000 #define EnableChA 0x8000 -#define SetNTSCTV 0x0000 /* TV Info */ #define SetTVLowResolution 0x0400 #define TVSimuMode 0x0800 #define RPLLDIV2XO 0x1000 @@ -167,24 +92,14 @@ #define TVSense 0xc7 -#define TVOverScan 0x10 /* CR35 */ - #define YPbPrMode 0xe0 #define YPbPrMode525i 0x00 #define YPbPrMode525p 0x20 #define YPbPrMode750p 0x40 #define YPbPrMode1080i 0x60 - -#define LCDRGB18Bit 0x01 /* CR37 */ -#define LCDNonExpanding 0x10 -#define LCDSync 0x20 -#define LCDSyncBit 0xe0 /* H/V polarity & sync ID */ - #define ScalingLCD 0x08 -#define EnableDualEdge 0x01 /* CR38 */ -#define SetToLCDA 0x02 #define SetYPbPr 0x04 /* ---------------------- VUMA Information */ @@ -207,28 +122,13 @@ /* translated from asm code 301def.h */ /* */ /* --------------------------------------------------------- */ -#define LCDDataLen 8 -#define TVDataLen 12 #define LVDSCRT1Len_H 8 #define LVDSCRT1Len_V 7 -#define LVDSDataLen 6 -#define LVDSDesDataLen 6 #define LCDDesDataLen 6 #define LVDSDesDataLen2 8 #define LCDDesDataLen2 8 -#define CHTVRegLen 16 -#define StHiTVHT 892 -#define StHiTVVT 1126 -#define StHiTextTVHT 1000 -#define StHiTextTVVT 1126 -#define ExtHiTVHT 2100 -#define ExtHiTVVT 1125 -#define NTSCHT 1716 -#define NTSCVT 525 #define NTSC1024x768HT 1908 -#define PALHT 1728 -#define PALVT 625 #define YPbPrTV525iHT 1716 /* YPbPr */ #define YPbPrTV525iVT 525 @@ -237,15 +137,10 @@ #define YPbPrTV750pHT 1650 #define YPbPrTV750pVT 750 -#define CRT2Delay1 0x04 /* XGI301 */ -#define CRT2Delay2 0x0A /* 301B,302 */ - - #define VCLK25_175 0x00 #define VCLK28_322 0x01 #define VCLK31_5 0x02 #define VCLK36 0x03 -#define VCLK40 0x04 #define VCLK43_163 0x05 #define VCLK44_9 0x06 #define VCLK49_5 0x07 @@ -289,7 +184,7 @@ #define XGI_YPbPr750pVCLK 0x57 #define VCLK39_77 0x40 -#define YPbPr525pVCLK 0x3A +#define YPbPr525pVCLK 0x3A #define NTSC1024VCLK 0x41 #define VCLK35_2 0x49 /* ; 800x480 */ #define VCLK122_61 0x4A -- cgit v1.2.3-70-g09d2 From 073863432f7eaa23c7c09733414d4be2eabf5eef Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Thu, 9 Feb 2012 16:37:17 -0600 Subject: staging: r8712u: Add missing initialization and remove configuration parameter CONFIG_R8712_AP When this driver was upgraded to the vendor 20100831 version in commit 93c55dda092c7 et al,, one listhead initialization was missed. This broke complete operation of the driver whenever AP mode was enabled. This fixes https://bugs.archlinux.org/task/27996. The configuration parameter R8712_AP is misleading as the driver cannot function as an AP without a heavily hacked version of hostapd. Thus, it makes sense to remove the parameter; however the code and data configured for the option is left in. Signed-off-by: Larry Finger Cc: Stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/Kconfig | 7 ------- drivers/staging/rtl8712/rtl871x_sta_mgt.c | 5 +---- drivers/staging/rtl8712/sta_info.h | 4 ---- 3 files changed, 1 insertion(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/Kconfig b/drivers/staging/rtl8712/Kconfig index ea37473f71e..6a43312380e 100644 --- a/drivers/staging/rtl8712/Kconfig +++ b/drivers/staging/rtl8712/Kconfig @@ -9,13 +9,6 @@ config R8712U This option adds the Realtek RTL8712 USB device such as the D-Link DWA-130. If built as a module, it will be called r8712u. -config R8712_AP - bool "Realtek RTL8712U AP code" - depends on R8712U - default N - ---help--- - This option allows the Realtek RTL8712 USB device to be an Access Point. - config R8712_TX_AGGR bool "Realtek RTL8712U Transmit Aggregation code" depends on R8712U && BROKEN diff --git a/drivers/staging/rtl8712/rtl871x_sta_mgt.c b/drivers/staging/rtl8712/rtl871x_sta_mgt.c index 64f56961883..1247b3d9719 100644 --- a/drivers/staging/rtl8712/rtl871x_sta_mgt.c +++ b/drivers/staging/rtl8712/rtl871x_sta_mgt.c @@ -42,9 +42,8 @@ static void _init_stainfo(struct sta_info *psta) _init_listhead(&psta->hash_list); _r8712_init_sta_xmit_priv(&psta->sta_xmitpriv); _r8712_init_sta_recv_priv(&psta->sta_recvpriv); -#ifdef CONFIG_R8712_AP + _init_listhead(&psta->asoc_list); _init_listhead(&psta->auth_list); -#endif } u32 _r8712_init_sta_priv(struct sta_priv *pstapriv) @@ -71,10 +70,8 @@ u32 _r8712_init_sta_priv(struct sta_priv *pstapriv) get_list_head(&pstapriv->free_sta_queue)); psta++; } -#ifdef CONFIG_R8712_AP _init_listhead(&pstapriv->asoc_list); _init_listhead(&pstapriv->auth_list); -#endif return _SUCCESS; } diff --git a/drivers/staging/rtl8712/sta_info.h b/drivers/staging/rtl8712/sta_info.h index 48d6a14c8f5..f8016e9abff 100644 --- a/drivers/staging/rtl8712/sta_info.h +++ b/drivers/staging/rtl8712/sta_info.h @@ -90,7 +90,6 @@ struct sta_info { * curr_network(mlme_priv/security_priv/qos/ht) : AP CAP/INFO * sta_info: (AP & STA) CAP/INFO */ -#ifdef CONFIG_R8712_AP struct list_head asoc_list; struct list_head auth_list; unsigned int expire_to; @@ -98,7 +97,6 @@ struct sta_info { unsigned int authalg; unsigned char chg_txt[128]; unsigned int tx_ra_bitmap; -#endif }; struct sta_priv { @@ -111,13 +109,11 @@ struct sta_priv { struct __queue sleep_q; struct __queue wakeup_q; struct _adapter *padapter; -#ifdef CONFIG_R8712_AP struct list_head asoc_list; struct list_head auth_list; unsigned int auth_to; /* sec, time to expire in authenticating. */ unsigned int assoc_to; /* sec, time to expire before associating. */ unsigned int expire_to; /* sec , time to expire after associated. */ -#endif }; static inline u32 wifi_mac_hash(u8 *mac) -- cgit v1.2.3-70-g09d2 From 242501ce5d5296236701612940ed397a2b3fd4bf Mon Sep 17 00:00:00 2001 From: Gerard Ryan Date: Fri, 10 Feb 2012 01:54:50 +0000 Subject: Staging: bcm: fix CodingStyle warnings/errors reported by checkpatch.pl in led_control.h This is a patch to the led_control.h file that fixes numerous warnings and errors reported by the checkpatch.pl tool. There still remain a few more, but as this is my first attempt at a commit, I'm not going to be too adventurous! Signed-off-by: Gerard Ryan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/led_control.h | 74 +++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/bcm/led_control.h b/drivers/staging/bcm/led_control.h index 0711ac20f6f..84d1a028e1e 100644 --- a/drivers/staging/bcm/led_control.h +++ b/drivers/staging/bcm/led_control.h @@ -4,11 +4,11 @@ /*************************TYPE DEF**********************/ #define NUM_OF_LEDS 4 -#define DSD_START_OFFSET 0x0200 -#define EEPROM_VERSION_OFFSET 0x020E -#define EEPROM_HW_PARAM_POINTER_ADDRESS 0x0218 -#define EEPROM_HW_PARAM_POINTER_ADDRRES_MAP5 0x0220 -#define GPIO_SECTION_START_OFFSET 0x03 +#define DSD_START_OFFSET 0x0200 +#define EEPROM_VERSION_OFFSET 0x020E +#define EEPROM_HW_PARAM_POINTER_ADDRESS 0x0218 +#define EEPROM_HW_PARAM_POINTER_ADDRRES_MAP5 0x0220 +#define GPIO_SECTION_START_OFFSET 0x03 #define COMPATIBILITY_SECTION_LENGTH 42 #define COMPATIBILITY_SECTION_LENGTH_MAP5 84 @@ -18,27 +18,27 @@ #define EEPROM_MAP5_MINORVERSION 0 -#define MAX_NUM_OF_BLINKS 10 -#define NUM_OF_GPIO_PINS 16 +#define MAX_NUM_OF_BLINKS 10 +#define NUM_OF_GPIO_PINS 16 -#define DISABLE_GPIO_NUM 0xFF -#define EVENT_SIGNALED 1 +#define DISABLE_GPIO_NUM 0xFF +#define EVENT_SIGNALED 1 -#define MAX_FILE_NAME_BUFFER_SIZE 100 +#define MAX_FILE_NAME_BUFFER_SIZE 100 -#define TURN_ON_LED(GPIO, index) do{ \ +#define TURN_ON_LED(GPIO, index) do { \ UINT gpio_val = GPIO; \ (Adapter->LEDInfo.LEDState[index].BitPolarity == 1) ? \ - wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_SET_REG, &gpio_val ,sizeof(gpio_val)) : \ - wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_CLR_REG, &gpio_val, sizeof(gpio_val)); \ - }while(0); + wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_SET_REG, &gpio_val, sizeof(gpio_val)) : \ + wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_CLR_REG, &gpio_val, sizeof(gpio_val)); \ + } while (0); #define TURN_OFF_LED(GPIO, index) do { \ UINT gpio_val = GPIO; \ (Adapter->LEDInfo.LEDState[index].BitPolarity == 1) ? \ - wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_CLR_REG,&gpio_val ,sizeof(gpio_val)) : \ - wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_SET_REG,&gpio_val ,sizeof(gpio_val)); \ - }while(0); + wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_CLR_REG, &gpio_val, sizeof(gpio_val)) : \ + wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_SET_REG, &gpio_val, sizeof(gpio_val)); \ + } while (0); #define B_ULONG32 unsigned long @@ -50,7 +50,7 @@ typedef enum _LEDColors{ BLUE_LED = 2, YELLOW_LED = 3, GREEN_LED = 4 -} LEDColors; /*Enumerated values of different LED types*/ +} LEDColors; /*Enumerated values of different LED types*/ typedef enum LedEvents { SHUTDOWN_EXIT = 0x00, @@ -62,43 +62,41 @@ typedef enum LedEvents { LOWPOWER_MODE_ENTER = 0x20, IDLEMODE_CONTINUE = 0x40, IDLEMODE_EXIT = 0x80, - LED_THREAD_INACTIVE = 0x100, //Makes the LED thread Inactivce. It wil be equivallent to putting the thread on hold. - LED_THREAD_ACTIVE = 0x200 //Makes the LED Thread Active back. -} LedEventInfo_t; /*Enumerated values of different driver states*/ + LED_THREAD_INACTIVE = 0x100, /* Makes the LED thread Inactivce. It wil be equivallent to putting the thread on hold. */ + LED_THREAD_ACTIVE = 0x200 /* Makes the LED Thread Active back. */ +} LedEventInfo_t; /* Enumerated values of different driver states */ #define DRIVER_HALT 0xff -/*Structure which stores the information of different LED types - * and corresponding LED state information of driver states*/ -typedef struct LedStateInfo_t -{ +/* + * Structure which stores the information of different LED types + * and corresponding LED state information of driver states + */ +typedef struct LedStateInfo_t { UCHAR LED_Type; /* specify GPIO number - use 0xFF if not used */ UCHAR LED_On_State; /* Bits set or reset for different states */ UCHAR LED_Blink_State; /* Bits set or reset for blinking LEDs for different states */ UCHAR GPIO_Num; - UCHAR BitPolarity; /*To represent whether H/W is normal polarity or reverse - polarity*/ -}LEDStateInfo, *pLEDStateInfo; + UCHAR BitPolarity; /* To represent whether H/W is normal polarity or reverse polarity */ +} LEDStateInfo, *pLEDStateInfo; -typedef struct _LED_INFO_STRUCT -{ +typedef struct _LED_INFO_STRUCT { LEDStateInfo LEDState[NUM_OF_LEDS]; - BOOLEAN bIdleMode_tx_from_host; /*Variable to notify whether driver came out - from idlemode due to Host or target*/ + BOOLEAN bIdleMode_tx_from_host; /* Variable to notify whether driver came out from idlemode due to Host or target*/ BOOLEAN bIdle_led_off; wait_queue_head_t notify_led_event; wait_queue_head_t idleModeSyncEvent; - struct task_struct *led_cntrl_threadid; - int led_thread_running; + struct task_struct *led_cntrl_threadid; + int led_thread_running; BOOLEAN bLedInitDone; } LED_INFO_STRUCT, *PLED_INFO_STRUCT; -//LED Thread state. -#define BCM_LED_THREAD_DISABLED 0 //LED Thread is not running. -#define BCM_LED_THREAD_RUNNING_ACTIVELY 1 //LED thread is running. -#define BCM_LED_THREAD_RUNNING_INACTIVELY 2 //LED thread has been put on hold +/* LED Thread state. */ +#define BCM_LED_THREAD_DISABLED 0 /* LED Thread is not running. */ +#define BCM_LED_THREAD_RUNNING_ACTIVELY 1 /* LED thread is running. */ +#define BCM_LED_THREAD_RUNNING_INACTIVELY 2 /*LED thread has been put on hold*/ -- cgit v1.2.3-70-g09d2 From 841cb11c6fc7ae559ef2d856932907056b75617d Mon Sep 17 00:00:00 2001 From: Arve Hjønnevåg Date: Thu, 9 Feb 2012 14:24:30 -0800 Subject: staging: android-alarm: Add android alarm driver & in-kernel alarm interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drivers can now create alarms that will use an hrtimer while the system is running and the rtc to wake up from suspend. CC: Arve Hjønnevåg CC: Android Kernel Team Signed-off-by: Arve Hjønnevåg [Fold and move alarm driver and interface to staging, fix whitespace issue, drop kconfig & make file changes as it currently doesn't build -jstultz] Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/alarm-dev.c | 286 ++++++++++++++++ drivers/staging/android/alarm.c | 586 ++++++++++++++++++++++++++++++++ drivers/staging/android/android_alarm.h | 106 ++++++ 3 files changed, 978 insertions(+) create mode 100644 drivers/staging/android/alarm-dev.c create mode 100644 drivers/staging/android/alarm.c create mode 100644 drivers/staging/android/android_alarm.h (limited to 'drivers') diff --git a/drivers/staging/android/alarm-dev.c b/drivers/staging/android/alarm-dev.c new file mode 100644 index 00000000000..ae56961f9c8 --- /dev/null +++ b/drivers/staging/android/alarm-dev.c @@ -0,0 +1,286 @@ +/* drivers/rtc/alarm-dev.c + * + * Copyright (C) 2007-2009 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 +#include +#include +#include "android_alarm.h" + +#define ANDROID_ALARM_PRINT_INFO (1U << 0) +#define ANDROID_ALARM_PRINT_IO (1U << 1) +#define ANDROID_ALARM_PRINT_INT (1U << 2) + +static int debug_mask = ANDROID_ALARM_PRINT_INFO; +module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); + +#define pr_alarm(debug_level_mask, args...) \ + do { \ + if (debug_mask & ANDROID_ALARM_PRINT_##debug_level_mask) { \ + pr_info(args); \ + } \ + } while (0) + +#define ANDROID_ALARM_WAKEUP_MASK ( \ + ANDROID_ALARM_RTC_WAKEUP_MASK | \ + ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK) + +/* support old usespace code */ +#define ANDROID_ALARM_SET_OLD _IOW('a', 2, time_t) /* set alarm */ +#define ANDROID_ALARM_SET_AND_WAIT_OLD _IOW('a', 3, time_t) + +static int alarm_opened; +static DEFINE_SPINLOCK(alarm_slock); +static struct wake_lock alarm_wake_lock; +static DECLARE_WAIT_QUEUE_HEAD(alarm_wait_queue); +static uint32_t alarm_pending; +static uint32_t alarm_enabled; +static uint32_t wait_pending; + +static struct alarm alarms[ANDROID_ALARM_TYPE_COUNT]; + +static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int rv = 0; + unsigned long flags; + struct timespec new_alarm_time; + struct timespec new_rtc_time; + struct timespec tmp_time; + enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd); + uint32_t alarm_type_mask = 1U << alarm_type; + + if (alarm_type >= ANDROID_ALARM_TYPE_COUNT) + return -EINVAL; + + if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) { + if ((file->f_flags & O_ACCMODE) == O_RDONLY) + return -EPERM; + if (file->private_data == NULL && + cmd != ANDROID_ALARM_SET_RTC) { + spin_lock_irqsave(&alarm_slock, flags); + if (alarm_opened) { + spin_unlock_irqrestore(&alarm_slock, flags); + return -EBUSY; + } + alarm_opened = 1; + file->private_data = (void *)1; + spin_unlock_irqrestore(&alarm_slock, flags); + } + } + + switch (ANDROID_ALARM_BASE_CMD(cmd)) { + case ANDROID_ALARM_CLEAR(0): + spin_lock_irqsave(&alarm_slock, flags); + pr_alarm(IO, "alarm %d clear\n", alarm_type); + alarm_try_to_cancel(&alarms[alarm_type]); + if (alarm_pending) { + alarm_pending &= ~alarm_type_mask; + if (!alarm_pending && !wait_pending) + wake_unlock(&alarm_wake_lock); + } + alarm_enabled &= ~alarm_type_mask; + spin_unlock_irqrestore(&alarm_slock, flags); + break; + + case ANDROID_ALARM_SET_OLD: + case ANDROID_ALARM_SET_AND_WAIT_OLD: + if (get_user(new_alarm_time.tv_sec, (int __user *)arg)) { + rv = -EFAULT; + goto err1; + } + new_alarm_time.tv_nsec = 0; + goto from_old_alarm_set; + + case ANDROID_ALARM_SET_AND_WAIT(0): + case ANDROID_ALARM_SET(0): + if (copy_from_user(&new_alarm_time, (void __user *)arg, + sizeof(new_alarm_time))) { + rv = -EFAULT; + goto err1; + } +from_old_alarm_set: + spin_lock_irqsave(&alarm_slock, flags); + pr_alarm(IO, "alarm %d set %ld.%09ld\n", alarm_type, + new_alarm_time.tv_sec, new_alarm_time.tv_nsec); + alarm_enabled |= alarm_type_mask; + alarm_start_range(&alarms[alarm_type], + timespec_to_ktime(new_alarm_time), + timespec_to_ktime(new_alarm_time)); + spin_unlock_irqrestore(&alarm_slock, flags); + if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_AND_WAIT(0) + && cmd != ANDROID_ALARM_SET_AND_WAIT_OLD) + break; + /* fall though */ + case ANDROID_ALARM_WAIT: + spin_lock_irqsave(&alarm_slock, flags); + pr_alarm(IO, "alarm wait\n"); + if (!alarm_pending && wait_pending) { + wake_unlock(&alarm_wake_lock); + wait_pending = 0; + } + spin_unlock_irqrestore(&alarm_slock, flags); + rv = wait_event_interruptible(alarm_wait_queue, alarm_pending); + if (rv) + goto err1; + spin_lock_irqsave(&alarm_slock, flags); + rv = alarm_pending; + wait_pending = 1; + alarm_pending = 0; + spin_unlock_irqrestore(&alarm_slock, flags); + break; + case ANDROID_ALARM_SET_RTC: + if (copy_from_user(&new_rtc_time, (void __user *)arg, + sizeof(new_rtc_time))) { + rv = -EFAULT; + goto err1; + } + rv = alarm_set_rtc(new_rtc_time); + spin_lock_irqsave(&alarm_slock, flags); + alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK; + wake_up(&alarm_wait_queue); + spin_unlock_irqrestore(&alarm_slock, flags); + if (rv < 0) + goto err1; + break; + case ANDROID_ALARM_GET_TIME(0): + switch (alarm_type) { + case ANDROID_ALARM_RTC_WAKEUP: + case ANDROID_ALARM_RTC: + getnstimeofday(&tmp_time); + break; + case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: + case ANDROID_ALARM_ELAPSED_REALTIME: + tmp_time = + ktime_to_timespec(alarm_get_elapsed_realtime()); + break; + case ANDROID_ALARM_TYPE_COUNT: + case ANDROID_ALARM_SYSTEMTIME: + ktime_get_ts(&tmp_time); + break; + } + if (copy_to_user((void __user *)arg, &tmp_time, + sizeof(tmp_time))) { + rv = -EFAULT; + goto err1; + } + break; + + default: + rv = -EINVAL; + goto err1; + } +err1: + return rv; +} + +static int alarm_open(struct inode *inode, struct file *file) +{ + file->private_data = NULL; + return 0; +} + +static int alarm_release(struct inode *inode, struct file *file) +{ + int i; + unsigned long flags; + + spin_lock_irqsave(&alarm_slock, flags); + if (file->private_data != 0) { + for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) { + uint32_t alarm_type_mask = 1U << i; + if (alarm_enabled & alarm_type_mask) { + pr_alarm(INFO, "alarm_release: clear alarm, " + "pending %d\n", + !!(alarm_pending & alarm_type_mask)); + alarm_enabled &= ~alarm_type_mask; + } + spin_unlock_irqrestore(&alarm_slock, flags); + alarm_cancel(&alarms[i]); + spin_lock_irqsave(&alarm_slock, flags); + } + if (alarm_pending | wait_pending) { + if (alarm_pending) + pr_alarm(INFO, "alarm_release: clear " + "pending alarms %x\n", alarm_pending); + wake_unlock(&alarm_wake_lock); + wait_pending = 0; + alarm_pending = 0; + } + alarm_opened = 0; + } + spin_unlock_irqrestore(&alarm_slock, flags); + return 0; +} + +static void alarm_triggered(struct alarm *alarm) +{ + unsigned long flags; + uint32_t alarm_type_mask = 1U << alarm->type; + + pr_alarm(INT, "alarm_triggered type %d\n", alarm->type); + spin_lock_irqsave(&alarm_slock, flags); + if (alarm_enabled & alarm_type_mask) { + wake_lock_timeout(&alarm_wake_lock, 5 * HZ); + alarm_enabled &= ~alarm_type_mask; + alarm_pending |= alarm_type_mask; + wake_up(&alarm_wait_queue); + } + spin_unlock_irqrestore(&alarm_slock, flags); +} + +static const struct file_operations alarm_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = alarm_ioctl, + .open = alarm_open, + .release = alarm_release, +}; + +static struct miscdevice alarm_device = { + .minor = MISC_DYNAMIC_MINOR, + .name = "alarm", + .fops = &alarm_fops, +}; + +static int __init alarm_dev_init(void) +{ + int err; + int i; + + err = misc_register(&alarm_device); + if (err) + return err; + + for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) + alarm_init(&alarms[i], i, alarm_triggered); + wake_lock_init(&alarm_wake_lock, WAKE_LOCK_SUSPEND, "alarm"); + + return 0; +} + +static void __exit alarm_dev_exit(void) +{ + misc_deregister(&alarm_device); + wake_lock_destroy(&alarm_wake_lock); +} + +module_init(alarm_dev_init); +module_exit(alarm_dev_exit); + diff --git a/drivers/staging/android/alarm.c b/drivers/staging/android/alarm.c new file mode 100644 index 00000000000..c5bd51fd839 --- /dev/null +++ b/drivers/staging/android/alarm.c @@ -0,0 +1,586 @@ +/* drivers/rtc/alarm.c + * + * Copyright (C) 2007-2009 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 +#include +#include "android_alarm.h" + +#define ANDROID_ALARM_PRINT_ERROR (1U << 0) +#define ANDROID_ALARM_PRINT_INIT_STATUS (1U << 1) +#define ANDROID_ALARM_PRINT_TSET (1U << 2) +#define ANDROID_ALARM_PRINT_CALL (1U << 3) +#define ANDROID_ALARM_PRINT_SUSPEND (1U << 4) +#define ANDROID_ALARM_PRINT_INT (1U << 5) +#define ANDROID_ALARM_PRINT_FLOW (1U << 6) + +static int debug_mask = ANDROID_ALARM_PRINT_ERROR | \ + ANDROID_ALARM_PRINT_INIT_STATUS; +module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); + +#define pr_alarm(debug_level_mask, args...) \ + do { \ + if (debug_mask & ANDROID_ALARM_PRINT_##debug_level_mask) { \ + pr_info(args); \ + } \ + } while (0) + +#define ANDROID_ALARM_WAKEUP_MASK ( \ + ANDROID_ALARM_RTC_WAKEUP_MASK | \ + ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK) + +/* support old usespace code */ +#define ANDROID_ALARM_SET_OLD _IOW('a', 2, time_t) /* set alarm */ +#define ANDROID_ALARM_SET_AND_WAIT_OLD _IOW('a', 3, time_t) + +struct alarm_queue { + struct rb_root alarms; + struct rb_node *first; + struct hrtimer timer; + ktime_t delta; + bool stopped; + ktime_t stopped_time; +}; + +static struct rtc_device *alarm_rtc_dev; +static DEFINE_SPINLOCK(alarm_slock); +static DEFINE_MUTEX(alarm_setrtc_mutex); +static struct wake_lock alarm_rtc_wake_lock; +static struct platform_device *alarm_platform_dev; +struct alarm_queue alarms[ANDROID_ALARM_TYPE_COUNT]; +static bool suspended; + +static void update_timer_locked(struct alarm_queue *base, bool head_removed) +{ + struct alarm *alarm; + bool is_wakeup = base == &alarms[ANDROID_ALARM_RTC_WAKEUP] || + base == &alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP]; + + if (base->stopped) { + pr_alarm(FLOW, "changed alarm while setting the wall time\n"); + return; + } + + if (is_wakeup && !suspended && head_removed) + wake_unlock(&alarm_rtc_wake_lock); + + if (!base->first) + return; + + alarm = container_of(base->first, struct alarm, node); + + pr_alarm(FLOW, "selected alarm, type %d, func %pF at %lld\n", + alarm->type, alarm->function, ktime_to_ns(alarm->expires)); + + if (is_wakeup && suspended) { + pr_alarm(FLOW, "changed alarm while suspened\n"); + wake_lock_timeout(&alarm_rtc_wake_lock, 1 * HZ); + return; + } + + hrtimer_try_to_cancel(&base->timer); + base->timer.node.expires = ktime_add(base->delta, alarm->expires); + base->timer._softexpires = ktime_add(base->delta, alarm->softexpires); + hrtimer_start_expires(&base->timer, HRTIMER_MODE_ABS); +} + +static void alarm_enqueue_locked(struct alarm *alarm) +{ + struct alarm_queue *base = &alarms[alarm->type]; + struct rb_node **link = &base->alarms.rb_node; + struct rb_node *parent = NULL; + struct alarm *entry; + int leftmost = 1; + + pr_alarm(FLOW, "added alarm, type %d, func %pF at %lld\n", + alarm->type, alarm->function, ktime_to_ns(alarm->expires)); + + if (base->first == &alarm->node) + base->first = rb_next(&alarm->node); + if (!RB_EMPTY_NODE(&alarm->node)) { + rb_erase(&alarm->node, &base->alarms); + RB_CLEAR_NODE(&alarm->node); + } + + while (*link) { + parent = *link; + entry = rb_entry(parent, struct alarm, node); + /* + * We dont care about collisions. Nodes with + * the same expiry time stay together. + */ + if (alarm->expires.tv64 < entry->expires.tv64) { + link = &(*link)->rb_left; + } else { + link = &(*link)->rb_right; + leftmost = 0; + } + } + if (leftmost) { + base->first = &alarm->node; + update_timer_locked(base, false); + } + + rb_link_node(&alarm->node, parent, link); + rb_insert_color(&alarm->node, &base->alarms); +} + +/** + * alarm_init - initialize an alarm + * @alarm: the alarm to be initialized + * @type: the alarm type to be used + * @function: alarm callback function + */ +void alarm_init(struct alarm *alarm, + enum android_alarm_type type, void (*function)(struct alarm *)) +{ + RB_CLEAR_NODE(&alarm->node); + alarm->type = type; + alarm->function = function; + + pr_alarm(FLOW, "created alarm, type %d, func %pF\n", type, function); +} + + +/** + * alarm_start_range - (re)start an alarm + * @alarm: the alarm to be added + * @start: earliest expiry time + * @end: expiry time + */ +void alarm_start_range(struct alarm *alarm, ktime_t start, ktime_t end) +{ + unsigned long flags; + + spin_lock_irqsave(&alarm_slock, flags); + alarm->softexpires = start; + alarm->expires = end; + alarm_enqueue_locked(alarm); + spin_unlock_irqrestore(&alarm_slock, flags); +} + +/** + * alarm_try_to_cancel - try to deactivate an alarm + * @alarm: alarm to stop + * + * Returns: + * 0 when the alarm was not active + * 1 when the alarm was active + * -1 when the alarm may currently be excuting the callback function and + * cannot be stopped (it may also be inactive) + */ +int alarm_try_to_cancel(struct alarm *alarm) +{ + struct alarm_queue *base = &alarms[alarm->type]; + unsigned long flags; + bool first = false; + int ret = 0; + + spin_lock_irqsave(&alarm_slock, flags); + if (!RB_EMPTY_NODE(&alarm->node)) { + pr_alarm(FLOW, "canceled alarm, type %d, func %pF at %lld\n", + alarm->type, alarm->function, + ktime_to_ns(alarm->expires)); + ret = 1; + if (base->first == &alarm->node) { + base->first = rb_next(&alarm->node); + first = true; + } + rb_erase(&alarm->node, &base->alarms); + RB_CLEAR_NODE(&alarm->node); + if (first) + update_timer_locked(base, true); + } else + pr_alarm(FLOW, "tried to cancel alarm, type %d, func %pF\n", + alarm->type, alarm->function); + spin_unlock_irqrestore(&alarm_slock, flags); + if (!ret && hrtimer_callback_running(&base->timer)) + ret = -1; + return ret; +} + +/** + * alarm_cancel - cancel an alarm and wait for the handler to finish. + * @alarm: the alarm to be cancelled + * + * Returns: + * 0 when the alarm was not active + * 1 when the alarm was active + */ +int alarm_cancel(struct alarm *alarm) +{ + for (;;) { + int ret = alarm_try_to_cancel(alarm); + if (ret >= 0) + return ret; + cpu_relax(); + } +} + +/** + * alarm_set_rtc - set the kernel and rtc walltime + * @new_time: timespec value containing the new time + */ +int alarm_set_rtc(struct timespec new_time) +{ + int i; + int ret; + unsigned long flags; + struct rtc_time rtc_new_rtc_time; + struct timespec tmp_time; + + rtc_time_to_tm(new_time.tv_sec, &rtc_new_rtc_time); + + pr_alarm(TSET, "set rtc %ld %ld - rtc %02d:%02d:%02d %02d/%02d/%04d\n", + new_time.tv_sec, new_time.tv_nsec, + rtc_new_rtc_time.tm_hour, rtc_new_rtc_time.tm_min, + rtc_new_rtc_time.tm_sec, rtc_new_rtc_time.tm_mon + 1, + rtc_new_rtc_time.tm_mday, + rtc_new_rtc_time.tm_year + 1900); + + mutex_lock(&alarm_setrtc_mutex); + spin_lock_irqsave(&alarm_slock, flags); + wake_lock(&alarm_rtc_wake_lock); + getnstimeofday(&tmp_time); + for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) { + hrtimer_try_to_cancel(&alarms[i].timer); + alarms[i].stopped = true; + alarms[i].stopped_time = timespec_to_ktime(tmp_time); + } + alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].delta = + alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta = + ktime_sub(alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta, + timespec_to_ktime(timespec_sub(tmp_time, new_time))); + spin_unlock_irqrestore(&alarm_slock, flags); + ret = do_settimeofday(&new_time); + spin_lock_irqsave(&alarm_slock, flags); + for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) { + alarms[i].stopped = false; + update_timer_locked(&alarms[i], false); + } + spin_unlock_irqrestore(&alarm_slock, flags); + if (ret < 0) { + pr_alarm(ERROR, "alarm_set_rtc: Failed to set time\n"); + goto err; + } + if (!alarm_rtc_dev) { + pr_alarm(ERROR, + "alarm_set_rtc: no RTC, time will be lost on reboot\n"); + goto err; + } + ret = rtc_set_time(alarm_rtc_dev, &rtc_new_rtc_time); + if (ret < 0) + pr_alarm(ERROR, "alarm_set_rtc: " + "Failed to set RTC, time will be lost on reboot\n"); +err: + wake_unlock(&alarm_rtc_wake_lock); + mutex_unlock(&alarm_setrtc_mutex); + return ret; +} + +/** + * alarm_get_elapsed_realtime - get the elapsed real time in ktime_t format + * + * returns the time in ktime_t format + */ +ktime_t alarm_get_elapsed_realtime(void) +{ + ktime_t now; + unsigned long flags; + struct alarm_queue *base = &alarms[ANDROID_ALARM_ELAPSED_REALTIME]; + + spin_lock_irqsave(&alarm_slock, flags); + now = base->stopped ? base->stopped_time : ktime_get_real(); + now = ktime_sub(now, base->delta); + spin_unlock_irqrestore(&alarm_slock, flags); + return now; +} + +static enum hrtimer_restart alarm_timer_triggered(struct hrtimer *timer) +{ + struct alarm_queue *base; + struct alarm *alarm; + unsigned long flags; + ktime_t now; + + spin_lock_irqsave(&alarm_slock, flags); + + base = container_of(timer, struct alarm_queue, timer); + now = base->stopped ? base->stopped_time : hrtimer_cb_get_time(timer); + now = ktime_sub(now, base->delta); + + pr_alarm(INT, "alarm_timer_triggered type %d at %lld\n", + base - alarms, ktime_to_ns(now)); + + while (base->first) { + alarm = container_of(base->first, struct alarm, node); + if (alarm->softexpires.tv64 > now.tv64) { + pr_alarm(FLOW, "don't call alarm, %pF, %lld (s %lld)\n", + alarm->function, ktime_to_ns(alarm->expires), + ktime_to_ns(alarm->softexpires)); + break; + } + base->first = rb_next(&alarm->node); + rb_erase(&alarm->node, &base->alarms); + RB_CLEAR_NODE(&alarm->node); + pr_alarm(CALL, "call alarm, type %d, func %pF, %lld (s %lld)\n", + alarm->type, alarm->function, + ktime_to_ns(alarm->expires), + ktime_to_ns(alarm->softexpires)); + spin_unlock_irqrestore(&alarm_slock, flags); + alarm->function(alarm); + spin_lock_irqsave(&alarm_slock, flags); + } + if (!base->first) + pr_alarm(FLOW, "no more alarms of type %d\n", base - alarms); + update_timer_locked(base, true); + spin_unlock_irqrestore(&alarm_slock, flags); + return HRTIMER_NORESTART; +} + +static void alarm_triggered_func(void *p) +{ + struct rtc_device *rtc = alarm_rtc_dev; + if (!(rtc->irq_data & RTC_AF)) + return; + pr_alarm(INT, "rtc alarm triggered\n"); + wake_lock_timeout(&alarm_rtc_wake_lock, 1 * HZ); +} + +static int alarm_suspend(struct platform_device *pdev, pm_message_t state) +{ + int err = 0; + unsigned long flags; + struct rtc_wkalrm rtc_alarm; + struct rtc_time rtc_current_rtc_time; + unsigned long rtc_current_time; + unsigned long rtc_alarm_time; + struct timespec rtc_current_timespec; + struct timespec rtc_delta; + struct alarm_queue *wakeup_queue = NULL; + struct alarm_queue *tmp_queue = NULL; + + pr_alarm(SUSPEND, "alarm_suspend(%p, %d)\n", pdev, state.event); + + spin_lock_irqsave(&alarm_slock, flags); + suspended = true; + spin_unlock_irqrestore(&alarm_slock, flags); + + hrtimer_cancel(&alarms[ANDROID_ALARM_RTC_WAKEUP].timer); + hrtimer_cancel(&alarms[ + ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK].timer); + + tmp_queue = &alarms[ANDROID_ALARM_RTC_WAKEUP]; + if (tmp_queue->first) + wakeup_queue = tmp_queue; + tmp_queue = &alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP]; + if (tmp_queue->first && (!wakeup_queue || + hrtimer_get_expires(&tmp_queue->timer).tv64 < + hrtimer_get_expires(&wakeup_queue->timer).tv64)) + wakeup_queue = tmp_queue; + if (wakeup_queue) { + rtc_read_time(alarm_rtc_dev, &rtc_current_rtc_time); + rtc_current_timespec.tv_nsec = 0; + rtc_tm_to_time(&rtc_current_rtc_time, + &rtc_current_timespec.tv_sec); + save_time_delta(&rtc_delta, &rtc_current_timespec); + + rtc_alarm_time = timespec_sub(ktime_to_timespec( + hrtimer_get_expires(&wakeup_queue->timer)), + rtc_delta).tv_sec; + + rtc_time_to_tm(rtc_alarm_time, &rtc_alarm.time); + rtc_alarm.enabled = 1; + rtc_set_alarm(alarm_rtc_dev, &rtc_alarm); + rtc_read_time(alarm_rtc_dev, &rtc_current_rtc_time); + rtc_tm_to_time(&rtc_current_rtc_time, &rtc_current_time); + pr_alarm(SUSPEND, + "rtc alarm set at %ld, now %ld, rtc delta %ld.%09ld\n", + rtc_alarm_time, rtc_current_time, + rtc_delta.tv_sec, rtc_delta.tv_nsec); + if (rtc_current_time + 1 >= rtc_alarm_time) { + pr_alarm(SUSPEND, "alarm about to go off\n"); + memset(&rtc_alarm, 0, sizeof(rtc_alarm)); + rtc_alarm.enabled = 0; + rtc_set_alarm(alarm_rtc_dev, &rtc_alarm); + + spin_lock_irqsave(&alarm_slock, flags); + suspended = false; + wake_lock_timeout(&alarm_rtc_wake_lock, 2 * HZ); + update_timer_locked(&alarms[ANDROID_ALARM_RTC_WAKEUP], + false); + update_timer_locked(&alarms[ + ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP], false); + err = -EBUSY; + spin_unlock_irqrestore(&alarm_slock, flags); + } + } + return err; +} + +static int alarm_resume(struct platform_device *pdev) +{ + struct rtc_wkalrm alarm; + unsigned long flags; + + pr_alarm(SUSPEND, "alarm_resume(%p)\n", pdev); + + memset(&alarm, 0, sizeof(alarm)); + alarm.enabled = 0; + rtc_set_alarm(alarm_rtc_dev, &alarm); + + spin_lock_irqsave(&alarm_slock, flags); + suspended = false; + update_timer_locked(&alarms[ANDROID_ALARM_RTC_WAKEUP], false); + update_timer_locked(&alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP], + false); + spin_unlock_irqrestore(&alarm_slock, flags); + + return 0; +} + +static struct rtc_task alarm_rtc_task = { + .func = alarm_triggered_func +}; + +static int rtc_alarm_add_device(struct device *dev, + struct class_interface *class_intf) +{ + int err; + struct rtc_device *rtc = to_rtc_device(dev); + + mutex_lock(&alarm_setrtc_mutex); + + if (alarm_rtc_dev) { + err = -EBUSY; + goto err1; + } + + alarm_platform_dev = + platform_device_register_simple("alarm", -1, NULL, 0); + if (IS_ERR(alarm_platform_dev)) { + err = PTR_ERR(alarm_platform_dev); + goto err2; + } + err = rtc_irq_register(rtc, &alarm_rtc_task); + if (err) + goto err3; + alarm_rtc_dev = rtc; + pr_alarm(INIT_STATUS, "using rtc device, %s, for alarms", rtc->name); + mutex_unlock(&alarm_setrtc_mutex); + + return 0; + +err3: + platform_device_unregister(alarm_platform_dev); +err2: +err1: + mutex_unlock(&alarm_setrtc_mutex); + return err; +} + +static void rtc_alarm_remove_device(struct device *dev, + struct class_interface *class_intf) +{ + if (dev == &alarm_rtc_dev->dev) { + pr_alarm(INIT_STATUS, "lost rtc device for alarms"); + rtc_irq_unregister(alarm_rtc_dev, &alarm_rtc_task); + platform_device_unregister(alarm_platform_dev); + alarm_rtc_dev = NULL; + } +} + +static struct class_interface rtc_alarm_interface = { + .add_dev = &rtc_alarm_add_device, + .remove_dev = &rtc_alarm_remove_device, +}; + +static struct platform_driver alarm_driver = { + .suspend = alarm_suspend, + .resume = alarm_resume, + .driver = { + .name = "alarm" + } +}; + +static int __init alarm_late_init(void) +{ + unsigned long flags; + struct timespec tmp_time, system_time; + + /* this needs to run after the rtc is read at boot */ + spin_lock_irqsave(&alarm_slock, flags); + /* We read the current rtc and system time so we can later calulate + * elasped realtime to be (boot_systemtime + rtc - boot_rtc) == + * (rtc - (boot_rtc - boot_systemtime)) + */ + getnstimeofday(&tmp_time); + ktime_get_ts(&system_time); + alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].delta = + alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta = + timespec_to_ktime(timespec_sub(tmp_time, system_time)); + + spin_unlock_irqrestore(&alarm_slock, flags); + return 0; +} + +static int __init alarm_driver_init(void) +{ + int err; + int i; + + for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) { + hrtimer_init(&alarms[i].timer, + CLOCK_REALTIME, HRTIMER_MODE_ABS); + alarms[i].timer.function = alarm_timer_triggered; + } + hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].timer, + CLOCK_MONOTONIC, HRTIMER_MODE_ABS); + alarms[ANDROID_ALARM_SYSTEMTIME].timer.function = alarm_timer_triggered; + err = platform_driver_register(&alarm_driver); + if (err < 0) + goto err1; + wake_lock_init(&alarm_rtc_wake_lock, WAKE_LOCK_SUSPEND, "alarm_rtc"); + rtc_alarm_interface.class = rtc_class; + err = class_interface_register(&rtc_alarm_interface); + if (err < 0) + goto err2; + + return 0; + +err2: + wake_lock_destroy(&alarm_rtc_wake_lock); + platform_driver_unregister(&alarm_driver); +err1: + return err; +} + +static void __exit alarm_exit(void) +{ + class_interface_unregister(&rtc_alarm_interface); + wake_lock_destroy(&alarm_rtc_wake_lock); + platform_driver_unregister(&alarm_driver); +} + +late_initcall(alarm_late_init); +module_init(alarm_driver_init); +module_exit(alarm_exit); + diff --git a/drivers/staging/android/android_alarm.h b/drivers/staging/android/android_alarm.h new file mode 100644 index 00000000000..753ed93bc4d --- /dev/null +++ b/drivers/staging/android/android_alarm.h @@ -0,0 +1,106 @@ +/* include/linux/android_alarm.h + * + * Copyright (C) 2006-2007 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_ANDROID_ALARM_H +#define _LINUX_ANDROID_ALARM_H + +#include +#include + +enum android_alarm_type { + /* return code bit numbers or set alarm arg */ + ANDROID_ALARM_RTC_WAKEUP, + ANDROID_ALARM_RTC, + ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, + ANDROID_ALARM_ELAPSED_REALTIME, + ANDROID_ALARM_SYSTEMTIME, + + ANDROID_ALARM_TYPE_COUNT, + + /* return code bit numbers */ + /* ANDROID_ALARM_TIME_CHANGE = 16 */ +}; + +#ifdef __KERNEL__ + +#include +#include + +/* + * The alarm interface is similar to the hrtimer interface but adds support + * for wakeup from suspend. It also adds an elapsed realtime clock that can + * be used for periodic timers that need to keep runing while the system is + * suspended and not be disrupted when the wall time is set. + */ + +/** + * struct alarm - the basic alarm structure + * @node: red black tree node for time ordered insertion + * @type: alarm type. rtc/elapsed-realtime/systemtime, wakeup/non-wakeup. + * @softexpires: the absolute earliest expiry time of the alarm. + * @expires: the absolute expiry time. + * @function: alarm expiry callback function + * + * The alarm structure must be initialized by alarm_init() + * + */ + +struct alarm { + struct rb_node node; + enum android_alarm_type type; + ktime_t softexpires; + ktime_t expires; + void (*function)(struct alarm *); +}; + +void alarm_init(struct alarm *alarm, + enum android_alarm_type type, void (*function)(struct alarm *)); +void alarm_start_range(struct alarm *alarm, ktime_t start, ktime_t end); +int alarm_try_to_cancel(struct alarm *alarm); +int alarm_cancel(struct alarm *alarm); +ktime_t alarm_get_elapsed_realtime(void); + +/* set rtc while preserving elapsed realtime */ +int alarm_set_rtc(const struct timespec ts); + +#endif + +enum android_alarm_return_flags { + ANDROID_ALARM_RTC_WAKEUP_MASK = 1U << ANDROID_ALARM_RTC_WAKEUP, + ANDROID_ALARM_RTC_MASK = 1U << ANDROID_ALARM_RTC, + ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK = + 1U << ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, + ANDROID_ALARM_ELAPSED_REALTIME_MASK = + 1U << ANDROID_ALARM_ELAPSED_REALTIME, + ANDROID_ALARM_SYSTEMTIME_MASK = 1U << ANDROID_ALARM_SYSTEMTIME, + ANDROID_ALARM_TIME_CHANGE_MASK = 1U << 16 +}; + +/* Disable alarm */ +#define ANDROID_ALARM_CLEAR(type) _IO('a', 0 | ((type) << 4)) + +/* Ack last alarm and wait for next */ +#define ANDROID_ALARM_WAIT _IO('a', 1) + +#define ALARM_IOW(c, type, size) _IOW('a', (c) | ((type) << 4), size) +/* Set alarm */ +#define ANDROID_ALARM_SET(type) ALARM_IOW(2, type, struct timespec) +#define ANDROID_ALARM_SET_AND_WAIT(type) ALARM_IOW(3, type, struct timespec) +#define ANDROID_ALARM_GET_TIME(type) ALARM_IOW(4, type, struct timespec) +#define ANDROID_ALARM_SET_RTC _IOW('a', 5, struct timespec) +#define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0))) +#define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4) + +#endif -- cgit v1.2.3-70-g09d2 From 5dd12c29b45f27d059e4bd58ff1854bc6a236804 Mon Sep 17 00:00:00 2001 From: Arve Hjønnevåg Date: Thu, 9 Feb 2012 14:24:31 -0800 Subject: staging: android-alarm: Don't use save_time_delta. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove references to non-existant save_time_delta. Change-Id: Iaefeca497de02fe36b7f5d79075912f6e349ec53 CC: Arve Hjønnevåg CC: Android Kernel Team Signed-off-by: Arve Hjønnevåg [Added commit message -jstultz] Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/alarm.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/alarm.c b/drivers/staging/android/alarm.c index c5bd51fd839..bc59ac405b2 100644 --- a/drivers/staging/android/alarm.c +++ b/drivers/staging/android/alarm.c @@ -373,8 +373,8 @@ static int alarm_suspend(struct platform_device *pdev, pm_message_t state) struct rtc_time rtc_current_rtc_time; unsigned long rtc_current_time; unsigned long rtc_alarm_time; - struct timespec rtc_current_timespec; struct timespec rtc_delta; + struct timespec wall_time; struct alarm_queue *wakeup_queue = NULL; struct alarm_queue *tmp_queue = NULL; @@ -398,10 +398,11 @@ static int alarm_suspend(struct platform_device *pdev, pm_message_t state) wakeup_queue = tmp_queue; if (wakeup_queue) { rtc_read_time(alarm_rtc_dev, &rtc_current_rtc_time); - rtc_current_timespec.tv_nsec = 0; - rtc_tm_to_time(&rtc_current_rtc_time, - &rtc_current_timespec.tv_sec); - save_time_delta(&rtc_delta, &rtc_current_timespec); + getnstimeofday(&wall_time); + rtc_tm_to_time(&rtc_current_rtc_time, &rtc_current_time); + set_normalized_timespec(&rtc_delta, + wall_time.tv_sec - rtc_current_time, + wall_time.tv_nsec); rtc_alarm_time = timespec_sub(ktime_to_timespec( hrtimer_get_expires(&wakeup_queue->timer)), -- cgit v1.2.3-70-g09d2 From bf647ea717e529fc4f3dfa17dffd40da10522b00 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Thu, 9 Feb 2012 14:24:32 -0800 Subject: staging: android-alarm: Add needed module.h includes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add module.h includes required to build CC: Arve Hjønnevåg CC: Android Kernel Team CC: Andy Green Signed-off-by: Andy Green [jstultz: Tweaked commit subject, folded two patches into one] Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/alarm-dev.c | 1 + drivers/staging/android/alarm.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/android/alarm-dev.c b/drivers/staging/android/alarm-dev.c index ae56961f9c8..7391f409039 100644 --- a/drivers/staging/android/alarm-dev.c +++ b/drivers/staging/android/alarm-dev.c @@ -14,6 +14,7 @@ */ #include +#include #include #include #include diff --git a/drivers/staging/android/alarm.c b/drivers/staging/android/alarm.c index bc59ac405b2..c16032b85d2 100644 --- a/drivers/staging/android/alarm.c +++ b/drivers/staging/android/alarm.c @@ -14,6 +14,7 @@ */ #include +#include #include #include #include -- cgit v1.2.3-70-g09d2 From d47908b20c4cc22c2700ca737252bdc555d4f28a Mon Sep 17 00:00:00 2001 From: John Stultz Date: Thu, 9 Feb 2012 14:24:33 -0800 Subject: staging: android-alarm: Fix include compile issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The file asm/mach/time.h doesn't exist on all arches, so include . Also linux/sysdev.h is gone so kill it. CC: Arve Hjønnevåg CC: Android Kernel Team Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/alarm-dev.c | 3 +-- drivers/staging/android/alarm.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/alarm-dev.c b/drivers/staging/android/alarm-dev.c index 7391f409039..80ea85086e4 100644 --- a/drivers/staging/android/alarm-dev.c +++ b/drivers/staging/android/alarm-dev.c @@ -13,7 +13,7 @@ * */ -#include +#include #include #include #include @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include "android_alarm.h" diff --git a/drivers/staging/android/alarm.c b/drivers/staging/android/alarm.c index c16032b85d2..7aaf5b8aa4f 100644 --- a/drivers/staging/android/alarm.c +++ b/drivers/staging/android/alarm.c @@ -13,7 +13,7 @@ * */ -#include +#include #include #include #include @@ -21,7 +21,6 @@ #include #include #include -#include #include #include "android_alarm.h" -- cgit v1.2.3-70-g09d2 From f2f28eacf240baffbba5e9744278f85fc62ddd60 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Thu, 9 Feb 2012 14:24:34 -0800 Subject: staging: android-alarm: Fix namespace collision with upstreamed alarmtimers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The upstreamed alarmtimers are similar but not quite 100% API compatibile with the android in-kernel alarm api. To aid the transition, prefix the the android in-kernel api with android_ CC: Arve Hjønnevåg CC: Android Kernel Team Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/alarm-dev.c | 14 ++++++------- drivers/staging/android/alarm.c | 37 +++++++++++++++++---------------- drivers/staging/android/android_alarm.h | 17 ++++++++------- 3 files changed, 35 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/alarm-dev.c b/drivers/staging/android/alarm-dev.c index 80ea85086e4..758d828784f 100644 --- a/drivers/staging/android/alarm-dev.c +++ b/drivers/staging/android/alarm-dev.c @@ -55,7 +55,7 @@ static uint32_t alarm_pending; static uint32_t alarm_enabled; static uint32_t wait_pending; -static struct alarm alarms[ANDROID_ALARM_TYPE_COUNT]; +static struct android_alarm alarms[ANDROID_ALARM_TYPE_COUNT]; static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -90,7 +90,7 @@ static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case ANDROID_ALARM_CLEAR(0): spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm %d clear\n", alarm_type); - alarm_try_to_cancel(&alarms[alarm_type]); + android_alarm_try_to_cancel(&alarms[alarm_type]); if (alarm_pending) { alarm_pending &= ~alarm_type_mask; if (!alarm_pending && !wait_pending) @@ -121,7 +121,7 @@ from_old_alarm_set: pr_alarm(IO, "alarm %d set %ld.%09ld\n", alarm_type, new_alarm_time.tv_sec, new_alarm_time.tv_nsec); alarm_enabled |= alarm_type_mask; - alarm_start_range(&alarms[alarm_type], + android_alarm_start_range(&alarms[alarm_type], timespec_to_ktime(new_alarm_time), timespec_to_ktime(new_alarm_time)); spin_unlock_irqrestore(&alarm_slock, flags); @@ -152,7 +152,7 @@ from_old_alarm_set: rv = -EFAULT; goto err1; } - rv = alarm_set_rtc(new_rtc_time); + rv = android_alarm_set_rtc(new_rtc_time); spin_lock_irqsave(&alarm_slock, flags); alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK; wake_up(&alarm_wait_queue); @@ -213,7 +213,7 @@ static int alarm_release(struct inode *inode, struct file *file) alarm_enabled &= ~alarm_type_mask; } spin_unlock_irqrestore(&alarm_slock, flags); - alarm_cancel(&alarms[i]); + android_alarm_cancel(&alarms[i]); spin_lock_irqsave(&alarm_slock, flags); } if (alarm_pending | wait_pending) { @@ -230,7 +230,7 @@ static int alarm_release(struct inode *inode, struct file *file) return 0; } -static void alarm_triggered(struct alarm *alarm) +static void alarm_triggered(struct android_alarm *alarm) { unsigned long flags; uint32_t alarm_type_mask = 1U << alarm->type; @@ -269,7 +269,7 @@ static int __init alarm_dev_init(void) return err; for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) - alarm_init(&alarms[i], i, alarm_triggered); + android_alarm_init(&alarms[i], i, alarm_triggered); wake_lock_init(&alarm_wake_lock, WAKE_LOCK_SUSPEND, "alarm"); return 0; diff --git a/drivers/staging/android/alarm.c b/drivers/staging/android/alarm.c index 7aaf5b8aa4f..1f8bb5ca568 100644 --- a/drivers/staging/android/alarm.c +++ b/drivers/staging/android/alarm.c @@ -70,7 +70,7 @@ static bool suspended; static void update_timer_locked(struct alarm_queue *base, bool head_removed) { - struct alarm *alarm; + struct android_alarm *alarm; bool is_wakeup = base == &alarms[ANDROID_ALARM_RTC_WAKEUP] || base == &alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP]; @@ -85,7 +85,7 @@ static void update_timer_locked(struct alarm_queue *base, bool head_removed) if (!base->first) return; - alarm = container_of(base->first, struct alarm, node); + alarm = container_of(base->first, struct android_alarm, node); pr_alarm(FLOW, "selected alarm, type %d, func %pF at %lld\n", alarm->type, alarm->function, ktime_to_ns(alarm->expires)); @@ -102,12 +102,12 @@ static void update_timer_locked(struct alarm_queue *base, bool head_removed) hrtimer_start_expires(&base->timer, HRTIMER_MODE_ABS); } -static void alarm_enqueue_locked(struct alarm *alarm) +static void alarm_enqueue_locked(struct android_alarm *alarm) { struct alarm_queue *base = &alarms[alarm->type]; struct rb_node **link = &base->alarms.rb_node; struct rb_node *parent = NULL; - struct alarm *entry; + struct android_alarm *entry; int leftmost = 1; pr_alarm(FLOW, "added alarm, type %d, func %pF at %lld\n", @@ -122,7 +122,7 @@ static void alarm_enqueue_locked(struct alarm *alarm) while (*link) { parent = *link; - entry = rb_entry(parent, struct alarm, node); + entry = rb_entry(parent, struct android_alarm, node); /* * We dont care about collisions. Nodes with * the same expiry time stay together. @@ -144,13 +144,13 @@ static void alarm_enqueue_locked(struct alarm *alarm) } /** - * alarm_init - initialize an alarm + * android_alarm_init - initialize an alarm * @alarm: the alarm to be initialized * @type: the alarm type to be used * @function: alarm callback function */ -void alarm_init(struct alarm *alarm, - enum android_alarm_type type, void (*function)(struct alarm *)) +void android_alarm_init(struct android_alarm *alarm, + enum android_alarm_type type, void (*function)(struct android_alarm *)) { RB_CLEAR_NODE(&alarm->node); alarm->type = type; @@ -161,12 +161,13 @@ void alarm_init(struct alarm *alarm, /** - * alarm_start_range - (re)start an alarm + * android_alarm_start_range - (re)start an alarm * @alarm: the alarm to be added * @start: earliest expiry time * @end: expiry time */ -void alarm_start_range(struct alarm *alarm, ktime_t start, ktime_t end) +void android_alarm_start_range(struct android_alarm *alarm, ktime_t start, + ktime_t end) { unsigned long flags; @@ -178,7 +179,7 @@ void alarm_start_range(struct alarm *alarm, ktime_t start, ktime_t end) } /** - * alarm_try_to_cancel - try to deactivate an alarm + * android_alarm_try_to_cancel - try to deactivate an alarm * @alarm: alarm to stop * * Returns: @@ -187,7 +188,7 @@ void alarm_start_range(struct alarm *alarm, ktime_t start, ktime_t end) * -1 when the alarm may currently be excuting the callback function and * cannot be stopped (it may also be inactive) */ -int alarm_try_to_cancel(struct alarm *alarm) +int android_alarm_try_to_cancel(struct android_alarm *alarm) { struct alarm_queue *base = &alarms[alarm->type]; unsigned long flags; @@ -218,17 +219,17 @@ int alarm_try_to_cancel(struct alarm *alarm) } /** - * alarm_cancel - cancel an alarm and wait for the handler to finish. + * android_alarm_cancel - cancel an alarm and wait for the handler to finish. * @alarm: the alarm to be cancelled * * Returns: * 0 when the alarm was not active * 1 when the alarm was active */ -int alarm_cancel(struct alarm *alarm) +int android_alarm_cancel(struct android_alarm *alarm) { for (;;) { - int ret = alarm_try_to_cancel(alarm); + int ret = android_alarm_try_to_cancel(alarm); if (ret >= 0) return ret; cpu_relax(); @@ -239,7 +240,7 @@ int alarm_cancel(struct alarm *alarm) * alarm_set_rtc - set the kernel and rtc walltime * @new_time: timespec value containing the new time */ -int alarm_set_rtc(struct timespec new_time) +int android_alarm_set_rtc(struct timespec new_time) { int i; int ret; @@ -317,7 +318,7 @@ ktime_t alarm_get_elapsed_realtime(void) static enum hrtimer_restart alarm_timer_triggered(struct hrtimer *timer) { struct alarm_queue *base; - struct alarm *alarm; + struct android_alarm *alarm; unsigned long flags; ktime_t now; @@ -331,7 +332,7 @@ static enum hrtimer_restart alarm_timer_triggered(struct hrtimer *timer) base - alarms, ktime_to_ns(now)); while (base->first) { - alarm = container_of(base->first, struct alarm, node); + alarm = container_of(base->first, struct android_alarm, node); if (alarm->softexpires.tv64 > now.tv64) { pr_alarm(FLOW, "don't call alarm, %pF, %lld (s %lld)\n", alarm->function, ktime_to_ns(alarm->expires), diff --git a/drivers/staging/android/android_alarm.h b/drivers/staging/android/android_alarm.h index 753ed93bc4d..9213581c927 100644 --- a/drivers/staging/android/android_alarm.h +++ b/drivers/staging/android/android_alarm.h @@ -57,23 +57,24 @@ enum android_alarm_type { * */ -struct alarm { +struct android_alarm { struct rb_node node; enum android_alarm_type type; ktime_t softexpires; ktime_t expires; - void (*function)(struct alarm *); + void (*function)(struct android_alarm *); }; -void alarm_init(struct alarm *alarm, - enum android_alarm_type type, void (*function)(struct alarm *)); -void alarm_start_range(struct alarm *alarm, ktime_t start, ktime_t end); -int alarm_try_to_cancel(struct alarm *alarm); -int alarm_cancel(struct alarm *alarm); +void android_alarm_init(struct android_alarm *alarm, + enum android_alarm_type type, void (*function)(struct android_alarm *)); +void android_alarm_start_range(struct android_alarm *alarm, ktime_t start, + ktime_t end); +int android_alarm_try_to_cancel(struct android_alarm *alarm); +int android_alarm_cancel(struct android_alarm *alarm); ktime_t alarm_get_elapsed_realtime(void); /* set rtc while preserving elapsed realtime */ -int alarm_set_rtc(const struct timespec ts); +int android_alarm_set_rtc(const struct timespec ts); #endif -- cgit v1.2.3-70-g09d2 From 79ef07162fb088f8afe7709881e2b5e2a4098202 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Thu, 9 Feb 2012 14:24:35 -0800 Subject: staging: android-alarm: HACK: wakelock workaround MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow Android alarmtimer device to build while wakelocks are still out of tree. CC: Arve Hjønnevåg CC: Android Kernel Team Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/alarm-dev.c | 13 ++++++++++++- drivers/staging/android/alarm.c | 12 +++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/alarm-dev.c b/drivers/staging/android/alarm-dev.c index 758d828784f..03efb34cbe2 100644 --- a/drivers/staging/android/alarm-dev.c +++ b/drivers/staging/android/alarm-dev.c @@ -22,13 +22,24 @@ #include #include #include -#include #include "android_alarm.h" +/* XXX - Hack out wakelocks, while they are out of tree */ +struct wake_lock { + int i; +}; +#define wake_lock(x) +#define wake_lock_timeout(x, y) +#define wake_unlock(x) +#define WAKE_LOCK_SUSPEND 0 +#define wake_lock_init(x, y, z) ((x)->i = 1) +#define wake_lock_destroy(x) + #define ANDROID_ALARM_PRINT_INFO (1U << 0) #define ANDROID_ALARM_PRINT_IO (1U << 1) #define ANDROID_ALARM_PRINT_INT (1U << 2) + static int debug_mask = ANDROID_ALARM_PRINT_INFO; module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); diff --git a/drivers/staging/android/alarm.c b/drivers/staging/android/alarm.c index 1f8bb5ca568..5370fdc8b01 100644 --- a/drivers/staging/android/alarm.c +++ b/drivers/staging/android/alarm.c @@ -21,9 +21,19 @@ #include #include #include -#include #include "android_alarm.h" +/* XXX - Hack out wakelocks, while they are out of tree */ +struct wake_lock { + int i; +}; +#define wake_lock(x) +#define wake_lock_timeout(x, y) +#define wake_unlock(x) +#define WAKE_LOCK_SUSPEND 0 +#define wake_lock_init(x, y, z) ((x)->i = 1) +#define wake_lock_destroy(x) + #define ANDROID_ALARM_PRINT_ERROR (1U << 0) #define ANDROID_ALARM_PRINT_INIT_STATUS (1U << 1) #define ANDROID_ALARM_PRINT_TSET (1U << 2) -- cgit v1.2.3-70-g09d2 From fe8d2727ffa65bcb516b4947bec1c546841e7d25 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Thu, 9 Feb 2012 14:24:36 -0800 Subject: staging: android-alarm: Reenable android alarm driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that it builds, re-enable android alarm driver in the makefile and kconfig CC: Arve Hjønnevåg CC: Android Kernel Team Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/Kconfig | 17 +++++++++++++++++ drivers/staging/android/Makefile | 2 ++ 2 files changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig index becf711117e..2a2b3867a65 100644 --- a/drivers/staging/android/Kconfig +++ b/drivers/staging/android/Kconfig @@ -105,6 +105,23 @@ config ANDROID_PMEM source "drivers/staging/android/switch/Kconfig" +config ANDROID_INTF_ALARM + bool "Android alarm driver" + depends on RTC_CLASS + default y + help + Provides non-wakeup and rtc backed wakeup alarms based on rtc or + elapsed realtime, and a non-wakeup alarm on the monotonic clock. + Also provides an interface to set the wall time which must be used + for elapsed realtime to work. + +config ANDROID_INTF_ALARM_DEV + bool "Android alarm device" + depends on ANDROID_INTF_ALARM + default y + help + Exports the alarm interface to user-space. + endif # if ANDROID endmenu diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile index eaed1ff64f0..7c6e53b89e6 100644 --- a/drivers/staging/android/Makefile +++ b/drivers/staging/android/Makefile @@ -7,3 +7,5 @@ obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o obj-$(CONFIG_ANDROID_PMEM) += pmem.o obj-$(CONFIG_ANDROID_SWITCH) += switch/ +obj-$(CONFIG_ANDROID_INTF_ALARM) += alarm.o +obj-$(CONFIG_ANDROID_INTF_ALARM_DEV) += alarm-dev.o -- cgit v1.2.3-70-g09d2 From 58a38ff3b12ebd103e3ca2c5dea3292ffbfd0f02 Mon Sep 17 00:00:00 2001 From: Praneeth Kumar Bajjuri Date: Thu, 9 Feb 2012 14:24:37 -0800 Subject: staging: android-alarm: Disable Android alarm driver by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do not enable Android alarm driver by default CC: Arve Hjønnevåg CC: Android Kernel Team CC: Praneeth Bajjuri Change-Id: Iff8f7a65c4eceecfd084074937c72824697b5e7f Signed-off-by: Praneeth Bajjuri [jstultz: tweaked commit subject & msg] Signed-off-by: John Stultz 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 2a2b3867a65..6bb4fa8e5ff 100644 --- a/drivers/staging/android/Kconfig +++ b/drivers/staging/android/Kconfig @@ -108,7 +108,7 @@ source "drivers/staging/android/switch/Kconfig" config ANDROID_INTF_ALARM bool "Android alarm driver" depends on RTC_CLASS - default y + default n help Provides non-wakeup and rtc backed wakeup alarms based on rtc or elapsed realtime, and a non-wakeup alarm on the monotonic clock. -- cgit v1.2.3-70-g09d2 From 66c48107719b751e8ec360034bc84ee1511147e4 Mon Sep 17 00:00:00 2001 From: Arve Hjønnevåg Date: Thu, 9 Feb 2012 14:24:38 -0800 Subject: staging: android-alarm: Update hrtimer if alarm at the head of the queue is reprogrammed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If an alarm was restarted with a value that moved it away from the head of a queue, the hrtimer would not be updated. This would cause unnecessary wakeups. CC: Arve Hjønnevåg CC: Android Kernel Team Change-Id: If379f8dd92b0bdb3173bd8d057adfe0dc1d15259 Signed-off-by: Arve Hjønnevåg Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/alarm.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/alarm.c b/drivers/staging/android/alarm.c index 5370fdc8b01..445c0b12c47 100644 --- a/drivers/staging/android/alarm.c +++ b/drivers/staging/android/alarm.c @@ -119,12 +119,15 @@ static void alarm_enqueue_locked(struct android_alarm *alarm) struct rb_node *parent = NULL; struct android_alarm *entry; int leftmost = 1; + bool was_first = false; pr_alarm(FLOW, "added alarm, type %d, func %pF at %lld\n", alarm->type, alarm->function, ktime_to_ns(alarm->expires)); - if (base->first == &alarm->node) + if (base->first == &alarm->node) { base->first = rb_next(&alarm->node); + was_first = true; + } if (!RB_EMPTY_NODE(&alarm->node)) { rb_erase(&alarm->node, &base->alarms); RB_CLEAR_NODE(&alarm->node); @@ -144,10 +147,10 @@ static void alarm_enqueue_locked(struct android_alarm *alarm) leftmost = 0; } } - if (leftmost) { + if (leftmost) base->first = &alarm->node; - update_timer_locked(base, false); - } + if (leftmost || was_first) + update_timer_locked(base, was_first); rb_link_node(&alarm->node, parent, link); rb_insert_color(&alarm->node, &base->alarms); -- cgit v1.2.3-70-g09d2 From f2d3c6898abd6c5d69e6d1504413434df1ea2538 Mon Sep 17 00:00:00 2001 From: JP Abgrall Date: Thu, 9 Feb 2012 14:24:39 -0800 Subject: staging: android-alarm: Fix bad index when canceling alarms[] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was using ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK as an index. CC: Arve Hjønnevåg CC: Android Kernel Team CC: JP Abgrall Change-Id: I919860cc71254453e382616bce9fd5455802cb3d Signed-off-by: JP Abgrall [jstultz: Tweaked commit subject] Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/alarm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/android/alarm.c b/drivers/staging/android/alarm.c index 445c0b12c47..642a22f01c1 100644 --- a/drivers/staging/android/alarm.c +++ b/drivers/staging/android/alarm.c @@ -400,7 +400,7 @@ static int alarm_suspend(struct platform_device *pdev, pm_message_t state) hrtimer_cancel(&alarms[ANDROID_ALARM_RTC_WAKEUP].timer); hrtimer_cancel(&alarms[ - ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK].timer); + ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].timer); tmp_queue = &alarms[ANDROID_ALARM_RTC_WAKEUP]; if (tmp_queue->first) -- cgit v1.2.3-70-g09d2 From 7f9b98a39bdd12db051514eb0daff689c34b8b4e Mon Sep 17 00:00:00 2001 From: John Stultz Date: Thu, 9 Feb 2012 14:24:40 -0800 Subject: staging: android-alarm: Fixup minor pr_alarm warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes the following warnings: drivers/staging/android/alarm.c: In function ‘alarm_timer_triggered’: drivers/staging/android/alarm.c:344: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘long int’ drivers/staging/android/alarm.c:367: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘long int’ CC: Arve Hjønnevåg CC: Android Kernel Team Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/alarm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/android/alarm.c b/drivers/staging/android/alarm.c index 642a22f01c1..c68950b9e08 100644 --- a/drivers/staging/android/alarm.c +++ b/drivers/staging/android/alarm.c @@ -341,7 +341,7 @@ static enum hrtimer_restart alarm_timer_triggered(struct hrtimer *timer) now = base->stopped ? base->stopped_time : hrtimer_cb_get_time(timer); now = ktime_sub(now, base->delta); - pr_alarm(INT, "alarm_timer_triggered type %d at %lld\n", + pr_alarm(INT, "alarm_timer_triggered type %ld at %lld\n", base - alarms, ktime_to_ns(now)); while (base->first) { @@ -364,7 +364,7 @@ static enum hrtimer_restart alarm_timer_triggered(struct hrtimer *timer) spin_lock_irqsave(&alarm_slock, flags); } if (!base->first) - pr_alarm(FLOW, "no more alarms of type %d\n", base - alarms); + pr_alarm(FLOW, "no more alarms of type %ld\n", base - alarms); update_timer_locked(base, true); spin_unlock_irqrestore(&alarm_slock, flags); return HRTIMER_NORESTART; -- cgit v1.2.3-70-g09d2 From 2157f896774ace6e98c851878f8089fb861502e2 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Thu, 9 Feb 2012 14:24:41 -0800 Subject: staging: android-alarm: Support old drivers via preprocessor aliasing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Older out of tree drivers that were desgined to the Android Alarm in-kernel API may not build due to the namespace collision fixed in an earlier patch. Per Arve's suggestion, this patch provides preprocessor macros that allow older drivers to build. CC: Arve Hjønnevåg CC: Android Kernel Team Signed-off-by: John Stultz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/Kconfig | 9 +++++++++ drivers/staging/android/android_alarm.h | 14 ++++++++++++++ 2 files changed, 23 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig index 6bb4fa8e5ff..75ca22581ec 100644 --- a/drivers/staging/android/Kconfig +++ b/drivers/staging/android/Kconfig @@ -122,6 +122,15 @@ config ANDROID_INTF_ALARM_DEV help Exports the alarm interface to user-space. +config ANDROID_ALARM_OLDDRV_COMPAT + bool "Android Alarm compatability with old drivers" + depends on ANDROID_INTF_ALARM + default n + help + Provides preprocessor alias to aid compatability with + older out-of-tree drivers that use the Android Alarm + in-kernel API. This will be removed eventually. + endif # if ANDROID endmenu diff --git a/drivers/staging/android/android_alarm.h b/drivers/staging/android/android_alarm.h index 9213581c927..6eecbde2ef6 100644 --- a/drivers/staging/android/android_alarm.h +++ b/drivers/staging/android/android_alarm.h @@ -76,6 +76,20 @@ ktime_t alarm_get_elapsed_realtime(void); /* set rtc while preserving elapsed realtime */ int android_alarm_set_rtc(const struct timespec ts); +#ifdef CONFIG_ANDROID_ALARM_OLDDRV_COMPAT +/* + * Some older drivers depend on the old API, + * so provide compatability macros for now. + */ +#define alarm android_alarm +#define alarm_init(x, y, z) android_alarm_init(x, y, z) +#define alarm_start_range(x, y, z) android_alarm_start_range(x, y, z) +#define alarm_try_to_cancel(x) android_alarm_try_to_cancel(x) +#define alarm_cancel(x) android_alarm_cancel(x) +#define alarm_set_rtc(x) android_alarm_set_rtc(x) +#endif + + #endif enum android_alarm_return_flags { -- cgit v1.2.3-70-g09d2 From ffcf12810ca11891deb580d166af13fae294fe2e Mon Sep 17 00:00:00 2001 From: "Mark A. Allyn" Date: Fri, 10 Feb 2012 13:52:27 +0000 Subject: staging: sep: Add new PCI identifier [This is picked out of the differences between the upstream driver and the staging driver. I'm resolving the differences as a series of updates -AC] Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver_hw_defs.h | 3 --- drivers/staging/sep/sep_main.c | 5 +++-- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/sep/sep_driver_hw_defs.h b/drivers/staging/sep/sep_driver_hw_defs.h index c48e49a741b..a6a44817038 100644 --- a/drivers/staging/sep/sep_driver_hw_defs.h +++ b/drivers/staging/sep/sep_driver_hw_defs.h @@ -33,9 +33,6 @@ #ifndef SEP_DRIVER_HW_DEFS__H #define SEP_DRIVER_HW_DEFS__H -/* PCI ID's */ -#define MFLD_PCI_DEVICE_ID 0x0826 - /*----------------------- */ /* HW Registers Defines. */ /* */ diff --git a/drivers/staging/sep/sep_main.c b/drivers/staging/sep/sep_main.c index 7f8362cab7a..421a2b1e898 100644 --- a/drivers/staging/sep/sep_main.c +++ b/drivers/staging/sep/sep_main.c @@ -4085,8 +4085,9 @@ static void sep_remove(struct pci_dev *pdev) /* Initialize struct pci_device_id for our driver */ static DEFINE_PCI_DEVICE_TABLE(sep_pci_id_tbl) = { - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MFLD_PCI_DEVICE_ID)}, - {0} + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0826)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x08e9)}, + {0} }; /* Export our pci_device_id structure to user space */ -- cgit v1.2.3-70-g09d2 From aca58ec828af52516816ec48e75a78f043e508c7 Mon Sep 17 00:00:00 2001 From: "Mark A. Allyn" Date: Fri, 10 Feb 2012 13:52:42 +0000 Subject: staging: sep: Basic infrastructure for SEP DMA access to non CPU regions [This is picked out of the differences between the upstream driver and the staging driver. I'm resolving the differences as a series of updates -AC] Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver_api.h | 15 ++- drivers/staging/sep/sep_main.c | 233 +++++++++++++++++++++++++++++++---- 2 files changed, 223 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/sep/sep_driver_api.h b/drivers/staging/sep/sep_driver_api.h index 78a4b69d3fd..8b797d5388b 100644 --- a/drivers/staging/sep/sep_driver_api.h +++ b/drivers/staging/sep/sep_driver_api.h @@ -61,7 +61,9 @@ enum hash_stage { HASH_INIT, HASH_UPDATE, HASH_FINISH, - HASH_DIGEST + HASH_DIGEST, + HASH_FINUP_DATA, + HASH_FINUP_FINISH }; /* @@ -205,6 +207,7 @@ struct sep_lli_entry { */ struct sep_fastcall_hdr { u32 magic; + u32 secure_dma; u32 msg_len; u32 num_dcbs; }; @@ -231,6 +234,8 @@ struct sep_dma_context { u32 dmatables_len; /* size of input data */ u32 input_data_len; + /* secure dma use (for imr memory restriced area in output */ + bool secure_dma; struct sep_dma_resource dma_res_arr[SEP_MAX_NUM_SYNC_DMA_OPS]; /* Scatter gather for kernel crypto */ struct scatterlist *src_sg; @@ -317,6 +322,7 @@ ssize_t sep_activate_dcb_dmatables_context(struct sep_device *sep, * @tail_block_size: u32; for size of tail block * @isapplet: bool; to indicate external app * @is_kva: bool; kernel buffer; only used for kernel crypto module + * @secure_dma; indicates whether this is secure_dma using IMR * * This function prepares the linked DMA tables and puts the * address for the linked list of tables inta a DCB (data control @@ -332,6 +338,7 @@ int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, u32 tail_block_size, bool isapplet, bool is_kva, + bool secure_dma, struct sep_dcblock *dcb_region, void **dmatables_region, struct sep_dma_context **dma_ctx, @@ -386,4 +393,10 @@ int sep_wait_transaction(struct sep_device *sep); struct sep_device; +#define SEP_IOCPREPAREDCB_SECURE_DMA \ + _IOW(SEP_IOC_MAGIC_NUMBER, 38, struct build_dcb_struct) + +#define SEP_IOCFREEDCB_SECURE_DMA \ + _IO(SEP_IOC_MAGIC_NUMBER, 39) + #endif diff --git a/drivers/staging/sep/sep_main.c b/drivers/staging/sep/sep_main.c index 421a2b1e898..7d7cb48d794 100644 --- a/drivers/staging/sep/sep_main.c +++ b/drivers/staging/sep/sep_main.c @@ -485,8 +485,15 @@ int sep_free_dma_table_data_handler(struct sep_device *sep, kfree(dma->in_map_array); } - /* Unmap output map array, DON'T free it yet */ - if (dma->out_map_array) { + /** + * Output is handled different. If + * this was a secure dma into restricted memory, + * then we skip this step altogether as restricted + * memory is not available to the o/s at all. + */ + if (((*dma_ctx)->secure_dma == false) && + (dma->out_map_array)) { + for (count = 0; count < dma->out_num_pages; count++) { dma_unmap_page(&sep->pdev->dev, dma->out_map_array[count].dma_addr, @@ -505,7 +512,10 @@ int sep_free_dma_table_data_handler(struct sep_device *sep, kfree(dma->in_page_array); } - if (dma->out_page_array) { + /* Again, we do this only for non secure dma */ + if (((*dma_ctx)->secure_dma == false) && + (dma->out_page_array)) { + for (count = 0; count < dma->out_num_pages; count++) { if (!PageReserved(dma->out_page_array[count])) @@ -1382,6 +1392,128 @@ end_function: return error; } +/** + * sep_lli_table_secure_dma - get lli array for IMR addresses + * @sep: pointer to struct sep_device + * @app_virt_addr: user memory data buffer + * @data_size: size of data buffer + * @lli_array_ptr: lli array + * @in_out_flag: not used + * @dma_ctx: pointer to struct sep_dma_context + * + * This function creates lli tables for outputting data to + * IMR memory, which is memory that cannot be accessed by the + * the x86 processor. + */ +static int sep_lli_table_secure_dma(struct sep_device *sep, + u32 app_virt_addr, + u32 data_size, + struct sep_lli_entry **lli_array_ptr, + int in_out_flag, + struct sep_dma_context *dma_ctx) + +{ + int error = 0; + u32 count; + /* The the page of the end address of the user space buffer */ + u32 end_page; + /* The page of the start address of the user space buffer */ + u32 start_page; + /* The range in pages */ + u32 num_pages; + /* Array of lli */ + struct sep_lli_entry *lli_array; + + /* Set start and end pages and num pages */ + end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT; + start_page = app_virt_addr >> PAGE_SHIFT; + num_pages = end_page - start_page + 1; + + dev_dbg(&sep->pdev->dev, "[PID%d] lock user pages" + " app_virt_addr is %x\n", current->pid, app_virt_addr); + + dev_dbg(&sep->pdev->dev, "[PID%d] data_size is (hex) %x\n", + current->pid, data_size); + dev_dbg(&sep->pdev->dev, "[PID%d] start_page is (hex) %x\n", + current->pid, start_page); + dev_dbg(&sep->pdev->dev, "[PID%d] end_page is (hex) %x\n", + current->pid, end_page); + dev_dbg(&sep->pdev->dev, "[PID%d] num_pages is (hex) %x\n", + current->pid, num_pages); + + lli_array = kmalloc(sizeof(struct sep_lli_entry) * num_pages, + GFP_ATOMIC); + + if (!lli_array) { + dev_warn(&sep->pdev->dev, + "[PID%d] kmalloc for lli_array failed\n", + current->pid); + return -ENOMEM; + } + + /* + * Fill the lli_array + */ + start_page = start_page << PAGE_SHIFT; + for (count = 0; count < num_pages; count++) { + /* Fill the lli array entry */ + lli_array[count].bus_address = start_page; + lli_array[count].block_size = PAGE_SIZE; + + start_page += PAGE_SIZE; + + dev_dbg(&sep->pdev->dev, + "[PID%d] lli_array[%x].bus_address is %08lx, " + "lli_array[%x].block_size is (hex) %x\n", + current->pid, + count, (unsigned long)lli_array[count].bus_address, + count, lli_array[count].block_size); + } + + /* Check the offset for the first page */ + lli_array[0].bus_address = + lli_array[0].bus_address + (app_virt_addr & (~PAGE_MASK)); + + /* Check that not all the data is in the first page only */ + if ((PAGE_SIZE - (app_virt_addr & (~PAGE_MASK))) >= data_size) + lli_array[0].block_size = data_size; + else + lli_array[0].block_size = + PAGE_SIZE - (app_virt_addr & (~PAGE_MASK)); + + dev_dbg(&sep->pdev->dev, + "[PID%d] After check if page 0 has all data\n" + "lli_array[0].bus_address is (hex) %08lx, " + "lli_array[0].block_size is (hex) %x\n", + current->pid, + (unsigned long)lli_array[0].bus_address, + lli_array[0].block_size); + + /* Check the size of the last page */ + if (num_pages > 1) { + lli_array[num_pages - 1].block_size = + (app_virt_addr + data_size) & (~PAGE_MASK); + if (lli_array[num_pages - 1].block_size == 0) + lli_array[num_pages - 1].block_size = PAGE_SIZE; + + dev_dbg(&sep->pdev->dev, + "[PID%d] After last page size adjustment\n" + "lli_array[%x].bus_address is (hex) %08lx, " + "lli_array[%x].block_size is (hex) %x\n", + current->pid, num_pages - 1, + (unsigned long)lli_array[num_pages - 1].bus_address, + num_pages - 1, + lli_array[num_pages - 1].block_size); + } + *lli_array_ptr = lli_array; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_num_pages = num_pages; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_page_array = NULL; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_map_array = NULL; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_map_num_entries = 0; + + return error; +} + /** * sep_calculate_lli_table_max_size - size the LLI table * @sep: pointer to struct sep_device @@ -1613,6 +1745,7 @@ static void sep_debug_print_lli_tables(struct sep_device *sep, unsigned long num_table_entries, unsigned long table_data_size) { +#ifdef DEBUG unsigned long table_count = 1; unsigned long entries_count = 0; @@ -1686,6 +1819,7 @@ static void sep_debug_print_lli_tables(struct sep_device *sep, } dev_dbg(&sep->pdev->dev, "[PID%d] sep_debug_print_lli_tables end\n", current->pid); +#endif } @@ -1956,8 +2090,10 @@ update_dcb_counter: end_function_error: /* Free all the allocated resources */ kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array); + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array = NULL; kfree(lli_array_ptr); kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array); + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array = NULL; end_function: return error; @@ -2360,20 +2496,42 @@ static int sep_prepare_input_output_dma_table(struct sep_device *sep, goto end_function; } - dev_dbg(&sep->pdev->dev, "[PID%d] Locking user output pages\n", + if (dma_ctx->secure_dma == true) { + /* secure_dma requires use of non accessible memory */ + dev_dbg(&sep->pdev->dev, "[PID%d] in secure_dma\n", + current->pid); + error = sep_lli_table_secure_dma(sep, + app_virt_out_addr, data_size, &lli_out_array, + SEP_DRIVER_OUT_FLAG, dma_ctx); + if (error) { + dev_warn(&sep->pdev->dev, + "[PID%d] secure dma table setup " + " for output virtual buffer failed\n", + current->pid); + + goto end_function_free_lli_in; + } + } else { + /* For normal, non-secure dma */ + dev_dbg(&sep->pdev->dev, "[PID%d] not in secure_dma\n", current->pid); - error = sep_lock_user_pages(sep, app_virt_out_addr, + dev_dbg(&sep->pdev->dev, + "[PID%d] Locking user output pages\n", + current->pid); + + error = sep_lock_user_pages(sep, app_virt_out_addr, data_size, &lli_out_array, SEP_DRIVER_OUT_FLAG, dma_ctx); - if (error) { - dev_warn(&sep->pdev->dev, + if (error) { + dev_warn(&sep->pdev->dev, "[PID%d] sep_lock_user_pages" " for output virtual buffer failed\n", current->pid); - goto end_function_free_lli_in; + goto end_function_free_lli_in; + } } } @@ -2421,13 +2579,17 @@ update_dcb_counter: end_function_with_error: kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_map_array); + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_map_array = NULL; kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_page_array); + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_page_array = NULL; kfree(lli_out_array); end_function_free_lli_in: kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array); + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array = NULL; kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array); + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array = NULL; kfree(lli_in_array); end_function: @@ -2445,6 +2607,7 @@ end_function: * @tail_block_size: u32; for size of tail block * @isapplet: bool; to indicate external app * @is_kva: bool; kernel buffer; only used for kernel crypto module + * @secure_dma; indicates whether this is secure_dma using IMR * * This function prepares the linked DMA tables and puts the * address for the linked list of tables inta a DCB (data control @@ -2460,6 +2623,7 @@ int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, u32 tail_block_size, bool isapplet, bool is_kva, + bool secure_dma, struct sep_dcblock *dcb_region, void **dmatables_region, struct sep_dma_context **dma_ctx, @@ -2534,6 +2698,8 @@ int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, current->pid, *dma_ctx); } + (*dma_ctx)->secure_dma = secure_dma; + /* these are for kernel crypto only */ (*dma_ctx)->src_sg = src_sg; (*dma_ctx)->dst_sg = dst_sg; @@ -2690,6 +2856,7 @@ int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, end_function_error: kfree(*dma_ctx); + *dma_ctx = NULL; end_function: return error; @@ -2719,15 +2886,22 @@ 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 (isapplet == true) { + if (((*dma_ctx)->secure_dma == false) && (isapplet == true)) { + dev_dbg(&sep->pdev->dev, "[PID%d] handling applet\n", + current->pid); + + /* Tail stuff is only for non secure_dma */ /* Set pointer to first DCB table */ dcb_table_ptr = (struct sep_dcblock *) (sep->shared_addr + SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES); - /* Go over each DCB and see if tail pointer must be updated */ - for (i = 0; - i < (*dma_ctx)->nr_dcb_creat; i++, dcb_table_ptr++) { + /** + * 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++) { if (dcb_table_ptr->out_vr_tail_pt) { pt_hold = (unsigned long)dcb_table_ptr-> out_vr_tail_pt; @@ -2749,6 +2923,7 @@ static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet, } } } + /* Free the output pages, if any */ sep_free_dma_table_data_handler(sep, dma_ctx); @@ -2762,11 +2937,13 @@ static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet, * sep_prepare_dcb_handler - prepare a control block * @sep: pointer to struct sep_device * @arg: pointer to user parameters + * @secure_dma: indicate whether we are using secure_dma on IMR * * This function will retrieve the RAR buffer physical addresses, type * & size corresponding to the RAR handles provided in the buffers vector. */ static int sep_prepare_dcb_handler(struct sep_device *sep, unsigned long arg, + bool secure_dma, struct sep_dma_context **dma_ctx) { int error; @@ -2812,7 +2989,7 @@ static int sep_prepare_dcb_handler(struct sep_device *sep, unsigned long arg, command_args.data_in_size, command_args.block_size, command_args.tail_block_size, command_args.is_applet, false, - NULL, NULL, dma_ctx, NULL, NULL); + secure_dma, NULL, NULL, dma_ctx, NULL, NULL); end_function: return error; @@ -2829,21 +3006,18 @@ end_function: static int sep_free_dcb_handler(struct sep_device *sep, struct sep_dma_context **dma_ctx) { - int error = 0; - if (!dma_ctx || !(*dma_ctx)) { - dev_dbg(&sep->pdev->dev, "[PID%d] no dma context defined, nothing to free\n", + dev_dbg(&sep->pdev->dev, + "[PID%d] no dma context defined, nothing to free\n", current->pid); - return error; + return -EINVAL; } dev_dbg(&sep->pdev->dev, "[PID%d] free dcbs num of DCBs %x\n", current->pid, (*dma_ctx)->nr_dcb_creat); - error = sep_free_dma_tables_and_dcb(sep, false, false, dma_ctx); - - return error; + return sep_free_dma_tables_and_dcb(sep, false, false, dma_ctx); } /** @@ -2931,7 +3105,7 @@ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) goto end_function; } - error = sep_prepare_dcb_handler(sep, arg, dma_ctx); + error = sep_prepare_dcb_handler(sep, arg, false, dma_ctx); dev_dbg(&sep->pdev->dev, "[PID%d] SEP_IOCPREPAREDCB end\n", current->pid); break; @@ -3170,13 +3344,14 @@ end_function: * @dma_ctx: DMA context buf to create for current transaction * @user_dcb_args: User arguments for DCB/MLLI creation * @num_dcbs: Number of DCBs to create + * @secure_dma: Indicate use of IMR restricted memory secure dma */ static ssize_t sep_create_dcb_dmatables_context(struct sep_device *sep, struct sep_dcblock **dcb_region, void **dmatables_region, struct sep_dma_context **dma_ctx, const struct build_dcb_struct __user *user_dcb_args, - const u32 num_dcbs) + const u32 num_dcbs, bool secure_dma) { int error = 0; int i = 0; @@ -3231,7 +3406,7 @@ static ssize_t sep_create_dcb_dmatables_context(struct sep_device *sep, dcb_args[i].block_size, dcb_args[i].tail_block_size, dcb_args[i].is_applet, - false, + false, secure_dma, *dcb_region, dmatables_region, dma_ctx, NULL, @@ -3242,6 +3417,9 @@ static ssize_t sep_create_dcb_dmatables_context(struct sep_device *sep, current->pid); goto end_function; } + + if (dcb_args[i].app_in_address != 0) + (*dma_ctx)->input_data_len += dcb_args[i].data_in_size; } end_function: @@ -3311,6 +3489,7 @@ int sep_create_dcb_dmatables_context_kernel(struct sep_device *sep, dcb_data->tail_block_size, dcb_data->is_applet, true, + false, *dcb_region, dmatables_region, dma_ctx, dcb_data->src_sg, @@ -3597,6 +3776,7 @@ static ssize_t sep_write(struct file *filp, struct sep_dcblock *dcb_region = NULL; ssize_t error = 0; struct sep_queue_info *my_queue_elem = NULL; + bool my_secure_dma; /* are we using secure_dma (IMR)? */ dev_dbg(&sep->pdev->dev, "[PID%d] sep dev is 0x%p\n", current->pid, sep); @@ -3609,6 +3789,11 @@ static ssize_t sep_write(struct file *filp, buf_user += sizeof(struct sep_fastcall_hdr); + if (call_hdr.secure_dma == 0) + my_secure_dma = false; + else + my_secure_dma = true; + /* * Controlling driver memory usage by limiting amount of * buffers created. Only SEP_DOUBLEBUF_USERS_LIMIT number @@ -3636,7 +3821,7 @@ static ssize_t sep_write(struct file *filp, &dma_ctx, (const struct build_dcb_struct __user *) buf_user, - call_hdr.num_dcbs); + call_hdr.num_dcbs, my_secure_dma); if (error) goto end_function_error_doublebuf; -- cgit v1.2.3-70-g09d2 From 6ab80c26085b91f4a6c0336bbc99b18e9938cfb2 Mon Sep 17 00:00:00 2001 From: "Mark A. Allyn" Date: Fri, 10 Feb 2012 13:52:55 +0000 Subject: staging: sep: Add interfaces for the new functions [This is picked out of the differences between the upstream driver and the staging driver. I'm resolving the differences as a series of updates -AC] Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_main.c | 60 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/sep/sep_main.c b/drivers/staging/sep/sep_main.c index 7d7cb48d794..1fcabca72d4 100644 --- a/drivers/staging/sep/sep_main.c +++ b/drivers/staging/sep/sep_main.c @@ -3067,9 +3067,13 @@ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) switch (cmd) { case SEP_IOCSENDSEPCOMMAND: + dev_dbg(&sep->pdev->dev, + "[PID%d] SEP_IOCSENDSEPCOMMAND start\n", + current->pid); if (1 == test_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET, &call_status->status)) { - dev_dbg(&sep->pdev->dev, "[PID%d] send msg already done\n", + dev_warn(&sep->pdev->dev, + "[PID%d] send msg already done\n", current->pid); error = -EPROTO; goto end_function; @@ -3079,37 +3083,71 @@ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (!error) set_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET, &call_status->status); - dev_dbg(&sep->pdev->dev, "[PID%d] SEP_IOCSENDSEPCOMMAND end\n", + dev_dbg(&sep->pdev->dev, + "[PID%d] SEP_IOCSENDSEPCOMMAND end\n", current->pid); break; case SEP_IOCENDTRANSACTION: + dev_dbg(&sep->pdev->dev, + "[PID%d] SEP_IOCENDTRANSACTION start\n", + current->pid); error = sep_end_transaction_handler(sep, dma_ctx, call_status, - my_queue_elem); - dev_dbg(&sep->pdev->dev, "[PID%d] SEP_IOCENDTRANSACTION end\n", + my_queue_elem); + dev_dbg(&sep->pdev->dev, + "[PID%d] SEP_IOCENDTRANSACTION end\n", current->pid); break; case SEP_IOCPREPAREDCB: + dev_dbg(&sep->pdev->dev, + "[PID%d] SEP_IOCPREPAREDCB start\n", + current->pid); + case SEP_IOCPREPAREDCB_SECURE_DMA: + dev_dbg(&sep->pdev->dev, + "[PID%d] SEP_IOCPREPAREDCB_SECURE_DMA start\n", + current->pid); if (1 == test_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET, &call_status->status)) { - dev_dbg(&sep->pdev->dev, - "[PID%d] dcb preparation needed before send msg\n", + dev_warn(&sep->pdev->dev, + "[PID%d] dcb prep needed before send msg\n", current->pid); error = -EPROTO; goto end_function; } if (!arg) { - dev_dbg(&sep->pdev->dev, - "[PID%d] dcb prep null arg\n", current->pid); - error = -EINVAL; + dev_warn(&sep->pdev->dev, + "[PID%d] dcb null arg\n", current->pid); + error = EINVAL; goto end_function; } - error = sep_prepare_dcb_handler(sep, arg, false, dma_ctx); - dev_dbg(&sep->pdev->dev, "[PID%d] SEP_IOCPREPAREDCB end\n", + if (cmd == SEP_IOCPREPAREDCB) { + /* No secure dma */ + dev_dbg(&sep->pdev->dev, + "[PID%d] SEP_IOCPREPAREDCB (no secure_dma)\n", + current->pid); + + error = sep_prepare_dcb_handler(sep, arg, false, + dma_ctx); + } else { + /* Secure dma */ + dev_dbg(&sep->pdev->dev, + "[PID%d] SEP_IOC_POC (with secure_dma)\n", + current->pid); + + error = sep_prepare_dcb_handler(sep, arg, true, + dma_ctx); + } + dev_dbg(&sep->pdev->dev, "[PID%d] dcb's end\n", current->pid); break; case SEP_IOCFREEDCB: + dev_dbg(&sep->pdev->dev, "[PID%d] SEP_IOCFREEDCB start\n", + current->pid); + case SEP_IOCFREEDCB_SECURE_DMA: + dev_dbg(&sep->pdev->dev, + "[PID%d] SEP_IOCFREEDCB_SECURE_DMA start\n", + current->pid); error = sep_free_dcb_handler(sep, dma_ctx); dev_dbg(&sep->pdev->dev, "[PID%d] SEP_IOCFREEDCB end\n", current->pid); -- cgit v1.2.3-70-g09d2 From ecd0cb003fda30702c6c1f007a58bef885f5cb42 Mon Sep 17 00:00:00 2001 From: "Mark A. Allyn" Date: Fri, 10 Feb 2012 13:53:08 +0000 Subject: staging: sep: update initialisation In particular we want to always do the reconfigure [This is picked out of the differences between the upstream driver and the staging driver. I'm resolving the differences as a series of updates -AC] Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_main.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/sep/sep_main.c b/drivers/staging/sep/sep_main.c index 1fcabca72d4..db51895f5b1 100644 --- a/drivers/staging/sep/sep_main.c +++ b/drivers/staging/sep/sep_main.c @@ -4150,7 +4150,6 @@ static int __devinit sep_probe(struct pci_dev *pdev, dev_dbg(&sep->pdev->dev, "sep probe: PCI obtained, " "device being prepared\n"); - dev_dbg(&sep->pdev->dev, "revision is %d\n", sep->pdev->revision); /* Set up our register area */ sep->reg_physical_addr = pci_resource_start(sep->pdev, 0); @@ -4213,38 +4212,39 @@ static int __devinit sep_probe(struct pci_dev *pdev, goto end_function_deallocate_sep_shared_area; /* The new chip requires a shared area reconfigure */ - if (sep->pdev->revision != 0) { /* Only for new chip */ - error = sep_reconfig_shared_area(sep); - if (error) - goto end_function_free_irq; - } + error = sep_reconfig_shared_area(sep); + if (error) + goto end_function_free_irq; sep->in_use = 1; /* Finally magic up the device nodes */ /* Register driver with the fs */ error = sep_register_driver_with_fs(sep); - if (error) + + if (error) { + dev_err(&sep->pdev->dev, "error registering dev file\n"); goto end_function_free_irq; + } + sep->in_use = 0; /* through touching the device */ #ifdef SEP_ENABLE_RUNTIME_PM pm_runtime_put_noidle(&sep->pdev->dev); pm_runtime_allow(&sep->pdev->dev); pm_runtime_set_autosuspend_delay(&sep->pdev->dev, SUSPEND_DELAY); pm_runtime_use_autosuspend(&sep->pdev->dev); + pm_runtime_mark_last_busy(&sep->pdev->dev); sep->power_save_setup = 1; #endif - - sep->in_use = 0; - /* register kernel crypto driver */ +#if defined(CONFIG_CRYPTO) error = sep_crypto_setup(); if (error) { - dev_dbg(&sep->pdev->dev, "crypto setup fail\n"); + dev_err(&sep->pdev->dev, "crypto setup failed\n"); goto end_function_free_irq; } - +#endif goto end_function; end_function_free_irq: @@ -4292,7 +4292,7 @@ static void sep_remove(struct pci_dev *pdev) /* Free the shared area */ sep_unmap_and_free_shared_area(sep_dev); - iounmap((void __iomem *)sep_dev->reg_addr); + iounmap(sep_dev->reg_addr); #ifdef SEP_ENABLE_RUNTIME_PM if (sep->in_use) { -- cgit v1.2.3-70-g09d2 From ab8ef35131ee42963abe87b2b1d2911bda4a8a48 Mon Sep 17 00:00:00 2001 From: "Mark A. Allyn" Date: Fri, 10 Feb 2012 13:53:21 +0000 Subject: staging: sep: NULL out pointers, mark debug code DEBUG to fix warnings [This is picked out of the differences between the upstream driver and the staging driver. I'm resolving the differences as a series of updates -AC] Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_main.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/sep/sep_main.c b/drivers/staging/sep/sep_main.c index db51895f5b1..cf420f6bbe1 100644 --- a/drivers/staging/sep/sep_main.c +++ b/drivers/staging/sep/sep_main.c @@ -40,6 +40,7 @@ /* #define SEP_PERF_DEBUG */ #include +#include #include #include #include @@ -197,9 +198,9 @@ static int sep_allocate_dmatables_region(struct sep_device *sep, struct sep_dma_context *dma_ctx, const u32 table_count) { - const size_t new_len = table_count * - sizeof(struct sep_lli_entry) * - SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; + const size_t new_len = + SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES - 1; + void *tmp_region = NULL; dev_dbg(&sep->pdev->dev, "[PID%d] dma_ctx = 0x%p\n", @@ -230,6 +231,7 @@ static int sep_allocate_dmatables_region(struct sep_device *sep, if (*dmatables_region) { memcpy(tmp_region, *dmatables_region, dma_ctx->dmatables_len); kfree(*dmatables_region); + *dmatables_region = NULL; } *dmatables_region = tmp_region; @@ -342,11 +344,12 @@ static void _sep_dump_message(struct sep_device *sep) u32 *p = sep->shared_addr; - for (count = 0; count < 40 * 4; count += 4) + for (count = 0; count < 10 * 4; count += 4) dev_dbg(&sep->pdev->dev, "[PID%d] Word %d of the message is %x\n", current->pid, count/4, *p++); } + #endif /** @@ -384,6 +387,8 @@ static void sep_unmap_and_free_shared_area(struct sep_device *sep) sep->shared_addr, sep->shared_bus); } +#ifdef DEBUG + /** * sep_shared_bus_to_virt - convert bus/virt addresses * @sep: pointer to struct sep_device @@ -398,6 +403,8 @@ static void *sep_shared_bus_to_virt(struct sep_device *sep, return sep->shared_addr + (bus_address - sep->shared_bus); } +#endif + /** * sep_open - device open method * @inode: inode of SEP device -- cgit v1.2.3-70-g09d2 From 9196dc1129fbb3ecf93027224a6bdbc86d086e3a Mon Sep 17 00:00:00 2001 From: "Mark A. Allyn" Date: Fri, 10 Feb 2012 13:53:36 +0000 Subject: staging: sep: reworked crypto layer This gets the SEP crypto layer up and running with things like dmcrypt. It's a fairly big set of changes because it has to rework the whole context handling system. [This is picked out of the differences between the upstream driver and the staging driver. I'm resolving the differences as a series of updates -AC] Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_crypto.c | 3058 +++++++++++++++++++++----------------- drivers/staging/sep/sep_crypto.h | 77 +- drivers/staging/sep/sep_dev.h | 3 +- 3 files changed, 1717 insertions(+), 1421 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/sep/sep_crypto.c b/drivers/staging/sep/sep_crypto.c index a6b0f8353bb..89b6814c70a 100644 --- a/drivers/staging/sep/sep_crypto.c +++ b/drivers/staging/sep/sep_crypto.c @@ -88,17 +88,17 @@ static void sep_dequeuer(void *data); * This will only print dump if DEBUG is set; it does * follow kernel debug print enabling */ -static void crypto_sep_dump_message(struct sep_system_ctx *sctx) +static void crypto_sep_dump_message(struct sep_device *sep, void *msg) { #if 0 u32 *p; u32 *i; int count; - p = sctx->sep_used->shared_addr; - i = (u32 *)sctx->msg; - for (count = 0; count < 40 * 4; count += 4) - dev_dbg(&sctx->sep_used->pdev->dev, + p = sep->shared_addr; + i = (u32 *)msg; + for (count = 0; count < 10 * 4; count += 4) + dev_dbg(&sep->pdev->dev, "[PID%d] Word %d of the message is %x (local)%x\n", current->pid, count/4, *p++, *i++); #endif @@ -534,6 +534,67 @@ static void sep_dump_sg(struct sep_device *sep, char *stg, #endif } +/* Debug - prints only if DEBUG is defined */ +static void sep_dump_ivs(struct ablkcipher_request *req, char *reason) + + { + unsigned char *cptr; + struct sep_aes_internal_context *aes_internal; + struct sep_des_internal_context *des_internal; + int ct1; + + struct this_task_ctx *ta_ctx; + struct crypto_ablkcipher *tfm; + struct sep_system_ctx *sctx; + + ta_ctx = ablkcipher_request_ctx(req); + tfm = crypto_ablkcipher_reqtfm(req); + sctx = crypto_ablkcipher_ctx(tfm); + + dev_dbg(&ta_ctx->sep_used->pdev->dev, "IV DUMP - %s\n", reason); + if ((ta_ctx->current_request == DES_CBC) && + (ta_ctx->des_opmode == SEP_DES_CBC)) { + + des_internal = (struct sep_des_internal_context *) + sctx->des_private_ctx.ctx_buf; + /* print vendor */ + dev_dbg(&ta_ctx->sep_used->pdev->dev, + "sep - vendor iv for DES\n"); + cptr = (unsigned char *)des_internal->iv_context; + for (ct1 = 0; ct1 < crypto_ablkcipher_ivsize(tfm); ct1 += 1) + dev_dbg(&ta_ctx->sep_used->pdev->dev, + "%02x\n", *(cptr + ct1)); + + /* print walk */ + dev_dbg(&ta_ctx->sep_used->pdev->dev, + "sep - walk from kernel crypto iv for DES\n"); + cptr = (unsigned char *)ta_ctx->walk.iv; + for (ct1 = 0; ct1 < crypto_ablkcipher_ivsize(tfm); ct1 += 1) + dev_dbg(&ta_ctx->sep_used->pdev->dev, + "%02x\n", *(cptr + ct1)); + } else if ((ta_ctx->current_request == AES_CBC) && + (ta_ctx->aes_opmode == SEP_AES_CBC)) { + + aes_internal = (struct sep_aes_internal_context *) + sctx->aes_private_ctx.cbuff; + /* print vendor */ + dev_dbg(&ta_ctx->sep_used->pdev->dev, + "sep - vendor iv for AES\n"); + cptr = (unsigned char *)aes_internal->aes_ctx_iv; + for (ct1 = 0; ct1 < crypto_ablkcipher_ivsize(tfm); ct1 += 1) + dev_dbg(&ta_ctx->sep_used->pdev->dev, + "%02x\n", *(cptr + ct1)); + + /* print walk */ + dev_dbg(&ta_ctx->sep_used->pdev->dev, + "sep - walk from kernel crypto iv for AES\n"); + cptr = (unsigned char *)ta_ctx->walk.iv; + for (ct1 = 0; ct1 < crypto_ablkcipher_ivsize(tfm); ct1 += 1) + dev_dbg(&ta_ctx->sep_used->pdev->dev, + "%02x\n", *(cptr + ct1)); + } +} + /** * RFC2451: Weak key check * Returns: 1 (weak), 0 (not weak) @@ -671,61 +732,61 @@ static u32 sep_sg_nents(struct scatterlist *sg) /** * sep_start_msg - - * @sctx: pointer to struct sep_system_ctx + * @ta_ctx: pointer to struct this_task_ctx * @returns: offset to place for the next word in the message * Set up pointer in message pool for new message */ -static u32 sep_start_msg(struct sep_system_ctx *sctx) +static u32 sep_start_msg(struct this_task_ctx *ta_ctx) { u32 *word_ptr; - sctx->msg_len_words = 2; - sctx->msgptr = sctx->msg; - memset(sctx->msg, 0, SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); - sctx->msgptr += sizeof(u32) * 2; - word_ptr = (u32 *)sctx->msgptr; + ta_ctx->msg_len_words = 2; + ta_ctx->msgptr = ta_ctx->msg; + memset(ta_ctx->msg, 0, SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); + ta_ctx->msgptr += sizeof(u32) * 2; + word_ptr = (u32 *)ta_ctx->msgptr; *word_ptr = SEP_START_MSG_TOKEN; return sizeof(u32) * 2; } /** * sep_end_msg - - * @sctx: pointer to struct sep_system_ctx + * @ta_ctx: pointer to struct this_task_ctx * @messages_offset: current message offset * Returns: 0 for success; <0 otherwise * End message; set length and CRC; and * send interrupt to the SEP */ -static void sep_end_msg(struct sep_system_ctx *sctx, u32 msg_offset) +static void sep_end_msg(struct this_task_ctx *ta_ctx, u32 msg_offset) { u32 *word_ptr; /* Msg size goes into msg after token */ - sctx->msg_len_words = msg_offset / sizeof(u32) + 1; - word_ptr = (u32 *)sctx->msgptr; + ta_ctx->msg_len_words = msg_offset / sizeof(u32) + 1; + word_ptr = (u32 *)ta_ctx->msgptr; word_ptr += 1; - *word_ptr = sctx->msg_len_words; + *word_ptr = ta_ctx->msg_len_words; /* CRC (currently 0) goes at end of msg */ - word_ptr = (u32 *)(sctx->msgptr + msg_offset); + word_ptr = (u32 *)(ta_ctx->msgptr + msg_offset); *word_ptr = 0; } /** * sep_start_inbound_msg - - * @sctx: pointer to struct sep_system_ctx + * @ta_ctx: pointer to struct this_task_ctx * @msg_offset: offset to place for the next word in the message * @returns: 0 for success; error value for failure * Set up pointer in message pool for inbound message */ -static u32 sep_start_inbound_msg(struct sep_system_ctx *sctx, u32 *msg_offset) +static u32 sep_start_inbound_msg(struct this_task_ctx *ta_ctx, u32 *msg_offset) { u32 *word_ptr; u32 token; u32 error = SEP_OK; *msg_offset = sizeof(u32) * 2; - word_ptr = (u32 *)sctx->msgptr; + word_ptr = (u32 *)ta_ctx->msgptr; token = *word_ptr; - sctx->msg_len_words = *(word_ptr + 1); + ta_ctx->msg_len_words = *(word_ptr + 1); if (token != SEP_START_MSG_TOKEN) { error = SEP_INVALID_START; @@ -739,7 +800,7 @@ end_function: /** * sep_write_msg - - * @sctx: pointer to struct sep_system_ctx + * @ta_ctx: pointer to struct this_task_ctx * @in_addr: pointer to start of parameter * @size: size of parameter to copy (in bytes) * @max_size: size to move up offset; SEP mesg is in word sizes @@ -747,12 +808,12 @@ end_function: * @byte_array: flag ti indicate wheter endian must be changed * Copies data into the message area from caller */ -static void sep_write_msg(struct sep_system_ctx *sctx, void *in_addr, +static void sep_write_msg(struct this_task_ctx *ta_ctx, void *in_addr, u32 size, u32 max_size, u32 *msg_offset, u32 byte_array) { u32 *word_ptr; void *void_ptr; - void_ptr = sctx->msgptr + *msg_offset; + void_ptr = ta_ctx->msgptr + *msg_offset; word_ptr = (u32 *)void_ptr; memcpy(void_ptr, in_addr, size); *msg_offset += max_size; @@ -767,18 +828,18 @@ static void sep_write_msg(struct sep_system_ctx *sctx, void *in_addr, /** * sep_make_header - * @sctx: pointer to struct sep_system_ctx + * @ta_ctx: pointer to struct this_task_ctx * @msg_offset: pointer to current offset (is updated) * @op_code: op code to put into message * Puts op code into message and updates offset */ -static void sep_make_header(struct sep_system_ctx *sctx, u32 *msg_offset, +static void sep_make_header(struct this_task_ctx *ta_ctx, u32 *msg_offset, u32 op_code) { u32 *word_ptr; - *msg_offset = sep_start_msg(sctx); - word_ptr = (u32 *)(sctx->msgptr + *msg_offset); + *msg_offset = sep_start_msg(ta_ctx); + word_ptr = (u32 *)(ta_ctx->msgptr + *msg_offset); *word_ptr = op_code; *msg_offset += sizeof(u32); } @@ -787,7 +848,7 @@ static void sep_make_header(struct sep_system_ctx *sctx, u32 *msg_offset, /** * sep_read_msg - - * @sctx: pointer to struct sep_system_ctx + * @ta_ctx: pointer to struct this_task_ctx * @in_addr: pointer to start of parameter * @size: size of parameter to copy (in bytes) * @max_size: size to move up offset; SEP mesg is in word sizes @@ -795,12 +856,12 @@ static void sep_make_header(struct sep_system_ctx *sctx, u32 *msg_offset, * @byte_array: flag ti indicate wheter endian must be changed * Copies data out of the message area to caller */ -static void sep_read_msg(struct sep_system_ctx *sctx, void *in_addr, +static void sep_read_msg(struct this_task_ctx *ta_ctx, void *in_addr, u32 size, u32 max_size, u32 *msg_offset, u32 byte_array) { u32 *word_ptr; void *void_ptr; - void_ptr = sctx->msgptr + *msg_offset; + void_ptr = ta_ctx->msgptr + *msg_offset; word_ptr = (u32 *)void_ptr; /* Do we need to manipulate endian? */ @@ -816,28 +877,28 @@ static void sep_read_msg(struct sep_system_ctx *sctx, void *in_addr, /** * sep_verify_op - - * @sctx: pointer to struct sep_system_ctx + * @ta_ctx: pointer to struct this_task_ctx * @op_code: expected op_code * @msg_offset: pointer to current offset (is updated) * @returns: 0 for success; error for failure */ -static u32 sep_verify_op(struct sep_system_ctx *sctx, u32 op_code, +static u32 sep_verify_op(struct this_task_ctx *ta_ctx, u32 op_code, u32 *msg_offset) { u32 error; u32 in_ary[2]; - struct sep_device *sep = sctx->sep_used; + struct sep_device *sep = ta_ctx->sep_used; dev_dbg(&sep->pdev->dev, "dumping return message\n"); - error = sep_start_inbound_msg(sctx, msg_offset); + error = sep_start_inbound_msg(ta_ctx, msg_offset); if (error) { dev_warn(&sep->pdev->dev, "sep_start_inbound_msg error\n"); return error; } - sep_read_msg(sctx, in_ary, sizeof(u32) * 2, sizeof(u32) * 2, + sep_read_msg(ta_ctx, in_ary, sizeof(u32) * 2, sizeof(u32) * 2, msg_offset, 0); if (in_ary[0] != op_code) { @@ -863,7 +924,7 @@ return 0; /** * sep_read_context - - * @sctx: pointer to struct sep_system_ctx + * @ta_ctx: pointer to struct this_task_ctx * @msg_offset: point to current place in SEP msg; is updated * @dst: pointer to place to put the context * @len: size of the context structure (differs for crypro/hash) @@ -873,16 +934,16 @@ return 0; * it skips over some words in the msg area depending on the size * of the context */ -static void sep_read_context(struct sep_system_ctx *sctx, u32 *msg_offset, +static void sep_read_context(struct this_task_ctx *ta_ctx, u32 *msg_offset, void *dst, u32 len) { u32 max_length = ((len + 3) / sizeof(u32)) * sizeof(u32); - sep_read_msg(sctx, dst, len, max_length, msg_offset, 0); + sep_read_msg(ta_ctx, dst, len, max_length, msg_offset, 0); } /** * sep_write_context - - * @sctx: pointer to struct sep_system_ctx + * @ta_ctx: pointer to struct this_task_ctx * @msg_offset: point to current place in SEP msg; is updated * @src: pointer to the current context * @len: size of the context structure (differs for crypro/hash) @@ -892,76 +953,77 @@ static void sep_read_context(struct sep_system_ctx *sctx, u32 *msg_offset, * it skips over some words in the msg area depending on the size * of the context */ -static void sep_write_context(struct sep_system_ctx *sctx, u32 *msg_offset, +static void sep_write_context(struct this_task_ctx *ta_ctx, u32 *msg_offset, void *src, u32 len) { u32 max_length = ((len + 3) / sizeof(u32)) * sizeof(u32); - sep_write_msg(sctx, src, len, max_length, msg_offset, 0); + sep_write_msg(ta_ctx, src, len, max_length, msg_offset, 0); } /** * sep_clear_out - - * @sctx: pointer to struct sep_system_ctx + * @ta_ctx: pointer to struct this_task_ctx * Clear out crypto related values in sep device structure * to enable device to be used by anyone; either kernel * crypto or userspace app via middleware */ -static void sep_clear_out(struct sep_system_ctx *sctx) +static void sep_clear_out(struct this_task_ctx *ta_ctx) { - if (sctx->src_sg_hold) { - sep_free_sg_buf(sctx->src_sg_hold); - sctx->src_sg_hold = NULL; + if (ta_ctx->src_sg_hold) { + sep_free_sg_buf(ta_ctx->src_sg_hold); + ta_ctx->src_sg_hold = NULL; } - if (sctx->dst_sg_hold) { - sep_free_sg_buf(sctx->dst_sg_hold); - sctx->dst_sg_hold = NULL; + if (ta_ctx->dst_sg_hold) { + sep_free_sg_buf(ta_ctx->dst_sg_hold); + ta_ctx->dst_sg_hold = NULL; } - sctx->src_sg = NULL; - sctx->dst_sg = NULL; + ta_ctx->src_sg = NULL; + ta_ctx->dst_sg = NULL; - sep_free_dma_table_data_handler(sctx->sep_used, &sctx->dma_ctx); + sep_free_dma_table_data_handler(ta_ctx->sep_used, &ta_ctx->dma_ctx); - if (sctx->i_own_sep) { + if (ta_ctx->i_own_sep) { /** * The following unlocks the sep and makes it available * to any other application * First, null out crypto entries in sep before relesing it */ - sctx->sep_used->current_hash_req = NULL; - sctx->sep_used->current_cypher_req = NULL; - sctx->sep_used->current_request = 0; - sctx->sep_used->current_hash_stage = 0; - sctx->sep_used->sctx = NULL; - sctx->sep_used->in_kernel = 0; + ta_ctx->sep_used->current_hash_req = NULL; + ta_ctx->sep_used->current_cypher_req = NULL; + ta_ctx->sep_used->current_request = 0; + ta_ctx->sep_used->current_hash_stage = 0; + ta_ctx->sep_used->ta_ctx = NULL; + ta_ctx->sep_used->in_kernel = 0; - sctx->call_status.status = 0; + ta_ctx->call_status.status = 0; /* Remove anything confidentail */ - memset(sctx->sep_used->shared_addr, 0, + memset(ta_ctx->sep_used->shared_addr, 0, SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); - sep_queue_status_remove(sctx->sep_used, &sctx->queue_elem); + sep_queue_status_remove(ta_ctx->sep_used, &ta_ctx->queue_elem); #ifdef SEP_ENABLE_RUNTIME_PM - sctx->sep_used->in_use = 0; - pm_runtime_mark_last_busy(&sctx->sep_used->pdev->dev); - pm_runtime_put_autosuspend(&sctx->sep_used->pdev->dev); + ta_ctx->sep_used->in_use = 0; + pm_runtime_mark_last_busy(&ta_ctx->sep_used->pdev->dev); + pm_runtime_put_autosuspend(&ta_ctx->sep_used->pdev->dev); #endif - clear_bit(SEP_WORKING_LOCK_BIT, &sctx->sep_used->in_use_flags); - sctx->sep_used->pid_doing_transaction = 0; + clear_bit(SEP_WORKING_LOCK_BIT, + &ta_ctx->sep_used->in_use_flags); + ta_ctx->sep_used->pid_doing_transaction = 0; - dev_dbg(&sctx->sep_used->pdev->dev, + dev_dbg(&ta_ctx->sep_used->pdev->dev, "[PID%d] waking up next transaction\n", current->pid); clear_bit(SEP_TRANSACTION_STARTED_LOCK_BIT, - &sctx->sep_used->in_use_flags); - wake_up(&sctx->sep_used->event_transactions); + &ta_ctx->sep_used->in_use_flags); + wake_up(&ta_ctx->sep_used->event_transactions); - sctx->i_own_sep = 0; + ta_ctx->i_own_sep = 0; } } @@ -969,22 +1031,34 @@ static void sep_clear_out(struct sep_system_ctx *sctx) * Release crypto infrastructure from EINPROGRESS and * clear sep_dev so that SEP is available to anyone */ -static void sep_crypto_release(struct sep_system_ctx *sctx, u32 error) +static void sep_crypto_release(struct sep_system_ctx *sctx, + struct this_task_ctx *ta_ctx, u32 error) { - struct ahash_request *hash_req = sctx->current_hash_req; + struct ahash_request *hash_req = ta_ctx->current_hash_req; struct ablkcipher_request *cypher_req = - sctx->current_cypher_req; - struct sep_device *sep = sctx->sep_used; + ta_ctx->current_cypher_req; + struct sep_device *sep = ta_ctx->sep_used; + + sep_clear_out(ta_ctx); - sep_clear_out(sctx); + /** + * This may not yet exist depending when we + * chose to bail out. If it does exist, set + * it to 1 + */ + if (ta_ctx->are_we_done_yet != NULL) + *ta_ctx->are_we_done_yet = 1; if (cypher_req != NULL) { - if (cypher_req->base.complete == NULL) { - dev_dbg(&sep->pdev->dev, - "release is null for cypher!"); - } else { - cypher_req->base.complete( - &cypher_req->base, error); + if ((sctx->key_sent == 1) || + ((error != 0) && (error != -EINPROGRESS))) { + if (cypher_req->base.complete == NULL) { + dev_dbg(&sep->pdev->dev, + "release is null for cypher!"); + } else { + cypher_req->base.complete( + &cypher_req->base, error); + } } } @@ -1005,20 +1079,20 @@ static void sep_crypto_release(struct sep_system_ctx *sctx, u32 error) * and it will return 0 if sep is now ours; error value if there * were problems */ -static int sep_crypto_take_sep(struct sep_system_ctx *sctx) +static int sep_crypto_take_sep(struct this_task_ctx *ta_ctx) { - struct sep_device *sep = sctx->sep_used; + struct sep_device *sep = ta_ctx->sep_used; int result; struct sep_msgarea_hdr *my_msg_header; - my_msg_header = (struct sep_msgarea_hdr *)sctx->msg; + my_msg_header = (struct sep_msgarea_hdr *)ta_ctx->msg; /* add to status queue */ - sctx->queue_elem = sep_queue_status_add(sep, my_msg_header->opcode, - sctx->nbytes, current->pid, + ta_ctx->queue_elem = sep_queue_status_add(sep, my_msg_header->opcode, + ta_ctx->nbytes, current->pid, current->comm, sizeof(current->comm)); - if (!sctx->queue_elem) { + if (!ta_ctx->queue_elem) { dev_dbg(&sep->pdev->dev, "[PID%d] updating queue" " status error\n", current->pid); return -EINVAL; @@ -1033,48 +1107,61 @@ static int sep_crypto_take_sep(struct sep_system_ctx *sctx) pm_runtime_get_sync(&sep_dev->pdev->dev); /* Copy in the message */ - memcpy(sep->shared_addr, sctx->msg, + memcpy(sep->shared_addr, ta_ctx->msg, SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); /* Copy in the dcb information if there is any */ - if (sctx->dcb_region) { + if (ta_ctx->dcb_region) { result = sep_activate_dcb_dmatables_context(sep, - &sctx->dcb_region, &sctx->dmatables_region, - sctx->dma_ctx); + &ta_ctx->dcb_region, &ta_ctx->dmatables_region, + ta_ctx->dma_ctx); if (result) return result; } /* Mark the device so we know how to finish the job in the tasklet */ - if (sctx->current_hash_req) - sep->current_hash_req = sctx->current_hash_req; + if (ta_ctx->current_hash_req) + sep->current_hash_req = ta_ctx->current_hash_req; else - sep->current_cypher_req = sctx->current_cypher_req; + sep->current_cypher_req = ta_ctx->current_cypher_req; - sep->current_request = sctx->current_request; - sep->current_hash_stage = sctx->current_hash_stage; - sep->sctx = sctx; + sep->current_request = ta_ctx->current_request; + sep->current_hash_stage = ta_ctx->current_hash_stage; + sep->ta_ctx = ta_ctx; sep->in_kernel = 1; - sctx->i_own_sep = 1; + ta_ctx->i_own_sep = 1; + + /* need to set bit first to avoid race condition with interrupt */ + set_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET, &ta_ctx->call_status.status); result = sep_send_command_handler(sep); dev_dbg(&sep->pdev->dev, "[PID%d]: sending command to the sep\n", current->pid); - if (!result) { - set_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET, - &sctx->call_status.status); + if (!result) dev_dbg(&sep->pdev->dev, "[PID%d]: command sent okay\n", current->pid); + else { + dev_dbg(&sep->pdev->dev, "[PID%d]: cant send command\n", + current->pid); + clear_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET, + &ta_ctx->call_status.status); } return result; } -/* This needs to be run as a work queue as it can be put asleep */ -static void sep_crypto_block(void *data) +/** + * This function sets things up for a crypto data block process + * This does all preparation, but does not try to grab the + * sep + * @req: pointer to struct ablkcipher_request + * returns: 0 if all went well, non zero if error + */ +static int sep_crypto_block_data(struct ablkcipher_request *req) { + int int_error; u32 msg_offset; static u32 msg[10]; @@ -1085,318 +1172,440 @@ static void sep_crypto_block(void *data) ssize_t copy_result; int result; - u32 max_length; struct scatterlist *new_sg; - struct ablkcipher_request *req; - struct sep_block_ctx *bctx; + struct this_task_ctx *ta_ctx; struct crypto_ablkcipher *tfm; struct sep_system_ctx *sctx; - req = (struct ablkcipher_request *)data; - bctx = ablkcipher_request_ctx(req); + struct sep_des_internal_context *des_internal; + struct sep_aes_internal_context *aes_internal; + + ta_ctx = ablkcipher_request_ctx(req); tfm = crypto_ablkcipher_reqtfm(req); sctx = crypto_ablkcipher_ctx(tfm); /* start the walk on scatterlists */ - ablkcipher_walk_init(&bctx->walk, req->src, req->dst, req->nbytes); - dev_dbg(&sctx->sep_used->pdev->dev, "sep crypto block data size of %x\n", + ablkcipher_walk_init(&ta_ctx->walk, req->src, req->dst, req->nbytes); + dev_dbg(&ta_ctx->sep_used->pdev->dev, "sep crypto block data size of %x\n", req->nbytes); - int_error = ablkcipher_walk_phys(req, &bctx->walk); + int_error = ablkcipher_walk_phys(req, &ta_ctx->walk); if (int_error) { - dev_warn(&sctx->sep_used->pdev->dev, "walk phys error %x\n", + dev_warn(&ta_ctx->sep_used->pdev->dev, "walk phys error %x\n", int_error); - sep_crypto_release(sctx, -ENOMEM); - return; - } - - /* check iv */ - if (bctx->des_opmode == SEP_DES_CBC) { - if (!bctx->walk.iv) { - dev_warn(&sctx->sep_used->pdev->dev, "no iv found\n"); - sep_crypto_release(sctx, -EINVAL); - return; - } - - memcpy(bctx->iv, bctx->walk.iv, SEP_DES_IV_SIZE_BYTES); - sep_dump(sctx->sep_used, "iv", bctx->iv, SEP_DES_IV_SIZE_BYTES); - } - - if (bctx->aes_opmode == SEP_AES_CBC) { - if (!bctx->walk.iv) { - dev_warn(&sctx->sep_used->pdev->dev, "no iv found\n"); - sep_crypto_release(sctx, -EINVAL); - return; - } - - memcpy(bctx->iv, bctx->walk.iv, SEP_AES_IV_SIZE_BYTES); - sep_dump(sctx->sep_used, "iv", bctx->iv, SEP_AES_IV_SIZE_BYTES); + return -ENOMEM; } - dev_dbg(&sctx->sep_used->pdev->dev, + dev_dbg(&ta_ctx->sep_used->pdev->dev, "crypto block: src is %lx dst is %lx\n", (unsigned long)req->src, (unsigned long)req->dst); /* Make sure all pages are even block */ - int_error = sep_oddball_pages(sctx->sep_used, req->src, - req->nbytes, bctx->walk.blocksize, &new_sg, 1); + int_error = sep_oddball_pages(ta_ctx->sep_used, req->src, + req->nbytes, ta_ctx->walk.blocksize, &new_sg, 1); if (int_error < 0) { - dev_warn(&sctx->sep_used->pdev->dev, "oddball page eerror\n"); - sep_crypto_release(sctx, -ENOMEM); - return; + dev_warn(&ta_ctx->sep_used->pdev->dev, "oddball page eerror\n"); + return -ENOMEM; } else if (int_error == 1) { - sctx->src_sg = new_sg; - sctx->src_sg_hold = new_sg; + ta_ctx->src_sg = new_sg; + ta_ctx->src_sg_hold = new_sg; } else { - sctx->src_sg = req->src; - sctx->src_sg_hold = NULL; + ta_ctx->src_sg = req->src; + ta_ctx->src_sg_hold = NULL; } - int_error = sep_oddball_pages(sctx->sep_used, req->dst, - req->nbytes, bctx->walk.blocksize, &new_sg, 0); + int_error = sep_oddball_pages(ta_ctx->sep_used, req->dst, + req->nbytes, ta_ctx->walk.blocksize, &new_sg, 0); if (int_error < 0) { - dev_warn(&sctx->sep_used->pdev->dev, "walk phys error %x\n", + dev_warn(&ta_ctx->sep_used->pdev->dev, "walk phys error %x\n", int_error); - sep_crypto_release(sctx, -ENOMEM); - return; + return -ENOMEM; } else if (int_error == 1) { - sctx->dst_sg = new_sg; - sctx->dst_sg_hold = new_sg; + ta_ctx->dst_sg = new_sg; + ta_ctx->dst_sg_hold = new_sg; } else { - sctx->dst_sg = req->dst; - sctx->dst_sg_hold = NULL; + ta_ctx->dst_sg = req->dst; + ta_ctx->dst_sg_hold = NULL; } - /* Do we need to perform init; ie; send key to sep? */ - if (sctx->key_sent == 0) { + /* set nbytes for queue status */ + ta_ctx->nbytes = req->nbytes; - dev_dbg(&sctx->sep_used->pdev->dev, "sending key\n"); + /* Key already done; this is for data */ + dev_dbg(&ta_ctx->sep_used->pdev->dev, "sending data\n"); - /* put together message to SEP */ - /* Start with op code */ - sep_make_header(sctx, &msg_offset, bctx->init_opcode); + sep_dump_sg(ta_ctx->sep_used, + "block sg in", ta_ctx->src_sg); - /* now deal with IV */ - if (bctx->init_opcode == SEP_DES_INIT_OPCODE) { - if (bctx->des_opmode == SEP_DES_CBC) { - sep_write_msg(sctx, bctx->iv, - SEP_DES_IV_SIZE_BYTES, sizeof(u32) * 4, - &msg_offset, 1); - sep_dump(sctx->sep_used, "initial IV", - bctx->walk.iv, SEP_DES_IV_SIZE_BYTES); - } else { - /* Skip if ECB */ - msg_offset += 4 * sizeof(u32); - } - } else { - max_length = ((SEP_AES_IV_SIZE_BYTES + 3) / - sizeof(u32)) * sizeof(u32); - if (bctx->aes_opmode == SEP_AES_CBC) { - sep_write_msg(sctx, bctx->iv, - SEP_AES_IV_SIZE_BYTES, max_length, - &msg_offset, 1); - sep_dump(sctx->sep_used, "initial IV", - bctx->walk.iv, SEP_AES_IV_SIZE_BYTES); - } else { - /* Skip if ECB */ - msg_offset += max_length; - } - } + /* check for valid data and proper spacing */ + src_ptr = sg_virt(ta_ctx->src_sg); + dst_ptr = sg_virt(ta_ctx->dst_sg); - /* load the key */ - if (bctx->init_opcode == SEP_DES_INIT_OPCODE) { - sep_write_msg(sctx, (void *)&sctx->key.des.key1, - sizeof(u32) * 8, sizeof(u32) * 8, - &msg_offset, 1); + if (!src_ptr || !dst_ptr || + (ta_ctx->current_cypher_req->nbytes % + crypto_ablkcipher_blocksize(tfm))) { + + dev_warn(&ta_ctx->sep_used->pdev->dev, + "cipher block size odd\n"); + dev_warn(&ta_ctx->sep_used->pdev->dev, + "cipher block size is %x\n", + crypto_ablkcipher_blocksize(tfm)); + dev_warn(&ta_ctx->sep_used->pdev->dev, + "cipher data size is %x\n", + ta_ctx->current_cypher_req->nbytes); + return -EINVAL; + } - msg[0] = (u32)sctx->des_nbr_keys; - msg[1] = (u32)bctx->des_encmode; - msg[2] = (u32)bctx->des_opmode; + if (partial_overlap(src_ptr, dst_ptr, + ta_ctx->current_cypher_req->nbytes)) { + dev_warn(&ta_ctx->sep_used->pdev->dev, + "block partial overlap\n"); + return -EINVAL; + } - sep_write_msg(sctx, (void *)msg, - sizeof(u32) * 3, sizeof(u32) * 3, - &msg_offset, 0); - } else { - sep_write_msg(sctx, (void *)&sctx->key.aes, - sctx->keylen, - SEP_AES_MAX_KEY_SIZE_BYTES, - &msg_offset, 1); + /* Put together the message */ + sep_make_header(ta_ctx, &msg_offset, ta_ctx->block_opcode); + + /* If des, and size is 1 block, put directly in msg */ + if ((ta_ctx->block_opcode == SEP_DES_BLOCK_OPCODE) && + (req->nbytes == crypto_ablkcipher_blocksize(tfm))) { + + dev_dbg(&ta_ctx->sep_used->pdev->dev, + "writing out one block des\n"); + + copy_result = sg_copy_to_buffer( + ta_ctx->src_sg, sep_sg_nents(ta_ctx->src_sg), + small_buf, crypto_ablkcipher_blocksize(tfm)); - msg[0] = (u32)sctx->aes_key_size; - msg[1] = (u32)bctx->aes_encmode; - msg[2] = (u32)bctx->aes_opmode; - msg[3] = (u32)0; /* Secret key is not used */ - sep_write_msg(sctx, (void *)msg, - sizeof(u32) * 4, sizeof(u32) * 4, - &msg_offset, 0); + if (copy_result != crypto_ablkcipher_blocksize(tfm)) { + dev_warn(&ta_ctx->sep_used->pdev->dev, + "des block copy faild\n"); + return -ENOMEM; } + /* Put data into message */ + sep_write_msg(ta_ctx, small_buf, + crypto_ablkcipher_blocksize(tfm), + crypto_ablkcipher_blocksize(tfm) * 2, + &msg_offset, 1); + + /* Put size into message */ + sep_write_msg(ta_ctx, &req->nbytes, + sizeof(u32), sizeof(u32), &msg_offset, 0); } else { + /* Otherwise, fill out dma tables */ + ta_ctx->dcb_input_data.app_in_address = src_ptr; + ta_ctx->dcb_input_data.data_in_size = req->nbytes; + ta_ctx->dcb_input_data.app_out_address = dst_ptr; + ta_ctx->dcb_input_data.block_size = + crypto_ablkcipher_blocksize(tfm); + ta_ctx->dcb_input_data.tail_block_size = 0; + ta_ctx->dcb_input_data.is_applet = 0; + ta_ctx->dcb_input_data.src_sg = ta_ctx->src_sg; + ta_ctx->dcb_input_data.dst_sg = ta_ctx->dst_sg; + + result = sep_create_dcb_dmatables_context_kernel( + ta_ctx->sep_used, + &ta_ctx->dcb_region, + &ta_ctx->dmatables_region, + &ta_ctx->dma_ctx, + &ta_ctx->dcb_input_data, + 1); + if (result) { + dev_warn(&ta_ctx->sep_used->pdev->dev, + "crypto dma table create failed\n"); + return -EINVAL; + } + + /* Portion of msg is nulled (no data) */ + msg[0] = (u32)0; + msg[1] = (u32)0; + msg[2] = (u32)0; + msg[3] = (u32)0; + msg[4] = (u32)0; + sep_write_msg(ta_ctx, (void *)msg, sizeof(u32) * 5, + sizeof(u32) * 5, &msg_offset, 0); + } - /* set nbytes for queue status */ - sctx->nbytes = req->nbytes; + /** + * Before we write the message, we need to overwrite the + * vendor's IV with the one from our own ablkcipher walk + * iv because this is needed for dm-crypt + */ + sep_dump_ivs(req, "sending data block to sep\n"); + if ((ta_ctx->current_request == DES_CBC) && + (ta_ctx->des_opmode == SEP_DES_CBC)) { + + dev_dbg(&ta_ctx->sep_used->pdev->dev, + "overwrite vendor iv on DES\n"); + des_internal = (struct sep_des_internal_context *) + sctx->des_private_ctx.ctx_buf; + memcpy((void *)des_internal->iv_context, + ta_ctx->walk.iv, crypto_ablkcipher_ivsize(tfm)); + } else if ((ta_ctx->current_request == AES_CBC) && + (ta_ctx->aes_opmode == SEP_AES_CBC)) { + + dev_dbg(&ta_ctx->sep_used->pdev->dev, + "overwrite vendor iv on AES\n"); + aes_internal = (struct sep_aes_internal_context *) + sctx->aes_private_ctx.cbuff; + memcpy((void *)aes_internal->aes_ctx_iv, + ta_ctx->walk.iv, crypto_ablkcipher_ivsize(tfm)); + } + + /* Write context into message */ + if (ta_ctx->block_opcode == SEP_DES_BLOCK_OPCODE) { + sep_write_context(ta_ctx, &msg_offset, + &sctx->des_private_ctx, + sizeof(struct sep_des_private_context)); + sep_dump(ta_ctx->sep_used, "ctx to block des", + &sctx->des_private_ctx, 40); + } else { + sep_write_context(ta_ctx, &msg_offset, + &sctx->aes_private_ctx, + sizeof(struct sep_aes_private_context)); + sep_dump(ta_ctx->sep_used, "ctx to block aes", + &sctx->aes_private_ctx, 20); + } - /* Key already done; this is for data */ - dev_dbg(&sctx->sep_used->pdev->dev, "sending data\n"); + /* conclude message */ + sep_end_msg(ta_ctx, msg_offset); - sep_dump_sg(sctx->sep_used, - "block sg in", sctx->src_sg); + /* Parent (caller) is now ready to tell the sep to do ahead */ + return 0; +} - /* check for valid data and proper spacing */ - src_ptr = sg_virt(sctx->src_sg); - dst_ptr = sg_virt(sctx->dst_sg); - if (!src_ptr || !dst_ptr || - (sctx->current_cypher_req->nbytes % - crypto_ablkcipher_blocksize(tfm))) { +/** + * This function sets things up for a crypto key submit process + * This does all preparation, but does not try to grab the + * sep + * @req: pointer to struct ablkcipher_request + * returns: 0 if all went well, non zero if error + */ +static int sep_crypto_send_key(struct ablkcipher_request *req) +{ - dev_warn(&sctx->sep_used->pdev->dev, - "cipher block size odd\n"); - dev_warn(&sctx->sep_used->pdev->dev, - "cipher block size is %x\n", - crypto_ablkcipher_blocksize(tfm)); - dev_warn(&sctx->sep_used->pdev->dev, - "cipher data size is %x\n", - sctx->current_cypher_req->nbytes); - sep_crypto_release(sctx, -EINVAL); - return; - } + int int_error; + u32 msg_offset; + static u32 msg[10]; - if (partial_overlap(src_ptr, dst_ptr, - sctx->current_cypher_req->nbytes)) { - dev_warn(&sctx->sep_used->pdev->dev, - "block partial overlap\n"); - sep_crypto_release(sctx, -EINVAL); - return; - } + u32 max_length; + struct this_task_ctx *ta_ctx; + struct crypto_ablkcipher *tfm; + struct sep_system_ctx *sctx; - /* Put together the message */ - sep_make_header(sctx, &msg_offset, bctx->block_opcode); + ta_ctx = ablkcipher_request_ctx(req); + tfm = crypto_ablkcipher_reqtfm(req); + sctx = crypto_ablkcipher_ctx(tfm); - /* If des, and size is 1 block, put directly in msg */ - if ((bctx->block_opcode == SEP_DES_BLOCK_OPCODE) && - (req->nbytes == crypto_ablkcipher_blocksize(tfm))) { + dev_dbg(&ta_ctx->sep_used->pdev->dev, "sending key\n"); - dev_dbg(&sctx->sep_used->pdev->dev, - "writing out one block des\n"); + /* start the walk on scatterlists */ + ablkcipher_walk_init(&ta_ctx->walk, req->src, req->dst, req->nbytes); + dev_dbg(&ta_ctx->sep_used->pdev->dev, + "sep crypto block data size of %x\n", req->nbytes); - copy_result = sg_copy_to_buffer( - sctx->src_sg, sep_sg_nents(sctx->src_sg), - small_buf, crypto_ablkcipher_blocksize(tfm)); + int_error = ablkcipher_walk_phys(req, &ta_ctx->walk); + if (int_error) { + dev_warn(&ta_ctx->sep_used->pdev->dev, "walk phys error %x\n", + int_error); + return -ENOMEM; + } - if (copy_result != crypto_ablkcipher_blocksize(tfm)) { - dev_warn(&sctx->sep_used->pdev->dev, - "des block copy faild\n"); - sep_crypto_release(sctx, -ENOMEM); - return; - } + /* check iv */ + if ((ta_ctx->current_request == DES_CBC) && + (ta_ctx->des_opmode == SEP_DES_CBC)) { + if (!ta_ctx->walk.iv) { + dev_warn(&ta_ctx->sep_used->pdev->dev, "no iv found\n"); + return -EINVAL; + } - /* Put data into message */ - sep_write_msg(sctx, small_buf, - crypto_ablkcipher_blocksize(tfm), - crypto_ablkcipher_blocksize(tfm) * 2, - &msg_offset, 1); + memcpy(ta_ctx->iv, ta_ctx->walk.iv, SEP_DES_IV_SIZE_BYTES); + sep_dump(ta_ctx->sep_used, "iv", + ta_ctx->iv, SEP_DES_IV_SIZE_BYTES); + } - /* Put size into message */ - sep_write_msg(sctx, &req->nbytes, - sizeof(u32), sizeof(u32), &msg_offset, 0); + if ((ta_ctx->current_request == AES_CBC) && + (ta_ctx->aes_opmode == SEP_AES_CBC)) { + if (!ta_ctx->walk.iv) { + dev_warn(&ta_ctx->sep_used->pdev->dev, "no iv found\n"); + return -EINVAL; + } + + memcpy(ta_ctx->iv, ta_ctx->walk.iv, SEP_AES_IV_SIZE_BYTES); + sep_dump(ta_ctx->sep_used, "iv", + ta_ctx->iv, SEP_AES_IV_SIZE_BYTES); + } + + /* put together message to SEP */ + /* Start with op code */ + sep_make_header(ta_ctx, &msg_offset, ta_ctx->init_opcode); + + /* now deal with IV */ + if (ta_ctx->init_opcode == SEP_DES_INIT_OPCODE) { + if (ta_ctx->des_opmode == SEP_DES_CBC) { + sep_write_msg(ta_ctx, ta_ctx->iv, + SEP_DES_IV_SIZE_BYTES, sizeof(u32) * 4, + &msg_offset, 1); + sep_dump(ta_ctx->sep_used, "initial IV", + ta_ctx->walk.iv, SEP_DES_IV_SIZE_BYTES); + } else { + /* Skip if ECB */ + msg_offset += 4 * sizeof(u32); + } + } else { + max_length = ((SEP_AES_IV_SIZE_BYTES + 3) / + sizeof(u32)) * sizeof(u32); + if (ta_ctx->aes_opmode == SEP_AES_CBC) { + sep_write_msg(ta_ctx, ta_ctx->iv, + SEP_AES_IV_SIZE_BYTES, max_length, + &msg_offset, 1); + sep_dump(ta_ctx->sep_used, "initial IV", + ta_ctx->walk.iv, SEP_AES_IV_SIZE_BYTES); } else { - /* Otherwise, fill out dma tables */ - sctx->dcb_input_data.app_in_address = src_ptr; - sctx->dcb_input_data.data_in_size = req->nbytes; - sctx->dcb_input_data.app_out_address = dst_ptr; - sctx->dcb_input_data.block_size = - crypto_ablkcipher_blocksize(tfm); - sctx->dcb_input_data.tail_block_size = 0; - sctx->dcb_input_data.is_applet = 0; - sctx->dcb_input_data.src_sg = sctx->src_sg; - sctx->dcb_input_data.dst_sg = sctx->dst_sg; - - result = sep_create_dcb_dmatables_context_kernel( - sctx->sep_used, - &sctx->dcb_region, - &sctx->dmatables_region, - &sctx->dma_ctx, - &sctx->dcb_input_data, - 1); - if (result) { - dev_warn(&sctx->sep_used->pdev->dev, - "crypto dma table create failed\n"); - sep_crypto_release(sctx, -EINVAL); - return; + /* Skip if ECB */ + msg_offset += max_length; } + } + + /* load the key */ + if (ta_ctx->init_opcode == SEP_DES_INIT_OPCODE) { + sep_write_msg(ta_ctx, (void *)&sctx->key.des.key1, + sizeof(u32) * 8, sizeof(u32) * 8, + &msg_offset, 1); + + msg[0] = (u32)sctx->des_nbr_keys; + msg[1] = (u32)ta_ctx->des_encmode; + msg[2] = (u32)ta_ctx->des_opmode; - /* Portion of msg is nulled (no data) */ - msg[0] = (u32)0; - msg[1] = (u32)0; - msg[2] = (u32)0; - msg[3] = (u32)0; - msg[4] = (u32)0; - sep_write_msg(sctx, (void *)msg, - sizeof(u32) * 5, - sizeof(u32) * 5, - &msg_offset, 0); + sep_write_msg(ta_ctx, (void *)msg, + sizeof(u32) * 3, sizeof(u32) * 3, + &msg_offset, 0); + } else { + sep_write_msg(ta_ctx, (void *)&sctx->key.aes, + sctx->keylen, + SEP_AES_MAX_KEY_SIZE_BYTES, + &msg_offset, 1); + + msg[0] = (u32)sctx->aes_key_size; + msg[1] = (u32)ta_ctx->aes_encmode; + msg[2] = (u32)ta_ctx->aes_opmode; + msg[3] = (u32)0; /* Secret key is not used */ + sep_write_msg(ta_ctx, (void *)msg, + sizeof(u32) * 4, sizeof(u32) * 4, + &msg_offset, 0); + } + + /* conclude message */ + sep_end_msg(ta_ctx, msg_offset); + + /* Parent (caller) is now ready to tell the sep to do ahead */ + return 0; +} + + +/* This needs to be run as a work queue as it can be put asleep */ +static void sep_crypto_block(void *data) +{ + unsigned long end_time; + + int result; + + struct ablkcipher_request *req; + struct this_task_ctx *ta_ctx; + struct crypto_ablkcipher *tfm; + struct sep_system_ctx *sctx; + int are_we_done_yet; + + req = (struct ablkcipher_request *)data; + ta_ctx = ablkcipher_request_ctx(req); + tfm = crypto_ablkcipher_reqtfm(req); + sctx = crypto_ablkcipher_ctx(tfm); + + ta_ctx->are_we_done_yet = &are_we_done_yet; + + pr_debug("sep_crypto_block\n"); + pr_debug("tfm is %p sctx is %p ta_ctx is %p\n", + tfm, sctx, ta_ctx); + pr_debug("key_sent is %d\n", sctx->key_sent); + + /* do we need to send the key */ + if (sctx->key_sent == 0) { + are_we_done_yet = 0; + result = sep_crypto_send_key(req); /* prep to send key */ + if (result != 0) { + dev_dbg(&ta_ctx->sep_used->pdev->dev, + "could not prep key %x\n", result); + sep_crypto_release(sctx, ta_ctx, result); + return; } - /* Write context into message */ - if (bctx->block_opcode == SEP_DES_BLOCK_OPCODE) { - sep_write_context(sctx, &msg_offset, - &bctx->des_private_ctx, - sizeof(struct sep_des_private_context)); - sep_dump(sctx->sep_used, "ctx to block des", - &bctx->des_private_ctx, 40); - } else { - sep_write_context(sctx, &msg_offset, - &bctx->aes_private_ctx, - sizeof(struct sep_aes_private_context)); - sep_dump(sctx->sep_used, "ctx to block aes", - &bctx->aes_private_ctx, 20); + result = sep_crypto_take_sep(ta_ctx); + if (result) { + dev_warn(&ta_ctx->sep_used->pdev->dev, + "sep_crypto_take_sep for key send failed\n"); + sep_crypto_release(sctx, ta_ctx, result); + return; + } + + /* now we sit and wait up to a fixed time for completion */ + end_time = jiffies + (WAIT_TIME * HZ); + while ((time_before(jiffies, end_time)) && + (are_we_done_yet == 0)) + schedule(); + + /* Done waiting; still not done yet? */ + if (are_we_done_yet == 0) { + dev_dbg(&ta_ctx->sep_used->pdev->dev, + "Send key job never got done\n"); + sep_crypto_release(sctx, ta_ctx, -EINVAL); + return; } + + /* Set the key sent variable so this can be skipped later */ + sctx->key_sent = 1; } - /* conclude message and then tell sep to do its thing */ - sctx->done_with_transaction = 0; + /* Key sent (or maybe not if we did not have to), now send block */ + are_we_done_yet = 0; - sep_end_msg(sctx, msg_offset); - result = sep_crypto_take_sep(sctx); - if (result) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep_crypto_take_sep failed\n"); - sep_crypto_release(sctx, -EINVAL); + result = sep_crypto_block_data(req); + + if (result != 0) { + dev_dbg(&ta_ctx->sep_used->pdev->dev, + "could prep not send block %x\n", result); + sep_crypto_release(sctx, ta_ctx, result); return; } - /** - * Sep is now working. Lets wait up to 5 seconds - * for completion. If it does not complete, we will do - * a crypto release with -EINVAL to release the - * kernel crypto infrastructure and let the system - * continue to boot up - * We have to wait this long because some crypto - * operations can take a while - */ - - dev_dbg(&sctx->sep_used->pdev->dev, - "waiting for done with transaction\n"); + result = sep_crypto_take_sep(ta_ctx); + if (result) { + dev_warn(&ta_ctx->sep_used->pdev->dev, + "sep_crypto_take_sep for block send failed\n"); + sep_crypto_release(sctx, ta_ctx, result); + return; + } - sctx->end_time = jiffies + (SEP_TRANSACTION_WAIT_TIME * HZ); - while ((time_before(jiffies, sctx->end_time)) && - (!sctx->done_with_transaction)) + /* now we sit and wait up to a fixed time for completion */ + end_time = jiffies + (WAIT_TIME * HZ); + while ((time_before(jiffies, end_time)) && (are_we_done_yet == 0)) schedule(); - dev_dbg(&sctx->sep_used->pdev->dev, - "done waiting for done with transaction\n"); - - /* are we done? */ - if (!sctx->done_with_transaction) { - /* Nope, lets release and tell crypto no */ - dev_warn(&sctx->sep_used->pdev->dev, - "[PID%d] sep_crypto_block never finished\n", - current->pid); - sep_crypto_release(sctx, -EINVAL); + /* Done waiting; still not done yet? */ + if (are_we_done_yet == 0) { + dev_dbg(&ta_ctx->sep_used->pdev->dev, + "Send block job never got done\n"); + sep_crypto_release(sctx, ta_ctx, -EINVAL); + return; } + + /* That's it; entire thing done, get out of queue */ + + pr_debug("crypto_block leaving\n"); + pr_debug("tfm is %p sctx is %p ta_ctx is %p\n", tfm, sctx, ta_ctx); } /** @@ -1405,7 +1614,6 @@ static void sep_crypto_block(void *data) static u32 crypto_post_op(struct sep_device *sep) { /* HERE */ - int int_error; u32 u32_error; u32 msg_offset; @@ -1413,169 +1621,185 @@ static u32 crypto_post_op(struct sep_device *sep) static char small_buf[100]; struct ablkcipher_request *req; - struct sep_block_ctx *bctx; + struct this_task_ctx *ta_ctx; struct sep_system_ctx *sctx; struct crypto_ablkcipher *tfm; + struct sep_des_internal_context *des_internal; + struct sep_aes_internal_context *aes_internal; + if (!sep->current_cypher_req) return -EINVAL; /* hold req since we need to submit work after clearing sep */ req = sep->current_cypher_req; - bctx = ablkcipher_request_ctx(sep->current_cypher_req); + ta_ctx = ablkcipher_request_ctx(sep->current_cypher_req); tfm = crypto_ablkcipher_reqtfm(sep->current_cypher_req); sctx = crypto_ablkcipher_ctx(tfm); - dev_dbg(&sctx->sep_used->pdev->dev, "crypto post_op\n"); - dev_dbg(&sctx->sep_used->pdev->dev, "crypto post_op message dump\n"); - crypto_sep_dump_message(sctx); + pr_debug("crypto_post op\n"); + pr_debug("key_sent is %d tfm is %p sctx is %p ta_ctx is %p\n", + sctx->key_sent, tfm, sctx, ta_ctx); - sctx->done_with_transaction = 1; + dev_dbg(&ta_ctx->sep_used->pdev->dev, "crypto post_op\n"); + dev_dbg(&ta_ctx->sep_used->pdev->dev, "crypto post_op message dump\n"); + crypto_sep_dump_message(ta_ctx->sep_used, ta_ctx->msg); /* first bring msg from shared area to local area */ - memcpy(sctx->msg, sep->shared_addr, + memcpy(ta_ctx->msg, sep->shared_addr, SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); /* Is this the result of performing init (key to SEP */ if (sctx->key_sent == 0) { /* Did SEP do it okay */ - u32_error = sep_verify_op(sctx, bctx->init_opcode, + u32_error = sep_verify_op(ta_ctx, ta_ctx->init_opcode, &msg_offset); if (u32_error) { - dev_warn(&sctx->sep_used->pdev->dev, + dev_warn(&ta_ctx->sep_used->pdev->dev, "aes init error %x\n", u32_error); - sep_crypto_release(sctx, u32_error); + sep_crypto_release(sctx, ta_ctx, u32_error); return u32_error; } /* Read Context */ - if (bctx->init_opcode == SEP_DES_INIT_OPCODE) { - sep_read_context(sctx, &msg_offset, - &bctx->des_private_ctx, + if (ta_ctx->init_opcode == SEP_DES_INIT_OPCODE) { + sep_read_context(ta_ctx, &msg_offset, + &sctx->des_private_ctx, sizeof(struct sep_des_private_context)); - sep_dump(sctx->sep_used, "ctx init des", - &bctx->des_private_ctx, 40); + sep_dump(ta_ctx->sep_used, "ctx init des", + &sctx->des_private_ctx, 40); } else { - sep_read_context(sctx, &msg_offset, - &bctx->aes_private_ctx, - sizeof(struct sep_des_private_context)); - - sep_dump(sctx->sep_used, "ctx init aes", - &bctx->aes_private_ctx, 20); - } - - /* We are done with init. Now send out the data */ - /* first release the sep */ - sctx->key_sent = 1; - sep_crypto_release(sctx, -EINPROGRESS); + sep_read_context(ta_ctx, &msg_offset, + &sctx->aes_private_ctx, + sizeof(struct sep_aes_private_context)); - spin_lock_irq(&queue_lock); - int_error = crypto_enqueue_request(&sep_queue, &req->base); - spin_unlock_irq(&queue_lock); - - if ((int_error != 0) && (int_error != -EINPROGRESS)) { - dev_warn(&sctx->sep_used->pdev->dev, - "spe cypher post op cant queue\n"); - sep_crypto_release(sctx, int_error); - return int_error; + sep_dump(ta_ctx->sep_used, "ctx init aes", + &sctx->aes_private_ctx, 20); } - /* schedule the data send */ - int_error = sep_submit_work(sep->workqueue, sep_dequeuer, - (void *)&sep_queue); + sep_dump_ivs(req, "after sending key to sep\n"); - if (int_error) { - dev_warn(&sep->pdev->dev, - "cant submit work sep_crypto_block\n"); - sep_crypto_release(sctx, -EINVAL); - return -EINVAL; - } + /* key sent went okay; release sep, and set are_we_done_yet */ + sctx->key_sent = 1; + sep_crypto_release(sctx, ta_ctx, -EINPROGRESS); } else { /** * This is the result of a block request */ - dev_dbg(&sctx->sep_used->pdev->dev, + dev_dbg(&ta_ctx->sep_used->pdev->dev, "crypto_post_op block response\n"); - u32_error = sep_verify_op(sctx, bctx->block_opcode, + u32_error = sep_verify_op(ta_ctx, ta_ctx->block_opcode, &msg_offset); if (u32_error) { - dev_warn(&sctx->sep_used->pdev->dev, + dev_warn(&ta_ctx->sep_used->pdev->dev, "sep block error %x\n", u32_error); - sep_crypto_release(sctx, u32_error); + sep_crypto_release(sctx, ta_ctx, u32_error); return -EINVAL; } - if (bctx->block_opcode == SEP_DES_BLOCK_OPCODE) { + if (ta_ctx->block_opcode == SEP_DES_BLOCK_OPCODE) { - dev_dbg(&sctx->sep_used->pdev->dev, + dev_dbg(&ta_ctx->sep_used->pdev->dev, "post op for DES\n"); /* special case for 1 block des */ if (sep->current_cypher_req->nbytes == crypto_ablkcipher_blocksize(tfm)) { - sep_read_msg(sctx, small_buf, + sep_read_msg(ta_ctx, small_buf, crypto_ablkcipher_blocksize(tfm), crypto_ablkcipher_blocksize(tfm) * 2, &msg_offset, 1); - dev_dbg(&sctx->sep_used->pdev->dev, + dev_dbg(&ta_ctx->sep_used->pdev->dev, "reading in block des\n"); copy_result = sg_copy_from_buffer( - sctx->dst_sg, - sep_sg_nents(sctx->dst_sg), + ta_ctx->dst_sg, + sep_sg_nents(ta_ctx->dst_sg), small_buf, crypto_ablkcipher_blocksize(tfm)); if (copy_result != crypto_ablkcipher_blocksize(tfm)) { - dev_warn(&sctx->sep_used->pdev->dev, + dev_warn(&ta_ctx->sep_used->pdev->dev, "des block copy faild\n"); - sep_crypto_release(sctx, -ENOMEM); + sep_crypto_release(sctx, ta_ctx, + -ENOMEM); return -ENOMEM; } } /* Read Context */ - sep_read_context(sctx, &msg_offset, - &bctx->des_private_ctx, + sep_read_context(ta_ctx, &msg_offset, + &sctx->des_private_ctx, sizeof(struct sep_des_private_context)); } else { - dev_dbg(&sctx->sep_used->pdev->dev, + dev_dbg(&ta_ctx->sep_used->pdev->dev, "post op for AES\n"); /* Skip the MAC Output */ msg_offset += (sizeof(u32) * 4); /* Read Context */ - sep_read_context(sctx, &msg_offset, - &bctx->aes_private_ctx, + sep_read_context(ta_ctx, &msg_offset, + &sctx->aes_private_ctx, sizeof(struct sep_aes_private_context)); } - sep_dump_sg(sctx->sep_used, - "block sg out", sctx->dst_sg); + sep_dump_sg(ta_ctx->sep_used, + "block sg out", ta_ctx->dst_sg); /* Copy to correct sg if this block had oddball pages */ - if (sctx->dst_sg_hold) - sep_copy_sg(sctx->sep_used, - sctx->dst_sg, - sctx->current_cypher_req->dst, - sctx->current_cypher_req->nbytes); + if (ta_ctx->dst_sg_hold) + sep_copy_sg(ta_ctx->sep_used, + ta_ctx->dst_sg, + ta_ctx->current_cypher_req->dst, + ta_ctx->current_cypher_req->nbytes); + + /** + * Copy the iv's back to the walk.iv + * This is required for dm_crypt + */ + sep_dump_ivs(req, "got data block from sep\n"); + if ((ta_ctx->current_request == DES_CBC) && + (ta_ctx->des_opmode == SEP_DES_CBC)) { + + dev_dbg(&ta_ctx->sep_used->pdev->dev, + "returning result iv to walk on DES\n"); + des_internal = (struct sep_des_internal_context *) + sctx->des_private_ctx.ctx_buf; + memcpy(ta_ctx->walk.iv, + (void *)des_internal->iv_context, + crypto_ablkcipher_ivsize(tfm)); + } else if ((ta_ctx->current_request == AES_CBC) && + (ta_ctx->aes_opmode == SEP_AES_CBC)) { + + dev_dbg(&ta_ctx->sep_used->pdev->dev, + "returning result iv to walk on AES\n"); + aes_internal = (struct sep_aes_internal_context *) + sctx->aes_private_ctx.cbuff; + memcpy(ta_ctx->walk.iv, + (void *)aes_internal->aes_ctx_iv, + crypto_ablkcipher_ivsize(tfm)); + } /* finished, release everything */ - sep_crypto_release(sctx, 0); + sep_crypto_release(sctx, ta_ctx, 0); } + pr_debug("crypto_post_op done\n"); + pr_debug("key_sent is %d tfm is %p sctx is %p ta_ctx is %p\n", + sctx->key_sent, tfm, sctx, ta_ctx); + return 0; } @@ -1584,35 +1808,33 @@ static u32 hash_init_post_op(struct sep_device *sep) u32 u32_error; u32 msg_offset; struct crypto_ahash *tfm = crypto_ahash_reqtfm(sep->current_hash_req); - struct sep_hash_ctx *ctx = ahash_request_ctx(sep->current_hash_req); + struct this_task_ctx *ta_ctx = ahash_request_ctx(sep->current_hash_req); struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); - dev_dbg(&sctx->sep_used->pdev->dev, + dev_dbg(&ta_ctx->sep_used->pdev->dev, "hash init post op\n"); - sctx->done_with_transaction = 1; - /* first bring msg from shared area to local area */ - memcpy(sctx->msg, sep->shared_addr, + memcpy(ta_ctx->msg, sep->shared_addr, SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); - u32_error = sep_verify_op(sctx, SEP_HASH_INIT_OPCODE, + u32_error = sep_verify_op(ta_ctx, SEP_HASH_INIT_OPCODE, &msg_offset); if (u32_error) { - dev_warn(&sctx->sep_used->pdev->dev, "hash init error %x\n", + dev_warn(&ta_ctx->sep_used->pdev->dev, "hash init error %x\n", u32_error); - sep_crypto_release(sctx, u32_error); + sep_crypto_release(sctx, ta_ctx, u32_error); return u32_error; } /* Read Context */ - sep_read_context(sctx, &msg_offset, - &ctx->hash_private_ctx, + sep_read_context(ta_ctx, &msg_offset, + &sctx->hash_private_ctx, sizeof(struct sep_hash_private_context)); /* Signal to crypto infrastructure and clear out */ - dev_dbg(&sctx->sep_used->pdev->dev, "hash init post op done\n"); - sep_crypto_release(sctx, 0); + dev_dbg(&ta_ctx->sep_used->pdev->dev, "hash init post op done\n"); + sep_crypto_release(sctx, ta_ctx, 0); return 0; } @@ -1621,33 +1843,69 @@ static u32 hash_update_post_op(struct sep_device *sep) u32 u32_error; u32 msg_offset; struct crypto_ahash *tfm = crypto_ahash_reqtfm(sep->current_hash_req); - struct sep_hash_ctx *ctx = ahash_request_ctx(sep->current_hash_req); + struct this_task_ctx *ta_ctx = ahash_request_ctx(sep->current_hash_req); struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); - dev_dbg(&sctx->sep_used->pdev->dev, + dev_dbg(&ta_ctx->sep_used->pdev->dev, "hash update post op\n"); - sctx->done_with_transaction = 1; - /* first bring msg from shared area to local area */ - memcpy(sctx->msg, sep->shared_addr, + memcpy(ta_ctx->msg, sep->shared_addr, SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); - u32_error = sep_verify_op(sctx, SEP_HASH_UPDATE_OPCODE, + u32_error = sep_verify_op(ta_ctx, SEP_HASH_UPDATE_OPCODE, &msg_offset); if (u32_error) { - dev_warn(&sctx->sep_used->pdev->dev, "hash init error %x\n", + dev_warn(&ta_ctx->sep_used->pdev->dev, "hash init error %x\n", u32_error); - sep_crypto_release(sctx, u32_error); + sep_crypto_release(sctx, ta_ctx, u32_error); return u32_error; } /* Read Context */ - sep_read_context(sctx, &msg_offset, - &ctx->hash_private_ctx, + sep_read_context(ta_ctx, &msg_offset, + &sctx->hash_private_ctx, sizeof(struct sep_hash_private_context)); - sep_crypto_release(sctx, 0); + /** + * Following is only for finup; if we just completd the + * data portion of finup, we now need to kick off the + * finish portion of finup. + */ + + if (ta_ctx->sep_used->current_hash_stage == HASH_FINUP_DATA) { + + /* first reset stage to HASH_FINUP_FINISH */ + ta_ctx->sep_used->current_hash_stage = HASH_FINUP_FINISH; + + /* now enqueue the finish operation */ + spin_lock_irq(&queue_lock); + u32_error = crypto_enqueue_request(&sep_queue, + &ta_ctx->sep_used->current_hash_req->base); + spin_unlock_irq(&queue_lock); + + if ((u32_error != 0) && (u32_error != -EINPROGRESS)) { + dev_warn(&ta_ctx->sep_used->pdev->dev, + "spe cypher post op cant queue\n"); + sep_crypto_release(sctx, ta_ctx, u32_error); + return u32_error; + } + + /* schedule the data send */ + u32_error = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + + if (u32_error) { + dev_warn(&ta_ctx->sep_used->pdev->dev, + "cant submit work sep_crypto_block\n"); + sep_crypto_release(sctx, ta_ctx, -EINVAL); + return -EINVAL; + } + } + + /* Signal to crypto infrastructure and clear out */ + dev_dbg(&ta_ctx->sep_used->pdev->dev, "hash update post op done\n"); + sep_crypto_release(sctx, ta_ctx, 0); return 0; } @@ -1658,45 +1916,44 @@ static u32 hash_final_post_op(struct sep_device *sep) u32 msg_offset; struct crypto_ahash *tfm = crypto_ahash_reqtfm(sep->current_hash_req); struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); - dev_dbg(&sctx->sep_used->pdev->dev, + struct this_task_ctx *ta_ctx = ahash_request_ctx(sep->current_hash_req); + dev_dbg(&ta_ctx->sep_used->pdev->dev, "hash final post op\n"); - sctx->done_with_transaction = 1; - /* first bring msg from shared area to local area */ - memcpy(sctx->msg, sep->shared_addr, + memcpy(ta_ctx->msg, sep->shared_addr, SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); - u32_error = sep_verify_op(sctx, SEP_HASH_FINISH_OPCODE, + u32_error = sep_verify_op(ta_ctx, SEP_HASH_FINISH_OPCODE, &msg_offset); if (u32_error) { - dev_warn(&sctx->sep_used->pdev->dev, "hash finish error %x\n", + dev_warn(&ta_ctx->sep_used->pdev->dev, "hash finish error %x\n", u32_error); - sep_crypto_release(sctx, u32_error); + sep_crypto_release(sctx, ta_ctx, u32_error); return u32_error; } /* Grab the result */ - if (sctx->current_hash_req->result == NULL) { + if (ta_ctx->current_hash_req->result == NULL) { /* Oops, null buffer; error out here */ - dev_warn(&sctx->sep_used->pdev->dev, + dev_warn(&ta_ctx->sep_used->pdev->dev, "hash finish null buffer\n"); - sep_crypto_release(sctx, (u32)-ENOMEM); + sep_crypto_release(sctx, ta_ctx, (u32)-ENOMEM); return -ENOMEM; } max_length = (((SEP_HASH_RESULT_SIZE_WORDS * sizeof(u32)) + 3) / sizeof(u32)) * sizeof(u32); - sep_read_msg(sctx, - sctx->current_hash_req->result, + sep_read_msg(ta_ctx, + ta_ctx->current_hash_req->result, crypto_ahash_digestsize(tfm), max_length, &msg_offset, 0); /* Signal to crypto infrastructure and clear out */ - dev_dbg(&sctx->sep_used->pdev->dev, "hash finish post op done\n"); - sep_crypto_release(sctx, 0); + dev_dbg(&ta_ctx->sep_used->pdev->dev, "hash finish post op done\n"); + sep_crypto_release(sctx, ta_ctx, 0); return 0; } @@ -1707,48 +1964,47 @@ static u32 hash_digest_post_op(struct sep_device *sep) u32 msg_offset; struct crypto_ahash *tfm = crypto_ahash_reqtfm(sep->current_hash_req); struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); - dev_dbg(&sctx->sep_used->pdev->dev, + struct this_task_ctx *ta_ctx = ahash_request_ctx(sep->current_hash_req); + dev_dbg(&ta_ctx->sep_used->pdev->dev, "hash digest post op\n"); - sctx->done_with_transaction = 1; - /* first bring msg from shared area to local area */ - memcpy(sctx->msg, sep->shared_addr, + memcpy(ta_ctx->msg, sep->shared_addr, SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); - u32_error = sep_verify_op(sctx, SEP_HASH_SINGLE_OPCODE, + u32_error = sep_verify_op(ta_ctx, SEP_HASH_SINGLE_OPCODE, &msg_offset); if (u32_error) { - dev_warn(&sctx->sep_used->pdev->dev, + dev_warn(&ta_ctx->sep_used->pdev->dev, "hash digest finish error %x\n", u32_error); - sep_crypto_release(sctx, u32_error); + sep_crypto_release(sctx, ta_ctx, u32_error); return u32_error; } /* Grab the result */ - if (sctx->current_hash_req->result == NULL) { + if (ta_ctx->current_hash_req->result == NULL) { /* Oops, null buffer; error out here */ - dev_warn(&sctx->sep_used->pdev->dev, + dev_warn(&ta_ctx->sep_used->pdev->dev, "hash digest finish null buffer\n"); - sep_crypto_release(sctx, (u32)-ENOMEM); + sep_crypto_release(sctx, ta_ctx, (u32)-ENOMEM); return -ENOMEM; } max_length = (((SEP_HASH_RESULT_SIZE_WORDS * sizeof(u32)) + 3) / sizeof(u32)) * sizeof(u32); - sep_read_msg(sctx, - sctx->current_hash_req->result, + sep_read_msg(ta_ctx, + ta_ctx->current_hash_req->result, crypto_ahash_digestsize(tfm), max_length, &msg_offset, 0); /* Signal to crypto infrastructure and clear out */ - dev_dbg(&sctx->sep_used->pdev->dev, + dev_dbg(&ta_ctx->sep_used->pdev->dev, "hash digest finish post op done\n"); - sep_crypto_release(sctx, 0); + sep_crypto_release(sctx, ta_ctx, 0); return 0; } @@ -1759,7 +2015,6 @@ static u32 hash_digest_post_op(struct sep_device *sep) */ static void sep_finish(unsigned long data) { - unsigned long flags; struct sep_device *sep_dev; int res; @@ -1776,18 +2031,15 @@ static void sep_finish(unsigned long data) return; } - spin_lock_irqsave(&sep_dev->busy_lock, flags); if (sep_dev->in_kernel == (u32)0) { - spin_unlock_irqrestore(&sep_dev->busy_lock, flags); dev_warn(&sep_dev->pdev->dev, "sep_finish; not in kernel operation\n"); return; } - spin_unlock_irqrestore(&sep_dev->busy_lock, flags); /* Did we really do a sep command prior to this? */ if (0 == test_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET, - &sep_dev->sctx->call_status.status)) { + &sep_dev->ta_ctx->call_status.status)) { dev_warn(&sep_dev->pdev->dev, "[PID%d] sendmsg not called\n", current->pid); @@ -1856,8 +2108,10 @@ static void sep_finish(unsigned long data) res = hash_init_post_op(sep_dev); break; case HASH_UPDATE: + case HASH_FINUP_DATA: res = hash_update_post_op(sep_dev); break; + case HASH_FINUP_FINISH: case HASH_FINISH: res = hash_final_post_op(sep_dev); break; @@ -1865,43 +2119,31 @@ static void sep_finish(unsigned long data) res = hash_digest_post_op(sep_dev); break; default: - dev_warn(&sep_dev->pdev->dev, - "invalid stage for hash finish\n"); + pr_debug("sep - invalid stage for hash finish\n"); } break; default: - dev_warn(&sep_dev->pdev->dev, - "invalid request for finish\n"); + pr_debug("sep - invalid request for finish\n"); } - if (res) { - dev_warn(&sep_dev->pdev->dev, - "finish returned error %x\n", res); - } + if (res) + pr_debug("sep - finish returned error %x\n", res); } static int sep_hash_cra_init(struct crypto_tfm *tfm) { - struct sep_system_ctx *sctx = crypto_tfm_ctx(tfm); const char *alg_name = crypto_tfm_alg_name(tfm); - sctx->sep_used = sep_dev; - - dev_dbg(&sctx->sep_used->pdev->dev, - "sep_hash_cra_init name is %s\n", alg_name); + pr_debug("sep_hash_cra_init name is %s\n", alg_name); crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), - sizeof(struct sep_hash_ctx)); + sizeof(struct this_task_ctx)); return 0; } static void sep_hash_cra_exit(struct crypto_tfm *tfm) { - struct sep_system_ctx *sctx = crypto_tfm_ctx(tfm); - - dev_dbg(&sctx->sep_used->pdev->dev, - "sep_hash_cra_exit\n"); - sctx->sep_used = NULL; + pr_debug("sep_hash_cra_exit\n"); } static void sep_hash_init(void *data) @@ -1910,60 +2152,49 @@ static void sep_hash_init(void *data) int result; struct ahash_request *req; struct crypto_ahash *tfm; - struct sep_hash_ctx *ctx; + struct this_task_ctx *ta_ctx; struct sep_system_ctx *sctx; + unsigned long end_time; + int are_we_done_yet; req = (struct ahash_request *)data; tfm = crypto_ahash_reqtfm(req); - ctx = ahash_request_ctx(req); sctx = crypto_ahash_ctx(tfm); + ta_ctx = ahash_request_ctx(req); + ta_ctx->sep_used = sep_dev; + + ta_ctx->are_we_done_yet = &are_we_done_yet; - dev_dbg(&sctx->sep_used->pdev->dev, + dev_dbg(&ta_ctx->sep_used->pdev->dev, "sep_hash_init\n"); - sctx->current_hash_stage = HASH_INIT; + ta_ctx->current_hash_stage = HASH_INIT; /* opcode and mode */ - sep_make_header(sctx, &msg_offset, SEP_HASH_INIT_OPCODE); - sep_write_msg(sctx, &ctx->hash_opmode, + sep_make_header(ta_ctx, &msg_offset, SEP_HASH_INIT_OPCODE); + sep_write_msg(ta_ctx, &ta_ctx->hash_opmode, sizeof(u32), sizeof(u32), &msg_offset, 0); - sep_end_msg(sctx, msg_offset); + sep_end_msg(ta_ctx, msg_offset); - sctx->done_with_transaction = 0; - - result = sep_crypto_take_sep(sctx); + are_we_done_yet = 0; + result = sep_crypto_take_sep(ta_ctx); if (result) { - dev_warn(&sctx->sep_used->pdev->dev, + dev_warn(&ta_ctx->sep_used->pdev->dev, "sep_hash_init take sep failed\n"); - sep_crypto_release(sctx, -EINVAL); + sep_crypto_release(sctx, ta_ctx, -EINVAL); } - /** - * Sep is now working. Lets wait up to 5 seconds - * for completion. If it does not complete, we will do - * a crypto release with -EINVAL to release the - * kernel crypto infrastructure and let the system - * continue to boot up - * We have to wait this long because some crypto - * operations can take a while - */ - dev_dbg(&sctx->sep_used->pdev->dev, - "waiting for done with transaction\n"); - - sctx->end_time = jiffies + (SEP_TRANSACTION_WAIT_TIME * HZ); - while ((time_before(jiffies, sctx->end_time)) && - (!sctx->done_with_transaction)) + /* now we sit and wait up to a fixed time for completion */ + end_time = jiffies + (WAIT_TIME * HZ); + while ((time_before(jiffies, end_time)) && (are_we_done_yet == 0)) schedule(); - dev_dbg(&sctx->sep_used->pdev->dev, - "done waiting for done with transaction\n"); - - /* are we done? */ - if (!sctx->done_with_transaction) { - /* Nope, lets release and tell crypto no */ - dev_warn(&sctx->sep_used->pdev->dev, - "[PID%d] sep_hash_init never finished\n", - current->pid); - sep_crypto_release(sctx, -EINVAL); + /* Done waiting; still not done yet? */ + if (are_we_done_yet == 0) { + dev_dbg(&ta_ctx->sep_used->pdev->dev, + "hash init never got done\n"); + sep_crypto_release(sctx, ta_ctx, -EINVAL); + return; } + } static void sep_hash_update(void *data) @@ -1975,6 +2206,8 @@ static void sep_hash_update(void *data) u32 block_size; u32 head_len; u32 tail_len; + int are_we_done_yet; + static u32 msg[10]; static char small_buf[100]; void *src_ptr; @@ -1982,184 +2215,174 @@ static void sep_hash_update(void *data) ssize_t copy_result; struct ahash_request *req; struct crypto_ahash *tfm; - struct sep_hash_ctx *ctx; + struct this_task_ctx *ta_ctx; struct sep_system_ctx *sctx; + unsigned long end_time; req = (struct ahash_request *)data; tfm = crypto_ahash_reqtfm(req); - ctx = ahash_request_ctx(req); sctx = crypto_ahash_ctx(tfm); + ta_ctx = ahash_request_ctx(req); + ta_ctx->sep_used = sep_dev; + + ta_ctx->are_we_done_yet = &are_we_done_yet; /* length for queue status */ - sctx->nbytes = req->nbytes; + ta_ctx->nbytes = req->nbytes; - dev_dbg(&sctx->sep_used->pdev->dev, + dev_dbg(&ta_ctx->sep_used->pdev->dev, "sep_hash_update\n"); - sctx->current_hash_stage = HASH_UPDATE; + ta_ctx->current_hash_stage = HASH_UPDATE; len = req->nbytes; block_size = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm)); tail_len = req->nbytes % block_size; - dev_dbg(&sctx->sep_used->pdev->dev, "length is %x\n", len); - dev_dbg(&sctx->sep_used->pdev->dev, "block_size is %x\n", block_size); - dev_dbg(&sctx->sep_used->pdev->dev, "tail len is %x\n", tail_len); + dev_dbg(&ta_ctx->sep_used->pdev->dev, "length is %x\n", len); + dev_dbg(&ta_ctx->sep_used->pdev->dev, "block_size is %x\n", block_size); + dev_dbg(&ta_ctx->sep_used->pdev->dev, "tail len is %x\n", tail_len); /* Compute header/tail sizes */ - int_ctx = (struct sep_hash_internal_context *)&ctx-> + int_ctx = (struct sep_hash_internal_context *)&sctx-> hash_private_ctx.internal_context; head_len = (block_size - int_ctx->prev_update_bytes) % block_size; tail_len = (req->nbytes - head_len) % block_size; /* Make sure all pages are even block */ - int_error = sep_oddball_pages(sctx->sep_used, req->src, + int_error = sep_oddball_pages(ta_ctx->sep_used, req->src, req->nbytes, block_size, &new_sg, 1); if (int_error < 0) { - dev_warn(&sctx->sep_used->pdev->dev, + dev_warn(&ta_ctx->sep_used->pdev->dev, "oddball pages error in crash update\n"); - sep_crypto_release(sctx, -ENOMEM); + sep_crypto_release(sctx, ta_ctx, -ENOMEM); return; } else if (int_error == 1) { - sctx->src_sg = new_sg; - sctx->src_sg_hold = new_sg; + ta_ctx->src_sg = new_sg; + ta_ctx->src_sg_hold = new_sg; } else { - sctx->src_sg = req->src; - sctx->src_sg_hold = NULL; + ta_ctx->src_sg = req->src; + ta_ctx->src_sg_hold = NULL; } - src_ptr = sg_virt(sctx->src_sg); + src_ptr = sg_virt(ta_ctx->src_sg); - if ((!req->nbytes) || (!ctx->sg)) { + if ((!req->nbytes) || (!ta_ctx->src_sg)) { /* null data */ src_ptr = NULL; } - sep_dump_sg(sctx->sep_used, "hash block sg in", sctx->src_sg); + sep_dump_sg(ta_ctx->sep_used, "hash block sg in", ta_ctx->src_sg); - sctx->dcb_input_data.app_in_address = src_ptr; - sctx->dcb_input_data.data_in_size = req->nbytes - (head_len + tail_len); - sctx->dcb_input_data.app_out_address = NULL; - sctx->dcb_input_data.block_size = block_size; - sctx->dcb_input_data.tail_block_size = 0; - sctx->dcb_input_data.is_applet = 0; - sctx->dcb_input_data.src_sg = sctx->src_sg; - sctx->dcb_input_data.dst_sg = NULL; + ta_ctx->dcb_input_data.app_in_address = src_ptr; + ta_ctx->dcb_input_data.data_in_size = + req->nbytes - (head_len + tail_len); + ta_ctx->dcb_input_data.app_out_address = NULL; + ta_ctx->dcb_input_data.block_size = block_size; + ta_ctx->dcb_input_data.tail_block_size = 0; + ta_ctx->dcb_input_data.is_applet = 0; + ta_ctx->dcb_input_data.src_sg = ta_ctx->src_sg; + ta_ctx->dcb_input_data.dst_sg = NULL; int_error = sep_create_dcb_dmatables_context_kernel( - sctx->sep_used, - &sctx->dcb_region, - &sctx->dmatables_region, - &sctx->dma_ctx, - &sctx->dcb_input_data, + ta_ctx->sep_used, + &ta_ctx->dcb_region, + &ta_ctx->dmatables_region, + &ta_ctx->dma_ctx, + &ta_ctx->dcb_input_data, 1); if (int_error) { - dev_warn(&sctx->sep_used->pdev->dev, + dev_warn(&ta_ctx->sep_used->pdev->dev, "hash update dma table create failed\n"); - sep_crypto_release(sctx, -EINVAL); + sep_crypto_release(sctx, ta_ctx, -EINVAL); return; } /* Construct message to SEP */ - sep_make_header(sctx, &msg_offset, SEP_HASH_UPDATE_OPCODE); + sep_make_header(ta_ctx, &msg_offset, SEP_HASH_UPDATE_OPCODE); msg[0] = (u32)0; msg[1] = (u32)0; msg[2] = (u32)0; - sep_write_msg(sctx, msg, sizeof(u32) * 3, sizeof(u32) * 3, + sep_write_msg(ta_ctx, msg, sizeof(u32) * 3, sizeof(u32) * 3, &msg_offset, 0); /* Handle remainders */ /* Head */ - sep_write_msg(sctx, &head_len, sizeof(u32), + sep_write_msg(ta_ctx, &head_len, sizeof(u32), sizeof(u32), &msg_offset, 0); if (head_len) { copy_result = sg_copy_to_buffer( req->src, - sep_sg_nents(sctx->src_sg), + sep_sg_nents(ta_ctx->src_sg), small_buf, head_len); if (copy_result != head_len) { - dev_warn(&sctx->sep_used->pdev->dev, + dev_warn(&ta_ctx->sep_used->pdev->dev, "sg head copy failure in hash block\n"); - sep_crypto_release(sctx, -ENOMEM); + sep_crypto_release(sctx, ta_ctx, -ENOMEM); return; } - sep_write_msg(sctx, small_buf, head_len, + sep_write_msg(ta_ctx, small_buf, head_len, sizeof(u32) * 32, &msg_offset, 1); } else { msg_offset += sizeof(u32) * 32; } /* Tail */ - sep_write_msg(sctx, &tail_len, sizeof(u32), + sep_write_msg(ta_ctx, &tail_len, sizeof(u32), sizeof(u32), &msg_offset, 0); if (tail_len) { copy_result = sep_copy_offset_sg( - sctx->sep_used, - sctx->src_sg, + ta_ctx->sep_used, + ta_ctx->src_sg, req->nbytes - tail_len, small_buf, tail_len); if (copy_result != tail_len) { - dev_warn(&sctx->sep_used->pdev->dev, + dev_warn(&ta_ctx->sep_used->pdev->dev, "sg tail copy failure in hash block\n"); - sep_crypto_release(sctx, -ENOMEM); + sep_crypto_release(sctx, ta_ctx, -ENOMEM); return; } - sep_write_msg(sctx, small_buf, tail_len, + sep_write_msg(ta_ctx, small_buf, tail_len, sizeof(u32) * 32, &msg_offset, 1); } else { msg_offset += sizeof(u32) * 32; } /* Context */ - sep_write_context(sctx, &msg_offset, &ctx->hash_private_ctx, + sep_write_context(ta_ctx, &msg_offset, &sctx->hash_private_ctx, sizeof(struct sep_hash_private_context)); - sep_end_msg(sctx, msg_offset); - sctx->done_with_transaction = 0; - int_error = sep_crypto_take_sep(sctx); + sep_end_msg(ta_ctx, msg_offset); + are_we_done_yet = 0; + int_error = sep_crypto_take_sep(ta_ctx); if (int_error) { - dev_warn(&sctx->sep_used->pdev->dev, + dev_warn(&ta_ctx->sep_used->pdev->dev, "sep_hash_update take sep failed\n"); - sep_crypto_release(sctx, -EINVAL); + sep_crypto_release(sctx, ta_ctx, -EINVAL); } - /** - * Sep is now working. Lets wait up to 5 seconds - * for completion. If it does not complete, we will do - * a crypto release with -EINVAL to release the - * kernel crypto infrastructure and let the system - * continue to boot up - * We have to wait this long because some crypto - * operations can take a while - */ - dev_dbg(&sctx->sep_used->pdev->dev, - "waiting for done with transaction\n"); - - sctx->end_time = jiffies + (SEP_TRANSACTION_WAIT_TIME * HZ); - while ((time_before(jiffies, sctx->end_time)) && - (!sctx->done_with_transaction)) + /* now we sit and wait up to a fixed time for completion */ + end_time = jiffies + (WAIT_TIME * HZ); + while ((time_before(jiffies, end_time)) && (are_we_done_yet == 0)) schedule(); - dev_dbg(&sctx->sep_used->pdev->dev, - "done waiting for done with transaction\n"); - - /* are we done? */ - if (!sctx->done_with_transaction) { - /* Nope, lets release and tell crypto no */ - dev_warn(&sctx->sep_used->pdev->dev, - "[PID%d] sep_hash_update never finished\n", - current->pid); - sep_crypto_release(sctx, -EINVAL); + /* Done waiting; still not done yet? */ + if (are_we_done_yet == 0) { + dev_dbg(&ta_ctx->sep_used->pdev->dev, + "hash update never got done\n"); + sep_crypto_release(sctx, ta_ctx, -EINVAL); + return; } + } static void sep_hash_final(void *data) @@ -2167,63 +2390,53 @@ static void sep_hash_final(void *data) u32 msg_offset; struct ahash_request *req; struct crypto_ahash *tfm; - struct sep_hash_ctx *ctx; + struct this_task_ctx *ta_ctx; struct sep_system_ctx *sctx; int result; + unsigned long end_time; + int are_we_done_yet; req = (struct ahash_request *)data; tfm = crypto_ahash_reqtfm(req); - ctx = ahash_request_ctx(req); sctx = crypto_ahash_ctx(tfm); + ta_ctx = ahash_request_ctx(req); + ta_ctx->sep_used = sep_dev; - dev_dbg(&sctx->sep_used->pdev->dev, + dev_dbg(&ta_ctx->sep_used->pdev->dev, "sep_hash_final\n"); - sctx->current_hash_stage = HASH_FINISH; + ta_ctx->current_hash_stage = HASH_FINISH; + + ta_ctx->are_we_done_yet = &are_we_done_yet; /* opcode and mode */ - sep_make_header(sctx, &msg_offset, SEP_HASH_FINISH_OPCODE); + sep_make_header(ta_ctx, &msg_offset, SEP_HASH_FINISH_OPCODE); /* Context */ - sep_write_context(sctx, &msg_offset, &ctx->hash_private_ctx, + sep_write_context(ta_ctx, &msg_offset, &sctx->hash_private_ctx, sizeof(struct sep_hash_private_context)); - sep_end_msg(sctx, msg_offset); - sctx->done_with_transaction = 0; - result = sep_crypto_take_sep(sctx); + sep_end_msg(ta_ctx, msg_offset); + are_we_done_yet = 0; + result = sep_crypto_take_sep(ta_ctx); if (result) { - dev_warn(&sctx->sep_used->pdev->dev, + dev_warn(&ta_ctx->sep_used->pdev->dev, "sep_hash_final take sep failed\n"); - sep_crypto_release(sctx, -EINVAL); + sep_crypto_release(sctx, ta_ctx, -EINVAL); } - /** - * Sep is now working. Lets wait up to 5 seconds - * for completion. If it does not complete, we will do - * a crypto release with -EINVAL to release the - * kernel crypto infrastructure and let the system - * continue to boot up - * We have to wait this long because some crypto - * operations can take a while - */ - dev_dbg(&sctx->sep_used->pdev->dev, - "waiting for done with transaction\n"); - - sctx->end_time = jiffies + (SEP_TRANSACTION_WAIT_TIME * HZ); - while ((time_before(jiffies, sctx->end_time)) && - (!sctx->done_with_transaction)) + /* now we sit and wait up to a fixed time for completion */ + end_time = jiffies + (WAIT_TIME * HZ); + while ((time_before(jiffies, end_time)) && (are_we_done_yet == 0)) schedule(); - dev_dbg(&sctx->sep_used->pdev->dev, - "done waiting for done with transaction\n"); - - /* are we done? */ - if (!sctx->done_with_transaction) { - /* Nope, lets release and tell crypto no */ - dev_warn(&sctx->sep_used->pdev->dev, - "[PID%d] sep_hash_final never finished\n", - current->pid); - sep_crypto_release(sctx, -EINVAL); + /* Done waiting; still not done yet? */ + if (are_we_done_yet == 0) { + dev_dbg(&ta_ctx->sep_used->pdev->dev, + "hash final job never got done\n"); + sep_crypto_release(sctx, ta_ctx, -EINVAL); + return; } + } static void sep_hash_digest(void *data) @@ -2234,6 +2447,7 @@ static void sep_hash_digest(void *data) u32 msg[10]; size_t copy_result; int result; + int are_we_done_yet; u32 tail_len; static char small_buf[100]; struct scatterlist *new_sg; @@ -2241,152 +2455,140 @@ static void sep_hash_digest(void *data) struct ahash_request *req; struct crypto_ahash *tfm; - struct sep_hash_ctx *ctx; + struct this_task_ctx *ta_ctx; struct sep_system_ctx *sctx; + unsigned long end_time; req = (struct ahash_request *)data; tfm = crypto_ahash_reqtfm(req); - ctx = ahash_request_ctx(req); sctx = crypto_ahash_ctx(tfm); + ta_ctx = ahash_request_ctx(req); + ta_ctx->sep_used = sep_dev; - dev_dbg(&sctx->sep_used->pdev->dev, + dev_dbg(&ta_ctx->sep_used->pdev->dev, "sep_hash_digest\n"); - sctx->current_hash_stage = HASH_DIGEST; + ta_ctx->current_hash_stage = HASH_DIGEST; + + ta_ctx->are_we_done_yet = &are_we_done_yet; /* length for queue status */ - sctx->nbytes = req->nbytes; + ta_ctx->nbytes = req->nbytes; block_size = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm)); tail_len = req->nbytes % block_size; - dev_dbg(&sctx->sep_used->pdev->dev, "length is %x\n", req->nbytes); - dev_dbg(&sctx->sep_used->pdev->dev, "block_size is %x\n", block_size); - dev_dbg(&sctx->sep_used->pdev->dev, "tail len is %x\n", tail_len); + dev_dbg(&ta_ctx->sep_used->pdev->dev, "length is %x\n", req->nbytes); + dev_dbg(&ta_ctx->sep_used->pdev->dev, "block_size is %x\n", block_size); + dev_dbg(&ta_ctx->sep_used->pdev->dev, "tail len is %x\n", tail_len); /* Make sure all pages are even block */ - int_error = sep_oddball_pages(sctx->sep_used, req->src, + int_error = sep_oddball_pages(ta_ctx->sep_used, req->src, req->nbytes, block_size, &new_sg, 1); if (int_error < 0) { - dev_warn(&sctx->sep_used->pdev->dev, + dev_warn(&ta_ctx->sep_used->pdev->dev, "oddball pages error in crash update\n"); - sep_crypto_release(sctx, -ENOMEM); + sep_crypto_release(sctx, ta_ctx, -ENOMEM); return; } else if (int_error == 1) { - sctx->src_sg = new_sg; - sctx->src_sg_hold = new_sg; + ta_ctx->src_sg = new_sg; + ta_ctx->src_sg_hold = new_sg; } else { - sctx->src_sg = req->src; - sctx->src_sg_hold = NULL; + ta_ctx->src_sg = req->src; + ta_ctx->src_sg_hold = NULL; } - src_ptr = sg_virt(sctx->src_sg); + src_ptr = sg_virt(ta_ctx->src_sg); - if ((!req->nbytes) || (!ctx->sg)) { + if ((!req->nbytes) || (!ta_ctx->src_sg)) { /* null data */ src_ptr = NULL; } - sep_dump_sg(sctx->sep_used, "hash block sg in", sctx->src_sg); + sep_dump_sg(ta_ctx->sep_used, "hash block sg in", ta_ctx->src_sg); - sctx->dcb_input_data.app_in_address = src_ptr; - sctx->dcb_input_data.data_in_size = req->nbytes - tail_len; - sctx->dcb_input_data.app_out_address = NULL; - sctx->dcb_input_data.block_size = block_size; - sctx->dcb_input_data.tail_block_size = 0; - sctx->dcb_input_data.is_applet = 0; - sctx->dcb_input_data.src_sg = sctx->src_sg; - sctx->dcb_input_data.dst_sg = NULL; + ta_ctx->dcb_input_data.app_in_address = src_ptr; + ta_ctx->dcb_input_data.data_in_size = req->nbytes - tail_len; + ta_ctx->dcb_input_data.app_out_address = NULL; + ta_ctx->dcb_input_data.block_size = block_size; + ta_ctx->dcb_input_data.tail_block_size = 0; + ta_ctx->dcb_input_data.is_applet = 0; + ta_ctx->dcb_input_data.src_sg = ta_ctx->src_sg; + ta_ctx->dcb_input_data.dst_sg = NULL; int_error = sep_create_dcb_dmatables_context_kernel( - sctx->sep_used, - &sctx->dcb_region, - &sctx->dmatables_region, - &sctx->dma_ctx, - &sctx->dcb_input_data, + ta_ctx->sep_used, + &ta_ctx->dcb_region, + &ta_ctx->dmatables_region, + &ta_ctx->dma_ctx, + &ta_ctx->dcb_input_data, 1); if (int_error) { - dev_warn(&sctx->sep_used->pdev->dev, + dev_warn(&ta_ctx->sep_used->pdev->dev, "hash update dma table create failed\n"); - sep_crypto_release(sctx, -EINVAL); + sep_crypto_release(sctx, ta_ctx, -EINVAL); return; } /* Construct message to SEP */ - sep_make_header(sctx, &msg_offset, SEP_HASH_SINGLE_OPCODE); - sep_write_msg(sctx, &ctx->hash_opmode, + sep_make_header(ta_ctx, &msg_offset, SEP_HASH_SINGLE_OPCODE); + sep_write_msg(ta_ctx, &ta_ctx->hash_opmode, sizeof(u32), sizeof(u32), &msg_offset, 0); msg[0] = (u32)0; msg[1] = (u32)0; msg[2] = (u32)0; - sep_write_msg(sctx, msg, sizeof(u32) * 3, sizeof(u32) * 3, + sep_write_msg(ta_ctx, msg, sizeof(u32) * 3, sizeof(u32) * 3, &msg_offset, 0); /* Tail */ - sep_write_msg(sctx, &tail_len, sizeof(u32), + sep_write_msg(ta_ctx, &tail_len, sizeof(u32), sizeof(u32), &msg_offset, 0); if (tail_len) { copy_result = sep_copy_offset_sg( - sctx->sep_used, - sctx->src_sg, + ta_ctx->sep_used, + ta_ctx->src_sg, req->nbytes - tail_len, small_buf, tail_len); if (copy_result != tail_len) { - dev_warn(&sctx->sep_used->pdev->dev, + dev_warn(&ta_ctx->sep_used->pdev->dev, "sg tail copy failure in hash block\n"); - sep_crypto_release(sctx, -ENOMEM); + sep_crypto_release(sctx, ta_ctx, -ENOMEM); return; } - sep_write_msg(sctx, small_buf, tail_len, + sep_write_msg(ta_ctx, small_buf, tail_len, sizeof(u32) * 32, &msg_offset, 1); } else { msg_offset += sizeof(u32) * 32; } - sep_end_msg(sctx, msg_offset); + sep_end_msg(ta_ctx, msg_offset); - sctx->done_with_transaction = 0; - - result = sep_crypto_take_sep(sctx); + are_we_done_yet = 0; + result = sep_crypto_take_sep(ta_ctx); if (result) { - dev_warn(&sctx->sep_used->pdev->dev, + dev_warn(&ta_ctx->sep_used->pdev->dev, "sep_hash_digest take sep failed\n"); - sep_crypto_release(sctx, -EINVAL); + sep_crypto_release(sctx, ta_ctx, -EINVAL); } - /** - * Sep is now working. Lets wait up to 5 seconds - * for completion. If it does not complete, we will do - * a crypto release with -EINVAL to release the - * kernel crypto infrastructure and let the system - * continue to boot up - * We have to wait this long because some crypto - * operations can take a while - */ - dev_dbg(&sctx->sep_used->pdev->dev, - "waiting for done with transaction\n"); - - sctx->end_time = jiffies + (SEP_TRANSACTION_WAIT_TIME * HZ); - while ((time_before(jiffies, sctx->end_time)) && - (!sctx->done_with_transaction)) + /* now we sit and wait up to a fixed time for completion */ + end_time = jiffies + (WAIT_TIME * HZ); + while ((time_before(jiffies, end_time)) && (are_we_done_yet == 0)) schedule(); - dev_dbg(&sctx->sep_used->pdev->dev, - "done waiting for done with transaction\n"); - - /* are we done? */ - if (!sctx->done_with_transaction) { - /* Nope, lets release and tell crypto no */ - dev_warn(&sctx->sep_used->pdev->dev, - "[PID%d] sep_hash_digest never finished\n", - current->pid); - sep_crypto_release(sctx, -EINVAL); + /* Done waiting; still not done yet? */ + if (are_we_done_yet == 0) { + dev_dbg(&ta_ctx->sep_used->pdev->dev, + "hash digest job never got done\n"); + sep_crypto_release(sctx, ta_ctx, -EINVAL); + return; } + } /** @@ -2404,6 +2606,7 @@ static void sep_dequeuer(void *data) struct ahash_request *hash_req; struct sep_system_ctx *sctx; struct crypto_ahash *hash_tfm; + struct this_task_ctx *ta_ctx; this_queue = (struct crypto_queue *)data; @@ -2481,22 +2684,32 @@ static void sep_dequeuer(void *data) return; } - if (sctx->current_hash_stage == HASH_INIT) { + ta_ctx = ahash_request_ctx(hash_req); + + if (ta_ctx->current_hash_stage == HASH_INIT) { pr_debug("sep crypto queue hash init\n"); sep_hash_init((void *)hash_req); return; - } else if (sctx->current_hash_stage == HASH_UPDATE) { + } else if (ta_ctx->current_hash_stage == HASH_UPDATE) { pr_debug("sep crypto queue hash update\n"); sep_hash_update((void *)hash_req); return; - } else if (sctx->current_hash_stage == HASH_FINISH) { + } else if (ta_ctx->current_hash_stage == HASH_FINISH) { pr_debug("sep crypto queue hash final\n"); sep_hash_final((void *)hash_req); return; - } else if (sctx->current_hash_stage == HASH_DIGEST) { + } else if (ta_ctx->current_hash_stage == HASH_DIGEST) { pr_debug("sep crypto queue hash digest\n"); sep_hash_digest((void *)hash_req); return; + } else if (ta_ctx->current_hash_stage == HASH_FINUP_DATA) { + pr_debug("sep crypto queue hash digest\n"); + sep_hash_update((void *)hash_req); + return; + } else if (ta_ctx->current_hash_stage == HASH_FINUP_FINISH) { + pr_debug("sep crypto queue hash digest\n"); + sep_hash_final((void *)hash_req); + return; } else { pr_debug("sep crypto queue hash oops nothing\n"); return; @@ -2507,605 +2720,671 @@ static void sep_dequeuer(void *data) static int sep_sha1_init(struct ahash_request *req) { int error; - struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct sep_hash_ctx *ctx = ahash_request_ctx(req); - struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + int error1; + struct this_task_ctx *ta_ctx = ahash_request_ctx(req); + + pr_debug("sep - doing sha1 init\n"); - dev_dbg(&sctx->sep_used->pdev->dev, "doing sha1 init\n"); - sctx->current_request = SHA1; - sctx->current_hash_req = req; - sctx->current_cypher_req = NULL; - ctx->hash_opmode = SEP_HASH_SHA1; - sctx->current_hash_stage = HASH_INIT; + /* Clear out task context */ + memset(ta_ctx, 0, sizeof(struct this_task_ctx)); + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = SHA1; + ta_ctx->current_hash_req = req; + ta_ctx->current_cypher_req = NULL; + ta_ctx->hash_opmode = SEP_HASH_SHA1; + ta_ctx->current_hash_stage = HASH_INIT; + + /* lock necessary so that only one entity touches the queues */ spin_lock_irq(&queue_lock); error = crypto_enqueue_request(&sep_queue, &req->base); - spin_unlock_irq(&queue_lock); - - if ((error != 0) && (error != -EINPROGRESS)) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep sha1 init cant enqueue\n"); - sep_crypto_release(sctx, error); - return error; - } - error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, - (void *)&sep_queue); - if (error) { - dev_warn(&sctx->sep_used->pdev->dev, - "sha1 init cannot submit queue\n"); - sep_crypto_release(sctx, -EINVAL); - return -EINVAL; - } - return -EINPROGRESS; + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); + spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; } static int sep_sha1_update(struct ahash_request *req) { int error; - struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct sep_hash_ctx *ctx = ahash_request_ctx(req); - struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + int error1; + struct this_task_ctx *ta_ctx = ahash_request_ctx(req); - dev_dbg(&sctx->sep_used->pdev->dev, "doing sha1 update\n"); - sctx->current_request = SHA1; - sctx->current_hash_req = req; - sctx->current_cypher_req = NULL; - ctx->hash_opmode = SEP_HASH_SHA1; - sctx->current_hash_stage = HASH_INIT; + pr_debug("sep - doing sha1 update\n"); + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = SHA1; + ta_ctx->current_hash_req = req; + ta_ctx->current_cypher_req = NULL; + ta_ctx->hash_opmode = SEP_HASH_SHA1; + ta_ctx->current_hash_stage = HASH_UPDATE; + + /* lock necessary so that only one entity touches the queues */ spin_lock_irq(&queue_lock); error = crypto_enqueue_request(&sep_queue, &req->base); - spin_unlock_irq(&queue_lock); - - if ((error != 0) && (error != -EINPROGRESS)) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep sha1 update cant enqueue\n"); - sep_crypto_release(sctx, error); - return error; - } - error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, - (void *)&sep_queue); - if (error) { - dev_warn(&sctx->sep_used->pdev->dev, - "sha1 update cannot submit queue\n"); - sep_crypto_release(sctx, -EINVAL); - return -EINVAL; - } - return -EINPROGRESS; + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); + spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; } static int sep_sha1_final(struct ahash_request *req) { int error; - struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct sep_hash_ctx *ctx = ahash_request_ctx(req); - struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); - dev_dbg(&sctx->sep_used->pdev->dev, "doing sha1 final\n"); - - sctx->current_request = SHA1; - sctx->current_hash_req = req; - sctx->current_cypher_req = NULL; - ctx->hash_opmode = SEP_HASH_SHA1; - sctx->current_hash_stage = HASH_FINISH; - + int error1; + struct this_task_ctx *ta_ctx = ahash_request_ctx(req); + pr_debug("sep - doing sha1 final\n"); + + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = SHA1; + ta_ctx->current_hash_req = req; + ta_ctx->current_cypher_req = NULL; + ta_ctx->hash_opmode = SEP_HASH_SHA1; + ta_ctx->current_hash_stage = HASH_FINISH; + + /* lock necessary so that only one entity touches the queues */ spin_lock_irq(&queue_lock); error = crypto_enqueue_request(&sep_queue, &req->base); - spin_unlock_irq(&queue_lock); - - if ((error != 0) && (error != -EINPROGRESS)) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep sha1 final cant enqueue\n"); - sep_crypto_release(sctx, error); - return error; - } - - error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, - (void *)&sep_queue); - if (error) { - dev_warn(&sctx->sep_used->pdev->dev, - "sha1 final cannot submit queue\n"); - sep_crypto_release(sctx, -EINVAL); - return -EINVAL; - } - return -EINPROGRESS; + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); + spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; } static int sep_sha1_digest(struct ahash_request *req) { int error; - struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct sep_hash_ctx *ctx = ahash_request_ctx(req); - struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); - dev_dbg(&sctx->sep_used->pdev->dev, "doing sha1 digest\n"); + int error1; + struct this_task_ctx *ta_ctx = ahash_request_ctx(req); + pr_debug("sep - doing sha1 digest\n"); - sctx->current_request = SHA1; - sctx->current_hash_req = req; - sctx->current_cypher_req = NULL; - ctx->hash_opmode = SEP_HASH_SHA1; - sctx->current_hash_stage = HASH_DIGEST; + /* Clear out task context */ + memset(ta_ctx, 0, sizeof(struct this_task_ctx)); + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = SHA1; + ta_ctx->current_hash_req = req; + ta_ctx->current_cypher_req = NULL; + ta_ctx->hash_opmode = SEP_HASH_SHA1; + ta_ctx->current_hash_stage = HASH_DIGEST; + + /* lock necessary so that only one entity touches the queues */ spin_lock_irq(&queue_lock); error = crypto_enqueue_request(&sep_queue, &req->base); - spin_unlock_irq(&queue_lock); - if ((error != 0) && (error != -EINPROGRESS)) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep sha1 digest cant enqueue\n"); - sep_crypto_release(sctx, error); - return error; - } + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); + spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; +} - error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, - (void *)&sep_queue); - if (error) { - dev_warn(&sctx->sep_used->pdev->dev, - "sha1 digest cannot submit queue\n"); - sep_crypto_release(sctx, -EINVAL); - return -EINVAL; - } - return -EINPROGRESS; +static int sep_sha1_finup(struct ahash_request *req) +{ + int error; + int error1; + struct this_task_ctx *ta_ctx = ahash_request_ctx(req); + pr_debug("sep - doing sha1 finup\n"); + + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = SHA1; + ta_ctx->current_hash_req = req; + ta_ctx->current_cypher_req = NULL; + ta_ctx->hash_opmode = SEP_HASH_SHA1; + ta_ctx->current_hash_stage = HASH_FINUP_DATA; + + /* lock necessary so that only one entity touches the queues */ + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); + spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; } static int sep_md5_init(struct ahash_request *req) { int error; - struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct sep_hash_ctx *ctx = ahash_request_ctx(req); - struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); - dev_dbg(&sctx->sep_used->pdev->dev, "doing md5 init\n"); + int error1; + struct this_task_ctx *ta_ctx = ahash_request_ctx(req); + pr_debug("sep - doing md5 init\n"); + + /* Clear out task context */ + memset(ta_ctx, 0, sizeof(struct this_task_ctx)); - sctx->current_request = MD5; - sctx->current_hash_req = req; - sctx->current_cypher_req = NULL; - ctx->hash_opmode = SEP_HASH_MD5; - sctx->current_hash_stage = HASH_INIT; + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = MD5; + ta_ctx->current_hash_req = req; + ta_ctx->current_cypher_req = NULL; + ta_ctx->hash_opmode = SEP_HASH_MD5; + ta_ctx->current_hash_stage = HASH_INIT; + /* lock necessary so that only one entity touches the queues */ spin_lock_irq(&queue_lock); error = crypto_enqueue_request(&sep_queue, &req->base); - spin_unlock_irq(&queue_lock); - - if ((error != 0) && (error != -EINPROGRESS)) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep md5 init cant enqueue\n"); - sep_crypto_release(sctx, error); - return error; - } - - error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, - (void *)&sep_queue); - if (error) { - dev_warn(&sctx->sep_used->pdev->dev, - "md5 init cannot submit queue\n"); - sep_crypto_release(sctx, -EINVAL); - return -EINVAL; - } - return -EINPROGRESS; + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); + spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; } static int sep_md5_update(struct ahash_request *req) { int error; - struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct sep_hash_ctx *ctx = ahash_request_ctx(req); - struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); - dev_dbg(&sctx->sep_used->pdev->dev, "doing md5 update\n"); - - sctx->current_request = MD5; - sctx->current_hash_req = req; - sctx->current_cypher_req = NULL; - ctx->hash_opmode = SEP_HASH_MD5; - sctx->current_hash_stage = HASH_UPDATE; - + int error1; + struct this_task_ctx *ta_ctx = ahash_request_ctx(req); + pr_debug("sep - doing md5 update\n"); + + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = MD5; + ta_ctx->current_hash_req = req; + ta_ctx->current_cypher_req = NULL; + ta_ctx->hash_opmode = SEP_HASH_MD5; + ta_ctx->current_hash_stage = HASH_UPDATE; + + /* lock necessary so that only one entity touches the queues */ spin_lock_irq(&queue_lock); error = crypto_enqueue_request(&sep_queue, &req->base); - spin_unlock_irq(&queue_lock); - if ((error != 0) && (error != -EINPROGRESS)) { - dev_warn(&sctx->sep_used->pdev->dev, - "md5 update cant enqueue\n"); - sep_crypto_release(sctx, error); - return error; - } - - error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, - (void *)&sep_queue); - if (error) { - dev_warn(&sctx->sep_used->pdev->dev, - "md5 update cannot submit queue\n"); - sep_crypto_release(sctx, -EINVAL); - return -EINVAL; - } - return -EINPROGRESS; + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); + spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; } static int sep_md5_final(struct ahash_request *req) { int error; - struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct sep_hash_ctx *ctx = ahash_request_ctx(req); - struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); - dev_dbg(&sctx->sep_used->pdev->dev, "doing md5 final\n"); - - sctx->current_request = MD5; - sctx->current_hash_req = req; - sctx->current_cypher_req = NULL; - ctx->hash_opmode = SEP_HASH_MD5; - sctx->current_hash_stage = HASH_FINISH; - + int error1; + struct this_task_ctx *ta_ctx = ahash_request_ctx(req); + pr_debug("sep - doing md5 final\n"); + + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = MD5; + ta_ctx->current_hash_req = req; + ta_ctx->current_cypher_req = NULL; + ta_ctx->hash_opmode = SEP_HASH_MD5; + ta_ctx->current_hash_stage = HASH_FINISH; + + /* lock necessary so that only one entity touches the queues */ spin_lock_irq(&queue_lock); error = crypto_enqueue_request(&sep_queue, &req->base); - spin_unlock_irq(&queue_lock); - - if ((error != 0) && (error != -EINPROGRESS)) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep md5 final cant enqueue\n"); - sep_crypto_release(sctx, error); - return error; - } - - error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, - (void *)&sep_queue); - if (error) { - dev_warn(&sctx->sep_used->pdev->dev, - "md5 final cannot submit queue\n"); - sep_crypto_release(sctx, -EINVAL); - return -EINVAL; - } - return -EINPROGRESS; + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); + spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; } static int sep_md5_digest(struct ahash_request *req) { int error; - struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct sep_hash_ctx *ctx = ahash_request_ctx(req); - struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + int error1; + struct this_task_ctx *ta_ctx = ahash_request_ctx(req); - dev_dbg(&sctx->sep_used->pdev->dev, "doing md5 digest\n"); - sctx->current_request = MD5; - sctx->current_hash_req = req; - sctx->current_cypher_req = NULL; - ctx->hash_opmode = SEP_HASH_MD5; - sctx->current_hash_stage = HASH_DIGEST; + pr_debug("sep - doing md5 digest\n"); + /* Clear out task context */ + memset(ta_ctx, 0, sizeof(struct this_task_ctx)); + + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = MD5; + ta_ctx->current_hash_req = req; + ta_ctx->current_cypher_req = NULL; + ta_ctx->hash_opmode = SEP_HASH_MD5; + ta_ctx->current_hash_stage = HASH_DIGEST; + + /* lock necessary so that only one entity touches the queues */ spin_lock_irq(&queue_lock); error = crypto_enqueue_request(&sep_queue, &req->base); - spin_unlock_irq(&queue_lock); - - if ((error != 0) && (error != -EINPROGRESS)) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep md5 digest cant enqueue\n"); - sep_crypto_release(sctx, error); - return error; - } - error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, - (void *)&sep_queue); - if (error) { - dev_warn(&sctx->sep_used->pdev->dev, - "md5 digest cannot submit queue\n"); - sep_crypto_release(sctx, -EINVAL); - return -EINVAL; - } - return -EINPROGRESS; + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); + spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; } -static int sep_sha224_init(struct ahash_request *req) +static int sep_md5_finup(struct ahash_request *req) { int error; - struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct sep_hash_ctx *ctx = ahash_request_ctx(req); - struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); - dev_dbg(&sctx->sep_used->pdev->dev, "doing sha224 init\n"); + int error1; + struct this_task_ctx *ta_ctx = ahash_request_ctx(req); + + pr_debug("sep - doing md5 finup\n"); - sctx->current_request = SHA224; - sctx->current_hash_req = req; - sctx->current_cypher_req = NULL; - ctx->hash_opmode = SEP_HASH_SHA224; - sctx->current_hash_stage = HASH_INIT; + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = MD5; + ta_ctx->current_hash_req = req; + ta_ctx->current_cypher_req = NULL; + ta_ctx->hash_opmode = SEP_HASH_MD5; + ta_ctx->current_hash_stage = HASH_FINUP_DATA; + /* lock necessary so that only one entity touches the queues */ spin_lock_irq(&queue_lock); error = crypto_enqueue_request(&sep_queue, &req->base); - spin_unlock_irq(&queue_lock); - - if ((error != 0) && (error != -EINPROGRESS)) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep sha224 init cant enqueue\n"); - sep_crypto_release(sctx, error); - return error; - } - error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, - (void *)&sep_queue); - if (error) { - dev_warn(&sctx->sep_used->pdev->dev, - "sha224 init cannot submit queue\n"); - sep_crypto_release(sctx, -EINVAL); - return -EINVAL; - } - return -EINPROGRESS; + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); + spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; } -static int sep_sha224_update(struct ahash_request *req) +static int sep_sha224_init(struct ahash_request *req) { int error; - struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct sep_hash_ctx *ctx = ahash_request_ctx(req); - struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); - dev_dbg(&sctx->sep_used->pdev->dev, "doing sha224 update\n"); + int error1; + struct this_task_ctx *ta_ctx = ahash_request_ctx(req); + pr_debug("sep - doing sha224 init\n"); + + /* Clear out task context */ + memset(ta_ctx, 0, sizeof(struct this_task_ctx)); - sctx->current_request = SHA224; - sctx->current_hash_req = req; - sctx->current_cypher_req = NULL; - ctx->hash_opmode = SEP_HASH_SHA224; - sctx->current_hash_stage = HASH_UPDATE; + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = SHA224; + ta_ctx->current_hash_req = req; + ta_ctx->current_cypher_req = NULL; + ta_ctx->hash_opmode = SEP_HASH_SHA224; + ta_ctx->current_hash_stage = HASH_INIT; + /* lock necessary so that only one entity touches the queues */ spin_lock_irq(&queue_lock); error = crypto_enqueue_request(&sep_queue, &req->base); + + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; +} - if ((error != 0) && (error != -EINPROGRESS)) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep sha224 update cant enqueue\n"); - sep_crypto_release(sctx, error); - return error; - } +static int sep_sha224_update(struct ahash_request *req) +{ + int error; + int error1; + struct this_task_ctx *ta_ctx = ahash_request_ctx(req); + pr_debug("sep - doing sha224 update\n"); + + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = SHA224; + ta_ctx->current_hash_req = req; + ta_ctx->current_cypher_req = NULL; + ta_ctx->hash_opmode = SEP_HASH_SHA224; + ta_ctx->current_hash_stage = HASH_UPDATE; + + /* lock necessary so that only one entity touches the queues */ + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); - error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, - (void *)&sep_queue); - if (error) { - dev_warn(&sctx->sep_used->pdev->dev, - "sha224 update cannot submit queue\n"); - sep_crypto_release(sctx, -EINVAL); - return -EINVAL; - } - return -EINPROGRESS; + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); + spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; } static int sep_sha224_final(struct ahash_request *req) { int error; - struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct sep_hash_ctx *ctx = ahash_request_ctx(req); - struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); - dev_dbg(&sctx->sep_used->pdev->dev, "doing sha224 final\n"); - - sctx->current_request = SHA224; - sctx->current_hash_req = req; - sctx->current_cypher_req = NULL; - ctx->hash_opmode = SEP_HASH_SHA224; - sctx->current_hash_stage = HASH_FINISH; - + int error1; + struct this_task_ctx *ta_ctx = ahash_request_ctx(req); + pr_debug("sep - doing sha224 final\n"); + + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = SHA224; + ta_ctx->current_hash_req = req; + ta_ctx->current_cypher_req = NULL; + ta_ctx->hash_opmode = SEP_HASH_SHA224; + ta_ctx->current_hash_stage = HASH_FINISH; + + /* lock necessary so that only one entity touches the queues */ spin_lock_irq(&queue_lock); error = crypto_enqueue_request(&sep_queue, &req->base); - spin_unlock_irq(&queue_lock); - if ((error != 0) && (error != -EINPROGRESS)) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep sha224 final cant enqueue\n"); - sep_crypto_release(sctx, error); - return error; - } - - error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, - (void *)&sep_queue); - if (error) { - dev_warn(&sctx->sep_used->pdev->dev, - "sha224 final cannot submit queue\n"); - sep_crypto_release(sctx, -EINVAL); - return -EINVAL; - } - return -EINPROGRESS; + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); + spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; } static int sep_sha224_digest(struct ahash_request *req) { int error; - struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct sep_hash_ctx *ctx = ahash_request_ctx(req); - struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + int error1; + struct this_task_ctx *ta_ctx = ahash_request_ctx(req); + + pr_debug("sep - doing sha224 digest\n"); - dev_dbg(&sctx->sep_used->pdev->dev, "doing 224 digest\n"); - sctx->current_request = SHA224; - sctx->current_hash_req = req; - sctx->current_cypher_req = NULL; - ctx->hash_opmode = SEP_HASH_SHA224; - sctx->current_hash_stage = HASH_DIGEST; + /* Clear out task context */ + memset(ta_ctx, 0, sizeof(struct this_task_ctx)); + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = SHA224; + ta_ctx->current_hash_req = req; + ta_ctx->current_cypher_req = NULL; + ta_ctx->hash_opmode = SEP_HASH_SHA224; + ta_ctx->current_hash_stage = HASH_DIGEST; + + /* lock necessary so that only one entity touches the queues */ spin_lock_irq(&queue_lock); error = crypto_enqueue_request(&sep_queue, &req->base); - spin_unlock_irq(&queue_lock); - if ((error != 0) && (error != -EINPROGRESS)) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep sha224 digest cant enqueue\n"); - sep_crypto_release(sctx, error); - return error; - } - - error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, - (void *)&sep_queue); - if (error) { - dev_warn(&sctx->sep_used->pdev->dev, - "sha256 digest cannot submit queue\n"); - sep_crypto_release(sctx, -EINVAL); - return -EINVAL; - } - return -EINPROGRESS; + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); + spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; } -static int sep_sha256_init(struct ahash_request *req) +static int sep_sha224_finup(struct ahash_request *req) { int error; - struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct sep_hash_ctx *ctx = ahash_request_ctx(req); - struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); - dev_dbg(&sctx->sep_used->pdev->dev, "doing sha256 init\n"); + int error1; + struct this_task_ctx *ta_ctx = ahash_request_ctx(req); + + pr_debug("sep - doing sha224 finup\n"); - sctx->current_request = SHA256; - sctx->current_hash_req = req; - sctx->current_cypher_req = NULL; - ctx->hash_opmode = SEP_HASH_SHA256; - sctx->current_hash_stage = HASH_INIT; + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = SHA224; + ta_ctx->current_hash_req = req; + ta_ctx->current_cypher_req = NULL; + ta_ctx->hash_opmode = SEP_HASH_SHA224; + ta_ctx->current_hash_stage = HASH_FINUP_DATA; + /* lock necessary so that only one entity touches the queues */ spin_lock_irq(&queue_lock); error = crypto_enqueue_request(&sep_queue, &req->base); - spin_unlock_irq(&queue_lock); - if ((error != 0) && (error != -EINPROGRESS)) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep sha256 init cant enqueue\n"); - sep_crypto_release(sctx, error); - return error; - } - - error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, - (void *)&sep_queue); - if (error) { - dev_warn(&sctx->sep_used->pdev->dev, - "sha256 init cannot submit queue\n"); - sep_crypto_release(sctx, -EINVAL); - return -EINVAL; - } - return -EINPROGRESS; + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); + spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; } -static int sep_sha256_update(struct ahash_request *req) +static int sep_sha256_init(struct ahash_request *req) { int error; - struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct sep_hash_ctx *ctx = ahash_request_ctx(req); - struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); - dev_dbg(&sctx->sep_used->pdev->dev, "doing sha256 update\n"); + int error1; + struct this_task_ctx *ta_ctx = ahash_request_ctx(req); + pr_debug("sep - doing sha256 init\n"); + + /* Clear out task context */ + memset(ta_ctx, 0, sizeof(struct this_task_ctx)); - sctx->current_request = SHA256; - sctx->current_hash_req = req; - sctx->current_cypher_req = NULL; - ctx->hash_opmode = SEP_HASH_SHA256; - sctx->current_hash_stage = HASH_UPDATE; + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = SHA256; + ta_ctx->current_hash_req = req; + ta_ctx->current_cypher_req = NULL; + ta_ctx->hash_opmode = SEP_HASH_SHA256; + ta_ctx->current_hash_stage = HASH_INIT; + /* lock necessary so that only one entity touches the queues */ spin_lock_irq(&queue_lock); error = crypto_enqueue_request(&sep_queue, &req->base); + + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; +} - if ((error != 0) && (error != -EINPROGRESS)) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep sha256 update cant enqueue\n"); - sep_crypto_release(sctx, error); - return error; - } +static int sep_sha256_update(struct ahash_request *req) +{ + int error; + int error1; + struct this_task_ctx *ta_ctx = ahash_request_ctx(req); + pr_debug("sep - doing sha256 update\n"); + + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = SHA256; + ta_ctx->current_hash_req = req; + ta_ctx->current_cypher_req = NULL; + ta_ctx->hash_opmode = SEP_HASH_SHA256; + ta_ctx->current_hash_stage = HASH_UPDATE; + + /* lock necessary so that only one entity touches the queues */ + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); - error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, - (void *)&sep_queue); - if (error) { - dev_warn(&sctx->sep_used->pdev->dev, - "sha256 update cannot submit queue\n"); - sep_crypto_release(sctx, -EINVAL); - return -EINVAL; - } - return -EINPROGRESS; + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); + spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; } static int sep_sha256_final(struct ahash_request *req) { int error; - struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct sep_hash_ctx *ctx = ahash_request_ctx(req); - struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); - dev_dbg(&sctx->sep_used->pdev->dev, "doing sha256 final\n"); - - sctx->current_request = SHA256; - sctx->current_hash_req = req; - sctx->current_cypher_req = NULL; - ctx->hash_opmode = SEP_HASH_SHA256; - sctx->current_hash_stage = HASH_FINISH; - + int error1; + struct this_task_ctx *ta_ctx = ahash_request_ctx(req); + pr_debug("sep - doing sha256 final\n"); + + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = SHA256; + ta_ctx->current_hash_req = req; + ta_ctx->current_cypher_req = NULL; + ta_ctx->hash_opmode = SEP_HASH_SHA256; + ta_ctx->current_hash_stage = HASH_FINISH; + + /* lock necessary so that only one entity touches the queues */ spin_lock_irq(&queue_lock); error = crypto_enqueue_request(&sep_queue, &req->base); - spin_unlock_irq(&queue_lock); - if ((error != 0) && (error != -EINPROGRESS)) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep sha256 final cant enqueue\n"); - sep_crypto_release(sctx, error); - return error; - } - - error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, - (void *)&sep_queue); - if (error) { - dev_warn(&sctx->sep_used->pdev->dev, - "sha256 final cannot submit queue\n"); - sep_crypto_release(sctx, -EINVAL); - return -EINVAL; - } - return -EINPROGRESS; + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); + spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; } static int sep_sha256_digest(struct ahash_request *req) { int error; - struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct sep_hash_ctx *ctx = ahash_request_ctx(req); - struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + int error1; + struct this_task_ctx *ta_ctx = ahash_request_ctx(req); + + pr_debug("sep - doing sha256 digest\n"); + + /* Clear out task context */ + memset(ta_ctx, 0, sizeof(struct this_task_ctx)); - dev_dbg(&sctx->sep_used->pdev->dev, "doing sha256 digest\n"); - sctx->current_request = SHA256; - sctx->current_hash_req = req; - sctx->current_cypher_req = NULL; - ctx->hash_opmode = SEP_HASH_SHA256; - sctx->current_hash_stage = HASH_DIGEST; + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = SHA256; + ta_ctx->current_hash_req = req; + ta_ctx->current_cypher_req = NULL; + ta_ctx->hash_opmode = SEP_HASH_SHA256; + ta_ctx->current_hash_stage = HASH_DIGEST; + /* lock necessary so that only one entity touches the queues */ spin_lock_irq(&queue_lock); error = crypto_enqueue_request(&sep_queue, &req->base); + + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; +} - if ((error != 0) && (error != -EINPROGRESS)) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep sha256 digest cant enqueue\n"); - sep_crypto_release(sctx, error); - return error; - } +static int sep_sha256_finup(struct ahash_request *req) +{ + int error; + int error1; + struct this_task_ctx *ta_ctx = ahash_request_ctx(req); - error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, - (void *)&sep_queue); - if (error) { - dev_warn(&sctx->sep_used->pdev->dev, - "sha256 digest cannot submit queue\n"); - sep_crypto_release(sctx, -EINVAL); - return -EINVAL; - } - return -EINPROGRESS; + pr_debug("sep - doing sha256 finup\n"); + + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = SHA256; + ta_ctx->current_hash_req = req; + ta_ctx->current_cypher_req = NULL; + ta_ctx->hash_opmode = SEP_HASH_SHA256; + ta_ctx->current_hash_stage = HASH_FINUP_DATA; + + /* lock necessary so that only one entity touches the queues */ + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); + spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; } static int sep_crypto_init(struct crypto_tfm *tfm) { - struct sep_system_ctx *sctx = crypto_tfm_ctx(tfm); const char *alg_name = crypto_tfm_alg_name(tfm); - sctx->sep_used = sep_dev; - if (alg_name == NULL) - dev_dbg(&sctx->sep_used->pdev->dev, "alg is NULL\n"); + pr_debug("sep_crypto_init alg is NULL\n"); else - dev_dbg(&sctx->sep_used->pdev->dev, "alg is %s\n", alg_name); + pr_debug("sep_crypto_init alg is %s\n", alg_name); - tfm->crt_ablkcipher.reqsize = sizeof(struct sep_block_ctx); - dev_dbg(&sctx->sep_used->pdev->dev, "sep_crypto_init\n"); + tfm->crt_ablkcipher.reqsize = sizeof(struct this_task_ctx); return 0; } static void sep_crypto_exit(struct crypto_tfm *tfm) { - struct sep_system_ctx *sctx = crypto_tfm_ctx(tfm); - dev_dbg(&sctx->sep_used->pdev->dev, "sep_crypto_exit\n"); - sctx->sep_used = NULL; + pr_debug("sep_crypto_exit\n"); } static int sep_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key, @@ -3113,8 +3392,9 @@ static int sep_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key, { struct sep_system_ctx *sctx = crypto_ablkcipher_ctx(tfm); - dev_dbg(&sctx->sep_used->pdev->dev, "sep aes setkey\n"); + pr_debug("sep aes setkey\n"); + pr_debug("tfm is %p sctx is %p\n", tfm, sctx); switch (keylen) { case SEP_AES_KEY_128_SIZE: sctx->aes_key_size = AES_128; @@ -3129,7 +3409,7 @@ static int sep_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key, sctx->aes_key_size = AES_512; break; default: - dev_warn(&sctx->sep_used->pdev->dev, "sep aes key size %x\n", + pr_debug("invalid sep aes key size %x\n", keylen); return -EINVAL; } @@ -3140,7 +3420,6 @@ static int sep_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key, sctx->keylen = keylen; /* Indicate to encrypt/decrypt function to send key to SEP */ sctx->key_sent = 0; - sctx->last_block = 0; return 0; } @@ -3148,153 +3427,159 @@ static int sep_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key, static int sep_aes_ecb_encrypt(struct ablkcipher_request *req) { int error; - struct sep_block_ctx *bctx = ablkcipher_request_ctx(req); - struct sep_system_ctx *sctx = crypto_ablkcipher_ctx( - crypto_ablkcipher_reqtfm(req)); + int error1; + struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req); + + pr_debug("sep - doing aes ecb encrypt\n"); - dev_dbg(&sctx->sep_used->pdev->dev, "sep aes ecb encrypt\n"); - sctx->current_request = AES_ECB; - sctx->current_hash_req = NULL; - sctx->current_cypher_req = req; - bctx->aes_encmode = SEP_AES_ENCRYPT; - bctx->aes_opmode = SEP_AES_ECB; - bctx->init_opcode = SEP_AES_INIT_OPCODE; - bctx->block_opcode = SEP_AES_BLOCK_OPCODE; + /* Clear out task context */ + memset(ta_ctx, 0, sizeof(struct this_task_ctx)); + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = AES_ECB; + ta_ctx->current_hash_req = NULL; + ta_ctx->current_cypher_req = req; + ta_ctx->aes_encmode = SEP_AES_ENCRYPT; + ta_ctx->aes_opmode = SEP_AES_ECB; + ta_ctx->init_opcode = SEP_AES_INIT_OPCODE; + ta_ctx->block_opcode = SEP_AES_BLOCK_OPCODE; + + /* lock necessary so that only one entity touches the queues */ spin_lock_irq(&queue_lock); error = crypto_enqueue_request(&sep_queue, &req->base); - spin_unlock_irq(&queue_lock); - - if ((error != 0) && (error != -EINPROGRESS)) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep_aes_ecb_encrypt cant enqueue\n"); - sep_crypto_release(sctx, error); - return error; - } - error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, - (void *)&sep_queue); - if (error) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep_aes_ecb_encrypt cannot submit queue\n"); - sep_crypto_release(sctx, -EINVAL); - return -EINVAL; - } - return -EINPROGRESS; + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); + spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; } static int sep_aes_ecb_decrypt(struct ablkcipher_request *req) { int error; - struct sep_block_ctx *bctx = ablkcipher_request_ctx(req); - struct sep_system_ctx *sctx = crypto_ablkcipher_ctx( - crypto_ablkcipher_reqtfm(req)); + int error1; + struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req); + + pr_debug("sep - doing aes ecb decrypt\n"); - dev_dbg(&sctx->sep_used->pdev->dev, "sep aes ecb decrypt\n"); - sctx->current_request = AES_ECB; - sctx->current_hash_req = NULL; - sctx->current_cypher_req = req; - bctx->aes_encmode = SEP_AES_DECRYPT; - bctx->aes_opmode = SEP_AES_ECB; - bctx->init_opcode = SEP_AES_INIT_OPCODE; - bctx->block_opcode = SEP_AES_BLOCK_OPCODE; + /* Clear out task context */ + memset(ta_ctx, 0, sizeof(struct this_task_ctx)); + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = AES_ECB; + ta_ctx->current_hash_req = NULL; + ta_ctx->current_cypher_req = req; + ta_ctx->aes_encmode = SEP_AES_DECRYPT; + ta_ctx->aes_opmode = SEP_AES_ECB; + ta_ctx->init_opcode = SEP_AES_INIT_OPCODE; + ta_ctx->block_opcode = SEP_AES_BLOCK_OPCODE; + + /* lock necessary so that only one entity touches the queues */ spin_lock_irq(&queue_lock); error = crypto_enqueue_request(&sep_queue, &req->base); - spin_unlock_irq(&queue_lock); - if ((error != 0) && (error != -EINPROGRESS)) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep_aes_ecb_decrypt cant enqueue\n"); - sep_crypto_release(sctx, error); - return error; - } - - error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, - (void *)&sep_queue); - if (error) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep_aes_ecb_decrypt cannot submit queue\n"); - sep_crypto_release(sctx, -EINVAL); - return -EINVAL; - } - return -EINPROGRESS; + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); + spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; } static int sep_aes_cbc_encrypt(struct ablkcipher_request *req) { int error; - struct sep_block_ctx *bctx = ablkcipher_request_ctx(req); + int error1; + struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req); struct sep_system_ctx *sctx = crypto_ablkcipher_ctx( crypto_ablkcipher_reqtfm(req)); - dev_dbg(&sctx->sep_used->pdev->dev, "sep aes cbc encrypt\n"); - sctx->current_request = AES_CBC; - sctx->current_hash_req = NULL; - sctx->current_cypher_req = req; - bctx->aes_encmode = SEP_AES_ENCRYPT; - bctx->aes_opmode = SEP_AES_CBC; - bctx->init_opcode = SEP_AES_INIT_OPCODE; - bctx->block_opcode = SEP_AES_BLOCK_OPCODE; + pr_debug("sep - doing aes cbc encrypt\n"); + + /* Clear out task context */ + memset(ta_ctx, 0, sizeof(struct this_task_ctx)); + + pr_debug("tfm is %p sctx is %p and ta_ctx is %p\n", + crypto_ablkcipher_reqtfm(req), sctx, ta_ctx); + + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = AES_CBC; + ta_ctx->current_hash_req = NULL; + ta_ctx->current_cypher_req = req; + ta_ctx->aes_encmode = SEP_AES_ENCRYPT; + ta_ctx->aes_opmode = SEP_AES_CBC; + ta_ctx->init_opcode = SEP_AES_INIT_OPCODE; + ta_ctx->block_opcode = SEP_AES_BLOCK_OPCODE; + /* lock necessary so that only one entity touches the queues */ spin_lock_irq(&queue_lock); error = crypto_enqueue_request(&sep_queue, &req->base); - spin_unlock_irq(&queue_lock); - if ((error != 0) && (error != -EINPROGRESS)) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep_aes_cbc_encrypt cant enqueue\n"); - sep_crypto_release(sctx, error); - return error; - } - - error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, - (void *)&sep_queue); - if (error) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep_aes_cbc_encrypt cannot submit queue\n"); - sep_crypto_release(sctx, -EINVAL); - return -EINVAL; - } - return -EINPROGRESS; + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); + spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; } static int sep_aes_cbc_decrypt(struct ablkcipher_request *req) { int error; - struct sep_block_ctx *bctx = ablkcipher_request_ctx(req); + int error1; + struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req); struct sep_system_ctx *sctx = crypto_ablkcipher_ctx( crypto_ablkcipher_reqtfm(req)); - dev_dbg(&sctx->sep_used->pdev->dev, "sep aes cbc decrypt\n"); - sctx->current_request = AES_CBC; - sctx->current_hash_req = NULL; - sctx->current_cypher_req = req; - bctx->aes_encmode = SEP_AES_DECRYPT; - bctx->aes_opmode = SEP_AES_CBC; - bctx->init_opcode = SEP_AES_INIT_OPCODE; - bctx->block_opcode = SEP_AES_BLOCK_OPCODE; + pr_debug("sep - doing aes cbc decrypt\n"); + + pr_debug("tfm is %p sctx is %p and ta_ctx is %p\n", + crypto_ablkcipher_reqtfm(req), sctx, ta_ctx); + /* Clear out task context */ + memset(ta_ctx, 0, sizeof(struct this_task_ctx)); + + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = AES_CBC; + ta_ctx->current_hash_req = NULL; + ta_ctx->current_cypher_req = req; + ta_ctx->aes_encmode = SEP_AES_DECRYPT; + ta_ctx->aes_opmode = SEP_AES_CBC; + ta_ctx->init_opcode = SEP_AES_INIT_OPCODE; + ta_ctx->block_opcode = SEP_AES_BLOCK_OPCODE; + + /* lock necessary so that only one entity touches the queues */ spin_lock_irq(&queue_lock); error = crypto_enqueue_request(&sep_queue, &req->base); - spin_unlock_irq(&queue_lock); - - if ((error != 0) && (error != -EINPROGRESS)) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep_aes_cbc_decrypt cant enqueue\n"); - sep_crypto_release(sctx, error); - return error; - } - error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, - (void *)&sep_queue); - if (error) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep_aes_cbc_decrypt cannot submit queue\n"); - sep_crypto_release(sctx, -EINVAL); - return -EINVAL; - } - return -EINPROGRESS; + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); + spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; } static int sep_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key, @@ -3304,7 +3589,7 @@ static int sep_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key, struct crypto_tfm *ctfm = crypto_ablkcipher_tfm(tfm); u32 *flags = &ctfm->crt_flags; - dev_dbg(&sctx->sep_used->pdev->dev, "sep des setkey\n"); + pr_debug("sep des setkey\n"); switch (keylen) { case DES_KEY_SIZE: @@ -3317,7 +3602,7 @@ static int sep_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key, sctx->des_nbr_keys = DES_KEY_3; break; default: - dev_dbg(&sctx->sep_used->pdev->dev, "invalid key size %x\n", + pr_debug("invalid key size %x\n", keylen); return -EINVAL; } @@ -3326,7 +3611,7 @@ static int sep_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key, (sep_weak_key(key, keylen))) { *flags |= CRYPTO_TFM_RES_WEAK_KEY; - dev_warn(&sctx->sep_used->pdev->dev, "weak key\n"); + pr_debug("weak key\n"); return -EINVAL; } @@ -3335,7 +3620,6 @@ static int sep_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key, sctx->keylen = keylen; /* Indicate to encrypt/decrypt function to send key to SEP */ sctx->key_sent = 0; - sctx->last_block = 0; return 0; } @@ -3343,153 +3627,149 @@ static int sep_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key, static int sep_des_ebc_encrypt(struct ablkcipher_request *req) { int error; - struct sep_block_ctx *bctx = ablkcipher_request_ctx(req); - struct sep_system_ctx *sctx = crypto_ablkcipher_ctx( - crypto_ablkcipher_reqtfm(req)); + int error1; + struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req); + + pr_debug("sep - doing des ecb encrypt\n"); - dev_dbg(&sctx->sep_used->pdev->dev, "sep des ecb encrypt\n"); - sctx->current_request = DES_ECB; - sctx->current_hash_req = NULL; - sctx->current_cypher_req = req; - bctx->des_encmode = SEP_DES_ENCRYPT; - bctx->des_opmode = SEP_DES_ECB; - bctx->init_opcode = SEP_DES_INIT_OPCODE; - bctx->block_opcode = SEP_DES_BLOCK_OPCODE; + /* Clear out task context */ + memset(ta_ctx, 0, sizeof(struct this_task_ctx)); + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = DES_ECB; + ta_ctx->current_hash_req = NULL; + ta_ctx->current_cypher_req = req; + ta_ctx->des_encmode = SEP_DES_ENCRYPT; + ta_ctx->des_opmode = SEP_DES_ECB; + ta_ctx->init_opcode = SEP_DES_INIT_OPCODE; + ta_ctx->block_opcode = SEP_DES_BLOCK_OPCODE; + + /* lock necessary so that only one entity touches the queues */ spin_lock_irq(&queue_lock); error = crypto_enqueue_request(&sep_queue, &req->base); - spin_unlock_irq(&queue_lock); - if ((error != 0) && (error != -EINPROGRESS)) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep_des_ecb_encrypt cant enqueue\n"); - sep_crypto_release(sctx, error); - return error; - } - - error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, - (void *)&sep_queue); - if (error) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep_des_ecb_encrypt cannot submit queue\n"); - sep_crypto_release(sctx, -EINVAL); - return -EINVAL; - } - return -EINPROGRESS; + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); + spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; } static int sep_des_ebc_decrypt(struct ablkcipher_request *req) { int error; - struct sep_block_ctx *bctx = ablkcipher_request_ctx(req); - struct sep_system_ctx *sctx = crypto_ablkcipher_ctx( - crypto_ablkcipher_reqtfm(req)); + int error1; + struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req); + + pr_debug("sep - doing des ecb decrypt\n"); - dev_dbg(&sctx->sep_used->pdev->dev, "sep des ecb decrypt\n"); - sctx->current_request = DES_ECB; - sctx->current_hash_req = NULL; - sctx->current_cypher_req = req; - bctx->des_encmode = SEP_DES_DECRYPT; - bctx->des_opmode = SEP_DES_ECB; - bctx->init_opcode = SEP_DES_INIT_OPCODE; - bctx->block_opcode = SEP_DES_BLOCK_OPCODE; + /* Clear out task context */ + memset(ta_ctx, 0, sizeof(struct this_task_ctx)); + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = DES_ECB; + ta_ctx->current_hash_req = NULL; + ta_ctx->current_cypher_req = req; + ta_ctx->des_encmode = SEP_DES_DECRYPT; + ta_ctx->des_opmode = SEP_DES_ECB; + ta_ctx->init_opcode = SEP_DES_INIT_OPCODE; + ta_ctx->block_opcode = SEP_DES_BLOCK_OPCODE; + + /* lock necessary so that only one entity touches the queues */ spin_lock_irq(&queue_lock); error = crypto_enqueue_request(&sep_queue, &req->base); - spin_unlock_irq(&queue_lock); - - if ((error != 0) && (error != -EINPROGRESS)) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep_des_ecb_decrypt cant enqueue\n"); - sep_crypto_release(sctx, error); - return error; - } - error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, - (void *)&sep_queue); - if (error) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep_des_ecb_decrypt cannot submit queue\n"); - sep_crypto_release(sctx, -EINVAL); - return -EINVAL; - } - return -EINPROGRESS; + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); + spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; } static int sep_des_cbc_encrypt(struct ablkcipher_request *req) { int error; - struct sep_block_ctx *bctx = ablkcipher_request_ctx(req); - struct sep_system_ctx *sctx = crypto_ablkcipher_ctx( - crypto_ablkcipher_reqtfm(req)); + int error1; + struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req); + + pr_debug("sep - doing des cbc encrypt\n"); - dev_dbg(&sctx->sep_used->pdev->dev, "sep des cbc encrypt\n"); - sctx->current_request = DES_CBC; - sctx->current_hash_req = NULL; - sctx->current_cypher_req = req; - bctx->des_encmode = SEP_DES_ENCRYPT; - bctx->des_opmode = SEP_DES_CBC; - bctx->init_opcode = SEP_DES_INIT_OPCODE; - bctx->block_opcode = SEP_DES_BLOCK_OPCODE; + /* Clear out task context */ + memset(ta_ctx, 0, sizeof(struct this_task_ctx)); + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = DES_CBC; + ta_ctx->current_hash_req = NULL; + ta_ctx->current_cypher_req = req; + ta_ctx->des_encmode = SEP_DES_ENCRYPT; + ta_ctx->des_opmode = SEP_DES_CBC; + ta_ctx->init_opcode = SEP_DES_INIT_OPCODE; + ta_ctx->block_opcode = SEP_DES_BLOCK_OPCODE; + + /* lock necessary so that only one entity touches the queues */ spin_lock_irq(&queue_lock); error = crypto_enqueue_request(&sep_queue, &req->base); - spin_unlock_irq(&queue_lock); - if ((error != 0) && (error != -EINPROGRESS)) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep_des_cbc_encrypt cant enqueue\n"); - sep_crypto_release(sctx, error); - return error; - } - - error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, - (void *)&sep_queue); - if (error) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep_des_cbc_encrypt cannot submit queue\n"); - sep_crypto_release(sctx, -EINVAL); - return -EINVAL; - } - return -EINPROGRESS; + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); + spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; } static int sep_des_cbc_decrypt(struct ablkcipher_request *req) { int error; - struct sep_block_ctx *bctx = ablkcipher_request_ctx(req); - struct sep_system_ctx *sctx = crypto_ablkcipher_ctx( - crypto_ablkcipher_reqtfm(req)); + int error1; + struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req); + + pr_debug("sep - doing des ecb decrypt\n"); - dev_dbg(&sctx->sep_used->pdev->dev, "sep des cbc decrypt\n"); - sctx->current_request = DES_CBC; - sctx->current_hash_req = NULL; - sctx->current_cypher_req = req; - bctx->des_encmode = SEP_DES_DECRYPT; - bctx->des_opmode = SEP_DES_CBC; - bctx->init_opcode = SEP_DES_INIT_OPCODE; - bctx->block_opcode = SEP_DES_BLOCK_OPCODE; + /* Clear out task context */ + memset(ta_ctx, 0, sizeof(struct this_task_ctx)); + ta_ctx->sep_used = sep_dev; + ta_ctx->current_request = DES_CBC; + ta_ctx->current_hash_req = NULL; + ta_ctx->current_cypher_req = req; + ta_ctx->des_encmode = SEP_DES_DECRYPT; + ta_ctx->des_opmode = SEP_DES_CBC; + ta_ctx->init_opcode = SEP_DES_INIT_OPCODE; + ta_ctx->block_opcode = SEP_DES_BLOCK_OPCODE; + + /* lock necessary so that only one entity touches the queues */ spin_lock_irq(&queue_lock); error = crypto_enqueue_request(&sep_queue, &req->base); - spin_unlock_irq(&queue_lock); - - if ((error != 0) && (error != -EINPROGRESS)) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep_des_cbc_decrypt cant enqueue\n"); - sep_crypto_release(sctx, error); - return error; - } - error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, - (void *)&sep_queue); - if (error) { - dev_warn(&sctx->sep_used->pdev->dev, - "sep_des_cbc_decrypt cannot submit queue\n"); - sep_crypto_release(sctx, -EINVAL); - return -EINVAL; - } - return -EINPROGRESS; + if ((error != 0) && (error != -EINPROGRESS)) + pr_debug(" sep - crypto enqueue failed: %x\n", + error); + error1 = sep_submit_work(ta_ctx->sep_used->workqueue, + sep_dequeuer, (void *)&sep_queue); + if (error1) + pr_debug(" sep - workqueue submit failed: %x\n", + error1); + spin_unlock_irq(&queue_lock); + /* We return result of crypto enqueue */ + return error; } static struct ahash_alg hash_algs[] = { @@ -3498,6 +3778,7 @@ static struct ahash_alg hash_algs[] = { .update = sep_sha1_update, .final = sep_sha1_final, .digest = sep_sha1_digest, + .finup = sep_sha1_finup, .halg = { .digestsize = SHA1_DIGEST_SIZE, .base = { @@ -3520,6 +3801,7 @@ static struct ahash_alg hash_algs[] = { .update = sep_md5_update, .final = sep_md5_final, .digest = sep_md5_digest, + .finup = sep_md5_finup, .halg = { .digestsize = MD5_DIGEST_SIZE, .base = { @@ -3542,6 +3824,7 @@ static struct ahash_alg hash_algs[] = { .update = sep_sha224_update, .final = sep_sha224_final, .digest = sep_sha224_digest, + .finup = sep_sha224_finup, .halg = { .digestsize = SHA224_DIGEST_SIZE, .base = { @@ -3564,6 +3847,7 @@ static struct ahash_alg hash_algs[] = { .update = sep_sha256_update, .final = sep_sha256_final, .digest = sep_sha256_digest, + .finup = sep_sha256_finup, .halg = { .digestsize = SHA256_DIGEST_SIZE, .base = { @@ -3621,6 +3905,7 @@ static struct crypto_alg crypto_algs[] = { .max_keysize = AES_MAX_KEY_SIZE, .setkey = sep_aes_setkey, .encrypt = sep_aes_cbc_encrypt, + .ivsize = AES_BLOCK_SIZE, .decrypt = sep_aes_cbc_decrypt, } }, @@ -3661,6 +3946,7 @@ static struct crypto_alg crypto_algs[] = { .max_keysize = DES_KEY_SIZE, .setkey = sep_des_setkey, .encrypt = sep_des_cbc_encrypt, + .ivsize = DES_BLOCK_SIZE, .decrypt = sep_des_cbc_decrypt, } }, @@ -3714,7 +4000,8 @@ int sep_crypto_setup(void) crypto_init_queue(&sep_queue, SEP_QUEUE_LENGTH); - sep_dev->workqueue = create_workqueue("sep_crypto_workqueue"); + sep_dev->workqueue = create_singlethread_workqueue( + "sep_crypto_workqueue"); if (!sep_dev->workqueue) { dev_warn(&sep_dev->pdev->dev, "cant create workqueue\n"); return -ENOMEM; @@ -3723,7 +4010,6 @@ int sep_crypto_setup(void) i = 0; j = 0; - spin_lock_init(&sep_dev->busy_lock); spin_lock_init(&queue_lock); err = 0; diff --git a/drivers/staging/sep/sep_crypto.h b/drivers/staging/sep/sep_crypto.h index 52c58c483c5..155c3c9b87c 100644 --- a/drivers/staging/sep/sep_crypto.h +++ b/drivers/staging/sep/sep_crypto.h @@ -117,7 +117,7 @@ #define SEP_TRANSACTION_WAIT_TIME 5 -#define SEP_QUEUE_LENGTH 10 +#define SEP_QUEUE_LENGTH 2 /* Macros */ #ifndef __LITTLE_ENDIAN #define CHG_ENDIAN(val) \ @@ -270,9 +270,26 @@ struct sep_hash_private_context { u8 internal_context[sizeof(struct sep_hash_internal_context)]; }; +union key_t { + struct sep_des_key des; + u32 aes[SEP_AES_MAX_KEY_SIZE_WORDS]; +}; + /* Context structures for crypto API */ -struct sep_block_ctx { - struct sep_device *sep; +/** + * Structure for this current task context + * This same structure is used for both hash + * and crypt in order to reduce duplicate code + * for stuff that is done for both hash operations + * and crypto operations. We cannot trust that the + * system context is not pulled out from under + * us during operation to operation, so all + * critical stuff such as data pointers must + * be in in a context that is exclusive for this + * particular task at hand. + */ +struct this_task_ctx { + struct sep_device *sep_used; u32 done; unsigned char iv[100]; enum des_enc_mode des_encmode; @@ -284,36 +301,7 @@ struct sep_block_ctx { size_t data_length; size_t ivlen; struct ablkcipher_walk walk; - struct sep_des_private_context des_private_ctx; - struct sep_aes_private_context aes_private_ctx; - }; - -struct sep_hash_ctx { - u32 done; - unsigned char *buf; - size_t buflen; - unsigned char *dgst; - int digest_size_words; - int digest_size_bytes; - int block_size_words; - int block_size_bytes; - struct scatterlist *sg; - enum hash_op_mode hash_opmode; - struct sep_hash_private_context hash_private_ctx; - }; - -struct sep_system_ctx { - struct sep_device *sep_used; - union key_t { - struct sep_des_key des; - u32 aes[SEP_AES_MAX_KEY_SIZE_WORDS]; - } key; int i_own_sep; /* Do I have custody of the sep? */ - size_t keylen; - enum des_numkey des_nbr_keys; - enum aes_keysize aes_key_size; - u32 key_sent; /* Indicate if key is sent to sep */ - u32 last_block; /* Indicate that this is the final block */ struct sep_call_status call_status; struct build_dcb_struct_kernel dcb_input_data; struct sep_dma_context *dma_ctx; @@ -331,9 +319,32 @@ struct sep_system_ctx { struct ahash_request *current_hash_req; struct ablkcipher_request *current_cypher_req; enum type_of_request current_request; + int digest_size_words; + int digest_size_bytes; + int block_size_words; + int block_size_bytes; + enum hash_op_mode hash_opmode; enum hash_stage current_hash_stage; - int done_with_transaction; + /** + * Not that this is a pointer. The are_we_done_yet variable is + * allocated by the task function. This way, even if the kernel + * crypto infrastructure has grabbed the task structure out from + * under us, the task function can still see this variable. + */ + int *are_we_done_yet; + unsigned long end_time; + }; + +struct sep_system_ctx { + union key_t key; + size_t keylen; + int key_sent; + enum des_numkey des_nbr_keys; + enum aes_keysize aes_key_size; unsigned long end_time; + struct sep_des_private_context des_private_ctx; + struct sep_aes_private_context aes_private_ctx; + struct sep_hash_private_context hash_private_ctx; }; /* work queue structures */ diff --git a/drivers/staging/sep/sep_dev.h b/drivers/staging/sep/sep_dev.h index 66d8e95523b..5f6a07f59dd 100644 --- a/drivers/staging/sep/sep_dev.h +++ b/drivers/staging/sep/sep_dev.h @@ -93,8 +93,7 @@ struct sep_device { enum hash_stage current_hash_stage; struct ahash_request *current_hash_req; struct ablkcipher_request *current_cypher_req; - struct sep_system_ctx *sctx; - spinlock_t busy_lock; + struct this_task_ctx *ta_ctx; struct workqueue_struct *workqueue; }; -- cgit v1.2.3-70-g09d2 From 548dd4b6da8a8e428453d55f7fa7b8a46498d147 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 10 Feb 2012 13:20:49 +0100 Subject: USB: serial: fix console error reporting Do not report errors in write path if port is used as a console as this may trigger the same error (and error report) resulting in a loop. Reported-by: Stephen Hemminger Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/generic.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index f7403576f99..e129fcd69fd 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -217,8 +217,10 @@ retry: clear_bit(i, &port->write_urbs_free); result = usb_submit_urb(urb, GFP_ATOMIC); if (result) { - dev_err(&port->dev, "%s - error submitting urb: %d\n", + if (!port->port.console) { + dev_err(&port->dev, "%s - error submitting urb: %d\n", __func__, result); + } set_bit(i, &port->write_urbs_free); spin_lock_irqsave(&port->lock, flags); port->tx_bytes -= count; -- cgit v1.2.3-70-g09d2 From f1475a00a11b07e6ac7f97971466c1bfbf491957 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 10 Feb 2012 13:20:50 +0100 Subject: USB: serial: use dev_err_console in generic write Use dev_err_console in write path so that an error at least gets reported once. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/generic.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index e129fcd69fd..2a2fa2d0489 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -217,10 +217,8 @@ retry: clear_bit(i, &port->write_urbs_free); result = usb_submit_urb(urb, GFP_ATOMIC); if (result) { - if (!port->port.console) { - dev_err(&port->dev, "%s - error submitting urb: %d\n", + dev_err_console(port, "%s - error submitting urb: %d\n", __func__, result); - } set_bit(i, &port->write_urbs_free); spin_lock_irqsave(&port->lock, flags); port->tx_bytes -= count; -- cgit v1.2.3-70-g09d2 From 22a416c4e0f2179b57028e084ac0ed2c110333bd Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 10 Feb 2012 13:20:51 +0100 Subject: USB: serial: use dev_err_console in custom write paths Use dev_err_console in write paths for devices which can be used as a console but do not use the generic write implementation. Compile-only tested. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cypress_m8.c | 2 +- drivers/usb/serial/digi_acceleport.c | 4 ++-- drivers/usb/serial/io_edgeport.c | 4 ++-- drivers/usb/serial/io_ti.c | 4 ++-- drivers/usb/serial/mos7720.c | 4 ++-- drivers/usb/serial/mos7840.c | 4 ++-- drivers/usb/serial/omninet.c | 2 +- drivers/usb/serial/oti6858.c | 6 +++--- drivers/usb/serial/ti_usb_3410_5052.c | 5 ++--- drivers/usb/serial/whiteheat.c | 2 +- 10 files changed, 18 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 3bdeafa29c2..5ae86b349ca 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -800,7 +800,7 @@ send: cypress_write_int_callback, port, priv->write_urb_interval); result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC); if (result) { - dev_err(&port->dev, + dev_err_console(port, "%s - failed submitting write urb, error %d\n", __func__, result); priv->write_urb_in_use = 0; diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index b23bebd721a..2b1da0cc071 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -995,7 +995,7 @@ static int digi_write(struct tty_struct *tty, struct usb_serial_port *port, /* return length of new data written, or error */ spin_unlock_irqrestore(&priv->dp_port_lock, flags); if (ret < 0) - dev_err(&port->dev, + dev_err_console(port, "%s: usb_submit_urb failed, ret=%d, port=%d\n", __func__, ret, priv->dp_port_num); dbg("digi_write: returning %d", ret); @@ -1065,7 +1065,7 @@ static void digi_write_bulk_callback(struct urb *urb) spin_unlock(&priv->dp_port_lock); if (ret && ret != -EPERM) - dev_err(&port->dev, + dev_err_console(port, "%s: usb_submit_urb failed, ret=%d, port=%d\n", __func__, ret, priv->dp_port_num); } diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 0497575e479..616b0786277 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -1286,7 +1286,7 @@ static void send_more_port_data(struct edgeport_serial *edge_serial, count = fifo->count; buffer = kmalloc(count+2, GFP_ATOMIC); if (buffer == NULL) { - dev_err(&edge_port->port->dev, + dev_err_console(edge_port->port, "%s - no more kernel memory...\n", __func__); edge_port->write_in_progress = false; goto exit_send; @@ -1331,7 +1331,7 @@ static void send_more_port_data(struct edgeport_serial *edge_serial, status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { /* something went wrong */ - dev_err(&edge_port->port->dev, + dev_err_console(edge_port->port, "%s - usb_submit_urb(write bulk) failed, status = %d, data lost\n", __func__, status); edge_port->write_in_progress = false; diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 65bf06aa591..311e4bf46de 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -1817,7 +1817,7 @@ static void edge_bulk_out_callback(struct urb *urb) __func__, status); return; default: - dev_err(&urb->dev->dev, "%s - nonzero write bulk status " + dev_err_console(port, "%s - nonzero write bulk status " "received: %d\n", __func__, status); } @@ -2111,7 +2111,7 @@ static void edge_send(struct tty_struct *tty) /* send the data out the bulk port */ result = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (result) { - dev_err(&port->dev, + dev_err_console(port, "%s - failed submitting write urb, error %d\n", __func__, result); edge_port->ep_write_urb_in_use = 0; diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 4554ee49e63..4fb29b4aaad 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -1294,7 +1294,7 @@ static int mos7720_write(struct tty_struct *tty, struct usb_serial_port *port, urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL); if (urb->transfer_buffer == NULL) { - dev_err(&port->dev, "%s no more kernel memory...\n", + dev_err_console(port, "%s no more kernel memory...\n", __func__); goto exit; } @@ -1315,7 +1315,7 @@ static int mos7720_write(struct tty_struct *tty, struct usb_serial_port *port, /* send it down the pipe */ status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { - dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed " + dev_err_console(port, "%s - usb_submit_urb(write bulk) failed " "with status = %d\n", __func__, status); bytes_sent = status; goto exit; diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 03b5e249e95..19b11cece6b 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -1509,7 +1509,7 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port, kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL); if (urb->transfer_buffer == NULL) { - dev_err(&port->dev, "%s no more kernel memory...\n", + dev_err_console(port, "%s no more kernel memory...\n", __func__); goto exit; } @@ -1535,7 +1535,7 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port, if (status) { mos7840_port->busy[i] = 0; - dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed " + dev_err_console(port, "%s - usb_submit_urb(write bulk) failed " "with status = %d\n", __func__, status); bytes_sent = status; goto exit; diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 8b8d58a2ac1..033e8afa6c7 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -254,7 +254,7 @@ static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port, result = usb_submit_urb(wport->write_urb, GFP_ATOMIC); if (result) { set_bit(0, &wport->write_urbs_free); - dev_err(&port->dev, + dev_err_console(port, "%s - failed submitting write urb, error %d\n", __func__, result); } else diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index e287fd32682..343e626a06f 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c @@ -302,7 +302,7 @@ static void send_data(struct work_struct *work) if (count != 0) { allow = kmalloc(1, GFP_KERNEL); if (!allow) { - dev_err(&port->dev, "%s(): kmalloc failed\n", + dev_err_console(port, "%s(): kmalloc failed\n", __func__); return; } @@ -334,7 +334,7 @@ static void send_data(struct work_struct *work) port->write_urb->transfer_buffer_length = count; result = usb_submit_urb(port->write_urb, GFP_NOIO); if (result != 0) { - dev_err(&port->dev, "%s(): usb_submit_urb() failed" + dev_err_console(port, "%s(): usb_submit_urb() failed" " with error %d\n", __func__, result); priv->flags.write_urb_in_use = 0; } @@ -938,7 +938,7 @@ static void oti6858_write_bulk_callback(struct urb *urb) port->write_urb->transfer_buffer_length = 1; result = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (result) { - dev_err(&port->dev, "%s(): usb_submit_urb() failed," + dev_err_console(port, "%s(): usb_submit_urb() failed," " error %d\n", __func__, result); } else { return; diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 8468eb769a2..91d0dc64036 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -1248,7 +1248,6 @@ static void ti_bulk_out_callback(struct urb *urb) { struct ti_port *tport = urb->context; struct usb_serial_port *port = tport->tp_port; - struct device *dev = &urb->dev->dev; int status = urb->status; dbg("%s - port %d", __func__, port->number); @@ -1266,7 +1265,7 @@ static void ti_bulk_out_callback(struct urb *urb) wake_up_interruptible(&tport->tp_write_wait); return; default: - dev_err(dev, "%s - nonzero urb status, %d\n", + dev_err_console(port, "%s - nonzero urb status, %d\n", __func__, status); tport->tp_tdev->td_urb_error = 1; wake_up_interruptible(&tport->tp_write_wait); @@ -1335,7 +1334,7 @@ static void ti_send(struct ti_port *tport) result = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (result) { - dev_err(&port->dev, "%s - submit write urb failed, %d\n", + dev_err_console(port, "%s - submit write urb failed, %d\n", __func__, result); tport->tp_write_urb_in_use = 0; /* TODO: reschedule ti_send */ diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 7e0acf5c8e3..007cf3a2481 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -740,7 +740,7 @@ static int whiteheat_write(struct tty_struct *tty, urb->transfer_buffer_length = bytes; result = usb_submit_urb(urb, GFP_ATOMIC); if (result) { - dev_err(&port->dev, + dev_err_console(port, "%s - failed submitting write urb, error %d\n", __func__, result); sent = result; -- cgit v1.2.3-70-g09d2 From 6816383a09b5be8d35f14f4c25dedb64498e4959 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Thu, 9 Feb 2012 18:48:19 -0500 Subject: tty: sparc: rename drivers/tty/serial/suncore.h -> include/linux/sunserialcore.h There are multiple users of this file from different source paths now, and rather than have ../ paths in include statements, just move the file to the linux header dir. Suggested-by: David S. Miller Signed-off-by: Paul Gortmaker Acked-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 2 +- drivers/tty/serial/8250/8250.c | 7 +++---- drivers/tty/serial/suncore.c | 2 +- drivers/tty/serial/suncore.h | 33 --------------------------------- drivers/tty/serial/sunhv.c | 3 +-- drivers/tty/serial/sunsab.c | 2 +- drivers/tty/serial/sunsu.c | 3 +-- drivers/tty/serial/sunzilog.c | 2 +- include/linux/sunserialcore.h | 33 +++++++++++++++++++++++++++++++++ 9 files changed, 42 insertions(+), 45 deletions(-) delete mode 100644 drivers/tty/serial/suncore.h create mode 100644 include/linux/sunserialcore.h (limited to 'drivers') diff --git a/MAINTAINERS b/MAINTAINERS index 9a648eb8e21..27c052cc883 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6187,8 +6187,8 @@ L: sparclinux@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6.git S: Maintained +F: include/linux/sunserialcore.h F: drivers/tty/serial/suncore.c -F: drivers/tty/serial/suncore.h F: drivers/tty/serial/sunhv.c F: drivers/tty/serial/sunsab.c F: drivers/tty/serial/sunsab.h diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c index b423d0f962a..917ab845274 100644 --- a/drivers/tty/serial/8250/8250.c +++ b/drivers/tty/serial/8250/8250.c @@ -38,16 +38,15 @@ #include #include #include +#ifdef CONFIG_SPARC +#include +#endif #include #include #include "8250.h" -#ifdef CONFIG_SPARC -#include "../suncore.h" -#endif - /* * Configuration: * share_irqs - whether we pass IRQF_SHARED to request_irq(). This option diff --git a/drivers/tty/serial/suncore.c b/drivers/tty/serial/suncore.c index 6381a0282ee..6e4ac8db2d7 100644 --- a/drivers/tty/serial/suncore.c +++ b/drivers/tty/serial/suncore.c @@ -17,11 +17,11 @@ #include #include #include +#include #include #include -#include "suncore.h" static int sunserial_current_minor = 64; diff --git a/drivers/tty/serial/suncore.h b/drivers/tty/serial/suncore.h deleted file mode 100644 index db2057936c3..00000000000 --- a/drivers/tty/serial/suncore.h +++ /dev/null @@ -1,33 +0,0 @@ -/* suncore.h - * - * Generic SUN serial/kbd/ms layer. Based entirely - * upon drivers/sbus/char/sunserial.h which is: - * - * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) - * - * Port to new UART layer is: - * - * Copyright (C) 2002 David S. Miller (davem@redhat.com) - */ - -#ifndef _SERIAL_SUN_H -#define _SERIAL_SUN_H - -/* Serial keyboard defines for L1-A processing... */ -#define SUNKBD_RESET 0xff -#define SUNKBD_L1 0x01 -#define SUNKBD_UP 0x80 -#define SUNKBD_A 0x4d - -extern unsigned int suncore_mouse_baud_cflag_next(unsigned int, int *); -extern int suncore_mouse_baud_detection(unsigned char, int); - -extern int sunserial_register_minors(struct uart_driver *, int); -extern void sunserial_unregister_minors(struct uart_driver *, int); - -extern int sunserial_console_match(struct console *, struct device_node *, - struct uart_driver *, int, bool); -extern void sunserial_console_termios(struct console *, - struct device_node *); - -#endif /* !(_SERIAL_SUN_H) */ diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c index c0b7246d733..3ba5d285c2d 100644 --- a/drivers/tty/serial/sunhv.c +++ b/drivers/tty/serial/sunhv.c @@ -29,8 +29,7 @@ #endif #include - -#include "suncore.h" +#include #define CON_BREAK ((long)-1) #define CON_HUP ((long)-2) diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c index b5fa2a57b9d..62dacd0ba52 100644 --- a/drivers/tty/serial/sunsab.c +++ b/drivers/tty/serial/sunsab.c @@ -43,8 +43,8 @@ #endif #include +#include -#include "suncore.h" #include "sunsab.h" struct uart_sunsab_port { diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c index ad0f8f5f6ea..d3ca6da129f 100644 --- a/drivers/tty/serial/sunsu.c +++ b/drivers/tty/serial/sunsu.c @@ -47,8 +47,7 @@ #endif #include - -#include "suncore.h" +#include /* We are on a NS PC87303 clocked with 24.0 MHz, which results * in a UART clock of 1.8462 MHz. diff --git a/drivers/tty/serial/sunzilog.c b/drivers/tty/serial/sunzilog.c index 5a47d1b196d..da4415842a4 100644 --- a/drivers/tty/serial/sunzilog.c +++ b/drivers/tty/serial/sunzilog.c @@ -43,8 +43,8 @@ #endif #include +#include -#include "suncore.h" #include "sunzilog.h" /* On 32-bit sparcs we need to delay after register accesses diff --git a/include/linux/sunserialcore.h b/include/linux/sunserialcore.h new file mode 100644 index 00000000000..68e7430bb0f --- /dev/null +++ b/include/linux/sunserialcore.h @@ -0,0 +1,33 @@ +/* sunserialcore.h + * + * Generic SUN serial/kbd/ms layer. Based entirely + * upon drivers/sbus/char/sunserial.h which is: + * + * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) + * + * Port to new UART layer is: + * + * Copyright (C) 2002 David S. Miller (davem@redhat.com) + */ + +#ifndef _SERIAL_SUN_H +#define _SERIAL_SUN_H + +/* Serial keyboard defines for L1-A processing... */ +#define SUNKBD_RESET 0xff +#define SUNKBD_L1 0x01 +#define SUNKBD_UP 0x80 +#define SUNKBD_A 0x4d + +extern unsigned int suncore_mouse_baud_cflag_next(unsigned int, int *); +extern int suncore_mouse_baud_detection(unsigned char, int); + +extern int sunserial_register_minors(struct uart_driver *, int); +extern void sunserial_unregister_minors(struct uart_driver *, int); + +extern int sunserial_console_match(struct console *, struct device_node *, + struct uart_driver *, int, bool); +extern void sunserial_console_termios(struct console *, + struct device_node *); + +#endif /* !(_SERIAL_SUN_H) */ -- cgit v1.2.3-70-g09d2 From e75892715db800ee96fe4ac0407b73b57d866a68 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Sat, 30 Jul 2011 01:25:29 +0000 Subject: viafb: add auxiliary device management infrastructure This patch adds the basic infrastructure and a few stub drivers for devices that are connected via I2C busses. The infrastructure will be used to replace and extend the support that is scattered throughout viafb. The stub drivers are not very useful yet but they show how the infrastructure works, provide information about the chips integrated into a system and maybe gather some testers as it would be very difficult for a single person to get a sane test environment. The only thing this actually does is probing the I2C busses which will hopefully not cause any regressions. Signed-off-by: Florian Tobias Schandinat --- drivers/video/via/Makefile | 5 ++- drivers/video/via/via_aux.c | 68 +++++++++++++++++++++++++++++ drivers/video/via/via_aux.h | 87 ++++++++++++++++++++++++++++++++++++++ drivers/video/via/via_aux_ch7301.c | 50 ++++++++++++++++++++++ drivers/video/via/via_aux_edid.c | 40 ++++++++++++++++++ drivers/video/via/via_aux_sii164.c | 54 +++++++++++++++++++++++ drivers/video/via/via_aux_vt1621.c | 44 +++++++++++++++++++ drivers/video/via/via_aux_vt1622.c | 50 ++++++++++++++++++++++ drivers/video/via/via_aux_vt1625.c | 50 ++++++++++++++++++++++ drivers/video/via/via_aux_vt1631.c | 46 ++++++++++++++++++++ drivers/video/via/via_aux_vt1632.c | 54 +++++++++++++++++++++++ drivers/video/via/via_aux_vt1636.c | 46 ++++++++++++++++++++ drivers/video/via/viafbdev.c | 27 ++++++++++++ drivers/video/via/viafbdev.h | 6 +++ 14 files changed, 626 insertions(+), 1 deletion(-) create mode 100644 drivers/video/via/via_aux.c create mode 100644 drivers/video/via/via_aux.h create mode 100644 drivers/video/via/via_aux_ch7301.c create mode 100644 drivers/video/via/via_aux_edid.c create mode 100644 drivers/video/via/via_aux_sii164.c create mode 100644 drivers/video/via/via_aux_vt1621.c create mode 100644 drivers/video/via/via_aux_vt1622.c create mode 100644 drivers/video/via/via_aux_vt1625.c create mode 100644 drivers/video/via/via_aux_vt1631.c create mode 100644 drivers/video/via/via_aux_vt1632.c create mode 100644 drivers/video/via/via_aux_vt1636.c (limited to 'drivers') diff --git a/drivers/video/via/Makefile b/drivers/video/via/Makefile index 5108136e877..159f26e6adb 100644 --- a/drivers/video/via/Makefile +++ b/drivers/video/via/Makefile @@ -6,4 +6,7 @@ obj-$(CONFIG_FB_VIA) += viafb.o viafb-y :=viafbdev.o hw.o via_i2c.o dvi.o lcd.o ioctl.o accel.o \ via_utility.o vt1636.o global.o tblDPASetting.o viamode.o \ - via-core.o via-gpio.o via_modesetting.o via_clock.o + via-core.o via-gpio.o via_modesetting.o via_clock.o \ + via_aux.o via_aux_edid.o via_aux_vt1636.o via_aux_vt1632.o \ + via_aux_vt1631.o via_aux_vt1625.o via_aux_vt1622.o via_aux_vt1621.o \ + via_aux_sii164.o via_aux_ch7301.o diff --git a/drivers/video/via/via_aux.c b/drivers/video/via/via_aux.c new file mode 100644 index 00000000000..e728b9bec23 --- /dev/null +++ b/drivers/video/via/via_aux.c @@ -0,0 +1,68 @@ +/* + * Copyright 2011 Florian Tobias Schandinat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; + * either version 2, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE.See the GNU General Public License + * for more details. + * + * You 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. + */ +/* + * infrastructure for devices connected via I2C + */ + +#include +#include "via_aux.h" + + +struct via_aux_bus *via_aux_probe(struct i2c_adapter *adap) +{ + struct via_aux_bus *bus; + + if (!adap) + return NULL; + + bus = kmalloc(sizeof(*bus), GFP_KERNEL); + if (!bus) + return NULL; + + bus->adap = adap; + INIT_LIST_HEAD(&bus->drivers); + + via_aux_edid_probe(bus); + via_aux_vt1636_probe(bus); + via_aux_vt1632_probe(bus); + via_aux_vt1631_probe(bus); + via_aux_vt1625_probe(bus); + via_aux_vt1622_probe(bus); + via_aux_vt1621_probe(bus); + via_aux_sii164_probe(bus); + via_aux_ch7301_probe(bus); + + return bus; +} + +void via_aux_free(struct via_aux_bus *bus) +{ + struct via_aux_drv *pos, *n; + + if (!bus) + return; + + list_for_each_entry_safe(pos, n, &bus->drivers, chain) { + list_del(&pos->chain); + kfree(pos); + } + + kfree(bus); +} diff --git a/drivers/video/via/via_aux.h b/drivers/video/via/via_aux.h new file mode 100644 index 00000000000..5a4867a2dcc --- /dev/null +++ b/drivers/video/via/via_aux.h @@ -0,0 +1,87 @@ +/* + * Copyright 2011 Florian Tobias Schandinat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; + * either version 2, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE.See the GNU General Public License + * for more details. + * + * You 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. + */ +/* + * infrastructure for devices connected via I2C + */ + +#ifndef __VIA_AUX_H__ +#define __VIA_AUX_H__ + + +#include +#include + + +struct via_aux_bus { + struct i2c_adapter *adap; /* the I2C device to access the bus */ + struct list_head drivers; /* drivers for devices on this bus */ +}; + +struct via_aux_drv { + struct list_head chain; /* chain to support multiple drivers */ + + struct via_aux_bus *bus; /* the I2C bus used */ + u8 addr; /* the I2C slave address */ + + const char *name; /* human readable name of the driver */ + void *data; /* private data of this driver */ +}; + + +struct via_aux_bus *via_aux_probe(struct i2c_adapter *adap); +void via_aux_free(struct via_aux_bus *bus); + + +static inline bool via_aux_add(struct via_aux_drv *drv) +{ + struct via_aux_drv *data = kmalloc(sizeof(*data), GFP_KERNEL); + + if (!data) + return false; + + *data = *drv; + list_add_tail(&data->chain, &data->bus->drivers); + return true; +} + +static inline bool via_aux_read(struct via_aux_drv *drv, u8 start, u8 *buf, + u8 len) +{ + struct i2c_msg msg[2] = { + {.addr = drv->addr, .flags = 0, .len = 1, .buf = &start}, + {.addr = drv->addr, .flags = I2C_M_RD, .len = len, .buf = buf} }; + + return i2c_transfer(drv->bus->adap, msg, 2) == 2; +} + + +/* probe functions of existing drivers - should only be called in via_aux.c */ +void via_aux_ch7301_probe(struct via_aux_bus *bus); +void via_aux_edid_probe(struct via_aux_bus *bus); +void via_aux_sii164_probe(struct via_aux_bus *bus); +void via_aux_vt1636_probe(struct via_aux_bus *bus); +void via_aux_vt1632_probe(struct via_aux_bus *bus); +void via_aux_vt1631_probe(struct via_aux_bus *bus); +void via_aux_vt1625_probe(struct via_aux_bus *bus); +void via_aux_vt1622_probe(struct via_aux_bus *bus); +void via_aux_vt1621_probe(struct via_aux_bus *bus); + + +#endif /* __VIA_AUX_H__ */ diff --git a/drivers/video/via/via_aux_ch7301.c b/drivers/video/via/via_aux_ch7301.c new file mode 100644 index 00000000000..1cbe5037a6b --- /dev/null +++ b/drivers/video/via/via_aux_ch7301.c @@ -0,0 +1,50 @@ +/* + * Copyright 2011 Florian Tobias Schandinat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; + * either version 2, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE.See the GNU General Public License + * for more details. + * + * You 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. + */ +/* + * driver for Chrontel CH7301 DVI Transmitter + */ + +#include +#include "via_aux.h" + + +static const char *name = "CH7301 DVI Transmitter"; + + +static void probe(struct via_aux_bus *bus, u8 addr) +{ + struct via_aux_drv drv = { + .bus = bus, + .addr = addr, + .name = name}; + u8 tmp; + + if (!via_aux_read(&drv, 0x4B, &tmp, 1) || tmp != 0x17) + return; + + printk(KERN_INFO "viafb: Found %s at address 0x%x\n", name, addr); + via_aux_add(&drv); +} + +void via_aux_ch7301_probe(struct via_aux_bus *bus) +{ + probe(bus, 0x75); + probe(bus, 0x76); +} diff --git a/drivers/video/via/via_aux_edid.c b/drivers/video/via/via_aux_edid.c new file mode 100644 index 00000000000..547bff53a44 --- /dev/null +++ b/drivers/video/via/via_aux_edid.c @@ -0,0 +1,40 @@ +/* + * Copyright 2011 Florian Tobias Schandinat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; + * either version 2, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE.See the GNU General Public License + * for more details. + * + * You 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. + */ +/* + * generic EDID driver + */ + +#include +#include "via_aux.h" + + +static const char *name = "EDID"; + + +void via_aux_edid_probe(struct via_aux_bus *bus) +{ + struct via_aux_drv drv = { + .bus = bus, + .addr = 0x50, + .name = name}; + + /* as EDID devices can be connected/disconnected just add the driver */ + via_aux_add(&drv); +} diff --git a/drivers/video/via/via_aux_sii164.c b/drivers/video/via/via_aux_sii164.c new file mode 100644 index 00000000000..ca1b35f033b --- /dev/null +++ b/drivers/video/via/via_aux_sii164.c @@ -0,0 +1,54 @@ +/* + * Copyright 2011 Florian Tobias Schandinat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; + * either version 2, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE.See the GNU General Public License + * for more details. + * + * You 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. + */ +/* + * driver for Silicon Image SiI 164 PanelLink Transmitter + */ + +#include +#include "via_aux.h" + + +static const char *name = "SiI 164 PanelLink Transmitter"; + + +static void probe(struct via_aux_bus *bus, u8 addr) +{ + struct via_aux_drv drv = { + .bus = bus, + .addr = addr, + .name = name}; + /* check vendor id and device id */ + const u8 id[] = {0x01, 0x00, 0x06, 0x00}, len = ARRAY_SIZE(id); + u8 tmp[len]; + + if (!via_aux_read(&drv, 0x00, tmp, len) || memcmp(id, tmp, len)) + return; + + printk(KERN_INFO "viafb: Found %s at address 0x%x\n", name, addr); + via_aux_add(&drv); +} + +void via_aux_sii164_probe(struct via_aux_bus *bus) +{ + u8 i; + + for (i = 0x38; i <= 0x3F; i++) + probe(bus, i); +} diff --git a/drivers/video/via/via_aux_vt1621.c b/drivers/video/via/via_aux_vt1621.c new file mode 100644 index 00000000000..38eca847989 --- /dev/null +++ b/drivers/video/via/via_aux_vt1621.c @@ -0,0 +1,44 @@ +/* + * Copyright 2011 Florian Tobias Schandinat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; + * either version 2, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE.See the GNU General Public License + * for more details. + * + * You 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. + */ +/* + * driver for VIA VT1621(M) TV Encoder + */ + +#include +#include "via_aux.h" + + +static const char *name = "VT1621(M) TV Encoder"; + + +void via_aux_vt1621_probe(struct via_aux_bus *bus) +{ + struct via_aux_drv drv = { + .bus = bus, + .addr = 0x20, + .name = name}; + u8 tmp; + + if (!via_aux_read(&drv, 0x1B, &tmp, 1) || tmp != 0x02) + return; + + printk(KERN_INFO "viafb: Found %s\n", name); + via_aux_add(&drv); +} diff --git a/drivers/video/via/via_aux_vt1622.c b/drivers/video/via/via_aux_vt1622.c new file mode 100644 index 00000000000..8c79c68ba68 --- /dev/null +++ b/drivers/video/via/via_aux_vt1622.c @@ -0,0 +1,50 @@ +/* + * Copyright 2011 Florian Tobias Schandinat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; + * either version 2, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE.See the GNU General Public License + * for more details. + * + * You 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. + */ +/* + * driver for VIA VT1622(M) Digital TV Encoder + */ + +#include +#include "via_aux.h" + + +static const char *name = "VT1622(M) Digital TV Encoder"; + + +static void probe(struct via_aux_bus *bus, u8 addr) +{ + struct via_aux_drv drv = { + .bus = bus, + .addr = addr, + .name = name}; + u8 tmp; + + if (!via_aux_read(&drv, 0x1B, &tmp, 1) || tmp != 0x03) + return; + + printk(KERN_INFO "viafb: Found %s at address 0x%x\n", name, addr); + via_aux_add(&drv); +} + +void via_aux_vt1622_probe(struct via_aux_bus *bus) +{ + probe(bus, 0x20); + probe(bus, 0x21); +} diff --git a/drivers/video/via/via_aux_vt1625.c b/drivers/video/via/via_aux_vt1625.c new file mode 100644 index 00000000000..03eb30165d3 --- /dev/null +++ b/drivers/video/via/via_aux_vt1625.c @@ -0,0 +1,50 @@ +/* + * Copyright 2011 Florian Tobias Schandinat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; + * either version 2, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE.See the GNU General Public License + * for more details. + * + * You 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. + */ +/* + * driver for VIA VT1625(M) HDTV Encoder + */ + +#include +#include "via_aux.h" + + +static const char *name = "VT1625(M) HDTV Encoder"; + + +static void probe(struct via_aux_bus *bus, u8 addr) +{ + struct via_aux_drv drv = { + .bus = bus, + .addr = addr, + .name = name}; + u8 tmp; + + if (!via_aux_read(&drv, 0x1B, &tmp, 1) || tmp != 0x50) + return; + + printk(KERN_INFO "viafb: Found %s at address 0x%x\n", name, addr); + via_aux_add(&drv); +} + +void via_aux_vt1625_probe(struct via_aux_bus *bus) +{ + probe(bus, 0x20); + probe(bus, 0x21); +} diff --git a/drivers/video/via/via_aux_vt1631.c b/drivers/video/via/via_aux_vt1631.c new file mode 100644 index 00000000000..06e742f1f72 --- /dev/null +++ b/drivers/video/via/via_aux_vt1631.c @@ -0,0 +1,46 @@ +/* + * Copyright 2011 Florian Tobias Schandinat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; + * either version 2, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE.See the GNU General Public License + * for more details. + * + * You 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. + */ +/* + * driver for VIA VT1631 LVDS Transmitter + */ + +#include +#include "via_aux.h" + + +static const char *name = "VT1631 LVDS Transmitter"; + + +void via_aux_vt1631_probe(struct via_aux_bus *bus) +{ + struct via_aux_drv drv = { + .bus = bus, + .addr = 0x38, + .name = name}; + /* check vendor id and device id */ + const u8 id[] = {0x06, 0x11, 0x91, 0x31}, len = ARRAY_SIZE(id); + u8 tmp[len]; + + if (!via_aux_read(&drv, 0x00, tmp, len) || memcmp(id, tmp, len)) + return; + + printk(KERN_INFO "viafb: Found %s\n", name); + via_aux_add(&drv); +} diff --git a/drivers/video/via/via_aux_vt1632.c b/drivers/video/via/via_aux_vt1632.c new file mode 100644 index 00000000000..d24f4cd9740 --- /dev/null +++ b/drivers/video/via/via_aux_vt1632.c @@ -0,0 +1,54 @@ +/* + * Copyright 2011 Florian Tobias Schandinat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; + * either version 2, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE.See the GNU General Public License + * for more details. + * + * You 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. + */ +/* + * driver for VIA VT1632 DVI Transmitter + */ + +#include +#include "via_aux.h" + + +static const char *name = "VT1632 DVI Transmitter"; + + +static void probe(struct via_aux_bus *bus, u8 addr) +{ + struct via_aux_drv drv = { + .bus = bus, + .addr = addr, + .name = name}; + /* check vendor id and device id */ + const u8 id[] = {0x06, 0x11, 0x92, 0x31}, len = ARRAY_SIZE(id); + u8 tmp[len]; + + if (!via_aux_read(&drv, 0x00, tmp, len) || memcmp(id, tmp, len)) + return; + + printk(KERN_INFO "viafb: Found %s at address 0x%x\n", name, addr); + via_aux_add(&drv); +} + +void via_aux_vt1632_probe(struct via_aux_bus *bus) +{ + u8 i; + + for (i = 0x08; i <= 0x0F; i++) + probe(bus, i); +} diff --git a/drivers/video/via/via_aux_vt1636.c b/drivers/video/via/via_aux_vt1636.c new file mode 100644 index 00000000000..9e015c101d4 --- /dev/null +++ b/drivers/video/via/via_aux_vt1636.c @@ -0,0 +1,46 @@ +/* + * Copyright 2011 Florian Tobias Schandinat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; + * either version 2, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE.See the GNU General Public License + * for more details. + * + * You 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. + */ +/* + * driver for VIA VT1636 LVDS Transmitter + */ + +#include +#include "via_aux.h" + + +static const char *name = "VT1636 LVDS Transmitter"; + + +void via_aux_vt1636_probe(struct via_aux_bus *bus) +{ + struct via_aux_drv drv = { + .bus = bus, + .addr = 0x40, + .name = name}; + /* check vendor id and device id */ + const u8 id[] = {0x06, 0x11, 0x45, 0x33}, len = ARRAY_SIZE(id); + u8 tmp[len]; + + if (!via_aux_read(&drv, 0x00, tmp, len) || memcmp(id, tmp, len)) + return; + + printk(KERN_INFO "viafb: Found %s\n", name); + via_aux_add(&drv); +} diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index a13c258bd32..6d5b6492323 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #define _MASTER_FILE @@ -1729,6 +1730,29 @@ static struct viafb_pm_hooks viafb_fb_pm_hooks = { #endif +static void __devinit i2c_bus_probe(struct viafb_shared *shared) +{ + /* should be always CRT */ + printk(KERN_INFO "viafb: Probing I2C bus 0x26\n"); + shared->i2c_26 = via_aux_probe(viafb_find_i2c_adapter(VIA_PORT_26)); + + /* seems to be usually DVP1 */ + printk(KERN_INFO "viafb: Probing I2C bus 0x31\n"); + shared->i2c_31 = via_aux_probe(viafb_find_i2c_adapter(VIA_PORT_31)); + + /* FIXME: what is this? */ + printk(KERN_INFO "viafb: Probing I2C bus 0x2C\n"); + shared->i2c_2C = via_aux_probe(viafb_find_i2c_adapter(VIA_PORT_2C)); + + printk(KERN_INFO "viafb: Finished I2C bus probing"); +} + +static void i2c_bus_free(struct viafb_shared *shared) +{ + via_aux_free(shared->i2c_26); + via_aux_free(shared->i2c_31); + via_aux_free(shared->i2c_2C); +} int __devinit via_fb_pci_probe(struct viafb_dev *vdev) { @@ -1762,6 +1786,7 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev) &viaparinfo->shared->lvds_setting_info2; viaparinfo->chip_info = &viaparinfo->shared->chip_info; + i2c_bus_probe(viaparinfo->shared); if (viafb_dual_fb) viafb_SAMM_ON = 1; parse_lcd_port(); @@ -1915,6 +1940,7 @@ out_fb1_release: if (viafbinfo1) framebuffer_release(viafbinfo1); out_fb_release: + i2c_bus_free(viaparinfo->shared); framebuffer_release(viafbinfo); return rc; } @@ -1927,6 +1953,7 @@ void __devexit via_fb_pci_remove(struct pci_dev *pdev) if (viafb_dual_fb) unregister_framebuffer(viafbinfo1); viafb_remove_proc(viaparinfo->shared); + i2c_bus_free(viaparinfo->shared); framebuffer_release(viafbinfo); if (viafb_dual_fb) framebuffer_release(viafbinfo1); diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h index d9440635d1d..f6b2ddf56e9 100644 --- a/drivers/video/via/viafbdev.h +++ b/drivers/video/via/viafbdev.h @@ -26,6 +26,7 @@ #include #include +#include "via_aux.h" #include "ioctl.h" #include "share.h" #include "chip.h" @@ -48,6 +49,11 @@ struct viafb_shared { struct proc_dir_entry *iga2_proc_entry; struct viafb_dev *vdev; /* Global dev info */ + /* I2C busses that may have auxiliary devices */ + struct via_aux_bus *i2c_26; + struct via_aux_bus *i2c_31; + struct via_aux_bus *i2c_2C; + /* All the information will be needed to set engine */ struct tmds_setting_information tmds_setting_info; struct lvds_setting_information lvds_setting_info; -- cgit v1.2.3-70-g09d2 From 88044202756925ad47c51c2f634a4f2c17afe068 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Fri, 10 Feb 2012 09:44:08 +0100 Subject: usb: cdc-wdm: make reset work with blocking IO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a flag to tell wdm_read/wdm_write that a reset is in progress, and wake any blocking read/write before taking the mutexes. This allows the device to reset without waiting for blocking IO to finish. Signed-off-by: Bjørn Mork Acked-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index f63601a2054..b27bbb957e1 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -70,6 +70,7 @@ MODULE_DEVICE_TABLE (usb, wdm_ids); #define WDM_POLL_RUNNING 6 #define WDM_RESPONDING 7 #define WDM_SUSPENDING 8 +#define WDM_RESETTING 9 #define WDM_MAX 16 @@ -340,6 +341,10 @@ static ssize_t wdm_write else if (test_bit(WDM_IN_USE, &desc->flags)) r = -EAGAIN; + + if (test_bit(WDM_RESETTING, &desc->flags)) + r = -EIO; + if (r < 0) { kfree(buf); goto out; @@ -419,6 +424,10 @@ retry: rv = -ENODEV; goto err; } + if (test_bit(WDM_RESETTING, &desc->flags)) { + rv = -EIO; + goto err; + } usb_mark_last_busy(interface_to_usbdev(desc->intf)); if (rv < 0) { rv = -ERESTARTSYS; @@ -859,10 +868,6 @@ static int wdm_pre_reset(struct usb_interface *intf) { struct wdm_device *desc = usb_get_intfdata(intf); - mutex_lock(&desc->rlock); - mutex_lock(&desc->wlock); - kill_urbs(desc); - /* * we notify everybody using poll of * an exceptional situation @@ -870,9 +875,16 @@ static int wdm_pre_reset(struct usb_interface *intf) * message from the device is lost */ spin_lock_irq(&desc->iuspin); + set_bit(WDM_RESETTING, &desc->flags); /* inform read/write */ + set_bit(WDM_READ, &desc->flags); /* unblock read */ + clear_bit(WDM_IN_USE, &desc->flags); /* unblock write */ desc->rerr = -EINTR; spin_unlock_irq(&desc->iuspin); wake_up_all(&desc->wait); + mutex_lock(&desc->rlock); + mutex_lock(&desc->wlock); + kill_urbs(desc); + cancel_work_sync(&desc->rxwork); return 0; } @@ -881,6 +893,7 @@ static int wdm_post_reset(struct usb_interface *intf) struct wdm_device *desc = usb_get_intfdata(intf); int rv; + clear_bit(WDM_RESETTING, &desc->flags); rv = recover_from_urb_loss(desc); mutex_unlock(&desc->wlock); mutex_unlock(&desc->rlock); -- cgit v1.2.3-70-g09d2 From e0e12a9282a879577ba8e35c73ff5d94ae1f50b9 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Wed, 19 Oct 2011 12:36:44 +0000 Subject: viafb: set correct polarity for second adapter This patch sets the correct polarity for the second adapter when viafb_SAMM_ON is set and viafb_dual_fb is not set. Just one step to make this mode useful. Signed-off-by: Florian Tobias Schandinat --- drivers/video/via/hw.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index d5aaca9cfa7..08c10366f75 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -1758,13 +1758,13 @@ static void set_display_channel(void) } } -static u8 get_sync(struct fb_info *info) +static u8 get_sync(struct fb_var_screeninfo *var) { u8 polarity = 0; - if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT)) + if (!(var->sync & FB_SYNC_HOR_HIGH_ACT)) polarity |= VIA_HSYNC_NEGATIVE; - if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT)) + if (!(var->sync & FB_SYNC_VERT_HIGH_ACT)) polarity |= VIA_VSYNC_NEGATIVE; return polarity; } @@ -1976,13 +1976,13 @@ int viafb_setmode(int video_bpp, int video_bpp1) viafb_DeviceStatus = CRT_Device; } device_on(); - if (!viafb_dual_fb) - via_set_sync_polarity(devices, get_sync(viafbinfo)); + if (!viafb_SAMM_ON) + via_set_sync_polarity(devices, get_sync(&viafbinfo->var)); else { via_set_sync_polarity(viaparinfo->shared->iga1_devices, - get_sync(viafbinfo)); + get_sync(&viafbinfo->var)); via_set_sync_polarity(viaparinfo->shared->iga2_devices, - get_sync(viafbinfo1)); + get_sync(&var2)); } clock.set_engine_pll_state(VIA_STATE_ON); -- cgit v1.2.3-70-g09d2 From 561c9079ea1de24f8d49c73391811c547d1b2636 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Wed, 19 Oct 2011 12:59:50 +0000 Subject: viafb: fill xres and yres This patch fills xres and yres in var which is required when a temporary var is genereated when viafb_SAMM_ON is set and viafb_dual_fb is not set. It also removes an obsolete comment. Signed-off-by: Florian Tobias Schandinat --- drivers/video/via/hw.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index 08c10366f75..399d50754c4 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -2125,7 +2125,6 @@ void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\ } } -/*According var's xres, yres fill var's other timing information*/ void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, struct crt_mode_table *mode) { @@ -2134,6 +2133,8 @@ void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, crt_reg = mode->crtc; var->pixclock = 1000000000 / (crt_reg.hor_total * crt_reg.ver_total) * 1000 / mode->refresh_rate; + var->xres = crt_reg.hor_addr; + var->yres = crt_reg.ver_addr; var->left_margin = crt_reg.hor_total - (crt_reg.hor_sync_start + crt_reg.hor_sync_end); var->right_margin = crt_reg.hor_sync_start - crt_reg.hor_addr; -- cgit v1.2.3-70-g09d2 From 532f9169db21fbffd07cc44075c7ea1859c07806 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Wed, 19 Oct 2011 20:32:50 +0000 Subject: viafb: make single framebuffer multiple adapter mode work This patch implementes this mode (viafb_SAMM_ON set and viafb_dual_fb not set) in a useful way for CRT and DVI devices. The same content is shown on both devices in different video modes. The first (primary) resolution must not be bigger than the secondary one and determines the visible region. The same content is shown centered on the secondary output. Signed-off-by: Florian Tobias Schandinat --- drivers/video/via/dvi.c | 5 +++-- drivers/video/via/dvi.h | 3 ++- drivers/video/via/hw.c | 41 +++++++++++++++++++++++------------------ drivers/video/via/hw.h | 3 ++- 4 files changed, 30 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c index 9138e517267..3312c81e861 100644 --- a/drivers/video/via/dvi.c +++ b/drivers/video/via/dvi.c @@ -172,7 +172,8 @@ static int tmds_register_read_bytes(int index, u8 *buff, int buff_len) } /* DVI Set Mode */ -void viafb_dvi_set_mode(const struct fb_var_screeninfo *var, int iga) +void viafb_dvi_set_mode(const struct fb_var_screeninfo *var, + u16 cxres, u16 cyres, int iga) { struct fb_var_screeninfo dvi_var = *var; struct crt_mode_table *rb_mode; @@ -185,7 +186,7 @@ void viafb_dvi_set_mode(const struct fb_var_screeninfo *var, int iga) viafb_fill_var_timing_info(&dvi_var, rb_mode); } - viafb_fill_crtc_timing(&dvi_var, iga); + viafb_fill_crtc_timing(&dvi_var, cxres, cyres, iga); } /* Sense DVI Connector */ diff --git a/drivers/video/via/dvi.h b/drivers/video/via/dvi.h index e2116aaf797..db757850c21 100644 --- a/drivers/video/via/dvi.h +++ b/drivers/video/via/dvi.h @@ -59,6 +59,7 @@ void viafb_dvi_enable(void); bool __devinit viafb_tmds_trasmitter_identify(void); void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, struct tmds_setting_information *tmds_setting); -void viafb_dvi_set_mode(const struct fb_var_screeninfo *var, int iga); +void viafb_dvi_set_mode(const struct fb_var_screeninfo *var, + u16 cxres, u16 cyres, int iga); #endif /* __DVI_H__ */ diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index 399d50754c4..e8725c5235c 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -1467,28 +1467,31 @@ void viafb_set_vclock(u32 clk, int set_iga) via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */ } -static struct display_timing var_to_timing(const struct fb_var_screeninfo *var) +static struct display_timing var_to_timing(const struct fb_var_screeninfo *var, u16 cxres, u16 cyres) { struct display_timing timing; + u16 dx = (var->xres - cxres) / 2, dy = (var->yres - cyres) / 2; - timing.hor_addr = var->xres; - timing.hor_sync_start = timing.hor_addr + var->right_margin; + timing.hor_addr = cxres; + timing.hor_sync_start = timing.hor_addr + var->right_margin + dx; timing.hor_sync_end = timing.hor_sync_start + var->hsync_len; - timing.hor_total = timing.hor_sync_end + var->left_margin; - timing.hor_blank_start = timing.hor_addr; - timing.hor_blank_end = timing.hor_total; - timing.ver_addr = var->yres; - timing.ver_sync_start = timing.ver_addr + var->lower_margin; + timing.hor_total = timing.hor_sync_end + var->left_margin + dx; + timing.hor_blank_start = timing.hor_addr + dx; + timing.hor_blank_end = timing.hor_total - dy; + timing.ver_addr = cyres; + timing.ver_sync_start = timing.ver_addr + var->lower_margin + dy; timing.ver_sync_end = timing.ver_sync_start + var->vsync_len; - timing.ver_total = timing.ver_sync_end + var->upper_margin; - timing.ver_blank_start = timing.ver_addr; - timing.ver_blank_end = timing.ver_total; + timing.ver_total = timing.ver_sync_end + var->upper_margin + dy; + timing.ver_blank_start = timing.ver_addr + dy; + timing.ver_blank_end = timing.ver_total - dy; return timing; } -void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var, int iga) +void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var, + u16 cxres, u16 cyres, int iga) { - struct display_timing crt_reg = var_to_timing(var); + struct display_timing crt_reg = var_to_timing(var, + cxres ? cxres : var->xres, cyres ? cyres : var->yres); if (iga == IGA1) via_set_primary_timing(&crt_reg); @@ -1842,7 +1845,7 @@ static void hw_init(void) int viafb_setmode(int video_bpp, int video_bpp1) { - int j; + int j, cxres = 0, cyres = 0; int port; u32 devices = viaparinfo->shared->iga1_devices | viaparinfo->shared->iga2_devices; @@ -1891,6 +1894,8 @@ int viafb_setmode(int video_bpp, int video_bpp1) } else if (viafb_SAMM_ON) { viafb_fill_var_timing_info(&var2, viafb_get_best_mode( viafb_second_xres, viafb_second_yres, viafb_refresh1)); + cxres = viafbinfo->var.xres; + cyres = viafbinfo->var.yres; var2.bits_per_pixel = viafbinfo->var.bits_per_pixel; } @@ -1898,9 +1903,9 @@ int viafb_setmode(int video_bpp, int video_bpp1) if (viafb_CRT_ON) { if (viaparinfo->shared->iga2_devices & VIA_CRT && viafb_SAMM_ON) - viafb_fill_crtc_timing(&var2, IGA2); + viafb_fill_crtc_timing(&var2, cxres, cyres, IGA2); else - viafb_fill_crtc_timing(&viafbinfo->var, + viafb_fill_crtc_timing(&viafbinfo->var, 0, 0, (viaparinfo->shared->iga1_devices & VIA_CRT) ? IGA1 : IGA2); @@ -1918,9 +1923,9 @@ int viafb_setmode(int video_bpp, int video_bpp1) if (viafb_DVI_ON) { if (viaparinfo->shared->tmds_setting_info.iga_path == IGA2 && viafb_SAMM_ON) - viafb_dvi_set_mode(&var2, IGA2); + viafb_dvi_set_mode(&var2, cxres, cyres, IGA2); else - viafb_dvi_set_mode(&viafbinfo->var, + viafb_dvi_set_mode(&viafbinfo->var, 0, 0, viaparinfo->tmds_setting_info->iga_path); } diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h index 4db5b6e8d8d..f8129e49aa2 100644 --- a/drivers/video/via/hw.h +++ b/drivers/video/via/hw.h @@ -637,7 +637,8 @@ extern int viafb_LCD_ON; extern int viafb_DVI_ON; extern int viafb_hotplug; -void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var, int iga); +void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var, + u16 cxres, u16 cyres, int iga); void viafb_set_vclock(u32 CLK, int set_iga); void viafb_load_reg(int timing_value, int viafb_load_reg_num, struct io_register *reg, -- cgit v1.2.3-70-g09d2 From 74d1d82cdaaec727f5072eb1c9f49b7e920e076f Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 6 Feb 2012 11:22:22 -0800 Subject: drivers/base: add bus for System-on-Chip devices Traditionally, any System-on-Chip based platform creates a flat list of platform_devices directly under /sys/devices/platform. In order to give these some better structure, this introduces a new bus type for soc_devices that are registered with the new soc_device_register() function. All devices that are on the same chip should then be registered as child devices of the soc device. The soc bus also exports a few standardised device attributes which allow user space to query the specific type of soc. Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- drivers/base/Kconfig | 3 + drivers/base/Makefile | 1 + drivers/base/soc.c | 183 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/sys_soc.h | 37 ++++++++++ 4 files changed, 224 insertions(+) create mode 100644 drivers/base/soc.c create mode 100644 include/linux/sys_soc.h (limited to 'drivers') diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index 7be9f79018e..9aa618acfe9 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -176,6 +176,9 @@ config GENERIC_CPU_DEVICES bool default n +config SOC_BUS + bool + source "drivers/base/regmap/Kconfig" config DMA_SHARED_BUFFER diff --git a/drivers/base/Makefile b/drivers/base/Makefile index 610f9997a40..b6d1b9c4200 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_MODULES) += module.o endif obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o obj-$(CONFIG_REGMAP) += regmap/ +obj-$(CONFIG_SOC_BUS) += soc.o ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG diff --git a/drivers/base/soc.c b/drivers/base/soc.c new file mode 100644 index 00000000000..05f150382da --- /dev/null +++ b/drivers/base/soc.c @@ -0,0 +1,183 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * Author: Lee Jones for ST-Ericsson. + * License terms: GNU General Public License (GPL), version 2 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static DEFINE_IDR(soc_ida); +static DEFINE_SPINLOCK(soc_lock); + +static ssize_t soc_info_get(struct device *dev, + struct device_attribute *attr, + char *buf); + +struct soc_device { + struct device dev; + struct soc_device_attribute *attr; + int soc_dev_num; +}; + +static struct bus_type soc_bus_type = { + .name = "soc", +}; + +static DEVICE_ATTR(machine, S_IRUGO, soc_info_get, NULL); +static DEVICE_ATTR(family, S_IRUGO, soc_info_get, NULL); +static DEVICE_ATTR(soc_id, S_IRUGO, soc_info_get, NULL); +static DEVICE_ATTR(revision, S_IRUGO, soc_info_get, NULL); + +struct device *soc_device_to_device(struct soc_device *soc_dev) +{ + return &soc_dev->dev; +} + +static mode_t soc_attribute_mode(struct kobject *kobj, + struct attribute *attr, + int index) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct soc_device *soc_dev = container_of(dev, struct soc_device, dev); + + if ((attr == &dev_attr_machine.attr) + && (soc_dev->attr->machine != NULL)) + return attr->mode; + if ((attr == &dev_attr_family.attr) + && (soc_dev->attr->family != NULL)) + return attr->mode; + if ((attr == &dev_attr_revision.attr) + && (soc_dev->attr->revision != NULL)) + return attr->mode; + if ((attr == &dev_attr_soc_id.attr) + && (soc_dev->attr->soc_id != NULL)) + return attr->mode; + + /* Unknown or unfilled attribute. */ + return 0; +} + +static ssize_t soc_info_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct soc_device *soc_dev = container_of(dev, struct soc_device, dev); + + if (attr == &dev_attr_machine) + return sprintf(buf, "%s\n", soc_dev->attr->machine); + if (attr == &dev_attr_family) + return sprintf(buf, "%s\n", soc_dev->attr->family); + if (attr == &dev_attr_revision) + return sprintf(buf, "%s\n", soc_dev->attr->revision); + if (attr == &dev_attr_soc_id) + return sprintf(buf, "%s\n", soc_dev->attr->soc_id); + + return -EINVAL; + +} + +static struct attribute *soc_attr[] = { + &dev_attr_machine.attr, + &dev_attr_family.attr, + &dev_attr_soc_id.attr, + &dev_attr_revision.attr, + NULL, +}; + +static const struct attribute_group soc_attr_group = { + .attrs = soc_attr, + .is_visible = soc_attribute_mode, +}; + +static const struct attribute_group *soc_attr_groups[] = { + &soc_attr_group, + NULL, +}; + +static void soc_release(struct device *dev) +{ + struct soc_device *soc_dev = container_of(dev, struct soc_device, dev); + + kfree(soc_dev); +} + +struct soc_device *soc_device_register(struct soc_device_attribute *soc_dev_attr) +{ + struct soc_device *soc_dev; + int ret; + + soc_dev = kzalloc(sizeof(*soc_dev), GFP_KERNEL); + if (!soc_dev) { + ret = -ENOMEM; + goto out1; + } + + /* Fetch a unique (reclaimable) SOC ID. */ + do { + if (!ida_pre_get(&soc_ida, GFP_KERNEL)) { + ret = -ENOMEM; + goto out2; + } + + spin_lock(&soc_lock); + ret = ida_get_new(&soc_ida, &soc_dev->soc_dev_num); + spin_unlock(&soc_lock); + + } while (ret == -EAGAIN); + + if (ret) + goto out2; + + soc_dev->attr = soc_dev_attr; + soc_dev->dev.bus = &soc_bus_type; + soc_dev->dev.groups = soc_attr_groups; + soc_dev->dev.release = soc_release; + + dev_set_name(&soc_dev->dev, "soc%d", soc_dev->soc_dev_num); + + ret = device_register(&soc_dev->dev); + if (ret) + goto out3; + + return soc_dev; + +out3: + ida_remove(&soc_ida, soc_dev->soc_dev_num); +out2: + kfree(soc_dev); +out1: + return ERR_PTR(ret); +} + +/* Ensure soc_dev->attr is freed prior to calling soc_device_unregister. */ +void soc_device_unregister(struct soc_device *soc_dev) +{ + ida_remove(&soc_ida, soc_dev->soc_dev_num); + + device_unregister(&soc_dev->dev); +} + +static int __init soc_bus_register(void) +{ + spin_lock_init(&soc_lock); + + return bus_register(&soc_bus_type); +} +core_initcall(soc_bus_register); + +static void __exit soc_bus_unregister(void) +{ + ida_destroy(&soc_ida); + + bus_unregister(&soc_bus_type); +} +module_exit(soc_bus_unregister); diff --git a/include/linux/sys_soc.h b/include/linux/sys_soc.h new file mode 100644 index 00000000000..2739ccb6957 --- /dev/null +++ b/include/linux/sys_soc.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * Author: Lee Jones for ST-Ericsson. + * License terms: GNU General Public License (GPL), version 2 + */ +#ifndef __SOC_BUS_H +#define __SOC_BUS_H + +#include + +struct soc_device_attribute { + const char *machine; + const char *family; + const char *revision; + const char *soc_id; +}; + +/** + * soc_device_register - register SoC as a device + * @soc_plat_dev_attr: Attributes passed from platform to be attributed to a SoC + */ +struct soc_device *soc_device_register( + struct soc_device_attribute *soc_plat_dev_attr); + +/** + * soc_device_unregister - unregister SoC device + * @dev: SoC device to be unregistered + */ +void soc_device_unregister(struct soc_device *soc_dev); + +/** + * soc_device_to_device - helper function to fetch struct device + * @soc: Previously registered SoC device container + */ +struct device *soc_device_to_device(struct soc_device *soc); + +#endif /* __SOC_BUS_H */ -- cgit v1.2.3-70-g09d2 From 28a8d14cc74a0180323d9150c3d3dbf9dd60d55a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 9 Feb 2012 01:52:22 +0100 Subject: pinctrl: break out a pinctrl consumer header This breaks out a header to be used by all pinmux and pinconfig alike, so drivers needing services from pinctrl does not need to include different headers. This is similar to the approach taken by the regulator API. Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- Documentation/pinctrl.txt | 6 +- arch/arm/mach-u300/core.c | 2 +- drivers/pinctrl/pinctrl-coh901.c | 2 +- include/linux/pinctrl/consumer.h | 118 +++++++++++++++++++++++++++++++++++++++ include/linux/pinctrl/pinconf.h | 39 ------------- include/linux/pinctrl/pinmux.h | 52 ----------------- 6 files changed, 125 insertions(+), 94 deletions(-) create mode 100644 include/linux/pinctrl/consumer.h (limited to 'drivers') diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index 14aecd2b2db..b268832c49d 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -208,6 +208,8 @@ unconnected. For example, a platform may do this: +#include + ret = pin_config_set("foo-dev", "FOO_GPIO_PIN", PLATFORM_X_PULL_UP); To pull up a pin to VDD. The pin configuration driver implements callbacks for @@ -920,7 +922,7 @@ this is not possible. A driver may request a certain mux to be activated, usually just the default mux like this: -#include +#include struct foo_state { struct pinmux *pmx; @@ -1019,6 +1021,8 @@ function, but with different named in the mapping as described under This snippet first muxes the function in the pins defined by group A, enables it, disables and releases it, and muxes it in on the pins defined by group B: +#include + foo_switch() { struct pinmux *pmx; diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index b4c6926a700..1429e528219 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c index 69fb7072a23..8bac3f093d5 100644 --- a/drivers/pinctrl/pinctrl-coh901.c +++ b/drivers/pinctrl/pinctrl-coh901.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include /* diff --git a/include/linux/pinctrl/consumer.h b/include/linux/pinctrl/consumer.h new file mode 100644 index 00000000000..9c8513d5d0f --- /dev/null +++ b/include/linux/pinctrl/consumer.h @@ -0,0 +1,118 @@ +/* + * Consumer interface the pin control subsystem + * + * Copyright (C) 2012 ST-Ericsson SA + * Written on behalf of Linaro for ST-Ericsson + * Based on bits of regulator core, gpio core and clk core + * + * Author: Linus Walleij + * + * License terms: GNU General Public License (GPL) version 2 + */ +#ifndef __LINUX_PINCTRL_CONSUMER_H +#define __LINUX_PINCTRL_CONSUMER_H + +#include +#include +#include "pinctrl.h" + +/* This struct is private to the core and should be regarded as a cookie */ +struct pinmux; + +#ifdef CONFIG_PINMUX + +/* External interface to pinmux */ +extern int pinmux_request_gpio(unsigned gpio); +extern void pinmux_free_gpio(unsigned gpio); +extern int pinmux_gpio_direction_input(unsigned gpio); +extern int pinmux_gpio_direction_output(unsigned gpio); +extern struct pinmux * __must_check pinmux_get(struct device *dev, const char *name); +extern void pinmux_put(struct pinmux *pmx); +extern int pinmux_enable(struct pinmux *pmx); +extern void pinmux_disable(struct pinmux *pmx); + +#else /* !CONFIG_PINMUX */ + +static inline int pinmux_request_gpio(unsigned gpio) +{ + return 0; +} + +static inline void pinmux_free_gpio(unsigned gpio) +{ +} + +static inline int pinmux_gpio_direction_input(unsigned gpio) +{ + return 0; +} + +static inline int pinmux_gpio_direction_output(unsigned gpio) +{ + return 0; +} + +static inline struct pinmux * __must_check pinmux_get(struct device *dev, const char *name) +{ + return NULL; +} + +static inline void pinmux_put(struct pinmux *pmx) +{ +} + +static inline int pinmux_enable(struct pinmux *pmx) +{ + return 0; +} + +static inline void pinmux_disable(struct pinmux *pmx) +{ +} + +#endif /* CONFIG_PINMUX */ + +#ifdef CONFIG_PINCONF + +extern int pin_config_get(const char *dev_name, const char *name, + unsigned long *config); +extern int pin_config_set(const char *dev_name, const char *name, + unsigned long config); +extern int pin_config_group_get(const char *dev_name, + const char *pin_group, + unsigned long *config); +extern int pin_config_group_set(const char *dev_name, + const char *pin_group, + unsigned long config); + +#else + +static inline int pin_config_get(const char *dev_name, const char *name, + unsigned long *config) +{ + return 0; +} + +static inline int pin_config_set(const char *dev_name, const char *name, + unsigned long config) +{ + return 0; +} + +static inline int pin_config_group_get(const char *dev_name, + const char *pin_group, + unsigned long *config) +{ + return 0; +} + +static inline int pin_config_group_set(const char *dev_name, + const char *pin_group, + unsigned long config) +{ + return 0; +} + +#endif + +#endif /* __LINUX_PINCTRL_CONSUMER_H */ diff --git a/include/linux/pinctrl/pinconf.h b/include/linux/pinctrl/pinconf.h index 477922cf043..f8cf156873d 100644 --- a/include/linux/pinctrl/pinconf.h +++ b/include/linux/pinctrl/pinconf.h @@ -53,45 +53,6 @@ struct pinconf_ops { unsigned selector); }; -extern int pin_config_get(const char *dev_name, const char *name, - unsigned long *config); -extern int pin_config_set(const char *dev_name, const char *name, - unsigned long config); -extern int pin_config_group_get(const char *dev_name, - const char *pin_group, - unsigned long *config); -extern int pin_config_group_set(const char *dev_name, - const char *pin_group, - unsigned long config); - -#else - -static inline int pin_config_get(const char *dev_name, const char *name, - unsigned long *config) -{ - return 0; -} - -static inline int pin_config_set(const char *dev_name, const char *name, - unsigned long config) -{ - return 0; -} - -static inline int pin_config_group_get(const char *dev_name, - const char *pin_group, - unsigned long *config) -{ - return 0; -} - -static inline int pin_config_group_set(const char *dev_name, - const char *pin_group, - unsigned long config) -{ - return 0; -} - #endif #endif /* __LINUX_PINCTRL_PINCONF_H */ diff --git a/include/linux/pinctrl/pinmux.h b/include/linux/pinctrl/pinmux.h index 937b3e2fa36..47e9237edd4 100644 --- a/include/linux/pinctrl/pinmux.h +++ b/include/linux/pinctrl/pinmux.h @@ -16,9 +16,6 @@ #include #include "pinctrl.h" -/* This struct is private to the core and should be regarded as a cookie */ -struct pinmux; - #ifdef CONFIG_PINMUX struct pinctrl_dev; @@ -88,55 +85,6 @@ struct pinmux_ops { bool input); }; -/* External interface to pinmux */ -extern int pinmux_request_gpio(unsigned gpio); -extern void pinmux_free_gpio(unsigned gpio); -extern int pinmux_gpio_direction_input(unsigned gpio); -extern int pinmux_gpio_direction_output(unsigned gpio); -extern struct pinmux * __must_check pinmux_get(struct device *dev, const char *name); -extern void pinmux_put(struct pinmux *pmx); -extern int pinmux_enable(struct pinmux *pmx); -extern void pinmux_disable(struct pinmux *pmx); - -#else /* !CONFIG_PINMUX */ - -static inline int pinmux_request_gpio(unsigned gpio) -{ - return 0; -} - -static inline void pinmux_free_gpio(unsigned gpio) -{ -} - -static inline int pinmux_gpio_direction_input(unsigned gpio) -{ - return 0; -} - -static inline int pinmux_gpio_direction_output(unsigned gpio) -{ - return 0; -} - -static inline struct pinmux * __must_check pinmux_get(struct device *dev, const char *name) -{ - return NULL; -} - -static inline void pinmux_put(struct pinmux *pmx) -{ -} - -static inline int pinmux_enable(struct pinmux *pmx) -{ - return 0; -} - -static inline void pinmux_disable(struct pinmux *pmx) -{ -} - #endif /* CONFIG_PINMUX */ #endif /* __LINUX_PINCTRL_PINMUX_H */ -- cgit v1.2.3-70-g09d2 From e93bcee00c43e2bd4037291262111016f4c05793 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 9 Feb 2012 07:23:28 +0100 Subject: pinctrl: move generic functions to the pinctrl_ namespace Since we want to use the former pinmux handles and mapping tables for generic control involving both muxing and configuration we begin refactoring by renaming them from pinmux_* to pinctrl_*. ChangeLog v1->v2: - Also rename the PINMUX_* macros in machine.h to PIN_ as indicated in the documentation so as to reflect the generic nature of these mapping entries from now on. Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- Documentation/pinctrl.txt | 118 ++++++------- arch/arm/mach-u300/core.c | 34 ++-- drivers/pinctrl/core.c | 4 +- drivers/pinctrl/core.h | 8 +- drivers/pinctrl/pinctrl-coh901.c | 4 +- drivers/pinctrl/pinmux.c | 351 ++++++++++++++++++++------------------- drivers/pinctrl/pinmux.h | 8 +- include/linux/pinctrl/consumer.h | 34 ++-- include/linux/pinctrl/machine.h | 26 +-- 9 files changed, 294 insertions(+), 293 deletions(-) (limited to 'drivers') diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index b268832c49d..2e7132355db 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -728,19 +728,19 @@ same time. All the above functions are mandatory to implement for a pinmux driver. -Pinmux interaction with the GPIO subsystem -========================================== +Pin control interaction with the GPIO subsystem +=============================================== -The public pinmux API contains two functions named pinmux_request_gpio() -and pinmux_free_gpio(). These two functions shall *ONLY* be called from +The public pinmux API contains two functions named pinctrl_request_gpio() +and pinctrl_free_gpio(). These two functions shall *ONLY* be called from gpiolib-based drivers as part of their gpio_request() and -gpio_free() semantics. Likewise the pinmux_gpio_direction_[input|output] +gpio_free() semantics. Likewise the pinctrl_gpio_direction_[input|output] shall only be called from within respective gpio_direction_[input|output] gpiolib implementation. NOTE that platforms and individual drivers shall *NOT* request GPIO pins to be -muxed in. Instead, implement a proper gpiolib driver and have that driver -request proper muxing for its pins. +controlled e.g. muxed in. Instead, implement a proper gpiolib driver and have +that driver request proper muxing and other control for its pins. The function list could become long, especially if you can convert every individual pin into a GPIO pin independent of any other pins, and then try @@ -749,7 +749,7 @@ the approach to define every pin as a function. In this case, the function array would become 64 entries for each GPIO setting and then the device functions. -For this reason there are two functions a pinmux driver can implement +For this reason there are two functions a pin control driver can implement to enable only GPIO on an individual pin: .gpio_request_enable() and .gpio_disable_free(). @@ -764,7 +764,7 @@ gpiolib driver and the affected GPIO range, pin offset and desired direction will be passed along to this function. Alternatively to using these special functions, it is fully allowed to use -named functions for each GPIO pin, the pinmux_request_gpio() will attempt to +named functions for each GPIO pin, the pinctrl_request_gpio() will attempt to obtain the function "gpioN" where "N" is the global GPIO pin number if no special GPIO-handler is registered. @@ -783,7 +783,7 @@ spi on the second function mapping: #include -static const struct pinmux_map __initdata pmx_mapping[] = { +static const struct pinctrl_map __initdata mapping[] = { { .ctrl_dev_name = "pinctrl-foo", .function = "spi0", @@ -811,14 +811,14 @@ to map. You register this pinmux mapping to the pinmux subsystem by simply: - ret = pinmux_register_mappings(pmx_mapping, ARRAY_SIZE(pmx_mapping)); + ret = pinctrl_register_mappings(mapping, ARRAY_SIZE(mapping)); Since the above construct is pretty common there is a helper macro to make it even more compact which assumes you want to use pinctrl-foo and position 0 for mapping, for example: -static struct pinmux_map __initdata pmx_mapping[] = { - PINMUX_MAP("I2CMAP", "pinctrl-foo", "i2c0", "foo-i2c.0"), +static struct pinctrl_map __initdata mapping[] = { + PIN_MAP("I2CMAP", "pinctrl-foo", "i2c0", "foo-i2c.0"), }; @@ -901,7 +901,7 @@ case), we define a mapping like this: The result of grabbing this mapping from the device with something like this (see next paragraph): - pmx = pinmux_get(&device, "8bit"); + p = pinctrl_get(&device, "8bit"); Will be that you activate all the three bottom records in the mapping at once. Since they share the same name, pin controller device, funcion and @@ -913,44 +913,44 @@ pinmux core. Pinmux requests from drivers ============================ -Generally it is discouraged to let individual drivers get and enable pinmuxes. -So if possible, handle the pinmuxes in platform code or some other place where -you have access to all the affected struct device * pointers. In some cases -where a driver needs to switch between different mux mappings at runtime -this is not possible. +Generally it is discouraged to let individual drivers get and enable pin +control. So if possible, handle the pin control in platform code or some other +place where you have access to all the affected struct device * pointers. In +some cases where a driver needs to e.g. switch between different mux mappings +at runtime this is not possible. -A driver may request a certain mux to be activated, usually just the default -mux like this: +A driver may request a certain control state to be activated, usually just the +default state like this: #include struct foo_state { - struct pinmux *pmx; + struct pinctrl *p; ... }; foo_probe() { /* Allocate a state holder named "state" etc */ - struct pinmux pmx; + struct pinctrl p; - pmx = pinmux_get(&device, NULL); - if IS_ERR(pmx) - return PTR_ERR(pmx); - pinmux_enable(pmx); + p = pinctrl_get(&device, NULL); + if IS_ERR(p) + return PTR_ERR(p); + pinctrl_enable(p); - state->pmx = pmx; + state->p = p; } foo_remove() { - pinmux_disable(state->pmx); - pinmux_put(state->pmx); + pinctrl_disable(state->p); + pinctrl_put(state->p); } -If you want to grab a specific mux mapping and not just the first one found for -this device you can specify a specific mapping name, for example in the above -example the second i2c0 setting: pinmux_get(&device, "spi0-pos-B"); +If you want to grab a specific control mapping and not just the first one +found for this device you can specify a specific mapping name, for example in +the above example the second i2c0 setting: pinctrl_get(&device, "spi0-pos-B"); This get/enable/disable/put sequence can just as well be handled by bus drivers if you don't want each and every driver to handle it and you know the @@ -958,35 +958,35 @@ arrangement on your bus. The semantics of the get/enable respective disable/put is as follows: -- pinmux_get() is called in process context to reserve the pins affected with +- pinctrl_get() is called in process context to reserve the pins affected with a certain mapping and set up the pinmux core and the driver. It will allocate a struct from the kernel memory to hold the pinmux state. -- pinmux_enable()/pinmux_disable() is quick and can be called from fastpath +- pinctrl_enable()/pinctrl_disable() is quick and can be called from fastpath (irq context) when you quickly want to set up/tear down the hardware muxing when running a device driver. Usually it will just poke some values into a register. -- pinmux_disable() is called in process context to tear down the pin requests - and release the state holder struct for the mux setting. +- pinctrl_disable() is called in process context to tear down the pin requests + and release the state holder struct for the mux setting etc. -Usually the pinmux core handled the get/put pair and call out to the device -drivers bookkeeping operations, like checking available functions and the -associated pins, whereas the enable/disable pass on to the pin controller +Usually the pin control core handled the get/put pair and call out to the +device drivers bookkeeping operations, like checking available functions and +the associated pins, whereas the enable/disable pass on to the pin controller driver which takes care of activating and/or deactivating the mux setting by quickly poking some registers. -The pins are allocated for your device when you issue the pinmux_get() call, +The pins are allocated for your device when you issue the pinctrl_get() call, after this you should be able to see this in the debugfs listing of all pins. -System pinmux hogging -===================== +System pin control hogging +========================== -A system pinmux map entry, i.e. a pinmux setting that does not have a device -associated with it, can be hogged by the core when the pin controller is -registered. This means that the core will attempt to call pinmux_get() and -pinmux_enable() on it immediately after the pin control device has been +A system pin control map entry, i.e. a pin control setting that does not have +a device associated with it, can be hogged by the core when the pin controller +is registered. This means that the core will attempt to call pinctrl_get() and +pinctrl_enable() on it immediately after the pin control device has been registered. This is enabled by simply setting the .hog_on_boot field in the map to true, @@ -1003,7 +1003,7 @@ Since it may be common to request the core to hog a few always-applicable mux settings on the primary pin controller, there is a convenience macro for this: -PINMUX_MAP_PRIMARY_SYS_HOG("POWERMAP", "power_func") +PIN_MAP_PRIMARY_SYS_HOG("POWERMAP", "power_func") This gives the exact same result as the above construction. @@ -1025,23 +1025,23 @@ it, disables and releases it, and muxes it in on the pins defined by group B: foo_switch() { - struct pinmux *pmx; + struct pinctrl *p; /* Enable on position A */ - pmx = pinmux_get(&device, "spi0-pos-A"); - if IS_ERR(pmx) - return PTR_ERR(pmx); - pinmux_enable(pmx); + p = pinctrl_get(&device, "spi0-pos-A"); + if IS_ERR(p) + return PTR_ERR(p); + pinctrl_enable(p); /* This releases the pins again */ - pinmux_disable(pmx); - pinmux_put(pmx); + pinctrl_disable(p); + pinctrl_put(p); /* Enable on position B */ - pmx = pinmux_get(&device, "spi0-pos-B"); - if IS_ERR(pmx) - return PTR_ERR(pmx); - pinmux_enable(pmx); + p = pinctrl_get(&device, "spi0-pos-B"); + if IS_ERR(p) + return PTR_ERR(p); + pinctrl_enable(p); ... } diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index 1429e528219..bb1034f8c2f 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c @@ -1605,21 +1605,21 @@ static struct platform_device pinmux_device = { }; /* Pinmux settings */ -static struct pinmux_map __initdata u300_pinmux_map[] = { +static struct pinctrl_map __initdata u300_pinmux_map[] = { /* anonymous maps for chip power and EMIFs */ - PINMUX_MAP_SYS_HOG("POWER", "pinmux-u300", "power"), - PINMUX_MAP_SYS_HOG("EMIF0", "pinmux-u300", "emif0"), - PINMUX_MAP_SYS_HOG("EMIF1", "pinmux-u300", "emif1"), + PIN_MAP_SYS_HOG("POWER", "pinmux-u300", "power"), + PIN_MAP_SYS_HOG("EMIF0", "pinmux-u300", "emif0"), + PIN_MAP_SYS_HOG("EMIF1", "pinmux-u300", "emif1"), /* per-device maps for MMC/SD, SPI and UART */ - PINMUX_MAP("MMCSD", "pinmux-u300", "mmc0", "mmci"), - PINMUX_MAP("SPI", "pinmux-u300", "spi0", "pl022"), - PINMUX_MAP("UART0", "pinmux-u300", "uart0", "uart0"), + PIN_MAP("MMCSD", "pinmux-u300", "mmc0", "mmci"), + PIN_MAP("SPI", "pinmux-u300", "spi0", "pl022"), + PIN_MAP("UART0", "pinmux-u300", "uart0", "uart0"), }; struct u300_mux_hog { const char *name; struct device *dev; - struct pinmux *pmx; + struct pinctrl *p; }; static struct u300_mux_hog u300_mux_hogs[] = { @@ -1637,31 +1637,31 @@ static struct u300_mux_hog u300_mux_hogs[] = { }, }; -static int __init u300_pinmux_fetch(void) +static int __init u300_pinctrl_fetch(void) { int i; for (i = 0; i < ARRAY_SIZE(u300_mux_hogs); i++) { - struct pinmux *pmx; + struct pinctrl *p; int ret; - pmx = pinmux_get(u300_mux_hogs[i].dev, NULL); - if (IS_ERR(pmx)) { + p = pinctrl_get(u300_mux_hogs[i].dev, NULL); + if (IS_ERR(p)) { pr_err("u300: could not get pinmux hog %s\n", u300_mux_hogs[i].name); continue; } - ret = pinmux_enable(pmx); + ret = pinctrl_enable(p); if (ret) { pr_err("u300: could enable pinmux hog %s\n", u300_mux_hogs[i].name); continue; } - u300_mux_hogs[i].pmx = pmx; + u300_mux_hogs[i].p = p; } return 0; } -subsys_initcall(u300_pinmux_fetch); +subsys_initcall(u300_pinctrl_fetch); /* * Notice that AMBA devices are initialized before platform devices. @@ -1861,8 +1861,8 @@ void __init u300_init_devices(void) u300_assign_physmem(); /* Initialize pinmuxing */ - pinmux_register_mappings(u300_pinmux_map, - ARRAY_SIZE(u300_pinmux_map)); + pinctrl_register_mappings(u300_pinmux_map, + ARRAY_SIZE(u300_pinmux_map)); /* Register subdevices on the I2C buses */ u300_i2c_register_board_devices(); diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 4f10476cc1f..75c6a6bb6c0 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -624,7 +624,7 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, mutex_lock(&pinctrldev_list_mutex); list_add(&pctldev->node, &pinctrldev_list); mutex_unlock(&pinctrldev_list_mutex); - pinmux_hog_maps(pctldev); + pinctrl_hog_maps(pctldev); return pctldev; out_err: @@ -645,7 +645,7 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev) return; pinctrl_remove_device_debugfs(pctldev); - pinmux_unhog_maps(pctldev); + pinctrl_unhog_maps(pctldev); /* TODO: check that no pinmuxes are still active? */ mutex_lock(&pinctrldev_list_mutex); list_del(&pctldev->node); diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 8a8b02e9c18..7a89888fce9 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -28,8 +28,8 @@ struct pinctrl_gpio_range; * @owner: module providing the pin controller, used for refcounting * @driver_data: driver data for drivers registering to the pin controller * subsystem - * @pinmux_hogs_lock: lock for the pinmux hog list - * @pinmux_hogs: list of pinmux maps hogged by this device + * @pinctrl_hogs_lock: lock for the pin control hog list + * @pinctrl_hogs: list of pin control maps hogged by this device */ struct pinctrl_dev { struct list_head node; @@ -45,8 +45,8 @@ struct pinctrl_dev { struct dentry *device_root; #endif #ifdef CONFIG_PINMUX - struct mutex pinmux_hogs_lock; - struct list_head pinmux_hogs; + struct mutex pinctrl_hogs_lock; + struct list_head pinctrl_hogs; #endif }; diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c index 8bac3f093d5..eba232a46a8 100644 --- a/drivers/pinctrl/pinctrl-coh901.c +++ b/drivers/pinctrl/pinctrl-coh901.c @@ -360,14 +360,14 @@ static int u300_gpio_request(struct gpio_chip *chip, unsigned offset) */ int gpio = chip->base + offset; - return pinmux_request_gpio(gpio); + return pinctrl_request_gpio(gpio); } static void u300_gpio_free(struct gpio_chip *chip, unsigned offset) { int gpio = chip->base + offset; - pinmux_free_gpio(gpio); + pinctrl_free_gpio(gpio); } static int u300_gpio_get(struct gpio_chip *chip, unsigned offset) diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 1311f1d2200..773835d18f5 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -1,7 +1,7 @@ /* * Core driver for the pin muxing portions of the pin control subsystem * - * Copyright (C) 2011 ST-Ericsson SA + * Copyright (C) 2011-2012 ST-Ericsson SA * Written on behalf of Linaro for ST-Ericsson * Based on bits of regulator core, gpio core and clk core * @@ -29,13 +29,13 @@ #include #include "core.h" -/* List of pinmuxes */ -static DEFINE_MUTEX(pinmux_list_mutex); -static LIST_HEAD(pinmux_list); +/* List of pin controller handles */ +static DEFINE_MUTEX(pinctrl_list_mutex); +static LIST_HEAD(pinctrl_list); -/* Global pinmux maps */ -static struct pinmux_map *pinmux_maps; -static unsigned pinmux_maps_num; +/* Global pinctrl maps */ +static struct pinctrl_map *pinctrl_maps; +static unsigned pinctrl_maps_num; /** * struct pinmux_group - group list item for pinmux groups @@ -48,12 +48,12 @@ struct pinmux_group { }; /** - * struct pinmux - per-device pinmux state holder + * struct pinctrl - per-device pin control state holder * @node: global list node - * @dev: the device using this pinmux - * @usecount: the number of active users of this mux setting, used to keep - * track of nested use cases - * @pctldev: pin control device handling this pinmux + * @dev: the device using this pin control handle + * @usecount: the number of active users of this pin controller setting, used + * to keep track of nested use cases + * @pctldev: pin control device handling this pin control handle * @func_selector: the function selector for the pinmux device handling * this pinmux * @groups: the group selectors for the pinmux device and @@ -62,7 +62,7 @@ struct pinmux_group { * get/put/enable/disable * @mutex: a lock for the pinmux state holder */ -struct pinmux { +struct pinctrl { struct list_head node; struct device *dev; unsigned usecount; @@ -73,15 +73,15 @@ struct pinmux { }; /** - * struct pinmux_hog - a list item to stash mux hogs - * @node: pinmux hog list node + * struct pinctrl_hog - a list item to stash control hogs + * @node: pin control hog list node * @map: map entry responsible for this hogging - * @pmx: the pinmux hogged by this item + * @pmx: the pin control hogged by this item */ -struct pinmux_hog { +struct pinctrl_hog { struct list_head node; - struct pinmux_map const *map; - struct pinmux *pmx; + struct pinctrl_map const *map; + struct pinctrl *p; }; /** @@ -207,14 +207,14 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin, } /** - * pinmux_request_gpio() - request a single pin to be muxed in as GPIO + * pinctrl_request_gpio() - request a single pin to be used in as GPIO * @gpio: the GPIO pin number from the GPIO subsystem number space * * This function should *ONLY* be used from gpiolib-based GPIO drivers, * as part of their gpio_request() semantics, platforms and individual drivers * shall *NOT* request GPIO pins to be muxed in. */ -int pinmux_request_gpio(unsigned gpio) +int pinctrl_request_gpio(unsigned gpio) { char gpiostr[16]; const char *function; @@ -243,17 +243,17 @@ int pinmux_request_gpio(unsigned gpio) return ret; } -EXPORT_SYMBOL_GPL(pinmux_request_gpio); +EXPORT_SYMBOL_GPL(pinctrl_request_gpio); /** - * pinmux_free_gpio() - free a single pin, currently used as GPIO + * pinctrl_free_gpio() - free control on a single pin, currently used as GPIO * @gpio: the GPIO pin number from the GPIO subsystem number space * * This function should *ONLY* be used from gpiolib-based GPIO drivers, * as part of their gpio_free() semantics, platforms and individual drivers * shall *NOT* request GPIO pins to be muxed out. */ -void pinmux_free_gpio(unsigned gpio) +void pinctrl_free_gpio(unsigned gpio) { struct pinctrl_dev *pctldev; struct pinctrl_gpio_range *range; @@ -271,9 +271,9 @@ void pinmux_free_gpio(unsigned gpio) func = pin_free(pctldev, pin, range); kfree(func); } -EXPORT_SYMBOL_GPL(pinmux_free_gpio); +EXPORT_SYMBOL_GPL(pinctrl_free_gpio); -static int pinmux_gpio_direction(unsigned gpio, bool input) +static int pinctrl_gpio_direction(unsigned gpio, bool input) { struct pinctrl_dev *pctldev; struct pinctrl_gpio_range *range; @@ -299,36 +299,36 @@ static int pinmux_gpio_direction(unsigned gpio, bool input) } /** - * pinmux_gpio_direction_input() - request a GPIO pin to go into input mode + * pinctrl_gpio_direction_input() - request a GPIO pin to go into input mode * @gpio: the GPIO pin number from the GPIO subsystem number space * * This function should *ONLY* be used from gpiolib-based GPIO drivers, * as part of their gpio_direction_input() semantics, platforms and individual - * drivers shall *NOT* touch pinmux GPIO calls. + * drivers shall *NOT* touch pin control GPIO calls. */ -int pinmux_gpio_direction_input(unsigned gpio) +int pinctrl_gpio_direction_input(unsigned gpio) { - return pinmux_gpio_direction(gpio, true); + return pinctrl_gpio_direction(gpio, true); } -EXPORT_SYMBOL_GPL(pinmux_gpio_direction_input); +EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_input); /** - * pinmux_gpio_direction_output() - request a GPIO pin to go into output mode + * pinctrl_gpio_direction_output() - request a GPIO pin to go into output mode * @gpio: the GPIO pin number from the GPIO subsystem number space * * This function should *ONLY* be used from gpiolib-based GPIO drivers, * as part of their gpio_direction_output() semantics, platforms and individual - * drivers shall *NOT* touch pinmux GPIO calls. + * drivers shall *NOT* touch pin control GPIO calls. */ -int pinmux_gpio_direction_output(unsigned gpio) +int pinctrl_gpio_direction_output(unsigned gpio) { - return pinmux_gpio_direction(gpio, false); + return pinctrl_gpio_direction(gpio, false); } -EXPORT_SYMBOL_GPL(pinmux_gpio_direction_output); +EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_output); /** - * pinmux_register_mappings() - register a set of pinmux mappings - * @maps: the pinmux mappings table to register, this should be marked with + * pinctrl_register_mappings() - register a set of pin controller mappings + * @maps: the pincontrol mappings table to register, this should be marked with * __initdata so it can be discarded after boot, this function will * perform a shallow copy for the mapping entries. * @num_maps: the number of maps in the mapping table @@ -338,8 +338,8 @@ EXPORT_SYMBOL_GPL(pinmux_gpio_direction_output); * passed into this function will be owned by the pinmux core and cannot be * freed. */ -int __init pinmux_register_mappings(struct pinmux_map const *maps, - unsigned num_maps) +int __init pinctrl_register_mappings(struct pinctrl_map const *maps, + unsigned num_maps) { void *tmp_maps; int i; @@ -380,26 +380,27 @@ int __init pinmux_register_mappings(struct pinmux_map const *maps, * Make a copy of the map array - string pointers will end up in the * kernel const section anyway so these do not need to be deep copied. */ - if (!pinmux_maps_num) { + if (!pinctrl_maps_num) { /* On first call, just copy them */ tmp_maps = kmemdup(maps, - sizeof(struct pinmux_map) * num_maps, + sizeof(struct pinctrl_map) * num_maps, GFP_KERNEL); if (!tmp_maps) return -ENOMEM; } else { /* Subsequent calls, reallocate array to new size */ - size_t oldsize = sizeof(struct pinmux_map) * pinmux_maps_num; - size_t newsize = sizeof(struct pinmux_map) * num_maps; + size_t oldsize = sizeof(struct pinctrl_map) * pinctrl_maps_num; + size_t newsize = sizeof(struct pinctrl_map) * num_maps; - tmp_maps = krealloc(pinmux_maps, oldsize + newsize, GFP_KERNEL); + tmp_maps = krealloc(pinctrl_maps, + oldsize + newsize, GFP_KERNEL); if (!tmp_maps) return -ENOMEM; memcpy((tmp_maps + oldsize), maps, newsize); } - pinmux_maps = tmp_maps; - pinmux_maps_num += num_maps; + pinctrl_maps = tmp_maps; + pinctrl_maps_num += num_maps; return 0; } @@ -560,7 +561,7 @@ static int pinmux_check_pin_group(struct pinctrl_dev *pctldev, * negative otherwise */ static int pinmux_search_function(struct pinctrl_dev *pctldev, - struct pinmux_map const *map, + struct pinctrl_map const *map, unsigned *func_selector, unsigned *group_selector) { @@ -598,10 +599,10 @@ static int pinmux_search_function(struct pinctrl_dev *pctldev, * pinmux_enable_muxmap() - enable a map entry for a certain pinmux */ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev, - struct pinmux *pmx, + struct pinctrl *p, struct device *dev, const char *devname, - struct pinmux_map const *map) + struct pinctrl_map const *map) { unsigned func_selector; unsigned group_selector; @@ -615,14 +616,14 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev, * by anyone else. */ - if (pmx->pctldev && pmx->pctldev != pctldev) { + if (p->pctldev && p->pctldev != pctldev) { dev_err(pctldev->dev, "different pin control devices given for device %s, function %s\n", devname, map->function); return -EINVAL; } - pmx->dev = dev; - pmx->pctldev = pctldev; + p->dev = dev; + p->pctldev = pctldev; /* Now go into the driver and try to match a function and group */ ret = pinmux_search_function(pctldev, map, &func_selector, @@ -635,14 +636,14 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev, * we support several groups with one function but not several * functions with one or several groups in the same pinmux. */ - if (pmx->func_selector != UINT_MAX && - pmx->func_selector != func_selector) { + if (p->func_selector != UINT_MAX && + p->func_selector != func_selector) { dev_err(pctldev->dev, "dual function defines in the map for device %s\n", devname); return -EINVAL; } - pmx->func_selector = func_selector; + p->func_selector = func_selector; /* Now add this group selector, we may have many of them */ grp = kmalloc(sizeof(struct pinmux_group), GFP_KERNEL); @@ -654,38 +655,38 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev, kfree(grp); return ret; } - list_add(&grp->node, &pmx->groups); + list_add(&grp->node, &p->groups); return 0; } -static void pinmux_free_groups(struct pinmux *pmx) +static void pinmux_free_groups(struct pinctrl *p) { struct list_head *node, *tmp; - list_for_each_safe(node, tmp, &pmx->groups) { + list_for_each_safe(node, tmp, &p->groups) { struct pinmux_group *grp = list_entry(node, struct pinmux_group, node); /* Release all pins taken by this group */ - release_pins(pmx->pctldev, grp->group_selector); + release_pins(p->pctldev, grp->group_selector); list_del(node); kfree(grp); } } /** - * pinmux_get() - retrieves the pinmux for a certain device - * @dev: the device to get the pinmux for - * @name: an optional specific mux mapping name or NULL, the name is only + * pinctrl_get() - retrieves the pin controller handle for a certain device + * @dev: the device to get the pin controller handle for + * @name: an optional specific control mapping name or NULL, the name is only * needed if you want to have more than one mapping per device, or if you - * need an anonymous pinmux (not tied to any specific device) + * need an anonymous pin control (not tied to any specific device) */ -struct pinmux *pinmux_get(struct device *dev, const char *name) +struct pinctrl *pinctrl_get(struct device *dev, const char *name) { - struct pinmux_map const *map = NULL; + struct pinctrl_map const *map = NULL; struct pinctrl_dev *pctldev = NULL; const char *devname = NULL; - struct pinmux *pmx; + struct pinctrl *p; bool found_map; unsigned num_maps = 0; int ret = -ENODEV; @@ -706,16 +707,16 @@ struct pinmux *pinmux_get(struct device *dev, const char *name) * mapping, this is what consumers will get when requesting * a pinmux handle with pinmux_get() */ - pmx = kzalloc(sizeof(struct pinmux), GFP_KERNEL); - if (pmx == NULL) + p = kzalloc(sizeof(struct pinctrl), GFP_KERNEL); + if (p == NULL) return ERR_PTR(-ENOMEM); - mutex_init(&pmx->mutex); - pmx->func_selector = UINT_MAX; - INIT_LIST_HEAD(&pmx->groups); + mutex_init(&p->mutex); + p->func_selector = UINT_MAX; + INIT_LIST_HEAD(&p->groups); - /* Iterate over the pinmux maps to locate the right ones */ - for (i = 0; i < pinmux_maps_num; i++) { - map = &pinmux_maps[i]; + /* Iterate over the pin control maps to locate the right ones */ + for (i = 0; i < pinctrl_maps_num; i++) { + map = &pinctrl_maps[i]; found_map = false; /* @@ -763,11 +764,11 @@ struct pinmux *pinmux_get(struct device *dev, const char *name) /* If this map is applicable, then apply it */ if (found_map) { - ret = pinmux_enable_muxmap(pctldev, pmx, dev, + ret = pinmux_enable_muxmap(pctldev, p, dev, devname, map); if (ret) { - pinmux_free_groups(pmx); - kfree(pmx); + pinmux_free_groups(p); + kfree(p); return ERR_PTR(ret); } num_maps++; @@ -780,7 +781,7 @@ struct pinmux *pinmux_get(struct device *dev, const char *name) pr_err("could not find any mux maps for device %s, ID %s\n", devname ? devname : "(anonymous)", name ? name : "(undefined)"); - kfree(pmx); + kfree(p); return ERR_PTR(-EINVAL); } @@ -790,96 +791,96 @@ struct pinmux *pinmux_get(struct device *dev, const char *name) name ? name : "(undefined)"); /* Add the pinmux to the global list */ - mutex_lock(&pinmux_list_mutex); - list_add(&pmx->node, &pinmux_list); - mutex_unlock(&pinmux_list_mutex); + mutex_lock(&pinctrl_list_mutex); + list_add(&p->node, &pinctrl_list); + mutex_unlock(&pinctrl_list_mutex); - return pmx; + return p; } -EXPORT_SYMBOL_GPL(pinmux_get); +EXPORT_SYMBOL_GPL(pinctrl_get); /** - * pinmux_put() - release a previously claimed pinmux - * @pmx: a pinmux previously claimed by pinmux_get() + * pinctrl_put() - release a previously claimed pin control handle + * @p: a pin control handle previously claimed by pinctrl_get() */ -void pinmux_put(struct pinmux *pmx) +void pinctrl_put(struct pinctrl *p) { - if (pmx == NULL) + if (p == NULL) return; - mutex_lock(&pmx->mutex); - if (pmx->usecount) - pr_warn("releasing pinmux with active users!\n"); + mutex_lock(&p->mutex); + if (p->usecount) + pr_warn("releasing pin control handle with active users!\n"); /* Free the groups and all acquired pins */ - pinmux_free_groups(pmx); - mutex_unlock(&pmx->mutex); + pinmux_free_groups(p); + mutex_unlock(&p->mutex); /* Remove from list */ - mutex_lock(&pinmux_list_mutex); - list_del(&pmx->node); - mutex_unlock(&pinmux_list_mutex); + mutex_lock(&pinctrl_list_mutex); + list_del(&p->node); + mutex_unlock(&pinctrl_list_mutex); - kfree(pmx); + kfree(p); } -EXPORT_SYMBOL_GPL(pinmux_put); +EXPORT_SYMBOL_GPL(pinctrl_put); /** - * pinmux_enable() - enable a certain pinmux setting - * @pmx: the pinmux to enable, previously claimed by pinmux_get() + * pinctrl_enable() - enable a certain pin controller setting + * @p: the pin control handle to enable, previously claimed by pinctrl_get() */ -int pinmux_enable(struct pinmux *pmx) +int pinctrl_enable(struct pinctrl *p) { int ret = 0; - if (pmx == NULL) + if (p == NULL) return -EINVAL; - mutex_lock(&pmx->mutex); - if (pmx->usecount++ == 0) { - struct pinctrl_dev *pctldev = pmx->pctldev; + mutex_lock(&p->mutex); + if (p->usecount++ == 0) { + struct pinctrl_dev *pctldev = p->pctldev; const struct pinmux_ops *ops = pctldev->desc->pmxops; struct pinmux_group *grp; - list_for_each_entry(grp, &pmx->groups, node) { - ret = ops->enable(pctldev, pmx->func_selector, + list_for_each_entry(grp, &p->groups, node) { + ret = ops->enable(pctldev, p->func_selector, grp->group_selector); if (ret) { /* * TODO: call disable() on all groups we called * enable() on to this point? */ - pmx->usecount--; + p->usecount--; break; } } } - mutex_unlock(&pmx->mutex); + mutex_unlock(&p->mutex); return ret; } -EXPORT_SYMBOL_GPL(pinmux_enable); +EXPORT_SYMBOL_GPL(pinctrl_enable); /** - * pinmux_disable() - disable a certain pinmux setting - * @pmx: the pinmux to disable, previously claimed by pinmux_get() + * pinctrl_disable() - disable a certain pin control setting + * @p: the pin control handle to disable, previously claimed by pinctrl_get() */ -void pinmux_disable(struct pinmux *pmx) +void pinctrl_disable(struct pinctrl *p) { - if (pmx == NULL) + if (p == NULL) return; - mutex_lock(&pmx->mutex); - if (--pmx->usecount == 0) { - struct pinctrl_dev *pctldev = pmx->pctldev; + mutex_lock(&p->mutex); + if (--p->usecount == 0) { + struct pinctrl_dev *pctldev = p->pctldev; const struct pinmux_ops *ops = pctldev->desc->pmxops; struct pinmux_group *grp; - list_for_each_entry(grp, &pmx->groups, node) { - ops->disable(pctldev, pmx->func_selector, + list_for_each_entry(grp, &p->groups, node) { + ops->disable(pctldev, p->func_selector, grp->group_selector); } } - mutex_unlock(&pmx->mutex); + mutex_unlock(&p->mutex); } -EXPORT_SYMBOL_GPL(pinmux_disable); +EXPORT_SYMBOL_GPL(pinctrl_disable); int pinmux_check_ops(struct pinctrl_dev *pctldev) { @@ -910,11 +911,11 @@ int pinmux_check_ops(struct pinctrl_dev *pctldev) } /* Hog a single map entry and add to the hoglist */ -static int pinmux_hog_map(struct pinctrl_dev *pctldev, - struct pinmux_map const *map) +static int pinctrl_hog_map(struct pinctrl_dev *pctldev, + struct pinctrl_map const *map) { - struct pinmux_hog *hog; - struct pinmux *pmx; + struct pinctrl_hog *hog; + struct pinctrl *p; int ret; if (map->dev_name) { @@ -929,61 +930,61 @@ static int pinmux_hog_map(struct pinctrl_dev *pctldev, return -EINVAL; } - hog = kzalloc(sizeof(struct pinmux_hog), GFP_KERNEL); + hog = kzalloc(sizeof(struct pinctrl_hog), GFP_KERNEL); if (!hog) return -ENOMEM; - pmx = pinmux_get(NULL, map->name); - if (IS_ERR(pmx)) { + p = pinctrl_get(NULL, map->name); + if (IS_ERR(p)) { kfree(hog); dev_err(pctldev->dev, - "could not get the %s pinmux mapping for hogging\n", + "could not get the %s pin control mapping for hogging\n", map->name); - return PTR_ERR(pmx); + return PTR_ERR(p); } - ret = pinmux_enable(pmx); + ret = pinctrl_enable(p); if (ret) { - pinmux_put(pmx); + pinctrl_put(p); kfree(hog); dev_err(pctldev->dev, - "could not enable the %s pinmux mapping for hogging\n", + "could not enable the %s pin control mapping for hogging\n", map->name); return ret; } hog->map = map; - hog->pmx = pmx; + hog->p = p; dev_info(pctldev->dev, "hogged map %s, function %s\n", map->name, map->function); - mutex_lock(&pctldev->pinmux_hogs_lock); - list_add(&hog->node, &pctldev->pinmux_hogs); - mutex_unlock(&pctldev->pinmux_hogs_lock); + mutex_lock(&pctldev->pinctrl_hogs_lock); + list_add(&hog->node, &pctldev->pinctrl_hogs); + mutex_unlock(&pctldev->pinctrl_hogs_lock); return 0; } /** - * pinmux_hog_maps() - hog specific map entries on controller device + * pinctrl_hog_maps() - hog specific map entries on controller device * @pctldev: the pin control device to hog entries on * * When the pin controllers are registered, there may be some specific pinmux * map entries that need to be hogged, i.e. get+enabled until the system shuts * down. */ -int pinmux_hog_maps(struct pinctrl_dev *pctldev) +int pinctrl_hog_maps(struct pinctrl_dev *pctldev) { struct device *dev = pctldev->dev; const char *devname = dev_name(dev); int ret; int i; - INIT_LIST_HEAD(&pctldev->pinmux_hogs); - mutex_init(&pctldev->pinmux_hogs_lock); + INIT_LIST_HEAD(&pctldev->pinctrl_hogs); + mutex_init(&pctldev->pinctrl_hogs_lock); - for (i = 0; i < pinmux_maps_num; i++) { - struct pinmux_map const *map = &pinmux_maps[i]; + for (i = 0; i < pinctrl_maps_num; i++) { + struct pinctrl_map const *map = &pinctrl_maps[i]; if (!map->hog_on_boot) continue; @@ -991,7 +992,7 @@ int pinmux_hog_maps(struct pinctrl_dev *pctldev) if (map->ctrl_dev_name && !strcmp(map->ctrl_dev_name, devname)) { /* OK time to hog! */ - ret = pinmux_hog_map(pctldev, map); + ret = pinctrl_hog_map(pctldev, map); if (ret) return ret; } @@ -1000,23 +1001,23 @@ int pinmux_hog_maps(struct pinctrl_dev *pctldev) } /** - * pinmux_unhog_maps() - unhog specific map entries on controller device + * pinctrl_unhog_maps() - unhog specific map entries on controller device * @pctldev: the pin control device to unhog entries on */ -void pinmux_unhog_maps(struct pinctrl_dev *pctldev) +void pinctrl_unhog_maps(struct pinctrl_dev *pctldev) { struct list_head *node, *tmp; - mutex_lock(&pctldev->pinmux_hogs_lock); - list_for_each_safe(node, tmp, &pctldev->pinmux_hogs) { - struct pinmux_hog *hog = - list_entry(node, struct pinmux_hog, node); - pinmux_disable(hog->pmx); - pinmux_put(hog->pmx); + mutex_lock(&pctldev->pinctrl_hogs_lock); + list_for_each_safe(node, tmp, &pctldev->pinctrl_hogs) { + struct pinctrl_hog *hog = + list_entry(node, struct pinctrl_hog, node); + pinctrl_disable(hog->p); + pinctrl_put(hog->p); list_del(node); kfree(hog); } - mutex_unlock(&pctldev->pinmux_hogs_lock); + mutex_unlock(&pctldev->pinctrl_hogs_lock); } #ifdef CONFIG_DEBUG_FS @@ -1085,11 +1086,11 @@ static int pinmux_pins_show(struct seq_file *s, void *what) static int pinmux_hogs_show(struct seq_file *s, void *what) { struct pinctrl_dev *pctldev = s->private; - struct pinmux_hog *hog; + struct pinctrl_hog *hog; - seq_puts(s, "Pinmux map hogs held by device\n"); + seq_puts(s, "Pin control map hogs held by device\n"); - list_for_each_entry(hog, &pctldev->pinmux_hogs, node) + list_for_each_entry(hog, &pctldev->pinctrl_hogs, node) seq_printf(s, "%s\n", hog->map->name); return 0; @@ -1097,11 +1098,11 @@ static int pinmux_hogs_show(struct seq_file *s, void *what) static int pinmux_show(struct seq_file *s, void *what) { - struct pinmux *pmx; + struct pinctrl *p; seq_puts(s, "Requested pinmuxes and their maps:\n"); - list_for_each_entry(pmx, &pinmux_list, node) { - struct pinctrl_dev *pctldev = pmx->pctldev; + list_for_each_entry(p, &pinctrl_list, node) { + struct pinctrl_dev *pctldev = p->pctldev; const struct pinmux_ops *pmxops; const struct pinctrl_ops *pctlops; struct pinmux_group *grp; @@ -1115,13 +1116,13 @@ static int pinmux_show(struct seq_file *s, void *what) pctlops = pctldev->desc->pctlops; seq_printf(s, "device: %s function: %s (%u),", - pinctrl_dev_get_name(pmx->pctldev), + pinctrl_dev_get_name(p->pctldev), pmxops->get_function_name(pctldev, - pmx->func_selector), - pmx->func_selector); + p->func_selector), + p->func_selector); seq_printf(s, " groups: ["); - list_for_each_entry(grp, &pmx->groups, node) { + list_for_each_entry(grp, &p->groups, node) { seq_printf(s, " %s (%u)", pctlops->get_group_name(pctldev, grp->group_selector), @@ -1130,21 +1131,21 @@ static int pinmux_show(struct seq_file *s, void *what) seq_printf(s, " ]"); seq_printf(s, " users: %u map-> %s\n", - pmx->usecount, - pmx->dev ? dev_name(pmx->dev) : "(system)"); + p->usecount, + p->dev ? dev_name(p->dev) : "(system)"); } return 0; } -static int pinmux_maps_show(struct seq_file *s, void *what) +static int pinctrl_maps_show(struct seq_file *s, void *what) { int i; - seq_puts(s, "Pinmux maps:\n"); + seq_puts(s, "Pinctrl maps:\n"); - for (i = 0; i < pinmux_maps_num; i++) { - struct pinmux_map const *map = &pinmux_maps[i]; + for (i = 0; i < pinctrl_maps_num; i++) { + struct pinctrl_map const *map = &pinctrl_maps[i]; seq_printf(s, "%s:\n", map->name); if (map->dev_name) @@ -1181,9 +1182,9 @@ static int pinmux_open(struct inode *inode, struct file *file) return single_open(file, pinmux_show, NULL); } -static int pinmux_maps_open(struct inode *inode, struct file *file) +static int pinctrl_maps_open(struct inode *inode, struct file *file) { - return single_open(file, pinmux_maps_show, NULL); + return single_open(file, pinctrl_maps_show, NULL); } static const struct file_operations pinmux_functions_ops = { @@ -1214,8 +1215,8 @@ static const struct file_operations pinmux_ops = { .release = single_release, }; -static const struct file_operations pinmux_maps_ops = { - .open = pinmux_maps_open, +static const struct file_operations pinctrl_maps_ops = { + .open = pinctrl_maps_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, @@ -1236,8 +1237,8 @@ void pinmux_init_debugfs(struct dentry *subsys_root) { debugfs_create_file("pinmuxes", S_IFREG | S_IRUGO, subsys_root, NULL, &pinmux_ops); - debugfs_create_file("pinmux-maps", S_IFREG | S_IRUGO, - subsys_root, NULL, &pinmux_maps_ops); + debugfs_create_file("pinctrl-maps", S_IFREG | S_IRUGO, + subsys_root, NULL, &pinctrl_maps_ops); } #endif /* CONFIG_DEBUG_FS */ diff --git a/drivers/pinctrl/pinmux.h b/drivers/pinctrl/pinmux.h index 97f52223fbc..dfe81726965 100644 --- a/drivers/pinctrl/pinmux.h +++ b/drivers/pinctrl/pinmux.h @@ -16,8 +16,8 @@ int pinmux_check_ops(struct pinctrl_dev *pctldev); void pinmux_init_device_debugfs(struct dentry *devroot, struct pinctrl_dev *pctldev); void pinmux_init_debugfs(struct dentry *subsys_root); -int pinmux_hog_maps(struct pinctrl_dev *pctldev); -void pinmux_unhog_maps(struct pinctrl_dev *pctldev); +int pinctrl_hog_maps(struct pinctrl_dev *pctldev); +void pinctrl_unhog_maps(struct pinctrl_dev *pctldev); #else @@ -35,12 +35,12 @@ static inline void pinmux_init_debugfs(struct dentry *subsys_root) { } -static inline int pinmux_hog_maps(struct pinctrl_dev *pctldev) +static inline int pinctrl_hog_maps(struct pinctrl_dev *pctldev) { return 0; } -static inline void pinmux_unhog_maps(struct pinctrl_dev *pctldev) +static inline void pinctrl_unhog_maps(struct pinctrl_dev *pctldev) { } diff --git a/include/linux/pinctrl/consumer.h b/include/linux/pinctrl/consumer.h index 9c8513d5d0f..c7d06177629 100644 --- a/include/linux/pinctrl/consumer.h +++ b/include/linux/pinctrl/consumer.h @@ -17,56 +17,56 @@ #include "pinctrl.h" /* This struct is private to the core and should be regarded as a cookie */ -struct pinmux; +struct pinctrl; #ifdef CONFIG_PINMUX /* External interface to pinmux */ -extern int pinmux_request_gpio(unsigned gpio); -extern void pinmux_free_gpio(unsigned gpio); -extern int pinmux_gpio_direction_input(unsigned gpio); -extern int pinmux_gpio_direction_output(unsigned gpio); -extern struct pinmux * __must_check pinmux_get(struct device *dev, const char *name); -extern void pinmux_put(struct pinmux *pmx); -extern int pinmux_enable(struct pinmux *pmx); -extern void pinmux_disable(struct pinmux *pmx); +extern int pinctrl_request_gpio(unsigned gpio); +extern void pinctrl_free_gpio(unsigned gpio); +extern int pinctrl_gpio_direction_input(unsigned gpio); +extern int pinctrl_gpio_direction_output(unsigned gpio); +extern struct pinctrl * __must_check pinctrl_get(struct device *dev, const char *name); +extern void pinctrl_put(struct pinctrl *p); +extern int pinctrl_enable(struct pinctrl *p); +extern void pinctrl_disable(struct pinctrl *p); #else /* !CONFIG_PINMUX */ -static inline int pinmux_request_gpio(unsigned gpio) +static inline int pinctrl_request_gpio(unsigned gpio) { return 0; } -static inline void pinmux_free_gpio(unsigned gpio) +static inline void pinctrl_free_gpio(unsigned gpio) { } -static inline int pinmux_gpio_direction_input(unsigned gpio) +static inline int pinctrl_gpio_direction_input(unsigned gpio) { return 0; } -static inline int pinmux_gpio_direction_output(unsigned gpio) +static inline int pinctrl_gpio_direction_output(unsigned gpio) { return 0; } -static inline struct pinmux * __must_check pinmux_get(struct device *dev, const char *name) +static inline struct pinctrl * __must_check pinctrl_get(struct device *dev, const char *name) { return NULL; } -static inline void pinmux_put(struct pinmux *pmx) +static inline void pinctrl_put(struct pinctrl *p) { } -static inline int pinmux_enable(struct pinmux *pmx) +static inline int pinctrl_enable(struct pinctrl *p) { return 0; } -static inline void pinmux_disable(struct pinmux *pmx) +static inline void pinctrl_disable(struct pinctrl *p) { } diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index f8593fdc646..a2ab524a010 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -9,11 +9,11 @@ * * License terms: GNU General Public License (GPL) version 2 */ -#ifndef __LINUX_PINMUX_MACHINE_H -#define __LINUX_PINMUX_MACHINE_H +#ifndef __LINUX_PINCTRL_MACHINE_H +#define __LINUX_PINCTRL_MACHINE_H /** - * struct pinmux_map - boards/machines shall provide this map for devices + * struct pinctrl_map - boards/machines shall provide this map for devices * @name: the name of this specific map entry for the particular machine. * This is the second parameter passed to pinmux_get() when you want * to have several mappings to the same device @@ -34,7 +34,7 @@ * a pinmux device supporting it is registered. These maps will not be * disabled and put until the system shuts down. */ -struct pinmux_map { +struct pinctrl_map { const char *name; const char *ctrl_dev_name; const char *function; @@ -47,41 +47,41 @@ struct pinmux_map { * Convenience macro to set a simple map from a certain pin controller and a * certain function to a named device */ -#define PINMUX_MAP(a, b, c, d) \ +#define PIN_MAP(a, b, c, d) \ { .name = a, .ctrl_dev_name = b, .function = c, .dev_name = d } /* * Convenience macro to map a system function onto a certain pinctrl device. * System functions are not assigned to a particular device. */ -#define PINMUX_MAP_SYS(a, b, c) \ +#define PIN_MAP_SYS(a, b, c) \ { .name = a, .ctrl_dev_name = b, .function = c } /* * Convenience macro to map a system function onto a certain pinctrl device, - * to be hogged by the pinmux core until the system shuts down. + * to be hogged by the pin control core until the system shuts down. */ -#define PINMUX_MAP_SYS_HOG(a, b, c) \ +#define PIN_MAP_SYS_HOG(a, b, c) \ { .name = a, .ctrl_dev_name = b, .function = c, \ .hog_on_boot = true } /* * Convenience macro to map a system function onto a certain pinctrl device - * using a specified group, to be hogged by the pinmux core until the system - * shuts down. + * using a specified group, to be hogged by the pin control core until the + * system shuts down. */ -#define PINMUX_MAP_SYS_HOG_GROUP(a, b, c, d) \ +#define PIN_MAP_SYS_HOG_GROUP(a, b, c, d) \ { .name = a, .ctrl_dev_name = b, .function = c, .group = d, \ .hog_on_boot = true } #ifdef CONFIG_PINMUX -extern int pinmux_register_mappings(struct pinmux_map const *map, +extern int pinctrl_register_mappings(struct pinctrl_map const *map, unsigned num_maps); #else -static inline int pinmux_register_mappings(struct pinmux_map const *map, +static inline int pinctrl_register_mappings(struct pinctrl_map const *map, unsigned num_maps) { return 0; -- cgit v1.2.3-70-g09d2 From befe5bdfbb698b3bc57c58d0bd7ca3391c9275ed Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 9 Feb 2012 19:47:48 +0100 Subject: pinctrl: factor pin control handles over to the core This moves the per-devices struct pinctrl handles and device map over from the pinmux part of the subsystem to the core pinctrl part. This makes the device handles core infrastructure with the goal of using these handles also for pin configuration, so that device drivers (or boards etc) will need one and only one handle to the pin control core. Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/pinctrl/core.c | 598 +++++++++++++++++++++++++++++++- drivers/pinctrl/core.h | 30 +- drivers/pinctrl/pinmux.c | 711 +++++---------------------------------- drivers/pinctrl/pinmux.h | 67 +++- include/linux/pinctrl/consumer.h | 8 +- 5 files changed, 779 insertions(+), 635 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 75c6a6bb6c0..ec32c545f07 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -1,7 +1,7 @@ /* * Core driver for the pin control subsystem * - * Copyright (C) 2011 ST-Ericsson SA + * Copyright (C) 2011-2012 ST-Ericsson SA * Written on behalf of Linaro for ST-Ericsson * Based on bits of regulator core, gpio core and clk core * @@ -30,10 +30,30 @@ #include "pinmux.h" #include "pinconf.h" +/** + * struct pinctrl_hog - a list item to stash control hogs + * @node: pin control hog list node + * @map: map entry responsible for this hogging + * @pmx: the pin control hogged by this item + */ +struct pinctrl_hog { + struct list_head node; + struct pinctrl_map const *map; + struct pinctrl *p; +}; + /* Global list of pin control devices */ static DEFINE_MUTEX(pinctrldev_list_mutex); static LIST_HEAD(pinctrldev_list); +/* List of pin controller handles */ +static DEFINE_MUTEX(pinctrl_list_mutex); +static LIST_HEAD(pinctrl_list); + +/* Global pinctrl maps */ +static struct pinctrl_map *pinctrl_maps; +static unsigned pinctrl_maps_num; + const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev) { /* We're not allowed to register devices without name */ @@ -337,6 +357,476 @@ int pinctrl_get_group_selector(struct pinctrl_dev *pctldev, return -EINVAL; } +/** + * pinctrl_request_gpio() - request a single pin to be used in as GPIO + * @gpio: the GPIO pin number from the GPIO subsystem number space + * + * This function should *ONLY* be used from gpiolib-based GPIO drivers, + * as part of their gpio_request() semantics, platforms and individual drivers + * shall *NOT* request GPIO pins to be muxed in. + */ +int pinctrl_request_gpio(unsigned gpio) +{ + struct pinctrl_dev *pctldev; + struct pinctrl_gpio_range *range; + int ret; + int pin; + + ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); + if (ret) + return -EINVAL; + + /* Convert to the pin controllers number space */ + pin = gpio - range->base + range->pin_base; + + return pinmux_request_gpio(pctldev, range, pin, gpio); +} +EXPORT_SYMBOL_GPL(pinctrl_request_gpio); + +/** + * pinctrl_free_gpio() - free control on a single pin, currently used as GPIO + * @gpio: the GPIO pin number from the GPIO subsystem number space + * + * This function should *ONLY* be used from gpiolib-based GPIO drivers, + * as part of their gpio_free() semantics, platforms and individual drivers + * shall *NOT* request GPIO pins to be muxed out. + */ +void pinctrl_free_gpio(unsigned gpio) +{ + struct pinctrl_dev *pctldev; + struct pinctrl_gpio_range *range; + int ret; + int pin; + + ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); + if (ret) + return; + + /* Convert to the pin controllers number space */ + pin = gpio - range->base + range->pin_base; + + return pinmux_free_gpio(pctldev, pin, range); +} +EXPORT_SYMBOL_GPL(pinctrl_free_gpio); + +static int pinctrl_gpio_direction(unsigned gpio, bool input) +{ + struct pinctrl_dev *pctldev; + struct pinctrl_gpio_range *range; + int ret; + int pin; + + ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); + if (ret) + return ret; + + /* Convert to the pin controllers number space */ + pin = gpio - range->base + range->pin_base; + + return pinmux_gpio_direction(pctldev, range, pin, input); +} + +/** + * pinctrl_gpio_direction_input() - request a GPIO pin to go into input mode + * @gpio: the GPIO pin number from the GPIO subsystem number space + * + * This function should *ONLY* be used from gpiolib-based GPIO drivers, + * as part of their gpio_direction_input() semantics, platforms and individual + * drivers shall *NOT* touch pin control GPIO calls. + */ +int pinctrl_gpio_direction_input(unsigned gpio) +{ + return pinctrl_gpio_direction(gpio, true); +} +EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_input); + +/** + * pinctrl_gpio_direction_output() - request a GPIO pin to go into output mode + * @gpio: the GPIO pin number from the GPIO subsystem number space + * + * This function should *ONLY* be used from gpiolib-based GPIO drivers, + * as part of their gpio_direction_output() semantics, platforms and individual + * drivers shall *NOT* touch pin control GPIO calls. + */ +int pinctrl_gpio_direction_output(unsigned gpio) +{ + return pinctrl_gpio_direction(gpio, false); +} +EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_output); + +/** + * pinctrl_get() - retrieves the pin controller handle for a certain device + * @dev: the device to get the pin controller handle for + * @name: an optional specific control mapping name or NULL, the name is only + * needed if you want to have more than one mapping per device, or if you + * need an anonymous pin control (not tied to any specific device) + */ +struct pinctrl *pinctrl_get(struct device *dev, const char *name) +{ + struct pinctrl_map const *map = NULL; + struct pinctrl_dev *pctldev = NULL; + const char *devname = NULL; + struct pinctrl *p; + bool found_map; + unsigned num_maps = 0; + int ret = -ENODEV; + int i; + + /* We must have dev or ID or both */ + if (!dev && !name) + return ERR_PTR(-EINVAL); + + if (dev) + devname = dev_name(dev); + + pr_debug("get pin control handle %s for device %s\n", name, + devname ? devname : "(none)"); + + /* + * create the state cookie holder struct pinctrl for each + * mapping, this is what consumers will get when requesting + * a pin control handle with pinctrl_get() + */ + p = kzalloc(sizeof(struct pinctrl), GFP_KERNEL); + if (p == NULL) + return ERR_PTR(-ENOMEM); + mutex_init(&p->mutex); + pinmux_init_pinctrl_handle(p); + + /* Iterate over the pin control maps to locate the right ones */ + for (i = 0; i < pinctrl_maps_num; i++) { + map = &pinctrl_maps[i]; + found_map = false; + + /* + * First, try to find the pctldev given in the map + */ + pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name); + if (!pctldev) { + pr_warning("could not find a pinctrl device for pinmux function %s, fishy, they shall all have one\n", + map->function); + pr_warning("given pinctrl device name: %s", + map->ctrl_dev_name); + + /* Continue to check the other mappings anyway... */ + continue; + } + + pr_debug("in map, found pctldev %s to handle function %s", + dev_name(pctldev->dev), map->function); + + + /* + * If we're looking for a specific named map, this must match, + * else we loop and look for the next. + */ + if (name != NULL) { + if (map->name == NULL) + continue; + if (strcmp(map->name, name)) + continue; + } + + /* + * This is for the case where no device name is given, we + * already know that the function name matches from above + * code. + */ + if (!map->dev_name && (name != NULL)) + found_map = true; + + /* If the mapping has a device set up it must match */ + if (map->dev_name && + (!devname || !strcmp(map->dev_name, devname))) + /* MATCH! */ + found_map = true; + + /* If this map is applicable, then apply it */ + if (found_map) { + ret = pinmux_apply_muxmap(pctldev, p, dev, + devname, map); + if (ret) { + kfree(p); + return ERR_PTR(ret); + } + num_maps++; + } + } + + /* We should have atleast one map, right */ + if (!num_maps) { + pr_err("could not find any mux maps for device %s, ID %s\n", + devname ? devname : "(anonymous)", + name ? name : "(undefined)"); + kfree(p); + return ERR_PTR(-EINVAL); + } + + pr_debug("found %u mux maps for device %s, UD %s\n", + num_maps, + devname ? devname : "(anonymous)", + name ? name : "(undefined)"); + + /* Add the pinmux to the global list */ + mutex_lock(&pinctrl_list_mutex); + list_add(&p->node, &pinctrl_list); + mutex_unlock(&pinctrl_list_mutex); + + return p; +} +EXPORT_SYMBOL_GPL(pinctrl_get); + +/** + * pinctrl_put() - release a previously claimed pin control handle + * @p: a pin control handle previously claimed by pinctrl_get() + */ +void pinctrl_put(struct pinctrl *p) +{ + if (p == NULL) + return; + + mutex_lock(&p->mutex); + if (p->usecount) + pr_warn("releasing pin control handle with active users!\n"); + /* Free the groups and all acquired pins */ + pinmux_put(p); + mutex_unlock(&p->mutex); + + /* Remove from list */ + mutex_lock(&pinctrl_list_mutex); + list_del(&p->node); + mutex_unlock(&pinctrl_list_mutex); + + kfree(p); +} +EXPORT_SYMBOL_GPL(pinctrl_put); + +/** + * pinctrl_enable() - enable a certain pin controller setting + * @p: the pin control handle to enable, previously claimed by pinctrl_get() + */ +int pinctrl_enable(struct pinctrl *p) +{ + int ret = 0; + + if (p == NULL) + return -EINVAL; + mutex_lock(&p->mutex); + if (p->usecount++ == 0) { + ret = pinmux_enable(p); + if (ret) + p->usecount--; + } + mutex_unlock(&p->mutex); + return ret; +} +EXPORT_SYMBOL_GPL(pinctrl_enable); + +/** + * pinctrl_disable() - disable a certain pin control setting + * @p: the pin control handle to disable, previously claimed by pinctrl_get() + */ +void pinctrl_disable(struct pinctrl *p) +{ + if (p == NULL) + return; + + mutex_lock(&p->mutex); + if (--p->usecount == 0) { + pinmux_disable(p); + } + mutex_unlock(&p->mutex); +} +EXPORT_SYMBOL_GPL(pinctrl_disable); + +/** + * pinctrl_register_mappings() - register a set of pin controller mappings + * @maps: the pincontrol mappings table to register, this should be marked with + * __initdata so it can be discarded after boot, this function will + * perform a shallow copy for the mapping entries. + * @num_maps: the number of maps in the mapping table + * + * Only call this once during initialization of your machine, the function is + * tagged as __init and won't be callable after init has completed. The map + * passed into this function will be owned by the pinmux core and cannot be + * freed. + */ +int __init pinctrl_register_mappings(struct pinctrl_map const *maps, + unsigned num_maps) +{ + void *tmp_maps; + int i; + + pr_debug("add %d pinmux maps\n", num_maps); + + /* First sanity check the new mapping */ + for (i = 0; i < num_maps; i++) { + if (!maps[i].name) { + pr_err("failed to register map %d: no map name given\n", + i); + return -EINVAL; + } + + if (!maps[i].ctrl_dev_name) { + pr_err("failed to register map %s (%d): no pin control device given\n", + maps[i].name, i); + return -EINVAL; + } + + if (!maps[i].function) { + pr_err("failed to register map %s (%d): no function ID given\n", + maps[i].name, i); + return -EINVAL; + } + + if (!maps[i].dev_name) + pr_debug("add system map %s function %s with no device\n", + maps[i].name, + maps[i].function); + else + pr_debug("register map %s, function %s\n", + maps[i].name, + maps[i].function); + } + + /* + * Make a copy of the map array - string pointers will end up in the + * kernel const section anyway so these do not need to be deep copied. + */ + if (!pinctrl_maps_num) { + /* On first call, just copy them */ + tmp_maps = kmemdup(maps, + sizeof(struct pinctrl_map) * num_maps, + GFP_KERNEL); + if (!tmp_maps) + return -ENOMEM; + } else { + /* Subsequent calls, reallocate array to new size */ + size_t oldsize = sizeof(struct pinctrl_map) * pinctrl_maps_num; + size_t newsize = sizeof(struct pinctrl_map) * num_maps; + + tmp_maps = krealloc(pinctrl_maps, + oldsize + newsize, GFP_KERNEL); + if (!tmp_maps) + return -ENOMEM; + memcpy((tmp_maps + oldsize), maps, newsize); + } + + pinctrl_maps = tmp_maps; + pinctrl_maps_num += num_maps; + return 0; +} + +/* Hog a single map entry and add to the hoglist */ +static int pinctrl_hog_map(struct pinctrl_dev *pctldev, + struct pinctrl_map const *map) +{ + struct pinctrl_hog *hog; + struct pinctrl *p; + int ret; + + if (map->dev_name) { + /* + * TODO: the day we have device tree support, we can + * traverse the device tree and hog to specific device nodes + * without any problems, so then we can hog pinmuxes for + * all devices that just want a static pin mux at this point. + */ + dev_err(pctldev->dev, "map %s wants to hog a non-system pinmux, this is not going to work\n", + map->name); + return -EINVAL; + } + + hog = kzalloc(sizeof(struct pinctrl_hog), GFP_KERNEL); + if (!hog) + return -ENOMEM; + + p = pinctrl_get(NULL, map->name); + if (IS_ERR(p)) { + kfree(hog); + dev_err(pctldev->dev, + "could not get the %s pin control mapping for hogging\n", + map->name); + return PTR_ERR(p); + } + + ret = pinctrl_enable(p); + if (ret) { + pinctrl_put(p); + kfree(hog); + dev_err(pctldev->dev, + "could not enable the %s pin control mapping for hogging\n", + map->name); + return ret; + } + + hog->map = map; + hog->p = p; + + dev_info(pctldev->dev, "hogged map %s, function %s\n", map->name, + map->function); + mutex_lock(&pctldev->pinctrl_hogs_lock); + list_add(&hog->node, &pctldev->pinctrl_hogs); + mutex_unlock(&pctldev->pinctrl_hogs_lock); + + return 0; +} + +/** + * pinctrl_hog_maps() - hog specific map entries on controller device + * @pctldev: the pin control device to hog entries on + * + * When the pin controllers are registered, there may be some specific pinmux + * map entries that need to be hogged, i.e. get+enabled until the system shuts + * down. + */ +int pinctrl_hog_maps(struct pinctrl_dev *pctldev) +{ + struct device *dev = pctldev->dev; + const char *devname = dev_name(dev); + int ret; + int i; + + INIT_LIST_HEAD(&pctldev->pinctrl_hogs); + mutex_init(&pctldev->pinctrl_hogs_lock); + + for (i = 0; i < pinctrl_maps_num; i++) { + struct pinctrl_map const *map = &pinctrl_maps[i]; + + if (!map->hog_on_boot) + continue; + + if (map->ctrl_dev_name && + !strcmp(map->ctrl_dev_name, devname)) { + /* OK time to hog! */ + ret = pinctrl_hog_map(pctldev, map); + if (ret) + return ret; + } + } + return 0; +} + +/** + * pinctrl_unhog_maps() - unhog specific map entries on controller device + * @pctldev: the pin control device to unhog entries on + */ +void pinctrl_unhog_maps(struct pinctrl_dev *pctldev) +{ + struct list_head *node, *tmp; + + mutex_lock(&pctldev->pinctrl_hogs_lock); + list_for_each_safe(node, tmp, &pctldev->pinctrl_hogs) { + struct pinctrl_hog *hog = + list_entry(node, struct pinctrl_hog, node); + pinctrl_disable(hog->p); + pinctrl_put(hog->p); + list_del(node); + kfree(hog); + } + mutex_unlock(&pctldev->pinctrl_hogs_lock); +} + #ifdef CONFIG_DEBUG_FS static int pinctrl_pins_show(struct seq_file *s, void *what) @@ -427,6 +917,43 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what) return 0; } +static int pinctrl_maps_show(struct seq_file *s, void *what) +{ + int i; + + seq_puts(s, "Pinctrl maps:\n"); + + for (i = 0; i < pinctrl_maps_num; i++) { + struct pinctrl_map const *map = &pinctrl_maps[i]; + + seq_printf(s, "%s:\n", map->name); + if (map->dev_name) + seq_printf(s, " device: %s\n", + map->dev_name); + else + seq_printf(s, " SYSTEM MUX\n"); + seq_printf(s, " controlling device %s\n", + map->ctrl_dev_name); + seq_printf(s, " function: %s\n", map->function); + seq_printf(s, " group: %s\n", map->group ? map->group : + "(default)"); + } + return 0; +} + +static int pinmux_hogs_show(struct seq_file *s, void *what) +{ + struct pinctrl_dev *pctldev = s->private; + struct pinctrl_hog *hog; + + seq_puts(s, "Pin control map hogs held by device\n"); + + list_for_each_entry(hog, &pctldev->pinctrl_hogs, node) + seq_printf(s, "%s\n", hog->map->name); + + return 0; +} + static int pinctrl_devices_show(struct seq_file *s, void *what) { struct pinctrl_dev *pctldev; @@ -450,6 +977,32 @@ static int pinctrl_devices_show(struct seq_file *s, void *what) return 0; } +static int pinctrl_show(struct seq_file *s, void *what) +{ + struct pinctrl *p; + + seq_puts(s, "Requested pin control handlers their pinmux maps:\n"); + list_for_each_entry(p, &pinctrl_list, node) { + struct pinctrl_dev *pctldev = p->pctldev; + + if (!pctldev) { + seq_puts(s, "NO PIN CONTROLLER DEVICE\n"); + continue; + } + + seq_printf(s, "device: %s", + pinctrl_dev_get_name(p->pctldev)); + + pinmux_dbg_show(s, p); + + seq_printf(s, " users: %u map-> %s\n", + p->usecount, + p->dev ? dev_name(p->dev) : "(system)"); + } + + return 0; +} + static int pinctrl_pins_open(struct inode *inode, struct file *file) { return single_open(file, pinctrl_pins_show, inode->i_private); @@ -465,11 +1018,26 @@ static int pinctrl_gpioranges_open(struct inode *inode, struct file *file) return single_open(file, pinctrl_gpioranges_show, inode->i_private); } +static int pinctrl_maps_open(struct inode *inode, struct file *file) +{ + return single_open(file, pinctrl_maps_show, inode->i_private); +} + +static int pinmux_hogs_open(struct inode *inode, struct file *file) +{ + return single_open(file, pinmux_hogs_show, inode->i_private); +} + static int pinctrl_devices_open(struct inode *inode, struct file *file) { return single_open(file, pinctrl_devices_show, NULL); } +static int pinctrl_open(struct inode *inode, struct file *file) +{ + return single_open(file, pinctrl_show, NULL); +} + static const struct file_operations pinctrl_pins_ops = { .open = pinctrl_pins_open, .read = seq_read, @@ -491,6 +1059,20 @@ static const struct file_operations pinctrl_gpioranges_ops = { .release = single_release, }; +static const struct file_operations pinctrl_maps_ops = { + .open = pinctrl_maps_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static const struct file_operations pinmux_hogs_ops = { + .open = pinmux_hogs_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + static const struct file_operations pinctrl_devices_ops = { .open = pinctrl_devices_open, .read = seq_read, @@ -498,6 +1080,13 @@ static const struct file_operations pinctrl_devices_ops = { .release = single_release, }; +static const struct file_operations pinctrl_ops = { + .open = pinctrl_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + static struct dentry *debugfs_root; static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev) @@ -519,6 +1108,10 @@ static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev) device_root, pctldev, &pinctrl_groups_ops); debugfs_create_file("gpio-ranges", S_IFREG | S_IRUGO, device_root, pctldev, &pinctrl_gpioranges_ops); + debugfs_create_file("pinctrl-maps", S_IFREG | S_IRUGO, + device_root, pctldev, &pinctrl_maps_ops); + debugfs_create_file("pinmux-hogs", S_IFREG | S_IRUGO, + device_root, pctldev, &pinmux_hogs_ops); pinmux_init_device_debugfs(device_root, pctldev); pinconf_init_device_debugfs(device_root, pctldev); } @@ -539,7 +1132,8 @@ static void pinctrl_init_debugfs(void) debugfs_create_file("pinctrl-devices", S_IFREG | S_IRUGO, debugfs_root, NULL, &pinctrl_devices_ops); - pinmux_init_debugfs(debugfs_root); + debugfs_create_file("pinctrl-handles", S_IFREG | S_IRUGO, + debugfs_root, NULL, &pinctrl_ops); } #else /* CONFIG_DEBUG_FS */ diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 7a89888fce9..a50cdb053c8 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -30,6 +30,7 @@ struct pinctrl_gpio_range; * subsystem * @pinctrl_hogs_lock: lock for the pin control hog list * @pinctrl_hogs: list of pin control maps hogged by this device + * @device_root: debugfs root for this device */ struct pinctrl_dev { struct list_head node; @@ -41,12 +42,37 @@ struct pinctrl_dev { struct device *dev; struct module *owner; void *driver_data; + struct mutex pinctrl_hogs_lock; + struct list_head pinctrl_hogs; #ifdef CONFIG_DEBUG_FS struct dentry *device_root; #endif +}; + +/** + * struct pinctrl - per-device pin control state holder + * @node: global list node + * @dev: the device using this pin control handle + * @usecount: the number of active users of this pin controller setting, used + * to keep track of nested use cases + * @pctldev: pin control device handling this pin control handle + * @mutex: a lock for the pin control state holder + * @func_selector: the function selector for the pinmux device handling + * this pinmux + * @groups: the group selectors for the pinmux device and + * selector combination handling this pinmux, this is a list that + * will be traversed on all pinmux operations such as + * get/put/enable/disable + */ +struct pinctrl { + struct list_head node; + struct device *dev; + unsigned usecount; + struct pinctrl_dev *pctldev; + struct mutex mutex; #ifdef CONFIG_PINMUX - struct mutex pinctrl_hogs_lock; - struct list_head pinctrl_hogs; + unsigned func_selector; + struct list_head groups; #endif }; diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 773835d18f5..fe4a00751c6 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -28,14 +28,7 @@ #include #include #include "core.h" - -/* List of pin controller handles */ -static DEFINE_MUTEX(pinctrl_list_mutex); -static LIST_HEAD(pinctrl_list); - -/* Global pinctrl maps */ -static struct pinctrl_map *pinctrl_maps; -static unsigned pinctrl_maps_num; +#include "pinmux.h" /** * struct pinmux_group - group list item for pinmux groups @@ -47,43 +40,6 @@ struct pinmux_group { unsigned group_selector; }; -/** - * struct pinctrl - per-device pin control state holder - * @node: global list node - * @dev: the device using this pin control handle - * @usecount: the number of active users of this pin controller setting, used - * to keep track of nested use cases - * @pctldev: pin control device handling this pin control handle - * @func_selector: the function selector for the pinmux device handling - * this pinmux - * @groups: the group selectors for the pinmux device and - * selector combination handling this pinmux, this is a list that - * will be traversed on all pinmux operations such as - * get/put/enable/disable - * @mutex: a lock for the pinmux state holder - */ -struct pinctrl { - struct list_head node; - struct device *dev; - unsigned usecount; - struct pinctrl_dev *pctldev; - unsigned func_selector; - struct list_head groups; - struct mutex mutex; -}; - -/** - * struct pinctrl_hog - a list item to stash control hogs - * @node: pin control hog list node - * @map: map entry responsible for this hogging - * @pmx: the pin control hogged by this item - */ -struct pinctrl_hog { - struct list_head node; - struct pinctrl_map const *map; - struct pinctrl *p; -}; - /** * pin_request() - request a single pin to be muxed in, typically for GPIO * @pin: the pin number in the global pin space @@ -207,28 +163,18 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin, } /** - * pinctrl_request_gpio() - request a single pin to be used in as GPIO - * @gpio: the GPIO pin number from the GPIO subsystem number space - * - * This function should *ONLY* be used from gpiolib-based GPIO drivers, - * as part of their gpio_request() semantics, platforms and individual drivers - * shall *NOT* request GPIO pins to be muxed in. + * pinmux_request_gpio() - request pinmuxing for a GPIO pin + * @pctldev: pin controller device affected + * @pin: the pin to mux in for GPIO + * @range: the applicable GPIO range */ -int pinctrl_request_gpio(unsigned gpio) +int pinmux_request_gpio(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned pin, unsigned gpio) { char gpiostr[16]; const char *function; - struct pinctrl_dev *pctldev; - struct pinctrl_gpio_range *range; int ret; - int pin; - - ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); - if (ret) - return -EINVAL; - - /* Convert to the pin controllers number space */ - pin = gpio - range->base + range->pin_base; /* Conjure some name stating what chip and pin this is taken by */ snprintf(gpiostr, 15, "%s:%d", range->name, gpio); @@ -243,53 +189,38 @@ int pinctrl_request_gpio(unsigned gpio) return ret; } -EXPORT_SYMBOL_GPL(pinctrl_request_gpio); /** - * pinctrl_free_gpio() - free control on a single pin, currently used as GPIO - * @gpio: the GPIO pin number from the GPIO subsystem number space - * - * This function should *ONLY* be used from gpiolib-based GPIO drivers, - * as part of their gpio_free() semantics, platforms and individual drivers - * shall *NOT* request GPIO pins to be muxed out. + * pinmux_free_gpio() - release a pin from GPIO muxing + * @pctldev: the pin controller device for the pin + * @pin: the affected currently GPIO-muxed in pin + * @range: applicable GPIO range */ -void pinctrl_free_gpio(unsigned gpio) +void pinmux_free_gpio(struct pinctrl_dev *pctldev, unsigned pin, + struct pinctrl_gpio_range *range) { - struct pinctrl_dev *pctldev; - struct pinctrl_gpio_range *range; - int ret; - int pin; const char *func; - ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); - if (ret) - return; - - /* Convert to the pin controllers number space */ - pin = gpio - range->base + range->pin_base; - func = pin_free(pctldev, pin, range); kfree(func); } -EXPORT_SYMBOL_GPL(pinctrl_free_gpio); -static int pinctrl_gpio_direction(unsigned gpio, bool input) +/** + * pinmux_gpio_direction() - set the direction of a single muxed-in GPIO pin + * @pctldev: the pin controller handling this pin + * @range: applicable GPIO range + * @pin: the affected GPIO pin in this controller + * @input: true if we set the pin as input, false for output + */ +int pinmux_gpio_direction(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned pin, bool input) { - struct pinctrl_dev *pctldev; - struct pinctrl_gpio_range *range; const struct pinmux_ops *ops; int ret; - int pin; - - ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); - if (ret) - return ret; ops = pctldev->desc->pmxops; - /* Convert to the pin controllers number space */ - pin = gpio - range->base + range->pin_base; - if (ops->gpio_set_direction) ret = ops->gpio_set_direction(pctldev, range, pin, input); else @@ -298,112 +229,6 @@ static int pinctrl_gpio_direction(unsigned gpio, bool input) return ret; } -/** - * pinctrl_gpio_direction_input() - request a GPIO pin to go into input mode - * @gpio: the GPIO pin number from the GPIO subsystem number space - * - * This function should *ONLY* be used from gpiolib-based GPIO drivers, - * as part of their gpio_direction_input() semantics, platforms and individual - * drivers shall *NOT* touch pin control GPIO calls. - */ -int pinctrl_gpio_direction_input(unsigned gpio) -{ - return pinctrl_gpio_direction(gpio, true); -} -EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_input); - -/** - * pinctrl_gpio_direction_output() - request a GPIO pin to go into output mode - * @gpio: the GPIO pin number from the GPIO subsystem number space - * - * This function should *ONLY* be used from gpiolib-based GPIO drivers, - * as part of their gpio_direction_output() semantics, platforms and individual - * drivers shall *NOT* touch pin control GPIO calls. - */ -int pinctrl_gpio_direction_output(unsigned gpio) -{ - return pinctrl_gpio_direction(gpio, false); -} -EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_output); - -/** - * pinctrl_register_mappings() - register a set of pin controller mappings - * @maps: the pincontrol mappings table to register, this should be marked with - * __initdata so it can be discarded after boot, this function will - * perform a shallow copy for the mapping entries. - * @num_maps: the number of maps in the mapping table - * - * Only call this once during initialization of your machine, the function is - * tagged as __init and won't be callable after init has completed. The map - * passed into this function will be owned by the pinmux core and cannot be - * freed. - */ -int __init pinctrl_register_mappings(struct pinctrl_map const *maps, - unsigned num_maps) -{ - void *tmp_maps; - int i; - - pr_debug("add %d pinmux maps\n", num_maps); - - /* First sanity check the new mapping */ - for (i = 0; i < num_maps; i++) { - if (!maps[i].name) { - pr_err("failed to register map %d: no map name given\n", - i); - return -EINVAL; - } - - if (!maps[i].ctrl_dev_name) { - pr_err("failed to register map %s (%d): no pin control device given\n", - maps[i].name, i); - return -EINVAL; - } - - if (!maps[i].function) { - pr_err("failed to register map %s (%d): no function ID given\n", - maps[i].name, i); - return -EINVAL; - } - - if (!maps[i].dev_name) - pr_debug("add system map %s function %s with no device\n", - maps[i].name, - maps[i].function); - else - pr_debug("register map %s, function %s\n", - maps[i].name, - maps[i].function); - } - - /* - * Make a copy of the map array - string pointers will end up in the - * kernel const section anyway so these do not need to be deep copied. - */ - if (!pinctrl_maps_num) { - /* On first call, just copy them */ - tmp_maps = kmemdup(maps, - sizeof(struct pinctrl_map) * num_maps, - GFP_KERNEL); - if (!tmp_maps) - return -ENOMEM; - } else { - /* Subsequent calls, reallocate array to new size */ - size_t oldsize = sizeof(struct pinctrl_map) * pinctrl_maps_num; - size_t newsize = sizeof(struct pinctrl_map) * num_maps; - - tmp_maps = krealloc(pinctrl_maps, - oldsize + newsize, GFP_KERNEL); - if (!tmp_maps) - return -ENOMEM; - memcpy((tmp_maps + oldsize), maps, newsize); - } - - pinctrl_maps = tmp_maps; - pinctrl_maps_num += num_maps; - return 0; -} - /** * acquire_pins() - acquire all the pins for a certain function on a pinmux * @pctldev: the device to take the pins on @@ -660,227 +485,81 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev, return 0; } -static void pinmux_free_groups(struct pinctrl *p) -{ - struct list_head *node, *tmp; - - list_for_each_safe(node, tmp, &p->groups) { - struct pinmux_group *grp = - list_entry(node, struct pinmux_group, node); - /* Release all pins taken by this group */ - release_pins(p->pctldev, grp->group_selector); - list_del(node); - kfree(grp); - } -} - /** - * pinctrl_get() - retrieves the pin controller handle for a certain device - * @dev: the device to get the pin controller handle for - * @name: an optional specific control mapping name or NULL, the name is only - * needed if you want to have more than one mapping per device, or if you - * need an anonymous pin control (not tied to any specific device) + * pinmux_apply_muxmap() - apply a certain mux mapping entry */ -struct pinctrl *pinctrl_get(struct device *dev, const char *name) +int pinmux_apply_muxmap(struct pinctrl_dev *pctldev, + struct pinctrl *p, + struct device *dev, + const char *devname, + struct pinctrl_map const *map) { - struct pinctrl_map const *map = NULL; - struct pinctrl_dev *pctldev = NULL; - const char *devname = NULL; - struct pinctrl *p; - bool found_map; - unsigned num_maps = 0; - int ret = -ENODEV; - int i; - - /* We must have dev or ID or both */ - if (!dev && !name) - return ERR_PTR(-EINVAL); - - if (dev) - devname = dev_name(dev); - - pr_debug("get mux %s for device %s\n", name, - devname ? devname : "(none)"); - - /* - * create the state cookie holder struct pinmux for each - * mapping, this is what consumers will get when requesting - * a pinmux handle with pinmux_get() - */ - p = kzalloc(sizeof(struct pinctrl), GFP_KERNEL); - if (p == NULL) - return ERR_PTR(-ENOMEM); - mutex_init(&p->mutex); - p->func_selector = UINT_MAX; - INIT_LIST_HEAD(&p->groups); - - /* Iterate over the pin control maps to locate the right ones */ - for (i = 0; i < pinctrl_maps_num; i++) { - map = &pinctrl_maps[i]; - found_map = false; - - /* - * First, try to find the pctldev given in the map - */ - pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name); - if (!pctldev) { - pr_warning("could not find a pinctrl device for pinmux function %s, fishy, they shall all have one\n", - map->function); - pr_warning("given pinctrl device name: %s", - map->ctrl_dev_name); - - /* Continue to check the other mappings anyway... */ - continue; - } - - pr_debug("in map, found pctldev %s to handle function %s", - dev_name(pctldev->dev), map->function); - - - /* - * If we're looking for a specific named map, this must match, - * else we loop and look for the next. - */ - if (name != NULL) { - if (map->name == NULL) - continue; - if (strcmp(map->name, name)) - continue; - } - - /* - * This is for the case where no device name is given, we - * already know that the function name matches from above - * code. - */ - if (!map->dev_name && (name != NULL)) - found_map = true; - - /* If the mapping has a device set up it must match */ - if (map->dev_name && - (!devname || !strcmp(map->dev_name, devname))) - /* MATCH! */ - found_map = true; - - /* If this map is applicable, then apply it */ - if (found_map) { - ret = pinmux_enable_muxmap(pctldev, p, dev, - devname, map); - if (ret) { - pinmux_free_groups(p); - kfree(p); - return ERR_PTR(ret); - } - num_maps++; - } - } - + int ret; - /* We should have atleast one map, right */ - if (!num_maps) { - pr_err("could not find any mux maps for device %s, ID %s\n", - devname ? devname : "(anonymous)", - name ? name : "(undefined)"); - kfree(p); - return ERR_PTR(-EINVAL); + ret = pinmux_enable_muxmap(pctldev, p, dev, + devname, map); + if (ret) { + pinmux_put(p); + return ret; } - pr_debug("found %u mux maps for device %s, UD %s\n", - num_maps, - devname ? devname : "(anonymous)", - name ? name : "(undefined)"); - - /* Add the pinmux to the global list */ - mutex_lock(&pinctrl_list_mutex); - list_add(&p->node, &pinctrl_list); - mutex_unlock(&pinctrl_list_mutex); - - return p; + return 0; } -EXPORT_SYMBOL_GPL(pinctrl_get); /** - * pinctrl_put() - release a previously claimed pin control handle - * @p: a pin control handle previously claimed by pinctrl_get() + * pinmux_put() - free up the pinmux portions of a pin controller handle */ -void pinctrl_put(struct pinctrl *p) +void pinmux_put(struct pinctrl *p) { - if (p == NULL) - return; - - mutex_lock(&p->mutex); - if (p->usecount) - pr_warn("releasing pin control handle with active users!\n"); - /* Free the groups and all acquired pins */ - pinmux_free_groups(p); - mutex_unlock(&p->mutex); - - /* Remove from list */ - mutex_lock(&pinctrl_list_mutex); - list_del(&p->node); - mutex_unlock(&pinctrl_list_mutex); + struct list_head *node, *tmp; - kfree(p); + list_for_each_safe(node, tmp, &p->groups) { + struct pinmux_group *grp = + list_entry(node, struct pinmux_group, node); + /* Release all pins taken by this group */ + release_pins(p->pctldev, grp->group_selector); + list_del(node); + kfree(grp); + } } -EXPORT_SYMBOL_GPL(pinctrl_put); /** - * pinctrl_enable() - enable a certain pin controller setting - * @p: the pin control handle to enable, previously claimed by pinctrl_get() + * pinmux_enable() - enable the pinmux portion of a pin control handle */ -int pinctrl_enable(struct pinctrl *p) +int pinmux_enable(struct pinctrl *p) { - int ret = 0; + struct pinctrl_dev *pctldev = p->pctldev; + const struct pinmux_ops *ops = pctldev->desc->pmxops; + struct pinmux_group *grp; + int ret; - if (p == NULL) - return -EINVAL; - mutex_lock(&p->mutex); - if (p->usecount++ == 0) { - struct pinctrl_dev *pctldev = p->pctldev; - const struct pinmux_ops *ops = pctldev->desc->pmxops; - struct pinmux_group *grp; - - list_for_each_entry(grp, &p->groups, node) { - ret = ops->enable(pctldev, p->func_selector, - grp->group_selector); - if (ret) { - /* - * TODO: call disable() on all groups we called - * enable() on to this point? - */ - p->usecount--; - break; - } - } + list_for_each_entry(grp, &p->groups, node) { + ret = ops->enable(pctldev, p->func_selector, + grp->group_selector); + if (ret) + /* + * TODO: call disable() on all groups we called + * enable() on to this point? + */ + return ret; } - mutex_unlock(&p->mutex); - return ret; + return 0; } -EXPORT_SYMBOL_GPL(pinctrl_enable); /** - * pinctrl_disable() - disable a certain pin control setting - * @p: the pin control handle to disable, previously claimed by pinctrl_get() + * pinmux_disable() - disable the pinmux portions of a pin control handle */ -void pinctrl_disable(struct pinctrl *p) +void pinmux_disable(struct pinctrl *p) { - if (p == NULL) - return; - - mutex_lock(&p->mutex); - if (--p->usecount == 0) { - struct pinctrl_dev *pctldev = p->pctldev; - const struct pinmux_ops *ops = pctldev->desc->pmxops; - struct pinmux_group *grp; + struct pinctrl_dev *pctldev = p->pctldev; + const struct pinmux_ops *ops = pctldev->desc->pmxops; + struct pinmux_group *grp; - list_for_each_entry(grp, &p->groups, node) { - ops->disable(pctldev, p->func_selector, - grp->group_selector); - } + list_for_each_entry(grp, &p->groups, node) { + ops->disable(pctldev, p->func_selector, + grp->group_selector); } - mutex_unlock(&p->mutex); } -EXPORT_SYMBOL_GPL(pinctrl_disable); int pinmux_check_ops(struct pinctrl_dev *pctldev) { @@ -910,116 +589,6 @@ int pinmux_check_ops(struct pinctrl_dev *pctldev) return 0; } -/* Hog a single map entry and add to the hoglist */ -static int pinctrl_hog_map(struct pinctrl_dev *pctldev, - struct pinctrl_map const *map) -{ - struct pinctrl_hog *hog; - struct pinctrl *p; - int ret; - - if (map->dev_name) { - /* - * TODO: the day we have device tree support, we can - * traverse the device tree and hog to specific device nodes - * without any problems, so then we can hog pinmuxes for - * all devices that just want a static pin mux at this point. - */ - dev_err(pctldev->dev, "map %s wants to hog a non-system pinmux, this is not going to work\n", - map->name); - return -EINVAL; - } - - hog = kzalloc(sizeof(struct pinctrl_hog), GFP_KERNEL); - if (!hog) - return -ENOMEM; - - p = pinctrl_get(NULL, map->name); - if (IS_ERR(p)) { - kfree(hog); - dev_err(pctldev->dev, - "could not get the %s pin control mapping for hogging\n", - map->name); - return PTR_ERR(p); - } - - ret = pinctrl_enable(p); - if (ret) { - pinctrl_put(p); - kfree(hog); - dev_err(pctldev->dev, - "could not enable the %s pin control mapping for hogging\n", - map->name); - return ret; - } - - hog->map = map; - hog->p = p; - - dev_info(pctldev->dev, "hogged map %s, function %s\n", map->name, - map->function); - mutex_lock(&pctldev->pinctrl_hogs_lock); - list_add(&hog->node, &pctldev->pinctrl_hogs); - mutex_unlock(&pctldev->pinctrl_hogs_lock); - - return 0; -} - -/** - * pinctrl_hog_maps() - hog specific map entries on controller device - * @pctldev: the pin control device to hog entries on - * - * When the pin controllers are registered, there may be some specific pinmux - * map entries that need to be hogged, i.e. get+enabled until the system shuts - * down. - */ -int pinctrl_hog_maps(struct pinctrl_dev *pctldev) -{ - struct device *dev = pctldev->dev; - const char *devname = dev_name(dev); - int ret; - int i; - - INIT_LIST_HEAD(&pctldev->pinctrl_hogs); - mutex_init(&pctldev->pinctrl_hogs_lock); - - for (i = 0; i < pinctrl_maps_num; i++) { - struct pinctrl_map const *map = &pinctrl_maps[i]; - - if (!map->hog_on_boot) - continue; - - if (map->ctrl_dev_name && - !strcmp(map->ctrl_dev_name, devname)) { - /* OK time to hog! */ - ret = pinctrl_hog_map(pctldev, map); - if (ret) - return ret; - } - } - return 0; -} - -/** - * pinctrl_unhog_maps() - unhog specific map entries on controller device - * @pctldev: the pin control device to unhog entries on - */ -void pinctrl_unhog_maps(struct pinctrl_dev *pctldev) -{ - struct list_head *node, *tmp; - - mutex_lock(&pctldev->pinctrl_hogs_lock); - list_for_each_safe(node, tmp, &pctldev->pinctrl_hogs) { - struct pinctrl_hog *hog = - list_entry(node, struct pinctrl_hog, node); - pinctrl_disable(hog->p); - pinctrl_put(hog->p); - list_del(node); - kfree(hog); - } - mutex_unlock(&pctldev->pinctrl_hogs_lock); -} - #ifdef CONFIG_DEBUG_FS /* Called from pincontrol core */ @@ -1083,83 +652,29 @@ static int pinmux_pins_show(struct seq_file *s, void *what) return 0; } -static int pinmux_hogs_show(struct seq_file *s, void *what) -{ - struct pinctrl_dev *pctldev = s->private; - struct pinctrl_hog *hog; - - seq_puts(s, "Pin control map hogs held by device\n"); - - list_for_each_entry(hog, &pctldev->pinctrl_hogs, node) - seq_printf(s, "%s\n", hog->map->name); - - return 0; -} - -static int pinmux_show(struct seq_file *s, void *what) +void pinmux_dbg_show(struct seq_file *s, struct pinctrl *p) { - struct pinctrl *p; - - seq_puts(s, "Requested pinmuxes and their maps:\n"); - list_for_each_entry(p, &pinctrl_list, node) { - struct pinctrl_dev *pctldev = p->pctldev; - const struct pinmux_ops *pmxops; - const struct pinctrl_ops *pctlops; - struct pinmux_group *grp; - - if (!pctldev) { - seq_puts(s, "NO PIN CONTROLLER DEVICE\n"); - continue; - } - - pmxops = pctldev->desc->pmxops; - pctlops = pctldev->desc->pctlops; - - seq_printf(s, "device: %s function: %s (%u),", - pinctrl_dev_get_name(p->pctldev), - pmxops->get_function_name(pctldev, - p->func_selector), - p->func_selector); - - seq_printf(s, " groups: ["); - list_for_each_entry(grp, &p->groups, node) { - seq_printf(s, " %s (%u)", - pctlops->get_group_name(pctldev, - grp->group_selector), - grp->group_selector); - } - seq_printf(s, " ]"); + struct pinctrl_dev *pctldev = p->pctldev; + const struct pinmux_ops *pmxops; + const struct pinctrl_ops *pctlops; + struct pinmux_group *grp; - seq_printf(s, " users: %u map-> %s\n", - p->usecount, - p->dev ? dev_name(p->dev) : "(system)"); - } + pmxops = pctldev->desc->pmxops; + pctlops = pctldev->desc->pctlops; - return 0; -} - -static int pinctrl_maps_show(struct seq_file *s, void *what) -{ - int i; + seq_printf(s, " function: %s (%u),", + pmxops->get_function_name(pctldev, + p->func_selector), + p->func_selector); - seq_puts(s, "Pinctrl maps:\n"); - - for (i = 0; i < pinctrl_maps_num; i++) { - struct pinctrl_map const *map = &pinctrl_maps[i]; - - seq_printf(s, "%s:\n", map->name); - if (map->dev_name) - seq_printf(s, " device: %s\n", - map->dev_name); - else - seq_printf(s, " SYSTEM MUX\n"); - seq_printf(s, " controlling device %s\n", - map->ctrl_dev_name); - seq_printf(s, " function: %s\n", map->function); - seq_printf(s, " group: %s\n", map->group ? map->group : - "(default)"); + seq_printf(s, " groups: ["); + list_for_each_entry(grp, &p->groups, node) { + seq_printf(s, " %s (%u)", + pctlops->get_group_name(pctldev, + grp->group_selector), + grp->group_selector); } - return 0; + seq_printf(s, " ]"); } static int pinmux_functions_open(struct inode *inode, struct file *file) @@ -1172,21 +687,6 @@ static int pinmux_pins_open(struct inode *inode, struct file *file) return single_open(file, pinmux_pins_show, inode->i_private); } -static int pinmux_hogs_open(struct inode *inode, struct file *file) -{ - return single_open(file, pinmux_hogs_show, inode->i_private); -} - -static int pinmux_open(struct inode *inode, struct file *file) -{ - return single_open(file, pinmux_show, NULL); -} - -static int pinctrl_maps_open(struct inode *inode, struct file *file) -{ - return single_open(file, pinctrl_maps_show, NULL); -} - static const struct file_operations pinmux_functions_ops = { .open = pinmux_functions_open, .read = seq_read, @@ -1201,27 +701,6 @@ static const struct file_operations pinmux_pins_ops = { .release = single_release, }; -static const struct file_operations pinmux_hogs_ops = { - .open = pinmux_hogs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations pinmux_ops = { - .open = pinmux_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations pinctrl_maps_ops = { - .open = pinctrl_maps_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - void pinmux_init_device_debugfs(struct dentry *devroot, struct pinctrl_dev *pctldev) { @@ -1229,16 +708,6 @@ void pinmux_init_device_debugfs(struct dentry *devroot, devroot, pctldev, &pinmux_functions_ops); debugfs_create_file("pinmux-pins", S_IFREG | S_IRUGO, devroot, pctldev, &pinmux_pins_ops); - debugfs_create_file("pinmux-hogs", S_IFREG | S_IRUGO, - devroot, pctldev, &pinmux_hogs_ops); -} - -void pinmux_init_debugfs(struct dentry *subsys_root) -{ - debugfs_create_file("pinmuxes", S_IFREG | S_IRUGO, - subsys_root, NULL, &pinmux_ops); - debugfs_create_file("pinctrl-maps", S_IFREG | S_IRUGO, - subsys_root, NULL, &pinctrl_maps_ops); } #endif /* CONFIG_DEBUG_FS */ diff --git a/drivers/pinctrl/pinmux.h b/drivers/pinctrl/pinmux.h index dfe81726965..7680a170325 100644 --- a/drivers/pinctrl/pinmux.h +++ b/drivers/pinctrl/pinmux.h @@ -15,9 +15,28 @@ int pinmux_check_ops(struct pinctrl_dev *pctldev); void pinmux_init_device_debugfs(struct dentry *devroot, struct pinctrl_dev *pctldev); -void pinmux_init_debugfs(struct dentry *subsys_root); -int pinctrl_hog_maps(struct pinctrl_dev *pctldev); -void pinctrl_unhog_maps(struct pinctrl_dev *pctldev); +int pinmux_request_gpio(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned pin, unsigned gpio); +void pinmux_free_gpio(struct pinctrl_dev *pctldev, unsigned pin, + struct pinctrl_gpio_range *range); +int pinmux_gpio_direction(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned pin, bool input); +static inline void pinmux_init_pinctrl_handle(struct pinctrl *p) +{ + p->func_selector = UINT_MAX; + INIT_LIST_HEAD(&p->groups); +} +int pinmux_apply_muxmap(struct pinctrl_dev *pctldev, + struct pinctrl *p, + struct device *dev, + const char *devname, + struct pinctrl_map const *map); +void pinmux_put(struct pinctrl *p); +int pinmux_enable(struct pinctrl *p); +void pinmux_disable(struct pinctrl *p); +void pinmux_dbg_show(struct seq_file *s, struct pinctrl *p); #else @@ -31,16 +50,52 @@ static inline void pinmux_init_device_debugfs(struct dentry *devroot, { } -static inline void pinmux_init_debugfs(struct dentry *subsys_root) +static inline int pinmux_request_gpio(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned pin, unsigned gpio) +{ + return 0; +} + +static inline void pinmux_free_gpio(struct pinctrl_dev *pctldev, + unsigned pin, + struct pinctrl_gpio_range *range) +{ +} + +static inline int pinmux_gpio_direction(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned pin, bool input) +{ + return 0; +} + +static inline void pinmux_init_pinctrl_handle(struct pinctrl *p) { } -static inline int pinctrl_hog_maps(struct pinctrl_dev *pctldev) +static inline int pinmux_apply_muxmap(struct pinctrl_dev *pctldev, + struct pinctrl *p, + struct device *dev, + const char *devname, + struct pinctrl_map const *map) { return 0; } -static inline void pinctrl_unhog_maps(struct pinctrl_dev *pctldev) +static inline void pinmux_put(struct pinctrl *p) +{ +} + +static inline int pinmux_enable(struct pinctrl *p) +{ +} + +static inline void pinmux_disable(struct pinctrl *p) +{ +} + +void pinmux_dbg_show(struct seq_file *s, struct pinctrl *p) { } diff --git a/include/linux/pinctrl/consumer.h b/include/linux/pinctrl/consumer.h index c7d06177629..30865947f2d 100644 --- a/include/linux/pinctrl/consumer.h +++ b/include/linux/pinctrl/consumer.h @@ -19,9 +19,9 @@ /* This struct is private to the core and should be regarded as a cookie */ struct pinctrl; -#ifdef CONFIG_PINMUX +#ifdef CONFIG_PINCTRL -/* External interface to pinmux */ +/* External interface to pin control */ extern int pinctrl_request_gpio(unsigned gpio); extern void pinctrl_free_gpio(unsigned gpio); extern int pinctrl_gpio_direction_input(unsigned gpio); @@ -31,7 +31,7 @@ extern void pinctrl_put(struct pinctrl *p); extern int pinctrl_enable(struct pinctrl *p); extern void pinctrl_disable(struct pinctrl *p); -#else /* !CONFIG_PINMUX */ +#else /* !CONFIG_PINCTRL */ static inline int pinctrl_request_gpio(unsigned gpio) { @@ -70,7 +70,7 @@ static inline void pinctrl_disable(struct pinctrl *p) { } -#endif /* CONFIG_PINMUX */ +#endif /* CONFIG_PINCTRL */ #ifdef CONFIG_PINCONF -- cgit v1.2.3-70-g09d2 From 77a5988355f993840928d195f790a939200a4ff0 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 10 Feb 2012 01:34:12 +0100 Subject: pinctrl: changes hog mechanism to be self-referential Instead of a specific boolean field to indicate if a map entry shall be hogged, treat self-reference as an indication of desired hogging. This drops one field off the map struct and has a nice Douglas R. Hofstadter-feel to it. Acked-by: Dong Aisheng Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- Documentation/pinctrl.txt | 8 ++++---- drivers/pinctrl/core.c | 6 ++---- include/linux/pinctrl/machine.h | 18 ++++++------------ 3 files changed, 12 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index 2e7132355db..ee3266b948e 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -989,21 +989,21 @@ is registered. This means that the core will attempt to call pinctrl_get() and pinctrl_enable() on it immediately after the pin control device has been registered. -This is enabled by simply setting the .hog_on_boot field in the map to true, -like this: +This is enabled by simply setting the .dev_name field in the map to the name +of the pin controller itself, like this: { .name = "POWERMAP" .ctrl_dev_name = "pinctrl-foo", .function = "power_func", - .hog_on_boot = true, + .dev_name = "pinctrl-foo", }, Since it may be common to request the core to hog a few always-applicable mux settings on the primary pin controller, there is a convenience macro for this: -PIN_MAP_PRIMARY_SYS_HOG("POWERMAP", "power_func") +PIN_MAP_PRIMARY_SYS_HOG("POWERMAP", "pinctrl-foo", "power_func") This gives the exact same result as the above construction. diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index ec32c545f07..c5f76ad5a8c 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -793,11 +793,9 @@ int pinctrl_hog_maps(struct pinctrl_dev *pctldev) for (i = 0; i < pinctrl_maps_num; i++) { struct pinctrl_map const *map = &pinctrl_maps[i]; - if (!map->hog_on_boot) - continue; - if (map->ctrl_dev_name && - !strcmp(map->ctrl_dev_name, devname)) { + !strcmp(map->ctrl_dev_name, devname) && + !strcmp(map->dev_name, devname)) { /* OK time to hog! */ ret = pinctrl_hog_map(pctldev, map); if (ret) diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index a2ab524a010..af145d57197 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -26,13 +26,9 @@ * selects a certain specific pin group to activate for the function, if * left as NULL, the first applicable group will be used * @dev_name: the name of the device using this specific mapping, the name - * must be the same as in your struct device* - * @hog_on_boot: if this is set to true, the pin control subsystem will itself - * hog the mappings as the pinmux device drivers are attached, so this is - * typically used with system maps (mux mappings without an assigned - * device) that you want to get hogged and enabled by default as soon as - * a pinmux device supporting it is registered. These maps will not be - * disabled and put until the system shuts down. + * must be the same as in your struct device*. If this name is set to the + * same name as the pin controllers own dev_name(), the map entry will be + * hogged by the driver itself upon registration */ struct pinctrl_map { const char *name; @@ -40,7 +36,6 @@ struct pinctrl_map { const char *function; const char *group; const char *dev_name; - bool hog_on_boot; }; /* @@ -62,8 +57,7 @@ struct pinctrl_map { * to be hogged by the pin control core until the system shuts down. */ #define PIN_MAP_SYS_HOG(a, b, c) \ - { .name = a, .ctrl_dev_name = b, .function = c, \ - .hog_on_boot = true } + { .name = a, .ctrl_dev_name = b, .dev_name = b, .function = c, } /* * Convenience macro to map a system function onto a certain pinctrl device @@ -71,8 +65,8 @@ struct pinctrl_map { * system shuts down. */ #define PIN_MAP_SYS_HOG_GROUP(a, b, c, d) \ - { .name = a, .ctrl_dev_name = b, .function = c, .group = d, \ - .hog_on_boot = true } + { .name = a, .ctrl_dev_name = b, .dev_name = b, .function = c, \ + .group = d, } #ifdef CONFIG_PINMUX -- cgit v1.2.3-70-g09d2 From 4c1975d77b73feed7161999aab4cc64c1ae7155c Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 31 Jan 2012 02:59:23 +0000 Subject: ixgbe: Minor refactor of RSC This change addresses several issue. First I had left the use of the next and prev skb pointers floating around in the code and they were overdue to be pulled since I had rewritten the RSC code in the out-of-tree driver some time ago to address issues brought up by David Miller in regards to this. I am also now defaulting to always leaving the first buffer unmapped on any packet and then unmapping it after we read the EOP descriptor. This allows a simplification of the path with less branching. Instead of counting packets received the code was changed some time ago to track the number of buffers received. This leads to inaccurate counting when you compare numbers of packets received by the hardware versus what is tracked by the software. To correct this I am revising things so that the append_cnt value for RSC accurately tracks the number of frames received. Signed-off-by: Alexander Duyck Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 10 +- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 235 +++++++++++++++----------- 2 files changed, 147 insertions(+), 98 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h index e6aeb64105a..fca05536284 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h @@ -535,12 +535,16 @@ enum ixbge_state_t { __IXGBE_IN_SFP_INIT, }; -struct ixgbe_rsc_cb { +struct ixgbe_cb { + union { /* Union defining head/tail partner */ + struct sk_buff *head; + struct sk_buff *tail; + }; dma_addr_t dma; - u16 skb_cnt; + u16 append_cnt; bool delay_unmap; }; -#define IXGBE_RSC_CB(skb) ((struct ixgbe_rsc_cb *)(skb)->cb) +#define IXGBE_CB(skb) ((struct ixgbe_cb *)(skb)->cb) enum ixgbe_boards { board_82598, diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index ecc46ce8b2c..18e474c25e6 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -1207,40 +1207,96 @@ static inline u16 ixgbe_get_hlen(union ixgbe_adv_rx_desc *rx_desc) } /** - * ixgbe_transform_rsc_queue - change rsc queue into a full packet - * @skb: pointer to the last skb in the rsc queue + * ixgbe_merge_active_tail - merge active tail into lro skb + * @tail: pointer to active tail in frag_list * - * This function changes a queue full of hw rsc buffers into a completed - * packet. It uses the ->prev pointers to find the first packet and then - * turns it into the frag list owner. + * This function merges the length and data of an active tail into the + * skb containing the frag_list. It resets the tail's pointer to the head, + * but it leaves the heads pointer to tail intact. **/ -static inline struct sk_buff *ixgbe_transform_rsc_queue(struct sk_buff *skb) +static inline struct sk_buff *ixgbe_merge_active_tail(struct sk_buff *tail) { - unsigned int frag_list_size = 0; - unsigned int skb_cnt = 1; + struct sk_buff *head = IXGBE_CB(tail)->head; - while (skb->prev) { - struct sk_buff *prev = skb->prev; - frag_list_size += skb->len; - skb->prev = NULL; - skb = prev; - skb_cnt++; + if (!head) + return tail; + + head->len += tail->len; + head->data_len += tail->len; + head->truesize += tail->len; + + IXGBE_CB(tail)->head = NULL; + + return head; +} + +/** + * ixgbe_add_active_tail - adds an active tail into the skb frag_list + * @head: pointer to the start of the skb + * @tail: pointer to active tail to add to frag_list + * + * This function adds an active tail to the end of the frag list. This tail + * will still be receiving data so we cannot yet ad it's stats to the main + * skb. That is done via ixgbe_merge_active_tail. + **/ +static inline void ixgbe_add_active_tail(struct sk_buff *head, + struct sk_buff *tail) +{ + struct sk_buff *old_tail = IXGBE_CB(head)->tail; + + if (old_tail) { + ixgbe_merge_active_tail(old_tail); + old_tail->next = tail; + } else { + skb_shinfo(head)->frag_list = tail; } - skb_shinfo(skb)->frag_list = skb->next; - skb->next = NULL; - skb->len += frag_list_size; - skb->data_len += frag_list_size; - skb->truesize += frag_list_size; - IXGBE_RSC_CB(skb)->skb_cnt = skb_cnt; + IXGBE_CB(tail)->head = head; + IXGBE_CB(head)->tail = tail; +} + +/** + * ixgbe_close_active_frag_list - cleanup pointers on a frag_list skb + * @head: pointer to head of an active frag list + * + * This function will clear the frag_tail_tracker pointer on an active + * frag_list and returns true if the pointer was actually set + **/ +static inline bool ixgbe_close_active_frag_list(struct sk_buff *head) +{ + struct sk_buff *tail = IXGBE_CB(head)->tail; + + if (!tail) + return false; - return skb; + ixgbe_merge_active_tail(tail); + + IXGBE_CB(head)->tail = NULL; + + return true; } -static inline bool ixgbe_get_rsc_state(union ixgbe_adv_rx_desc *rx_desc) +static void ixgbe_get_rsc_cnt(struct ixgbe_ring *rx_ring, + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb) { - return !!(le32_to_cpu(rx_desc->wb.lower.lo_dword.data) & - IXGBE_RXDADV_RSCCNT_MASK); + __le32 rsc_enabled; + u32 rsc_cnt; + + if (!ring_is_rsc_enabled(rx_ring)) + return; + + rsc_enabled = rx_desc->wb.lower.lo_dword.data & + cpu_to_le32(IXGBE_RXDADV_RSCCNT_MASK); + + /* If this is an RSC frame rsc_cnt should be non-zero */ + if (!rsc_enabled) + return; + + rsc_cnt = le32_to_cpu(rsc_enabled); + rsc_cnt >>= IXGBE_RXDADV_RSCCNT_SHIFT; + + IXGBE_CB(skb)->append_cnt += rsc_cnt - 1; } static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, @@ -1249,7 +1305,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, { struct ixgbe_adapter *adapter = q_vector->adapter; union ixgbe_adv_rx_desc *rx_desc, *next_rxd; - struct ixgbe_rx_buffer *rx_buffer_info, *next_buffer; + struct ixgbe_rx_buffer *rx_buffer_info; struct sk_buff *skb; unsigned int total_rx_bytes = 0, total_rx_packets = 0; const int current_node = numa_node_id(); @@ -1259,7 +1315,6 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, u32 staterr; u16 i; u16 cleaned_count = 0; - bool pkt_is_rsc = false; i = rx_ring->next_to_clean; rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i); @@ -1276,32 +1331,9 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, rx_buffer_info->skb = NULL; prefetch(skb->data); - if (ring_is_rsc_enabled(rx_ring)) - pkt_is_rsc = ixgbe_get_rsc_state(rx_desc); - /* linear means we are building an skb from multiple pages */ if (!skb_is_nonlinear(skb)) { u16 hlen; - if (pkt_is_rsc && - !(staterr & IXGBE_RXD_STAT_EOP) && - !skb->prev) { - /* - * When HWRSC is enabled, delay unmapping - * of the first packet. It carries the - * header information, HW may still - * access the header after the writeback. - * Only unmap it when EOP is reached - */ - IXGBE_RSC_CB(skb)->delay_unmap = true; - IXGBE_RSC_CB(skb)->dma = rx_buffer_info->dma; - } else { - dma_unmap_single(rx_ring->dev, - rx_buffer_info->dma, - rx_ring->rx_buf_len, - DMA_FROM_DEVICE); - } - rx_buffer_info->dma = 0; - if (ring_is_ps_enabled(rx_ring)) { hlen = ixgbe_get_hlen(rx_desc); upper_len = le16_to_cpu(rx_desc->wb.upper.length); @@ -1310,6 +1342,23 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, } skb_put(skb, hlen); + + /* + * Delay unmapping of the first packet. It carries the + * header information, HW may still access the header + * after writeback. Only unmap it when EOP is reached + */ + if (!IXGBE_CB(skb)->head) { + IXGBE_CB(skb)->delay_unmap = true; + IXGBE_CB(skb)->dma = rx_buffer_info->dma; + } else { + skb = ixgbe_merge_active_tail(skb); + dma_unmap_single(rx_ring->dev, + rx_buffer_info->dma, + rx_ring->rx_buf_len, + DMA_FROM_DEVICE); + } + rx_buffer_info->dma = 0; } else { /* assume packet split since header is unmapped */ upper_len = le16_to_cpu(rx_desc->wb.upper.length); @@ -1337,6 +1386,8 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, skb->truesize += PAGE_SIZE / 2; } + ixgbe_get_rsc_cnt(rx_ring, rx_desc, skb); + i++; if (i == rx_ring->count) i = 0; @@ -1345,55 +1396,50 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, prefetch(next_rxd); cleaned_count++; - if (pkt_is_rsc) { - u32 nextp = (staterr & IXGBE_RXDADV_NEXTP_MASK) >> - IXGBE_RXDADV_NEXTP_SHIFT; + if (!(staterr & IXGBE_RXD_STAT_EOP)) { + struct ixgbe_rx_buffer *next_buffer; + u32 nextp; + + if (IXGBE_CB(skb)->append_cnt) { + nextp = staterr & IXGBE_RXDADV_NEXTP_MASK; + nextp >>= IXGBE_RXDADV_NEXTP_SHIFT; + } else { + nextp = i; + } + next_buffer = &rx_ring->rx_buffer_info[nextp]; - } else { - next_buffer = &rx_ring->rx_buffer_info[i]; - } - if (!(staterr & IXGBE_RXD_STAT_EOP)) { if (ring_is_ps_enabled(rx_ring)) { rx_buffer_info->skb = next_buffer->skb; rx_buffer_info->dma = next_buffer->dma; next_buffer->skb = skb; next_buffer->dma = 0; } else { - skb->next = next_buffer->skb; - skb->next->prev = skb; + struct sk_buff *next_skb = next_buffer->skb; + ixgbe_add_active_tail(skb, next_skb); + IXGBE_CB(next_skb)->head = skb; } rx_ring->rx_stats.non_eop_descs++; goto next_desc; } - if (skb->prev) { - skb = ixgbe_transform_rsc_queue(skb); + dma_unmap_single(rx_ring->dev, + IXGBE_CB(skb)->dma, + rx_ring->rx_buf_len, + DMA_FROM_DEVICE); + IXGBE_CB(skb)->dma = 0; + IXGBE_CB(skb)->delay_unmap = false; + + if (ixgbe_close_active_frag_list(skb) && + !IXGBE_CB(skb)->append_cnt) { /* if we got here without RSC the packet is invalid */ - if (!pkt_is_rsc) { - __pskb_trim(skb, 0); - rx_buffer_info->skb = skb; - goto next_desc; - } + dev_kfree_skb_any(skb); + goto next_desc; } - if (ring_is_rsc_enabled(rx_ring)) { - if (IXGBE_RSC_CB(skb)->delay_unmap) { - dma_unmap_single(rx_ring->dev, - IXGBE_RSC_CB(skb)->dma, - rx_ring->rx_buf_len, - DMA_FROM_DEVICE); - IXGBE_RSC_CB(skb)->dma = 0; - IXGBE_RSC_CB(skb)->delay_unmap = false; - } - } - if (pkt_is_rsc) { - if (ring_is_ps_enabled(rx_ring)) - rx_ring->rx_stats.rsc_count += - skb_shinfo(skb)->nr_frags; - else - rx_ring->rx_stats.rsc_count += - IXGBE_RSC_CB(skb)->skb_cnt; + if (IXGBE_CB(skb)->append_cnt) { + rx_ring->rx_stats.rsc_count += + IXGBE_CB(skb)->append_cnt; rx_ring->rx_stats.rsc_flush++; } @@ -3881,19 +3927,18 @@ static void ixgbe_clean_rx_ring(struct ixgbe_ring *rx_ring) if (rx_buffer_info->skb) { struct sk_buff *skb = rx_buffer_info->skb; rx_buffer_info->skb = NULL; - do { - struct sk_buff *this = skb; - if (IXGBE_RSC_CB(this)->delay_unmap) { - dma_unmap_single(dev, - IXGBE_RSC_CB(this)->dma, - rx_ring->rx_buf_len, - DMA_FROM_DEVICE); - IXGBE_RSC_CB(this)->dma = 0; - IXGBE_RSC_CB(skb)->delay_unmap = false; - } - skb = skb->prev; - dev_kfree_skb(this); - } while (skb); + /* We need to clean up RSC frag lists */ + skb = ixgbe_merge_active_tail(skb); + ixgbe_close_active_frag_list(skb); + if (IXGBE_CB(skb)->delay_unmap) { + dma_unmap_single(dev, + IXGBE_CB(skb)->dma, + rx_ring->rx_buf_len, + DMA_FROM_DEVICE); + IXGBE_CB(skb)->dma = 0; + IXGBE_CB(skb)->delay_unmap = false; + } + dev_kfree_skb(skb); } if (!rx_buffer_info->page) continue; -- cgit v1.2.3-70-g09d2 From 1d2024f61ec14bdb0c57a97a3fe73685abc2d198 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 31 Jan 2012 02:59:29 +0000 Subject: ixgbe: Address fact that RSC was not setting GSO size for incoming frames This patch is meant to address the fact that RSC has not been setting the gso_size value on the skb. As a result performance on lossy TCP connections was negatively impacted. This change resolves the issue by setting gso_size to the average size for incoming packets. Signed-off-by: Alexander Duyck Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 130 +++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 18e474c25e6..762f33777a7 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -1276,6 +1276,104 @@ static inline bool ixgbe_close_active_frag_list(struct sk_buff *head) return true; } +/** + * ixgbe_get_headlen - determine size of header for RSC/LRO/GRO/FCOE + * @data: pointer to the start of the headers + * @max_len: total length of section to find headers in + * + * This function is meant to determine the length of headers that will + * be recognized by hardware for LRO, GRO, and RSC offloads. The main + * motivation of doing this is to only perform one pull for IPv4 TCP + * packets so that we can do basic things like calculating the gso_size + * based on the average data per packet. + **/ +static unsigned int ixgbe_get_headlen(unsigned char *data, + unsigned int max_len) +{ + union { + unsigned char *network; + /* l2 headers */ + struct ethhdr *eth; + struct vlan_hdr *vlan; + /* l3 headers */ + struct iphdr *ipv4; + } hdr; + __be16 protocol; + u8 nexthdr = 0; /* default to not TCP */ + u8 hlen; + + /* this should never happen, but better safe than sorry */ + if (max_len < ETH_HLEN) + return max_len; + + /* initialize network frame pointer */ + hdr.network = data; + + /* set first protocol and move network header forward */ + protocol = hdr.eth->h_proto; + hdr.network += ETH_HLEN; + + /* handle any vlan tag if present */ + if (protocol == __constant_htons(ETH_P_8021Q)) { + if ((hdr.network - data) > (max_len - VLAN_HLEN)) + return max_len; + + protocol = hdr.vlan->h_vlan_encapsulated_proto; + hdr.network += VLAN_HLEN; + } + + /* handle L3 protocols */ + if (protocol == __constant_htons(ETH_P_IP)) { + if ((hdr.network - data) > (max_len - sizeof(struct iphdr))) + return max_len; + + /* access ihl as a u8 to avoid unaligned access on ia64 */ + hlen = (hdr.network[0] & 0x0F) << 2; + + /* verify hlen meets minimum size requirements */ + if (hlen < sizeof(struct iphdr)) + return hdr.network - data; + + /* record next protocol */ + nexthdr = hdr.ipv4->protocol; + hdr.network += hlen; +#ifdef CONFIG_FCOE + } else if (protocol == __constant_htons(ETH_P_FCOE)) { + if ((hdr.network - data) > (max_len - FCOE_HEADER_LEN)) + return max_len; + hdr.network += FCOE_HEADER_LEN; +#endif + } else { + return hdr.network - data; + } + + /* finally sort out TCP */ + if (nexthdr == IPPROTO_TCP) { + if ((hdr.network - data) > (max_len - sizeof(struct tcphdr))) + return max_len; + + /* access doff as a u8 to avoid unaligned access on ia64 */ + hlen = (hdr.network[12] & 0xF0) >> 2; + + /* verify hlen meets minimum size requirements */ + if (hlen < sizeof(struct tcphdr)) + return hdr.network - data; + + hdr.network += hlen; + } + + /* + * If everything has gone correctly hdr.network should be the + * data section of the packet and will be the end of the header. + * If not then it probably represents the end of the last recognized + * header. + */ + if ((hdr.network - data) < max_len) + return hdr.network - data; + else + return max_len; +} + static void ixgbe_get_rsc_cnt(struct ixgbe_ring *rx_ring, union ixgbe_adv_rx_desc *rx_desc, struct sk_buff *skb) @@ -1299,6 +1397,32 @@ static void ixgbe_get_rsc_cnt(struct ixgbe_ring *rx_ring, IXGBE_CB(skb)->append_cnt += rsc_cnt - 1; } +static void ixgbe_set_rsc_gso_size(struct ixgbe_ring *ring, + struct sk_buff *skb) +{ + u16 hdr_len = ixgbe_get_headlen(skb->data, skb_headlen(skb)); + + /* set gso_size to avoid messing up TCP MSS */ + skb_shinfo(skb)->gso_size = DIV_ROUND_UP((skb->len - hdr_len), + IXGBE_CB(skb)->append_cnt); +} + +static void ixgbe_update_rsc_stats(struct ixgbe_ring *rx_ring, + struct sk_buff *skb) +{ + /* if append_cnt is 0 then frame is not RSC */ + if (!IXGBE_CB(skb)->append_cnt) + return; + + rx_ring->rx_stats.rsc_count += IXGBE_CB(skb)->append_cnt; + rx_ring->rx_stats.rsc_flush++; + + ixgbe_set_rsc_gso_size(rx_ring, skb); + + /* gso_size is computed using append_cnt so always clear it last */ + IXGBE_CB(skb)->append_cnt = 0; +} + static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, struct ixgbe_ring *rx_ring, int budget) @@ -1437,11 +1561,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, goto next_desc; } - if (IXGBE_CB(skb)->append_cnt) { - rx_ring->rx_stats.rsc_count += - IXGBE_CB(skb)->append_cnt; - rx_ring->rx_stats.rsc_flush++; - } + ixgbe_update_rsc_stats(rx_ring, skb); /* ERR_MASK will only have valid bits if EOP set */ if (unlikely(staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK)) { -- cgit v1.2.3-70-g09d2 From f990b79bc80ca7a23b8a6c33241c439072d0b85b Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 31 Jan 2012 02:59:34 +0000 Subject: ixgbe: Let the Rx buffer allocation clear status bits instead of cleanup This change makes it so that we always clear the status/error bits in the Rx descriptor in the allocation path instead of the cleanup path. The advantage to this is that we spend less time modifying data. As such we can modify the data once and then let it go cold in the cache instead of writing it, reading it, and then writing it again. Signed-off-by: Alexander Duyck Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 155 +++++++++++++++----------- 1 file changed, 93 insertions(+), 62 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 762f33777a7..538577b08e2 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -1101,8 +1101,75 @@ static inline void ixgbe_release_rx_desc(struct ixgbe_ring *rx_ring, u32 val) writel(val, rx_ring->tail); } +static bool ixgbe_alloc_mapped_skb(struct ixgbe_ring *rx_ring, + struct ixgbe_rx_buffer *bi) +{ + struct sk_buff *skb = bi->skb; + dma_addr_t dma = bi->dma; + + if (dma) + return true; + + if (likely(!skb)) { + skb = netdev_alloc_skb_ip_align(rx_ring->netdev, + rx_ring->rx_buf_len); + bi->skb = skb; + if (!skb) { + rx_ring->rx_stats.alloc_rx_buff_failed++; + return false; + } + + /* initialize skb for ring */ + skb_record_rx_queue(skb, rx_ring->queue_index); + } + + dma = dma_map_single(rx_ring->dev, skb->data, + rx_ring->rx_buf_len, DMA_FROM_DEVICE); + + if (dma_mapping_error(rx_ring->dev, dma)) { + rx_ring->rx_stats.alloc_rx_buff_failed++; + return false; + } + + bi->dma = dma; + return true; +} + +static bool ixgbe_alloc_mapped_page(struct ixgbe_ring *rx_ring, + struct ixgbe_rx_buffer *bi) +{ + struct page *page = bi->page; + dma_addr_t page_dma = bi->page_dma; + unsigned int page_offset = bi->page_offset ^ (PAGE_SIZE / 2); + + if (page_dma) + return true; + + if (!page) { + page = alloc_page(GFP_ATOMIC | __GFP_COLD); + bi->page = page; + if (unlikely(!page)) { + rx_ring->rx_stats.alloc_rx_page_failed++; + return false; + } + } + + page_dma = dma_map_page(rx_ring->dev, page, + page_offset, PAGE_SIZE / 2, + DMA_FROM_DEVICE); + + if (dma_mapping_error(rx_ring->dev, page_dma)) { + rx_ring->rx_stats.alloc_rx_page_failed++; + return false; + } + + bi->page_dma = page_dma; + bi->page_offset = page_offset; + return true; +} + /** - * ixgbe_alloc_rx_buffers - Replace used receive buffers; packet split + * ixgbe_alloc_rx_buffers - Replace used receive buffers * @rx_ring: ring to place buffers on * @cleaned_count: number of buffers to replace **/ @@ -1110,82 +1177,48 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_ring *rx_ring, u16 cleaned_count) { union ixgbe_adv_rx_desc *rx_desc; struct ixgbe_rx_buffer *bi; - struct sk_buff *skb; u16 i = rx_ring->next_to_use; - /* do nothing if no valid netdev defined */ - if (!rx_ring->netdev) + /* nothing to do or no valid netdev defined */ + if (!cleaned_count || !rx_ring->netdev) return; - while (cleaned_count--) { - rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i); - bi = &rx_ring->rx_buffer_info[i]; - skb = bi->skb; - - if (!skb) { - skb = netdev_alloc_skb_ip_align(rx_ring->netdev, - rx_ring->rx_buf_len); - if (!skb) { - rx_ring->rx_stats.alloc_rx_buff_failed++; - goto no_buffers; - } - /* initialize queue mapping */ - skb_record_rx_queue(skb, rx_ring->queue_index); - bi->skb = skb; - } + rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i); + bi = &rx_ring->rx_buffer_info[i]; + i -= rx_ring->count; - if (!bi->dma) { - bi->dma = dma_map_single(rx_ring->dev, - skb->data, - rx_ring->rx_buf_len, - DMA_FROM_DEVICE); - if (dma_mapping_error(rx_ring->dev, bi->dma)) { - rx_ring->rx_stats.alloc_rx_buff_failed++; - bi->dma = 0; - goto no_buffers; - } - } + while (cleaned_count--) { + if (!ixgbe_alloc_mapped_skb(rx_ring, bi)) + break; + /* Refresh the desc even if buffer_addrs didn't change + * because each write-back erases this info. */ if (ring_is_ps_enabled(rx_ring)) { - if (!bi->page) { - bi->page = alloc_page(GFP_ATOMIC | __GFP_COLD); - if (!bi->page) { - rx_ring->rx_stats.alloc_rx_page_failed++; - goto no_buffers; - } - } + rx_desc->read.hdr_addr = cpu_to_le64(bi->dma); - if (!bi->page_dma) { - /* use a half page if we're re-using */ - bi->page_offset ^= PAGE_SIZE / 2; - bi->page_dma = dma_map_page(rx_ring->dev, - bi->page, - bi->page_offset, - PAGE_SIZE / 2, - DMA_FROM_DEVICE); - if (dma_mapping_error(rx_ring->dev, - bi->page_dma)) { - rx_ring->rx_stats.alloc_rx_page_failed++; - bi->page_dma = 0; - goto no_buffers; - } - } + if (!ixgbe_alloc_mapped_page(rx_ring, bi)) + break; - /* Refresh the desc even if buffer_addrs didn't change - * because each write-back erases this info. */ rx_desc->read.pkt_addr = cpu_to_le64(bi->page_dma); - rx_desc->read.hdr_addr = cpu_to_le64(bi->dma); } else { rx_desc->read.pkt_addr = cpu_to_le64(bi->dma); - rx_desc->read.hdr_addr = 0; } + rx_desc++; + bi++; i++; - if (i == rx_ring->count) - i = 0; + if (unlikely(!i)) { + rx_desc = IXGBE_RX_DESC_ADV(rx_ring, 0); + bi = rx_ring->rx_buffer_info; + i -= rx_ring->count; + } + + /* clear the hdr_addr for the next_to_use descriptor */ + rx_desc->read.hdr_addr = 0; } -no_buffers: + i += rx_ring->count; + if (rx_ring->next_to_use != i) { rx_ring->next_to_use = i; ixgbe_release_rx_desc(rx_ring, i); @@ -1593,8 +1626,6 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, budget--; next_desc: - rx_desc->wb.upper.status_error = 0; - if (!budget) break; -- cgit v1.2.3-70-g09d2 From f56e0cb1fea6aa3caace1c1ddde3f847793dcf38 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 31 Jan 2012 02:59:39 +0000 Subject: ixgbe: Add function for testing status bits in Rx descriptor This change adds a small function for testing Rx status bits in the descriptor. The advantage to this is that we can avoid unnecessary byte swaps on big endian systems. Signed-off-by: Alexander Duyck Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 10 ++++- drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c | 59 ++++++++++++++++----------- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 51 ++++++++++------------- 3 files changed, 65 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h index fca05536284..260e1763788 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h @@ -329,6 +329,13 @@ struct ixgbe_q_vector { #define IXGBE_10K_ITR 400 #define IXGBE_8K_ITR 500 +/* ixgbe_test_staterr - tests bits in Rx descriptor status and error fields */ +static inline __le32 ixgbe_test_staterr(union ixgbe_adv_rx_desc *rx_desc, + const u32 stat_err_bits) +{ + return rx_desc->wb.upper.status_error & cpu_to_le32(stat_err_bits); +} + static inline u16 ixgbe_desc_unused(struct ixgbe_ring *ring) { u16 ntc = ring->next_to_clean; @@ -618,8 +625,7 @@ extern int ixgbe_fso(struct ixgbe_ring *tx_ring, struct sk_buff *skb, extern void ixgbe_cleanup_fcoe(struct ixgbe_adapter *adapter); extern int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, union ixgbe_adv_rx_desc *rx_desc, - struct sk_buff *skb, - u32 staterr); + struct sk_buff *skb); extern int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, struct scatterlist *sgl, unsigned int sgc); extern int ixgbe_fcoe_ddp_target(struct net_device *netdev, u16 xid, diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c index 4bc79424980..da7da752b6b 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c @@ -357,22 +357,20 @@ int ixgbe_fcoe_ddp_target(struct net_device *netdev, u16 xid, */ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, union ixgbe_adv_rx_desc *rx_desc, - struct sk_buff *skb, - u32 staterr) + struct sk_buff *skb) { - u16 xid; - u32 fctl; - u32 fceofe, fcerr, fcstat; int rc = -EINVAL; struct ixgbe_fcoe *fcoe; struct ixgbe_fcoe_ddp *ddp; struct fc_frame_header *fh; struct fcoe_crc_eof *crc; + __le32 fcerr = ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_FCERR); + __le32 ddp_err; + u32 fctl; + u16 xid; - fcerr = (staterr & IXGBE_RXDADV_ERR_FCERR); - fceofe = (staterr & IXGBE_RXDADV_ERR_FCEOFE); - if (fcerr == IXGBE_FCERR_BADCRC) - skb_checksum_none_assert(skb); + if (fcerr == cpu_to_le32(IXGBE_FCERR_BADCRC)) + skb->ip_summed = CHECKSUM_NONE; else skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -382,6 +380,7 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, else fh = (struct fc_frame_header *)(skb->data + sizeof(struct fcoe_hdr)); + fctl = ntoh24(fh->fh_f_ctl); if (fctl & FC_FC_EX_CTX) xid = be16_to_cpu(fh->fh_ox_id); @@ -396,27 +395,39 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, if (!ddp->udl) goto ddp_out; - if (fcerr | fceofe) + ddp_err = ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_FCEOFE | + IXGBE_RXDADV_ERR_FCERR); + if (ddp_err) goto ddp_out; - fcstat = (staterr & IXGBE_RXDADV_STAT_FCSTAT); - if (fcstat) { + switch (ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_FCSTAT)) { + /* return 0 to bypass going to ULD for DDPed data */ + case __constant_cpu_to_le32(IXGBE_RXDADV_STAT_FCSTAT_DDP): /* update length of DDPed data */ ddp->len = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss); - /* unmap the sg list when FCP_RSP is received */ - if (fcstat == IXGBE_RXDADV_STAT_FCSTAT_FCPRSP) { - pci_unmap_sg(adapter->pdev, ddp->sgl, - ddp->sgc, DMA_FROM_DEVICE); - ddp->err = (fcerr | fceofe); - ddp->sgl = NULL; - ddp->sgc = 0; - } - /* return 0 to bypass going to ULD for DDPed data */ - if (fcstat == IXGBE_RXDADV_STAT_FCSTAT_DDP) - rc = 0; - else if (ddp->len) + rc = 0; + break; + /* unmap the sg list when FCPRSP is received */ + case __constant_cpu_to_le32(IXGBE_RXDADV_STAT_FCSTAT_FCPRSP): + pci_unmap_sg(adapter->pdev, ddp->sgl, + ddp->sgc, DMA_FROM_DEVICE); + ddp->err = ddp_err; + ddp->sgl = NULL; + ddp->sgc = 0; + /* fall through */ + /* if DDP length is present pass it through to ULD */ + case __constant_cpu_to_le32(IXGBE_RXDADV_STAT_FCSTAT_NODDP): + /* update length of DDPed data */ + ddp->len = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss); + if (ddp->len) rc = ddp->len; + break; + /* no match will return as an error */ + case __constant_cpu_to_le32(IXGBE_RXDADV_STAT_FCSTAT_NOMTCH): + default: + break; } + /* In target mode, check the last data frame of the sequence. * For DDP in target mode, data is already DDPed but the header * indication of the last data frame ould allow is to tell if we diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 538577b08e2..b0469ddb158 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -1019,25 +1019,23 @@ static inline bool ixgbe_rx_is_fcoe(struct ixgbe_adapter *adapter, * ixgbe_receive_skb - Send a completed packet up the stack * @adapter: board private structure * @skb: packet to send up - * @status: hardware indication of status of receive * @rx_ring: rx descriptor ring (for a specific queue) to setup * @rx_desc: rx descriptor **/ static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector, - struct sk_buff *skb, u8 status, + struct sk_buff *skb, struct ixgbe_ring *ring, union ixgbe_adv_rx_desc *rx_desc) { struct ixgbe_adapter *adapter = q_vector->adapter; - struct napi_struct *napi = &q_vector->napi; - bool is_vlan = (status & IXGBE_RXD_STAT_VP); - u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan); - if (is_vlan && (tag & VLAN_VID_MASK)) - __vlan_hwaccel_put_tag(skb, tag); + if (ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) { + u16 vid = le16_to_cpu(rx_desc->wb.upper.vlan); + __vlan_hwaccel_put_tag(skb, vid); + } if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) - napi_gro_receive(napi, skb); + napi_gro_receive(&q_vector->napi, skb); else netif_rx(skb); } @@ -1047,12 +1045,10 @@ static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector, * @adapter: address of board private structure * @status_err: hardware indication of status of receive * @skb: skb currently being received and modified - * @status_err: status error value of last descriptor in packet **/ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter, union ixgbe_adv_rx_desc *rx_desc, - struct sk_buff *skb, - u32 status_err) + struct sk_buff *skb) { skb->ip_summed = CHECKSUM_NONE; @@ -1061,16 +1057,16 @@ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter, return; /* if IP and error */ - if ((status_err & IXGBE_RXD_STAT_IPCS) && - (status_err & IXGBE_RXDADV_ERR_IPE)) { + if (ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_IPCS) && + ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_IPE)) { adapter->hw_csum_rx_error++; return; } - if (!(status_err & IXGBE_RXD_STAT_L4CS)) + if (!ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_L4CS)) return; - if (status_err & IXGBE_RXDADV_ERR_TCPE) { + if (ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_TCPE)) { u16 pkt_info = rx_desc->wb.lower.lo_dword.hs_rss.pkt_info; /* @@ -1091,6 +1087,7 @@ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter, static inline void ixgbe_release_rx_desc(struct ixgbe_ring *rx_ring, u32 val) { + rx_ring->next_to_use = val; /* * Force memory writes to complete before letting h/w * know there are new descriptors to fetch. (Only @@ -1219,10 +1216,8 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_ring *rx_ring, u16 cleaned_count) i += rx_ring->count; - if (rx_ring->next_to_use != i) { - rx_ring->next_to_use = i; + if (rx_ring->next_to_use != i) ixgbe_release_rx_desc(rx_ring, i); - } } static inline u16 ixgbe_get_hlen(union ixgbe_adv_rx_desc *rx_desc) @@ -1469,15 +1464,13 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, #ifdef IXGBE_FCOE int ddp_bytes = 0; #endif /* IXGBE_FCOE */ - u32 staterr; u16 i; u16 cleaned_count = 0; i = rx_ring->next_to_clean; rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i); - staterr = le32_to_cpu(rx_desc->wb.upper.status_error); - while (staterr & IXGBE_RXD_STAT_DD) { + while (ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_DD)) { u32 upper_len = 0; rmb(); /* read descriptor and rx_buffer_info after status DD */ @@ -1553,12 +1546,13 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, prefetch(next_rxd); cleaned_count++; - if (!(staterr & IXGBE_RXD_STAT_EOP)) { + if ((!ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_EOP))) { struct ixgbe_rx_buffer *next_buffer; u32 nextp; if (IXGBE_CB(skb)->append_cnt) { - nextp = staterr & IXGBE_RXDADV_NEXTP_MASK; + nextp = le32_to_cpu( + rx_desc->wb.upper.status_error); nextp >>= IXGBE_RXDADV_NEXTP_SHIFT; } else { nextp = i; @@ -1597,12 +1591,13 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, ixgbe_update_rsc_stats(rx_ring, skb); /* ERR_MASK will only have valid bits if EOP set */ - if (unlikely(staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK)) { + if (unlikely(ixgbe_test_staterr(rx_desc, + IXGBE_RXDADV_ERR_FRAME_ERR_MASK))) { dev_kfree_skb_any(skb); goto next_desc; } - ixgbe_rx_checksum(adapter, rx_desc, skb, staterr); + ixgbe_rx_checksum(adapter, rx_desc, skb); if (adapter->netdev->features & NETIF_F_RXHASH) ixgbe_rx_hash(rx_desc, skb); @@ -1614,15 +1609,14 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, #ifdef IXGBE_FCOE /* if ddp, not passing to ULD unless for FCP_RSP or error */ if (ixgbe_rx_is_fcoe(adapter, rx_desc)) { - ddp_bytes = ixgbe_fcoe_ddp(adapter, rx_desc, skb, - staterr); + ddp_bytes = ixgbe_fcoe_ddp(adapter, rx_desc, skb); if (!ddp_bytes) { dev_kfree_skb_any(skb); goto next_desc; } } #endif /* IXGBE_FCOE */ - ixgbe_receive_skb(q_vector, skb, staterr, rx_ring, rx_desc); + ixgbe_receive_skb(q_vector, skb, rx_ring, rx_desc); budget--; next_desc: @@ -1637,7 +1631,6 @@ next_desc: /* use prefetched values */ rx_desc = next_rxd; - staterr = le32_to_cpu(rx_desc->wb.upper.status_error); } rx_ring->next_to_clean = i; -- cgit v1.2.3-70-g09d2 From e4f740287fbfdc7b68634e93c098c8ea8de691f1 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 31 Jan 2012 02:59:44 +0000 Subject: ixgbe: Drop the _ADV of descriptor macros since all ixgbe descriptors are ADV It doesn't make much sense to differentiate between advanced and legacy descriptors when the only descriptors that ixgbe uses are advanced descriptors. As such we can drop the _ADV suffix since all ixgbe descriptors are automatically advanced. Signed-off-by: Alexander Duyck Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 6 +++--- drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 4 ++-- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 26 ++++++++++++------------ 3 files changed, 18 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h index 260e1763788..882a58051a1 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h @@ -344,11 +344,11 @@ static inline u16 ixgbe_desc_unused(struct ixgbe_ring *ring) return ((ntc > ntu) ? 0 : ring->count) + ntc - ntu - 1; } -#define IXGBE_RX_DESC_ADV(R, i) \ +#define IXGBE_RX_DESC(R, i) \ (&(((union ixgbe_adv_rx_desc *)((R)->desc))[i])) -#define IXGBE_TX_DESC_ADV(R, i) \ +#define IXGBE_TX_DESC(R, i) \ (&(((union ixgbe_adv_tx_desc *)((R)->desc))[i])) -#define IXGBE_TX_CTXTDESC_ADV(R, i) \ +#define IXGBE_TX_CTXTDESC(R, i) \ (&(((struct ixgbe_adv_tx_context_desc *)((R)->desc))[i])) #define IXGBE_MAX_JUMBO_FRAME_SIZE 16128 diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index 1f31a04d3c9..1214fc178ee 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c @@ -1725,7 +1725,7 @@ static u16 ixgbe_clean_test_rings(struct ixgbe_ring *rx_ring, /* initialize next to clean and descriptor values */ rx_ntc = rx_ring->next_to_clean; tx_ntc = tx_ring->next_to_clean; - rx_desc = IXGBE_RX_DESC_ADV(rx_ring, rx_ntc); + rx_desc = IXGBE_RX_DESC(rx_ring, rx_ntc); staterr = le32_to_cpu(rx_desc->wb.upper.status_error); while (staterr & IXGBE_RXD_STAT_DD) { @@ -1756,7 +1756,7 @@ static u16 ixgbe_clean_test_rings(struct ixgbe_ring *rx_ring, tx_ntc = 0; /* fetch next descriptor */ - rx_desc = IXGBE_RX_DESC_ADV(rx_ring, rx_ntc); + rx_desc = IXGBE_RX_DESC(rx_ring, rx_ntc); staterr = le32_to_cpu(rx_desc->wb.upper.status_error); } diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index b0469ddb158..381d4dc88dc 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -366,7 +366,7 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter) "leng ntw timestamp bi->skb\n"); for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) { - tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i); + tx_desc = IXGBE_TX_DESC(tx_ring, i); tx_buffer_info = &tx_ring->tx_buffer_info[i]; u0 = (struct my_u0 *)tx_desc; pr_info("T [0x%03X] %016llX %016llX %016llX" @@ -447,7 +447,7 @@ rx_ring_summary: for (i = 0; i < rx_ring->count; i++) { rx_buffer_info = &rx_ring->rx_buffer_info[i]; - rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i); + rx_desc = IXGBE_RX_DESC(rx_ring, i); u0 = (struct my_u0 *)rx_desc; staterr = le32_to_cpu(rx_desc->wb.upper.status_error); if (staterr & IXGBE_RXD_STAT_DD) { @@ -754,7 +754,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, u16 i = tx_ring->next_to_clean; tx_buffer = &tx_ring->tx_buffer_info[i]; - tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i); + tx_desc = IXGBE_TX_DESC(tx_ring, i); for (; budget; budget--) { union ixgbe_adv_tx_desc *eop_desc = tx_buffer->next_to_watch; @@ -795,7 +795,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, i = 0; tx_buffer = tx_ring->tx_buffer_info; - tx_desc = IXGBE_TX_DESC_ADV(tx_ring, 0); + tx_desc = IXGBE_TX_DESC(tx_ring, 0); } } while (eop_desc); @@ -812,7 +812,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, if (check_for_tx_hang(tx_ring) && ixgbe_check_tx_hang(tx_ring)) { /* schedule immediate reset if we believe we hung */ struct ixgbe_hw *hw = &adapter->hw; - tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i); + tx_desc = IXGBE_TX_DESC(tx_ring, i); e_err(drv, "Detected Tx Unit Hang\n" " Tx Queue <%d>\n" " TDH, TDT <%x>, <%x>\n" @@ -1180,7 +1180,7 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_ring *rx_ring, u16 cleaned_count) if (!cleaned_count || !rx_ring->netdev) return; - rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i); + rx_desc = IXGBE_RX_DESC(rx_ring, i); bi = &rx_ring->rx_buffer_info[i]; i -= rx_ring->count; @@ -1205,7 +1205,7 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_ring *rx_ring, u16 cleaned_count) bi++; i++; if (unlikely(!i)) { - rx_desc = IXGBE_RX_DESC_ADV(rx_ring, 0); + rx_desc = IXGBE_RX_DESC(rx_ring, 0); bi = rx_ring->rx_buffer_info; i -= rx_ring->count; } @@ -1468,7 +1468,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, u16 cleaned_count = 0; i = rx_ring->next_to_clean; - rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i); + rx_desc = IXGBE_RX_DESC(rx_ring, i); while (ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_DD)) { u32 upper_len = 0; @@ -1542,7 +1542,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, if (i == rx_ring->count) i = 0; - next_rxd = IXGBE_RX_DESC_ADV(rx_ring, i); + next_rxd = IXGBE_RX_DESC(rx_ring, i); prefetch(next_rxd); cleaned_count++; @@ -6469,7 +6469,7 @@ void ixgbe_tx_ctxtdesc(struct ixgbe_ring *tx_ring, u32 vlan_macip_lens, struct ixgbe_adv_tx_context_desc *context_desc; u16 i = tx_ring->next_to_use; - context_desc = IXGBE_TX_CTXTDESC_ADV(tx_ring, i); + context_desc = IXGBE_TX_CTXTDESC(tx_ring, i); i++; tx_ring->next_to_use = (i < tx_ring->count) ? i : 0; @@ -6702,7 +6702,7 @@ static void ixgbe_tx_map(struct ixgbe_ring *tx_ring, cmd_type = ixgbe_tx_cmd_type(tx_flags); olinfo_status = ixgbe_tx_olinfo_status(tx_flags, paylen); - tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i); + tx_desc = IXGBE_TX_DESC(tx_ring, i); for (;;) { while (size > IXGBE_MAX_DATA_PER_TXD) { @@ -6717,7 +6717,7 @@ static void ixgbe_tx_map(struct ixgbe_ring *tx_ring, tx_desc++; i++; if (i == tx_ring->count) { - tx_desc = IXGBE_TX_DESC_ADV(tx_ring, 0); + tx_desc = IXGBE_TX_DESC(tx_ring, 0); i = 0; } } @@ -6753,7 +6753,7 @@ static void ixgbe_tx_map(struct ixgbe_ring *tx_ring, tx_desc++; i++; if (i == tx_ring->count) { - tx_desc = IXGBE_TX_DESC_ADV(tx_ring, 0); + tx_desc = IXGBE_TX_DESC(tx_ring, 0); i = 0; } } -- cgit v1.2.3-70-g09d2 From 8a0da21be84019d605af2c9a92b20a084db77de1 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 31 Jan 2012 02:59:49 +0000 Subject: ixgbe: Combine post-DMA processing of sk_buff fields into single function This change combines a number of post-DMA Rx packet processing functions into a single function. The advantage of this is that it combines most of the Rx descriptor processing into one spot so it should all be warm in the cache. Signed-off-by: Alexander Duyck Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 3 +- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 127 ++++++++++++++------------ 2 files changed, 71 insertions(+), 59 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h index 882a58051a1..2807a25e04e 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h @@ -190,6 +190,7 @@ struct ixgbe_rx_queue_stats { u64 non_eop_descs; u64 alloc_rx_page_failed; u64 alloc_rx_buff_failed; + u64 csum_err; }; enum ixbge_ring_state_t { @@ -198,6 +199,7 @@ enum ixbge_ring_state_t { __IXGBE_HANG_CHECK_ARMED, __IXGBE_RX_PS_ENABLED, __IXGBE_RX_RSC_ENABLED, + __IXGBE_RX_CSUM_UDP_ZERO_ERR, }; #define ring_is_ps_enabled(ring) \ @@ -379,7 +381,6 @@ struct ixgbe_adapter { * thus the additional *_CAPABLE flags. */ u32 flags; -#define IXGBE_FLAG_RX_CSUM_ENABLED (u32)(1) #define IXGBE_FLAG_MSI_CAPABLE (u32)(1 << 1) #define IXGBE_FLAG_MSI_ENABLED (u32)(1 << 2) #define IXGBE_FLAG_MSIX_CAPABLE (u32)(1 << 3) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 381d4dc88dc..ac1d925c000 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -991,10 +991,12 @@ static int __ixgbe_notify_dca(struct device *dev, void *data) } #endif /* CONFIG_IXGBE_DCA */ -static inline void ixgbe_rx_hash(union ixgbe_adv_rx_desc *rx_desc, +static inline void ixgbe_rx_hash(struct ixgbe_ring *ring, + union ixgbe_adv_rx_desc *rx_desc, struct sk_buff *skb) { - skb->rxhash = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss); + if (ring->netdev->features & NETIF_F_RXHASH) + skb->rxhash = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss); } /** @@ -1015,51 +1017,26 @@ static inline bool ixgbe_rx_is_fcoe(struct ixgbe_adapter *adapter, IXGBE_RXDADV_PKTTYPE_ETQF_SHIFT))); } -/** - * ixgbe_receive_skb - Send a completed packet up the stack - * @adapter: board private structure - * @skb: packet to send up - * @rx_ring: rx descriptor ring (for a specific queue) to setup - * @rx_desc: rx descriptor - **/ -static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector, - struct sk_buff *skb, - struct ixgbe_ring *ring, - union ixgbe_adv_rx_desc *rx_desc) -{ - struct ixgbe_adapter *adapter = q_vector->adapter; - - if (ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) { - u16 vid = le16_to_cpu(rx_desc->wb.upper.vlan); - __vlan_hwaccel_put_tag(skb, vid); - } - - if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) - napi_gro_receive(&q_vector->napi, skb); - else - netif_rx(skb); -} - /** * ixgbe_rx_checksum - indicate in skb if hw indicated a good cksum - * @adapter: address of board private structure - * @status_err: hardware indication of status of receive + * @ring: structure containing ring specific data + * @rx_desc: current Rx descriptor being processed * @skb: skb currently being received and modified **/ -static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter, +static inline void ixgbe_rx_checksum(struct ixgbe_ring *ring, union ixgbe_adv_rx_desc *rx_desc, struct sk_buff *skb) { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* Rx csum disabled */ - if (!(adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED)) + if (!(ring->netdev->features & NETIF_F_RXCSUM)) return; /* if IP and error */ if (ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_IPCS) && ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_IPE)) { - adapter->hw_csum_rx_error++; + ring->rx_stats.csum_err++; return; } @@ -1073,11 +1050,11 @@ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter, * 82599 errata, UDP frames with a 0 checksum can be marked as * checksum errors. */ - if ((pkt_info & IXGBE_RXDADV_PKTTYPE_UDP) && - (adapter->hw.mac.type == ixgbe_mac_82599EB)) + if ((pkt_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_UDP)) && + test_bit(__IXGBE_RX_CSUM_UDP_ZERO_ERR, &ring->state)) return; - adapter->hw_csum_rx_error++; + ring->rx_stats.csum_err++; return; } @@ -1115,9 +1092,6 @@ static bool ixgbe_alloc_mapped_skb(struct ixgbe_ring *rx_ring, rx_ring->rx_stats.alloc_rx_buff_failed++; return false; } - - /* initialize skb for ring */ - skb_record_rx_queue(skb, rx_ring->queue_index); } dma = dma_map_single(rx_ring->dev, skb->data, @@ -1451,17 +1425,58 @@ static void ixgbe_update_rsc_stats(struct ixgbe_ring *rx_ring, IXGBE_CB(skb)->append_cnt = 0; } +/** + * ixgbe_process_skb_fields - Populate skb header fields from Rx descriptor + * @rx_ring: rx descriptor ring packet is being transacted on + * @rx_desc: pointer to the EOP Rx descriptor + * @skb: pointer to current skb being populated + * + * This function checks the ring, descriptor, and packet information in + * order to populate the hash, checksum, VLAN, timestamp, protocol, and + * other fields within the skb. + **/ +static void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring, + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb) +{ + ixgbe_update_rsc_stats(rx_ring, skb); + + ixgbe_rx_hash(rx_ring, rx_desc, skb); + + ixgbe_rx_checksum(rx_ring, rx_desc, skb); + + if (ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) { + u16 vid = le16_to_cpu(rx_desc->wb.upper.vlan); + __vlan_hwaccel_put_tag(skb, vid); + } + + skb_record_rx_queue(skb, rx_ring->queue_index); + + skb->protocol = eth_type_trans(skb, rx_ring->netdev); +} + +static void ixgbe_rx_skb(struct ixgbe_q_vector *q_vector, + struct sk_buff *skb) +{ + struct ixgbe_adapter *adapter = q_vector->adapter; + + if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) + napi_gro_receive(&q_vector->napi, skb); + else + netif_rx(skb); +} + static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, struct ixgbe_ring *rx_ring, int budget) { - struct ixgbe_adapter *adapter = q_vector->adapter; union ixgbe_adv_rx_desc *rx_desc, *next_rxd; struct ixgbe_rx_buffer *rx_buffer_info; struct sk_buff *skb; unsigned int total_rx_bytes = 0, total_rx_packets = 0; const int current_node = numa_node_id(); #ifdef IXGBE_FCOE + struct ixgbe_adapter *adapter = q_vector->adapter; int ddp_bytes = 0; #endif /* IXGBE_FCOE */ u16 i; @@ -1588,8 +1603,6 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, goto next_desc; } - ixgbe_update_rsc_stats(rx_ring, skb); - /* ERR_MASK will only have valid bits if EOP set */ if (unlikely(ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_FRAME_ERR_MASK))) { @@ -1597,15 +1610,13 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, goto next_desc; } - ixgbe_rx_checksum(adapter, rx_desc, skb); - if (adapter->netdev->features & NETIF_F_RXHASH) - ixgbe_rx_hash(rx_desc, skb); - /* probably a little skewed due to removing CRC */ total_rx_bytes += skb->len; total_rx_packets++; - skb->protocol = eth_type_trans(skb, rx_ring->netdev); + /* populate checksum, timestamp, VLAN, and protocol */ + ixgbe_process_skb_fields(rx_ring, rx_desc, skb); + #ifdef IXGBE_FCOE /* if ddp, not passing to ULD unless for FCP_RSP or error */ if (ixgbe_rx_is_fcoe(adapter, rx_desc)) { @@ -1616,7 +1627,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, } } #endif /* IXGBE_FCOE */ - ixgbe_receive_skb(q_vector, skb, rx_ring, rx_desc); + ixgbe_rx_skb(q_vector, skb); budget--; next_desc: @@ -4851,6 +4862,13 @@ static int ixgbe_alloc_queues(struct ixgbe_adapter *adapter) ring->dev = &adapter->pdev->dev; ring->netdev = adapter->netdev; + /* + * 82599 errata, UDP frames with a 0 checksum can be marked as + * checksum errors. + */ + if (adapter->hw.mac.type == ixgbe_mac_82599EB) + set_bit(__IXGBE_RX_CSUM_UDP_ZERO_ERR, &ring->state); + adapter->rx_ring[rx] = ring; } @@ -5255,9 +5273,6 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) return -EIO; } - /* enable rx csum by default */ - adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED; - /* get assigned NUMA node */ adapter->node = dev_to_node(&pdev->dev); @@ -5748,7 +5763,7 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) u32 i, missed_rx = 0, mpc, bprc, lxon, lxoff, xon_off_tot; u64 non_eop_descs = 0, restart_queue = 0, tx_busy = 0; u64 alloc_rx_page_failed = 0, alloc_rx_buff_failed = 0; - u64 bytes = 0, packets = 0; + u64 bytes = 0, packets = 0, hw_csum_rx_error = 0; #ifdef IXGBE_FCOE struct ixgbe_fcoe *fcoe = &adapter->fcoe; unsigned int cpu; @@ -5778,12 +5793,14 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) non_eop_descs += rx_ring->rx_stats.non_eop_descs; alloc_rx_page_failed += rx_ring->rx_stats.alloc_rx_page_failed; alloc_rx_buff_failed += rx_ring->rx_stats.alloc_rx_buff_failed; + hw_csum_rx_error += rx_ring->rx_stats.csum_err; bytes += rx_ring->stats.bytes; packets += rx_ring->stats.packets; } adapter->non_eop_descs = non_eop_descs; adapter->alloc_rx_page_failed = alloc_rx_page_failed; adapter->alloc_rx_buff_failed = alloc_rx_buff_failed; + adapter->hw_csum_rx_error = hw_csum_rx_error; netdev->stats.rx_bytes = bytes; netdev->stats.rx_packets = packets; @@ -7412,12 +7429,6 @@ static int ixgbe_set_features(struct net_device *netdev, struct ixgbe_adapter *adapter = netdev_priv(netdev); bool need_reset = false; - /* If Rx checksum is disabled, then RSC/LRO should also be disabled */ - if (!(data & NETIF_F_RXCSUM)) - adapter->flags &= ~IXGBE_FLAG_RX_CSUM_ENABLED; - else - adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED; - /* Make sure RSC matches LRO, reset if change */ if (!!(data & NETIF_F_LRO) != !!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)) { -- cgit v1.2.3-70-g09d2 From c9157198417076c0c2664ba997e7b0217f61fcce Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Fri, 10 Feb 2012 21:30:27 +0530 Subject: regmap: Support for caching in reg_raw_write() Adding support for caching of data into the non-volatile register from the call of reg_raw_write(). This will allow the larger block of data write into multiple register without worrying whether register is cached or not through reg_raw_write(). Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 65558034318..74a6d4f8e3b 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -321,6 +321,26 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, if (!map->writeable_reg(map->dev, reg + i)) return -EINVAL; + if (!map->cache_bypass && map->format.parse_val) { + unsigned int ival; + int val_bytes = map->format.val_bytes; + for (i = 0; i < val_len / val_bytes; i++) { + memcpy(map->work_buf, val + (i * val_bytes), val_bytes); + ival = map->format.parse_val(map->work_buf); + ret = regcache_write(map, reg + i, ival); + if (ret) { + dev_err(map->dev, + "Error in caching of register: %u ret: %d\n", + reg + i, ret); + return ret; + } + } + if (map->cache_only) { + map->cache_dirty = true; + return 0; + } + } + map->format.format_reg(map->work_buf, reg); u8[0] |= map->write_flag_mask; @@ -366,7 +386,7 @@ int _regmap_write(struct regmap *map, unsigned int reg, int ret; BUG_ON(!map->format.format_write && !map->format.format_val); - if (!map->cache_bypass) { + if (!map->cache_bypass && map->format.format_write) { ret = regcache_write(map, reg, val); if (ret != 0) return ret; @@ -441,12 +461,8 @@ EXPORT_SYMBOL_GPL(regmap_write); int regmap_raw_write(struct regmap *map, unsigned int reg, const void *val, size_t val_len) { - size_t val_count = val_len / map->format.val_bytes; int ret; - WARN_ON(!regmap_volatile_range(map, reg, val_count) && - map->cache_type != REGCACHE_NONE); - mutex_lock(&map->lock); ret = _regmap_raw_write(map, reg, val, val_len); -- cgit v1.2.3-70-g09d2 From dd202c6dd612beecf87b8b85c2f09b23f77364a2 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Thu, 9 Feb 2012 10:15:18 +0100 Subject: drm/i915: use gtfifodbg Add register definitions for GTFIFODBG, and clear it during init time to make sure state is correct. This register tells us if either a read, or a write occurred while the fifo was full. It seems like bit 2 is an OR of bit 0 and bit 1, so we check that as well, but the documents are not quite clear. Reviewed-by: Chris Wilson Reviewed-by (v1): Eugeni Dodonov Signed-off-by: Ben Widawsky Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 6 ++++++ drivers/gpu/drm/i915/intel_display.c | 8 ++++++++ 2 files changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 7b4477cb165..5c62b788c25 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3703,6 +3703,12 @@ #define ECOBUS 0xa180 #define FORCEWAKE_MT_ENABLE (1<<5) +#define GTFIFODBG 0x120000 +#define GT_FIFO_CPU_ERROR_MASK 7 +#define GT_FIFO_OVFERR (1<<2) +#define GT_FIFO_IAWRERR (1<<1) +#define GT_FIFO_IARDERR (1<<0) + #define GT_FIFO_FREE_ENTRIES 0x120008 #define GT_FIFO_NUM_RESERVED_ENTRIES 20 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 7fae6917bea..db7ccbbb97c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8241,6 +8241,7 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); u32 pcu_mbox, rc6_mask = 0; + u32 gtfifodbg; int cur_freq, min_freq, max_freq; int i; @@ -8252,6 +8253,13 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) */ I915_WRITE(GEN6_RC_STATE, 0); mutex_lock(&dev_priv->dev->struct_mutex); + + /* Clear the DBG now so we don't confuse earlier errors */ + if ((gtfifodbg = I915_READ(GTFIFODBG))) { + DRM_ERROR("GT fifo had a previous error %x\n", gtfifodbg); + I915_WRITE(GTFIFODBG, gtfifodbg); + } + gen6_gt_force_wake_get(dev_priv); /* disable the counters and set deterministic thresholds */ -- cgit v1.2.3-70-g09d2 From ee64cbdbf617067988168a4a49fcaabdd2743da6 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Thu, 9 Feb 2012 10:15:19 +0100 Subject: drm/i915: catch gtfifo errors on forcewake_put This is similar to a patch I wrote several months ago. It's been updated for the new FORCEWAKE_MT. As recommended by Chris Wilson, use WARN() instead of DRM_ERROR, so we can get a backtrace. This shouldn't impact performance too much as the extra register read can replace the POSTING_READ we had previously. Reviewed-by: Chris Wilson Signed-off-by: Ben Widawsky Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 189041984ab..d783e2b4c91 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -385,16 +385,27 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); } +static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv) +{ + u32 gtfifodbg; + gtfifodbg = I915_READ_NOTRACE(GTFIFODBG); + if (WARN(gtfifodbg & GT_FIFO_CPU_ERROR_MASK, + "MMIO read or write has been dropped %x\n", gtfifodbg)) + I915_WRITE_NOTRACE(GTFIFODBG, GT_FIFO_CPU_ERROR_MASK); +} + void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) { I915_WRITE_NOTRACE(FORCEWAKE, 0); - POSTING_READ(FORCEWAKE); + /* The below doubles as a POSTING_READ */ + gen6_gt_check_fifodbg(dev_priv); } void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) { I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<16) | 0); - POSTING_READ(FORCEWAKE_MT); + /* The below doubles as a POSTING_READ */ + gen6_gt_check_fifodbg(dev_priv); } /* -- cgit v1.2.3-70-g09d2 From 67a3744f7515edda9888df5b226ec3b358908b42 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Thu, 9 Feb 2012 10:15:20 +0100 Subject: drm/i915: check gtfifodbg after possibly failed writes If we don't have a sufficient number of free entries in the FIFO, we proceed to do a write anyway. With this check we should have a clue if that write actually failed or not. After some discussion with Daniel Vetter regarding his original complaint, we agreed upon this. Reviewed-by: Chris Wilson Signed-off-by: Ben Widawsky Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 15 ++++++++++++--- drivers/gpu/drm/i915/i915_drv.h | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index d783e2b4c91..0694e170a33 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -421,8 +421,10 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); } -void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) +int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) { + int ret = 0; + if (dev_priv->gt_fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) { int loop = 500; u32 fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); @@ -430,10 +432,13 @@ void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) udelay(10); fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); } - WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES); + if (WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES)) + ++ret; dev_priv->gt_fifo_count = fifo; } dev_priv->gt_fifo_count--; + + return ret; } static int i915_drm_freeze(struct drm_device *dev) @@ -1001,11 +1006,15 @@ __i915_read(64, q) #define __i915_write(x, y) \ void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \ + u32 __fifo_ret = 0; \ trace_i915_reg_rw(true, reg, val, sizeof(val)); \ if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ - __gen6_gt_wait_for_fifo(dev_priv); \ + __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ } \ write##y(val, dev_priv->regs + reg); \ + if (unlikely(__fifo_ret)) { \ + gen6_gt_check_fifodbg(dev_priv); \ + } \ } __i915_write(8, b) __i915_write(16, w) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 922aed33035..000a9ad17dd 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1401,7 +1401,7 @@ extern void intel_display_print_error_state(struct seq_file *m, */ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv); void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv); -void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv); +int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv); /* We give fast paths for the really cool registers */ #define NEEDS_FORCE_WAKE(dev_priv, reg) \ -- cgit v1.2.3-70-g09d2 From 4e5527c9d1f373cb7dda6eec3af1d7b9659cdf85 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Sun, 12 Feb 2012 20:08:41 +0000 Subject: viafb: make SAMM to also work on LCD This patch enables LCD to handle SAMM without dual fb. Signed-off-by: Florian Tobias Schandinat --- drivers/video/via/chip.h | 2 -- drivers/video/via/hw.c | 27 +++++++++++---------------- drivers/video/via/lcd.c | 18 +++++++++--------- drivers/video/via/lcd.h | 3 ++- 4 files changed, 22 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/video/via/chip.h b/drivers/video/via/chip.h index 3ebf20c06ee..c2ecdb5a94d 100644 --- a/drivers/video/via/chip.h +++ b/drivers/video/via/chip.h @@ -146,8 +146,6 @@ struct tmds_setting_information { struct lvds_setting_information { int iga_path; - int h_active; - int v_active; int bpp; int lcd_panel_hres; int lcd_panel_vres; diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index e8725c5235c..d35ced70139 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -1530,11 +1530,7 @@ void viafb_update_device_setting(int hres, int vres, int bpp, int flag) viaparinfo->tmds_setting_info->h_active = hres; viaparinfo->tmds_setting_info->v_active = vres; - viaparinfo->lvds_setting_info->h_active = hres; - viaparinfo->lvds_setting_info->v_active = vres; viaparinfo->lvds_setting_info->bpp = bpp; - viaparinfo->lvds_setting_info2->h_active = hres; - viaparinfo->lvds_setting_info2->v_active = vres; viaparinfo->lvds_setting_info2->bpp = bpp; } else { @@ -1543,16 +1539,11 @@ void viafb_update_device_setting(int hres, int vres, int bpp, int flag) viaparinfo->tmds_setting_info->v_active = vres; } - if (viaparinfo->lvds_setting_info->iga_path == IGA2) { - viaparinfo->lvds_setting_info->h_active = hres; - viaparinfo->lvds_setting_info->v_active = vres; + if (viaparinfo->lvds_setting_info->iga_path == IGA2) viaparinfo->lvds_setting_info->bpp = bpp; - } - if (IGA2 == viaparinfo->lvds_setting_info2->iga_path) { - viaparinfo->lvds_setting_info2->h_active = hres; - viaparinfo->lvds_setting_info2->v_active = vres; + + if (IGA2 == viaparinfo->lvds_setting_info2->iga_path) viaparinfo->lvds_setting_info2->bpp = bpp; - } } } @@ -1933,7 +1924,8 @@ int viafb_setmode(int video_bpp, int video_bpp1) if (viafb_SAMM_ON && (viaparinfo->lvds_setting_info->iga_path == IGA2)) { viaparinfo->lvds_setting_info->bpp = video_bpp1; - viafb_lcd_set_mode(viaparinfo->lvds_setting_info, + viafb_lcd_set_mode(&var2, cxres, cyres, + viaparinfo->lvds_setting_info, &viaparinfo->chip_info->lvds_chip_info); } else { /* IGA1 doesn't have LCD scaling, so set it center. */ @@ -1942,7 +1934,8 @@ int viafb_setmode(int video_bpp, int video_bpp1) LCD_CENTERING; } viaparinfo->lvds_setting_info->bpp = video_bpp; - viafb_lcd_set_mode(viaparinfo->lvds_setting_info, + viafb_lcd_set_mode(&viafbinfo->var, 0, 0, + viaparinfo->lvds_setting_info, &viaparinfo->chip_info->lvds_chip_info); } } @@ -1950,7 +1943,8 @@ int viafb_setmode(int video_bpp, int video_bpp1) if (viafb_SAMM_ON && (viaparinfo->lvds_setting_info2->iga_path == IGA2)) { viaparinfo->lvds_setting_info2->bpp = video_bpp1; - viafb_lcd_set_mode(viaparinfo->lvds_setting_info2, + viafb_lcd_set_mode(&var2, cxres, cyres, + viaparinfo->lvds_setting_info2, &viaparinfo->chip_info->lvds_chip_info2); } else { /* IGA1 doesn't have LCD scaling, so set it center. */ @@ -1959,7 +1953,8 @@ int viafb_setmode(int video_bpp, int video_bpp1) LCD_CENTERING; } viaparinfo->lvds_setting_info2->bpp = video_bpp; - viafb_lcd_set_mode(viaparinfo->lvds_setting_info2, + viafb_lcd_set_mode(&viafbinfo->var, 0, 0, + viaparinfo->lvds_setting_info2, &viaparinfo->chip_info->lvds_chip_info2); } } diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c index 5f3b4e394e8..02cfdc8d7ed 100644 --- a/drivers/video/via/lcd.c +++ b/drivers/video/via/lcd.c @@ -55,8 +55,7 @@ static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres, int panel_vres); static void via_pitch_alignment_patch_lcd( struct lvds_setting_information *plvds_setting_info, - struct lvds_chip_information - *plvds_chip_info); + struct lvds_chip_information *plvds_chip_info, int hres); static void lcd_patch_skew_dvp0(struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info); @@ -456,14 +455,13 @@ static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres, static void via_pitch_alignment_patch_lcd( struct lvds_setting_information *plvds_setting_info, - struct lvds_chip_information - *plvds_chip_info) + struct lvds_chip_information *plvds_chip_info, int hres) { unsigned char cr13, cr35, cr65, cr66, cr67; unsigned long dwScreenPitch = 0; unsigned long dwPitch; - dwPitch = plvds_setting_info->h_active * (plvds_setting_info->bpp >> 3); + dwPitch = hres * (plvds_setting_info->bpp >> 3); if (dwPitch & 0x1F) { dwScreenPitch = ((dwPitch + 31) & ~31) >> 3; if (plvds_setting_info->iga_path == IGA2) { @@ -548,13 +546,14 @@ static void lcd_patch_skew(struct lvds_setting_information } /* LCD Set Mode */ -void viafb_lcd_set_mode(struct lvds_setting_information *plvds_setting_info, +void viafb_lcd_set_mode(const struct fb_var_screeninfo *var, u16 cxres, + u16 cyres, struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info) { int set_iga = plvds_setting_info->iga_path; int mode_bpp = plvds_setting_info->bpp; - int set_hres = plvds_setting_info->h_active; - int set_vres = plvds_setting_info->v_active; + int set_hres = cxres ? cxres : var->xres; + int set_vres = cyres ? cyres : var->yres; int panel_hres = plvds_setting_info->lcd_panel_hres; int panel_vres = plvds_setting_info->lcd_panel_vres; u32 clock; @@ -613,7 +612,8 @@ void viafb_lcd_set_mode(struct lvds_setting_information *plvds_setting_info, viafb_write_reg_mask(CR6A, VIACR, 0x01, BIT0); /* Patch for non 32bit alignment mode */ - via_pitch_alignment_patch_lcd(plvds_setting_info, plvds_chip_info); + via_pitch_alignment_patch_lcd(plvds_setting_info, plvds_chip_info, + set_hres); } static void integrated_lvds_disable(struct lvds_setting_information diff --git a/drivers/video/via/lcd.h b/drivers/video/via/lcd.h index 77ca7b862e6..8f3e4e06156 100644 --- a/drivers/video/via/lcd.h +++ b/drivers/video/via/lcd.h @@ -76,7 +76,8 @@ void __devinit viafb_init_lvds_output_interface(struct lvds_chip_information *plvds_chip_info, struct lvds_setting_information *plvds_setting_info); -void viafb_lcd_set_mode(struct lvds_setting_information *plvds_setting_info, +void viafb_lcd_set_mode(const struct fb_var_screeninfo *var, u16 cxres, + u16 cyres, struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info); bool __devinit viafb_lvds_trasmitter_identify(void); void viafb_init_lvds_output_interface(struct lvds_chip_information -- cgit v1.2.3-70-g09d2 From 2c4c8a8a73b64a8ea86ad85d8a59a5914d2f81ea Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Thu, 29 Dec 2011 23:37:07 +0000 Subject: viafb: fix I2C emulation on GPIO ports This patch fixes the I2C emulation on GPIO ports by enabling it (software controlled) and disabling the output on a GPIO line before reading it. Signed-off-by: Florian Tobias Schandinat --- drivers/video/via/via_i2c.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c index 78f1405dbab..dd53058bbbb 100644 --- a/drivers/video/via/via_i2c.c +++ b/drivers/video/via/via_i2c.c @@ -51,7 +51,7 @@ static void via_i2c_setscl(void *data, int state) val |= 0x01; break; case VIA_PORT_GPIO: - val |= 0x80; + val |= 0x82; break; default: printk(KERN_ERR "viafb_i2c: specify wrong i2c type.\n"); @@ -67,6 +67,9 @@ static int via_i2c_getscl(void *data) int ret = 0; spin_lock_irqsave(&i2c_vdev->reg_lock, flags); + if (adap_data->type == VIA_PORT_GPIO) + via_write_reg_mask(adap_data->io_port, adap_data->ioport_index, + 0, 0x80); if (via_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x08) ret = 1; spin_unlock_irqrestore(&i2c_vdev->reg_lock, flags); @@ -80,6 +83,9 @@ static int via_i2c_getsda(void *data) int ret = 0; spin_lock_irqsave(&i2c_vdev->reg_lock, flags); + if (adap_data->type == VIA_PORT_GPIO) + via_write_reg_mask(adap_data->io_port, adap_data->ioport_index, + 0, 0x40); if (via_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x04) ret = 1; spin_unlock_irqrestore(&i2c_vdev->reg_lock, flags); @@ -103,7 +109,7 @@ static void via_i2c_setsda(void *data, int state) val |= 0x01; break; case VIA_PORT_GPIO: - val |= 0x40; + val |= 0x42; break; default: printk(KERN_ERR "viafb_i2c: specify wrong i2c type.\n"); -- cgit v1.2.3-70-g09d2 From c718a54649475cc397484f96e70f6d0fdd267165 Mon Sep 17 00:00:00 2001 From: Danny Kukawka Date: Mon, 30 Jan 2012 23:00:17 +0100 Subject: riva/fbdev: fix several -Wuninitialized Fix several -Wuninitialized compiler warnings by changing the order of getting modedb in riva_update_default_var() to set first the fallback and then the prefered timing. Signed-off-by: Danny Kukawka Signed-off-by: Florian Tobias Schandinat --- drivers/video/riva/fbdev.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index 2f58cf9c813..90df1a60bd1 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c @@ -1816,6 +1816,8 @@ static void __devinit riva_update_default_var(struct fb_var_screeninfo *var, specs->modedb, specs->modedb_len, NULL, 8); } else if (specs->modedb != NULL) { + /* get first mode in database as fallback */ + modedb = specs->modedb[0]; /* get preferred timing */ if (info->monspecs.misc & FB_MISC_1ST_DETAIL) { int i; @@ -1826,9 +1828,6 @@ static void __devinit riva_update_default_var(struct fb_var_screeninfo *var, break; } } - } else { - /* otherwise, get first mode in database */ - modedb = specs->modedb[0]; } var->bits_per_pixel = 8; riva_update_var(var, &modedb); -- cgit v1.2.3-70-g09d2 From 3a84409ce3cccdbe1753dd9fd4eb1a7a9dded5c3 Mon Sep 17 00:00:00 2001 From: "Manjunathappa, Prakash" Date: Thu, 9 Feb 2012 10:34:38 +0530 Subject: video: da8xx-fb: Fix build warning on unused label Patch fixes build warning on label "err_cpu_freq" when CONFIG_CPU_FREQ is not defined. Signed-off-by: Manjunathappa, Prakash Signed-off-by: Florian Tobias Schandinat --- drivers/video/da8xx-fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 9ecc30744c6..720cb837fed 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -1270,8 +1270,8 @@ static int __devinit fb_probe(struct platform_device *device) irq_freq: #ifdef CONFIG_CPU_FREQ lcd_da8xx_cpufreq_deregister(par); -#endif err_cpu_freq: +#endif unregister_framebuffer(da8xx_fb_info); err_dealloc_cmap: -- cgit v1.2.3-70-g09d2 From 12fa8350244d73b6111ec9bc6c2fd5d49fa601b5 Mon Sep 17 00:00:00 2001 From: "Manjunathappa, Prakash" Date: Thu, 9 Feb 2012 11:54:06 +0530 Subject: video:da8xx-fb: calculate pixel clock period for the panel Patch calculates pixel clock period in pico seconds and updates the same in variable screen information structure. fbset utility uses this information. Signed-off-by: Manjunathappa, Prakash Signed-off-by: Florian Tobias Schandinat --- drivers/video/da8xx-fb.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 720cb837fed..dd80386b0ed 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -32,6 +32,7 @@ #include #include #include